GCC Code Coverage Report


Directory: ./
File: tasks/galkin_d_ring/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 57 61 93.4%
Functions: 8 8 100.0%
Branches: 33 54 61.1%

Line Branch Exec Source
1 #include "galkin_d_ring/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <vector>
8
9 #include "galkin_d_ring/common/include/common.hpp"
10
11 namespace galkin_d_ring {
12
13 namespace {
14
15 struct CommGuard {
16 MPI_Comm *comm = nullptr;
17
18 explicit CommGuard(MPI_Comm *c) : comm(c) {}
19
20 ~CommGuard() {
21
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if (comm != nullptr && *comm != MPI_COMM_NULL) {
22 12 MPI_Comm_free(comm);
23 *comm = MPI_COMM_NULL;
24 }
25 }
26 };
27
28 bool ValidateParams(const InType &in, int size) {
29
4/8
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
12 return (in.count > 0) && (in.src >= 0) && (in.src < size) && (in.dest >= 0) && (in.dest < size);
30 }
31
32 8 std::vector<int> InitBuffer(int rank, int src, int count) {
33 8 std::vector<int> buffer(static_cast<std::size_t>(count), 0);
34
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == src) {
35
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 4 times.
72 for (std::size_t i = 0; i < buffer.size(); ++i) {
36 68 buffer[i] = static_cast<int>(i) + 1;
37 }
38 }
39 8 return buffer;
40 }
41
42 8 void RingTransfer(MPI_Comm comm, int rank, int size, int src, int dest, std::vector<int> &buffer) {
43 8 const int count = static_cast<int>(buffer.size());
44 8 const int steps = (dest - src + size) % size;
45
46
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int step = 1; step <= steps; ++step) {
47 8 const int sender = (src + step - 1) % size;
48 8 const int receiver = (src + step) % size;
49
50
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == sender) {
51 4 MPI_Send(buffer.data(), count, MPI_INT, receiver, 0, comm);
52
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 } else if (rank == receiver) {
53 4 MPI_Recv(buffer.data(), count, MPI_INT, sender, 0, comm, MPI_STATUS_IGNORE);
54 }
55 }
56 8 }
57
58 8 int CheckAndReduce(MPI_Comm comm, int rank, int dest, const std::vector<int> &buffer) {
59 8 int local_ok = 1;
60
61
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == dest) {
62
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 4 times.
72 for (std::size_t i = 0; i < buffer.size(); ++i) {
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (buffer[i] != static_cast<int>(i) + 1) {
64 local_ok = 0;
65 break;
66 }
67 }
68 }
69
70 8 int global_ok = 0;
71 8 MPI_Allreduce(&local_ok, &global_ok, 1, MPI_INT, MPI_LAND, comm);
72 8 return global_ok;
73 }
74
75 } // namespace
76
77 12 GalkinDRingMPI::GalkinDRingMPI(const InType &in) {
78 SetTypeOfTask(GetStaticTypeOfTask());
79 12 GetInput() = in;
80 GetOutput() = 0;
81 12 }
82
83 12 bool GalkinDRingMPI::ValidationImpl() {
84 const auto &in = GetInput();
85
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (in.count <= 0) {
87 return false;
88 }
89
90 12 int size = 1;
91 12 MPI_Comm_size(MPI_COMM_WORLD, &size);
92 size = std::max(size, 1);
93
94
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (in.src < 0 || in.src >= size) {
95 return false;
96 }
97
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (in.dest < 0 || in.dest >= size) {
98 return false;
99 }
100
101 return true;
102 }
103
104 12 bool GalkinDRingMPI::PreProcessingImpl() {
105 12 GetOutput() = 0;
106 12 return true;
107 }
108
109 12 bool GalkinDRingMPI::RunImpl() {
110 12 MPI_Comm comm = MPI_COMM_NULL;
111 12 MPI_Comm_dup(MPI_COMM_WORLD, &comm);
112 CommGuard guard(&comm);
113
114 12 int rank = 0;
115 12 int size = 1;
116
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_rank(comm, &rank);
117
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 MPI_Comm_size(comm, &size);
118
119 12 const auto in = GetInput();
120
121
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (!ValidateParams(in, size)) {
122 GetOutput() = 0;
123 return true;
124 }
125
126
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
12 if (in.src == in.dest) {
127 4 GetOutput() = 1;
128 4 return true;
129 }
130
131
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 auto buffer = InitBuffer(rank, in.src, in.count);
132
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 RingTransfer(comm, rank, size, in.src, in.dest, buffer);
133
134
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 GetOutput() = CheckAndReduce(comm, rank, in.dest, buffer);
135 return true;
136 }
137
138 12 bool GalkinDRingMPI::PostProcessingImpl() {
139 12 return true;
140 }
141
142 } // namespace galkin_d_ring
143