Newer
Older
/**
* Author: Baptiste Coudray
* School: HEPIA
* Class: ITI-3
* Year 2020-2021
*/
#include <stdio.h>
#include "stdlib.h"
#include <mpi.h>
#include "../futhark_mpi/dispatch.h"
#define INDEX_3D_TO_1D(y, x, z, nb_columns, nb_depths) x + HEIGHT* (y + WIDTH* z)
#define N_MEASURES 15
#define N_ITERATIONS 100
typedef struct lbm_values {
float values[NB_VALUES];
} lbm_values_t;
void init_chunk_lbm(chunk_info_t *ci) {
for (size_t i = 0; i < ci->count; ++i) {
for (int l = 0; l < NB_VALUES; ++l) {
data32[i].values[l] = ((float) rand() / (float) rand());
}
}
}
struct futhark_f32_4d *
convert_chunk_with_envelope(struct futhark_context *fc, const void *data, int64_t dim0, int64_t dim1, int64_t dim2) {
return futhark_new_f32_4d(fc, data, dim0, dim1, dim2, NB_VALUES);
}
void compute_next_lbm(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) {
struct futhark_f32_4d *fut_chunk_with_envelope = get_chunk_with_envelope(dc, fc, 1, convert_chunk_with_envelope);
struct futhark_f32_4d *fut_next_chunk_lbm;
futhark_entry_next_chunk_lbm(fc, &fut_next_chunk_lbm, fut_chunk_with_envelope);
futhark_context_sync(fc);
futhark_context_sync(fc);
futhark_free_f32_4d(fc, fut_chunk_with_envelope);
futhark_free_f32_4d(fc, fut_next_chunk_lbm);
}
int main(int argc, char *argv[]) {
if (argc < 4) {
printf("usage: mpirun -n <nb_proc> %s <nb_devices> <height> <width> <depth>\n", argv[0]);
return EXIT_FAILURE;
}
MPI_Init(&argc, &argv);
int my_rank;
int world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
struct futhark_context_config *fut_config = futhark_context_config_new();
int nb_devices = atoi(argv[1]);
#if defined(FUTHARK_BACKEND_cuda) || defined(FUTHARK_BACKEND_opencl)
#if defined(FUTHARK_BACKEND_opencl)
futhark_context_config_list_devices(fut_config);
#endif
char device[4] = {0};
snprintf(device, sizeof(device), "#%d", my_rank % nb_devices);
futhark_context_config_set_device(fut_config, device);
#endif
struct futhark_context *fut_context = futhark_context_new(fut_config);
int lbm_dimensions[3] = {atoi(argv[2]), atoi(argv[3]), atoi(argv[4])};
// https://stackoverflow.com/a/33624425
int count = 1;
int array_of_blocklengths[] = {NB_VALUES};
MPI_Aint array_of_displacements[] = {offsetof(struct lbm_values, values)};
MPI_Datatype array_of_types[] = {MPI_FLOAT};
MPI_Datatype tmp_type, my_mpi_type;
MPI_Aint lb, extent;
MPI_Type_create_struct(count, array_of_blocklengths, array_of_displacements,
array_of_types, &tmp_type);
MPI_Type_get_extent(tmp_type, &lb, &extent);
MPI_Type_create_resized(tmp_type, lb, extent, &my_mpi_type);
MPI_Type_commit(&my_mpi_type);
struct dispatch_context *disp_context = dispatch_context_new(lbm_dimensions, my_mpi_type, 3);
chunk_info_t ci = get_chunk_info(disp_context);
init_chunk_lbm(&ci);
for (int i = 0; i < N_MEASURES; ++i) {
double start = MPI_Wtime();
for (int j = 0; j < N_ITERATIONS; ++j) {
compute_next_lbm(disp_context, fut_context, &ci);
}
double finish = MPI_Wtime();
if (my_rank == ROOT_RANK) {
printf("%d;%d;%d;%f\n", world_size, nb_devices, lbm_dimensions[0], finish - start);
}
}
dispatch_context_free(disp_context);
futhark_context_config_free(fut_config);
futhark_context_free(fut_context);
MPI_Type_free(&tmp_type);
MPI_Type_free(&my_mpi_type);
return MPI_Finalize();
}