GCC Code Coverage Report


Directory: ./
File: tasks/kopilov_d_sum_val_col_mat/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 48 49 98.0%
Functions: 5 5 100.0%
Branches: 28 54 51.9%

Line Branch Exec Source
1 #include "kopilov_d_sum_val_col_mat/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <utility>
7 #include <vector>
8
9 #include "kopilov_d_sum_val_col_mat/common/include/common.hpp"
10
11 namespace kopilov_d_sum_val_col_mat {
12
13
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 KopilovDSumValColMatMPI::KopilovDSumValColMatMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 6 GetOutput() = OutType{};
17 6 }
18
19 6 bool KopilovDSumValColMatMPI::ValidationImpl() {
20 6 return true;
21 }
22
23 6 bool KopilovDSumValColMatMPI::PreProcessingImpl() {
24 6 return true;
25 }
26
27 6 bool KopilovDSumValColMatMPI::RunImpl() {
28 6 int world_rank = 0;
29 6 int world_size = 1;
30 6 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
31 6 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
32
33 6 int rows = 0;
34 6 int cols = 0;
35 const double *send_buffer_ptr = nullptr;
36
37
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (world_rank == 0) {
38 3 rows = GetInput().rows;
39 3 cols = GetInput().cols;
40
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const std::size_t expected_size = static_cast<std::size_t>(rows) * static_cast<std::size_t>(cols);
41
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (GetInput().data.size() != expected_size) {
42 return false;
43 }
44 send_buffer_ptr = GetInput().data.data();
45 }
46
47 6 MPI_Bcast(&rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
48 6 MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
49
50
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if (rows == 0 || cols == 0) {
51 GetOutput().col_sum.clear();
52 return true;
53 }
54
55 // compute rows per process (by rows, not by elements) to avoid fractional rows
56 6 std::vector<int> rows_per_rank(static_cast<std::size_t>(world_size), 0);
57 6 const int base_rows = rows / world_size;
58 6 const int remainder_rows = rows % world_size;
59
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (int pid = 0; pid < world_size; ++pid) {
60
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
18 rows_per_rank[static_cast<std::size_t>(pid)] = base_rows + (pid < remainder_rows ? 1 : 0);
61 }
62
63 // send_counts/displs are in number of doubles (elements)
64
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> send_counts(static_cast<std::size_t>(world_size), 0);
65
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> displacements(static_cast<std::size_t>(world_size), 0);
66 int offset = 0;
67
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
18 for (int pid = 0; pid < world_size; ++pid) {
68 12 send_counts[static_cast<std::size_t>(pid)] = rows_per_rank[static_cast<std::size_t>(pid)] * cols;
69 12 displacements[static_cast<std::size_t>(pid)] = offset;
70 12 offset += send_counts[static_cast<std::size_t>(pid)];
71 }
72
73
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 const int recv_count = send_counts[static_cast<std::size_t>(world_rank)];
74
2/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
6 std::vector<double> recv_buffer(static_cast<std::size_t>(recv_count), 0.0);
75
76
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Scatterv(send_buffer_ptr, send_counts.data(), displacements.data(), MPI_DOUBLE, recv_buffer.data(), recv_count,
77 MPI_DOUBLE, 0, MPI_COMM_WORLD);
78
79
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 const int local_rows = (cols == 0) ? 0 : static_cast<int>(recv_buffer.size()) / cols;
80
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<double> local_col_sum(static_cast<std::size_t>(cols), 0.0);
81
82
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 6 times.
21 for (int row = 0; row < local_rows; ++row) {
83
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 15 times.
98 for (int col = 0; col < cols; ++col) {
84 83 local_col_sum[static_cast<std::size_t>(col)] +=
85 83 recv_buffer[(static_cast<std::size_t>(row) * static_cast<std::size_t>(cols)) + static_cast<std::size_t>(col)];
86 }
87 }
88
89
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<double> global_col_sum(static_cast<std::size_t>(cols), 0.0);
90
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Reduce(local_col_sum.data(), global_col_sum.data(), cols, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
91
92 // Broadcast result to all processes so tests can validate on any rank
93
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(global_col_sum.data(), cols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
94
95 6 GetOutput().col_sum = std::move(global_col_sum);
96
97 return true;
98 }
99
100 6 bool KopilovDSumValColMatMPI::PostProcessingImpl() {
101 6 return true;
102 }
103
104 } // namespace kopilov_d_sum_val_col_mat
105