Skip to content
Snippets Groups Projects
main.c 3.78 KiB
Newer Older
/**
 * Author: Baptiste Coudray
 * School: HEPIA
 * Class: ITI-3
 * Year: 2020-2021
#include <stddef.h>
baptiste.coudray's avatar
baptiste.coudray committed
#include "lbm.h"
baptiste.coudray's avatar
baptiste.coudray committed
#define N_MEASURES 15

#if defined(FUTHARK_BACKEND_cuda) || defined(FUTHARK_BACKEND_opencl)
baptiste.coudray's avatar
baptiste.coudray committed
#define N_ITERATIONS 100
#else
#define N_ITERATIONS 50
#endif

baptiste.coudray's avatar
baptiste.coudray committed
#define NB_VALUES 27
baptiste.coudray's avatar
baptiste.coudray committed
#define ROOT_RANK 0
baptiste.coudray's avatar
baptiste.coudray committed

typedef struct lbm_values {
    float values[NB_VALUES];
} lbm_values_t;

void init_chunk_lbm(chunk_info_t *ci) {
    lbm_values_t *data32 = ci->data;
baptiste.coudray's avatar
baptiste.coudray committed
    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());
baptiste.coudray's avatar
baptiste.coudray committed
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);
}
baptiste.coudray's avatar
baptiste.coudray committed
double compute_next_lbm(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) {
baptiste.coudray's avatar
baptiste.coudray committed
    double start = MPI_Wtime();
baptiste.coudray's avatar
baptiste.coudray committed
    struct futhark_f32_4d *fut_chunk_with_envelope = get_chunk_with_envelope(dc, fc, 1, convert_chunk_with_envelope);
baptiste.coudray's avatar
baptiste.coudray committed
    struct futhark_f32_4d *fut_next_chunk_lbm;
baptiste.coudray's avatar
baptiste.coudray committed
    for (int i = 0; i < N_ITERATIONS; ++i) {
        futhark_entry_next_chunk_lbm(fc, &fut_next_chunk_lbm, fut_chunk_with_envelope);
        futhark_context_sync(fc);
baptiste.coudray's avatar
baptiste.coudray committed
        if (i + 1 < N_ITERATIONS) {
            futhark_free_f32_4d(fc, fut_next_chunk_lbm);
        }
baptiste.coudray's avatar
baptiste.coudray committed
    }
baptiste.coudray's avatar
baptiste.coudray committed
    futhark_values_f32_4d(fc, fut_next_chunk_lbm, ci->data);
baptiste.coudray's avatar
baptiste.coudray committed
    futhark_free_f32_4d(fc, fut_next_chunk_lbm);
baptiste.coudray's avatar
baptiste.coudray committed
    futhark_free_f32_4d(fc, fut_chunk_with_envelope);
baptiste.coudray's avatar
baptiste.coudray committed
    double finish = MPI_Wtime();
baptiste.coudray's avatar
baptiste.coudray committed
    return finish - start;
    if (argc < 5) {
baptiste.coudray's avatar
baptiste.coudray committed
        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();
baptiste.coudray's avatar
baptiste.coudray committed
    int nb_devices = atoi(argv[1]);
#if defined(FUTHARK_BACKEND_cuda) || defined(FUTHARK_BACKEND_opencl)
baptiste.coudray's avatar
baptiste.coudray committed
#if defined(FUTHARK_BACKEND_opencl)
baptiste.coudray's avatar
baptiste.coudray committed
    futhark_context_config_list_devices(fut_config);
#endif
    char device[4] = {0};
    snprintf(device, sizeof(device), "#%d", my_rank % nb_devices);
baptiste.coudray's avatar
baptiste.coudray committed
    futhark_context_config_set_device(fut_config, "AMD");
baptiste.coudray's avatar
baptiste.coudray committed
#endif
    struct futhark_context *fut_context = futhark_context_new(fut_config);

baptiste.coudray's avatar
baptiste.coudray committed
    int lbm_dimensions[3] = {atoi(argv[2]), atoi(argv[3]), atoi(argv[4])};
    // https://stackoverflow.com/a/33624425
    int count = 1;
baptiste.coudray's avatar
baptiste.coudray committed
    int block_lengths[] = {NB_VALUES};
    MPI_Aint displacements[] = {offsetof(struct lbm_values, values)};
    MPI_Datatype types[] = {MPI_FLOAT};
    MPI_Datatype tmp_type, lbm_type;
    MPI_Aint lb, extent;

baptiste.coudray's avatar
baptiste.coudray committed
    MPI_Type_create_struct(count, block_lengths, displacements, types, &tmp_type);
    MPI_Type_get_extent(tmp_type, &lb, &extent);
baptiste.coudray's avatar
baptiste.coudray committed
    MPI_Type_create_resized(tmp_type, lb, extent, &lbm_type);
    MPI_Type_commit(&lbm_type);
baptiste.coudray's avatar
baptiste.coudray committed
    struct dispatch_context *disp_context = dispatch_context_new(lbm_dimensions, lbm_type, 3);
    chunk_info_t ci = get_chunk_info(disp_context);
    init_chunk_lbm(&ci);

baptiste.coudray's avatar
baptiste.coudray committed
    for (int i = 0; i < N_MEASURES; ++i) {
baptiste.coudray's avatar
baptiste.coudray committed
        double time = compute_next_lbm(disp_context, fut_context, &ci);
baptiste.coudray's avatar
baptiste.coudray committed
        if (my_rank == ROOT_RANK) {
baptiste.coudray's avatar
baptiste.coudray committed
            printf("%d;%d;%d;%f\n", world_size, nb_devices, lbm_dimensions[0], time);
    }

    dispatch_context_free(disp_context);
    futhark_context_config_free(fut_config);
    futhark_context_free(fut_context);
    MPI_Type_free(&tmp_type);
baptiste.coudray's avatar
baptiste.coudray committed
    MPI_Type_free(&lbm_type);