GCC Code Coverage Report


Directory: ./
File: tasks/goriacheva_k_mult_sparse_complex_matrix_ccs/all/src/ops_all.cpp
Date: 2026-05-11 08:26:31
Exec Total Coverage
Lines: 107 107 100.0%
Functions: 7 7 100.0%
Branches: 81 128 63.3%

Line Branch Exec Source
1 #include "goriacheva_k_mult_sparse_complex_matrix_ccs/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <omp.h>
5
6 #include <algorithm>
7 #include <cstddef>
8 #include <ranges>
9 #include <utility>
10 #include <vector>
11
12 #include "goriacheva_k_mult_sparse_complex_matrix_ccs/common/include/common.hpp"
13
14 namespace goriacheva_k_mult_sparse_complex_matrix_ccs {
15
16
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 GoriachevaKMultSparseComplexMatrixCcsALL::GoriachevaKMultSparseComplexMatrixCcsALL(const InType &in) {
17 SetTypeOfTask(GetStaticTypeOfTask());
18 GetInput() = in;
19 28 }
20
21 28 bool GoriachevaKMultSparseComplexMatrixCcsALL::ValidationImpl() {
22 auto &[a, b] = GetInput();
23
3/6
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
28 return (a.cols == b.rows) && !a.col_ptr.empty() && !b.col_ptr.empty();
24 }
25
26 28 bool GoriachevaKMultSparseComplexMatrixCcsALL::PreProcessingImpl() {
27 28 GetOutput() = {};
28 28 return true;
29 }
30
31 namespace {
32
33 41 void ProcessColumn(int j, const SparseMatrixCCS &a, const SparseMatrixCCS &b, std::vector<Complex> &values,
34 std::vector<int> &rows) {
35 41 std::vector<Complex> accumulator(a.rows);
36
1/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
41 std::vector<int> marker(a.rows, -1);
37 41 std::vector<int> used_rows;
38
39
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 41 times.
69 for (int bi = b.col_ptr[j]; bi < b.col_ptr[j + 1]; bi++) {
40 28 int k = b.row_ind[bi];
41 28 Complex b_val = b.values[bi];
42
43
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 28 times.
55 for (int ai = a.col_ptr[k]; ai < a.col_ptr[k + 1]; ai++) {
44
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 int i = a.row_ind[ai];
45
46
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if (marker[i] != j) {
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 marker[i] = j;
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 accumulator[i] = Complex(0.0, 0.0);
49 used_rows.push_back(i);
50 }
51
52 accumulator[i] += a.values[ai] * b_val;
53 }
54 }
55
56 std::ranges::sort(used_rows);
57
58
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 41 times.
68 for (int r : used_rows) {
59
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 24 times.
27 if (accumulator[r] != Complex(0.0, 0.0)) {
60 rows.push_back(r);
61 values.push_back(accumulator[r]);
62 }
63 }
64 41 }
65
66 void ComputeDispls(const std::vector<int> &recv_counts, std::vector<int> &displs, int &total_nnz) {
67 total_nnz = 0;
68
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (std::size_t i = 0; i < recv_counts.size(); i++) {
69 28 displs[i] = total_nnz;
70 28 total_nnz += recv_counts[i];
71 }
72 }
73
74 28 void BuildGlobalColPtr(int size, int cols_per_proc, int total_cols, const std::vector<int> &local_col_ptr,
75 std::vector<int> &global_col_ptr, int rank, MPI_Comm comm) {
76 int offset = 0;
77 int global_col = 0;
78
79
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 for (int proc = 0; proc < size; proc++) {
80 56 int start = proc * cols_per_proc;
81
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2 times.
56 int end = std::min(start + cols_per_proc, total_cols);
82
83 int p_cols = 0;
84
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2 times.
56 if (start < end) {
85 54 p_cols = end - start;
86 }
87
88 56 std::vector<int> tmp_col_ptr(p_cols + 1);
89
90
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 if (rank == proc) {
91
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 tmp_col_ptr = local_col_ptr;
92 }
93
94
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 MPI_Bcast(tmp_col_ptr.data(), p_cols + 1, MPI_INT, proc, comm);
95
96
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 if (rank == 0) {
97
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 28 times.
69 for (int j = 0; j < p_cols; j++) {
98 41 global_col_ptr[global_col++] = offset + tmp_col_ptr[j];
99 }
100 28 offset += tmp_col_ptr[p_cols];
101 }
102 }
103 28 }
104
105 } // namespace
106
107 28 bool GoriachevaKMultSparseComplexMatrixCcsALL::RunImpl() {
108 auto &a = std::get<0>(GetInput());
109 auto &b = std::get<1>(GetInput());
110 auto &c = GetOutput();
111
112 28 int rank = 0;
113 28 int size = 1;
114
115 28 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
116 28 MPI_Comm_size(MPI_COMM_WORLD, &size);
117
118 28 c.rows = a.rows;
119 28 c.cols = b.cols;
120
121 28 int cols_per_proc = (b.cols + size - 1) / size;
122 28 int start = rank * cols_per_proc;
123
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 int end = std::min(start + cols_per_proc, b.cols);
124 int local_cols = 0;
125
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
28 if (start < end) {
126 27 local_cols = end - start;
127 }
128
129 28 std::vector<std::vector<Complex>> local_values(local_cols);
130
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<std::vector<int>> local_rows(local_cols);
131
132 28 #pragma omp parallel for default(none) shared(a, b, local_values, local_rows, start, local_cols)
133 for (int j = 0; j < local_cols; j++) {
134 ProcessColumn(start + j, a, b, local_values[j], local_rows[j]);
135 }
136
137
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::vector<int> local_col_ptr(local_cols + 1);
138 28 int local_nnz = 0;
139
140
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 28 times.
69 for (int j = 0; j < local_cols; j++) {
141 41 local_col_ptr[j] = local_nnz;
142 41 local_nnz += static_cast<int>(local_values[j].size());
143 }
144
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 local_col_ptr[local_cols] = local_nnz;
145
146 28 std::vector<Complex> local_vals;
147 28 std::vector<int> local_inds;
148
149
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 local_vals.reserve(local_nnz);
150
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 local_inds.reserve(local_nnz);
151
152
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 28 times.
69 for (int j = 0; j < local_cols; j++) {
153
2/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
41 local_vals.insert(local_vals.end(), local_values[j].begin(), local_values[j].end());
154 41 local_inds.insert(local_inds.end(), local_rows[j].begin(), local_rows[j].end());
155 }
156
157
2/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 std::vector<int> recv_counts(size);
158
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Gather(&local_nnz, 1, MPI_INT, recv_counts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
159
160
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<int> displs(size, 0);
161 28 int total_nnz = 0;
162
163
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
164 ComputeDispls(recv_counts, displs, total_nnz);
165 }
166
167
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<int> recv_counts_dbl(size);
168
1/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
28 std::vector<int> displs_dbl(size);
169
170
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
171
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 14 times.
42 for (int i = 0; i < size; i++) {
172 28 recv_counts_dbl[i] = recv_counts[i] * 2;
173 28 displs_dbl[i] = displs[i] * 2;
174 }
175 }
176
177 28 std::vector<Complex> global_vals;
178 28 std::vector<int> global_inds;
179
180
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
181
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 global_vals.resize(total_nnz);
182
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 global_inds.resize(total_nnz);
183 }
184
185
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Gatherv(local_vals.data(), local_nnz * 2, MPI_DOUBLE, global_vals.data(), recv_counts_dbl.data(),
186 displs_dbl.data(), MPI_DOUBLE, 0, MPI_COMM_WORLD);
187
188
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Gatherv(local_inds.data(), local_nnz, MPI_INT, global_inds.data(), recv_counts.data(), displs.data(), MPI_INT, 0,
189 MPI_COMM_WORLD);
190
191
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
192
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 c.col_ptr.resize(c.cols + 1);
193 }
194
195
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 BuildGlobalColPtr(size, cols_per_proc, b.cols, local_col_ptr, c.col_ptr, rank, MPI_COMM_WORLD);
196
197
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank == 0) {
198 14 c.col_ptr[c.cols] = total_nnz;
199 14 c.values = std::move(global_vals);
200 14 c.row_ind = std::move(global_inds);
201 }
202
203
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(&total_nnz, 1, MPI_INT, 0, MPI_COMM_WORLD);
204
205
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
28 if (rank != 0) {
206 14 c.rows = a.rows;
207 14 c.cols = b.cols;
208
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 c.values.resize(total_nnz);
209
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 c.row_ind.resize(total_nnz);
210
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 c.col_ptr.resize(c.cols + 1);
211 }
212
213
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(c.values.data(), total_nnz * 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
214
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(c.row_ind.data(), total_nnz, MPI_INT, 0, MPI_COMM_WORLD);
215
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 MPI_Bcast(c.col_ptr.data(), c.cols + 1, MPI_INT, 0, MPI_COMM_WORLD);
216
217 28 return true;
218 28 }
219
220 28 bool GoriachevaKMultSparseComplexMatrixCcsALL::PostProcessingImpl() {
221 28 return true;
222 }
223
224 } // namespace goriacheva_k_mult_sparse_complex_matrix_ccs
225