Skip to content

The pre-merge lane compiles no Metal TU: metal_mlx_provider.mm is built only by the tag-triggered release.yml, so a seam refactor breaks it silently until a release is cut #1765

Description

@localai-bot

src/vt/metal/metal_mlx_provider.mm is compiled by nothing that runs before a merge, so a refactor of the vt::OpProvider seam it depends on breaks it silently and the breakage surfaces at release-cut time. #1584 is the first demonstration: its edit to MlxFallback landed unbuilt and unrun, and #1692 records that.

One correction to #1692 first, because it changes what is owed. #1692 states the file is "compiled by NO job in this repository". That is not accurate. .github/workflows/release.yml:347 mlx_arm64 runs on macos-15, pip install 'mlx==0.32.0', and calls scripts/build-macos-release.sh macos-arm64-metal-mlx preview ... "$mlx_root" 0.32.0 ..., which configures -DVLLM_CPP_MLX=ON and compiles the file for real, against real MLX, on real Apple hardware.

The defect is the trigger, not the absence:

on:
  workflow_dispatch: {}
  push:
    tags: ['v*']

release.yml fires on a v* tag or a manual dispatch. It never runs on a pull request and never on a push to main. .github/workflows/ci.yml — the pre-merge lane — has no macOS runner at all: every one of its 20 runs-on lines is ubuntu-latest, ubuntu-24.04-arm or windows-2022. So the only build of this file happens after the change has landed, and only when somebody cuts a release. A broken .mm is discovered as a blocked release rather than as a red check.

What can be done cheaply, and what cannot.

metal_mlx_provider.mm is the one Metal TU that is plain C++ wearing an ObjC++ extension. It contains zero Objective-C constructs: no message send, no @-keyword, no id<...>, no NS/MTL type outside comments. Its two #imports are <Foundation/Foundation.h> and <Metal/Metal.h>, and it uses nothing from either — the Metal handles reach it as void*, because metal_buffers.h and metal_context.h are deliberately plain C++ (metal_context.h:22: "This header is deliberately PLAIN C++ (no Objective-C types)"). The other three (metal_ops.mm, metal_backend.mm, metal_context.mm) carry real ObjC and are not covered by this.

That makes a compile-only bit-rot guard possible on Linux, in the shape this tree already uses twice: vllm_rocm_platform_syntax_check (CMakeLists.txt:1665, an OBJECT library that is never linked, whose comment states this exact argument) and vllm_music3_depth_stage_ab_{before,after} (CMakeLists.txt:2546).

Scope, stated as a limit rather than a claim. Such a target must stub the two Apple framework headers (trivially — nothing is used from them) and the six MLX public headers. It therefore proves that the file compiles against the real vt:: seam headers, and proves nothing about the MLX API, which only mlx_arm64 can. That is the whole defect being closed and no more of it: the #1584 break was a change to our header, not to MLX.

Owed after such a change, and not discharged by it: the CUDA and Metal runtime arms of #1692 (a GPU and a Mac), and the MLX API surface (release-time only).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions