diff --git a/ggml-metal.h b/ggml-metal.h index be2731f..de46b88 100644 --- a/ggml-metal.h +++ b/ggml-metal.h @@ -52,6 +52,11 @@ void ggml_metal_free(struct ggml_metal_context * ctx); void * ggml_metal_host_malloc(size_t n); void ggml_metal_host_free (void * data); +// helper to check if the device supports a specific family +// ideally, the user code should be doing these checks +// ref: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf +bool ggml_metal_supports_family(struct ggml_metal_context * ctx, int family); + // set the number of command buffers to use void ggml_metal_set_n_cb(struct ggml_metal_context * ctx, int n_cb); @@ -100,6 +105,8 @@ GGML_API bool ggml_backend_is_metal(ggml_backend_t backend); GGML_API void ggml_backend_metal_set_n_cb(ggml_backend_t backend, int n_cb); +GGML_API bool ggml_backend_metal_supports_family(ggml_backend_t backend, int family); + #ifdef __cplusplus } #endif diff --git a/ggml-metal.m b/ggml-metal.m index 3591b87..51382ad 100644 --- a/ggml-metal.m +++ b/ggml-metal.m @@ -459,6 +459,10 @@ void ggml_metal_host_free(void * data) { free(data); } +bool ggml_metal_supports_family(struct ggml_metal_context * ctx, int family) { + return [ctx->device supportsFamily:(MTLGPUFamilyApple1 + family - 1)]; +} + void ggml_metal_set_n_cb(struct ggml_metal_context * ctx, int n_cb) { ctx->n_cb = MIN(n_cb, GGML_METAL_MAX_BUFFERS); } @@ -1751,3 +1755,9 @@ void ggml_backend_metal_set_n_cb(ggml_backend_t backend, int n_cb) { ggml_metal_set_n_cb(ctx, n_cb); } + +bool ggml_backend_metal_supports_family(ggml_backend_t backend, int family) { + struct ggml_metal_context * ctx = (struct ggml_metal_context *)backend->context; + + return ggml_metal_supports_family(ctx, family); +} diff --git a/whisper.cpp b/whisper.cpp index e2bb1bb..971b8e6 100644 --- a/whisper.cpp +++ b/whisper.cpp @@ -1078,6 +1078,11 @@ static ggml_backend_t whisper_backend_init(const whisper_context_params & params if (!backend_gpu) { WHISPER_LOG_ERROR("%s: ggml_backend_metal_init() failed\n", __func__); } + if (!ggml_backend_metal_supports_family(backend_gpu, 7)) { + WHISPER_LOG_ERROR("%s: Metal GPU does not support family 7 - falling back to CPU\n", __func__); + ggml_backend_free(backend_gpu); + backend_gpu = NULL; + } } #endif