char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
a2878d30d
char/aliceai-t5-moe
1find_library ( FOUNDATION_LIBRARY Foundation REQUIRED ) 2find_library ( METAL_FRAMEWORK Metal REQUIRED ) 3find_library ( METALKIT_FRAMEWORK MetalKit REQUIRED ) 4 5message ( STATUS "Metal framework found" ) 6 7ggml_add_backend_library ( ggml-metal 8ggml-metal.cpp 9ggml-metal-device.m 10ggml-metal-device.cpp 11ggml-metal-common.cpp 12ggml-metal-context.m 13ggml-metal-fusion.cpp 14ggml-metal-ops.cpp 15ggml-metal-tuning.cpp 16) 17 18target_link_libraries ( ggml-metal PRIVATE 19${ FOUNDATION_LIBRARY } 20${ METAL_FRAMEWORK } 21${ METALKIT_FRAMEWORK } 22) 23 24if ( GGML_METAL_NDEBUG) 25add_compile_definitions ( GGML_METAL_NDEBUG ) 26endif () 27 28set ( METALLIB_COMMON " ${ CMAKE_CURRENT_SOURCE_DIR } /../ggml-common.h" ) 29set ( METALLIB_KERNELS_COMMON " ${ CMAKE_CURRENT_SOURCE_DIR } /kernels/common.h" ) 30set ( METALLIB_KERNELS_DEQUANTIZE " ${ CMAKE_CURRENT_SOURCE_DIR } /kernels/dequantize.h" ) 31set ( METALLIB_KERNELS_QUANTIZE " ${ CMAKE_CURRENT_SOURCE_DIR } /kernels/quantize.h" ) 32 33set ( METALLIB_KERNEL_SOURCES 34kernels/fa.metal 35kernels/mul_mv.metal 36kernels/mul_mm.metal 37kernels/quantize.metal 38kernels/softmax.metal 39kernels/norm.metal 40kernels/unary.metal 41kernels/binbcast.metal 42kernels/reduce.metal 43kernels/tri.metal 44kernels/ssm.metal 45kernels/wkv.metal 46kernels/gated_delta_net.metal 47kernels/solve_tri.metal 48kernels/rope.metal 49kernels/conv.metal 50kernels/upscale.metal 51kernels/argsort.metal 52kernels/pool.metal 53kernels/misc.metal 54) 55 56if ( GGML_METAL_EMBED_LIBRARY) 57enable_language ( ASM ) 58 59add_compile_definitions ( GGML_METAL_EMBED_LIBRARY ) 60 61set ( METALLIB_IMPL " ${ CMAKE_CURRENT_SOURCE_DIR } /ggml-metal-impl.h" ) 62 63file ( MAKE_DIRECTORY " ${ CMAKE_CURRENT_BINARY_DIR } /autogenerated" ) 64 65set ( METALLIB_EMBED_ASM_FILES "" ) 66foreach ( src${ METALLIB_KERNEL_SOURCES }) 67get_filename_component ( kind ${ src } NAME_WE ) 68# symbol names must be valid C identifiers ('-' is not allowed) 69string ( REPLACE "-" "_" kind_sym ${ kind }) 70 71set ( SRC " ${ CMAKE_CURRENT_SOURCE_DIR } /kernels/ ${ kind } .metal" ) 72set ( EMBED " ${ CMAKE_CURRENT_BINARY_DIR } /autogenerated/ggml-metal-embed- ${ kind } .metal" ) 73set ( ASM " ${ CMAKE_CURRENT_BINARY_DIR } /autogenerated/ggml-metal-embed- ${ kind } .s" ) 74 75# only prepend headers that this source actually includes 76set ( HEADERS_FOR_SRC ${ METALLIB_KERNELS_COMMON }) 77file ( STRINGS ${ SRC } _has_dequantize REGEX "#include \"dequantize\\.h\"" ) 78file ( STRINGS ${ SRC } _has_quantize REGEX "#include \"quantize\\.h\"" ) 79if ( _has_dequantize) 80list ( APPEND HEADERS_FOR_SRC ${ METALLIB_KERNELS_DEQUANTIZE }) 81endif () 82if ( _has_quantize) 83list ( APPEND HEADERS_FOR_SRC ${ METALLIB_KERNELS_QUANTIZE }) 84endif () 85 86add_custom_command ( 87OUTPUT " ${ ASM } " 88# Step 1: concatenate shared headers + this kernel source 89COMMAND cat ${ HEADERS_FOR_SRC } ${ SRC } > " ${ EMBED } .tmp1" 90# Step 2: remove internal #include and #pragma once 91COMMAND sed -e "/\#include \"common.h\"/d" -e "/\#include \"dequantize.h\"/d" -e "/\#include \"quantize.h\"/d" -e "/\#pragma once/d" < " ${ EMBED } .tmp1" > " ${ EMBED } .tmp2" 92# Step 3: inline ggml-common.h (replacing __embed_ggml-common.h__ sentinel) 93COMMAND sed -e "/__embed_ggml-common.h__/r ${ METALLIB_COMMON } " -e "/__embed_ggml-common.h__/d" < " ${ EMBED } .tmp2" > " ${ EMBED } .tmp3" 94# Step 4: inline ggml-metal-impl.h 95COMMAND sed -e "/\#include \"ggml-metal-impl.h\"/r ${ METALLIB_IMPL } " -e "/\#include \"ggml-metal-impl.h\"/d" < " ${ EMBED } .tmp3" > " ${ EMBED } " 96# Step 5: emit an asm chunk with kind-specific start/end symbols 97# note: '-' is illegal in C symbols, so we use kind_sym; the macOS 98# section name is limited to 16 chars so we keep it shared 99# across kinds (__ggml_metallib) and only vary the global symbols. 100COMMAND echo ".section __DATA,__ggml_metallib" > " ${ ASM } " 101COMMAND echo ".globl _ggml_metallib_ ${ kind_sym } _start" >> " ${ ASM } " 102COMMAND echo "_ggml_metallib_ ${ kind_sym } _start:" >> " ${ ASM } " 103COMMAND echo .incbin "\" ${ EMBED } \"" >> " ${ ASM } " 104COMMAND echo ".globl _ggml_metallib_ ${ kind_sym } _end" >> " ${ ASM } " 105COMMAND echo "_ggml_metallib_ ${ kind_sym } _end:" >> " ${ ASM } " 106DEPENDS ../ggml-common.h ggml-metal-impl.h 107kernels/common.h kernels/dequantize.h kernels/quantize.h 108kernels/ ${ kind } .metal 109COMMENT "Generate embedded Metal library for ${ kind } " 110VERBATIM 111) 112 113list ( APPEND METALLIB_EMBED_ASM_FILES " ${ ASM } " ) 114endforeach () 115 116target_sources ( ggml-metal PRIVATE ${ METALLIB_EMBED_ASM_FILES }) 117else () 118# copy header files to bin directory 119configure_file ( ../ggml-common.h ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-common.h COPYONLY ) 120configure_file ( ggml-metal-impl.h ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-metal-impl.h COPYONLY ) 121 122file ( MAKE_DIRECTORY " ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels" ) 123configure_file ( kernels/common.h ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels/common.h COPYONLY ) 124configure_file ( kernels/dequantize.h ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels/dequantize.h COPYONLY ) 125configure_file ( kernels/quantize.h ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels/quantize.h COPYONLY ) 126 127foreach ( src${ METALLIB_KERNEL_SOURCES }) 128configure_file ( $ { src } ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } / ${ src } COPYONLY ) 129endforeach () 130 131# CMAKE_OSX_SYSROOT is an SDK name or path - xcrun accepts both 132set ( METAL_SDK ${ CMAKE_OSX_SYSROOT }) 133if ( NOT METAL_SDK) 134set ( METAL_SDK macosx ) 135endif () 136 137if ( CMAKE_OSX_SYSROOTMATCHES "[Ss]imulator" ) 138set ( METAL_TARGET_SIM "-simulator" ) 139else () 140set ( METAL_TARGET_SIM "" ) 141endif () 142 143if ( GGML_METAL_SHADER_DEBUG) 144# note: disabling fast math is needed in order to pass tests/test-backend-ops 145# note: adding -fno-inline fixes the tests when using MTL_SHADER_VALIDATION=1 146# note: unfortunately, we have to call it default.metallib instead of ggml.metallib 147# ref: https://github.com/ggml-org/whisper.cpp/issues/1720 148# note: adding -g causes segmentation fault during compile 149set ( XC_FLAGS -fno-fast-math -fno-inline ) 150else () 151set ( XC_FLAGS -O3 ) 152endif () 153 154execute_process ( COMMAND xcrun -sdk ${ METAL_SDK } --show-sdk-version OUTPUT_VARIABLE METAL_SDK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) 155if ( METAL_SDK_VERSIONVERSION_GREATER_EQUAL 26.0) 156set ( GGML_METAL_HAS_TENSOR_LIB ON ) 157else () 158message ( STATUS "Metal SDK ${ METAL_SDK_VERSION } does not support the tensor API, skipping ggml-tensor.metallib" ) 159endif () 160 161if ( GGML_METAL_MACOSX_VERSION_MIN) 162message ( STATUS "Adding -mmacosx-version-min= ${ GGML_METAL_MACOSX_VERSION_MIN } flag to metal compilation" ) 163list ( APPEND XC_FLAGS -mmacosx-version-min= ${ GGML_METAL_MACOSX_VERSION_MIN }) 164elseif ( NOT GGML_METAL_TARGET_OSSTREQUAL "macos" AND CMAKE_OSX_DEPLOYMENT_TARGET) 165message ( STATUS "Adding -mtargetos= ${ GGML_METAL_TARGET_OS }${ CMAKE_OSX_DEPLOYMENT_TARGET }${ METAL_TARGET_SIM } flag to metal compilation" ) 166list ( APPEND XC_FLAGS -mtargetos= ${ GGML_METAL_TARGET_OS }${ CMAKE_OSX_DEPLOYMENT_TARGET }${ METAL_TARGET_SIM }) 167endif () 168 169if ( GGML_METAL_STD) 170message ( STATUS "Adding -std= ${ GGML_METAL_STD } flag to metal compilation" ) 171list ( APPEND XC_FLAGS -std= ${ GGML_METAL_STD }) 172endif () 173 174# Compile each kernel source to .air, then link into default.metallib 175set ( AIR_FILES "" ) 176foreach ( src${ METALLIB_KERNEL_SOURCES }) 177get_filename_component ( name ${ src } NAME_WE ) 178set ( AIR " ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } / ${ name } .air" ) 179list ( APPEND AIR_FILES ${ AIR }) 180add_custom_command ( 181OUTPUT ${ AIR } 182COMMAND xcrun -sdk ${ METAL_SDK } metal ${ XC_FLAGS } -I ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } -c ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } / ${ src } -o ${ AIR } 183DEPENDS ${ src } kernels/common.h kernels/dequantize.h kernels/quantize.h ${ METALLIB_COMMON } ggml-metal-impl.h 184COMMENT "Compiling ${ src } " 185VERBATIM 186) 187endforeach () 188 189set ( METALLIB_FILES ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /default.metallib ) 190 191# the tensor API kernels go in a separate metallib, loaded only where supported 192if ( GGML_METAL_HAS_TENSOR_LIB) 193set ( AIR_MM_TENSOR " ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /mul_mm_tensor.air" ) 194# the tensor API needs OS 26+ 195set ( XC_FLAGS_TENSOR ${ XC_FLAGS } -mtargetos= ${ GGML_METAL_TARGET_OS } 26.0 ${ METAL_TARGET_SIM }) 196add_custom_command ( 197OUTPUT ${ AIR_MM_TENSOR } 198COMMAND xcrun -sdk ${ METAL_SDK } metal ${ XC_FLAGS_TENSOR } -DGGML_METAL_HAS_TENSOR -I ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } -c ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels/mul_mm.metal -o ${ AIR_MM_TENSOR } 199DEPENDS kernels/mul_mm.metal kernels/common.h kernels/dequantize.h ${ METALLIB_COMMON } ggml-metal-impl.h 200COMMENT "Compiling kernels/mul_mm.metal (tensor API)" 201VERBATIM 202) 203 204add_custom_command ( 205OUTPUT ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-tensor.metallib 206COMMAND xcrun -sdk ${ METAL_SDK } metallib ${ AIR_MM_TENSOR } -o ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-tensor.metallib 207DEPENDS ${ AIR_MM_TENSOR } 208COMMENT "Linking tensor API Metal kernels into ggml-tensor.metallib" 209) 210 211list ( APPEND METALLIB_FILES ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-tensor.metallib ) 212endif () 213 214add_custom_command ( 215OUTPUT ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /default.metallib 216COMMAND xcrun -sdk ${ METAL_SDK } metallib ${ AIR_FILES } -o ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /default.metallib 217COMMAND rm -f ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-common.h 218COMMAND rm -f ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /ggml-metal-impl.h 219COMMAND rm -rf ${ CMAKE_RUNTIME_OUTPUT_DIRECTORY } /kernels 220DEPENDS ${ AIR_FILES } ${ AIR_MM_TENSOR } 221COMMENT "Linking Metal kernels into default.metallib" 222) 223 224add_custom_target ( 225ggml-metal-lib ALL 226DEPENDS ${ METALLIB_FILES } 227) 228endif () # GGML_METAL_EMBED_LIBRARY 229 230if ( NOT GGML_METAL_EMBED_LIBRARY) 231install ( 232DIRECTORY ${ CMAKE_CURRENT_SOURCE_DIR } /kernels/ 233DESTINATION ${ CMAKE_INSTALL_BINDIR } /kernels 234FILES_MATCHING PATTERN "*.metal" PATTERN "*.h" 235) 236 237install ( 238FILES ${ METALLIB_FILES } 239DESTINATION ${ CMAKE_INSTALL_BINDIR } 240) 241endif ()