GCC Code Coverage Report


Directory: ./
File: tasks/vdovin_a_words_counting/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 60 60 100.0%
Functions: 6 6 100.0%
Branches: 60 86 69.8%

Line Branch Exec Source
1 #include "vdovin_a_words_counting/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <array>
6 #include <cstddef>
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "vdovin_a_words_counting/common/include/common.hpp"
12
13 namespace vdovin_a_words_counting {
14
15 namespace {
16 6 std::pair<int, std::array<char, 2>> CountWordsInRange(const std::string &input, std::size_t begin, std::size_t end) {
17 int counter = 0;
18 bool on_word = false;
19
2/2
✓ Branch 0 taken 6529 times.
✓ Branch 1 taken 6 times.
6535 for (std::size_t i = begin; i < end; ++i) {
20
4/4
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 5521 times.
✓ Branch 2 taken 1005 times.
✓ Branch 3 taken 3 times.
6529 if (input[i] == ' ' && on_word) {
21 1005 ++counter;
22 on_word = false;
23
2/2
✓ Branch 0 taken 5521 times.
✓ Branch 1 taken 3 times.
5524 } else if (input[i] != ' ') {
24 on_word = true;
25 }
26 }
27
28 std::array<char, 2> flags = {0, 0};
29
3/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 3 times.
6 if (!input.empty() && input[begin] != ' ') {
30 flags[0] = 1;
31 }
32
3/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
6 if (!input.empty() && input[end - 1] != ' ') {
33 5 ++counter;
34 flags[1] = 1;
35 }
36
37 6 return {counter, flags};
38 }
39
40 void ComputeSendCountsAndDispls(const std::string &input, int size, std::vector<int> &send_counts,
41 std::vector<int> &send_displs) {
42 3 const std::size_t chunk = input.size() / static_cast<std::size_t>(size);
43
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (int i = 0; i < size; ++i) {
44
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 send_displs[i] = static_cast<int>(chunk * static_cast<std::size_t>(i));
45
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (i == size - 1) {
46 3 send_counts[i] = static_cast<int>(input.size()) - send_displs[i];
47 } else {
48 3 send_counts[i] = static_cast<int>(chunk);
49 }
50 }
51 }
52
53 void ProcessBoundaryFlagMatching(const std::vector<char> &all_flags, int size, int &counter_sum) {
54
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (int i = 1; i < size; ++i) {
55
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 const std::size_t prev_end_idx = (static_cast<std::size_t>(i) * 2U) - 1U;
56 const std::size_t curr_begin_idx = prev_end_idx + 1U;
57
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
3 if ((all_flags[prev_end_idx] == 1) && (all_flags[curr_begin_idx] == 1)) {
58 2 --counter_sum;
59 }
60 }
61 }
62 } // namespace
63
64
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 VdovinAWordsCountingMPI::VdovinAWordsCountingMPI(const InType &in) {
65 SetTypeOfTask(GetStaticTypeOfTask());
66 GetInput() = in;
67 6 GetOutput() = 0;
68 6 }
69
70
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 bool VdovinAWordsCountingMPI::ValidationImpl() {
71
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 return (!GetInput().empty()) && (GetOutput() == 0);
72 }
73
74 6 bool VdovinAWordsCountingMPI::PreProcessingImpl() {
75 6 return true;
76 }
77
78 6 bool VdovinAWordsCountingMPI::RunImpl() {
79 6 int rank = 0;
80 6 int size = 0;
81 6 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
82 6 MPI_Comm_size(MPI_COMM_WORLD, &size);
83
84 std::string input;
85
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 std::vector<int> send_counts(size, 0);
86
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> send_displs(size, 0);
87
88
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
89 input = GetInput();
90
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (input.empty()) {
91 return false;
92 }
93 3 ComputeSendCountsAndDispls(input, size, send_counts, send_displs);
94 }
95
96
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(send_counts.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
97
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(send_displs.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
98
99
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 int local_size = send_counts[rank];
100
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<char> local_data(local_size);
101
102 6 std::vector<char> input_chars;
103
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
104 3 input_chars.assign(input.begin(), input.end());
105 }
106
107
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
6 MPI_Scatterv(input_chars.empty() && rank == 0 ? nullptr : input_chars.data(), send_counts.data(), send_displs.data(),
108 MPI_CHAR, local_data.data(), local_size, MPI_CHAR, 0, MPI_COMM_WORLD);
109
110
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 std::string local_input(local_data.begin(), local_data.end());
111
112 6 auto [counter, flags] = CountWordsInRange(local_input, 0, local_input.size());
113 6 std::array<char, 2> local_flags = flags;
114
115 6 std::vector<char> all_flags;
116
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
117
1/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 all_flags.resize(static_cast<std::size_t>(2) * static_cast<std::size_t>(size), 0);
118 }
119
120
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
9 MPI_Gather(local_flags.data(), 2, MPI_CHAR, (rank == 0 ? all_flags.data() : nullptr), 2, MPI_CHAR, 0, MPI_COMM_WORLD);
121
122 6 int counter_sum = 0;
123
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Reduce(&counter, &counter_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
124
125
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (rank == 0) {
126 3 ProcessBoundaryFlagMatching(all_flags, size, counter_sum);
127 3 GetOutput() = counter_sum;
128 }
129
130
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(&counter_sum, 1, MPI_INT, 0, MPI_COMM_WORLD);
131
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 GetOutput() = counter_sum;
132 return true;
133 }
134
135 6 bool VdovinAWordsCountingMPI::PostProcessingImpl() {
136 6 return true;
137 }
138
139 } // namespace vdovin_a_words_counting
140