GCC Code Coverage Report


Directory: ./
File: tasks/golovanov_d_bcast/mpi/src/ops_mpi.cpp
Date: 2026-01-27 01:59:34
Exec Total Coverage
Lines: 53 58 91.4%
Functions: 6 6 100.0%
Branches: 25 48 52.1%

Line Branch Exec Source
1 #include "golovanov_d_bcast/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <cmath>
6 #include <cstdio>
7 #include <vector>
8
9 #include "golovanov_d_bcast/common/include/common.hpp"
10
11 namespace golovanov_d_bcast {
12
13
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 GolovanovDBcastMPI::GolovanovDBcastMPI(const InType &in) {
14 SetTypeOfTask(GetStaticTypeOfTask());
15 GetInput() = in;
16 4 GetOutput() = false;
17 4 }
18
19 4 bool GolovanovDBcastMPI::ValidationImpl() {
20 4 int n = std::get<1>(GetInput());
21 4 auto size = static_cast<size_t>(n);
22
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 return ((n > -1) && (std::get<2>(GetInput()).size() == size) && (std::get<3>(GetInput()).size() == size) &&
23
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
8 (std::get<4>(GetInput()).size() == size) && !GetOutput());
24 }
25
26 4 bool GolovanovDBcastMPI::PreProcessingImpl() {
27 int &index = std::get<0>(GetInput());
28 4 int world_size = 0;
29 4 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
30
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (index >= world_size || index < 0) {
31 index = 0;
32 }
33 4 return true;
34 }
35
36 4 bool GolovanovDBcastMPI::RunImpl() {
37 4 int rank = 0;
38 4 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
39 4 int main_proc = std::get<0>(GetInput());
40 4 int n = 0;
41
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == main_proc) {
42 2 n = std::get<1>(GetInput());
43 }
44 4 MyBcast(&n, 1, MPI_INT, main_proc, MPI_COMM_WORLD);
45 4 std::vector<int> v_int(n);
46
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<float> v_float(n);
47
1/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 std::vector<double> v_double(n);
48
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (rank == main_proc) {
49
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 v_int = std::get<2>(GetInput());
50
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 v_float = std::get<3>(GetInput());
51
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 v_double = std::get<4>(GetInput());
52 }
53
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MyBcast(v_int.data(), n, MPI_INT, main_proc, MPI_COMM_WORLD);
54
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MyBcast(v_float.data(), n, MPI_FLOAT, main_proc, MPI_COMM_WORLD);
55
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 MyBcast(v_double.data(), n, MPI_DOUBLE, main_proc, MPI_COMM_WORLD);
56
57
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 GetOutput() = true;
58 4 return true;
59 }
60
61 4 bool GolovanovDBcastMPI::PostProcessingImpl() {
62 4 return true;
63 }
64
65 16 int GolovanovDBcastMPI::MyBcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
66 16 int real_rank = 0;
67 16 MPI_Comm_rank(comm, &real_rank);
68 16 int world_size = 0;
69 16 MPI_Comm_size(comm, &world_size);
70 16 int local_rank = (real_rank - root + world_size) % world_size;
71 int rank_lvl = 0;
72 // корень отправляет первому
73
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (local_rank == 0) {
74
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (world_size > 1) {
75 rank_lvl = 1;
76 int local_child = 1;
77 8 int real_child = (root + local_child) % world_size;
78 8 MPI_Send(buffer, count, datatype, real_child, 0, comm);
79 }
80 }
81 // не-корень получает впервые
82 else {
83 8 rank_lvl = static_cast<int>(floor(log2(local_rank))) + 1;
84 8 int parent_offset = static_cast<int>(pow(2, rank_lvl - 1));
85 8 int local_parent = local_rank - parent_offset;
86 8 int real_parent = (root + local_parent) % world_size;
87 8 MPI_Recv(buffer, count, datatype, real_parent, 0, comm, MPI_STATUS_IGNORE);
88 }
89 // расслыка
90 16 int local_child = local_rank + static_cast<int>(pow(2, rank_lvl));
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 while (local_child < world_size) {
92 int real_child = (root + local_child) % world_size;
93 MPI_Send(buffer, count, datatype, real_child, 0, comm);
94 rank_lvl++;
95 local_child = local_rank + static_cast<int>(pow(2, rank_lvl));
96 }
97 16 return MPI_SUCCESS;
98 }
99
100 } // namespace golovanov_d_bcast
101