예제 #1
0
/* Function to compute Fibonacci numbers */
void fibonacci_task(void *arguments)
{
    int n, result;
    task_args *a1, *a2, *parent, *temp;
    ABT_task t1, t2;

    task_args *args = (task_args *)arguments;
    n = args->n;
    parent = args->parent;

    /* checking for base cases */
    if (n <= 2) {
        args->result = 1;
        result = 1;
        int flag = 1;
        while (flag && parent != NULL) {
            ABT_mutex_lock(parent->mutex);
            parent->result += result;
            if (result == parent->result) flag = 0;
            ABT_mutex_unlock(parent->mutex);
            result = parent->result;
            temp = parent->parent;

            if (flag && temp) {
                ABT_mutex_free(&parent->mutex);
                free(parent);
            }

            parent = temp;
        }

        ABT_mutex_free(&args->mutex);
        if (args->parent) {
            free(args);
        }
    } else {
        a1 = (task_args *)malloc(sizeof(task_args));
        a1->n = n - 1;
        a1->result = 0;
        ABT_mutex_create(&a1->mutex);
        a1->parent = args;
        ABT_task_create(g_pool, fibonacci_task, a1, &t1);

        a2 = (task_args *)malloc(sizeof(task_args));
        a2->n = n - 2;
        a2->result = 0;
        ABT_mutex_create(&a2->mutex);
        a2->parent = args;
        ABT_task_create(g_pool, fibonacci_task, a2, &t2);
    }
}
예제 #2
0
파일: accalt.c 프로젝트: adcastel/ULT_work
void accalt_tasklet_creation_to(void(*thread_func)(void *), void *arg, ACCALT_tasklet *new_ult, int dest) {
#ifdef ARGOBOTS
    ABT_pool pool;
    ABT_xstream_get_main_pools(main_team->team[dest], 1, &pool);
    ABT_task_create(pool, thread_func, arg, new_ult);
#endif
#ifdef MASSIVETHREADS
    accalt_ult_creation(thread_func, arg, new_ult);
#endif
#ifdef QTHREADS
    qthread_fork_to((void *) thread_func, arg, new_ult, dest);
#endif
}
예제 #3
0
파일: accalt.c 프로젝트: adcastel/ULT_work
void accalt_tasklet_creation(void(*thread_func)(void *), void *arg, ACCALT_tasklet *new_ult) {
#ifdef ARGOBOTS
    ABT_xstream xstream;
    ABT_xstream_self(&xstream);
    ABT_pool pool;
    ABT_xstream_get_main_pools(xstream, 1, &pool);
    ABT_task_create(pool, thread_func, arg, new_ult);
#endif
#ifdef MASSIVETHREADS
    *new_ult = myth_create((void *) thread_func, arg);
#endif
#ifdef QTHREADS
    qthread_fork((void *) thread_func, arg, new_ult);
#endif
}
예제 #4
0
static void gen_work(void *arg)
{
    int idx = (size_t)arg;
    int num_pools = g_data.num_pools[idx];
    ABT_pool *my_pools = g_data.pools[idx];
    ABT_bool flag;
    int i, ret;
    unsigned seed = time(NULL);

    ABT_test_printf(1, "[E%d] creating work units\n", idx);

    /* Create work units on the current ES */
    /* TODO: add work units to pools of other ESs */
    for (i = 0; i < num_units; i++) {
        unit_arg_t *my_arg = (unit_arg_t *)malloc(sizeof(unit_arg_t));
        my_arg->es_id = idx;
        my_arg->my_id = i;
        my_arg->prio = rand_r(&seed) % num_pools;

        if (i & 1) {
            ret = ABT_thread_create(my_pools[my_arg->prio],
                                    thread_func, (void *)my_arg,
                                    ABT_THREAD_ATTR_NULL, NULL);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
        } else {
            ret = ABT_task_create(my_pools[my_arg->prio],
                                  task_func, (void *)my_arg,
                                  NULL);
            ABT_TEST_ERROR(ret, "ABT_task_create");
        }
    }

    /* Stack the priority scheduler if it is associated with PW pools */
    ret = ABT_self_on_primary_xstream(&flag);
    ABT_TEST_ERROR(ret, "ABT_self_on_primary_stream");
    if (flag == ABT_FALSE) {
        if (accesses[idx] == ABT_POOL_ACCESS_PRIV ||
            accesses[idx] == ABT_POOL_ACCESS_SPSC ||
            accesses[idx] == ABT_POOL_ACCESS_SPMC) {
                ABT_pool main_pool;
                ret = ABT_xstream_get_main_pools(g_data.xstreams[idx],
                                                 1, &main_pool);
                ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools");
                ret = ABT_pool_add_sched(main_pool, g_data.scheds[idx]);
                ABT_TEST_ERROR(ret, "ABT_pool_add_sched");
        }
    }
}
void vector_scal_launch(void *arguments)
{
    int i, it, j, num_ults, rank, mystart, myend, p;
    ABT_task *tasks;
    ABT_xstream xstream;
    ABT_xstream_self(&xstream);
    vector_scal_task_args_t *arg;
    arg = (vector_scal_task_args_t *) arguments;
    vector_scal_args_t *args;
    it = arg->it;
    num_ults = arg->nxstreams;
    mystart = arg->start;
    myend = arg->end;

    args = (vector_scal_args_t *)malloc(sizeof(vector_scal_args_t)
                                        * num_ults);

    tasks = (ABT_task *)malloc(sizeof(ABT_task) * num_ults);

    int bloc = it / (num_ults);
    int rest = it % (num_ults);
    ABT_xstream_self_rank(&rank);
    for (i = mystart; i < myend; i++) {
        int start = 0;
        int end = 0;
        for (j = 0; j < num_ults; j++) {
            start = end;
            int inc = (j < rest) ? 1 : 0;
            end += bloc + inc;
            args[j].start = start;
            args[j].end = end;
            args[j].x = i;

            if (j > 0) {
                ABT_task_create(g_pools[rank], vector_scal, (void *)&args[j], &tasks[j]);
            }
        }
        vector_scal((void *)&args[0]);
        for (p = 1; p < num_ults; p++) {
            ABT_task_free(&tasks[p]);
        }
    }

    free(tasks);
    free(args);
}
예제 #6
0
void rt1_launcher(void *arg)
{
    int idx = (int)(intptr_t)arg;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_sched_config config;
    ABT_sched sched;
    size_t size;
    double t_start, t_end;

    ABT_sched_config_var cv_event_freq = {
        .idx = 0,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_config_var cv_idx = {
        .idx = 1,
        .type = ABT_SCHED_CONFIG_INT
    };

    ABT_sched_def sched_def = {
        .type = ABT_SCHED_TYPE_ULT,
        .init = sched_init,
        .run = sched_run,
        .free = sched_free,
        .get_migr_pool = NULL
    };

    /* Create a scheduler */
    ABT_sched_config_create(&config,
                            cv_event_freq, 10,
                            cv_idx, idx,
                            ABT_sched_config_var_end);
    ABT_sched_create(&sched_def, 1, &rt1_data->pool, config, &sched);

    /* Push the scheduler to the current pool */
    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);
    ABT_pool_add_sched(cur_pool, sched);

    /* Free */
    ABT_sched_config_free(&config);

    t_start = ABT_get_wtime();
    while (1) {
        rt1_app(idx);

        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) {
            ABT_sched_free(&sched);
            int rank;
            ABT_xstream_self_rank(&rank);
            printf("ES%d: finished\n", rank);
            ABT_mutex_lock(rt1_data->mutex);
            rt1_data->xstreams[rank] = ABT_XSTREAM_NULL;
            rt1_data->num_xstreams--;
            ABT_mutex_unlock(rt1_data->mutex);
            break;
        }

        t_end = ABT_get_wtime();
        if ((t_end - t_start) > g_timeout) {
            ABT_sched_finish(sched);
        }
    }
}

static void rt1_app(int eid)
{
    int i, num_comps;
    size_t size;
    ABT_thread cur_thread;
    ABT_pool cur_pool;

    ABT_thread_self(&cur_thread);
    ABT_thread_get_last_pool(cur_thread, &cur_pool);

    if (eid == 0) ABT_event_prof_start();

    num_comps = rt1_data->num_comps;
    for (i = 0; i < num_comps * 2; i += 2) {
        ABT_thread_create(rt1_data->pool, rt1_app_compute,
                          (void *)(intptr_t)(eid * num_comps * 2 + i),
                          ABT_THREAD_ATTR_NULL, NULL);
        ABT_task_create(rt1_data->pool, rt1_app_compute,
                        (void *)(intptr_t)(eid * num_comps * 2 + i + 1),
                        NULL);
    }

    do {
        ABT_thread_yield();

        /* If the size of cur_pool is zero, it means the stacked scheduler has
         * been terminated because of the shrinking event. */
        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) break;

        ABT_pool_get_total_size(rt1_data->pool, &size);
    } while (size > 0);

    if (eid == 0) {
        ABT_event_prof_stop();

        int cnt = __atomic_exchange_n(&rt1_data->cnt, 0, __ATOMIC_SEQ_CST);
        double local_work = (double)(cnt * rt1_data->num_iters);
        ABT_event_prof_publish("ops", local_work, local_work);
    }
}

static void rt1_app_compute(void *arg)
{
    int pos = (int)(intptr_t)arg;
    int i;

    rt1_data->app_data[pos] = 0;
    for (i = 0; i < rt1_data->num_iters; i++) {
        rt1_data->app_data[pos] += sin((double)pos);
    }

    __atomic_fetch_add(&rt1_data->cnt, 1, __ATOMIC_SEQ_CST);
}
예제 #7
0
/* 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;
}
예제 #8
0
void eventual_test(void *arg)
{
    int i, t, ret;
    size_t pid = (size_t)arg;
    int eid = (int)pid;

    ABT_thread *threads;
    arg_t *thread_args;
    int *nbytes;
    ABT_eventual *evs1;

    ABT_thread *waiters;
    arg_t *waiter_args;
    ABT_task *tasks;
    arg_t *task_args;
    ABT_eventual *evs2;

    ABT_test_printf(1, "[M%u] start\n", (unsigned)(size_t)arg);

    assert(num_tasks * 2 == num_threads);

    threads = (ABT_thread *)malloc(num_threads * sizeof(ABT_thread));
    thread_args = (arg_t *)malloc(num_threads * sizeof(arg_t));
    nbytes = (int *)malloc(num_tasks * sizeof(int));
    evs1 = (ABT_eventual *)malloc(num_tasks * sizeof(ABT_eventual));
    assert(threads && thread_args && nbytes && evs1);

    waiters = (ABT_thread *)malloc(num_tasks * sizeof(ABT_thread));
    waiter_args = (arg_t *)malloc(num_tasks * sizeof(arg_t));
    tasks = (ABT_task *)malloc(num_tasks * sizeof(ABT_task));
    task_args = (arg_t *)malloc(num_tasks * sizeof(arg_t));
    evs2 = (ABT_eventual *)malloc(num_tasks * sizeof(ABT_eventual));
    assert(waiters && waiter_args && tasks && task_args && evs2);

    for (t = 0; t < num_tasks; t++) {
        nbytes[t] = (t & 1) ? sizeof(int) : 0;

        ret = ABT_eventual_create(nbytes[t], &evs1[t]);
        ABT_TEST_ERROR(ret, "ABT_eventual_create");

        ret = ABT_eventual_create(nbytes[t], &evs2[t]);
        ABT_TEST_ERROR(ret, "ABT_eventual_create");
    }

    for (i = 0; i < num_iter; i++) {
        ABT_test_printf(2, "[M%u] iter=%d\n", (unsigned)(size_t)arg, i);

        /* Use eventual between ULTs */
        for (t = 0; t < num_threads; t += 2) {
            thread_args[t].eid = eid;
            thread_args[t].tid = t;
            thread_args[t].ev = evs1[t/2];
            thread_args[t].nbytes = nbytes[t/2];
            thread_args[t].op_type = OP_WAIT;
            ret = ABT_thread_create(pools[pid], thread_func, &thread_args[t],
                                    ABT_THREAD_ATTR_NULL, &threads[t]);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
            pid = (pid + 1) % num_xstreams;

            thread_args[t+1].eid = eid;
            thread_args[t+1].tid = t + 1;
            thread_args[t+1].ev = evs1[t/2];
            thread_args[t+1].nbytes = nbytes[t/2];
            thread_args[t+1].op_type = OP_SET;
            ret = ABT_thread_create(pools[pid], thread_func, &thread_args[t+1],
                                    ABT_THREAD_ATTR_NULL, &threads[t+1]);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
            pid = (pid + 1) % num_xstreams;
        }

        /* Use eventual between ULT and tasklet */
        for (t = 0; t < num_tasks; t++) {
            waiter_args[t].ev = evs2[t];
            waiter_args[t].nbytes = nbytes[t];
            waiter_args[t].op_type = OP_WAIT;
            ret = ABT_thread_create(pools[pid], thread_func, &waiter_args[t],
                                    ABT_THREAD_ATTR_NULL, &waiters[t]);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
            pid = (pid + 1) % num_xstreams;

            task_args[t].ev = evs2[t];
            task_args[t].nbytes = nbytes[t];
            task_args[t].op_type = OP_SET;
            ret = ABT_task_create(pools[pid], task_func, &task_args[t], &tasks[t]);
            ABT_TEST_ERROR(ret, "ABT_task_create");
            pid = (pid + 1) % num_xstreams;
        }

        for (t = 0; t < num_threads; t++) {
            ret = ABT_thread_free(&threads[t]);
            ABT_TEST_ERROR(ret, "ABT_thread_free");
        }

        for (t = 0; t < num_tasks; t++) {
            ret = ABT_thread_free(&waiters[t]);
            ABT_TEST_ERROR(ret, "ABT_thread_free");
            ret = ABT_task_free(&tasks[t]);
            ABT_TEST_ERROR(ret, "ABT_task_free");
        }

        for (t = 0; t < num_tasks; t++) {
            ret = ABT_eventual_reset(evs1[t]);
            ABT_TEST_ERROR(ret, "ABT_eventual_reset");
            ret = ABT_eventual_reset(evs2[t]);
            ABT_TEST_ERROR(ret, "ABT_eventual_reset");
        }

    }

    for (t = 0; t < num_tasks; t++) {
        ret = ABT_eventual_free(&evs1[t]);
        ABT_TEST_ERROR(ret, "ABT_eventual_free");
        ret = ABT_eventual_free(&evs2[t]);
        ABT_TEST_ERROR(ret, "ABT_eventual_free");
    }

    free(threads);
    free(thread_args);
    free(nbytes);
    free(evs1);

    free(waiters);
    free(waiter_args);
    free(tasks);
    free(task_args);
    free(evs2);

    ABT_test_printf(1, "[M%u] end\n", (unsigned)(size_t)arg);
}
예제 #9
0
int main(int argc, char *argv[])
{
    int i, j, ret;
    int num_xstreams = DEFAULT_NUM_XSTREAMS;
    int num_threads = DEFAULT_NUM_THREADS;
    int num_tasks = DEFAULT_NUM_TASKS;
    if (argc > 1) num_xstreams = atoi(argv[1]);
    assert(num_xstreams >= 0);
    if (argc > 2) num_threads = atoi(argv[2]);
    assert(num_threads >= 0);
    if (argc > 3) num_tasks = atoi(argv[3]);
    assert(num_tasks >= 0);

    ABT_xstream *xstreams;
    ABT_thread **threads;
    thread_arg_t **thread_args;
    ABT_task *tasks;
    task_arg_t *task_args;

    xstreams = (ABT_xstream *)malloc(sizeof(ABT_xstream) * num_xstreams);
    threads = (ABT_thread **)malloc(sizeof(ABT_thread *) * num_xstreams);
    thread_args = (thread_arg_t **)malloc(sizeof(thread_arg_t*) * num_xstreams);
    for (i = 0; i < num_xstreams; i++) {
        threads[i] = (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads);
        for (j = 0; j < num_threads; j++) {
            threads[i][j] = ABT_THREAD_NULL;
        }
        thread_args[i] = (thread_arg_t *)malloc(sizeof(thread_arg_t) *
                                                num_threads);
    }
    tasks = (ABT_task *)malloc(sizeof(ABT_task) * num_tasks);
    task_args = (task_arg_t *)malloc(sizeof(task_arg_t) * num_tasks);

    /* Initialize */
    ABT_test_init(argc, argv);

    /* Create Execution Streams */
    ret = ABT_xstream_self(&xstreams[0]);
    ABT_TEST_ERROR(ret, "ABT_xstream_self");
    for (i = 1; i < num_xstreams; i++) {
        ret = ABT_xstream_create(ABT_SCHED_NULL, &xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_create");
    }

    /* Get the pools attached to an execution stream */
    ABT_pool *pools;
    pools = (ABT_pool *)malloc(sizeof(ABT_pool) * num_xstreams);
    for (i = 0; i < num_xstreams; i++) {
        ret = ABT_xstream_get_main_pools(xstreams[i], 1, pools+i);
        ABT_TEST_ERROR(ret, "ABT_xstream_get_main_pools");
    }

    /* Create threads */
    for (i = 0; i < num_xstreams; i++) {
        for (j = 0; j < num_threads; j++) {
            int tid = i * num_threads + j + 1;
            thread_args[i][j].id = tid;
            thread_args[i][j].num_threads = num_threads;
            thread_args[i][j].threads = &threads[i][0];
            ret = ABT_thread_create(pools[i],
                    thread_func, (void *)&thread_args[i][j],
                    ABT_THREAD_ATTR_NULL,
                    &threads[i][j]);
            ABT_TEST_ERROR(ret, "ABT_thread_create");
        }
    }

    /* Create tasks with task_func1 */
    for (i = 0; i < num_tasks; i++) {
        size_t num = 100 + i;
        ret = ABT_task_create(pools[i % num_xstreams],
                              task_func1, (void *)num,
                              NULL);
        ABT_TEST_ERROR(ret, "ABT_task_create");
    }

    /* Create tasks with task_func2 */
    for (i = 0; i < num_tasks; i++) {
        task_args[i].num = 100 + i;
        ret = ABT_task_create(pools[i % num_xstreams],
                              task_func2, (void *)&task_args[i],
                              &tasks[i]);
        ABT_TEST_ERROR(ret, "ABT_task_create");
    }

    /* Switch to other work units */
    ABT_thread_yield();

    /* Results of task_funcs2 */
    for (i = 0; i < num_tasks; i++) {
        ABT_task_state state;
        do {
            ABT_task_get_state(tasks[i], &state);
            ABT_thread_yield();
        } while (state != ABT_TASK_STATE_TERMINATED);

        ABT_test_printf(1, "task_func2: num=%lu result=%llu\n",
               task_args[i].num, task_args[i].result);

        /* Free named tasks */
        ret = ABT_task_free(&tasks[i]);
        ABT_TEST_ERROR(ret, "ABT_task_free");
    }

    /* Join Execution Streams */
    for (i = 1; i < num_xstreams; i++) {
        ret = ABT_xstream_join(xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_join");
    }

    /* Free Execution Streams */
    for (i = 0; i < num_xstreams; i++) {
        for (j = 0; j < num_threads; j++) {
            ret = ABT_thread_free(&threads[i][j]);
            ABT_TEST_ERROR(ret, "ABT_thread_free");
        }

        if (i == 0) continue;

        ret = ABT_xstream_free(&xstreams[i]);
        ABT_TEST_ERROR(ret, "ABT_xstream_free");
    }

    /* Finalize */
    ret = ABT_test_finalize(0);

    for (i = 0; i < num_xstreams; i++) {
        free(thread_args[i]);
        free(threads[i]);
    }
    free(thread_args);
    free(threads);
    free(task_args);
    free(tasks);
    free(pools);
    free(xstreams);

    return ret;
}