Skip to content
Snippets Groups Projects
Verified Commit f5475709 authored by baptiste.coudray's avatar baptiste.coudray
Browse files

Added get_subdomain, added seq version

parent bb363d3e
No related branches found
No related tags found
No related merge requests found
...@@ -21,6 +21,13 @@ add_custom_command( ...@@ -21,6 +21,13 @@ add_custom_command(
) )
add_custom_target(futhark_opencl DEPENDS envelope.h envelope.c) add_custom_target(futhark_opencl DEPENDS envelope.h envelope.c)
add_executable(futhark_mpi_tests tests/main.c dispatch.h dispatch.c envelope.h envelope.c) add_executable(futhark_mpi_tests tests/main.c chunk_info.h chunk_info.c dispatch.h dispatch.c envelope.h envelope.c)
add_dependencies(futhark_mpi_tests futhark_opencl) add_dependencies(futhark_mpi_tests futhark_opencl)
target_link_libraries(futhark_mpi_tests m ${MPI_C_LIBRARIES} "-framework OpenCL")
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
target_link_libraries(futhark_mpi_tests m ${MPI_C_LIBRARIES} "-framework OpenCL")
endif ()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(futhark_mpi_tests OpenCL m ${MPI_C_LIBRARIES})
endif ()
...@@ -47,6 +47,7 @@ struct dispatch_context { ...@@ -47,6 +47,7 @@ struct dispatch_context {
chunk_info_t *chunk_info; chunk_info_t *chunk_info;
int type; int type;
chunk_info_t *chunks_info; chunk_info_t *chunks_info;
chunk_info_t active_domain;
}; };
static void get_world_size(struct dispatch_context *dc) { static void get_world_size(struct dispatch_context *dc) {
...@@ -165,11 +166,12 @@ extern struct dispatch_context *dispatch_context_new(const int *dimensions, MPI_ ...@@ -165,11 +166,12 @@ extern struct dispatch_context *dispatch_context_new(const int *dimensions, MPI_
MPI_Abort(MPI_COMM_WORLD, 1); MPI_Abort(MPI_COMM_WORLD, 1);
break; break;
} }
dc->count = (size_t) dc->data_dimensions[0] * (size_t) dc->data_dimensions[1];
find_network_dimensions(dc); find_network_dimensions(dc);
create_network_communicators(dc); create_network_communicators(dc);
divide_data(dc); divide_data(dc);
dc->count = (size_t) dc->data_dimensions[0] * (size_t) dc->data_dimensions[1]; dc->active_domain = *dc->chunk_info;
return dc; return dc;
} }
...@@ -187,25 +189,17 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh ...@@ -187,25 +189,17 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh
int thickness_x = min(thickness, dc->chunk_info->dimensions[1]); int thickness_x = min(thickness, dc->chunk_info->dimensions[1]);
int dimensions[2] = {1, thickness_x}; int dimensions[2] = {1, thickness_x};
// struct futhark_opaque_envelope_1d_t *fut_inner_envelope;
futhark_context_sync(fc); 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_entry_get_envelope_1d(fc, &fut_west, &fut_east, fut_chunk_data, dimensions[1] * dc->type);
futhark_context_sync(fc); futhark_context_sync(fc);
futhark_free_u8_1d(fc, fut_chunk_data); 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}; 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 // West
{ {
int start_x = dc->chunk_info->x; int start_x = dc->chunk_info->x;
chunk_info_init(&inner_envelope.west, dc->type, dimensions, 0, start_x, false); 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); futhark_values_u8_1d(fc, fut_west, inner_envelope.west.data);
} }
...@@ -213,7 +207,6 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh ...@@ -213,7 +207,6 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh
{ {
int start_x = dc->chunk_info->x + dc->chunk_info->dimensions[1] - thickness_x; 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, false); 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); futhark_values_u8_1d(fc, fut_east, inner_envelope.east.data);
} }
...@@ -224,9 +217,9 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh ...@@ -224,9 +217,9 @@ static envelope_t get_inner_envelope_1d(struct dispatch_context *dc, struct futh
} }
static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futhark_context *fc, int thickness) { static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futhark_context *fc, int thickness) {
struct futhark_u8_2d *fut_chunk_data = futhark_new_u8_2d(fc, dc->chunk_info->data, struct futhark_u8_2d *fut_chunk_data = futhark_new_u8_2d(fc, dc->active_domain.data,
dc->chunk_info->dimensions[0], dc->active_domain.dimensions[0],
dc->chunk_info->dimensions[1] * dc->type); dc->active_domain.dimensions[1] * dc->type);
struct futhark_u8_2d *fut_north_west; struct futhark_u8_2d *fut_north_west;
struct futhark_u8_2d *fut_north; struct futhark_u8_2d *fut_north;
...@@ -237,37 +230,33 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh ...@@ -237,37 +230,33 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh
struct futhark_u8_2d *fut_south; struct futhark_u8_2d *fut_south;
struct futhark_u8_2d *fut_south_east; struct futhark_u8_2d *fut_south_east;
int thickness_y = min(thickness, dc->chunk_info->dimensions[0]); int thickness_y = min(thickness, dc->active_domain.dimensions[0]);
int thickness_x = min(thickness, dc->chunk_info->dimensions[1]); int thickness_x = min(thickness, dc->active_domain.dimensions[1]);
// struct futhark_opaque_envelope_2d_t *fut_inner_envelope;
futhark_context_sync(fc); 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_west, &fut_south_west,
futhark_entry_get_envelope_2d(fc, &fut_north_west, &fut_north, &fut_north_east, &fut_west, &fut_east, &fut_south, &fut_south_east,
&fut_south_west, &fut_south, &fut_south_east, fut_chunk_data, thickness_y, &fut_east, &fut_north_east, &fut_north,
thickness_x * dc->type); fut_chunk_data, thickness_y,thickness_x * dc->type);
futhark_context_sync(fc); futhark_context_sync(fc);
futhark_free_u8_2d(fc, fut_chunk_data); futhark_free_u8_2d(fc, fut_chunk_data);
envelope_t inner_envelope = (envelope_t) {0}; 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 // North-West
{ {
int dimensions[2] = {thickness_y, thickness_x}; int dimensions[2] = {thickness_y, thickness_x};
int start_y = dc->chunk_info->y; int start_y = dc->active_domain.y;
int start_x = dc->chunk_info->x; int start_x = dc->active_domain.x;
chunk_info_init(&inner_envelope.north_west, dc->type, dimensions, start_y, start_x, true); 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); futhark_values_u8_2d(fc, fut_north_west, inner_envelope.north_west.data);
} }
// North // North
{ {
int dimensions[2] = {thickness_y, dc->chunk_info->dimensions[1]}; int dimensions[2] = {thickness_y, dc->active_domain.dimensions[1]};
int start_y = dc->chunk_info->y; int start_y = dc->active_domain.y;
int start_x = dc->chunk_info->x; int start_x = dc->active_domain.x;
chunk_info_init(&inner_envelope.north, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.north, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_north, inner_envelope.north.data); futhark_values_u8_2d(fc, fut_north, inner_envelope.north.data);
} }
...@@ -275,17 +264,17 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh ...@@ -275,17 +264,17 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh
// North-East // North-East
{ {
int dimensions[2] = {thickness_y, thickness_x}; int dimensions[2] = {thickness_y, thickness_x};
int start_y = dc->chunk_info->y; int start_y = dc->active_domain.y;
int start_x = dc->chunk_info->x + dc->chunk_info->dimensions[1] - thickness_x; int start_x = dc->active_domain.x + dc->active_domain.dimensions[1] - thickness_x;
chunk_info_init(&inner_envelope.north_east, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.north_east, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_north_east, inner_envelope.north_east.data); futhark_values_u8_2d(fc, fut_north_east, inner_envelope.north_east.data);
} }
// West // West
{ {
int dimensions[2] = {dc->chunk_info->dimensions[0], thickness_x}; int dimensions[2] = {dc->active_domain.dimensions[0], thickness_x};
int start_y = dc->chunk_info->y; int start_y = dc->active_domain.y;
int start_x = dc->chunk_info->x; int start_x = dc->active_domain.x;
chunk_info_init(&inner_envelope.west, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.west, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_west, inner_envelope.west.data); futhark_values_u8_2d(fc, fut_west, inner_envelope.west.data);
} }
...@@ -293,8 +282,8 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh ...@@ -293,8 +282,8 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh
// East // East
{ {
int dimensions[2] = {dc->chunk_info->dimensions[0], thickness_x}; int dimensions[2] = {dc->chunk_info->dimensions[0], thickness_x};
int start_y = dc->chunk_info->y; int start_y = dc->active_domain.y;
int start_x = dc->chunk_info->x + dc->chunk_info->dimensions[1] - thickness_x; int start_x = dc->active_domain.x + dc->active_domain.dimensions[1] - thickness_x;
chunk_info_init(&inner_envelope.east, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.east, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_east, inner_envelope.east.data); futhark_values_u8_2d(fc, fut_east, inner_envelope.east.data);
} }
...@@ -302,17 +291,17 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh ...@@ -302,17 +291,17 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh
// South-West // South-West
{ {
int dimensions[2] = {thickness_y, thickness_x}; int dimensions[2] = {thickness_y, thickness_x};
int start_y = dc->chunk_info->y + dc->chunk_info->dimensions[0] - thickness_y; int start_y = dc->active_domain.y + dc->active_domain.dimensions[0] - thickness_y;
int start_x = dc->chunk_info->x; int start_x = dc->active_domain.x;
chunk_info_init(&inner_envelope.south_west, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.south_west, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_south_west, inner_envelope.south_west.data); futhark_values_u8_2d(fc, fut_south_west, inner_envelope.south_west.data);
} }
// South // South
{ {
int dimensions[2] = {thickness_y, dc->chunk_info->dimensions[1]}; int dimensions[2] = {thickness_y, dc->active_domain.dimensions[1]};
int start_y = dc->chunk_info->y + dc->chunk_info->dimensions[0] - thickness_y; int start_y = dc->active_domain.y + dc->active_domain.dimensions[0] - thickness_y;
int start_x = dc->chunk_info->x; int start_x = dc->active_domain.x;
chunk_info_init(&inner_envelope.south, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.south, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_south, inner_envelope.south.data); futhark_values_u8_2d(fc, fut_south, inner_envelope.south.data);
} }
...@@ -320,8 +309,8 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh ...@@ -320,8 +309,8 @@ static envelope_t get_inner_envelope_2d(struct dispatch_context *dc, struct futh
// South-East // South-East
{ {
int dimensions[2] = {thickness_y, thickness_x}; int dimensions[2] = {thickness_y, thickness_x};
int start_y = dc->chunk_info->y + dc->chunk_info->dimensions[0] - thickness_y; int start_y = dc->active_domain.y + dc->active_domain.dimensions[0] - thickness_y;
int start_x = dc->chunk_info->x + dc->chunk_info->dimensions[1] - thickness_x; int start_x = dc->active_domain.x + dc->active_domain.dimensions[1] - thickness_x;
chunk_info_init(&inner_envelope.south_east, dc->type, dimensions, start_y, start_x, true); chunk_info_init(&inner_envelope.south_east, dc->type, dimensions, start_y, start_x, true);
futhark_values_u8_2d(fc, fut_south_east, inner_envelope.south_east.data); futhark_values_u8_2d(fc, fut_south_east, inner_envelope.south_east.data);
} }
...@@ -351,26 +340,26 @@ static void futhark_outer_envelope_2d_new(struct futhark_context *fc, envelope_t ...@@ -351,26 +340,26 @@ static void futhark_outer_envelope_2d_new(struct futhark_context *fc, envelope_t
futhark_envelope[0] = f(fc, outer_envelope->north_west.data, outer_envelope->north_west.dimensions[0], futhark_envelope[0] = f(fc, outer_envelope->north_west.data, outer_envelope->north_west.dimensions[0],
outer_envelope->north_west.dimensions[1]); outer_envelope->north_west.dimensions[1]);
futhark_envelope[1] = f(fc, outer_envelope->north.data, outer_envelope->north.dimensions[0], futhark_envelope[1] = f(fc, outer_envelope->west.data, outer_envelope->west.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]); outer_envelope->west.dimensions[1]);
futhark_envelope[4] = f(fc, outer_envelope->east.data, outer_envelope->east.dimensions[0], futhark_envelope[2] = f(fc, outer_envelope->south_west.data, outer_envelope->south_west.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]); outer_envelope->south_west.dimensions[1]);
futhark_envelope[6] = f(fc, outer_envelope->south.data, outer_envelope->south.dimensions[0], futhark_envelope[3] = f(fc, outer_envelope->south.data, outer_envelope->south.dimensions[0],
outer_envelope->south.dimensions[1]); outer_envelope->south.dimensions[1]);
futhark_envelope[7] = f(fc, outer_envelope->south_east.data, outer_envelope->south_east.dimensions[0], futhark_envelope[4] = f(fc, outer_envelope->south_east.data, outer_envelope->south_east.dimensions[0],
outer_envelope->south_east.dimensions[1]); outer_envelope->south_east.dimensions[1]);
futhark_envelope[5] = f(fc, outer_envelope->east.data, outer_envelope->east.dimensions[0],
outer_envelope->east.dimensions[1]);
futhark_envelope[6] = f(fc, outer_envelope->north_east.data, outer_envelope->north_east.dimensions[0],
outer_envelope->north_east.dimensions[1]);
futhark_envelope[7] = f(fc, outer_envelope->north.data, outer_envelope->north.dimensions[0],
outer_envelope->north.dimensions[1]);
} }
extern void futhark_outer_envelope_new(struct dispatch_context *dc, struct futhark_context *fc, extern void futhark_outer_envelope_new(struct dispatch_context *dc, struct futhark_context *fc,
...@@ -712,6 +701,69 @@ extern void futhark_outer_envelope_free(struct dispatch_context *dc, struct futh ...@@ -712,6 +701,69 @@ extern void futhark_outer_envelope_free(struct dispatch_context *dc, struct futh
} }
} }
static void set_active_domain_1d( struct dispatch_context *dc, struct futhark_context *fc, int dimensions[1], int x) {
chunk_info_init(&dc->active_domain, dc->type, dimensions, 0, x, true);
int64_t dimensions64[1];
dimensions64[0] = dimensions[0] * dc->type;
struct futhark_u8_1d *fut_chunk_data = futhark_new_u8_1d(fc, dc->chunk_info->data, dimensions64[0] * dc->type);
struct futhark_i64_1d* fut_dimension = futhark_new_i64_1d(fc, dimensions64, 1);
struct futhark_u8_1d *subdomain;
futhark_context_sync(fc);
futhark_entry_get_subdomain_1d(fc, &subdomain, fut_chunk_data, x * dc->type, fut_dimension);
futhark_context_sync(fc);
futhark_values_u8_1d(fc, subdomain, dc->active_domain.data);
futhark_context_sync(fc);
futhark_free_u8_1d(fc, fut_chunk_data);
futhark_free_i64_1d(fc, fut_dimension);
futhark_free_u8_1d(fc, subdomain);
}
static void
set_active_domain_2d(struct dispatch_context *dc, struct futhark_context *fc, int dimensions[2], int y, int x) {
chunk_info_init(&dc->active_domain, dc->type, dimensions, y, x, true);
int64_t dimensions64[2];
dimensions64[0] = dimensions[0];
dimensions64[1] = dimensions[1] * dc->type;
struct futhark_u8_2d *fut_chunk_data = futhark_new_u8_2d(fc, dc->chunk_info->data, dimensions64[0],
dimensions64[1]);
struct futhark_i64_1d *fut_dimensions = futhark_new_i64_1d(fc, dimensions64, 2);
struct futhark_u8_2d *subdomain;
futhark_context_sync(fc);
futhark_entry_get_subdomain_2d(fc, &subdomain, fut_chunk_data, y, x * dc->type, fut_dimensions);
futhark_context_sync(fc);
futhark_values_u8_2d(fc, subdomain, dc->active_domain.data);
futhark_context_sync(fc);
futhark_free_u8_2d(fc, fut_chunk_data);
futhark_free_i64_1d(fc, fut_dimensions);
futhark_free_u8_2d(fc, subdomain);
}
extern void set_active_domain(struct dispatch_context *dc, struct futhark_context *fc, int *dimensions, int y, int x) {
switch (dc->n_dimensions) {
case 1:
set_active_domain_1d(dc, fc, dimensions, x);
break;
case 2:
set_active_domain_2d(dc, fc, dimensions, y, x);
break;
default:
break;
}
}
extern void restore_active_domain(struct dispatch_context *dc) {
chunk_info_free(&dc->active_domain);
dc->active_domain = *dc->chunk_info;
}
extern void envelope_free(envelope_t *envelope) { extern void envelope_free(envelope_t *envelope) {
chunk_info_free(&envelope->north); chunk_info_free(&envelope->north);
chunk_info_free(&envelope->north_east); chunk_info_free(&envelope->north_east);
......
-- type envelope_1d_t [n] = {
-- west: [n]u8,
-- east: [n]u8
-- }
-- type envelope_2d_t [n][m][ty][tx] = {
-- north_west: [ty][tx]u8,
-- north: [ty][m]u8,
-- north_east: [ty][tx]u8,
-- west: [n][tx]u8,
-- east: [n][tx]u8,
-- south_west: [ty][tx]u8,
-- south: [ty][m]u8,
-- south_east: [ty][tx]u8
-- }
entry get_envelope_1d [n] (xs: [n]u8) (thickness: i64) : ([]u8, []u8) = entry get_envelope_1d [n] (xs: [n]u8) (thickness: i64) : ([]u8, []u8) =
let west = xs[0:thickness] :> [thickness]u8 let west = xs[0:thickness] :> [thickness]u8
let east = xs[n - thickness:] :> [thickness]u8 let east = xs[n - thickness:] :> [thickness]u8
in (west, east) 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) = 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 let north = matrix[0:thickness_y] :> [thickness_y][m]u8
...@@ -38,20 +17,10 @@ entry get_envelope_2d [n][m] (matrix: [n][m]u8) (thickness_y: i64) (thickness_x: ...@@ -38,20 +17,10 @@ entry get_envelope_2d [n][m] (matrix: [n][m]u8) (thickness_y: i64) (thickness_x:
let east = matrix[:,m - (thickness_x):] :> [n][thickness_x]u8 let east = matrix[:,m - (thickness_x):] :> [n][thickness_x]u8
let west = matrix[:,0: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) in (north_west, west, south_west, south, south_east, east, north_east, north)
-- 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] = entry get_subdomain_1d [n] (xs: [n]u8) (x:i64) (dimensions: [1]i64) : []u8 =
-- let north = matrix[0:thickness_y] :> [thickness_y][m]u8 xs[x:x+dimensions[0]]
--
-- let north_west = matrix[0:thickness_y,0:thickness_x] :> [thickness_y][thickness_x]u8 entry get_subdomain_2d [n][m] (matrix: [n][m]u8) (y:i64) (x:i64) (dimensions: [2]i64) : [][]u8 =
-- let north_east = matrix[0:thickness_y,m - thickness_x:m] :> [thickness_y][thickness_x]u8 matrix[y:y+dimensions[0],x:x+dimensions[1]]
--
-- 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}
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*/ */
#ifndef _FUTHARK_H_ #ifndef _FUTHARK_H_
#define _FUTHARK_H_ #define _FUTHARK_H_
#include <stdint.h>
struct futhark_context; struct futhark_context;
...@@ -34,6 +35,16 @@ int futhark_entry_get_envelope_2d(struct futhark_context *ctx, ...@@ -34,6 +35,16 @@ int futhark_entry_get_envelope_2d(struct futhark_context *ctx,
struct futhark_u8_2d *in0, int64_t in1, struct futhark_u8_2d *in0, int64_t in1,
int64_t in2); int64_t in2);
int futhark_entry_get_subdomain_1d(struct futhark_context *ctx,
struct futhark_u8_1d **out0, const
struct futhark_u8_1d *in0, const int64_t in1,
const struct futhark_i64_1d *in2);
int futhark_entry_get_subdomain_2d(struct futhark_context *ctx,
struct futhark_u8_2d **out0, const
struct futhark_u8_2d *in0, const int64_t in1,
const int64_t in2, const
struct futhark_i64_1d *in3);
struct futhark_u8_1d *futhark_new_u8_1d(struct futhark_context *ctx, const uint8_t *data, int64_t dim0); struct futhark_u8_1d *futhark_new_u8_1d(struct futhark_context *ctx, const uint8_t *data, int64_t dim0);
struct futhark_u8_2d *futhark_new_u8_2d(struct futhark_context *ctx, const struct futhark_u8_2d *futhark_new_u8_2d(struct futhark_context *ctx, const
...@@ -46,4 +57,12 @@ int futhark_values_u8_2d(struct futhark_context *ctx, struct futhark_u8_2d *arr, ...@@ -46,4 +57,12 @@ int futhark_values_u8_2d(struct futhark_context *ctx, struct futhark_u8_2d *arr,
int futhark_context_sync(struct futhark_context *ctx); int futhark_context_sync(struct futhark_context *ctx);
struct futhark_i64_1d ;
struct futhark_i64_1d *futhark_new_i64_1d(struct futhark_context *ctx, const
int64_t *data, int64_t dim0);
int futhark_free_i64_1d(struct futhark_context *ctx,
struct futhark_i64_1d *arr);
int futhark_values_i64_1d(struct futhark_context *ctx,
struct futhark_i64_1d *arr, int64_t *data);
#endif //_FUTHARK_H_ #endif //_FUTHARK_H_
...@@ -19,7 +19,7 @@ void tests_1_process(struct futhark_context *fc) { ...@@ -19,7 +19,7 @@ void tests_1_process(struct futhark_context *fc) {
printf("Testing dispatch_context_new with 1 process. Dimensions = 1x15...\n"); printf("Testing dispatch_context_new with 1 process. Dimensions = 1x15...\n");
{ {
int dimensions[1] = {15}; int dimensions[1] = {15};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 1); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 1);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
assert(ci.dimensions[0] == 1 && ci.dimensions[1] == 15); assert(ci.dimensions[0] == 1 && ci.dimensions[1] == 15);
assert(ci.data != NULL); assert(ci.data != NULL);
...@@ -82,7 +82,7 @@ void tests_1_process(struct futhark_context *fc) { ...@@ -82,7 +82,7 @@ void tests_1_process(struct futhark_context *fc) {
printf("Testing dispatch_context_new with 1 process. Dimensions = 10x15...\n"); printf("Testing dispatch_context_new with 1 process. Dimensions = 10x15...\n");
{ {
int dimensions[2] = {10, 15}; int dimensions[2] = {10, 15};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
assert(ci.dimensions[0] == 10 && ci.dimensions[1] == 15); assert(ci.dimensions[0] == 10 && ci.dimensions[1] == 15);
assert(ci.data != NULL); assert(ci.data != NULL);
...@@ -147,7 +147,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) { ...@@ -147,7 +147,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 2 processes. Dimensions = 1x16...\n"); printf("Testing dispatch_context_new with 2 processes. Dimensions = 1x16...\n");
{ {
int dimensions[1] = {16}; int dimensions[1] = {16};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 1); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 1);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
...@@ -192,7 +192,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) { ...@@ -192,7 +192,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 2 processes. Dimensions = 1x15...\n"); printf("Testing dispatch_context_new with 2 processes. Dimensions = 1x15...\n");
{ {
int dimensions[1] = {15}; int dimensions[1] = {15};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 1); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 1);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 1 && ci.dimensions[1] == 8); assert(ci.dimensions[0] == 1 && ci.dimensions[1] == 8);
...@@ -251,7 +251,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) { ...@@ -251,7 +251,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 2 processes. Dimensions = 20x40...\n"); printf("Testing dispatch_context_new with 2 processes. Dimensions = 20x40...\n");
{ {
int dimensions[2] = {20, 40}; int dimensions[2] = {20, 40};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 20 && ci.dimensions[1] == 20); assert(ci.dimensions[0] == 20 && ci.dimensions[1] == 20);
...@@ -346,7 +346,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) { ...@@ -346,7 +346,7 @@ void tests_2_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 2 processes. Dimensions = 21x41...\n"); printf("Testing dispatch_context_new with 2 processes. Dimensions = 21x41...\n");
{ {
int dimensions[2] = {21, 41}; int dimensions[2] = {21, 41};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 21 && ci.dimensions[1] == 21); assert(ci.dimensions[0] == 21 && ci.dimensions[1] == 21);
...@@ -367,7 +367,7 @@ void tests_3_processes(int my_rank, struct futhark_context *fc) { ...@@ -367,7 +367,7 @@ void tests_3_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 3 processes. Dimensions = 20x40...\n"); printf("Testing dispatch_context_new with 3 processes. Dimensions = 20x40...\n");
{ {
int dimensions[2] = {20, 40}; int dimensions[2] = {20, 40};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 20 && ci.dimensions[1] == 14); assert(ci.dimensions[0] == 20 && ci.dimensions[1] == 14);
...@@ -390,7 +390,7 @@ void tests_3_processes(int my_rank, struct futhark_context *fc) { ...@@ -390,7 +390,7 @@ void tests_3_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 2 processes. Dimensions = 21x42...\n"); printf("Testing dispatch_context_new with 2 processes. Dimensions = 21x42...\n");
{ {
int dimensions[2] = {21, 42}; int dimensions[2] = {21, 42};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 21 && ci.dimensions[1] == 14); assert(ci.dimensions[0] == 21 && ci.dimensions[1] == 14);
...@@ -416,7 +416,7 @@ void tests_4_processes(int my_rank, struct futhark_context *fc) { ...@@ -416,7 +416,7 @@ void tests_4_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 4 processes. Dimensions = 20x40...\n"); printf("Testing dispatch_context_new with 4 processes. Dimensions = 20x40...\n");
{ {
int dimensions[2] = {20, 40}; int dimensions[2] = {20, 40};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 10 && ci.dimensions[1] == 20); assert(ci.dimensions[0] == 10 && ci.dimensions[1] == 20);
...@@ -455,7 +455,7 @@ void tests_4_processes(int my_rank, struct futhark_context *fc) { ...@@ -455,7 +455,7 @@ void tests_4_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 4 processes. Dimensions = 21x42...\n"); printf("Testing dispatch_context_new with 4 processes. Dimensions = 21x42...\n");
{ {
int dimensions[2] = {21, 42}; int dimensions[2] = {21, 42};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
if (my_rank == 0) { if (my_rank == 0) {
assert(ci.dimensions[0] == 11 && ci.dimensions[1] == 21); assert(ci.dimensions[0] == 11 && ci.dimensions[1] == 21);
...@@ -486,7 +486,7 @@ void tests_6_processes(int my_rank, struct futhark_context *fc) { ...@@ -486,7 +486,7 @@ void tests_6_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 6 processes. Dimensions = 20x40...\n"); printf("Testing dispatch_context_new with 6 processes. Dimensions = 20x40...\n");
{ {
int dimensions[2] = {20, 40}; int dimensions[2] = {20, 40};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
switch (my_rank) { switch (my_rank) {
...@@ -538,7 +538,7 @@ void tests_6_processes(int my_rank, struct futhark_context *fc) { ...@@ -538,7 +538,7 @@ void tests_6_processes(int my_rank, struct futhark_context *fc) {
printf("Testing dispatch_context_new with 4 processes. Dimensions = 21x42...\n"); printf("Testing dispatch_context_new with 4 processes. Dimensions = 21x42...\n");
{ {
int dimensions[2] = {21, 42}; int dimensions[2] = {21, 42};
struct dispatch_context *dc = dispatch_context_new(dimensions, sizeof(int), 2); struct dispatch_context *dc = dispatch_context_new(dimensions, MPI_INT, 2);
chunk_info_t ci = get_chunk_info(dc); chunk_info_t ci = get_chunk_info(dc);
switch (my_rank) { switch (my_rank) {
......
...@@ -23,6 +23,13 @@ include_directories(${MPI_C_INCLUDE_PATH}) ...@@ -23,6 +23,13 @@ include_directories(${MPI_C_INCLUDE_PATH})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMPILE_FLAGS}")
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/gol_seq.h ${CMAKE_CURRENT_SOURCE_DIR}/gol_seq.c
COMMAND futhark c ${CMAKE_CURRENT_SOURCE_DIR}/gol.fut --library
DEPENDS gol.fut
)
add_custom_target(futhark_gol_seq DEPENDS gol_seq.h gol_seq.c)
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/gol_cda.h ${CMAKE_CURRENT_SOURCE_DIR}/gol_cda.c OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/gol_cda.h ${CMAKE_CURRENT_SOURCE_DIR}/gol_cda.c
COMMAND futhark cuda ${CMAKE_CURRENT_SOURCE_DIR}/gol.fut --library COMMAND futhark cuda ${CMAKE_CURRENT_SOURCE_DIR}/gol.fut --library
...@@ -58,6 +65,12 @@ endif () ...@@ -58,6 +65,12 @@ endif ()
########## Game of Life - Benchmark ########## ########## Game of Life - Benchmark ##########
## Sequential
add_executable(game_of_life_seq_bench benchmark/main.c gol.h gol.c ../futhark_mpi/dispatch.h ../futhark_mpi/dispatch.c ../futhark_mpi/chunk_info.c ../futhark_mpi/chunk_info.h)
add_dependencies(game_of_life_seq_bench futhark_gol_seq)
target_link_libraries(game_of_life_seq_bench m ${MPI_C_LIBRARIES})
## CUDA ## CUDA
if (CMAKE_SYSTEM_NAME MATCHES "Linux") if (CMAKE_SYSTEM_NAME MATCHES "Linux")
add_executable(game_of_life_cuda_bench benchmark/main.c gol.h gol.c ../futhark_mpi/dispatch.h ../futhark_mpi/dispatch.c ../futhark_mpi/chunk_info.c ../futhark_mpi/chunk_info.h) add_executable(game_of_life_cuda_bench benchmark/main.c gol.h gol.c ../futhark_mpi/dispatch.h ../futhark_mpi/dispatch.c ../futhark_mpi/chunk_info.c ../futhark_mpi/chunk_info.h)
......
...@@ -41,9 +41,9 @@ void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_contex ...@@ -41,9 +41,9 @@ void compute_next_chunk_board(struct dispatch_context *dc, struct futhark_contex
futhark_context_sync(fc); futhark_context_sync(fc);
futhark_entry_next_chunk_board(fc, &fut_next_chunk_board, fut_chunk_board, 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[0], fut_outer_envelope[7], fut_outer_envelope[6],
fut_outer_envelope[3], fut_outer_envelope[4], fut_outer_envelope[1], fut_outer_envelope[5],
fut_outer_envelope[5], fut_outer_envelope[6], fut_outer_envelope[7]); fut_outer_envelope[2], fut_outer_envelope[3], fut_outer_envelope[4]);
futhark_context_sync(fc); futhark_context_sync(fc);
futhark_values_i8_2d(fc, fut_next_chunk_board, ci->data); futhark_values_i8_2d(fc, fut_next_chunk_board, ci->data);
...@@ -69,7 +69,7 @@ int main(int argc, char *argv[]) { ...@@ -69,7 +69,7 @@ int main(int argc, char *argv[]) {
struct futhark_context_config *fut_config = futhark_context_config_new(); struct futhark_context_config *fut_config = futhark_context_config_new();
int nb_devices = atoi(argv[1]); int nb_devices = atoi(argv[1]);
#ifndef FUTHARK_BACKEND_multicore #if defined(FUTHARK_BACKEND_cuda) || defined(FUTHARK_BACKEND_opencl)
char device[4] = {0}; char device[4] = {0};
snprintf(device, sizeof(device), "#%d", my_rank % nb_devices); snprintf(device, sizeof(device), "#%d", my_rank % nb_devices);
futhark_context_config_set_device(fut_config, device); futhark_context_config_set_device(fut_config, device);
......
module env = import "../futhark_mpi/envelope" 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_1d = env.get_envelope_1d
entry get_envelope_2d = env.get_envelope_2d entry get_envelope_2d = env.get_envelope_2d
entry get_subdomain_1d = env.get_subdomain_1d
entry get_subdomain_2d = env.get_subdomain_2d
let count_neighbours [n][m] (board: [n][m]i8) : [n][m]i8 = let count_neighbours [n][m] (board: [n][m]i8) : [n][m]i8 =
let north = rotate (-1) board let north = rotate (-1) board
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment