GCC Code Coverage Report


Directory: ./
File: tasks/kulik_a_mat_mul_double_ccs/omp/src/ops_omp.cpp
Date: 2026-04-02 17:12:27
Exec Total Coverage
Lines: 43 43 100.0%
Functions: 6 6 100.0%
Branches: 23 36 63.9%

Line Branch Exec Source
1 #include "kulik_a_mat_mul_double_ccs/omp/include/ops_omp.hpp"
2
3 #include <omp.h>
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <tuple>
8 #include <vector>
9
10 #include "kulik_a_mat_mul_double_ccs/common/include/common.hpp"
11
12 namespace kulik_a_mat_mul_double_ccs {
13
14 24 void KulikAMatMulDoubleCcsOMP::ProcessColumn(size_t j, int tid, const CCS &a, const CCS &b,
15 std::vector<std::vector<double>> &thread_accum,
16 std::vector<std::vector<bool>> &thread_nz,
17 std::vector<std::vector<size_t>> &thread_nnz_rows,
18 std::vector<std::vector<double>> &local_values,
19 std::vector<std::vector<size_t>> &local_rows) {
20
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 24 times.
60 for (size_t k = b.col_ind[j]; k < b.col_ind[j + 1]; ++k) {
21 36 size_t ind = b.row[k];
22 36 double b_val = b.value[k];
23
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 36 times.
92 for (size_t zc = a.col_ind[ind]; zc < a.col_ind[ind + 1]; ++zc) {
24 56 size_t i = a.row[zc];
25 56 double a_val = a.value[zc];
26
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 thread_accum[tid][i] += a_val * b_val;
27
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 if (!thread_nz[tid][i]) {
28 thread_nz[tid][i] = true;
29 thread_nnz_rows[tid].push_back(i);
30 }
31 }
32 }
33
34 24 std::ranges::sort(thread_nnz_rows[tid]);
35
36
3/4
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 24 times.
72 for (size_t i : thread_nnz_rows[tid]) {
37
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (thread_accum[tid][i] != 0.0) {
38 local_rows[j].push_back(i);
39 local_values[j].push_back(thread_accum[tid][i]);
40 }
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 thread_accum[tid][i] = 0.0;
42 thread_nz[tid][i] = false;
43 }
44 thread_nnz_rows[tid].clear();
45 24 }
46
47
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 KulikAMatMulDoubleCcsOMP::KulikAMatMulDoubleCcsOMP(const InType &in) {
48 SetTypeOfTask(GetStaticTypeOfTask());
49 GetInput() = in;
50 4 }
51
52 4 bool KulikAMatMulDoubleCcsOMP::ValidationImpl() {
53 const auto &a = std::get<0>(GetInput());
54 const auto &b = std::get<1>(GetInput());
55 4 return (a.m == b.n);
56 }
57
58 4 bool KulikAMatMulDoubleCcsOMP::PreProcessingImpl() {
59 4 return true;
60 }
61
62 4 bool KulikAMatMulDoubleCcsOMP::RunImpl() {
63 const auto &a = std::get<0>(GetInput());
64 const auto &b = std::get<1>(GetInput());
65 OutType &c = GetOutput();
66 4 c.n = a.n;
67 4 c.m = b.m;
68 4 c.col_ind.assign(c.m + 1, 0);
69
70 4 std::vector<std::vector<double>> local_values(b.m);
71
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::vector<std::vector<size_t>> local_rows(b.m);
72
73 4 int num_threads = omp_get_max_threads();
74
75
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 std::vector<std::vector<double>> thread_accum(num_threads, std::vector<double>(a.n, 0.0));
76
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 std::vector<std::vector<bool>> thread_nz(num_threads, std::vector<bool>(a.n, false));
77
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::vector<std::vector<size_t>> thread_nnz_rows(num_threads);
78
79 4 #pragma omp parallel for default(none) schedule(static) \
80 shared(a, b, thread_accum, thread_nz, thread_nnz_rows, local_values, local_rows)
81 for (size_t j = 0; j < b.m; ++j) {
82 int tid = omp_get_thread_num();
83 ProcessColumn(j, tid, a, b, thread_accum, thread_nz, thread_nnz_rows, local_values, local_rows);
84 }
85
86 size_t total_nz = 0;
87
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 for (size_t j = 0; j < b.m; ++j) {
88 24 c.col_ind[j] = total_nz;
89 24 total_nz += local_values[j].size();
90 }
91 4 c.col_ind[b.m] = total_nz;
92 4 c.nz = total_nz;
93
94
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 c.value.resize(total_nz);
95
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 c.row.resize(total_nz);
96
97 4 #pragma omp parallel for default(none) schedule(static) shared(b, c, local_values, local_rows)
98 for (size_t j = 0; j < b.m; ++j) {
99 size_t offset = c.col_ind[j];
100 size_t col_nz = local_values[j].size();
101 for (size_t k = 0; k < col_nz; ++k) {
102 c.value[offset + k] = local_values[j][k];
103 c.row[offset + k] = local_rows[j][k];
104 }
105 }
106
107 4 return true;
108 4 }
109
110 4 bool KulikAMatMulDoubleCcsOMP::PostProcessingImpl() {
111 4 return true;
112 }
113
114 } // namespace kulik_a_mat_mul_double_ccs
115