GCC Code Coverage Report


Directory: ./
File: tasks/polukhin_v_string_diff/mpi/src/ops_mpi.cpp
Date: 2026-02-02 01:14:38
Exec Total Coverage
Lines: 69 69 100.0%
Functions: 9 9 100.0%
Branches: 38 62 61.3%

Line Branch Exec Source
1 #include "polukhin_v_string_diff/mpi/include/ops_mpi.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <cstdint>
7 #include <string>
8 #include <vector>
9
10 #include "mpi.h"
11 #include "polukhin_v_string_diff/common/include/common.hpp"
12
13 namespace polukhin_v_string_diff {
14
15
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 StringDiffTaskMPI::StringDiffTaskMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17 GetInput() = in;
18 22 GetOutput() = 0;
19 22 }
20
21 22 bool StringDiffTaskMPI::ValidationImpl() {
22 22 return true;
23 }
24 22 bool StringDiffTaskMPI::PreProcessingImpl() {
25 22 return true;
26 }
27 22 bool StringDiffTaskMPI::PostProcessingImpl() {
28 22 return true;
29 }
30
31 namespace {
32
33 22 void BroadcastStringLengths(int rank, int &len1, int &len2) {
34 if (rank == 0) {
35 }
36 22 MPI_Bcast(&len1, 1, MPI_INT, 0, MPI_COMM_WORLD);
37 22 MPI_Bcast(&len2, 1, MPI_INT, 0, MPI_COMM_WORLD);
38 22 }
39
40 18 void PrepareDataDistribution(int rank, int size, int min_len, std::vector<int> &sendcounts, std::vector<int> &displs) {
41
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank != 0) {
42 return;
43 }
44
45 std::ranges::fill(sendcounts, 0);
46 std::ranges::fill(displs, 0);
47
48 9 const int els_per_process = (min_len + size - 1) / size;
49 int offset = 0;
50
51
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9 times.
27 for (int i = 0; i < size; ++i) {
52 18 const int start = i * els_per_process;
53
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 const int end = std::min(start + els_per_process, min_len);
54
55
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (start < min_len) {
56 18 sendcounts[i] = end - start;
57 }
58
59
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 displs[i] = offset;
60
61
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (start < min_len) {
62 18 offset += sendcounts[i];
63 }
64 }
65 }
66
67 uint64_t ComputeLocalDifferences(const std::vector<char> &local_str1, const std::vector<char> &local_str2) {
68 uint64_t local_count = 0;
69 const size_t recvcount = local_str1.size();
70
71
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 18 times.
62 for (size_t i = 0; i < recvcount; ++i) {
72
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 22 times.
44 if (local_str1[i] != local_str2[i]) {
73 22 ++local_count;
74 }
75 }
76 return local_count;
77 }
78
79 18 void DistributeStrings(int rank, int recvcount, const std::vector<int> &sendcounts, const std::vector<int> &displs,
80 const std::string &str1, const std::string &str2, std::vector<char> &local_str1,
81 std::vector<char> &local_str2) {
82
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (recvcount <= 0) {
83 return;
84 }
85
86
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
27 MPI_Scatterv(rank == 0 ? str1.data() : nullptr, sendcounts.data(), displs.data(), MPI_CHAR, local_str1.data(),
87 recvcount, MPI_CHAR, 0, MPI_COMM_WORLD);
88
89
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
27 MPI_Scatterv(rank == 0 ? str2.data() : nullptr, sendcounts.data(), displs.data(), MPI_CHAR, local_str2.data(),
90 recvcount, MPI_CHAR, 0, MPI_COMM_WORLD);
91 }
92
93 22 void CollectAndSetResults(int rank, uint64_t local_count, int length_diff, size_t &output) {
94 22 uint64_t total_count = 0;
95 22 MPI_Reduce(&local_count, &total_count, 1, MPI_UINT64_T, MPI_SUM, 0, MPI_COMM_WORLD);
96
97
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
98 11 total_count += static_cast<uint64_t>(length_diff);
99 11 output = static_cast<size_t>(total_count);
100 }
101
102 11 uint64_t result = 0;
103 if (rank == 0) {
104 11 result = total_count;
105 }
106 22 MPI_Bcast(&result, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
107
108
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank != 0) {
109 11 output = static_cast<size_t>(result);
110 }
111 22 }
112
113 } // namespace
114
115 22 bool StringDiffTaskMPI::RunImpl() {
116 22 int rank = 0;
117 22 int size = 0;
118 22 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
119 22 MPI_Comm_size(MPI_COMM_WORLD, &size);
120
121 std::string str1;
122 std::string str2;
123 22 int len1 = 0;
124 22 int len2 = 0;
125
126
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 if (rank == 0) {
127 const auto &input = GetInput();
128
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 str1 = input.first;
129
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 str2 = input.second;
130 11 len1 = static_cast<int>(str1.size());
131 11 len2 = static_cast<int>(str2.size());
132 }
133
134
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 BroadcastStringLengths(rank, len1, len2);
135
136 const int min_len = std::min(len1, len2);
137 22 const int length_diff = std::abs(len1 - len2);
138
139 uint64_t local_count = 0;
140
141
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 4 times.
22 if (min_len > 0) {
142
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 std::vector<int> sendcounts(size, 0);
143
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<int> displs(size, 0);
144
145 18 PrepareDataDistribution(rank, size, min_len, sendcounts, displs);
146
147
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 int recvcount = 0;
148
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recvcount, 1, MPI_INT, 0, MPI_COMM_WORLD);
149
150
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (recvcount > 0) {
151
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<char> local_str1(recvcount);
152
1/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
18 std::vector<char> local_str2(recvcount);
153
154
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 DistributeStrings(rank, recvcount, sendcounts, displs, str1, str2, local_str1, local_str2);
155
156 local_count = ComputeLocalDifferences(local_str1, local_str2);
157 }
158 }
159
160
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 CollectAndSetResults(rank, local_count, length_diff, GetOutput());
161
162 22 return true;
163 }
164
165 } // namespace polukhin_v_string_diff
166