GCC Code Coverage Report


Directory: ./
File: tasks/kulik_a_star/mpi/src/ops_mpi.cpp
Date: 2026-01-09 01:27:18
Exec Total Coverage
Lines: 34 84 40.5%
Functions: 5 11 45.5%
Branches: 8 62 12.9%

Line Branch Exec Source
1 #include "kulik_a_star/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <chrono>
6 #include <climits>
7 #include <cmath>
8 #include <cstddef>
9 #include <thread>
10 #include <vector>
11
12 #include "kulik_a_star/common/include/common.hpp"
13
14 namespace kulik_a_star {
15
16
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 KulikAStarMPI::KulikAStarMPI(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 10 auto source_rank = std::get<0>(in);
19 10 int proc_rank = 0;
20
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
21
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 if (proc_rank == source_rank) {
22 GetInput() = in;
23 } else {
24 6 GetInput() = InType{};
25 }
26 10 }
27
28 10 bool KulikAStarMPI::ValidationImpl() {
29 10 int proc_num = 0;
30 10 MPI_Comm_size(MPI_COMM_WORLD, &proc_num);
31 10 int proc_rank = 0;
32 10 auto source_rank = std::get<0>(GetInput());
33 10 auto destination_rank = std::get<1>(GetInput());
34 10 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
35
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if (proc_rank == source_rank) {
36 8 bool fs = (source_rank >= 0);
37 8 bool fd = (destination_rank >= 0);
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (proc_num >= 3) {
39 fs = fs && (source_rank < proc_num);
40 fd = fd && (destination_rank < proc_num);
41 }
42 8 return (fs && fd);
43 }
44 return true;
45 }
46
47 10 bool KulikAStarMPI::PreProcessingImpl() {
48 10 return true;
49 }
50
51 int KulikAStarMPI::FindActualSourceRank(int proc_num, int has_data) {
52 std::vector<int> all_has_data(proc_num);
53 MPI_Allgather(&has_data, 1, MPI_INT, all_has_data.data(), 1, MPI_INT, MPI_COMM_WORLD);
54 for (int i = 0; i < proc_num; i++) {
55 if (all_has_data[i] == 1) {
56 return i;
57 }
58 }
59 return -1;
60 }
61
62 void KulikAStarMPI::HandleSameSourceDestination(int proc_rank, int source_rank, size_t size,
63 const std::vector<int> &source_data, std::vector<int> &output) {
64 if (proc_rank == source_rank) {
65 output = source_data;
66 }
67 MPI_Bcast(output.data(), static_cast<int>(size), MPI_INT, source_rank, MPI_COMM_WORLD);
68 }
69
70 void KulikAStarMPI::ProcessZeroRouting(int source_rank, int destination_rank, size_t size,
71 const std::vector<int> &source_data, std::vector<int> &output) {
72 std::vector<int> buff(size);
73 MPI_Status status;
74
75 if (source_rank != 0) {
76 MPI_Recv(buff.data(), static_cast<int>(size), MPI_INT, source_rank, 0, MPI_COMM_WORLD, &status);
77 if (destination_rank != 0) {
78 MPI_Send(buff.data(), static_cast<int>(size), MPI_INT, destination_rank, 0, MPI_COMM_WORLD);
79 } else {
80 output = buff;
81 }
82 } else {
83 MPI_Send(source_data.data(), static_cast<int>(size), MPI_INT, destination_rank, 0, MPI_COMM_WORLD);
84 }
85 }
86
87 void KulikAStarMPI::ProcessDestination(int destination_rank, size_t size, std::vector<int> &output) {
88 std::vector<int> buff(size);
89 if (destination_rank != 0) {
90 MPI_Status status;
91 MPI_Recv(buff.data(), static_cast<int>(size), MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
92 }
93 output = buff;
94 }
95
96 void KulikAStarMPI::ProcessSource(int source_rank, size_t size, const std::vector<int> &source_data) {
97 if (source_rank != 0) {
98 MPI_Send(source_data.data(), static_cast<int>(size), MPI_INT, 0, 0, MPI_COMM_WORLD);
99 }
100 }
101
102 void KulikAStarMPI::HandleDifferentSourceDestination(int proc_rank, int source_rank, int destination_rank, size_t size,
103 const std::vector<int> &source_data, std::vector<int> &output) {
104 if (proc_rank == 0) {
105 ProcessZeroRouting(source_rank, destination_rank, size, source_data, output);
106 } else if (proc_rank == destination_rank) {
107 ProcessDestination(destination_rank, size, output);
108 } else if (proc_rank == source_rank) {
109 ProcessSource(source_rank, size, source_data);
110 }
111 MPI_Bcast(output.data(), static_cast<int>(size), MPI_INT, destination_rank, MPI_COMM_WORLD);
112 }
113
114 10 bool KulikAStarMPI::RunImpl() {
115 10 int proc_num = 0;
116 10 int proc_rank = 0;
117 10 MPI_Comm_size(MPI_COMM_WORLD, &proc_num);
118 10 MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
119 const auto &input = GetInput();
120 10 auto source_rank = std::get<0>(input);
121
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (proc_num < 3) {
122 10 GetOutput().resize(1U);
123 10 GetOutput()[0] = INT_MAX;
124 10 std::this_thread::sleep_for(std::chrono::milliseconds(1));
125 } else {
126 auto destination_rank = std::get<1>(input);
127 size_t size = std::get<2>(input).size();
128 int has_data = (size > 0) ? 1 : 0;
129 int actual_source = FindActualSourceRank(proc_num, has_data);
130 MPI_Bcast(&source_rank, 1, MPI_INT, actual_source, MPI_COMM_WORLD);
131 MPI_Bcast(&destination_rank, 1, MPI_INT, actual_source, MPI_COMM_WORLD);
132 MPI_Bcast(&size, 1, MPI_UINT64_T, actual_source, MPI_COMM_WORLD);
133 GetOutput().resize(size);
134 if (source_rank == destination_rank) {
135 HandleSameSourceDestination(proc_rank, source_rank, size, std::get<2>(input), GetOutput());
136 } else {
137 HandleDifferentSourceDestination(proc_rank, source_rank, destination_rank, size, std::get<2>(input), GetOutput());
138 }
139 }
140 10 return true;
141 }
142
143 10 bool KulikAStarMPI::PostProcessingImpl() {
144 10 return true;
145 }
146
147 } // namespace kulik_a_star
148