| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "makoveeva_matmul_double_seq/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <vector> | ||
| 6 | |||
| 7 | #include "makoveeva_matmul_double_seq/common/include/common.hpp" // для InType | ||
| 8 | |||
| 9 | namespace makoveeva_matmul_double_seq { | ||
| 10 | namespace { | ||
| 11 | |||
| 12 | ✗ | void ProcessBlock(const std::vector<double> &a, const std::vector<double> &b, std::vector<double> &c, int n, | |
| 13 | int i_start, int i_end, int j_start, int j_end, int k_start, int k_end) { | ||
| 14 | ✗ | for (int i = i_start; i < i_end; ++i) { | |
| 15 | ✗ | for (int j = j_start; j < j_end; ++j) { | |
| 16 | double sum = 0.0; | ||
| 17 | ✗ | for (int k = k_start; k < k_end; ++k) { | |
| 18 | ✗ | sum += a[(i * n) + k] * b[(k * n) + j]; | |
| 19 | } | ||
| 20 | ✗ | c[(i * n) + j] += sum; | |
| 21 | } | ||
| 22 | } | ||
| 23 | ✗ | } | |
| 24 | |||
| 25 | int CalculateBlockSize(int n) { | ||
| 26 | ✗ | return std::max(1, static_cast<int>(std::sqrt(static_cast<double>(n)))); | |
| 27 | } | ||
| 28 | |||
| 29 | int CalculateNumBlocks(int n, int block_size) { | ||
| 30 | ✗ | return (n + block_size - 1) / block_size; | |
| 31 | } | ||
| 32 | |||
| 33 | } // namespace | ||
| 34 | |||
| 35 | ✗ | MatmulDoubleSeqTask::MatmulDoubleSeqTask(const InType &in) | |
| 36 | ✗ | : n_(std::get<0>(in)), A_(std::get<1>(in)), B_(std::get<2>(in)), C_(n_ * n_, 0.0) { | |
| 37 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 38 | ✗ | GetOutput() = C_; | |
| 39 | ✗ | } | |
| 40 | |||
| 41 | ✗ | bool MatmulDoubleSeqTask::ValidationImpl() { | |
| 42 | ✗ | const bool valid_n = n_ > 0; | |
| 43 | ✗ | const bool valid_a = A_.size() == n_ * n_; | |
| 44 | const bool valid_b = B_.size() == n_ * n_; | ||
| 45 | ✗ | return valid_n && valid_a && valid_b; | |
| 46 | } | ||
| 47 | |||
| 48 | ✗ | bool MatmulDoubleSeqTask::PreProcessingImpl() { | |
| 49 | ✗ | return true; | |
| 50 | } | ||
| 51 | |||
| 52 | ✗ | bool MatmulDoubleSeqTask::RunImpl() { | |
| 53 | ✗ | if (n_ <= 0) { | |
| 54 | return false; | ||
| 55 | } | ||
| 56 | |||
| 57 | // Очищаем C_ перед вычислениями | ||
| 58 | ✗ | C_.assign(C_.size(), 0.0); | |
| 59 | |||
| 60 | ✗ | const int n_int = static_cast<int>(n_); | |
| 61 | const int block_size = CalculateBlockSize(n_int); | ||
| 62 | const int num_blocks = CalculateNumBlocks(n_int, block_size); | ||
| 63 | |||
| 64 | ✗ | for (int ib = 0; ib < num_blocks; ++ib) { | |
| 65 | ✗ | for (int jb = 0; jb < num_blocks; ++jb) { | |
| 66 | ✗ | for (int kb = 0; kb < num_blocks; ++kb) { | |
| 67 | ✗ | const int i_start = ib * block_size; | |
| 68 | ✗ | const int i_end = std::min(i_start + block_size, n_int); | |
| 69 | ✗ | const int j_start = jb * block_size; | |
| 70 | ✗ | const int j_end = std::min(j_start + block_size, n_int); | |
| 71 | ✗ | const int k_start = kb * block_size; | |
| 72 | ✗ | const int k_end = std::min(k_start + block_size, n_int); | |
| 73 | |||
| 74 | ✗ | ProcessBlock(A_, B_, C_, n_int, i_start, i_end, j_start, j_end, k_start, k_end); | |
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | ✗ | GetOutput() = C_; | |
| 80 | return true; | ||
| 81 | } | ||
| 82 | |||
| 83 | ✗ | bool MatmulDoubleSeqTask::PostProcessingImpl() { | |
| 84 | ✗ | return true; | |
| 85 | } | ||
| 86 | |||
| 87 | } // namespace makoveeva_matmul_double_seq | ||
| 88 |