From 07bbb7acfd301454e74948c33be484967bda8d6d Mon Sep 17 00:00:00 2001 From: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:16:50 -0300 Subject: [PATCH] Fix loading on unsupported platforms (#459) * Gate getpagesize call behind function * Make `functional` require a fully-supported GPU --- lib/mtl/buffer.jl | 13 ++++++++++--- src/initialization.jl | 20 +++++++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/mtl/buffer.jl b/lib/mtl/buffer.jl index bf0b8d637..d9de6d9b3 100644 --- a/lib/mtl/buffer.jl +++ b/lib/mtl/buffer.jl @@ -49,16 +49,23 @@ function MTLBuffer(dev::MTLDevice, bytesize::Integer, ptr::Ptr; return MTLBuffer(ptr) end -const PAGESIZE = ccall(:getpagesize, Cint, ()) +const _page_size::Ref{Int} = Ref{Int}(0) +function page_size() + if _page_size[] == 0 + _page_size[] = Int(ccall(:getpagesize, Cint, ())) + end + _page_size[] +end + function can_alloc_nocopy(ptr::Ptr, bytesize::Integer) # newBufferWithBytesNoCopy has several restrictions: ## the pointer has to be page-aligned - if Int64(ptr) % PAGESIZE != 0 + if Int(ptr) % page_size() != 0 return false end ## the new buffer needs to be page-aligned ## XXX: on macOS 14, this doesn't seem required; is this a documentation issue? - if bytesize % PAGESIZE != 0 + if bytesize % page_size() != 0 return false end return true diff --git a/src/initialization.jl b/src/initialization.jl index 7a6d270b2..6e621a189 100644 --- a/src/initialization.jl +++ b/src/initialization.jl @@ -1,5 +1,16 @@ -const _functional = Ref{Bool}(false) -functional() = _functional[] +# Starts at `nothing`. Only false when it's determined +const _functional = Ref{Union{Nothing,Bool}}(false) + +function functional() + if isnothing(_functional[]) + dev = device() + + _functional[] = + supports_family(dev, MTL.MTLGPUFamilyApple7) && + supports_family(dev, MTL.MTLGPUFamilyMetal3) + end + _functional[] +end function __init__() precompiling = ccall(:jl_generating_output, Cint, ()) != 0 @@ -39,7 +50,10 @@ function __init__() load_framework("CoreGraphics") ver = MTL.MTLCompileOptions().languageVersion @debug "Successfully loaded Metal; targeting v$ver." - _functional[] = true + + # Successful loading of CoreGraphics means there's a + # chance the graphics device is supported + _functional[] = nothing catch err @error "Failed to load Metal" exception=(err,catch_backtrace()) return