GCC Code Coverage Report


Directory: ./
File: tasks/zenin_a_sum_values_by_columns_matrix/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 61 62 98.4%
Functions: 6 6 100.0%
Branches: 44 74 59.5%

Line Branch Exec Source
1 #include "zenin_a_sum_values_by_columns_matrix/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstddef>
7 #include <stdexcept>
8 #include <tuple>
9 #include <utility>
10 #include <vector>
11
12 #include "zenin_a_sum_values_by_columns_matrix/common/include/common.hpp"
13
14 namespace zenin_a_sum_values_by_columns_matrix {
15
16
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 ZeninASumValuesByColumnsMatrixMPI::ZeninASumValuesByColumnsMatrixMPI(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 30 GetOutput() = OutType{};
20 30 }
21
22 30 bool ZeninASumValuesByColumnsMatrixMPI::ValidationImpl() {
23 auto &input = GetInput();
24
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 return ((std::get<0>(input)) * std::get<1>(input) == std::get<2>(input).size() && (GetOutput().empty()));
25 }
26
27 30 bool ZeninASumValuesByColumnsMatrixMPI::PreProcessingImpl() {
28 30 int rank = 0;
29 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
30
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank != 0) {
31 return true;
32 }
33 GetOutput().clear();
34 return true;
35 }
36
37 15 void ZeninASumValuesByColumnsMatrixMPI::FillSendBuffer(const std::vector<double> &mat, std::vector<double> &sendbuf,
38 size_t rows, size_t cols, size_t base, size_t rest,
39 int world_size) {
40 size_t pos = 0;
41
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
45 for (int proc = 0; proc < world_size; proc++) {
42 30 auto proc_size = static_cast<size_t>(proc);
43 30 size_t pc_begin = (proc_size * base) + (std::cmp_less(proc_size, rest) ? proc_size : rest);
44
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 size_t pc_end = pc_begin + (base + (std::cmp_less(proc_size, rest) ? 1 : 0));
45
2/2
✓ Branch 0 taken 11697 times.
✓ Branch 1 taken 30 times.
11727 for (size_t col = pc_begin; col < pc_end; col++) {
46
2/2
✓ Branch 0 taken 1061987 times.
✓ Branch 1 taken 11697 times.
1073684 for (size_t row = 0; row < rows; row++) {
47 1061987 sendbuf[pos++] = mat[(row * cols) + col];
48 }
49 }
50 }
51 15 }
52
53 30 bool ZeninASumValuesByColumnsMatrixMPI::RunImpl() {
54 30 auto rows = static_cast<size_t>(std::get<0>(GetInput()));
55 30 auto cols = static_cast<size_t>(std::get<1>(GetInput()));
56 const std::vector<double> &mat = std::get<2>(GetInput());
57
58 std::vector<double> &global_sum = GetOutput();
59
60 30 int rank = 0;
61 30 int world_size = 0;
62
63 30 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
64 30 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
65
66 30 const size_t base = cols / static_cast<size_t>(world_size);
67 30 const size_t rest = cols % static_cast<size_t>(world_size);
68
69
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 const size_t my_cols = base + (std::cmp_less(static_cast<size_t>(rank), rest) ? 1 : 0);
70
71 30 std::vector<int> sendcounts(static_cast<size_t>(world_size));
72
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<int> displs(static_cast<size_t>(world_size));
73
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
74 int offset = 0;
75
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
45 for (int proc = 0; proc < world_size; proc++) {
76
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 size_t pc = base + (std::cmp_less(static_cast<size_t>(proc), rest) ? 1 : 0);
77 30 sendcounts[proc] = static_cast<int>(pc * rows);
78 30 displs[proc] = offset;
79 30 offset += sendcounts[proc];
80 }
81 }
82
83 30 std::vector<double> sendbuf;
84
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
85
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 sendbuf.resize(rows * cols);
86 15 FillSendBuffer(mat, sendbuf, rows, cols, base, rest, world_size);
87 }
88
2/6
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
30 std::vector<double> local_block(rows * my_cols);
89
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_DOUBLE, local_block.data(),
90 static_cast<int>(local_block.size()), MPI_DOUBLE, 0, MPI_COMM_WORLD);
91
92
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<double> local_sum(my_cols, 0.0);
93
2/2
✓ Branch 0 taken 11697 times.
✓ Branch 1 taken 30 times.
11727 for (size_t col_id = 0; col_id < my_cols; col_id++) {
94
2/2
✓ Branch 0 taken 1061987 times.
✓ Branch 1 taken 11697 times.
1073684 for (size_t row_id = 0; row_id < rows; row_id++) {
95 1061987 local_sum[col_id] += local_block[(col_id * rows) + row_id];
96 }
97 }
98
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<int> recvcounts(static_cast<size_t>(world_size));
99
1/4
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
30 std::vector<int> recvdispls(static_cast<size_t>(world_size));
100
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (rows == 0) {
102 throw std::runtime_error("Matrix has zero rows");
103 }
104
105
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
30 if (rank == 0) {
106 size_t offset = 0;
107
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 15 times.
45 for (int proc = 0; proc < world_size; proc++) {
108 30 recvcounts[proc] = sendcounts[proc] / static_cast<int>(rows);
109 30 recvdispls[proc] = static_cast<int>(offset);
110 30 offset += static_cast<size_t>(recvcounts[proc]);
111 }
112
1/4
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
15 global_sum.assign(cols, 0.0);
113 }
114
115
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 MPI_Gatherv(local_sum.data(), static_cast<int>(my_cols), MPI_DOUBLE, global_sum.data(), recvcounts.data(),
116 recvdispls.data(), MPI_DOUBLE, 0, MPI_COMM_WORLD);
117
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 global_sum.resize(cols);
118
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 MPI_Bcast(global_sum.data(), static_cast<int>(cols), MPI_DOUBLE, 0, MPI_COMM_WORLD);
119 30 return true;
120 }
121
122 30 bool ZeninASumValuesByColumnsMatrixMPI::PostProcessingImpl() {
123 30 return true;
124 }
125
126 } // namespace zenin_a_sum_values_by_columns_matrix
127