GCC Code Coverage Report


Directory: ./
File: tasks/egashin_k_lexicographical_check/mpi/src/ops_mpi.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 0 64 0.0%
Functions: 0 8 0.0%
Branches: 0 84 0.0%

Line Branch Exec Source
1 #include "egashin_k_lexicographical_check/mpi/include/ops_mpi.hpp"
2
3 #include <mpi.h>
4
5 #include <algorithm>
6 #include <vector>
7
8 #include "egashin_k_lexicographical_check/common/include/common.hpp"
9
10 namespace egashin_k_lexicographical_check {
11
12 TestTaskMPI::TestTaskMPI(const InType &in) {
13 SetTypeOfTask(GetStaticTypeOfTask());
14 GetInput() = in;
15 GetOutput() = false;
16 }
17
18 bool TestTaskMPI::ValidationImpl() {
19 return true;
20 }
21
22 bool TestTaskMPI::PreProcessingImpl() {
23 return true;
24 }
25
26 bool TestTaskMPI::PostProcessingImpl() {
27 return true;
28 }
29
30 void TestTaskMPI::CalculateDistribution(int size, int min_len, std::vector<int> &counts, std::vector<int> &displs) {
31 int delta = min_len / size;
32 int remainder = min_len % size;
33 for (int i = 0; i < size; ++i) {
34 counts[i] = delta + (i < remainder ? 1 : 0);
35 displs[i] = (i == 0) ? 0 : displs[i - 1] + counts[i - 1];
36 }
37 }
38
39 int TestTaskMPI::CompareLocal(const std::vector<char> &s1, const std::vector<char> &s2, int count) {
40 for (int i = 0; i < count; ++i) {
41 auto c1 = static_cast<unsigned char>(s1[i]);
42 auto c2 = static_cast<unsigned char>(s2[i]);
43 if (c1 < c2) {
44 return -1;
45 }
46 if (c1 > c2) {
47 return 1;
48 }
49 }
50 return 0;
51 }
52
53 bool TestTaskMPI::GetFinalDecision(const std::vector<int> &global_results, int s1_len, int s2_len) {
54 for (int res : global_results) {
55 if (res != 0) {
56 return res == -1;
57 }
58 }
59 return s1_len < s2_len;
60 }
61
62 bool TestTaskMPI::RunImpl() {
63 int rank = 0;
64 int size = 0;
65 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
66 MPI_Comm_size(MPI_COMM_WORLD, &size);
67
68 int min_len = 0;
69 int s1_len = 0;
70 int s2_len = 0;
71
72 if (rank == 0) {
73 s1_len = static_cast<int>(GetInput().first.size());
74 s2_len = static_cast<int>(GetInput().second.size());
75 min_len = std::min(s1_len, s2_len);
76 }
77
78 MPI_Bcast(&min_len, 1, MPI_INT, 0, MPI_COMM_WORLD);
79
80 if (min_len == 0) {
81 if (rank == 0) {
82 GetOutput() = (s1_len < s2_len);
83 }
84 return true;
85 }
86
87 std::vector<int> counts(size);
88 std::vector<int> displs(size);
89
90 if (rank == 0) {
91 CalculateDistribution(size, min_len, counts, displs);
92 }
93
94 int local_count = 0;
95 MPI_Scatter(counts.data(), 1, MPI_INT, &local_count, 1, MPI_INT, 0, MPI_COMM_WORLD);
96
97 std::vector<char> local_s1(local_count);
98 std::vector<char> local_s2(local_count);
99 const char *send_s1 = (rank == 0) ? GetInput().first.data() : nullptr;
100 const char *send_s2 = (rank == 0) ? GetInput().second.data() : nullptr;
101
102 if (local_count > 0 || rank == 0) {
103 MPI_Scatterv(send_s1, counts.data(), displs.data(), MPI_CHAR, local_s1.data(), local_count, MPI_CHAR, 0,
104 MPI_COMM_WORLD);
105 MPI_Scatterv(send_s2, counts.data(), displs.data(), MPI_CHAR, local_s2.data(), local_count, MPI_CHAR, 0,
106 MPI_COMM_WORLD);
107 } else {
108 MPI_Scatterv(send_s1, counts.data(), displs.data(), MPI_CHAR, local_s1.data(), 0, MPI_CHAR, 0, MPI_COMM_WORLD);
109 MPI_Scatterv(send_s2, counts.data(), displs.data(), MPI_CHAR, local_s2.data(), 0, MPI_CHAR, 0, MPI_COMM_WORLD);
110 }
111
112 int local_res = CompareLocal(local_s1, local_s2, local_count);
113
114 std::vector<int> global_results(size);
115 MPI_Gather(&local_res, 1, MPI_INT, global_results.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
116
117 if (rank == 0) {
118 GetOutput() = GetFinalDecision(global_results, s1_len, s2_len);
119 }
120 return true;
121 }
122
123 } // namespace egashin_k_lexicographical_check
124