feat(cpp-object-oriented-modular-refactoring): step 10 - dense-blas-adapter

This commit is contained in:
KOKO\Mimi
2026-08-16 07:49:57 +09:00
parent 6b0ff31db0
commit 89fc13c873
7 changed files with 146 additions and 49 deletions
+20 -25
View File
@@ -6,6 +6,8 @@
#include <stdexcept>
#include <utility>
#include "math/dense_blas_internal.h"
namespace fesa {
namespace {
@@ -21,25 +23,15 @@ std::size_t CheckedStorageSize(const std::size_t rows,
return rows * columns;
}
/// @brief Converts a dense matrix dimension to the private MKL integer
/// contract.
MKL_INT ToMklSize(const std::size_t size) {
if (size > static_cast<std::size_t>((std::numeric_limits<MKL_INT>::max)())) {
/// @brief Preserves the Matrix exception contract around private size
/// conversion.
MKL_INT MklSizeOrThrow(const std::size_t size) {
const auto converted = dense_blas_internal::ToMklSize(size);
if (!converted.HasValue()) {
throw std::length_error{
"Dense matrix dimension exceeds the MKL integer range."};
}
return static_cast<MKL_INT>(size);
}
/// @brief Copies owned values without exposing the dense backend publicly.
void CopyValues(const std::vector<double>& source,
std::vector<double>& destination) {
if (source.empty()) {
return;
}
cblas_dcopy(ToMklSize(source.size()), source.data(), 1, destination.data(),
1);
return converted.Value();
}
} // namespace
@@ -54,7 +46,8 @@ Matrix::Matrix(const Matrix& other)
: rows_(other.rows_),
columns_(other.columns_),
values_(other.values_.size()) {
CopyValues(other.values_, values_);
dense_blas_internal::CopyValues(other.values_.data(), other.values_.size(),
values_.data());
}
Matrix::Matrix(Matrix&& other) noexcept
@@ -69,7 +62,8 @@ Matrix::Matrix(Matrix&& other) noexcept
Matrix& Matrix::operator=(const Matrix& other) {
if (this != &other) {
std::vector<double> copied(other.values_.size());
CopyValues(other.values_, copied);
dense_blas_internal::CopyValues(other.values_.data(), other.values_.size(),
copied.data());
rows_ = other.rows_;
columns_ = other.columns_;
values_.swap(copied);
@@ -121,9 +115,9 @@ Vector Matrix::Multiply(const Vector& rhs) const {
// The owned layout is row-major, so the leading dimension is the column
// count for the adapter call and remains invisible to public consumers.
cblas_dgemv(CblasRowMajor, CblasNoTrans, ToMklSize(rows_),
ToMklSize(columns_), 1.0, values_.data(), ToMklSize(columns_),
rhs.Data(), 1, 0.0, result.Data(), 1);
cblas_dgemv(CblasRowMajor, CblasNoTrans, MklSizeOrThrow(rows_),
MklSizeOrThrow(columns_), 1.0, values_.data(),
MklSizeOrThrow(columns_), rhs.Data(), 1, 0.0, result.Data(), 1);
return result;
}
@@ -138,10 +132,11 @@ Matrix Matrix::Multiply(const Matrix& rhs) const {
return result;
}
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, ToMklSize(rows_),
ToMklSize(rhs.columns_), ToMklSize(columns_), 1.0, values_.data(),
ToMklSize(columns_), rhs.values_.data(), ToMklSize(rhs.columns_),
0.0, result.values_.data(), ToMklSize(rhs.columns_));
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, MklSizeOrThrow(rows_),
MklSizeOrThrow(rhs.columns_), MklSizeOrThrow(columns_), 1.0,
values_.data(), MklSizeOrThrow(columns_), rhs.values_.data(),
MklSizeOrThrow(rhs.columns_), 0.0, result.values_.data(),
MklSizeOrThrow(rhs.columns_));
return result;
}