GCC Code Coverage Report


Directory: ./
File: tasks/dilshodov_a_max_val_rows_matrix/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 73 75 97.3%
Functions: 7 7 100.0%
Branches: 44 68 64.7%

Line Branch Exec Source
1 #include "dilshodov_a_max_val_rows_matrix/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <array>
7 #include <cstddef>
8 #include <limits>
9 #include <vector>
10
11 #include "dilshodov_a_max_val_rows_matrix/common/include/common.hpp"
12
13 namespace dilshodov_a_max_val_rows_matrix {
14
15
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MaxValRowsMatrixTaskMPI::MaxValRowsMatrixTaskMPI(const InType &in) {
16 SetTypeOfTask(GetStaticTypeOfTask());
17
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 InType copy = in;
18 GetInput().swap(copy);
19 12 }
20
21 12 bool MaxValRowsMatrixTaskMPI::ValidationImpl() {
22 12 int rank = 0;
23 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
24
25 12 int is_valid = 0;
26
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
27 const auto &input = GetInput();
28
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if (!input.empty() && !input[0].empty()) {
29 std::size_t cols = input[0].size();
30 6 is_valid = 1;
31
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 6 times.
175 for (const auto &row : input) {
32
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
169 if (row.size() != cols) {
33 is_valid = 0;
34 break;
35 }
36 }
37 }
38 }
39
40 12 MPI_Bcast(&is_valid, 1, MPI_INT, 0, MPI_COMM_WORLD);
41 12 return is_valid != 0;
42 }
43
44 12 bool MaxValRowsMatrixTaskMPI::PreProcessingImpl() {
45 12 int rank = 0;
46 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47
48
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
49 6 GetOutput().assign(GetInput().size(), std::numeric_limits<int>::min());
50 }
51 12 return true;
52 }
53
54 12 bool MaxValRowsMatrixTaskMPI::RunImpl() {
55 12 int rank = 0;
56 12 int size = 0;
57 12 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
58 12 MPI_Comm_size(MPI_COMM_WORLD, &size);
59
60 12 std::array<int, 2> dims = {0, 0};
61
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
62 const auto &input = GetInput();
63 6 dims[0] = static_cast<int>(input.size());
64 6 dims[1] = static_cast<int>(input[0].size());
65 }
66 12 MPI_Bcast(dims.data(), 2, MPI_INT, 0, MPI_COMM_WORLD);
67
68 12 int rows = dims[0];
69 12 int cols = dims[1];
70 12 int base_rows = rows / size;
71 12 int extra_rows = rows % size;
72
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 int local_rows = base_rows + ((rank < extra_rows) ? 1 : 0);
73
74 12 std::vector<int> local_matrix(static_cast<size_t>(local_rows) * cols);
75
1/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
12 std::vector<int> local_max(local_rows);
76
77
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (rank == 0) {
78
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 RunMaster(rows, cols, base_rows, extra_rows, local_rows, local_matrix, local_max);
79 } else {
80
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 RunWorker(cols, local_rows, local_matrix, local_max);
81 }
82
83 12 return true;
84 }
85
86 6 void MaxValRowsMatrixTaskMPI::RunMaster(int rows, int cols, int base_rows, int extra_rows, int local_rows,
87 std::vector<int> &local_matrix, std::vector<int> &local_max) {
88 6 int size = 0;
89 6 MPI_Comm_size(MPI_COMM_WORLD, &size);
90
91 const auto &input = GetInput();
92
93
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 6 times.
92 for (int i = 0; i < local_rows; ++i) {
94 86 std::ranges::copy(input[i], local_matrix.data() + (static_cast<std::ptrdiff_t>(i) * cols));
95 }
96
97 6 std::vector<MPI_Request> send_requests(size - 1);
98
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<std::vector<int>> send_buffers(size - 1);
99
100 int row_offset = local_rows;
101
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int proc = 1; proc < size; ++proc) {
102
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int proc_rows = base_rows + ((proc < extra_rows) ? 1 : 0);
103
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 send_buffers[proc - 1].resize(static_cast<size_t>(proc_rows) * cols);
104
105
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 6 times.
89 for (int i = 0; i < proc_rows; ++i) {
106 83 std::ranges::copy(input[row_offset + i], send_buffers[proc - 1].data() + (static_cast<std::ptrdiff_t>(i) * cols));
107 }
108
109
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Isend(send_buffers[proc - 1].data(), proc_rows * cols, MPI_INT, proc, 0, MPI_COMM_WORLD,
110 &send_requests[proc - 1]);
111 6 row_offset += proc_rows;
112 }
113
114 const int *row_ptr = local_matrix.data();
115
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 6 times.
92 for (int i = 0; i < local_rows; ++i) {
116
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
172 local_max[i] = *std::max_element(row_ptr, row_ptr + cols);
117 row_ptr += cols;
118 }
119
120
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (size > 1) {
121
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Waitall(size - 1, send_requests.data(), MPI_STATUSES_IGNORE);
122 }
123
124
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 GetOutput().resize(rows);
125 std::ranges::copy(local_max, GetOutput().begin());
126
127 int result_offset = local_rows;
128
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for (int proc = 1; proc < size; ++proc) {
129
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
12 int proc_rows = base_rows + ((proc < extra_rows) ? 1 : 0);
130
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Recv(GetOutput().data() + result_offset, proc_rows, MPI_INT, proc, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
131 6 result_offset += proc_rows;
132 }
133 12 }
134
135 6 void MaxValRowsMatrixTaskMPI::RunWorker(int cols, int local_rows, std::vector<int> &local_matrix,
136 std::vector<int> &local_max) {
137 6 MPI_Recv(local_matrix.data(), local_rows * cols, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
138
139 const int *row_ptr = local_matrix.data();
140
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 6 times.
89 for (int i = 0; i < local_rows; ++i) {
141
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
166 local_max[i] = *std::max_element(row_ptr, row_ptr + cols);
142 row_ptr += cols;
143 }
144
145 6 MPI_Send(local_max.data(), local_rows, MPI_INT, 0, 1, MPI_COMM_WORLD);
146 6 }
147
148 12 bool MaxValRowsMatrixTaskMPI::PostProcessingImpl() {
149 12 return true;
150 }
151
152 } // namespace dilshodov_a_max_val_rows_matrix
153