Repository navigation
fix(latent): build the latent instance the Fitness way under JAX (#732) - #734
Merged
Merged
Conversation
`LatentLens.variables` built its per-sample instance with `model.instance_from_vector(vector=parameters)`, whose default assertion check applies a Python `not` to a traced boolean. The latent engine evaluates `variables` under a per-sample `jax.jit`, so a model carrying any assertion (the ordered two-basis MGE lens light of the Euclid `vis_lp` stage) raised `TracerBoolConversionError` on every sample; the engine swallowed each raise into a NaN row, the global mask found nothing, and the search wrote no latent output at all (RAL job 342398, all ten euclid_dr1_prelim tiles). Add `latent_instance_from(model, parameters, xp)`: the NumPy path is unchanged (assertions checked, a violation raises FitException and is dropped as a NaN row); under JAX it skips assertions and threads `xp`, exactly as `Fitness` does on its JAX path. `LatentLens.variables` uses it and the class docstring tells subclasses that build their own instance to do the same. Tests: the helper on both backends (the default path is shown to raise under jit), and `LatentLens.variables` end to end under `jax.jit` on a model with an assertion, finite and equal to the NumPy evaluation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFSFgEBiZc7kTRutfK1RsN
3 tasks done
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.
Summary
Closes #732. The Euclid
initial_lens_model/vis_lpstage (two-basis MGE lens light, SIE + shear, MGE source) of RAL job 342398 wrote no latent output on all teneuclid_dr1_prelimtiles.LatentLens.variablesbuilt its per-sample instance withmodel.instance_from_vector(vector=parameters), whose default assertion check applies a Pythonnotto a traced boolean. The latent engine evaluatesvariablesunder a per-samplejax.jit, so a model carrying any assertion (the ordered MGE bases added tovis_lpon 2026-09-08) raisedTracerBoolConversionErroron every sample; the engine swallowed each raise into a NaN row, the global mask found nothing, and the search logged only "no finite latent samples remained".This adds
latent_instance_from(model, parameters, xp): the NumPy path is unchanged (assertions checked, a violation raisesFitExceptionand is dropped as a NaN row); under JAX it skips assertions and threadsxp, exactly asFitnessdoes on its JAX path.LatentLens.variablesuses it, and the class docstring tells subclasses that build their own instance to do the same. The companion PyAutoFit PR makes the engine report the exceptions it swallows; the euclid pipeline's own two trace failures are filed in PyAutoMind asdraft/bug/euclid/vis_lp_latent_euclid_jit_trace.md.API Changes
Added one public helper,
autolens.analysis.latent.latent_instance_from. No existing symbol changed; NumPy-path behaviour ofLatentLens.variablesis unchanged, the JAX path now succeeds where it silently produced NaN rows.See full details below.
Test Plan
test_latent_instance_from_numpy_checks_assertions— violation raisesFitException, satisfied builds the instancetest_latent_instance_from_jax_skips_assertions_under_jit— the default path raisesTracerBoolConversionErrorunderjax.jit, the helper tracestest_latent_lens_variables_traces_under_jit_with_model_assertion— end to end on the 7x7 fixture withuse_jax=True, every latent finite and equal to the NumPy evaluationjax.jit(LatentEuclid.variables)returns all 12 latents finite and equal to the eager valuesFull API Changes (for automation & release notes)
Added
autolens.analysis.latent.latent_instance_from(model, parameters, xp=np)— builds the instance a latent function is evaluated on; NumPy checks assertions, JAX skips them withignore_assertions=True, xp=xpChanged Behaviour
LatentLens.variablesunder JAX: previously raised inside the engine's per-samplejax.jitfor any model with an assertion (silently masked to NaN rows); now evaluatesMigration
LatentLenssubclass that builds its own instance: replacemodel.instance_from_vector(vector=parameters)withlatent_instance_from(model=model, parameters=parameters, xp=analysis._xp)Generated by the PyAutoLabs agent workflow.
🤖 Generated with Claude Code
https://claude.ai/code/session_01FFSFgEBiZc7kTRutfK1RsN
Generated by Claude Code