static void init(int num_xstreams) { int i; ABT_mutex_create(&g_mutex); g_xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * max_xstreams); g_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * max_xstreams); g_signal = (int *)calloc(max_xstreams, sizeof(int)); for (i = 0; i < max_xstreams; i++) { g_xstreams[i] = ABT_XSTREAM_NULL; g_pools[i] = ABT_POOL_NULL; } /* Create pools */ for (i = 0; i < max_xstreams; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pools[i]); } /* Create ESs */ ABT_xstream_self(&g_xstreams[0]); for (i = 1; i < num_xstreams; i++) { create_xstream(i); } }
void rt1_init(int max_xstreams, ABT_xstream *xstreams) { int i; char *env; rt1_data = (rt1_data_t *)calloc(1, sizeof(rt1_data_t)); rt1_data->max_xstreams = max_xstreams; rt1_data->num_xstreams = max_xstreams; rt1_data->xstreams = (ABT_xstream *)malloc(max_xstreams*sizeof(ABT_xstream)); for (i = 0; i < max_xstreams; i++) { rt1_data->xstreams[i] = xstreams[i]; } ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &rt1_data->pool); ABT_mutex_create(&rt1_data->mutex); ABT_barrier_create(rt1_data->num_xstreams, &rt1_data->bar); /* Add event callbacks */ /* NOTE: Each runtime needs to register callbacks only once for each event. * If it registers more than once, callbacks will be invoked as many times * as they are registered. */ ABT_event_add_callback(ABT_EVENT_STOP_XSTREAM, rt1_ask_stop_xstream, rt1_data, rt1_act_stop_xstream, rt1_data, &rt1_data->stop_cb_id); ABT_event_add_callback(ABT_EVENT_ADD_XSTREAM, rt1_ask_add_xstream, rt1_data, rt1_act_add_xstream, rt1_data, &rt1_data->add_cb_id); /* application data */ env = getenv("APP_NUM_COMPS"); if (env) { rt1_data->num_comps = atoi(env); } else { rt1_data->num_comps = NUM_COMPS; } env = getenv("APP_NUM_ITERS"); if (env) { rt1_data->num_iters = atoi(env); } else { rt1_data->num_iters = NUM_ITERS; } size_t num_elems = rt1_data->max_xstreams * rt1_data->num_comps * 2; rt1_data->app_data = (double *)calloc(num_elems, sizeof(double)); printf("# of WUs created per ES: %d\n", rt1_data->num_comps); printf("# of iterations per WU : %d\n", rt1_data->num_iters); }
GLT_func_prefix void glt_init(int argc, char * argv[]) { int num_threads = get_nprocs(); main_team = (glt_team_t *) malloc(sizeof (glt_team_t)); CHECK(ABT_init(argc, argv),ABT_SUCCESS); if (getenv("GLT_NUM_THREADS") != NULL) { num_threads = atoi(getenv("GLT_NUM_THREADS")); } int num_pools = num_threads; if (getenv("GLT_NUM_POOLS") != NULL) { num_pools = atoi(getenv("GLT_NUM_POOLS")); } CHECK(ABT_xstream_self(&main_team->master),ABT_SUCCESS); main_team->num_xstreams = num_threads; main_team->num_pools = num_pools; main_team->max_elem = get_nprocs(); main_team->team = (ABT_xstream *) malloc(sizeof (ABT_xstream) * num_threads);//main_team->max_elem); main_team->pools = (ABT_pool *) malloc(sizeof (ABT_pool) * num_pools);//main_team->max_elem); for (int i = 0; i < num_pools; i++) { CHECK(ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &main_team->pools[i]),ABT_SUCCESS); } CHECK(ABT_xstream_self(&main_team->team[0]),ABT_SUCCESS); CHECK(ABT_xstream_set_main_sched_basic(main_team->team[0], ABT_SCHED_DEFAULT, 1, &main_team->pools[0]),ABT_SUCCESS); for (int i = 1; i < num_threads; i++) { CHECK(ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &main_team->pools[i % main_team->num_pools], ABT_SCHED_CONFIG_NULL, &main_team->team[i]),ABT_SUCCESS); CHECK(ABT_xstream_start(main_team->team[i]),ABT_SUCCESS); } }
/* Main function */ int main(int argc, char *argv[]) { int n, i, expected; int num_xstreams; ABT_xstream *xstreams; ABT_thread thread; thread_args args; if (argc > 1 && strcmp(argv[1], "-h") == 0) { printf("Usage: %s [N=10] [num_ES=4]\n", argv[0]); return EXIT_SUCCESS; } n = argc > 1 ? atoi(argv[1]) : N; num_xstreams = argc > 2 ? atoi(argv[2]) : NUM_XSTREAMS; printf("# of ESs: %d\n", num_xstreams); /* initialization */ ABT_init(argc, argv); /* shared pool creation */ ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pool); /* ES creation */ xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pool); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pool, ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } args.n = n; args.future = ABT_FUTURE_NULL; ABT_thread_create(g_pool, fibonacci, &args, ABT_THREAD_ATTR_NULL, &thread); /* join the thread */ ABT_thread_join(thread); ABT_thread_free(&thread); /* join ESs */ for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } ABT_finalize(); free(xstreams); printf("Fib(%d): %d\n", n, args.result); expected = verify(n); if (args.result != expected) { fprintf(stderr, "ERROR: expected=%d\n", expected); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
static void create_scheds_and_xstreams(void) { int i, k, ret; int num_scheds = g_data.num_scheds; ABT_sched *scheds = g_data.scheds; int *num_pools = g_data.num_pools; ABT_pool **pools = g_data.pools; ABT_xstream *xstreams = g_data.xstreams; for (i = 0; i < num_scheds; i++) { if (i == num_scheds-1) { /* Create pools and then create a scheduler */ num_pools[i] = 2; pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); pools[i][0] = ABT_POOL_NULL; for (k = 1; k < num_pools[i]; k++) { ret = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC, ABT_TRUE, &pools[i][k]); ABT_TEST_ERROR(ret, "ABT_pool_create_basic"); } ret = ABT_sched_create_basic(ABT_SCHED_PRIO, num_pools[i], pools[i], ABT_SCHED_CONFIG_NULL, &scheds[i]); ABT_TEST_ERROR(ret, "ABT_sched_create_basic"); } else { /* Create a scheduler and then get the list of pools */ ABT_sched_config config; ret = ABT_sched_config_create(&config, ABT_sched_config_access, accesses[i], ABT_sched_config_var_end); ABT_TEST_ERROR(ret, "ABT_sched_config_create"); ret = ABT_sched_create_basic(ABT_SCHED_PRIO, 0, NULL, config, &scheds[i]); ABT_TEST_ERROR(ret, "ABT_sched_create_basic"); ret = ABT_sched_config_free(&config); ABT_TEST_ERROR(ret, "ABT_sched_config_free"); ret = ABT_sched_get_num_pools(scheds[i], &num_pools[i]); ABT_TEST_ERROR(ret, "ABT_sched_get_num_pools"); pools[i] = (ABT_pool *)malloc(num_pools[i] * sizeof(ABT_pool)); } ret = ABT_sched_get_pools(scheds[i], num_pools[i], 0, pools[i]); ABT_TEST_ERROR(ret, "ABT_sched_get_pools"); /* Create ES */ if (i == 0) { ret = ABT_xstream_self(&xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_self"); ret = ABT_xstream_set_main_sched(xstreams[i], scheds[i]); ABT_TEST_ERROR(ret, "ABT_xstream_set_main_sched"); } else { /* If the predefined scheduler is associated with PW pools, we will stack it so that the primary ULT can add the initial work unit. */ if (accesses[i] == ABT_POOL_ACCESS_PRIV || accesses[i] == ABT_POOL_ACCESS_SPSC || accesses[i] == ABT_POOL_ACCESS_SPMC) { ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } else { ret = ABT_xstream_create(scheds[i], &xstreams[i]); ABT_TEST_ERROR(ret, "ABT_xstream_create"); } } } }
/* Main function */ int main(int argc, char *argv[]) { int n, i, result, expected; int num_xstreams; ABT_xstream *xstreams; ABT_thread thread; thread_args args_thread; ABT_task task; task_args *args_task; if (argc > 1 && strcmp(argv[1], "-h") == 0) { printf("Usage: %s [N=10] [num_ES=4]\n", argv[0]); return EXIT_SUCCESS; } n = argc > 1 ? atoi(argv[1]) : N; num_xstreams = argc > 2 ? atoi(argv[2]) : NUM_XSTREAMS; printf("# of ESs: %d\n", num_xstreams); if (n <= 2) { result = 1; goto fn_result; } /* initialization */ ABT_init(argc, argv); /* shared pool creation */ ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pool); /* ES creation */ xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pool); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pool, ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } /* creating thread */ args_thread.n = n - 1; args_thread.eventual = ABT_EVENTUAL_NULL; ABT_thread_create(g_pool, fibonacci_thread, &args_thread, ABT_THREAD_ATTR_NULL, &thread); /* creating task */ args_task = (task_args *)malloc(sizeof(task_args)); args_task->n = n - 2; args_task->result = 0; ABT_mutex_create(&args_task->mutex); args_task->parent = NULL; ABT_task_create(g_pool, fibonacci_task, args_task, &task); /* switch to other user-level threads */ ABT_thread_yield(); /* join other threads */ ABT_thread_join(thread); ABT_thread_free(&thread); /* join ESs */ for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } result = args_thread.result + args_task->result; free(args_task); ABT_finalize(); free(xstreams); fn_result: printf("Fib(%d): %d\n", n, result); expected = verify(n); if (result != expected) { fprintf(stderr, "ERROR: expected=%d\n", expected); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
/** * @ingroup SCHED * @brief Create a new user-defined scheduler and return its handle through * newsched. * * The pools used by the new scheduler are provided by \c pools. The contents * of this array is copied, so it can be freed. If a pool in the array is * ABT_POOL_NULL, the corresponding pool is automatically created. * The config must have been created by ABT_sched_config_create, and will be * used as argument in the initialization. If no specific configuration is * required, the parameter will be ABT_CONFIG_NULL. * * @param[in] def definition required for scheduler creation * @param[in] num_pools number of pools associated with this scheduler * @param[in] pools pools associated with this scheduler * @param[in] config specific config used during the scheduler creation * @param[out] newsched handle to a new scheduler * @return Error code * @retval ABT_SUCCESS on success */ int ABT_sched_create(ABT_sched_def *def, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched) { int abt_errno = ABT_SUCCESS; ABTI_sched *p_sched; int p; ABTI_CHECK_TRUE(newsched != NULL, ABT_ERR_SCHED); p_sched = (ABTI_sched *)ABTU_malloc(sizeof(ABTI_sched)); /* Copy of the contents of pools */ ABT_pool *pool_list; pool_list = (ABT_pool *)ABTU_malloc(num_pools*sizeof(ABT_pool)); for (p = 0; p < num_pools; p++) { if (pools[p] == ABT_POOL_NULL) { abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC, ABT_TRUE, &pool_list[p]); ABTI_CHECK_ERROR(abt_errno); } else { pool_list[p] = pools[p]; } } /* Check if the pools are available */ for (p = 0; p < num_pools; p++) { ABTI_pool_retain(ABTI_pool_get_ptr(pool_list[p])); } p_sched->used = ABTI_SCHED_NOT_USED; p_sched->automatic = ABT_FALSE; p_sched->kind = ABTI_sched_get_kind(def); p_sched->state = ABT_SCHED_STATE_READY; p_sched->request = 0; p_sched->pools = pool_list; p_sched->num_pools = num_pools; p_sched->type = def->type; p_sched->p_thread = NULL; p_sched->p_task = NULL; p_sched->p_ctx = NULL; p_sched->init = def->init; p_sched->run = def->run; p_sched->free = def->free; p_sched->get_migr_pool = def->get_migr_pool; #ifdef ABT_CONFIG_USE_DEBUG_LOG p_sched->id = ABTI_sched_get_new_id(); #endif LOG_EVENT("[S%" PRIu64 "] created\n", p_sched->id); /* Return value */ *newsched = ABTI_sched_get_handle(p_sched); /* Specific initialization */ p_sched->init(*newsched, config); fn_exit: return abt_errno; fn_fail: *newsched = ABT_SCHED_NULL; HANDLE_ERROR_FUNC_WITH_CODE(abt_errno); goto fn_exit; }
/** * @ingroup SCHED * @brief Create a predefined scheduler. * * \c ABT_sched_create_basic() creates a predefined scheduler and returns its * handle through \c newsched. The pools used by the new scheduler are * provided by \c pools. The contents of this array is copied, so it can be * freed. If a pool in the array is \c ABT_POOL_NULL, the corresponding pool is * automatically created. The pool array can be \c NULL. In this case, all * the pools will be created automatically. The config must have been created * by \c ABT_sched_config_create(), and will be used as argument in the * initialization. If no specific configuration is required, the parameter can * be \c ABT_CONFIG_NULL. * * NOTE: The new scheduler will be automatically freed when it is not used * anymore or its associated ES is terminated. Accordingly, the pools * associated with the new scheduler will be automatically freed if they are * exclusive to the scheduler and are not user-defined ones (i.e., created by * \c ABT_pool_create_basic() or implicitly created because \c pools is \c NULL * or a pool in the \c pools array is \c ABT_POOL_NULL). If the pools were * created using \c ABT_pool_create() by the user, they have to be freed * explicitly with \c ABT_pool_free(). * * @param[in] predef predefined scheduler * @param[in] num_pools number of pools associated with this scheduler * @param[in] pools pools associated with this scheduler * @param[in] config specific config used during the scheduler creation * @param[out] newsched handle to a new scheduler * @return Error code * @retval ABT_SUCCESS on success */ int ABT_sched_create_basic(ABT_sched_predef predef, int num_pools, ABT_pool *pools, ABT_sched_config config, ABT_sched *newsched) { int abt_errno = ABT_SUCCESS; ABT_pool_access access; ABT_bool automatic; int p; /* We set the access to the default one */ access = ABT_POOL_ACCESS_MPSC; automatic = ABT_TRUE;; /* We read the config and set the configured parameters */ abt_errno = ABTI_sched_config_read_global(config, &access, &automatic); ABTI_CHECK_ERROR(abt_errno); /* A pool array is provided, predef has to be compatible */ if (pools != NULL) { /* Copy of the contents of pools */ ABT_pool *pool_list; pool_list = (ABT_pool *)ABTU_malloc(num_pools*sizeof(ABT_pool)); for (p = 0; p < num_pools; p++) { if (pools[p] == ABT_POOL_NULL) { abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO, access, ABT_TRUE, &pool_list[p]); ABTI_CHECK_ERROR(abt_errno); } else { pool_list[p] = pools[p]; } } /* Creation of the scheduler */ switch (predef) { case ABT_SCHED_DEFAULT: case ABT_SCHED_BASIC: abt_errno = ABT_sched_create(ABTI_sched_get_basic_def(), num_pools, pool_list, ABT_SCHED_CONFIG_NULL, newsched); break; case ABT_SCHED_PRIO: abt_errno = ABT_sched_create(ABTI_sched_get_prio_def(), num_pools, pool_list, ABT_SCHED_CONFIG_NULL, newsched); break; case ABT_SCHED_RANDWS: abt_errno = ABT_sched_create(ABTI_sched_get_randws_def(), num_pools, pool_list, ABT_SCHED_CONFIG_NULL, newsched); break; default: abt_errno = ABT_ERR_INV_SCHED_PREDEF; break; } ABTI_CHECK_ERROR(abt_errno); ABTU_free(pool_list); } /* No pool array is provided, predef has to be compatible */ else { /* Set the number of pools */ switch (predef) { case ABT_SCHED_DEFAULT: case ABT_SCHED_BASIC: num_pools = 1; break; case ABT_SCHED_PRIO: num_pools = ABTI_SCHED_NUM_PRIO; break; case ABT_SCHED_RANDWS: num_pools = 1; break; default: abt_errno = ABT_ERR_INV_SCHED_PREDEF; ABTI_CHECK_ERROR(abt_errno); break; } /* Creation of the pools */ /* To avoid the malloc overhead, we use a stack array. */ ABT_pool pool_list[ABTI_SCHED_NUM_PRIO]; int p; for (p = 0; p < num_pools; p++) { abt_errno = ABT_pool_create_basic(ABT_POOL_FIFO, access, ABT_TRUE, pool_list+p); ABTI_CHECK_ERROR(abt_errno); } /* Creation of the scheduler */ switch (predef) { case ABT_SCHED_DEFAULT: case ABT_SCHED_BASIC: abt_errno = ABT_sched_create(ABTI_sched_get_basic_def(), num_pools, pool_list, config, newsched); break; case ABT_SCHED_PRIO: abt_errno = ABT_sched_create(ABTI_sched_get_prio_def(), num_pools, pool_list, config, newsched); break; case ABT_SCHED_RANDWS: abt_errno = ABT_sched_create(ABTI_sched_get_randws_def(), num_pools, pool_list, config, newsched); break; default: abt_errno = ABT_ERR_INV_SCHED_PREDEF; ABTI_CHECK_ERROR(abt_errno); break; } } ABTI_CHECK_ERROR(abt_errno); ABTI_sched *p_sched = ABTI_sched_get_ptr(*newsched); p_sched->automatic = automatic; fn_exit: return abt_errno; fn_fail: HANDLE_ERROR_FUNC_WITH_CODE(abt_errno); *newsched = ABT_SCHED_NULL; goto fn_exit; }
int main(int argc, char *argv[]) { int i, j, r; int num_xstreams; char *str, *endptr; ABT_xstream *xstreams; ABT_thread *threads; vector_scal_task_args_t *args; int inner_xstreams; double *time, avg_time = 0.0; num_xstreams = (argc > 1) ? atoi(argv[1]) : NUM_XSTREAMS; inner_xstreams = (argc > 2) ? atoi(argv[2]) : NUM_XSTREAMS; int rep = (argc > 3) ? atoi(argv[3]) : NUM_REPS; time = (double *)malloc(sizeof(double) * rep); init(); g_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); threads = (ABT_thread *)malloc(sizeof(ABT_thread) * num_xstreams); args = (vector_scal_task_args_t *)malloc(sizeof(vector_scal_task_args_t) * num_xstreams); /* initialization */ ABT_init(argc, argv); for (i = 0; i < num_xstreams; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pools[i]); } /* ES creation */ ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pools[0]); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pools[i], ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } /* Each task is created on the xstream which is going to execute it */ for (r = 0; r < rep; r++) { time[r] = ABT_get_wtime(); int bloc = NUM / (num_xstreams); int rest = NUM % (num_xstreams); int start = 0; int end = 0; for (j = 0; j < num_xstreams; j++) { start = end; int inc = (j < rest) ? 1 : 0; end += bloc + inc; args[j].start = start; args[j].end = end; args[j].it = NUM; args[j].nxstreams = inner_xstreams; if (j > 0) { ABT_thread_create(g_pools[j], vector_scal_launch, (void *)&args[j], ABT_THREAD_ATTR_NULL, &threads[j]); } } vector_scal_launch((void *)&args[0]); for (j = 1; j < num_xstreams; j++) { ABT_thread_free(&threads[j]); } time[r] = ABT_get_wtime() - time[r]; avg_time += time[r]; } avg_time /= rep; printf("%d %d %f\n", num_xstreams, inner_xstreams, avg_time); check(); for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } ABT_finalize(); free(g_pools); free(xstreams); free(threads); free(args); free(time); return EXIT_SUCCESS; }
void accalt_init(int argc, char * argv[]) { int num_threads = 1; main_team = (accalt_team_t *) malloc(sizeof (accalt_team_t)); #ifdef ARGOBOTS ABT_init(argc, argv); int num_pools = 1; if (getenv("ACCALT_NUM_THREADS") != NULL) { num_threads = atoi(getenv("ACCALT_NUM_THREADS")); } if (getenv("ACCALT_NUM_POOLS") != NULL) { num_pools = atoi(getenv("ACCALT_NUM_POOLS")); } main_team->num_xstreams = num_threads; main_team->num_pools = num_pools; //printf("Argobots %d ES, %d Pools\n", num_threads, num_pools); ABT_xstream_self(&main_team->master); main_team->team = (ABT_xstream *) malloc(sizeof (ABT_xstream) * num_threads); main_team->pools = (ABT_pool *) malloc(sizeof (ABT_pool) * num_pools); for (int i = 0; i < num_pools; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &main_team->pools[i]); } ABT_xstream_self(&main_team->team[0]); ABT_xstream_set_main_sched_basic(main_team->team[0], ABT_SCHED_DEFAULT, 1, &main_team->pools[0]); for (int i = 1; i < num_threads; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &main_team->pools[i % main_team->num_pools], ABT_SCHED_CONFIG_NULL, &main_team->team[i]); ABT_xstream_start(main_team->team[i]); } #endif #ifdef MASSIVETHREADS char buff[10]; if (getenv("ACCALT_NUM_THREADS") != NULL) { num_threads = atoi(getenv("ACCALT_NUM_THREADS")); sprintf(buff, "%d", num_threads); setenv("MYTH_WORKER_NUM", buff, 1); } else num_threads = atoi(getenv("MYTH_WORKER_NUM")); setenv("MYTH_BIND_WORKERS", "1", 1); //printf("Massive %d Workers\n", num_threads); main_team->num_workers = num_threads; myth_init(); //MassiveThreads #endif #ifdef QTHREADS char buff[10]; int num_workers_per_thread; if (getenv("ACCALT_NUM_THREADS") != NULL) { num_threads = atoi(getenv("ACCALT_NUM_THREADS")); sprintf(buff, "%d", num_threads); setenv("QTHREAD_NUM_SHEPHERDS", buff, 1); } else num_threads = atoi(getenv("QTHREAD_NUM_SHEPHERDS")); if (getenv("ACCALT_NUM_WORKERS_PER_THREAD") != NULL) { num_workers_per_thread = atoi(getenv("ACCALT_NUM_WORKERS_PER_THREAD")); sprintf(buff, "%d", num_workers_per_thread); setenv("QTHREAD_NUM_WORKERS_PER_SHEPHERD", buff, 1); } else num_workers_per_thread = atoi(getenv("QTHREAD_NUM_WORKERS_PER_SHEPHERD")); if (num_threads == 1 && num_workers_per_thread > 1) { setenv("QTHREAD_SHEPHERDS_BOUNDARY", "node", 1); setenv("QTHREAD_WORKER_UNIT", "core", 1); } if (num_threads > 1) { setenv("QTHREAD_SHEPHERDS_BOUNDARY", "core", 1); setenv("QTHREAD_WORKER_UNIT", "core", 1); } setenv("QTHREAD_AFFINITY", "yes", 1); //printf("Qthreads %d Shepherds, %d Workers_per_shepherd\n", num_threads, num_workers_per_thread); main_team->num_shepherds = num_threads; main_team->num_workers_per_shepherd = num_workers_per_thread; qthread_initialize(); //qthreads #endif }
int main(int argc, char *argv[]) { // Argobots definitions int ret, i; num_threads = 0; // Sockets Definitions int fd, cfd; struct sockaddr_in svaddr; struct sockaddr_storage claddr; socklen_t addrlen; signal(SIGINT, sighandler); ABT_init(argc, argv); int abts = 0;//ABT_snoozer_xstream_self_set(); if (abts != 0){ fprintf(stderr, "%s\n", "ABT snoozer xstream self error"); exit(-1); } xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * CORES); ret = ABT_xstream_self(&xstreams[0]); if(ret != 0){ fprintf(stderr, "%s\n", "ABT xstream self error"); exit(-1); } ret = ABT_xstream_get_main_pools(xstreams[0], 1, &pool); if(ret != 0){ fprintf(stderr, "%s\n", "ABT xstream pool error"); exit(-1); } ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pool); /* ES creation */ ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pool); for (i = 1; i < CORES; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pool, ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } //abtio = abt_io_init(CORES); //assert(abtio != NULL); fd = socket(AF_INET, SOCK_STREAM, 0); if(fd < 0){ fprintf(stderr, "%s\n", "Socket creating error"); exit(-1); } memset(&svaddr, 0, sizeof(struct sockaddr_in)); svaddr.sin_family = AF_INET; svaddr.sin_addr.s_addr = INADDR_ANY; svaddr.sin_port = htons(PORTNUM); ret = bind(fd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_in)); if(ret < 0){ fprintf(stderr, "%s\n", "Socket binding error"); exit(-1); } if( listen(fd, BACKLOG) == -1) { fprintf(stderr, "%s\n", "Socket listening error"); exit(-1); } int aio_sock = abt_io_socket_initialize(1000); if(aio_sock <= 0) printf("Initialize io_sock error\n"); //printf("USer: main: epoll fd = %d\n", aio_sock); addrlen = sizeof(struct sockaddr_storage); while(1){ cfd = accept(fd, (struct sockaddr *)&claddr, &addrlen); if(cfd == -1){ fprintf(stderr, "%s\n", "Socket accepting error"); exit(-1); } //printf("accepted client on file descriptor %d\n", cfd); struct thread_args* ta = (struct thread_args*) malloc (sizeof(ta)); ta->epfd = aio_sock; ta->fd = cfd; ABT_thread_create(g_pool, handle_client, (void *) ta, ABT_THREAD_ATTR_NULL, threads[num_threads++]); } return 0; }
int main(int argc, char *argv[]) { int i, j; int ntasks; int start, end; int num_xstreams; ABT_xstream *xstreams; vector_scal_task_args_t *args; struct timeval t_start, t_end, t_end2; char *str, *endptr; float *a; num_xstreams = argc > 1 ? atoi(argv[1]) : NUM_XSTREAMS; if (argc > 2) { str = argv[2]; } ntasks = argc > 2 ? strtoll(str, &endptr, 10) : NUM_TASKS; if (ntasks < num_xstreams) { ntasks = num_xstreams; } printf("# of ESs: %d\n", num_xstreams); xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams); args = (vector_scal_task_args_t *)malloc(sizeof(vector_scal_task_args_t) * num_xstreams); g_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams); a = malloc(sizeof(float) * ntasks); for (i = 0; i < ntasks; i++) { a[i] = i + 100.0f; } /* initialization */ ABT_init(argc, argv); for (i = 0; i < num_xstreams; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPMC, ABT_TRUE, &g_pools[i]); } /* ES creation */ ABT_xstream_self(&xstreams[0]); ABT_xstream_set_main_sched_basic(xstreams[0], ABT_SCHED_DEFAULT, 1, &g_pools[0]); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create_basic(ABT_SCHED_DEFAULT, 1, &g_pools[i], ABT_SCHED_CONFIG_NULL, &xstreams[i]); ABT_xstream_start(xstreams[i]); } /* Work here */ start = end = 0; int bloc = ntasks / num_xstreams; int rest = ntasks % num_xstreams; gettimeofday(&t_start, NULL); for (j = 0; j < num_xstreams; j++) { start = end; end = start + bloc; if (j < rest) { end++; } args[j].ptr = a; args[j].value = 0.9f; args[j].start = start; args[j].end = end; args[j].id = j; ABT_thread_create_on_xstream(xstreams[j], task_creator, (void *)&args[j], ABT_THREAD_ATTR_NULL, NULL); } gettimeofday(&t_end2, NULL); for (i = 0; i < num_xstreams; i++) { size_t size; do { ABT_thread_yield(); ABT_pool_get_size(g_pools[i], &size); } while (size != 0); } gettimeofday(&t_end, NULL); for (i = 0; i < ntasks; i++) { if (a[i] != (i + 100.0f) * 0.9f) { printf("error: a[%d]\n", i); } } double time = (t_end.tv_sec * 1000000 + t_end.tv_usec) - (t_start.tv_sec * 1000000 + t_start.tv_usec); double time2 = (t_end2.tv_sec * 1000000 + t_end2.tv_usec) - (t_start.tv_sec * 1000000 + t_start.tv_usec); printf("nxstreams: %d\nntasks %d\nTime(s): %f\n", num_xstreams, ntasks, time / 1000000.0); /* join ESs */ for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(xstreams[i]); ABT_xstream_free(&xstreams[i]); } printf("Creation time=%f\n", time2 / 1000000.0); ABT_finalize(); free(xstreams); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { ABT_pool (*all_pools)[2]; ABT_sched *scheds; ABT_thread *top_threads; size_t i, t; uint64_t t_start; /* initialize */ ABT_test_init(argc, argv); for (i = 0; i < T_LAST; i++) { t_times[i] = 0; } /* read command-line arguments */ num_xstreams = ABT_test_get_arg_val(ABT_TEST_ARG_N_ES); num_threads = ABT_test_get_arg_val(ABT_TEST_ARG_N_ULT); iter = ABT_test_get_arg_val(ABT_TEST_ARG_N_ITER); g_xstreams = (ABT_xstream *)malloc(num_xstreams * sizeof(ABT_xstream)); g_pools = (ABT_pool *)malloc(num_xstreams * sizeof(ABT_pool)); g_threads = (ABT_thread **)malloc(num_xstreams * sizeof(ABT_thread *)); for (i = 0; i < num_xstreams; i++) { g_threads[i] = (ABT_thread *)malloc(num_threads * sizeof(ABT_thread)); } all_pools = (ABT_pool (*)[2])malloc(num_xstreams * sizeof(ABT_pool) * 2); scheds = (ABT_sched *)malloc(num_xstreams * sizeof(ABT_sched)); top_threads = (ABT_thread *)malloc(num_xstreams * sizeof(ABT_thread)); /* create pools and schedulers */ for (i = 0; i < num_xstreams; i++) { ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_MPSC, ABT_TRUE, &all_pools[i][0]); ABT_pool_create_basic(ABT_POOL_FIFO, ABT_POOL_ACCESS_PRIV, ABT_TRUE, &all_pools[i][1]); g_pools[i] = all_pools[i][1]; ABT_sched_create_basic(ABT_SCHED_DEFAULT, 2, all_pools[i], ABT_SCHED_CONFIG_NULL, &scheds[i]); } /* create ESs */ ABT_xstream_self(&g_xstreams[0]); ABT_xstream_set_main_sched(g_xstreams[0], scheds[0]); for (i = 1; i < num_xstreams; i++) { ABT_xstream_create(scheds[i], &g_xstreams[i]); } /* benchmarking */ for (t = 0; t < T_LAST; t++) { void (*test_fn)(void *); if (t == T_YIELD) { if (t_times[T_YIELD_ALL] > t_times[T_YIELD_OVERHEAD]) { t_times[t] = t_times[T_YIELD_ALL] - t_times[T_YIELD_OVERHEAD]; } else { t_times[t] = 0; } continue; } else if (t == T_YIELD_TO) { if (t_times[T_YIELD_TO_ALL] > t_times[T_YIELD_TO_OVERHEAD]) { t_times[t] = t_times[T_YIELD_TO_ALL] - t_times[T_YIELD_TO_OVERHEAD]; } else { t_times[t] = 0; } continue; } switch (t) { case T_CREATE_JOIN: test_fn = test_create_join; break; case T_CREATE_UNNAMED: test_fn = test_create_unnamed; break; case T_YIELD_OVERHEAD: test_fn = test_yield_overhead; break; case T_YIELD_ALL: test_fn = test_yield; break; case T_YIELD_TO_OVERHEAD: test_fn = test_yield_to_overhead; break; case T_YIELD_TO_ALL: test_fn = test_yield_to; break; #ifdef TEST_MIGRATE_TO case T_MIGRATE_TO_XSTREAM: test_fn = test_migrate_to_xstream; break; #endif default: assert(0); } /* warm-up */ for (i = 0; i < num_xstreams; i++) { ABT_thread_create(all_pools[i][0], test_fn, (void *)i, ABT_THREAD_ATTR_NULL, &top_threads[i]); } for (i = 0; i < num_xstreams; i++) { ABT_thread_free(&top_threads[i]); } /* measurement */ #ifdef USE_TIME t_start = ABT_get_wtime(); #else t_start = ABT_test_get_cycles(); #endif for (i = 0; i < num_xstreams; i++) { ABT_thread_create(all_pools[i][0], test_fn, (void *)i, ABT_THREAD_ATTR_NULL, &top_threads[i]); } for (i = 0; i < num_xstreams; i++) { ABT_thread_free(&top_threads[i]); } #ifdef USE_TIME t_times[t] = ABT_get_wtime() - t_start; #else t_times[t] = ABT_test_get_cycles() - t_start; #endif } /* join and free */ for (i = 1; i < num_xstreams; i++) { ABT_xstream_join(g_xstreams[i]); ABT_xstream_free(&g_xstreams[i]); } /* finalize */ ABT_test_finalize(0); /* compute the execution time for one iteration */ for (i = 0; i < T_LAST; i++) { t_times[i] = t_times[i] / iter / num_threads; } /* output */ int line_size = 56; ABT_test_print_line(stdout, '-', line_size); printf("%s\n", "Argobots"); ABT_test_print_line(stdout, '-', line_size); printf("# of ESs : %d\n", num_xstreams); printf("# of ULTs per ES: %d\n", num_threads); ABT_test_print_line(stdout, '-', line_size); printf("Avg. execution time (in seconds, %d times)\n", iter); ABT_test_print_line(stdout, '-', line_size); printf("%-20s %-s\n", "operation", "time"); ABT_test_print_line(stdout, '-', line_size); for (i = 0; i < T_LAST; i++) { #ifdef USE_TIME printf("%-19s %.9lf\n", t_names[i], t_times[i]); #else printf("%-19s %11" PRIu64 "\n", t_names[i], t_times[i]); #endif } ABT_test_print_line(stdout, '-', line_size); free(g_xstreams); free(g_pools); for (i = 0; i < num_xstreams; i++) { free(g_threads[i]); } free(g_threads); free(all_pools); free(scheds); free(top_threads); return EXIT_SUCCESS; }