Repository navigation
Detach weight-free while loops whose result reaches a hidden state indirectly (#186) - #191
Merged
Merged
Conversation
…directly (#186) The perturbation pass detached a while loop only when one of its own outvars was a hidden outvar. A loop whose result passes through further equations (V <- while(V) + I) or that is fed only by the input was left in place, and jax.vjp of the step failed to transpose it. Detach every while whose outputs reach a hidden outvar (one backward reachability pass). A loop reaching no hidden state keeps the loud error. Also bring the control-flow section of the limitations page up to date (cond is if-converted, static scans are unrolled or descended, weight-free while loops are supported).
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Merged
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 #186.
Summary
Cause:
JaxprEvalForHiddenPerturbation._eval_while(_compiler/hidden_pertubation.py) detached awhileonly when one of the loop's own outvars was a hidden outvar. In two cases the loop stayed in the perturbed step andjax.vjpraised the reverse-through-while_loopValueError:V <- while(...)(V) + I, the issue's case);V <- 0.9 V + while(...)(x) @ w).Fix:
compile()now finds every top-levelwhilewhose outputs reach any hidden outvar, in one backward reachability pass (_while_eqns_reaching), and detaches exactly those. The direct case is a subset, so its behaviour is unchanged. Each detach still emits the WARNINGCONTROL_FLOW_OPAQUE_FWD. The hidden-to-hidden Jacobian already uses forward mode for any transition containing awhile.A loop that reaches no hidden state (e.g. on the readout only) is deliberately left alone. Detaching it would silently zero
dL/dh, so it keeps the loud error.docs/advanced/limitations.ipynb: the control-flow section was stale. It saidcond/scan/while_loopare "NOT supported" and thatjnp.wherebreaks compilation. It is rewritten to match current behaviour:jitinlined;condif-converted, with the dead-branch NaN caveat;whilesupported under single-step;whileis an error.A new executed example (weight inside vs. outside a
while) replaces thecond"will not work" example, which does compile today.Spec:
docs/specs/2026-10-24-issue-186-while-reaching-hidden.md.Before / after (issue repro)
while_leakis a different model, so its value differs. It equals its unrolled twin element-wise (see tests).Tests
_compiler/hidden_pertubation_test.py:The old
test_non_hidden_while_untouchedpinned an input-fed loop that does reach the hidden state. That loop madeetrace_gradraise onmain, so the test is replaced._algorithm/tests/while_support_test.py:leak/inputcells equals the unrolled twin element-wise, throughetrace_gradand through the single-step oracle;6 of the new tests fail without the fix.
Full suite (local CPU): 2921 passed, 0 failed. No new mypy errors compared with
main(thetypecheck_and_buildjob fails onmaintoo).