100 lines
4.6 KiB
C++
100 lines
4.6 KiB
C++
#ifndef FESA_SRC_FESA_MATH_DENSE_BLAS_INTERNAL_H_
|
|
#define FESA_SRC_FESA_MATH_DENSE_BLAS_INTERNAL_H_
|
|
|
|
#include <mkl.h>
|
|
|
|
#include <cstddef>
|
|
|
|
#include "fesa/core/status.h"
|
|
#include "fesa/math/matrix.h"
|
|
#include "fesa/math/vector.h"
|
|
|
|
namespace fesa::dense_blas_internal {
|
|
|
|
/// @brief Limits only default-policy one-equation backend calls to one thread.
|
|
/// @note Existing caller TLS overrides are retained. Destruction restores the
|
|
/// default request; process-wide MKL/OpenMP settings are never changed.
|
|
class ScopedSingleEquationThreads {
|
|
public:
|
|
explicit ScopedSingleEquationThreads(std::size_t equation_count) noexcept;
|
|
ScopedSingleEquationThreads(const ScopedSingleEquationThreads&) = delete;
|
|
ScopedSingleEquationThreads& operator=(const ScopedSingleEquationThreads&) =
|
|
delete;
|
|
~ScopedSingleEquationThreads();
|
|
|
|
private:
|
|
bool restore_default_{false};
|
|
};
|
|
|
|
/// @brief Limits element-local dense work under the caller's default policy.
|
|
/// @note Positive caller TLS overrides are retained. Default requests are
|
|
/// restored on success and unwind; process-wide settings are never changed.
|
|
class ScopedLocalDenseThreads {
|
|
public:
|
|
ScopedLocalDenseThreads() noexcept;
|
|
ScopedLocalDenseThreads(const ScopedLocalDenseThreads&) = delete;
|
|
ScopedLocalDenseThreads& operator=(const ScopedLocalDenseThreads&) = delete;
|
|
~ScopedLocalDenseThreads();
|
|
|
|
private:
|
|
bool restore_default_{false};
|
|
};
|
|
|
|
/// @brief Converts a dense storage length to the private MKL integer type.
|
|
/// @return The converted length or an uncategorized overflow failure.
|
|
Result<MKL_INT> ToMklSize(std::size_t size);
|
|
|
|
/// @brief Computes left-transpose times right through ordinary dense MKL.
|
|
/// @throws std::invalid_argument for mismatched rows or nonfinite operands.
|
|
Matrix MultiplyTransposeLeft(const Matrix& left, const Matrix& right);
|
|
|
|
/// @brief Multiplies a compact diagonal matrix by a vector through MKL.
|
|
/// @throws std::invalid_argument if shapes differ or inputs are nonfinite.
|
|
/// @throws std::length_error if the size exceeds the backend integer range.
|
|
Vector MultiplyDiagonal(const Vector& diagonal, const Vector& rhs);
|
|
|
|
/// @brief Writes one row-major outer product through MKL without allocation.
|
|
/// @note Source arrays and destination must not alias. A nonfinite input
|
|
/// returns false before writing; finite product overflow remains for the
|
|
/// owner's gate. A zero dimension accepts null pointers and performs no backend
|
|
/// call.
|
|
/// @throws std::invalid_argument for null storage of a nonempty product.
|
|
/// @throws std::length_error for dimensions outside the backend integer range.
|
|
bool OuterProduct(const double* left, std::size_t rows, const double* right,
|
|
std::size_t columns, double* destination);
|
|
|
|
/// @brief Writes left times right-transpose to nonaliased contiguous storage.
|
|
/// @note Inputs are row-major rows-by-inner and columns-by-inner. Nonfinite
|
|
/// input returns false before writing. Finite output overflow is not hidden.
|
|
/// Zero output dimensions accept null pointers; inner zero writes exact zeros.
|
|
/// @throws std::invalid_argument for missing nonempty storage.
|
|
/// @throws std::length_error for dimension or storage-size overflow.
|
|
bool MultiplyTransposeRight(const double* left, std::size_t rows,
|
|
const double* right, std::size_t columns,
|
|
std::size_t inner, double* destination);
|
|
|
|
/// @brief Distinguishes positive-factor failure from inverse failure.
|
|
enum class CholeskyFailure { kNone, kPivot, kInverse };
|
|
|
|
/// @brief Computes a lower Cholesky factor and its inverse with MKL LAPACK.
|
|
/// @return False for a nonpositive pivot or nonfinite factor/inverse.
|
|
/// @note Outputs are replaced only after both finite candidates succeed.
|
|
/// The optional failure output is initialized even when validation throws.
|
|
/// @throws std::invalid_argument for a nonsquare or nonfinite input.
|
|
/// @throws std::length_error for a backend size overflow.
|
|
bool CholeskyLowerAndInverse(const Matrix& matrix, Matrix& lower,
|
|
Matrix& inverse_lower,
|
|
CholeskyFailure* failure = nullptr);
|
|
|
|
/// @brief Copies contiguous double values through the private BLAS backend.
|
|
/// @param source Readable storage for size values when size is nonzero.
|
|
/// @param size Number of contiguous values to copy.
|
|
/// @param destination Writable storage for size values when size is nonzero.
|
|
/// @throws std::length_error if size exceeds the MKL integer range.
|
|
/// @note A zero-length copy accepts null pointers and does not call BLAS.
|
|
void CopyValues(const double* source, std::size_t size, double* destination);
|
|
|
|
} // namespace fesa::dense_blas_internal
|
|
|
|
#endif // FESA_SRC_FESA_MATH_DENSE_BLAS_INTERNAL_H_
|