Skip to content
This repository has been archived by the owner on Jan 18, 2025. It is now read-only.

Commit

Permalink
added env
Browse files Browse the repository at this point in the history
  • Loading branch information
Palani Johnson committed Dec 9, 2021
1 parent f95bde2 commit eefd52b
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 11 deletions.
8 changes: 5 additions & 3 deletions cuda_game.cu
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ void ppm_write_from_cuda(struct GameOfLife *life, struct GameOfLife *cuda_life,
}

int main(int argc, char** argv) {
get_env;

if (argc != 7) {
fprintf(
stderr,
Expand Down Expand Up @@ -143,16 +145,16 @@ int main(int argc, char** argv) {
cuda_life_d = cuda_init_life(life, cuda_life_h);

cuda_write_video_buffer<<<blocks, threads>>>(cuda_life_d);
ppm_write_from_cuda(life, cuda_life_h, stdout);
if (DO_IO) ppm_write_from_cuda(life, cuda_life_h, stdout);

for (int i = 0; i < iterations; i++) {
//make_torus(cuda_life_h);
if (DO_TORIS) make_torus(cuda_life_h);
cuda_gen_next_buff<<<blocks, threads>>>(cuda_life_d);
iterate_buff(cuda_life_h);
cudaMemcpy(cuda_life_d, cuda_life_h, sizeof(GameOfLife), cudaMemcpyHostToDevice);

cuda_write_video_buffer<<<blocks, threads>>>(cuda_life_d);
ppm_write_from_cuda(life, cuda_life_h, stdout);
if (DO_IO) ppm_write_from_cuda(life, cuda_life_h, stdout);
}

return EXIT_SUCCESS;
Expand Down
3 changes: 1 addition & 2 deletions game.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ void ppm_write(struct GameOfLife *life, FILE *f) {
// Allocates random data to a life struct buffer
bool *alloc_random_buff(struct GameOfLife *life, int seed, int fill) {
bool *buff;
buff = calloc(life->buff_size, sizeof(bool));

if (seed == -1) {
buff = calloc(life->buff_size, sizeof(bool));
for (int i = 0; i < 3; i++)
buff[game_pos(life, i, 1)] = 1;
} else {
srand(seed);
buff = malloc(life->buff_size * sizeof(bool));
for (int j = 0; j < life->height; j++)
for (int i = 0; i < life->width; i++)
buff[game_pos(life, i, j)] = (rand() / (double)RAND_MAX)
Expand Down
6 changes: 6 additions & 0 deletions game_of_life.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@
void ppm_write(struct GameOfLife *life, FILE *f);
void iterate_buff(struct GameOfLife *life);
void free_buffs(struct GameOfLife *life);
bool *alloc_random_buff(struct GameOfLife *life, int seed, int fill);
bool *alloc_buff_from_file(struct GameOfLife *life, char *file, int seed, int fill);


#define get_env bool DO_TORIS = getenv("GAME_DO_TORIS") != NULL; \
bool DO_IO = getenv("GAME_DONT_DO_IO") == NULL;
#endif
160 changes: 160 additions & 0 deletions mpi_game.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* File: mpi_game.c
*
* Compile: mpicc -g -Wall -o mip_game game.c mpi_game.c
* Run: ./mpi_game [random|rand] [board_width] [board_height] [seed] [fill] [iterations]
*
* Examples:
* Gen 500x500 game board with seed 50 and fill 50 and save as game.ppm:
* ./mpi_game rand 500 500 10 50 600 > game.ppm
*
* View ppm:
* mpv --no-correct-pts --fps=10 game.ppm
*
* Stream game with pipe into mpv:
* ./mpi_game rand 500 500 10 50 600 | mpv --no-correct-pts --fps=10 -
*/
#include <mpi.h>
#include "game_of_life.h"

#define error_if(check, msg, v1) if (check) { \
fprintf(stderr, msg, v1); \
MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); \
MPI_Finalize(); \
exit(EXIT_FAILURE); }

int PROCESSES, THIS_PROCESS;

// Copies data into the extra space of a life buffer so that
// it has the topology of a torus
void make_torus(struct GameOfLife *life) {
int wm1 = life->width-1;
int hm1 = life->height-1;
int bm1 = life->buff_size-1;

for (int j = 0; j < life->height; j++) {
life->buff[game_pos(life, life->width, j)] = life->buff[game_pos(life, 0, j)];
life->buff[game_pos(life, -1, j)] = life->buff[game_pos(life, wm1, j)];
}

for (int i = 0; i < life->width; i++) {
life->buff[game_pos(life, i, life->height)] = life->buff[game_pos(life, i, 0)];
life->buff[game_pos(life, i, -1)] = life->buff[game_pos(life, i, hm1)];
}

life->buff[bm1] = life->buff[game_pos(life, 0, 0)];
life->buff[0] = life->buff[game_pos(life, wm1, hm1)];
life->buff[life->width + 1] = life->buff[game_pos(life, 0, hm1)];
life->buff[bm1 - (life->width + 1)] = life->buff[game_pos(life, wm1, 0)];
}

// Creates the next buffer in a life struct
void gen_next_buff(struct GameOfLife *life) {
int i, j, w, h, sum, p;

for (j = 0; j < life->height; j++) {
for (i = 0; i < life->width; i++) {
sum = 0;
for (h = j-1; h <= j+1; h++)
for (w = i-1; w <= i+1; w++)
if (life->buff[game_pos(life, w, h)]) sum++;

p = game_pos(life, i, j);
life->next_buff[p] = sum == 3 || (life->buff[p] && sum == 4);
}
}
}

void write_video_buffer(struct GameOfLife *life) {
int i, j, b, c, jh, i3;

for (j = 0; j < life->height; j++) {
jh = j * (life->height) * 3;
for (i = 0; i < life->width; i++) {
i3 = i*3;
b = life->buff[game_pos(life, i, j)] ? 0 : 255;
for(c = 0; c < 3; c++) life->vid_buff[i3 + jh + c] = b;
}
}
}

void mpi_init_life(
struct GameOfLife *life,
int init_type,
int width,
int height,
int op1,
int op2
) {
life->width = width;
life->height = height;
life->buff_size = (life->width + 2) * (life->height + 2);
life->_w2 = life->width + 2;
life->_w3 = life->height + 3;

life->next_buff = malloc(life->buff_size * sizeof(bool));
if(THIS_PROCESS == 0)
life->buff = init_type
? alloc_random_buff(life, op1, op2)
: alloc_buff_from_file(life, init_type, op1, op2);

life->vid_buff_size = life->width * life->height * 3;
life->vid_buff = malloc(life->vid_buff_size * sizeof(char));
}

int main(int argc, char** argv) {
get_env;

MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &PROCESSES);
MPI_Comm_rank(MPI_COMM_WORLD, &THIS_PROCESS);

int argi[6];

if(THIS_PROCESS == 0) {
error_if(
argc != 7,
"usage: %s [random|rand] [board_width] [board_height] [seed] [fill] [iterations]\n",
argv[0]
)
argi[0] = strcmp(argv[1], "random") || strcmp(argv[0], "rand");
argi[1] = strtol(argv[2], NULL, 10);
argi[2] = strtol(argv[3], NULL, 10);
argi[3] = strtol(argv[4], NULL, 10);
argi[4] = strtol(argv[5], NULL, 10);
argi[5] = strtol(argv[6], NULL, 10);

error_if(argi[1] % PROCESSES == 0, "Width mod %d (processes) must be 0", PROCESSES)
error_if(argi[2] % PROCESSES == 0, "Height mod %d (processes) must be 0", PROCESSES)
}

MPI_Bcast(&argi, 6, MPI_INT, 0, MPI_COMM_WORLD);

struct GameOfLife life_struct, *life;
life = &life_struct;

mpi_init_life(life, argi[0], argi[1], argi[2], argi[3], argi[4]);
MPI_Barrier(MPI_COMM_WORLD);

write_video_buffer(life);
MPI_Barrier(MPI_COMM_WORLD);
if(THIS_PROCESS == 0 && DO_IO) ppm_write(life, stdout);

for (int i = 0; i < argi[5]; i++) {
if (DO_TORIS) make_torus(life);

gen_next_buff(life);
MPI_Barrier(MPI_COMM_WORLD);

if (THIS_PROCESS == 0) iterate_buff(life);
MPI_Barrier(MPI_COMM_WORLD);

write_video_buffer(life);
MPI_Barrier(MPI_COMM_WORLD);
if(THIS_PROCESS == 0 && DO_IO) ppm_write(life, stdout);
}

free_buffs(life);
MPI_Finalize();

return EXIT_SUCCESS;
}
8 changes: 5 additions & 3 deletions omp_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ void omp_write_video_buffer(struct GameOfLife *life) {
}

int main(int argc, char** argv) {
get_env;

if (argc != 8) {
fprintf(
stderr,
Expand Down Expand Up @@ -105,10 +107,10 @@ int main(int argc, char** argv) {
omp_write_video_buffer(life);

#pragma omp single
ppm_write(life, stdout);
if (DO_IO) ppm_write(life, stdout);

for (int i = 0; i < iterations; i++) {
omp_make_torus(life);
if (DO_TORIS) omp_make_torus(life);
omp_gen_next_buff(life);

#pragma omp single
Expand All @@ -117,7 +119,7 @@ int main(int argc, char** argv) {
omp_write_video_buffer(life);

#pragma omp single
ppm_write(life, stdout);
if (DO_IO) ppm_write(life, stdout);
}
}

Expand Down
8 changes: 5 additions & 3 deletions serial_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ void write_video_buffer(struct GameOfLife *life) {
}

int main(int argc, char** argv) {
get_env;

if (argc != 7) {
fprintf(
stderr,
Expand All @@ -93,15 +95,15 @@ int main(int argc, char** argv) {
int iterations = strtol(argv[6], NULL, 10);

write_video_buffer(life);
ppm_write(life, stdout);
if (DO_IO) ppm_write(life, stdout);

for (int i = 0; i < iterations; i++) {
make_torus(life);
if (DO_TORIS) make_torus(life);
gen_next_buff(life);
iterate_buff(life);

write_video_buffer(life);
ppm_write(life, stdout);
if (DO_IO) ppm_write(life, stdout);
}

free_buffs(life);
Expand Down

0 comments on commit eefd52b

Please sign in to comment.