GCC Code Coverage Report


Directory: ./
File: tasks/sannikov_i_column_sum/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 54 54 100.0%
Functions: 6 6 100.0%
Branches: 38 64 59.4%

Line Branch Exec Source
1 #include "sannikov_i_column_sum/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstddef>
6 #include <cstdint>
7 #include <limits>
8 #include <vector>
9
10 #include "sannikov_i_column_sum/common/include/common.hpp"
11
12 namespace sannikov_i_column_sum {
13
14
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 SannikovIColumnSumMPI::SannikovIColumnSumMPI(const InType &in) {
15 SetTypeOfTask(GetStaticTypeOfTask());
16 auto &input_buffer = GetInput();
17
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 InType tmp(in);
18 input_buffer.swap(tmp);
19 GetOutput().clear();
20 32 }
21
22
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 bool SannikovIColumnSumMPI::ValidationImpl() {
23 const auto &input_matrix = GetInput();
24
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
32 if (input_matrix.empty() || input_matrix.front().empty()) {
25 return false;
26 }
27
28 const std::size_t columns = input_matrix.front().size();
29
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 for (const auto &row : input_matrix) {
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (row.size() != columns) {
31 return false;
32 }
33 }
34
35 32 return GetOutput().empty();
36 }
37
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 bool SannikovIColumnSumMPI::PreProcessingImpl() {
39 GetOutput().clear();
40 32 return true;
41 }
42
43 32 void SannikovIColumnSumMPI::PrepareSendBuffer(const InType &input_matrix, int rank, std::uint64_t rows,
44 std::uint64_t columns, std::vector<int> &sendbuf) {
45
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (rank != 0) {
46 return;
47 }
48 if (rank == 0) {
49 16 const std::uint64_t base = rows * columns;
50 16 sendbuf.resize(static_cast<std::size_t>(base));
51
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
64 for (std::uint64_t i = 0; i < rows; i++) {
52
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 48 times.
174 for (std::uint64_t j = 0; j < columns; j++) {
53 126 sendbuf[static_cast<std::size_t>((i * columns) + (j))] =
54 input_matrix[static_cast<std::size_t>(i)][static_cast<std::size_t>(j)];
55 }
56 }
57 }
58 }
59
60 32 bool SannikovIColumnSumMPI::RunImpl() {
61 const auto &input_matrix = GetInput();
62
63 32 int rank = 0;
64 32 int size = 1;
65 32 std::uint64_t rows = 0;
66 32 std::uint64_t columns = 0;
67
68 32 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
69 32 MPI_Comm_size(MPI_COMM_WORLD, &size);
70
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (rank == 0) {
71 16 rows = static_cast<std::uint64_t>(input_matrix.size());
72 16 columns = static_cast<std::uint64_t>(input_matrix.front().size());
73 }
74
75 32 MPI_Bcast(&rows, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
76 32 MPI_Bcast(&columns, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
77
78 32 const std::uint64_t base = rows * columns;
79
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (columns > static_cast<std::uint64_t>(std::numeric_limits<int>::max()) ||
80 (base > static_cast<std::uint64_t>(std::numeric_limits<int>::max()))) {
81 return false;
82 }
83 32 const int columns_int = static_cast<int>(columns);
84 32 const int base_int = static_cast<int>(base);
85 32 GetOutput().assign(static_cast<std::size_t>(columns_int), 0);
86
87 32 std::vector<int> sendbuf;
88
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 PrepareSendBuffer(input_matrix, rank, rows, columns, sendbuf);
89
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> elem_for_proc(size);
90
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> id_elem(size);
91 int displacement = 0;
92
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 32 times.
96 for (int i = 0; i < size; i++) {
93
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 20 times.
108 elem_for_proc[i] = static_cast<int>(base_int / size) + (i < (base_int % size) ? 1 : 0);
94 64 id_elem[i] = displacement;
95 64 displacement += elem_for_proc[i];
96 }
97
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 const int mpi_displacement = id_elem[rank] % static_cast<int>(columns_int);
98
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> buf(static_cast<std::size_t>(elem_for_proc[rank]), 0);
99
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 32 times.
✗ Branch 4 not taken.
48 MPI_Scatterv(rank == 0 ? sendbuf.data() : nullptr, elem_for_proc.data(), id_elem.data(), MPI_INT, buf.data(),
100
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 elem_for_proc[rank], MPI_INT, 0, MPI_COMM_WORLD);
101
1/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
32 std::vector<int> sum(static_cast<std::size_t>(columns_int), 0);
102
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 32 times.
158 for (int i = 0; i < (elem_for_proc[rank]); i++) {
103 126 int new_col = (i + mpi_displacement) % columns_int;
104 126 sum[static_cast<std::size_t>(new_col)] += buf[static_cast<std::size_t>(i)];
105 }
106
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 MPI_Allreduce(sum.data(), GetOutput().data(), columns_int, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
107
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 return !GetOutput().empty();
108 }
109
110 32 bool SannikovIColumnSumMPI::PostProcessingImpl() {
111 32 return !GetOutput().empty();
112 }
113
114 } // namespace sannikov_i_column_sum
115