From a8c1d9962baae7b57f5cb0a6ad90b4c4dbcf004a Mon Sep 17 00:00:00 2001 From: "raphael.bach" <raphael.bach@etu.hesge.ch> Date: Mon, 18 Jul 2022 22:33:57 +0200 Subject: [PATCH] Add Game of Life example --- Makefile | 36 ++++++++++++- examples/game_of_life/.gitignore | 7 +++ examples/game_of_life/Makefile | 87 ++++++++++++++++++++++++++++++++ examples/game_of_life/gol.fut | 11 ++++ examples/game_of_life/main.c | 85 +++++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 examples/game_of_life/.gitignore create mode 100644 examples/game_of_life/Makefile create mode 100644 examples/game_of_life/gol.fut create mode 100644 examples/game_of_life/main.c diff --git a/Makefile b/Makefile index 1eba9c4..f65a966 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ src/futhark/fmpi_entry.h src/futhark/fmpi_entry.c &: src/futhark/fmpi_entry.fut # BUILD TARGETS - EXAMPLES ################################################################################ .PHONY: examples -examples: array-sum rule-110 +examples: array-sum rule-110 gol #------------------------------------------------------------------------------- # Array sum #------------------------------------------------------------------------------- @@ -131,6 +131,22 @@ rule-110-pp: export BUILD_MODE := $(BUILD_MODE) rule-110-pp: export CFLAGS := $(filter-out -Iinclude,$(CFLAGS)) -I../../include rule-110-pp: $(MAKE) -C examples/rule_110 pp +#------------------------------------------------------------------------------- +# Game of Life +#------------------------------------------------------------------------------- +.PHONY: gol +gol: export BUILD_MODE := $(BUILD_MODE) +gol: export CFLAGS := $(filter-out -Iinclude,$(CFLAGS)) -I../../include +gol: export LDFLAGS := $(LDFLAGS) -L../../build/$(BUILD_MODE) +gol: export LDLIBS := $(LDLIBS) -lfmpi -lm +gol: + $(MAKE) -C examples/game_of_life + +.PHONY: gol-pp +gol-pp: export BUILD_MODE := $(BUILD_MODE) +gol-pp: export CFLAGS := $(filter-out -Iinclude,$(CFLAGS)) -I../../include +gol-pp: + $(MAKE) -C examples/gol pp ################################################################################ # INSTALL TARGETS ################################################################################ @@ -206,16 +222,19 @@ clean-examples: clean-examples-$(BUILD_MODE) .PHONY: clean-examples-all clean-examples-all: $(MAKE) -C examples/array_sum clean-all + $(MAKE) -C examples/game_of_life clean-all $(MAKE) -C examples/rule_110 clean-all .PHONY: clean-examples-debug clean-examples-debug: $(MAKE) -C examples/array_sum clean-debug + $(MAKE) -C examples/game_of_life clean-debug $(MAKE) -C examples/rule_110 clean-debug .PHONY: clean-examples-release clean-examples-release: $(MAKE) -C examples/array_sum clean-release + $(MAKE) -C examples/game_of_life clean-release $(MAKE) -C examples/rule_110 clean-release ################################################################################ # REBUILD TARGETS @@ -259,6 +278,20 @@ run-r110-debug: .PHONY: run-r110-release run-r110-release: $(MAKE) -C examples/rule_110 run-release +#------------------------------------------------------------------------------- +# Game of Life +#------------------------------------------------------------------------------- +.PHONY: run-gol +run-gol: + $(MAKE) -C examples/game_of_life run-$(BUILD_MODE) + +.PHONY: run-gol-debug +run-gol-debug: + $(MAKE) -C examples/game_of_life run-debug + +.PHONY: run-gol-release +run-gol-release: + $(MAKE) -C examples/game_of_life run-release ################################################################################ # MISC TARGETS ################################################################################ @@ -320,6 +353,7 @@ help: @printf "\n" @printf "RUN:\n" @printf " run-as : Run 'Array sum' example.\n" + @printf " run-gol : Run 'Game of Life' example.\n" @printf " run-r110 : Run 'Rule 110' example.\n" @printf "\n" @printf "UNINSTALL:\n" diff --git a/examples/game_of_life/.gitignore b/examples/game_of_life/.gitignore new file mode 100644 index 0000000..bfce2aa --- /dev/null +++ b/examples/game_of_life/.gitignore @@ -0,0 +1,7 @@ +*.json +*.o +*.pp +gol-debug +gol-release +gol.c +gol.h diff --git a/examples/game_of_life/Makefile b/examples/game_of_life/Makefile new file mode 100644 index 0000000..a2f4c0d --- /dev/null +++ b/examples/game_of_life/Makefile @@ -0,0 +1,87 @@ +################################################################################ +# BUILD TARGETS - MAIN +################################################################################ +NAME := gol + +.PHONY: all +all: $(NAME)-$(BUILD_MODE) + +.PHONY: all-debug +all_debug: + $(MAKE) all BUILD_MODE=debug + +.PHONY: all-release +all_release: + $(MAKE) all BUILD_MODE=release + +$(NAME)-$(BUILD_MODE): main-$(BUILD_MODE).o $(NAME)-$(BUILD_MODE).o + $(CC) $^ -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS) + +main-$(BUILD_MODE).o: main.c $(NAME).h + $(CC) $< -o $@ -c -fPIC $(CFLAGS) + +$(NAME)-$(BUILD_MODE).o: $(NAME).c $(NAME).h + $(CC) $< -o $@ -c -fPIC $(CFLAGS_FUTHARK) + +$(NAME).h $(NAME).c &: $(NAME).fut + futhark c --library $< + +.PHONY: pp +pp: main.pp + +main.pp: main.c + $(CC) $< -o $@ $(CFLAGS) -dU -E +################################################################################ +# CLEAN TARGETS +################################################################################ +.PHONY: clean +clean: clean-$(BUILD_MODE) + +.PHONY: clean-all +clean-all: clean-debug clean-release clean-futhark + +.PHONY: clean-debug +clean-debug: + rm -f $(NAME)-debug + rm -f $(NAME)-debug.o + rm -f main-debug.o + +.PHONY: clean-release +clean-release: + rm -f $(NAME)-release + rm -f $(NAME)-release.o + rm -f main-release.o + +.PHONY: clean-futhark +clean-futhark: + rm -f $(NAME).h + rm -f $(NAME).c + rm -f $(NAME).json +################################################################################ +# REBUILD TARGETS +################################################################################ +.PHONY: rebuild +rebuild: clean all + +.PHONY: rebuild-debug +rebuild_debug: clean-debug all-debug + +.PHONY: rebuild-release +rebuild_release: clean-release all-release +################################################################################ +# RUN TARGETS +################################################################################ +.PHONY: run +run: run-$(BUILD_MODE) + +.PHONY: run-debug +run-debug: export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):../../build/debug +run-debug: + mpirun $(NAME)-debug + +.PHONY: run-release +run-release: export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):../../build/release +run-release: + mpirun $(NAME)-release +################################################################################ +.DELETE_ON_ERROR: diff --git a/examples/game_of_life/gol.fut b/examples/game_of_life/gol.fut new file mode 100644 index 0000000..281aea8 --- /dev/null +++ b/examples/game_of_life/gol.fut @@ -0,0 +1,11 @@ +entry gol [y][x] (xs: [y][x]u64): [][]u64 = + let res = tabulate_2d (y) (x) (\i j -> + if(i > 0 && i < (y-1) && j > 0 && j < (x-1)) then + let cnt = + xs[(i-1), (j-1)] + xs[(i-1), j] + xs[(i-1), (j+1)] + + xs[ i , (j-1)] + 0 + xs[ i , (j+1)] + + xs[(i+1), (j-1)] + xs[(i+1), j] + xs[(i+1), (j+1)] + in u64.bool ((cnt == 3) || ((xs[i, j] == 1) && (cnt == 2))) + else xs[i,j] + ) + in res[1:(y-1), 1:(x-1)] diff --git a/examples/game_of_life/main.c b/examples/game_of_life/main.c new file mode 100644 index 0000000..6525451 --- /dev/null +++ b/examples/game_of_life/main.c @@ -0,0 +1,85 @@ +// C Standard Library +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +// fmpi +#include <fmpi.h> +// Internal +#include "gol.h" + +#define T u64 +#define STEP_CNT 20 +#define X_LEN 8 +#define Y_LEN 8 + +FMPI_TASK_FUTHARK(gol, 1) + +int main(int argc, char * argv[]) +{ + struct fmpi_ctx * ctx = fmpi_init(&argc, &argv); + if(ctx == NULL) { + fprintf(stderr, "fmpi_init() failed!\n"); + return EXIT_FAILURE; + } + T in[] = { + 0,1,0,0,0,0,0,0, + 0,0,1,0,0,0,0,0, + 1,1,1,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + }; + #define in_size (sizeof(in)/sizeof(T)) + T out[in_size] = {0}; + struct fmpi_task gol_task = FMPI_REGISTER_SYNC_TASK( + ctx, gol, fmpi_stencil_square(1), + fmpi_data_2d_out(ctx, out, X_LEN, Y_LEN), + fmpi_data_2d_in(ctx, in, X_LEN, Y_LEN) + ); + for(size_t i = 0; i < STEP_CNT; i++) { + if(fmpi_run_task(ctx, &gol_task) != FMPI_SUCCESS) { + printf("Error rank=%d: fmpi_run_task()\n", fmpi_world_rank(ctx)); + } + } + if(fmpi_task_finalize(ctx, &gol_task, FMPI_TASK_OP_GATHER) != FMPI_SUCCESS) { + printf("Error rank=%d: fmpi_task_finalize()\n", fmpi_world_rank(ctx)); + } + if(fmpi_is_root(ctx)) { + T expected[] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0, + 0,0,0,0,0,0,0,1, + 0,0,0,0,0,1,1,1, + }; + printf("Expected =>\n"); + for(size_t i = 0; i < in_size; i++) { + printf("%"PRIu64, expected[i]); + if((i+1) % X_LEN == 0) { + printf("\n"); + } + } + printf("Actual =>\n"); + size_t correct_cnt = 0; + for(size_t i = 0; i < in_size; i++) { + if(out[i] == expected[i]) { + correct_cnt++; + } + printf("%"PRIu64, out[i]); + if((i+1) % X_LEN == 0) { + printf("\n"); + } + } + if(correct_cnt == in_size) { + printf("OK!\n"); + } + } + fmpi_exit(&ctx); + return EXIT_SUCCESS; +} -- GitLab