Skip to content

Warn at configure time when NAX kernels are disabled - #3824

Merged
zcbenz merged 1 commit into
ml-explore:mainfrom
pierre427:warn-when-nax-disabled
Jul 10, 2026
Merged

zcbenz merged 1 commit into
ml-explore:mainfrom
pierre427:warn-when-nax-disabled

Conversation

@pierre427

Copy link
Copy Markdown
Contributor

Fixes #3821.

What

Add a message(WARNING) in the else() branch of the NAX-kernel gate in
mlx/backend/metal/kernels/CMakeLists.txt, so a build that silently drops the
M-series Neural-Accelerator (NAX) kernels says so — and prints the two inputs
that decided it:

  else()
    message(
      WARNING "NAX kernels require Metal 4, macOS SDK >= 26.2, and "
              "MACOSX_DEPLOYMENT_TARGET >= 26.2 (SDK ${MACOS_SDK_VERSION}, "
              "CMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}). "
              "Building without NAX kernels.")
    target_compile_definitions(mlx PRIVATE MLX_METAL_NO_NAX)
  endif()

Why

The NAX gate (added in #3622) requires Metal 4, macOS SDK ≥ 26.2, and
CMAKE_OSX_DEPLOYMENT_TARGET ≥ 26.2. CMake takes the deployment target from the
MACOSX_DEPLOYMENT_TARGET environment variable when the Python build toolchain
exports one (with it unset, the top-level CMakeLists falls back to the host OS
version). Any target in [14.0, 26.2) configures fine but silently compiles
without NAX — that is exactly how we hit it: a build with target 26.0 lost the
NAX kernels with no indication, costing ≈3–4× on prefill-dominated workloads
(NAX covers GEMM / quantized-matmul / attention) and a debugging session that
initially looked like an upstream performance regression. A configure-time
warning turns that silent cliff into a one-line diagnosis; printing the actual
SDK and deployment-target values makes it self-explanatory.

Notes on scope

  • The warning fires on the condition (the gate evaluated false → NAX is
    being dropped), not on any inference about why the target is set the way it
    is. zcbenz noted on the issue he wasn't sure there is a reliable way to detect
    whether the target came from the Python toolchain vs. elsewhere — this change
    sidesteps that question entirely: it states the requirement, prints the
    observed values, and makes no claim about intent. Anyone who set the target
    deliberately can read it and move on.
  • It also fires for hosts that cannot build NAX (older SDK / Xcode), where it
    is informational rather than actionable. If that is too chatty, the warning
    could be limited to the actionable case (SDK ≥ 26.2 but target < 26.2) with
    a message(STATUS) otherwise — either shape works; this PR keeps the simple
    form.
  • JIT builds are unaffected (kernels are runtime-compiled and NAX availability
    is a runtime check there); non-macOS builds never enter this file.

+5 lines, cmake-format (v0.6.13, the pre-commit pin) clean, no behavior change
to the build output itself.

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@zcbenz
zcbenz merged commit 4367c73 into ml-explore:main Jul 10, 2026
28 checks passed
@BrewTestBot BrewTestBot mentioned this pull request Aug 18, 2026
1 task done
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.

Source builds silently drop the NAX kernels when MACOSX_DEPLOYMENT_TARGET < 26.2 — no configure-time warning

2 participants