summaryrefslogtreecommitdiff
path: root/tabulator-mpi/head.cpp
blob: 70267467ca8d6f2abb5f4f487eac1508dca3def8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <lib94/lib94.hpp>
#include <csignal>
#include <cstdio>
#include <mpi.h>

#include "constants.hpp"

static int **wins;

static int get_result() {
  int result[4];
  MPI_Status status;
  MPI_Recv(result, 4, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD, &status);

  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) {
  wins = new int *[warrior_count];
  for (int i = 0; i < warrior_count; ++i) {
    wins[i] = new int[warrior_count];
    for (int j = 0; j < warrior_count; ++j)
      wins[i][j] = 0;
  }

  int chunks = warrior_count * (warrior_count - 1) / 2 * CHUNKS_PER_PAIR;
  int on_chunk = 0;

  int right_name_width = 0;
  for (int i = 0; i < warrior_count; ++i)
    if ((int)warriors[i]->name.size() > right_name_width)
      right_name_width = warriors[i]->name.size();

  int rank_width = std::max(std::string("rank").size(), std::to_string(comm_size - 1).size());
  int right_round_width = std::to_string(CHUNKS_PER_PAIR * ROUNDS_PER_CHUNK).size();
  int right_chunk_width = std::to_string(chunks).size();

  int left_name_width = std::max(right_name_width, (int)std::string("match").size() - right_name_width - 4);
  int left_round_width = std::max((int)std::to_string((CHUNKS_PER_PAIR - 1) * ROUNDS_PER_CHUNK + 1).size(), (int)std::string("rounds").size() - right_round_width - 3);
  int left_chunk_width = std::max(right_chunk_width, (int)std::string("chunk").size() - right_chunk_width - 3);

  fprintf(stderr, "\x1b""7\x1b[?47h\x1b[?25l\x1b[2J\x1b[0H");
  fprintf(stderr, "%*s | %*s | %*s | %*s", rank_width, "rank",
    left_name_width + 4 + right_name_width, "match",
    left_round_width + 3 + right_round_width, "rounds",
    left_chunk_width + 3 + right_chunk_width, "chunk");

  for (int i = 0; i < warrior_count; ++i)
    for (int j = i + 1; j < warrior_count; ++j)
      for (int x = 0; x < CHUNKS_PER_PAIR; ++x) {
        ++on_chunk;
        int rank = get_result();
        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,
          left_chunk_width, on_chunk, right_chunk_width, chunks);
      }

  for (int i = 0; i < comm_size - 1; ++i) {
    int rank = get_result();
    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, "",
      left_round_width + 3 + right_round_width, "",
      left_chunk_width + 3 + right_chunk_width, "done");
  }

  fprintf(stderr, "\x1b[?25h\x1b[?47l\x1b""8");

  int *tab_widths = new int[warrior_count + 1];
  tab_widths[0] = 0;

  for (int i = 0; i < warrior_count; ++i) {
    int len = warriors[i]->name.size();
    if (len > tab_widths[0])
      tab_widths[0] = len;
    tab_widths[i + 1] = len > 5 ? len : 5;
  }

  printf(" %*s", tab_widths[0], "");
  for (int j = 0; j < warrior_count; ++j)
    printf(" | %*s", tab_widths[j + 1], warriors[j]->name.c_str());
  putchar('\n');

  putchar('-');
  for (int x = 0; x < tab_widths[0]; ++x)
    putchar('-');
  for (int j = 0; j < warrior_count; ++j) {
    printf("-+-");
    for (int x = 0; x < tab_widths[j + 1]; ++x)
      putchar('-');
  }
  printf("-\n");

  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)
      if (i == j)
        printf(" | %*s", tab_widths[j + 1], "x");
      else
        printf(" | %*d", tab_widths[j + 1], wins[i][j]);
    putchar('\n');
  }
}