char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
73a43d1f6
char/aliceai-t5-moe
1#pragma once 2 3#include "mma.cuh" 4#include "common.cuh" 5#include "convert.cuh" 6 7using namespace ggml_cuda_mma; 8 9#define MMF_ROWS_PER_BLOCK 32 10#define MMF_ROWS_PER_BLOCK_CDNA 64 11 12static __forceinline__ int64_t mmf_get_max_block_size(int cc) { 13 if (GGML_CUDA_CC_IS_CDNA(cc)) { 14 return 512; 15 } else { 16 return 256; 17 } 18} 19 20static __forceinline__ int mmf_get_padding(int cc) { 21 if (GGML_CUDA_CC_IS_CDNA(cc)) { 22 return 2; 23 } else { 24 return 4; 25 } 26} 27 28static constexpr __device__ int mmf_get_padding() { 29#if defined(AMD_MFMA_AVAILABLE) 30 return 2; 31#else 32 return 4; 33#endif // defined(AMD_MFMA_AVAILABLE) 34} 35 36struct mmf_ids_data { 37 const int32_t * ids_src_compact = nullptr; 38 const int32_t * ids_dst_compact = nullptr; 39 const int32_t * expert_bounds_dev = nullptr; 40 int n_experts = 0; 41 int sis1 = 0; 42}; 43 44void ggml_cuda_mul_mat_f(ggml_backend_cuda_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1, const ggml_tensor * ids, ggml_tensor * dst); 45 46bool ggml_cuda_should_use_mmf(enum ggml_type type, int cc, int warp_size, const int64_t * scr0_ne, const size_t * src0_nb, const int src1_ncols, bool mul_mat_id); 47 48template <typename T, int rows_per_block, int cols_per_block, int nwarps, bool has_ids> 49__launch_bounds__(ggml_cuda_get_physical_warp_size()*nwarps, 1) 50static __global__ void mul_mat_f( 51 const T * __restrict__ x, const float * __restrict__ y, const int32_t * __restrict__ ids, float * __restrict__ dst, 52 const int ncols, const int ncols_dst_total, const int nchannels_dst, const int stride_row, const int stride_col_y, const int stride_col_dst, 53 const int stride_col_id, const int stride_row_id, 54 const int channel_ratio, const int stride_channel_x, const int stride_channel_y, const int stride_channel_dst, 55 const int sample_ratio, const int stride_sample_x, const int stride_sample_y, const int stride_sample_dst) { 56// TODO: handle this in a consistent and simpler way after AMD MFMA support has been added 57#if defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 58#if defined(AMD_WMMA_AVAILABLE) 59 if constexpr (!(std::is_same_v<T, half2> || std::is_same_v<T, nv_bfloat162>) || rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 60 typedef tile<16, 8, T, get_input_data_layout()> tile_A; 61 typedef tile<16, 8, T, get_input_data_layout()> tile_B; 62 typedef tile<16, 16, float, DATA_LAYOUT_J_MAJOR> tile_C; 63#elif defined(AMD_MFMA_AVAILABLE) 64 if constexpr (rows_per_block != MMF_ROWS_PER_BLOCK_CDNA) {NO_DEVICE_CODE;} else { 65 typedef tile<16, 8, T, DATA_LAYOUT_I_MAJOR> tile_A; 66 typedef tile<16, 8, T, DATA_LAYOUT_I_MAJOR> tile_B; 67 typedef tile<16, 16, float, DATA_LAYOUT_J_MAJOR> tile_C; 68#else 69#ifdef VOLTA_MMA_AVAILABLE 70 if constexpr (!std::is_same_v<T, half2> || rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 71 typedef tile<32, 4, T, DATA_LAYOUT_I_MAJOR> tile_A; 72 typedef tile< 8, 4, T, DATA_LAYOUT_I_MAJOR_MIRRORED> tile_B; 73 typedef tile<32, 8, float, DATA_LAYOUT_I_MAJOR> tile_C; 74#else 75 if constexpr (rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 76 typedef tile<16, 8, T> tile_A; 77 typedef tile<8, 8, T> tile_B; 78 typedef tile<16, 8, float> tile_C; 79#endif // VOLTA_MMA_AVAILABLE 80#endif // defined(AMD_WMMA_AVAILABLE) 81 if constexpr (!tile_A::supported() || !tile_B::supported() || !tile_C::supported()) { 82 NO_DEVICE_CODE; 83 return; 84 } 85 86 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 87 constexpr int tile_k_padded = warp_size + mmf_get_padding(); 88 constexpr int ntA = rows_per_block / tile_A::I; 89 constexpr int ntB = (cols_per_block + tile_B::I - 1) / tile_B::I; 90 91 const int row0 = blockIdx.x * rows_per_block; 92 93 int expert_idx = 0; 94 [[maybe_unused]] int col_base = 0; 95 96 const int channel_dst = has_ids ? 0 : blockIdx.y; 97 98 if constexpr (has_ids) { 99 // experts + tiles of ncols_dst are packed in the y dimension 100 int col_tiles = (ncols_dst_total + cols_per_block - 1) / cols_per_block; 101 const int nchannels_x = gridDim.y / col_tiles; 102 const int tile_idx = blockIdx.y / nchannels_x; 103 expert_idx = blockIdx.y - tile_idx * nchannels_x; 104 col_base = tile_idx * cols_per_block; 105 } 106 107 const int channel_x = has_ids ? expert_idx : (channel_dst / channel_ratio); 108 const int channel_y = channel_dst; 109 const int sample_dst = blockIdx.z; 110 const int sample_x = sample_dst / sample_ratio; 111 const int sample_y = sample_dst; 112 113 x += int64_t(sample_x) *stride_sample_x + channel_x *stride_channel_x + row0*stride_row ; 114 y += int64_t(sample_y) *stride_sample_y + (has_ids ? 0 : channel_y *stride_channel_y); 115 dst += int64_t(sample_dst)*stride_sample_dst + (has_ids ? 0 : channel_dst*stride_channel_dst); 116 117 if constexpr (has_ids) { 118 constexpr int y_stride_scale = std::is_same_v<T, float> ? 1 : 2; 119 const int64_t col_offset = col_base; 120 y += col_offset * stride_col_y * y_stride_scale; 121 dst += col_offset * stride_col_dst; 122 ids += col_offset * stride_row_id; 123 } 124 125 [[maybe_unused]] const float2 * y2 = (const float2 *) y; 126 127 extern __shared__ char data_mmv[]; 128 129 char * shmem_base = data_mmv; 130 [[maybe_unused]] int * slot_map = (int *) shmem_base; 131 char * compute_base = has_ids ? (shmem_base + GGML_PAD(cols_per_block, 16) * sizeof(int)) : shmem_base; 132 133 tile_C C[ntA][ntB]; 134 135 T * tile_xy = (T *) compute_base + threadIdx.y*(tile_A::I * tile_k_padded); 136 137 if constexpr (has_ids) { 138 int found = 0; 139 140 for (int j0 = 0; j0 < cols_per_block; j0 += nwarps) { 141 const int j = j0 + threadIdx.y; 142 143 if (threadIdx.x == 0) { 144 slot_map[j] = -1; 145 } 146 ggml_cuda_syncwarp(); 147 148 if (col_base + j >= ncols_dst_total) { 149 continue; 150 } 151 152 const int32_t * __restrict__ id_row = ids + j*stride_row_id; 153 154 for (int k = threadIdx.x; k < nchannels_dst; k += warp_size) { 155 int match = id_row[k*stride_col_id] == expert_idx; 156 157 if (match) { 158 slot_map[j] = k; 159 found = 1; 160 break; 161 } 162 } 163 } 164 165 if (!__syncthreads_or(found)) { 166 return; 167 } 168 } 169 170 171 for (int col = threadIdx.y*warp_size + threadIdx.x; col < ncols; col += nwarps*warp_size) { 172 tile_A A[ntA][warp_size / tile_A::J]; 173#pragma unroll 174 for (int itA = 0; itA < ntA; ++itA) { 175 ggml_cuda_syncwarp(); 176#pragma unroll 177 for (int i = 0; i < tile_A::I; ++i) { 178 tile_xy[i*tile_k_padded + threadIdx.x] = x[(itA*tile_A::I + i)*stride_row + col]; 179 } 180 ggml_cuda_syncwarp(); 181#pragma unroll 182 for (int k0 = 0; k0 < warp_size; k0 += tile_A::J) { 183 load_ldmatrix(A[itA][k0/tile_A::J], tile_xy + k0, tile_k_padded); 184 } 185 } 186 187#pragma unroll 188 for (int itB = 0; itB < ntB; ++itB) { 189 ggml_cuda_syncwarp(); 190 if constexpr (std::is_same_v<T, float>) { 191#pragma unroll 192 for (int j0 = 0; j0 < tile_B::I; ++j0) { 193 const int j = j0 + itB*tile_B::I; 194 195 if constexpr (!has_ids) { 196 tile_xy[j0*tile_k_padded + threadIdx.x] = j < cols_per_block ? y[j*stride_col_y + col] : 0.0f; 197 } else { 198 const bool valid = j < cols_per_block && (col_base + j) < ncols_dst_total && slot_map[j] >= 0; 199 tile_xy[j0*tile_k_padded + threadIdx.x] = valid ? y[slot_map[j]*stride_channel_y + j*stride_col_y + col] : 0.0f; 200 } 201 } 202 } else if constexpr (std::is_same_v<T, half2> || std::is_same_v<T, nv_bfloat162>) { 203#pragma unroll 204 for (int j0 = 0; j0 < tile_B::I; ++j0) { 205 const int j = j0 + itB*tile_B::I; 206 207 if constexpr (!has_ids) { 208 const float2 tmp = j < cols_per_block ? y2[j*stride_col_y + col] : make_float2(0.0f, 0.0f); 209 tile_xy[j0*tile_k_padded + threadIdx.x] = ggml_cuda_cast<T>(tmp); 210 } else { 211 const bool valid = j < cols_per_block && (col_base + j) < ncols_dst_total && slot_map[j] >= 0; 212 float2 tmp = valid ? *(const float2*) &y[slot_map[j]*stride_channel_y + 2*(j*stride_col_y + col)] : make_float2(0.0f, 0.0f); 213 tile_xy[j0*tile_k_padded + threadIdx.x] = ggml_cuda_cast<T>(tmp); 214 } 215 } 216 } else { 217 static_assert(std::is_same_v<T, void>, "unsupported type"); 218 } 219 ggml_cuda_syncwarp(); 220#pragma unroll 221 for (int k0 = 0; k0 < warp_size; k0 += tile_B::J) { 222 tile_B B; 223 load_ldmatrix(B, tile_xy + k0, tile_k_padded); 224#pragma unroll 225 for (int itA = 0; itA < ntA; ++itA) { 226 mma(C[itA][itB], A[itA][k0/tile_B::J], B); 227 } 228 } 229 } 230 } 231 232 float * buf_iw = (float *) compute_base; 233 constexpr int kiw = nwarps*rows_per_block + mmf_get_padding(); 234 235 if (nwarps > 1) { 236 __syncthreads(); 237 } else { 238 ggml_cuda_syncwarp(); 239 } 240#pragma unroll 241 for (int itB = 0; itB < ntB; ++itB) { 242#pragma unroll 243 for (int itA = 0; itA < ntA; ++itA) { 244#pragma unroll 245 for (int l = 0; l < tile_C::ne; ++l) { 246 const int i = threadIdx.y*rows_per_block + itA*tile_C::I + tile_C::get_i(l); 247 const int j = itB*tile_C::J + tile_C::get_j(l); 248 buf_iw[j*kiw + i] = C[itA][itB].x[l]; 249 } 250 } 251 } 252 253 if (nwarps > 1) { 254 __syncthreads(); 255 } else { 256 ggml_cuda_syncwarp(); 257 } 258 259#pragma unroll 260 for (int j0 = 0; j0 < cols_per_block; j0 += nwarps) { 261 const int j = j0 + threadIdx.y; 262 263 if (j0 + nwarps > cols_per_block && j >= cols_per_block) { 264 return; 265 } 266 267 float sum[rows_per_block/warp_size] = {0.0f}; 268 static_assert((rows_per_block % warp_size) == 0, "rows_per_block must be a multiple of warp_size."); 269#pragma unroll 270 for (int i0 = 0; i0 < nwarps*rows_per_block; i0 += rows_per_block) { 271#pragma unroll 272 for (int i1 = 0; i1 < sizeof(sum)/sizeof(sum[0]); ++i1) { 273 const int i = i0 + i1*warp_size + threadIdx.x; 274 275 sum[i1] += buf_iw[j*kiw + i]; 276 } 277 } 278 279 if constexpr (!has_ids) { 280#pragma unroll 281 for (int i0 = 0; i0 < sizeof(sum)/sizeof(sum[0]); ++i0) { 282 dst[j*stride_col_dst + row0 + i0*warp_size + threadIdx.x] = sum[i0]; 283 } 284 } else { 285 const int slot = (j < cols_per_block) ? slot_map[j] : -1; 286 if (slot >= 0 && (col_base + j) < ncols_dst_total) { 287#pragma unroll 288 for (int i0 = 0; i0 < sizeof(sum)/sizeof(sum[0]); ++i0) { 289 dst[slot*stride_channel_dst + j*stride_col_dst + row0 + i0*warp_size + threadIdx.x] = sum[i0]; 290 } 291 } 292 } 293 } 294 } 295#else 296 GGML_UNUSED_VARS(x, y, ids, dst, 297 ncols, ncols_dst_total, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 298 stride_col_id, stride_row_id, 299 channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 300 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst); 301 NO_DEVICE_CODE; 302#endif // defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 303} 304 305//This kernel is for larger batch sizes of mul_mat_id 306template <typename T, int rows_per_block, int cols_per_block, int nwarps> 307__launch_bounds__(ggml_cuda_get_physical_warp_size()*nwarps, 1) 308static __global__ void mul_mat_f_ids( 309 const T * __restrict__ x, const float * __restrict__ y, 310 const int32_t * __restrict__ ids_src_compact, const int32_t * __restrict__ ids_dst_compact, 311 const int32_t * __restrict__ expert_bounds, float * __restrict__ dst, 312 const int ncols, const int ncols_dst_total, const int nchannels_dst, const int stride_row, const int stride_col_y, const int stride_col_dst, 313 const int channel_ratio, const int stride_channel_x, const int stride_channel_y, const int stride_channel_dst, 314 const int sample_ratio, const int stride_sample_x, const int stride_sample_y, const int stride_sample_dst, 315 const uint3 sis1_fd, const uint3 nch_fd) { 316// TODO: handle this in a consistent and simpler way after AMD MFMA support has been added 317#if defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 318#if defined(AMD_WMMA_AVAILABLE) 319 if constexpr (!(std::is_same_v<T, half2> || std::is_same_v<T, nv_bfloat162>) || rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 320 typedef tile<16, 8, T, get_input_data_layout()> tile_A; 321 typedef tile<16, 8, T, get_input_data_layout()> tile_B; 322 typedef tile<16, 16, float, DATA_LAYOUT_J_MAJOR> tile_C; 323#elif defined(AMD_MFMA_AVAILABLE) 324 if constexpr (rows_per_block != MMF_ROWS_PER_BLOCK_CDNA) {NO_DEVICE_CODE;} else { 325 typedef tile<16, 8, T, DATA_LAYOUT_I_MAJOR> tile_A; 326 typedef tile<16, 8, T, DATA_LAYOUT_I_MAJOR> tile_B; 327 typedef tile<16, 16, float, DATA_LAYOUT_J_MAJOR> tile_C; 328#else 329#ifdef VOLTA_MMA_AVAILABLE 330 if constexpr (!std::is_same_v<T, half2> || rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 331 typedef tile<32, 4, T, DATA_LAYOUT_I_MAJOR> tile_A; 332 typedef tile< 8, 4, T, DATA_LAYOUT_I_MAJOR_MIRRORED> tile_B; 333 typedef tile<32, 8, float, DATA_LAYOUT_I_MAJOR> tile_C; 334#else 335 if constexpr (rows_per_block != MMF_ROWS_PER_BLOCK) {NO_DEVICE_CODE;} else { 336 typedef tile<16, 8, T> tile_A; 337 typedef tile<8, 8, T> tile_B; 338 typedef tile<16, 8, float> tile_C; 339#endif // VOLTA_MMA_AVAILABLE 340#endif // defined(AMD_WMMA_AVAILABLE) 341 if constexpr (!tile_A::supported() || !tile_B::supported() || !tile_C::supported()) { 342 NO_DEVICE_CODE; 343 return; 344 } 345 346 347 constexpr int warp_size = ggml_cuda_get_physical_warp_size(); 348 constexpr int tile_k_padded = warp_size + mmf_get_padding(); 349 constexpr int ntA = rows_per_block / tile_A::I; 350 constexpr int ntB = (cols_per_block + tile_B::I - 1) / tile_B::I; 351 352 const int row0 = blockIdx.x * rows_per_block; 353 354 const int expert_idx = blockIdx.y; 355 const int expert_start = expert_bounds[expert_idx]; 356 const int expert_end = expert_bounds[expert_idx + 1]; 357 const int ncols_expert = expert_end - expert_start; 358 359 const int tiles_for_expert = (ncols_expert + cols_per_block - 1) / cols_per_block; 360 const int tile_idx = blockIdx.z; 361 if (tile_idx >= tiles_for_expert) { 362 return; 363 } 364 365 const int col_base = tile_idx * cols_per_block; 366 367 GGML_UNUSED(channel_ratio); 368 369 const int channel_x = expert_idx; 370 const int sample_dst = 0; 371 const int sample_x = sample_dst / sample_ratio; 372 const int sample_y = sample_dst; 373 374 x += int64_t(sample_x) *stride_sample_x + channel_x *stride_channel_x + row0*stride_row; 375 y += int64_t(sample_y) *stride_sample_y; 376 dst += int64_t(sample_dst)*stride_sample_dst; 377 378 const int32_t * ids_src_expert = ids_src_compact + expert_start; 379 const int32_t * ids_dst_expert = ids_dst_compact + expert_start; 380 381 extern __shared__ char data_mmv[]; 382 char * compute_base = data_mmv; 383 384 //const float2 * y2 = (const float2 *) y; 385 386 tile_C C[ntA][ntB]; 387 388 T * tile_xy = (T *) compute_base + threadIdx.y*(tile_A::I * tile_k_padded); 389 390 for (int col = threadIdx.y*warp_size + threadIdx.x; col < ncols; col += nwarps*warp_size) { 391 tile_A A[ntA][warp_size / tile_A::J]; 392#pragma unroll 393 for (int itA = 0; itA < ntA; ++itA) { 394 ggml_cuda_syncwarp(); 395#pragma unroll 396 for (int i = 0; i < tile_A::I; ++i) { 397 tile_xy[i*tile_k_padded + threadIdx.x] = x[(itA*tile_A::I + i)*stride_row + col]; 398 } 399 ggml_cuda_syncwarp(); 400#pragma unroll 401 for (int k0 = 0; k0 < warp_size; k0 += tile_A::J) { 402 load_ldmatrix(A[itA][k0/tile_A::J], tile_xy + k0, tile_k_padded); 403 } 404 } 405 406 if constexpr (std::is_same_v<T, float>) { 407 float vals_buf[2][tile_B::I]; 408 auto gather_tile = [&](int tile_idx_local, float *vals) { 409#pragma unroll 410 for (int j0 = 0; j0 < tile_B::I; ++j0) { 411 const int j = j0 + tile_idx_local*tile_B::I; 412 const int global_j = col_base + j; 413 float val = 0.0f; 414 if (j < cols_per_block && global_j < ncols_expert) { 415 const int src_entry = ids_src_expert[global_j]; 416 const uint2 qrm = fast_div_modulo((uint32_t) src_entry, sis1_fd); 417 const int token = (int) qrm.x; 418 const int channel = (int) qrm.y; 419 if (token < ncols_dst_total) { 420 val = y[channel*stride_channel_y + token*stride_col_y + col]; 421 } 422 } 423 vals[j0] = val; 424 } 425 }; 426 427 gather_tile(0, vals_buf[0]); 428 429 int curr_buf = 0; 430 int next_buf = 1; 431#pragma unroll 432 for (int itB = 0; itB < ntB; ++itB) { 433 ggml_cuda_syncwarp(); 434#pragma unroll 435 for (int j0 = 0; j0 < tile_B::I; ++j0) { 436 tile_xy[j0*tile_k_padded + threadIdx.x] = vals_buf[curr_buf][j0]; 437 } 438 439 if (itB + 1 < ntB) { 440 gather_tile(itB + 1, vals_buf[next_buf]); 441 } 442 443 ggml_cuda_syncwarp(); 444#pragma unroll 445 for (int k0 = 0; k0 < warp_size; k0 += tile_B::J) { 446 tile_B B; 447 load_ldmatrix(B, tile_xy + k0, tile_k_padded); 448#pragma unroll 449 for (int itA = 0; itA < ntA; ++itA) { 450 mma(C[itA][itB], A[itA][k0/tile_B::J], B); 451 } 452 } 453 454 if (itB + 1 < ntB) { 455 curr_buf ^= 1; 456 next_buf ^= 1; 457 } 458 } 459 } else if constexpr (std::is_same_v<T, half2> || std::is_same_v<T, nv_bfloat162>) { 460 float2 vals_buf[2][tile_B::I]; 461 auto gather_tile = [&](int tile_idx_local, float2 *vals) { 462#pragma unroll 463 for (int j0 = 0; j0 < tile_B::I; ++j0) { 464 const int j = j0 + tile_idx_local*tile_B::I; 465 const int global_j = col_base + j; 466 float2 tmp = make_float2(0.0f, 0.0f); 467 if (j < cols_per_block && global_j < ncols_expert) { 468 const int src_entry = ids_src_expert[global_j]; 469 const uint2 qrm = fast_div_modulo((uint32_t) src_entry, sis1_fd); 470 const int token = (int) qrm.x; 471 const int channel = (int) qrm.y; 472 if (token < ncols_dst_total) { 473 tmp = *(const float2*) &y[channel*stride_channel_y + 2*(token*stride_col_y + col)]; 474 } 475 } 476 vals[j0] = tmp; 477 } 478 }; 479 480 if (ntB > 0) { 481 gather_tile(0, vals_buf[0]); 482 } 483 484 int curr_buf = 0; 485 int next_buf = 1; 486#pragma unroll 487 for (int itB = 0; itB < ntB; ++itB) { 488 ggml_cuda_syncwarp(); 489#pragma unroll 490 for (int j0 = 0; j0 < tile_B::I; ++j0) { 491 const float2 tmp = vals_buf[curr_buf][j0]; 492 tile_xy[j0*tile_k_padded + threadIdx.x] = ggml_cuda_cast<T>(tmp); 493 } 494 495 if (itB + 1 < ntB) { 496 gather_tile(itB + 1, vals_buf[next_buf]); 497 } 498 499 ggml_cuda_syncwarp(); 500#pragma unroll 501 for (int k0 = 0; k0 < warp_size; k0 += tile_B::J) { 502 tile_B B; 503 load_ldmatrix(B, tile_xy + k0, tile_k_padded); 504#pragma unroll 505 for (int itA = 0; itA < ntA; ++itA) { 506 mma(C[itA][itB], A[itA][k0/tile_B::J], B); 507 } 508 } 509 510 if (itB + 1 < ntB) { 511 curr_buf ^= 1; 512 next_buf ^= 1; 513 } 514 } 515 } else { 516 static_assert(std::is_same_v<T, void>, "unsupported type"); 517 } 518 } 519 520 float * buf_iw = (float *) compute_base; 521 constexpr int kiw = nwarps*rows_per_block + mmf_get_padding(); 522 523 if (nwarps > 1) { 524 __syncthreads(); 525 } else { 526 ggml_cuda_syncwarp(); 527 } 528#pragma unroll 529 for (int itB = 0; itB < ntB; ++itB) { 530#pragma unroll 531 for (int itA = 0; itA < ntA; ++itA) { 532#pragma unroll 533 for (int l = 0; l < tile_C::ne; ++l) { 534 const int i = threadIdx.y*rows_per_block + itA*tile_C::I + tile_C::get_i(l); 535 const int j = itB*tile_C::J + tile_C::get_j(l); 536 buf_iw[j*kiw + i] = C[itA][itB].x[l]; 537 } 538 } 539 } 540 541 if (nwarps > 1) { 542 __syncthreads(); 543 } else { 544 ggml_cuda_syncwarp(); 545 } 546 547#pragma unroll 548 for (int j0 = 0; j0 < cols_per_block; j0 += nwarps) { 549 const int j = j0 + threadIdx.y; 550 551 if (j0 + nwarps > cols_per_block && j >= cols_per_block) { 552 return; 553 } 554 555 float sum[rows_per_block/warp_size] = {0.0f}; 556 static_assert((rows_per_block % warp_size) == 0, "rows_per_block must be a multiple of warp_size."); 557#pragma unroll 558 for (int i0 = 0; i0 < nwarps*rows_per_block; i0 += rows_per_block) { 559#pragma unroll 560 for (int i1 = 0; i1 < sizeof(sum)/sizeof(sum[0]); ++i1) { 561 const int i = i0 + i1*warp_size + threadIdx.x; 562 563 sum[i1] += buf_iw[j * kiw + i]; 564 } 565 } 566 567 const int global_j = col_base + j; 568 if (j < cols_per_block && global_j < ncols_expert && nchannels_dst > 0) { 569 const int dst_entry = ids_dst_expert[global_j]; 570 const uint2 qrm = fast_div_modulo((uint32_t) dst_entry, nch_fd); 571 const int token = (int) qrm.x; 572 if (token < ncols_dst_total) { 573 const int slot = (int) qrm.y; 574#pragma unroll 575 for (int i0 = 0; i0 < sizeof(sum)/sizeof(sum[0]); ++i0) { 576 dst[slot * stride_channel_dst + token * stride_col_dst + row0 + i0*warp_size + threadIdx.x] = sum[i0]; 577 } 578 } 579 } 580 } 581 } 582#else 583 GGML_UNUSED_VARS(x, y, ids_src_compact, ids_dst_compact, expert_bounds, dst, 584 ncols, ncols_dst_total, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 585 channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 586 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, sis1_fd, nch_fd); 587 NO_DEVICE_CODE; 588#endif // defined(VOLTA_MMA_AVAILABLE) || defined(TURING_MMA_AVAILABLE) || defined(AMD_WMMA_AVAILABLE) || defined(AMD_MFMA_AVAILABLE) 589} 590 591template<typename T, int rows_per_block, int cols_per_block, int nwarps> 592static inline void mul_mat_f_switch_ids( 593 const T * x, const float * y, const int32_t * ids, float * dst, 594 const int64_t ncols_x, const int64_t ncols_dst, const int64_t nchannels_dst, 595 const int64_t stride_row, const int64_t stride_col_y, const int64_t stride_col_dst, 596 const int64_t stride_col_id, const int64_t stride_row_id, 597 const int64_t channel_ratio, const int64_t stride_channel_x, const int64_t stride_channel_y, const int64_t stride_channel_dst, 598 const int64_t sample_ratio, const int64_t stride_sample_x, const int64_t stride_sample_y, const int64_t stride_sample_dst, 599 const dim3 & block_nums, const dim3 & block_dims, const int nbytes_shared_total, cudaStream_t stream, 600 const mmf_ids_data * ids_data) { 601 const bool has_ids_data = ids_data && ids_data->ids_src_compact; 602 603 // Use the compact-ids kernel only for larger tiles; for small ncols_dst (< 16) 604 // we prefer the normal mul_mat_f path with has_ids=true. 605 if (has_ids_data && ncols_dst > 16) { 606 const int max_tiles = (int) ((ncols_dst + cols_per_block - 1) / cols_per_block); 607 if (max_tiles == 0) { 608 return; 609 } 610 dim3 block_nums_ids(block_nums.x, ids_data->n_experts, max_tiles); 611 612 const uint3 sis1_fd = ids_data->sis1 > 0 ? init_fastdiv_values((uint32_t) ids_data->sis1) : make_uint3(0, 0, 1); 613 const uint3 nch_fd = init_fastdiv_values((uint32_t) nchannels_dst); 614 615 mul_mat_f_ids<T, rows_per_block, cols_per_block, nwarps><<<block_nums_ids, block_dims, nbytes_shared_total, stream>>> 616 (x, y, ids_data->ids_src_compact, ids_data->ids_dst_compact, ids_data->expert_bounds_dev, dst, 617 ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 618 channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 619 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, 620 sis1_fd, nch_fd); 621 } else if (ids) { 622 const int64_t col_tiles = (ncols_dst + cols_per_block - 1) / cols_per_block; 623 dim3 block_nums_ids = block_nums; 624 block_nums_ids.y *= col_tiles; 625 626 mul_mat_f<T, rows_per_block, cols_per_block, nwarps, true><<<block_nums_ids, block_dims, nbytes_shared_total, stream>>> 627 (x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 628 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 629 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst); 630 } else { 631 mul_mat_f<T, rows_per_block, cols_per_block, nwarps, false><<<block_nums, block_dims, nbytes_shared_total, stream>>> 632 (x, y, ids, dst, ncols_x, cols_per_block, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 633 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 634 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst); 635 } 636} 637 638template <typename T, int rows_per_block, int cols_per_block> 639void mul_mat_f_cuda( 640 const T * x, const float * y, const int32_t * ids, float * dst, 641 const int64_t ncols_x, const int64_t nrows_x, const int64_t ncols_dst, 642 const int64_t stride_row, const int64_t stride_col_y, const int64_t stride_col_dst, 643 const int64_t stride_col_id, const int64_t stride_row_id, 644 const int64_t nchannels_x, const int64_t nchannels_y, const int64_t nchannels_dst, 645 const int64_t stride_channel_x, const int64_t stride_channel_y, const int64_t stride_channel_dst, const int64_t nsamples_x, 646 const int64_t nsamples_dst, const int64_t stride_sample_x, const int64_t stride_sample_y, const int64_t stride_sample_dst, 647 cudaStream_t stream, const mmf_ids_data * ids_data) { 648 typedef tile<16, 8, T> tile_A_16; 649 typedef tile<32, 8, T> tile_A_32; 650 typedef tile<16, 8, T> tile_B_16; 651 typedef tile< 8, 8, T> tile_B_8; 652 653 GGML_ASSERT(ncols_x % 2 == 0); 654 GGML_ASSERT(stride_row % 2 == 0); 655 GGML_ASSERT(stride_col_y % 2 == 0); 656 GGML_ASSERT(ids || nchannels_dst % nchannels_x == 0); 657 GGML_ASSERT( nsamples_dst % nsamples_x == 0); 658 const int64_t channel_ratio = nchannels_dst / nchannels_x; 659 const int64_t sample_ratio = nsamples_dst / nsamples_x; 660 661 const int device = ggml_cuda_get_device(); 662 const int cc = ggml_cuda_info().devices[device].cc; 663 const int warp_size = ggml_cuda_info().devices[device].warp_size; 664 665 int64_t nwarps_best = 1; 666 int64_t niter_best = (ncols_x + warp_size*2 - 1) / (warp_size*2); 667 int64_t max_block_size = mmf_get_max_block_size(cc); 668 for (int64_t nwarps = 2; nwarps <= max_block_size/warp_size; nwarps++) { 669 const int64_t niter = (ncols_x + nwarps*warp_size*2 - 1) / (nwarps*warp_size*2); 670 if (niter < niter_best) { 671 niter_best = niter; 672 nwarps_best = nwarps; 673 } 674 } 675 676 const int nbytes_shared_iter = nwarps_best * (volta_mma_available(cc) ? tile_A_32::I : tile_A_16::I) * (warp_size + mmf_get_padding(cc)) * 4; 677 const int nbytes_cols_per_block_pad = (amd_wmma_available(cc) || amd_mfma_available(cc)) ? tile_B_16::I : tile_B_8::I; 678 const int nbytes_shared_combine = GGML_PAD(cols_per_block, nbytes_cols_per_block_pad) * (nwarps_best*rows_per_block + mmf_get_padding(cc)) * 4; 679 const int nbytes_shared = std::max(nbytes_shared_iter, nbytes_shared_combine); 680 const int nbytes_slotmap = ids ? GGML_PAD(cols_per_block, 16) * sizeof(int) : 0; 681 const int nbytes_shared_total = nbytes_shared + nbytes_slotmap; 682 const int64_t grid_y = ids ? nchannels_x : nchannels_dst; 683 684 const dim3 block_nums(nrows_x/rows_per_block, grid_y, nsamples_dst); 685 const dim3 block_dims(warp_size, nwarps_best, 1); 686 687 switch (nwarps_best) { 688 case 1: { 689 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 1>( 690 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 691 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 692 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 693 ids_data); 694 } break; 695 case 2: { 696 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 2>( 697 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 698 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 699 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 700 ids_data); 701 } break; 702 case 3: { 703 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 3>( 704 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 705 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 706 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 707 ids_data); 708 } break; 709 case 4: { 710 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 4>( 711 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 712 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 713 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 714 ids_data); 715 } break; 716 case 5: { 717 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 5>( 718 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 719 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 720 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 721 ids_data); 722 } break; 723 case 6: { 724 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 6>( 725 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 726 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 727 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 728 ids_data); 729 } break; 730 case 7: { 731 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 7>( 732 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 733 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 734 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 735 ids_data); 736 } break; 737 case 8: { 738 mul_mat_f_switch_ids<T, rows_per_block, cols_per_block, 8>( 739 x, y, ids, dst, ncols_x, ncols_dst, nchannels_dst, stride_row, stride_col_y, stride_col_dst, 740 stride_col_id, stride_row_id, channel_ratio, stride_channel_x, stride_channel_y, stride_channel_dst, 741 sample_ratio, stride_sample_x, stride_sample_y, stride_sample_dst, block_nums, block_dims, nbytes_shared_total, stream, 742 ids_data); 743 } break; 744 default: { 745 GGML_ABORT("fatal error"); 746 } break; 747 } 748 749 GGML_UNUSED_VARS(nchannels_y); 750} 751 752template <typename T, int rows_per_block> 753static void mul_mat_f_switch_cols_per_block( 754 const T * x, const float * y, const int32_t * ids, float * dst, 755 const int64_t ncols_x, const int64_t nrows_x, const int64_t ncols_dst, 756 const int64_t stride_row, const int64_t stride_col_y, const int64_t stride_col_dst, 757 const int64_t stride_col_id, const int stride_row_id, 758 const int64_t nchannels_x, const int64_t nchannels_y, const int64_t nchannels_dst, 759 const int64_t stride_channel_x, const int64_t stride_channel_y, const int64_t stride_channel_dst, const int64_t nsamples_x, 760 const int64_t nsamples_dst, const int64_t stride_sample_x, const int64_t stride_sample_y, const int64_t stride_sample_dst, 761 cudaStream_t stream, const mmf_ids_data * ids_data) { 762 763 const int ncols_case = (ids && ncols_dst > 16) ? 16 : ncols_dst; 764 765 GGML_ASSERT(ids || ncols_dst <= 16); 766 767 switch (ncols_case) { 768 case 1: { 769 mul_mat_f_cuda<T, rows_per_block, 1>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 770 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 771 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 772 } break; 773 case 2: { 774 mul_mat_f_cuda<T, rows_per_block, 2>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 775 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 776 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 777 } break; 778 case 3: { 779 mul_mat_f_cuda<T, rows_per_block, 3>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 780 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 781 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 782 } break; 783 case 4: { 784 mul_mat_f_cuda<T, rows_per_block, 4>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 785 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 786 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 787 } break; 788 case 5: { 789 mul_mat_f_cuda<T, rows_per_block, 5>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 790 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 791 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 792 } break; 793 case 6: { 794 mul_mat_f_cuda<T, rows_per_block, 6>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 795 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 796 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 797 } break; 798 case 7: { 799 mul_mat_f_cuda<T, rows_per_block, 7>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 800 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 801 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 802 } break; 803 case 8: { 804 mul_mat_f_cuda<T, rows_per_block, 8>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 805 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 806 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 807 } break; 808 case 9: { 809 mul_mat_f_cuda<T, rows_per_block, 9>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 810 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 811 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 812 } break; 813 case 10: { 814 mul_mat_f_cuda<T, rows_per_block, 10>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 815 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 816 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 817 } break; 818 case 11: { 819 mul_mat_f_cuda<T, rows_per_block, 11>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 820 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 821 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 822 } break; 823 case 12: { 824 mul_mat_f_cuda<T, rows_per_block, 12>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 825 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 826 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 827 } break; 828 case 13: { 829 mul_mat_f_cuda<T, rows_per_block, 13>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 830 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 831 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 832 } break; 833 case 14: { 834 mul_mat_f_cuda<T, rows_per_block, 14>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 835 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 836 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 837 } break; 838 case 15: { 839 mul_mat_f_cuda<T, rows_per_block, 15>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 840 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 841 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 842 } break; 843 case 16: { 844 mul_mat_f_cuda<T, rows_per_block, 16>(x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 845 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 846 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 847 } break; 848 default: { 849 GGML_ABORT("fatal error"); 850 } break; 851 } 852} 853 854template <typename T> 855static void mul_mat_f_switch_rows_per_block( 856 const int rows_per_block, const T * x, const float * y, const int32_t * ids, float * dst, 857 const int64_t ncols_x, const int64_t nrows_x, const int64_t ncols_dst, 858 const int64_t stride_row, const int64_t stride_col_y, const int64_t stride_col_dst, 859 const int64_t stride_col_id, const int stride_row_id, 860 const int64_t nchannels_x, const int64_t nchannels_y, const int64_t nchannels_dst, 861 const int64_t stride_channel_x, const int64_t stride_channel_y, const int64_t stride_channel_dst, const int64_t nsamples_x, 862 const int64_t nsamples_dst, const int64_t stride_sample_x, const int64_t stride_sample_y, const int64_t stride_sample_dst, 863 cudaStream_t stream, const mmf_ids_data * ids_data) { 864 switch (rows_per_block) { 865 case MMF_ROWS_PER_BLOCK: { 866 mul_mat_f_switch_cols_per_block<T, MMF_ROWS_PER_BLOCK>( 867 x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 868 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 869 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 870 } break; 871 case MMF_ROWS_PER_BLOCK_CDNA: { 872 mul_mat_f_switch_cols_per_block<T, MMF_ROWS_PER_BLOCK_CDNA>( 873 x, y, ids, dst, ncols_x, nrows_x, ncols_dst, stride_row, stride_col_y, stride_col_dst, 874 stride_col_id, stride_row_id, nchannels_x, nchannels_y, nchannels_dst, stride_channel_x, stride_channel_y, stride_channel_dst, 875 nsamples_x, nsamples_dst, stride_sample_x, stride_sample_y, stride_sample_dst, stream, ids_data); 876 } break; 877 default: 878 GGML_ABORT("unsupported rows_per_block: %i", rows_per_block); 879 } 880} 881 882#define DECL_MMF_CASE_HELPER(T, nrows_dst, ncols_dst) \ 883 template void mul_mat_f_cuda<T, nrows_dst, ncols_dst>( \ 884 const T * x, const float * y, const int32_t * ids, float * dst, \ 885 const int64_t ncols_x, const int64_t nrows_x, int64_t ncols_dst_total, const int64_t stride_row, const int64_t stride_col_y, const int64_t stride_col_dst, \ 886 const int64_t stride_col_id, const int64_t stride_row_id, \ 887 const int64_t nchannels_x, const int64_t nchannels_y, const int64_t nchannels_dst, \ 888 const int64_t stride_channel_x, const int64_t stride_channel_y, const int64_t stride_channel_dst, const int64_t nsamples_x,\ 889 const int64_t nsamples_dst, const int64_t stride_sample_x, const int64_t stride_sample_y, const int64_t stride_sample_dst, \ 890 cudaStream_t stream, const mmf_ids_data * ids_data); 891 892#if !defined(GGML_USE_MUSA) 893#define DECL_MMF_CASE_EXTERN(ncols_dst) \ 894 extern DECL_MMF_CASE_HELPER(float, MMF_ROWS_PER_BLOCK, ncols_dst) \ 895 extern DECL_MMF_CASE_HELPER(half2, MMF_ROWS_PER_BLOCK, ncols_dst) \ 896 extern DECL_MMF_CASE_HELPER(nv_bfloat162, MMF_ROWS_PER_BLOCK, ncols_dst) \ 897 extern DECL_MMF_CASE_HELPER(float, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) \ 898 extern DECL_MMF_CASE_HELPER(half2, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) \ 899 extern DECL_MMF_CASE_HELPER(nv_bfloat162, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) 900 901#define DECL_MMF_CASE(ncols_dst) \ 902 DECL_MMF_CASE_HELPER(float, MMF_ROWS_PER_BLOCK, ncols_dst) \ 903 DECL_MMF_CASE_HELPER(half2, MMF_ROWS_PER_BLOCK, ncols_dst) \ 904 DECL_MMF_CASE_HELPER(nv_bfloat162, MMF_ROWS_PER_BLOCK, ncols_dst) \ 905 DECL_MMF_CASE_HELPER(float, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) \ 906 DECL_MMF_CASE_HELPER(half2, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) \ 907 DECL_MMF_CASE_HELPER(nv_bfloat162, MMF_ROWS_PER_BLOCK_CDNA, ncols_dst) 908 909DECL_MMF_CASE_EXTERN(1); 910DECL_MMF_CASE_EXTERN(2); 911DECL_MMF_CASE_EXTERN(3); 912DECL_MMF_CASE_EXTERN(4); 913DECL_MMF_CASE_EXTERN(5); 914DECL_MMF_CASE_EXTERN(6); 915DECL_MMF_CASE_EXTERN(7); 916DECL_MMF_CASE_EXTERN(8); 917DECL_MMF_CASE_EXTERN(9); 918DECL_MMF_CASE_EXTERN(10); 919DECL_MMF_CASE_EXTERN(11); 920DECL_MMF_CASE_EXTERN(12); 921DECL_MMF_CASE_EXTERN(13); 922DECL_MMF_CASE_EXTERN(14); 923DECL_MMF_CASE_EXTERN(15); 924DECL_MMF_CASE_EXTERN(16); 925#else 926#define DECL_MMF_CASE(ncols_dst) 927#endif