From 77f4bf49c8ab90d45a83185d5f7d364e2507c96f Mon Sep 17 00:00:00 2001 From: Georgi Gerganov Date: Wed, 13 Sep 2023 13:34:51 +0300 Subject: [PATCH] cmake : update to support Metal build --- CMakeLists.txt | 64 +++++++++++++++++++++++++++++++++++++++++++------- ggml-metal.m | 4 ++-- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bfd14b9..8b800e07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.0) +cmake_minimum_required (VERSION 3.5) project(whisper.cpp VERSION 1.4.2) @@ -35,6 +35,12 @@ endif() # options +if (APPLE) + set(WHISPER_METAL_DEFAULT ON) +else() + set(WHISPER_METAL_DEFAULT OFF) +endif() + option(BUILD_SHARED_LIBS "whisper: build shared libs" ${BUILD_SHARED_LIBS_DEFAULT}) option(WHISPER_ALL_WARNINGS "whisper: enable all compiler warnings" ON) @@ -58,6 +64,8 @@ option(WHISPER_OPENVINO "whisper: support for OpenVINO" OFF) if (APPLE) option(WHISPER_NO_ACCELERATE "whisper: disable Accelerate framework" OFF) + option(WHISPER_METAL "whisper: use Metal" ${WHISPER_METAL_DEFAULT}) + option(WHISPER_METAL_NDEBUG "whisper: disable Metal debugging" OFF) option(WHISPER_COREML "whisper: enable Core ML framework" OFF) option(WHISPER_COREML_ALLOW_FALLBACK "whisper: allow non-CoreML fallback" OFF) else() @@ -113,6 +121,34 @@ if (APPLE) endif() endif() + if (WHISPER_METAL) + find_library(FOUNDATION_LIBRARY Foundation REQUIRED) + find_library(METAL_FRAMEWORK Metal REQUIRED) + find_library(METALKIT_FRAMEWORK MetalKit REQUIRED) + + if (METAL_FRAMEWORK) + message(STATUS "Metal framework found") + + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} + ${FOUNDATION_LIBRARY} + ${METAL_FRAMEWORK} + ${METALKIT_FRAMEWORK} + ) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_METAL) + + if (WHISPER_METAL_NDEBUG) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_METAL_NDEBUG) + endif() + else() + message(WARNING "Metal framework not found") + endif() + + set(GGML_SOURCES_METAL ggml-metal.m ggml-metal.h) + + # copy ggml-metal.metal to bin directory + configure_file(ggml-metal.metal bin/ggml-metal.metal COPYONLY) + endif() + if (WHISPER_COREML) find_library(FOUNDATION_FRAMEWORK Foundation) find_library(COREML_FRAMEWORK CoreML) @@ -177,7 +213,7 @@ if (WHISPER_CUBLAS) enable_language(CUDA) - set(GGML_CUDA_SOURCES ggml-cuda.cu ggml-cuda.h) + set(GGML_SOURCES_CUDA ggml-cuda.cu ggml-cuda.h) add_compile_definitions(GGML_USE_CUBLAS) @@ -228,7 +264,7 @@ if (WHISPER_CLBLAST) if (CLBlast_FOUND) message(STATUS "CLBlast found") - set(GGML_OPENCL_SOURCES ggml-opencl.cpp ggml-opencl.h) + set(GGML_SOURCES_OPENCL ggml-opencl.cpp ggml-opencl.h) add_compile_definitions(GGML_USE_CLBLAST) @@ -428,8 +464,9 @@ add_library(${TARGET} ggml.c ggml-alloc.h ggml-alloc.c - ${GGML_CUDA_SOURCES} - ${GGML_OPENCL_SOURCES} + ${GGML_SOURCES_METAL} + ${GGML_SOURCES_CUDA} + ${GGML_SOURCES_OPENCL} whisper.h whisper.cpp ) @@ -470,9 +507,15 @@ if (BUILD_SHARED_LIBS) WHISPER_BUILD GGML_BUILD ) + + if (WHISPER_METAL) + # TODO: I think this should make ggml-metal.m "see" the ggml-metal.metal file from the "bin" directory + # but for some reason it does not work here like it does in llama.cpp + set_target_properties(${TARGET} PROPERTIES RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/ggml-metal.metal") + endif() endif() -if (GGML_CUDA_SOURCES) +if (GGML_SOURCES_CUDA) message(STATUS "GGML CUDA sources found, configuring CUDA architecture") set_property(TARGET whisper PROPERTY CUDA_ARCHITECTURES OFF) set_property(TARGET whisper PROPERTY CUDA_SELECT_NVCC_ARCH_FLAGS "Auto") @@ -488,10 +531,13 @@ target_compile_definitions(${TARGET} PUBLIC set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "whisper.h") +include(GNUInstallDirs) + install(TARGETS ${TARGET} - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib/static - RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib/static + RUNTIME DESTINATION bin + RESOURCE DESTINATION bin PUBLIC_HEADER DESTINATION include ) diff --git a/ggml-metal.m b/ggml-metal.m index b21564db..a810e5c5 100644 --- a/ggml-metal.m +++ b/ggml-metal.m @@ -140,7 +140,7 @@ struct ggml_metal_context * ggml_metal_init(int n_cb) { ctx->n_buffers = 0; ctx->concur_list_len = 0; - ctx->d_queue = dispatch_queue_create("llama.cpp", DISPATCH_QUEUE_CONCURRENT); + ctx->d_queue = dispatch_queue_create("ggml-metal", DISPATCH_QUEUE_CONCURRENT); #if 0 // compile from source string and show compile log @@ -162,7 +162,7 @@ struct ggml_metal_context * ggml_metal_init(int n_cb) { //NSString * path = [[NSBundle mainBundle] pathForResource:@"../../examples/metal/metal" ofType:@"metal"]; NSBundle * bundle = [NSBundle bundleForClass:[GGMLMetalClass class]]; - NSString * path = [bundle pathForResource:@"ggml-metal" ofType:@"metal"]; + NSString * path = [bundle pathForResource:@"ggml-metal" ofType:@"metal"]; metal_printf("%s: loading '%s'\n", __func__, [path UTF8String]); NSString * src = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];