Skip to content

fix(metal): METAL=1 could not build on a stock macOS - #807

Open
ThefloorMiner wants to merge 1 commit into
JustVugg:devfrom
ThefloorMiner:fix/metal-builds-without-libomp
Open

fix(metal): METAL=1 could not build on a stock macOS#807
ThefloorMiner wants to merge 1 commit into
JustVugg:devfrom
ThefloorMiner:fix/metal-builds-without-libomp

Conversation

@ThefloorMiner

Copy link
Copy Markdown

make colibri METAL=1 fails on any macOS that does not have Homebrew libomp installed:

colibri.c:81:10: fatal error: 'omp.h' file not found
   81 | #include <omp.h>

The Makefile treats the no-libomp case as supported β€” it warns and carries on:

Makefile:53: libomp not found: building single-threaded. For multithreading: brew install libomp

and colibri.c has the matching fallback. The Metal backend just does not reach it.

Two gaps, both in that fallback

1. #include <omp.h> inside the COLI_METAL block, eleven lines after the guarded include that exists for exactly this reason:

#ifdef _OPENMP
#include <omp.h>
#else
static inline int omp_get_max_threads(void){ return 1; }
static inline int omp_get_thread_num(void){ return 0; }
#endif

The second, unguarded include defeats it. Removed β€” the guarded one already covers the Metal path.

2. The shim is incomplete. With the include gone the build gets further and then fails on omp_in_parallel(), called from the Metal GEMM gate:

if(g_metal_enabled && S>=g_metal_gemm_min && ... && !omp_in_parallel()){

The engine calls four omp_* functions; the shim covered two. It now covers omp_in_parallel (no runtime β†’ never inside a team) and omp_set_num_threads (no-op).

This is why it went unnoticed. The CPU build happens never to reach omp_in_parallel, so the fallback looked complete on every platform that exercised it. METAL=1 is the only configuration that reaches it, and Metal is macOS-only β€” the one platform where Apple clang ships no OpenMP runtime.

Verified

On an Apple M3 Ultra, 512 GB unified, macOS with Command Line Tools only and no Homebrew β€” i.e. the failing configuration:

  • make colibri METAL=1 β†’ binary produced, was a hard error before
  • the plain CPU build still compiles on the same host, unchanged
  • both shims are unreachable when _OPENMP is defined, so a Homebrew-libomp build is byte-identical

Not covered

I have not yet run inference with this binary β€” the model is being staged onto that host now. This PR is the build fix only; if the Metal path has runtime problems on a machine this size I will report those separately rather than fold them in here.

Worth flagging why I was building there at all: the benchmark table's largest Apple entry is a 128 GB M5 Max. On 512 GB of unified memory GLM-5.2's 429 GB is fully resident with no tiering at all, which is a regime the engine has never been measured in. I will post numbers once it runs.

`make colibri METAL=1` fails on any macOS without Homebrew libomp:

    colibri.c:81:10: fatal error: 'omp.h' file not found

Two independent gaps, both in the OpenMP fallback the file already has.

1. The COLI_METAL block included <omp.h> unconditionally, eleven lines
   after the guarded include that exists precisely so a build without an
   OpenMP runtime works:

       #ifdef _OPENMP
       #include <omp.h>
       #else
       static inline int omp_get_max_threads(void){ return 1; }
       static inline int omp_get_thread_num(void){ return 0; }
       #endif

   The second include defeats it. Removed; the guarded one covers Metal.

2. With that gone the build gets further and then fails on
   omp_in_parallel(), called from the Metal GEMM gate. The shim covers
   omp_get_max_threads and omp_get_thread_num only. It now also covers
   omp_in_parallel (no runtime -> never inside a team) and
   omp_set_num_threads (no-op).

   This is why the gap went unnoticed: the CPU build happens not to reach
   omp_in_parallel, so the fallback looked complete. Only METAL=1 does.

The Makefile advertises this path -- "libomp not found: building
single-threaded. For multithreading: brew install libomp" -- so the
single-threaded build is supported, not accidental. It just did not work
for the one backend that is macOS-only.

Verified on an Apple M3 Ultra (512 GB, macOS, Command Line Tools only, no
Homebrew): `make colibri METAL=1` now produces a binary. Also rechecked
that the plain CPU build still compiles unchanged on the same host, and
that neither shim is reachable when _OPENMP is defined.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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