From 3dee5bca428d5334ecff9b31a40cb127b06858b7 Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Thu, 6 Nov 2025 13:27:37 -0500 Subject: [PATCH 1/9] Add MacOS GPU runner to CI --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13eabef2..90dbb870 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,12 @@ permissions: jobs: test: - runs-on: github-gpu + strategy: + matrix: + include: + - machine: github-gpu + - machine: macos-15-xlarge + runs-on: ${{ matrix.machine }} steps: - uses: actions/checkout@v4 From 1a06b56444019b6be6fd70392e0ccfa7344e769e Mon Sep 17 00:00:00 2001 From: "Ehsan M. Kermani" Date: Thu, 6 Nov 2025 11:02:57 -0800 Subject: [PATCH 2/9] Try with latest --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90dbb870..f1144754 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: matrix: include: - machine: github-gpu - - machine: macos-15-xlarge + - machine: macos-latest-xlarge runs-on: ${{ matrix.machine }} steps: - uses: actions/checkout@v4 From fd31c17e793f3e03cf9940686af229eb9c4664bb Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 7 Nov 2025 15:00:57 +0000 Subject: [PATCH 3/9] Switch test runner OS check from OSTYPE to uname for Mac CI The run.sh script used the $OSTYPE environment variable to determine whether the host system is Apple. This environment variable is available in bash, so might not be a guarantee - and is potentially why CI is failing on Mac in this branch. Using uname -s is likely a more robust check locally and in CI. --- solutions/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/run.sh b/solutions/run.sh index 8480e54d..040b416c 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -57,7 +57,7 @@ detect_gpu_platform() { fi # Check for Apple Silicon (macOS) - if [[ "$OSTYPE" == "darwin"* ]]; then + if [[ "$(uname -s)" == "Darwin"* ]]; then if system_profiler SPDisplaysDataType 2>/dev/null | grep -q "Apple"; then echo "apple" return From 79fb651a9b629bff62ff63c8ca6e49090d08599b Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 7 Nov 2025 16:29:50 +0000 Subject: [PATCH 4/9] Properly identify apple silicon host Replace use of system_profiler for identification with another call to uname. It may be that SPDisplaysDataType does not function as expected on the virtualised github mac runners. Also we are properly ensuring the host is an arm mac this way. --- solutions/run.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/run.sh b/solutions/run.sh index 040b416c..2b1cab79 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -57,12 +57,12 @@ detect_gpu_platform() { fi # Check for Apple Silicon (macOS) - if [[ "$(uname -s)" == "Darwin"* ]]; then - if system_profiler SPDisplaysDataType 2>/dev/null | grep -q "Apple"; then + if [[ "$(uname -s)" == "Darwin" ]]; then + if [[ "$(uname -m)" == "arm64" ]]; then echo "apple" return fi - fi + fi echo "unknown" } From c72c9b310313bc310802eee55eecc55030188803 Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 10 Nov 2025 15:51:10 +0000 Subject: [PATCH 5/9] Temporarily collect debug info for mac A temporary mechanism to collect some information about the hardware from system_profiler to see if anything reports unusually. I think these CI runners do something a little differently. --- solutions/run.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/solutions/run.sh b/solutions/run.sh index 2b1cab79..7b330d66 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -534,6 +534,15 @@ print_startup_banner() { local compute_cap=$(detect_gpu_compute_capability) local gpu_name="" + # TEMPORARY Debugging MacOS CI issue + local mac_displays_info=$(system_profiler SPDisplaysDataType) + local mac_hardware_info=$(system_profiler SPHardwareDataType) + echo -e "Debug info about Mac displays:" + echo -e "$mac_displays_info" + echo -e "Debug info about Mac hardware:" + echo -e "$mac_hardware_info" + # End + echo -e "${BOLD}GPU Information:${NC}" echo -e " ${BULLET} Platform: ${CYAN}$(echo "$gpu_platform" | tr '[:lower:]' '[:upper:]')${NC}" From 523f0d56ebd947a3751c47c2e937337154f7c82b Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 10 Nov 2025 16:05:33 +0000 Subject: [PATCH 6/9] Mac GPU debug info from Swift Trying a little in-line Swift to gather information about the GPU since it's clear from system_profiler that the CPU appears with a different designation thanks to being virtualised. Perhaps the GPU does too, and therefore is not recognised properly by info.mojo Using Swift since system_profiler SPDisplaysDataType doesn't seem to work for headless machines. --- solutions/run.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/solutions/run.sh b/solutions/run.sh index 7b330d66..6517e49e 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -541,6 +541,21 @@ print_startup_banner() { echo -e "$mac_displays_info" echo -e "Debug info about Mac hardware:" echo -e "$mac_hardware_info" + echo -e "Debug info from Swift:" + swift - <<'EOF' +import Metal +guard let device = MTLCreateSystemDefaultDevice() else { + print("Error: Could not find Metal device.") + exit(1) +} +print("Name: \(device.name)") +print("Is Headless: \(device.isHeadless)") +print("Supports Raytracing: \(device.supportsRaytracing)") +print("Supports Dynamic Libraries: \(device.supportsDynamicLibraries)") +print("Supports 32-bit float atomics: \(device.supports32BitFloatAtomics)") +print("Max Buffer (GB): \(String(format: "%.2f", Double(device.maxBufferLength) / 1.0e9))") +print("Recommended Max VRAM (GB): \(String(format: "%.2f", Double(device.recommendedMaxWorkingSetSize) / 1.0e9))") +EOF # End echo -e "${BOLD}GPU Information:${NC}" From 03823d2c6e432c7de048fff75432a2916da8e77a Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 10 Nov 2025 16:23:39 +0000 Subject: [PATCH 7/9] Moved swift debug code to standalone script and fixed error Fixed the capabilities being requested and moved the swift code to a temporary standalone script file to make things easier. --- scripts/debug_mac_gpu.swift | 11 +++++++++++ solutions/run.sh | 17 +++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 scripts/debug_mac_gpu.swift diff --git a/scripts/debug_mac_gpu.swift b/scripts/debug_mac_gpu.swift new file mode 100644 index 00000000..24ba3915 --- /dev/null +++ b/scripts/debug_mac_gpu.swift @@ -0,0 +1,11 @@ +import Metal +guard let device = MTLCreateSystemDefaultDevice() else { + print("Error: Could not find Metal device.") + exit(1) +} +print("Name: \(device.name)") +print("Is Headless: \(device.isHeadless)") +print("Supports Raytracing: \(device.supportsRaytracing)") +print("Supports Dynamic Libraries: \(device.supportsDynamicLibraries)") +print("Max Buffer (GB): \(String(format: "%.2f", Double(device.maxBufferLength) / 1.0e9))") +print("Recommended Max VRAM (GB): \(String(format: "%.2f", Double(device.recommendedMaxWorkingSetSize) / 1.0e9))") \ No newline at end of file diff --git a/solutions/run.sh b/solutions/run.sh index 6517e49e..d00dc0d0 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -537,25 +537,14 @@ print_startup_banner() { # TEMPORARY Debugging MacOS CI issue local mac_displays_info=$(system_profiler SPDisplaysDataType) local mac_hardware_info=$(system_profiler SPHardwareDataType) + local mac_swift_debug=$(swift scripts/debug_mac_gpu.swift) echo -e "Debug info about Mac displays:" echo -e "$mac_displays_info" echo -e "Debug info about Mac hardware:" echo -e "$mac_hardware_info" echo -e "Debug info from Swift:" - swift - <<'EOF' -import Metal -guard let device = MTLCreateSystemDefaultDevice() else { - print("Error: Could not find Metal device.") - exit(1) -} -print("Name: \(device.name)") -print("Is Headless: \(device.isHeadless)") -print("Supports Raytracing: \(device.supportsRaytracing)") -print("Supports Dynamic Libraries: \(device.supportsDynamicLibraries)") -print("Supports 32-bit float atomics: \(device.supports32BitFloatAtomics)") -print("Max Buffer (GB): \(String(format: "%.2f", Double(device.maxBufferLength) / 1.0e9))") -print("Recommended Max VRAM (GB): \(String(format: "%.2f", Double(device.recommendedMaxWorkingSetSize) / 1.0e9))") -EOF + echo -e "$mac_swift_debug" + # End echo -e "${BOLD}GPU Information:${NC}" From 038cda94c803fcf94328fdfbcabb0fdd0e7869b5 Mon Sep 17 00:00:00 2001 From: aaron Date: Mon, 10 Nov 2025 16:29:22 +0000 Subject: [PATCH 8/9] Fixed path for swift script --- solutions/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/run.sh b/solutions/run.sh index d00dc0d0..bc6dfa2b 100644 --- a/solutions/run.sh +++ b/solutions/run.sh @@ -537,7 +537,7 @@ print_startup_banner() { # TEMPORARY Debugging MacOS CI issue local mac_displays_info=$(system_profiler SPDisplaysDataType) local mac_hardware_info=$(system_profiler SPHardwareDataType) - local mac_swift_debug=$(swift scripts/debug_mac_gpu.swift) + local mac_swift_debug=$(swift ../scripts/debug_mac_gpu.swift) echo -e "Debug info about Mac displays:" echo -e "$mac_displays_info" echo -e "Debug info about Mac hardware:" From f563a8f9f5b1d9a6616149abdb03c5c129f260c3 Mon Sep 17 00:00:00 2001 From: aaron Date: Thu, 13 Nov 2025 10:42:09 +0000 Subject: [PATCH 9/9] Querying MPS capabilities in Swift debug script GitHub's large runner documentation says that MPS isn't available on the Mac large runners thanks to complications in Apple's Virtualization Framework, lets just be sure. --- scripts/debug_mac_gpu.swift | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/scripts/debug_mac_gpu.swift b/scripts/debug_mac_gpu.swift index 24ba3915..b09ded89 100644 --- a/scripts/debug_mac_gpu.swift +++ b/scripts/debug_mac_gpu.swift @@ -1,4 +1,6 @@ import Metal +import MetalPerformanceShaders + guard let device = MTLCreateSystemDefaultDevice() else { print("Error: Could not find Metal device.") exit(1) @@ -8,4 +10,30 @@ print("Is Headless: \(device.isHeadless)") print("Supports Raytracing: \(device.supportsRaytracing)") print("Supports Dynamic Libraries: \(device.supportsDynamicLibraries)") print("Max Buffer (GB): \(String(format: "%.2f", Double(device.maxBufferLength) / 1.0e9))") -print("Recommended Max VRAM (GB): \(String(format: "%.2f", Double(device.recommendedMaxWorkingSetSize) / 1.0e9))") \ No newline at end of file +print("Recommended Max VRAM (GB): \(String(format: "%.2f", Double(device.recommendedMaxWorkingSetSize) / 1.0e9))") +if device.supportsFamily(.metal3) { + print("Supports Metal 3 features") +} else { + print("Does not support Metal 3 features") +} +if device.supportsFamily(.common3) { + print("Supports Common Family 3 features") +} else { + print("Does not support Common Family 3 features") +} +if device.supportsFamily(.common2) { + print("Supports Common Family 2 features") +} else { + print("Does not support Common Family 2 features") +} +if device.supportsFamily(.common1) { + print("Supports Common Family 1 features") +} else { + print("Does not support Common Family 1 features") +} +if MPSSupportsMTLDevice(device) { + print("Supports Metal Performance Shaders") +} else { + print("Does not support Metal Performance Shaders") +} +