bake-client.c 36.9 KB
Newer Older
Philip Carns's avatar
Philip Carns committed
1
2
/*
 * (C) 2016 The University of Chicago
Philip Carns's avatar
Philip Carns committed
3
 *
Philip Carns's avatar
Philip Carns committed
4
5
6
 * See COPYRIGHT in top-level directory.
 */

7
8
#include "bake-config.h"

9
#include <assert.h>
Philip Carns's avatar
Philip Carns committed
10
#include <margo.h>
11
#include <bake-client.h>
Philip Carns's avatar
Philip Carns committed
12
#include "uthash.h"
13
#include "bake-rpc.h"
14
#include "bake-timing.h"
Philip Carns's avatar
Philip Carns committed
15

16
#define BAKE_DEFAULT_EAGER_LIMIT 2048
17

18
/* Refers to a single Margo initialization, for now this is shared by
19
20
 * all remote BAKE targets.  In the future we probably need to support
 * multiple in case we run atop more than one transport at a time.
21
 */
Philip Carns's avatar
Philip Carns committed
22
23
struct bake_client {
    margo_instance_id mid;
24

25
26
27
28
29
30
    hg_id_t bake_probe_id;
    hg_id_t bake_create_id;
    hg_id_t bake_eager_write_id;
    hg_id_t bake_eager_read_id;
    hg_id_t bake_write_id;
    hg_id_t bake_persist_id;
31
    hg_id_t bake_create_write_persist_id;
32
    hg_id_t bake_eager_create_write_persist_id;
33
    hg_id_t bake_get_size_id;
34
    hg_id_t bake_get_data_id;
35
36
    hg_id_t bake_read_id;
    hg_id_t bake_noop_id;
Shane Snyder's avatar
Shane Snyder committed
37
    hg_id_t bake_remove_id;
38
    hg_id_t bake_migrate_region_id;
39
    hg_id_t bake_migrate_target_id;
40
41

    uint64_t num_provider_handles;
42
43
};

44
struct bake_provider_handle {
45
    struct bake_client* client;
46
    hg_addr_t           addr;
47
    uint16_t            provider_id;
48
    uint64_t            refcount;
49
    uint64_t            eager_limit;
50
};
Philip Carns's avatar
Philip Carns committed
51

52
static int bake_client_register(bake_client_t client, margo_instance_id mid)
Philip Carns's avatar
Philip Carns committed
53
{
54
    client->mid = mid;
Philip Carns's avatar
Philip Carns committed
55

56
57
    /* check if RPCs have already been registered */
    hg_bool_t flag;
Philip Carns's avatar
Philip Carns committed
58
    hg_id_t   id;
59
60
    margo_registered_name(mid, "bake_probe_rpc", &id, &flag);

Philip Carns's avatar
Philip Carns committed
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    if (flag == HG_TRUE) { /* RPCs already registered */

        margo_registered_name(mid, "bake_probe_rpc", &client->bake_probe_id,
                              &flag);
        margo_registered_name(mid, "bake_create_rpc", &client->bake_create_id,
                              &flag);
        margo_registered_name(mid, "bake_write_rpc", &client->bake_write_id,
                              &flag);
        margo_registered_name(mid, "bake_eager_write_rpc",
                              &client->bake_eager_write_id, &flag);
        margo_registered_name(mid, "bake_eager_read_rpc",
                              &client->bake_eager_read_id, &flag);
        margo_registered_name(mid, "bake_persist_rpc", &client->bake_persist_id,
                              &flag);
        margo_registered_name(mid, "bake_create_write_persist_rpc",
                              &client->bake_create_write_persist_id, &flag);
        margo_registered_name(mid, "bake_eager_create_write_persist_rpc",
                              &client->bake_eager_create_write_persist_id,
                              &flag);
        margo_registered_name(mid, "bake_get_size_rpc",
                              &client->bake_get_size_id, &flag);
        margo_registered_name(mid, "bake_get_data_rpc",
                              &client->bake_get_data_id, &flag);
        margo_registered_name(mid, "bake_read_rpc", &client->bake_read_id,
                              &flag);
        margo_registered_name(mid, "bake_noop_rpc", &client->bake_noop_id,
                              &flag);
        margo_registered_name(mid, "bake_remove_rpc", &client->bake_remove_id,
                              &flag);
        margo_registered_name(mid, "bake_migrate_region_rpc",
                              &client->bake_migrate_region_id, &flag);
        margo_registered_name(mid, "bake_migrate_target_rpc",
                              &client->bake_migrate_target_id, &flag);
94
95
96

    } else { /* RPCs not already registered */

Philip Carns's avatar
Philip Carns committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        client->bake_probe_id = MARGO_REGISTER(
            mid, "bake_probe_rpc", bake_probe_in_t, bake_probe_out_t, NULL);
        client->bake_create_id = MARGO_REGISTER(
            mid, "bake_create_rpc", bake_create_in_t, bake_create_out_t, NULL);
        client->bake_write_id = MARGO_REGISTER(
            mid, "bake_write_rpc", bake_write_in_t, bake_write_out_t, NULL);
        client->bake_eager_write_id
            = MARGO_REGISTER(mid, "bake_eager_write_rpc", bake_eager_write_in_t,
                             bake_eager_write_out_t, NULL);
        client->bake_eager_read_id
            = MARGO_REGISTER(mid, "bake_eager_read_rpc", bake_eager_read_in_t,
                             bake_eager_read_out_t, NULL);
        client->bake_persist_id
            = MARGO_REGISTER(mid, "bake_persist_rpc", bake_persist_in_t,
                             bake_persist_out_t, NULL);
        client->bake_create_write_persist_id
            = MARGO_REGISTER(mid, "bake_create_write_persist_rpc",
                             bake_create_write_persist_in_t,
                             bake_create_write_persist_out_t, NULL);
        client->bake_eager_create_write_persist_id
            = MARGO_REGISTER(mid, "bake_eager_create_write_persist_rpc",
                             bake_eager_create_write_persist_in_t,
                             bake_eager_create_write_persist_out_t, NULL);
        client->bake_get_size_id
            = MARGO_REGISTER(mid, "bake_get_size_rpc", bake_get_size_in_t,
                             bake_get_size_out_t, NULL);
        client->bake_get_data_id
            = MARGO_REGISTER(mid, "bake_get_data_rpc", bake_get_data_in_t,
                             bake_get_data_out_t, NULL);
        client->bake_read_id = MARGO_REGISTER(
            mid, "bake_read_rpc", bake_read_in_t, bake_read_out_t, NULL);
        client->bake_noop_id
            = MARGO_REGISTER(mid, "bake_noop_rpc", void, void, NULL);
        client->bake_remove_id = MARGO_REGISTER(
            mid, "bake_remove_rpc", bake_remove_in_t, bake_remove_out_t, NULL);
        client->bake_migrate_region_id = MARGO_REGISTER(
            mid, "bake_migrate_region_rpc", bake_migrate_region_in_t,
            bake_migrate_region_out_t, NULL);
        client->bake_migrate_target_id = MARGO_REGISTER(
            mid, "bake_migrate_target_rpc", bake_migrate_target_in_t,
            bake_migrate_target_out_t, NULL);
138
    }
Philip Carns's avatar
Philip Carns committed
139

Matthieu Dorier's avatar
Matthieu Dorier committed
140
    return BAKE_SUCCESS;
141
142
}

143
144
145
int bake_client_init(margo_instance_id mid, bake_client_t* client)
{
    bake_client_t c = (bake_client_t)calloc(1, sizeof(*c));
Philip Carns's avatar
Philip Carns committed
146
    if (!c) return BAKE_ERR_ALLOCATION;
147

148
149
    c->num_provider_handles = 0;

150
    int ret = bake_client_register(c, mid);
Philip Carns's avatar
Philip Carns committed
151
    if (ret != BAKE_SUCCESS) return ret;
152
153

    *client = c;
Matthieu Dorier's avatar
Matthieu Dorier committed
154
    return BAKE_SUCCESS;
155
156
157
158
}

int bake_client_finalize(bake_client_t client)
{
Philip Carns's avatar
Philip Carns committed
159
    if (client->num_provider_handles != 0) {
Philip Carns's avatar
Philip Carns committed
160
161
162
163
        BAKE_WARNING(client->mid,
                     "%llu provider handles not released before "
                     "bake_client_finalize was called\n",
                     (long long unsigned int)client->num_provider_handles);
164
    }
165
    free(client);
Matthieu Dorier's avatar
Matthieu Dorier committed
166
    return BAKE_SUCCESS;
167
168
}

Philip Carns's avatar
Philip Carns committed
169
170
171
172
int bake_probe(bake_provider_handle_t provider,
               uint64_t               max_targets,
               bake_target_id_t*      bti,
               uint64_t*              num_targets)
173
{
Philip Carns's avatar
Philip Carns committed
174
175
176
177
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t      hret;
    int              ret;
    bake_probe_in_t  in;
178
    bake_probe_out_t out;
Philip Carns's avatar
Philip Carns committed
179
    hg_handle_t      handle;
Philip Carns's avatar
Philip Carns committed
180

Philip Carns's avatar
Philip Carns committed
181
    if (bti == NULL) max_targets = 0;
182
183
    in.max_targets = max_targets;

184
    /* create handle */
Philip Carns's avatar
Philip Carns committed
185
186
    hret = margo_create(provider->client->mid, provider->addr,
                        provider->client->bake_probe_id, &handle);
187

Philip Carns's avatar
Philip Carns committed
188
    if (hret != HG_SUCCESS) return BAKE_ERR_MERCURY;
189

190
191
    TIMERS_END_STEP(0);

192
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
193
    if (hret != HG_SUCCESS) {
194
        margo_destroy(handle);
Matthieu Dorier's avatar
Matthieu Dorier committed
195
        return BAKE_ERR_MERCURY;
196
197
    }

198
199
    TIMERS_END_STEP(1);

200
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
201
    if (hret != HG_SUCCESS) {
202
        margo_destroy(handle);
Matthieu Dorier's avatar
Matthieu Dorier committed
203
        return BAKE_ERR_MERCURY;
204
205
206
207
    }

    ret = out.ret;

Philip Carns's avatar
Philip Carns committed
208
209
    if (ret == HG_SUCCESS) {
        if (max_targets == 0) {
210
211
            *num_targets = out.num_targets;
        } else {
Philip Carns's avatar
Philip Carns committed
212
213
214
            uint64_t s
                = out.num_targets > max_targets ? max_targets : out.num_targets;
            if (s > 0) { memcpy(bti, out.targets, sizeof(*bti) * s); }
215
            *num_targets = s;
216
        }
217
218
    }

219
220
221
    margo_free_output(handle, &out);
    margo_destroy(handle);

222
223
224
    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

225
    return ret;
Philip Carns's avatar
Philip Carns committed
226
}
227

Philip Carns's avatar
Philip Carns committed
228
229
230
231
int bake_provider_handle_create(bake_client_t           client,
                                hg_addr_t               addr,
                                uint16_t                provider_id,
                                bake_provider_handle_t* handle)
Philip Carns's avatar
Philip Carns committed
232
{
Philip Carns's avatar
Philip Carns committed
233
    if (client == BAKE_CLIENT_NULL) return BAKE_ERR_INVALID_ARG;
234

Philip Carns's avatar
Philip Carns committed
235
236
    bake_provider_handle_t provider
        = (bake_provider_handle_t)calloc(1, sizeof(*provider));
237

Philip Carns's avatar
Philip Carns committed
238
    if (!provider) return BAKE_ERR_ALLOCATION;
239
240

    hg_return_t ret = margo_addr_dup(client->mid, addr, &(provider->addr));
Philip Carns's avatar
Philip Carns committed
241
    if (ret != HG_SUCCESS) {
242
        free(provider);
Matthieu Dorier's avatar
Matthieu Dorier committed
243
        return BAKE_ERR_MERCURY;
244
    }
Philip Carns's avatar
Philip Carns committed
245
246

    provider->client      = client;
247
    provider->provider_id = provider_id;
Philip Carns's avatar
Philip Carns committed
248
    provider->refcount    = 1;
249
    provider->eager_limit = BAKE_DEFAULT_EAGER_LIMIT;
250

251
252
    client->num_provider_handles += 1;

253
    *handle = provider;
Matthieu Dorier's avatar
Matthieu Dorier committed
254
    return BAKE_SUCCESS;
255
256
}

Philip Carns's avatar
Philip Carns committed
257
258
int bake_provider_handle_get_eager_limit(bake_provider_handle_t handle,
                                         uint64_t*              limit)
259
{
Philip Carns's avatar
Philip Carns committed
260
    if (handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
261
    *limit = handle->eager_limit;
Matthieu Dorier's avatar
Matthieu Dorier committed
262
    return BAKE_SUCCESS;
263
264
}

Philip Carns's avatar
Philip Carns committed
265
266
int bake_provider_handle_set_eager_limit(bake_provider_handle_t handle,
                                         uint64_t               limit)
267
{
Philip Carns's avatar
Philip Carns committed
268
    if (handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
269
    handle->eager_limit = limit;
Matthieu Dorier's avatar
Matthieu Dorier committed
270
    return BAKE_SUCCESS;
271
272
}

273
274
int bake_provider_handle_ref_incr(bake_provider_handle_t handle)
{
Philip Carns's avatar
Philip Carns committed
275
    if (handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
276
    handle->refcount += 1;
Matthieu Dorier's avatar
Matthieu Dorier committed
277
    return BAKE_SUCCESS;
Philip Carns's avatar
Philip Carns committed
278
279
}

Matthieu Dorier's avatar
Matthieu Dorier committed
280
int bake_provider_handle_get_info(bake_provider_handle_t handle,
Philip Carns's avatar
Philip Carns committed
281
282
283
                                  bake_client_t*         client,
                                  hg_addr_t*             addr,
                                  uint16_t*              provider_id)
284
{
Philip Carns's avatar
Philip Carns committed
285
    int         ret  = BAKE_SUCCESS;
286
    hg_return_t hret = HG_SUCCESS;
Philip Carns's avatar
Philip Carns committed
287
288
289
290
291
    if (handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
    if (client) *client = handle->client;
    if (addr) hret = margo_addr_dup(handle->client->mid, handle->addr, addr);
    if (provider_id) *provider_id = handle->provider_id;
    if (hret != HG_SUCCESS) ret = BAKE_ERR_MERCURY;
292
293
294
    return ret;
}

295
296
int bake_provider_handle_release(bake_provider_handle_t handle)
{
Philip Carns's avatar
Philip Carns committed
297
    if (handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
298
    handle->refcount -= 1;
Philip Carns's avatar
Philip Carns committed
299
    if (handle->refcount == 0) {
300
        margo_addr_free(handle->client->mid, handle->addr);
301
        handle->client->num_provider_handles -= 1;
302
303
        free(handle);
    }
Matthieu Dorier's avatar
Matthieu Dorier committed
304
    return BAKE_SUCCESS;
305
}
Philip Carns's avatar
Philip Carns committed
306

307
int bake_shutdown_service(bake_client_t client, hg_addr_t addr)
Philip Carns's avatar
Philip Carns committed
308
{
309
    return margo_shutdown_remote_instance(client->mid, addr);
Philip Carns's avatar
Philip Carns committed
310
}
Philip Carns's avatar
Philip Carns committed
311

Philip Carns's avatar
Philip Carns committed
312
313
314
315
316
317
static int bake_eager_write(bake_provider_handle_t provider,
                            bake_target_id_t       tid,
                            bake_region_id_t       rid,
                            uint64_t               region_offset,
                            void const*            buf,
                            uint64_t               buf_size)
Philip Carns's avatar
Philip Carns committed
318
{
Philip Carns's avatar
Philip Carns committed
319
320
321
322
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t            hret;
    hg_handle_t            handle = HG_HANDLE_NULL;
    bake_eager_write_in_t  in;
323
    bake_eager_write_out_t out;
Philip Carns's avatar
Philip Carns committed
324
    int                    ret;
Philip Carns's avatar
Philip Carns committed
325

Philip Carns's avatar
Philip Carns committed
326
327
    in.bti           = tid;
    in.rid           = rid;
Philip Carns's avatar
Philip Carns committed
328
    in.region_offset = region_offset;
Philip Carns's avatar
Philip Carns committed
329
330
331
332
333
    in.size          = buf_size;
    in.buffer        = (char*)buf;

    hret = margo_create(provider->client->mid, provider->addr,
                        provider->client->bake_eager_write_id, &handle);
334

Philip Carns's avatar
Philip Carns committed
335
    if (hret != HG_SUCCESS) {
336
337
338
339
340
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
Philip Carns's avatar
Philip Carns committed
341

342
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
343
    if (hret != HG_SUCCESS) {
344
345
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
346
347
    }

348
349
    TIMERS_END_STEP(1);

Shane Snyder's avatar
Shane Snyder committed
350
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
351
    if (hret != HG_SUCCESS) {
Shane Snyder's avatar
Shane Snyder committed
352
        margo_destroy(handle);
Matthieu Dorier's avatar
Matthieu Dorier committed
353
        return BAKE_ERR_MERCURY;
Philip Carns's avatar
Philip Carns committed
354
    }
355

Philip Carns's avatar
Philip Carns committed
356
357
    ret = out.ret;

358
finish:
Shane Snyder's avatar
Shane Snyder committed
359
360
    margo_free_output(handle, &out);
    margo_destroy(handle);
361
362
    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();
363

Matthieu Dorier's avatar
Matthieu Dorier committed
364
    return ret;
Philip Carns's avatar
Philip Carns committed
365
366
}

Philip Carns's avatar
Philip Carns committed
367
368
369
370
371
372
int bake_write(bake_provider_handle_t provider,
               bake_target_id_t       tid,
               bake_region_id_t       rid,
               uint64_t               region_offset,
               void const*            buf,
               uint64_t               buf_size)
Philip Carns's avatar
Philip Carns committed
373
{
Philip Carns's avatar
Philip Carns committed
374
375
    hg_return_t     hret;
    hg_handle_t     handle = HG_HANDLE_NULL;
376
    bake_write_in_t in;
377
    in.bulk_handle = HG_BULK_NULL;
378
    bake_write_out_t out;
Philip Carns's avatar
Philip Carns committed
379
    int              ret;
380

Philip Carns's avatar
Philip Carns committed
381
382
383
    if (buf_size <= provider->eager_limit)
        return (
            bake_eager_write(provider, tid, rid, region_offset, buf, buf_size));
Philip Carns's avatar
Philip Carns committed
384

385
386
    TIMERS_INITIALIZE("bulk_create", "forward", "end");

Philip Carns's avatar
Philip Carns committed
387
388
    in.bti           = tid;
    in.rid           = rid;
Philip Carns's avatar
Philip Carns committed
389
    in.region_offset = region_offset;
Philip Carns's avatar
Philip Carns committed
390
391
392
393
394
395
396
397
398
    in.bulk_offset   = 0;
    in.bulk_handle   = HG_BULK_NULL;
    in.bulk_size     = buf_size;
    in.remote_addr_str
        = NULL; /* set remote_addr to NULL to disable proxy write */

    hret = margo_bulk_create(provider->client->mid, 1, (void**)(&buf),
                             &buf_size, HG_BULK_READ_ONLY, &in.bulk_handle);
    if (hret != HG_SUCCESS) {
399
400
401
402
403
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
404

Philip Carns's avatar
Philip Carns committed
405
406
407
408
    hret = margo_create(provider->client->mid, provider->addr,
                        provider->client->bake_write_id, &handle);

    if (hret != HG_SUCCESS) {
409
410
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
411
412
    }

413
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
414
    if (hret != HG_SUCCESS) {
415
416
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
417
418
    }

419
420
    TIMERS_END_STEP(1);

Shane Snyder's avatar
Shane Snyder committed
421
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
422
    if (hret != HG_SUCCESS) {
423
424
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
425
    }
Philip Carns's avatar
Philip Carns committed
426

Philip Carns's avatar
Philip Carns committed
427
428
    ret = out.ret;

429
430
finish:

Shane Snyder's avatar
Shane Snyder committed
431
    margo_free_output(handle, &out);
432
    margo_bulk_free(in.bulk_handle);
Shane Snyder's avatar
Shane Snyder committed
433
    margo_destroy(handle);
434
435
436
437

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Matthieu Dorier's avatar
Matthieu Dorier committed
438
    return ret;
Philip Carns's avatar
Philip Carns committed
439
440
}

Philip Carns's avatar
Philip Carns committed
441
442
443
444
445
446
447
448
int bake_proxy_write(bake_provider_handle_t provider,
                     bake_target_id_t       tid,
                     bake_region_id_t       rid,
                     uint64_t               region_offset,
                     hg_bulk_t              remote_bulk,
                     uint64_t               remote_offset,
                     const char*            remote_addr,
                     uint64_t               size)
449
{
Philip Carns's avatar
Philip Carns committed
450
451
452
453
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t      hret;
    hg_handle_t      handle = HG_HANDLE_NULL;
    bake_write_in_t  in;
454
    bake_write_out_t out;
Philip Carns's avatar
Philip Carns committed
455
456
457
458
459
460
461
462
    int              ret;

    in.bti             = tid;
    in.rid             = rid;
    in.region_offset   = region_offset;
    in.bulk_handle     = remote_bulk;
    in.bulk_offset     = remote_offset;
    in.bulk_size       = size;
463
    in.remote_addr_str = (char*)remote_addr;
Shane Snyder's avatar
Shane Snyder committed
464

465
    hret = margo_create(provider->client->mid, provider->addr,
Philip Carns's avatar
Philip Carns committed
466
                        provider->client->bake_write_id, &handle);
467

Philip Carns's avatar
Philip Carns committed
468
    if (hret != HG_SUCCESS) {
469
470
471
472
473
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
474

475
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
476
    if (hret != HG_SUCCESS) {
477
478
        ret = BAKE_ERR_MERCURY;
        goto finish;
479
    }
480
481

    TIMERS_END_STEP(1);
Philip Carns's avatar
Philip Carns committed
482

483
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
484
    if (hret != HG_SUCCESS) {
485
486
        ret = BAKE_ERR_MERCURY;
        goto finish;
487
488
489
490
    }

    ret = out.ret;

491
492
finish:

493
494
    margo_free_output(handle, &out);
    margo_destroy(handle);
495
496
497
498

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
499
    return (ret);
500
501
}

Philip Carns's avatar
Philip Carns committed
502
503
504
505
int bake_create(bake_provider_handle_t provider,
                bake_target_id_t       bti,
                uint64_t               region_size,
                bake_region_id_t*      rid)
Philip Carns's avatar
Philip Carns committed
506
{
507
    TIMERS_INITIALIZE("start", "forward", "end");
Philip Carns's avatar
Philip Carns committed
508
509
510
    hg_return_t       hret;
    hg_handle_t       handle = HG_HANDLE_NULL;
    bake_create_in_t  in;
511
    bake_create_out_t out;
Philip Carns's avatar
Philip Carns committed
512
    int               ret = 0;
513

Philip Carns's avatar
Philip Carns committed
514
    in.bti         = bti;
Philip Carns's avatar
Philip Carns committed
515
516
    in.region_size = region_size;

517
    hret = margo_create(provider->client->mid, provider->addr,
Philip Carns's avatar
Philip Carns committed
518
                        provider->client->bake_create_id, &handle);
519

Philip Carns's avatar
Philip Carns committed
520
    if (hret != HG_SUCCESS) {
521
522
        ret = BAKE_ERR_MERCURY;
        goto finish;
523
524
    }

525
526
    TIMERS_END_STEP(0);

527
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
528
    if (hret != HG_SUCCESS) {
529
530
        ret = BAKE_ERR_MERCURY;
        goto finish;
531
    }
Philip Carns's avatar
Philip Carns committed
532

533
534
    TIMERS_END_STEP(1);

Shane Snyder's avatar
Shane Snyder committed
535
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
536
    if (hret != HG_SUCCESS) {
537
538
        ret = BAKE_ERR_MERCURY;
        goto finish;
539
540
541
    }

    ret = out.ret;
542
543
544

finish:

Philip Carns's avatar
Philip Carns committed
545
    if (ret == BAKE_SUCCESS) *rid = out.rid;
546

Shane Snyder's avatar
Shane Snyder committed
547
548
    margo_free_output(handle, &out);
    margo_destroy(handle);
549
550
551
552

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
553
    return (ret);
Philip Carns's avatar
Philip Carns committed
554
555
}

Philip Carns's avatar
Philip Carns committed
556
557
558
559
560
int bake_persist(bake_provider_handle_t provider,
                 bake_target_id_t       tid,
                 bake_region_id_t       rid,
                 size_t                 offset,
                 size_t                 size)
Philip Carns's avatar
Philip Carns committed
561
{
562
    TIMERS_INITIALIZE("start", "forward", "end");
Philip Carns's avatar
Philip Carns committed
563
564
565
    hg_return_t        hret;
    hg_handle_t        handle = HG_HANDLE_NULL;
    bake_persist_in_t  in;
566
    bake_persist_out_t out;
Philip Carns's avatar
Philip Carns committed
567
    int                ret;
568

Philip Carns's avatar
Philip Carns committed
569
570
    in.bti    = tid;
    in.rid    = rid;
Matthieu Dorier's avatar
Matthieu Dorier committed
571
    in.offset = offset;
Philip Carns's avatar
Philip Carns committed
572
    in.size   = size;
Philip Carns's avatar
Philip Carns committed
573

574
    hret = margo_create(provider->client->mid, provider->addr,
Philip Carns's avatar
Philip Carns committed
575
                        provider->client->bake_persist_id, &handle);
576

Philip Carns's avatar
Philip Carns committed
577
    if (hret != HG_SUCCESS) {
578
579
580
581
582
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
Philip Carns's avatar
Philip Carns committed
583

584
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
585
    if (hret != HG_SUCCESS) {
586
587
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
588
589
    }

590
591
    TIMERS_END_STEP(1);

Shane Snyder's avatar
Shane Snyder committed
592
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
593
    if (hret != HG_SUCCESS) {
594
595
        ret = BAKE_ERR_MERCURY;
        goto finish;
Philip Carns's avatar
Philip Carns committed
596
597
598
599
    }

    ret = out.ret;

600
finish:
Shane Snyder's avatar
Shane Snyder committed
601
602
    margo_free_output(handle, &out);
    margo_destroy(handle);
603
604
605
606

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
607
    return (ret);
Philip Carns's avatar
Philip Carns committed
608
}
Philip Carns's avatar
Philip Carns committed
609

Philip Carns's avatar
Philip Carns committed
610
611
612
613
614
static int bake_eager_create_write_persist(bake_provider_handle_t provider,
                                           bake_target_id_t       bti,
                                           void const*            buf,
                                           uint64_t               buf_size,
                                           bake_region_id_t*      rid)
615
{
Philip Carns's avatar
Philip Carns committed
616
617
618
619
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t                           hret;
    hg_handle_t                           handle = HG_HANDLE_NULL;
    bake_eager_create_write_persist_in_t  in;
620
    bake_eager_create_write_persist_out_t out;
Philip Carns's avatar
Philip Carns committed
621
    int                                   ret;
622

Philip Carns's avatar
Philip Carns committed
623
    in.bti    = bti;
624
    in.buffer = (char*)buf;
Philip Carns's avatar
Philip Carns committed
625
    in.size   = buf_size;
626
627

    hret = margo_create(provider->client->mid, provider->addr,
Philip Carns's avatar
Philip Carns committed
628
629
630
                        provider->client->bake_eager_create_write_persist_id,
                        &handle);
    if (hret != HG_SUCCESS) {
631
632
        ret = BAKE_ERR_MERCURY;
        goto finish;
633
634
    }

635
636
    TIMERS_END_STEP(0);

637
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
638
    if (hret != HG_SUCCESS) {
639
640
        ret = BAKE_ERR_MERCURY;
        goto finish;
641
642
    }

643
644
    TIMERS_END_STEP(1);

645
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
646
    if (hret != HG_SUCCESS) {
647
648
        ret = BAKE_ERR_MERCURY;
        goto finish;
649
650
651
    }

    ret = out.ret;
652
653
654

finish:

Philip Carns's avatar
Philip Carns committed
655
    if (ret == 0) *rid = out.rid;
656
657
658

    margo_free_output(handle, &out);
    margo_destroy(handle);
659
660
661
662

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
663
    return (ret);
664
665
}

Philip Carns's avatar
Philip Carns committed
666
667
668
669
670
int bake_create_write_persist(bake_provider_handle_t provider,
                              bake_target_id_t       bti,
                              void const*            buf,
                              uint64_t               buf_size,
                              bake_region_id_t*      rid)
671
{
Philip Carns's avatar
Philip Carns committed
672
673
    hg_return_t                    hret;
    hg_handle_t                    handle = HG_HANDLE_NULL;
674
    bake_create_write_persist_in_t in;
675
    in.bulk_handle = HG_BULK_NULL;
676
    bake_create_write_persist_out_t out;
Philip Carns's avatar
Philip Carns committed
677
    int                             ret;
678

Philip Carns's avatar
Philip Carns committed
679
680
681
    if (buf_size <= provider->eager_limit)
        return (
            bake_eager_create_write_persist(provider, bti, buf, buf_size, rid));
682

Philip Carns's avatar
Philip Carns committed
683
    TIMERS_INITIALIZE("bulk_create", "forward", "end");
684

Philip Carns's avatar
Philip Carns committed
685
    in.bti         = bti;
686
    in.bulk_offset = 0;
Philip Carns's avatar
Philip Carns committed
687
    in.bulk_size   = buf_size;
Philip Carns's avatar
Philip Carns committed
688
    in.region_size = buf_size;
Philip Carns's avatar
Philip Carns committed
689
690
    in.remote_addr_str
        = NULL; /* set remote_addr to NULL to disable proxy write */
691

Philip Carns's avatar
Philip Carns committed
692
693
694
    hret = margo_bulk_create(provider->client->mid, 1, (void**)(&buf),
                             &buf_size, HG_BULK_READ_ONLY, &in.bulk_handle);
    if (hret != HG_SUCCESS) {
695
696
697
698
699
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
700

Philip Carns's avatar
Philip Carns committed
701
702
703
    hret
        = margo_create(provider->client->mid, provider->addr,
                       provider->client->bake_create_write_persist_id, &handle);
704

Philip Carns's avatar
Philip Carns committed
705
    if (hret != HG_SUCCESS) {
706
707
        ret = BAKE_ERR_MERCURY;
        goto finish;
708
709
    }

710
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
711
    if (hret != HG_SUCCESS) {
712
713
        ret = BAKE_ERR_MERCURY;
        goto finish;
714
715
    }

716
717
    TIMERS_END_STEP(1);

718
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
719
    if (hret != HG_SUCCESS) {
720
721
        ret = BAKE_ERR_MERCURY;
        goto finish;
722
723
724
    }

    ret = out.ret;
725
726
727

finish:

Philip Carns's avatar
Philip Carns committed
728
    if (ret == 0) *rid = out.rid;
729
730
731
732

    margo_free_output(handle, &out);
    margo_bulk_free(in.bulk_handle);
    margo_destroy(handle);
733
734
    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();
Philip Carns's avatar
Philip Carns committed
735
    return (ret);
736
737
}

Philip Carns's avatar
Philip Carns committed
738
739
740
741
742
743
744
int bake_create_write_persist_proxy(bake_provider_handle_t provider,
                                    bake_target_id_t       bti,
                                    hg_bulk_t              remote_bulk,
                                    uint64_t               remote_offset,
                                    const char*            remote_addr,
                                    uint64_t               size,
                                    bake_region_id_t*      rid)
745
{
Philip Carns's avatar
Philip Carns committed
746
747
748
749
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t                     hret;
    hg_handle_t                     handle = HG_HANDLE_NULL;
    bake_create_write_persist_in_t  in;
750
    bake_create_write_persist_out_t out;
Philip Carns's avatar
Philip Carns committed
751
    int                             ret;
752

Philip Carns's avatar
Philip Carns committed
753
754
755
756
    in.bti             = bti;
    in.bulk_handle     = remote_bulk;
    in.bulk_offset     = remote_offset;
    in.bulk_size       = size;
757
758
    in.remote_addr_str = (char*)remote_addr;

Philip Carns's avatar
Philip Carns committed
759
760
761
    hret
        = margo_create(provider->client->mid, provider->addr,
                       provider->client->bake_create_write_persist_id, &handle);
762

Philip Carns's avatar
Philip Carns committed
763
    if (hret != HG_SUCCESS) {
764
765
766
767
768
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
769

770
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
771
    if (hret != HG_SUCCESS) {
772
773
        ret = BAKE_ERR_MERCURY;
        goto finish;
774
775
    }

776
777
    TIMERS_END_STEP(1);

778
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
779
    if (hret != HG_SUCCESS) {
780
781
        ret = BAKE_ERR_MERCURY;
        goto finish;
782
783
784
    }

    ret = out.ret;
Philip Carns's avatar
Philip Carns committed
785
    if (ret == BAKE_SUCCESS) *rid = out.rid;
786

787
finish:
788
789
    margo_free_output(handle, &out);
    margo_destroy(handle);
790
791
792
793

    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
794
    return (ret);
795
796
}

Philip Carns's avatar
Philip Carns committed
797
798
799
800
int bake_get_size(bake_provider_handle_t provider,
                  bake_target_id_t       bti,
                  bake_region_id_t       rid,
                  uint64_t*              region_size)
801
{
802
    TIMERS_INITIALIZE("start", "forward", "end");
Philip Carns's avatar
Philip Carns committed
803
804
805
    hg_return_t         hret;
    hg_handle_t         handle = HG_HANDLE_NULL;
    bake_get_size_in_t  in;
806
    bake_get_size_out_t out;
Philip Carns's avatar
Philip Carns committed
807
    int                 ret;
808

809
    in.bti = bti;
810
811
    in.rid = rid;

812
    hret = margo_create(provider->client->mid, provider->addr,
Philip Carns's avatar
Philip Carns committed
813
                        provider->client->bake_get_size_id, &handle);
814

Philip Carns's avatar
Philip Carns committed
815
    if (hret != HG_SUCCESS) {
816
817
818
819
820
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }

    TIMERS_END_STEP(0);
821

822
    hret = margo_provider_forward(provider->provider_id, handle, &in);
Philip Carns's avatar
Philip Carns committed
823
    if (hret != HG_SUCCESS) {
824
825
        ret = BAKE_ERR_MERCURY;
        goto finish;
826
827
    }

828
829
    TIMERS_END_STEP(1);

Shane Snyder's avatar
Shane Snyder committed
830
    hret = margo_get_output(handle, &out);
Philip Carns's avatar
Philip Carns committed
831
    if (hret != HG_SUCCESS) {
832
833
        ret = BAKE_ERR_MERCURY;
        goto finish;
834
835
    }

Philip Carns's avatar
Philip Carns committed
836
    ret          = out.ret;
837
838
    *region_size = out.size;

839
840
finish:

Shane Snyder's avatar
Shane Snyder committed
841
842
    margo_free_output(handle, &out);
    margo_destroy(handle);
843
844
845
    TIMERS_END_STEP(2);
    TIMERS_FINALIZE();

Philip Carns's avatar
Philip Carns committed
846
    return (ret);
847
848
}

Philip Carns's avatar
Philip Carns committed
849
850
851
852
int bake_get_data(bake_provider_handle_t provider,
                  bake_target_id_t       bti,
                  bake_region_id_t       rid,
                  void**                 ptr)
853
{
Philip Carns's avatar
Philip Carns committed
854
855
856
857
    TIMERS_INITIALIZE("start", "forward", "end");
    hg_return_t         hret;
    hg_handle_t         handle = HG_HANDLE_NULL;
    bake_get_data_in_t  in;
858
    bake_get_data_out_t out;
Philip Carns's avatar
Philip Carns committed
859
    int                 ret;
860
861

    // make sure the target provider is on the same address space
862
    hg_addr_t self_addr = HG_ADDR_NULL;
Philip Carns's avatar
Philip Carns committed
863
    if (HG_SUCCESS != margo_addr_self(provider->client->mid, &self_addr)) {
864
865
866
        ret = BAKE_ERR_MERCURY;
        goto finish;
    }
867
    hg_addr_t trgt_addr = provider->addr;
868
    hg_size_t addr_size = 1024;
Philip Carns's avatar
Philip Carns committed
869
870
    char      self_addr_str[1024];
    char      trgt_addr_str[1024];
871

Philip Carns's avatar
Philip Carns committed
872
873
874
    if (HG_SUCCESS
        != margo_addr_to_string(provider->client->mid, self_addr_str,
                                &addr_size, self_addr)) {
875
        margo_addr_free(provider->client->mid, self_addr);
876
877
        ret = BAKE_ERR_MERCURY;
        goto finish;
878
    }
Philip Carns's avatar
Philip Carns committed
879
880
881
    if (HG_SUCCESS
        != margo_addr_to_string(provider->client->mid, trgt_addr_str,
                                &addr_size, trgt_addr)) {
882
        margo_addr_free(provider->client->mid, self_addr);
883
884
        ret = BAKE_ERR_MERCURY;
        goto finish;
885
    }
Philip Carns's avatar
Philip Carns committed
886
    if (strcmp(self_addr_str, trgt_addr_str) != 0) {
887
        margo_addr_free(provider->client->mid, self_addr);
888
889
        ret = BAKE_ERR_MERCURY;
        goto finish;
890
891
892
    }
    margo_addr_free(provider->client->mid, self_addr);

</