# MKL 적용 범위와 수명 근거 FEM-REQ-PERF-004/005/007/009의 T2 구현 기록이다. 공통 요구사항·물리·수치 기준과 reference는 변경하지 않았다. T3/T4 인계 목록은 해당 owner가 완료한 실제 diff와 검사를 통합한 뒤 갱신한다. 이 기록만으로 전체 production 적용이나 세 모델의 공식 시간 목표 통과를 주장하지 않는다. ## 공통 연산 경계 | 위치 | 연산 / 실제 private 호출 | 유지하는 의미 | | --- | --- | --- | | `math/matrix.cpp::Multiply` | dense gemv/gemm, `cblas_dgemv/dgemm` | 기존 shape/empty/checked MKL_INT 및 새 actual operand finite preflight | | `math/vector.cpp` | Dot/Scale/Axpy와 copy, dense BLAS | 기존 공개 값·실패 의미 유지 | | `math/dense_blas_internal.cpp::MultiplyTransposeLeft` | transpose storage copy 뒤 `Matrix::Multiply`; diagonal DSBMV(k0); LAPACK dpotrf/dtrtri | transpose-left shape 확인; ordinary product는 MKL | | `math/sparse_matrix.cpp::Multiply` | `mkl_sparse_d_create_csr` → `mkl_sparse_d_mv` → destroy | canonical CSR와 structural zeros, general full matrix, zero-based index | | `solvers/linear/mkl_pardiso_solver.cpp` | PARDISO SPD factorization/solve | 기존 경로와 scoped n=1 policy | | `solvers/linear/mkl_pardiso_tangent_solver.cpp` | fresh phase 11/22, solve 33 | 새 분해 전 release; 실패 뒤 stale 사용 금지; 동일 성공 분해의 여러 RHS 허용 | | `results/global_equilibrium_recovery.cpp` | full K*d, free/constrained masked RHS의 각 K*d | Kff*df/Kfc*dc scale를 별도로 유지; 원래 free rows만 norm 판정 | | `analysis/linear_frequency_procedure.cpp` / `solid_frequency_procedure.cpp` | original/whitened pencil sparse action, dense Dot | original-pencil finite/independent residual/energy/Gram 검사 유지 | | `solvers/eigen/mkl_feast_eigen_solver.cpp` | independent scaled full/mass/mirrored sparse actions; QR ddot/daxpy | FEAST actual 호출·count/solve budget·seed/Householder 절차 유지; backend residual로 독립 residual 대체하지 않음 | | `analysis/eigen_reduction.cpp` | nodal/block congruence, mode restoration, nodal mass action | nodal analytic null split과 scaled original pencil 유지 | | `analysis/thermal_transient_algebra.cpp` | BE RHS entry의 compact diagonal DSBMV, reduced/full/dissipation CSR actions | raw old constrained state·signed temperature·actual delta·independent interval companion 보존 | | `elements/euler_beam_3d.cpp` | B*d, BᵀDB, TᵀKT, interpolationᵀq | 2 Gauss points·closed stiffness invariant·local force/section identity 유지 | ### Sparse 단발 자원 입력 의존성은 현재 matrix의 전체 CSR shape/index/value와 현재 RHS이다. `Validate()`가 canonical CSR와 finite coefficient를 확인한 뒤 actual `MKL_INT` 폭에 맞춰 rows/columns/nnz/각 index를 checked 변환한다. 공개 `size_t` storage는 변경하지 않고 기존 private `ToMklSize`를 재사용한다. 이 설치의 ILP64를 public API에 하드코딩하지 않는다. 호출 stack이 변환 index 배열·복사 values와 handle을 소유한다. handle은 배열 뒤에 생성되며 RAII destroy가 배열 소멸보다 먼저 실행된다. MKL이 CSR 배열을 참조한다는 [Intel create CSR 계약](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/mkl-sparse-create-csr.html)을 따른다. 직접 private values 복사는 const-cast 없이 const 동시 호출을 분리한다. 호출 종료가 invalidation이며 지속 handle/cache가 없다. 저장량은 단발 `(rows+1+nnz)*sizeof(MKL_INT)+nnz*sizeof(double)` 및 output이다. 측정 근거 없는 symbolic/persistent cache는 채택하지 않았다. 아래 n=1 PARDISO의 제한된 TLS 정책만 실제 baseline/보조 근거로 채택했다. 0 rows/0 columns/no entries는 검증과 index range 확인 뒤 zero vector를 반환한다. nonempty matrix의 구조상 빈 row는 MKL 결과의 zero row다. Copy/move/assignment는 공개 CSR 값 storage 수명만 갖고 backend pointer를 보관하지 않는다. Moved-from 불완전 CSR은 사용 전에 validation에서 거부되므로 indexing UB로 진행하지 않는다. backend failure는 scalar fallback이나 성공 candidate 없이 `runtime_error`로, integer overflow는 `length_error`로 전달한다. vendor enum/원시 오류 번호는 공개하지 않는다. `GlobalEquilibriumRecovery`와 frequency/eigen/thermal consumer는 해당 새 실패를 `Status/Result`로 변환하며 이전 state/history/final 결과를 commit하지 않는다. 실제 allocation/backend fault를 강제한 native 시험은 실행하지 않았다. 해당 실패 branch의 fallback 부재·exception 변환·RAII 해제는 정적 검토 범위이며, 일반 실패/반복·copy/move·동시 const 호출과 bad RHS 복구는 실제 검사 범위다. ### Finite의 owner CSR coefficient와 모든 RHS는 MKL 호출 전 math에서 finite 검증한다. 비유한 RHS는 기존 값 반환/exception 형식의 `invalid_argument`로 거부하며, public signature는 변경하지 않는다. Finite-input product overflow는 consumer의 기존 output finite 검증으로 실패한다. Empty/zero shape도 입력 finite/shape/range 검증을 유지한다. 밀집 GEMV/GEMM은 `Matrix::Multiply`에서 양쪽 matrix storage와 Vector RHS를 호출 전에 finite 검사한다. Private transpose-left 연산도 이 경계를 사용하며 비유한 입력은 `invalid_argument`로 거부한다. Eigen reduction·frequency·FEAST owner는 이를 기존 Result 실패 형식으로 변환한다. MakeLift의 실제 basis와 scaled operand, FEAST의 normalized phi와 mass_modes도 dispatch 전에 검사한다. Production caller finite 입력은 별도로 확인한다. Recovery는 기존 `IsFiniteVector`→Multiply→finite output 순서를 유지한다. Linear frequency의 physical 및 whitened x, solid frequency의 raw/normalized mode는 finite-first이며, FEAST가 반환한 벡터의 finite gate도 기존대로 유지한다. Thermal은 기존 Validate·solver candidate finite와 interval enclosures를 사용한다. Thermal RHS의 각 entry는 `(c/delta)*(old-g)-k*g`라는 원래 association을 먼저 계산한 뒤 원래 row 순서로 누적한다. 두 행곱을 별도로 합산한 뒤 빼는 후보는 stable b=4를 잃어 기존 Cancellation 검사를 실패했으므로 폐기했다. 현재 private diagonal MKL은 O(nnz) compact band k=0 storage로 entry별 곱만 계산한다. Exact companion과 construction error·gamma·underflow certification·free/reaction 판정은 그대로다. 비유한 product를 정상값으로 clamp하거나 tolerance를 완화하지 않는다. ### PARDISO 수명 현재 구현 그대로 `release → CSR/shape/width 확인 → private arrays → phase11 → phase22` 를 수행한다. 값/pattern이 달라지면 `FactorizeFresh`를 다시 호출한다. 새 singular 분해 실패 뒤 `SolveCorrection`은 not-factorized이며 caller correction은 보존된다. 잘못된 RHS의 실패는 output 보존과 유효한 기존 matrix 분해의 수명을 구별한다. 여러 RHS는 같은 성공 분해의 phase33을 사용할 수 있다. 새로운 symbolic 재사용이나 다중 RHS framework를 도입하지 않았다. ### One-equation PARDISO의 scoped 자원 정책 [T1 실제 VTune](verification.md)의 OMP worker/spin 비용과 아래 toy n=1 lifecycle 근거로, SPD/Tangent의 `CallPardiso`에서 **현재 retained equation_count=1**인 경우만 호출의 기본 thread 수를 1로 제한한다. Phase 11/22/33/−1 각각의 호출 범위다. `mkl_set_num_threads_local(1)`의 이전 TLS override가 0일 때만 1을 유지하고, 범위 종료 시 0을 복원한다. 이전값이 비영이면 즉시 그 값을 복원하여 호출자의 override로 backend를 실행한다. n=0 또는 n≥2, 전역 MKL/OpenMP 요청, dispatch, iparm·pivot/scaling·regularization·acceptance는 변경하지 않는다. 계측하지 않은 더 넓은 size threshold는 채택하지 않았다. Release는 이전 factor의 retained count, 새 factor는 새 count를 사용한다. 따라서 작은 matrix의 release 뒤 큰 matrix 호출에 설정이 남지 않는다. 외부 MKL/OMP 요청은 baseline과 같은 8/dynamic FALSE지만, 소스의 실제 자원 정책은 기본 설정의 1×1 호출에서 달라진다. 두 조건을 구분해 보고한다. Phase 성공·오류·exception, 잘못된 RHS와 동시 호출에서 TLS 복원과 candidate 보존을 검사한다. Native process crash는 C++ RAII unwind를 보장하지 않는다. 종료한 process의 TLS 설정은 다음 실행이나 전역 환경에 남지 않는다. ### Baseline PARDISO heap failure와 제한 기존 static partial fixture는 full 24×24/free 1×1이다. `backend-isolation`의 SpMV-only 생성·곱셈·해제 1,000회는 native 0이었다. PARDISO-only 100회 예정 실행은 native `−1073740940 (0xc0000374)`로 중단됐다. 별도의 반복 static fixture도 iteration 3에서 같은 heap 손상을 재현했다. 새 SpMV 수명 회귀와 분리해 기록하며 이 실패를 검사 통과로 표시하지 않는다. 같은 독립 진단 소스를 T1의 기존 Release library에 `/O2 /Ob2 /MD /DNDEBUG /Zi`로 link해 baseline을 대조했다. 기본 8-thread 실행은 61회 완료 뒤 62회에서 같은 native crash가 발생했다. Scoped 1-thread는 100회 native 0이며 각 범위 종료 뒤 effective 8 복원을 기록했다. 현재 Debug `/Od /Ob0 /MDd /RTC1 /Zi` 대조의 8/1-thread는 각각 100회 완료했지만, 이전 Debug 진단의 iteration 2/3 crash도 보존한다. 간헐적 실패이므로 100회 통과를 vendor 문제의 해결 확정으로 쓰지 않는다. Debug/Release도 구분한다. Ordered full/free CSR offsets·columns·raw double bits와 RHS의 input SHA는 양쪽 `CC7E72000783E9694BAF76627D95AB7B420A31198B210B5A60C7ACE93E5E2258`로같다. ILP64·mtype 2·실제 pardisoinit 기본 controls(26 checker/34 zero-based 포함), 동일 MKL/runtimeDLL hash는[recorded-probes metadata](../../.harness/performance/t2/recorded-probes-metadata.json)와 [native 기록](../../.harness/performance/t2/recorded-probes-native.json)에 있다. 기존 PARDISO/backend 영역의 실패를 실제 baseline에서 재현했지만 내부 원인은 미확정이다. [Intel release notes](https://www.intel.com/content/www/us/en/developer/articles/release-notes/onemkl/2026.html)의 non-AVX2 PARDISO sporadic pivoting issue는 조사 근거이며 현재 원인을 확정하지 않는다. 설치·dispatch·전역 registry/pageheap은 변경하지 않았다. 같은 toy n=1 보조 실행에서 default 8-thread는 11회 뒤 crash/0.24초, scoped 1-thread는 100회 완료/0.15초였다. 입력 준비와 로그를 포함한 보조 자료이며, 실패와 표본 수 차이가 있어 공식 모델의 개선 배수나 시간 목표 판정에 사용하지 않는다. [비용기록](../../.harness/performance/t2/tiny-pardiso-cost-native.json)에 실제 범위를 남겼다. ## 특수 정밀도 개선과 예외 T1의 실제 Hex8 VTune stack은 `TwoSum → Add → Multiply → hex8_high_low::operator*` 비용 및 frexp/ldexp 분류 비용을 확인했다. T2는 arithmetic association과 underflow 정책을 바꾸지 않고 두 helper만 개선했다. - `high_low_arithmetic.h::IsNormalized`: finite와 canonical exact-zero guard 뒤 `RN(high+low)==high`. 이 경우 기존 TwoSum의 bridge=0/restored=high/error=low이며, 반대 방향도 기존 predicate의 high equality가 같은 조건이다. overflow/nonfinite와 noncanonical signed zero를 먼저 거부한다. - `LowestBitExponent`: IEEE binary64를 memcpy로 읽어 정상은 `(encoded exponent−1075)+trailing(implicit53bits)`, subnormal은 `−1074+trailing(fraction)`으로 계산한다. 부호를 제외하고 actual least bit를 보존한다. TwoProduct의 least-bit-sum < −1074 거부와 FMA residual·TwoSum 정규화는 그대로다. - zero/low-zero shortcut, nonzero multiplication association 변경은 채택하지 않았다. [독립 수치 검토](../../.harness/performance/t2/arithmetic-numerical-review.md)는 위 두 helper proof/source 범위 PASS이며 실제 검사/속도와 전체 MKL diff 검토를 대체하지 않는다. Frozen original oracle는 pinned `b4fc1bb`의 원본이며 include guard와 namespace만 바꾼 test 전용 `high_low_arithmetic_original.h`이다. 실제 모든 정상 exponent×53 trailing-bit×양 부호, subnormal boundaries, signed zero/ties/overflow/ invalid/raw random 입력의 bit 대조 및 기존 analytical checks를 실행했다. | 파일 / 함수 | 연산·크기·정밀도 | 예외 이유 / 검사·owner | | --- | --- | --- | | `math/high_low_arithmetic.h` 전체, `elements/hex8_high_low.cpp::EvaluateHighLow` | normalized binary64 high+low, 3×3 tensor 및 24×24 pair tangent | ordinary Float64 BLAS로 low/tail rejection을 잃을 수 없음; frozen oracle/Hex8HighLow·T3 | | `elements/hex8_geometry.cpp`의 interval/relative coordinate 인증 | 3×3 inverse/Jacobian 및 outward interval | whole-cell certificate·직접 geometry predicate 보존; Hex8 geometry 검사·T3 | | `elements/hex8_element.cpp` gradient/inverse·F/S/P/FFT/stress의 3×3 tensor | fixed3-coordinate contraction | 3-coordinate geometry/constitutive 의미; 24×24 ordinary tangent는 이 예외로 일괄 분류하지 않음·T3 | | `elements/finite_rotation.cpp` Rodrigues/skew/invariant | fixed3×3 axis coordinate | 좌표 rotation/invariant; finite rotation 검사 | | `analysis/eigen_reduction.cpp::MakeLift` analytic director/frame basis와 null-coordinate checks | fixed6 nodal coordinates, 최대6 positive basis | 고정 director/frame의 analytic 좌표 선택만 예외. 일반 mass whitening/Cholesky/inverse/congruence/reconstruction은 MKL 전환·EigenReduction | | `elements/thermal_shell.cpp` shape/metric contraction | fixed4 shape·fixed3 gradient·2D metric, separable integration coefficient | local coordinate/shape quadrature; global capacity/conduction actions는 MKL·thermal local oracle | | `analysis/thermal_transient_algebra.cpp`의 `I`/Add/Mul/Sub/Div/Norm/Error/Roundoff/Tiny | outward interval·construction/underflow enclosure | floating product와 분리된 정확대수 인증, gamma/epsilon/limit 변경없음·TransientHeatProcedure/ThermalPhysics | | `analysis/hht_reduced_operators.cpp` Projection/Embed/Sum, BasisValue, reduced blocks | compensated sums 및 outward basis radius | low/error compensation 유지, ordinary Hessian/product는 T4 판별/전환 | | `analysis/hht_dynamic_algebra.cpp` AddCompensated·constraint radius 및 3-vector director dot | compensated error·fixed coordinate | 승인 N3/N7·scale 인증; 일반 CSR contraction과 구별·T4 | | `elements/nonlinear_mitc4_shell.cpp` / `nonlinear_mitc4_inertia.cpp` Jet 산술 | analytic derivative jets, fixed3 rotation | AD derivative association/coordinate 의미; ordinary24×24 Hessian/dense congruence blanket 예외 금지·T4 | | `io/hdf5/nonlinear_hdf5_results_writer.cpp` spatial moment transform | fixed3×3 rotation coordinate | 공개 generalized/spatial quantity 변환 보존·T4 | ## T3/T4 인계 전수 검색의 raw 위치 목록은 [ordinary-product-audit](../../.harness/performance/t2/ordinary-product-audit.txt)다. 검색은 +=*만으로 완료하지 않고 Multiply·중첩 루프와 각 함수의 precision/owner를 함께 확인했다. 이 목록은 후속 diff에서 갱신해야 한다. - T3: Hex8 pair tangent/relative geometry/mean-volume certification은 pair/interval 예외로 유지한다. Float64 24×24 response/tangent의 일반 contractions와 procedure 직접 products는 ordinary MKL 적용 여부를 확인한다. - T4: `mitc4_shell.cpp::` transformation congruence(기존241 주변), strainᵀCstrain stiffness(기존635 주변), `nonlinear_mitc4_inertia.cpp` complement Gram/projection (기존449/456), `hht_reduced_operators.cpp` bilinear Hessian action(기존620), reduced block/gradient products(기존970 이후), `hht_dynamic_algebra.cpp` 일반 stiffness projection(기존442)은 MKL 또는 구체적인 compensated 예외 근거가 필요하다. `Jet*`의 derivative array 크기가24라는 이유만으로 모든24×24 Float64 products를 특수 정밀도 예외로 분류하지 않는다. - 공통 recovery/eigen/thermal/beam은 T2 확장 owner로 직접 변경했다. Shared assembly tuple reduction/source identity와 task별 CMake 등록은 root owner이며 변경하지 않았다. ## 실제 검증과 남은 작업 Parent artifact `.harness/performance/t2/`는 worktree cleanup 뒤에도 남는다. 각 native JSON은 argv/cwd/실제 exit와 source 또는 snapshot 구분을 보존한다. 아래 링크는 통합한 저장소의 feature 문서 위치를 기준으로 한다. | 실행 범위 / source | 결과 | 실제 기록 | | --- | --- | --- | | 최초 Debug build | include 누락 exit2; 수정 뒤 build0 | `build-debug-initial-failed.txt`, `build-native-initial-failed.json` | | 초기 개발 snapshot | core43/43·consumer71/71 PASS; whole-source hash 없는 precommit 자료 | `core-native.json`, `consumer-native.json` | | Extended66 개발 snapshot | 64 PASS·1 thermal FAIL·1 large-mesh interrupted; whole native−1 | `extended-native.json`, `extended-checks.txt`, `extended-interruption.json`, `extended-cleanup.json` | | 59c8e93 후보100개 | 99 PASS·열 RHS 상쇄1 FAIL; native8 | `final-native.json`, `final-checks.txt` | | Thermal/finite/Gram/whitening 수정 snapshot82개 | 82/82 PASS; native0 | `corrected-native.json`, `corrected-checks.txt` | | 후속 eigen20개 | 19 PASS·기존 PARDISO heap fixture1 native crash; native8 | `null-products-native.json`, `null-products-checks.txt` | | 770fa2a scoped-policy 후보 | build0·99/99 PASS; native0 | `policy-build-native.json`, `policy-native.json` | | 9c4e685 중앙 dense finite 후보 | build0·120/120 PASS; native0 | [build](../../.harness/performance/t2/finite-build-native.json), [native](../../.harness/performance/t2/finite-native.json), [log](../../.harness/performance/t2/finite-checks.txt) | | 6fc7011 tests-only delta | build0·1↔2 retained-size 전환2/2 PASS; native0 | [build](../../.harness/performance/t2/transition-build-native.json), [native](../../.harness/performance/t2/transition-native.json), [log](../../.harness/performance/t2/transition-checks.txt) | `MklPardisoSolver.SingleEquationScopeTransitionsBetweenRetainedSizes`와 `TangentSolver.SingleEquationScopeTransitionsBetweenRetainedSizes`는 각각 1→2→1 factorize/solve와 old/new retained count별 TLS 복원을 직접 확인한다. 동시 default TLS의 성공→다른값→bad RHS→새 분해 실패→stale solve 거부는 `SingleEquationPolicyPreservesLifecycleAndConcurrentTls` 및 `SingleEquationScopeRestoresTlsAcrossFreshFailureAndReuse`에서 확인한다. Caller의 비영 TLS override·exception unwind와 큰 크기 정책은 `DenseBlasInternal.SingleEquationScopeRestoresTlsAndRespectsOverrides`의 직접 관찰이다. SpMV destroy/PARDISO release-error를 live 주입한 검사는 미실행이다. 유효 handle에서 이를 안전하게 발생시킬 근거가 없고 production mutable fault hook은 추가하지 않았다. 정상 release·분해 오류 후 release·반복 및 크기 전환은 실제 검사이며, 원시 release 오류 분기의 candidate 실패 전달과 자원 수명은 독립 정적 검토 범위다. 9c4e685 production source의 [독립 conformance 재검토](../../.harness/performance/t2/source-conformance-review.md)는 PASS다. 이후 6fc7011은 검토자가 요청한 transition tests-only delta이며 production source는 같다. High+low 두 helper의 독립 proof는 앞 절의 실제 보고서와 연결했다. 검토 PASS와 actual execution PASS는 서로 대체하지 않는다. 최초 실패·상쇄 회귀·간헐적 heap 실패·중단 자료를 삭제하거나 현재 PASS로 바꾸지 않았다. 전체 MSVC Debug/CTest, 원본3+Hex8 필수5 비교, VTune 최종 raw 및 공식 no-warmup/one-measurement 평가는 T5에서 미실행 항목을 완료해야 한다. Task source를 fresh build했으며 다른 source의 object를 수동 복사하지 않았다. Baseline-linked auxiliary는 root가 승인한 보존된 T1 Release library를 직접 link하고 그 flags/runtime/input을 별도로 기록했으므로 현재 Debug evidence로 대체하지 않는다. High+low standalone 보조 microbenchmark는 같은 compiler/한 exe에서 original/optimized 각400000 products를3회 대조했다. Original은 0.129315/0.129951/0.129560s, optimized는0.069739/0.070177/0.068700s이며 모든 checksum이 같고 native0이다. [보조기록](../../.harness/performance/t2/microbench.jsonl)과 [native](../../.harness/performance/t2/microbench-native.json)는 helper 비용 근거이며 3모델의 공식 wall 평가를 대체하지 않는다. CSR consumer 전수 보강 검색은 [csr-consumer-audit](../../.harness/performance/t2/csr-consumer-audit.txt)에 있다. `assembly/load_assembler.cpp::EffectiveFreeRhs`의 Kfc*dc는 root owner가 T2 통합 뒤 entrywise MKL diagonal products와 기존 개별 product/ordered row-sum finite gate로 연결한다. 이 공유 파일은 T2가 수정하지 않았다. 최종 production 전수 완료는 이 인계와 T3/T4 일반 연산 적용까지 확인해야 한다. 최종 source/test hash·production 검토 이후 source 변경 없음·874개 검사 discovery native0은 [final-source-manifest](../../.harness/performance/t2/final-source-manifest.json)에 기록했다. [final CMakeCache](../../.harness/performance/t2/final-CMakeCache.txt)는 actual dependency와 Debug flags를 보존한다. Whole changed-file clang-format dry-run은 기존 및 후보 formatting 위반으로 exit1이었다. [실제 기록](../../.harness/performance/t2/clang-format-native.json)을 보존하며 formatter PASS로 보고하지 않는다.