Team Ai
Apppublic

KBaba7/llama.cpp

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
0likes
common.cuh715 linesDownload Raw Back to ggml-cuda
1#pragma once2 3#include "ggml.h"4#include "ggml-cuda.h"5 6#include <cstdint>7#include <memory>8 9#if defined(GGML_USE_HIP)10#define GGML_COMMON_DECL_HIP11#define GGML_COMMON_IMPL_HIP12#else13#define GGML_COMMON_DECL_CUDA14#define GGML_COMMON_IMPL_CUDA15#if defined(GGML_USE_MUSA)16#define GGML_COMMON_DECL_MUSA17#define GGML_COMMON_IMPL_MUSA18#endif19#endif20#include "ggml-common.h"21 22#include <cstdio>23#include <array>24#include <cassert>25#include <cfloat>26#include <string>27#include <vector>28 29#if defined(GGML_USE_HIP)30#include "vendors/hip.h"31#elif defined(GGML_USE_MUSA)32#include "vendors/musa.h"33#else34#include "vendors/cuda.h"35#endif // defined(GGML_USE_HIP)36 37#define STRINGIZE_IMPL(...) #__VA_ARGS__38#define STRINGIZE(...) STRINGIZE_IMPL(__VA_ARGS__)39 40#define WARP_SIZE 3241#define CUDART_HMAX   11070 // CUDA 11.7, min. ver. for which __hmax and __hmax2 are known to work (may be higher than needed)42#define CUDART_HMASK  12000 // CUDA 12.0, min. ver. for half2 -> uint mask comparisons43 44#define GGML_CUDA_CC_PASCAL     60045#define GGML_CUDA_CC_DP4A       610 // minimum compute capability for __dp4a, an intrinsic for byte-wise dot products46#define GGML_CUDA_CC_VOLTA      70047#define GGML_CUDA_CC_TURING     75048#define GGML_CUDA_CC_AMPERE     80049#define GGML_CUDA_CC_OFFSET_AMD 0x100000050 51// GCN/CNDA, wave size is 6452#define GGML_CUDA_CC_GCN4       (GGML_CUDA_CC_OFFSET_AMD + 0x803)  // Tonga, Fiji, Polaris, minimum for fast fp1653#define GGML_CUDA_CC_VEGA       (GGML_CUDA_CC_OFFSET_AMD + 0x900)  // Vega56/64, minimum for fp16 dual issue54#define GGML_CUDA_CC_VEGA20     (GGML_CUDA_CC_OFFSET_AMD + 0x906)  // MI50/Radeon VII, minimum for dp4a55#define GGML_CUDA_CC_CDNA       (GGML_CUDA_CC_OFFSET_AMD + 0x908)  // MI100, minimum for MFMA, acc registers56#define GGML_CUDA_CC_CDNA2      (GGML_CUDA_CC_OFFSET_AMD + 0x910)  // MI210, minimum acc register renameing57#define GGML_CUDA_CC_CDNA3      (GGML_CUDA_CC_OFFSET_AMD + 0x942)  // MI30058 59// RNDA removes MFMA, dp4a, xnack, acc registers, wave size is 3260#define GGML_CUDA_CC_RDNA1      (GGML_CUDA_CC_OFFSET_AMD + 0x1010) // RX 500061#define GGML_CUDA_CC_RDNA2      (GGML_CUDA_CC_OFFSET_AMD + 0x1030) // RX 6000, minimum for dp4a62#define GGML_CUDA_CC_RDNA3      (GGML_CUDA_CC_OFFSET_AMD + 0x1100) // RX 7000, minimum for WMMA63 64#define GGML_CUDA_CC_IS_RDNA(cc)  (cc >= GGML_CUDA_CC_RDNA1)65#define GGML_CUDA_CC_IS_RDNA1(cc) (cc >= GGML_CUDA_CC_RDNA1 && cc < GGML_CUDA_CC_RDNA2)66#define GGML_CUDA_CC_IS_RDNA2(cc) (cc >= GGML_CUDA_CC_RDNA2 && cc < GGML_CUDA_CC_RDNA3)67#define GGML_CUDA_CC_IS_RDNA3(cc) (cc >= GGML_CUDA_CC_RDNA3)68#define GGML_CUDA_CC_IS_GCN(cc)   (cc > GGML_CUDA_CC_OFFSET_AMD && cc < GGML_CUDA_CC_CDNA)69#define GGML_CUDA_CC_IS_CDNA(cc)  (cc >= GGML_CUDA_CC_CDNA && cc < GGML_CUDA_CC_RDNA1)70 71#define GGML_CUDA_CC_QY1        21072#define GGML_CUDA_CC_QY2        22073 74#define MATRIX_ROW_PADDING 512 // last row of quant. matrices is a multiple of this to avoid out-of-bounds memory accesses75 76#if defined(_MSC_VER)77#pragma warning(disable: 4244 4267) // possible loss of data78#endif79 80#define GGML_CUDA_MAX_STREAMS 881 82[[noreturn]]83void ggml_cuda_error(const char * stmt, const char * func, const char * file, int line, const char * msg);84 85#define CUDA_CHECK_GEN(err, success, error_fn)                                      \86     do {                                                                           \87        auto err_ = (err);                                                          \88        if (err_ != (success)) {                                                    \89            ggml_cuda_error(#err, __func__, __FILE__, __LINE__, error_fn(err_));    \90        }                                                                           \91    } while (0)92 93#define CUDA_CHECK(err) CUDA_CHECK_GEN(err, cudaSuccess, cudaGetErrorString)94 95#if CUDART_VERSION >= 12000 || defined(GGML_USE_MUSA)96    static const char * cublas_get_error_str(const cublasStatus_t err) {97        return cublasGetStatusString(err);98    }99#else100    static const char * cublas_get_error_str(const cublasStatus_t err) {101        switch (err) {102            case CUBLAS_STATUS_SUCCESS: return "CUBLAS_STATUS_SUCCESS";103            case CUBLAS_STATUS_NOT_INITIALIZED: return "CUBLAS_STATUS_NOT_INITIALIZED";104            case CUBLAS_STATUS_ALLOC_FAILED: return "CUBLAS_STATUS_ALLOC_FAILED";105            case CUBLAS_STATUS_INVALID_VALUE: return "CUBLAS_STATUS_INVALID_VALUE";106            case CUBLAS_STATUS_ARCH_MISMATCH: return "CUBLAS_STATUS_ARCH_MISMATCH";107            case CUBLAS_STATUS_MAPPING_ERROR: return "CUBLAS_STATUS_MAPPING_ERROR";108            case CUBLAS_STATUS_EXECUTION_FAILED: return "CUBLAS_STATUS_EXECUTION_FAILED";109            case CUBLAS_STATUS_INTERNAL_ERROR: return "CUBLAS_STATUS_INTERNAL_ERROR";110            case CUBLAS_STATUS_NOT_SUPPORTED: return "CUBLAS_STATUS_NOT_SUPPORTED";111            default: return "unknown error";112        }113    }114#endif // CUDART_VERSION >= 12000115 116#define CUBLAS_CHECK(err) CUDA_CHECK_GEN(err, CUBLAS_STATUS_SUCCESS, cublas_get_error_str)117 118#if !defined(GGML_USE_HIP)119static const char * cu_get_error_str(CUresult err) {120    const char * err_str;121    cuGetErrorString(err, &err_str);122    return err_str;123}124#define CU_CHECK(err) CUDA_CHECK_GEN(err, CUDA_SUCCESS, cu_get_error_str)125#endif126 127#if CUDART_VERSION >= 11100 || defined(GGML_USE_MUSA)128#define GGML_CUDA_ASSUME(x) __builtin_assume(x)129#else130#define GGML_CUDA_ASSUME(x)131#endif // CUDART_VERSION >= 11100132 133#ifdef GGML_CUDA_F16134typedef half dfloat; // dequantize float135typedef half2 dfloat2;136#else137typedef float dfloat; // dequantize float138typedef float2 dfloat2;139#endif // GGML_CUDA_F16140 141#if (!defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM)) || (defined(GGML_USE_HIP) && !defined(GGML_HIP_NO_VMM))142#define GGML_USE_VMM143#endif // (!defined(GGML_USE_HIP) && !defined(GGML_CUDA_NO_VMM)) || (defined(GGML_USE_HIP) && !defined(GGML_HIP_NO_VMM))144 145#if (defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) || __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL146#define FP16_AVAILABLE147#endif // (defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) || __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL148 149#if defined(FP16_AVAILABLE) && __CUDA_ARCH__ != 610150#define FAST_FP16_AVAILABLE151#endif // defined(FP16_AVAILABLE) && __CUDA_ARCH__ != 610152 153#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_VOLTA154#define FP16_MMA_AVAILABLE155#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_VOLTA156 157#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_TURING158#define NEW_MMA_AVAILABLE159#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_TURING160 161#if !(defined(GGML_USE_MUSA) && __MUSA_ARCH__ <= GGML_CUDA_CC_QY1)162#define FLASH_ATTN_AVAILABLE163#endif // !(defined(GGML_USE_MUSA) && __MUSA_ARCH__ <= GGML_CUDA_CC_QY1)164 165static constexpr bool fast_fp16_available(const int cc) {166    return cc >= GGML_CUDA_CC_PASCAL && cc != 610;167}168 169// Any FP16 tensor cores are available.170static constexpr bool fp16_mma_available(const int cc) {171    return cc < GGML_CUDA_CC_OFFSET_AMD && cc >= GGML_CUDA_CC_VOLTA;172}173 174// Volta technically had FP16 tensor cores but they work very differently compared to Turing and later.175static constexpr bool new_mma_available(const int cc) {176    return cc < GGML_CUDA_CC_OFFSET_AMD && cc >= GGML_CUDA_CC_TURING;177}178 179static constexpr __device__ int ggml_cuda_get_physical_warp_size() {180#if defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)181    return __AMDGCN_WAVEFRONT_SIZE;182#else183    return 32;184#endif // defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)185}186 187[[noreturn]]188static __device__ void no_device_code(189    const char * file_name, const int line, const char * function_name, const int arch, const char * arch_list) {190 191#if defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)192    printf("%s:%d: ERROR: HIP kernel %s has no device code compatible with HIP arch %d.\n",193           file_name, line, function_name, arch);194    GGML_UNUSED(arch_list);195#else196    printf("%s:%d: ERROR: CUDA kernel %s has no device code compatible with CUDA arch %d. ggml-cuda.cu was compiled for: %s\n",197           file_name, line, function_name, arch, arch_list);198#endif // defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)199    __trap();200 201    GGML_UNUSED(no_device_code); // suppress unused function warning202}203 204#ifdef __CUDA_ARCH__205#define NO_DEVICE_CODE no_device_code(__FILE__, __LINE__, __FUNCTION__, __CUDA_ARCH__, STRINGIZE(__CUDA_ARCH_LIST__))206#else207#define NO_DEVICE_CODE //GGML_ABORT("NO_DEVICE_CODE not valid in host code.")208#endif // __CUDA_ARCH__209 210template<int width = WARP_SIZE>211static __device__ __forceinline__ int warp_reduce_sum(int x) {212#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE213    return __reduce_add_sync(0xffffffff, x);214#else215#pragma unroll216    for (int offset = width/2; offset > 0; offset >>= 1) {217        x += __shfl_xor_sync(0xffffffff, x, offset, width);218    }219    return x;220#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_AMPERE221}222 223template<int width = WARP_SIZE>224static __device__ __forceinline__ float warp_reduce_sum(float x) {225#pragma unroll226    for (int offset = width/2; offset > 0; offset >>= 1) {227        x += __shfl_xor_sync(0xffffffff, x, offset, width);228    }229    return x;230}231 232template<int width = WARP_SIZE>233static __device__ __forceinline__ float2 warp_reduce_sum(float2 a) {234#pragma unroll235    for (int offset = width/2; offset > 0; offset >>= 1) {236        a.x += __shfl_xor_sync(0xffffffff, a.x, offset, width);237        a.y += __shfl_xor_sync(0xffffffff, a.y, offset, width);238    }239    return a;240}241 242template<int width = WARP_SIZE>243static __device__ __forceinline__ half2 warp_reduce_sum(half2 a) {244#ifdef FP16_AVAILABLE245#pragma unroll246    for (int offset = width/2; offset > 0; offset >>= 1) {247        a = __hadd2(a, __shfl_xor_sync(0xffffffff, a, offset, width));248    }249    return a;250 251#else252    NO_DEVICE_CODE;253    return a;254#endif // FP16_AVAILABLE255}256 257template<int width = WARP_SIZE>258static __device__ __forceinline__ float warp_reduce_max(float x) {259#pragma unroll260    for (int offset = width/2; offset > 0; offset >>= 1) {261        x = fmaxf(x, __shfl_xor_sync(0xffffffff, x, offset, width));262    }263    return x;264}265 266static __device__ __forceinline__ half ggml_cuda_hmax(const half a, const half b) {267#ifdef FP16_AVAILABLE268 269#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && CUDART_VERSION < CUDART_HMAX270    return __float2half(fmaxf(__half2float(a), __half2float(b)));271#else272    return __hmax(a, b);273#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && CUDART_VERSION < CUDART_HMAX274 275#else276   NO_DEVICE_CODE;277   GGML_UNUSED(b);278   return a;279#endif // FP16_AVAILABLE280}281 282static __device__ __forceinline__ half2 ggml_cuda_hmax2(const half2 a, const half2 b) {283#if defined(GGML_USE_HIP) && HIP_VERSION >= 50700000284    return half2(__hmax(a.x, b.x), __hmax(a.y, b.y));285#elif !defined(GGML_USE_HIP) && CUDART_VERSION >= CUDART_HMAX286    return __hmax2(a, b);287#elif !defined(GGML_USE_HIP)288    half2 ret;289    reinterpret_cast<half&>(ret.x) = __float2half(fmaxf( __low2float(a),  __low2float(b)));290    reinterpret_cast<half&>(ret.y) = __float2half(fmaxf(__high2float(a), __high2float(b)));291    return ret;292#else293    GGML_UNUSED(a);294    GGML_UNUSED(b);295    NO_DEVICE_CODE;296#endif297}298 299template<int width = WARP_SIZE>300static __device__ __forceinline__ half2 warp_reduce_max(half2 x) {301#if !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL || (defined(GGML_USE_HIP) && HIP_VERSION >= 50700000)302#pragma unroll303   for (int offset = width/2; offset > 0; offset >>= 1) {304       x = ggml_cuda_hmax2(x, __shfl_xor_sync(0xffffffff, x, offset, width));305   }306   return x;307#else308   GGML_UNUSED(x);309   NO_DEVICE_CODE;310#endif // !(defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)) && __CUDA_ARCH__ >= GGML_CUDA_CC_PASCAL || (defined(GGML_USE_HIP) && HIP_VERSION >= 50700000)311}312 313#if CUDART_VERSION < CUDART_HMASK314static __device__ __forceinline__ uint32_t __hgt2_mask(const half2 a, const half2 b) {315    const uint32_t mask_low  = 0x0000FFFF * (float( __low2half(a)) > float( __low2half(b)));316    const uint32_t mask_high = 0xFFFF0000 * (float(__high2half(a)) > float(__high2half(b)));317    return mask_low | mask_high;318}319#endif // CUDART_VERSION < CUDART_HMASK320 321static __device__ __forceinline__ int ggml_cuda_dp4a(const int a, const int b, int c) {322#if defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)323#if defined(__gfx906__) || defined(__gfx908__) || defined(__gfx90a__) || defined(RDNA2)324    c = __builtin_amdgcn_sdot4(a, b, c, false);325#elif defined(RDNA3)326    c = __builtin_amdgcn_sudot4( true, a, true, b, c, false);327#elif defined(__gfx1010__) || defined(__gfx900__)328    int tmp1;329    int tmp2;330    asm("\n \331        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 \332        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 \333        v_add3_u32 %0, %1, %2, %0 \n \334        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 \335        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 \336        v_add3_u32 %0, %1, %2, %0 \n \337        "338        : "+v"(c), "=&v"(tmp1), "=&v"(tmp2)339        : "v"(a), "v"(b)340    );341#else342    const int8x4_t va = reinterpret_cast<const int8x4_t&>(a);343    const int8x4_t vb = reinterpret_cast<const int8x4_t&>(b);344    c += va[0] * vb[0] + va[1] * vb[1] + va[2] * vb[2] + va[3] * vb[3];345#endif346    return c;347 348#else // defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)349 350#if __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A351    return __dp4a(a, b, c);352#else // __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A353    const int8_t * a8 = (const int8_t *) &a;354    const int8_t * b8 = (const int8_t *) &b;355    return c + a8[0]*b8[0] + a8[1]*b8[1] + a8[2]*b8[2] + a8[3]*b8[3];356#endif // __CUDA_ARCH__ >= GGML_CUDA_CC_DP4A357 358#endif // defined(GGML_USE_HIP) && defined(__HIP_PLATFORM_AMD__)359}360 361// TODO: move to ggml-common.h362static constexpr __device__ int8_t kvalues_iq4nl[16] = {-127, -104, -83, -65, -49, -35, -22, -10, 1, 13, 25, 38, 53, 69, 89, 113};363 364typedef void (*dequantize_kernel_t)(const void * vx, const int64_t ib, const int iqs, dfloat2 & v);365 366static __device__ __forceinline__ float get_alibi_slope(367    const float max_bias, const uint32_t h, const uint32_t n_head_log2, const float m0, const float m1368) {369    if (max_bias <= 0.0f) {370        return 1.0f;371    }372    const float base = h < n_head_log2 ? m0 : m1;373    const int   exph = h < n_head_log2 ? h + 1 : 2*(h - n_head_log2) + 1;374 375    return powf(base, exph);376}377 378template <ggml_type type>379struct ggml_cuda_type_traits;380 381template<>382struct ggml_cuda_type_traits<GGML_TYPE_F16> {383    static constexpr int qk = 1;384    static constexpr int qr = 1;385};386 387template<>388struct ggml_cuda_type_traits<GGML_TYPE_Q4_0> {389    static constexpr int qk = QK4_0;390    static constexpr int qr = QR4_0;391    static constexpr int qi = QI4_0;392};393 394template<>395struct ggml_cuda_type_traits<GGML_TYPE_Q4_1> {396    static constexpr int qk = QK4_1;397    static constexpr int qr = QR4_1;398    static constexpr int qi = QI4_1;399};400 401template<>402struct ggml_cuda_type_traits<GGML_TYPE_Q5_0> {403    static constexpr int qk = QK5_0;404    static constexpr int qr = QR5_0;405    static constexpr int qi = QI5_0;406};407 408template<>409struct ggml_cuda_type_traits<GGML_TYPE_Q5_1> {410    static constexpr int qk = QK5_1;411    static constexpr int qr = QR5_1;412    static constexpr int qi = QI5_1;413};414 415template<>416struct ggml_cuda_type_traits<GGML_TYPE_Q8_0> {417    static constexpr int qk = QK8_0;418    static constexpr int qr = QR8_0;419    static constexpr int qi = QI8_0;420};421 422template<>423struct ggml_cuda_type_traits<GGML_TYPE_Q2_K> {424    static constexpr int qk = QK_K;425    static constexpr int qr = QR2_K;426    static constexpr int qi = QI2_K;427};428 429template<>430struct ggml_cuda_type_traits<GGML_TYPE_Q3_K> {431    static constexpr int qk = QK_K;432    static constexpr int qr = QR3_K;433    static constexpr int qi = QI3_K;434};435 436template<>437struct ggml_cuda_type_traits<GGML_TYPE_Q4_K> {438    static constexpr int qk = QK_K;439    static constexpr int qr = QR4_K;440    static constexpr int qi = QI4_K;441};442 443template<>444struct ggml_cuda_type_traits<GGML_TYPE_Q5_K> {445    static constexpr int qk = QK_K;446    static constexpr int qr = QR5_K;447    static constexpr int qi = QI5_K;448};449 450template<>451struct ggml_cuda_type_traits<GGML_TYPE_Q6_K> {452    static constexpr int qk = QK_K;453    static constexpr int qr = QR6_K;454    static constexpr int qi = QI6_K;455};456 457template<>458struct ggml_cuda_type_traits<GGML_TYPE_IQ2_XXS> {459    static constexpr int qk = QK_K;460    static constexpr int qr = QR2_XXS;461    static constexpr int qi = QI2_XXS;462};463 464template<>465struct ggml_cuda_type_traits<GGML_TYPE_IQ2_XS> {466    static constexpr int qk = QK_K;467    static constexpr int qr = QR2_XS;468    static constexpr int qi = QI2_XS;469};470 471template<>472struct ggml_cuda_type_traits<GGML_TYPE_IQ2_S> {473    static constexpr int qk = QK_K;474    static constexpr int qr = QR2_S;475    static constexpr int qi = QI2_S;476};477 478template<>479struct ggml_cuda_type_traits<GGML_TYPE_IQ3_XXS> {480    static constexpr int qk = QK_K;481    static constexpr int qr = QR3_XXS;482    static constexpr int qi = QI3_XXS;483};484 485template<>486struct ggml_cuda_type_traits<GGML_TYPE_IQ1_S> {487    static constexpr int qk = QK_K;488    static constexpr int qr = QR1_S;489    static constexpr int qi = QI1_S;490};491 492template<>493struct ggml_cuda_type_traits<GGML_TYPE_IQ1_M> {494    static constexpr int qk = QK_K;495    static constexpr int qr = QR1_M;496    static constexpr int qi = QI1_M;497};498 499template<>500struct ggml_cuda_type_traits<GGML_TYPE_IQ4_NL> {501    static constexpr int qk = QK4_NL;502    static constexpr int qr = QR4_NL;503    static constexpr int qi = QI4_NL;504};505 506template<>507struct ggml_cuda_type_traits<GGML_TYPE_IQ4_XS> {508    static constexpr int qk = QK_K;509    static constexpr int qr = QR4_XS;510    static constexpr int qi = QI4_XS;511};512 513template<>514struct ggml_cuda_type_traits<GGML_TYPE_IQ3_S> {515    static constexpr int qk = QK_K;516    static constexpr int qr = QR3_S;517    static constexpr int qi = QI3_S;518};519 520//////////////////////521 522struct ggml_cuda_device_info {523    int device_count;524 525    struct cuda_device_info {526        int     cc;                 // compute capability527        int     nsm;                // number of streaming multiprocessors528        size_t  smpb;               // max. shared memory per block529        size_t  smpbo;              // max. shared memory per block (with opt-in)530        bool    vmm;                // virtual memory support531        size_t  vmm_granularity;    // granularity of virtual memory532        size_t  total_vram;533        int     warp_size;          // Number of threads in a dispatch534    };535 536    cuda_device_info devices[GGML_CUDA_MAX_DEVICES] = {};537 538    std::array<float, GGML_CUDA_MAX_DEVICES> default_tensor_split = {};539};540 541const ggml_cuda_device_info & ggml_cuda_info();542 543void ggml_cuda_set_device(int device);544int ggml_cuda_get_device();545 546struct ggml_cuda_pool {547    virtual ~ggml_cuda_pool() = default;548 549    virtual void * alloc(size_t size, size_t * actual_size) = 0;550    virtual void free(void * ptr, size_t size) = 0;551};552 553template<typename T>554struct ggml_cuda_pool_alloc {555    ggml_cuda_pool * pool = nullptr;556    T * ptr = nullptr;557    size_t actual_size = 0;558 559    ggml_cuda_pool_alloc() = default;560 561    explicit ggml_cuda_pool_alloc(ggml_cuda_pool & pool) : pool(&pool) {562    }563 564    ggml_cuda_pool_alloc(ggml_cuda_pool & pool, size_t size) : pool(&pool) {565        alloc(size);566    }567 568    ~ggml_cuda_pool_alloc() {569        if (ptr != nullptr) {570            pool->free(ptr, actual_size);571        }572    }573 574    // size is in number of elements575    T * alloc(size_t size) {576        GGML_ASSERT(pool != nullptr);577        GGML_ASSERT(ptr == nullptr);578        ptr = (T *) pool->alloc(size * sizeof(T), &this->actual_size);579        return ptr;580    }581 582    T * alloc(ggml_cuda_pool & pool, size_t size) {583        this->pool = &pool;584        return alloc(size);585    }586 587    T * get() {588        return ptr;589    }590 591    ggml_cuda_pool_alloc(const ggml_cuda_pool_alloc &) = delete;592    ggml_cuda_pool_alloc(ggml_cuda_pool_alloc &&) = delete;593    ggml_cuda_pool_alloc& operator=(const ggml_cuda_pool_alloc &) = delete;594    ggml_cuda_pool_alloc& operator=(ggml_cuda_pool_alloc &&) = delete;595};596 597 598// backend interface599 600struct ggml_tensor_extra_gpu {601    void * data_device[GGML_CUDA_MAX_DEVICES]; // 1 pointer for each device for split tensors602    cudaEvent_t events[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS]; // events for synchronizing multiple GPUs603};604 605 606#if ((CUDART_VERSION >= 12000) && defined(GGML_CUDA_USE_GRAPHS)) || defined(GGML_HIP_GRAPHS)607#define USE_CUDA_GRAPH608#endif609 610struct ggml_graph_node_properties {611    void * node_address;612    ggml_op node_op;613    int64_t ne[GGML_MAX_DIMS];614    size_t nb[GGML_MAX_DIMS];615    void * src_address[GGML_MAX_SRC];616    int32_t op_params[GGML_MAX_OP_PARAMS / sizeof(int32_t)];617};618 619struct ggml_cuda_graph {620#ifdef USE_CUDA_GRAPH621    ~ggml_cuda_graph() {622        if (instance != nullptr) {623            CUDA_CHECK(cudaGraphExecDestroy(instance));624        }625        if (graph != nullptr) {626            CUDA_CHECK(cudaGraphDestroy(graph));627        }628    }629    cudaGraph_t graph = nullptr;630    cudaGraphExec_t instance = nullptr;631    size_t num_nodes = 0;632    std::vector<cudaGraphNode_t> nodes;633    std::vector<cudaKernelNodeParams> params;634    bool disable_due_to_gpu_arch = false;635    bool disable_due_to_too_many_updates = false;636    bool disable_due_to_failed_graph_capture = false;637    int number_consecutive_updates = 0;638    std::vector<ggml_graph_node_properties> ggml_graph_properties;639    std::vector<char **> updated_kernel_arg;640#endif641};642 643struct ggml_backend_cuda_context {644    int device;645    std::string name;646    cudaEvent_t copy_event = nullptr;647 648    cudaStream_t streams[GGML_CUDA_MAX_DEVICES][GGML_CUDA_MAX_STREAMS] = { { nullptr } };649    cublasHandle_t cublas_handles[GGML_CUDA_MAX_DEVICES] = {nullptr};650 651    std::unique_ptr<ggml_cuda_graph> cuda_graph;652 653    explicit ggml_backend_cuda_context(int device) :654        device(device),655        name(GGML_CUDA_NAME + std::to_string(device)) {656    }657 658    ~ggml_backend_cuda_context() {659        if (copy_event != nullptr) {660            CUDA_CHECK(cudaEventDestroy(copy_event));661        }662        for (int i = 0; i < GGML_CUDA_MAX_DEVICES; ++i) {663            for (int j = 0; j < GGML_CUDA_MAX_STREAMS; ++j) {664                if (streams[i][j] != nullptr) {665                    CUDA_CHECK(cudaStreamDestroy(streams[i][j]));666                }667            }668            if (cublas_handles[i] != nullptr) {669                CUBLAS_CHECK(cublasDestroy(cublas_handles[i]));670            }671        }672    }673 674    cudaStream_t stream(int device, int stream) {675        if (streams[device][stream] == nullptr) {676            ggml_cuda_set_device(device);677            CUDA_CHECK(cudaStreamCreateWithFlags(&streams[device][stream], cudaStreamNonBlocking));678        }679        return streams[device][stream];680    }681 682    cudaStream_t stream() {683        return stream(device, 0);684    }685 686    cublasHandle_t cublas_handle(int device) {687        if (cublas_handles[device] == nullptr) {688            ggml_cuda_set_device(device);689            CUBLAS_CHECK(cublasCreate(&cublas_handles[device]));690            CUBLAS_CHECK(cublasSetMathMode(cublas_handles[device], CUBLAS_TF32_TENSOR_OP_MATH));691        }692        return cublas_handles[device];693    }694 695    cublasHandle_t cublas_handle() {696        return cublas_handle(device);697    }698 699    // pool700    std::unique_ptr<ggml_cuda_pool> pools[GGML_CUDA_MAX_DEVICES];701 702    static std::unique_ptr<ggml_cuda_pool> new_pool_for_device(int device);703 704    ggml_cuda_pool & pool(int device) {705        if (pools[device] == nullptr) {706            pools[device] = new_pool_for_device(device);707        }708        return *pools[device];709    }710 711    ggml_cuda_pool & pool() {712        return pool(device);713    }714};715