fix: use residual stopping for FEAST eigenanalysis
This commit is contained in:
@@ -86,4 +86,14 @@
|
|||||||
- 근거: [실행 결과](implementation-verification.md), [독립 수치 검토](implementation-numerical-review.md), [S3 검토](implementation-numerical-review-s3-static.md).
|
- 근거: [실행 결과](implementation-verification.md), [독립 수치 검토](implementation-numerical-review.md), [S3 검토](implementation-numerical-review-s3-static.md).
|
||||||
- 관찰: 원본 모델은 고정 FEAST trace stopping의 실제 반환값에서 전체 c residual 기준을 넘는다. S3 public static은 rotation-only drilling의 미평형 모멘트 때문에 실패한다.
|
- 관찰: 원본 모델은 고정 FEAST trace stopping의 실제 반환값에서 전체 c residual 기준을 넘는다. S3 public static은 rotation-only drilling의 미평형 모멘트 때문에 실패한다.
|
||||||
- 현재 처리: r1 controls·tolerance·물리 식을 유지하고 실패를 명시한다. 요청 N 밖의 모드를 버리거나 reaction에서 torque를 제거하지 않는다. 구현 진행분은 커밋하되 기능 완료로 표시하지 않는다.
|
- 현재 처리: r1 controls·tolerance·물리 식을 유지하고 실패를 명시한다. 요청 N 밖의 모드를 버리거나 reaction에서 torque를 제거하지 않는다. 구현 진행분은 커밋하되 기능 완료로 표시하지 않는다.
|
||||||
- 후속 제안: residual stopping 후보의 FEAST 제어와 S3 정식화/회복/평형 계약을 사용자 결정 후 formulation·NR에서 재검토한다. 아직 채택·승인된 변경은 없다.
|
- 당시 후속 제안: residual stopping 후보의 FEAST 제어와 S3 정식화/회복/평형 계약을 사용자 결정 후 formulation·NR에서 재검토한다. 이 기록 시점에는 채택·승인된 변경이 없었다. 이후 FEAST 제어만 ADR-011로 변경한다.
|
||||||
|
|
||||||
|
## MFE2-ADR-011 — FEAST residual stopping과 S3 후속 분리
|
||||||
|
|
||||||
|
- 상태: 사용자 명시 승인, 2026-09-10. Owner: 메인 assistant; 수치 검토: numerical-review-agent.
|
||||||
|
- 승인 근거: “FEAST 잔차 초과 문제를 Trace 기반 종료 → residual 기반 종료로 변경”, “S3 문제는 추후에 고려”.
|
||||||
|
- 결정: C-index `fpm[5]`를 `1`에서 `0`으로 변경한다. `fpm[2]=12`, `fpm[3]=20`, count/solve 구간·capacity·seed·thread·실패 정책 및 전체 c개 독립 `1e-10` 검증은 유지한다.
|
||||||
|
- 이유: trace 변화의 수렴만으로는 원본 모델 전체 고유쌍의 독립 잔차를 충족하지 못했다. 개별 잔차를 사용하는 backend 종료를 선택하되 backend 성공을 독립 검증으로 대체하지 않는다.
|
||||||
|
- 영향: [정식화 E5](formulation-eigen.md), [수치 controls C5](numerical-review-controls.md), backend와 HDF5 writer의 control 검증을 함께 갱신한다. 기존 schema의 실제 `base_fpm[5]` 기록값이 바뀌며 field·shape·단위와 reference mapping은 유지한다.
|
||||||
|
- 검증: [실행 결과](implementation-verification.md) 및 [독립 수치 검토](implementation-feast-residual-review.md)에 새 실행을 기록한다. 기존 trace 실패 evidence는 당시 결과로 보존한다.
|
||||||
|
- 범위: S3 정식화·부분 회전 BC·reaction·평형 기준은 변경하지 않고 알려진 충돌을 후속 과제로 유지한다. S3를 해결하거나 unsupported로 재분류한 결정이 아니다. 외부 reference와 공통 tolerance도 유지한다.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
- Feature ID: `mitc4-shell-feast-eigen2`
|
- Feature ID: `mitc4-shell-feast-eigen2`
|
||||||
- Owner: 메인 assistant
|
- Owner: 메인 assistant
|
||||||
- Requirement baseline revision: `r1`
|
- Requirement baseline revision: `r1`
|
||||||
- 현재 작업: 확정된 requirement/formulation/NR/I/O r1을 기준으로 implementation과 필요한 실행 검증을 진행한다.
|
- 현재 작업: requirement/formulation/I/O r1과 [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 FEAST residual stopping 변경을 적용한다. C5 controls는 r2이며 S3는 후속 과제로 유지한다.
|
||||||
- 목적: MITC4 질량행렬과 FEAST 고유진동 해석의 요구사항을 이론·수학·수치 검토·입출력 계약으로 구체화한다.
|
- 목적: MITC4 질량행렬과 FEAST 고유진동 해석의 요구사항을 이론·수학·수치 검토·입출력 계약으로 구체화한다.
|
||||||
- 현재 checklist: [PRD](PRD.md#현재-checklist).
|
- 현재 checklist: [PRD](PRD.md#현재-checklist).
|
||||||
|
|
||||||
@@ -40,5 +40,6 @@
|
|||||||
| [implementation-verification.md](implementation-verification.md) | 메인 assistant | 실제 구현·실행·실패·남은 evidence와 후속 결정 |
|
| [implementation-verification.md](implementation-verification.md) | 메인 assistant | 실제 구현·실행·실패·남은 evidence와 후속 결정 |
|
||||||
| [구현 수치 검토](implementation-numerical-review.md), [검토 이력](implementation-numerical-review-history.md), [S3 정적 검토](implementation-numerical-review-s3-static.md) | numerical-review-agent | 구현의 독립 수치 대조와 계약 충돌 |
|
| [구현 수치 검토](implementation-numerical-review.md), [검토 이력](implementation-numerical-review-history.md), [S3 정적 검토](implementation-numerical-review-s3-static.md) | numerical-review-agent | 구현의 독립 수치 대조와 계약 충돌 |
|
||||||
| [구현 물리 검토](implementation-physics-review.md) | physics-evaluation-agent | 실제 retained 결과의 물리 evidence·범위와 기존 문제 |
|
| [구현 물리 검토](implementation-physics-review.md) | physics-evaluation-agent | 실제 retained 결과의 물리 evidence·범위와 기존 문제 |
|
||||||
|
| [FEAST 종료 제어 검토](implementation-feast-residual-review.md) | numerical-review-agent | 사용자 승인 residual stopping의 독립 검토와 새 실행 판정 |
|
||||||
|
|
||||||
반환은 결과·변경 파일·정적 확인·미해결 항목으로 충분하다. Git 경로 선택·커밋과 최종 결과 확인은 메인이 수행한다.
|
반환은 결과·변경 파일·정적 확인·미해결 항목으로 충분하다. Git 경로 선택·커밋과 최종 결과 확인은 메인이 수행한다.
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ solver build/test·reference 비교와 release 감사는 포함하지 않는다.
|
|||||||
코드·테스트·실제 FEAST 및 필수 reference/회귀 검증과 작업별 커밋이다. 앞의 30분 제한은
|
코드·테스트·실제 FEAST 및 필수 reference/회귀 검증과 작업별 커밋이다. 앞의 30분 제한은
|
||||||
완료된 문서 작업의 이력이다. 원본 reference 생성·변경과 push/release는 포함하지 않는다.
|
완료된 문서 작업의 이력이다. 원본 reference 생성·변경과 push/release는 포함하지 않는다.
|
||||||
|
|
||||||
|
2026-09-10 사용자는 FEAST 종료 조건을 trace에서 residual로 변경하고 S3는 추후 고려하도록
|
||||||
|
명시했다. [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)에 따라 backend·저장 control 검증·관련 문서를 갱신하며,
|
||||||
|
기존 독립 잔차와 외부 tolerance, 질량·drilling 수식은 유지한다.
|
||||||
|
|
||||||
## 솔버 기능의 요구 범위 요약
|
## 솔버 기능의 요구 범위 요약
|
||||||
|
|
||||||
기존 사용자 결정에 기록된 다음 의미를 새 요구사항의 출발점으로 사용한다.
|
기존 사용자 결정에 기록된 다음 의미를 새 요구사항의 출발점으로 사용한다.
|
||||||
@@ -83,10 +87,16 @@ solver build/test·reference 비교와 release 감사는 포함하지 않는다.
|
|||||||
- [ ] 제외 예제 사용 없이 남는 static/내부 회귀·전체 build/test·필수 reference 실행.
|
- [ ] 제외 예제 사용 없이 남는 static/내부 회귀·전체 build/test·필수 reference 실행.
|
||||||
- [ ] 관련 독립 numerical/physics 확인, 결과·한계 기록과 커밋.
|
- [ ] 관련 독립 numerical/physics 확인, 결과·한계 기록과 커밋.
|
||||||
|
|
||||||
|
- [x] 승인된 FEAST residual stopping과 HDF5 control 검증을 함께 적용하고 변경 전 실패·변경 후 검사를 확인한다.
|
||||||
|
- [x] 원본 eigen의 전체 c개 독립 잔차·복구·HDF5 생성을 확인하고 종료 제어의 독립 수치 검토를 받는다.
|
||||||
|
- [ ] 원본 eigen의 외부 Value 불일치 원인을 조사한다. 현재 Mode2–10의 모드별 RMS가 1%를 초과한다.
|
||||||
|
- [ ] S3 public static 정적 평형 계약 충돌은 사용자 요청에 따라 후속 검토한다.
|
||||||
|
|
||||||
현재 구현·실행은 [implementation-verification](implementation-verification.md)에 기록했다.
|
현재 구현·실행은 [implementation-verification](implementation-verification.md)에 기록했다.
|
||||||
실제 mass/reduction/FEAST/procedure/HDF5 경로와 focused 검사가 있으며, 체크되지 않은 항목이
|
실제 mass/reduction/FEAST/procedure/HDF5 경로와 focused 검사가 있으며, 체크되지 않은 항목이
|
||||||
전부 미구현이라는 뜻은 아니다. 원본 eigen의 전체 c residual 실패와 S3 public static
|
전부 미구현이라는 뜻은 아니다. 원본 eigen의 전체 c residual 실패는 residual stopping으로
|
||||||
계약 충돌, 세부 case의 미완료 evidence 때문에 기능 전체 acceptance는 완료하지 않았다.
|
해소했다. 현재 외부 Value 불일치와 S3 public static 계약 충돌, 세부 case의 미완료 evidence가
|
||||||
|
남으므로 기능 전체 acceptance는 완료하지 않았다.
|
||||||
|
|
||||||
## 이전 문서 단계의 결과와 구현 입력
|
## 이전 문서 단계의 결과와 구현 입력
|
||||||
|
|
||||||
|
|||||||
@@ -128,8 +128,10 @@ K와 identity의 pattern이 같을 필요는 없다. Vendor types와 workspace
|
|||||||
|
|
||||||
매 call마다 `feastinit` 후 명시 controls를 채운다. C-index `fpm[49]=1`은 CSR count를
|
매 call마다 `feastinit` 후 명시 controls를 채운다. C-index `fpm[49]=1`은 CSR count를
|
||||||
m0로 반환하고 flag가 0으로 reset된다. Count output m0·solve requested m0·allocated capacity를
|
m0로 반환하고 flag가 0으로 reset된다. Count output m0·solve requested m0·allocated capacity를
|
||||||
분리한다. CSR/SPD 검사를 켜고 subspace-only를 끈다. Zero mode에도 적용할 수 있도록
|
분리한다. CSR/SPD 검사를 켜고 subspace-only를 끈다.
|
||||||
`fpm[5]=1` trace stopping을 사용하며 residual을 독립 검증한다. `epsout`은
|
[MFE2-ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 사용자 승인으로
|
||||||
|
`fpm[5]=0` residual stopping을 사용한다. 내부 목표 `1e-12`와 전체 c개 독립 residual
|
||||||
|
기준 `1e-10`을 유지하며 zero/mixed-zero mode에도 실제 backend 회귀를 수행한다. `epsout`은
|
||||||
`|trace_i-trace_previous|/max(|emin|,|emax|)`이며 eigenpair 상대오차가 아니다.
|
`|trace_i-trace_previous|/max(|emin|,|emax|)`이며 eigenpair 상대오차가 아니다.
|
||||||
|
|
||||||
`info=1`은 certified empty count가 아니다. 넓은 interval의 isolated cluster를 놓친
|
`info=1`은 certified empty count가 아니다. 넓은 interval의 isolated cluster를 놓친
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ Numerical scale은 초기 physical rotary diagonal 8개 trace 평균의 `10^-3`
|
|||||||
질량 및 trace 평균은 FESA 운동학에서 유도한 선택이다. 외부 source가 이 lumping/scale을
|
질량 및 trace 평균은 FESA 운동학에서 유도한 선택이다. 외부 source가 이 lumping/scale을
|
||||||
지정한다고 주장하지 않는다. 최신 API 근거와 검토 한계는 [research](research.md)와
|
지정한다고 주장하지 않는다. 최신 API 근거와 검토 한계는 [research](research.md)와
|
||||||
[research evidence](research-evidence.md)에 연결한다. FEAST count의 `fpm[49]=1`과
|
[research evidence](research-evidence.md)에 연결한다. FEAST count의 `fpm[49]=1`과
|
||||||
trace stopping의 `fpm[5]=1`은 C-index다. 빈 count interval의 `info=0,m0=0`과 작은
|
residual stopping의 `fpm[5]=0`은 C-index다. 종료 제어는 [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)과
|
||||||
|
[controls C5](numerical-review-controls.md#c5-fixed-lower-enclosure와-bounded-upper-search)의 승인된 변경을 적용한다.
|
||||||
|
빈 count interval의 `info=0,m0=0`과 작은
|
||||||
scratch 허용은 보장된 vendor 계약으로 채택하지 않는다.
|
scratch 허용은 보장된 vendor 계약으로 채택하지 않는다.
|
||||||
|
|
||||||
## 검증 의무와 미해결 항목
|
## 검증 의무와 미해결 항목
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# FEAST residual stopping 독립 검토
|
||||||
|
|
||||||
|
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 2026-09-10.
|
||||||
|
- 범위: 사용자 승인 `fpm[5]:1→0`, `[2]=12`, `[3]=20` 유지. S3는 보류 상태를 유지한다.
|
||||||
|
- 판정: **`PASS` — 승인된 종료 제어 변경**, **`FAIL` — 원본 외부 Value acceptance**.
|
||||||
|
전체 기능 완료 판정이 아니다.
|
||||||
|
- 기준: [PRD](PRD.md), [ADR](ADR.md), [E4–E7](formulation-eigen.md),
|
||||||
|
[C3/C5](numerical-review-controls.md), [I/O](io-schema.md), [TOLERANCE](../TOLERANCE.md).
|
||||||
|
|
||||||
|
## 판단과 필요한 확인
|
||||||
|
|
||||||
|
| 항목 | 독립 판단 |
|
||||||
|
| --- | --- |
|
||||||
|
| 종료 기준 | [Intel C parameter 표](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)는 `[5]=0` residual, `1` trace이며 double epsilon은 `10^-fpm[2]`임을 명시한다. `1e-12` vendor stopping과 독립 all-c `1e-10`은 서로 다른 metric이다 |
|
||||||
|
| 불변 수식 | `B=A/s`, `mu=lambda/s`는 무차원이고 `rho_B=norm2(Bx-mu x)/norm2(x)`도 무차원이다. 종료 시점만 바뀌며 K/M, 부호·단위·DOF 순서, 적분, whitening, raw sort, 복구·state commit 식은 그대로다 |
|
||||||
|
| 전체 c | 요청 N 밖을 포함한 c개 residual과 pairwise/Frobenius Gram 검증 후 첫 N개를 공개해야 한다. FEAST 성공이나 작은 epsout으로 생략할 수 없다 |
|
||||||
|
| Zero·반복군 | 정확한 zero의 backend residual이 비유한이면 기존 available=false 표현을 유지한다. 독립 zero identity와 nonzero vector·Gram은 검증한다. Residual stopping에서 zero/mixed-zero의 실제 성공 여부는 실행으로 확인해야 하며 trace fallback을 추가하지 않는다. 반복군은 multiplicity·공간·Gram으로 판단하고 개별 벡터 방향의 유일성을 요구하지 않는다 |
|
||||||
|
| 상태·metadata | `SetControls`를 count/solve마다 재초기화하며 count의 `[49]=1` reset을 다음 solve에 전파하지 않는다. `base_fpm[5]=0,[2]=12,[3]=20`은 실제 새 HDF5에서 확인한다. `epsout`은 기존 trace 변화 진단량이며 residual stopping 지표로 이름·의미를 바꾸지 않는다 |
|
||||||
|
| 실패·안정성 | Refinement 최대20, bounded interval/capacity retry와 독립 검증 실패 즉시 종료를 유지한다. 새 종료 조건에서도 모든 conditioning의 수렴을 보장하지 않는다. Source의 미수렴/status/budget/allocation 전체 실패 주입 coverage는 기존 미완료 위험으로 남는다 |
|
||||||
|
|
||||||
|
검토 source: [backend](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp),
|
||||||
|
[기존 backend tests](../../tests/unit/solvers/eigen/mkl_feast_eigen_solver_test.cpp).
|
||||||
|
추가로 [writer 검증](../../src/fesa/io/hdf5/eigen_hdf5_results_writer.cpp)의 `[5]=0` 제한과
|
||||||
|
[실제 HDF5 readback·변조 거부 검사](../../tests/unit/io/hdf5/eigen_hdf5_results_writer_test.cpp)를
|
||||||
|
대조했다. Schema의 field/type/layout 변경 없이 승인된 control 값만 일치시킨다.
|
||||||
|
본 검토자는 source/tests를 변경하거나 build/test를 중복 실행하지 않고 메인의 실행 로그를 대조했다.
|
||||||
|
|
||||||
|
## 새 실행 evidence
|
||||||
|
|
||||||
|
개인 `.harness/config.json`과 preset의 MSVC x64 Debug·oneMKL 2026.1 설정을 확인했다.
|
||||||
|
|
||||||
|
| Evidence 경로 | 확인 결과 |
|
||||||
|
| --- | --- |
|
||||||
|
| `.harness/feast-residual-red.log` | 변경 전 backend와 실제 HDF5에서 `[5]=1`을 읽어 새 `[5]=0` 검사 두 개가 실패함 |
|
||||||
|
| `.harness/feast-residual-focused.log` | 12개 중 11 통과. Backend 10개는 n1/all-zero/mixed-zero/repeated40 prefix/close distinct·Givens/negative/invalid/thread 복원 포함. Writer 한 개는 실제 control readback·trace로 변조한 candidate 거부 포함 |
|
||||||
|
| 같은 focused log의 원본 reference | Application 성공 후 Value 비교까지 진행했으나 10 singleton 중 9개 실패. 기존 독립 residual 차단과 다른 외부 acceptance 실패이며 전체 검사가 통과한 것은 아님 |
|
||||||
|
| `.harness/feast-residual-full-run.log` | 구성된 전체 build/test에서 CTest 395개 중 394 통과, 원본 Value reference 한 개 실패, CTest exit8, 실행178.42초. 전체 통과 아님 |
|
||||||
|
| `.harness/build-ninja-msvc-debug/feast-residual-metrics.json` | `.harness/build-ninja-msvc-debug/extract_feast_residual.py`가 공식 원본 sibling HDF5를 read-only 추출한 값. 스크립트의 실제 dataset·mode_id 대응과 JSON을 대조함 |
|
||||||
|
|
||||||
|
원본 새 HDF5에서 `c=22,m0=33,info=0,loop=6`, controls `[2]=12,[3]=20,[5]=0`,
|
||||||
|
`epsout=2.4227135616446226e-17`을 확인했다. 전체 c개의 최대값은 다음과 같다.
|
||||||
|
|
||||||
|
| Metric | 실제 최대값 | 판정 기준 |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| 독립 rho_B | `1.605467212112365e-13` | `<=1e-10`, PASS |
|
||||||
|
| Original-free eta_r / whitened eta_w | `9.981033437726324e-15` / `7.315529163435965e-15` | 각각 `<=1e-10`, PASS |
|
||||||
|
| Gram eta_gram / max_eta_orth | `1.3777964580680282e-15` / `1.6958335496991244e-15` | 각각 `<=1e-10`, PASS |
|
||||||
|
| Backend res | `8.280018892001454e-13` | vendor 진단량, 독립 rho_B 대체 아님 |
|
||||||
|
|
||||||
|
Value 행별 상대오차는 전부 5% 이내지만 Mode2–10의 singleton RMS는 1%를 초과한다.
|
||||||
|
Mode1은 `0.5648341627%`로 PASS, Mode2–10은 `1.3496440956%`–`4.2613310845%`로 FAIL이다.
|
||||||
|
양의 singleton은 RMS가 relative error와 같다는 [승인된 family 계약](reference-model.md)을
|
||||||
|
그대로 적용했다. 행 5%만으로 전체 PASS를 선언하거나 frame을 합쳐 RMS를 완화할 수 없다.
|
||||||
|
**필요한 후속 correction:** 메인이 이 외부 불일치의 원인·모델 가정을 별도 조사해야 한다.
|
||||||
|
현재 evidence만으로 질량·stabilization 등 특정 물리 식이 원인이라고 단정할 수 없다.
|
||||||
|
|
||||||
|
반복군 검사 통과를 모든 projector·3회 결정론·vendor 실패 주입 coverage 완료로 확장하지 않는다.
|
||||||
|
|
||||||
|
## Trace stopping 이력과 잔여 위험
|
||||||
|
|
||||||
|
[기존 실행 기록](implementation-verification.md)의 trace stopping 실패는
|
||||||
|
`n=3125,N=10,c=22,m0=33,info=0,loop=4`, raw solver column20의
|
||||||
|
`rho_B=1.48674481038207483e-10>1e-10`, `epsout=2.82488401287762986e-14`다.
|
||||||
|
Full/upper action 차이 `1.38724134018909290e-17`은 해당 실패 크기를 설명하지 못한다.
|
||||||
|
이 관찰은 trace 수렴이 각 vector residual 통과를 보장하지 않는 실제 반례이며,
|
||||||
|
새 제어의 개선 정도·통과 여부를 선취하지 않는다.
|
||||||
|
|
||||||
|
공통 외부 정책은 필요한 row의 누락·추가·중복·비유한을 tolerance 전에 거부하고 승인된
|
||||||
|
Value family에 적용한다. 독립 modal 허용오차를 외부 reference tolerance로 대체하지 않는다.
|
||||||
|
S3 정적 계약 충돌과 기존 nonlinear recovery 문제, 27개 case 전체 세부 coverage 미완료는
|
||||||
|
[기존 독립 검토](implementation-numerical-review.md)의 별도 제한으로 남는다.
|
||||||
@@ -1,12 +1,81 @@
|
|||||||
# MITC4 eigen 구현 및 실행 결과
|
# MITC4 eigen 구현 및 실행 결과
|
||||||
|
|
||||||
- Feature: `mitc4-shell-feast-eigen2`; Owner: 메인 assistant; 2026-09-09 KST.
|
- Feature: `mitc4-shell-feast-eigen2`; Owner: 메인 assistant; 갱신 2026-09-10 KST.
|
||||||
- 판정: **구현 진행분 보존, 기능 acceptance 미완료**. 시간 제한으로 중지한 작업이 아니다.
|
- 현재 판정: **FEAST 잔차 초과 해소, 외부 Value 비교와 기능 acceptance 미완료**.
|
||||||
|
아래 2026-09-10 결과가 최신이며 2026-09-09 trace 실행은 당시 evidence로 보존한다.
|
||||||
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](PRD.md), [ADR](ADR.md),
|
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](PRD.md), [ADR](ADR.md),
|
||||||
[정식화](formulation.md), [수치 controls](numerical-review-controls.md), [I/O](io.md).
|
[정식화](formulation.md), [수치 controls](numerical-review-controls.md), [I/O](io.md).
|
||||||
- 독립 검토: [수치](implementation-numerical-review.md),
|
- 독립 검토: [수치](implementation-numerical-review.md),
|
||||||
[S3 정적 계약](implementation-numerical-review-s3-static.md),
|
[S3 정적 계약](implementation-numerical-review-s3-static.md),
|
||||||
[물리](implementation-physics-review.md).
|
[물리](implementation-physics-review.md), [FEAST 종료 변경](implementation-feast-residual-review.md).
|
||||||
|
|
||||||
|
## 2026-09-10 FEAST residual stopping 변경 결과
|
||||||
|
|
||||||
|
[ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 사용자 승인에 따라 backend의 C-index
|
||||||
|
`fpm[5]`만 `1→0`으로 변경하고 HDF5 writer의 실제 control 검증도 `0`으로 맞췄다.
|
||||||
|
`fpm[2]=12`, `[3]=20`, seed/thread/구간/capacity/실패 정책과 모든 독립 tolerance는 유지했다.
|
||||||
|
S3, K/M·질량 축소·회복 수식, reference artifact는 변경하지 않았다.
|
||||||
|
|
||||||
|
새 테스트는 실제 backend snapshot과 저장한 HDF5의 `[5]=0`을 확인하고 trace 값으로
|
||||||
|
변조한 candidate를 거부하면서 기존 최종 파일을 보존하는지 검사한다. 변경 전 `[5]=1`
|
||||||
|
때문에 두 검사가 실패한 뒤 최소 source 수정으로 통과했다.
|
||||||
|
|
||||||
|
| 실행 | 결과 |
|
||||||
|
| --- | --- |
|
||||||
|
| 변경 전 backend/HDF5 focused CTest | 2/2 실패, `[5]=1` 확인. `.harness/feast-residual-red.log` |
|
||||||
|
| MSVC x64 Debug 3개 test target build | exit0, 새 compiler warning 없음 |
|
||||||
|
| 변경 후 backend/writer/원본 reference focused CTest | 12개 중 11 통과, exit1. 영·혼합 영·반복·근접 고유값, thread 복원, control readback/변조 거부 통과. 원본은 해석 성공 후 외부 Value 비교에서 실패 |
|
||||||
|
| `python scripts/execute.py` | build 성공, runner exit1 / CTest exit8. **395개 중 394 통과**, 원본 Value reference 1개 실패. 178.42초; unit320, integration42, reference33 |
|
||||||
|
| 공식 HDF5 read-only 추출 | 전체 c개 metric과 실제 controls·backend call·10개 Value를 확인. Focused와 full 실행의 modes/vectors/eigenpair_checks/base_fpm dataset bytes 동일 |
|
||||||
|
|
||||||
|
전체 실행은 `.harness/feast-residual-full-run.log`, 상세 CTest는
|
||||||
|
`.harness/feast-residual-full-ctest.log`, focused는 `.harness/feast-residual-focused.log`다.
|
||||||
|
Read-only 추출 스크립트와 JSON은 최종적으로 ignored build directory에 보관했다.
|
||||||
|
재현 명령은 `uv run --with h5py python .harness/build-ninja-msvc-debug/extract_feast_residual.py`이며,
|
||||||
|
그 directory의 `feast-residual-metrics.json`과 `feast-residual-full-metrics.json`이 각 실행의 기록이다.
|
||||||
|
개인 환경·추출 스크립트·기계 생성 로그/결과는 커밋하지 않는다. 이 작업에서 Python Harness suite는 실행하지 않았다.
|
||||||
|
|
||||||
|
원본 [결과 HDF5](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine_results.h5)는
|
||||||
|
이번 실제 해석이 새로 생성한 공식 sibling output이다. 생성과 closed-file self-check는 성공했고,
|
||||||
|
기존 외부 INP/TXT의 실행 전후 bytes는 reference test에서 보존을 확인했다.
|
||||||
|
|
||||||
|
| Metric | 새 결과 |
|
||||||
|
| --- | ---: |
|
||||||
|
| 요청 N / 계산 c / m0 | 10 / 22 / 33 |
|
||||||
|
| Count / solve calls | 25 / 1 |
|
||||||
|
| FEAST info / loop | 0 / 6 (기존 trace는 4회) |
|
||||||
|
| 전체 c 최대 rho_B | `1.605467212112365e-13` |
|
||||||
|
| 최대 original-free eta_r / whitened eta_w | `9.981033437726324e-15` / `7.315529163435965e-15` |
|
||||||
|
| eta_gram / max_eta_orth | `1.3777964580680282e-15` / `1.6958335496991244e-15` |
|
||||||
|
| 최대 backend_res | `8.280018892001454e-13` |
|
||||||
|
| epsout (trace 변화 진단량) | `2.4227135616446226e-17` |
|
||||||
|
|
||||||
|
전체 22개는 각각 독립 `1e-10` 기준을 통과한다. 기존 실패 column20의
|
||||||
|
`rho_B=1.48674481038207483e-10` 대비 같은 column의 잔차가 약926배 감소했다.
|
||||||
|
기존 trace 진단에서 추출한 첫10개 Value 대비 새 Value의 최대 상대 변화는 약`2.74e-14`다.
|
||||||
|
따라서 이 개선은 고유쌍의 대수적 잔차 개선이며 외부 reference와의 일치를 보장하지 않는다.
|
||||||
|
|
||||||
|
| Mode | FESA Value (표시 반올림) | Abaqus Value | 상대오차 / singleton RMS (%) |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| 1 | 218267.149475 | 219507 | 0.564834 |
|
||||||
|
| 2 | 873571.591115 | 885523 | 1.349644 |
|
||||||
|
| 3 | 873571.591115 | 885523 | 1.349644 |
|
||||||
|
| 4 | 1816890.360227 | 1855340 | 2.072377 |
|
||||||
|
| 5 | 2669030.373076 | 2740230 | 2.598308 |
|
||||||
|
| 6 | 2703557.194039 | 2775150 | 2.579781 |
|
||||||
|
| 7 | 4013818.213002 | 4149410 | 3.267737 |
|
||||||
|
| 8 | 4013818.213002 | 4149410 | 3.267737 |
|
||||||
|
| 9 | 6446840.913563 | 6733790 | 4.261331 |
|
||||||
|
| 10 | 6446840.913563 | 6733790 | 4.261331 |
|
||||||
|
|
||||||
|
모드별 singleton family와 [공통 tolerance](../TOLERANCE.md)를 그대로 적용했다.
|
||||||
|
모든 행은 상대오차5% 이내지만 Mode2–10은 RMS1%를 초과하여 blocking FAIL이다.
|
||||||
|
이는 이전에는 residual 실패 때문에 도달하지 못했던 비교 결과다. 원인은 이번 변경에서
|
||||||
|
확정하지 않았으며 질량·drilling 정식화나 tolerance를 결과에 맞춰 수정하지 않았다.
|
||||||
|
독립 수치 검토는 이번 종료 제어 변경을 PASS로 판단했으나 외부 acceptance는 FAIL로 구분했다.
|
||||||
|
S3의 알려진 실패와 아래 기존 세부 coverage 제한도 남는다.
|
||||||
|
|
||||||
|
## 2026-09-09 trace stopping 구현 이력
|
||||||
|
|
||||||
## 구현된 경로
|
## 구현된 경로
|
||||||
|
|
||||||
@@ -95,11 +164,12 @@ Newton tangent/objectivity/energy/rollback와 pressure synthetic 검사는 초
|
|||||||
full-row-sum mutation, C06 이종 section 공유 node mass assembly, C21/22의 vendor-status/
|
full-row-sum mutation, C06 이종 section 공유 node mass assembly, C21/22의 vendor-status/
|
||||||
budget/allocation 실패 주입 전체, C24의 close/replace 실패 주입 전체는 추가 evidence가 필요하다.
|
budget/allocation 실패 주입 전체, C24의 close/replace 실패 주입 전체는 추가 evidence가 필요하다.
|
||||||
|
|
||||||
## 사용자 결정이 필요한 후속 작업
|
## 2026-09-09 당시 후속 제안
|
||||||
|
|
||||||
현재 요구·정식화·NR·I/O의 수치를 구현 결과에 맞춰 조용히 바꾸지 않는다.
|
현재 요구·정식화·NR·I/O의 수치를 구현 결과에 맞춰 조용히 바꾸지 않는다.
|
||||||
[프로젝트 지침](../../AGENTS.md)의 Physics/지원 범위/acceptance 변경 및 미해결 필수 계약 충돌
|
[프로젝트 지침](../../AGENTS.md)의 Physics/지원 범위/acceptance 변경 및 미해결 필수 계약 충돌
|
||||||
경계에 따라 다음 재검토를 제안한다. 아래는 **미승인 제안**이다.
|
경계에 따라 다음 재검토를 제안했다. 당시에는 **미승인 제안**이었으며,
|
||||||
|
이후 1번의 residual stopping만 ADR-011로 승인·실행했다. 2번 S3는 사용자 요청으로 후속 검토한다.
|
||||||
|
|
||||||
1. `rho_B<=1e-10`과 전체 c 검증을 유지하면서 FEAST 종료 제어를 재검토한다.
|
1. `rho_B<=1e-10`과 전체 c 검증을 유지하면서 FEAST 종료 제어를 재검토한다.
|
||||||
`fpm[5]=0` residual stopping은 검토 후보이며, actual runtime·zero/repeated/endpoint/
|
`fpm[5]=0` residual stopping은 검토 후보이며, actual runtime·zero/repeated/endpoint/
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
# 내부 수치 기준과 FEAST controls
|
# 내부 수치 기준과 FEAST controls
|
||||||
|
|
||||||
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r1`.
|
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10, C5 종료 제어만 변경).
|
||||||
- 기본 보고서: [numerical-review](numerical-review.md); 수식: [새 formulation](formulation.md).
|
- 기본 보고서: [numerical-review](numerical-review.md); 수식: [새 formulation](formulation.md).
|
||||||
- IEEE binary64의 내부 검증 계약이며 [외부 TOLERANCE](../TOLERANCE.md)를 변경하지 않는다.
|
- IEEE binary64의 내부 검증 계약이며 [외부 TOLERANCE](../TOLERANCE.md)를 변경하지 않는다.
|
||||||
|
- 아래 `NOT RUN`은 r1 문서 검토 당시의 기록이다. 변경된 C5의 실제 실행 판정은
|
||||||
|
[종료 제어 구현 검토](implementation-feast-residual-review.md)를 따른다.
|
||||||
|
|
||||||
## C1–C4, C6, C7의 독립 검토 후 명시 채택
|
## C1–C4, C6, C7의 독립 검토 후 명시 채택
|
||||||
|
|
||||||
@@ -46,15 +48,25 @@ Seed 변경으로 통과를 찾지 않는다. oneMKL thread-local 1을 설정하
|
|||||||
| Index | 값 |
|
| Index | 값 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `[0],[1],[2],[3]` | `0,16,12,20` |
|
| `[0],[1],[2],[3]` | `0,16,12,20` |
|
||||||
| `[4],[5],[13]` | `1,1,0` |
|
| `[4],[5],[13]` | `1,0,0` |
|
||||||
| `[26],[27]` | `1,1` |
|
| `[26],[27]` | `1,1` |
|
||||||
| `[49]` | Count `1`, solve `0` |
|
| `[49]` | Count `1`, solve `0` |
|
||||||
| `[63]` | `0` |
|
| `[63]` | `0` |
|
||||||
|
|
||||||
나머지는 해당 설치의 초기값을 유지·기록한다. 이번 [Intel parameter table](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)의 허용 contour16,
|
나머지는 해당 설치의 초기값을 유지·기록한다. 이번 [Intel parameter table](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)의 허용 contour16,
|
||||||
trace stopping, CSR/SPD checks와 count flag reset을 확인했다. 위 값은 FESA의 고정
|
residual stopping, CSR/SPD checks와 count flag reset을 확인했다. 위 값은 FESA의 고정
|
||||||
제어 선택이며 어떤 matrix에서도 수렴한다는 vendor 보장이 아니다.
|
제어 선택이며 어떤 matrix에서도 수렴한다는 vendor 보장이 아니다.
|
||||||
|
|
||||||
|
2026-09-10 사용자 승인으로 C-index `fpm[5]=1` trace stopping을 `0` residual stopping으로
|
||||||
|
대체한다. Double precision의 vendor stopping epsilon은 `10^-fpm[2]=1e-12`이며
|
||||||
|
`fpm[3]=20`을 유지한다. Count/solve 모두 같은 초기 controls를 적용하고 `[49]`만 구분한다.
|
||||||
|
전체 c개의 독립 `rho_B=||Bx-mu x||2/||x||2<=1e-10`, Gram 및 original-free 복구 검증은
|
||||||
|
그대로다. Vendor residual의 정규화와 독립 rho_B를 동일시하지 않으며 `info=0`도 독립 검증을
|
||||||
|
대체하지 않는다. `epsout`은 trace 변화 진단량으로 보존하고 새 residual 오차로 재해석하지 않는다.
|
||||||
|
기존 trace 실행의 pass/fail·loop·epsout은 당시 controls의 이력이다. Zero/mixed-zero/repeated
|
||||||
|
및 원본 모델의 새 실행과 미해결 위험은 [종료 제어 구현 검토](implementation-feast-residual-review.md)에
|
||||||
|
구분한다. S3·물리 정식화·공통 외부 tolerance는 이 결정으로 변경하지 않는다.
|
||||||
|
|
||||||
Gershgorin off-diagonal absolute row sum은 매 합산 뒤 `nextafter(+infinity)`로 outward
|
Gershgorin off-diagonal absolute row sum은 매 합산 뒤 `nextafter(+infinity)`로 outward
|
||||||
누적하고 diagonal±sum도 바깥 한 ULP를 적용한다. `beta=norm(B,inf)`도 outward로 구한다.
|
누적하고 diagonal±sum도 바깥 한 ULP를 적용한다. `beta=norm(B,inf)`도 outward로 구한다.
|
||||||
`B=0`의 algorithmic enclosure에서만 beta=1이며 physical mass/λ floor가 아니다.
|
`B=0`의 algorithmic enclosure에서만 beta=1이며 physical mass/λ floor가 아니다.
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ Status Validate(const Domain& domain, const EigenAnalysisState& state,
|
|||||||
{2U, 12},
|
{2U, 12},
|
||||||
{3U, 20},
|
{3U, 20},
|
||||||
{4U, 1},
|
{4U, 1},
|
||||||
{5U, 1},
|
{5U, 0},
|
||||||
{13U, 0},
|
{13U, 0},
|
||||||
{26U, 1},
|
{26U, 1},
|
||||||
{27U, 1},
|
{27U, 1},
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ void SetControls(std::array<MKL_INT, 128>& fpm, const bool count) {
|
|||||||
fpm[2] = 12;
|
fpm[2] = 12;
|
||||||
fpm[3] = 20;
|
fpm[3] = 20;
|
||||||
fpm[4] = 1;
|
fpm[4] = 1;
|
||||||
fpm[5] = 1;
|
fpm[5] = 0; // Trace convergence alone can leave individual pairs inaccurate.
|
||||||
fpm[13] = 0;
|
fpm[13] = 0;
|
||||||
fpm[26] = 1;
|
fpm[26] = 1;
|
||||||
fpm[27] = 1;
|
fpm[27] = 1;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <hdf5.h>
|
#include <hdf5.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -78,6 +80,15 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
|||||||
H5Fopen(path.string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
H5Fopen(path.string().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
|
||||||
ASSERT_GE(file, 0);
|
ASSERT_GE(file, 0);
|
||||||
EXPECT_GT(H5Lexists(file, "/steps/Step-1/eigen/modes", H5P_DEFAULT), 0);
|
EXPECT_GT(H5Lexists(file, "/steps/Step-1/eigen/modes", H5P_DEFAULT), 0);
|
||||||
|
const hid_t controls =
|
||||||
|
H5Dopen2(file, "/steps/Step-1/eigen/backend/base_fpm", H5P_DEFAULT);
|
||||||
|
ASSERT_GE(controls, 0);
|
||||||
|
std::array<std::int64_t, 128> stored_controls{};
|
||||||
|
ASSERT_GE(H5Dread(controls, H5T_NATIVE_INT64, H5S_ALL, H5S_ALL,
|
||||||
|
H5P_DEFAULT, stored_controls.data()),
|
||||||
|
0);
|
||||||
|
EXPECT_EQ(stored_controls[5U], 0);
|
||||||
|
EXPECT_GE(H5Dclose(controls), 0);
|
||||||
EXPECT_GE(H5Fclose(file), 0);
|
EXPECT_GE(H5Fclose(file), 0);
|
||||||
std::ifstream original_file{path, std::ios::binary};
|
std::ifstream original_file{path, std::ios::binary};
|
||||||
const std::string original{std::istreambuf_iterator<char>{original_file}, {}};
|
const std::string original{std::istreambuf_iterator<char>{original_file}, {}};
|
||||||
@@ -91,6 +102,7 @@ TEST(EigenHdf5ResultsWriter, WritesModalSchemaAndRejectsTamperedState) {
|
|||||||
[](auto& candidate) { candidate.modes[0].cluster_id = 7U; },
|
[](auto& candidate) { candidate.modes[0].cluster_id = 7U; },
|
||||||
[](auto& candidate) { candidate.constraint_mask[0] = 1U; },
|
[](auto& candidate) { candidate.constraint_mask[0] = 1U; },
|
||||||
[](auto& candidate) { candidate.nodal_reduction[0].rcond_inf = 1e-15; },
|
[](auto& candidate) { candidate.nodal_reduction[0].rcond_inf = 1e-15; },
|
||||||
|
[](auto& candidate) { candidate.backend.base_fpm[5U] = 1; },
|
||||||
[](auto& candidate) { candidate.eta_gram = 1e-5; }};
|
[](auto& candidate) { candidate.eta_gram = 1e-5; }};
|
||||||
for (const auto& mutate : mutations) {
|
for (const auto& mutate : mutations) {
|
||||||
auto candidate = state;
|
auto candidate = state;
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ TEST(MklFeastEigenSolver, SolvesN1AndRetainsBackendEvidence) {
|
|||||||
EXPECT_EQ(result.Value().eigenvectors.Rows(), 1U);
|
EXPECT_EQ(result.Value().eigenvectors.Rows(), 1U);
|
||||||
EXPECT_EQ(result.Value().eigenvectors.Columns(), 1U);
|
EXPECT_EQ(result.Value().eigenvectors.Columns(), 1U);
|
||||||
EXPECT_EQ(result.Value().thread_count, 1U);
|
EXPECT_EQ(result.Value().thread_count, 1U);
|
||||||
|
ASSERT_EQ(result.Value().base_fpm.size(), 128U);
|
||||||
|
EXPECT_EQ(result.Value().base_fpm[5U], 0);
|
||||||
ASSERT_FALSE(result.Value().backend_calls.empty());
|
ASSERT_FALSE(result.Value().backend_calls.empty());
|
||||||
EXPECT_EQ(result.Value().backend_calls.front().purpose, "total-enclosure");
|
EXPECT_EQ(result.Value().backend_calls.front().purpose, "total-enclosure");
|
||||||
EXPECT_EQ(result.Value().backend_calls.back().kind, "solve");
|
EXPECT_EQ(result.Value().backend_calls.back().kind, "solve");
|
||||||
|
|||||||
Reference in New Issue
Block a user