Ejemplo n.º 1
0
void thread_func(void *arg)
{
    ABT_thread my_handle;
    ABT_thread_state my_state;
    ABT_thread_self(&my_handle);
    ABT_thread_get_state(my_handle, &my_state);
    if (my_state != ABT_THREAD_STATE_RUNNING) {
        fprintf(stderr, "ERROR: not in the RUNNUNG state\n");
    }
    ABT_thread_release(my_handle);

    thread_arg_t *t_arg = (thread_arg_t *)arg;
    ABT_thread next;

    ABT_test_printf(1, "[TH%d]: before yield\n", t_arg->id);
    next = pick_one(t_arg->threads, t_arg->num_threads);
    ABT_thread_yield_to(next);

    ABT_test_printf(1, "[TH%d]: doing something ...\n", t_arg->id);
    next = pick_one(t_arg->threads, t_arg->num_threads);
    ABT_thread_yield_to(next);

    ABT_test_printf(1, "[TH%d]: after yield\n", t_arg->id);

    ABT_task task;
    ABT_task_self(&task);
    if (task != ABT_TASK_NULL) {
        fprintf(stderr, "ERROR: should not be tasklet\n");
    }
}
Ejemplo n.º 2
0
static void thread_hello(void *arg)
{
    int old_rank, cur_rank;
    ABT_thread self;
    ABT_thread_id id;
    char *msg;

    ABT_xstream_self_rank(&cur_rank);
    ABT_thread_self(&self);
    ABT_thread_get_id(self, &id);
    ABT_thread_release(self);

    test_printf("[U%lu:E%d] Hello, world!\n", id, cur_rank);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Hello again #1.%s\n", id, cur_rank, msg);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Hello again #2.%s\n", id, cur_rank, msg);

    ABT_thread_yield();

    old_rank = cur_rank;
    ABT_xstream_self_rank(&cur_rank);
    msg = (cur_rank == old_rank) ? "" : " (stolen)";
    test_printf("[U%lu:E%d] Goodbye, world!%s\n", id, cur_rank, msg);
}
Ejemplo n.º 3
0
void thread_func_migrate_to_xstream(void *arg)
{
    arg_t *my_arg = (arg_t *)arg;
    int eid = my_arg->eid;
    ABT_xstream cur_xstream, tar_xstream;
    ABT_thread self;
    int i, next;

    ABT_thread_self(&self);

    for (i = 0; i < iter; i++) {
        next = (eid + 1) % num_xstreams;
        tar_xstream = g_xstreams[next];

        ABT_thread_migrate_to_xstream(self, tar_xstream);
        while (1) {
            ABT_bool flag;
            ABT_xstream_self(&cur_xstream);
            ABT_xstream_equal(cur_xstream, tar_xstream, &flag);
            if (flag == ABT_TRUE) {
                break;
            }
            ABT_thread_yield();
        }
        eid = next;
    }
}
Ejemplo n.º 4
0
void thread_create(void *arg)
{
    int rank, i, ret;
    ABT_thread self;
    ABT_thread_id id;
    ABT_pool my_pool;
    ABT_thread *threads;

    assert((size_t)arg == 0);

    ret = ABT_xstream_self_rank(&rank);
    ABT_TEST_ERROR(ret, "ABT_xstream_self_rank");
    ret = ABT_thread_self(&self);
    ABT_TEST_ERROR(ret, "ABT_thread_self");
    ret = ABT_thread_get_id(self, &id);
    ABT_TEST_ERROR(ret, "ABT_thread_get_id");
    ret = ABT_thread_get_last_pool(self, &my_pool);
    ABT_TEST_ERROR(ret, "ABT_thread_get_last_pool");

    threads = (ABT_thread *)malloc(num_threads * sizeof(ABT_thread));

    /* Create ULTs */
    for (i = 0; i < num_threads; i++) {
        ret = ABT_thread_create(my_pool, thread_func, (void *)1,
                                ABT_THREAD_ATTR_NULL, &threads[i]);
        ABT_TEST_ERROR(ret, "ABT_thread_create");
    }
    ABT_test_printf(1, "[U%lu:E%u]: created %d ULTs\n", id, rank, num_threads);

    /* Join ULTs */
    for (i = 0; i < num_threads; i++) {
        ret = ABT_thread_join(threads[i]);
        ABT_TEST_ERROR(ret, "ABT_thread_join");
    }
    ABT_test_printf(1, "[U%lu:E%u]: joined %d ULTs\n", id, rank, num_threads);

    /* Revive ULTs with a different function */
    for (i = 0; i < num_threads; i++) {
        ret = ABT_thread_revive(my_pool, thread_func2, (void *)2, &threads[i]);
        ABT_TEST_ERROR(ret, "ABT_thread_revive");
    }
    ABT_test_printf(1, "[U%lu:E%u]: revived %d ULTs\n", id, rank, num_threads);

    /* Join and free ULTs */
    for (i = 0; i < num_threads; i++) {
        ret = ABT_thread_free(&threads[i]);
        ABT_TEST_ERROR(ret, "ABT_thread_free");
    }
    ABT_test_printf(1, "[U%lu:E%u]: freed %d ULTs\n", id, rank, num_threads);

    free(threads);
}
Ejemplo n.º 5
0
void task_func2(void *arg)
{
    ABT_thread thread;
    ABT_thread_self(&thread);
    if (thread != ABT_THREAD_NULL) {
        fprintf(stderr, "ERROR: should not be ULT\n");
    }

    size_t i;
    task_arg_t *my_arg = (task_arg_t *)arg;
    unsigned long long result = 1;
    for (i = 2; i <= my_arg->num; i++) {
        result += i;
    }
    my_arg->result = result;
}
Ejemplo n.º 6
0
void thread_func2(void *arg)
{
    int rank, ret;
    ABT_thread self;
    ABT_thread_id id;

    assert((size_t)arg == 2);

    ret = ABT_xstream_self_rank(&rank);
    ABT_TEST_ERROR(ret, "ABT_xstream_self_rank");
    ret = ABT_thread_self(&self);
    ABT_TEST_ERROR(ret, "ABT_thread_self");
    ret = ABT_thread_get_id(self, &id);
    ABT_TEST_ERROR(ret, "ABT_thread_get_id");

    ABT_test_printf(1, "[U%lu:E%u]: Good-bye, world!\n", id, rank);
}
Ejemplo n.º 7
0
void thread_recv_func(void *arg)
{
    ABT_thread ult_self__;
    ABT_thread_self(&ult_self__);
    size_t my_id = (size_t) arg;
    if (verbose)
        printf("[rank %d, TH%lu]: receive\n", rank, my_id);

    int i, j;
    for (i = 0; i < num_loop; i++) {
        for (j = 1; j < size; j++) {
            int source = (rank + size - j) % size;
            if (verbose)
                printf("[rank %d, TH%lu]: MPI_Recv from %d\n", rank, my_id, source);
            MPI_Recv(recv_buf, buf_size, MPI_INT, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            sum += recv_buf[0];
        }
    }
}
Ejemplo n.º 8
0
void thread_send_func(void *arg)
{
    ABT_thread ult_self__;
    ABT_thread_self(&ult_self__);
    size_t my_id = (size_t) arg;
    if (verbose)
        printf("[rank %d, TH%lu]: send\n", rank, my_id);

    int i, j;
    for (i = 0; i < num_loop; i++) {
        for (j = 1; j < size; j++) {
            int dest = (rank + j) % size;
            send_buf[0] = rank;
            if (verbose)
                printf("[rank %d, TH%lu]: MPI_Send to %d\n", rank, my_id, dest);
            MPI_Send(send_buf, buf_size, MPI_INT, dest, 0, MPI_COMM_WORLD);
        }
    }

}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
/* Create a work-stealing scheduler and push it to the pool */
static void thread_add_sched(void *arg)
{
    int idx = (int)(intptr_t)arg;
    int i;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_pool *my_pools;
    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);
    my_pools = (ABT_pool *)malloc(sizeof(ABT_pool) * max_xstreams);
    for (i = 0; i < max_xstreams; i++) {
        my_pools[i] = g_pools[(idx + i) % max_xstreams];
    }
    ABT_sched_create(&sched_def, max_xstreams, my_pools, config, &sched);

    /* Create a ULT for the new scheduler */
    ABT_thread_create(my_pools[0], thread_work, arg, ABT_THREAD_ATTR_NULL,
                      NULL);

    /* 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_thread_release(cur_thread);
    ABT_sched_config_free(&config);
    free(my_pools);

    t_start = ABT_get_wtime();
    while (1) {
        ABT_thread_yield();

        ABT_pool_get_total_size(cur_pool, &size);
        if (size == 0) {
            ABT_sched_free(&sched);
            break;
        }

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

static void thread_work(void *arg)
{
    int idx = (int)(intptr_t)arg;
    int i;
    ABT_thread cur_thread;
    ABT_pool cur_pool;
    ABT_thread *threads;
    int num_threads;
    double t_start, t_end;

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

    t_start = ABT_get_wtime();
    while (1) {
        num_threads = 2;
        threads = (ABT_thread *)malloc(sizeof(ABT_thread) * num_threads);
        for (i = 0; i < num_threads; i++) {
            ABT_thread_create(cur_pool, thread_hello, NULL,
                              ABT_THREAD_ATTR_NULL, &threads[i]);
        }
        for (i = 0; i < num_threads; i++) {
            ABT_thread_free(&threads[i]);
        }
        free(threads);

        if (g_signal[idx]) {
            ABT_xstream xstream;
            ABT_xstream_self(&xstream);
            ABT_xstream_cancel(xstream);
            g_signal[idx] = 0;
            break;
        }

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

static void test_printf(const char *format, ...)
{
#if 0
    va_start(list, format);
    vprintf(format, list);
    va_end(list);
    fflush(stdout);
#endif
}