feat(cpp-object-oriented-modular-refactoring): step 10 - dense-blas-adapter
This commit is contained in:
+20
-25
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user