GCC Code Coverage Report


Directory: ./
File: tasks/telnov_transfer_one_all/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 4 12 33.3%
Branches: 15 24 62.5%

Line Branch Exec Source
1 #include "telnov_transfer_one_all/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cstdlib>
6 #include <type_traits>
7
8 namespace telnov_transfer_one_all {
9
10 template <typename T>
11
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 TelnovTransferOneAllMPI<T>::TelnovTransferOneAllMPI(const InType &in) {
12 this->SetTypeOfTask(GetStaticTypeOfTask());
13
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 this->GetInput() = in;
14
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 this->GetOutput().resize(0);
15 24 }
16
17 template <typename T>
18
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
24 bool TelnovTransferOneAllMPI<T>::ValidationImpl() {
19
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
24 return (!this->GetInput().empty()) && (this->GetOutput().empty());
20 }
21
22 template <typename T>
23 24 bool TelnovTransferOneAllMPI<T>::PreProcessingImpl() {
24 24 return true;
25 }
26
27 template <typename T>
28 24 bool TelnovTransferOneAllMPI<T>::RunImpl() {
29 static struct MPIInit {
30 MPIInit() {
31 8 int initialized = 0;
32
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 MPI_Initialized(&initialized);
33 }
34
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
32 } mpi_init;
35 (void)mpi_init;
36
37 24 int rank = 0;
38 24 int size = 0;
39 24 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
40 24 MPI_Comm_size(MPI_COMM_WORLD, &size);
41
42 MPI_Datatype mpi_type = MPI_DATATYPE_NULL;
43 if constexpr (std::is_same_v<T, int>) {
44 mpi_type = MPI_INT;
45 } else if constexpr (std::is_same_v<T, float>) {
46 mpi_type = MPI_FLOAT;
47 } else if constexpr (std::is_same_v<T, double>) {
48 mpi_type = MPI_DOUBLE;
49 } else {
50 return false;
51 }
52
53 auto &input = this->GetInput();
54 24 int count = static_cast<int>(input.size());
55 void *data_ptr = input.data();
56
57 const int root = 0;
58 24 int virtual_rank = (rank + size - root) % size;
59
60 int mask = 1;
61
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
36 while (mask < size) {
62
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
24 if ((virtual_rank & mask) == 0) {
63 12 int dest = virtual_rank | mask;
64
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 if (dest < size) {
65 12 int real_dest = (dest + root) % size;
66 12 MPI_Send(data_ptr, count, mpi_type, real_dest, 0, MPI_COMM_WORLD);
67 }
68 } else {
69 12 int src = virtual_rank & (~mask);
70 12 int real_src = (src + root) % size;
71 12 MPI_Recv(data_ptr, count, mpi_type, real_src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
72 break;
73 }
74 12 mask <<= 1;
75 }
76
77 24 this->GetOutput() = input;
78 24 return true;
79 }
80
81 template <typename T>
82 12 bool TelnovTransferOneAllMPI<T>::PostProcessingImpl() {
83 12 return !this->GetOutput().empty();
84 }
85
86 template class TelnovTransferOneAllMPI<int>;
87 template class TelnovTransferOneAllMPI<float>;
88 template class TelnovTransferOneAllMPI<double>;
89
90 } // namespace telnov_transfer_one_all
91