Avatar for the GalacticDynamics user
GalacticDynamics
unxt
BlogDocsChangelog

Performance History

Latest Results

ci(prek): protect main and versions/ branches from direct commits (#929) * ci(prek): protect main and versions/ branches from direct commits * ci: explicitly set always_run: true on no-commit-to-branch * fix(ci): skip no-commit-to-branch in the full-suite CI run * fix(ci): don't clobber an existing SKIP when skipping no-commit-to-branch * fix(pre-commit): scope no-commit-to-branch to the pre-commit stage * fix(ci): use SKIP env var, not --skip, to skip no-commit-to-branch * docs(nox): clarify the no-commit-to-branch skip isn't CI-specific Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
main
2 days ago
✨ feat(linalg): astropy conversions for the matrix containers (#926) * ✨ feat(linalg): astropy conversions for the matrix containers `UnitsMatrix` and `astropy.units.StructuredUnit` are the same idea in two libraries -- a nested layout of units -- and `QuantityMatrix` is that layout with values attached, which astropy spells as a `Quantity` over a structured dtype. Nothing converted between them here, so a downstream package (coordinax) was carrying the conversions instead, in a module that imported nothing of its own. `astropy` is already a hard dependency of `unxt`, which `unxts.linalg` requires, so these register unconditionally, the way `unxts.parametric`'s do. The `QuantityMatrix -> Quantity` direction reads the layout rather than the value's `ndim`: a nested layout over a (2, 2) value is one record of records, a flat one over a (4, 3) value is four records, and the two are indistinguishable by `ndim` alone. A value with more leading axes than astropy's structured dtype can carry says so. * πŸ› fix(linalg): a too-deep StructuredUnit named the wrong fault Review: astropy nests to any depth, a `UnitsMatrix` is a vector or a matrix, and anything deeper reached `UnitsMatrix`'s own check and came back as "ragged structure" -- which is not what is wrong with it. Refuse by depth, and say the depth. An empty `StructuredUnit` keeps its existing message, which is already accurate; it is skipped here because it has no first value to recurse into. * πŸ› fix(linalg): an empty unit layout raised a bare StopIteration Review, and reachable: `UnitsMatrix(np.empty(0, dtype=object))` is legal -- its own `__pow__` documents it -- so a `QuantityMatrix` can carry an empty layout, and `_structured_depth` then had no first value to recurse into. The conversion died on a message-less `StopIteration`. Astropy has no counterpart to convert it to either: a structured dtype must have at least one field. So this now says that, before computing a depth. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
main
3 days ago
✨ feat(unitsystems): name the Planck and atomic base units (#875) Closes #868. `astropy.units` has no names for these, so they could only be spelled as a scale times an SI unit -- and `to_string()` truncates past six significant figures, so that spelling neither read well nor reparsed: planck["length"] -> Unit("1.61626e-35 m") # and does *not* reparse planck["length"] -> Unit("l_P") # now Eight units: `l_P`, `m_P`, `t_P`, `T_P` for Planck, and `a_0`, `m_e`, `t_au`, `e` for Hartree atomic. Only these two systems get names -- `hep` and `geometrized` take a free scale, so their bases change with the parameter and no fixed name would be right. Each is defined from the *same constant expression* that already built its unit system rather than a hard-coded number, so the values track whatever CODATA revision `astropy.constants` ships. A test pins that. Three things the naming had to dodge, each verified rather than assumed: - `a0` and `Eh` are **not** free. astropy already parses them as *dimensionless* and as a *time* (`E`Γ—`h`, hour). Hence `a_0`, and no Hartree-energy unit. - A unit named `e` does not disturb scientific notation -- `1e5 m` and `1.5e3 kg` still parse as a scale times a unit. - astropy ignores a `format` string identical to the unit's own name and then escapes the underscore, so `a_0` needed `a_{0}` to render as `$a_{0}$` rather than `$\mathrm{a\_0}$`. Registered with `add_enabled_units` at import, so `unxt.unit("l_P")` resolves and the spelling round-trips. That mutates astropy's registry process-wide; it is the reason this was kept out of #855, and the trade is deliberate. Upstream issue to follow, which would let unxt drop the module entirely. Doctests that hid these values behind `...` no longer need to: a name is stable across CODATA revisions where six significant figures were not. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
main
10 days ago
πŸ“ docs: exclude the dead pre-Diataxis paths from the Sphinx build (#922) `nox -s docs` fails on any machine that built the docs before #909, with a confusing error that names a file the build did not create: WARNING: (broken) guides/perf.html redirects to how-to/optimize-performance.html but .../guides/perf.html already exists! #909 moved `guides/perf.md` to `how-to/optimize-performance.md` and updated both the noxfile's jupytext target and `.gitignore` to the new path. What it could not do is remove the notebook already generated at the old path on developer machines. `.ipynb` is in `source_suffix`, so Sphinx still picks that leftover up as a source document, builds `guides/perf.html` from it, and rediraffe then refuses to write its redirect over the file -- which it reports as broken. Nothing should live under `docs/guides/` any more: the directory is untracked, every path beneath it is a rediraffe redirect target, and rediraffe owns those URLs. Excluding the tree makes a stale artifact unable to shadow a redirect. CI never saw this -- it checks out clean, so the leftover does not exist there -- which is exactly why it is worth fixing in the repo rather than leaving each developer to work out that an untracked file from two releases ago is what broke their build. Verified with `docs/guides/perf.ipynb` deliberately left in place: the build goes from exit 1 to exit 0, `guides/perf.html` is the redirect stub again rather than a rendered notebook, and `how-to/optimize-performance.html` still builds. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
main
10 days ago
πŸ“ docs(dimensions): blank-line the lists in `dimension`'s docstring (#919) Sphinx reported `ERROR: Unexpected indentation` against `unxts.api._src.dimensions.dimension`, twice -- once per entry point (`unxt/dims.py` and `unxt/__init__.py`). The docstring it names is plum's *composed* one, so the reported line lands in the `str` method registered here rather than in the abstract stub. reStructuredText needs a blank line between a paragraph and a list that follows it. Five lists in this docstring had none. Only the "Unsupported Operators" one raised, because it is the only one with a wrapped continuation line for docutils to trip over -- but the error was the smaller half of the problem. Without the blank line docutils folds a list into the preceding paragraph, so *none* of the six lists were being parsed: `publish_doctree` found 0 `bullet_list` and 0 `enumerated_list` nodes, and they rendered as run-together prose. With the blank lines added it finds 5 and 1, and the built HTML carries real `<ul>`/`<ol>` markup. A local `nox -s docs` is clean, with no remaining `Unexpected indentation` anywhere in the build. Note that this error did not fail the docs job. The one red `Docs` run on #917 was the external-link checker taking 504s from github.com on three unrelated URLs, and it passed on re-run. This is a latent rendering bug, not a broken build. A repo-wide scan finds 18 further docstrings with the same paragraph-then-list shape, none of which error but which likely mis-render the same way. Left for a separate pass rather than widened into this one. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
main
10 days ago
πŸ“Œ pin(deps): exclude plum-dispatch 2.10.0 (#917) * πŸ“Œ pin(deps): exclude plum-dispatch 2.10.0 plum 2.10.0 is the first release to ship mypyc-compiled wheels, and `_function.py` is in the compile set. A mypyc *native* class gets neither `__dict__` nor `__weakref__`, so `plum.Function` instances are no longer weak-referenceable. `jax.jit` weakly references the callable it wraps (`jax/_src/pjit.py:_cpp_pjit`), so every `jax.jit(<dispatched function>)` now raises on first call: TypeError: cannot create weak reference to 'Function' object `unxt.uconvert` and `unxt.uconvert_value` are `plum.Function`s, so this is user-facing, not merely a CI break. Reproduced by building v2.10.0 with mypyc locally: 7 failures and 2 errors across `tests/integration/test_uconvert_value_performance.py` and `tests/benchmark/test_uconvert_value.py`, all of them `jax.jit` over a dispatched function. Only cp310-cp313 on manylinux, Windows and macOS x86_64 are affected -- plum publishes no cp314 wheel and no macOS arm64 wheel, so those platforms fall back to `py3-none-any` and are fine. That is why the weekly pre-release job failed on 3.12 and 3.13 but passed on 3.14, and why the break does not reproduce on an arm64 Mac. The exclusion is unconditional anyway: the resolver cannot know which wheel a given install will get. `uv.lock` already pinned 2.9.0, so PR CI never saw this; only the weekly `--upgrade` job did. The lock change here is metadata only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * πŸ“Œ pin(deps): give `unxts.api` the 3.14 plum floor Review follow-up. `unxts.api` is the one package here with no `unxt` dependency, so nothing supplies the root's `plum-dispatch>=2.9.0; python_version>='3.14'` floor transitively. plum declares no upper `requires-python` bound on any release (2.5.7 says `>=3.8`), so a standalone install of `unxts.api` on 3.14 could resolve 2.5.7 -- below the version where plum gained 3.14 support. Spell the floor out here; `uv pip compile --python-version 3.14` now picks 2.9.0. `unxts.linalg` and `unxts.parametric` both depend on `unxt>=2.0.0` and inherit the floor through it, the same way they already inherit its `>=2.7.0` over their own `>=2.5.7`, so they are left alone. Also sharpen the root comment: cp310-cp313 describes plum's wheel range, but `unxt` requires >=3.12, so only 3.12 and 3.13 are actually reachable here. Link the upstream fix as the trigger for removing the exclusion. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
main
11 days ago

Latest Branches

CodSpeed Performance Gauge
-11%
✨ feat: add natural unit systems (Planck, HEP, geometrized, atomic)#768
2 months ago
0080e56
nstarman:claude/unit-systems-plum-d66f71
CodSpeed Performance Gauge
-19%
CodSpeed Performance Gauge
+20%
2 years ago
9d3d51f
nstarman:tests/fix-benchmarks
Β© 2026 CodSpeed Technology
Home Terms Privacy Docs