From bb363d3ed66aa6a1fffa3eed660e4d6f7f2bb737 Mon Sep 17 00:00:00 2001 From: "baptiste.coudray" <baptiste.coudray@etu.hesge.ch> Date: Tue, 8 Jun 2021 11:10:20 +0200 Subject: [PATCH] Added function to create futhark outer envelope --- futhark_mpi/CMakeLists.txt | 2 +- futhark_mpi/dispatch.c | 80 ++++++++++++++++++++++++++++++++++- futhark_mpi/dispatch.h | 7 +++ futhark_mpi/envelope.fut | 23 +++++++++- game_of_life/benchmark/main.c | 52 +++++------------------ game_of_life/gol.fut | 5 ++- game_of_life/main.c | 52 +++++------------------ 7 files changed, 133 insertions(+), 88 deletions(-) diff --git a/futhark_mpi/CMakeLists.txt b/futhark_mpi/CMakeLists.txt index 7ffd907..444c380 100644 --- a/futhark_mpi/CMakeLists.txt +++ b/futhark_mpi/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 11) if (CMAKE_BUILD_TYPE MATCHES Debug) set(GCC_COMPILE_FLAGS "-Wall -Wextra -Wconversion -pedantic -fsanitize=address -fsanitize=undefined") elseif (CMAKE_BUILD_TYPE MATCHES Release) - set(GCC_COMPILE_FLAGS "-O2") + set(GCC_COMPILE_FLAGS "-O3") endif () find_package(MPI REQUIRED) diff --git a/futhark_mpi/dispatch.c b/futhark_mpi/dispatch.c index 0cc2396..7b69024 100644 --- a/futhark_mpi/dispatch.c +++ b/futhark_mpi/dispatch.c @@ -187,23 +187,33 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh int thickness_x = min(thickness, dc->chunk_info->dimensions[1]); int dimensions[2] = {1, thickness_x}; +// struct futhark_opaque_envelope_1d_t *fut_inner_envelope; futhark_context_sync(fc); +// futhark_entry_get_envelope_1d(fc, &fut_inner_envelope, fut_chunk_data, thickness_x * dc->type); futhark_entry_get_envelope_1d(fc, &fut_west, &fut_east, fut_chunk_data, dimensions[1] * dc->type); futhark_context_sync(fc); futhark_free_u8_1d(fc, fut_chunk_data); +// futhark_context_sync(fc); +// futhark_free_u8_1d(fc, fut_chunk_data); + envelope_t inner_envelope = (envelope_t) {0}; +// size_t size; +// futhark_store_opaque_envelope_1d_t(fc, fut_inner_envelope, &inner_envelope.futhark_bytes, &size); + // West { int start_x = dc->chunk_info->x; - chunk_info_init(&inner_envelope.west, dc->type, dimensions, 0, start_x, true); + chunk_info_init(&inner_envelope.west, dc->type, dimensions, 0, start_x, false); +// inner_envelope.west.data = ((uint8_t *) inner_envelope.futhark_bytes) + 0x0F; futhark_values_u8_1d(fc, fut_west, inner_envelope.west.data); } // East { int start_x = dc->chunk_info->x + dc->chunk_info->dimensions[1] - thickness_x; - chunk_info_init(&inner_envelope.east, dc->type, dimensions, 0, start_x, true); + chunk_info_init(&inner_envelope.east, dc->type, dimensions, 0, start_x, false); +// inner_envelope.east.data = ((uint8_t *) inner_envelope.futhark_bytes) + 0x0F + thickness_x * dc->type + 0x0F; futhark_values_u8_1d(fc, fut_east, inner_envelope.east.data); } @@ -230,7 +240,9 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh int thickness_y = min(thickness, dc->chunk_info->dimensions[0]); int thickness_x = min(thickness, dc->chunk_info->dimensions[1]); +// struct futhark_opaque_envelope_2d_t *fut_inner_envelope; futhark_context_sync(fc); +// futhark_entry_get_envelope_2d(fc, &fut_inner_envelope, fut_chunk_data, thickness_y, thickness_x * dc->type); futhark_entry_get_envelope_2d(fc, &fut_north_west, &fut_north, &fut_north_east, &fut_west, &fut_east, &fut_south_west, &fut_south, &fut_south_east, fut_chunk_data, thickness_y, thickness_x * dc->type); @@ -238,6 +250,8 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh futhark_free_u8_2d(fc, fut_chunk_data); envelope_t inner_envelope = (envelope_t) {0}; +// size_t size; +// futhark_store_opaque_envelope_2d_t(fc, fut_inner_envelope, &inner_envelope.futhark_bytes, &size); // North-West { @@ -245,6 +259,7 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh int start_y = dc->chunk_info->y; int start_x = dc->chunk_info->x; chunk_info_init(&inner_envelope.north_west, dc->type, dimensions, start_y, start_x, true); +// inner_envelope.north_west.data = ((uint8_t *) inner_envelope.futhark_bytes) + 0x0F; futhark_values_u8_2d(fc, fut_north_west, inner_envelope.north_west.data); } @@ -323,6 +338,60 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh return inner_envelope; } +static void futhark_outer_envelope_1d_new(struct futhark_context *fc, envelope_t *outer_envelope, + void *f(struct futhark_context *, uint8_t *, int64_t), + void *futhark_envelope[2]) { + futhark_envelope[0] = f(fc, outer_envelope->west.data, outer_envelope->west.dimensions[1]); + futhark_envelope[1] = f(fc, outer_envelope->east.data, outer_envelope->east.dimensions[1]); +} + +static void futhark_outer_envelope_2d_new(struct futhark_context *fc, envelope_t *outer_envelope, + void *f(struct futhark_context *, uint8_t *, int64_t, int64_t), + void *futhark_envelope[2]) { + futhark_envelope[0] = f(fc, outer_envelope->north_west.data, outer_envelope->north_west.dimensions[0], + outer_envelope->north_west.dimensions[1]); + + futhark_envelope[1] = f(fc, outer_envelope->north.data, outer_envelope->north.dimensions[0], + outer_envelope->north.dimensions[1]); + + futhark_envelope[2] = f(fc, outer_envelope->north_east.data, outer_envelope->north_east.dimensions[0], + outer_envelope->north_east.dimensions[1]); + + futhark_envelope[3] = f(fc, outer_envelope->west.data, outer_envelope->west.dimensions[0], + outer_envelope->west.dimensions[1]); + + futhark_envelope[4] = f(fc, outer_envelope->east.data, outer_envelope->east.dimensions[0], + outer_envelope->east.dimensions[1]); + + futhark_envelope[5] = f(fc, outer_envelope->south_west.data, outer_envelope->south_west.dimensions[0], + outer_envelope->south_west.dimensions[1]); + + futhark_envelope[6] = f(fc, outer_envelope->south.data, outer_envelope->south.dimensions[0], + outer_envelope->south.dimensions[1]); + + futhark_envelope[7] = f(fc, outer_envelope->south_east.data, outer_envelope->south_east.dimensions[0], + outer_envelope->south_east.dimensions[1]); +} + +extern void futhark_outer_envelope_new(struct dispatch_context *dc, struct futhark_context *fc, + envelope_t *outer_envelope, void *f(struct futhark_context *, uint8_t *, ...), + void *futhark_envelope[]) { + switch (dc->n_dimensions) { + case 1: + futhark_outer_envelope_1d_new(fc, outer_envelope, + (void *(*)(struct futhark_context *, uint8_t *, int64_t)) f, + futhark_envelope); + break; + case 2: + futhark_outer_envelope_2d_new(fc, outer_envelope, + (void *(*)(struct futhark_context *, uint8_t *, int64_t, int64_t)) f, + futhark_envelope); + break; + default: + break; + } +} + static envelope_t get_outer_envelope_1d(struct dispatch_context *dc, int thickness, envelope_t *inner_envelope) { int coordinate_x = dc->coordinates[1]; MPI_Request requests[4]; @@ -636,6 +705,13 @@ extern void dispatch_context_free(struct dispatch_context *dc) { MPI_Comm_free(&dc->communicators[0]); } +extern void futhark_outer_envelope_free(struct dispatch_context *dc, struct futhark_context *fc, + int f(struct futhark_context *, void *), void *foe[]) { + for (int i = 0; i < (dc->n_dimensions * dc->n_dimensions) * 2; ++i) { + f(fc, foe[i]); + } +} + extern void envelope_free(envelope_t *envelope) { chunk_info_free(&envelope->north); chunk_info_free(&envelope->north_east); diff --git a/futhark_mpi/dispatch.h b/futhark_mpi/dispatch.h index 3e0c848..df9df9c 100644 --- a/futhark_mpi/dispatch.h +++ b/futhark_mpi/dispatch.h @@ -25,12 +25,19 @@ extern envelope_t get_inner_envelope(struct dispatch_context *dc, struct futhark extern envelope_t get_outer_envelope(struct dispatch_context *dc, struct futhark_context *fc, int thickness); +extern void futhark_outer_envelope_new(struct dispatch_context *dc, struct futhark_context *fc, + envelope_t *outer_envelope, void *f(struct futhark_context *, uint8_t *, ...), + void *futhark_envelope[]); + extern chunk_info_t get_chunk_info(struct dispatch_context *dc); extern void *get_data(struct dispatch_context *dc); extern void dispatch_context_free(struct dispatch_context *dc); +extern void futhark_outer_envelope_free(struct dispatch_context *dc, struct futhark_context *fc, + int f(struct futhark_context *, void *), void *foe[]); + extern void envelope_free(envelope_t *envelope); #endif //_DISPATCH_H_ diff --git a/futhark_mpi/envelope.fut b/futhark_mpi/envelope.fut index be9c774..e132ee4 100644 --- a/futhark_mpi/envelope.fut +++ b/futhark_mpi/envelope.fut @@ -2,7 +2,7 @@ -- west: [n]u8, -- east: [n]u8 -- } --- + -- type envelope_2d_t [n][m][ty][tx] = { -- north_west: [ty][tx]u8, -- north: [ty][m]u8, @@ -19,6 +19,11 @@ entry get_envelope_1d [n] (xs: [n]u8) (thickness: i64) : ([]u8, []u8) = let east = xs[n - thickness:] :> [thickness]u8 in (west, east) +-- entry get_envelope_1d [n] (xs: [n]u8) (thickness: i64) : envelope_1d_t [thickness] = +-- let west = xs[0:thickness] :> [thickness]u8 +-- let east = xs[n - thickness:] :> [thickness]u8 +-- in {west, east} + entry get_envelope_2d [n][m] (matrix: [n][m]u8) (thickness_y: i64) (thickness_x: i64): ([][]u8, [][]u8, [][]u8, [][]u8, [][]u8, [][]u8, [][]u8, [][]u8) = let north = matrix[0:thickness_y] :> [thickness_y][m]u8 @@ -34,3 +39,19 @@ entry get_envelope_2d [n][m] (matrix: [n][m]u8) (thickness_y: i64) (thickness_x: let west = matrix[:,0:thickness_x] :> [n][thickness_x]u8 in (north_west, north, north_east, west, east, south_west, south, south_east) + +-- entry get_envelope_2d [n][m] (matrix: [n][m]u8) (thickness_y: i64) (thickness_x: i64): envelope_2d_t [n][m][thickness_y][thickness_x] = +-- let north = matrix[0:thickness_y] :> [thickness_y][m]u8 +-- +-- let north_west = matrix[0:thickness_y,0:thickness_x] :> [thickness_y][thickness_x]u8 +-- let north_east = matrix[0:thickness_y,m - thickness_x:m] :> [thickness_y][thickness_x]u8 +-- +-- let south = matrix[n - thickness_y:] :> [thickness_y][m]u8 +-- +-- let south_east = matrix[n - thickness_y:n,m - thickness_x:m] :> [thickness_y][thickness_x]u8 +-- let south_west = matrix[n - thickness_y:n,0:thickness_x] :> [thickness_y][thickness_x]u8 +-- +-- let east = matrix[:,m - (thickness_x):] :> [n][thickness_x]u8 +-- let west = matrix[:,0:thickness_x] :> [n][thickness_x]u8 +-- +-- in {north_west, north, north_east, west, east, south_west, south, south_east} diff --git a/game_of_life/benchmark/main.c b/game_of_life/benchmark/main.c index 9c7c7fe..140888d 100644 --- a/game_of_life/benchmark/main.c +++ b/game_of_life/benchmark/main.c @@ -31,45 +31,19 @@ void init_chunk_board(chunk_info_t *ci) { void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) { envelope_t outer_envelope = get_outer_envelope(dc, fc, 1); - struct futhark_i8_2d *fut_north = futhark_new_i8_2d(fc, outer_envelope.north.data, - outer_envelope.north.dimensions[0], - outer_envelope.north.dimensions[1]); - - struct futhark_i8_2d *fut_north_east = futhark_new_i8_2d(fc, outer_envelope.north_east.data, - outer_envelope.north_east.dimensions[0], - outer_envelope.north_east.dimensions[1]); - - struct futhark_i8_2d *fut_east = futhark_new_i8_2d(fc, outer_envelope.east.data, - outer_envelope.east.dimensions[0], - outer_envelope.east.dimensions[1]); - - struct futhark_i8_2d *fut_south_east = futhark_new_i8_2d(fc, outer_envelope.south_east.data, - outer_envelope.south_east.dimensions[0], - outer_envelope.south_east.dimensions[1]); - - struct futhark_i8_2d *fut_south = futhark_new_i8_2d(fc, outer_envelope.south.data, - outer_envelope.south.dimensions[0], - outer_envelope.south.dimensions[1]); - - struct futhark_i8_2d *fut_south_west = futhark_new_i8_2d(fc, outer_envelope.south_west.data, - outer_envelope.south_west.dimensions[0], - outer_envelope.south_west.dimensions[1]); - - struct futhark_i8_2d *fut_west = futhark_new_i8_2d(fc, outer_envelope.west.data, - outer_envelope.west.dimensions[0], - outer_envelope.west.dimensions[1]); - - struct futhark_i8_2d *fut_north_west = futhark_new_i8_2d(fc, outer_envelope.north_west.data, - outer_envelope.north_west.dimensions[0], - outer_envelope.north_west.dimensions[1]); + struct futhark_i8_2d *fut_outer_envelope[8] = {0}; + futhark_outer_envelope_new(dc, fc, &outer_envelope, + (void *(*)(struct futhark_context *, uint8_t *, ...)) futhark_new_i8_2d, + (void **) fut_outer_envelope); struct futhark_i8_2d *fut_chunk_board = futhark_new_i8_2d(fc, ci->data, ci->dimensions[0], ci->dimensions[1]); struct futhark_i8_2d *fut_next_chunk_board; futhark_context_sync(fc); - futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, fut_north_west, fut_north, - fut_north_east, fut_west, fut_east, fut_south_west, fut_south, - fut_south_east); + futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, + fut_outer_envelope[0], fut_outer_envelope[1], fut_outer_envelope[2], + fut_outer_envelope[3], fut_outer_envelope[4], + fut_outer_envelope[5], fut_outer_envelope[6], fut_outer_envelope[7]); futhark_context_sync(fc); futhark_values_i8_2d(fc, fut_next_chunk_board, ci->data); @@ -77,14 +51,8 @@ void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_contex futhark_free_i8_2d(fc, fut_next_chunk_board); futhark_free_i8_2d(fc, fut_chunk_board); - futhark_free_i8_2d(fc, fut_north_west); - futhark_free_i8_2d(fc, fut_north); - futhark_free_i8_2d(fc, fut_north_east); - futhark_free_i8_2d(fc, fut_west); - futhark_free_i8_2d(fc, fut_east); - futhark_free_i8_2d(fc, fut_south_west); - futhark_free_i8_2d(fc, fut_south); - futhark_free_i8_2d(fc, fut_south_east); + futhark_outer_envelope_free(dc, fc, (int (*)(struct futhark_context *, void *)) futhark_free_i8_2d, + (void **) fut_outer_envelope); envelope_free(&outer_envelope); } diff --git a/game_of_life/gol.fut b/game_of_life/gol.fut index 3a1ba4b..224c3c7 100644 --- a/game_of_life/gol.fut +++ b/game_of_life/gol.fut @@ -1,5 +1,8 @@ module env = import "../futhark_mpi/envelope" +-- type envelope_1d_t [n] = env.envelope_1d_t [n] +-- type envelope_2d_t [n][m][ty][tx] = env.envelope_2d_t [n][m][ty][tx] + entry get_envelope_1d = env.get_envelope_1d entry get_envelope_2d = env.get_envelope_2d @@ -46,7 +49,7 @@ let augment_board [n][m] (chunk_board:[n][m]i8) entry next_chunk_board [n][m] (chunk_board :[n][m]i8) (nw:[1][1]i8) (no:[1][m]i8) (ne:[1][1]i8) (we:[n][1]i8) (ea:[n][1]i8) - (sw:[1][1]i8) (so:[1][m]i8) (se:[1][1]i8) :[][]i8 = + (sw:[1][1]i8) (so:[1][m]i8) (se:[1][1]i8) :[n][m]i8 = let augmented_board = augment_board chunk_board nw no ne we ea sw so se let neighbours = count_neighbours augmented_board let next_board = map2 (\augmented_board_r neighbours_r -> diff --git a/game_of_life/main.c b/game_of_life/main.c index e58f97b..f393772 100644 --- a/game_of_life/main.c +++ b/game_of_life/main.c @@ -31,44 +31,19 @@ void init_chunk_board(chunk_info_t *ci) { void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_context *fc, chunk_info_t *ci) { envelope_t outer_envelope = get_outer_envelope(dc, fc, 1); - struct futhark_i8_2d *fut_north = futhark_new_i8_2d(fc, outer_envelope.north.data, - outer_envelope.north.dimensions[0], - outer_envelope.north.dimensions[1]); - - struct futhark_i8_2d *fut_north_east = futhark_new_i8_2d(fc, outer_envelope.north_east.data, - outer_envelope.north_east.dimensions[0], - outer_envelope.north_east.dimensions[1]); - - struct futhark_i8_2d *fut_east = futhark_new_i8_2d(fc, outer_envelope.east.data, - outer_envelope.east.dimensions[0], - outer_envelope.east.dimensions[1]); - - struct futhark_i8_2d *fut_south_east = futhark_new_i8_2d(fc, outer_envelope.south_east.data, - outer_envelope.south_east.dimensions[0], - outer_envelope.south_east.dimensions[1]); - - struct futhark_i8_2d *fut_south = futhark_new_i8_2d(fc, outer_envelope.south.data, - outer_envelope.south.dimensions[0], - outer_envelope.south.dimensions[1]); - - struct futhark_i8_2d *fut_south_west = futhark_new_i8_2d(fc, outer_envelope.south_west.data, - outer_envelope.south_west.dimensions[0], - outer_envelope.south_west.dimensions[1]); - - struct futhark_i8_2d *fut_west = futhark_new_i8_2d(fc, outer_envelope.west.data, - outer_envelope.west.dimensions[0], - outer_envelope.west.dimensions[1]); - - struct futhark_i8_2d *fut_north_west = futhark_new_i8_2d(fc, outer_envelope.north_west.data, - outer_envelope.north_west.dimensions[0], - outer_envelope.north_west.dimensions[1]); + struct futhark_i8_2d *fut_outer_envelope[8] = {0}; + futhark_outer_envelope_new(dc, fc, &outer_envelope, + (void *(*)(struct futhark_context *, uint8_t *, ...)) futhark_new_i8_2d, + (void **) fut_outer_envelope); struct futhark_i8_2d *fut_chunk_board = futhark_new_i8_2d(fc, ci->data, ci->dimensions[0], ci->dimensions[1]); struct futhark_i8_2d *fut_next_chunk_board; futhark_context_sync(fc); - futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, fut_north_west, fut_north, - fut_north_east, fut_west, fut_east, fut_south_west, fut_south, fut_south_east); + futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, + fut_outer_envelope[0], fut_outer_envelope[1], fut_outer_envelope[2], + fut_outer_envelope[3], fut_outer_envelope[4], + fut_outer_envelope[5], fut_outer_envelope[6], fut_outer_envelope[7]); futhark_context_sync(fc); futhark_values_i8_2d(fc, fut_next_chunk_board, ci->data); @@ -76,16 +51,11 @@ void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_contex futhark_free_i8_2d(fc, fut_next_chunk_board); futhark_free_i8_2d(fc, fut_chunk_board); - futhark_free_i8_2d(fc, fut_north_west); - futhark_free_i8_2d(fc, fut_north); - futhark_free_i8_2d(fc, fut_north_east); - futhark_free_i8_2d(fc, fut_west); - futhark_free_i8_2d(fc, fut_east); - futhark_free_i8_2d(fc, fut_south_west); - futhark_free_i8_2d(fc, fut_south); - futhark_free_i8_2d(fc, fut_south_east); + futhark_outer_envelope_free(dc, fc, (int (*)(struct futhark_context *, void *)) futhark_free_i8_2d, + (void **) fut_outer_envelope); envelope_free(&outer_envelope); } + int main(int argc, char *argv[]) { if (argc < 3) { printf("usage: mpirun -n <nb_proc> %s <height> <width>\n", argv[0]); -- GitLab