| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "sokolov_k_matrix_double_fox/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <cstddef> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "sokolov_k_matrix_double_fox/common/include/common.hpp" | ||
| 9 | |||
| 10 | namespace sokolov_k_matrix_double_fox { | ||
| 11 | |||
| 12 | namespace { | ||
| 13 | |||
| 14 | 192 | void DecomposeToBlocks(const std::vector<double> &flat, std::vector<double> &blocks, int n, int bs, int q) { | |
| 15 |
2/2✓ Branch 0 taken 880 times.
✓ Branch 1 taken 192 times.
|
1072 | for (int bi = 0; bi < q; bi++) { |
| 16 |
2/2✓ Branch 0 taken 5616 times.
✓ Branch 1 taken 880 times.
|
6496 | for (int bj = 0; bj < q; bj++) { |
| 17 | 5616 | int block_off = ((bi * q) + bj) * (bs * bs); | |
| 18 |
2/2✓ Branch 0 taken 27568 times.
✓ Branch 1 taken 5616 times.
|
33184 | for (int i = 0; i < bs; i++) { |
| 19 |
2/2✓ Branch 0 taken 206160 times.
✓ Branch 1 taken 27568 times.
|
233728 | for (int j = 0; j < bs; j++) { |
| 20 | 206160 | blocks[block_off + (i * bs) + j] = flat[(((bi * bs) + i) * n) + ((bj * bs) + j)]; | |
| 21 | } | ||
| 22 | } | ||
| 23 | } | ||
| 24 | } | ||
| 25 | 192 | } | |
| 26 | |||
| 27 | 96 | void AssembleFromBlocks(const std::vector<double> &blocks, std::vector<double> &flat, int n, int bs, int q) { | |
| 28 |
2/2✓ Branch 0 taken 440 times.
✓ Branch 1 taken 96 times.
|
536 | for (int bi = 0; bi < q; bi++) { |
| 29 |
2/2✓ Branch 0 taken 2808 times.
✓ Branch 1 taken 440 times.
|
3248 | for (int bj = 0; bj < q; bj++) { |
| 30 | 2808 | int block_off = ((bi * q) + bj) * (bs * bs); | |
| 31 |
2/2✓ Branch 0 taken 13784 times.
✓ Branch 1 taken 2808 times.
|
16592 | for (int i = 0; i < bs; i++) { |
| 32 |
2/2✓ Branch 0 taken 103080 times.
✓ Branch 1 taken 13784 times.
|
116864 | for (int j = 0; j < bs; j++) { |
| 33 | 103080 | flat[(((bi * bs) + i) * n) + ((bj * bs) + j)] = blocks[block_off + (i * bs) + j]; | |
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | 96 | } | |
| 39 | |||
| 40 | 22040 | void MultiplyBlocks(const std::vector<double> &a, int a_off, const std::vector<double> &b, int b_off, | |
| 41 | std::vector<double> &c, int c_off, int bs) { | ||
| 42 |
2/2✓ Branch 0 taken 128264 times.
✓ Branch 1 taken 22040 times.
|
150304 | for (int i = 0; i < bs; i++) { |
| 43 |
2/2✓ Branch 0 taken 1013144 times.
✓ Branch 1 taken 128264 times.
|
1141408 | for (int k = 0; k < bs; k++) { |
| 44 | 1013144 | double val = a[a_off + (i * bs) + k]; | |
| 45 |
2/2✓ Branch 0 taken 9024200 times.
✓ Branch 1 taken 1013144 times.
|
10037344 | for (int j = 0; j < bs; j++) { |
| 46 | 9024200 | c[c_off + (i * bs) + j] += val * b[b_off + (k * bs) + j]; | |
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | 22040 | } | |
| 51 | |||
| 52 | 440 | void FoxStep(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c, int bs, int q, | |
| 53 | int step) { | ||
| 54 | 440 | int bsq = bs * bs; | |
| 55 |
2/2✓ Branch 0 taken 2808 times.
✓ Branch 1 taken 440 times.
|
3248 | for (int i = 0; i < q; i++) { |
| 56 | 2808 | int k = (i + step) % q; | |
| 57 |
2/2✓ Branch 0 taken 22040 times.
✓ Branch 1 taken 2808 times.
|
24848 | for (int j = 0; j < q; j++) { |
| 58 | 22040 | MultiplyBlocks(a, ((i * q) + k) * bsq, b, ((k * q) + j) * bsq, c, ((i * q) + j) * bsq, bs); | |
| 59 | } | ||
| 60 | } | ||
| 61 | 440 | } | |
| 62 | |||
| 63 | void FoxMultiply(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c, int bs, int q) { | ||
| 64 |
2/2✓ Branch 0 taken 440 times.
✓ Branch 1 taken 96 times.
|
536 | for (int step = 0; step < q; step++) { |
| 65 | 440 | FoxStep(a, b, c, bs, q, step); | |
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | 96 | int ChooseBlockSize(int n) { | |
| 70 |
1/2✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
|
136 | for (int div = static_cast<int>(std::sqrt(static_cast<double>(n))); div >= 1; div--) { |
| 71 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 96 times.
|
136 | if (n % div == 0) { |
| 72 | return div; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | return 1; | ||
| 76 | } | ||
| 77 | |||
| 78 | } // namespace | ||
| 79 | |||
| 80 | 96 | SokolovKMatrixDoubleFoxSEQ::SokolovKMatrixDoubleFoxSEQ(const InType &in) { | |
| 81 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 82 | 96 | GetInput() = in; | |
| 83 | GetOutput() = 0; | ||
| 84 | 96 | } | |
| 85 | |||
| 86 | 96 | bool SokolovKMatrixDoubleFoxSEQ::ValidationImpl() { | |
| 87 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
|
96 | return (GetInput() > 0) && (GetOutput() == 0); |
| 88 | } | ||
| 89 | |||
| 90 | 96 | bool SokolovKMatrixDoubleFoxSEQ::PreProcessingImpl() { | |
| 91 | 96 | GetOutput() = 0; | |
| 92 | 96 | n_ = GetInput(); | |
| 93 | 96 | block_size_ = ChooseBlockSize(n_); | |
| 94 | 96 | q_ = n_ / block_size_; | |
| 95 | 96 | auto sz = static_cast<std::size_t>(n_) * n_; | |
| 96 | 96 | std::vector<double> a(sz, 1.5); | |
| 97 |
1/4✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
96 | std::vector<double> b(sz, 2.0); |
| 98 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | blocks_a_.resize(sz); |
| 99 |
1/2✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
|
96 | blocks_b_.resize(sz); |
| 100 |
1/4✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
96 | blocks_c_.assign(sz, 0.0); |
| 101 | 96 | DecomposeToBlocks(a, blocks_a_, n_, block_size_, q_); | |
| 102 | 96 | DecomposeToBlocks(b, blocks_b_, n_, block_size_, q_); | |
| 103 | 96 | return true; | |
| 104 | } | ||
| 105 | |||
| 106 |
1/2✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
|
96 | bool SokolovKMatrixDoubleFoxSEQ::RunImpl() { |
| 107 | std::ranges::fill(blocks_c_, 0.0); | ||
| 108 | 96 | FoxMultiply(blocks_a_, blocks_b_, blocks_c_, block_size_, q_); | |
| 109 | 96 | return true; | |
| 110 | } | ||
| 111 | |||
| 112 | 96 | bool SokolovKMatrixDoubleFoxSEQ::PostProcessingImpl() { | |
| 113 | 96 | std::vector<double> result(static_cast<std::size_t>(n_) * n_); | |
| 114 | 96 | AssembleFromBlocks(blocks_c_, result, n_, block_size_, q_); | |
| 115 | 96 | double expected = 3.0 * n_; | |
| 116 |
1/2✓ Branch 0 taken 103080 times.
✗ Branch 1 not taken.
|
103080 | bool ok = std::ranges::all_of(result, [expected](double v) { return std::abs(v - expected) <= 1e-9; }); |
| 117 |
2/4✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
|
96 | GetOutput() = ok ? GetInput() : -1; |
| 118 | std::vector<double>().swap(blocks_a_); | ||
| 119 | std::vector<double>().swap(blocks_b_); | ||
| 120 | std::vector<double>().swap(blocks_c_); | ||
| 121 | 96 | return true; | |
| 122 | } | ||
| 123 | |||
| 124 | } // namespace sokolov_k_matrix_double_fox | ||
| 125 |