perf(shell): route local products through MKL and reduce Hessian storage work
This commit is contained in:
@@ -6,10 +6,12 @@
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "fesa/solvers/linear/tangent_solver.h"
|
||||
#include "math/dense_blas_internal.h"
|
||||
#include "math/high_low_arithmetic.h"
|
||||
|
||||
namespace fesa::hht_reduced_internal {
|
||||
@@ -614,10 +616,33 @@ Matrix PhysicalJacobian(const ConstraintOperators& operators,
|
||||
|
||||
Vector ContractConstraintHessian(const ConstraintOperators& operators,
|
||||
const Vector& left, const Vector& right) {
|
||||
const dense_blas_internal::ScopedLocalDenseThreads local_threads{};
|
||||
Vector result{operators.rows.size()};
|
||||
for (std::size_t row = 0U; row < operators.rows.size(); ++row)
|
||||
for (const auto& entry : operators.rows[row].hessian)
|
||||
result[row] += entry.value * left[entry.row] * right[entry.column];
|
||||
for (std::size_t row = 0U; row < operators.rows.size(); ++row) {
|
||||
const auto& hessian = operators.rows[row].hessian;
|
||||
Vector coefficients{hessian.size()};
|
||||
Vector left_values{hessian.size()};
|
||||
Vector right_values{hessian.size()};
|
||||
for (std::size_t i = 0U; i < hessian.size(); ++i) {
|
||||
coefficients[i] = hessian[i].value;
|
||||
left_values[i] = left[hessian[i].row];
|
||||
right_values[i] = right[hessian[i].column];
|
||||
}
|
||||
try {
|
||||
const Vector first =
|
||||
dense_blas_internal::MultiplyDiagonal(coefficients, left_values);
|
||||
const Vector products =
|
||||
dense_blas_internal::MultiplyDiagonal(first, right_values);
|
||||
// Retain the original entry order and left-associated products; only
|
||||
// ordinary products move to MKL. This is failure-only replay evidence.
|
||||
for (std::size_t i = 0U; i < products.Size(); ++i)
|
||||
result[row] += products[i];
|
||||
} catch (const std::invalid_argument&) {
|
||||
// A nonfinite input/intermediate cannot yield a finite original sum.
|
||||
// Keep the existing caller's finite failure without a scalar fallback.
|
||||
result[row] = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1186,13 +1211,19 @@ Result<double> CheckGraphRegularity(
|
||||
Failure("Reduced graph regularity node is invalid.",
|
||||
"dynamic-mass-regularity"));
|
||||
const auto& null = assembly.rotations[node].drill_null;
|
||||
double metric = 0.0;
|
||||
for (std::size_t i = 0U; i < 3U; ++i)
|
||||
Matrix metric_block{3U, 3U};
|
||||
Vector direction{3U};
|
||||
for (std::size_t i = 0U; i < 3U; ++i) {
|
||||
direction[i] = null[i];
|
||||
for (std::size_t j = 0U; j < 3U; ++j)
|
||||
metric += null[i] *
|
||||
SparseEntry(assembly.drilling_metric, 6U * node + 3U + i,
|
||||
6U * node + 3U + j) *
|
||||
null[j];
|
||||
metric_block(i, j) = SparseEntry(
|
||||
assembly.drilling_metric, 6U * node + 3U + i, 6U * node + 3U + j);
|
||||
}
|
||||
double metric = 0.0;
|
||||
{
|
||||
const dense_blas_internal::ScopedLocalDenseThreads local_threads{};
|
||||
metric = direction.Dot(metric_block.Multiply(direction));
|
||||
}
|
||||
if (!std::isfinite(metric) || !(metric > 0.0))
|
||||
return Result<double>::Failure(Failure(
|
||||
"Reduced graph requires a positive finite null drilling metric.",
|
||||
|
||||
Reference in New Issue
Block a user