GCC Code Coverage Report


Directory: ./
File: tasks/ermakov_a_ring/seq/src/ops_seq.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 28 77 36.4%
Functions: 6 7 85.7%
Branches: 15 66 22.7%

Line Branch Exec Source
1 #include "ermakov_a_ring/seq/include/ops_seq.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <array>
7 #include <cmath>
8 #include <cstddef>
9 #include <vector>
10
11 #include "ermakov_a_ring/common/include/common.hpp"
12 #include "util/include/util.hpp"
13
14 namespace ermakov_a_ring {
15
16 namespace {
17
18
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 8 times.
104 bool RunLocalLogic(ErmakovATestTaskSEQ *task, const int s, const int d) {
19 auto &input_data = task->GetInput().data;
20
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 8 times.
104 if (!input_data.empty()) {
21
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 96 times.
312 for (size_t i = 0; i < input_data.size(); ++i) {
22 216 input_data[i] = static_cast<int>(std::sqrt(std::abs(std::sin(static_cast<double>(i)))));
23 }
24 }
25
26 104 const int v_size = std::max(s, d) + 1;
27 104 const int fwd = (d - s + v_size) % v_size;
28 104 const int bwd = (s - d + v_size) % v_size;
29
30 bool go_fwd = (fwd <= bwd);
31
32 104 std::vector<int> res;
33 104 int curr = s;
34 while (true) {
35 res.push_back(curr);
36
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 104 times.
240 if (curr == d) {
37 break;
38 }
39
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 48 times.
136 if (go_fwd) {
40 88 curr = (curr + 1) % v_size;
41 } else {
42 48 curr = (curr - 1 + v_size) % v_size;
43 }
44 }
45
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 task->GetOutput() = res;
46 104 return true;
47 }
48
49 bool RunMpiTopologyLogic(ErmakovATestTaskSEQ *task, const int s_idx, const int d_idx) {
50 int w_rank = 0;
51 int w_size = 0;
52 MPI_Comm_rank(MPI_COMM_WORLD, &w_rank);
53 MPI_Comm_size(MPI_COMM_WORLD, &w_size);
54
55 const int s = s_idx % w_size;
56 const int d = d_idx % w_size;
57 auto payload = task->GetInput().data;
58
59 std::array<int, 1> dims = {w_size};
60 std::array<int, 1> periods = {1};
61 MPI_Comm ring_comm = MPI_COMM_NULL;
62 MPI_Cart_create(MPI_COMM_WORLD, 1, dims.data(), periods.data(), 0, &ring_comm);
63
64 int l_peer = 0;
65 int r_peer = 0;
66 MPI_Cart_shift(ring_comm, 0, 1, &l_peer, &r_peer);
67
68 const int r_dist = (d - s + w_size) % w_size;
69 const int l_dist = (s - d + w_size) % w_size;
70
71 bool move_r = (r_dist <= l_dist);
72 int nxt = l_peer;
73 int prv = r_peer;
74 int steps_total = l_dist;
75 int my_dist = (s - w_rank + w_size) % w_size;
76
77 if (move_r) {
78 nxt = r_peer;
79 prv = l_peer;
80 steps_total = r_dist;
81 my_dist = (w_rank - s + w_size) % w_size;
82 }
83
84 std::vector<int> path;
85 if (w_rank == s) {
86 path.push_back(s);
87 if (s != d) {
88 const int psz = static_cast<int>(path.size());
89 MPI_Send(payload.data(), static_cast<int>(payload.size()), MPI_INT, nxt, 100, ring_comm);
90 MPI_Send(&psz, 1, MPI_INT, nxt, 10, ring_comm);
91 MPI_Send(path.data(), psz, MPI_INT, nxt, 11, ring_comm);
92 }
93 }
94
95 if (my_dist > 0 && my_dist <= steps_total) {
96 int in_sz = 0;
97 MPI_Recv(payload.data(), static_cast<int>(payload.size()), MPI_INT, prv, 100, ring_comm, MPI_STATUS_IGNORE);
98 MPI_Recv(&in_sz, 1, MPI_INT, prv, 10, ring_comm, MPI_STATUS_IGNORE);
99 path.resize(static_cast<size_t>(in_sz));
100 MPI_Recv(path.data(), in_sz, MPI_INT, prv, 11, ring_comm, MPI_STATUS_IGNORE);
101 path.push_back(w_rank);
102 if (w_rank != d) {
103 const int out_sz = static_cast<int>(path.size());
104 MPI_Send(payload.data(), static_cast<int>(payload.size()), MPI_INT, nxt, 100, ring_comm);
105 MPI_Send(&out_sz, 1, MPI_INT, nxt, 10, ring_comm);
106 MPI_Send(path.data(), out_sz, MPI_INT, nxt, 11, ring_comm);
107 }
108 }
109
110 int total_len = static_cast<int>(path.size());
111 MPI_Bcast(&total_len, 1, MPI_INT, d, ring_comm);
112 if (w_rank != d) {
113 path.resize(static_cast<size_t>(total_len));
114 }
115 MPI_Bcast(path.data(), total_len, MPI_INT, d, ring_comm);
116
117 task->GetOutput() = path;
118 MPI_Comm_free(&ring_comm);
119 return true;
120 }
121
122 } // namespace
123
124
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 ErmakovATestTaskSEQ::ErmakovATestTaskSEQ(const InType &in) {
125 SetTypeOfTask(GetStaticTypeOfTask());
126 GetInput() = in;
127 104 }
128
129 104 bool ErmakovATestTaskSEQ::ValidationImpl() {
130 const auto &input = GetInput();
131
2/4
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 104 times.
104 return input.source >= 0 && input.dest >= 0;
132 }
133
134 104 bool ErmakovATestTaskSEQ::PreProcessingImpl() {
135 104 return true;
136 }
137
138 104 bool ErmakovATestTaskSEQ::RunImpl() {
139 104 const int src = GetInput().source;
140 104 const int dst = GetInput().dest;
141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
104 if (ppc::util::IsUnderMpirun()) {
142 return RunMpiTopologyLogic(this, src, dst);
143 }
144 104 return RunLocalLogic(this, src, dst);
145 }
146
147 104 bool ErmakovATestTaskSEQ::PostProcessingImpl() {
148 104 return true;
149 }
150
151 } // namespace ermakov_a_ring
152