Newer
Older
}
extern void *
get_chunk_with_envelope(struct dispatch_context *dc, struct futhark_context *fc, int thickness,
envelope_t *outer_envelope = get_outer_envelope(dc, fc, thickness);
result = get_chunk_with_envelope_1d(dc, fc, outer_envelope,
(void *(*)(struct futhark_context *, const void *, int64_t)) f);
result = get_chunk_with_envelope_2d(dc, fc, outer_envelope,
(void *(*)(struct futhark_context *, const void *, int64_t,
int64_t)) f);
result = get_chunk_with_envelope_3d(dc, fc, outer_envelope,
(void *(*)(struct futhark_context *, const void *, int64_t, int64_t,
int64_t)) f);
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) {
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);
}
extern void *get_data(struct dispatch_context *dc) {
void *data = NULL;
if (dc->my_rank == ROOT_RANK) {
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) {
chunk_info_allocate_data(&dc->chunks_info[i], dc->type);
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);
MPI_Send(dc->chunk_info->data, (int) dc->chunk_info->count, dc->datatype, ROOT_RANK, CHUNK_DATA_TAG,
MPI_COMM_WORLD);
}
return data;
}
extern chunk_info_t get_chunk_info(struct dispatch_context *dc) {
return *dc->chunk_info;
}
extern void dispatch_context_free(struct dispatch_context *dc) {
MPI_Comm_free(&dc->communicators[2]);
MPI_Comm_free(&dc->communicators[1]);
MPI_Comm_free(&dc->communicators[0]);
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]);
}
}
for (int i = 0; i < NB_SIDES; ++i) {
side_envelope_free(&envelope->sides[i]);
}