Files
FESADev/docs/calculation-performance/mkl-coverage.md
T

24 KiB
Raw Blame History

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 Kd, free/constrained masked RHS의 각 Kd Kffdf/Kfcdc 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 계약을 따른다. 직접 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의 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와 native 기록에 있다. 기존 PARDISO/backend 영역의 실패를 실제 baseline에서 재현했지만 내부 원인은 미확정이다. Intel release notes의 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초였다. 입력 준비와 로그를 포함한 보조 자료이며, 실패와 표본 수 차이가 있어 공식 모델의 개선 배수나 시간 목표 판정에 사용하지 않는다. 비용기록에 실제 범위를 남겼다.

특수 정밀도 개선과 예외

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 변경은 채택하지 않았다.

이후 공통 산술 담당자는 실제 fpclassify 비용을 근거로 이 private header의 finite 분류만 보강했다. IsFiniteBinary64는 memcpy로 읽은 binary64 exponent가 2047인지 확인하며 NaN/Inf를 거부한다. 연산식·검사 위치·정규화·FMA·exact-tail 기준은 그대로다. 독립 source 검토는 분류와 지원 환경의 값·실패 조건 보존을 확인했다. Signaling NaN의 exception flag나 trap 관측까지 동등하다고 주장하지 않는다. 원래 분류의 새 경계 검사 9/9와 변경 후 pair bit oracle·Hex8·paired state/kinematics 62/62가 native 0으로 통과했다. 변경 전 기록, 변경 후 기록과 검사 로그를 보존한다. 이 결과는 최종 모델의 시간 목표나 전체 회귀 검사를 대체하지 않는다.

위 검증 중 기존 MSVC/Ninja의 include prefix 인식 오류도 확인했다. 이 PC에는 한국어 compiler resource만 있어 VSLANG=1033만 지정한 fresh build도 dependency가 0개였다. 실제 출력 접두사 참고: 포함 파일: 를 별도 로컬 CMake include로 지정한 fresh build에서는 hex8_high_low.cpp.obj의 13개 dependency와 산술 header를 확인했다. 실제 dependency를 보존한다. 공용 preset·compiler flags·설치 환경은 바꾸지 않았다. 기존 자료의 직접 cpp 재컴파일과 header 변경 추적의 한계를 구별하며 최종 검증도 보정한 fresh build에서 수행한다.

독립 수치 검토는 위 두 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다. 검색은 +=*만으로 완료하지 않고 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, native, log
6fc7011 tests-only delta build0·1↔2 retained-size 전환2/2 PASS; native0 build, native, log

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 재검토는 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이다. 보조기록과 native는 helper 비용 근거이며 3모델의 공식 wall 평가를 대체하지 않는다.

CSR consumer 전수 보강 검색은 csr-consumer-audit에 있다. assembly/load_assembler.cpp::EffectiveFreeRhs의 Kfc*dc는 공통 조립 담당자가 entrywise MKL diagonal products와 기존 개별 product/ordered row-sum finite gate로 연결했다. O(nnz) 입력 벡터를 사용하며 원래 CSR 순서의 상쇄와 첫 오류 진단을 유지한다. 변경 전 LoadAssembly 13개, 변경 후 관련 조립·복구·선형 정적 검사 41개가 native 0으로 통과했다. 실행 기록과 검사 로그를 보존한다. 독립 정적 검토는 compact band k=0 layout과 row 진단 순서 보존을 확인했다. 이 공유 파일은 T2가 수정하지 않았다. 최종 production 전수 완료는 이 인계와 T3/T4 일반 연산 적용까지 확인해야 한다.

최종 source/test hash·production 검토 이후 source 변경 없음·874개 검사 discovery native0은 final-source-manifest에 기록했다. final CMakeCache는 actual dependency와 Debug flags를 보존한다. Whole changed-file clang-format dry-run은 기존 및 후보 formatting 위반으로 exit1이었다. 실제 기록을 보존하며 formatter PASS로 보고하지 않는다.