| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "borunov_v_cnt_words/mpi/include/ops_mpi.hpp" | ||
| 2 | |||
| 3 | #include <mpi.h> | ||
| 4 | |||
| 5 | #include <cctype> | ||
| 6 | #include <cstdint> | ||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "borunov_v_cnt_words/common/include/common.hpp" | ||
| 11 | |||
| 12 | namespace borunov_v_cnt_words { | ||
| 13 | |||
| 14 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | BorunovVCntWordsMPI::BorunovVCntWordsMPI(const InType &in) { |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | GetInput() = in; | ||
| 17 | 16 | GetOutput() = 0; | |
| 18 | 16 | } | |
| 19 | |||
| 20 | 16 | bool BorunovVCntWordsMPI::ValidationImpl() { | |
| 21 | 16 | return true; | |
| 22 | } | ||
| 23 | |||
| 24 | 16 | bool BorunovVCntWordsMPI::PreProcessingImpl() { | |
| 25 | 16 | return true; | |
| 26 | } | ||
| 27 | |||
| 28 | 14 | void BorunovVCntWordsMPI::CalculateDistribution(int text_len, int world_size, std::vector<int> &counts, | |
| 29 | std::vector<int> &displs) { | ||
| 30 | 14 | counts.resize(world_size); | |
| 31 | 14 | displs.resize(world_size); | |
| 32 | |||
| 33 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | if (world_size == 0) { |
| 34 | return; | ||
| 35 | } | ||
| 36 | |||
| 37 | 14 | int base_count = text_len / world_size; | |
| 38 | 14 | int remainder = text_len % world_size; | |
| 39 | int current_displ = 0; | ||
| 40 | |||
| 41 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
|
42 | for (int i = 0; i < world_size; ++i) { |
| 42 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
|
52 | counts[i] = base_count + (i < remainder ? 1 : 0); |
| 43 | 28 | displs[i] = current_displ; | |
| 44 | 28 | current_displ += counts[i]; | |
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | 15 | uint64_t BorunovVCntWordsMPI::CountWordsLocal(const char *data, int count, char prev_char) { | |
| 49 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
|
15 | if (count == 0) { |
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | uint64_t local_cnt = 0; | ||
| 54 | |||
| 55 |
2/2✓ Branch 0 taken 102 times.
✓ Branch 1 taken 14 times.
|
116 | for (int i = 0; i < count; ++i) { |
| 56 | 102 | auto current = static_cast<unsigned char>(data[i]); | |
| 57 | |||
| 58 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 34 times.
|
102 | if (std::isspace(current) == 0) { |
| 59 | unsigned char prev = 0; | ||
| 60 | |||
| 61 |
2/2✓ Branch 0 taken 59 times.
✓ Branch 1 taken 9 times.
|
68 | if (i == 0) { |
| 62 | prev = static_cast<unsigned char>(prev_char); | ||
| 63 | } else { | ||
| 64 | 59 | prev = static_cast<unsigned char>(data[i - 1]); | |
| 65 | } | ||
| 66 | |||
| 67 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 50 times.
|
68 | if (std::isspace(prev) != 0) { |
| 68 | 18 | local_cnt++; | |
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | return local_cnt; | ||
| 73 | } | ||
| 74 | |||
| 75 | 16 | bool BorunovVCntWordsMPI::RunImpl() { | |
| 76 | 16 | int rank = 0; | |
| 77 | 16 | int world_size = 0; | |
| 78 | 16 | MPI_Comm_rank(MPI_COMM_WORLD, &rank); | |
| 79 | 16 | MPI_Comm_size(MPI_COMM_WORLD, &world_size); | |
| 80 | |||
| 81 | 16 | int text_len = 0; | |
| 82 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (rank == 0) { |
| 83 | 8 | text_len = static_cast<int>(GetInput().size()); | |
| 84 | } | ||
| 85 | |||
| 86 | 16 | MPI_Bcast(&text_len, 1, MPI_INT, 0, MPI_COMM_WORLD); | |
| 87 | |||
| 88 | 16 | uint64_t global_result = 0; | |
| 89 | |||
| 90 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 14 times.
|
16 | if (text_len < world_size) { |
| 91 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (rank == 0) { |
| 92 | 1 | global_result = CountWordsLocal(GetInput().data(), text_len, ' '); | |
| 93 | } | ||
| 94 | 2 | MPI_Bcast(&global_result, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); | |
| 95 | 2 | GetOutput() = global_result; | |
| 96 | 2 | return true; | |
| 97 | } | ||
| 98 | |||
| 99 | 14 | std::vector<int> send_counts; | |
| 100 | 14 | std::vector<int> displs; | |
| 101 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | CalculateDistribution(text_len, world_size, send_counts, displs); |
| 102 | |||
| 103 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | int local_count = send_counts[rank]; |
| 104 |
1/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
14 | std::vector<char> local_data(local_count); |
| 105 | |||
| 106 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | const char *send_buf = (rank == 0) ? GetInput().data() : nullptr; |
| 107 | |||
| 108 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Scatterv(send_buf, send_counts.data(), displs.data(), MPI_CHAR, local_data.data(), local_count, MPI_CHAR, 0, |
| 109 | MPI_COMM_WORLD); | ||
| 110 | |||
| 111 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | int left_neighbor = (rank == 0) ? MPI_PROC_NULL : rank - 1; |
| 112 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | int right_neighbor = (rank == world_size - 1) ? MPI_PROC_NULL : rank + 1; |
| 113 | |||
| 114 | 14 | char char_to_send = ' '; | |
| 115 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | if (local_count > 0) { |
| 116 | 14 | char_to_send = local_data.back(); | |
| 117 | } | ||
| 118 | |||
| 119 | 14 | char prev_char = ' '; | |
| 120 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Sendrecv(&char_to_send, 1, MPI_CHAR, right_neighbor, 0, &prev_char, 1, MPI_CHAR, left_neighbor, 0, MPI_COMM_WORLD, |
| 121 | MPI_STATUS_IGNORE); | ||
| 122 | |||
| 123 | 14 | uint64_t local_result = 0; | |
| 124 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | if (local_count > 0) { |
| 125 | 14 | local_result = CountWordsLocal(local_data.data(), local_count, prev_char); | |
| 126 | } | ||
| 127 | |||
| 128 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Reduce(&local_result, &global_result, 1, MPI_UINT64_T, MPI_SUM, 0, MPI_COMM_WORLD); |
| 129 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | MPI_Bcast(&global_result, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD); |
| 130 | |||
| 131 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | GetOutput() = global_result; |
| 132 | |||
| 133 | return true; | ||
| 134 | } | ||
| 135 | |||
| 136 | 16 | bool BorunovVCntWordsMPI::PostProcessingImpl() { | |
| 137 | 16 | return true; | |
| 138 | } | ||
| 139 | |||
| 140 | } // namespace borunov_v_cnt_words | ||
| 141 |