GCC Code Coverage Report


Directory: ./
File: tasks/timofeev_n_ribbon_scheme_only_a/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 92 115 80.0%
Functions: 11 13 84.6%
Branches: 68 130 52.3%

Line Branch Exec Source
1 #include "timofeev_n_ribbon_scheme_only_a/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <vector>
7
8 #include "timofeev_n_ribbon_scheme_only_a/common/include/common.hpp"
9
10 namespace timofeev_n_ribbon_scheme_only_a {
11
12
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 TimofeevNRibbonSchemeOnlyAMPI::TimofeevNRibbonSchemeOnlyAMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14 GetInput() = in;
15
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 GetOutput() = std::vector<std::vector<int>>(0, std::vector<int>(0));
16 32 }
17
18
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 bool TimofeevNRibbonSchemeOnlyAMPI::ValidationImpl() {
19 std::vector<std::vector<int>> &a = GetInput().first;
20 std::vector<std::vector<int>> &b = GetInput().second;
21 size_t n = a.size();
22 size_t m2 = a[0].size();
23 size_t m1 = b.size();
24 size_t k = b[0].size();
25
3/6
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 32 times.
32 return (m2 == m1 && n != 0 && m1 != 0 && m2 != 0 && k != 0);
26 }
27
28 32 bool TimofeevNRibbonSchemeOnlyAMPI::PreProcessingImpl() {
29 32 return true;
30 }
31
32
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 void TimofeevNRibbonSchemeOnlyAMPI::SendingAParts(MatrixType &a, int &size, size_t k) {
33
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (a.empty()) {
34 return;
35 }
36 size_t a_row_size = a[0].size();
37 size_t a_size = a.size();
38 size_t i = 0;
39 size_t iter = 0;
40 16 std::vector<size_t> sizes(size - 1, 0);
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 for (size_t p_ind = 0; p_ind < sizes.size() - 1; p_ind++) {
42 sizes[p_ind] = (a_size >= k ? k : 0);
43 if (a_size >= k) {
44 a_size -= k;
45 iter++;
46 }
47 }
48 16 sizes[size - 2] = a_size;
49 iter = 0;
50
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for (; i < sizes.size(); i++) {
51
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Send(&sizes[i], 1, MPI_UNSIGNED_LONG, static_cast<int>(i + 1), 0, MPI_COMM_WORLD);
52
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t j = 0; j < sizes[i]; j++) {
53
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Send(a[iter].data(), static_cast<int>(a_row_size), MPI_INT, static_cast<int>(i + 1), 0, MPI_COMM_WORLD);
54 37 iter++;
55 }
56 }
57 }
58
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 void TimofeevNRibbonSchemeOnlyAMPI::ReceivingCParts(MatrixType &cmatr, int &size, size_t k, size_t &b_row_size) {
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (cmatr.empty()) {
61 return;
62 }
63 size_t c_size = cmatr.size();
64 size_t i = 0;
65 size_t iter = 0;
66 16 std::vector<size_t> sizes(size - 1, 0);
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 for (size_t p_ind = 0; p_ind < sizes.size() - 1; p_ind++) {
68 sizes[p_ind] = (c_size >= k ? k : 0);
69 if (c_size >= k) {
70 c_size -= k;
71 iter++;
72 }
73 }
74 16 sizes[size - 2] = c_size;
75 iter = 0;
76
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 for (; i < sizes.size(); i++) {
77
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t j = 0; j < sizes[i]; j++) {
78
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Recv(cmatr[iter].data(), static_cast<int>(b_row_size), MPI_INT, static_cast<int>(i + 1), 1, MPI_COMM_WORLD,
79 MPI_STATUS_IGNORE);
80 37 iter++;
81 }
82 }
83 }
84
85 105 int TimofeevNRibbonSchemeOnlyAMPI::CalculatingCElement(MatrixType &a_part, MatrixType &b_copy, size_t &i, size_t &j) {
86 int summ = 0;
87
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 105 times.
465 for (size_t kk = 0; kk < a_part[0].size(); kk++) {
88 360 summ += a_part[i][kk] * b_copy[kk][j];
89 }
90 105 return summ;
91 }
92
93 16 void TimofeevNRibbonSchemeOnlyAMPI::CalculatingCPart(size_t &k, MatrixType &a_part, MatrixType &b_copy,
94 MatrixType &c_part) {
95
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t i = 0; i < k; i++) {
96
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 37 times.
142 for (size_t j = 0; j < b_copy[0].size(); j++) {
97 105 c_part[i][j] = CalculatingCElement(a_part, b_copy, i, j);
98 }
99 }
100 16 }
101
102 32 void TimofeevNRibbonSchemeOnlyAMPI::BroadcastingParameters(size_t &a_size, size_t &a_row_size, size_t &b_size,
103 size_t &b_row_size) {
104 32 MPI_Bcast(&a_size, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
105 32 MPI_Bcast(&a_row_size, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
106 32 MPI_Bcast(&b_size, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
107 32 MPI_Bcast(&b_row_size, 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD);
108 32 }
109
110
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 void TimofeevNRibbonSchemeOnlyAMPI::BroadcastingB(MatrixType &b) {
111
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (b.empty() || b[0].empty()) {
112 return;
113 }
114 size_t b_row_size = b[0].size();
115
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 32 times.
130 for (auto &i : b) {
116 98 MPI_Bcast(i.data(), static_cast<int>(b_row_size), MPI_INT, 0, MPI_COMM_WORLD);
117 }
118 }
119
120 int TimofeevNRibbonSchemeOnlyAMPI::CalculatingCElementOneProcess(MatrixType &a, MatrixType &b, size_t &i, size_t &j) {
121 int summ = 0;
122 for (size_t kk = 0; kk < b.size(); kk++) {
123 summ += a[i][kk] * b[kk][j];
124 }
125 return summ;
126 }
127
128 void TimofeevNRibbonSchemeOnlyAMPI::CalculatingCOneProcess(MatrixType &a, MatrixType &b, MatrixType &c) {
129 for (size_t i = 0; i < a.size(); i++) {
130 c[i].resize(b[0].size());
131 for (size_t j = 0; j < b[0].size(); j++) {
132 c[i][j] = CalculatingCElementOneProcess(a, b, i, j);
133 }
134 }
135 }
136
137 32 bool TimofeevNRibbonSchemeOnlyAMPI::RunImpl() {
138 32 int rank = 0;
139 32 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
140 32 int size = 0;
141 32 MPI_Comm_size(MPI_COMM_WORLD, &size);
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (size == 1) {
143 MatrixType a = GetInput().first;
144 MatrixType b = GetInput().second;
145 GetOutput().resize(a.size());
146 CalculatingCOneProcess(a, b, GetOutput());
147 return true;
148 }
149
150
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (rank == 0) {
151 16 MatrixType a = GetInput().first;
152
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MatrixType b = GetInput().second;
153 size_t k = 0;
154
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 k = (a.size() / static_cast<size_t>(size - 1)) + (a.size() % static_cast<size_t>(size - 1) > 0 ? 1 : 0);
155
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 size_t a_size = a.size();
156 16 size_t a_row_size = a[0].size();
157 16 size_t b_size = b.size();
158 16 size_t b_row_size = b[0].size();
159
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BroadcastingParameters(a_size, a_row_size, b_size, b_row_size);
160
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BroadcastingB(b);
161
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 SendingAParts(a, size, k);
162
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 std::vector<std::vector<int>> cmatr(a.size(), std::vector<int>(b_row_size));
163
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 ReceivingCParts(cmatr, size, k, b_row_size);
164
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (auto &i : cmatr) { // рассылка того, что получилось
165
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Bcast(i.data(), static_cast<int>(b_row_size), MPI_INT, 0, MPI_COMM_WORLD);
166 }
167
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetOutput() = cmatr;
168 16 } else {
169 16 size_t k = 0;
170 16 size_t a_size = 0;
171 16 size_t a_row_size = 0;
172 16 size_t b_size = 0;
173 16 size_t b_row_size = 0;
174 16 BroadcastingParameters(a_size, a_row_size, b_size, b_row_size);
175
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 std::vector<std::vector<int>> b_copy(b_size, std::vector<int>(b_row_size));
176
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 BroadcastingB(b_copy);
177
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Recv(&k, 1, MPI_UNSIGNED_LONG, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
178
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 std::vector<std::vector<int>> a_part(k, std::vector<int>(a_row_size));
179
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t j = 0; j < k; j++) { // принимаем строки A
180
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Recv(a_part[j].data(), static_cast<int>(a_row_size), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
181 }
182
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 std::vector<std::vector<int>> c_part(k, std::vector<int>(b_row_size));
183 16 CalculatingCPart(k, a_part, b_copy, c_part); // можем вычислить k строк (k * b_row_size элементов) матрицы C
184
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t i = 0; i < k; i++) { // у нас есть матрица k * b_row_size
185
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Send(c_part[i].data(), static_cast<int>(b_row_size), MPI_INT, 0, 1, MPI_COMM_WORLD);
186 }
187
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetOutput().resize(a_size);
188
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (size_t i = 0; i < a_size; i++) { // принимает результат из Bcast
189
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 GetOutput()[i].resize(b_row_size);
190
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 MPI_Bcast(GetOutput()[i].data(), static_cast<int>(b_row_size), MPI_INT, 0, MPI_COMM_WORLD);
191 }
192 16 }
193 32 MPI_Barrier(MPI_COMM_WORLD);
194 return true;
195 }
196
197 32 bool TimofeevNRibbonSchemeOnlyAMPI::PostProcessingImpl() {
198 32 return true;
199 }
200
201 } // namespace timofeev_n_ribbon_scheme_only_a
202