perf(assembly): use MKL entry products with ordered load diagnostics

This commit is contained in:
KOKO\Mimi
2026-10-14 16:39:17 +09:00
parent ab00ea7415
commit 8c7c41729e
3 changed files with 76 additions and 4 deletions
+7 -2
View File
@@ -245,9 +245,14 @@ original/optimized 각400000 products를3회 대조했다. Original은
CSR consumer 전수 보강 검색은
[csr-consumer-audit](../../.harness/performance/t2/csr-consumer-audit.txt)에 있다.
`assembly/load_assembler.cpp::EffectiveFreeRhs`의 Kfc*dc는 root owner가 T2 통합 뒤
`assembly/load_assembler.cpp::EffectiveFreeRhs`의 Kfc*dc는 공통 조립 담당자가
entrywise MKL diagonal products와 기존 개별 product/ordered row-sum finite gate로
연결한다. 이 공유 파일은 T2가 수정하지 않았다. 최종 production 전수 완료는
연결했다. O(nnz) 입력 벡터를 사용하며 원래 CSR 순서의 상쇄와 첫 오류 진단을 유지한다.
변경 전 LoadAssembly 13개, 변경 후 관련 조립·복구·선형 정적 검사 41개가 native 0으로
통과했다. [실행 기록](../../.harness/performance/shared-assembly/after-native.json)과
[검사 로그](../../.harness/performance/shared-assembly/after-checks.txt)를 보존한다.
독립 정적 검토는 compact band k=0 layout과 row 진단 순서 보존을 확인했다.
이 공유 파일은 T2가 수정하지 않았다. 최종 production 전수 완료는
이 인계와 T3/T4 일반 연산 적용까지 확인해야 한다.
최종 source/test hash·production 검토 이후 source 변경 없음·874개 검사 discovery native0은
+25 -2
View File
@@ -11,6 +11,7 @@
#include "fesa/constraints/essential_constraint_policy.h"
#include "fesa/loads/load.h"
#include "fesa/model/source_target_resolver.h"
#include "math/dense_blas_internal.h"
namespace fesa {
namespace {
@@ -279,13 +280,35 @@ Result<Vector> LoadAssembler::EffectiveFreeRhs(const Vector& full_load,
return Result<Vector>::Failure(prescribed_status);
}
Vector entry_coefficients{kfc.Values().size()};
Vector entry_prescribed{kfc.Values().size()};
for (std::size_t position = 0U; position < kfc.Values().size(); ++position) {
entry_coefficients[position] = kfc.Values()[position];
entry_prescribed[position] =
prescribed_values[kfc.ColumnIndices()[position]];
}
Vector entry_products{0U};
try {
entry_products = dense_blas_internal::MultiplyDiagonal(entry_coefficients,
entry_prescribed);
} catch (const std::length_error&) {
return Result<Vector>::Failure(LoadFailure(
"load-backend-dimension-overflow", location, "LOAD_ASSEMBLER", "Kfc",
"Prescribed displacement products exceed the backend integer range."));
} catch (const std::invalid_argument&) {
return Result<Vector>::Failure(LoadFailure(
"invalid-load-product", location, "LOAD_ASSEMBLER", "Kfc",
"Prescribed displacement product inputs must be finite and compatible."));
}
// MKL computes independent entries; ordered CSR reduction below retains
// cancellation and the first product/row-sum overflow diagnostic.
Vector correction{kfc.Rows()};
for (std::size_t row = 0U; row < kfc.Rows(); ++row) {
double sum = 0.0;
for (std::size_t position = kfc.RowOffsets()[row];
position < kfc.RowOffsets()[row + 1U]; ++position) {
const double product = kfc.Values()[position] *
prescribed_values[kfc.ColumnIndices()[position]];
const double product = entry_products[position];
if (!std::isfinite(product)) {
return Result<Vector>::Failure(LoadFailure(
"nonfinite-load-accumulation", location, "LOAD_ASSEMBLER",
@@ -481,3 +481,47 @@ TEST(LoadAssembly, ZeroLoadsRemainZero) {
ASSERT_TRUE(constrained_rhs.HasValue());
EXPECT_EQ(constrained_rhs.Value().Size(), 0U);
}
TEST(LoadAssembly, PreservesOrderedCancellationInPrescribedCorrection) {
const std::filesystem::path source{"models/load-assembly.inp"};
auto fixture = MakeFixture(
1U, {},
{{"10", 1, 1, 1.0, {source, 21U}},
{"10", 3, 3, 1.0, {source, 22U}},
{"10", 5, 5, 1.0, {source, 23U}}},
{});
const double large = 72057594037927936.0; // 2^56, exactly representable.
const auto kfc = MakeDenseSparse(
3U, 3U, {large, 1.0, -large, large, -large, 1.0, 0.0, 0.0, 0.0});
const auto rhs = fesa::LoadAssembler::EffectiveFreeRhs(
fesa::Vector{6U}, kfc, fixture.dofs->PrescribedValues(), *fixture.dofs);
ASSERT_TRUE(rhs.HasValue());
ASSERT_EQ(rhs.Value().Size(), 3U);
EXPECT_DOUBLE_EQ(rhs.Value()[0U], 0.0);
EXPECT_DOUBLE_EQ(rhs.Value()[1U], -1.0);
EXPECT_DOUBLE_EQ(rhs.Value()[2U], 0.0);
}
TEST(LoadAssembly, SelectsFirstOrderedOverflowDiagnostic) {
const std::filesystem::path source{"models/load-assembly.inp"};
auto fixture = MakeFixture(
1U, {},
{{"10", 1, 1, 1.0, {source, 21U}},
{"10", 3, 3, 1.0, {source, 22U}},
{"10", 5, 5, 2.0, {source, 23U}}},
{});
const double maximum = (std::numeric_limits<double>::max)();
const auto kfc = MakeDenseSparse(
3U, 3U, {maximum, maximum, 0.0, 0.0, 0.0, maximum, 0.0, 0.0, 0.0});
const auto rhs = fesa::LoadAssembler::EffectiveFreeRhs(
fesa::Vector{6U}, kfc, fixture.dofs->PrescribedValues(), *fixture.dofs);
ExpectFailureCode(rhs, "nonfinite-load-accumulation");
ASSERT_EQ(rhs.GetStatus().Diagnostics().size(), 1U);
EXPECT_EQ(rhs.GetStatus().Diagnostics()[0U].entity_identity, "0");
EXPECT_NE(rhs.GetStatus().Diagnostics()[0U].message.find("row sum"),
std::string::npos);
}