static int _test_set_rsync_remote_handler(void) { hpx_addr_t peer = HPX_THERE((HPX_LOCALITY_ID + 1) % HPX_LOCALITIES); hpx_addr_t lco; hpx_call_sync(peer, _new_future_at, &lco, sizeof(lco)); hpx_call_sync(peer, _test_set_rsync, NULL, 0, &lco); return hpx_call_cc(lco, hpx_lco_delete_action); }
/// Instantiate a single hpx_gas_memput_lsync test. /// /// This will allocate an lsync LCO at @p at test the lsync version. /// /// @param buffer The local buffer to put from. /// @param n The number of bytes to put. /// @param block The global address to put into. /// @param at The locality to allocate the lsync at. void test_lsync(const uint64_t *buffer, size_t n, hpx_addr_t block, hpx_addr_t at) { hpx_addr_t lsync = HPX_NULL; CHECK( hpx_call_sync(at, future_at, &lsync, sizeof(lsync)) ); CHECK( hpx_gas_memput_lsync(block, buffer, n, lsync) ); CHECK( hpx_lco_wait(lsync) ); CHECK( hpx_call_sync(block, verify, NULL, 0, buffer, n) ); hpx_lco_delete_sync(lsync); }
static int _uts_main_action(void *args, size_t size) { Node *root = (Node *)args; Node temp; uts_initRoot(&temp, type); //bots_number_of_tasks = parallel_uts(&temp); printf("Computing Unbalance Tree Search algorithm "); hpx_addr_t theThread = HPX_HERE; counter_t num_nodes; hpx_time_t start; struct thread_data input; input.depth = 0; memcpy(&input.parent, &temp, sizeof(Node)); input.numChildren = getNumRootChildren(&temp); start = hpx_time_now(); hpx_call_sync(theThread, _uts, &num_nodes, sizeof(num_nodes), &input, sizeof(input)); bots_time_program = hpx_time_elapsed_ms(start)/1e3; bots_number_of_tasks = num_nodes; printf(" completed!"); uts_show_stats(); uts_check_result(); hpx_shutdown(HPX_SUCCESS); }
hpx_addr_t hpx_lco_user_new(size_t size, hpx_action_t id, hpx_action_t op, hpx_action_t predicate, void *init, size_t init_size) { _user_lco_t *u = NULL; hpx_addr_t gva = lco_alloc_local(1, sizeof(*u) + size + init_size, 0); if (!hpx_gas_try_pin(gva, (void**)&u)) { size_t args_size = sizeof(_user_lco_t) + init_size; _user_lco_init_args_t *args = calloc(1, args_size); args->size = size; args->id = id; args->op = op; args->predicate = predicate; args->init_size = init_size; memcpy(args->data, init, init_size); int e = hpx_call_sync(gva, _user_lco_init_action, NULL, 0, args, args_size); dbg_check(e, "could not initialize an allreduce at %"PRIu64"\n", gva); free(args); } else { LCO_LOG_NEW(gva, u); memcpy(u->data, init, init_size); _user_lco_init(u, size, id, op, predicate, init, init_size); hpx_gas_unpin(gva); } return gva; }
static int _test_thread_sigmask_handler(void) { int out; CHECK(hpx_call_sync(HPX_HERE, _check_null, &out, sizeof(out))); int mask = hpx_thread_sigmask(HPX_SIG_BLOCK, HPX_SIGNONE); test_assert((mask & HPX_SIGSEGV) == 0); return HPX_SUCCESS; }
void sim_village_main_hpx(struct Village *top) { long i; for (i = 0; i < sim_time; i++) { hpx_call_sync(HPX_HERE, _health, NULL, 0, top, sizeof(struct Village)); } }
/// Delete a process. void hpx_process_delete(hpx_addr_t process, hpx_addr_t sync) { if (process == HPX_NULL) { return; } hpx_call_sync(process, _proc_delete, NULL, 0, NULL, 0); EVENT_PROCESS_DELETE(process); hpx_gas_free(process, sync); }
/// Get the ID for alltoall. This is global getid for the user to use. /// Since the LCO is local, we use the local get functionality /// /// @param alltoall Global address of the alltoall LCO /// @param id The ID of our rank /// @param size The size of the data being gathered /// @param value Address of the value buffer hpx_status_t hpx_lco_alltoall_getid(hpx_addr_t alltoall, unsigned id, int size, void *value) { hpx_status_t status = HPX_SUCCESS; _alltoall_t *local; if (!hpx_gas_try_pin(alltoall, (void**)&local)) { _alltoall_get_offset_t args = {.size = size, .offset = id}; hpx_action_t act = _alltoall_getid_proxy; return hpx_call_sync(alltoall, act, value, size, &args, sizeof(args)); }
/// Initialize the global data for a rank. int init_handler(hpx_addr_t data) { size_t n = ELEMENTS * sizeof(uint64_t); int rank = HPX_LOCALITY_ID; int peer = (rank + 1) % HPX_LOCALITIES; data = data; local = hpx_addr_add(data, rank * n, n); remote = hpx_addr_add(data, peer * n, n); CHECK( hpx_call_sync(local, reset, NULL, 0) ); return HPX_SUCCESS; }
static counter_t _uts_action(void *args, size_t size) { int i, j; struct thread_data *my_data; struct thread_data temp, input; my_data = (struct thread_data *)args; Node n[my_data->numChildren], *nodePtr; counter_t subtreesize = 1, partialCount[my_data->numChildren]; temp.depth = my_data->depth; memcpy(&temp.parent, &my_data->parent, sizeof(Node)); temp.numChildren = my_data->numChildren; //hpx_lco_sema_p (mutex); //printf("D: %d; child: %d; spawns:%.0f\n", temp.depth, temp.numChildren, spawns_counter++); //hpx_lco_sema_v_sync (mutex); /* printf("\n[Node] height = %d; numChildren = %d\n" , temp.parent.height , temp.parent.numChildren); */ hpx_addr_t theThread = HPX_HERE; hpx_addr_t done = hpx_lco_future_new(sizeof(uint64_t)); // Recurse on the children for (i = 0; i < temp.numChildren; i++) { nodePtr = &n[i]; nodePtr->height = temp.parent.height + 1; // The following line is the work (one or more SHA-1 ops) for (j = 0; j < computeGranularity; j++) { rng_spawn(temp.parent.state.state, nodePtr->state.state, i); } nodePtr->numChildren = uts_numChildren(nodePtr); input.depth = temp.depth+1; memcpy(&input.parent, nodePtr, sizeof(Node)); input.numChildren = nodePtr->numChildren; //partialCount[i] = parTreeSearch(depth+1, nodePtr, nodePtr->numChildren); hpx_call_sync(theThread, _uts, &partialCount[i], sizeof(partialCount[i]), &input, sizeof(input)); } for (i = 0; i < temp.numChildren; i++) { subtreesize += partialCount[i]; } HPX_THREAD_CONTINUE(subtreesize); return HPX_SUCCESS; }
static hpx_addr_t _pgas_gas_calloc_cyclic(size_t n, uint32_t bsize, uint32_t boundary, uint32_t attr) { hpx_addr_t addr; if (here->rank == 0) { addr = pgas_calloc_cyclic_sync(n, bsize); } else { int e = hpx_call_sync(HPX_THERE(0), pgas_calloc_cyclic, &addr, sizeof(addr), &n, &bsize); dbg_check(e, "Failed to call pgas_calloc_cyclic_handler.\n"); } dbg_assert_str(addr != HPX_NULL, "HPX_NULL is not a valid allocation\n"); return addr; }
static int _health_action(void *args, size_t size) { struct Village *village = (struct Village *)args; struct Village *vlist; printf("[%d]input village: %p, %d\n", village->id, village, village); // lowest level returns nothing // only for sim_village first call with village = NULL // recursive call cannot occurs if (village == NULL) { printf("I'm NULL!!!\n"); return HPX_SUCCESS; } /* printf("ID[%d] at level %d with seed %.0f. In Hosp, %d, %d, %p.\n", village->id, village->level, village->seed, village->hosp.personnel, village->hosp.free_personnel, village->hosp.realloc_lock ); */ /* Traverse village hierarchy (lower level first)*/ vlist = village->forward; while(vlist) { //printf("----> before vlist = %p, %d\n", vlist, vlist); hpx_call_sync(HPX_HERE, _health, NULL, 0, vlist, sizeof(struct Village)); vlist = vlist->next; //printf("----> after vlist = %p, %d\n", vlist, vlist); } //printf("health_action: %p, %d\n", village, village); /* Uses lists v->hosp->inside, and v->return */ check_patients_inside(village); /* Uses lists v->hosp->assess, v->hosp->inside, v->population and (v->back->hosp->realloc) !!! */ check_patients_assess_par(village); /* Uses lists v->hosp->waiting, and v->hosp->assess */ check_patients_waiting(village); /* Uses lists v->hosp->realloc, v->hosp->asses and v->hosp->waiting */ check_patients_realloc(village); /* Uses list v->population, v->hosp->asses and v->h->waiting */ check_patients_population(village); return HPX_SUCCESS; }
static int lco_getall_handler(void) { uint32_t n, ssn; printf("Starting the HPX LCO get all test\n"); for (uint32_t i = 0; i < 6; i++) { ssn = 0; n = i + 1; hpx_time_t t1 = hpx_time_now(); printf("Square series for (%d): ", n); hpx_call_sync(HPX_HERE, _getAll, &ssn, sizeof(ssn), &n, sizeof(n)); printf("%d", ssn); printf(" Elapsed: %.7f\n", hpx_time_elapsed_ms(t1)/1e3); } return HPX_SUCCESS; }
static int _lco_get_remote_handler(void) { int rank = (HPX_LOCALITY_ID + 1) % HPX_LOCALITIES; hpx_addr_t there = HPX_THERE(rank); hpx_addr_t lco; int e = hpx_call_sync(there, _new_future, &lco, sizeof(lco)); assert(e == HPX_SUCCESS); int i = 42; e = hpx_call(lco, hpx_lco_set_action, HPX_NULL, &i, sizeof(i)); assert(e == HPX_SUCCESS); i = 0; e = hpx_lco_get(lco, sizeof(i), &i); assert(e == HPX_SUCCESS); assert(i = 42); return hpx_call_cc(lco, hpx_lco_delete_action); }
counter_t parallel_uts ( Node *root ) { struct thread_data input; hpx_time_t start; hpx_addr_t theThread = HPX_HERE; counter_t num_nodes; input.depth = 0; memcpy(&input.parent, root, sizeof(Node)); input.numChildren = getNumRootChildren(root); printf("Computing Unbalance Tree Search algorithm "); hpx_addr_t done = hpx_lco_future_new(sizeof(uint64_t)); start = hpx_time_now(); hpx_call_sync(theThread, _uts, &num_nodes, sizeof(num_nodes), &input, sizeof(input)); bots_time_program = hpx_time_elapsed_ms(start)/1e3; printf(" completed!"); return num_nodes; }
static int parcel_send_rendezvous_handler(void) { printf("Testing the hpx parcel send function for large parcels\n"); unsigned seed = 0; const libhpx_config_t *cfg = libhpx_get_config(); size_t eagerlimit = cfg->pwc_parceleagerlimit; size_t N = eagerlimit / sizeof(int) + 1; for (int i = 1, e = 10; i < e; ++i) { size_t scale = i * N; size_t size = scale * sizeof(int); int *send = malloc(size); int *recv = malloc(size); for (size_t i = 0, e = scale; i < e; ++i) { send[i] = rand_r(&seed); } int peer = (HPX_LOCALITY_ID + rand_r(&seed)) % HPX_LOCALITIES; printf("sending %zu integers (%zu-bytes) to %d\n", scale, size, peer); hpx_call_sync(HPX_THERE(peer), _echo, recv, size, send, size); for (size_t i = 0, e = scale; i < e; ++i) { if (send[i] != recv[i]) { fprintf(stderr, "data corruption\n" "scale: %zu\n" "offset: %zu\n" "expected: %d\n" "actual: %d\n", scale, i, send[i], recv[i]); exit(EXIT_FAILURE); } } free(send); free(recv); } return HPX_SUCCESS; }
/// Allocate an array of user LCO local to the calling locality. /// @param n The (total) number of lcos to allocate /// @param size The size of the LCO Buffer /// @param id An initialization function for the data, this is /// used to initialize the data in every epoch. /// @param op The commutative-associative operation we're /// performing. /// @param predicate Predicate to guard the LCO. /// @param init The initialization data address. /// @param init_size The size of the initialization data. /// /// @returns the global address of the allocated array lco. hpx_addr_t hpx_lco_user_local_array_new(int n, size_t size, hpx_action_t id, hpx_action_t op, hpx_action_t predicate, void *init, size_t init_size) { uint32_t lco_bytes = sizeof(_user_lco_t) + size + init_size; dbg_assert(n * lco_bytes < UINT32_MAX); hpx_addr_t base = lco_alloc_local(n, lco_bytes, 0); size_t args_size = sizeof(_user_lco_t) + init_size; _user_lco_init_args_t *args = calloc(1, args_size); args->n = n; args->size = size; args->id = id; args->op = op; args->predicate = predicate; args->init_size = init_size; memcpy(args->data, init, init_size); int e = hpx_call_sync(base, _block_init, NULL, 0, args, args_size); dbg_check(e, "call of _block_init_action failed\n"); free(args); // return the base address of the allocation return base; }
static int _init_memory_handler(uint32_t *args, size_t n) { hpx_addr_t local = hpx_thread_current_target(); hpx_call_sync(local, _init_block, NULL, 0, args, sizeof(*args)); return HPX_SUCCESS; }
/// Test the gas_memput_rsync operation. /// /// @param buffer The local buffer to put from. /// @param n The number of bytes to put. /// @param block The global address to put into. void test_memput_rsync(const uint64_t *buffer, size_t n, hpx_addr_t block) { CHECK( hpx_gas_memput_rsync(block, buffer, n) ); CHECK( hpx_call_sync(block, verify, NULL, 0, buffer, n) ); }
static int _test_set_rsync_local_handler(void) { hpx_addr_t lco; hpx_call_sync(HPX_HERE, _new_future_at, &lco, sizeof(lco)); hpx_call_sync(HPX_HERE, _test_set_rsync, NULL, 0, &lco); return hpx_call_cc(lco, hpx_lco_delete_action); }