// Testcase to test hpx_lco_get_all function static int _getAll_handler(uint32_t *args, size_t size) { uint32_t n = *args; if (n < 2) { return HPX_THREAD_CONTINUE(n); } hpx_addr_t peers[] = { HPX_HERE, HPX_HERE }; uint32_t ns[] = { n - 1, n - 2 }; hpx_addr_t futures[] = { hpx_lco_future_new(sizeof(uint32_t)), hpx_lco_future_new(sizeof(uint32_t)) }; uint32_t ssn[] = { 0, 0 }; void *addrs[] = { &ssn[0], &ssn[1] }; size_t sizes[] = { sizeof(uint32_t), sizeof(uint32_t) }; hpx_call(peers[0], _getAll, futures[0], &ns[0], sizeof(uint32_t)); hpx_call(peers[1], _getAll, futures[1], &ns[1], sizeof(uint32_t)); hpx_lco_get_all(2, futures, sizes, addrs, NULL); hpx_lco_wait(futures[0]); hpx_lco_wait(futures[1]); hpx_addr_t wait = hpx_lco_future_new(0); hpx_lco_delete_all(2, futures, wait); hpx_lco_wait(wait); hpx_lco_delete(wait, HPX_NULL); uint32_t sn = ssn[0] * ssn[0] + ssn[1] * ssn[1]; return HPX_THREAD_CONTINUE(sn); }
/// Instantiate a single hpx_gas_memput test. /// /// This will allocate lsync and rsync lcos at @p lat and @p rat, respectively, /// and initiate and check the memput. /// /// @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 lat The locality to allocate the lsync at. /// @param rat The locality to allocate the rsync at. void test(const uint64_t *buffer, size_t n, hpx_addr_t block, hpx_addr_t lat, hpx_addr_t rat) { hpx_addr_t lsync = HPX_NULL; hpx_addr_t rsync = HPX_NULL; CHECK( hpx_call_sync(lat, future_at, &lsync, sizeof(lsync)) ); CHECK( hpx_call_sync(rat, future_at, &rsync, sizeof(rsync)) ); CHECK( hpx_gas_memput(block, buffer, n, lsync, rsync) ); CHECK( hpx_lco_wait(lsync) ); CHECK( hpx_lco_wait(rsync) ); CHECK( hpx_call_sync(block, verify, NULL, 0, buffer, n) ); hpx_lco_delete_sync(lsync); hpx_lco_delete_sync(rsync); }
static int _jacobi_main_handler(int n, int nsteps) { double h = 1.0/n; // allocate and initialize arrays hpx_addr_t u = hpx_gas_calloc_local_attr((n+1), BSIZE, 0, HPX_GAS_ATTR_LB); hpx_addr_t f = hpx_gas_alloc_local((n+1), BSIZE, 0); hpx_addr_t and = hpx_lco_and_new(n+1); for (int i = 0; i <= n; ++i) { double val = i*h; hpx_gas_memput_lsync(IDX(f,i), &val, sizeof(val), and); } hpx_lco_wait(and); hpx_lco_delete(and, HPX_NULL); printf("starting jacobi iterations...\n"); hpx_time_t start = hpx_time_now(); jacobi(n, nsteps, u, f); double elapsed = hpx_time_elapsed_ms(start)/1e3; // run the solver printf("n: %d\n", n); printf("nsteps: %d\n", nsteps); printf("seconds: %.7f\n", elapsed); // write the results if (fname) { write_solution(n, u, fname); } hpx_gas_free(f, HPX_NULL); hpx_gas_free(u, HPX_NULL); hpx_exit(HPX_SUCCESS); }
static int _delete_handler(const hpx_addr_t * const lcos, size_t n) { hpx_lco_wait(lcos[2]); hpx_lco_delete(lcos[2], HPX_NULL); hpx_lco_delete(lcos[0], HPX_NULL); hpx_lco_set(lcos[1], 0, NULL, HPX_NULL, HPX_NULL); return HPX_SUCCESS; }
int _hpx_process_call(hpx_addr_t process, hpx_addr_t addr, hpx_action_t id, hpx_addr_t result, int n, ...) { va_list args; va_start(args, n); hpx_action_t set = hpx_lco_set_action; hpx_parcel_t *p = action_new_parcel_va(id, addr, result, set, n, &args); va_end(args); if (hpx_thread_current_pid() == hpx_process_getpid(process)) { hpx_parcel_send_sync(p); return HPX_SUCCESS; } hpx_addr_t sync = hpx_lco_future_new(0); hpx_parcel_t *q = hpx_parcel_acquire(NULL, parcel_size(p)); q->target = process; q->action = _proc_call; q->c_target = sync; q->c_action = hpx_lco_set_action; hpx_parcel_set_data(q, p, parcel_size(p)); q->pid = 0; q->credit = 0; EVENT_PROCESS_CALL(process, q->pid); hpx_parcel_send_sync(q); parcel_delete(p); hpx_lco_wait(sync); hpx_lco_delete(sync, HPX_NULL); return HPX_SUCCESS; }
static int _test_set_lsync_handler(hpx_addr_t lco) { hpx_addr_t rsync = hpx_lco_future_new(4); printf("\ttesting ... "); { _cpy(_set, ONES); hpx_lco_set_lsync(lco, sizeof(ONES), ONES, HPX_NULL); _cpy(_set, ZEROS); hpx_lco_get(lco, sizeof(_get), &_get); _verify_get(); _reset(_set, _get, HPX_NULL, lco); } printf("ok\n"); printf("\ttesting rsync ... "); { _cpy(_set, ONES); hpx_lco_set_lsync(lco, sizeof(ONES), ONES, rsync); _cpy(_set, ZEROS); hpx_lco_wait(rsync); hpx_lco_get(lco, sizeof(_get), &_get); _verify_get(); _reset(_set, _get, rsync, lco); } printf("ok\n"); return hpx_call_cc(rsync, hpx_lco_delete_action); }
static int thread_cont_action_handler(void) { printf("Starting the Thread continue target and action test\n"); // Start the timer hpx_time_t t1 = hpx_time_now(); hpx_addr_t *cont_and = calloc(hpx_get_num_ranks(), sizeof(hpx_addr_t)); for (int i = 0; i < hpx_get_num_ranks(); i++) { cont_and[i] = hpx_lco_and_new(2); hpx_parcel_t *p = hpx_parcel_acquire(NULL, DATA_SIZE); hpx_parcel_set_target(p, HPX_THERE(i)); hpx_parcel_set_action(p, _thread_current_cont_target); hpx_parcel_set_cont_target(p, cont_and[i]); hpx_parcel_set_cont_action(p, hpx_lco_set_action); hpx_parcel_send_sync(p); printf("Started index %d.\n", i); } for (int i = 0; i < hpx_get_num_ranks(); i++) { hpx_lco_wait(cont_and[i]); printf("Received continuation from %d\n",i); hpx_lco_delete(cont_and[i], HPX_NULL); } free(cont_and); printf(" Elapsed: %g\n", hpx_time_elapsed_ms(t1)); return HPX_SUCCESS; }
static int lco_error_handler(void) { printf("Starting the HPX LCO get all test\n"); hpx_time_t t1 = hpx_time_now(); hpx_addr_t lco = hpx_lco_future_new(0); hpx_addr_t done = hpx_lco_future_new(0); hpx_call(HPX_HERE, _errorset, done, &lco, sizeof(lco)); hpx_status_t status = hpx_lco_wait(lco); printf("status == %d\n", status); assert(status == HPX_ERROR); hpx_lco_wait(done); hpx_lco_delete(lco, HPX_NULL); hpx_lco_delete(done, HPX_NULL); printf(" Elapsed: %.7f\n", hpx_time_elapsed_ms(t1)/1e3); return HPX_SUCCESS; }
static int _test_recursion_top_handler(void) { static int DEPTH = 500; hpx_addr_t and = hpx_lco_and_new(DEPTH); int e = hpx_xcall(HPX_HERE, _test_recursion, and, DEPTH, and); if (HPX_SUCCESS == e) { e = hpx_lco_wait(and); } hpx_lco_delete(and, HPX_NULL); return e; }
/// This action can be used by a thread to wait on an LCO through suspension. /// /// @param reset Flag saying if this is just a wait, or a wait + reset. /// @param parcel The address to be forwarded back to the caller. /// /// @returns HPX_SUCCESS static int _isir_lco_wait_handler(int reset, void *parcel) { if (reset) { dbg_check( hpx_lco_wait_reset(self->current->target) ); } else { dbg_check( hpx_lco_wait(self->current->target) ); } return hpx_thread_continue(parcel); }
/// Use the join_async operation in the allreduce leaf. static int _join_async_leaf_handler(hpx_addr_t allreduce, int i, int j, hpx_addr_t sum) { int r; hpx_addr_t f = hpx_lco_future_new(0); CHECK( hpx_lco_allreduce_join_async(allreduce, i, sizeof(j), &j, &r, f) ); CHECK( hpx_lco_wait(f) ); hpx_lco_delete(f, HPX_NULL); test_assert(r == HPX_LOCALITIES * N * (N + 1) / 2); return hpx_call_cc(sum, hpx_lco_set_action, &r, sizeof(r)); }
/// A utility that tests a certain leaf function through I iterations. static int _benchmark(char *name, hpx_action_t op, int iters, size_t size) { int ranks = HPX_LOCALITIES * HPX_THREADS; hpx_addr_t allreduce = hpx_lco_allreduce_new(ranks, ranks, size, _init, _min); hpx_addr_t done = hpx_lco_and_new(ranks); hpx_time_t start = hpx_time_now(); hpx_bcast(_fill_node, HPX_NULL, HPX_NULL, &op, &done, &allreduce, &iters, &size); hpx_lco_wait(done); double elapsed = hpx_time_elapsed_ms(start); hpx_lco_delete(allreduce, HPX_NULL); hpx_lco_delete(done, HPX_NULL); printf("%s: %.7f\n", name, elapsed/iters); return HPX_SUCCESS; }
static int lco_wait_handler(void) { printf("Starting the LCO wait test.\n"); // allocate and start a timer const hpx_time_t t1 = hpx_time_now(); const hpx_addr_t termination_lco = hpx_lco_and_new(2 * LCOS_PER_LOCALITY * HPX_LOCALITIES); hpx_bcast(_spawn, HPX_NULL, HPX_NULL, &termination_lco); hpx_lco_wait(termination_lco); hpx_lco_delete(termination_lco, HPX_NULL); printf(" Elapsed: %g\n", hpx_time_elapsed_ms(t1)); return HPX_SUCCESS; }
static int _test_try_task_handler(void) { barrier = sr_barrier_new(HPX_THREADS); assert(barrier); hpx_addr_t and = hpx_lco_and_new(HPX_THREADS + 1); assert(and); for (int i = 0; i < HPX_THREADS; ++i) { int e = hpx_call(HPX_HERE, _test_action, and); assert(e == HPX_SUCCESS); } hpx_lco_wait(and); hpx_lco_delete(and, HPX_NULL); sync_barrier_delete(barrier); return HPX_SUCCESS; }
static int _main_action(int *args, size_t size) { int n = *args; printf("seqspawn(%d)\n", n); fflush(stdout); hpx_addr_t and = hpx_lco_and_new(n); hpx_time_t now = hpx_time_now(); for (int i = 0; i < n; i++) hpx_call(HPX_HERE, _nop, and, 0, 0); hpx_lco_wait(and); double elapsed = hpx_time_elapsed_ms(now)/1e3; hpx_lco_delete(and, HPX_NULL); printf("seconds: %.7f\n", elapsed); printf("localities: %d\n", HPX_LOCALITIES); printf("threads: %d\n", HPX_THREADS); hpx_exit(HPX_SUCCESS); }
int parallel_nqueens(int n, int col, int *hist) { hpx_addr_t theThread = HPX_HERE; struct thread_data td; //td.lyst = hist; td.n = n; td.col = col; memcpy(td.lyst, hist, MAX_SIZE*sizeof(int)); //printf("thread_data size:%d\n", sizeof(struct thread_data)); mutex = hpx_lco_sema_new(1); //solve(td.n, td.col, td.lyst); hpx_addr_t done = hpx_lco_future_new(sizeof(uint64_t)); hpx_call(theThread, _nqueens, done, &td, sizeof(td)); hpx_lco_wait(done); hpx_lco_delete(done, HPX_NULL); return HPX_SUCCESS; }
// Test code -- ThreadCreate static int thread_create_handler(int *args, size_t size) { printf("Starting the Threads test\n"); // Start the timer hpx_time_t t1 = hpx_time_now(); hpx_addr_t addr = hpx_gas_alloc_cyclic(NUM_THREADS, sizeof(initBuffer_t), 0); // HPX Threads are spawned as a result of hpx_parcel_send() / hpx_parcel_ // sync(). for (int t = 0; t < NUM_THREADS; t++) { hpx_addr_t done = hpx_lco_and_new(1); hpx_parcel_t *p = hpx_parcel_acquire(NULL, sizeof(initBuffer_t)); // Fill the buffer initBuffer_t *init = hpx_parcel_get_data(p); init->index = t; strcpy(init->message, "Thread creation test"); // Set the target address and action for the parcel hpx_parcel_set_target(p, hpx_addr_add(addr, sizeof(initBuffer_t) * t, sizeof(initBuffer_t))); hpx_parcel_set_action(p, _initData); // Set the continuation target and action for parcel hpx_parcel_set_cont_target(p, done); hpx_parcel_set_cont_action(p, hpx_lco_set_action); // and send the parcel, this spawns the HPX thread hpx_parcel_send(p, HPX_NULL); hpx_lco_wait(done); hpx_lco_delete(done, HPX_NULL); } hpx_gas_free(addr, HPX_NULL); printf(" Elapsed: %g\n", hpx_time_elapsed_ms(t1)); hpx_exit(HPX_SUCCESS); }
static int parcel_get_continuation_handler(void) { printf("Testing parcel contination target and action\n"); hpx_time_t t1 = hpx_time_now(); hpx_addr_t addr = hpx_gas_alloc_cyclic(1, sizeof(uint64_t), sizeof(uint64_t)); hpx_addr_t done = hpx_lco_and_new(1); hpx_parcel_t *p = hpx_parcel_acquire(NULL, sizeof(uint64_t)); // Get access to the data, and fill it with the necessary data. uint64_t *result = hpx_parcel_get_data(p); *result = 1234; // Set the target address and action for the parcel hpx_parcel_set_target(p, addr); hpx_parcel_set_action(p, _get_cont_value); // Set the continuation target and action for the parcel hpx_parcel_set_cont_target(p, done); hpx_parcel_set_cont_action(p, hpx_lco_set_action); hpx_action_t get_act = hpx_parcel_get_cont_action(p); assert_msg(get_act == hpx_lco_set_action, "Error in getting cont action"); assert(hpx_parcel_get_cont_target(p) == done); // Send the parcel hpx_parcel_send(p, HPX_NULL); hpx_lco_wait(done); hpx_lco_delete(done, HPX_NULL); hpx_gas_free(addr, HPX_NULL); printf("Elapsed: %g\n", hpx_time_elapsed_ms(t1)); return HPX_SUCCESS; }
static int _wait_handler(const hpx_addr_t * const future, size_t n) { //printf("Waiting on %zu on %d\n", *future, HPX_LOCALITY_ID); hpx_lco_wait(*future); return HPX_SUCCESS; }
static int _main_action(int *args, size_t size) { hpx_time_t t; int count; fprintf(stdout, HEADER); fprintf(stdout, "# Latency in (ms)\n"); t = hpx_time_now(); hpx_addr_t done = hpx_lco_future_new(0); fprintf(stdout, "Creation time: %g\n", hpx_time_elapsed_ms(t)); value = 1234; t = hpx_time_now(); hpx_call(HPX_HERE, _set_value, done, &value, sizeof(value)); fprintf(stdout, "Value set time: %g\n", hpx_time_elapsed_ms(t)); t = hpx_time_now(); hpx_lco_wait(done); fprintf(stdout, "Wait time: %g\n", hpx_time_elapsed_ms(t)); t = hpx_time_now(); hpx_lco_delete(done, HPX_NULL); fprintf(stdout, "Deletion time: %g\n", hpx_time_elapsed_ms(t)); fprintf(stdout, "%s\t%*s%*s%*s\n", "# NumReaders " , FIELD_WIDTH, "Get_Value ", FIELD_WIDTH, " LCO_Getall ", FIELD_WIDTH, "Delete"); for (int i = 0; i < sizeof(num_readers)/sizeof(num_readers[0]); i++) { fprintf(stdout, "%d\t\t", num_readers[i]); count = num_readers[i]; int values[count]; void *addrs[count]; size_t sizes[count]; hpx_addr_t futures[count]; for (int j = 0; j < count; j++) { addrs[j] = &values[j]; sizes[j] = sizeof(int); futures[j] = hpx_lco_future_new(sizeof(int)); } t = hpx_time_now(); for (int j = 0; j < count; j++) { t = hpx_time_now(); hpx_call(HPX_HERE, _get_value, futures[j], NULL, 0); hpx_lco_wait(futures[j]); } fprintf(stdout, "%*g", FIELD_WIDTH, hpx_time_elapsed_ms(t)); t = hpx_time_now(); hpx_lco_get_all(count, futures, sizes, addrs, NULL); fprintf(stdout, "%*g", FIELD_WIDTH, hpx_time_elapsed_ms(t)); t = hpx_time_now(); for (int j = 0; j < count; j++) hpx_lco_delete(futures[j], HPX_NULL); fprintf(stdout, "%*g\n", FIELD_WIDTH, hpx_time_elapsed_ms(t)); } hpx_exit(HPX_SUCCESS); }