diff options
-rw-r--r-- | makefile | 6 | ||||
-rw-r--r-- | score/main.cpp | 109 | ||||
-rw-r--r-- | tabulator-mpi/constants.hpp | 2 | ||||
-rw-r--r-- | tabulator-mpi/head.cpp | 38 | ||||
-rw-r--r-- | tabulator-mpi/worker.cpp | 25 |
5 files changed, 34 insertions, 146 deletions
@@ -7,7 +7,7 @@ GTKMM_LD_ARGS = $(shell pkg-config --libs gtkmm-4.0) MPI_CPP_ARGS = $(shell mpic++ --showme:compile) -DOMPI_SKIP_MPICXX MPI_LD_ARGS = $(shell mpic++ --showme:link) -default: bin/bench bin/score bin/tabulator-mpi +default: bin/bench bin/tabulator-mpi clean: rm -r obj bin @@ -16,10 +16,6 @@ bin/bench: obj/bench/main.o obj/bench/bench_window.o obj/bench/core_widget.o obj @mkdir -p $(dir $@) g++ ${CPP_ARGS} $^ ${GTKMM_LD_ARGS} -o $@ -bin/score: obj/score/main.o obj/lib94.o - @mkdir -p $(dir $@) - g++ ${CPP_ARGS} $^ -o $@ - bin/tabulator-mpi: obj/tabulator-mpi/main.o obj/tabulator-mpi/head.o obj/tabulator-mpi/worker.o obj/lib94.o @mkdir -p $(dir $@) g++ ${CPP_ARGS} $^ ${MPI_LD_ARGS} -o $@ diff --git a/score/main.cpp b/score/main.cpp deleted file mode 100644 index aae9ba2..0000000 --- a/score/main.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include <lib94/lib94.hpp> -#include <iostream> -#include <fstream> - -[[noreturn]] void usage(const char *argv0) { - std::cout << "usage: " << argv0 << " <first warrior> <second warrior> <number of rounds> <steps until tie>\n"; - exit(1); -} - -void print_warrior(const lib94::warrior *w) { - std::cerr << ";name " << w->name << '\n'; - std::cerr << ";author " << w->author << '\n'; - if (w->org != 0) - std::cerr << "org " << w->org << '\n'; - for (const auto &i : w->instructions) - std::cerr << lib94::instruction_to_string(i) << '\n'; - std::cerr << '\n'; -} - -int main(int argc, const char **argv) { - if (argc != 5) - usage(argv[0]); - - unsigned round_count, steps_until_tie; - - try { - round_count = std::stoul(argv[3]); - steps_until_tie = std::stoul(argv[4]); - } - catch (const std::exception &e) { - usage(argv[0]); - } - - std::ifstream file1(argv[1]); - std::ifstream file2(argv[2]); - - if (!file1 || !file2) - usage(argv[0]); - - std::string source1(std::istreambuf_iterator<char>(file1), {}); - std::string source2(std::istreambuf_iterator<char>(file2), {}); - - file1.close(); - file2.close(); - - lib94::warrior *w1, *w2; - - try { - w1 = lib94::compile_warrior(source1); - } - catch (const lib94::compiler_exception &ex) { - std::cout << "error in " << argv[1] << " on line " << ex.line_number << ": " << ex.message << '\n'; - return 1; - } - - try { - w2 = lib94::compile_warrior(source2); - } - catch (const lib94::compiler_exception &ex) { - std::cout << "error in " << argv[2] << " on line " << ex.line_number << ": " << ex.message << '\n'; - return 1; - } - - const lib94::warrior *ws[2] = {w1, w2}; - - print_warrior(ws[0]); - print_warrior(ws[1]); - - unsigned w1_wins = 0; - unsigned w2_wins = 0; - - lib94::seed_prng(time(NULL)); - - for (unsigned round_number = 0; round_number < round_count; ++round_number) { - - std::cerr << "round " << round_number + 1 << "\x1b[0G"; - - lib94::clear_core({ - .op = lib94::DAT, .mod = lib94::F, - .amode = lib94::DIRECT, .bmode = lib94::DIRECT, - .anumber = 0, .bnumber = 0 - }); - - lib94::init_round(ws, 2); - - for (unsigned step_number = 0; step_number < steps_until_tie; ++step_number) { - - const lib94::warrior *w = lib94::single_step<false>(); - - if (w == ws[0]) { - ++w2_wins; - break; - } - - if (w == ws[1]) { - ++w1_wins; - break; - } - - } - - } - - std::cout << round_count << " rounds completed\n"; - std::cout << w1_wins << " wins, " << w2_wins << " losses\n"; - std::cout << "score " << (int)w1_wins - (int)w2_wins << '\n'; - - return 0; -} diff --git a/tabulator-mpi/constants.hpp b/tabulator-mpi/constants.hpp index 3f80bff..de4dd27 100644 --- a/tabulator-mpi/constants.hpp +++ b/tabulator-mpi/constants.hpp @@ -1,3 +1,3 @@ #define STEPS_TO_TIE 1000000 -#define ROUNDS_PER_CHUNK 500 +#define ROUNDS_PER_CHUNK 200 #define CHUNKS_PER_PAIR 5 diff --git a/tabulator-mpi/head.cpp b/tabulator-mpi/head.cpp index c425865..7026746 100644 --- a/tabulator-mpi/head.cpp +++ b/tabulator-mpi/head.cpp @@ -5,25 +5,27 @@ #include "constants.hpp" -static int **score_results; +static int **wins; static int get_result() { - int result[3]; + int result[4]; MPI_Status status; - MPI_Recv(result, 3, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &status); + MPI_Recv(result, 4, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &status); - if (result[0] != -1) - score_results[result[0]][result[1]] += result[2]; + if (result[0] != -1) { + wins[result[0]][result[1]] += result[2]; + wins[result[1]][result[0]] += result[3]; + } return status.MPI_SOURCE; } void head_main(int comm_size, int warrior_count, const lib94::warrior *const *warriors) { - score_results = new int *[warrior_count]; + wins = new int *[warrior_count]; for (int i = 0; i < warrior_count; ++i) { - score_results[i] = new int[warrior_count]; + wins[i] = new int[warrior_count]; for (int j = 0; j < warrior_count; ++j) - score_results[i][j] = 0; + wins[i][j] = 0; } int chunks = warrior_count * (warrior_count - 1) / 2 * CHUNKS_PER_PAIR; @@ -53,8 +55,8 @@ void head_main(int comm_size, int warrior_count, const lib94::warrior *const *wa for (int x = 0; x < CHUNKS_PER_PAIR; ++x) { ++on_chunk; int rank = get_result(); - int message[3] = {i, j, x * ROUNDS_PER_CHUNK}; - MPI_Send(message, 2, MPI_INT, rank, 0, MPI_COMM_WORLD); + int message[4] = {i, j, x * ROUNDS_PER_CHUNK}; + MPI_Send(message, 4, MPI_INT, rank, 0, MPI_COMM_WORLD); fprintf(stderr, "\x1b[%d;0H%*d | %*s vs %*s | %*d - %*d | %*d / %*d\x1b[0K", rank + 1, rank_width, rank, left_name_width, warriors[i]->name.c_str(), right_name_width, warriors[j]->name.c_str(), left_round_width, x * ROUNDS_PER_CHUNK + 1, right_round_width, x * ROUNDS_PER_CHUNK + ROUNDS_PER_CHUNK, @@ -63,8 +65,8 @@ void head_main(int comm_size, int warrior_count, const lib94::warrior *const *wa for (int i = 0; i < comm_size - 1; ++i) { int rank = get_result(); - int message[3] = {-1}; - MPI_Send(message, 3, MPI_INT, rank, 0, MPI_COMM_WORLD); + int message[4] = {-1}; + MPI_Send(message, 4, MPI_INT, rank, 0, MPI_COMM_WORLD); fprintf(stderr, "\x1b[%d;0H%*d | %*s | %*s | %*s\x1b[0K", rank + 1, rank_width, rank, left_name_width + 4 + right_name_width, "", @@ -74,13 +76,6 @@ void head_main(int comm_size, int warrior_count, const lib94::warrior *const *wa fprintf(stderr, "\x1b[?25h\x1b[?47l\x1b""8"); - for (int i = 0; i < warrior_count; ++i) - for (int j = i + 1; j < warrior_count; ++j) - if (score_results[i][j] < 0) { - score_results[j][i] = -score_results[i][j]; - score_results[i][j] = 0; - } - int *tab_widths = new int[warrior_count + 1]; tab_widths[0] = 0; @@ -109,7 +104,10 @@ void head_main(int comm_size, int warrior_count, const lib94::warrior *const *wa for (int i = 0; i < warrior_count; ++i) { printf(" %*s", tab_widths[0], warriors[i]->name.c_str()); for (int j = 0; j < warrior_count; ++j) - printf(" | %*d", tab_widths[j + 1], score_results[i][j]); + if (i == j) + printf(" | %*s", tab_widths[j + 1], "x"); + else + printf(" | %*d", tab_widths[j + 1], wins[i][j]); putchar('\n'); } } diff --git a/tabulator-mpi/worker.cpp b/tabulator-mpi/worker.cpp index 5a20db2..ea1b17a 100644 --- a/tabulator-mpi/worker.cpp +++ b/tabulator-mpi/worker.cpp @@ -3,7 +3,7 @@ #include "constants.hpp" -static int do_round(const lib94::warrior *w1, const lib94::warrior *w2) { +static void do_round(const lib94::warrior *w1, const lib94::warrior *w2, int &w1_wins, int& w2_wins) { const lib94::warrior *ws[2] = {w1, w2}; lib94::instruction background = { @@ -18,28 +18,31 @@ static int do_round(const lib94::warrior *w1, const lib94::warrior *w2) { for (int i = 0; i < STEPS_TO_TIE; ++i) { const lib94::warrior *result = lib94::single_step<false>(); - if (result == w1) - return -1; - if (result == w2) - return 1; + if (result == w1) { + ++w2_wins; + return; + } + if (result == w2) { + ++w1_wins; + return; + } } - - return 0; } void worker_main(const lib94::warrior *const *warriors) { - int buffer[3] = {-1}; + int buffer[4] = {-1}; while (1) { - MPI_Send(buffer, 3, MPI_INT, 0, 1, MPI_COMM_WORLD); - MPI_Recv(buffer, 3, MPI_INT, 0, 0, MPI_COMM_WORLD, 0); + MPI_Send(buffer, 4, MPI_INT, 0, 1, MPI_COMM_WORLD); + MPI_Recv(buffer, 4, MPI_INT, 0, 0, MPI_COMM_WORLD, 0); if (buffer[0] == -1) return; buffer[2] = 0; + buffer[3] = 0; for (int i = 0; i < ROUNDS_PER_CHUNK; ++i) - buffer[2] += do_round(warriors[buffer[0]], warriors[buffer[1]]); + do_round(warriors[buffer[0]], warriors[buffer[1]], buffer[2], buffer[3]); } } |