/*---------------------------------------------------------------------------*/ hg_class_t * HG_Test_server_init(int argc, char *argv[], hg_addr_t **addr_table, unsigned int *addr_table_size, unsigned int *max_number_of_peers, hg_context_t **context) { size_t bulk_size = 1024 * 1024 * MERCURY_TESTING_BUFFER_SIZE; hg_return_t ret; hg_test_na_class_g = NA_Test_server_init(argc, argv, NA_FALSE, &hg_test_addr_name_table_g, &hg_test_addr_table_size_g, max_number_of_peers); hg_test_na_context_g = NA_Context_create(hg_test_na_class_g); /* Initalize atomic variable to finalize server */ hg_atomic_set32(&hg_test_finalizing_count_g, 0); #ifdef MERCURY_TESTING_HAS_THREAD_POOL hg_thread_mutex_init(&hg_test_local_bulk_handle_mutex_g); hg_thread_pool_init(MERCURY_TESTING_NUM_THREADS, &hg_test_thread_pool_g); printf("# Starting server with %d threads...\n", MERCURY_TESTING_NUM_THREADS); #endif ret = HG_Hl_init_na(hg_test_na_class_g, hg_test_na_context_g); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not initialize Mercury\n"); goto done; } /* Register test routines */ hg_test_register(HG_CLASS_DEFAULT); /* Create bulk buffer that can be used for receiving data */ HG_Bulk_create(HG_CLASS_DEFAULT, 1, NULL, &bulk_size, HG_BULK_READWRITE, &hg_test_local_bulk_handle_g); if (hg_test_addr_table_size_g > 1) { unsigned int i; hg_test_addr_table_g = (hg_addr_t *) malloc(hg_test_addr_table_size_g * sizeof(hg_addr_t)); for (i = 0; i < hg_test_addr_table_size_g; i++) { ret = HG_Hl_addr_lookup_wait(HG_CONTEXT_DEFAULT, HG_REQUEST_CLASS_DEFAULT, hg_test_addr_name_table_g[i], &hg_test_addr_table_g[i], HG_MAX_IDLE_TIME); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not find addr %s\n", hg_test_addr_name_table_g[i]); goto done; } } } if (addr_table) *addr_table = hg_test_addr_table_g; if (addr_table_size) *addr_table_size = hg_test_addr_table_size_g; /* Used by CTest Test Driver */ printf("Waiting for client...\n"); fflush(stdout); if (context) *context = HG_CONTEXT_DEFAULT; done: return HG_CLASS_DEFAULT; }
int main(int argc, char *argv[]) { hg_thread_t thread, thread1; hg_atomic_int32_t atomic_int32; hg_util_int32_t value32 = 0; #ifndef HG_UTIL_HAS_OPA_PRIMITIVES_H hg_atomic_int64_t atomic_int64; hg_util_int64_t value64 = 0; #endif int ret = EXIT_SUCCESS; (void) argc; (void) argv; /* Atomic 32 test */ hg_thread_init(&thread); hg_atomic_set32(&atomic_int32, value32); hg_thread_create(&thread, thread_cb_incr32, &atomic_int32); hg_thread_join(thread); hg_thread_init(&thread1); hg_thread_create(&thread1, thread_cb_cas32, &atomic_int32); hg_thread_create(&thread, thread_cb_cas32, &atomic_int32); hg_thread_join(thread); hg_thread_join(thread1); value32 = hg_atomic_get32(&atomic_int32); if (value32 != 100) { fprintf(stderr, "Error: atomic value is %d\n", value32); ret = EXIT_FAILURE; } #ifndef HG_UTIL_HAS_OPA_PRIMITIVES_H /* Atomic 64 test */ hg_thread_init(&thread); hg_atomic_set64(&atomic_int64, value64); hg_thread_create(&thread, thread_cb_incr64, &atomic_int64); hg_thread_join(thread); hg_thread_init(&thread1); hg_thread_create(&thread1, thread_cb_cas64, &atomic_int64); hg_thread_create(&thread, thread_cb_cas64, &atomic_int64); hg_thread_join(thread); hg_thread_join(thread1); value64 = hg_atomic_get64(&atomic_int64); if (value64 != 100) { fprintf(stderr, "Error: atomic value is %ld\n", (long) value64); ret = EXIT_FAILURE; } #endif return ret; }
/*---------------------------------------------------------------------------*/ HG_TEST_RPC_CB(hg_test_bulk_seg_write, handle) { struct hg_info *hg_info = NULL; hg_bulk_t origin_bulk_handle = HG_BULK_NULL; hg_bulk_t local_bulk_handle = HG_BULK_NULL; struct hg_test_bulk_args *bulk_args = NULL; size_t nbytes_read; size_t offset; hg_return_t ret = HG_SUCCESS; bulk_write_in_t in_struct; bulk_args = (struct hg_test_bulk_args *) malloc( sizeof(struct hg_test_bulk_args)); /* Keep handle to pass to callback */ bulk_args->handle = handle; /* Get info from handle */ hg_info = HG_Get_info(handle); /* Get input parameters and data */ ret = HG_Get_input(handle, &in_struct); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not get input\n"); return ret; } /* Get parameters */ origin_bulk_handle = in_struct.bulk_handle; hg_atomic_set32(&bulk_args->completed_transfers, 0); /* Create a new block handle to read the data */ bulk_args->nbytes = HG_Bulk_get_size(origin_bulk_handle); bulk_args->fildes = in_struct.fildes; /* For testing purposes try to read the data in two blocks of different sizes */ nbytes_read = bulk_args->nbytes / 2 + 16; printf("Start reading first chunk of %lu bytes...\n", nbytes_read); /* Create a new bulk handle to read the data */ HG_Bulk_create(hg_info->hg_class, 1, NULL, (hg_size_t *) &bulk_args->nbytes, HG_BULK_READWRITE, &local_bulk_handle); /* Pull bulk data */ ret = HG_Bulk_transfer(hg_info->context, hg_test_bulk_seg_transfer_cb, bulk_args, HG_BULK_PULL, hg_info->addr, origin_bulk_handle, 0, local_bulk_handle, 0, nbytes_read, HG_OP_ID_IGNORE); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not read bulk data\n"); return ret; } offset = nbytes_read; nbytes_read = bulk_args->nbytes - nbytes_read; printf("Start reading second chunk of %lu bytes...\n", nbytes_read); ret = HG_Bulk_transfer(hg_info->context, hg_test_bulk_seg_transfer_cb, bulk_args, HG_BULK_PULL, hg_info->addr, origin_bulk_handle, offset, local_bulk_handle, offset, nbytes_read, HG_OP_ID_IGNORE); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not read bulk data\n"); return ret; } HG_Free_input(handle, &in_struct); return ret; }
/*---------------------------------------------------------------------------*/ HG_TEST_RPC_CB(hg_test_perf_bulk, handle) { hg_return_t ret = HG_SUCCESS; struct hg_info *hg_info = NULL; hg_bulk_t origin_bulk_handle = HG_BULK_NULL; hg_bulk_t local_bulk_handle = HG_BULK_NULL; struct hg_test_bulk_args *bulk_args = NULL; bulk_write_in_t in_struct; bulk_args = (struct hg_test_bulk_args *) malloc( sizeof(struct hg_test_bulk_args)); /* Keep handle to pass to callback */ bulk_args->handle = handle; /* Get info from handle */ hg_info = HG_Get_info(handle); /* Get input struct */ ret = HG_Get_input(handle, &in_struct); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not get input struct\n"); return ret; } origin_bulk_handle = in_struct.bulk_handle; hg_atomic_set32(&bulk_args->completed_transfers, 0); /* Create a new block handle to read the data */ bulk_args->nbytes = HG_Bulk_get_size(origin_bulk_handle); bulk_args->fildes = in_struct.fildes; #ifdef MERCURY_TESTING_USE_LOCAL_BULK /* Create a new bulk handle to read the data */ HG_Bulk_create(hg_info->hg_class, 1, NULL, &bulk_args->nbytes, HG_BULK_READWRITE, &local_bulk_handle); #else #ifdef MERCURY_TESTING_HAS_THREAD_POOL hg_thread_mutex_lock(&hg_test_local_bulk_handle_mutex_g); #endif local_bulk_handle = hg_test_local_bulk_handle_g; #endif /* Pull bulk data */ ret = HG_Bulk_transfer(hg_info->context, hg_test_perf_bulk_transfer_cb, bulk_args, HG_BULK_PULL, hg_info->addr, origin_bulk_handle, 0, local_bulk_handle, 0, bulk_args->nbytes, HG_OP_ID_IGNORE); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not read bulk data\n"); return ret; } #ifndef MERCURY_TESTING_USE_LOCAL_BULK #ifdef MERCURY_TESTING_HAS_THREAD_POOL hg_thread_mutex_unlock(&hg_test_local_bulk_handle_mutex_g); #endif #endif HG_Free_input(handle, &in_struct); return ret; }
static hg_return_t measure_bulk_transfer(struct hg_test_info *hg_test_info, size_t total_size, unsigned int nhandles) { bulk_write_in_t in_struct; char *bulk_buf; void **buf_ptrs; size_t *buf_sizes; hg_bulk_t bulk_handle = HG_BULK_NULL; size_t nbytes = total_size; double nmbytes = (double) total_size / (1024 * 1024); size_t loop = (total_size > LARGE_SIZE) ? MERCURY_TESTING_MAX_LOOP : MERCURY_TESTING_MAX_LOOP * 10; size_t skip = (total_size > LARGE_SIZE) ? LARGE_SKIP : SMALL_SKIP; hg_handle_t *handles = NULL; hg_request_t *request; struct hg_test_perf_args args; size_t avg_iter; double time_read = 0, read_bandwidth; hg_return_t ret = HG_SUCCESS; size_t i; /* Prepare bulk_buf */ bulk_buf = malloc(nbytes); for (i = 0; i < nbytes; i++) bulk_buf[i] = 1; buf_ptrs = (void **) &bulk_buf; buf_sizes = &nbytes; /* Create handles */ handles = malloc(nhandles * sizeof(hg_handle_t)); for (i = 0; i < nhandles; i++) { ret = HG_Create(hg_test_info->context, hg_test_info->target_addr, hg_test_perf_bulk_read_id_g, &handles[i]); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not start call\n"); goto done; } } request = hg_request_create(hg_test_info->request_class); hg_atomic_init32(&args.op_completed_count, 0); args.op_count = nhandles; args.request = request; /* Register memory */ ret = HG_Bulk_create(hg_test_info->hg_class, 1, buf_ptrs, (hg_size_t *) buf_sizes, HG_BULK_READWRITE, &bulk_handle); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not create bulk data handle\n"); goto done; } /* Fill input structure */ in_struct.fildes = 0; in_struct.bulk_handle = bulk_handle; /* Warm up for bulk data */ for (i = 0; i < skip; i++) { unsigned int j; for (j = 0; j < nhandles; j++) { ret = HG_Forward(handles[j], hg_test_perf_forward_cb, &args, &in_struct); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not forward call\n"); goto done; } } hg_request_wait(request, HG_MAX_IDLE_TIME, NULL); hg_request_reset(request); hg_atomic_set32(&args.op_completed_count, 0); } NA_Test_barrier(&hg_test_info->na_test_info); /* Bulk data benchmark */ for (avg_iter = 0; avg_iter < loop; avg_iter++) { hg_time_t t1, t2; unsigned int j; hg_time_get_current(&t1); for (j = 0; j < nhandles; j++) { ret = HG_Forward(handles[j], hg_test_perf_forward_cb, &args, &in_struct); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not forward call\n"); goto done; } } hg_request_wait(request, HG_MAX_IDLE_TIME, NULL); NA_Test_barrier(&hg_test_info->na_test_info); hg_time_get_current(&t2); time_read += hg_time_to_double(hg_time_subtract(t2, t1)); hg_request_reset(request); hg_atomic_set32(&args.op_completed_count, 0); #ifdef MERCURY_TESTING_PRINT_PARTIAL read_bandwidth = nmbytes * (double) (nhandles * (avg_iter + 1) * (unsigned int) hg_test_info->na_test_info.mpi_comm_size) / time_read; /* At this point we have received everything so work out the bandwidth */ if (hg_test_info->na_test_info.mpi_comm_rank == 0) fprintf(stdout, "%-*d%*.*f\r", 10, (int) nbytes, NWIDTH, NDIGITS, read_bandwidth); #endif #ifdef MERCURY_TESTING_HAS_VERIFY_DATA for (i = 0; i < nbytes; i++) { if (bulk_buf[i] != (char) i) { printf("Error detected in bulk transfer, buf[%d] = %d, " "was expecting %d!\n", (int) i, (char) bulk_buf[i], (char) i); break; } } #endif } #ifndef MERCURY_TESTING_PRINT_PARTIAL read_bandwidth = nmbytes * (double) (nhandles * loop * (unsigned int) hg_test_info->na_test_info.mpi_comm_size) / time_read; /* At this point we have received everything so work out the bandwidth */ if (hg_test_info->na_test_info.mpi_comm_rank == 0) fprintf(stdout, "%-*d%*.*f", 10, (int) nbytes, NWIDTH, NDIGITS, read_bandwidth); #endif if (hg_test_info->na_test_info.mpi_comm_rank == 0) fprintf(stdout, "\n"); /* Free memory handle */ ret = HG_Bulk_free(bulk_handle); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not free bulk data handle\n"); goto done; } /* Complete */ hg_request_destroy(request); for (i = 0; i < nhandles; i++) { ret = HG_Destroy(handles[i]); if (ret != HG_SUCCESS) { fprintf(stderr, "Could not complete\n"); goto done; } } done: free(bulk_buf); free(handles); return ret; }
/*---------------------------------------------------------------------------*/ static hg_return_t hg_bulk_transfer(hg_context_t *context, hg_cb_t callback, void *arg, hg_bulk_op_t op, struct hg_addr *origin_addr, struct hg_bulk *hg_bulk_origin, hg_size_t origin_offset, struct hg_bulk *hg_bulk_local, hg_size_t local_offset, hg_size_t size, hg_op_id_t *op_id) { hg_uint32_t origin_segment_start_index = 0, local_segment_start_index = 0; hg_size_t origin_segment_start_offset = origin_offset, local_segment_start_offset = local_offset; struct hg_bulk_op_id *hg_bulk_op_id = NULL; na_bulk_op_t na_bulk_op; na_addr_t na_origin_addr = HG_Core_addr_get_na(origin_addr); na_class_t *na_class = HG_Core_class_get_na(hg_bulk_origin->hg_class); hg_bool_t is_self = NA_Addr_is_self(na_class, na_origin_addr); hg_bool_t scatter_gather = (na_class->mem_handle_create_segments && !is_self) ? HG_TRUE : HG_FALSE; hg_return_t ret = HG_SUCCESS; unsigned int i; /* Map op to NA op */ switch (op) { case HG_BULK_PUSH: na_bulk_op = (is_self) ? hg_bulk_memcpy_put : hg_bulk_na_put; break; case HG_BULK_PULL: /* Eager mode can only be used when data is pulled from origin */ na_bulk_op = (is_self || hg_bulk_origin->eager_mode) ? hg_bulk_memcpy_get : hg_bulk_na_get; break; default: HG_LOG_ERROR("Unknown bulk operation"); ret = HG_INVALID_PARAM; goto done; } /* Allocate op_id */ hg_bulk_op_id = (struct hg_bulk_op_id *) malloc( sizeof(struct hg_bulk_op_id)); if (!hg_bulk_op_id) { HG_LOG_ERROR("Could not allocate HG Bulk operation ID"); ret = HG_NOMEM_ERROR; goto done; } hg_bulk_op_id->hg_class = hg_bulk_origin->hg_class; hg_bulk_op_id->context = context; hg_bulk_op_id->callback = callback; hg_bulk_op_id->arg = arg; hg_atomic_set32(&hg_bulk_op_id->completed, 0); hg_atomic_set32(&hg_bulk_op_id->canceled, 0); hg_bulk_op_id->op_count = 1; /* Default */ hg_atomic_set32(&hg_bulk_op_id->op_completed_count, 0); hg_bulk_op_id->op = op; hg_bulk_op_id->hg_bulk_origin = hg_bulk_origin; hg_atomic_incr32(&hg_bulk_origin->ref_count); /* Increment ref count */ hg_bulk_op_id->hg_bulk_local = hg_bulk_local; hg_atomic_incr32(&hg_bulk_local->ref_count); /* Increment ref count */ hg_bulk_op_id->na_op_ids = NULL; hg_bulk_op_id->is_self = is_self; /* Translate bulk_offset */ if (origin_offset && !scatter_gather) hg_bulk_offset_translate(hg_bulk_origin, origin_offset, &origin_segment_start_index, &origin_segment_start_offset); /* Translate block offset */ if (local_offset && !scatter_gather) hg_bulk_offset_translate(hg_bulk_local, local_offset, &local_segment_start_index, &local_segment_start_offset); /* Figure out number of NA operations required */ if (!scatter_gather) { hg_bulk_transfer_pieces(NULL, NA_ADDR_NULL, hg_bulk_origin, origin_segment_start_index, origin_segment_start_offset, hg_bulk_local, local_segment_start_index, local_segment_start_offset, size, HG_FALSE, NULL, &hg_bulk_op_id->op_count); if (!hg_bulk_op_id->op_count) { HG_LOG_ERROR("Could not get bulk op_count"); ret = HG_INVALID_PARAM; goto done; } } /* Allocate memory for NA operation IDs */ hg_bulk_op_id->na_op_ids = malloc(sizeof(na_op_id_t) * hg_bulk_op_id->op_count); if (!hg_bulk_op_id->na_op_ids) { HG_LOG_ERROR("Could not allocate memory for op_ids"); ret = HG_NOMEM_ERROR; goto done; } for (i = 0; i < hg_bulk_op_id->op_count; i++) hg_bulk_op_id->na_op_ids[i] = NA_OP_ID_NULL; /* Assign op_id */ if (op_id && op_id != HG_OP_ID_IGNORE) *op_id = (hg_op_id_t) hg_bulk_op_id; /* Do actual transfer */ ret = hg_bulk_transfer_pieces(na_bulk_op, na_origin_addr, hg_bulk_origin, origin_segment_start_index, origin_segment_start_offset, hg_bulk_local, local_segment_start_index, local_segment_start_offset, size, scatter_gather, hg_bulk_op_id, NULL); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not transfer data pieces"); goto done; } done: if (ret != HG_SUCCESS && hg_bulk_op_id) { free(hg_bulk_op_id->na_op_ids); free(hg_bulk_op_id); } return ret; }
/*---------------------------------------------------------------------------*/ static hg_return_t hg_bulk_create(struct hg_class *hg_class, hg_uint32_t count, void **buf_ptrs, const hg_size_t *buf_sizes, hg_uint8_t flags, struct hg_bulk **hg_bulk_ptr) { struct hg_bulk *hg_bulk = NULL; hg_return_t ret = HG_SUCCESS; na_return_t na_ret; na_class_t *na_class = HG_Core_class_get_na(hg_class); hg_bool_t use_register_segments = (hg_bool_t) (na_class->mem_handle_create_segments && count > 1); unsigned int i; hg_bulk = (struct hg_bulk *) malloc(sizeof(struct hg_bulk)); if (!hg_bulk) { HG_LOG_ERROR("Could not allocate handle"); ret = HG_NOMEM_ERROR; goto done; } hg_bulk->hg_class = hg_class; hg_bulk->total_size = 0; hg_bulk->segment_count = count; hg_bulk->segments = NULL; hg_bulk->na_mem_handle_count = (use_register_segments) ? 1 : count; hg_bulk->na_mem_handles = NULL; hg_bulk->segment_published = HG_FALSE; hg_bulk->segment_alloc = (!buf_ptrs); hg_bulk->flags = flags; hg_bulk->eager_mode = HG_FALSE; hg_atomic_set32(&hg_bulk->ref_count, 1); /* Allocate segments */ hg_bulk->segments = (struct hg_bulk_segment *) malloc( hg_bulk->segment_count * sizeof(struct hg_bulk_segment)); if (!hg_bulk->segments) { HG_LOG_ERROR("Could not allocate segment array"); ret = HG_NOMEM_ERROR; goto done; } memset(hg_bulk->segments, 0, hg_bulk->segment_count * sizeof(struct hg_bulk_segment)); /* Loop over the list of segments */ for (i = 0; i < hg_bulk->segment_count; i++) { hg_bulk->segments[i].size = buf_sizes[i]; hg_bulk->total_size += hg_bulk->segments[i].size; if (buf_ptrs) hg_bulk->segments[i].address = (hg_ptr_t) buf_ptrs[i]; else { /* Use calloc to avoid uninitialized memory used for transfer */ hg_bulk->segments[i].address = (hg_ptr_t) calloc( hg_bulk->segments[i].size, sizeof(char)); if (!hg_bulk->segments[i].address) { HG_LOG_ERROR("Could not allocate segment"); ret = HG_NOMEM_ERROR; goto done; } } } /* Allocate NA memory handles */ hg_bulk->na_mem_handles = (na_mem_handle_t *) malloc( hg_bulk->na_mem_handle_count * sizeof(na_mem_handle_t)); if (!hg_bulk->na_mem_handles) { HG_LOG_ERROR("Could not allocate mem handle array"); ret = HG_NOMEM_ERROR; goto done; } for (i = 0; i < hg_bulk->na_mem_handle_count; i++) hg_bulk->na_mem_handles[i] = NA_MEM_HANDLE_NULL; /* Create and register NA memory handles */ for (i = 0; i < hg_bulk->na_mem_handle_count; i++) { /* na_mem_handle_count always <= segment_count */ if (!hg_bulk->segments[i].address) continue; if (use_register_segments) { struct na_segment *na_segments = (struct na_segment *) hg_bulk->segments; na_size_t na_segment_count = (na_size_t) hg_bulk->segment_count; na_ret = NA_Mem_handle_create_segments(na_class, na_segments, na_segment_count, flags, &hg_bulk->na_mem_handles[i]); if (na_ret != NA_SUCCESS) { HG_LOG_ERROR("NA_Mem_handle_create_segments failed"); ret = HG_NA_ERROR; goto done; } } else { na_ret = NA_Mem_handle_create(na_class, (void *) hg_bulk->segments[i].address, hg_bulk->segments[i].size, flags, &hg_bulk->na_mem_handles[i]); if (na_ret != NA_SUCCESS) { HG_LOG_ERROR("NA_Mem_handle_create failed"); ret = HG_NA_ERROR; goto done; } } /* Register segment */ na_ret = NA_Mem_register(na_class, hg_bulk->na_mem_handles[i]); if (na_ret != NA_SUCCESS) { HG_LOG_ERROR("NA_Mem_register failed"); ret = HG_NA_ERROR; goto done; } } *hg_bulk_ptr = hg_bulk; done: if (ret != HG_SUCCESS) { hg_bulk_free(hg_bulk); } return ret; }
/*---------------------------------------------------------------------------*/ hg_return_t HG_Bulk_deserialize(hg_class_t *hg_class, hg_bulk_t *handle, const void *buf, hg_size_t buf_size) { struct hg_bulk *hg_bulk = NULL; const char *buf_ptr = (const char *) buf; ssize_t buf_size_left = (ssize_t) buf_size; hg_return_t ret = HG_SUCCESS; hg_uint32_t i; if (!handle) { HG_LOG_ERROR("NULL pointer to memory handle passed"); ret = HG_INVALID_PARAM; goto done; } hg_bulk = (struct hg_bulk *) malloc(sizeof(struct hg_bulk)); if (!hg_bulk) { HG_LOG_ERROR("Could not allocate handle"); ret = HG_NOMEM_ERROR; goto done; } memset(hg_bulk, 0, sizeof(struct hg_bulk)); hg_bulk->hg_class = hg_class; hg_atomic_set32(&hg_bulk->ref_count, 1); /* Get the permission flags */ ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->flags, sizeof(hg_bulk->flags)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode permission flags"); goto done; } /* Get the total size of the segments */ ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->total_size, sizeof(hg_bulk->total_size)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode total size"); goto done; } /* Get the number of segments */ ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->segment_count, sizeof(hg_bulk->segment_count)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode segment count"); goto done; } /* Get the array of segments */ hg_bulk->segments = (struct hg_bulk_segment *) malloc( hg_bulk->segment_count * sizeof(struct hg_bulk_segment)); if (!hg_bulk->segments) { HG_LOG_ERROR("Could not allocate segment array"); ret = HG_NOMEM_ERROR; goto done; } for (i = 0; i < hg_bulk->segment_count; i++) { ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->segments[i], sizeof(hg_bulk->segments[i])); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode segment"); goto done; } } /* Get the number of NA memory handles */ ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->na_mem_handle_count, sizeof(hg_bulk->na_mem_handle_count)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode NA memory handle count"); goto done; } /* Get the NA memory handles */ hg_bulk->na_mem_handles = (na_mem_handle_t *) malloc( hg_bulk->na_mem_handle_count * sizeof(na_mem_handle_t)); if (!hg_bulk->na_mem_handles) { HG_LOG_ERROR("Could not allocate NA memory handle array"); ret = HG_NOMEM_ERROR; goto done; } for (i = 0; i < hg_bulk->na_mem_handle_count; i++) { na_size_t serialize_size; na_return_t na_ret; ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &serialize_size, sizeof(serialize_size)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode serialize size"); goto done; } if (serialize_size) { na_ret = NA_Mem_handle_deserialize( HG_Core_class_get_na(hg_bulk->hg_class), &hg_bulk->na_mem_handles[i], buf_ptr, (na_size_t) buf_size_left); if (na_ret != NA_SUCCESS) { HG_LOG_ERROR("Could not deserialize memory handle"); ret = HG_NA_ERROR; goto done; } buf_ptr += serialize_size; buf_size_left -= (ssize_t) serialize_size; } else { hg_bulk->na_mem_handles[i] = NA_MEM_HANDLE_NULL; } } /* Get whether data is serialized or not */ ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, &hg_bulk->eager_mode, sizeof(hg_bulk->eager_mode)); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode eager_mode bool"); goto done; } /* Get the serialized data */ if (hg_bulk->eager_mode) { hg_bulk->segment_alloc = HG_TRUE; for (i = 0; i < hg_bulk->segment_count; i++) { if (!hg_bulk->segments[i].size) continue; /* Use calloc to avoid uninitialized memory used for transfer */ hg_bulk->segments[i].address = (hg_ptr_t) calloc( hg_bulk->segments[i].size, sizeof(char)); if (!hg_bulk->segments[i].address) { HG_LOG_ERROR("Could not allocate segment"); ret = HG_NOMEM_ERROR; goto done; } ret = hg_bulk_deserialize_memcpy(&buf_ptr, &buf_size_left, (void *) hg_bulk->segments[i].address, hg_bulk->segments[i].size); if (ret != HG_SUCCESS) { HG_LOG_ERROR("Could not decode segment data"); goto done; } } } if (buf_size_left) HG_LOG_WARNING("Buf size left greater than 0, %zd", buf_size_left); *handle = (hg_bulk_t) hg_bulk; done: if (ret != HG_SUCCESS) { hg_bulk_free(hg_bulk); } return ret; }