GCC Code Coverage Report


Directory: ./
File: tasks/gasenin_l_lex_dif/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 61 61 100.0%
Functions: 5 5 100.0%
Branches: 51 72 70.8%

Line Branch Exec Source
1 #include "gasenin_l_lex_dif/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <string>
8 #include <vector>
9
10 #include "gasenin_l_lex_dif/common/include/common.hpp"
11
12 namespace {
13
14 struct LocalDiff {
15 size_t diff_pos;
16 int result;
17 };
18
19 LocalDiff FindLocalDifference(const std::vector<char> &s1_chunk, const std::vector<char> &s2_chunk,
20 size_t global_start) {
21
2/2
✓ Branch 0 taken 20024 times.
✓ Branch 1 taken 13 times.
20037 for (size_t i = 0; i < s1_chunk.size(); ++i) {
22
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 20015 times.
20024 if (s1_chunk[i] != s2_chunk[i]) {
23
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 return {.diff_pos = global_start + i, .result = (s1_chunk[i] < s2_chunk[i]) ? -1 : 1};
24 }
25 }
26 return {.diff_pos = std::string::npos, .result = 0};
27 }
28
29 void CalculateDistribution(int min_len, int size, std::vector<int> &sendcounts, std::vector<int> &displs) {
30 22 int remainder = min_len % size;
31 22 int chunk_size = min_len / size;
32 int prefix_sum = 0;
33
34
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 22 times.
66 for (int i = 0; i < size; ++i) {
35
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 10 times.
78 sendcounts[i] = chunk_size + (i < remainder ? 1 : 0);
36 44 displs[i] = prefix_sum;
37 44 prefix_sum += sendcounts[i];
38 }
39 }
40
41 int GetFinalResultByLength(int len1, int len2) {
42
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 if (len1 < len2) {
43 return -1;
44 }
45
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (len1 > len2) {
46 2 return 1;
47 }
48 return 0;
49 }
50
51 } // namespace
52
53 namespace gasenin_l_lex_dif {
54
55
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 GaseninLLexDifMPI::GaseninLLexDifMPI(const InType &in) {
56 SetTypeOfTask(GetStaticTypeOfTask());
57 GetInput() = in;
58 24 GetOutput() = 0;
59 24 }
60
61 24 bool GaseninLLexDifMPI::ValidationImpl() {
62 24 int rank = 0;
63 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
64
65
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
66 const auto &[str1, str2] = GetInput();
67
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 return str1.length() <= 100000000 && str2.length() <= 100000000;
68 }
69 return true;
70 }
71
72 24 bool GaseninLLexDifMPI::PreProcessingImpl() {
73 24 return true;
74 }
75
76 24 bool GaseninLLexDifMPI::RunImpl() {
77 24 int rank = 0;
78 24 int size = 0;
79 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
80 24 MPI_Comm_size(MPI_COMM_WORLD, &size);
81
82 const auto &input_data = GetInput();
83 const std::string &str1 = input_data.first;
84 const std::string &str2 = input_data.second;
85
86 24 std::vector<int> lengths(2, 0);
87
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 if (rank == 0) {
88 12 lengths[0] = static_cast<int>(str1.length());
89 12 lengths[1] = static_cast<int>(str2.length());
90 }
91
92
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 MPI_Bcast(lengths.data(), 2, MPI_INT, 0, MPI_COMM_WORLD);
93
94 24 int len1 = lengths[0];
95
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 18 times.
24 int len2 = lengths[1];
96 int min_len = std::min(len1, len2);
97
98
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4 times.
24 if (min_len == 0 && len1 == len2) {
99 2 GetOutput() = 0;
100 2 return true;
101 }
102
103
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> sendcounts(size);
104
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<int> displs(size);
105 22 CalculateDistribution(min_len, size, sendcounts, displs);
106
107
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 int local_count = sendcounts[rank];
108 22 auto global_start = static_cast<size_t>(displs[rank]);
109
110
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<char> local_str1(local_count);
111
1/4
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
22 std::vector<char> local_str2(local_count);
112
113
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 const char *sendbuf1 = (rank == 0) ? str1.data() : nullptr;
114
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 const char *sendbuf2 = (rank == 0) ? str2.data() : nullptr;
115
116
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Scatterv(sendbuf1, sendcounts.data(), displs.data(), MPI_CHAR, local_str1.data(), local_count, MPI_CHAR, 0,
117 MPI_COMM_WORLD);
118
119
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Scatterv(sendbuf2, sendcounts.data(), displs.data(), MPI_CHAR, local_str2.data(), local_count, MPI_CHAR, 0,
120 MPI_COMM_WORLD);
121
122 LocalDiff local_diff = FindLocalDifference(local_str1, local_str2, global_start);
123
124
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 13 times.
22 int local_diff_pos_int = (local_diff.diff_pos == std::string::npos) ? min_len : static_cast<int>(local_diff.diff_pos);
125 22 int global_min_pos_int = min_len;
126
127
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Allreduce(&local_diff_pos_int, &global_min_pos_int, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
128
129 22 int result_for_sum = 0;
130
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 10 times.
22 if (local_diff_pos_int == global_min_pos_int && local_diff_pos_int < min_len) {
131 6 result_for_sum = local_diff.result;
132 }
133
134 22 int final_result = 0;
135
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 MPI_Allreduce(&result_for_sum, &final_result, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
136
137
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 12 times.
22 if (global_min_pos_int == min_len) {
138 10 final_result = GetFinalResultByLength(len1, len2);
139 }
140
141
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 4 times.
22 GetOutput() = final_result;
142 return true;
143 }
144
145 24 bool GaseninLLexDifMPI::PostProcessingImpl() {
146 24 return true;
147 }
148
149 } // namespace gasenin_l_lex_dif
150