GCC Code Coverage Report


Directory: ./
File: tasks/akimov_i_words_string_count/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 63 63 100.0%
Functions: 5 5 100.0%
Branches: 37 52 71.2%

Line Branch Exec Source
1 #include "akimov_i_words_string_count/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cctype>
7 #include <cstddef>
8 #include <vector>
9
10 #include "akimov_i_words_string_count/common/include/common.hpp"
11
12 namespace akimov_i_words_string_count {
13
14 namespace {
15
16 inline bool IsSpaceChar(char ch) {
17
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ch == ' ' || ch == '\n' || ch == '\t';
18 }
19
20 int CountWordsInBuffer(const InType &buf) {
21 int count = 0;
22 bool in_word = false;
23
24
4/4
✓ Branch 0 taken 158 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 194 times.
✓ Branch 3 taken 2 times.
196 for (char c : buf) {
25 if (IsSpaceChar(c)) {
26 in_word = false;
27 } else {
28
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 131 times.
158 if (!in_word) {
29 27 count++;
30 in_word = true;
31 }
32 }
33 }
34 return count;
35 }
36
37 } // namespace
38
39
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 AkimovIWordsStringCountMPI::AkimovIWordsStringCountMPI(const InType &in) {
40 SetTypeOfTask(GetStaticTypeOfTask());
41
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 GetInput() = in;
42 2 GetOutput() = 0;
43 2 }
44
45 2 bool AkimovIWordsStringCountMPI::ValidationImpl() {
46 2 int rank = 0;
47 2 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
48
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (rank == 0) {
49
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return (!GetInput().empty()) && (GetOutput() == 0);
50 }
51 return true;
52 }
53
54 2 bool AkimovIWordsStringCountMPI::PreProcessingImpl() {
55 2 int rank = 0;
56 2 int size = 1;
57 2 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
58 2 MPI_Comm_size(MPI_COMM_WORLD, &size);
59
60 2 local_space_count_ = 0;
61 2 global_space_count_ = 0;
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 word_count_ = 0;
63 local_buffer_.clear();
64 input_buffer_.clear();
65
66 std::size_t total = 0;
67
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (rank == 0) {
68 1 input_buffer_ = GetInput();
69 total = input_buffer_.size();
70 }
71
72 2 int base = 0;
73 2 int remainder = 0;
74
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (rank == 0) {
75 1 base = static_cast<int>(total / static_cast<std::size_t>(size));
76 1 remainder = static_cast<int>(total % static_cast<std::size_t>(size));
77 }
78
79 2 MPI_Bcast(&base, 1, MPI_INT, 0, MPI_COMM_WORLD);
80 2 MPI_Bcast(&remainder, 1, MPI_INT, 0, MPI_COMM_WORLD);
81
82
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 int my_count = base + ((rank < remainder) ? 1 : 0);
83 2 local_buffer_.resize(my_count);
84
85 2 std::vector<int> counts(size);
86
1/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 std::vector<int> displs(size);
87
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < size; ++i) {
88
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 counts[i] = base + ((i < remainder) ? 1 : 0);
89 }
90 2 displs[0] = 0;
91
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for (int i = 1; i < size; ++i) {
92 2 displs[i] = displs[i - 1] + counts[i - 1];
93 }
94
95 const char *sendbuf = nullptr;
96
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 if (rank == 0 && !input_buffer_.empty()) {
97 sendbuf = input_buffer_.data();
98 }
99
100
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 MPI_Scatterv(sendbuf, counts.data(), displs.data(), MPI_CHAR, local_buffer_.data(), my_count, MPI_CHAR, 0,
101 MPI_COMM_WORLD);
102
103 2 return true;
104 }
105
106 2 bool AkimovIWordsStringCountMPI::RunImpl() {
107 2 int rank = 0;
108 2 int size = 1;
109 2 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
110 2 MPI_Comm_size(MPI_COMM_WORLD, &size);
111
112 2 int local_word_count = CountWordsInBuffer(local_buffer_);
113
114 2 char recv_prev_last = ' ';
115
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 char send_last = local_buffer_.empty() ? ' ' : local_buffer_.back();
116
117
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 int dest = (rank + 1 < size) ? rank + 1 : MPI_PROC_NULL;
118
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 int src = (rank - 1 >= 0) ? rank - 1 : MPI_PROC_NULL;
119
120 2 MPI_Sendrecv(&send_last, 1, MPI_CHAR, dest, 0, &recv_prev_last, 1, MPI_CHAR, src, 0, MPI_COMM_WORLD,
121 MPI_STATUS_IGNORE);
122
123
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!local_buffer_.empty()) {
124 2 char first_char = local_buffer_.front();
125
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (!IsSpaceChar(recv_prev_last) && !IsSpaceChar(first_char)) {
126 1 local_word_count = std::max(local_word_count - 1, 0);
127 }
128 }
129
130 2 MPI_Reduce(&local_word_count, &word_count_, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
131 2 MPI_Bcast(&word_count_, 1, MPI_INT, 0, MPI_COMM_WORLD);
132
133 2 GetOutput() = word_count_;
134
135 2 return true;
136 }
137
138 2 bool AkimovIWordsStringCountMPI::PostProcessingImpl() {
139 2 return true;
140 }
141
142 } // namespace akimov_i_words_string_count
143