ADR-0422: CLI HIP and Metal Backend Selectors¶
- Status: Accepted
- Date: 2026-05-11
- Deciders: Kilian, Claude (Anthropic)
- Tags:
cli,hip,metal,gpu,fork-local
Context¶
The Metal backend (T8-1b, ADR-0420/ADR-0421) and the HIP backend (ADR-0212 scaffold) are fully wired at the engine level — feature extractors are registered under HAVE_METAL / HAVE_HIP guards and imported into VmafContext via vmaf_metal_import_state / vmaf_hip_import_state. However, the standalone vmaf CLI (core/tools/) lacked the surface flags to activate either backend at runtime:
- No
--no_hip/--hip_deviceflags existed (HIP shipped with engine wiring but no CLI counterparts). - No
--no_metal/--metal_deviceflags existed. --backenddid not accepthipormetalas values.
This meant a user could not select HIP or Metal via the CLI even on a binary built with -Denable_hip=true or (on macOS) with Metal enabled. The gap was discovered during a post-merge audit of the Metal runtime PR (#765).
The fix is symmetric: add the four flag pairs and two --backend values following the established Vulkan/SYCL pattern (X_device >= 0 as the activation trigger; --backend X disables all siblings and defaults device to 0).
Decision¶
Add --no_hip, --hip_device <N>, --no_metal, --metal_device <N> to the CLI argument parser (CLISettings, ARG_* enum, long_opts[], switch cases, usage string), extend --backend to accept hip and metal, and add the corresponding vmaf_hip_state_init / vmaf_metal_state_init blocks to init_gpu_backends() in vmaf.c. Activation follows the Vulkan opt-in model: the device flag must be non-negative (explicitly set) for the backend to engage; --backend hip|metal defaults the device index to 0 and disables all other backends.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
Activate HIP/Metal via --gpumask like CUDA | Consistent with CUDA | gpumask is a CUDA-specific disable bitmask; reusing it for AMD/Apple semantics is confusing and conflicts with the CUDA-disable bit contract | Rejected |
| Auto-activate when built in (no explicit flag required) | Less user friction | Silent GPU use surprises users on multi-backend Linux hosts; breaks the opt-in contract SYCL/Vulkan/HIP already established | Rejected |
Ship only --backend hip|metal, skip per-flag pairs | Smaller diff | Users cannot combine --no_hip --no_metal on a fully-built binary to force CPU; breaks the granular-disable pattern used by CUDA/SYCL/Vulkan | Rejected |
Consequences¶
- Positive: HIP and Metal are now fully CLI-accessible;
--backend hip/--backend metalwork analogously to--backend vulkan;--backend cpunow correctly disables all five GPU backends. - Positive: Test coverage added (
test_backend_hip,test_backend_metal,test_hip_device_explicit,test_metal_device_explicit,test_no_hip_no_metal_flagsincore/test/test_cli_parse.c). - Neutral:
docs/usage/cli.mdupdated; no ffmpeg-patches update required (the patches consumelibvmafC API / public headers, not thevmafCLI tool flags). - Negative: None identified.
References¶
- ADR-0420: Metal backend runtime (T8-1b).
- ADR-0421: Metal first kernel (
motion_v2). - ADR-0212 placeholder: HIP scaffold.
- PR #765: Metal test-link fix + ffmpeg-patch 0012 repair (merged, master
5cb295ec). - User direction: the user requested HIP and Metal CLI parity after the audit revealed both backends were wired at engine level but not exposed via the CLI.