GCC Code Coverage Report


Directory: ./
File: tasks/nikitina_v_max_elem_matr/mpi/src/ops_mpi.cpp
Date: 2025-12-13 04:24:21
Exec Total Coverage
Lines: 56 58 96.6%
Functions: 6 7 85.7%
Branches: 36 56 64.3%

Line Branch Exec Source
1 #include "nikitina_v_max_elem_matr/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <iterator>
8 #include <limits>
9 #include <vector>
10
11 #include "nikitina_v_max_elem_matr/common/include/common.hpp"
12
13 namespace nikitina_v_max_elem_matr {
14
15
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MaxElementMatrMPI::MaxElementMatrMPI(const InType &in) : BaseTask() {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetInput() = in;
18 16 }
19
20 16 bool MaxElementMatrMPI::ValidationImpl() {
21 16 int rank = 0;
22 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
23
24
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
25 const auto &in = GetInput();
26
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (in.size() < 2) {
27 return false;
28 }
29 8 rows_ = in[0];
30 8 cols_ = in[1];
31
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 return rows_ >= 0 && cols_ >= 0 && static_cast<size_t>(rows_) * cols_ == in.size() - 2;
32 }
33 return true;
34 }
35
36 16 bool MaxElementMatrMPI::PreProcessingImpl() {
37 16 int rank = 0;
38 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
39
40
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (rank == 0) {
41 const auto &in = GetInput();
42 matrix_.clear();
43
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
8 if (rows_ > 0 && cols_ > 0) {
44 5 matrix_.reserve(static_cast<size_t>(rows_) * cols_);
45 std::copy(in.begin() + 2, in.end(), std::back_inserter(matrix_));
46 }
47 }
48 16 return true;
49 }
50
51 void MaxElementMatrMPI::CalculateScatterParams(int total_elements, int world_size, std::vector<int> &sendcounts,
52 std::vector<int> &displs) {
53 5 const int elements_per_proc = total_elements / world_size;
54 5 const int remainder_elements = total_elements % world_size;
55 int current_displ = 0;
56
2/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 for (int i = 0; i < world_size; ++i) {
57
2/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 sendcounts[i] = (i < remainder_elements) ? elements_per_proc + 1 : elements_per_proc;
58 10 displs[i] = current_displ;
59 10 current_displ += sendcounts[i];
60 }
61 }
62
63
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 int MaxElementMatrMPI::FindLocalMax(const std::vector<int> &data) {
64
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 if (data.empty()) {
65 return std::numeric_limits<int>::min();
66 }
67 9 int max_val = data[0];
68
2/2
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 9 times.
236 for (size_t i = 1; i < data.size(); ++i) {
69 227 max_val = std::max(max_val, data[i]);
70 }
71 9 return max_val;
72 }
73
74 16 bool MaxElementMatrMPI::RunImpl() {
75 16 int world_size = 0;
76 16 int rank = 0;
77 16 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
78 16 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
79
80 16 MPI_Bcast(&rows_, 1, MPI_INT, 0, MPI_COMM_WORLD);
81 16 MPI_Bcast(&cols_, 1, MPI_INT, 0, MPI_COMM_WORLD);
82
83
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if (static_cast<size_t>(rows_) * cols_ == 0) {
84 6 global_max_ = std::numeric_limits<int>::min();
85 } else {
86 10 const int total_elements = rows_ * cols_;
87 10 std::vector<int> sendcounts(world_size);
88
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> displs(world_size);
89
90
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
91 5 CalculateScatterParams(total_elements, world_size, sendcounts, displs);
92 }
93
94
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Bcast(sendcounts.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
95
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Bcast(displs.data(), world_size, MPI_INT, 0, MPI_COMM_WORLD);
96
97
1/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
10 std::vector<int> recv_buf(sendcounts[rank]);
98
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 const int *send_buf = (rank == 0) ? matrix_.data() : nullptr;
99
100
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Scatterv(send_buf, sendcounts.data(), displs.data(), MPI_INT, recv_buf.data(), sendcounts[rank], MPI_INT, 0,
101 MPI_COMM_WORLD);
102
103 10 int local_max = FindLocalMax(recv_buf);
104
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Reduce(&local_max, &global_max_, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
105 }
106
107 16 MPI_Bcast(&global_max_, 1, MPI_INT, 0, MPI_COMM_WORLD);
108 16 return true;
109 }
110
111 16 bool MaxElementMatrMPI::PostProcessingImpl() {
112 16 GetOutput() = global_max_;
113 16 return true;
114 }
115
116 } // namespace nikitina_v_max_elem_matr
117