GCC Code Coverage Report


Directory: ./
File: tasks/yurkin_counting_number/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 58 60 96.7%
Functions: 6 6 100.0%
Branches: 37 56 66.1%

Line Branch Exec Source
1 #include "yurkin_counting_number/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <tuple>
8 #include <utility>
9 #include <vector>
10
11 #include "yurkin_counting_number/common/include/common.hpp"
12
13 namespace yurkin_counting_number {
14
15 namespace {
16
17 8 std::pair<std::vector<int>, std::vector<int>> ComputeSendCountsAndDispls(int total_size, int world_size) {
18 8 std::vector<int> sendcounts(static_cast<std::size_t>(world_size), 0);
19
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<int> displs(static_cast<std::size_t>(world_size), 0);
20
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (world_size <= 0 || total_size <= 0) {
21
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 return {sendcounts, displs};
22 }
23 7 const auto n = static_cast<std::size_t>(total_size);
24 const auto ws = static_cast<std::size_t>(world_size);
25 7 const auto chunk = (ws > 0U) ? (n / ws) : 0U;
26 7 const auto rem = (ws > 0U) ? (n % ws) : 0U;
27 std::size_t offset = 0;
28
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7 times.
21 for (std::size_t i = 0; i < ws; ++i) {
29
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
14 const auto add = chunk + (i < rem ? 1U : 0U);
30 14 sendcounts[i] = static_cast<int>(add);
31 14 displs[i] = static_cast<int>(offset);
32 14 offset += add;
33 }
34
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 return {sendcounts, displs};
35 }
36
37 } // namespace
38
39
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 YurkinCountingNumberMPI::YurkinCountingNumberMPI(const InType &in) {
40 SetTypeOfTask(GetStaticTypeOfTask());
41
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 GetInput() = in;
42 16 GetOutput() = 0;
43 16 }
44
45 16 bool YurkinCountingNumberMPI::ValidationImpl() {
46 16 return GetOutput() == 0;
47 }
48
49 16 bool YurkinCountingNumberMPI::PreProcessingImpl() {
50 16 GetOutput() = 0;
51 16 return true;
52 }
53
54 16 bool YurkinCountingNumberMPI::RunImpl() {
55 16 int world_rank = 0;
56 16 int world_size = 0;
57 16 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
58 16 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
59
60 const InType &global_input = GetInput();
61 16 int total_size = 0;
62
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (world_rank == 0) {
63 8 total_size = static_cast<int>(global_input.size());
64 }
65
66 16 MPI_Bcast(&total_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
67
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (world_size <= 0) {
69 GetOutput() = 0;
70 return true;
71 }
72
73 16 std::vector<int> sendcounts;
74 16 std::vector<int> displs;
75
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (world_rank == 0) {
76
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::tie(sendcounts, displs) = ComputeSendCountsAndDispls(total_size, world_size);
77 } else {
78
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 sendcounts.assign(static_cast<std::size_t>(world_size), 0);
79
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 displs.assign(static_cast<std::size_t>(world_size), 0);
80 }
81
82 16 int recvcount = 0;
83
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (world_rank == 0) {
84
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recvcount, 1, MPI_INT, 0, MPI_COMM_WORLD);
85 } else {
86
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Scatter(nullptr, 1, MPI_INT, &recvcount, 1, MPI_INT, 0, MPI_COMM_WORLD);
87 }
88
89 16 recvcount = std::max(recvcount, 0);
90
91
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 std::vector<char> local_buffer(static_cast<std::size_t>(recvcount), '\0');
92
93
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (world_rank == 0) {
94
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Scatterv(global_input.data(), sendcounts.data(), displs.data(), MPI_CHAR, local_buffer.data(), recvcount,
95 MPI_CHAR, 0, MPI_COMM_WORLD);
96 } else {
97
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Scatterv(nullptr, nullptr, nullptr, MPI_CHAR, local_buffer.data(), recvcount, MPI_CHAR, 0, MPI_COMM_WORLD);
98 }
99
100 16 int local_count = 0;
101
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 16 times.
133 for (int i = 0; i < recvcount; ++i) {
102
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 37 times.
117 const auto uc = static_cast<unsigned char>(local_buffer[static_cast<std::size_t>(i)]);
103
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 37 times.
117 if ((uc >= 'A' && uc <= 'Z') || (uc >= 'a' && uc <= 'z')) {
104 80 ++local_count;
105 }
106 }
107
108 16 int global_count = 0;
109
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 MPI_Allreduce(&local_count, &global_count, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
110
111
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 GetOutput() = global_count;
112 return true;
113 }
114
115 16 bool YurkinCountingNumberMPI::PostProcessingImpl() {
116 16 return GetOutput() >= 0;
117 }
118
119 } // namespace yurkin_counting_number
120