事象
Epic #54 の CI(run 31603441394、commit 4314369)で test (python 3.11) の
tests/test_estimator_stage3.py::test_stage3_matches_oracle_directed_case[f] が
convergence True != oracle False で fail。同一 commit の再実行(別ランナー)では success。
同一 run 内の 3.12 も success、過去の 3.11 run(31601692004 / 31602226220)も success。
分析
- case f は converge_cases.mat 中で最長の 100 反復。非線形な CAVI 反復は浮動小数点の
微小差を増幅する(case a=23 / b=5 反復は全ランナーで green)
- GitHub ホストランナーは CPU 世代が不均一で、numpy は実行時に CPU 機能(AVX512 等)で
SIMD カーネルを選ぶ → 同一 wheel でも ~1ulp の演算差が出うる
- oracle の最終 loglik 差は +9.6e-08(tol=1e-16 の 8 桁上)なので、収束フラグが割れたことは
当該ランナーで軌道自体が oracle 許容誤差(rtol=1e-9)を超えて乖離した可能性を示す
(配列 assert は convergence assert の後にあり未到達)
論点(次の判断者へ)
- oracle 厳密一致(rtol=1e-9)を100反復ケースに要求するのはハードウェア可搬性の観点で
過剰かどうか(ADR-0001 の oracle 方針と、反復回数に応じた許容誤差の緩和のトレードオフ)
- 短期対応の選択肢: (a) case f のみ許容誤差を緩和(仕様変更、要レビュー)、(b) CI の
再実行ポリシーを明文化(フレーク許容)、(c) 反復回数の短い代替ケースへ差し替え
(fixture 再生成は MATLAB 評価版失効のため不可 — 既存 fixture の範囲で選ぶ)
E7(#54)はこの issue の起票をもって当該事象の記録とし、スコープに含めない
(発見の経緯: docs/design/epic-07-packaging.md Story Timeline 2026-08-12)。
事象
Epic #54 の CI(run 31603441394、commit
4314369)でtest (python 3.11)のtests/test_estimator_stage3.py::test_stage3_matches_oracle_directed_case[f]がconvergence True != oracle False で fail。同一 commit の再実行(別ランナー)では success。
同一 run 内の 3.12 も success、過去の 3.11 run(31601692004 / 31602226220)も success。
分析
微小差を増幅する(case a=23 / b=5 反復は全ランナーで green)
SIMD カーネルを選ぶ → 同一 wheel でも ~1ulp の演算差が出うる
当該ランナーで軌道自体が oracle 許容誤差(rtol=1e-9)を超えて乖離した可能性を示す
(配列 assert は convergence assert の後にあり未到達)
論点(次の判断者へ)
過剰かどうか(ADR-0001 の oracle 方針と、反復回数に応じた許容誤差の緩和のトレードオフ)
再実行ポリシーを明文化(フレーク許容)、(c) 反復回数の短い代替ケースへ差し替え
(fixture 再生成は MATLAB 評価版失効のため不可 — 既存 fixture の範囲で選ぶ)
E7(#54)はこの issue の起票をもって当該事象の記録とし、スコープに含めない
(発見の経緯: docs/design/epic-07-packaging.md Story Timeline 2026-08-12)。