Summary
The mlx-metal macOS 26 wheel is built with a 26.2 deployment target (.github/workflows/release.yml: macos-target: '26.2'), but it is tagged macosx_26_0_arm64, so pip installs it on macOS 26.0 and 26.1.
Observed
otool -l mlx/lib/libmlx.dylib | grep -A4 LC_BUILD_VERSION
| mlx-metal 0.32.2 wheel |
minos |
macosx_14_0_arm64 |
14.0 |
macosx_15_0_arm64 |
15.0 |
macosx_26_0_arm64 |
26.2 |
0.32.0's macOS 26 build is also 26.2; 0.31.2's is 26.0.
Why it matters
With a 26.2 target, the __builtin_available(macOS 26.2, ...) in is_nax_available() (mlx/backend/metal/device.cpp) is folded to true. On an M5-class GPU (get_architecture_gen() >= 17) running macOS 26.0 or 26.1, the NAX kernels are therefore selected on an OS that predates them. M1–M4 are unaffected by this check, because the generation test keeps NAX off.
We haven't run this on 26.0/26.1 hardware; judging by #3951, the binary would load and fail at runtime rather than at load.
The platform tag cannot express the requirement: for macOS 11+ pip only generates macosx_N_0 tags, so there is no macosx_26_2 tag to publish under.
Possible fixes
- State in the install docs that the macOS 26 wheel needs macOS 26.2+ (they currently say macOS >= 14.0), with the workaround for 26.0/26.1: update macOS, or install an earlier mlx.
- In the 26.2-target build, check the running OS version for real (not a folded
__builtin_available) before enabling NAX, and fall back below 26.2.
Context
Found while lowering our package's floor to macOS 15; it links the libmlx.dylib from whichever mlx-metal build pip picks. Related: #3821 (why the 26 wheel targets 26.2) and #3951 (a newer-target binary on an older OS).
Summary
The
mlx-metalmacOS 26 wheel is built with a 26.2 deployment target (.github/workflows/release.yml:macos-target: '26.2'), but it is taggedmacosx_26_0_arm64, so pip installs it on macOS 26.0 and 26.1.Observed
otool -l mlx/lib/libmlx.dylib | grep -A4 LC_BUILD_VERSIONmacosx_14_0_arm64macosx_15_0_arm64macosx_26_0_arm640.32.0's macOS 26 build is also 26.2; 0.31.2's is 26.0.
Why it matters
With a 26.2 target, the
__builtin_available(macOS 26.2, ...)inis_nax_available()(mlx/backend/metal/device.cpp) is folded totrue. On an M5-class GPU (get_architecture_gen() >= 17) running macOS 26.0 or 26.1, the NAX kernels are therefore selected on an OS that predates them. M1–M4 are unaffected by this check, because the generation test keeps NAX off.We haven't run this on 26.0/26.1 hardware; judging by #3951, the binary would load and fail at runtime rather than at load.
The platform tag cannot express the requirement: for macOS 11+ pip only generates
macosx_N_0tags, so there is nomacosx_26_2tag to publish under.Possible fixes
__builtin_available) before enabling NAX, and fall back below 26.2.Context
Found while lowering our package's floor to macOS 15; it links the
libmlx.dylibfrom whichevermlx-metalbuild pip picks. Related: #3821 (why the 26 wheel targets 26.2) and #3951 (a newer-target binary on an older OS).