Skip to content

fix(export): correct and complete the PyTorch and JAX operator mappings - #1415

Merged
MilesCranmer merged 3 commits into
astroautomata:masterfrom
M-Colley:fix/torch-jax-export
Oct 8, 2026
Merged

MilesCranmer merged 3 commits into
astroautomata:masterfrom
M-Colley:fix/torch-jax-export

Conversation

@M-Colley

@M-Colley M-Colley commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes PyTorch and JAX export, finishing the Piecewise support started in #433.

  • The SymPy forms of greater, less, greater_equal, less_equal, cond, logical_or, logical_and, relu and clamp use Piecewise, which had no PyTorch or JAX mapping, so exporting any of them raised a KeyError. Piecewise now maps to nested torch.where/jnp.where, with NaN where no branch applies, matching SymPy.
  • JAX mapped LessThan (<=) and GreaterThan (>=) to the strict comparisons, and had no mapping for the strict relations.
  • JAX mapped Max/Min to the reductions jnp.max/jnp.min, which read the second argument as an axis, so max(x0, x1) raised a TypeError. They now map to jnp.maximum/jnp.minimum.
  • Max/Min with three or more arguments, which SymPy produces from max(max(x0, x1), x2), failed on both backends. They are now folded pairwise.
  • PyTorch looked up its built-in mappings before extra_torch_mappings, so users could not override them.
  • torch_initialized/jax_initialized were never set, so setup reran on every export.

Tests

  • test_piecewise_comparison_and_extremum_operators, for both PyTorch and JAX, checks 11 operators against SymPy's NumPy output, on data with ties so < and <= can be told apart.
  • test_extra_mappings_take_precedence.

M-Colley and others added 2 commits October 8, 2026 20:10
Wrong results:
- JAX mapped `sympy.LessThan` (`<=`) to `jnp.less` and `GreaterThan`
  (`>=`) to `jnp.greater`, so `less_equal`/`greater_equal` were wrong
  at ties; the strict relations had no mapping at all.
- JAX mapped `Max`/`Min` to the reductions `jnp.max`/`jnp.min`, so the
  second argument was read as an axis: `max(x0, 0.5)` raised a
  `TypeError`. Both backends also failed on `Max`/`Min`/`And`/`Or` with
  more than two arguments, which SymPy produces from nested calls such as
  `max(max(x0, x1), x2)`. These are now elementwise and folded pairwise.
- PyTorch looked up built-in mappings before `extra_torch_mappings`, so
  users could not override them (the JAX export already let them).
- PyTorch shared one trainable parameter between equal constants, e.g.
  `x0 * 2.5 + x1 * 2.5` had one parameter, versus two in the search and in
  the JAX export.

Missing support:
- `Piecewise`, which the SymPy forms of `greater`, `less`,
  `greater_equal`, `less_equal`, `cond`, `logical_or`, `logical_and`,
  `relu` and `clamp` use, had no PyTorch or JAX mapping, so exporting any
  of these operators raised a `KeyError`. Map it to nested
  `torch.where`/`jnp.where`, with NaN where no branch applies, as in
  SymPy. This finishes the work started in #433.
- Add `erfc` for PyTorch and `gamma`/`loggamma` for JAX.

Robustness:
- `pytorch()` and `jax()` set `output_torch_format`/`output_jax_format`
  before refreshing. When one equation could not be exported, the flag
  stayed set, so every later `refresh()`, and therefore `sympy()` and
  `latex()`, raised the same error. Restore the flag when the export
  fails.
- `torch_initialized`/`jax_initialized` were never set, so the torch
  module classes were redefined on every export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both exporters now translate Piecewise (used by greater, less, cond, relu, clamp, logical_and/or) into nested where calls, and fold Max/Min over any number of arguments. JAX maps Max/Min to the elementwise jnp.maximum/jnp.minimum and maps strict and non-strict relations correctly. User extra_torch_mappings now override built-in mappings, and both exporters cache their lazy imports.

Co-authored-by: Miles Cranmer <miles.cranmer@gmail.com>
Comment thread pysr/test/params.py Outdated
Co-authored-by: Miles Cranmer <miles.cranmer@gmail.com>
@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread pysr/test/test_jax.py
@MilesCranmer
MilesCranmer merged commit 1fd4114 into astroautomata:master Oct 8, 2026
48 checks passed
@M-Colley
M-Colley deleted the fix/torch-jax-export branch October 9, 2026 07:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants