char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
ad6c66839
char/aliceai-t5-moe
1#pragma once 2 3#include "ggml.h" 4#include "ggml-impl.h" 5#include "ggml-cuda.h" 6 7#include <cstdint> 8#include <cstdlib> 9#include <memory> 10#include <mutex> 11 12#if defined(GGML_USE_HIP) 13#define GGML_COMMON_DECL_HIP 14#define GGML_COMMON_IMPL_HIP 15#else 16#define GGML_COMMON_DECL_CUDA 17#define GGML_COMMON_IMPL_CUDA 18#if defined(GGML_USE_MUSA) 19#define GGML_COMMON_DECL_MUSA 20#define GGML_COMMON_IMPL_MUSA 21#endif 22#endif 23#include "ggml-common.h" 24 25#include <array> 26#include <algorithm> 27#include <cassert> 28#include <cfloat> 29#include <cstdio> 30#include <string> 31#include <unordered_map> 32#include <utility> 33#include <vector> 34 35#if defined(GGML_USE_HIP) 36#include "vendors/hip.h" 37#elif defined(GGML_USE_MUSA) 38#include "vendors/musa.h" 39#else 40#include "vendors/cuda.h" 41#endif // defined(GGML_USE_HIP) 42 43#define STRINGIZE_IMPL(...) #__VA_ARGS__ 44#define STRINGIZE(...) STRINGIZE_IMPL(__VA_ARGS__) 45 46#define WARP_SIZE 32 47#define CUDART_HMAX 11070 // CUDA 11.7, min. ver. for which __hmax and __hmax2 are known to work (may be higher than needed) 48#define CUDART_HMASK 12000 // CUDA 12.0, min. ver. for half2 -> uint mask comparisons 49 50#define GGML_CUDA_CC_PASCAL 600 51#define GGML_CUDA_CC_DP4A 610 // minimum compute capability for __dp4a, an intrinsic for byte-wise dot products 52#define GGML_CUDA_CC_VOLTA 700 53#define GGML_CUDA_CC_TURING 750 54#define GGML_CUDA_CC_AMPERE 800 55#define GGML_CUDA_CC_ORIN 870 56#define GGML_CUDA_CC_ADA_LOVELACE 890 57#define GGML_CUDA_CC_HOPPER 900 58// While BW spans CC 1000, 1100 & 1200, we are integrating Tensor Core instructions available to 1200 family, see 59// https://docs.nvidia.com/cutlass/media/docs/cpp/blackwell_functionality.html#blackwell-sm120-gemms 60#define GGML_CUDA_CC_BLACKWELL 1200 61#define GGML_CUDA_CC_DGX_SPARK 1210 62#define GGML_CUDA_CC_RUBIN 1300 63#define GGML_CUDA_CC_OFFSET_AMD 0x1000000 64#define GGML_CUDA_CC_OFFSET_MTHREADS 0x0100000 65#define GGML_CUDA_CC_IS_NVIDIA(cc) (cc < GGML_CUDA_CC_OFFSET_MTHREADS) 66 67// AMD 68// GCN/CDNA, wave size is 64 69#define GGML_CUDA_CC_GCN4 (GGML_CUDA_CC_OFFSET_AMD + 0x803) // Tonga, Fiji, Polaris, minimum for fast fp16 70#define GGML_CUDA_CC_VEGA (GGML_CUDA_CC_OFFSET_AMD + 0x900) // Vega56/64, minimum for fp16 dual issue 71#define GGML_CUDA_CC_VEGA20 (GGML_CUDA_CC_OFFSET_AMD + 0x906) // MI50/Radeon VII, minimum for dp4a 72#define GGML_CUDA_CC_GFX909 (GGML_CUDA_CC_OFFSET_AMD + 0x909) // GCN APU 73#define GGML_CUDA_CC_GFX90C (GGML_CUDA_CC_OFFSET_AMD + 0x90c) // GCN APU 74#define GGML_CUDA_CC_CDNA1 (GGML_CUDA_CC_OFFSET_AMD + 0x908) // MI100, minimum for MFMA, acc registers 75#define GGML_CUDA_CC_CDNA2 (GGML_CUDA_CC_OFFSET_AMD + 0x90a) // MI210 (gfx90a), minimum acc register renaming 76#define GGML_CUDA_CC_CDNA3 (GGML_CUDA_CC_OFFSET_AMD + 0x942) // MI300 77#define GGML_CUDA_CC_CDNA4 (GGML_CUDA_CC_OFFSET_AMD + 0x950) // MI350X/MI355X 78 79// RDNA removes MFMA, dp4a, xnack, acc registers, wave size is 32 80#define GGML_CUDA_CC_RDNA1 (GGML_CUDA_CC_OFFSET_AMD + 0x1010) // RX 5000 81#define GGML_CUDA_CC_RDNA2 (GGML_CUDA_CC_OFFSET_AMD + 0x1030) // RX 6000, minimum for dp4a 82#define GGML_CUDA_CC_RDNA3 (GGML_CUDA_CC_OFFSET_AMD + 0x1100) // RX 7000, minimum for WMMA 83#define GGML_CUDA_CC_RDNA3_5 (GGML_CUDA_CC_OFFSET_AMD + 0x1150) // AI 370, AI Max 395 laptops. 84#define GGML_CUDA_CC_RDNA4 (GGML_CUDA_CC_OFFSET_AMD + 0x1200) // RX 9000 85 86#define GGML_CUDA_CC_IS_AMD(cc) (cc >= GGML_CUDA_CC_OFFSET_AMD) 87#define GGML_CUDA_CC_IS_RDNA(cc) (cc >= GGML_CUDA_CC_RDNA1) 88#define GGML_CUDA_CC_IS_RDNA1(cc) (cc >= GGML_CUDA_CC_RDNA1 && cc < GGML_CUDA_CC_RDNA2) 89#define GGML_CUDA_CC_IS_RDNA2(cc) (cc >= GGML_CUDA_CC_RDNA2 && cc < GGML_CUDA_CC_RDNA3) 90#define GGML_CUDA_CC_IS_RDNA3_0(cc) (cc >= GGML_CUDA_CC_RDNA3 && cc < GGML_CUDA_CC_RDNA3_5) 91#define GGML_CUDA_CC_IS_RDNA3_5(cc) (cc >= GGML_CUDA_CC_RDNA3_5 && cc < GGML_CUDA_CC_RDNA4) 92#define GGML_CUDA_CC_IS_RDNA3(cc) (GGML_CUDA_CC_IS_RDNA3_0(cc) || GGML_CUDA_CC_IS_RDNA3_5(cc)) 93#define GGML_CUDA_CC_IS_RDNA4(cc) (cc >= GGML_CUDA_CC_RDNA4) 94#define GGML_CUDA_CC_IS_GCN_APU(cc) ((cc) == GGML_CUDA_CC_GFX909 || (cc) == GGML_CUDA_CC_GFX90C) 95#define GGML_CUDA_CC_IS_GCN(cc) ((cc > GGML_CUDA_CC_OFFSET_AMD && cc < GGML_CUDA_CC_CDNA1) || GGML_CUDA_CC_IS_GCN_APU(cc)) 96#define GGML_CUDA_CC_IS_CDNA(cc) (!GGML_CUDA_CC_IS_GCN_APU(cc) && cc >= GGML_CUDA_CC_CDNA1 && cc < GGML_CUDA_CC_RDNA1) 97#define GGML_CUDA_CC_IS_CDNA1(cc) (GGML_CUDA_CC_IS_CDNA(cc) && cc >= GGML_CUDA_CC_CDNA1 && cc < GGML_CUDA_CC_CDNA2) 98#define GGML_CUDA_CC_IS_CDNA2(cc) (GGML_CUDA_CC_IS_CDNA(cc) && cc >= GGML_CUDA_CC_CDNA2 && cc < GGML_CUDA_CC_CDNA3) 99#define GGML_CUDA_CC_IS_CDNA3(cc) (GGML_CUDA_CC_IS_CDNA(cc) && cc >= GGML_CUDA_CC_CDNA3 && cc < GGML_CUDA_CC_CDNA4) 100#define GGML_CUDA_CC_IS_CDNA4(cc) (GGML_CUDA_CC_IS_CDNA(cc) && cc >= GGML_CUDA_CC_CDNA4 && cc < GGML_CUDA_CC_RDNA1) 101 102// Moore Threads 103#define MUSART_HMASK 40300 // MUSA rc4.3, min. ver. for half2 -> uint mask comparisons 104 105#define GGML_CUDA_CC_QY1 (GGML_CUDA_CC_OFFSET_MTHREADS + 0x210) // MTT S80, MTT S3000 106#define GGML_CUDA_CC_QY2 (GGML_CUDA_CC_OFFSET_MTHREADS + 0x220) // MTT S4000 107#define GGML_CUDA_CC_PH1 (GGML_CUDA_CC_OFFSET_MTHREADS + 0x310) // MTT S5000 108 109#define GGML_CUDA_CC_IS_MTHREADS(cc) (cc >= GGML_CUDA_CC_OFFSET_MTHREADS && cc < GGML_CUDA_CC_OFFSET_AMD) 110#define GGML_CUDA_CC_IS_QY1(cc) (cc >= GGML_CUDA_CC_QY1 && cc < GGML_CUDA_CC_QY2) 111#define GGML_CUDA_CC_IS_QY2(cc) (cc >= GGML_CUDA_CC_QY2 && cc < GGML_CUDA_CC_PH1) 112#define GGML_CUDA_CC_IS_PH1(cc) (cc >= GGML_CUDA_CC_PH1) 113 114#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) && CUDART_VERSION >= 11070 115# define GGML_CUDA_USE_CUB 116#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) && CUDART_VERSION >= 11070 117 118// PDL host-side support (cudaLaunchKernelEx) requires CUDART >= 11.8. 119// However, this has been bugged in CTK < 12.3 for MSVC builds, see 120// https://github.com/ggml-org/llama.cpp/pull/22522#discussion_r3302393293 121// __CUDA_ARCH__ is undefined in host passes; GPU arch check happens in device-side code. 122#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) && \ 123 (CUDART_VERSION >= 12030 || (!(defined(_MSC_VER) && !defined(__clang__)) && CUDART_VERSION >= 11080)) 124# define GGML_CUDA_USE_PDL 125#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) && (CUDART_VERSION >= 12030 || (!(defined(_MSC_VER) && !defined(__clang__)) && CUDART_VERSION >= 11080)) 126 127static __device__ __forceinline__ void ggml_cuda_syncwarp() { 128#ifndef GGML_USE_HIP 129 __syncwarp(); 130#endif // GGML_USE_HIP 131} 132 133static __device__ __forceinline__ void ggml_cuda_pdl_sync() { 134#if defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER 135 cudaGridDependencySynchronize(); 136#endif // defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER 137} 138 139static __device__ __forceinline__ void ggml_cuda_pdl_lc() { 140#if defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER 141 cudaTriggerProgrammaticLaunchCompletion(); 142#endif // defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER 143} 144 145#ifdef __CUDA_ARCH_LIST__ 146constexpr bool ggml_cuda_has_arch_impl(int) { 147 return false; 148} 149 150template<class ... Archs> 151constexpr bool ggml_cuda_has_arch_impl(const int arch, const int first, Archs... rest) { 152 return arch == first || ggml_cuda_has_arch_impl(arch, rest...); 153} 154 155constexpr bool ggml_cuda_has_arch(const int arch) { 156 return ggml_cuda_has_arch_impl(arch, __CUDA_ARCH_LIST__); 157} 158 159constexpr int ggml_cuda_highest_compiled_arch_impl(const int /*arch*/, const int cur) { 160 if (cur == 0) { 161 return -1; 162 } 163 return cur; 164} 165 166template<class ... Archs> 167constexpr int ggml_cuda_highest_compiled_arch_impl(const int arch, const int cur, const int first, Archs... rest) { 168 if (first <= arch && first > cur) { 169 return ggml_cuda_highest_compiled_arch_impl(arch, first, rest...); 170 } else { 171 return ggml_cuda_highest_compiled_arch_impl(arch, cur, rest...); 172 } 173} 174 175constexpr int ggml_cuda_highest_compiled_arch(const int arch) { 176 return ggml_cuda_highest_compiled_arch_impl(arch, 0, __CUDA_ARCH_LIST__); 177} 178#else 179static int ggml_cuda_highest_compiled_arch(const int arch) { 180 return arch; 181} 182#endif // __CUDA_ARCH_LIST__ 183 184// --------------------------------------------------------------------------------------------------------- 185 186#define MATRIX_ROW_PADDING 512 // last row of quant. matrices is a multiple of this to avoid out-of-bounds memory accesses 187 188#define GGML_CUDA_MAX_STREAMS 8 189 190[[noreturn]] 191void ggml_cuda_error(const char * stmt, const char * func, const char * file, int line, const char * msg); 192 193#define CUDA_CHECK_GEN(err, success, error_fn) \ 194 do { \ 195 auto err_ = (err); \ 196 if (err_ != (success)) { \ 197 ggml_cuda_error(#err, __func__, __FILE__, __LINE__, error_fn(err_)); \ 198 } \ 199 } while (0) 200 201#define CUDA_CHECK(err) CUDA_CHECK_GEN(err, cudaSuccess, cudaGetErrorString) 202 203 204#if CUDART_VERSION >= 12000 || defined(GGML_USE_MUSA) 205 static const char * cublas_get_error_str(const cublasStatus_t err) { 206 return cublasGetStatusString(err); 207 } 208#else 209 static const char * cublas_get_error_str(const cublasStatus_t err) { 210 switch (err) { 211 case CUBLAS_STATUS_SUCCESS: return "CUBLAS_STATUS_SUCCESS"; 212 case CUBLAS_STATUS_NOT_INITIALIZED: return "CUBLAS_STATUS_NOT_INITIALIZED"; 213 case CUBLAS_STATUS_ALLOC_FAILED: return "CUBLAS_STATUS_ALLOC_FAILED"; 214 case CUBLAS_STATUS_INVALID_VALUE: return "CUBLAS_STATUS_INVALID_VALUE"; 215 case CUBLAS_STATUS_ARCH_MISMATCH: return "CUBLAS_STATUS_ARCH_MISMATCH"; 216 case CUBLAS_STATUS_MAPPING_ERROR: return "CUBLAS_STATUS_MAPPING_ERROR"; 217 case CUBLAS_STATUS_EXECUTION_FAILED: return "CUBLAS_STATUS_EXECUTION_FAILED"; 218 case CUBLAS_STATUS_INTERNAL_ERROR: return "CUBLAS_STATUS_INTERNAL_ERROR"; 219 case CUBLAS_STATUS_NOT_SUPPORTED: return "CUBLAS_STATUS_NOT_SUPPORTED"; 220 default: return "unknown error"; 221 } 222 } 223#endif // CUDART_VERSION >= 12000 224 225#define CUBLAS_CHECK(err) CUDA_CHECK_GEN(err, CUBLAS_STATUS_SUCCESS, cublas_get_error_str) 226 227#ifdef GGML_USE_NCCL 228#define NCCL_CHECK(err) CUDA_CHECK_GEN(err, ncclSuccess, ncclGetErrorString) 229#endif // GGML_USE_NCCL 230 231#if !defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM) 232static const char * cu_get_error_str(CUresult err) { 233 const char * err_str; 234 cuGetErrorString(err, &err_str); 235 return err_str; 236} 237#define CU_CHECK(err) CUDA_CHECK_GEN(err, CUDA_SUCCESS, cu_get_error_str) 238#endif 239 240#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 241# define CUDA_SET_SHARED_MEMORY_LIMIT(kernel, nbytes) \ 242 do { \ 243 static bool shared_memory_limit_raised[GGML_CUDA_MAX_DEVICES] = { false }; \ 244 const int id = ggml_cuda_get_device(); \ 245 if (!shared_memory_limit_raised[id]) { \ 246 CUDA_CHECK(cudaFuncSetAttribute(kernel, cudaFuncAttributeMaxDynamicSharedMemorySize, nbytes)); \ 247 shared_memory_limit_raised[id] = true; \ 248 } \ 249 } while (0) 250#else 251# define CUDA_SET_SHARED_MEMORY_LIMIT(kernel, nbytes) \ 252 do { \ 253 GGML_UNUSED(nbytes); \ 254 } while (0) 255#endif // !(defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 256 257#if CUDART_VERSION >= 11010 || defined(GGML_USE_MUSA) 258#define GGML_CUDA_ASSUME(x) __builtin_assume(x) 259#else 260#define GGML_CUDA_ASSUME(x) 261#endif // CUDART_VERSION >= 11010 262 263#if (!defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM)) || (defined(GGML_USE_HIP) && !defined(GGML_HIP_NO_VMM)) 264#define GGML_USE_VMM 265#endif // (!defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM)) || (defined(GGML_USE_HIP) && !defined(GGML_HIP_NO_VMM)) 266 267#if defined(GGML_USE_HIP) || defined(GGML_USE_MUSA) || __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL 268#define FP16_AVAILABLE 269#endif // defined(GGML_USE_HIP) || defined(GGML_USE_MUSA) || __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL 270 271#if defined(FP16_AVAILABLE) && __CUDA_ARCH__ != 610 272#define FAST_FP16_AVAILABLE 273#endif // defined(FP16_AVAILABLE) && __CUDA_ARCH__ != 610 274 275#if defined(GGML_USE_HIP) && defined(CDNA) && !defined(GGML_HIP_NO_MMQ_MFMA) 276#define AMD_MFMA_AVAILABLE 277#endif // defined(GGML_USE_HIP) && defined(CDNA) && !defined(GGML_HIP_NO_MMQ_MFMA) 278 279#if defined(GGML_USE_HIP) && (defined(RDNA4) || defined(RDNA3)) 280#define AMD_WMMA_AVAILABLE 281#endif // defined(GGML_USE_HIP) && defined(RDNA4) 282 283// The Volta instructions are in principle available on Turing or newer but they are effectively unusable: 284#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ == GGML_CUDA_CC_VOLTA 285#define VOLTA_MMA_AVAILABLE 286#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ == GGML_CUDA_CC_VOLTA 287 288#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_TURING 289#define TURING_MMA_AVAILABLE 290#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_TURING 291 292#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 293#define AMPERE_MMA_AVAILABLE 294#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 295 296#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_BLACKWELL && __CUDA_ARCH__ < GGML_CUDA_CC_RUBIN 297# define BLACKWELL_MMA_AVAILABLE 298#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_BLACKWELL 299 300#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 301#define CP_ASYNC_AVAILABLE 302#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 303 304#if !defined(GGML_CUDA_NO_FA) && !(defined(GGML_USE_MUSA) && __MUSA_ARCH__ < 220) 305#define FLASH_ATTN_AVAILABLE 306#endif // !defined(GGML_CUDA_NO_FA) && !(defined(GGML_USE_MUSA) && __MUSA_ARCH__ < 220) 307 308static bool fp16_available(const int cc) { 309 return ggml_cuda_highest_compiled_arch(cc) >= GGML_CUDA_CC_PASCAL || 310 (GGML_CUDA_CC_IS_MTHREADS(cc) && cc >= GGML_CUDA_CC_PH1); 311} 312 313static bool fast_fp16_available(const int cc) { 314 return GGML_CUDA_CC_IS_AMD(cc) || 315 (GGML_CUDA_CC_IS_NVIDIA(cc) && fp16_available(cc) && ggml_cuda_highest_compiled_arch(cc) != 610) || 316 (GGML_CUDA_CC_IS_MTHREADS(cc) && fp16_available(cc)); 317} 318 319// To be used for feature selection of external libraries, e.g. cuBLAS. 320static bool fast_fp16_hardware_available(const int cc) { 321 return (GGML_CUDA_CC_IS_NVIDIA(cc) && cc >= GGML_CUDA_CC_PASCAL && cc != 610) || GGML_CUDA_CC_IS_AMD(cc) || 322 (GGML_CUDA_CC_IS_MTHREADS(cc) && cc >= GGML_CUDA_CC_QY2); 323} 324 325// To be used for feature selection of external libraries, e.g. cuBLAS. 326static bool fp16_mma_hardware_available(const int cc) { 327 return (GGML_CUDA_CC_IS_NVIDIA(cc) && cc >= GGML_CUDA_CC_VOLTA) || 328 GGML_CUDA_CC_IS_CDNA(cc) || GGML_CUDA_CC_IS_RDNA3(cc) || GGML_CUDA_CC_IS_RDNA4(cc) || 329 (GGML_CUDA_CC_IS_MTHREADS(cc) && cc >= GGML_CUDA_CC_QY2); 330} 331 332// To be used for feature selection of external libraries, e.g. cuBLAS. 333static bool fast_bf16_hardware_available(const int cc) { 334 return (GGML_CUDA_CC_IS_AMD(cc) && (cc >= GGML_CUDA_CC_RDNA3 || GGML_CUDA_CC_IS_CDNA(cc))) 335 || (GGML_CUDA_CC_IS_NVIDIA(cc) && cc >= GGML_CUDA_CC_AMPERE); 336} 337 338static bool bf16_mma_hardware_available(const int cc) { 339 return (GGML_CUDA_CC_IS_NVIDIA(cc) && cc >= GGML_CUDA_CC_AMPERE) || 340 GGML_CUDA_CC_IS_CDNA(cc) || cc >= GGML_CUDA_CC_RDNA3 || 341 (GGML_CUDA_CC_IS_MTHREADS(cc) && cc >= GGML_CUDA_CC_PH1); 342} 343 344static bool fp32_mma_hardware_available(const int cc) { 345 return GGML_CUDA_CC_IS_CDNA(cc); 346} 347 348static bool amd_mfma_available(const int cc) { 349#if !defined(GGML_HIP_NO_MMQ_MFMA) 350 return GGML_CUDA_CC_IS_CDNA(cc); 351#else 352 return false; 353#endif //!defined(GGML_HIP_NO_MMQ_MFMA) 354} 355 356static bool amd_wmma_available(const int cc) { 357 return (GGML_CUDA_CC_IS_RDNA4(cc) || GGML_CUDA_CC_IS_RDNA3(cc)); 358} 359 360static bool volta_mma_available(const int cc) { 361 return GGML_CUDA_CC_IS_NVIDIA(cc) && ggml_cuda_highest_compiled_arch(cc) == GGML_CUDA_CC_VOLTA; 362} 363 364static bool turing_mma_available(const int cc) { 365 return GGML_CUDA_CC_IS_NVIDIA(cc) && ggml_cuda_highest_compiled_arch(cc) >= GGML_CUDA_CC_TURING; 366} 367 368static bool ampere_mma_available(const int cc) { 369 return GGML_CUDA_CC_IS_NVIDIA(cc) && ggml_cuda_highest_compiled_arch(cc) >= GGML_CUDA_CC_AMPERE; 370} 371 372static bool cp_async_available(const int cc) { 373 return GGML_CUDA_CC_IS_NVIDIA(cc) && ggml_cuda_highest_compiled_arch(cc) >= GGML_CUDA_CC_AMPERE; 374} 375 376static bool blackwell_mma_available(const int cc) { 377 return GGML_CUDA_CC_IS_NVIDIA(cc) && ggml_cuda_highest_compiled_arch(cc) >= GGML_CUDA_CC_BLACKWELL && 378 ggml_cuda_highest_compiled_arch(cc) < GGML_CUDA_CC_RUBIN; 379} 380 381// Checks whether the tensor's base data pointer and higher-dimensional strides are byte-aligned to `alignment` bytes. 382static bool ggml_cuda_is_aligned(const ggml_tensor * tensor, const size_t alignment) { 383 GGML_ASSERT(tensor != nullptr); 384 return (reinterpret_cast<uintptr_t>(tensor->data) % alignment) == 0 && 385 tensor->nb[1] % alignment == 0 && 386 tensor->nb[2] % alignment == 0 && 387 tensor->nb[3] % alignment == 0; 388} 389 390static constexpr __device__ int ggml_cuda_get_physical_warp_size() { 391#if defined(GGML_USE_HIP) && (defined(__GFX9__) || defined(__GFX8__)) 392 return 64; 393#else 394 return 32; 395#endif // defined(GGML_USE_HIP) && (defined(__GFX9__) || defined(__GFX8__)) 396} 397 398// Maximum number of bytes that can be copied in a single instruction. 399static constexpr __device__ int ggml_cuda_get_max_cpy_bytes() { 400#ifdef GGML_USE_HIP 401 return 16; 402#else 403#if __CUDA_ARCH__ >= GGML_CUDA_CC_VOLTA 404 return 16; 405#else 406 return 8; 407#endif // __CUDA_ARCH__ >= GGML_CUDA_CC_VOLTA 408#endif // GGML_USE_HIP 409} 410 411 412[[noreturn]] 413static __device__ void no_device_code( 414 const char * file_name, const int line, const char * function_name, const int arch, const char * arch_list) { 415 416#if defined(GGML_USE_HIP) 417 printf("%s:%d: ERROR: HIP kernel %s has no device code compatible with HIP arch %d.\n", 418 file_name, line, function_name, arch); 419 GGML_UNUSED(arch_list); 420#else 421 printf("%s:%d: ERROR: CUDA kernel %s has no device code compatible with CUDA arch %d. ggml-cuda.cu was compiled for: %s\n", 422 file_name, line, function_name, arch, arch_list); 423#endif // defined(GGML_USE_HIP) 424 __trap(); 425 426 GGML_UNUSED(no_device_code); // suppress unused function warning 427 428#if defined(GGML_USE_MUSA) 429 __builtin_unreachable(); 430#endif // defined(GGML_USE_MUSA) 431} 432 433#ifdef __CUDA_ARCH__ 434#define NO_DEVICE_CODE no_device_code(__FILE__, __LINE__, __FUNCTION__, __CUDA_ARCH__, STRINGIZE(__CUDA_ARCH_LIST__)) 435#else 436#define NO_DEVICE_CODE //GGML_ABORT("NO_DEVICE_CODE not valid in host code.") 437#endif // __CUDA_ARCH__ 438 439// The compiler is always able to unroll loops if they contain continue expressions. 440// In such cases loop unrolling can still be achieved via recursion: 441template <int n> 442struct ggml_cuda_unroll { 443 template <typename Func, typename... Args> 444 __device__ void operator()(const Func & f, Args... args) const { 445 f(n - 1, args...); 446 ggml_cuda_unroll<n - 1>{}(f, args...); 447 } 448}; 449 450template <> 451struct ggml_cuda_unroll<1> { 452 template <typename Func, typename... Args> 453 __device__ void operator()(const Func & f, Args... args) const { 454 f(0, args...); 455 } 456}; 457 458template<int width = WARP_SIZE> 459static __device__ __forceinline__ int warp_reduce_sum(int x) { 460#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 461 return __reduce_add_sync(0xffffffff, x); 462#else 463#pragma unroll 464 for (int offset = width/2; offset > 0; offset >>= 1) { 465 x += __shfl_xor_sync(0xffffffff, x, offset, width); 466 } 467 return x; 468#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE 469} 470 471template<int width = WARP_SIZE> 472static __device__ __forceinline__ float warp_reduce_sum(float x) { 473#pragma unroll 474 for (int offset = width/2; offset > 0; offset >>= 1) { 475 x += __shfl_xor_sync(0xffffffff, x, offset, width); 476 } 477 return x; 478} 479 480template<int width = WARP_SIZE> 481static __device__ __forceinline__ float2 warp_reduce_sum(float2 a) { 482#pragma unroll 483 for (int offset = width/2; offset > 0; offset >>= 1) { 484 a.x += __shfl_xor_sync(0xffffffff, a.x, offset, width); 485 a.y += __shfl_xor_sync(0xffffffff, a.y, offset, width); 486 } 487 return a; 488} 489 490template<int width = WARP_SIZE> 491static __device__ __forceinline__ half2 warp_reduce_sum(half2 a) { 492#ifdef FP16_AVAILABLE 493#pragma unroll 494 for (int offset = width/2; offset > 0; offset >>= 1) { 495 a = __hadd2(a, __shfl_xor_sync(0xffffffff, a, offset, width)); 496 } 497 return a; 498 499#else 500 NO_DEVICE_CODE; 501 return a; 502#endif // FP16_AVAILABLE 503} 504 505template<int width = WARP_SIZE> 506static __device__ __forceinline__ int warp_reduce_all(int x) { 507 if (width == ggml_cuda_get_physical_warp_size()) { 508 return __all_sync(0xffffffff, x); 509 } else { 510#pragma unroll 511 for (int offset = width/2; offset > 0; offset >>= 1) { 512 x = __shfl_xor_sync(0xffffffff, x, offset, width) && x; 513 } 514 return x; 515 } 516} 517 518template<int width = WARP_SIZE> 519static __device__ __forceinline__ int warp_reduce_any(int x) { 520 if (width == ggml_cuda_get_physical_warp_size()) { 521 return __any_sync(0xffffffff, x); 522 } else { 523#pragma unroll 524 for (int offset = width/2; offset > 0; offset >>= 1) { 525 x = __shfl_xor_sync(0xffffffff, x, offset, width) || x; 526 } 527 return x; 528 } 529} 530 531template<int width = WARP_SIZE> 532static __device__ __forceinline__ float warp_reduce_max(float x) { 533#pragma unroll 534 for (int offset = width/2; offset > 0; offset >>= 1) { 535 x = fmaxf(x, __shfl_xor_sync(0xffffffff, x, offset, width)); 536 } 537 return x; 538} 539 540template<typename T, int width = WARP_SIZE> 541static __device__ __forceinline__ T warp_prefix_inclusive_sum(T x) { 542 const int lane_id = threadIdx.x % width; 543#pragma unroll 544 for (int offset = 1; offset < width; offset <<= 1) { 545 const T t = __shfl_up_sync(0xffffffff, x, offset, width); 546 if (lane_id >= offset) { 547 x += t; 548 } 549 } 550 return x; 551} 552 553template<int width = WARP_SIZE> 554static __device__ __forceinline__ float2 warp_prefix_inclusive_sum(float2 a) { 555 const int lane_id = threadIdx.x % width; 556#pragma unroll 557 for (int offset = 1; offset < width; offset <<= 1) { 558 const float t_x = __shfl_up_sync(0xffffffff, a.x, offset, width); 559 const float t_y = __shfl_up_sync(0xffffffff, a.y, offset, width); 560 if (lane_id >= offset) { 561 a.x += t_x; 562 a.y += t_y; 563 } 564 } 565 return a; 566} 567 568template<int width = WARP_SIZE> 569static __device__ __forceinline__ half2 warp_prefix_inclusive_sum(half2 a) { 570#ifdef FP16_AVAILABLE 571 const int lane_id = threadIdx.x % width; 572#pragma unroll 573 for (int offset = 1; offset < width; offset <<= 1) { 574 const half2 t = __shfl_up_sync(0xffffffff, a, offset, width); 575 if (lane_id >= offset) { 576 a = __hadd2(a, t); 577 } 578 } 579 return a; 580 581#else 582 NO_DEVICE_CODE; 583 return a; 584#endif // FP16_AVAILABLE 585} 586 587enum class block_reduce_method { 588 MAX, 589 SUM, 590}; 591 592template<block_reduce_method method_t, typename T> 593struct block_reduce_policy; 594 595template <typename T, typename... Ts> 596inline constexpr bool is_any = (std::is_same_v<T, Ts> || ...); 597 598template<typename...> 599inline constexpr bool ggml_cuda_dependent_false_v = false; 600 601template <typename T> struct block_reduce_policy<block_reduce_method::SUM, T> { 602 static __device__ T reduce(T val) { 603 if constexpr(is_any<T, float, float2, half2, int>) { 604 return warp_reduce_sum(val); 605 } else { 606 static_assert(ggml_cuda_dependent_false_v<T>, "Unsupported type for block reduce sum"); 607 } 608 } 609 610 static __device__ T sentinel() { 611 if constexpr (std::is_same_v<T, float>) { 612 return 0.0f; 613 } else if constexpr (std::is_same_v<T, float2>) { 614 return make_float2(0.0f, 0.0f); 615 } else if constexpr (std::is_same_v<T, half2>) { 616 return make_half2(0.0f, 0.0f); 617 } else if constexpr (std::is_same_v<T, int>) { 618 return 0; 619 } else { 620 static_assert(ggml_cuda_dependent_false_v<T>, "Unsupported type for block reduce sum"); 621 } 622 } 623}; 624 625template <typename T> struct block_reduce_policy<block_reduce_method::MAX, T> { 626 static __device__ T reduce(T val) { 627 if constexpr (is_any<T, float, half2>) { 628 return warp_reduce_max(val); 629 } else { 630 static_assert(ggml_cuda_dependent_false_v<T>, "Unsupported type for block reduce max"); 631 } 632 } 633 634 static __device__ T sentinel() { 635 if constexpr (std::is_same_v<T, float>) { 636 return -INFINITY; 637 } else if constexpr (std::is_same_v<T, half2>) { 638 return make_half2(-INFINITY, -INFINITY); 639 } else { 640 static_assert(ggml_cuda_dependent_false_v<T>, "Unsupported type for block reduce max"); 641 } 642 } 643}; 644 645template <block_reduce_method reduce_method_t, const unsigned int block_size_template = 0, typename T> 646static __device__ T block_reduce(T val, [[maybe_unused]] T * shared_vals) { 647 // for multi-warp reductions, callers must not reuse shared_vals until all reads from this invocation have completed 648 val = block_reduce_policy<reduce_method_t, T>::reduce(val); 649 const unsigned int block_size = block_size_template == 0 ? blockDim.x : block_size_template; 650 if (block_size > WARP_SIZE) { 651 assert((block_size <= 1024) && (block_size % WARP_SIZE) == 0); 652 const int warp_id = threadIdx.x / WARP_SIZE; 653 const int lane_id = threadIdx.x % WARP_SIZE; 654 if (lane_id == 0) { 655 shared_vals[warp_id] = val; 656 } 657 __syncthreads(); 658 val = block_reduce_policy<reduce_method_t, T>::sentinel(); 659 if (lane_id < (static_cast<int>(block_size) / WARP_SIZE)) { 660 val = shared_vals[lane_id]; 661 } 662 return block_reduce_policy<reduce_method_t, T>::reduce(val); 663 } 664 665 return val; 666} 667 668static __device__ __forceinline__ half ggml_cuda_hmax(const half a, const half b) { 669#ifdef FP16_AVAILABLE 670 671#if !defined(GGML_USE_HIP) && CUDART_VERSION < CUDART_HMAX 672 return __float2half(fmaxf(__half2float(a), __half2float(b))); 673#else 674 return __hmax(a, b); 675#endif // !defined(GGML_USE_HIP) && CUDART_VERSION < CUDART_HMAX 676 677#else 678 NO_DEVICE_CODE; 679 GGML_UNUSED(b); 680 return a; 681#endif // FP16_AVAILABLE 682} 683 684static __device__ __forceinline__ half2 ggml_cuda_hmax2(const half2 a, const half2 b) { 685#if defined(GGML_USE_HIP) 686 return half2(__hmax(a.x, b.x), __hmax(a.y, b.y)); 687#elif CUDART_VERSION >= CUDART_HMAX 688 return __hmax2(a, b); 689#else 690 half2 ret; 691 reinterpret_cast<half&>(ret.x) = __float2half(fmaxf( __low2float(a), __low2float(b))); 692 reinterpret_cast<half&>(ret.y) = __float2half(fmaxf(__high2float(a), __high2float(b))); 693 return ret; 694#endif 695} 696 697template<int width = WARP_SIZE> 698static __device__ __forceinline__ half2 warp_reduce_max(half2 x) { 699#if !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL || defined(GGML_USE_HIP) 700#pragma unroll 701 for (int offset = width/2; offset > 0; offset >>= 1) { 702 x = ggml_cuda_hmax2(x, __shfl_xor_sync(0xffffffff, x, offset, width)); 703 } 704 return x; 705#else 706 GGML_UNUSED(x); 707 NO_DEVICE_CODE; 708#endif // !defined(GGML_USE_HIP) && __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL || defined(GGML_USE_HIP) 709} 710 711#if (defined(CUDART_VERSION) && CUDART_VERSION < CUDART_HMASK) || defined(GGML_USE_HIP) || \ 712 (defined(MUSART_VERSION) && MUSART_VERSION < MUSART_HMASK) 713static __device__ __forceinline__ uint32_t __hgt2_mask(const half2 a, const half2 b) { 714 const uint32_t mask_low = 0x0000FFFF * (float( __low2half(a)) > float( __low2half(b))); 715 const uint32_t mask_high = 0xFFFF0000 * (float(__high2half(a)) > float(__high2half(b))); 716 return mask_low | mask_high; 717} 718#endif // (defined(CUDART_VERSION) && CUDART_VERSION < CUDART_HMASK) || defined(GGML_USE_HIP) || (defined(MUSART_VERSION) && MUSART_VERSION < MUSART_HMASK) 719 720static __device__ __forceinline__ int ggml_cuda_dp4a(const int a, const int b, int c) { 721#if defined(GGML_USE_HIP) 722#if defined(CDNA) || defined(RDNA2) || defined(__gfx906__) 723 c = __builtin_amdgcn_sdot4(a, b, c, false); 724#elif defined(RDNA3) || defined(RDNA4) 725 c = __builtin_amdgcn_sudot4( true, a, true, b, c, false); 726#elif defined(RDNA1) || defined(__gfx900__) 727 int tmp1; 728 int tmp2; 729 asm("\n \ 730 v_mul_i32_i24 %1, sext(%3), sext(%4) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:BYTE_0 \n \ 731 v_mul_i32_i24 %2, sext(%3), sext(%4) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_1 src1_sel:BYTE_1 \n \ 732 v_add3_u32 %0, %1, %2, %0 \n \ 733 v_mul_i32_i24 %1, sext(%3), sext(%4) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_2 src1_sel:BYTE_2 \n \ 734 v_mul_i32_i24 %2, sext(%3), sext(%4) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_3 src1_sel:BYTE_3 \n \ 735 v_add3_u32 %0, %1, %2, %0 \n \ 736 " 737 : "+v"(c), "=&v"(tmp1), "=&v"(tmp2) 738 : "v"(a), "v"(b) 739 ); 740#else 741 const int8x4_t va = reinterpret_cast<const int8x4_t&>(a); 742 const int8x4_t vb = reinterpret_cast<const int8x4_t&>(b); 743 c += va[0] * vb[0] + va[1] * vb[1] + va[2] * vb[2] + va[3] * vb[3]; 744#endif 745 return c; 746 747#else // defined(GGML_USE_HIP) 748 749#if __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A || defined(GGML_USE_MUSA) 750 return __dp4a(a, b, c); 751#else // __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A || defined(GGML_USE_MUSA) 752 const int8_t * a8 = (const int8_t *) &a; 753 const int8_t * b8 = (const int8_t *) &b; 754 return c + a8[0]*b8[0] + a8[1]*b8[1] + a8[2]*b8[2] + a8[3]*b8[3]; 755#endif // __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A || defined(GGML_USE_MUSA) 756 757#endif // defined(GGML_USE_HIP) 758} 759 760static __device__ __forceinline__ void ggml_cuda_mad(float & acc, const float v, const float u) { 761 acc += v*u; 762} 763 764static __device__ __forceinline__ void ggml_cuda_mad(float & acc, const float2 v, const float2 u) { 765 acc += v.x*u.x; 766 acc += v.y*u.y; 767} 768 769#if defined(GGML_USE_HIP) && (defined(RDNA2) || defined(RDNA3) || defined(RDNA4) || defined(__gfx906__) || defined(CDNA)) 770#define V_DOT2_F32_F16_AVAILABLE 771#endif // defined(GGML_USE_HIP) && (defined(RDNA2) || defined(RDNA3) || defined(RDNA4) || defined(__gfx906__) || defined(CDNA)) 772 773static __device__ __forceinline__ void ggml_cuda_mad(float & acc, const half2 v, const half2 u) { 774#ifdef V_DOT2_F32_F16_AVAILABLE 775 asm volatile("v_dot2_f32_f16 %0, %1, %2, %0" : "+v"(acc) : "v"(v), "v"(u)); 776#else 777#ifdef FAST_FP16_AVAILABLE 778 const float2 tmp = __half22float2(v*u); 779 acc += tmp.x + tmp.y; 780#else 781 const float2 tmpv = __half22float2(v); 782 const float2 tmpu = __half22float2(u); 783 acc += tmpv.x * tmpu.x; 784 acc += tmpv.y * tmpu.y; 785#endif // FAST_FP16_AVAILABLE 786#endif // V_DOT2_F32_F16_AVAILABLE 787} 788 789static __device__ __forceinline__ void ggml_cuda_mad(half2 & acc, const half2 v, const half2 u) { 790#ifdef FAST_FP16_AVAILABLE 791 acc += v*u; 792#else 793 const float2 tmpv = __half22float2(v); 794 const float2 tmpu = __half22float2(u); 795 float2 tmpacc = __half22float2(acc); 796 tmpacc.x += tmpv.x * tmpu.x; 797 tmpacc.y += tmpv.y * tmpu.y; 798 acc = make_half2(tmpacc.x, tmpacc.y); 799#endif // FAST_FP16_AVAILABLE 800} 801 802// Aligned memory transfers of 8/16 bytes can be faster than 2 transfers with 4 bytes, especially on AMD. 803// Important: do not use this function if dst and src both point at registers. 804// Due to the strict aliasing rule the compiler can do incorrect optimizations if src and dst have different types. 805// The function is intended for copies between registers and SRAM/VRAM to make the compiler emit the right instructions. 806// If dst and src point at different address spaces then they are guaranteed to not be aliased. 807template <int nbytes, int alignment = 0> 808static __device__ __forceinline__ void ggml_cuda_memcpy_1(void * __restrict__ dst, const void * __restrict__ src) { 809 static_assert( 810 nbytes <= ggml_cuda_get_max_cpy_bytes() || alignment == 0, 811 "You are misusing the alignment parameter for ggml_cuda_memcpy_1. " 812 "The intent is for the parameter is only as a workaround if either one of the pointers is not properly aligned. " 813 "If you use it to do more bytes per copy than ggml_cuda_max_cpy_bytes() the reads and writes may not be coalesced. " 814 "Call ggml_cuda_memcpy_1 in a loop instead."); 815 if constexpr (alignment != 0) { 816 static_assert(nbytes % alignment == 0, "bad alignment"); 817 } 818 constexpr int nb_per_cpy = alignment == 0 ? nbytes : alignment; 819 820#pragma unroll 821 for (int i = 0; i < nbytes/nb_per_cpy; ++i) { 822 if constexpr (nb_per_cpy == 1) { 823 ((char *) dst)[i] = ((const char *) src)[i]; 824 } else if constexpr (nb_per_cpy == 2) { 825 ((short *) dst)[i] = ((const short *) src)[i]; 826 } else if constexpr (nb_per_cpy == 4) { 827 ((int *) dst)[i] = ((const int *) src)[i]; 828 } else if constexpr (nb_per_cpy == 8) { 829 ((int2 *) dst)[i] = ((const int2 *) src)[i]; 830 } else if constexpr (nb_per_cpy == 16) { 831 ((int4 *) dst)[i] = ((const int4 *) src)[i]; 832 } else { 833 static_assert(nbytes == 0 && nbytes == -1, "bad nbytes"); 834 } 835 } 836} 837 838static __device__ __forceinline__ float ggml_cuda_e8m0_to_fp32(uint8_t x) { 839#if CUDART_VERSION >= 12080 840 const nv_bfloat16 e = __nv_cvt_e8m0_to_bf16raw(x); 841 return (float) e; 842#else 843 uint32_t bits; 844 if (x == 0) { 845 bits = 0x00400000; 846 } else { 847 bits = (uint32_t) x << 23; 848 } 849 850 float result; 851 memcpy(&result, &bits, sizeof(float)); 852 return result; 853#endif // CUDART_VERSION >= 12050 854} 855 856static __device__ __forceinline__ float ggml_cuda_ue4m3_to_fp32(uint8_t x) { 857#if defined(GGML_USE_HIP) && defined(CDNA3) && defined(FP8_AVAILABLE) && HIP_VERSION >= 60200000 858 // ROCm does not support fp8 in software on devices with fp8 hardware, 859 // but CDNA3 supports only e4m3_fnuz (no inf). 860 const uint32_t bits = x * (x != 0x7F && x != 0xFF); // Convert NaN to 0.0f to match CPU implementation. 861 const __hip_fp8_e4m3_fnuz xf = *reinterpret_cast<const __hip_fp8_e4m3_fnuz *>(&bits); 862 return static_cast<float>(xf) / 2; 863#else 864#if defined(FP8_AVAILABLE) && !defined(GGML_USE_HIP) 865 const uint32_t bits = x * (x != 0x7F && x != 0xFF); // Convert NaN to 0.0f to match CPU implementation. 866 const __nv_fp8_e4m3 xf = *reinterpret_cast<const __nv_fp8_e4m3 *>(&bits); 867 return static_cast<float>(xf) / 2; 868#else 869 if (x == 0 || (x == 0x7F && x != 0xFF)) { // Convert NaN to 0.0f 870 return 0.0f; 871 } 872 const int exp = (x >> 3) & 0xF; 873 const int man = x & 0x7; 874 float raw; 875 if (exp == 0) { 876 raw = ldexpf((float) man, -9); 877 } else { 878 raw = ldexpf(1.0f + (float) man / 8.0f, exp - 7); 879 } 880 return static_cast<float>(raw / 2); 881#endif // defined(FP8_AVAILABLE) && !defined(GGML_USE_HIP) 882#endif // defined(GGML_USE_HIP) && defined(CDNA3) && defined(FP8_AVAILABLE) && HIP_VERSION >= 60200000 883} 884 885static __device__ __forceinline__ uint8_t ggml_cuda_fp32_to_ue4m3(float x) { 886#if defined(BLACKWELL_MMA_AVAILABLE) // This is used for NVFP4 subblock scale quantizations only 887 if (!(x > 0.0f)) { 888 return 0; 889 } 890 const __nv_fp8_e4m3 xf(x); 891 return xf.__x; 892#else 893 NO_DEVICE_CODE; // Used only for NVFP4 Scales for Activations, only for Blackwell 894#endif // defined(BLACKWELL_MMA_AVAILABLE) 895} 896 897__device__ __forceinline__ uint8_t ggml_cuda_float_to_fp4_e2m1(float x, float e) { 898 const uint8_t sign_bit = (x < 0.0f) << 3; 899 float ax = fabsf(x) * e; 900 901 // Positive LUT 902 static constexpr float pos_lut[8] = { 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f }; 903 904 int best_i = 0; 905 float best_err = fabsf(ax - pos_lut[0]); 906 907#pragma unroll 908 for (int i = 1; i < 8; ++i) { 909 const float err = fabsf(ax - pos_lut[i]); 910 if (err < best_err) { 911 best_err = err; 912 best_i = i; 913 } 914 } 915 916 return static_cast<uint8_t>(best_i | sign_bit); 917} 918 919// See https://gmplib.org/~tege/divcnst-pldi94.pdf figure 4.1. 920// Precompute mp (m' in the paper) and L such that division 921// can be computed using a multiply (high 32b of 64b result) 922// and a shift: 923// 924// n/d = (mulhi(n, mp) + n) >> L; 925static const uint3 init_fastdiv_values(uint64_t d_64) { 926 GGML_ASSERT(d_64 != 0); 927 GGML_ASSERT(d_64 <= std::numeric_limits<uint32_t>::max()); 928 929 uint32_t d = (uint32_t)d_64; 930 931 // compute L = ceil(log2(d)); 932 uint32_t L = 0; 933 while (L < 32 && (uint32_t{ 1 } << L) < d) { 934 L++; 935 } 936 937 uint32_t mp = (uint32_t) ((uint64_t{ 1 } << 32) * ((uint64_t{ 1 } << L) - d) / d + 1); 938 // pack divisor as well to reduce error surface 939 return make_uint3(mp, L, d); 940} 941 942static __device__ __forceinline__ uint32_t fastdiv(uint32_t n, const uint3 fastdiv_values) { 943 // expects fastdiv_values to contain <mp, L, divisor> in <x, y, z> 944 // fastdiv_values.z is unused and optimized away by the compiler. 945 // Compute high 32 bits of n * mp 946 const uint32_t hi = __umulhi(n, fastdiv_values.x); 947 // add n, apply bit shift 948 return (hi + n) >> fastdiv_values.y; 949} 950 951static __device__ __forceinline__ uint32_t fastmodulo(uint32_t n, const uint3 fastdiv_values) { 952 // expects fastdiv_values to contain <mp, L, divisor> in <x, y, z> (see init_fastdiv_values) 953 return n - fastdiv(n, fastdiv_values) * fastdiv_values.z; 954} 955 956// Calculate both division and modulo at once, returns <n/divisor, n%divisor> 957static __device__ __forceinline__ uint2 fast_div_modulo(uint32_t n, const uint3 fastdiv_values) { 958 // expects fastdiv_values to contain <mp, L, divisor> in <x, y, z> (see init_fastdiv_values) 959 const uint32_t div_val = fastdiv(n, fastdiv_values); 960 const uint32_t mod_val = n - div_val * fastdiv_values.z; 961 return make_uint2(div_val, mod_val); 962} 963 964typedef void (*dequantize_kernel_t)(const void * vx, const int64_t ib, const int iqs, float2 & v); 965 966template<typename dst_t> 967using dequantize_kq_t = void (*)(const void * vx, const int64_t ib, dst_t * y, const int tid); 968 969static __device__ __forceinline__ float get_alibi_slope( 970 const float max_bias, const uint32_t h, const uint32_t n_head_log2, const float m0, const float m1 971) { 972 if (max_bias <= 0.0f) { 973 return 1.0f; 974 } 975 const float base = h < n_head_log2 ? m0 : m1; 976 const int exph = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1; 977 978 return powf(base, exph); 979} 980 981template <ggml_type type> 982struct ggml_cuda_type_traits; 983 984template<> 985struct ggml_cuda_type_traits<GGML_TYPE_F16> { 986 static constexpr int qk = 1; 987 static constexpr int qr = 1; 988 static constexpr int bs = sizeof(ggml_half); 989}; 990 991template<> 992struct ggml_cuda_type_traits<GGML_TYPE_Q1_0> { 993 static constexpr int qk = QK1_0; 994 static constexpr int qr = QR1_0; 995 static constexpr int qi = QI1_0; 996 static constexpr int bs = sizeof(block_q1_0); 997}; 998 999template<> 1000struct ggml_cuda_type_traits<GGML_TYPE_Q2_0> { 1001 static constexpr int qk = QK2_0; 1002 static constexpr int qr = QR2_0; 1003 static constexpr int qi = QI2_0; 1004 static constexpr int bs = sizeof(block_q2_0); 1005}; 1006 1007template<> 1008struct ggml_cuda_type_traits<GGML_TYPE_Q4_0> { 1009 static constexpr int qk = QK4_0; 1010 static constexpr int qr = QR4_0; 1011 static constexpr int qi = QI4_0; 1012 static constexpr int bs = sizeof(block_q4_0); 1013}; 1014 1015template<> 1016struct ggml_cuda_type_traits<GGML_TYPE_Q4_1> { 1017 static constexpr int qk = QK4_1; 1018 static constexpr int qr = QR4_1; 1019 static constexpr int qi = QI4_1; 1020 static constexpr int bs = sizeof(block_q4_1); 1021}; 1022 1023template<> 1024struct ggml_cuda_type_traits<GGML_TYPE_Q5_0> { 1025 static constexpr int qk = QK5_0; 1026 static constexpr int qr = QR5_0; 1027 static constexpr int qi = QI5_0; 1028 static constexpr int bs = sizeof(block_q5_0); 1029}; 1030 1031template<> 1032struct ggml_cuda_type_traits<GGML_TYPE_Q5_1> { 1033 static constexpr int qk = QK5_1; 1034 static constexpr int qr = QR5_1; 1035 static constexpr int qi = QI5_1; 1036 static constexpr int bs = sizeof(block_q5_1); 1037}; 1038 1039template<> 1040struct ggml_cuda_type_traits<GGML_TYPE_Q8_0> { 1041 static constexpr int qk = QK8_0; 1042 static constexpr int qr = QR8_0; 1043 static constexpr int qi = QI8_0; 1044 static constexpr int bs = sizeof(block_q8_0); 1045}; 1046 1047template<> 1048struct ggml_cuda_type_traits<GGML_TYPE_MXFP4> { 1049 static constexpr int qk = QK_MXFP4; 1050 static constexpr int qr = QR_MXFP4; 1051 static constexpr int qi = QI_MXFP4; 1052 static constexpr int bs = sizeof(block_mxfp4); 1053}; 1054 1055template<> 1056struct ggml_cuda_type_traits<GGML_TYPE_NVFP4> { 1057 static constexpr int qk = QK_NVFP4; 1058 static constexpr int qr = QR_NVFP4; 1059 static constexpr int qi = QI_NVFP4; 1060 static constexpr int bs = sizeof(block_nvfp4); 1061}; 1062 1063template<> 1064struct ggml_cuda_type_traits<GGML_TYPE_Q2_K> { 1065 static constexpr int qk = QK_K; 1066 static constexpr int qr = QR2_K; 1067 static constexpr int qi = QI2_K; 1068 static constexpr int bs = sizeof(block_q2_K); 1069}; 1070 1071template<> 1072struct ggml_cuda_type_traits<GGML_TYPE_Q3_K> { 1073 static constexpr int qk = QK_K; 1074 static constexpr int qr = QR3_K; 1075 static constexpr int qi = QI3_K; 1076 static constexpr int bs = sizeof(block_q3_K); 1077}; 1078 1079template<> 1080struct ggml_cuda_type_traits<GGML_TYPE_Q4_K> { 1081 static constexpr int qk = QK_K; 1082 static constexpr int qr = QR4_K; 1083 static constexpr int qi = QI4_K; 1084 static constexpr int bs = sizeof(block_q4_K); 1085}; 1086 1087template<> 1088struct ggml_cuda_type_traits<GGML_TYPE_Q5_K> { 1089 static constexpr int qk = QK_K; 1090 static constexpr int qr = QR5_K; 1091 static constexpr int qi = QI5_K; 1092 static constexpr int bs = sizeof(block_q5_K); 1093}; 1094 1095template<> 1096struct ggml_cuda_type_traits<GGML_TYPE_Q6_K> { 1097 static constexpr int qk = QK_K; 1098 static constexpr int qr = QR6_K; 1099 static constexpr int qi = QI6_K; 1100 static constexpr int bs = sizeof(block_q6_K); 1101}; 1102 1103template<> 1104struct ggml_cuda_type_traits<GGML_TYPE_IQ2_XXS> { 1105 static constexpr int qk = QK_K; 1106 static constexpr int qr = QR2_XXS; 1107 static constexpr int qi = QI2_XXS; 1108 static constexpr int bs = sizeof(block_iq2_xxs); 1109}; 1110 1111template<> 1112struct ggml_cuda_type_traits<GGML_TYPE_IQ2_XS> { 1113 static constexpr int qk = QK_K; 1114 static constexpr int qr = QR2_XS; 1115 static constexpr int qi = QI2_XS; 1116 static constexpr int bs = sizeof(block_iq2_xs); 1117}; 1118 1119template<> 1120struct ggml_cuda_type_traits<GGML_TYPE_IQ2_S> { 1121 static constexpr int qk = QK_K; 1122 static constexpr int qr = QR2_S; 1123 static constexpr int qi = QI2_S; 1124 static constexpr int bs = sizeof(block_iq2_s); 1125}; 1126 1127template<> 1128struct ggml_cuda_type_traits<GGML_TYPE_IQ3_XXS> { 1129 static constexpr int qk = QK_K; 1130 static constexpr int qr = QR3_XXS; 1131 static constexpr int qi = QI3_XXS; 1132 static constexpr int bs = sizeof(block_iq3_xxs); 1133}; 1134 1135template<> 1136struct ggml_cuda_type_traits<GGML_TYPE_IQ1_S> { 1137 static constexpr int qk = QK_K; 1138 static constexpr int qr = QR1_S; 1139 static constexpr int qi = QI1_S; 1140 static constexpr int bs = sizeof(block_iq1_s); 1141}; 1142 1143template<> 1144struct ggml_cuda_type_traits<GGML_TYPE_IQ1_M> { 1145 static constexpr int qk = QK_K; 1146 static constexpr int qr = QR1_M; 1147 static constexpr int qi = QI1_M; 1148 static constexpr int bs = sizeof(block_iq1_m); 1149}; 1150 1151template<> 1152struct ggml_cuda_type_traits<GGML_TYPE_IQ4_NL> { 1153 static constexpr int qk = QK4_NL; 1154 static constexpr int qr = QR4_NL; 1155 static constexpr int qi = QI4_NL; 1156 static constexpr int bs = sizeof(block_iq4_nl); 1157}; 1158 1159template<> 1160struct ggml_cuda_type_traits<GGML_TYPE_IQ4_XS> { 1161 static constexpr int qk = QK_K; 1162 static constexpr int qr = QR4_XS; 1163 static constexpr int qi = QI4_XS; 1164 static constexpr int bs = sizeof(block_iq4_xs); 1165}; 1166 1167template<> 1168struct ggml_cuda_type_traits<GGML_TYPE_IQ3_S> { 1169 static constexpr int qk = QK_K; 1170 static constexpr int qr = QR3_S; 1171 static constexpr int qi = QI3_S; 1172 static constexpr int bs = sizeof(block_iq3_s); 1173}; 1174 1175////////////////////// 1176 1177struct ggml_cuda_device_info { 1178 int device_count; // number of (possibly virtual) devices exposed to the rest of ggml 1179 int physical_device_count; // number of physical CUDA devices actually present 1180 1181 struct cuda_device_info { 1182 int cc; // compute capability 1183 int nsm; // number of streaming multiprocessors 1184 size_t smpb; // max. shared memory per block 1185 size_t smpbo; // max. shared memory per block (with opt-in) 1186 bool integrated; // Device is integrated as opposed to discrete 1187 bool vmm; // virtual memory support 1188 size_t vmm_granularity; // granularity of virtual memory 1189 size_t total_vram; 1190 int warp_size; // Number of threads in a dispatch 1191 bool supports_cooperative_launch; // whether cooperative launch is supported 1192 int physical_device; // backing physical CUDA device for this (virtual) device 1193 int physical_share_count; // number of (virtual) devices sharing this device's physical GPU 1194 int virtual_index; // index of this (virtual) device among those sharing its physical GPU 1195 }; 1196 1197 cuda_device_info devices[GGML_CUDA_MAX_DEVICES] = {}; 1198 1199 std::array<float, GGML_CUDA_MAX_DEVICES> default_tensor_split = {}; 1200}; 1201 1202const ggml_cuda_device_info & ggml_cuda_info(); 1203 1204void ggml_cuda_set_device(int device); 1205int ggml_cuda_get_device(); 1206 1207struct ggml_cuda_pool { 1208 virtual ~ggml_cuda_pool() = default; 1209 1210 virtual void * alloc(size_t size, size_t * actual_size) = 0; 1211 virtual void free(void * ptr, size_t size) = 0; 1212}; 1213 1214template<typename T> 1215struct ggml_cuda_pool_alloc { 1216 ggml_cuda_pool * pool = nullptr; 1217 T * ptr = nullptr; 1218 size_t actual_size = 0; 1219 1220 ggml_cuda_pool_alloc() = default; 1221 1222 explicit ggml_cuda_pool_alloc(ggml_cuda_pool & pool) : pool(&pool) { 1223 } 1224 1225 ggml_cuda_pool_alloc(ggml_cuda_pool & pool, size_t size) : pool(&pool) { 1226 alloc(size); 1227 } 1228 1229 ~ggml_cuda_pool_alloc() { 1230 if (ptr != nullptr) { 1231 pool->free(ptr, actual_size); 1232 } 1233 } 1234 1235 // size is in number of elements 1236 T * alloc(size_t size) { 1237 GGML_ASSERT(pool != nullptr); 1238 GGML_ASSERT(ptr == nullptr); 1239 ptr = (T *) pool->alloc(size * sizeof(T), &this->actual_size); 1240 return ptr; 1241 } 1242 1243 T * alloc(ggml_cuda_pool & pool, size_t size) { 1244 this->pool = &pool; 1245 return alloc(size); 1246 } 1247 1248 T * get() { 1249 return ptr; 1250 } 1251 1252 ggml_cuda_pool_alloc(const ggml_cuda_pool_alloc &) = delete; 1253 ggml_cuda_pool_alloc(ggml_cuda_pool_alloc &&) = delete; 1254 ggml_cuda_pool_alloc& operator=(const ggml_cuda_pool_alloc &) = delete; 1255 ggml_cuda_pool_alloc& operator=(ggml_cuda_pool_alloc &&) = delete; 1256}; 1257 1258 1259// backend interface 1260 1261struct ggml_tensor_extra_gpu { 1262 void * data_device[GGML_CUDA_MAX_DEVICES]; // 1 pointer for each device for split tensors 1263 cudaEvent_t events[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS]; // events for synchronizing multiple GPUs 1264}; 1265 1266 1267#if (defined(GGML_CUDA_USE_GRAPHS) || defined(GGML_HIP_GRAPHS)) || defined(GGML_MUSA_GRAPHS) 1268#define USE_CUDA_GRAPH 1269#endif 1270 1271struct ggml_cuda_graph { 1272#ifdef USE_CUDA_GRAPH 1273 ~ggml_cuda_graph() { 1274 if (instance != nullptr) { 1275 CUDA_CHECK(cudaGraphExecDestroy(instance)); 1276 } 1277 if (graph != nullptr) { 1278 CUDA_CHECK(cudaGraphDestroy(graph)); 1279 } 1280 } 1281 cudaGraph_t graph = nullptr; 1282 cudaGraphExec_t instance = nullptr; 1283 size_t num_nodes = 0; 1284 std::vector<cudaGraphNode_t> nodes; 1285 bool disable_due_to_gpu_arch = false; 1286 bool warmup_complete = false; 1287 uint64_t uid = 0; 1288 int64_t last_used_time = 0; 1289 struct node_properties { 1290 ggml_tensor node; 1291 void * node_src_data_ptrs[GGML_MAX_SRC]; 1292 int64_t node_src_ne[GGML_MAX_SRC][GGML_MAX_DIMS]; 1293 size_t node_src_nb[GGML_MAX_SRC][GGML_MAX_DIMS]; 1294 }; 1295 std::vector<node_properties> node_props; 1296 1297 bool is_enabled() const { 1298 static const bool disable_cuda_graphs_due_to_env = (getenv("GGML_CUDA_DISABLE_GRAPHS") != nullptr); 1299 return !(disable_due_to_gpu_arch || disable_cuda_graphs_due_to_env); 1300 } 1301#endif 1302}; 1303 1304struct ggml_cuda_concurrent_event { 1305 std::vector<cudaEvent_t> join_events; 1306 cudaEvent_t fork_event = nullptr; 1307 1308 int n_streams = 0; 1309 std::unordered_map<const ggml_tensor *, int> stream_mapping; 1310 1311 // Original order of nodes in this concurrent region (before interleaving) 1312 // Used to restore grouping for fusion within streams 1313 std::vector<const ggml_tensor *> original_order; 1314 1315 const ggml_tensor * join_node; 1316 1317 ggml_cuda_concurrent_event() = default; 1318 1319 ggml_cuda_concurrent_event(const ggml_cuda_concurrent_event &) = delete; 1320 ggml_cuda_concurrent_event & operator=(const ggml_cuda_concurrent_event &) = delete; 1321 1322 explicit ggml_cuda_concurrent_event(int n_streams) : n_streams(n_streams) { 1323 join_events.resize(n_streams); 1324 1325 for (size_t i = 0; i < join_events.size(); ++i) { 1326 CUDA_CHECK(cudaEventCreateWithFlags(&join_events[i], cudaEventDisableTiming)); 1327 } 1328 1329 CUDA_CHECK(cudaEventCreateWithFlags(&fork_event, cudaEventDisableTiming)); 1330 } 1331 1332 ggml_cuda_concurrent_event(ggml_cuda_concurrent_event && other) noexcept 1333 : join_events(std::move(other.join_events)) 1334 , fork_event(other.fork_event) 1335 , n_streams(other.n_streams) 1336 , stream_mapping(std::move(other.stream_mapping)) 1337 , original_order(std::move(other.original_order)) 1338 , join_node(other.join_node) { 1339 other.fork_event = nullptr; 1340 } 1341 1342 // 1. check if any branches write to overlapping memory ranges (except the join node) 1343 // 2. check whether all srcs are either within the branch or outside the nodes covered by ggml_cuda_concurrent_event 1344 // we assume all nodes have the same buffer 1345 bool is_valid() const { 1346 std::vector<std::vector<std::pair<int64_t, int64_t>>> write_ranges; 1347 write_ranges.resize(n_streams); 1348 1349 // get join_node's memory range to exclude from overlap checking. 1350 // multiple nodes can use join_node's buffer; we synchronize on the join node. 1351 const ggml_tensor * join_t = join_node->view_src ? join_node->view_src : join_node; 1352 const int64_t join_start = (int64_t) join_t->data; 1353 const int64_t join_end = join_start + ggml_nbytes(join_t); 1354 1355 for (const auto & [tensor, stream] : stream_mapping) { 1356 const ggml_tensor * t = tensor->view_src ? tensor->view_src : tensor; 1357 const int64_t t_start = (int64_t) t->data; 1358 const int64_t t_end = t_start + ggml_nbytes(t); 1359 1360 // skip tensors that overlap with join_node's buffer. 1361 if ((t_start <= join_start && join_start < t_end) || (join_start <= t_start && t_start < join_end)) { 1362 continue; 1363 } 1364 1365 // concurrent streams begin from 1 1366 write_ranges[stream - 1].emplace_back(t_start, t_end); 1367 } 1368 1369 for (int i = 0; i < n_streams; ++i) { 1370 // sorts first by start then by end of write range 1371 std::sort(write_ranges[i].begin(), write_ranges[i].end()); 1372 } 1373 1374 bool writes_overlap = false; 1375 bool dependent_srcs = false; 1376 for (const auto & [tensor, stream] : stream_mapping) { 1377 const ggml_tensor * t = tensor->view_src ? tensor->view_src : tensor; 1378 const int64_t t_start = (int64_t) t->data; 1379 const int64_t t_end = t_start + ggml_nbytes(t); 1380 1381 // skip tensors that overlap with join_node's buffer 1382 if ((t_start <= join_start && join_start < t_end) || (join_start <= t_start && t_start < join_end)) { 1383 continue; 1384 } 1385 1386 // check if this buffer's write data overlaps with another stream's 1387 std::pair<int64_t, int64_t> data_range = std::make_pair(t_start, t_end); 1388 for (int i = 0; i < n_streams; ++i) { 1389 if (i == stream - 1) { 1390 continue; 1391 } 1392 auto it = std::lower_bound(write_ranges[i].begin(), write_ranges[i].end(), data_range); 1393 1394 if (it != write_ranges[i].end()) { 1395 const std::pair<int64_t, int64_t> & other = *it; 1396 1397 // std::lower_bound returns the first element where other >= data_range (lexicographically). 1398 // This guarantees other.first >= data_range.first. 1399 // Therefore, overlap occurs iff other.first < data_range.second 1400 // (i.e., the other range starts before this range ends). 1401 if (other.first < data_range.second) { 1402 GGML_LOG_DEBUG("Writes overlap for %s", tensor->name); 1403 writes_overlap = true; 1404 break; 1405 } 1406 } 1407 } 1408 1409 //check if all srcs are either in branch or don't have a branch 1410 for (int i = 0; i < GGML_MAX_SRC; ++i) { 1411 if (!tensor->src[i]) { 1412 continue; 1413 } 1414 1415 auto it = stream_mapping.find(tensor->src[i]); 1416 1417 if (it == stream_mapping.end()) { 1418 continue; 1419 } 1420 1421 if (it->second != stream) { 1422 dependent_srcs = true; 1423 break; 1424 } 1425 } 1426 1427 if (dependent_srcs || writes_overlap) { 1428 break; 1429 } 1430 } 1431 1432 return !writes_overlap && !dependent_srcs; 1433 } 1434 1435 ~ggml_cuda_concurrent_event() { 1436 if (fork_event != nullptr) { 1437 CUDA_CHECK(cudaEventDestroy(fork_event)); 1438 } 1439 for (cudaEvent_t e : join_events) { 1440 if (e != nullptr) { 1441 CUDA_CHECK(cudaEventDestroy(e)); 1442 } 1443 } 1444 } 1445}; 1446 1447struct ggml_cuda_stream_context { 1448 std::unordered_map<const ggml_tensor *, ggml_cuda_concurrent_event> concurrent_events; 1449 1450 void reset() { 1451 concurrent_events.clear(); 1452 } 1453}; 1454 1455struct ggml_backend_cuda_context { 1456 int device; 1457 std::string name; 1458 cudaEvent_t copy_event = nullptr; 1459 1460 cudaStream_t streams[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS] = { { nullptr } }; 1461 cublasHandle_t cublas_handles[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS] = {nullptr}; 1462 void * cublas_workspaces[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS] = {nullptr}; 1463 size_t cublas_workspace_sizes[GGML_CUDA_MAX_DEVICES] = {0}; 1464 1465 int curr_stream_no = 0; 1466 1467#ifdef USE_CUDA_GRAPH 1468 // Map from first_node_ptr to cuda_graph - allows multiple graphs per context 1469 // when the computation is split across CPU/GPU (e.g., with --n-cpu-moe) 1470 std::unordered_map<const void *, std::unique_ptr<ggml_cuda_graph>> cuda_graphs; 1471 1472 int64_t last_graph_eviction_sweep = 0; 1473 1474 ggml_cuda_graph * cuda_graph(const void * first_node_ptr) { 1475 const int64_t time_now = ggml_time_us(); 1476 1477 // sweep every 5s, evicting cuda graphs unused for >=10s 1478 if (time_now - last_graph_eviction_sweep >= 5'000'000) { 1479 last_graph_eviction_sweep = time_now; 1480 for (auto it = cuda_graphs.begin(); it != cuda_graphs.end(); ) { 1481 if (time_now - it->second->last_used_time >= 10'000'000) { 1482 it = cuda_graphs.erase(it); 1483 } else { 1484 ++it; 1485 } 1486 } 1487 } 1488 1489 auto it = cuda_graphs.find(first_node_ptr); 1490 if (it == cuda_graphs.end()) { 1491 it = cuda_graphs.emplace(first_node_ptr, std::make_unique<ggml_cuda_graph>()).first; 1492 } 1493 it->second->last_used_time = time_now; 1494 return it->second.get(); 1495 } 1496 1497 // Check if any CUDA graph is enabled for this context (used by kernels that need to know 1498 // if graphs are in use without having access to the specific graph key) 1499 bool any_cuda_graph_enabled() const { 1500 for (const auto & [key, graph] : cuda_graphs) { 1501 if (graph && graph->is_enabled()) { 1502 return true; 1503 } 1504 } 1505 return false; 1506 } 1507 1508 // Check if any CUDA graph has an instance for this context 1509 bool any_cuda_graph_has_instance() const { 1510 for (const auto & [key, graph] : cuda_graphs) { 1511 if (graph && graph->instance != nullptr) { 1512 return true; 1513 } 1514 } 1515 return false; 1516 } 1517#endif // USE_CUDA_GRAPH 1518 1519 explicit ggml_backend_cuda_context(int device) : 1520 device(device), 1521 name(GGML_CUDA_NAME + std::to_string(device)) { 1522 } 1523 1524 ggml_cuda_stream_context concurrent_stream_context; 1525 1526 ~ggml_backend_cuda_context(); 1527 1528 cudaStream_t stream(int device, int stream) { 1529 if (streams[device][stream] == nullptr) { 1530 ggml_cuda_set_device(device); 1531 CUDA_CHECK(cudaStreamCreateWithFlags(&streams[device][stream], cudaStreamNonBlocking)); 1532 } 1533 return streams[device][stream]; 1534 } 1535 1536 cudaStream_t stream() { return stream(device, curr_stream_no); } 1537 1538 ggml_cuda_stream_context & stream_context() { return concurrent_stream_context; } 1539 1540 cublasHandle_t cublas_handle() { 1541 if (cublas_handles[device][curr_stream_no] == nullptr) { 1542 ggml_cuda_set_device(device); 1543 CUBLAS_CHECK(cublasCreate(&cublas_handles[device][curr_stream_no])); 1544 CUBLAS_CHECK(cublasSetMathMode(cublas_handles[device][curr_stream_no], CUBLAS_TF32_TENSOR_OP_MATH)); 1545 CUBLAS_CHECK(cublasSetStream(cublas_handles[device][curr_stream_no], stream())); 1546#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) && (CUBLAS_VER_MAJOR > 11 || (CUBLAS_VER_MAJOR == 11 && CUBLAS_VER_MINOR >= 2)) 1547 if (cublas_workspace_sizes[device] == 0) { 1548 const int cc = ggml_cuda_info().devices[device].cc; 1549 cublas_workspace_sizes[device] = (cc >= GGML_CUDA_CC_HOPPER) ? 32 * 1024 * 1024 : 4 * 1024 * 1024; 1550 } 1551 CUDA_CHECK(cudaMalloc(&cublas_workspaces[device][curr_stream_no], cublas_workspace_sizes[device])); 1552 CUBLAS_CHECK(cublasSetWorkspace(cublas_handles[device][curr_stream_no], cublas_workspaces[device][curr_stream_no], cublas_workspace_sizes[device])); 1553#endif 1554 } 1555 return cublas_handles[device][curr_stream_no]; 1556 } 1557 1558 // pool 1559 std::unique_ptr<ggml_cuda_pool> pools[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS]; 1560 1561 static std::unique_ptr<ggml_cuda_pool> new_pool_for_device(int device, int stream_no); 1562 1563 ggml_cuda_pool & pool(int device) { 1564 if (pools[device][curr_stream_no] == nullptr) { 1565 pools[device][curr_stream_no] = new_pool_for_device(device, curr_stream_no); 1566 } 1567 return *pools[device][curr_stream_no]; 1568 } 1569 1570 ggml_cuda_pool & pool() { 1571 return pool(device); 1572 } 1573}; 1574 1575struct ggml_cuda_mm_fusion_args_host { 1576 const ggml_tensor * x_bias = nullptr; 1577 const ggml_tensor * gate = nullptr; 1578 const ggml_tensor * gate_bias = nullptr; 1579 const ggml_tensor * x_scale = nullptr; 1580 const ggml_tensor * gate_scale = nullptr; 1581 ggml_glu_op glu_op; 1582 float glu_limit = 0.0f; 1583}; 1584struct ggml_cuda_mm_fusion_args_device { 1585 const void * x_bias = nullptr; 1586 const void * gate = nullptr; 1587 const void * gate_bias = nullptr; 1588 const void * x_scale = nullptr; 1589 const void * gate_scale = nullptr; 1590 ggml_glu_op glu_op; 1591 float glu_limit = 0.0f; 1592}; 1593 1594struct ggml_cuda_kernel_launch_params { 1595 dim3 block_nums; 1596 dim3 block_dims; 1597 size_t shmem; 1598 cudaStream_t stream; 1599 1600 // size_t shmem 1601 ggml_cuda_kernel_launch_params(const dim3& block_nums_, const dim3& block_dims_, const size_t shmem_, const cudaStream_t stream_) 1602 : block_nums(block_nums_), block_dims(block_dims_), shmem(shmem_), stream(stream_) {} 1603 1604 // Some call sites pass ints instead of the required size_t. This 2nd constructor casts int->size_t to avoid these -Wnarrowing warnings. 1605 ggml_cuda_kernel_launch_params(const dim3& block_nums_, const dim3& block_dims_, const int shmem_, const cudaStream_t stream_) 1606 : block_nums(block_nums_), block_dims(block_dims_), shmem((size_t)shmem_), stream(stream_) {} 1607}; 1608 1609#if defined(GGML_CUDA_USE_PDL) 1610struct ggml_cuda_pdl_config { 1611 cudaLaunchAttribute attr; 1612 cudaLaunchConfig_t cfg; 1613 1614 ggml_cuda_pdl_config(const ggml_cuda_kernel_launch_params & params) { 1615 attr.id = cudaLaunchAttributeProgrammaticStreamSerialization; 1616 attr.val.programmaticStreamSerializationAllowed = 1; 1617 1618 cfg = {}; 1619 cfg.gridDim = params.block_nums; 1620 cfg.blockDim = params.block_dims; 1621 cfg.dynamicSmemBytes = params.shmem; 1622 cfg.stream = params.stream; 1623 cfg.attrs = &attr; 1624 cfg.numAttrs = 1; 1625 } 1626 1627 // Delete due to &attr 1628 ggml_cuda_pdl_config(const ggml_cuda_pdl_config&) = delete; 1629 ggml_cuda_pdl_config& operator=(const ggml_cuda_pdl_config&) = delete; 1630 ggml_cuda_pdl_config& operator=(ggml_cuda_pdl_config&&) = delete; 1631 1632}; 1633 1634static bool ggml_cuda_kernel_can_use_pdl(const void * kernel) { 1635 const int device = ggml_cuda_get_device(); 1636 1637 struct cache_key { 1638 int device; 1639 const void * kernel; 1640 1641 bool operator==(const cache_key & other) const { return device == other.device && kernel == other.kernel; } 1642 }; 1643 1644 struct cache_key_hash { 1645 // MurmurHash3 mixing function for better hash distribution (vs. just std::hash which in some implementations simply returns the identity) 1646 static size_t hash_mix(size_t x) { 1647 std::uint64_t y = x; 1648 const std::uint64_t m = 0xe9846af9b1a615d; 1649 1650 y ^= y >> 32; 1651 y *= m; 1652 y ^= y >> 32; 1653 y *= m; 1654 y ^= y >> 28; 1655 1656 return static_cast<size_t>(y); 1657 } 1658 1659 size_t operator()(const cache_key & key) const { 1660 // Use a nonzero seed to avoid mapping all-zero keys to zero 1661 size_t h = 42; 1662 h = hash_mix(h + key.device); 1663 h = hash_mix(h + reinterpret_cast<size_t>(key.kernel)); 1664 return h; 1665 } 1666 }; 1667 1668 static std::mutex cache_mutex; 1669 static std::unordered_map<cache_key, bool, cache_key_hash> cache; 1670 1671 const cache_key key = { device, kernel }; 1672 std::lock_guard<std::mutex> lock(cache_mutex); 1673 const auto it = cache.find(key); 1674 if (it != cache.end()) { 1675 return it->second; 1676 } 1677 1678 cudaFuncAttributes attr = {}; 1679 CUDA_CHECK(cudaFuncGetAttributes(&attr, kernel)); 1680 1681 // PDL device-side primitives are emitted only for PTX versions >= 90. 1682 // We have to guard on a loaded kernel's PTX version so a kernel forward-JIT'ed 1683 // from pre-Hopper PTX to a Hopper-or-newer GPU does not opt into PDL. 1684 const bool can_use_pdl = attr.ptxVersion >= 90; 1685 cache.emplace(key, can_use_pdl); 1686 return can_use_pdl; 1687} 1688 1689#endif //defined(GGML_CUDA_USE_PDL) 1690 1691// PDL and __restrict__ need to be mutually exclusive, see https://github.com/ggml-org/llama.cpp/pull/24030 1692# if (defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER) 1693# define GGML_CUDA_RESTRICT 1694# else 1695# define GGML_CUDA_RESTRICT __restrict__ 1696# endif // defined(GGML_CUDA_USE_PDL) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= GGML_CUDA_CC_HOPPER 1697 1698template<typename Kernel, typename... Args> 1699static __inline__ void ggml_cuda_kernel_launch(Kernel kernel, const ggml_cuda_kernel_launch_params & launch_params, Args&&... args) { 1700#if defined(GGML_CUDA_USE_PDL) 1701 1702 static const bool env_pdl_enabled = []() { 1703 const char * env = getenv("GGML_CUDA_PDL"); 1704 return env == nullptr || std::atoi(env) != 0; 1705 }(); 1706 1707 if (env_pdl_enabled && ggml_cuda_kernel_can_use_pdl(reinterpret_cast<const void *>(kernel))) { 1708 auto pdl_cfg = ggml_cuda_pdl_config(launch_params); 1709 1710 CUDA_CHECK(cudaLaunchKernelEx(&pdl_cfg.cfg, kernel, std::forward<Args>(args)... )); 1711 return; 1712 } 1713#endif //defined(GGML_CUDA_USE_PDL) 1714 1715 kernel<<<launch_params.block_nums, launch_params.block_dims, launch_params.shmem, launch_params.stream>>>(std::forward<Args>(args)... ); 1716 CUDA_CHECK(cudaGetLastError()); 1717}