char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
3b5321936
char/aliceai-t5-moe
1#include "common.cuh" 2#include "lightning-indexer.cuh" 3#include "fattn-common.cuh" 4#include "convert.cuh" 5 6#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 7#if defined(TURING_MMA_AVAILABLE) 8 9typedef union { 10 int2 i2; 11 half2 h2[2]; 12} half4; 13 14// TODO add support for AMD cards via rocWMMA 15#include <mma.h> 16namespace wmma = nvcuda::wmma; 17 18template <int WARPS_PER_BLOCK, int K_VECS_PER_BLOCK, int64_t N_EMBD, int64_t N_HEAD, ggml_type TYPE_K> 19static __global__ void lightning_indexer_kernel_wmma( 20 const float * Q, const char * K, const float * W, const half * M, float * dst, 21 int64_t n_stream, int64_t n_batch, int64_t n_kv, 22 size_t nb1, size_t nb2, size_t nb3, 23 size_t nbq1, size_t nbq2, size_t nbq3, 24 size_t nbk1, size_t nbk2, size_t nbk3, 25 size_t nbw1, size_t nbw2, size_t nbw3, 26 size_t nbm1, size_t nbm2, size_t nbm3, 27 int64_t nem3 28 ) { 29 30 constexpr int THREADS_PER_BLOCK = WARPS_PER_BLOCK * WARP_SIZE; 31 constexpr int HEADS_PER_INNER_LOOP = 8; 32 constexpr int K_EMBD_PER_INNER_LOOP = 16; 33 constexpr int N_EMBD_PADDED = N_EMBD + 8; 34 35 const int i_batch = blockIdx.y; 36 const int i_stream = blockIdx.z; 37 const int i_warp = threadIdx.y; 38 const int i_lane = threadIdx.x; 39 const int tid = i_warp * WARP_SIZE + i_lane; 40 41 // each block processes K_VECS_PER_BLOCK K vectors 42 const int start_kv = blockIdx.x * K_VECS_PER_BLOCK; 43 44 const char * q_base = (const char *) Q + i_batch*nbq2 + i_stream*nbq3; 45 const float * w_base = (const float *) ((const char *) W + i_batch*nbw1 + i_stream*nbw3); 46 47 // phase 1 - load weights and first Q tile to shared memory 48 49 __shared__ float w_shared[N_HEAD]; 50 __shared__ int2 q_shared_h[HEADS_PER_INNER_LOOP][N_EMBD_PADDED / 4]; 51 52 if (tid < N_HEAD) { 53 w_shared[tid] = w_base[tid]; 54 } 55 56 // total number of half4 elements in HEADS_PER_INNER_LOOP x N_EMBD Q tile 57 constexpr int N_Q_TILE = HEADS_PER_INNER_LOOP * (N_EMBD / 4); 58 // number of registers needed in each thread to store Q tile in thread block 59 constexpr int N_Q_NEXT = (N_Q_TILE + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK; 60 61#pragma unroll 62 for (int i_q = tid; i_q < N_Q_TILE; i_q += THREADS_PER_BLOCK) { 63 const int i_head = i_q / (N_EMBD / 4); 64 const int i_embd = i_q % (N_EMBD / 4); 65 const float4 q = *(const float4 *) (q_base + i_head*nbq1 + i_embd*sizeof(float4)); 66 half4 q_packed; 67 q_packed.h2[0] = __float22half2_rn(make_float2(q.x, q.y)); 68 q_packed.h2[1] = __float22half2_rn(make_float2(q.z, q.w)); 69 q_shared_h[i_head][i_embd] = q_packed.i2; 70 } 71 72 // phase 2 - load (and dequantize if needed) K to shared mem 73 74 __shared__ half2 k_shared_h[K_VECS_PER_BLOCK][N_EMBD_PADDED / 4][2]; 75 76 constexpr int n_k = K_VECS_PER_BLOCK * (N_EMBD / 4); 77 78 if constexpr (TYPE_K == GGML_TYPE_F16) { 79#pragma unroll 80 for (int i_k = tid; i_k < n_k; i_k += THREADS_PER_BLOCK) { 81 const int i_k_vec = i_k / (N_EMBD / 4); 82 const int i_embd = i_k % (N_EMBD / 4); 83 const int i_kv = start_kv + i_k_vec; 84 if (i_kv < n_kv) { 85 const int2 * k_base = (const int2 *) ((const char *) K + i_kv*nbk2 + i_stream*nbk3); 86 *(int2*) &k_shared_h[i_k_vec][i_embd] = k_base[i_embd]; 87 } else { 88 *(int2*) &k_shared_h[i_k_vec][i_embd] = make_int2(0, 0); 89 } 90 } 91 } else { 92 constexpr dequantize_V_t dequantize_k = get_dequantize_V<TYPE_K, half, 4>(); 93#pragma unroll 94 for (int i_k = tid; i_k < n_k; i_k += THREADS_PER_BLOCK) { 95 const int i_k_vec = i_k / (N_EMBD / 4); 96 const int i_embd = i_k % (N_EMBD / 4); 97 const int i_kv = start_kv + i_k_vec; 98 if (i_kv < n_kv) { 99 const void * k_base = (const void *) ((const char *) K + i_kv*nbk2 + i_stream*nbk3); 100 dequantize_k(k_base, &k_shared_h[i_k_vec][i_embd][0], i_embd * 4); 101 } else { 102 *(int2*) &k_shared_h[i_k_vec][i_embd] = make_int2(0, 0); 103 } 104 } 105 } 106 107 __syncthreads(); 108 109 // phase 3 - calculate lightning indexer scores 110 111 __shared__ float qk_shared[WARPS_PER_BLOCK][HEADS_PER_INNER_LOOP][K_VECS_PER_BLOCK]; 112 113 // load K fragment 114 wmma::fragment<wmma::matrix_b, HEADS_PER_INNER_LOOP, K_VECS_PER_BLOCK, K_EMBD_PER_INNER_LOOP, half, wmma::col_major> frag_k; 115 wmma::load_matrix_sync(frag_k, (half*) &k_shared_h[0][i_warp * K_EMBD_PER_INNER_LOOP / 4], N_EMBD_PADDED); 116 117 float score_k = 0.0f; 118 119 for (int i_head_0 = 0; i_head_0 < N_HEAD; i_head_0 += HEADS_PER_INNER_LOOP) { 120 const int i_head_next = i_head_0 + HEADS_PER_INNER_LOOP; 121 122 // we don't use accumulator for anything, fill it with zeros 123 wmma::fragment<wmma::accumulator, HEADS_PER_INNER_LOOP, K_VECS_PER_BLOCK, K_EMBD_PER_INNER_LOOP, float> frag_acc; 124 wmma::fill_fragment(frag_acc, 0.0f); 125 126 // load Q fragment 127 wmma::fragment<wmma::matrix_a, HEADS_PER_INNER_LOOP, K_VECS_PER_BLOCK, K_EMBD_PER_INNER_LOOP, half, wmma::row_major> frag_q; 128 wmma::load_matrix_sync(frag_q, (half*) &q_shared_h[0][i_warp * K_EMBD_PER_INNER_LOOP / 4], N_EMBD_PADDED); 129 130 // preload next Q tile to registers during matrix multiplication 131 float4 q_next[N_Q_NEXT]; 132 133 if (i_head_next < N_HEAD) { 134#pragma unroll 135 for (int i_q = tid, i_q_next = 0; i_q < N_Q_TILE; i_q += THREADS_PER_BLOCK) { 136 const int i_head = i_head_next + i_q / (N_EMBD / 4); 137 const int i_embd = i_q % (N_EMBD / 4); 138 q_next[i_q_next++] = *(const float4 *) (q_base + i_head*nbq1 + i_embd*sizeof(float4)); 139 } 140 } 141 142 // perform matrix multiplication 143 wmma::mma_sync(frag_acc, frag_q, frag_k, frag_acc); 144 wmma::store_matrix_sync((float*) &qk_shared[i_warp][0][0], frag_acc, K_VECS_PER_BLOCK, wmma::mem_row_major); 145 146 // make sure all threads finished using q_shared_h so we can store next tile 147 __syncthreads(); 148 149 // write preloaded Q tile to shared memory 150 if (i_head_next < N_HEAD) { 151#pragma unroll 152 for (int i_q = tid, i_q_next = 0; i_q < N_Q_TILE; i_q += THREADS_PER_BLOCK) { 153 const int i_head = i_q / (N_EMBD / 4); 154 const int i_embd = i_q % (N_EMBD / 4); 155 half4 q_packed; 156 q_packed.h2[0] = __float22half2_rn(make_float2(q_next[i_q_next].x, q_next[i_q_next].y)); 157 q_packed.h2[1] = __float22half2_rn(make_float2(q_next[i_q_next].z, q_next[i_q_next].w)); 158 q_shared_h[i_head][i_embd] = q_packed.i2; 159 ++i_q_next; 160 } 161 } 162 163 // accumulate QK multiplication results from all block warps 164 // (there are 256 threads in block and 256 matmul outputs) 165 // TODO it will break if WARP_SIZE is not 32 166 const int h = tid / K_VECS_PER_BLOCK; 167 const int k = tid % K_VECS_PER_BLOCK; 168 const float w_val = w_shared[i_head_0 + h]; 169 170 float sum = 0.0f; 171#pragma unroll 172 for (int w = 0; w < WARPS_PER_BLOCK; ++w) { 173 sum += qk_shared[w][h][k]; 174 } 175 176 // ReLU, weight 177 sum = sum > 0.0f ? sum : 0.0f; 178 sum *= w_val; 179 180 // wait until qk_shared[0] is no longer used 181 __syncthreads(); 182 183 // reuse qk_shared[0] for storing partial results 184 qk_shared[0][h][k] = sum; 185 186 // wait until all threads write their results 187 __syncthreads(); 188 189 // accumulate result over heads 190 if (tid < K_VECS_PER_BLOCK) { 191#pragma unroll 192 for (int i_head = 0; i_head < HEADS_PER_INNER_LOOP; ++i_head) { 193 score_k += qk_shared[0][i_head][tid]; 194 } 195 } 196 197 // make sure all threads finished using qk_shared 198 __syncthreads(); 199 } 200 201 // phase 4 - store output to VRAM 202 203 if (tid < K_VECS_PER_BLOCK) { 204 const int i_kv = start_kv + tid; 205 if (i_kv < n_kv) { 206 const half * m_base = (const half *) ((const char *) M + i_batch*nbm1 + (i_stream%nem3)*nbm3); 207 float * dst_base = (float *) ((char *) dst + i_batch*nb1 + i_stream*nb3); 208 dst_base[i_kv] = score_k + __half2float(m_base[i_kv]); 209 } 210 } 211} 212 213#else // defined(TURING_MMA_AVAILABLE) 214 215template <int WARPS_PER_BLOCK, int K_VECS_PER_BLOCK, int64_t N_EMBD, int64_t N_HEAD, ggml_type TYPE_K> 216static __global__ void lightning_indexer_kernel_wmma( 217 const float * Q, const char * K, const float * W, const half * M, float * dst, 218 int64_t n_stream, int64_t n_batch, int64_t n_kv, 219 size_t nb1, size_t nb2, size_t nb3, 220 size_t nbq1, size_t nbq2, size_t nbq3, 221 size_t nbk1, size_t nbk2, size_t nbk3, 222 size_t nbw1, size_t nbw2, size_t nbw3, 223 size_t nbm1, size_t nbm2, size_t nbm3, 224 int64_t nem3 225 ) { 226 GGML_UNUSED_VARS(Q, K, W, M, dst, 227 n_stream, n_batch, n_kv, 228 nb1, nb2, nb3, 229 nbq1, nbq2, nbq3, 230 nbk1, nbk2, nbk3, 231 nbw1, nbw2, nbw3, 232 nem3); 233 NO_DEVICE_CODE; 234} 235 236#endif // defined(TURING_MMA_AVAILABLE) 237#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 238 239// TODO there is one ugly assumption used in this kernel - that WARP_SIZE is equal to 32 240// thanks to that one warp operating on float4 processes whole indexer K/Q vectors 241// 32 * 4 = 128 (N_EMBD) 242 243template <int WARPS_PER_BLOCK, int K_VECS_PER_BLOCK, int64_t N_EMBD, int64_t N_HEAD, ggml_type TYPE_K> 244static __global__ void lightning_indexer_kernel_vec( 245 const float * Q, const char * K, const float * W, const half * M, float * dst, 246 int64_t n_stream, int64_t n_batch, int64_t n_kv, 247 size_t nb1, size_t nb2, size_t nb3, 248 size_t nbq1, size_t nbq2, size_t nbq3, 249 size_t nbk1, size_t nbk2, size_t nbk3, 250 size_t nbw1, size_t nbw2, size_t nbw3, 251 size_t nbm1, size_t nbm2, size_t nbm3, 252 int64_t nem3 253 ) { 254 255 constexpr int K_VECS_PER_WARP = K_VECS_PER_BLOCK / WARPS_PER_BLOCK; 256 constexpr int THREADS_PER_BLOCK = WARPS_PER_BLOCK * WARP_SIZE; 257 258 const int i_batch = blockIdx.y; 259 const int i_stream = blockIdx.z; 260 const int i_warp = threadIdx.y; 261 const int i_lane = threadIdx.x; 262 const int tid = i_warp * WARP_SIZE + i_lane; 263 264 // each warp processes K_VECS_PER_WARP K vectors 265 const int start_kv_block = blockIdx.x * K_VECS_PER_BLOCK; 266 const int start_kv = start_kv_block + i_warp * K_VECS_PER_WARP; 267 268 const char * q_base = (const char *) Q + i_batch*nbq2 + i_stream*nbq3; 269 const float * w_base = (const float *) ((const char *) W + i_batch*nbw1 + i_stream*nbw3); 270 271 // phase 1 - load (and dequantize if needed) K to registers 272 273 float4 k_reg_f[K_VECS_PER_WARP]; 274 275 if constexpr (TYPE_K == GGML_TYPE_F32) { 276 // direct copy of float4 277#pragma unroll 278 for (int k = 0; k < K_VECS_PER_WARP; ++k) { 279 int i_kv = start_kv + k; 280 if (i_kv < n_kv) { 281 const float4 * k_base = (const float4 *) ((const char *) K + i_kv*nbk2 + i_stream*nbk3); 282 k_reg_f[k] = k_base[i_lane]; 283 } else { 284 k_reg_f[k] = make_float4(0, 0, 0, 0); 285 } 286 } 287 } else { 288 // dequantize remaining types to float 289 constexpr dequantize_V_t dequantize_k = get_dequantize_V<TYPE_K, float, 4>(); 290#pragma unroll 291 for (int k = 0; k < K_VECS_PER_WARP; ++k) { 292 int i_kv = start_kv + k; 293 if (i_kv < n_kv) { 294 const void * k_base = (const void *) ((const char *) K + i_kv*nbk2 + i_stream*nbk3); 295 dequantize_k(k_base, &k_reg_f[k], i_lane * 4); 296 } else { 297 k_reg_f[k] = make_float4(0, 0, 0, 0); 298 } 299 } 300 } 301 302 float score_k[K_VECS_PER_WARP] = { 0.0f }; 303 304 // load weights and Q only for N_HEAD_INNER heads at once to reduce shared memory usage 305 constexpr int N_HEAD_INNER = N_HEAD / 4; 306 307 for (int i_head_0 = 0; i_head_0 < N_HEAD; i_head_0 += N_HEAD_INNER) { 308 // phase 2 - load weights and Q to shared memory 309 310 __shared__ float w_shared[N_HEAD_INNER]; 311 __shared__ float4 q_shared_f[N_HEAD_INNER][N_EMBD / 4]; 312 313 if (tid < N_HEAD_INNER) { 314 w_shared[tid] = w_base[i_head_0 + tid]; 315 } 316 317 constexpr int n_q = N_HEAD_INNER * (N_EMBD / 4); 318#pragma unroll 319 for (int i_q = tid; i_q < n_q; i_q += THREADS_PER_BLOCK) { 320 const int i_head_inner = i_q / (N_EMBD / 4); 321 const int i_head = i_head_0 + i_head_inner; 322 const int i_embd = i_q % (N_EMBD / 4); 323 q_shared_f[i_head_inner][i_embd] = *(const float4 *) (q_base + i_head*nbq1 + i_embd*sizeof(float4)); 324 } 325 326 __syncthreads(); 327 328 // phase 3 - calculate lightning indexer scores 329 330 for (int i_head_inner = 0; i_head_inner < N_HEAD_INNER; ++i_head_inner) { 331 const float w_val = w_shared[i_head_inner]; 332 float qk[K_VECS_PER_WARP] = { 0.0f }; 333 334 // dot product of floats 335 const float4 q_vec = q_shared_f[i_head_inner][i_lane]; 336 337#pragma unroll 338 for (int k = 0; k < K_VECS_PER_WARP; ++k) { 339 ggml_cuda_mad(qk[k], q_vec.x, k_reg_f[k].x); 340 ggml_cuda_mad(qk[k], q_vec.y, k_reg_f[k].y); 341 ggml_cuda_mad(qk[k], q_vec.z, k_reg_f[k].z); 342 ggml_cuda_mad(qk[k], q_vec.w, k_reg_f[k].w); 343 } 344 345#pragma unroll 346 for (int k = 0; k < K_VECS_PER_WARP; ++k) { 347 float sum = warp_reduce_sum(qk[k]); 348 349 // ReLU, weight 350 if (i_lane == 0) { 351 sum = (sum > 0.0f) ? sum : 0.0f; 352 score_k[k] += sum * w_val; 353 } 354 } 355 } 356 357 __syncthreads(); 358 } 359 360 // phase 4 - store outputs to shared memory 361 362 __shared__ float dst_shared[K_VECS_PER_BLOCK]; 363 364 if (i_lane == 0) { 365#pragma unroll 366 for (int k = 0; k < K_VECS_PER_WARP; ++k) { 367 dst_shared[i_warp * K_VECS_PER_WARP + k] = score_k[k]; 368 } 369 } 370 371 __syncthreads(); 372 373 // phase 5 - write from shared memory to VRAM in coalesced manner 374 375 if (tid < K_VECS_PER_BLOCK) { 376 int i_kv = start_kv_block + tid; 377 if (i_kv < n_kv) { 378 const half * m_base = (const half *) ((const char *) M + i_batch*nbm1 + (i_stream%nem3)*nbm3); 379 float * dst_base = (float *) ((char *) dst + i_batch*nb1 + i_stream*nb3); 380 dst_base[i_kv] = dst_shared[tid] + __half2float(m_base[i_kv]); 381 } 382 } 383} 384 385#define LIGHTNING_INDEXER_CASE(lightning_indexer_kernel, n_embd, n_head, K, type_K) \ 386 if (K->type == (type_K)) { \ 387 lightning_indexer_kernel<WARPS_PER_BLOCK, K_VECS_PER_BLOCK, n_embd, n_head, type_K> \ 388 <<<grid, block, 0, ctx.stream()>>>( \ 389 q_d, k_d, w_d, m_d, dst_d, \ 390 n_stream, n_batch, n_kv, \ 391 nb1, nb2, nb3, \ 392 nbq1, nbq2, nbq3, \ 393 nbk1, nbk2, nbk3, \ 394 nbw1, nbw2, nbw3, \ 395 nbm1, nbm2, nbm3, \ 396 nem3 \ 397 ); \ 398 } else 399 400void ggml_cuda_lightning_indexer(ggml_backend_cuda_context & ctx, ggml_tensor * dst) { 401 const ggml_tensor * q = dst->src[0]; 402 const ggml_tensor * k = dst->src[1]; 403 const ggml_tensor * w = dst->src[2]; // weights 404 const ggml_tensor * m = dst->src[3]; // mask 405 406 GGML_ASSERT(dst->type == GGML_TYPE_F32); 407 GGML_ASSERT( q->type == GGML_TYPE_F32); 408 GGML_ASSERT( w->type == GGML_TYPE_F32); 409 GGML_ASSERT( m->type == GGML_TYPE_F16); 410 411 GGML_TENSOR_LOCALS(int64_t, neq, q, ne) 412 GGML_TENSOR_LOCALS(size_t, nbq, q, nb) 413 GGML_TENSOR_LOCALS(int64_t, nek, k, ne) 414 GGML_TENSOR_LOCALS(size_t, nbk, k, nb) 415 GGML_TENSOR_LOCALS(int64_t, new, w, ne) 416 GGML_TENSOR_LOCALS(size_t, nbw, w, nb) 417 GGML_TENSOR_LOCALS(int64_t, nem, m, ne) 418 GGML_TENSOR_LOCALS(size_t, nbm, m, nb) 419 GGML_TENSOR_LOCALS(int64_t, ne, dst, ne) 420 GGML_TENSOR_LOCALS(size_t, nb, dst, nb) 421 422 // input tensor rows must be contiguous 423 GGML_ASSERT(nbq0 == ggml_type_size(q->type)); 424 GGML_ASSERT(nbk0 == ggml_type_size(k->type)); 425 GGML_ASSERT(nbw0 == ggml_type_size(w->type)); 426 GGML_ASSERT(nbm0 == ggml_type_size(m->type)); 427 428 // dst cannot be transposed or permuted 429 GGML_ASSERT(nb0 == sizeof(float)); 430 GGML_ASSERT(nb0 <= nb1); 431 GGML_ASSERT(nb1 <= nb2); 432 GGML_ASSERT(nb2 <= nb3); 433 434 const int n_embd = q->ne[0]; 435 const int n_head = q->ne[1]; 436 const int n_batch = q->ne[2]; 437 const int n_stream = q->ne[3]; 438 const int n_kv = k->ne[2]; 439 440 const float * q_d = (const float *) q->data; 441 const char * k_d = (const char *) k->data; 442 const float * w_d = (const float *) w->data; 443 const half * m_d = (const half *) m->data; 444 float * dst_d = ( float *) dst->data; 445 446 const int device = ggml_cuda_get_device(); 447 const int cc = ggml_cuda_info().devices[device].cc; 448 449 if (n_embd == 128 && n_head == 64) { 450#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 451 if (GGML_CUDA_CC_IS_NVIDIA(cc) && turing_mma_available(cc) && k->type != GGML_TYPE_F32 && k->type != GGML_TYPE_BF16) { 452 // use wmma kernel 453 constexpr int K_VECS_PER_BLOCK = 32; 454 constexpr int WARPS_PER_BLOCK = 8; 455 456 dim3 block(32, WARPS_PER_BLOCK); 457 int num_kv_blocks = (n_kv + (K_VECS_PER_BLOCK) - 1) / (K_VECS_PER_BLOCK); 458 dim3 grid(num_kv_blocks, n_batch, n_stream); 459 460 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_F16) 461 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_Q4_0) 462 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_Q4_1) 463 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_Q5_0) 464 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_Q5_1) 465 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 64, k, GGML_TYPE_Q8_0) 466 GGML_ABORT("fatal error"); 467 } else { 468#else // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 469 { 470#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 471 // use vector kernel 472 constexpr int K_VECS_PER_WARP = 8; 473 constexpr int WARPS_PER_BLOCK = 8; 474 constexpr int K_VECS_PER_BLOCK = K_VECS_PER_WARP * WARPS_PER_BLOCK; 475 476 dim3 block(32, WARPS_PER_BLOCK); 477 int num_kv_blocks = (n_kv + (K_VECS_PER_BLOCK) - 1) / (K_VECS_PER_BLOCK); 478 dim3 grid(num_kv_blocks, n_batch, n_stream); 479 480 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_F16) 481 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_Q4_0) 482 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_Q4_1) 483 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_Q5_0) 484 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_Q5_1) 485 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_Q8_0) 486 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_BF16) 487 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 64, k, GGML_TYPE_F32) 488 GGML_ABORT("fatal error"); 489 } 490 } else if (n_embd == 128 && n_head == 32) { 491#if !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 492 if (GGML_CUDA_CC_IS_NVIDIA(cc) && turing_mma_available(cc) && k->type != GGML_TYPE_F32 && k->type != GGML_TYPE_BF16) { 493 // use wmma kernel 494 constexpr int K_VECS_PER_BLOCK = 32; 495 constexpr int WARPS_PER_BLOCK = 8; 496 497 dim3 block(32, WARPS_PER_BLOCK); 498 int num_kv_blocks = (n_kv + (K_VECS_PER_BLOCK) - 1) / (K_VECS_PER_BLOCK); 499 dim3 grid(num_kv_blocks, n_batch, n_stream); 500 501 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_F16) 502 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_Q4_0) 503 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_Q4_1) 504 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_Q5_0) 505 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_Q5_1) 506 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_wmma, 128, 32, k, GGML_TYPE_Q8_0) 507 GGML_ABORT("fatal error"); 508 } else { 509#else // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 510 { 511#endif // !defined(GGML_USE_HIP) && !defined(GGML_USE_MUSA) 512 // use vector kernel 513 constexpr int K_VECS_PER_WARP = 8; 514 constexpr int WARPS_PER_BLOCK = 8; 515 constexpr int K_VECS_PER_BLOCK = K_VECS_PER_WARP * WARPS_PER_BLOCK; 516 517 dim3 block(32, WARPS_PER_BLOCK); 518 int num_kv_blocks = (n_kv + (K_VECS_PER_BLOCK) - 1) / (K_VECS_PER_BLOCK); 519 dim3 grid(num_kv_blocks, n_batch, n_stream); 520 521 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_F16) 522 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_Q4_0) 523 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_Q4_1) 524 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_Q5_0) 525 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_Q5_1) 526 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_Q8_0) 527 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_BF16) 528 LIGHTNING_INDEXER_CASE(lightning_indexer_kernel_vec, 128, 32, k, GGML_TYPE_F32) 529 GGML_ABORT("fatal error"); 530 } 531 } else { 532 GGML_ABORT("fatal error"); 533 } 534} 535 536bool ggml_cuda_lightning_indexer_supported(int device, const ggml_tensor * dst) { 537 GGML_UNUSED(device); 538 539 const ggml_tensor * q = dst->src[0]; 540 const ggml_tensor * k = dst->src[1]; 541 const ggml_tensor * w = dst->src[2]; // weights 542 const ggml_tensor * m = dst->src[3]; // mask 543 544 GGML_TENSOR_LOCALS(int64_t, neq, q, ne) 545 GGML_TENSOR_LOCALS(size_t, nbq, q, nb) 546 GGML_TENSOR_LOCALS(int64_t, nek, k, ne) 547 GGML_TENSOR_LOCALS(size_t, nbk, k, nb) 548 GGML_TENSOR_LOCALS(int64_t, new, w, ne) 549 GGML_TENSOR_LOCALS(size_t, nbw, w, nb) 550 GGML_TENSOR_LOCALS(int64_t, nem, m, ne) 551 GGML_TENSOR_LOCALS(size_t, nbm, m, nb) 552 GGML_TENSOR_LOCALS(int64_t, ne, dst, ne) 553 GGML_TENSOR_LOCALS(size_t, nb, dst, nb) 554 555 if (neq0 != 128) { 556 return false; 557 } 558 559 if (neq1 != 64 && neq1 != 32) { 560 return false; 561 } 562 563 // alignment checks 564 for (const ggml_tensor * t : {q, k}) { 565 if (ggml_is_quantized(t->type)) { 566 continue; 567 } 568 for (size_t i = 1; i < GGML_MAX_DIMS; ++i) { 569 if (t->nb[i] % 16 != 0) { 570 return false; 571 } 572 } 573 } 574 575 switch(k->type) { 576 case GGML_TYPE_F32: 577 case GGML_TYPE_BF16: 578 case GGML_TYPE_F16: 579 case GGML_TYPE_Q8_0: 580 case GGML_TYPE_Q5_1: 581 case GGML_TYPE_Q5_0: 582 case GGML_TYPE_Q4_1: 583 case GGML_TYPE_Q4_0: 584 return true; 585 default: 586 return false; 587 } 588}