Skip to content

Pass axis as a Python int in the MLX sort/argsort dispatches - #2400

Open
guillaume-osmo wants to merge 2 commits into
pymc-devs:mainfrom
guillaume-osmo:fix-mlx-sort-axis
Open

Pass axis as a Python int in the MLX sort/argsort dispatches#2400
guillaume-osmo wants to merge 2 commits into
pymc-devs:mainfrom
guillaume-osmo:fix-mlx-sort-axis

Conversation

@guillaume-osmo

Copy link
Copy Markdown

Closes #2391.

Stacked on #2395axis=None flattens through Reshape, so it needs that fix too. Review that one first; this diff will shrink once it merges.

Motivation

mlx_funcify_Sort and mlx_funcify_ArgSort forwarded the axis input straight to mx.sort / mx.argsort, but the linker typifies every input to mx.array and both require a Python int, so nothing on this backend sorted at all. Same root cause as #2386.

All five tests in tests/link/mlx/test_sort.py were already red on main.

Found while fixing #2385: the gradient of a batched solve reaches argsort through the pivot-to-permutation step.

Implementation

Coerce axis with int(...). Unlike the shape in #2386, axis is a scalar and always static, so no funcify-time resolution is needed.

Tests

The five existing tests pass now. Added test_sort_axis_variants, covering positive, negative and None axes for both sort and argsort on a 3-d input.

Full tests/link/mlx/ suite: no regressions.

`mlx_funcify_Reshape` forwarded the shape input straight to `mx.reshape`,
but the linker typifies every input to `mx.array` while `mx.reshape` only
accepts a Python sequence of ints, so every reshape raised `TypeError`.

Reading the array back at runtime is not an option either: the linker
enables `mx.compile` by default and MLX forbids evaluating a traced array,
so the shape has to be resolved when the dispatch is built. Prefer the
statically inferred output shape (which already resolves any `-1`, and
covers shapes read off another input such as `x.reshape(y.shape)`), then
fall back to a constant shape input. A genuinely data-dependent shape now
raises `NotImplementedError` with an explanation instead of an eval error
from deep inside MLX.

This turns four already-red tests in `tests/link/mlx/test_shape.py` green
and adds regression tests under the full "MLX" mode.
`mlx_funcify_Sort` and `mlx_funcify_ArgSort` forwarded the `axis` input
straight to `mx.sort` / `mx.argsort`, but the linker typifies every input to
`mx.array` and both functions require a Python int, so nothing on this
backend sorted at all -- every call raised `TypeError`. Same root cause as
the `Reshape` dispatch (pymc-devs#2386), which `axis=None` also goes through, since
it flattens first.

All five tests in `tests/link/mlx/test_sort.py` were already red on main;
they pass now, and a parametrized test covers positive, negative and `None`
axes on a 3-d input.

Found while fixing pymc-devs#2385: the gradient of a batched `solve` reaches
`argsort` through the pivot-to-permutation step.
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.

MLX backend: sort and argsort always raise TypeError (axis passed as mx.array)

1 participant