Newer
Older
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
let count_neighbours [n][m] (board: [n][m]i8) : [n][m]i8 =
let north = rotate (-1) board
let south = rotate 1 board
let east = map(rotate 1) board
let west = map(rotate (-1)) board
let north_east = map(rotate 1) north
let north_west = map(rotate (-1)) north
let south_east = map(rotate 1) south
let south_west = map(rotate (-1)) south
in map3 (\(nwr,nr,ner) (wr, br, er) (swr, sr, ser) ->
map3 (\(nw,n,ne) (w, _, e) (sw, s, se) -> nw + n + ne + w + e + sw + s + se)
(zip3 nwr nr ner) (zip3 wr br er) (zip3 swr sr ser))
(zip3 north_west north north_east) (zip3 west board east) (zip3 south_west south south_east)
let augment_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 =
tabulate_2d (n+2) (m+2) (\i j ->
-- North-West
if (i == 0 && j == 0) then nw[0,0]
-- North-East
else if (i == 0 && j == m+1) then ne[0,0]
-- South-West
else if (i == n+1 && j == 0) then sw[0,0]
-- South-East
else if (i == n+1 && j == m+1) then se[0,0]
-- North
else if (i == 0) then no[0, j-1]
-- West
else if (j == 0) then we[i-1, 0]
-- East
else if (j == m + 1) then ea[i-1, 0]
-- South
else if (i == n+1) then so[0,j-1]
else chunk_board[i-1, j-1]
)
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) :[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 ->
map2(\cell nb_alive_cells ->
if (cell == 1 && (nb_alive_cells == 2 || nb_alive_cells == 3)) || (cell == 0 && nb_alive_cells == 3)
then 1
else 0)
augmented_board_r neighbours_r)
augmented_board neighbours
in next_board[1:n+1, 1:m+1] :> [n][m]i8