Repository navigation
fix(nvf): recompute the floor's SVD with ?gesvd where ?gesdd fails, and say so - #128
Merged
Merged
Conversation
…nd say so The NVF inverse-rule floor takes singular vectors of <1/eps> where it binds. LAPACK's divide-and-conquer ?gesdd can report no convergence on a finite, well-conditioned matrix: a DLASD2 deflation bug (Reference-LAPACK #1138) present in MKL up to 2026.1 (bundled by PyTorch's CPU wheels), reference LAPACK up to 3.12.1 and OpenBLAS up to 0.3.30. The previous retry used NumPy's SVD, which is the same driver and fails the same way wherever NumPy links an affected LAPACK (the default MKL build on Anaconda's defaults). - NumPy and PyTorch: a failure on a finite matrix is recomputed with SciPy's QR-based ?gesvd on the host; a non-finite matrix keeps its error. - JAX returns NaN factors instead of raising, so eager JAX checks them and recomputes with SvdAlgorithm.QR. Under jax.jit nothing can be recomputed; the layer is then left unfloored, and a jax.debug.callback warns. - New wavebit.rcwa.diagnostics.SvdConvergenceWarning announces each case without naming the cause, since ?gesdd can fail for other reasons too. Fixes #127 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RKzHy8gt3tzmq4rXfS56Le
…ilure Section 6 of the torch upstream defects page: what was measured (pytorch/pytorch#202596), the LAPACK cause, how it reaches wavebit only through the NVF floor's SVD, and when the retry can go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RKzHy8gt3tzmq4rXfS56Le
…lure is retried main now decides the passive-dielectric case on the host, so under jax.jit a material that is a constant of the trace skips the SVD; only a layer whose permittivity is a jit argument or a vmap lane (or a metal) still takes it. The warning's docstring and the defects page said every NVF layer under jit. The NVF theory page now also says a ?gesdd failure is recomputed with ?gesvd. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RKzHy8gt3tzmq4rXfS56Le
yonghakim
marked this pull request as ready for review
October 30, 2026 01:05
yonghakim
enabled auto-merge (rebase)
October 30, 2026 01:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #127.
The NVF inverse-rule floor takes singular vectors of
<1/eps>where it binds. LAPACK's divide-and-conquer?gesddcan report no convergence on a finite, well-conditioned matrix, through aDLASD2deflation bug (Reference-LAPACK #1138, fixed by its PR #1140, in no reference release yet). The bug is in MKL up to 2026.1, which PyTorch's CPU wheels bundle (pytorch/pytorch#202596), in reference LAPACK up to 3.12.1, and in OpenBLAS up to 0.3.30. The previous retry used NumPy's SVD. That is the same driver, and it fails the same way wherever NumPy links an affected LAPACK, such as the default MKL build on Anaconda'sdefaultschannel.Changes
_svd(NumPy, PyTorch): a failure on a finite matrix is recomputed with SciPy's QR-based?gesvdon the host. A non-finite matrix keeps its error, and so does atorch.func.vmaplane, which has no host values.?gesddfailures come back as NaN factors rather than an error. Eager JAX checks for that and recomputes withSvdAlgorithm.QR. Underjax.jitnothing can be recomputed. NaN singular values are below no floor, so the layer is left unfloored, and ajax.debug.callbackwarns. That is harmless on a passive dielectric and wrong by the floor on a metal.wavebit.rcwa.diagnostics.SvdConvergenceWarning: it announces each case without naming the cause, since?gesddcan fail for other reasons too.docs/development/torch-upstream-defects.mdrecords the measurement and the cause;gesvd, not NumPy, and gives the same floored matrix and gradient;vmap.Validation
Linux x86-64 (AVX-512), Python 3.13.17, torch 2.14.1+cpu, jax 0.12.0.1, NumPy 2.5.4, SciPy 1.18.1.
torch.linalg.svdactually fails on two matrices: the r = 161.48 nm<1/eps>from NVF: decide the inverse-rule floor from the materials, not a full SVD #121 and the bidiagonal matrix from CPUtorch.linalg.svdraises LinAlgError on well-conditioned matrices: bundled MKL 2024.2 carries LAPACK DLASD2 deflation bug (Reference-LAPACK #1138, fixed upstream) pytorch/pytorch#202596._svdrecomputed both, with residual 2.5e-14 and 5.7e-14 and singular values within 5.3e-14 and 3.7e-14 of NumPy's. Each warned once. A NaN matrix kept itsLinAlgError.tests/rcwa/test_nvf_metal_inverse_rule.py,tests/rcwa/test_torch_vmap_autograd.py,tests/api/test_public_api.pyandtests/api/test_docs_contract.py, on this branch merged with current main: 592 passed, 1 skipped, 1 failed. The failure,test_a_port_named_tuple_constructor_cannot_name_its_replacement, fails on main too. Python 3.13's namedtuple_replaceraisesTypeErrorthere rather thanValueError, which is unrelated to this change.tests/rcwa -k "nvf or factoriz or floor or inverse_rule"gave 918 passed and 30 skipped. 41 failed only because the optionalcontourpywas missing; with it installed, those four files gave 204 passed. NoSvdConvergenceWarningwas raised anywhere outside the new tests.python tools/run_verification.py --profile quickgave 17 passed.Not verified
Generated by Claude Code