GCC Code Coverage Report


Directory: ./
File: tasks/zyazeva_s_vector_dot_product/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 57 57 100.0%
Functions: 4 4 100.0%
Branches: 32 40 80.0%

Line Branch Exec Source
1 #include "zyazeva_s_vector_dot_product/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstdint>
6 #include <vector>
7
8 #include "zyazeva_s_vector_dot_product/common/include/common.hpp"
9
10 namespace zyazeva_s_vector_dot_product {
11
12 namespace {
13 bool CheckInputValid(const std::vector<std::vector<int32_t>> &input, int64_t &total_elements) {
14
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (input.size() < 2) {
15 return false;
16 }
17
18 const auto &vector1 = input[0];
19 const auto &vector2 = input[1];
20
21
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (vector1.size() != vector2.size()) {
22 return false;
23 }
24
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
6 if (vector1.empty() || vector2.empty()) {
25 return false;
26 }
27
28 5 total_elements = static_cast<int64_t>(vector1.size());
29 return true;
30 }
31
32 void CalculateChunkParams(int rank, int size, int64_t total_elements, int64_t &local_size, int64_t &start) {
33 15 const int64_t base_chunk_size = total_elements / size;
34 15 const int64_t remainder = total_elements % size;
35
36 30 local_size = base_chunk_size + (rank < remainder ? 1 : 0);
37
38
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
15 if (rank < remainder) {
39 4 start = rank * (base_chunk_size + 1);
40 } else {
41 11 start = (remainder * (base_chunk_size + 1)) + ((rank - remainder) * base_chunk_size);
42 }
43 }
44
45 } // namespace
46
47 18 bool ZyazevaSVecDotProductMPI::ValidationImpl() {
48 18 int rank = 0;
49 18 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
50
51 18 bool is_valid = false;
52
53
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == 0) {
54 9 is_valid = true;
55 }
56
57 18 MPI_Bcast(&is_valid, 1, MPI_C_BOOL, 0, MPI_COMM_WORLD);
58 18 return is_valid;
59 }
60
61 18 bool ZyazevaSVecDotProductMPI::PreProcessingImpl() {
62 18 GetOutput() = 0;
63 18 return true;
64 }
65
66 18 bool ZyazevaSVecDotProductMPI::RunImpl() {
67 18 int rank = 0;
68 18 int size = 1;
69 18 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
70 18 MPI_Comm_size(MPI_COMM_WORLD, &size);
71
72 18 int64_t total_elements = 0;
73 bool error_handling = true;
74
75
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 if (rank == 0) {
76 const auto &input = GetInput();
77 error_handling = CheckInputValid(input, total_elements);
78 if (!error_handling) {
79 4 GetOutput() = 0;
80 }
81 }
82
83 18 int error_flag = error_handling ? 1 : 0;
84 18 MPI_Bcast(&error_flag, 1, MPI_INT, 0, MPI_COMM_WORLD);
85
86
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10 times.
18 if (error_flag == 0) {
87
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank != 0) {
88 4 GetOutput() = 0;
89 }
90 8 return true;
91 }
92
93 10 MPI_Bcast(&total_elements, 1, MPI_INT64_T, 0, MPI_COMM_WORLD);
94
95 int64_t local_size = 0;
96 int64_t start = 0;
97
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 CalculateChunkParams(rank, size, total_elements, local_size, start);
98
99 10 int64_t local_dot_product = 0;
100
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (rank == 0) {
101 const auto &input = GetInput();
102 const auto &vector1_full = input[0];
103 const auto &vector2_full = input[1];
104
105
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 for (int64_t i = start; i < start + local_size; ++i) {
106 8 local_dot_product += static_cast<int64_t>(vector1_full[i]) * static_cast<int64_t>(vector2_full[i]);
107 }
108
109
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 for (int i = 1; i < size; i++) {
110 int64_t i_local_size = 0;
111 int64_t i_start = 0;
112
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 CalculateChunkParams(i, size, total_elements, i_local_size, i_start);
113
114 5 MPI_Send(vector1_full.data() + i_start, static_cast<int>(i_local_size), MPI_INT, i, 0, MPI_COMM_WORLD);
115 5 MPI_Send(vector2_full.data() + i_start, static_cast<int>(i_local_size), MPI_INT, i, 1, MPI_COMM_WORLD);
116 }
117 } else {
118 5 std::vector<int32_t> local_vector1(local_size);
119
1/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
5 std::vector<int32_t> local_vector2(local_size);
120
121
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 MPI_Recv(local_vector1.data(), static_cast<int>(local_size), MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
122
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 MPI_Recv(local_vector2.data(), static_cast<int>(local_size), MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
123
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 for (int64_t i = 0; i < local_size; ++i) {
124 4 local_dot_product += static_cast<int64_t>(local_vector1[i]) * static_cast<int64_t>(local_vector2[i]);
125 }
126 }
127
128 10 int64_t global_dot_product = 0;
129 10 MPI_Allreduce(&local_dot_product, &global_dot_product, 1, MPI_INT64_T, MPI_SUM, MPI_COMM_WORLD);
130
131 10 GetOutput() = static_cast<OutType>(global_dot_product);
132 10 return true;
133 }
134
135 18 bool ZyazevaSVecDotProductMPI::PostProcessingImpl() {
136 18 return true;
137 }
138
139 } // namespace zyazeva_s_vector_dot_product
140