GCC Code Coverage Report


Directory: ./
File: tasks/kulik_a_the_most_different_adjacent/mpi/src/ops_mpi.cpp
Date: 2026-01-09 01:27:18
Exec Total Coverage
Lines: 72 74 97.3%
Functions: 8 8 100.0%
Branches: 44 66 66.7%

Line Branch Exec Source
1 #include "kulik_a_the_most_different_adjacent/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cmath>
7 #include <cstddef>
8 #include <cstdint>
9 #include <utility>
10 #include <vector>
11
12 #include "kulik_a_the_most_different_adjacent/common/include/common.hpp"
13
14 namespace kulik_a_the_most_different_adjacent {
15
16
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 KulikATheMostDifferentAdjacentMPI::KulikATheMostDifferentAdjacentMPI(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 6 int proc_rank = 0;
19
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
20
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (proc_rank == 0) {
21
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 GetInput() = in;
22 } else {
23 3 GetInput() = InType{};
24 }
25 6 }
26
27 6 bool KulikATheMostDifferentAdjacentMPI::ValidationImpl() {
28 6 int proc_rank = 0;
29 6 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
30
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (proc_rank == 0) {
31 3 return (GetInput().size() >= 2);
32 }
33 return true;
34 }
35
36 6 bool KulikATheMostDifferentAdjacentMPI::PreProcessingImpl() {
37 6 return true;
38 }
39
40 6 void KulikATheMostDifferentAdjacentMPI::CalculateDistribution(int proc_rank, int proc_num, uint64_t n,
41 std::vector<int> &elemcnt, std::vector<int> &startpos) {
42
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 uint64_t active_procs = std::min(n, static_cast<uint64_t>(proc_num));
43
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 uint64_t size = (active_procs > 0) ? n / active_procs : 0;
44 6 uint64_t r = (active_procs > 0) ? n % active_procs : 0;
45 auto unsigned_proc_num = static_cast<uint64_t>(proc_num);
46
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (proc_rank == 0) {
47 uint64_t offset = 0;
48
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (uint64_t i = 0; i < unsigned_proc_num; ++i) {
49
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (i < active_procs) {
50
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 elemcnt[i] = (i < r) ? static_cast<int>(size + 1) : static_cast<int>(size);
51 6 startpos[i] = static_cast<int>(offset);
52 6 offset += elemcnt[i];
53 } else {
54 elemcnt[i] = 0;
55 startpos[i] = 0;
56 }
57 }
58 }
59 6 }
60
61
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 void KulikATheMostDifferentAdjacentMPI::FindLocalMax(const std::vector<double> &buf, int start_index,
62 double &max_diff_val, uint64_t &max_diff_ind) {
63
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if (buf.size() >= 2) {
64
2/2
✓ Branch 0 taken 9100002 times.
✓ Branch 1 taken 5 times.
9100007 for (size_t i = 0; i < buf.size() - 1; ++i) {
65
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 9099941 times.
9100002 if (std::abs(buf[i + 1] - buf[i]) > max_diff_val) {
66 61 max_diff_val = std::abs(buf[i + 1] - buf[i]);
67 61 max_diff_ind = static_cast<uint64_t>(start_index) + i;
68 }
69 }
70 }
71 6 }
72
73 6 void KulikATheMostDifferentAdjacentMPI::CheckBoundaries(int proc_rank, int proc_num, const std::vector<int> &elemcnt,
74 const std::vector<int> &startpos,
75 const std::vector<double> &buf, double &max_diff_val,
76 uint64_t &max_diff_ind) {
77 MPI_Status status;
78
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (elemcnt[proc_rank] > 0) {
79 6 double temp = 0.;
80
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (proc_rank > 0 && elemcnt[proc_rank - 1] > 0) {
81 3 MPI_Recv(&temp, 1, MPI_DOUBLE, proc_rank - 1, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
82
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (std::abs(buf[0] - temp) > max_diff_val) {
83 1 max_diff_val = std::abs(buf[0] - temp);
84 1 max_diff_ind = static_cast<uint64_t>(startpos[proc_rank]) - 1;
85 }
86 }
87
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (proc_rank < proc_num - 1 && elemcnt[proc_rank + 1] > 0) {
88 3 MPI_Send(&buf.back(), 1, MPI_DOUBLE, proc_rank + 1, 0, MPI_COMM_WORLD);
89 }
90 }
91 6 }
92
93 6 bool KulikATheMostDifferentAdjacentMPI::RunImpl() {
94 6 int proc_num = 0;
95 6 int proc_rank = 0;
96 6 MPI_Comm_size(MPI_COMM_WORLD, &proc_num);
97 6 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
98 const auto &input = GetInput();
99 6 auto n = static_cast<uint64_t>(input.size());
100 6 MPI_Bcast(&n, 1, MPI_UINT64_T, 0, MPI_COMM_WORLD);
101
102 6 std::vector<int> elemcnt(proc_num, 0);
103
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<int> startpos(proc_num, 0);
104
105 6 CalculateDistribution(proc_rank, proc_num, n, elemcnt, startpos);
106
107
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(elemcnt.data(), proc_num, MPI_INT, 0, MPI_COMM_WORLD);
108
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Bcast(startpos.data(), proc_num, MPI_INT, 0, MPI_COMM_WORLD);
109
110
1/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6 std::vector<double> buf(elemcnt[proc_rank]);
111
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Scatterv(input.data(), elemcnt.data(), startpos.data(), MPI_DOUBLE, buf.data(), elemcnt[proc_rank], MPI_DOUBLE, 0,
112 MPI_COMM_WORLD);
113
114 6 double max_diff_val = 0.0;
115 6 uint64_t max_diff_ind = 0;
116
117 6 FindLocalMax(buf, startpos[proc_rank], max_diff_val, max_diff_ind);
118
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 CheckBoundaries(proc_rank, proc_num, elemcnt, startpos, buf, max_diff_val, max_diff_ind);
119
120 6 double max_diffall_val = 0.0;
121 6 uint64_t max_diffall_ind = 0;
122
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Allreduce(&max_diff_val, &max_diffall_val, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
123
124
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 uint64_t poss_index = (std::abs(max_diff_val - max_diffall_val) < 1e-12) ? max_diff_ind : UINT64_MAX;
125
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Allreduce(&poss_index, &max_diffall_ind, 1, MPI_UINT64_T, MPI_MIN, MPI_COMM_WORLD);
126
127 OutType &ans = GetOutput();
128 6 ans.first = max_diffall_ind;
129 6 ans.second = max_diffall_ind + 1;
130
131
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 MPI_Barrier(MPI_COMM_WORLD);
132 6 return true;
133 }
134
135 6 bool KulikATheMostDifferentAdjacentMPI::PostProcessingImpl() {
136 6 return (GetOutput().first + 1 == GetOutput().second);
137 }
138
139 } // namespace kulik_a_the_most_different_adjacent
140