Skip to content

Conversation

@mirsad-presagetech
Copy link

Problem: Metal Compiler Error Messages Corrupt JIT Header Parsing

Unfiltered Output (Before Fix)

When the Metal compiler encounters missing headers, error messages are mixed with valid -H output:

. /path/to/mlx/backend/metal/kernels/steel/gemm/params.h
/tmp/test_error.h:2:10: fatal error: 'nonexistent_header.h' file not found
#include "nonexistent_header.h"
^~~~~~~~~~~~~~~~~~~~~~
. /path/to/mlx/backend/metal/kernels/steel/gemm/gemm_nax.h
.. /path/to/mlx/backend/metal/kernels/steel/gemm/nax.h
... /path/to/mlx/backend/metal/kernels/steel/defines.h
... /path/to/mlx/backend/metal/kernels/steel/gemm/transforms.h
.... /path/to/mlx/backend/metal/kernels/steel/utils.h
... /path/to/mlx/backend/metal/kernels/steel/utils/integral_constant.h
.... /path/to/mlx/backend/metal/kernels/steel/utils/type_traits.h
... /path/to/Xcode.app/.../MetalPerformancePrimitives.framework/Headers/MetalPerformancePrimitives.h
.... /path/to/Xcode.app/.../MetalPerformancePrimitives.framework/Headers/MPPTensorOpsConvolution2d.h
.... /path/to/Xcode.app/.../MetalPerformancePrimitives.framework/Headers/MPPTensorOpsMatMul2d.h
1 error generated.

The script parses this by splitting on whitespace and pairing depth indicators (dots) with paths. Error messages break this pairing, causing headers like params.h to be lost.

Filtered Output (After Fix)

With the fix (grep -E "^.+ /"), only valid header lines are kept:

. /path/to/mlx/backend/metal/kernels/steel/gemm/params.h
. /path/to/mlx/backend/metal/kernels/steel/gemm/gemm_nax.h
.. /path/to/mlx/backend/metal/kernels/steel/gemm/nax.h
... /path/to/mlx/backend/metal/kernels/steel/defines.h
... /path/to/mlx/backend/metal/kernels/steel/gemm/transforms.h
.... /path/to/mlx/backend/metal/kernels/steel/utils.h
... /path/to/mlx/backend/metal/kernels/steel/utils/integral_constant.h
.... /path/to/mlx/backend/metal/kernels/steel/utils/type_traits.h

Result

  • Error messages are filtered out
  • Xcode framework paths are filtered out
  • Valid header ordering is preserved: params.h appears before gemm_nax.h
  • The GEMMParams struct (defined in params.h) is available when gemm_nax.h is processed

The make_compiled_preamble.sh script uses the Metal compiler's -H flag to determine header dependencies for JIT source generation. On macOS 15 SDK, when MetalPerformancePrimitives headers are not available, the compiler outputs error messages to stderr which were incorrectly parsed as header paths. This caused critical headers like params.h (containing GEMMParams struct) to be omitted from the generated JIT source, resulting in runtime Metal compilation errors: "unknown type name 'GEMMParams'" The fix filters the -H output to only keep lines matching the expected format: one or more dots followed by an absolute path. This cleanly removes error messages, warnings, and other unexpected compiler output.
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.

1 participant