GCC Code Coverage Report


Directory: ./
File: tasks/nikolaev_d_most_dif_vec_neighbors/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 56 56 100.0%
Functions: 7 7 100.0%
Branches: 40 58 69.0%

Line Branch Exec Source
1 #include "nikolaev_d_most_dif_vec_neighbors/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstdint>
8 #include <cstdlib>
9 #include <utility>
10 #include <vector>
11
12 #include "nikolaev_d_most_dif_vec_neighbors/common/include/common.hpp"
13
14 namespace nikolaev_d_most_dif_vec_neighbors {
15
16
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 NikolaevDMostDifVecNeighborsMPI::NikolaevDMostDifVecNeighborsMPI(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 GetInput() = in;
19 GetOutput() = OutType{};
20 20 }
21
22 20 bool NikolaevDMostDifVecNeighborsMPI::ValidationImpl() {
23 20 return GetInput().size() >= 2;
24 }
25
26 20 bool NikolaevDMostDifVecNeighborsMPI::PreProcessingImpl() {
27 20 return true;
28 }
29
30 20 bool NikolaevDMostDifVecNeighborsMPI::RunImpl() {
31 const auto &input = GetInput();
32 20 int rank = 0;
33 20 int size = 0;
34 20 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
35 20 MPI_Comm_size(MPI_COMM_WORLD, &size);
36
37
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (input.size() < 2) {
38 return false;
39 }
40
41 20 int n = static_cast<int>(input.size());
42 int actual_processes = std::min(size, n);
43 20 int elements_per_process = n / actual_processes;
44 20 int remainder = n % actual_processes;
45
46 20 std::vector<int> send_counts(size, 0);
47
1/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
20 std::vector<int> displacements(size, 0);
48 int current_displacement = 0;
49
50
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
60 for (int i = 0; i < actual_processes; i++) {
51
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 6 times.
74 send_counts[i] = elements_per_process + (i < remainder ? 1 : 0);
52 40 displacements[i] = current_displacement;
53 40 current_displacement += send_counts[i];
54 }
55
56
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 int local_size = send_counts[rank];
57
2/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
20 std::vector<int> local_data(local_size);
58
59
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Scatterv(input.data(), send_counts.data(), displacements.data(), MPI_INT, local_data.data(), local_size, MPI_INT,
60 0, MPI_COMM_WORLD);
61
62
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 FindLocalDiff(rank, size, actual_processes, local_data, local_size);
63
64 return true;
65 }
66
67 20 void NikolaevDMostDifVecNeighborsMPI::FindLocalDiff(int rank, int size, int actual_processes,
68 std::vector<int> &local_data, int local_size) {
69 int64_t local_max_diff = -1;
70 std::pair<int, int> local_result = {0, 0};
71
72
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 if (local_size >= 2) {
73
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 15 times.
48 for (int i = 0; i < local_size - 1; i++) {
74
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 int64_t diff = std::llabs(static_cast<int64_t>(local_data[i + 1]) - static_cast<int64_t>(local_data[i]));
75
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 if (diff > local_max_diff) {
76 local_max_diff = diff;
77 local_result = {local_data[i], local_data[i + 1]};
78 }
79 }
80 }
81
82
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 int first_element = local_data.empty() ? 0 : local_data[0];
83
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 int last_element = local_data.empty() ? 0 : local_data[local_size - 1];
84
85 LocalMaxInfo local_info;
86 20 local_info.diff = local_max_diff;
87 20 local_info.pair_first = local_result.first;
88 20 local_info.pair_second = local_result.second;
89 20 local_info.first_elem = first_element;
90 20 local_info.last_elem = last_element;
91
92 20 std::vector<LocalMaxInfo> all_info;
93
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
94
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 all_info.resize(size);
95 }
96
97
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 MPI_Gather(&local_info, sizeof(LocalMaxInfo), MPI_BYTE, all_info.data(), sizeof(LocalMaxInfo), MPI_BYTE, 0,
98 MPI_COMM_WORLD);
99
100
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 ProcessLocalData(rank, actual_processes, all_info);
101 20 }
102
103 20 void NikolaevDMostDifVecNeighborsMPI::ProcessLocalData(int rank, int actual_processes,
104 std::vector<LocalMaxInfo> &all_info) {
105 20 std::pair<int, int> global_result;
106
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if (rank == 0) {
107 int64_t global_max_diff = -1;
108
109 // обработка локальных максимумов из каждого сегмента
110
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 for (int i = 0; i < actual_processes; i++) {
111
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7 times.
20 if (all_info[i].diff > global_max_diff) {
112 global_max_diff = all_info[i].diff;
113 global_result = {all_info[i].pair_first, all_info[i].pair_second};
114 }
115 }
116
117 // обработка граничных пар между сегментами
118
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for (int i = 0; i < actual_processes - 1; i++) {
119 int64_t diff =
120
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 std::llabs(static_cast<int64_t>(all_info[i + 1].first_elem) - static_cast<int64_t>(all_info[i].last_elem));
121
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 if (diff > global_max_diff) {
122 global_max_diff = diff;
123 global_result = {all_info[i].last_elem, all_info[i + 1].first_elem};
124 }
125 }
126 }
127
128 20 MPI_Bcast(&global_result, 2, MPI_INT, 0, MPI_COMM_WORLD);
129
130 GetOutput() = global_result;
131 20 }
132
133 20 bool NikolaevDMostDifVecNeighborsMPI::PostProcessingImpl() {
134 20 return true;
135 }
136
137 } // namespace nikolaev_d_most_dif_vec_neighbors
138