Skip to content

fix: don't register JAX-leaf types (int) as pytree nodes (shapelet vmap crash)#1366

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/jax-pytree-leaf-registration
Jul 13, 2026
Merged

fix: don't register JAX-leaf types (int) as pytree nodes (shapelet vmap crash)#1366
Jammy2211 merged 1 commit into
mainfrom
feature/jax-pytree-leaf-registration

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

JAX-fitting a shapelet model crashed in jax.vmap(jax.jit(self.call)) (Fitness._vmap) with TypeError: vars() argument must have __dict__ attribute (release-validation run 29266305445).

Root cause (differs from the issue's initial hypothesis)

Not a __slots__/array-like component. af.Model(ShapeletPolar) auto-wraps its int-typed n/m args as af.Model(int) sub-models, and register_model._walk registered builtins.int as a pytree node. JAX then ran the instance-flatten _partition(5) on every int leaf → vars(5) crash. Confirmed by walking the tree (int ∈ _REGISTERED_INSTANCE_CLASSES) and reproduced in pure autofit via af.Model(int). int (like float/str) is a native JAX leaf and must never be registered.

Fix

autofit/jax/pytrees.py: new helper _instances_carry_dict(cls) (any("__dict__" in vars(k) for k in cls.__mro__)); register_model._walk now gates the register_pytree_node block on it. Leaf types and purely __slots__ classes are left as opaque JAX leaves; real model components (which have __dict__) register as before. Producer-side — no silent fallback inside _partition (per the no-silent-guards principle).

Verification

  • Shapelet repro now tree_flattens cleanly (was crashing on main).
  • New assertion (paired autofit_workspace_test PR): leaf types not registered, tree_flatten/tree_unflatten round-trip.
  • Existing jax_assertions/pytrees.py + enable_pytrees.py still pass (no regression).
  • pytest test_autofit/1473 passed, 1 skipped.

API Changes

None — one private helper added; public surface unchanged.

Fixes #1365

🤖 Generated with Claude Code

https://claude.ai/code/session_01TDCsgNCXacXqiWAPTswWCt

register_model walked every Model.cls into a pytree registration, including the
af.Model(int) sub-models autofit auto-creates for int-typed constructor args
(e.g. a shapelet's n/m). Registering builtins.int made JAX call the instance
flatten _partition(5) on every int leaf, and vars(5) raised
'TypeError: vars() argument must have __dict__ attribute', crashing
jax.vmap(jax.jit(...)) for any JAX shapelet fit (release-validation run
29266305445).

Gate registration on _instances_carry_dict(cls): only classes whose instances
carry a __dict__ (real model components) are registered; native JAX leaves
(int/float/str/...) and purely __slots__ classes are left as opaque leaves.
Producer-side fix — no silent fallback inside _partition.

Fixes #1365

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TDCsgNCXacXqiWAPTswWCt
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 13, 2026
@Jammy2211 Jammy2211 merged commit 240e9ca into main Jul 13, 2026
5 checks passed
@Jammy2211 Jammy2211 deleted the feature/jax-pytree-leaf-registration branch July 13, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: JAX pytree registers leaf types (int) → _partition vars() crash

1 participant