Repository navigation
Follow-ups to #142: jit (0, 1) abort, v10 tetm migration, tetm docs, test_boundary x64, chapter 12 - #143
Merged
Conversation
… process jax.jit of a public rcwa run whose PlaneWave polarization was exactly (0, 1) killed the Python process rather than raising, under jit and jit(grad) alike, on jax/jaxlib 0.11.0. The cause was the prepared run's nonzero-polarization guard, which squared the pair with xp.abs(a)**2. XLA's algebraic simplifier reads the complex constant [0, 1] as an iota and rewrites abs(iota) to the iota itself, a complex value where a real one belongs. The compile then fails a RET_CHECK in HandleAbs and aborts. (1, 0), the word 'p', and eager jax.grad and vmap were unaffected. The guard now takes |a|^2 as real(a * conj(a)). Its truth value is the same, so nothing it guards moves. The same script ran on origin/main 93cf7cb and on this commit and gave 184 arrays, all bit-identical: amplitudes, efficiencies, powers, fields, scattering blocks, jit/grad/vmap values, torch gradients and single precision. Test: test_jit_of_the_jones_pair_0_1_compiles_instead_of_aborting runs the jitted call in a subprocess, so a regression fails the test rather than ending the session that runs it. It holds jit against the eager NumPy run to 1e-12 and requires a finite jit(grad). With the old guard restored it fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ame light
migrate_legacy_jobs read old.tetm.name.lower(), but the v10 reader stores the
word ('te' / 'tm', _normalise_tetm), not a Tetm member. Every v10 document that
declared incidence.tetm therefore raised AttributeError: 'str' object has no
attribute 'name'. It now maps through the same normalizer: 'te' becomes 's'
and 'tm' becomes 'p', case-insensitively.
Test: test_a_tetm_declaration_migrates_to_the_word_for_the_same_light covers
'te', 'tm' and 'TM'. It runs the migrated job and holds R, T and all four s/p
amplitudes against the original v10 run to 2e-13. With the old line restored all
three cases fail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- development/solver-integration.md: there is no public wavebit.Tetm. The engine accepts members of its own wavebit._common.enums.Tetm. - learn/fundamentals/results.md, and its Korean page: the "incident and output polarization" section described s_inc / p_inc and tetm= in the present tense. It now states the current reading: amplitude_s / amplitude_p are output polarization, the incident polarization is the PlaneWave's, and two runs give the s and p responses. The earlier interface's three result objects move into an "Earlier interface" box. The rest of chapter 12 is still written against the earlier interface (solver.solve(), result.order) under the chapter note; rewriting it is a separate piece. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under pytest-xdist, 11 tests in tests/rcwa/test_boundary.py computed their JAX solves in float32 and failed, e.g. 0.8902014493942261 where 0.890202199751976 +- 1e-12 was expected. The file passed when run alone. The cause: importing the private JAX RCWA backend lifts JAX's 32-bit cap, but not inside a public run's Execution scope, which suppresses the legacy lift on purpose. A worker whose first JAX test was a public single-precision run imported the backend inside that scope with x64 off, and every later engine JAX solve in the file ran in float32. A public run with precision='single', followed by a legacy JAX solver, reproduces it directly (T dtype float32). The file now calls `_enable_x64()` at import, guarded for an absent JAX, as tests/rcwa/test_laurent_factorization.py already does. To test the fix, a scratch pytest plugin ran a public single-precision JAX run at session start. Before the fix, the three of the eleven run in that order all failed. After it, all eleven passed in that order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"12. Reading results" still taught the earlier interface under its chapter note: solver.solve(), result.order(m, n).R, result.r_s and (1, 21) arrays. It now uses rcwa.run, in English and in Korean together: - result.reflection / result.transmission .order(m, n) with .efficiency and .amplitude_s / .amplitude_p; - the (wavelength, order_v, order_u) shape, where the zeroth order is T[0, 0, 10]; - orders_u / orders_v on each port, amplitude_xyz, and k_parallel / k_normal for the evanescent test; - reference['plane'] and the cell-centre lateral reference for the phases; - result.outputs['power_entering'] and result.absorption, one value per wavelength. The earlier spellings (solver.solve(), result.order, result.incident, answers='efficiency', R_s / T_p) move into "Earlier interface" boxes, and the chapter note is gone. Every printed value was re-measured through the current API on Chapter 4's grating, with the snippets run as written: 0.2053, 0.3531, 0.7947, (1, 1, 21), and |t_s(0, 0)| = 0.4852 at 115.5 degrees. The values are unchanged, and Figure 12-1's labels carry no API names, so the figure stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yonghakim
marked this pull request as ready for review
November 3, 2026 17:24
yonghakim
enabled auto-merge (rebase)
November 3, 2026 17:25
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.
What changes
Five independent changes found while preparing #142, the pure 1D TE/TM path. Each is its own self-contained commit. This branch starts from
main93cf7cb, not from #142, so the two PRs land independently.fix(rcwa): a jitted run of the Jones pair(0, 1)no longer aborts the process.jax.jitof a publicrcwarun withPlaneWave(polarization=(0., 1.))killed Python underjitandjit(grad)on jax/jaxlib 0.11.0. It raised no exception._lifecycle._runtime_checks) tookxp.abs(a)**2. XLA's algebraic simplifier reads the complex constant[0, 1]as an iota and rewritesabs(iota)to the iota itself, which has the wrong (complex) type. The compile then fails aRET_CHECKinHandleAbs.real(a * conj(a)). Its truth value is the same.fix(migration): a v10tetmdeclaration migrates to the word for the same light.migrate_legacy_jobsreadold.tetm.name, but the v10 reader stores the word'te'/'tm', so every v10 document that declaredtetmraisedAttributeError.'te'becomes's'and'tm'becomes'p'.docs: two statements that treatedtetmas current.solver-integration.mdnamed awavebit.Tetmthat does not exist.s_inc/p_incandtetm=in the present tense. It now gives the current reading and keeps the earlier interface in a marked box, in English and Korean.test(rcwa):tests/rcwa/test_boundary.pyasks for JAX double precision itself.Executionscope, which suppresses that lift on purpose. A worker whose first JAX test was a public single-precision run therefore left x64 off for every later engine JAX solve._enable_x64()at import, guarded for an absent JAX, astest_laurent_factorization.pyalready does.docs(learn): chapter 12 reads results through the current API, in English and Korean.rcwa.run, the ports'order(m, n)with.efficiency/.amplitude_s/.amplitude_p, the (wavelength, order_v, order_u) shape,orders_u/orders_v,k_parallel/k_normal,reference['plane'],outputs['power_entering']andabsorption.Verification
jit,jit(grad),vmapandgrad, and its jittedRmatches the eager NumPy value to 1e-12.test_jit_of_the_jones_pair_0_1_compiles_instead_of_abortingruns the jitted call in a subprocess and fails with the old guard restored.mainand on this branch and gave 184 arrays, all bit-identical: amplitudes, efficiencies, powers, fields, S blocks, jit/grad/vmap values, torch gradients and single precision.test_a_tetm_declaration_migrates_to_the_word_for_the_same_lightcovers'te','tm'and'TM'. It holds R, T and all four s/p amplitudes against the original v10 run to 2e-13, and all three cases fail with the old line restored.(1, 1, 21), and|t_s(0, 0)|= 0.4852 at 115.5°.sphinx-build -W -b html docsbuilds clean, andtests/api/test_docs_contract.pypasses (166).not slow and not research, 4 workers), on the first three commits: 1240 passed, 11 failed. All 11 failures are intests/rcwa/test_boundary.py, and commit 4 fixes them.wavebit, Python 3.12.9, numpy 2.5.1, jax/jaxlib 0.11.0, torch 2.14.1, macOS arm64.Not done
tests/api/test_unified_rcwa_pure_1d.pycan write that pair as(0, 1)again instead of(0, 2). That is a one-line follow-up.🤖 Generated with Claude Code