GCC Code Coverage Report


Directory: ./
File: tasks/korolev_k_ring_topology/seq/src/ops_seq.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 0 71 0.0%
Functions: 0 9 0.0%
Branches: 0 38 0.0%

Line Branch Exec Source
1 #include "korolev_k_ring_topology/seq/include/ops_seq.hpp"
2
3 #include <mpi.h>
4
5 #include <array>
6 #include <cstdint>
7 #include <vector>
8
9 #include "korolev_k_ring_topology/common/include/common.hpp"
10
11 namespace korolev_k_ring_topology {
12
13 KorolevKRingTopologySEQ::KorolevKRingTopologySEQ(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 GetOutput() = {};
17 }
18
19 bool KorolevKRingTopologySEQ::ValidationImpl() {
20 int size = 0;
21 MPI_Comm_size(MPI_COMM_WORLD, &size);
22
23 const auto &input = GetInput();
24 if (input.source < 0 || input.source >= size) {
25 return false;
26 }
27 if (input.dest < 0 || input.dest >= size) {
28 return false;
29 }
30 return true;
31 }
32
33 bool KorolevKRingTopologySEQ::PreProcessingImpl() {
34 GetOutput() = {};
35 return true;
36 }
37
38 namespace {
39 void HandleSelfSend(int rank, int source, const std::vector<int> &input_data, MPI_Comm cart_comm,
40 std::vector<int> &output) {
41 if (rank == source) {
42 output = input_data;
43 }
44 uint64_t data_size = input_data.size();
45 MPI_Bcast(&data_size, 1, MPI_UINT64_T, source, cart_comm);
46 if (rank != source) {
47 output.resize(data_size);
48 }
49 MPI_Bcast(output.data(), static_cast<int>(data_size), MPI_INT, source, cart_comm);
50 }
51
52 void SendDataFromSource(int rank, int source, int right_neighbor, const std::vector<int> &input_data,
53 MPI_Comm cart_comm) {
54 if (rank == source) {
55 auto data_size = static_cast<uint64_t>(input_data.size());
56 MPI_Send(&data_size, 1, MPI_UINT64_T, right_neighbor, 0, cart_comm);
57 MPI_Send(input_data.data(), static_cast<int>(data_size), MPI_INT, right_neighbor, 1, cart_comm);
58 }
59 }
60
61 void ForwardDataInRing(int rank, int source, int dest, int size, int left_neighbor, int right_neighbor,
62 MPI_Comm cart_comm, std::vector<int> &data, std::vector<int> &output) {
63 int steps_right = (dest - source + size) % size;
64 int current_step = (rank - source + size) % size;
65
66 if (current_step > 0 && current_step <= steps_right) {
67 uint64_t data_size = 0;
68 MPI_Recv(&data_size, 1, MPI_UINT64_T, left_neighbor, 0, cart_comm, MPI_STATUS_IGNORE);
69 data.resize(data_size);
70 MPI_Recv(data.data(), static_cast<int>(data_size), MPI_INT, left_neighbor, 1, cart_comm, MPI_STATUS_IGNORE);
71
72 if (rank == dest) {
73 output = data;
74 } else {
75 MPI_Send(&data_size, 1, MPI_UINT64_T, right_neighbor, 0, cart_comm);
76 MPI_Send(data.data(), static_cast<int>(data_size), MPI_INT, right_neighbor, 1, cart_comm);
77 }
78 }
79 }
80
81 void BroadcastResult(int rank, int dest, MPI_Comm cart_comm, uint64_t data_size, std::vector<int> &output) {
82 MPI_Bcast(&data_size, 1, MPI_UINT64_T, dest, cart_comm);
83 if (rank != dest) {
84 output.resize(data_size);
85 }
86 MPI_Bcast(output.data(), static_cast<int>(data_size), MPI_INT, dest, cart_comm);
87 }
88
89 void ProcessOutputIteration(int iter, std::vector<int> &output) {
90 for (auto &elem : output) {
91 elem += iter;
92 elem -= iter;
93 }
94 }
95 } // namespace
96
97 bool KorolevKRingTopologySEQ::RunImpl() {
98 int rank = 0;
99 int size = 0;
100 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
101 MPI_Comm_size(MPI_COMM_WORLD, &size);
102
103 const auto &input = GetInput();
104 int source = input.source;
105 int dest = input.dest;
106
107 std::array<int, 1> dims = {size};
108 std::array<int, 1> periods = {1};
109 int reorder = 0;
110
111 MPI_Comm cart_comm = MPI_COMM_NULL;
112 MPI_Cart_create(MPI_COMM_WORLD, 1, dims.data(), periods.data(), reorder, &cart_comm);
113
114 int left_neighbor = 0;
115 int right_neighbor = 0;
116 MPI_Cart_shift(cart_comm, 0, 1, &left_neighbor, &right_neighbor);
117
118 std::vector<int> data;
119 const int num_iterations = 50;
120
121 for (int iter = 0; iter < num_iterations; ++iter) {
122 if (source == dest) {
123 HandleSelfSend(rank, source, input.data, cart_comm, GetOutput());
124 ProcessOutputIteration(iter, GetOutput());
125 continue;
126 }
127
128 SendDataFromSource(rank, source, right_neighbor, input.data, cart_comm);
129 ForwardDataInRing(rank, source, dest, size, left_neighbor, right_neighbor, cart_comm, data, GetOutput());
130
131 uint64_t data_size = (rank == dest) ? static_cast<uint64_t>(GetOutput().size()) : 0;
132 BroadcastResult(rank, dest, cart_comm, data_size, GetOutput());
133 ProcessOutputIteration(iter, GetOutput());
134 }
135
136 MPI_Comm_free(&cart_comm);
137
138 return true;
139 }
140
141 bool KorolevKRingTopologySEQ::PostProcessingImpl() {
142 return true;
143 }
144
145 } // namespace korolev_k_ring_topology
146