Skip to content

Commit b53be27

Browse files
committed
GPU: check that the toolchain can compile MSL 4.1 before enabling Metal
The Metal frameworks are present on every macOS, so finding them said nothing about whether the backend can be built. It needs MSL 4.1, which arrives with macOS 27 and its toolchain, and a library compiled as MSL 4.1 only loads on macOS 27 and later. The deployment target has no say in this: the -std= flag is what picks the target OS, and MACOSX_DEPLOYMENT_TARGET and -mmacosx-version-min are both ignored by the Metal compiler. Compiling a three-line kernel answers the question directly. AUTO now turns Metal off on an older toolchain instead of failing somewhere in the middle of the build, and an explicit ENABLE_METAL=ON says why it cannot be honoured.
1 parent da3986b commit b53be27

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

‎dependencies/FindO2GPU.cmake‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# or submit itself to any jurisdiction.
1111

1212
# NOTE!!!! - Whenever this file is changed, move it over to alidist/resources
13-
# FindO2GPU.cmake Version 20
13+
# FindO2GPU.cmake Version 21
1414

1515
set(CUDA_COMPUTETARGET_DEFAULT_FULL 80-real;86-real;89-real;120-real;75-virtual)
1616
set(HIP_AMDGPUTARGET_DEFAULT_FULL gfx906;gfx908)
@@ -450,12 +450,29 @@ if(ENABLE_METAL)
450450
find_library(COREFOUNDATION_FRAMEWORK CoreFoundation)
451451
find_library(FOUNDATION_FRAMEWORK Foundation)
452452
find_library(QUARTZCORE_FRAMEWORK QuartzCore)
453-
if(METAL_FRAMEWORK AND COREFOUNDATION_FRAMEWORK AND FOUNDATION_FRAMEWORK AND QUARTZCORE_FRAMEWORK)
453+
# The frameworks are there on every macOS, but the backend needs MSL 4.1, which
454+
# is macOS 27 and its toolchain, so ask the compiler instead of assuming. A
455+
# library built as MSL 4.1 also only loads on macOS 27 and later.
456+
if(NOT DEFINED GPUCA_METAL_MSL41)
457+
set(GPUCA_METAL_PROBE "${CMAKE_CURRENT_BINARY_DIR}/metal_msl41_probe.metal")
458+
file(WRITE "${GPUCA_METAL_PROBE}" "#include <metal_stdlib>\nkernel void probe(device float* o [[buffer(0)]], uint i [[thread_position_in_grid]]) { o[i] = o[i] * 2.0f; }\n")
459+
execute_process(COMMAND xcrun -sdk macosx metal -std=metal4.1 -c "${GPUCA_METAL_PROBE}" -o "${GPUCA_METAL_PROBE}.air"
460+
RESULT_VARIABLE GPUCA_METAL_PROBE_RESULT OUTPUT_QUIET ERROR_QUIET)
461+
if(GPUCA_METAL_PROBE_RESULT EQUAL 0)
462+
set(GPUCA_METAL_MSL41 ON CACHE INTERNAL "Metal toolchain compiles MSL 4.1")
463+
else()
464+
set(GPUCA_METAL_MSL41 OFF CACHE INTERNAL "Metal toolchain compiles MSL 4.1")
465+
endif()
466+
endif()
467+
if(METAL_FRAMEWORK AND COREFOUNDATION_FRAMEWORK AND FOUNDATION_FRAMEWORK AND QUARTZCORE_FRAMEWORK AND GPUCA_METAL_MSL41)
454468
set(METAL_ENABLED ON)
455469
set(METAL_FRAMEWORKS ${METAL_FRAMEWORK} ${COREFOUNDATION_FRAMEWORK}
456470
${FOUNDATION_FRAMEWORK} ${QUARTZCORE_FRAMEWORK})
457471
message(STATUS "Found Metal frameworks")
458472
elseif(NOT ENABLE_METAL STREQUAL "AUTO")
473+
if(NOT GPUCA_METAL_MSL41)
474+
message(FATAL_ERROR "The Metal backend needs MSL 4.1: this toolchain rejects -std=metal4.1, and the result would need macOS 27 to run")
475+
endif()
459476
message(FATAL_ERROR "Metal frameworks not available")
460477
else()
461478
set(METAL_ENABLED OFF)

0 commit comments

Comments
 (0)