GCC Code Coverage Report


Directory: ./
File: tasks/tsyplakov_k_mul_double_crs_matrix/all/src/ops_all.cpp
Date: 2026-06-04 20:25:32
Exec Total Coverage
Lines: 76 76 100.0%
Functions: 7 7 100.0%
Branches: 56 102 54.9%

Line Branch Exec Source
1 #include "tsyplakov_k_mul_double_crs_matrix/all/include/ops_all.hpp"
2
3 #include <mpi.h>
4 #include <tbb/blocked_range.h>
5 #include <tbb/parallel_for.h>
6
7 #include <algorithm>
8 #include <cmath>
9 #include <unordered_map>
10 #include <utility>
11 #include <vector>
12
13 #include "tsyplakov_k_mul_double_crs_matrix/common/include/common.hpp"
14
15 namespace tsyplakov_k_mul_double_crs_matrix {
16
17 namespace {
18
19 9 void ComputeRow(const SparseMatrixCRS &a, const SparseMatrixCRS &b, int row, std::vector<double> &values,
20 std::vector<int> &cols) {
21 std::unordered_map<int, double> acc;
22
23
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 9 times.
20 for (int ia = a.row_ptr[row]; ia < a.row_ptr[row + 1]; ++ia) {
24 11 const int k = a.col_index[ia];
25 11 const double va = a.values[ia];
26
27
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
22 for (int ib = b.row_ptr[k]; ib < b.row_ptr[k + 1]; ++ib) {
28
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 acc[b.col_index[ib]] += va * b.values[ib];
29 }
30 }
31
32
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 for (const auto &[c, v] : acc) {
33
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (std::fabs(v) > 1e-12) {
34 cols.push_back(c);
35 values.push_back(v);
36 }
37 }
38 9 }
39
40 } // namespace
41
42
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 TsyplakovKTestTaskALL::TsyplakovKTestTaskALL(const InType &in) {
43 SetTypeOfTask(GetStaticTypeOfTask());
44 GetInput() = in;
45 8 }
46
47 8 bool TsyplakovKTestTaskALL::ValidationImpl() {
48 const auto &in = GetInput();
49 8 return in.a.cols == in.b.rows;
50 }
51
52 8 bool TsyplakovKTestTaskALL::PreProcessingImpl() {
53 8 return true;
54 }
55
56 8 bool TsyplakovKTestTaskALL::RunImpl() {
57 8 const auto &a = GetInput().a;
58 8 const auto &b = GetInput().b;
59
60 8 int rank = 0;
61 8 int size = 1;
62
63 8 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
64 8 MPI_Comm_size(MPI_COMM_WORLD, &size);
65
66 8 const int n = a.rows;
67
68 8 const int base = n / size;
69 8 const int rem = n % size;
70
71
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 const int start = (rank * base) + std::min(rank, rem);
72
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 const int local_n = base + (rank < rem ? 1 : 0);
73
74 8 std::vector<std::vector<double>> loc_vals(local_n);
75
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<std::vector<int>> loc_cols(local_n);
76
77
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
17 tbb::parallel_for(tbb::blocked_range<int>(0, local_n), [&](const tbb::blocked_range<int> &r) {
78
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 9 times.
18 for (int i = r.begin(); i < r.end(); ++i) {
79 9 ComputeRow(a, b, start + i, loc_vals[i], loc_cols[i]);
80 }
81 9 });
82
83
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 std::vector<int> local_sizes(local_n);
84
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
17 for (int i = 0; i < local_n; ++i) {
85 9 local_sizes[i] = static_cast<int>(loc_vals[i].size());
86 }
87
88
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 std::vector<int> rows_per_proc(size);
89
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Gather(&local_n, 1, MPI_INT, rows_per_proc.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
90
91
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<int> row_displs(size, 0);
92
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == 0) {
93
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (int i = 1; i < size; ++i) {
94 4 row_displs[i] = row_displs[i - 1] + rows_per_proc[i - 1];
95 }
96 }
97
98
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 std::vector<int> flat_sizes(n, 0);
99
100
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Gatherv(local_sizes.data(), local_n, MPI_INT, flat_sizes.data(), rows_per_proc.data(), row_displs.data(), MPI_INT,
101 0, MPI_COMM_WORLD);
102
103
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(flat_sizes.data(), n, MPI_INT, 0, MPI_COMM_WORLD);
104
105 8 std::vector<double> local_v;
106 8 std::vector<int> local_c;
107
108 8 int local_nnz = 0;
109
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
17 for (int i = 0; i < local_n; ++i) {
110
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 local_nnz += static_cast<int>(loc_vals[i].size());
111
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 local_v.insert(local_v.end(), loc_vals[i].begin(), loc_vals[i].end());
112 9 local_c.insert(local_c.end(), loc_cols[i].begin(), loc_cols[i].end());
113 }
114
115
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 std::vector<int> nnz_counts(size);
116
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Gather(&local_nnz, 1, MPI_INT, nnz_counts.data(), 1, MPI_INT, 0, MPI_COMM_WORLD);
117
118
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<int> nnz_disp(size, 0);
119 8 int total_nnz = 0;
120
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (rank == 0) {
121
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (int i = 1; i < size; ++i) {
122 4 nnz_disp[i] = nnz_disp[i - 1] + nnz_counts[i - 1];
123 }
124 4 total_nnz = nnz_disp[size - 1] + nnz_counts[size - 1];
125 }
126
127
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(nnz_counts.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
128
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(nnz_disp.data(), size, MPI_INT, 0, MPI_COMM_WORLD);
129
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Bcast(&total_nnz, 1, MPI_INT, 0, MPI_COMM_WORLD);
130
131
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<double> out_v(total_nnz);
132
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<int> out_c(total_nnz);
133
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 std::vector<int> out_row_ptr(n + 1, 0);
134
135
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Allgatherv(local_v.data(), local_nnz, MPI_DOUBLE, out_v.data(), nnz_counts.data(), nnz_disp.data(), MPI_DOUBLE,
136 MPI_COMM_WORLD);
137
138
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 MPI_Allgatherv(local_c.data(), local_nnz, MPI_INT, out_c.data(), nnz_counts.data(), nnz_disp.data(), MPI_INT,
139 MPI_COMM_WORLD);
140
141
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8 times.
26 for (int i = 0; i < n; ++i) {
142 18 out_row_ptr[i + 1] = out_row_ptr[i] + flat_sizes[i];
143 }
144
145
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 SparseMatrixCRS res(n, b.cols);
146 res.values = std::move(out_v);
147 res.col_index = std::move(out_c);
148 res.row_ptr = std::move(out_row_ptr);
149 8 GetOutput() = std::move(res);
150
151 8 return true;
152 16 }
153
154 8 bool TsyplakovKTestTaskALL::PostProcessingImpl() {
155 8 return true;
156 }
157
158 } // namespace tsyplakov_k_mul_double_crs_matrix
159