| |
| |
| #include "cuda_fp16.h" |
| #include "cuda_bf16.h" |
| #include<stdint.h> |
|
|
| #define GGML_UNUSED(x) (void)(x) |
| #define GGML_CUDA_ASSUME(x) |
|
|
| #ifdef GGML_QKK_64 |
| #define QK_K 64 |
| #define K_SCALE_SIZE 4 |
| #else |
| #define QK_K 256 |
| #define K_SCALE_SIZE 12 |
| #endif |
|
|
| #undef GGML_CUDA_F16 |
| #define GGML_CUDA_DMMV_X 32 |
| #define CUDA_QUANTIZE_BLOCK_SIZE 256 |
| #define CUDA_DEQUANTIZE_BLOCK_SIZE 256 |
| #define CUDA_GET_ROWS_BLOCK_SIZE 256 |
| #define K_QUANTS_PER_ITERATION 2 |
|
|
| typedef uint16_t ggml_fp16_t; |
| typedef float dfloat; |
| typedef float2 dfloat2; |
| typedef void (*dequantize_kernel_t)(const void * vx, const int ib, const int iqs, dfloat2 & v); |
|
|
| static __device__ __forceinline__ float warp_reduce_sum(float x) { |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| x += __shfl_xor_sync(0xffffffff, x, mask, 32); |
| } |
| return x; |
| } |
|
|
| static __device__ __forceinline__ float warp_reduce_max(float x) { |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| x = fmaxf(x, __shfl_xor_sync(0xffffffff, x, mask, 32)); |
| } |
| return x; |
| } |
|
|
| static __device__ __forceinline__ int get_int_from_int8(const int8_t * x8, const int & i32) { |
| const uint16_t * x16 = (const uint16_t *) (x8 + sizeof(int) * i32); |
|
|
| int x32 = 0; |
| x32 |= x16[0] << 0; |
| x32 |= x16[1] << 16; |
|
|
| return x32; |
| } |
|
|
| static __device__ __forceinline__ int get_int_from_uint8(const uint8_t * x8, const int & i32) { |
| const uint16_t * x16 = (const uint16_t *) (x8 + sizeof(int) * i32); |
|
|
| int x32 = 0; |
| x32 |= x16[0] << 0; |
| x32 |= x16[1] << 16; |
|
|
| return x32; |
| } |
|
|
| static __device__ __forceinline__ int get_int_from_int8_aligned(const int8_t * x8, const int & i32) { |
| return *((const int *) (x8 + sizeof(int) * i32)); |
| } |
|
|
| static __device__ __forceinline__ int get_int_from_uint8_aligned(const uint8_t * x8, const int & i32) { |
| return *((const int *) (x8 + sizeof(int) * i32)); |
| } |
|
|
|
|
| #define WARP_SIZE 32 |
| #define CUDART_HMAX 11070 |
|
|
| #define CUDA_CC_PASCAL 600 |
| #define MIN_CC_DP4A 610 |
| #define CUDA_CC_VOLTA 700 |
| #define CC_OFFSET_AMD 1000000 |
| #define CC_RDNA1 (CC_OFFSET_AMD + 1010) |
| #define CC_RDNA2 (CC_OFFSET_AMD + 1030) |
| #define CC_RDNA3 (CC_OFFSET_AMD + 1100) |
|
|
| static __device__ __forceinline__ int ggml_cuda_dp4a(const int a, const int b, int c) { |
| #if __CUDA_ARCH__ >= MIN_CC_DP4A |
| return __dp4a(a, b, c); |
| #else |
| const int8_t * a8 = (const int8_t *) &a; |
| const int8_t * b8 = (const int8_t *) &b; |
| return c + a8[0]*b8[0] + a8[1]*b8[1] + a8[2]*b8[2] + a8[3]*b8[3]; |
| #endif |
| } |
|
|
|
|
| #define MMQ_X_Q4_0_RDNA2 64 |
| #define MMQ_Y_Q4_0_RDNA2 128 |
| #define NWARPS_Q4_0_RDNA2 8 |
| #define MMQ_X_Q4_0_RDNA1 64 |
| #define MMQ_Y_Q4_0_RDNA1 64 |
| #define NWARPS_Q4_0_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q4_0_AMPERE 4 |
| #define MMQ_Y_Q4_0_AMPERE 32 |
| #define NWARPS_Q4_0_AMPERE 4 |
| #else |
| #define MMQ_X_Q4_0_AMPERE 64 |
| #define MMQ_Y_Q4_0_AMPERE 128 |
| #define NWARPS_Q4_0_AMPERE 4 |
| #endif |
| #define MMQ_X_Q4_0_PASCAL 64 |
| #define MMQ_Y_Q4_0_PASCAL 64 |
| #define NWARPS_Q4_0_PASCAL 8 |
|
|
| #define MMQ_X_Q4_1_RDNA2 64 |
| #define MMQ_Y_Q4_1_RDNA2 128 |
| #define NWARPS_Q4_1_RDNA2 8 |
| #define MMQ_X_Q4_1_RDNA1 64 |
| #define MMQ_Y_Q4_1_RDNA1 64 |
| #define NWARPS_Q4_1_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q4_1_AMPERE 4 |
| #define MMQ_Y_Q4_1_AMPERE 32 |
| #define NWARPS_Q4_1_AMPERE 4 |
| #else |
| #define MMQ_X_Q4_1_AMPERE 64 |
| #define MMQ_Y_Q4_1_AMPERE 128 |
| #define NWARPS_Q4_1_AMPERE 4 |
| #endif |
| #define MMQ_X_Q4_1_PASCAL 64 |
| #define MMQ_Y_Q4_1_PASCAL 64 |
| #define NWARPS_Q4_1_PASCAL 8 |
|
|
| #define MMQ_X_Q5_0_RDNA2 64 |
| #define MMQ_Y_Q5_0_RDNA2 128 |
| #define NWARPS_Q5_0_RDNA2 8 |
| #define MMQ_X_Q5_0_RDNA1 64 |
| #define MMQ_Y_Q5_0_RDNA1 64 |
| #define NWARPS_Q5_0_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q5_0_AMPERE 4 |
| #define MMQ_Y_Q5_0_AMPERE 32 |
| #define NWARPS_Q5_0_AMPERE 4 |
| #else |
| #define MMQ_X_Q5_0_AMPERE 128 |
| #define MMQ_Y_Q5_0_AMPERE 64 |
| #define NWARPS_Q5_0_AMPERE 4 |
| #endif |
| #define MMQ_X_Q5_0_PASCAL 64 |
| #define MMQ_Y_Q5_0_PASCAL 64 |
| #define NWARPS_Q5_0_PASCAL 8 |
|
|
| #define MMQ_X_Q5_1_RDNA2 64 |
| #define MMQ_Y_Q5_1_RDNA2 128 |
| #define NWARPS_Q5_1_RDNA2 8 |
| #define MMQ_X_Q5_1_RDNA1 64 |
| #define MMQ_Y_Q5_1_RDNA1 64 |
| #define NWARPS_Q5_1_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q5_1_AMPERE 4 |
| #define MMQ_Y_Q5_1_AMPERE 32 |
| #define NWARPS_Q5_1_AMPERE 4 |
| #else |
| #define MMQ_X_Q5_1_AMPERE 128 |
| #define MMQ_Y_Q5_1_AMPERE 64 |
| #define NWARPS_Q5_1_AMPERE 4 |
| #endif |
| #define MMQ_X_Q5_1_PASCAL 64 |
| #define MMQ_Y_Q5_1_PASCAL 64 |
| #define NWARPS_Q5_1_PASCAL 8 |
|
|
| #define MMQ_X_Q8_0_RDNA2 64 |
| #define MMQ_Y_Q8_0_RDNA2 128 |
| #define NWARPS_Q8_0_RDNA2 8 |
| #define MMQ_X_Q8_0_RDNA1 64 |
| #define MMQ_Y_Q8_0_RDNA1 64 |
| #define NWARPS_Q8_0_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q8_0_AMPERE 4 |
| #define MMQ_Y_Q8_0_AMPERE 32 |
| #define NWARPS_Q8_0_AMPERE 4 |
| #else |
| #define MMQ_X_Q8_0_AMPERE 128 |
| #define MMQ_Y_Q8_0_AMPERE 64 |
| #define NWARPS_Q8_0_AMPERE 4 |
| #endif |
| #define MMQ_X_Q8_0_PASCAL 64 |
| #define MMQ_Y_Q8_0_PASCAL 64 |
| #define NWARPS_Q8_0_PASCAL 8 |
|
|
| #define MMQ_X_Q2_K_RDNA2 64 |
| #define MMQ_Y_Q2_K_RDNA2 128 |
| #define NWARPS_Q2_K_RDNA2 8 |
| #define MMQ_X_Q2_K_RDNA1 128 |
| #define MMQ_Y_Q2_K_RDNA1 32 |
| #define NWARPS_Q2_K_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q2_K_AMPERE 4 |
| #define MMQ_Y_Q2_K_AMPERE 32 |
| #define NWARPS_Q2_K_AMPERE 4 |
| #else |
| #define MMQ_X_Q2_K_AMPERE 64 |
| #define MMQ_Y_Q2_K_AMPERE 128 |
| #define NWARPS_Q2_K_AMPERE 4 |
| #endif |
| #define MMQ_X_Q2_K_PASCAL 64 |
| #define MMQ_Y_Q2_K_PASCAL 64 |
| #define NWARPS_Q2_K_PASCAL 8 |
|
|
| #define MMQ_X_Q3_K_RDNA2 128 |
| #define MMQ_Y_Q3_K_RDNA2 64 |
| #define NWARPS_Q3_K_RDNA2 8 |
| #define MMQ_X_Q3_K_RDNA1 32 |
| #define MMQ_Y_Q3_K_RDNA1 128 |
| #define NWARPS_Q3_K_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q3_K_AMPERE 4 |
| #define MMQ_Y_Q3_K_AMPERE 32 |
| #define NWARPS_Q3_K_AMPERE 4 |
| #else |
| #define MMQ_X_Q3_K_AMPERE 128 |
| #define MMQ_Y_Q3_K_AMPERE 128 |
| #define NWARPS_Q3_K_AMPERE 4 |
| #endif |
| #define MMQ_X_Q3_K_PASCAL 64 |
| #define MMQ_Y_Q3_K_PASCAL 64 |
| #define NWARPS_Q3_K_PASCAL 8 |
|
|
| #define MMQ_X_Q4_K_RDNA2 64 |
| #define MMQ_Y_Q4_K_RDNA2 128 |
| #define NWARPS_Q4_K_RDNA2 8 |
| #define MMQ_X_Q4_K_RDNA1 32 |
| #define MMQ_Y_Q4_K_RDNA1 64 |
| #define NWARPS_Q4_K_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q4_K_AMPERE 4 |
| #define MMQ_Y_Q4_K_AMPERE 32 |
| #define NWARPS_Q4_K_AMPERE 4 |
| #else |
| #define MMQ_X_Q4_K_AMPERE 64 |
| #define MMQ_Y_Q4_K_AMPERE 128 |
| #define NWARPS_Q4_K_AMPERE 4 |
| #endif |
| #define MMQ_X_Q4_K_PASCAL 64 |
| #define MMQ_Y_Q4_K_PASCAL 64 |
| #define NWARPS_Q4_K_PASCAL 8 |
|
|
| #define MMQ_X_Q5_K_RDNA2 64 |
| #define MMQ_Y_Q5_K_RDNA2 128 |
| #define NWARPS_Q5_K_RDNA2 8 |
| #define MMQ_X_Q5_K_RDNA1 32 |
| #define MMQ_Y_Q5_K_RDNA1 64 |
| #define NWARPS_Q5_K_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q5_K_AMPERE 4 |
| #define MMQ_Y_Q5_K_AMPERE 32 |
| #define NWARPS_Q5_K_AMPERE 4 |
| #else |
| #define MMQ_X_Q5_K_AMPERE 64 |
| #define MMQ_Y_Q5_K_AMPERE 128 |
| #define NWARPS_Q5_K_AMPERE 4 |
| #endif |
| #define MMQ_X_Q5_K_PASCAL 64 |
| #define MMQ_Y_Q5_K_PASCAL 64 |
| #define NWARPS_Q5_K_PASCAL 8 |
|
|
| #define MMQ_X_Q6_K_RDNA2 64 |
| #define MMQ_Y_Q6_K_RDNA2 128 |
| #define NWARPS_Q6_K_RDNA2 8 |
| #define MMQ_X_Q6_K_RDNA1 32 |
| #define MMQ_Y_Q6_K_RDNA1 64 |
| #define NWARPS_Q6_K_RDNA1 8 |
| #if defined(CUDA_USE_TENSOR_CORES) |
| #define MMQ_X_Q6_K_AMPERE 4 |
| #define MMQ_Y_Q6_K_AMPERE 32 |
| #define NWARPS_Q6_K_AMPERE 4 |
| #else |
| #define MMQ_X_Q6_K_AMPERE 64 |
| #define MMQ_Y_Q6_K_AMPERE 64 |
| #define NWARPS_Q6_K_AMPERE 4 |
| #endif |
| #define MMQ_X_Q6_K_PASCAL 64 |
| #define MMQ_Y_Q6_K_PASCAL 64 |
| #define NWARPS_Q6_K_PASCAL 8 |
|
|
|
|
| |
| |
| |
|
|
| #define QK4_0 32 |
| #define QR4_0 2 |
| #define QI4_0 (QK4_0 / (4 * QR4_0)) |
| typedef struct { |
| half d; |
| uint8_t qs[QK4_0 / 2]; |
| } block_q4_0; |
| static_assert(sizeof(block_q4_0) == sizeof(ggml_fp16_t) + QK4_0 / 2, "wrong q4_0 block size/padding"); |
|
|
| #define QK4_1 32 |
| #define QR4_1 2 |
| #define QI4_1 (QK4_1 / (4 * QR4_1)) |
| typedef struct { |
| half2 dm; |
| uint8_t qs[QK4_1 / 2]; |
| } block_q4_1; |
| static_assert(sizeof(block_q4_1) == sizeof(ggml_fp16_t) * 2 + QK4_1 / 2, "wrong q4_1 block size/padding"); |
|
|
| #define QK5_0 32 |
| #define QR5_0 2 |
| #define QI5_0 (QK5_0 / (4 * QR5_0)) |
| typedef struct { |
| half d; |
| uint8_t qh[4]; |
| uint8_t qs[QK5_0 / 2]; |
| } block_q5_0; |
| static_assert(sizeof(block_q5_0) == sizeof(ggml_fp16_t) + sizeof(uint32_t) + QK5_0 / 2, "wrong q5_0 block size/padding"); |
|
|
| #define QK5_1 32 |
| #define QR5_1 2 |
| #define QI5_1 (QK5_1 / (4 * QR5_1)) |
| typedef struct { |
| half2 dm; |
| uint8_t qh[4]; |
| uint8_t qs[QK5_1 / 2]; |
| } block_q5_1; |
| static_assert(sizeof(block_q5_1) == 2 * sizeof(ggml_fp16_t) + sizeof(uint32_t) + QK5_1 / 2, "wrong q5_1 block size/padding"); |
|
|
| #define QK8_0 32 |
| #define QR8_0 1 |
| #define QI8_0 (QK8_0 / (4 * QR8_0)) |
| typedef struct { |
| half d; |
| int8_t qs[QK8_0]; |
| } block_q8_0; |
| static_assert(sizeof(block_q8_0) == sizeof(ggml_fp16_t) + QK8_0, "wrong q8_0 block size/padding"); |
|
|
| #define QK8_1 32 |
| #define QR8_1 1 |
| #define QI8_1 (QK8_1 / (4 * QR8_1)) |
| typedef struct { |
| half2 ds; |
| int8_t qs[QK8_0]; |
| } block_q8_1; |
| static_assert(sizeof(block_q8_1) == 2*sizeof(ggml_fp16_t) + QK8_0, "wrong q8_1 block size/padding"); |
|
|
| typedef float (*vec_dot_q_cuda_t)(const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs); |
| typedef void (*allocate_tiles_cuda_t)(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc); |
| typedef void (*load_tiles_cuda_t)( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row); |
| typedef float (*vec_dot_q_mul_mat_cuda_t)( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ms, const int & i, const int & j, const int & k); |
|
|
| #define QR2_K 4 |
| #define QI2_K (QK_K / (4*QR2_K)) |
| typedef struct { |
| uint8_t scales[QK_K/16]; |
| uint8_t qs[QK_K/4]; |
| half2 dm; |
| } block_q2_K; |
| static_assert(sizeof(block_q2_K) == 2*sizeof(ggml_fp16_t) + QK_K/16 + QK_K/4, "wrong q2_K block size/padding"); |
|
|
| #define QR3_K 4 |
| #define QI3_K (QK_K / (4*QR3_K)) |
| typedef struct { |
| uint8_t hmask[QK_K/8]; |
| uint8_t qs[QK_K/4]; |
| #ifdef GGML_QKK_64 |
| uint8_t scales[2]; |
| #else |
| uint8_t scales[K_SCALE_SIZE]; |
| #endif |
| half d; |
| } block_q3_K; |
| |
|
|
| #define QR4_K 2 |
| #define QI4_K (QK_K / (4*QR4_K)) |
| #ifdef GGML_QKK_64 |
| typedef struct { |
| half dm[2]; |
| uint8_t scales[2]; |
| uint8_t qs[QK_K/2]; |
| } block_q4_K; |
| static_assert(sizeof(block_q4_K) == sizeof(half2) + QK_K/2 + 2, "wrong q4_K block size/padding"); |
| #else |
| typedef struct { |
| half2 dm; |
| uint8_t scales[3*QK_K/64]; |
| uint8_t qs[QK_K/2]; |
| } block_q4_K; |
| static_assert(sizeof(block_q4_K) == 2*sizeof(ggml_fp16_t) + 3*QK_K/64 + QK_K/2, "wrong q4_K block size/padding"); |
| #endif |
|
|
| #define QR5_K 2 |
| #define QI5_K (QK_K / (4*QR5_K)) |
| #ifdef GGML_QKK_64 |
| typedef struct { |
| half d; |
| int8_t scales[QK_K/16]; |
| uint8_t qh[QK_K/8]; |
| uint8_t qs[QK_K/2]; |
| } block_q5_K; |
| static_assert(sizeof(block_q5_K) == sizeof(ggml_fp16_t) + QK_K/2 + QK_K/8 + QK_K/16, "wrong q5_K block size/padding"); |
| #else |
| typedef struct { |
| half2 dm; |
| uint8_t scales[K_SCALE_SIZE]; |
| uint8_t qh[QK_K/8]; |
| uint8_t qs[QK_K/2]; |
| } block_q5_K; |
| static_assert(sizeof(block_q5_K) == 2*sizeof(ggml_fp16_t) + K_SCALE_SIZE + QK_K/2 + QK_K/8, "wrong q5_K block size/padding"); |
| #endif |
|
|
| #define QR6_K 2 |
| #define QI6_K (QK_K / (4*QR6_K)) |
| typedef struct { |
| uint8_t ql[QK_K/2]; |
| uint8_t qh[QK_K/4]; |
| int8_t scales[QK_K/16]; |
| half d; |
| } block_q6_K; |
| static_assert(sizeof(block_q6_K) == sizeof(ggml_fp16_t) + 13*QK_K/16, "wrong q6_K block size/padding"); |
|
|
| |
| typedef struct { |
| float d; |
| int8_t qs[QK_K]; |
| int16_t bsums[QK_K/16]; |
| } block_q8_K; |
| static_assert(sizeof(block_q8_K) == sizeof(float) + QK_K + QK_K/16*sizeof(int16_t), "wrong q8_K block size/padding"); |
|
|
|
|
| template <int qk, int qr, int qi, bool need_sum, typename block_q_t, int mmq_x, int mmq_y, int nwarps, |
| allocate_tiles_cuda_t allocate_tiles, load_tiles_cuda_t load_tiles, int vdr, vec_dot_q_mul_mat_cuda_t vec_dot> |
| static __device__ __forceinline__ void mul_mat_q( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
|
|
| const block_q_t * x = (const block_q_t *) vx; |
| const block_q8_1 * y = (const block_q8_1 *) vy; |
|
|
| const int blocks_per_row_x = ncols_x / qk; |
| const int blocks_per_col_y = nrows_y / QK8_1; |
| const int blocks_per_warp = WARP_SIZE / qi; |
|
|
| const int & ncols_dst = ncols_y; |
|
|
| const int row_dst_0 = blockIdx.x*mmq_y; |
| const int & row_x_0 = row_dst_0; |
|
|
| const int col_dst_0 = blockIdx.y*mmq_x; |
| const int & col_y_0 = col_dst_0; |
|
|
| int * tile_x_ql = nullptr; |
| half2 * tile_x_dm = nullptr; |
| int * tile_x_qh = nullptr; |
| int * tile_x_sc = nullptr; |
|
|
| allocate_tiles(&tile_x_ql, &tile_x_dm, &tile_x_qh, &tile_x_sc); |
|
|
| __shared__ int tile_y_qs[mmq_x * WARP_SIZE]; |
| __shared__ half2 tile_y_ds[mmq_x * WARP_SIZE/QI8_1]; |
|
|
| float sum[mmq_y/WARP_SIZE][mmq_x/nwarps] = {{0.0f}}; |
|
|
| for (int ib0 = 0; ib0 < blocks_per_row_x; ib0 += blocks_per_warp) { |
|
|
| load_tiles(x + row_x_0*blocks_per_row_x + ib0, tile_x_ql, tile_x_dm, tile_x_qh, tile_x_sc, |
| threadIdx.y, nrows_x-row_x_0-1, threadIdx.x, blocks_per_row_x); |
|
|
| #pragma unroll |
| for (int ir = 0; ir < qr; ++ir) { |
| const int kqs = ir*WARP_SIZE + threadIdx.x; |
| const int kbxd = kqs / QI8_1; |
|
|
| #pragma unroll |
| for (int i = 0; i < mmq_x; i += nwarps) { |
| const int col_y_eff = min(col_y_0 + threadIdx.y + i, ncols_y-1); |
|
|
| const block_q8_1 * by0 = &y[col_y_eff*blocks_per_col_y + ib0 * (qk/QK8_1) + kbxd]; |
|
|
| const int index_y = (threadIdx.y + i) * WARP_SIZE + kqs % WARP_SIZE; |
| tile_y_qs[index_y] = get_int_from_int8_aligned(by0->qs, threadIdx.x % QI8_1); |
| } |
|
|
| #pragma unroll |
| for (int ids0 = 0; ids0 < mmq_x; ids0 += nwarps * QI8_1) { |
| const int ids = (ids0 + threadIdx.y * QI8_1 + threadIdx.x / (WARP_SIZE/QI8_1)) % mmq_x; |
| const int kby = threadIdx.x % (WARP_SIZE/QI8_1); |
| const int col_y_eff = min(col_y_0 + ids, ncols_y-1); |
|
|
| |
| const half2 * dsi_src = &y[col_y_eff*blocks_per_col_y + ib0 * (qk/QK8_1) + ir*(WARP_SIZE/QI8_1) + kby].ds; |
| half2 * dsi_dst = &tile_y_ds[ids * (WARP_SIZE/QI8_1) + kby]; |
| if (need_sum) { |
| *dsi_dst = *dsi_src; |
| } else { |
| float * dfi_dst = (float *) dsi_dst; |
| *dfi_dst = __low2half(*dsi_src); |
| } |
| } |
|
|
| __syncthreads(); |
|
|
| |
| for (int k = ir*WARP_SIZE/qr; k < (ir+1)*WARP_SIZE/qr; k += vdr) { |
| #pragma unroll |
| for (int j = 0; j < mmq_x; j += nwarps) { |
| #pragma unroll |
| for (int i = 0; i < mmq_y; i += WARP_SIZE) { |
| sum[i/WARP_SIZE][j/nwarps] += vec_dot( |
| tile_x_ql, tile_x_dm, tile_x_qh, tile_x_sc, tile_y_qs, tile_y_ds, |
| threadIdx.x + i, threadIdx.y + j, k); |
| } |
| } |
| } |
|
|
| __syncthreads(); |
| } |
| } |
|
|
| #pragma unroll |
| for (int j = 0; j < mmq_x; j += nwarps) { |
| const int col_dst = col_dst_0 + j + threadIdx.y; |
|
|
| if (col_dst >= ncols_dst) { |
| return; |
| } |
|
|
| #pragma unroll |
| for (int i = 0; i < mmq_y; i += WARP_SIZE) { |
| const int row_dst = row_dst_0 + threadIdx.x + i; |
|
|
| if (row_dst >= nrows_dst) { |
| continue; |
| } |
|
|
| dst[col_dst*nrows_dst + row_dst] = sum[i/WARP_SIZE][j/nwarps]; |
| } |
| } |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q4_0( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| (void)x_qh; (void)x_sc; |
|
|
| const int kbx = k / QI4_0; |
| const int kqsx = k % QI4_0; |
|
|
| const block_q4_0 * bx0 = (const block_q4_0 *) vx; |
|
|
| float * x_dmf = (float *) x_dm; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_0 * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_uint8(bxi->qs, kqsx); |
| |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI4_0; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI4_0) { |
| int i = i0 + i_offset * QI4_0 + k / blocks_per_tile_x_row; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_0 * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dmf[i * (WARP_SIZE/QI4_0) + i / QI4_0 + kbxd] = bxi->d; |
| } |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q4_1( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI4_1; |
| const int kqsx = k % QI4_1; |
|
|
| const block_q4_1 * bx0 = (const block_q4_1 *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_1 * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_uint8_aligned(bxi->qs, kqsx); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI4_1; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI4_1) { |
| int i = i0 + i_offset * QI4_1 + k / blocks_per_tile_x_row; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_1 * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dm[i * (WARP_SIZE/QI4_1) + i / QI4_1 + kbxd] = bxi->dm; |
| } |
| } |
|
|
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q4_0(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| (void)x_qh; (void)x_sc; |
|
|
| __shared__ int tile_x_qs[mmq_y * (WARP_SIZE) + mmq_y]; |
| __shared__ float tile_x_d[mmq_y * (WARP_SIZE/QI4_0) + mmq_y/QI4_0]; |
|
|
| *x_ql = tile_x_qs; |
| *x_dm = (half2 *) tile_x_d; |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q4_1(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| __shared__ int tile_x_qs[mmq_y * (WARP_SIZE) + + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI4_1) + mmq_y/QI4_1]; |
|
|
| *x_ql = tile_x_qs; |
| *x_dm = tile_x_dm; |
| } |
|
|
| static __device__ __forceinline__ void dequantize_q4_0(const void * vx, const int ib, const int iqs, dfloat2 & v){ |
| const block_q4_0 * x = (const block_q4_0 *) vx; |
|
|
| const dfloat d = x[ib].d; |
|
|
| const int vui = x[ib].qs[iqs]; |
|
|
| v.x = vui & 0xF; |
| v.y = vui >> 4; |
|
|
| #ifdef GGML_CUDA_F16 |
| v = __hsub2(v, {8.0f, 8.0f}); |
| v = __hmul2(v, {d, d}); |
| #else |
| v.x = (v.x - 8.0f) * d; |
| v.y = (v.y - 8.0f) * d; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ void dequantize_q4_1(const void * vx, const int ib, const int iqs, dfloat2 & v){ |
| const block_q4_1 * x = (const block_q4_1 *) vx; |
|
|
| const dfloat d = __low2half(x[ib].dm); |
| const dfloat m = __high2half(x[ib].dm); |
|
|
| const int vui = x[ib].qs[iqs]; |
|
|
| v.x = vui & 0xF; |
| v.y = vui >> 4; |
|
|
| #ifdef GGML_CUDA_F16 |
| v = __hmul2(v, {d, d}); |
| v = __hadd2(v, {m, m}); |
| #else |
| v.x = (v.x * d) + m; |
| v.y = (v.y * d) + m; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ void dequantize_q5_0(const void * vx, const int ib, const int iqs, dfloat2 & v){ |
| const block_q5_0 * x = (const block_q5_0 *) vx; |
|
|
| const dfloat d = x[ib].d; |
|
|
| uint32_t qh; |
| memcpy(&qh, x[ib].qh, sizeof(qh)); |
|
|
| const int xh_0 = ((qh >> (iqs + 0)) << 4) & 0x10; |
| const int xh_1 = ((qh >> (iqs + 12)) ) & 0x10; |
|
|
| v.x = ((x[ib].qs[iqs] & 0xf) | xh_0); |
| v.y = ((x[ib].qs[iqs] >> 4) | xh_1); |
|
|
| #ifdef GGML_CUDA_F16 |
| v = __hsub2(v, {16.0f, 16.0f}); |
| v = __hmul2(v, {d, d}); |
| #else |
| v.x = (v.x - 16.0f) * d; |
| v.y = (v.y - 16.0f) * d; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ void dequantize_q5_1(const void * vx, const int ib, const int iqs, dfloat2 & v){ |
| const block_q5_1 * x = (const block_q5_1 *) vx; |
|
|
| const dfloat d = __low2half(x[ib].dm); |
| const dfloat m = __high2half(x[ib].dm); |
|
|
| uint32_t qh; |
| memcpy(&qh, x[ib].qh, sizeof(qh)); |
|
|
| const int xh_0 = ((qh >> (iqs + 0)) << 4) & 0x10; |
| const int xh_1 = ((qh >> (iqs + 12)) ) & 0x10; |
|
|
| v.x = ((x[ib].qs[iqs] & 0xf) | xh_0); |
| v.y = ((x[ib].qs[iqs] >> 4) | xh_1); |
|
|
| #ifdef GGML_CUDA_F16 |
| v = __hmul2(v, {d, d}); |
| v = __hadd2(v, {m, m}); |
| #else |
| v.x = (v.x * d) + m; |
| v.y = (v.y * d) + m; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ void dequantize_q8_0(const void * vx, const int ib, const int iqs, dfloat2 & v){ |
| const block_q8_0 * x = (const block_q8_0 *) vx; |
|
|
| const dfloat d = x[ib].d; |
|
|
| v.x = x[ib].qs[iqs + 0]; |
| v.y = x[ib].qs[iqs + 1]; |
|
|
| #ifdef GGML_CUDA_F16 |
| v = __hmul2(v, {d, d}); |
| #else |
| v.x *= d; |
| v.y *= d; |
| #endif |
| } |
|
|
|
|
| template <int qk, int qr, dequantize_kernel_t dequantize_kernel, typename dst_t> |
| static __device__ void dequantize_block(const void * __restrict__ vx, dst_t * __restrict__ y, const int k) { |
| const int i = 2*(blockDim.x*blockIdx.x + threadIdx.x); |
|
|
| if (i >= k) { |
| return; |
| } |
|
|
| const int ib = i/qk; |
| const int iqs = (i%qk)/qr; |
| const int iybs = i - i%qk; |
| const int y_offset = qr == 1 ? 1 : qk/2; |
|
|
| |
| dfloat2 v; |
| dequantize_kernel(vx, ib, iqs, v); |
|
|
| y[iybs + iqs + 0] = v.x; |
| y[iybs + iqs + y_offset] = v.y; |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q4_0(const void * __restrict__ vx, dst_t * __restrict__ yy, int nb32) { |
|
|
| const int64_t i = blockIdx.x; |
|
|
| |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int64_t ib = 8*i + ir; |
| if (ib >= nb32) { |
| return; |
| } |
|
|
| dst_t * y = yy + 256*i + 32*ir + 4*il; |
|
|
| const block_q4_0 * x = (const block_q4_0 *)vx + ib; |
| const float d = __half2float(x->d); |
| const float dm = -8*d; |
|
|
| const uint8_t * q = x->qs + 4*il; |
|
|
| for (int l = 0; l < 4; ++l) { |
| y[l+ 0] = d * (q[l] & 0xF) + dm; |
| y[l+16] = d * (q[l] >> 4) + dm; |
| } |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q4_1(const void * __restrict__ vx, dst_t * __restrict__ yy, int nb32) { |
|
|
| const int64_t i = blockIdx.x; |
|
|
| |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int64_t ib = 8*i + ir; |
| if (ib >= nb32) { |
| return; |
| } |
|
|
| dst_t * y = yy + 256*i + 32*ir + 4*il; |
|
|
| const block_q4_1 * x = (const block_q4_1 *)vx + ib; |
| const float2 d = __half22float2(x->dm); |
|
|
| const uint8_t * q = x->qs + 4*il; |
|
|
| for (int l = 0; l < 4; ++l) { |
| y[l+ 0] = d.x * (q[l] & 0xF) + d.y; |
| y[l+16] = d.x * (q[l] >> 4) + d.y; |
| } |
| } |
|
|
| |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q2_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
|
|
| const int i = blockIdx.x; |
| const block_q2_K * x = (const block_q2_K *) vx; |
|
|
| const int tid = threadIdx.x; |
| #if QK_K == 256 |
| const int n = tid/32; |
| const int l = tid - 32*n; |
| const int is = 8*n + l/16; |
|
|
| const uint8_t q = x[i].qs[32*n + l]; |
| dst_t * y = yy + i*QK_K + 128*n; |
|
|
| float dall = __low2half(x[i].dm); |
| float dmin = __high2half(x[i].dm); |
| y[l+ 0] = dall * (x[i].scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x[i].scales[is+0] >> 4); |
| y[l+32] = dall * (x[i].scales[is+2] & 0xF) * ((q >> 2) & 3) - dmin * (x[i].scales[is+2] >> 4); |
| y[l+64] = dall * (x[i].scales[is+4] & 0xF) * ((q >> 4) & 3) - dmin * (x[i].scales[is+4] >> 4); |
| y[l+96] = dall * (x[i].scales[is+6] & 0xF) * ((q >> 6) & 3) - dmin * (x[i].scales[is+6] >> 4); |
| #else |
| const int is = tid/16; |
| const int il = tid%16; |
| const uint8_t q = x[i].qs[il] >> (2*is); |
| dst_t * y = yy + i*QK_K + 16*is + il; |
| float dall = __low2half(x[i].dm); |
| float dmin = __high2half(x[i].dm); |
| y[ 0] = dall * (x[i].scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x[i].scales[is+0] >> 4); |
| y[32] = dall * (x[i].scales[is+2] & 0xF) * ((q >> 4) & 3) - dmin * (x[i].scales[is+2] >> 4); |
| #endif |
|
|
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q3_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
|
|
| const int i = blockIdx.x; |
| const block_q3_K * x = (const block_q3_K *) vx; |
|
|
| #if QK_K == 256 |
| const int r = threadIdx.x/4; |
| const int tid = r/2; |
| const int is0 = r%2; |
| const int l0 = 16*is0 + 4*(threadIdx.x%4); |
| const int n = tid / 4; |
| const int j = tid - 4*n; |
|
|
| uint8_t m = 1 << (4*n + j); |
| int is = 8*n + 2*j + is0; |
| int shift = 2*j; |
|
|
| int8_t us = is < 4 ? (x[i].scales[is-0] & 0xF) | (((x[i].scales[is+8] >> 0) & 3) << 4) : |
| is < 8 ? (x[i].scales[is-0] & 0xF) | (((x[i].scales[is+4] >> 2) & 3) << 4) : |
| is < 12 ? (x[i].scales[is-8] >> 4) | (((x[i].scales[is+0] >> 4) & 3) << 4) : |
| (x[i].scales[is-8] >> 4) | (((x[i].scales[is-4] >> 6) & 3) << 4); |
| float d_all = x[i].d; |
| float dl = d_all * (us - 32); |
|
|
| dst_t * y = yy + i*QK_K + 128*n + 32*j; |
| const uint8_t * q = x[i].qs + 32*n; |
| const uint8_t * hm = x[i].hmask; |
|
|
| for (int l = l0; l < l0+4; ++l) y[l] = dl * ((int8_t)((q[l] >> shift) & 3) - ((hm[l] & m) ? 0 : 4)); |
| #else |
| const int tid = threadIdx.x; |
| const int is = tid/16; |
| const int il = tid%16; |
| const int im = il/8; |
| const int in = il%8; |
|
|
| dst_t * y = yy + i*QK_K + 16*is + il; |
|
|
| const uint8_t q = x[i].qs[il] >> (2*is); |
| const uint8_t h = x[i].hmask[in] >> (2*is + im); |
| const float d = (float)x[i].d; |
|
|
| if (is == 0) { |
| y[ 0] = d * ((x[i].scales[0] & 0xF) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4)); |
| y[32] = d * ((x[i].scales[1] & 0xF) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4)); |
| } else { |
| y[ 0] = d * ((x[i].scales[0] >> 4) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4)); |
| y[32] = d * ((x[i].scales[1] >> 4) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4)); |
| } |
| #endif |
|
|
| } |
|
|
| #if QK_K == 256 |
| static inline __device__ void get_scale_min_k4(int j, const uint8_t * q, uint8_t & d, uint8_t & m) { |
| if (j < 4) { |
| d = q[j] & 63; m = q[j + 4] & 63; |
| } else { |
| d = (q[j+4] & 0xF) | ((q[j-4] >> 6) << 4); |
| m = (q[j+4] >> 4) | ((q[j-0] >> 6) << 4); |
| } |
| } |
| #endif |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q4_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
| const block_q4_K * x = (const block_q4_K *) vx; |
|
|
| const int i = blockIdx.x; |
|
|
| #if QK_K == 256 |
| |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int is = 2*il; |
| const int n = 4; |
|
|
| dst_t * y = yy + i*QK_K + 64*il + n*ir; |
|
|
| const float dall = __low2half(x[i].dm); |
| const float dmin = __high2half(x[i].dm); |
|
|
| const uint8_t * q = x[i].qs + 32*il + n*ir; |
|
|
| uint8_t sc, m; |
| get_scale_min_k4(is + 0, x[i].scales, sc, m); |
| const float d1 = dall * sc; const float m1 = dmin * m; |
| get_scale_min_k4(is + 1, x[i].scales, sc, m); |
| const float d2 = dall * sc; const float m2 = dmin * m; |
| for (int l = 0; l < n; ++l) { |
| y[l + 0] = d1 * (q[l] & 0xF) - m1; |
| y[l +32] = d2 * (q[l] >> 4) - m2; |
| } |
| #else |
| const int tid = threadIdx.x; |
| const uint8_t * q = x[i].qs; |
| dst_t * y = yy + i*QK_K; |
| const float d = (float)x[i].dm[0]; |
| const float m = (float)x[i].dm[1]; |
| y[tid+ 0] = d * (x[i].scales[0] & 0xF) * (q[tid] & 0xF) - m * (x[i].scales[0] >> 4); |
| y[tid+32] = d * (x[i].scales[1] & 0xF) * (q[tid] >> 4) - m * (x[i].scales[1] >> 4); |
| #endif |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q5_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
| const block_q5_K * x = (const block_q5_K *) vx; |
|
|
| const int i = blockIdx.x; |
|
|
| #if QK_K == 256 |
| |
| const int tid = threadIdx.x; |
| const int il = tid/16; |
| const int ir = tid%16; |
| const int is = 2*il; |
|
|
| dst_t * y = yy + i*QK_K + 64*il + 2*ir; |
|
|
| const float dall = __low2half(x[i].dm); |
| const float dmin = __high2half(x[i].dm); |
|
|
| const uint8_t * ql = x[i].qs + 32*il + 2*ir; |
| const uint8_t * qh = x[i].qh + 2*ir; |
|
|
| uint8_t sc, m; |
| get_scale_min_k4(is + 0, x[i].scales, sc, m); |
| const float d1 = dall * sc; const float m1 = dmin * m; |
| get_scale_min_k4(is + 1, x[i].scales, sc, m); |
| const float d2 = dall * sc; const float m2 = dmin * m; |
|
|
| uint8_t hm = 1 << (2*il); |
| y[ 0] = d1 * ((ql[ 0] & 0xF) + (qh[ 0] & hm ? 16 : 0)) - m1; |
| y[ 1] = d1 * ((ql[ 1] & 0xF) + (qh[ 1] & hm ? 16 : 0)) - m1; |
| hm <<= 1; |
| y[32] = d2 * ((ql[ 0] >> 4) + (qh[ 0] & hm ? 16 : 0)) - m2; |
| y[33] = d2 * ((ql[ 1] >> 4) + (qh[ 1] & hm ? 16 : 0)) - m2; |
| #else |
| const int tid = threadIdx.x; |
| const uint8_t q = x[i].qs[tid]; |
| const int im = tid/8; |
| const int in = tid%8; |
| const int is = tid/16; |
| const uint8_t h = x[i].qh[in] >> im; |
| const float d = x[i].d; |
| dst_t * y = yy + i*QK_K + tid; |
| y[ 0] = d * x[i].scales[is+0] * ((q & 0xF) - ((h >> 0) & 1 ? 0 : 16)); |
| y[32] = d * x[i].scales[is+2] * ((q >> 4) - ((h >> 4) & 1 ? 0 : 16)); |
| #endif |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q6_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
| const block_q6_K * x = (const block_q6_K *) vx; |
|
|
| const int64_t i = blockIdx.x; |
| #if QK_K == 256 |
|
|
| |
| const int64_t tid = threadIdx.x; |
| const int64_t ip = tid/32; |
| const int64_t il = tid - 32*ip; |
| const int64_t is = 8*ip + il/16; |
|
|
| dst_t * y = yy + i*QK_K + 128*ip + il; |
|
|
| const float d = x[i].d; |
|
|
| const uint8_t * ql = x[i].ql + 64*ip + il; |
| const uint8_t qh = x[i].qh[32*ip + il]; |
| const int8_t * sc = x[i].scales + is; |
|
|
| y[ 0] = d * sc[0] * ((int8_t)((ql[ 0] & 0xF) | (((qh >> 0) & 3) << 4)) - 32); |
| y[32] = d * sc[2] * ((int8_t)((ql[32] & 0xF) | (((qh >> 2) & 3) << 4)) - 32); |
| y[64] = d * sc[4] * ((int8_t)((ql[ 0] >> 4) | (((qh >> 4) & 3) << 4)) - 32); |
| y[96] = d * sc[6] * ((int8_t)((ql[32] >> 4) | (((qh >> 6) & 3) << 4)) - 32); |
| #else |
|
|
| |
| const int64_t tid = threadIdx.x; |
| const int64_t ip = tid/16; |
| const int64_t il = tid - 16*ip; |
|
|
| dst_t * y = yy + i*QK_K + 16*ip + il; |
|
|
| const float d = x[i].d; |
|
|
| const uint8_t ql = x[i].ql[16*ip + il]; |
| const uint8_t qh = x[i].qh[il] >> (2*ip); |
| const int8_t * sc = x[i].scales; |
|
|
| y[ 0] = d * sc[ip+0] * ((int8_t)((ql & 0xF) | (((qh >> 0) & 3) << 4)) - 32); |
| y[32] = d * sc[ip+2] * ((int8_t)((ql >> 4) | (((qh >> 4) & 3) << 4)) - 32); |
| #endif |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q8_0(const void * __restrict__ vx, dst_t * __restrict__ yy, int nb32) { |
| const int i = blockIdx.x; |
|
|
| |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int ib = 8*i + ir; |
| if (ib >= nb32) { |
| return; |
| } |
|
|
| dst_t * y = yy + 256*i + 32*ir + 8*il; |
|
|
| const block_q8_0 * x = (const block_q8_0 *)vx + ib; |
| const float d = __half2float(x->d); |
|
|
| const int8_t * q = x->qs + 8*il; |
|
|
| for (int l = 0; l < 8; ++l) { |
| y[l] = d * q[l]; |
| } |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q8_K(const void * __restrict__ vx, dst_t * __restrict__ yy) { |
| const block_q8_K * x = (const block_q8_K *) vx; |
|
|
| const int i = blockIdx.x; |
|
|
| #if QK_K == 256 |
| |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int n = 8; |
|
|
| dst_t * y = yy + i*QK_K + 64*il + n*ir; |
|
|
| const int8_t * q = x[i].qs + 64*il + n*ir; |
|
|
| for (int l = 0; l < n; ++l) { |
| y[l] = q[l] * x[i].d; |
| } |
| #else |
| const int tid = threadIdx.x; |
| const uint8_t * q = x[i].qs; |
| float * y = yy + i*QK_K; |
| y[tid] = x[i].d * x[i].scales[0]; |
| #endif |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q5_0(const void * __restrict__ vx, dst_t * __restrict__ yy, int nb32) { |
| return dequantize_block<QK5_0, QR5_0, dequantize_q5_0>(vx, yy, nb32); |
| } |
|
|
| template<typename dst_t> |
| static __device__ void dequantize_block_q5_1(const void * __restrict__ vx, dst_t * __restrict__ yy, int nb32) { |
| return dequantize_block<QK5_1, QR5_1, dequantize_q5_1>(vx, yy, nb32); |
| } |
|
|
| #define DEQUANTIZE_K(QNAME) \ |
| extern "C" __global__ void dequantize_block_##QNAME##_f32(const void * __restrict__ vx, float * __restrict__ y) { \ |
| dequantize_block_##QNAME(vx, y); \ |
| } \ |
| extern "C" __global__ void dequantize_block_##QNAME##_f16(const void * __restrict__ vx, half * __restrict__ y) { \ |
| dequantize_block_##QNAME(vx, y); \ |
| } \ |
| |
| #define DEQUANTIZE(QNAME) \ |
| extern "C" __global__ void dequantize_block_##QNAME##_f32(const void * __restrict__ vx, float * __restrict__ y, const int k) { \ |
| dequantize_block_##QNAME(vx, y, k); \ |
| } \ |
| extern "C" __global__ void dequantize_block_##QNAME##_f16(const void * __restrict__ vx, half * __restrict__ y, const int k) { \ |
| dequantize_block_##QNAME(vx, y, k); \ |
| } \ |
| |
| DEQUANTIZE_K(q2_K) |
| DEQUANTIZE_K(q3_K) |
| DEQUANTIZE_K(q4_K) |
| DEQUANTIZE_K(q5_K) |
| DEQUANTIZE_K(q6_K) |
| DEQUANTIZE_K(q8_K) |
| DEQUANTIZE(q4_0) |
| DEQUANTIZE(q4_1) |
| DEQUANTIZE(q5_0) |
| DEQUANTIZE(q5_1) |
| DEQUANTIZE(q8_0) |
|
|
| template<int qk, int qr, dequantize_kernel_t dequantize_kernel> |
| static __device__ void get_rows_q( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| for (int64_t i00 = 2*(blockIdx.y*blockDim.x + threadIdx.x); i00 < ne00; i00 += gridDim.y*blockDim.x) { |
| const int i10 = blockIdx.x; |
| const int i01 = src1[i10]; |
|
|
| float * dst_row = dst + i10*ne00; |
| const void * src0_row = (const char *) src0 + i01*nb01; |
|
|
| const int ib = i00/qk; |
| const int iqs = (i00%qk)/qr; |
| const int iybs = i00 - i00%qk; |
| const int y_offset = qr == 1 ? 1 : qk/2; |
|
|
| float2 v; |
| dequantize_kernel(src0_row, ib, iqs, v); |
|
|
| dst_row[iybs + iqs + 0] = v.x; |
| dst_row[iybs + iqs + y_offset] = v.y; |
| } |
| } |
|
|
| static __device__ __forceinline__ float get_rows_to_float(const float v) { |
| return v; |
| } |
|
|
| static __device__ __forceinline__ float get_rows_to_float(const half v) { |
| return __half2float(v); |
| } |
|
|
| static __device__ __forceinline__ float get_rows_to_float(const __nv_bfloat16 v) { |
| return __bfloat162float(v); |
| } |
|
|
| template<typename src0_t> |
| static __device__ void get_rows_float( |
| const src0_t * src0, const uint32_t * src1, float * dst, const int64_t ne00) { |
| for (int64_t i00 = blockIdx.y*blockDim.x + threadIdx.x; i00 < ne00; i00 += gridDim.y*blockDim.x) { |
| const int i10 = blockIdx.x; |
| const int i01 = src1[i10]; |
|
|
| float * dst_row = dst + i10*ne00; |
| const src0_t * src0_row = src0 + i01*ne00; |
|
|
| dst_row[i00] = get_rows_to_float(src0_row[i00]); |
| } |
| } |
|
|
| static __device__ void get_rows_q2_K_block(const block_q2_K * x, float * y) { |
| const int tid = threadIdx.x; |
| #if QK_K == 256 |
| const int n = tid/32; |
| const int l = tid - 32*n; |
| const int is = 8*n + l/16; |
|
|
| const uint8_t q = x->qs[32*n + l]; |
| float * yy = y + 128*n; |
|
|
| float dall = __low2half(x->dm); |
| float dmin = __high2half(x->dm); |
| yy[l+ 0] = dall * (x->scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x->scales[is+0] >> 4); |
| yy[l+32] = dall * (x->scales[is+2] & 0xF) * ((q >> 2) & 3) - dmin * (x->scales[is+2] >> 4); |
| yy[l+64] = dall * (x->scales[is+4] & 0xF) * ((q >> 4) & 3) - dmin * (x->scales[is+4] >> 4); |
| yy[l+96] = dall * (x->scales[is+6] & 0xF) * ((q >> 6) & 3) - dmin * (x->scales[is+6] >> 4); |
| #else |
| const int is = tid/16; |
| const int il = tid%16; |
| const uint8_t q = x->qs[il] >> (2*is); |
| float * yy = y + 16*is + il; |
| float dall = __low2half(x->dm); |
| float dmin = __high2half(x->dm); |
| yy[ 0] = dall * (x->scales[is+0] & 0xF) * ((q >> 0) & 3) - dmin * (x->scales[is+0] >> 4); |
| yy[32] = dall * (x->scales[is+2] & 0xF) * ((q >> 4) & 3) - dmin * (x->scales[is+2] >> 4); |
| #endif |
| } |
|
|
| static __device__ void get_rows_q3_K_block(const block_q3_K * x, float * y) { |
| #if QK_K == 256 |
| const int r = threadIdx.x/4; |
| const int tid = r/2; |
| const int is0 = r%2; |
| const int l0 = 16*is0 + 4*(threadIdx.x%4); |
| const int n = tid / 4; |
| const int j = tid - 4*n; |
|
|
| uint8_t m = 1 << (4*n + j); |
| int is = 8*n + 2*j + is0; |
| int shift = 2*j; |
|
|
| int8_t us = is < 4 ? (x->scales[is-0] & 0xF) | (((x->scales[is+8] >> 0) & 3) << 4) : |
| is < 8 ? (x->scales[is-0] & 0xF) | (((x->scales[is+4] >> 2) & 3) << 4) : |
| is < 12 ? (x->scales[is-8] >> 4) | (((x->scales[is+0] >> 4) & 3) << 4) : |
| (x->scales[is-8] >> 4) | (((x->scales[is-4] >> 6) & 3) << 4); |
| float d_all = x->d; |
| float dl = d_all * (us - 32); |
|
|
| float * yy = y + 128*n + 32*j; |
| const uint8_t * q = x->qs + 32*n; |
| const uint8_t * hm = x->hmask; |
|
|
| for (int l = l0; l < l0+4; ++l) yy[l] = dl * ((int8_t)((q[l] >> shift) & 3) - ((hm[l] & m) ? 0 : 4)); |
| #else |
| const int tid = threadIdx.x; |
| const int is = tid/16; |
| const int il = tid%16; |
| const int im = il/8; |
| const int in = il%8; |
|
|
| float * yy = y + 16*is + il; |
|
|
| const uint8_t q = x->qs[il] >> (2*is); |
| const uint8_t h = x->hmask[in] >> (2*is + im); |
| const float d = (float)x->d; |
|
|
| if (is == 0) { |
| yy[ 0] = d * ((x->scales[0] & 0xF) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4)); |
| yy[32] = d * ((x->scales[1] & 0xF) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4)); |
| } else { |
| yy[ 0] = d * ((x->scales[0] >> 4) - 8) * ((int8_t)((q >> 0) & 3) - ((h >> 0) & 1 ? 0 : 4)); |
| yy[32] = d * ((x->scales[1] >> 4) - 8) * ((int8_t)((q >> 4) & 3) - ((h >> 4) & 1 ? 0 : 4)); |
| } |
| #endif |
| } |
|
|
| static __device__ void get_rows_q4_K_block(const block_q4_K * x, float * y) { |
| #if QK_K == 256 |
| const int tid = threadIdx.x; |
| const int il = tid/8; |
| const int ir = tid%8; |
| const int is = 2*il; |
| const int n = 4; |
|
|
| float * yy = y + 64*il + n*ir; |
|
|
| const float dall = __low2half(x->dm); |
| const float dmin = __high2half(x->dm); |
|
|
| const uint8_t * q = x->qs + 32*il + n*ir; |
|
|
| uint8_t sc, m; |
| get_scale_min_k4(is + 0, x->scales, sc, m); |
| const float d1 = dall * sc; const float m1 = dmin * m; |
| get_scale_min_k4(is + 1, x->scales, sc, m); |
| const float d2 = dall * sc; const float m2 = dmin * m; |
| for (int l = 0; l < n; ++l) { |
| yy[l + 0] = d1 * (q[l] & 0xF) - m1; |
| yy[l +32] = d2 * (q[l] >> 4) - m2; |
| } |
| #else |
| const int tid = threadIdx.x; |
| const uint8_t * q = x->qs; |
| const float d = (float)x->dm[0]; |
| const float m = (float)x->dm[1]; |
| y[tid+ 0] = d * (x->scales[0] & 0xF) * (q[tid] & 0xF) - m * (x->scales[0] >> 4); |
| y[tid+32] = d * (x->scales[1] & 0xF) * (q[tid] >> 4) - m * (x->scales[1] >> 4); |
| #endif |
| } |
|
|
| static __device__ void get_rows_q5_K_block(const block_q5_K * x, float * y) { |
| #if QK_K == 256 |
| const int tid = threadIdx.x; |
| const int il = tid/16; |
| const int ir = tid%16; |
| const int is = 2*il; |
|
|
| float * yy = y + 64*il + 2*ir; |
|
|
| const float dall = __low2half(x->dm); |
| const float dmin = __high2half(x->dm); |
|
|
| const uint8_t * ql = x->qs + 32*il + 2*ir; |
| const uint8_t * qh = x->qh + 2*ir; |
|
|
| uint8_t sc, m; |
| get_scale_min_k4(is + 0, x->scales, sc, m); |
| const float d1 = dall * sc; const float m1 = dmin * m; |
| get_scale_min_k4(is + 1, x->scales, sc, m); |
| const float d2 = dall * sc; const float m2 = dmin * m; |
|
|
| uint8_t hm = 1 << (2*il); |
| yy[ 0] = d1 * ((ql[ 0] & 0xF) + (qh[ 0] & hm ? 16 : 0)) - m1; |
| yy[ 1] = d1 * ((ql[ 1] & 0xF) + (qh[ 1] & hm ? 16 : 0)) - m1; |
| hm <<= 1; |
| yy[32] = d2 * ((ql[ 0] >> 4) + (qh[ 0] & hm ? 16 : 0)) - m2; |
| yy[33] = d2 * ((ql[ 1] >> 4) + (qh[ 1] & hm ? 16 : 0)) - m2; |
| #else |
| const int tid = threadIdx.x; |
| const uint8_t q = x->qs[tid]; |
| const int im = tid/8; |
| const int in = tid%8; |
| const int is = tid/16; |
| const uint8_t h = x->qh[in] >> im; |
| const float d = x->d; |
| y[tid + 0] = d * x->scales[is+0] * ((q & 0xF) - ((h >> 0) & 1 ? 0 : 16)); |
| y[tid+32] = d * x->scales[is+2] * ((q >> 4) - ((h >> 4) & 1 ? 0 : 16)); |
| #endif |
| } |
|
|
| static __device__ void get_rows_q6_K_block(const block_q6_K * x, float * y) { |
| #if QK_K == 256 |
| const int64_t tid = threadIdx.x; |
| const int64_t ip = tid/32; |
| const int64_t il = tid - 32*ip; |
| const int64_t is = 8*ip + il/16; |
|
|
| float * yy = y + 128*ip + il; |
|
|
| const float d = x->d; |
|
|
| const uint8_t * ql = x->ql + 64*ip + il; |
| const uint8_t qh = x->qh[32*ip + il]; |
| const int8_t * sc = x->scales + is; |
|
|
| yy[ 0] = d * sc[0] * ((int8_t)((ql[ 0] & 0xF) | (((qh >> 0) & 3) << 4)) - 32); |
| yy[32] = d * sc[2] * ((int8_t)((ql[32] & 0xF) | (((qh >> 2) & 3) << 4)) - 32); |
| yy[64] = d * sc[4] * ((int8_t)((ql[ 0] >> 4) | (((qh >> 4) & 3) << 4)) - 32); |
| yy[96] = d * sc[6] * ((int8_t)((ql[32] >> 4) | (((qh >> 6) & 3) << 4)) - 32); |
| #else |
| const int64_t tid = threadIdx.x; |
| const int64_t ip = tid/16; |
| const int64_t il = tid - 16*ip; |
|
|
| float * yy = y + 16*ip + il; |
|
|
| const float d = x->d; |
|
|
| const uint8_t ql = x->ql[16*ip + il]; |
| const uint8_t qh = x->qh[il] >> (2*ip); |
| const int8_t * sc = x->scales; |
|
|
| yy[ 0] = d * sc[ip+0] * ((int8_t)((ql & 0xF) | (((qh >> 0) & 3) << 4)) - 32); |
| yy[32] = d * sc[ip+2] * ((int8_t)((ql >> 4) | (((qh >> 4) & 3) << 4)) - 32); |
| #endif |
| } |
|
|
| #define GET_ROWS_K(QNAME, BLOCK_Q_T) \ |
| extern "C" __global__ void get_rows_##QNAME( \ |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, \ |
| const int64_t ne00, const size_t nb01) { \ |
| const int i10 = blockIdx.x; \ |
| const int i01 = src1[i10]; \ |
| const int ib = blockIdx.y; \ |
| const int blocks_per_row = nb01 / sizeof(BLOCK_Q_T); \ |
| const BLOCK_Q_T * src0_row = (const BLOCK_Q_T *) src0 + i01*blocks_per_row; \ |
| float * dst_row = dst + i10*ne00; \ |
| get_rows_##QNAME##_block(src0_row + ib, dst_row + ib*QK_K); \ |
| } |
|
|
| extern "C" __global__ void get_rows_q4_0( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| get_rows_q<QK4_0, QR4_0, dequantize_q4_0>(src0, src1, dst, ne00, nb01); |
| } |
|
|
| extern "C" __global__ void get_rows_q4_1( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| get_rows_q<QK4_1, QR4_1, dequantize_q4_1>(src0, src1, dst, ne00, nb01); |
| } |
|
|
| extern "C" __global__ void get_rows_q5_0( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| get_rows_q<QK5_0, QR5_0, dequantize_q5_0>(src0, src1, dst, ne00, nb01); |
| } |
|
|
| extern "C" __global__ void get_rows_q5_1( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| get_rows_q<QK5_1, QR5_1, dequantize_q5_1>(src0, src1, dst, ne00, nb01); |
| } |
|
|
| extern "C" __global__ void get_rows_q8_0( |
| const void * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| get_rows_q<QK8_0, QR8_0, dequantize_q8_0>(src0, src1, dst, ne00, nb01); |
| } |
|
|
| extern "C" __global__ void get_rows_f32( |
| const float * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| GGML_UNUSED(nb01); |
| get_rows_float(src0, src1, dst, ne00); |
| } |
|
|
| extern "C" __global__ void get_rows_f16( |
| const half * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| GGML_UNUSED(nb01); |
| get_rows_float(src0, src1, dst, ne00); |
| } |
|
|
| extern "C" __global__ void get_rows_bf16( |
| const __nv_bfloat16 * __restrict__ src0, const uint32_t * __restrict__ src1, float * __restrict__ dst, |
| const int64_t ne00, const size_t nb01) { |
| GGML_UNUSED(nb01); |
| get_rows_float(src0, src1, dst, ne00); |
| } |
|
|
| GET_ROWS_K(q2_K, block_q2_K) |
| GET_ROWS_K(q3_K, block_q3_K) |
| GET_ROWS_K(q4_K, block_q4_K) |
| GET_ROWS_K(q5_K, block_q5_K) |
| GET_ROWS_K(q6_K, block_q6_K) |
|
|
| template <int qk, int qr, dequantize_kernel_t dequantize_kernel> |
| static __device__ void dequantize_mul_mat_vec(const void * __restrict__ vx, const dfloat * __restrict__ y, float * __restrict__ dst, const int ncols, const int nrows) { |
| |
| |
| const int row = blockIdx.x*blockDim.y + threadIdx.y; |
|
|
| if (row >= nrows) { |
| return; |
| } |
|
|
| const int tid = threadIdx.x; |
|
|
| const int iter_stride = 2*GGML_CUDA_DMMV_X; |
| const int vals_per_iter = iter_stride / WARP_SIZE; |
| const int y_offset = qr == 1 ? 1 : qk/2; |
|
|
| |
| #ifdef GGML_CUDA_F16 |
| half2 tmp = {0.0f, 0.0f}; |
| #else |
| float tmp = 0.0f; |
| #endif |
|
|
| for (int i = 0; i < ncols; i += iter_stride) { |
| const int col = i + vals_per_iter*tid; |
| const int ib = (row*ncols + col)/qk; |
| const int iqs = (col%qk)/qr; |
| const int iybs = col - col%qk; |
|
|
| |
| #pragma unroll |
| for (int j = 0; j < vals_per_iter; j += 2) { |
| |
|
|
| |
| |
| dfloat2 v; |
| dequantize_kernel(vx, ib, iqs + j/qr, v); |
|
|
| |
| |
| #ifdef GGML_CUDA_F16 |
| tmp += __hmul2(v, { |
| y[iybs + iqs + j/qr + 0], |
| y[iybs + iqs + j/qr + y_offset] |
| }); |
| #else |
| tmp += v.x * y[iybs + iqs + j/qr + 0]; |
| tmp += v.y * y[iybs + iqs + j/qr + y_offset]; |
| #endif |
| } |
| } |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (tid == 0) { |
| #ifdef GGML_CUDA_F16 |
| dst[row] = tmp.x + tmp.y; |
| #else |
| dst[row] = tmp; |
| #endif |
| } |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q4_0_cuda(const void * vx, const dfloat * y, float * dst, const int ncols, const int nrows) { |
| dequantize_mul_mat_vec<QK4_0, QR4_0, dequantize_q4_0>(vx, y, dst, ncols, nrows); |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q4_1_cuda(const void * vx, const dfloat * y, float * dst, const int ncols, const int nrows) { |
| dequantize_mul_mat_vec<QK4_1, QR4_1, dequantize_q4_1>(vx, y, dst, ncols, nrows); |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q5_0_cuda(const void * vx, const dfloat * y, float * dst, const int ncols, const int nrows) { |
| dequantize_mul_mat_vec<QK5_0, QR5_0, dequantize_q5_0>(vx, y, dst, ncols, nrows); |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q5_1_cuda(const void * vx, const dfloat * y, float * dst, const int ncols, const int nrows) { |
| dequantize_mul_mat_vec<QK5_1, QR5_1, dequantize_q5_1>(vx, y, dst, ncols, nrows); |
| } |
| extern "C" __global__ void dequantize_mul_mat_vec_q8_0_cuda(const void * vx, const dfloat * y, float * dst, const int ncols, const int nrows) { |
| dequantize_mul_mat_vec<QK8_0, QR8_0, dequantize_q8_0>(vx, y, dst, ncols, nrows); |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q2_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols, int nrows) { |
|
|
| static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION"); |
|
|
| const int row = blockIdx.x*blockDim.y + threadIdx.y; |
| if (row > nrows) return; |
|
|
| const int num_blocks_per_row = ncols / QK_K; |
| const int ib0 = row*num_blocks_per_row; |
|
|
| const block_q2_K * x = (const block_q2_K *)vx + ib0; |
|
|
| float tmp = 0; |
|
|
| #if QK_K == 256 |
| const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; |
| const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; |
|
|
| const int step = 16/K_QUANTS_PER_ITERATION; |
|
|
| const int im = tid/step; |
| const int in = tid - step*im; |
|
|
| const int l0 = K_QUANTS_PER_ITERATION*in; |
| const int q_offset = 32*im + l0; |
| const int s_offset = 8*im; |
| const int y_offset = 128*im + l0; |
|
|
| uint32_t aux[4]; |
| const uint8_t * d = (const uint8_t *)aux; |
| const uint8_t * m = (const uint8_t *)(aux + 2); |
|
|
| for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + y_offset; |
| const uint8_t * q = x[i].qs + q_offset; |
|
|
| const float dall = __low2half(x[i].dm); |
| const float dmin = __high2half(x[i].dm); |
|
|
| const uint32_t * a = (const uint32_t *)(x[i].scales + s_offset); |
| aux[0] = a[0] & 0x0f0f0f0f; |
| aux[1] = a[1] & 0x0f0f0f0f; |
| aux[2] = (a[0] >> 4) & 0x0f0f0f0f; |
| aux[3] = (a[1] >> 4) & 0x0f0f0f0f; |
|
|
| float sum1 = 0, sum2 = 0; |
| for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) { |
| sum1 += y[l+ 0] * d[0] * ((q[l+ 0] >> 0) & 3) |
| + y[l+32] * d[2] * ((q[l+ 0] >> 2) & 3) |
| + y[l+64] * d[4] * ((q[l+ 0] >> 4) & 3) |
| + y[l+96] * d[6] * ((q[l+ 0] >> 6) & 3) |
| + y[l+16] * d[1] * ((q[l+16] >> 0) & 3) |
| + y[l+48] * d[3] * ((q[l+16] >> 2) & 3) |
| + y[l+80] * d[5] * ((q[l+16] >> 4) & 3) |
| +y[l+112] * d[7] * ((q[l+16] >> 6) & 3); |
| sum2 += y[l+ 0] * m[0] + y[l+32] * m[2] + y[l+64] * m[4] + y[ l+96] * m[6] |
| + y[l+16] * m[1] + y[l+48] * m[3] + y[l+80] * m[5] + y[l+112] * m[7]; |
|
|
| } |
| tmp += dall * sum1 - dmin * sum2; |
|
|
| } |
| #else |
| const int tid = threadIdx.x/(2*K_QUANTS_PER_ITERATION); |
| const int ix = threadIdx.x%(2*K_QUANTS_PER_ITERATION); |
| const int offset = tid * K_QUANTS_PER_ITERATION; |
|
|
| uint32_t uaux[2]; |
| const uint8_t * d = (const uint8_t *)uaux; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + offset; |
| const uint8_t * q = x[i].qs + offset; |
| const uint32_t * s = (const uint32_t *)x[i].scales; |
|
|
| uaux[0] = s[0] & 0x0f0f0f0f; |
| uaux[1] = (s[0] >> 4) & 0x0f0f0f0f; |
|
|
| const float2 dall = __half22float2(x[i].dm); |
|
|
| float sum1 = 0, sum2 = 0; |
| for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) { |
| const uint8_t ql = q[l]; |
| sum1 += y[l+ 0] * d[0] * ((ql >> 0) & 3) |
| + y[l+16] * d[1] * ((ql >> 2) & 3) |
| + y[l+32] * d[2] * ((ql >> 4) & 3) |
| + y[l+48] * d[3] * ((ql >> 6) & 3); |
| sum2 += y[l+0] * d[4] + y[l+16] * d[5] + y[l+32] * d[6] + y[l+48] * d[7]; |
| } |
| tmp += dall.x * sum1 - dall.y * sum2; |
| } |
| #endif |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (threadIdx.x == 0) { |
| dst[row] = tmp; |
| } |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q3_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols, int nrows) { |
|
|
| const int row = blockIdx.x*blockDim.y + threadIdx.y; |
| if (row > nrows) return; |
|
|
| const int num_blocks_per_row = ncols / QK_K; |
| const int ib0 = row*num_blocks_per_row; |
|
|
| const block_q3_K * x = (const block_q3_K *)vx + ib0; |
|
|
| float tmp = 0; |
|
|
| #if QK_K == 256 |
|
|
| const uint16_t kmask1 = 0x0303; |
| const uint16_t kmask2 = 0x0f0f; |
|
|
| const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; |
| const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; |
|
|
| const int n = K_QUANTS_PER_ITERATION; |
| const int step = 16/K_QUANTS_PER_ITERATION; |
| const int im = tid/step; |
| const int in = tid - step*im; |
|
|
| const uint8_t m = 1 << (4*im); |
|
|
| const int l0 = n*in; |
| const int q_offset = 32*im + l0; |
| const int y_offset = 128*im + l0; |
|
|
| uint16_t utmp[4]; |
| const int8_t * s = (const int8_t *)utmp; |
|
|
| const uint16_t s_shift = 4*im; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + y_offset; |
| const uint8_t * q = x[i].qs + q_offset; |
| const uint8_t * h = x[i].hmask + l0; |
|
|
| const uint16_t * a = (const uint16_t *)x[i].scales; |
| utmp[0] = ((a[0] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 0)) & kmask1) << 4); |
| utmp[1] = ((a[1] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 0)) & kmask1) << 4); |
| utmp[2] = ((a[2] >> s_shift) & kmask2) | (((a[4] >> (s_shift + 2)) & kmask1) << 4); |
| utmp[3] = ((a[3] >> s_shift) & kmask2) | (((a[5] >> (s_shift + 2)) & kmask1) << 4); |
|
|
| const float d = x[i].d; |
|
|
| float sum = 0; |
| for (int l = 0; l < n; ++l) { |
| sum += y[l+ 0] * (s[0] - 32) * (((q[l] >> 0) & 3) - (h[l] & (m << 0) ? 0 : 4)) |
| + y[l+32] * (s[2] - 32) * (((q[l] >> 2) & 3) - (h[l] & (m << 1) ? 0 : 4)) |
| + y[l+64] * (s[4] - 32) * (((q[l] >> 4) & 3) - (h[l] & (m << 2) ? 0 : 4)) |
| + y[l+96] * (s[6] - 32) * (((q[l] >> 6) & 3) - (h[l] & (m << 3) ? 0 : 4)); |
| sum += y[l+16] * (s[1] - 32) * (((q[l+16] >> 0) & 3) - (h[l+16] & (m << 0) ? 0 : 4)) |
| + y[l+48] * (s[3] - 32) * (((q[l+16] >> 2) & 3) - (h[l+16] & (m << 1) ? 0 : 4)) |
| + y[l+80] * (s[5] - 32) * (((q[l+16] >> 4) & 3) - (h[l+16] & (m << 2) ? 0 : 4)) |
| + y[l+112] * (s[7] - 32) * (((q[l+16] >> 6) & 3) - (h[l+16] & (m << 3) ? 0 : 4)); |
| } |
| tmp += d * sum; |
|
|
| } |
| #else |
|
|
| const int tid = threadIdx.x/(2*K_QUANTS_PER_ITERATION); |
| const int ix = threadIdx.x%(2*K_QUANTS_PER_ITERATION); |
| const int offset = tid * K_QUANTS_PER_ITERATION; |
| const int in = offset/8; |
| const int im = offset%8; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + offset; |
| const uint8_t * q = x[i].qs + offset; |
| const uint8_t * s = x[i].scales; |
|
|
| const float dall = (float)x[i].d; |
|
|
| float sum = 0; |
| for (int l = 0; l < K_QUANTS_PER_ITERATION; ++l) { |
| const uint8_t hl = x[i].hmask[im+l] >> in; |
| const uint8_t ql = q[l]; |
| sum += y[l+ 0] * dall * ((s[0] & 0xF) - 8) * ((int8_t)((ql >> 0) & 3) - ((hl >> 0) & 1 ? 0 : 4)) |
| + y[l+16] * dall * ((s[0] >> 4) - 8) * ((int8_t)((ql >> 2) & 3) - ((hl >> 2) & 1 ? 0 : 4)) |
| + y[l+32] * dall * ((s[1] & 0xF) - 8) * ((int8_t)((ql >> 4) & 3) - ((hl >> 4) & 1 ? 0 : 4)) |
| + y[l+48] * dall * ((s[1] >> 4) - 8) * ((int8_t)((ql >> 6) & 3) - ((hl >> 6) & 1 ? 0 : 4)); |
| } |
| tmp += sum; |
| } |
| #endif |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (threadIdx.x == 0) { |
| dst[row] = tmp; |
| } |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q4_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols, int nrows) { |
|
|
| const int row = blockIdx.x*blockDim.y + threadIdx.y; |
| if (row > nrows) return; |
| const int num_blocks_per_row = ncols / QK_K; |
| const int ib0 = row*num_blocks_per_row; |
|
|
| const block_q4_K * x = (const block_q4_K *)vx + ib0; |
|
|
| #if QK_K == 256 |
| const uint16_t kmask1 = 0x3f3f; |
| const uint16_t kmask2 = 0x0f0f; |
| const uint16_t kmask3 = 0xc0c0; |
|
|
| const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; |
| const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; |
|
|
| const int step = 8/K_QUANTS_PER_ITERATION; |
|
|
| const int il = tid/step; |
| const int ir = tid - step*il; |
| const int n = 2 * K_QUANTS_PER_ITERATION; |
|
|
| const int im = il/2; |
| const int in = il%2; |
|
|
| const int l0 = n*(2*ir + in); |
| const int q_offset = 32*im + l0; |
| const int y_offset = 64*im + l0; |
|
|
| uint16_t aux[4]; |
| const uint8_t * sc = (const uint8_t *)aux; |
|
|
| #if K_QUANTS_PER_ITERATION == 2 |
| uint32_t q32[4]; |
| const uint8_t * q4 = (const uint8_t *)q32; |
| #else |
| uint16_t q16[4]; |
| const uint8_t * q4 = (const uint8_t *)q16; |
| #endif |
|
|
| float tmp = 0; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) { |
|
|
| const float * y1 = yy + i*QK_K + y_offset; |
| const float * y2 = y1 + 128; |
|
|
| const float dall = __low2half(x[i].dm); |
| const float dmin = __high2half(x[i].dm); |
|
|
| const uint16_t * a = (const uint16_t *)x[i].scales; |
| aux[0] = a[im+0] & kmask1; |
| aux[1] = a[im+2] & kmask1; |
| aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2); |
| aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2); |
|
|
| #if K_QUANTS_PER_ITERATION == 2 |
| const uint32_t * q1 = (const uint32_t *)(x[i].qs + q_offset); |
| const uint32_t * q2 = q1 + 16; |
|
|
| q32[0] = q1[0] & 0x0f0f0f0f; |
| q32[1] = q1[0] & 0xf0f0f0f0; |
| q32[2] = q2[0] & 0x0f0f0f0f; |
| q32[3] = q2[0] & 0xf0f0f0f0; |
|
|
| float4 s = {0.f, 0.f, 0.f, 0.f}; |
| float smin = 0; |
| for (int l = 0; l < 4; ++l) { |
| s.x += y1[l] * q4[l+0]; s.y += y1[l+32] * q4[l+ 4]; |
| s.z += y2[l] * q4[l+8]; s.w += y2[l+32] * q4[l+12]; |
| smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7]; |
| } |
| tmp += dall * (s.x * sc[0] + s.y * sc[1] * 1.f/16.f + s.z * sc[4] + s.w * sc[5] * 1.f/16.f) - dmin * smin; |
| #else |
| const uint16_t * q1 = (const uint16_t *)(x[i].qs + q_offset); |
| const uint16_t * q2 = q1 + 32; |
|
|
| q16[0] = q1[0] & 0x0f0f; |
| q16[1] = q1[0] & 0xf0f0; |
| q16[2] = q2[0] & 0x0f0f; |
| q16[3] = q2[0] & 0xf0f0; |
|
|
| float4 s = {0.f, 0.f, 0.f, 0.f}; |
| float smin = 0; |
| for (int l = 0; l < 2; ++l) { |
| s.x += y1[l] * q4[l+0]; s.y += y1[l+32] * q4[l+2]; |
| s.z += y2[l] * q4[l+4]; s.w += y2[l+32] * q4[l+6]; |
| smin += y1[l] * sc[2] + y1[l+32] * sc[3] + y2[l] * sc[6] + y2[l+32] * sc[7]; |
| } |
| tmp += dall * (s.x * sc[0] + s.y * sc[1] * 1.f/16.f + s.z * sc[4] + s.w * sc[5] * 1.f/16.f) - dmin * smin; |
| #endif |
|
|
| } |
| #else |
| const int tid = threadIdx.x/(2*K_QUANTS_PER_ITERATION); |
| const int ix = threadIdx.x%(2*K_QUANTS_PER_ITERATION); |
|
|
| const int step = tid * K_QUANTS_PER_ITERATION; |
|
|
| uint16_t aux16[2]; |
| const uint8_t * s = (const uint8_t *)aux16; |
|
|
| float tmp = 0; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) { |
| const uint8_t * q = x[i].qs + step; |
| const float * y = yy + i*QK_K + step; |
| const uint16_t * a = (const uint16_t *)x[i].scales; |
| aux16[0] = a[0] & 0x0f0f; |
| aux16[1] = (a[0] >> 4) & 0x0f0f; |
| const float d = (float)x[i].dm[0]; |
| const float m = (float)x[i].dm[1]; |
| float sum = 0.f; |
| for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) { |
| sum += y[j+ 0] * (d * s[0] * (q[j+ 0] & 0xF) - m * s[2]) |
| + y[j+16] * (d * s[0] * (q[j+16] & 0xF) - m * s[2]) |
| + y[j+32] * (d * s[1] * (q[j+ 0] >> 4) - m * s[3]) |
| + y[j+48] * (d * s[1] * (q[j+16] >> 4) - m * s[3]); |
| } |
| tmp += sum; |
| } |
|
|
| #endif |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (tid == 0) { |
| dst[row] = tmp; |
| } |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q5_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols) { |
|
|
| const int row = blockIdx.x; |
| const int num_blocks_per_row = ncols / QK_K; |
| const int ib0 = row*num_blocks_per_row; |
|
|
| const block_q5_K * x = (const block_q5_K *)vx + ib0; |
|
|
| float tmp = 0; |
|
|
| #if QK_K == 256 |
| const uint16_t kmask1 = 0x3f3f; |
| const uint16_t kmask2 = 0x0f0f; |
| const uint16_t kmask3 = 0xc0c0; |
|
|
| const int tid = threadIdx.x/2; |
| const int ix = threadIdx.x%2; |
|
|
| const int il = tid/4; |
| const int ir = tid - 4*il; |
| const int n = 2; |
|
|
| const int im = il/2; |
| const int in = il%2; |
|
|
| const int l0 = n*(2*ir + in); |
| const int q_offset = 32*im + l0; |
| const int y_offset = 64*im + l0; |
|
|
| const uint8_t hm1 = 1 << (2*im); |
| const uint8_t hm2 = hm1 << 4; |
|
|
| uint16_t aux[4]; |
| const uint8_t * sc = (const uint8_t *)aux; |
|
|
| uint16_t q16[8]; |
| const uint8_t * q4 = (const uint8_t *)q16; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2) { |
|
|
| const uint8_t * ql1 = x[i].qs + q_offset; |
| const uint8_t * qh = x[i].qh + l0; |
| const float * y1 = yy + i*QK_K + y_offset; |
| const float * y2 = y1 + 128; |
|
|
| const float dall = __low2half(x[i].dm); |
| const float dmin = __high2half(x[i].dm); |
|
|
| const uint16_t * a = (const uint16_t *)x[i].scales; |
| aux[0] = a[im+0] & kmask1; |
| aux[1] = a[im+2] & kmask1; |
| aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2); |
| aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2); |
|
|
| float4 sum = {0.f, 0.f, 0.f, 0.f}; |
| float smin = 0; |
| const uint16_t * q1 = (const uint16_t *)ql1; |
| const uint16_t * q2 = q1 + 32; |
| q16[0] = q1[0] & 0x0f0f; |
| q16[1] = q1[8] & 0x0f0f; |
| q16[2] = (q1[0] >> 4) & 0x0f0f; |
| q16[3] = (q1[8] >> 4) & 0x0f0f; |
| q16[4] = q2[0] & 0x0f0f; |
| q16[5] = q2[8] & 0x0f0f; |
| q16[6] = (q2[0] >> 4) & 0x0f0f; |
| q16[7] = (q2[8] >> 4) & 0x0f0f; |
| for (int l = 0; l < n; ++l) { |
| sum.x += y1[l+ 0] * (q4[l +0] + (qh[l+ 0] & (hm1 << 0) ? 16 : 0)) |
| + y1[l+16] * (q4[l +2] + (qh[l+16] & (hm1 << 0) ? 16 : 0)); |
| sum.y += y1[l+32] * (q4[l +4] + (qh[l+ 0] & (hm1 << 1) ? 16 : 0)) |
| + y1[l+48] * (q4[l +6] + (qh[l+16] & (hm1 << 1) ? 16 : 0)); |
| sum.z += y2[l+ 0] * (q4[l +8] + (qh[l+ 0] & (hm2 << 0) ? 16 : 0)) |
| + y2[l+16] * (q4[l+10] + (qh[l+16] & (hm2 << 0) ? 16 : 0)); |
| sum.w += y2[l+32] * (q4[l+12] + (qh[l+ 0] & (hm2 << 1) ? 16 : 0)) |
| + y2[l+48] * (q4[l+14] + (qh[l+16] & (hm2 << 1) ? 16 : 0)); |
| smin += (y1[l] + y1[l+16]) * sc[2] + (y1[l+32] + y1[l+48]) * sc[3] |
| + (y2[l] + y2[l+16]) * sc[6] + (y2[l+32] + y2[l+48]) * sc[7]; |
| } |
| tmp += dall * (sum.x * sc[0] + sum.y * sc[1] + sum.z * sc[4] + sum.w * sc[5]) - dmin * smin; |
| } |
|
|
| #else |
| const int tid = threadIdx.x/(2*K_QUANTS_PER_ITERATION); |
| const int ix = threadIdx.x%(2*K_QUANTS_PER_ITERATION); |
| const int step = tid * K_QUANTS_PER_ITERATION; |
| const int im = step/8; |
| const int in = step%8; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) { |
| const uint8_t * q = x[i].qs + step; |
| const int8_t * s = x[i].scales; |
| const float * y = yy + i*QK_K + step; |
| const float d = x[i].d; |
| float sum = 0.f; |
| for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) { |
| const uint8_t h = x[i].qh[in+j] >> im; |
| sum += y[j+ 0] * d * s[0] * ((q[j+ 0] & 0xF) - ((h >> 0) & 1 ? 0 : 16)) |
| + y[j+16] * d * s[1] * ((q[j+16] & 0xF) - ((h >> 2) & 1 ? 0 : 16)) |
| + y[j+32] * d * s[2] * ((q[j+ 0] >> 4) - ((h >> 4) & 1 ? 0 : 16)) |
| + y[j+48] * d * s[3] * ((q[j+16] >> 4) - ((h >> 6) & 1 ? 0 : 16)); |
| } |
| tmp += sum; |
| } |
| #endif |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (threadIdx.x == 0) { |
| dst[row] = tmp; |
| } |
| } |
|
|
| extern "C" __global__ void dequantize_mul_mat_vec_q6_k(const void * __restrict__ vx, const float * __restrict__ yy, float * __restrict__ dst, const int ncols, int nrows) { |
|
|
| static_assert(16%K_QUANTS_PER_ITERATION == 0, "16 must be divisible by K_QUANTS_PER_ITERATION"); |
|
|
| const int row = blockIdx.x*blockDim.y + threadIdx.y; |
| if (row > nrows) return; |
|
|
| const int num_blocks_per_row = ncols / QK_K; |
| const int ib0 = row*num_blocks_per_row; |
|
|
| const block_q6_K * x = (const block_q6_K *)vx + ib0; |
|
|
| #if QK_K == 256 |
|
|
| const int tid = threadIdx.x/K_QUANTS_PER_ITERATION; |
| const int ix = threadIdx.x%K_QUANTS_PER_ITERATION; |
|
|
| const int step = 16/K_QUANTS_PER_ITERATION; |
|
|
| const int im = tid/step; |
| const int in = tid - step*im; |
|
|
| #if K_QUANTS_PER_ITERATION == 1 |
| const int l0 = K_QUANTS_PER_ITERATION*in; |
| const int is = 0; |
| #else |
| const int l0 = 4 * in; |
| const int is = in / 4; |
| #endif |
| const int ql_offset = 64*im + l0; |
| const int qh_offset = 32*im + l0; |
| const int s_offset = 8*im + is; |
| const int y_offset = 128*im + l0; |
|
|
| float tmp = 0; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + y_offset; |
| const uint8_t * ql = x[i].ql + ql_offset; |
| const uint8_t * qh = x[i].qh + qh_offset; |
| const int8_t * s = x[i].scales + s_offset; |
|
|
| const float d = x[i].d; |
|
|
| #if K_QUANTS_PER_ITERATION == 1 |
| float sum = y[ 0] * s[0] * d * ((int8_t)((ql[ 0] & 0xF) | ((qh[ 0] & 0x03) << 4)) - 32) |
| + y[16] * s[1] * d * ((int8_t)((ql[16] & 0xF) | ((qh[16] & 0x03) << 4)) - 32) |
| + y[32] * s[2] * d * ((int8_t)((ql[32] & 0xF) | ((qh[ 0] & 0x0c) << 2)) - 32) |
| + y[48] * s[3] * d * ((int8_t)((ql[48] & 0xF) | ((qh[16] & 0x0c) << 2)) - 32) |
| + y[64] * s[4] * d * ((int8_t)((ql[ 0] >> 4) | ((qh[ 0] & 0x30) >> 0)) - 32) |
| + y[80] * s[5] * d * ((int8_t)((ql[16] >> 4) | ((qh[16] & 0x30) >> 0)) - 32) |
| + y[96] * s[6] * d * ((int8_t)((ql[32] >> 4) | ((qh[ 0] & 0xc0) >> 2)) - 32) |
| +y[112] * s[7] * d * ((int8_t)((ql[48] >> 4) | ((qh[16] & 0xc0) >> 2)) - 32); |
| tmp += sum; |
| #else |
| float sum = 0; |
| for (int l = 0; l < 4; ++l) { |
| sum += y[l+ 0] * s[0] * d * ((int8_t)((ql[l+ 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32) |
| + y[l+32] * s[2] * d * ((int8_t)((ql[l+32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32) |
| + y[l+64] * s[4] * d * ((int8_t)((ql[l+ 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32) |
| + y[l+96] * s[6] * d * ((int8_t)((ql[l+32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32); |
| } |
| tmp += sum; |
| #endif |
|
|
| } |
|
|
| #else |
|
|
| const int tid = threadIdx.x/(2*K_QUANTS_PER_ITERATION); |
| const int ix = threadIdx.x%(2*K_QUANTS_PER_ITERATION); |
|
|
| const int step = tid * K_QUANTS_PER_ITERATION; |
|
|
| float tmp = 0; |
|
|
| for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) { |
|
|
| const float * y = yy + i * QK_K + step; |
| const uint8_t * ql = x[i].ql + step; |
| const uint8_t * qh = x[i].qh + step; |
| const int8_t * s = x[i].scales; |
|
|
| const float d = x[i+0].d; |
|
|
| float sum = 0; |
| for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) { |
| sum += y[j+ 0] * s[0] * d * ((int8_t)((ql[j+ 0] & 0xF) | ((qh[j] & 0x03) << 4)) - 32) |
| + y[j+16] * s[1] * d * ((int8_t)((ql[j+16] & 0xF) | ((qh[j] & 0x0c) << 2)) - 32) |
| + y[j+32] * s[2] * d * ((int8_t)((ql[j+ 0] >> 4) | ((qh[j] & 0x30) >> 0)) - 32) |
| + y[j+48] * s[3] * d * ((int8_t)((ql[j+16] >> 4) | ((qh[j] & 0xc0) >> 2)) - 32); |
| } |
| tmp += sum; |
|
|
| } |
|
|
| #endif |
|
|
| |
| #pragma unroll |
| for (int mask = 16; mask > 0; mask >>= 1) { |
| tmp += __shfl_xor_sync(0xffffffff, tmp, mask, 32); |
| } |
|
|
| if (tid == 0) { |
| dst[row] = tmp; |
| } |
| } |
|
|
| |
| |
|
|
| #define VDR_Q4_0_Q8_1_MMVQ 2 |
| #define VDR_Q4_0_Q8_1_MMQ 4 |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q4_0_q8_1_impl( |
| const int * v, const int * u, const float & d4, const half2 & ds8) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| const int vi0 = (v[i] >> 0) & 0x0F0F0F0F; |
| const int vi1 = (v[i] >> 4) & 0x0F0F0F0F; |
|
|
| |
| sumi = ggml_cuda_dp4a(vi0, u[2*i+0], sumi); |
| sumi = ggml_cuda_dp4a(vi1, u[2*i+1], sumi); |
| } |
|
|
| const float2 ds8f = __half22float2(ds8); |
|
|
| |
| return d4 * (sumi * ds8f.x - (8*vdr/QI4_0) * ds8f.y); |
| } |
|
|
| #define VDR_Q4_1_Q8_1_MMVQ 2 |
| #define VDR_Q4_1_Q8_1_MMQ 4 |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q4_1_q8_1_impl( |
| const int * v, const int * u, const half2 & dm4, const half2 & ds8) { |
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| const int vi0 = (v[i] >> 0) & 0x0F0F0F0F; |
| const int vi1 = (v[i] >> 4) & 0x0F0F0F0F; |
|
|
| |
| sumi = ggml_cuda_dp4a(vi0, u[2*i+0], sumi); |
| sumi = ggml_cuda_dp4a(vi1, u[2*i+1], sumi); |
| } |
|
|
| #ifdef GGML_CUDA_F16 |
| const float2 tmp = __half22float2(__hmul2(dm4, ds8)); |
| const float d4d8 = tmp.x; |
| const float m4s8 = tmp.y; |
| #else |
| const float2 dm4f = __half22float2(dm4); |
| const float2 ds8f = __half22float2(ds8); |
| const float d4d8 = dm4f.x * ds8f.x; |
| const float m4s8 = dm4f.y * ds8f.y; |
| #endif |
|
|
| |
| return sumi * d4d8 + m4s8 / (QI8_1 / (vdr * QR4_1)); |
| } |
|
|
| #define VDR_Q5_0_Q8_1_MMVQ 2 |
| #define VDR_Q5_0_Q8_1_MMQ 4 |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q5_0_q8_1_impl( |
| const int * vl, const int * vh, const int * u, const float & d5, const half2 & ds8) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| int vi0 = (vl[i] >> 0) & 0x0F0F0F0F; |
| vi0 |= (vh[i] << 4) & 0x00000010; |
| vi0 |= (vh[i] << 11) & 0x00001000; |
| vi0 |= (vh[i] << 18) & 0x00100000; |
| vi0 |= (vh[i] << 25) & 0x10000000; |
| sumi = ggml_cuda_dp4a(vi0, u[2*i+0], sumi); |
|
|
| int vi1 = (vl[i] >> 4) & 0x0F0F0F0F; |
| vi1 |= (vh[i] >> 12) & 0x00000010; |
| vi1 |= (vh[i] >> 5) & 0x00001000; |
| vi1 |= (vh[i] << 2) & 0x00100000; |
| vi1 |= (vh[i] << 9) & 0x10000000; |
| sumi = ggml_cuda_dp4a(vi1, u[2*i+1], sumi); |
| } |
|
|
| const float2 ds8f = __half22float2(ds8); |
|
|
| |
| return d5 * (sumi * ds8f.x - (16*vdr/QI5_0) * ds8f.y); |
| } |
|
|
| #define VDR_Q5_1_Q8_1_MMVQ 2 |
| #define VDR_Q5_1_Q8_1_MMQ 4 |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q5_1_q8_1_impl( |
| const int * vl, const int * vh, const int * u, const half2 & dm5, const half2 & ds8) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| int vi0 = (vl[i] >> 0) & 0x0F0F0F0F; |
| vi0 |= (vh[i] << 4) & 0x00000010; |
| vi0 |= (vh[i] << 11) & 0x00001000; |
| vi0 |= (vh[i] << 18) & 0x00100000; |
| vi0 |= (vh[i] << 25) & 0x10000000; |
| sumi = ggml_cuda_dp4a(vi0, u[2*i+0], sumi); |
|
|
| int vi1 = (vl[i] >> 4) & 0x0F0F0F0F; |
| vi1 |= (vh[i] >> 12) & 0x00000010; |
| vi1 |= (vh[i] >> 5) & 0x00001000; |
| vi1 |= (vh[i] << 2) & 0x00100000; |
| vi1 |= (vh[i] << 9) & 0x10000000; |
| sumi = ggml_cuda_dp4a(vi1, u[2*i+1], sumi); |
| } |
|
|
| #ifdef GGML_CUDA_F16 |
| const float2 tmp = __half22float2(__hmul2(dm5, ds8)); |
| const float d5d8 = tmp.x; |
| const float m5s8 = tmp.y; |
| #else |
| const float2 dm5f = __half22float2(dm5); |
| const float2 ds8f = __half22float2(ds8); |
| const float d5d8 = dm5f.x * ds8f.x; |
| const float m5s8 = dm5f.y * ds8f.y; |
| #endif |
|
|
| |
| return sumi*d5d8 + m5s8 / (QI5_1 / vdr); |
| } |
|
|
| #define VDR_Q8_0_Q8_1_MMVQ 2 |
| #define VDR_Q8_0_Q8_1_MMQ 8 |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q8_0_q8_1_impl( |
| const int * v, const int * u, const float & d8_0, const float & d8_1) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| |
| sumi = ggml_cuda_dp4a(v[i], u[i], sumi); |
| } |
|
|
| return d8_0*d8_1 * sumi; |
| } |
|
|
| template <int vdr> static __device__ __forceinline__ float vec_dot_q8_1_q8_1_impl( |
| const int * v, const int * u, const half2 & dm8, const half2 & ds8) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i = 0; i < vdr; ++i) { |
| |
| sumi = ggml_cuda_dp4a(v[i], u[i], sumi); |
| } |
|
|
| #ifdef GGML_CUDA_F16 |
| const float2 tmp = __half22float2(__hmul2(dm8, ds8)); |
| const float d8d8 = tmp.x; |
| const float m8s8 = tmp.y; |
| #else |
| const float2 dm8f = __half22float2(dm8); |
| const float2 ds8f = __half22float2(ds8); |
| const float d8d8 = dm8f.x * ds8f.x; |
| const float m8s8 = dm8f.y * ds8f.y; |
| #endif |
|
|
| |
| return sumi*d8d8 + m8s8 / (QI8_1 / vdr); |
| } |
|
|
| #define VDR_Q2_K_Q8_1_MMVQ 1 |
| #define VDR_Q2_K_Q8_1_MMQ 2 |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q2_K_q8_1_impl_mmvq( |
| const int & v, const int * __restrict__ u, const uint8_t * __restrict__ scales, |
| const half2 & dm2, const float * __restrict__ d8) { |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR2_K; ++i) { |
| const int sc = scales[2*i]; |
|
|
| const int vi = (v >> (2*i)) & 0x03030303; |
|
|
| sumf_d += d8[i] * (ggml_cuda_dp4a(vi, u[i], 0) * (sc & 0xF)); |
|
|
| |
| int m = sc >> 4; |
| m |= m << 8; |
| m |= m << 16; |
| sumf_m += d8[i] * ggml_cuda_dp4a(m, u[i], 0); |
| } |
|
|
| const float2 dm2f = __half22float2(dm2); |
|
|
| return dm2f.x*sumf_d - dm2f.y*sumf_m; |
| } |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q2_K_q8_1_impl_mmq( |
| const int * __restrict__ v, const int * __restrict__ u, const uint8_t * __restrict__ scales, |
| const half2 & dm2, const float & d8) { |
|
|
| int sumi_d = 0; |
| int sumi_m = 0; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < QI8_1; i0 += QI8_1/2) { |
| int sumi_d_sc = 0; |
|
|
| const int sc = scales[i0 / (QI8_1/2)]; |
|
|
| |
| int m = sc >> 4; |
| m |= m << 8; |
| m |= m << 16; |
|
|
| #pragma unroll |
| for (int i = i0; i < i0 + QI8_1/2; ++i) { |
| sumi_d_sc = ggml_cuda_dp4a(v[i], u[i], sumi_d_sc); |
| sumi_m = ggml_cuda_dp4a(m, u[i], sumi_m); |
| } |
|
|
| sumi_d += sumi_d_sc * (sc & 0xF); |
| } |
|
|
| const float2 dm2f = __half22float2(dm2); |
|
|
| return d8 * (dm2f.x*sumi_d - dm2f.y*sumi_m); |
| } |
|
|
| #define VDR_Q3_K_Q8_1_MMVQ 1 |
| #define VDR_Q3_K_Q8_1_MMQ 2 |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q3_K_q8_1_impl_mmvq( |
| const int & vl, const int & vh, const int * __restrict__ u, const uint8_t * __restrict__ scales, |
| const int & scale_offset, const float & d3, const float * __restrict__ d8) { |
|
|
| float sumf = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR3_K; ++i) { |
| const int isc = scale_offset + 2*i; |
|
|
| const int isc_low = isc % (QK_K/32); |
| const int sc_shift_low = 4 * (isc / (QK_K/32)); |
| const int sc_low = (scales[isc_low] >> sc_shift_low) & 0xF; |
|
|
| const int isc_high = isc % (QK_K/64); |
| const int sc_shift_high = 2 * (isc / (QK_K/64)); |
| const int sc_high = ((scales[(QK_K/32) + isc_high] >> sc_shift_high) & 3) << 4; |
|
|
| const int sc = (sc_low | sc_high) - 32; |
|
|
| const int vil = (vl >> (2*i)) & 0x03030303; |
|
|
| const int vih = ((vh >> i) << 2) & 0x04040404; |
|
|
| const int vi = __vsubss4(vil, vih); |
|
|
| sumf += d8[i] * (ggml_cuda_dp4a(vi, u[i], 0) * sc); |
| } |
|
|
| return d3 * sumf; |
| } |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q3_K_q8_1_impl_mmq( |
| const int * __restrict__ v, const int * __restrict__ u, const int8_t * __restrict__ scales, |
| const float & d3, const float & d8) { |
|
|
| int sumi = 0; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < QR3_K*VDR_Q3_K_Q8_1_MMQ; i0 += QI8_1/2) { |
| int sumi_sc = 0; |
|
|
| for (int i = i0; i < i0 + QI8_1/2; ++i) { |
| sumi_sc = ggml_cuda_dp4a(v[i], u[i], sumi_sc); |
| } |
|
|
| sumi += sumi_sc * scales[i0 / (QI8_1/2)]; |
| } |
|
|
| return d3*d8 * sumi; |
| } |
|
|
| #define VDR_Q4_K_Q8_1_MMVQ 2 |
| #define VDR_Q4_K_Q8_1_MMQ 8 |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q4_K_q8_1_impl_vmmq( |
| const int * __restrict__ v, const int * __restrict__ u, const uint8_t * __restrict__ sc, |
| const uint8_t * __restrict__ m, const half2 & dm4, const float * __restrict__ d8) { |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR4_K; ++i) { |
| const int v0i = (v[0] >> (4*i)) & 0x0F0F0F0F; |
| const int v1i = (v[1] >> (4*i)) & 0x0F0F0F0F; |
|
|
| const int dot1 = ggml_cuda_dp4a(v1i, u[2*i+1], ggml_cuda_dp4a(v0i, u[2*i+0], 0)); |
| const int dot2 = ggml_cuda_dp4a(0x01010101, u[2*i+1], ggml_cuda_dp4a(0x01010101, u[2*i+0], 0)); |
|
|
| sumf_d += d8[i] * (dot1 * sc[i]); |
| sumf_m += d8[i] * (dot2 * m[i]); |
| } |
|
|
| const float2 dm4f = __half22float2(dm4); |
|
|
| return dm4f.x*sumf_d - dm4f.y*sumf_m; |
| } |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q4_K_q8_1_impl_mmq( |
| const int * __restrict__ v, const int * __restrict__ u, const uint8_t * __restrict__ sc, |
| const uint8_t * __restrict__ m, const half2 & dm4, const half2 * __restrict__ ds8) { |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR4_K*VDR_Q4_K_Q8_1_MMQ/QI8_1; ++i) { |
| int sumi_d = 0; |
|
|
| #pragma unroll |
| for (int j = 0; j < QI8_1; ++j) { |
| sumi_d = ggml_cuda_dp4a((v[j] >> (4*i)) & 0x0F0F0F0F, u[i*QI8_1 + j], sumi_d); |
| } |
|
|
| const float2 ds8f = __half22float2(ds8[i]); |
|
|
| sumf_d += ds8f.x * (sc[i] * sumi_d); |
| sumf_m += ds8f.y * m[i]; |
| } |
|
|
| const float2 dm4f = __half22float2(dm4); |
|
|
| return dm4f.x*sumf_d - dm4f.y*sumf_m; |
| } |
|
|
| #define VDR_Q5_K_Q8_1_MMVQ 2 |
| #define VDR_Q5_K_Q8_1_MMQ 8 |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q5_K_q8_1_impl_vmmq( |
| const int * __restrict__ vl, const int * __restrict__ vh, const int * __restrict__ u, const uint8_t * __restrict__ sc, |
| const uint8_t * __restrict__ m, const half2 & dm5, const float * __restrict__ d8) { |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR5_K; ++i) { |
| const int vl0i = (vl[0] >> (4*i)) & 0x0F0F0F0F; |
| const int vl1i = (vl[1] >> (4*i)) & 0x0F0F0F0F; |
|
|
| const int vh0i = ((vh[0] >> i) << 4) & 0x10101010; |
| const int vh1i = ((vh[1] >> i) << 4) & 0x10101010; |
|
|
| const int v0i = vl0i | vh0i; |
| const int v1i = vl1i | vh1i; |
|
|
| const int dot1 = ggml_cuda_dp4a(v0i, u[2*i+0], ggml_cuda_dp4a(v1i, u[2*i+1], 0)); |
| const int dot2 = ggml_cuda_dp4a(0x01010101, u[2*i+0], ggml_cuda_dp4a(0x01010101, u[2*i+1], 0)); |
|
|
| sumf_d += d8[i] * (dot1 * sc[i]); |
| sumf_m += d8[i] * (dot2 * m[i]); |
|
|
| } |
|
|
| const float2 dm5f = __half22float2(dm5); |
|
|
| return dm5f.x*sumf_d - dm5f.y*sumf_m; |
| } |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q5_K_q8_1_impl_mmq( |
| const int * __restrict__ v, const int * __restrict__ u, const uint8_t * __restrict__ sc, |
| const uint8_t * __restrict__ m, const half2 & dm4, const half2 * __restrict__ ds8) { |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR5_K*VDR_Q5_K_Q8_1_MMQ/QI8_1; ++i) { |
| int sumi_d = 0; |
|
|
| #pragma unroll |
| for (int j = 0; j < QI8_1; ++j) { |
| sumi_d = ggml_cuda_dp4a(v[i*QI8_1 + j], u[i*QI8_1 + j], sumi_d); |
| } |
|
|
| const float2 ds8f = __half22float2(ds8[i]); |
|
|
| sumf_d += ds8f.x * (sc[i] * sumi_d); |
| sumf_m += ds8f.y * m[i]; |
| } |
|
|
| const float2 dm4f = __half22float2(dm4); |
|
|
| return dm4f.x*sumf_d - dm4f.y*sumf_m; |
| } |
|
|
| #define VDR_Q6_K_Q8_1_MMVQ 1 |
| #define VDR_Q6_K_Q8_1_MMQ 8 |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q6_K_q8_1_impl_mmvq( |
| const int & vl, const int & vh, const int * __restrict__ u, const int8_t * __restrict__ scales, |
| const float & d, const float * __restrict__ d8) { |
|
|
| float sumf = 0.0f; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR6_K; ++i) { |
| const int sc = scales[4*i]; |
|
|
| const int vil = (vl >> (4*i)) & 0x0F0F0F0F; |
|
|
| const int vih = ((vh >> (4*i)) << 4) & 0x30303030; |
|
|
| const int vi = __vsubss4((vil | vih), 0x20202020); |
|
|
| sumf += d8[i] * (ggml_cuda_dp4a(vi, u[i], 0) * sc); |
| } |
|
|
| return d*sumf; |
| } |
|
|
| |
| static __device__ __forceinline__ float vec_dot_q6_K_q8_1_impl_mmq( |
| const int * __restrict__ v, const int * __restrict__ u, const int8_t * __restrict__ sc, |
| const float & d6, const float * __restrict__ d8) { |
|
|
| float sumf_d = 0.0f; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < VDR_Q6_K_Q8_1_MMQ; i0 += 4) { |
| int2 sumi_d = {0, 0}; |
|
|
| #pragma unroll |
| for (int i = i0; i < i0 + 2; ++i) { |
| sumi_d.x = ggml_cuda_dp4a(v[2*i+0], u[2*i+0], sumi_d.x); |
| sumi_d.x = ggml_cuda_dp4a(v[2*i+1], u[2*i+1], sumi_d.x); |
|
|
| sumi_d.y = ggml_cuda_dp4a(v[2*i+4], u[2*i+4], sumi_d.y); |
| sumi_d.y = ggml_cuda_dp4a(v[2*i+5], u[2*i+5], sumi_d.y); |
| } |
|
|
| sumf_d += d8[i0/4] * (sc[i0/2+0]*sumi_d.x + sc[i0/2+1]*sumi_d.y); |
| } |
|
|
| return d6 * sumf_d; |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q4_0_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q4_0 * bq4_0 = (const block_q4_0 *) vbq; |
|
|
| int v[VDR_Q4_0_Q8_1_MMVQ]; |
| int u[2*VDR_Q4_0_Q8_1_MMVQ]; |
|
|
| #pragma unroll |
| for (int i = 0; i < VDR_Q4_0_Q8_1_MMVQ; ++i) { |
| v[i] = get_int_from_uint8(bq4_0->qs, iqs + i); |
| u[2*i+0] = get_int_from_int8_aligned(bq8_1->qs, iqs + i); |
| u[2*i+1] = get_int_from_int8_aligned(bq8_1->qs, iqs + i + QI4_0); |
| } |
|
|
| return vec_dot_q4_0_q8_1_impl<VDR_Q4_0_Q8_1_MMVQ>(v, u, bq4_0->d, bq8_1->ds); |
| } |
|
|
|
|
| static __device__ __forceinline__ float vec_dot_q4_1_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q4_1 * bq4_1 = (const block_q4_1 *) vbq; |
|
|
| int v[VDR_Q4_1_Q8_1_MMVQ]; |
| int u[2*VDR_Q4_1_Q8_1_MMVQ]; |
|
|
| #pragma unroll |
| for (int i = 0; i < VDR_Q4_1_Q8_1_MMVQ; ++i) { |
| v[i] = get_int_from_uint8_aligned(bq4_1->qs, iqs + i); |
| u[2*i+0] = get_int_from_int8_aligned(bq8_1->qs, iqs + i); |
| u[2*i+1] = get_int_from_int8_aligned(bq8_1->qs, iqs + i + QI4_1); |
| } |
|
|
| return vec_dot_q4_1_q8_1_impl<VDR_Q4_1_Q8_1_MMVQ>(v, u, bq4_1->dm, bq8_1->ds); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_0_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q5_0 * bq5_0 = (const block_q5_0 *) vbq; |
|
|
| int vl[VDR_Q5_0_Q8_1_MMVQ]; |
| int vh[VDR_Q5_0_Q8_1_MMVQ]; |
| int u[2*VDR_Q5_0_Q8_1_MMVQ]; |
|
|
| #pragma unroll |
| for (int i = 0; i < VDR_Q5_0_Q8_1_MMVQ; ++i) { |
| vl[i] = get_int_from_uint8(bq5_0->qs, iqs + i); |
| vh[i] = get_int_from_uint8(bq5_0->qh, 0) >> (4 * (iqs + i)); |
| u[2*i+0] = get_int_from_int8_aligned(bq8_1->qs, iqs + i); |
| u[2*i+1] = get_int_from_int8_aligned(bq8_1->qs, iqs + i + QI5_0); |
| } |
|
|
| return vec_dot_q5_0_q8_1_impl<VDR_Q5_0_Q8_1_MMVQ>(vl, vh, u, bq5_0->d, bq8_1->ds); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_1_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q5_1 * bq5_1 = (const block_q5_1 *) vbq; |
|
|
| int vl[VDR_Q5_1_Q8_1_MMVQ]; |
| int vh[VDR_Q5_1_Q8_1_MMVQ]; |
| int u[2*VDR_Q5_1_Q8_1_MMVQ]; |
|
|
| #pragma unroll |
| for (int i = 0; i < VDR_Q5_1_Q8_1_MMVQ; ++i) { |
| vl[i] = get_int_from_uint8_aligned(bq5_1->qs, iqs + i); |
| vh[i] = get_int_from_uint8_aligned(bq5_1->qh, 0) >> (4 * (iqs + i)); |
| u[2*i+0] = get_int_from_int8_aligned(bq8_1->qs, iqs + i); |
| u[2*i+1] = get_int_from_int8_aligned(bq8_1->qs, iqs + i + QI5_1); |
| } |
|
|
| return vec_dot_q5_1_q8_1_impl<VDR_Q5_1_Q8_1_MMVQ>(vl, vh, u, bq5_1->dm, bq8_1->ds); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q8_0_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q8_0 * bq8_0 = (const block_q8_0 *) vbq; |
|
|
| int v[VDR_Q8_0_Q8_1_MMVQ]; |
| int u[VDR_Q8_0_Q8_1_MMVQ]; |
|
|
| #pragma unroll |
| for (int i = 0; i < VDR_Q8_0_Q8_1_MMVQ; ++i) { |
| v[i] = get_int_from_int8(bq8_0->qs, iqs + i); |
| u[i] = get_int_from_int8_aligned(bq8_1->qs, iqs + i); |
| } |
|
|
| return vec_dot_q8_0_q8_1_impl<VDR_Q8_0_Q8_1_MMVQ>(v, u, bq8_0->d, __low2half(bq8_1->ds)); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q2_K_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q2_K * bq2_K = (const block_q2_K *) vbq; |
|
|
| const int bq8_offset = QR2_K * (iqs / QI8_1); |
| const int scale_offset = iqs - iqs % QI8_1 + (iqs % QI8_1) / (QI8_1/2); |
|
|
| const uint8_t * scales = bq2_K->scales + scale_offset; |
|
|
| const int v = get_int_from_uint8_aligned(bq2_K->qs, iqs); |
| int u[QR2_K]; |
| float d8[QR2_K]; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR2_K; ++ i) { |
| u[i] = get_int_from_int8_aligned(bq8_1[bq8_offset + i].qs, iqs % QI8_1); |
| d8[i] = __low2float(bq8_1[bq8_offset + i].ds); |
| } |
|
|
| return vec_dot_q2_K_q8_1_impl_mmvq(v, u, scales, bq2_K->dm, d8); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q3_K_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q3_K * bq3_K = (const block_q3_K *) vbq; |
|
|
| const int bq8_offset = QR3_K * (iqs / (QI3_K/2)); |
| const int scale_offset = iqs - iqs % QI8_1 + (iqs % QI8_1) / (QI8_1/2); |
|
|
| const float d = bq3_K->d; |
|
|
| const int vl = get_int_from_uint8(bq3_K->qs, iqs); |
|
|
| |
| const int vh = ~get_int_from_uint8(bq3_K->hmask, iqs % (QI3_K/2)) >> bq8_offset; |
|
|
| int u[QR3_K]; |
| float d8[QR3_K]; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR3_K; ++i) { |
| u[i] = get_int_from_int8_aligned(bq8_1[bq8_offset + i].qs, iqs % QI8_1); |
| d8[i] = __low2float(bq8_1[bq8_offset + i].ds); |
| } |
|
|
| return vec_dot_q3_K_q8_1_impl_mmvq(vl, vh, u, bq3_K->scales, scale_offset, d, d8); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q4_K_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| #ifndef GGML_QKK_64 |
| const block_q4_K * bq4_K = (const block_q4_K *) vbq; |
|
|
| int v[2]; |
| int u[2*QR4_K]; |
| float d8[QR4_K]; |
|
|
| |
| const int bq8_offset = QR4_K * ((iqs/2) / (QI8_1/2)); |
|
|
| |
| |
| |
| |
|
|
| const int * q4 = (const int *)(bq4_K->qs + 16 * bq8_offset + 4 * ((iqs/2)%4)); |
| v[0] = q4[0]; |
| v[1] = q4[4]; |
|
|
| const uint16_t * scales = (const uint16_t *)bq4_K->scales; |
| uint16_t aux[2]; |
| const int j = bq8_offset/2; |
| if (j < 2) { |
| aux[0] = scales[j+0] & 0x3f3f; |
| aux[1] = scales[j+2] & 0x3f3f; |
| } else { |
| aux[0] = ((scales[j+2] >> 0) & 0x0f0f) | ((scales[j-2] & 0xc0c0) >> 2); |
| aux[1] = ((scales[j+2] >> 4) & 0x0f0f) | ((scales[j-0] & 0xc0c0) >> 2); |
| } |
| const uint8_t * sc = (const uint8_t *)aux; |
| const uint8_t * m = sc + 2; |
|
|
| for (int i = 0; i < QR4_K; ++i) { |
| const block_q8_1 * bq8i = bq8_1 + bq8_offset + i; |
| d8[i] = __low2float(bq8i->ds); |
|
|
| const int * q8 = (const int *)bq8i->qs + ((iqs/2)%4); |
| u[2*i+0] = q8[0]; |
| u[2*i+1] = q8[4]; |
| } |
|
|
| return vec_dot_q4_K_q8_1_impl_vmmq(v, u, sc, m, bq4_K->dm, d8); |
|
|
| #else |
|
|
| const block_q4_K * bq4_K = (const block_q4_K *) vbq; |
|
|
| float sumf_d = 0.0f; |
| float sumf_m = 0.0f; |
|
|
| uint16_t aux16[2]; |
| const uint8_t * s = (const uint8_t *)aux16; |
|
|
| const uint16_t * a = (const uint16_t *)bq4_K->scales; |
| aux16[0] = a[0] & 0x0f0f; |
| aux16[1] = (a[0] >> 4) & 0x0f0f; |
|
|
| const float dall = bq4_K->dm[0]; |
| const float dmin = bq4_K->dm[1]; |
|
|
| const float d8_1 = __low2float(bq8_1[0].ds); |
| const float d8_2 = __low2float(bq8_1[1].ds); |
|
|
| const int ui1 = *((const int *)bq8_1[0].qs + (iqs/2)); |
| const int ui2 = *((const int *)bq8_1[0].qs + (iqs/2) + 4); |
| const int ui3 = *((const int *)bq8_1[1].qs + (iqs/2)); |
| const int ui4 = *((const int *)bq8_1[1].qs + (iqs/2) + 4); |
|
|
| const int * q4 = (const int *)bq4_K->qs + (iqs/2); |
| const int v1 = q4[0]; |
| const int v2 = q4[4]; |
|
|
| const int dot1 = ggml_cuda_dp4a(ui2, v2 & 0x0f0f0f0f, ggml_cuda_dp4a(ui1, v1 & 0x0f0f0f0f, 0)); |
| const int dot2 = ggml_cuda_dp4a(ui4, (v2 >> 4) & 0x0f0f0f0f, ggml_cuda_dp4a(ui3, (v1 >> 4) & 0x0f0f0f0f, 0)); |
| const int dot3 = ggml_cuda_dp4a(0x01010101, ui2, ggml_cuda_dp4a(0x01010101, ui1, 0)); |
| const int dot4 = ggml_cuda_dp4a(0x01010101, ui4, ggml_cuda_dp4a(0x01010101, ui3, 0)); |
|
|
| sumf_d += d8_1 * (dot1 * s[0]) + d8_2 * (dot2 * s[1]); |
| sumf_m += d8_1 * (dot3 * s[2]) + d8_2 * (dot4 * s[3]); |
|
|
| return dall * sumf_d - dmin * sumf_m; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_K_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| #ifndef GGML_QKK_64 |
| const block_q5_K * bq5_K = (const block_q5_K *) vbq; |
|
|
| int vl[2]; |
| int vh[2]; |
| int u[2*QR5_K]; |
| float d8[QR5_K]; |
|
|
| const int bq8_offset = QR5_K * ((iqs/2) / (QI8_1/2)); |
| const int * ql = (const int *)(bq5_K->qs + 16 * bq8_offset + 4 * ((iqs/2)%4)); |
| const int * qh = (const int *)(bq5_K->qh + 4 * ((iqs/2)%4)); |
|
|
| vl[0] = ql[0]; |
| vl[1] = ql[4]; |
|
|
| vh[0] = qh[0] >> bq8_offset; |
| vh[1] = qh[4] >> bq8_offset; |
|
|
| const uint16_t * scales = (const uint16_t *)bq5_K->scales; |
| uint16_t aux[2]; |
| const int j = bq8_offset/2; |
| if (j < 2) { |
| aux[0] = scales[j+0] & 0x3f3f; |
| aux[1] = scales[j+2] & 0x3f3f; |
| } else { |
| aux[0] = ((scales[j+2] >> 0) & 0x0f0f) | ((scales[j-2] & 0xc0c0) >> 2); |
| aux[1] = ((scales[j+2] >> 4) & 0x0f0f) | ((scales[j-0] & 0xc0c0) >> 2); |
| } |
| const uint8_t * sc = (const uint8_t *)aux; |
| const uint8_t * m = sc + 2; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR5_K; ++i) { |
| const block_q8_1 * bq8i = bq8_1 + bq8_offset + i; |
| d8[i] = __low2float(bq8i->ds); |
|
|
| const int * q8 = (const int *)bq8i->qs + ((iqs/2)%4); |
| u[2*i+0] = q8[0]; |
| u[2*i+1] = q8[4]; |
| } |
|
|
| return vec_dot_q5_K_q8_1_impl_vmmq(vl, vh, u, sc, m, bq5_K->dm, d8); |
|
|
| #else |
|
|
| const block_q5_K * bq5_K = (const block_q5_K *) vbq; |
|
|
| const int8_t * s = bq5_K->scales; |
|
|
| const float d = bq5_K->d; |
|
|
| const float d8_1 = __low2half(bq8_1[0].ds); |
| const float d8_2 = __low2half(bq8_1[1].ds); |
|
|
| const int ui1 = *((const int *)bq8_1[0].qs + (iqs/2)); |
| const int ui2 = *((const int *)bq8_1[0].qs + (iqs/2) + 4); |
| const int ui3 = *((const int *)bq8_1[1].qs + (iqs/2)); |
| const int ui4 = *((const int *)bq8_1[1].qs + (iqs/2) + 4); |
|
|
| const int * ql = (const int *)bq5_K->qs + (iqs/2); |
| const int vl1 = ql[0]; |
| const int vl2 = ql[4]; |
|
|
| const int step = 4 * (iqs/2); |
| const int im = step/8; |
| const int in = step%8; |
| const int vh = (*((const int *)(bq5_K->qh + in))) >> im; |
|
|
| const int v1 = (((vh << 4) & 0x10101010) ^ 0x10101010) | ((vl1 >> 0) & 0x0f0f0f0f); |
| const int v2 = (((vh << 2) & 0x10101010) ^ 0x10101010) | ((vl2 >> 0) & 0x0f0f0f0f); |
| const int v3 = (((vh >> 0) & 0x10101010) ^ 0x10101010) | ((vl1 >> 4) & 0x0f0f0f0f); |
| const int v4 = (((vh >> 2) & 0x10101010) ^ 0x10101010) | ((vl2 >> 4) & 0x0f0f0f0f); |
|
|
| const float sumf_d = d8_1 * (ggml_cuda_dp4a(ui1, v1, 0) * s[0] + ggml_cuda_dp4a(ui2, v2, 0) * s[1]) |
| + d8_2 * (ggml_cuda_dp4a(ui3, v3, 0) * s[2] + ggml_cuda_dp4a(ui4, v4, 0) * s[3]); |
|
|
| return d * sumf_d; |
| #endif |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q6_K_q8_1( |
| const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs) { |
|
|
| const block_q6_K * bq6_K = (const block_q6_K *) vbq; |
|
|
| const int bq8_offset = 2 * QR6_K * (iqs / (QI6_K/2)) + (iqs % (QI6_K/2)) / (QI6_K/4); |
| const int scale_offset = (QI6_K/4) * (iqs / (QI6_K/2)) + (iqs % (QI6_K/2)) / (QI6_K/8); |
| const int vh_shift = 2 * ((iqs % (QI6_K/2)) / (QI6_K/4)); |
|
|
| const int vl = get_int_from_uint8(bq6_K->ql, iqs); |
| const int vh = get_int_from_uint8(bq6_K->qh, (QI6_K/4) * (iqs / (QI6_K/2)) + iqs % (QI6_K/4)) >> vh_shift; |
|
|
| const int8_t * scales = bq6_K->scales + scale_offset; |
|
|
| int u[QR6_K]; |
| float d8[QR6_K]; |
|
|
| #pragma unroll |
| for (int i = 0; i < QR6_K; ++i) { |
| u[i] = get_int_from_int8_aligned(bq8_1[bq8_offset + 2*i].qs, iqs % QI8_1); |
| d8[i] = __low2float(bq8_1[bq8_offset + 2*i].ds); |
| } |
|
|
| return vec_dot_q6_K_q8_1_impl_mmvq(vl, vh, u, scales, bq6_K->d, d8); |
| } |
|
|
| |
| typedef float (*vec_dot_q_cuda_t)(const void * __restrict__ vbq, const block_q8_1 * __restrict__ bq8_1, const int & iqs); |
|
|
| template <int ncols_y, int qk, int qi, typename block_q_t, int vdr, vec_dot_q_cuda_t vec_dot_q_cuda> |
| static __device__ void mul_mat_vec_q( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| #if defined(GGML_USE_HIPBLAS) && defined(__HIP_PLATFORM_AMD__) && (defined(RDNA2) || defined(RDNA3)) |
| constexpr int nwarps = 1; |
| constexpr int rows_per_cuda_block = 1; |
| #else |
| constexpr int nwarps = ncols_y <= 4 ? 4 : 2; |
| constexpr int rows_per_cuda_block = ncols_y == 1 ? 1 : 2; |
| #endif |
|
|
| const int tid = WARP_SIZE*threadIdx.y + threadIdx.x; |
| const int row0 = rows_per_cuda_block*blockIdx.x; |
| const int blocks_per_row_x = ncols_x / qk; |
| const int blocks_per_col_y = nrows_y / QK8_1; |
| constexpr int blocks_per_iter = vdr * nwarps*WARP_SIZE / qi; |
|
|
| |
| float tmp[ncols_y][rows_per_cuda_block] = {0.0f}; |
|
|
| const block_q_t * x = (const block_q_t *) vx; |
| const block_q8_1 * y = (const block_q8_1 *) vy; |
|
|
| for (int kbx = tid / (qi/vdr); kbx < blocks_per_row_x; kbx += blocks_per_iter) { |
| const int kby = kbx * (qk/QK8_1); |
|
|
| |
| const int kqs = vdr * (tid % (qi/vdr)); |
|
|
| #pragma unroll |
| for (int j = 0; j < ncols_y; ++j) { |
| #pragma unroll |
| for (int i = 0; i < rows_per_cuda_block; ++i) { |
| tmp[j][i] += vec_dot_q_cuda( |
| &x[kbx + (row0 + i)*blocks_per_row_x], &y[j*blocks_per_col_y + kby], kqs); |
| } |
| } |
| } |
|
|
| __shared__ float tmp_shared[nwarps-1 > 0 ? nwarps-1 : 1][ncols_y][rows_per_cuda_block][WARP_SIZE]; |
| if (threadIdx.y > 0) { |
| #pragma unroll |
| for (int j = 0; j < ncols_y; ++j) { |
| #pragma unroll |
| for (int i = 0; i < rows_per_cuda_block; ++i) { |
| tmp_shared[threadIdx.y-1][j][i][threadIdx.x] = tmp[j][i]; |
| } |
| } |
| } |
| __syncthreads(); |
| if (threadIdx.y > 0) { |
| return; |
| } |
|
|
| |
| #pragma unroll |
| for (int j = 0; j < ncols_y; ++j) { |
| #pragma unroll |
| for (int i = 0; i < rows_per_cuda_block; ++i) { |
| #pragma unroll |
| for (int l = 0; l < nwarps-1; ++l) { |
| tmp[j][i] += tmp_shared[l][j][i][threadIdx.x]; |
| } |
| tmp[j][i] = warp_reduce_sum(tmp[j][i]); |
| } |
|
|
| if (threadIdx.x < rows_per_cuda_block) { |
| dst[j*nrows_dst + row0 + threadIdx.x] = tmp[j][threadIdx.x]; |
| } |
| } |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda1( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<1, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda2( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<2, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda3( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<3, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda4( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<4, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda5( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<5, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda6( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<6, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda7( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<7, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| |
| extern "C" __global__ void mul_mat_vec_q4_0_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK4_0, QI4_0, block_q4_0, VDR_Q4_0_Q8_1_MMVQ, vec_dot_q4_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_1_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK4_1, QI4_1, block_q4_1, VDR_Q4_1_Q8_1_MMVQ, vec_dot_q4_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_0_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK5_0, QI5_0, block_q5_0, VDR_Q5_0_Q8_1_MMVQ, vec_dot_q5_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_1_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK5_1, QI5_1, block_q5_1, VDR_Q5_1_Q8_1_MMVQ, vec_dot_q5_1_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q8_0_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q2_K_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q3_K_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q4_K_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q5_K_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void mul_mat_vec_q6_K_q8_1_cuda8( |
| const void * vx, const void * vy, float * dst, |
| const int ncols_x, const int nrows_x, const int nrows_y, const int nrows_dst) { |
|
|
| mul_mat_vec_q<8, QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (vx, vy, dst, ncols_x, nrows_x, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void quantize_q8_1(const float * __restrict__ x, void * __restrict__ vy, const int kx, const int kx_padded) { |
| const int ix = blockDim.x*blockIdx.x + threadIdx.x; |
|
|
| if (ix >= kx_padded) { |
| return; |
| } |
|
|
| const int iy = blockDim.y*blockIdx.y + threadIdx.y; |
|
|
| const int i_padded = iy*kx_padded + ix; |
|
|
| block_q8_1 * y = (block_q8_1 *) vy; |
|
|
| const int ib = i_padded / QK8_1; |
| const int iqs = i_padded % QK8_1; |
|
|
| const float xi = ix < kx ? x[iy*kx + ix] : 0.0f; |
| float amax = fabsf(xi); |
| float sum = xi; |
|
|
| amax = warp_reduce_max(amax); |
| sum = warp_reduce_sum(sum); |
|
|
| const float d = amax / 127; |
| const int8_t q = amax == 0.0f ? 0 : roundf(xi / d); |
|
|
| y[ib].qs[iqs] = q; |
|
|
| if (iqs > 0) { |
| return; |
| } |
|
|
| reinterpret_cast<half&>(y[ib].ds.x) = d; |
| reinterpret_cast<half&>(y[ib].ds.y) = sum; |
| } |
|
|
| |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q5_0(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| __shared__ int tile_x_ql[mmq_y * (2*WARP_SIZE) + mmq_y]; |
| __shared__ float tile_x_d[mmq_y * (WARP_SIZE/QI5_0) + mmq_y/QI5_0]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = (half2 *) tile_x_d; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q5_0( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI5_0; |
| const int kqsx = k % QI5_0; |
|
|
| const block_q5_0 * bx0 = (const block_q5_0 *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_0 * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| const int ql = get_int_from_uint8(bxi->qs, kqsx); |
| const int qh = get_int_from_uint8(bxi->qh, 0) >> (4 * (k % QI5_0)); |
|
|
| int qs0 = (ql >> 0) & 0x0F0F0F0F; |
| qs0 |= (qh << 4) & 0x00000010; |
| qs0 |= (qh << 11) & 0x00001000; |
| qs0 |= (qh << 18) & 0x00100000; |
| qs0 |= (qh << 25) & 0x10000000; |
| qs0 = __vsubss4(qs0, 0x10101010); |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + 2*k+0] = qs0; |
|
|
| int qs1 = (ql >> 4) & 0x0F0F0F0F; |
| qs1 |= (qh >> 12) & 0x00000010; |
| qs1 |= (qh >> 5) & 0x00001000; |
| qs1 |= (qh << 2) & 0x00100000; |
| qs1 |= (qh << 9) & 0x10000000; |
| qs1 = __vsubss4(qs1, 0x10101010); |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + 2*k+1] = qs1; |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI5_0; |
| const int kbxd = k % blocks_per_tile_x_row; |
| float * x_dmf = (float *) x_dm; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI5_0) { |
| int i = i0 + i_offset * QI5_0 + k / blocks_per_tile_x_row; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_0 * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dmf[i * (WARP_SIZE/QI5_0) + i / QI5_0 + kbxd] = bxi->d; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_0_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| const int kyqs = k % (QI8_1/2) + QI8_1 * (k / (QI8_1/2)); |
| const int index_bx = i * (WARP_SIZE/QI5_0) + i/QI5_0 + k/QI5_0; |
| const float * x_dmf = (const float *) x_dm; |
| const float * y_df = (const float *) y_ds; |
|
|
| int u[2*VDR_Q5_0_Q8_1_MMQ]; |
|
|
| #pragma unroll |
| for (int l = 0; l < VDR_Q5_0_Q8_1_MMQ; ++l) { |
| u[2*l+0] = y_qs[j * WARP_SIZE + (kyqs + l) % WARP_SIZE]; |
| u[2*l+1] = y_qs[j * WARP_SIZE + (kyqs + l + QI5_0) % WARP_SIZE]; |
| } |
|
|
| return vec_dot_q8_0_q8_1_impl<QR5_0*VDR_Q5_0_Q8_1_MMQ> |
| (&x_ql[i * (2*WARP_SIZE + 1) + 2 * k], u, x_dmf[index_bx], y_df[j * (WARP_SIZE/QI8_1) + (2*k/QI8_1) % (WARP_SIZE/QI8_1)]); |
| } |
|
|
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q5_1(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| __shared__ int tile_x_ql[mmq_y * (2*WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI5_1) + mmq_y/QI5_1]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q5_1( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI5_1; |
| const int kqsx = k % QI5_1; |
|
|
| const block_q5_1 * bx0 = (const block_q5_1 *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_1 * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| const int ql = get_int_from_uint8_aligned(bxi->qs, kqsx); |
| const int qh = get_int_from_uint8_aligned(bxi->qh, 0) >> (4 * (k % QI5_1)); |
|
|
| int qs0 = (ql >> 0) & 0x0F0F0F0F; |
| qs0 |= (qh << 4) & 0x00000010; |
| qs0 |= (qh << 11) & 0x00001000; |
| qs0 |= (qh << 18) & 0x00100000; |
| qs0 |= (qh << 25) & 0x10000000; |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + 2*k+0] = qs0; |
|
|
| int qs1 = (ql >> 4) & 0x0F0F0F0F; |
| qs1 |= (qh >> 12) & 0x00000010; |
| qs1 |= (qh >> 5) & 0x00001000; |
| qs1 |= (qh << 2) & 0x00100000; |
| qs1 |= (qh << 9) & 0x10000000; |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + 2*k+1] = qs1; |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI5_1; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI5_1) { |
| int i = i0 + i_offset * QI5_1 + k / blocks_per_tile_x_row; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_1 * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dm[i * (WARP_SIZE/QI5_1) + i / QI5_1 + kbxd] = bxi->dm; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_1_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| const int kyqs = k % (QI8_1/2) + QI8_1 * (k / (QI8_1/2)); |
| const int index_bx = i * (WARP_SIZE/QI5_1) + + i/QI5_1 + k/QI5_1; |
|
|
| int u[2*VDR_Q5_1_Q8_1_MMQ]; |
|
|
| #pragma unroll |
| for (int l = 0; l < VDR_Q5_1_Q8_1_MMQ; ++l) { |
| u[2*l+0] = y_qs[j * WARP_SIZE + (kyqs + l) % WARP_SIZE]; |
| u[2*l+1] = y_qs[j * WARP_SIZE + (kyqs + l + QI5_1) % WARP_SIZE]; |
| } |
|
|
| return vec_dot_q8_1_q8_1_impl<QR5_1*VDR_Q5_1_Q8_1_MMQ> |
| (&x_ql[i * (2*WARP_SIZE + 1) + 2 * k], u, x_dm[index_bx], y_ds[j * (WARP_SIZE/QI8_1) + (2*k/QI8_1) % (WARP_SIZE/QI8_1)]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q8_0(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| __shared__ int tile_x_qs[mmq_y * (WARP_SIZE) + mmq_y]; |
| __shared__ float tile_x_d[mmq_y * (WARP_SIZE/QI8_0) + mmq_y/QI8_0]; |
|
|
| *x_ql = tile_x_qs; |
| *x_dm = (half2 *) tile_x_d; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q8_0( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI8_0; |
| const int kqsx = k % QI8_0; |
| float * x_dmf = (float *) x_dm; |
|
|
| const block_q8_0 * bx0 = (const block_q8_0 *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q8_0 * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_int8(bxi->qs, kqsx); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI8_0; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI8_0) { |
| int i = i0 + i_offset * QI8_0 + k / blocks_per_tile_x_row; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q8_0 * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dmf[i * (WARP_SIZE/QI8_0) + i / QI8_0 + kbxd] = bxi->d; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q8_0_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| const float * x_dmf = (const float *) x_dm; |
| const float * y_df = (const float *) y_ds; |
|
|
| return vec_dot_q8_0_q8_1_impl<VDR_Q8_0_Q8_1_MMQ> |
| (&x_ql[i * (WARP_SIZE + 1) + k], &y_qs[j * WARP_SIZE + k], x_dmf[i * (WARP_SIZE/QI8_0) + i/QI8_0 + k/QI8_0], |
| y_df[j * (WARP_SIZE/QI8_1) + k/QI8_1]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q2_K(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); |
|
|
| __shared__ int tile_x_ql[mmq_y * (WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI2_K) + mmq_y/QI2_K]; |
| __shared__ int tile_x_sc[mmq_y * (WARP_SIZE/4) + mmq_y/4]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| *x_sc = tile_x_sc; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q2_K( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI2_K; |
| const int kqsx = k % QI2_K; |
|
|
| const block_q2_K * bx0 = (const block_q2_K *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q2_K * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_uint8_aligned(bxi->qs, kqsx); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI2_K; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI2_K) { |
| int i = (i0 + i_offset * QI2_K + k / blocks_per_tile_x_row) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q2_K * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dm[i * (WARP_SIZE/QI2_K) + i / QI2_K + kbxd] = bxi->dm; |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 4) { |
| int i = i0 + i_offset * 4 + k / (WARP_SIZE/4); |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q2_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/4)) / (QI2_K/4); |
|
|
| x_sc[i * (WARP_SIZE/4) + i / 4 + k % (WARP_SIZE/4)] = get_int_from_uint8_aligned(bxi->scales, k % (QI2_K/4)); |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q2_K_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); |
|
|
| const int kbx = k / QI2_K; |
| const int ky = (k % QI2_K) * QR2_K; |
| const float * y_df = (const float *) y_ds; |
|
|
| int v[QR2_K*VDR_Q2_K_Q8_1_MMQ]; |
|
|
| const int kqsx = i * (WARP_SIZE + 1) + kbx*QI2_K + (QI2_K/2) * (ky/(2*QI2_K)) + ky % (QI2_K/2); |
| const int shift = 2 * ((ky % (2*QI2_K)) / (QI2_K/2)); |
|
|
| #pragma unroll |
| for (int l = 0; l < QR2_K*VDR_Q2_K_Q8_1_MMQ; ++l) { |
| v[l] = (x_ql[kqsx + l] >> shift) & 0x03030303; |
| } |
|
|
| const uint8_t * scales = ((const uint8_t *) &x_sc[i * (WARP_SIZE/4) + i/4 + kbx*4]) + ky/4; |
|
|
| const int index_y = j * WARP_SIZE + (QR2_K*k) % WARP_SIZE; |
| return vec_dot_q2_K_q8_1_impl_mmq(v, &y_qs[index_y], scales, x_dm[i * (WARP_SIZE/QI2_K) + i/QI2_K + kbx], y_df[index_y/QI8_1]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q3_K(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
|
|
| __shared__ int tile_x_ql[mmq_y * (WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI3_K) + mmq_y/QI3_K]; |
| __shared__ int tile_x_qh[mmq_y * (WARP_SIZE/2) + mmq_y/2]; |
| __shared__ int tile_x_sc[mmq_y * (WARP_SIZE/4) + mmq_y/4]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| *x_qh = tile_x_qh; |
| *x_sc = tile_x_sc; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q3_K( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI3_K; |
| const int kqsx = k % QI3_K; |
|
|
| const block_q3_K * bx0 = (const block_q3_K *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q3_K * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_uint8(bxi->qs, kqsx); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI3_K; |
| const int kbxd = k % blocks_per_tile_x_row; |
| float * x_dmf = (float *) x_dm; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI3_K) { |
| int i = (i0 + i_offset * QI3_K + k / blocks_per_tile_x_row) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q3_K * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dmf[i * (WARP_SIZE/QI3_K) + i / QI3_K + kbxd] = bxi->d; |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 2) { |
| int i = i0 + i_offset * 2 + k / (WARP_SIZE/2); |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q3_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/2)) / (QI3_K/2); |
|
|
| |
| x_qh[i * (WARP_SIZE/2) + i / 2 + k % (WARP_SIZE/2)] = ~get_int_from_uint8(bxi->hmask, k % (QI3_K/2)); |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 4) { |
| int i = i0 + i_offset * 4 + k / (WARP_SIZE/4); |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q3_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/4)) / (QI3_K/4); |
|
|
| const int ksc = k % (QI3_K/4); |
|
|
| const int ksc_low = ksc % (QI3_K/8); |
| const int shift_low = 4 * (ksc / (QI3_K/8)); |
| const int sc_low = (get_int_from_uint8(bxi->scales, ksc_low) >> shift_low) & 0x0F0F0F0F; |
|
|
| const int ksc_high = QI3_K/8; |
| const int shift_high = 2 * ksc; |
| const int sc_high = ((get_int_from_uint8(bxi->scales, ksc_high) >> shift_high) << 4) & 0x30303030; |
|
|
| const int sc = __vsubss4(sc_low | sc_high, 0x20202020); |
|
|
| x_sc[i * (WARP_SIZE/4) + i / 4 + k % (WARP_SIZE/4)] = sc; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q3_K_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
|
|
| const int kbx = k / QI3_K; |
| const int ky = (k % QI3_K) * QR3_K; |
| const float * x_dmf = (const float *) x_dm; |
| const float * y_df = (const float *) y_ds; |
|
|
| const int8_t * scales = ((const int8_t *) (x_sc + i * (WARP_SIZE/4) + i/4 + kbx*4)) + ky/4; |
|
|
| int v[QR3_K*VDR_Q3_K_Q8_1_MMQ]; |
|
|
| #pragma unroll |
| for (int l = 0; l < QR3_K*VDR_Q3_K_Q8_1_MMQ; ++l) { |
| const int kqsx = i * (WARP_SIZE + 1) + kbx*QI3_K + (QI3_K/2) * (ky/(2*QI3_K)) + ky % (QI3_K/2); |
| const int shift = 2 * ((ky % 32) / 8); |
| const int vll = (x_ql[kqsx + l] >> shift) & 0x03030303; |
|
|
| const int vh = x_qh[i * (WARP_SIZE/2) + i/2 + kbx * (QI3_K/2) + (ky+l)%8] >> ((ky+l) / 8); |
| const int vlh = (vh << 2) & 0x04040404; |
|
|
| v[l] = __vsubss4(vll, vlh); |
| } |
|
|
| const int index_y = j * WARP_SIZE + (k*QR3_K) % WARP_SIZE; |
| return vec_dot_q3_K_q8_1_impl_mmq(v, &y_qs[index_y], scales, x_dmf[i * (WARP_SIZE/QI3_K) + i/QI3_K + kbx], y_df[index_y/QI8_1]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q4_K(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); |
|
|
| __shared__ int tile_x_ql[mmq_y * (WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI4_K) + mmq_y/QI4_K]; |
| __shared__ int tile_x_sc[mmq_y * (WARP_SIZE/8) + mmq_y/8]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| *x_sc = tile_x_sc; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q4_K( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI4_K; |
| const int kqsx = k % QI4_K; |
|
|
| const block_q4_K * bx0 = (const block_q4_K *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_K * bxi = bx0 + i*blocks_per_row + kbx; |
|
|
| x_ql[i * (WARP_SIZE + 1) + k] = get_int_from_uint8_aligned(bxi->qs, kqsx); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI4_K; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI4_K) { |
| int i = (i0 + i_offset * QI4_K + k / blocks_per_tile_x_row) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_K * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| #if QK_K == 256 |
| x_dm[i * (WARP_SIZE/QI4_K) + i / QI4_K + kbxd] = bxi->dm; |
| #else |
| x_dm[i * (WARP_SIZE/QI4_K) + i / QI4_K + kbxd] = {bxi->dm[0], bxi->dm[1]}; |
| #endif |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 8) { |
| int i = (i0 + i_offset * 8 + k / (WARP_SIZE/8)) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q4_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/8)) / (QI4_K/8); |
|
|
| const int * scales = (const int *) bxi->scales; |
|
|
| const int ksc = k % (WARP_SIZE/8); |
|
|
| |
| int scales8 = (scales[(ksc%2) + (ksc!=0)] >> (4 * (ksc & (ksc/2)))) & 0x0F0F0F0F; |
| scales8 |= (scales[ksc/2] >> (2 * (ksc % 2))) & 0x30303030; |
|
|
| x_sc[i * (WARP_SIZE/8) + i / 8 + ksc] = scales8; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q4_K_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); |
|
|
| const uint8_t * sc = ((const uint8_t *) &x_sc[i * (WARP_SIZE/8) + i/8 + k/16]) + 2*((k % 16) / 8); |
|
|
| const int index_y = j * WARP_SIZE + (QR4_K*k) % WARP_SIZE; |
| return vec_dot_q4_K_q8_1_impl_mmq(&x_ql[i * (WARP_SIZE + 1) + k], &y_qs[index_y], sc, sc+8, |
| x_dm[i * (WARP_SIZE/QI4_K) + i/QI4_K], &y_ds[index_y/QI8_1]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q5_K(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); |
|
|
| __shared__ int tile_x_ql[mmq_y * (2*WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI5_K) + mmq_y/QI5_K]; |
| __shared__ int tile_x_sc[mmq_y * (WARP_SIZE/8) + mmq_y/8]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| *x_sc = tile_x_sc; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q5_K( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI5_K; |
| const int kqsx = k % QI5_K; |
|
|
| const block_q5_K * bx0 = (const block_q5_K *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_K * bxi = bx0 + i*blocks_per_row + kbx; |
| const int ky = QR5_K*kqsx; |
|
|
| const int ql = get_int_from_uint8_aligned(bxi->qs, kqsx); |
| const int ql0 = (ql >> 0) & 0x0F0F0F0F; |
| const int ql1 = (ql >> 4) & 0x0F0F0F0F; |
|
|
| const int qh = get_int_from_uint8_aligned(bxi->qh, kqsx % (QI5_K/4)); |
| const int qh0 = ((qh >> (2 * (kqsx / (QI5_K/4)) + 0)) << 4) & 0x10101010; |
| const int qh1 = ((qh >> (2 * (kqsx / (QI5_K/4)) + 1)) << 4) & 0x10101010; |
|
|
| const int kq0 = ky - ky % (QI5_K/2) + k % (QI5_K/4) + 0; |
| const int kq1 = ky - ky % (QI5_K/2) + k % (QI5_K/4) + (QI5_K/4); |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + kq0] = ql0 | qh0; |
| x_ql[i * (2*WARP_SIZE + 1) + kq1] = ql1 | qh1; |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI5_K; |
| const int kbxd = k % blocks_per_tile_x_row; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI5_K) { |
| int i = (i0 + i_offset * QI5_K + k / blocks_per_tile_x_row) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_K * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| #if QK_K == 256 |
| x_dm[i * (WARP_SIZE/QI5_K) + i / QI5_K + kbxd] = bxi->dm; |
| #endif |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 8) { |
| int i = (i0 + i_offset * 8 + k / (WARP_SIZE/8)) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q5_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/8)) / (QI5_K/8); |
|
|
| const int * scales = (const int *) bxi->scales; |
|
|
| const int ksc = k % (WARP_SIZE/8); |
|
|
| |
| int scales8 = (scales[(ksc%2) + (ksc!=0)] >> (4 * (ksc & (ksc/2)))) & 0x0F0F0F0F; |
| scales8 |= (scales[ksc/2] >> (2 * (ksc % 2))) & 0x30303030; |
|
|
| x_sc[i * (WARP_SIZE/8) + i / 8 + ksc] = scales8; |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q5_K_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); |
|
|
| const uint8_t * sc = ((const uint8_t *) &x_sc[i * (WARP_SIZE/8) + i/8 + k/16]) + 2 * ((k % 16) / 8); |
|
|
| const int index_x = i * (QR5_K*WARP_SIZE + 1) + QR5_K*k; |
| const int index_y = j * WARP_SIZE + (QR5_K*k) % WARP_SIZE; |
| return vec_dot_q5_K_q8_1_impl_mmq(&x_ql[index_x], &y_qs[index_y], sc, sc+8, |
| x_dm[i * (WARP_SIZE/QI5_K) + i/QI5_K], &y_ds[index_y/QI8_1]); |
| } |
|
|
| template <int mmq_y> static __device__ __forceinline__ void allocate_tiles_q6_K(int ** x_ql, half2 ** x_dm, int ** x_qh, int ** x_sc) { |
| GGML_UNUSED(x_qh); |
|
|
| __shared__ int tile_x_ql[mmq_y * (2*WARP_SIZE) + mmq_y]; |
| __shared__ half2 tile_x_dm[mmq_y * (WARP_SIZE/QI6_K) + mmq_y/QI6_K]; |
| __shared__ int tile_x_sc[mmq_y * (WARP_SIZE/8) + mmq_y/8]; |
|
|
| *x_ql = tile_x_ql; |
| *x_dm = tile_x_dm; |
| *x_sc = tile_x_sc; |
| } |
|
|
| template <int mmq_y, int nwarps, bool need_check> static __device__ __forceinline__ void load_tiles_q6_K( |
| const void * __restrict__ vx, int * __restrict__ x_ql, half2 * __restrict__ x_dm, int * __restrict__ x_qh, |
| int * __restrict__ x_sc, const int & i_offset, const int & i_max, const int & k, const int & blocks_per_row) { |
| GGML_UNUSED(x_qh); |
|
|
| GGML_CUDA_ASSUME(i_offset >= 0); |
| GGML_CUDA_ASSUME(i_offset < nwarps); |
| GGML_CUDA_ASSUME(k >= 0); |
| GGML_CUDA_ASSUME(k < WARP_SIZE); |
|
|
| const int kbx = k / QI6_K; |
| const int kqsx = k % QI6_K; |
|
|
| const block_q6_K * bx0 = (const block_q6_K *) vx; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps) { |
| int i = i0 + i_offset; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q6_K * bxi = bx0 + i*blocks_per_row + kbx; |
| const int ky = QR6_K*kqsx; |
|
|
| const int ql = get_int_from_uint8(bxi->ql, kqsx); |
| const int ql0 = (ql >> 0) & 0x0F0F0F0F; |
| const int ql1 = (ql >> 4) & 0x0F0F0F0F; |
|
|
| const int qh = get_int_from_uint8(bxi->qh, (QI6_K/4) * (kqsx / (QI6_K/2)) + kqsx % (QI6_K/4)); |
| const int qh0 = ((qh >> (2 * ((kqsx % (QI6_K/2)) / (QI6_K/4)))) << 4) & 0x30303030; |
| const int qh1 = (qh >> (2 * ((kqsx % (QI6_K/2)) / (QI6_K/4)))) & 0x30303030; |
|
|
| const int kq0 = ky - ky % QI6_K + k % (QI6_K/2) + 0; |
| const int kq1 = ky - ky % QI6_K + k % (QI6_K/2) + (QI6_K/2); |
|
|
| x_ql[i * (2*WARP_SIZE + 1) + kq0] = __vsubss4(ql0 | qh0, 0x20202020); |
| x_ql[i * (2*WARP_SIZE + 1) + kq1] = __vsubss4(ql1 | qh1, 0x20202020); |
| } |
|
|
| const int blocks_per_tile_x_row = WARP_SIZE / QI6_K; |
| const int kbxd = k % blocks_per_tile_x_row; |
| float * x_dmf = (float *) x_dm; |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * QI6_K) { |
| int i = (i0 + i_offset * QI6_K + k / blocks_per_tile_x_row) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q6_K * bxi = bx0 + i*blocks_per_row + kbxd; |
|
|
| x_dmf[i * (WARP_SIZE/QI6_K) + i / QI6_K + kbxd] = bxi->d; |
| } |
|
|
| #pragma unroll |
| for (int i0 = 0; i0 < mmq_y; i0 += nwarps * 8) { |
| int i = (i0 + i_offset * 8 + k / (WARP_SIZE/8)) % mmq_y; |
|
|
| if (need_check) { |
| i = min(i, i_max); |
| } |
|
|
| const block_q6_K * bxi = bx0 + i*blocks_per_row + (k % (WARP_SIZE/8)) / 4; |
|
|
| x_sc[i * (WARP_SIZE/8) + i / 8 + k % (WARP_SIZE/8)] = get_int_from_int8(bxi->scales, k % (QI6_K/8)); |
| } |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q6_K_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); |
|
|
| const float * x_dmf = (const float *) x_dm; |
| const float * y_df = (const float *) y_ds; |
|
|
| const int8_t * sc = ((const int8_t *) &x_sc[i * (WARP_SIZE/8) + i/8 + k/8]); |
|
|
| const int index_x = i * (QR6_K*WARP_SIZE + 1) + QR6_K*k; |
| const int index_y = j * WARP_SIZE + (QR6_K*k) % WARP_SIZE; |
| return vec_dot_q6_K_q8_1_impl_mmq(&x_ql[index_x], &y_qs[index_y], sc, x_dmf[i * (WARP_SIZE/QI6_K) + i/QI6_K], &y_df[index_y/QI8_1]); |
| } |
|
|
|
|
| static __device__ __forceinline__ float vec_dot_q4_0_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
|
|
| const int kyqs = k % (QI8_1/2) + QI8_1 * (k / (QI8_1/2)); |
| const float * x_dmf = (const float *) x_dm; |
|
|
| int u[2*VDR_Q4_0_Q8_1_MMQ]; |
|
|
| #pragma unroll |
| for (int l = 0; l < VDR_Q4_0_Q8_1_MMQ; ++l) { |
| u[2*l+0] = y_qs[j * WARP_SIZE + (kyqs + l) % WARP_SIZE]; |
| u[2*l+1] = y_qs[j * WARP_SIZE + (kyqs + l + QI4_0) % WARP_SIZE]; |
| } |
|
|
| return vec_dot_q4_0_q8_1_impl<VDR_Q4_0_Q8_1_MMQ> |
| (&x_ql[i * (WARP_SIZE + 1) + k], u, x_dmf[i * (WARP_SIZE/QI4_0) + i/QI4_0 + k/QI4_0], |
| y_ds[j * (WARP_SIZE/QI8_1) + (2*k/QI8_1) % (WARP_SIZE/QI8_1)]); |
| } |
|
|
| static __device__ __forceinline__ float vec_dot_q4_1_q8_1_mul_mat( |
| const int * __restrict__ x_ql, const half2 * __restrict__ x_dm, const int * __restrict__ x_qh, const int * __restrict__ x_sc, |
| const int * __restrict__ y_qs, const half2 * __restrict__ y_ds, const int & i, const int & j, const int & k) { |
| GGML_UNUSED(x_qh); GGML_UNUSED(x_sc); |
|
|
| const int kyqs = k % (QI8_1/2) + QI8_1 * (k / (QI8_1/2)); |
|
|
| int u[2*VDR_Q4_1_Q8_1_MMQ]; |
|
|
| #pragma unroll |
| for (int l = 0; l < VDR_Q4_1_Q8_1_MMQ; ++l) { |
| u[2*l+0] = y_qs[j * WARP_SIZE + (kyqs + l) % WARP_SIZE]; |
| u[2*l+1] = y_qs[j * WARP_SIZE + (kyqs + l + QI4_1) % WARP_SIZE]; |
| } |
|
|
| return vec_dot_q4_1_q8_1_impl<VDR_Q4_1_Q8_1_MMQ> |
| (&x_ql[i * (WARP_SIZE + 1) + k], u, x_dm[i * (WARP_SIZE/QI4_1) + i/QI4_1 + k/QI4_1], |
| y_ds[j * (WARP_SIZE/QI8_1) + (2*k/QI8_1) % (WARP_SIZE/QI8_1)]); |
| } |
|
|
|
|
| extern "C" __global__ void |
| mul_mat_q4_0( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q4_0_AMPERE; |
| const int mmq_y = MMQ_Y_Q4_0_AMPERE; |
| const int nwarps = NWARPS_Q4_0_AMPERE; |
|
|
| mul_mat_q<QK4_0, QR4_0, QI4_0, true, block_q4_0, mmq_x, mmq_y, nwarps, allocate_tiles_q4_0<mmq_y>, |
| load_tiles_q4_0<mmq_y, nwarps, true>, VDR_Q4_0_Q8_1_MMQ, vec_dot_q4_0_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q4_1( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q4_1_AMPERE; |
| const int mmq_y = MMQ_Y_Q4_1_AMPERE; |
| const int nwarps = NWARPS_Q4_1_AMPERE; |
|
|
| mul_mat_q<QK4_1, QR4_1, QI4_1, true, block_q4_1, mmq_x, mmq_y, nwarps, allocate_tiles_q4_1<mmq_y>, |
| load_tiles_q4_1<mmq_y, nwarps, true>, VDR_Q4_1_Q8_1_MMQ, vec_dot_q4_1_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
|
|
| extern "C" __global__ void |
| mul_mat_q5_0( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q5_0_AMPERE; |
| const int mmq_y = MMQ_Y_Q5_0_AMPERE; |
| const int nwarps = NWARPS_Q5_0_AMPERE; |
|
|
| mul_mat_q<QK5_0, QR5_0, QI5_0, false, block_q5_0, mmq_x, mmq_y, nwarps, allocate_tiles_q5_0<mmq_y>, |
| load_tiles_q5_0<mmq_y, nwarps, true>, VDR_Q5_0_Q8_1_MMQ, vec_dot_q5_0_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q5_1( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q5_1_AMPERE; |
| const int mmq_y = MMQ_Y_Q5_1_AMPERE; |
| const int nwarps = NWARPS_Q5_1_AMPERE; |
|
|
| mul_mat_q<QK5_1, QR5_1, QI5_1, true, block_q5_1, mmq_x, mmq_y, nwarps, allocate_tiles_q5_1<mmq_y>, |
| load_tiles_q5_1<mmq_y, nwarps, true>, VDR_Q5_1_Q8_1_MMQ, vec_dot_q5_1_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q8_0( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q8_0_AMPERE; |
| const int mmq_y = MMQ_Y_Q8_0_AMPERE; |
| const int nwarps = NWARPS_Q8_0_AMPERE; |
|
|
| mul_mat_q<QK8_0, QR8_0, QI8_0, false, block_q8_0, mmq_x, mmq_y, nwarps, allocate_tiles_q8_0<mmq_y>, |
| load_tiles_q8_0<mmq_y, nwarps, true>, VDR_Q8_0_Q8_1_MMQ, vec_dot_q8_0_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q2_K( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q2_K_AMPERE; |
| const int mmq_y = MMQ_Y_Q2_K_AMPERE; |
| const int nwarps = NWARPS_Q2_K_AMPERE; |
| mul_mat_q<QK_K, QR2_K, QI2_K, false, block_q2_K, mmq_x, mmq_y, nwarps, allocate_tiles_q2_K<mmq_y>, |
| load_tiles_q2_K<mmq_y, nwarps, true>, VDR_Q2_K_Q8_1_MMQ, vec_dot_q2_K_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q3_K( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q3_K_AMPERE; |
| const int mmq_y = MMQ_Y_Q3_K_AMPERE; |
| const int nwarps = NWARPS_Q3_K_AMPERE; |
| mul_mat_q<QK_K, QR3_K, QI3_K, false, block_q3_K, mmq_x, mmq_y, nwarps, allocate_tiles_q3_K<mmq_y>, |
| load_tiles_q3_K<mmq_y, nwarps, true>, VDR_Q3_K_Q8_1_MMQ, vec_dot_q3_K_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q4_K( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q4_K_AMPERE; |
| const int mmq_y = MMQ_Y_Q4_K_AMPERE; |
| const int nwarps = NWARPS_Q4_K_AMPERE; |
| mul_mat_q<QK_K, QR4_K, QI4_K, true, block_q4_K, mmq_x, mmq_y, nwarps, allocate_tiles_q4_K<mmq_y>, |
| load_tiles_q4_K<mmq_y, nwarps, true>, VDR_Q4_K_Q8_1_MMQ, vec_dot_q4_K_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q5_K( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q5_K_AMPERE; |
| const int mmq_y = MMQ_Y_Q5_K_AMPERE; |
| const int nwarps = NWARPS_Q5_K_AMPERE; |
| mul_mat_q<QK_K, QR5_K, QI5_K, true, block_q5_K, mmq_x, mmq_y, nwarps, allocate_tiles_q5_K<mmq_y>, |
| load_tiles_q5_K<mmq_y, nwarps, true>, VDR_Q5_K_Q8_1_MMQ, vec_dot_q5_K_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
| extern "C" __global__ void |
| mul_mat_q6_K( |
| const void * __restrict__ vx, const void * __restrict__ vy, float * __restrict__ dst, |
| const int ncols_x, const int nrows_x, const int ncols_y, const int nrows_y, const int nrows_dst) { |
| const int mmq_x = MMQ_X_Q6_K_AMPERE; |
| const int mmq_y = MMQ_Y_Q6_K_AMPERE; |
| const int nwarps = NWARPS_Q6_K_AMPERE; |
| mul_mat_q<QK_K, QR6_K, QI6_K, false, block_q6_K, mmq_x, mmq_y, nwarps, allocate_tiles_q6_K<mmq_y>, |
| load_tiles_q6_K<mmq_y, nwarps, true>, VDR_Q6_K_Q8_1_MMQ, vec_dot_q6_K_q8_1_mul_mat> |
| (vx, vy, dst, ncols_x, nrows_x, ncols_y, nrows_y, nrows_dst); |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <int qk, int qi, typename block_q_t, int vdr, vec_dot_q_cuda_t vec_dot_q_cuda> |
| __device__ void indexed_moe_forward( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
|
|
| |
| const int current_batch = blockIdx.y; |
| |
| const int current_topk = blockIdx.z; |
|
|
| |
| |
| const int task_id = current_batch * gridDim.z + current_topk; |
| if (task_id >= gridDim.y * gridDim.z) { |
| return; |
| } |
| |
| |
| const int input_idx = (input_dim1 == 1) ? current_batch : task_id; |
|
|
| |
| const unsigned int expert_id = indices[task_id]; |
|
|
| |
| const size_t weight_block_size = sizeof(block_q_t); |
| const size_t input_block_size = sizeof(block_q8_1); |
| const size_t weight_expert_stride_bytes = (size_t)(n * k) / QK_K * weight_block_size; |
| const size_t input_task_stride_bytes = (size_t)k_padded / QK8_1 * input_block_size; |
| const size_t output_task_stride_elems = n; |
|
|
| |
| const void * current_input_ptr = (const char *)all_inputs + input_idx * input_task_stride_bytes; |
| const void * current_weight_ptr = (const char *)all_weights + expert_id * weight_expert_stride_bytes; |
| float * current_output_ptr = all_outputs + task_id * output_task_stride_elems; |
|
|
| |
| constexpr int ncols_y = 1; |
| constexpr int nwarps = 4; |
| constexpr int rows_per_cuda_block = 1; |
|
|
| const int tid = WARP_SIZE * threadIdx.y + threadIdx.x; |
| const int row0 = rows_per_cuda_block * blockIdx.x; |
|
|
| if (row0 >= n) { |
| return; |
| } |
|
|
| const int blocks_per_row_x = k / qk; |
| const int blocks_per_col_y = k_padded / QK8_1; |
| constexpr int blocks_per_iter = vdr * nwarps * WARP_SIZE / qi; |
|
|
| float tmp = 0.0f; |
|
|
| const block_q_t * w = (const block_q_t *) current_weight_ptr; |
| const block_q8_1 * x = (const block_q8_1 *) current_input_ptr; |
|
|
| for (int kbx = tid / (qi / vdr); kbx < blocks_per_row_x; kbx += blocks_per_iter) { |
| const int kby = kbx * (qk / QK8_1); |
| const int kqs = vdr * (tid % (qi / vdr)); |
| tmp += vec_dot_q_cuda(&w[kbx + row0 * blocks_per_row_x], &x[kby], kqs); |
| } |
|
|
| |
| __shared__ float tmp_shared[nwarps - 1][WARP_SIZE]; |
| if (threadIdx.y > 0) { |
| tmp_shared[threadIdx.y - 1][threadIdx.x] = tmp; |
| } |
| __syncthreads(); |
|
|
| if (threadIdx.y == 0) { |
| for (int l = 0; l < nwarps - 1; ++l) { |
| tmp += tmp_shared[l][threadIdx.x]; |
| } |
| tmp = warp_reduce_sum(tmp); |
| if (threadIdx.x == 0) { |
| current_output_ptr[row0] = tmp; |
| } |
| } |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q2k_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK_K, QI2_K, block_q2_K, VDR_Q2_K_Q8_1_MMVQ, vec_dot_q2_K_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q3k_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK_K, QI3_K, block_q3_K, VDR_Q3_K_Q8_1_MMVQ, vec_dot_q3_K_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q4k_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK_K, QI4_K, block_q4_K, VDR_Q4_K_Q8_1_MMVQ, vec_dot_q4_K_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q5k_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK_K, QI5_K, block_q5_K, VDR_Q5_K_Q8_1_MMVQ, vec_dot_q5_K_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q6k_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK_K, QI6_K, block_q6_K, VDR_Q6_K_Q8_1_MMVQ, vec_dot_q6_K_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| extern "C" __global__ void indexed_moe_forward_q8_0_q8_1( |
| const void * __restrict__ all_weights, |
| const void * __restrict__ all_inputs, |
| const unsigned int * __restrict__ indices, |
| float * __restrict__ all_outputs, |
| const int n, |
| const int k, |
| const int batch, |
| const int topk, |
| const int k_padded, |
| const int input_dim1) { |
| indexed_moe_forward<QK8_0, QI8_0, block_q8_0, VDR_Q8_0_Q8_1_MMVQ, vec_dot_q8_0_q8_1> |
| (all_weights, all_inputs, indices, all_outputs, n, k, batch, topk, k_padded, input_dim1); |
| } |
|
|
| #include "nvfp4.cu" |
|
|