| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ermakov_a_spar_mat_mult/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <complex> | ||
| 5 | #include <cstddef> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "ermakov_a_spar_mat_mult/common/include/common.hpp" | ||
| 9 | |||
| 10 | namespace ermakov_a_spar_mat_mult { | ||
| 11 | |||
| 12 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | ErmakovASparMatMultSEQ::ErmakovASparMatMultSEQ(const InType &in) { |
| 13 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 14 | GetInput() = in; | ||
| 15 | 32 | } | |
| 16 | |||
| 17 | 64 | bool ErmakovASparMatMultSEQ::ValidateMatrix(const MatrixCRS &m) { | |
| 18 |
2/4✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
|
64 | if (m.rows < 0 || m.cols < 0) { |
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (m.row_ptr.size() != static_cast<size_t>(m.rows) + 1) { |
| 23 | return false; | ||
| 24 | } | ||
| 25 | |||
| 26 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (m.values.size() != m.col_index.size()) { |
| 27 | return false; | ||
| 28 | } | ||
| 29 | |||
| 30 | 64 | const int nnz = static_cast<int>(m.values.size()); | |
| 31 | |||
| 32 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
|
64 | if (m.row_ptr.empty()) { |
| 33 | return false; | ||
| 34 | } | ||
| 35 | |||
| 36 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 64 times.
|
64 | if (m.row_ptr.front() != 0 || m.row_ptr.back() != nnz) { |
| 37 | return false; | ||
| 38 | } | ||
| 39 | |||
| 40 |
2/2✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 64 times.
|
1072 | for (int i = 0; i < m.rows; ++i) { |
| 41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1008 times.
|
1008 | if (m.row_ptr[i] > m.row_ptr[i + 1]) { |
| 42 | return false; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 |
2/2✓ Branch 0 taken 11413 times.
✓ Branch 1 taken 64 times.
|
11477 | for (int k = 0; k < nnz; ++k) { |
| 47 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 11413 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11413 times.
|
11413 | if (m.col_index[k] < 0 || m.col_index[k] >= m.cols) { |
| 48 | return false; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | 32 | bool ErmakovASparMatMultSEQ::ValidationImpl() { | |
| 56 | 32 | const auto &a = GetInput().A; | |
| 57 | 32 | const auto &b = GetInput().B; | |
| 58 | |||
| 59 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | if (a.cols != b.rows) { |
| 60 | return false; | ||
| 61 | } | ||
| 62 | |||
| 63 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | if (!ValidateMatrix(a)) { |
| 64 | return false; | ||
| 65 | } | ||
| 66 | |||
| 67 | 32 | if (!ValidateMatrix(b)) { | |
| 68 | return false; | ||
| 69 | } | ||
| 70 | |||
| 71 | return true; | ||
| 72 | } | ||
| 73 | |||
| 74 | 32 | bool ErmakovASparMatMultSEQ::PreProcessingImpl() { | |
| 75 | 32 | a_ = GetInput().A; | |
| 76 | 32 | b_ = GetInput().B; | |
| 77 | |||
| 78 | 32 | c_.rows = a_.rows; | |
| 79 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | c_.cols = b_.cols; |
| 80 | c_.values.clear(); | ||
| 81 | c_.col_index.clear(); | ||
| 82 | 32 | c_.row_ptr.assign(static_cast<size_t>(c_.rows) + 1, 0); | |
| 83 | |||
| 84 | 32 | return true; | |
| 85 | } | ||
| 86 | |||
| 87 | 504 | void ErmakovASparMatMultSEQ::ProcessRow(int i, std::vector<std::complex<double>> &row_vals, std::vector<int> &row_mark, | |
| 88 | std::vector<int> &used_cols, int &nnz_so_far) { | ||
| 89 | 504 | const int a_start = a_.row_ptr[i]; | |
| 90 | 504 | const int a_end = a_.row_ptr[i + 1]; | |
| 91 | |||
| 92 |
2/2✓ Branch 0 taken 5649 times.
✓ Branch 1 taken 504 times.
|
6153 | for (int ak = a_start; ak < a_end; ++ak) { |
| 93 | 5649 | const int j = a_.col_index[ak]; | |
| 94 | 5649 | const auto a_ij = a_.values[ak]; | |
| 95 | |||
| 96 | 5649 | const int b_start = b_.row_ptr[j]; | |
| 97 | 5649 | const int b_end = b_.row_ptr[j + 1]; | |
| 98 | |||
| 99 |
2/2✓ Branch 0 taken 106585 times.
✓ Branch 1 taken 5649 times.
|
112234 | for (int bk = b_start; bk < b_end; ++bk) { |
| 100 |
2/2✓ Branch 0 taken 9030 times.
✓ Branch 1 taken 97555 times.
|
106585 | const int k = b_.col_index[bk]; |
| 101 | 106585 | const auto b_jk = b_.values[bk]; | |
| 102 | |||
| 103 |
2/2✓ Branch 0 taken 9030 times.
✓ Branch 1 taken 97555 times.
|
106585 | if (row_mark[k] != i) { |
| 104 |
1/2✓ Branch 0 taken 9030 times.
✗ Branch 1 not taken.
|
9030 | row_mark[k] = i; |
| 105 |
1/2✓ Branch 0 taken 9030 times.
✗ Branch 1 not taken.
|
9030 | row_vals[k] = a_ij * b_jk; |
| 106 | used_cols.push_back(k); | ||
| 107 | } else { | ||
| 108 | row_vals[k] += a_ij * b_jk; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | 504 | c_.row_ptr[i] = nnz_so_far; | |
| 114 | |||
| 115 | std::ranges::sort(used_cols); | ||
| 116 | |||
| 117 |
2/2✓ Branch 0 taken 9030 times.
✓ Branch 1 taken 504 times.
|
9534 | for (int k : used_cols) { |
| 118 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9030 times.
|
9030 | const auto v = row_vals[k]; |
| 119 | ✗ | if (v == std::complex<double>(0.0, 0.0)) { | |
| 120 | ✗ | continue; | |
| 121 | } | ||
| 122 | |||
| 123 |
2/2✓ Branch 0 taken 8835 times.
✓ Branch 1 taken 195 times.
|
9030 | c_.col_index.push_back(k); |
| 124 |
2/2✓ Branch 0 taken 8835 times.
✓ Branch 1 taken 195 times.
|
9030 | c_.values.push_back(v); |
| 125 | 9030 | ++nnz_so_far; | |
| 126 | } | ||
| 127 | 504 | } | |
| 128 | |||
| 129 | 32 | bool ErmakovASparMatMultSEQ::RunImpl() { | |
| 130 | 32 | const int m = a_.rows; | |
| 131 | 32 | const int p = b_.cols; | |
| 132 | |||
| 133 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | if (a_.cols != b_.rows) { |
| 134 | return false; | ||
| 135 | } | ||
| 136 | |||
| 137 | c_.values.clear(); | ||
| 138 | c_.col_index.clear(); | ||
| 139 | std::ranges::fill(c_.row_ptr, 0); | ||
| 140 | |||
| 141 | 32 | std::vector<std::complex<double>> row_vals(static_cast<size_t>(p), std::complex<double>(0.0, 0.0)); | |
| 142 |
1/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
32 | std::vector<int> row_mark(static_cast<size_t>(p), -1); |
| 143 | 32 | std::vector<int> used_cols; | |
| 144 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | used_cols.reserve(256); |
| 145 | |||
| 146 | 32 | int nnz_so_far = 0; | |
| 147 | |||
| 148 |
2/2✓ Branch 0 taken 504 times.
✓ Branch 1 taken 32 times.
|
536 | for (int i = 0; i < m; ++i) { |
| 149 | used_cols.clear(); | ||
| 150 |
1/2✓ Branch 1 taken 504 times.
✗ Branch 2 not taken.
|
504 | ProcessRow(i, row_vals, row_mark, used_cols, nnz_so_far); |
| 151 | } | ||
| 152 | |||
| 153 |
1/2✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
|
32 | c_.row_ptr[m] = nnz_so_far; |
| 154 | return true; | ||
| 155 | } | ||
| 156 | |||
| 157 | 32 | bool ErmakovASparMatMultSEQ::PostProcessingImpl() { | |
| 158 | 32 | GetOutput() = c_; | |
| 159 | 32 | return true; | |
| 160 | } | ||
| 161 | |||
| 162 | } // namespace ermakov_a_spar_mat_mult | ||
| 163 |