perf(solvers): scope default one-equation calls to one thread
This commit is contained in:
@@ -8,6 +8,24 @@
|
||||
|
||||
namespace fesa::dense_blas_internal {
|
||||
|
||||
ScopedSingleEquationThreads::ScopedSingleEquationThreads(
|
||||
const std::size_t equation_count) noexcept {
|
||||
// The measured 1x1 PARDISO case has backend/thread overhead and an
|
||||
// intermittently failing default-thread lifecycle. Broader sizes are not
|
||||
// inferred from this auxiliary evidence.
|
||||
if (equation_count != 1U) return;
|
||||
const int previous = mkl_set_num_threads_local(1);
|
||||
if (previous == 0) {
|
||||
restore_default_ = true;
|
||||
} else {
|
||||
static_cast<void>(mkl_set_num_threads_local(previous));
|
||||
}
|
||||
}
|
||||
|
||||
ScopedSingleEquationThreads::~ScopedSingleEquationThreads() {
|
||||
if (restore_default_) static_cast<void>(mkl_set_num_threads_local(0));
|
||||
}
|
||||
|
||||
bool CholeskyLowerAndInverse(const Matrix& matrix, Matrix& lower,
|
||||
Matrix& inverse_lower) {
|
||||
if (matrix.Rows() != matrix.Columns())
|
||||
|
||||
@@ -11,6 +11,21 @@
|
||||
|
||||
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 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);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "fesa/math/sparse_matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "math/dense_blas_internal.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
@@ -286,6 +287,8 @@ class MklPardisoSolver::Impl {
|
||||
/// @brief Calls PARDISO with retained private arrays and phase state.
|
||||
void CallPardiso(const MKL_INT phase, double* rhs, double* solution,
|
||||
MKL_INT& error) {
|
||||
const dense_blas_internal::ScopedSingleEquationThreads thread_scope{
|
||||
static_cast<std::size_t>(equation_count_)};
|
||||
pardiso(pt_.data(), &max_factorizations_, &matrix_number_, &mtype_, &phase,
|
||||
&equation_count_, values_.data(), row_offsets_.data(),
|
||||
column_indices_.data(), permutation_.data(), &rhs_count_,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "fesa/math/sparse_matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "math/dense_blas_internal.h"
|
||||
|
||||
namespace fesa {
|
||||
namespace {
|
||||
@@ -230,6 +231,8 @@ class MklPardisoTangentSolver::Impl {
|
||||
/// @brief Calls PARDISO with retained private arrays and phase state.
|
||||
void CallPardiso(const MKL_INT phase, double* rhs, double* correction,
|
||||
MKL_INT& error) {
|
||||
const dense_blas_internal::ScopedSingleEquationThreads thread_scope{
|
||||
static_cast<std::size_t>(equation_count_)};
|
||||
pardiso(pt_.data(), &max_factorizations_, &matrix_number_, &mtype_, &phase,
|
||||
&equation_count_, values_.data(), row_offsets_.data(),
|
||||
column_indices_.data(), permutation_.data(), &rhs_count_,
|
||||
|
||||
Reference in New Issue
Block a user