Skip to content
Snippets Groups Projects
dispatch.c 98.1 KiB
Newer Older
}

extern void *
get_chunk_with_envelope(struct dispatch_context *dc, struct futhark_context *fc, int thickness,
baptiste.coudray's avatar
baptiste.coudray committed
                        void *f(struct futhark_context *, const void *, ...)) {
    envelope_t *outer_envelope = get_outer_envelope(dc, fc, thickness);
baptiste.coudray's avatar
baptiste.coudray committed
    void *result = NULL;
baptiste.coudray's avatar
baptiste.coudray committed
    switch (dc->n_dimensions) {
        case 1:
baptiste.coudray's avatar
baptiste.coudray committed
            result = get_chunk_with_envelope_1d(dc, fc, outer_envelope,
                                                (void *(*)(struct futhark_context *, const void *, int64_t)) f);
baptiste.coudray's avatar
baptiste.coudray committed
            break;
baptiste.coudray's avatar
baptiste.coudray committed
        case 2:
baptiste.coudray's avatar
baptiste.coudray committed
            result = get_chunk_with_envelope_2d(dc, fc, outer_envelope,
                                                (void *(*)(struct futhark_context *, const void *, int64_t,
                                                           int64_t)) f);
baptiste.coudray's avatar
baptiste.coudray committed
            break;
baptiste.coudray's avatar
baptiste.coudray committed
        case 3:
baptiste.coudray's avatar
baptiste.coudray committed
            result = get_chunk_with_envelope_3d(dc, fc, outer_envelope,
                                                (void *(*)(struct futhark_context *, const void *, int64_t, int64_t,
                                                           int64_t)) f);
    envelope_free(outer_envelope);
baptiste.coudray's avatar
baptiste.coudray committed
    return result;
static void chunk_data_to_data(struct dispatch_context *dc, void *chunk_data, void *data, int rank) {
    int y = dc->chunks_info[rank].y;
    int x = dc->chunks_info[rank].x;
    int z = dc->chunks_info[rank].z;
    uint8_t *data8 = (uint8_t *) data;
    uint8_t *chunk_data8 = (uint8_t *) chunk_data;

    for (int i = 0; i < dc->chunks_info[rank].dimensions[0]; ++i) {
baptiste.coudray's avatar
baptiste.coudray committed
        for (int j = 0; j < dc->chunks_info[rank].dimensions[1]; ++j) {
            for (int k = 0; k < dc->chunks_info[rank].dimensions[2]; ++k) {
                uint8_t *src = chunk_data8 + (INDEX_3D_TO_1D(i, j, k, dc->chunks_info[rank].dimensions[1],
                                                             dc->chunks_info[rank].dimensions[2]) * dc->type);
                uint8_t *dst = data8
                               + (INDEX_3D_TO_1D(y + i, x + j, z + k,
                                                 dc->data_dimensions[1], dc->data_dimensions[2])
                                  * dc->type);
                memcpy(dst, src, (size_t) dc->type);
            }
baptiste.coudray's avatar
baptiste.coudray committed
extern void *get_data(struct dispatch_context *dc) {
    void *data = NULL;
    if (dc->my_rank == ROOT_RANK) {
baptiste.coudray's avatar
baptiste.coudray committed
        data = calloc(dc->count, (size_t) dc->type);
        chunk_data_to_data(dc, dc->chunk_info->data, data, dc->my_rank);
        for (int i = 0; i < dc->world_size; ++i) {
            if (i != dc->my_rank) {
baptiste.coudray's avatar
baptiste.coudray committed
                chunk_info_allocate_data(&dc->chunks_info[i], dc->type);
baptiste.coudray's avatar
baptiste.coudray committed
                MPI_Recv(dc->chunks_info[i].data, (int) dc->chunks_info[i].count, dc->datatype, i, CHUNK_DATA_TAG,
                         MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                chunk_data_to_data(dc, dc->chunks_info[i].data, data, i);
baptiste.coudray's avatar
baptiste.coudray committed
                chunk_info_free(&dc->chunks_info[i]);
baptiste.coudray's avatar
baptiste.coudray committed
        MPI_Send(dc->chunk_info->data, (int) dc->chunk_info->count, dc->datatype, ROOT_RANK, CHUNK_DATA_TAG,
baptiste.coudray's avatar
baptiste.coudray committed
extern chunk_info_t get_chunk_info(struct dispatch_context *dc) {
    return *dc->chunk_info;
}

baptiste.coudray's avatar
baptiste.coudray committed
extern void dispatch_context_free(struct dispatch_context *dc) {
baptiste.coudray's avatar
baptiste.coudray committed
    chunk_info_free(dc->chunk_info);
    free(dc->chunks_info);
baptiste.coudray's avatar
baptiste.coudray committed
    MPI_Comm_free(&dc->communicators[3]);
    MPI_Comm_free(&dc->communicators[2]);
    MPI_Comm_free(&dc->communicators[1]);
    MPI_Comm_free(&dc->communicators[0]);
baptiste.coudray's avatar
baptiste.coudray committed
    free(dc);
baptiste.coudray's avatar
baptiste.coudray committed
static void side_envelope_free(side_envelope_t *side_envelope) {
    for (int i = 0; i < NB_CHUNKS; ++i) {
        chunk_info_free(&side_envelope->chunks[i]);
    }
}

baptiste.coudray's avatar
baptiste.coudray committed
extern void envelope_free(envelope_t *envelope) {
baptiste.coudray's avatar
baptiste.coudray committed
    for (int i = 0; i < NB_SIDES; ++i) {
        side_envelope_free(&envelope->sides[i]);
    }