char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
aac810230
char/aliceai-t5-moe
1#include "common.h" 2#include "dequantize.h" 3// Q1_0 dot product: dot = d * (2 * Σ(yl[i] where bit=1) - sumy) 4inline float block_q_n_dot_y(device const block_q1_0 * qb_curr, float sumy, thread float * yl, int il) { 5 device const uint8_t * qs = qb_curr->qs + il / 8; 6 const uint8_t b0 = qs[0]; 7 const uint8_t b1 = qs[1]; 8 9 float acc = 0.0f; 10 11 acc += select(0.0f, yl[ 0], bool(b0 & 0x01)); 12 acc += select(0.0f, yl[ 1], bool(b0 & 0x02)); 13 acc += select(0.0f, yl[ 2], bool(b0 & 0x04)); 14 acc += select(0.0f, yl[ 3], bool(b0 & 0x08)); 15 acc += select(0.0f, yl[ 4], bool(b0 & 0x10)); 16 acc += select(0.0f, yl[ 5], bool(b0 & 0x20)); 17 acc += select(0.0f, yl[ 6], bool(b0 & 0x40)); 18 acc += select(0.0f, yl[ 7], bool(b0 & 0x80)); 19 20 acc += select(0.0f, yl[ 8], bool(b1 & 0x01)); 21 acc += select(0.0f, yl[ 9], bool(b1 & 0x02)); 22 acc += select(0.0f, yl[10], bool(b1 & 0x04)); 23 acc += select(0.0f, yl[11], bool(b1 & 0x08)); 24 acc += select(0.0f, yl[12], bool(b1 & 0x10)); 25 acc += select(0.0f, yl[13], bool(b1 & 0x20)); 26 acc += select(0.0f, yl[14], bool(b1 & 0x40)); 27 acc += select(0.0f, yl[15], bool(b1 & 0x80)); 28 29 return qb_curr->d * (2.0f * acc - sumy); 30} 31 32// Q2_0 dot: d * (sum_lo(y) + 2*sum_hi(y) - sumy) via per-bit conditional adds 33inline float block_q_n_dot_y(device const block_q2_0 * qb_curr, float sumy, thread float * yl, int il) { 34 device const uint8_t * qs = qb_curr->qs + (il / 4); 35 const uint8_t b0 = qs[0]; 36 const uint8_t b1 = qs[1]; 37 const uint8_t b2 = qs[2]; 38 const uint8_t b3 = qs[3]; 39 40 // Accumulate where low bit is set (bits 0,2,4,6 of each byte) 41 float acc_lo = 0.0f; 42 acc_lo += select(0.0f, yl[ 0], bool(b0 & 0x01)); 43 acc_lo += select(0.0f, yl[ 1], bool(b0 & 0x04)); 44 acc_lo += select(0.0f, yl[ 2], bool(b0 & 0x10)); 45 acc_lo += select(0.0f, yl[ 3], bool(b0 & 0x40)); 46 acc_lo += select(0.0f, yl[ 4], bool(b1 & 0x01)); 47 acc_lo += select(0.0f, yl[ 5], bool(b1 & 0x04)); 48 acc_lo += select(0.0f, yl[ 6], bool(b1 & 0x10)); 49 acc_lo += select(0.0f, yl[ 7], bool(b1 & 0x40)); 50 acc_lo += select(0.0f, yl[ 8], bool(b2 & 0x01)); 51 acc_lo += select(0.0f, yl[ 9], bool(b2 & 0x04)); 52 acc_lo += select(0.0f, yl[10], bool(b2 & 0x10)); 53 acc_lo += select(0.0f, yl[11], bool(b2 & 0x40)); 54 acc_lo += select(0.0f, yl[12], bool(b3 & 0x01)); 55 acc_lo += select(0.0f, yl[13], bool(b3 & 0x04)); 56 acc_lo += select(0.0f, yl[14], bool(b3 & 0x10)); 57 acc_lo += select(0.0f, yl[15], bool(b3 & 0x40)); 58 59 // Accumulate where high bit is set (bits 1,3,5,7 of each byte) 60 float acc_hi = 0.0f; 61 acc_hi += select(0.0f, yl[ 0], bool(b0 & 0x02)); 62 acc_hi += select(0.0f, yl[ 1], bool(b0 & 0x08)); 63 acc_hi += select(0.0f, yl[ 2], bool(b0 & 0x20)); 64 acc_hi += select(0.0f, yl[ 3], bool(b0 & 0x80)); 65 acc_hi += select(0.0f, yl[ 4], bool(b1 & 0x02)); 66 acc_hi += select(0.0f, yl[ 5], bool(b1 & 0x08)); 67 acc_hi += select(0.0f, yl[ 6], bool(b1 & 0x20)); 68 acc_hi += select(0.0f, yl[ 7], bool(b1 & 0x80)); 69 acc_hi += select(0.0f, yl[ 8], bool(b2 & 0x02)); 70 acc_hi += select(0.0f, yl[ 9], bool(b2 & 0x08)); 71 acc_hi += select(0.0f, yl[10], bool(b2 & 0x20)); 72 acc_hi += select(0.0f, yl[11], bool(b2 & 0x80)); 73 acc_hi += select(0.0f, yl[12], bool(b3 & 0x02)); 74 acc_hi += select(0.0f, yl[13], bool(b3 & 0x08)); 75 acc_hi += select(0.0f, yl[14], bool(b3 & 0x20)); 76 acc_hi += select(0.0f, yl[15], bool(b3 & 0x80)); 77 78 return qb_curr->d * (acc_lo + 2.0f * acc_hi - sumy); 79} 80 81// function for calculate inner product between half a q4_0 block and 16 floats (yl), sumy is SUM(yl[i]) 82// il indicates where the q4 quants begin (0 or QK4_0/4) 83// we assume that the yl's have been multiplied with the appropriate scale factor 84// that corresponds to the missing bit shifts (1, 1/16, 1/256, 1/4096) 85inline float block_q_n_dot_y(device const block_q4_0 * qb_curr, float sumy, thread float * yl, int il) { 86 float d = qb_curr->d; 87 88 float acc[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 89 90 device const uint16_t * qs = ((device const uint16_t *) qb_curr + 1 + il/2); 91 92 for (int i = 0; i < 8; i += 2) { 93 acc[0] += yl[i + 0] * (qs[i / 2] & 0x000F); 94 acc[1] += yl[i + 1] * (qs[i / 2] & 0x0F00); 95 acc[2] += yl[i + 8] * (qs[i / 2] & 0x00F0); 96 acc[3] += yl[i + 9] * (qs[i / 2] & 0xF000); 97 } 98 99 return d * (sumy * -8.f + acc[0] + acc[1] + acc[2] + acc[3]); 100} 101 102// function for calculate inner product between half a q4_1 block and 16 floats (yl), sumy is SUM(yl[i]) 103// il indicates where the q4 quants begin (0 or QK4_0/4) 104// we assume that the yl's have been multiplied with the appropriate scale factor 105// that corresponds to the missing bit shifts (1, 1/16, 1/256, 1/4096) 106inline float block_q_n_dot_y(device const block_q4_1 * qb_curr, float sumy, thread float * yl, int il) { 107 float d = qb_curr->d; 108 float m = qb_curr->m; 109 110 float acc[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 111 112 device const uint16_t * qs = ((device const uint16_t *) qb_curr + 2 + il/2); 113 114 for (int i = 0; i < 8; i+=2) { 115 acc[0] += yl[i + 0] * (qs[i / 2] & 0x000F); 116 acc[1] += yl[i + 1] * (qs[i / 2] & 0x0F00); 117 acc[2] += yl[i + 8] * (qs[i / 2] & 0x00F0); 118 acc[3] += yl[i + 9] * (qs[i / 2] & 0xF000); 119 } 120 121 return d * (acc[0] + acc[1] + acc[2] + acc[3]) + sumy * m; 122} 123 124// function for calculate inner product between half a q5_0 block and 16 floats (yl), sumy is SUM(yl[i]) 125// il indicates where the q5 quants begin (0 or QK5_0/4) 126// we assume that the yl's have been multiplied with the appropriate scale factor 127// that corresponds to the missing bit shifts (1, 1/16, 1/256, 1/4096) 128inline float block_q_n_dot_y(device const block_q5_0 * qb_curr, float sumy, thread float * yl, int il) { 129 float d = qb_curr->d; 130 131 float acc[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 132 133 device const uint16_t * qs = ((device const uint16_t *)qb_curr + 3 + il/2); 134 const uint32_t qh = *((device const uint32_t *)qb_curr->qh); 135 136 for (int i = 0; i < 8; i+=2) { 137 acc[0] += yl[i + 0] * ((qs[i / 2] & 0x000F) | ((qh >> (i+0+il ) << 4 ) & 0x00010)); 138 acc[1] += yl[i + 1] * ((qs[i / 2] & 0x0F00) | ((qh >> (i+1+il ) << 12) & 0x01000)); 139 acc[2] += yl[i + 8] * ((qs[i / 2] & 0x00F0) | ((qh >> (i+0+il+QK5_0/2) << 8 ) & 0x00100)); 140 acc[3] += yl[i + 9] * ((qs[i / 2] & 0xF000) | ((qh >> (i+1+il+QK5_0/2) << 16) & 0x10000)); 141 } 142 143 return d * (sumy * -16.f + acc[0] + acc[1] + acc[2] + acc[3]); 144} 145 146// function for calculate inner product between half a q5_1 block and 16 floats (yl), sumy is SUM(yl[i]) 147// il indicates where the q5 quants begin (0 or QK5_1/4) 148// we assume that the yl's have been multiplied with the appropriate scale factor 149// that corresponds to the missing bit shifts (1, 1/16, 1/256, 1/4096) 150inline float block_q_n_dot_y(device const block_q5_1 * qb_curr, float sumy, thread float * yl, int il) { 151 float d = qb_curr->d; 152 float m = qb_curr->m; 153 154 float acc[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 155 156 device const uint16_t * qs = ((device const uint16_t *)qb_curr + 4 + il/2); 157 const uint32_t qh = *((device const uint32_t *)qb_curr->qh); 158 159 for (int i = 0; i < 8; i+=2) { 160 acc[0] += yl[i + 0] * ((qs[i / 2] & 0x000F) | ((qh >> (i+0+il ) << 4 ) & 0x00010)); 161 acc[1] += yl[i + 1] * ((qs[i / 2] & 0x0F00) | ((qh >> (i+1+il ) << 12) & 0x01000)); 162 acc[2] += yl[i + 8] * ((qs[i / 2] & 0x00F0) | ((qh >> (i+0+il+QK5_0/2) << 8 ) & 0x00100)); 163 acc[3] += yl[i + 9] * ((qs[i / 2] & 0xF000) | ((qh >> (i+1+il+QK5_0/2) << 16) & 0x10000)); 164 } 165 166 return d * (acc[0] + acc[1] + acc[2] + acc[3]) + sumy * m; 167} 168 169template<short NR0> 170static inline void helper_mv_reduce_and_write( 171 device float * dst_f32, 172 float sumf[NR0], 173 const int r0, 174 const int ne01, 175 ushort tiisg, 176 ushort sgitg, 177 threadgroup char * shmem) { 178 constexpr short NW = N_SIMDWIDTH; 179 180 threadgroup float * shmem_f32[NR0]; 181 182 for (short row = 0; row < NR0; ++row) { 183 shmem_f32[row] = (threadgroup float *) shmem + NW*row; 184 185 if (sgitg == 0) { 186 shmem_f32[row][tiisg] = 0.0f; 187 } 188 189 sumf[row] = simd_sum(sumf[row]); 190 } 191 192 threadgroup_barrier(mem_flags::mem_threadgroup); 193 194 for (short row = 0; row < NR0; ++row) { 195 if (tiisg == 0) { 196 shmem_f32[row][sgitg] = sumf[row]; 197 } 198 } 199 200 threadgroup_barrier(mem_flags::mem_threadgroup); 201 202 for (short row = 0; row < NR0 && r0 + row < ne01; ++row) { 203 float tot = simd_sum(shmem_f32[row][tiisg]); 204 205 if (tiisg == 0 && sgitg == 0) { 206 dst_f32[r0 + row] = tot; 207 } 208 } 209} 210 211constant short FC_mul_mv_nsg [[function_constant(FC_MUL_MV + 0)]]; 212constant short FC_mul_mv_nxpsg [[function_constant(FC_MUL_MV + 1)]]; 213constant short FC_mul_mv_ne12 [[function_constant(FC_MUL_MV + 2)]]; 214constant short FC_mul_mv_r2 [[function_constant(FC_MUL_MV + 3)]]; 215constant short FC_mul_mv_r3 [[function_constant(FC_MUL_MV + 4)]]; 216constant bool FC_mul_mv_split [[function_constant(FC_MUL_MV + 5)]]; 217 218template<typename block_q_type, short NR0, typename args_t> 219void mul_vec_q_n_f32_impl( 220 args_t args, 221 device const char * src0, 222 device const char * src1, 223 device char * dst, 224 threadgroup char * shmem, 225 uint3 tgpig, 226 ushort tiisg, 227 ushort sgitg) { 228 const short NSG = FC_mul_mv_nsg; 229 230 constexpr short NW = N_SIMDWIDTH; 231 constexpr short NQ = 16; 232 233 const int nb = args.ne00/QK4_0; 234 235 const int r0 = (tgpig.x*NSG + sgitg)*NR0; 236 //const int r0 = tgpig.x*NR0; 237 const int r1 = tgpig.y; 238 const int im = tgpig.z; 239 240 const uint i12 = im%FC_mul_mv_ne12; 241 const uint i13 = im/FC_mul_mv_ne12; 242 243 //const uint64_t offset0 = r0*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 244 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 245 246 //device const block_q_type * x = (device const block_q_type *) (src0 + offset0); 247 device const float * y = (device const float *) (src1 + offset1); 248 249 // pointers to src0 rows 250 device const block_q_type * ax[NR0]; 251 FOR_UNROLL (int row = 0; row < NR0; ++row) { 252 const uint64_t offset0 = (r0 + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 253 254 ax[row] = (device const block_q_type *) ((device char *) src0 + offset0); 255 } 256 257 float sumf[NR0] = {0.f}; 258 259 const short ix = (tiisg/(NW/NQ)); 260 const short il = (tiisg%(NW/NQ))*8; 261 262 //const int ib0 = sgitg*NQ + ix; 263 const int ib0 = ix; 264 265 float yl[16]; // src1 vector cache 266 267 //device const float * yb = y + ix*QK4_0 + il; 268 device const float * yb = y + ib0*QK4_0 + il; 269 270 // each thread in a SIMD group deals with half a block. 271 //for (int ib = ib0; ib < nb; ib += NSG*NQ) { 272 for (int ib = ib0; ib < nb; ib += NQ) { 273 float sumy[2] = { 0.f, 0.f }; 274 275 FOR_UNROLL (short i = 0; i < 8; i += 2) { 276 sumy[0] += yb[i + 0] + yb[i + 1]; 277 yl[i + 0] = yb[i + 0]; 278 yl[i + 1] = yb[i + 1]/256.f; 279 280 sumy[1] += yb[i + 16] + yb[i + 17]; 281 yl[i + 8] = yb[i + 16]/16.f; 282 yl[i + 9] = yb[i + 17]/4096.f; 283 } 284 285 FOR_UNROLL (short row = 0; row < NR0; row++) { 286 sumf[row] += block_q_n_dot_y(ax[row] + ib, sumy[0] + sumy[1], yl, il); 287 } 288 289 yb += QK4_0 * 16; 290 //yb += NSG*NQ*QK4_0; 291 } 292 293 device float * dst_f32 = (device float *) dst + im*args.ne0*args.ne1 + r1*args.ne0; 294 295 //helper_mv_reduce_and_write<NR0>(dst_f32, sumf, r0, args.ne01, tiisg, sgitg, shmem); 296 297 for (int row = 0; row < NR0; ++row) { 298 const float tot = simd_sum(sumf[row]); 299 300 if (tiisg == 0 && r0 + row < args.ne01) { 301 dst_f32[r0 + row] = tot; 302 } 303 } 304} 305 306template<int nr0, typename args_t> 307void kernel_mul_mv_q1_0_f32_impl( 308 args_t args, 309 device const char * src0, 310 device const char * src1, 311 device char * dst, 312 threadgroup char * shmem, 313 uint3 tgpig, 314 ushort tiisg, 315 ushort sgitg) { 316 const short NSG = FC_mul_mv_nsg; 317 318 const int nb = args.ne00/QK1_0; 319 320 const int r0 = tgpig.x; 321 const int r1 = tgpig.y; 322 const int im = tgpig.z; 323 324 const int first_row = (r0 * NSG + sgitg) * nr0; 325 326 const uint i12 = im%FC_mul_mv_ne12; 327 const uint i13 = im/FC_mul_mv_ne12; 328 329 const uint64_t offset1 = r1*args.nb11 + (i12)*args.nb12 + (i13)*args.nb13; 330 331 device const float * y = (device const float *) (src1 + offset1); 332 333 device const block_q1_0 * ax[nr0]; 334 for (int row = 0; row < nr0; ++row) { 335 const uint64_t offset0 = (first_row + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 336 ax[row] = (device const block_q1_0 *) ((device char *) src0 + offset0); 337 } 338 339 float yl[16]; 340 float sumf[nr0] = {0.f}; 341 342 const short ix = (tiisg/8); 343 const short il = (tiisg%8)*16; 344 345 device const float * yb = y + ix*QK1_0 + il; 346 347 for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/8) { 348 float sumy = 0.f; 349 350 FOR_UNROLL (short i = 0; i < 16; i++) { 351 yl[i] = yb[i]; 352 sumy += yb[i]; 353 } 354 355 FOR_UNROLL (short row = 0; row < nr0; row++) { 356 sumf[row] += block_q_n_dot_y(ax[row] + ib, sumy, yl, il); 357 } 358 359 yb += QK1_0 * (N_SIMDWIDTH/8); 360 } 361 362 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 363 364 for (int row = 0; row < nr0; ++row) { 365 const float tot = simd_sum(sumf[row]); 366 367 if (tiisg == 0 && first_row + row < args.ne01) { 368 dst_f32[first_row + row] = tot; 369 } 370 } 371} 372 373[[host_name("kernel_mul_mv_q1_0_f32")]] 374kernel void kernel_mul_mv_q1_0_f32( 375 constant ggml_metal_kargs_mul_mv & args, 376 device const char * src0, 377 device const char * src1, 378 device char * dst, 379 uint3 tgpig[[threadgroup_position_in_grid]], 380 ushort tiisg[[thread_index_in_simdgroup]], 381 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 382 kernel_mul_mv_q1_0_f32_impl<N_R0_Q1_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 383} 384 385template<int nr0, typename args_t> 386void kernel_mul_mv_q2_0_f32_impl( 387 args_t args, 388 device const char * src0, 389 device const char * src1, 390 device char * dst, 391 threadgroup char * shmem, 392 uint3 tgpig, 393 ushort tiisg, 394 ushort sgitg) { 395 const short NSG = FC_mul_mv_nsg; 396 397 const int nb = args.ne00/QK2_0; 398 399 const int r0 = tgpig.x; 400 const int r1 = tgpig.y; 401 const int im = tgpig.z; 402 403 const int first_row = (r0 * NSG + sgitg) * nr0; 404 405 const uint i12 = im%FC_mul_mv_ne12; 406 const uint i13 = im/FC_mul_mv_ne12; 407 408 const uint64_t offset1 = r1*args.nb11 + (i12)*args.nb12 + (i13)*args.nb13; 409 410 device const float * y = (device const float *) (src1 + offset1); 411 412 device const block_q2_0 * ax[nr0]; 413 for (int row = 0; row < nr0; ++row) { 414 const uint64_t offset0 = (first_row + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 415 ax[row] = (device const block_q2_0 *) ((device char *) src0 + offset0); 416 } 417 418 float yl[16]; 419 float sumf[nr0] = {0.f}; 420 421 // group 64: 4 sub-blocks of 16 weights per Q2_0 block 422 const short ix = (tiisg/4); 423 const short il = (tiisg%4)*16; 424 425 device const float * yb = y + ix*QK2_0 + il; 426 427 for (int ib = ix; ib < nb; ib += N_SIMDWIDTH/4) { 428 float sumy = 0.f; 429 430 FOR_UNROLL (short i = 0; i < 16; i++) { 431 yl[i] = yb[i]; 432 sumy += yb[i]; 433 } 434 435 FOR_UNROLL (short row = 0; row < nr0; row++) { 436 sumf[row] += block_q_n_dot_y(ax[row] + ib, sumy, yl, il); 437 } 438 439 yb += QK2_0 * (N_SIMDWIDTH/4); 440 } 441 442 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 443 444 for (int row = 0; row < nr0; ++row) { 445 const float tot = simd_sum(sumf[row]); 446 447 if (tiisg == 0 && first_row + row < args.ne01) { 448 dst_f32[first_row + row] = tot; 449 } 450 } 451} 452 453[[host_name("kernel_mul_mv_q2_0_f32")]] 454kernel void kernel_mul_mv_q2_0_f32( 455 constant ggml_metal_kargs_mul_mv & args, 456 device const char * src0, 457 device const char * src1, 458 device char * dst, 459 uint3 tgpig[[threadgroup_position_in_grid]], 460 ushort tiisg[[thread_index_in_simdgroup]], 461 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 462 kernel_mul_mv_q2_0_f32_impl<N_R0_Q2_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 463} 464 465kernel void kernel_mul_mv_q4_0_f32( 466 constant ggml_metal_kargs_mul_mv & args, 467 device const char * src0, 468 device const char * src1, 469 device char * dst, 470 threadgroup char * shmem [[threadgroup(0)]], 471 uint3 tgpig[[threadgroup_position_in_grid]], 472 ushort tiisg[[thread_index_in_simdgroup]], 473 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 474 mul_vec_q_n_f32_impl<block_q4_0, N_R0_Q4_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 475} 476 477kernel void kernel_mul_mv_q4_1_f32( 478 constant ggml_metal_kargs_mul_mv & args, 479 device const char * src0, 480 device const char * src1, 481 device char * dst, 482 threadgroup char * shmem [[threadgroup(0)]], 483 uint3 tgpig[[threadgroup_position_in_grid]], 484 ushort tiisg[[thread_index_in_simdgroup]], 485 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 486 mul_vec_q_n_f32_impl<block_q4_1, N_R0_Q4_1, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 487} 488 489kernel void kernel_mul_mv_q5_0_f32( 490 constant ggml_metal_kargs_mul_mv & args, 491 device const char * src0, 492 device const char * src1, 493 device char * dst, 494 threadgroup char * shmem [[threadgroup(0)]], 495 uint3 tgpig[[threadgroup_position_in_grid]], 496 ushort tiisg[[thread_index_in_simdgroup]], 497 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 498 mul_vec_q_n_f32_impl<block_q5_0, N_R0_Q5_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 499} 500 501kernel void kernel_mul_mv_q5_1_f32( 502 constant ggml_metal_kargs_mul_mv & args, 503 device const char * src0, 504 device const char * src1, 505 device char * dst, 506 threadgroup char * shmem [[threadgroup(0)]], 507 uint3 tgpig[[threadgroup_position_in_grid]], 508 ushort tiisg[[thread_index_in_simdgroup]], 509 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 510 mul_vec_q_n_f32_impl<block_q5_1, N_R0_Q5_1, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 511} 512 513template<short NR0, typename args_t> 514void kernel_mul_mv_q8_0_f32_impl( 515 args_t args, 516 device const char * src0, 517 device const char * src1, 518 device char * dst, 519 threadgroup char * shmem, 520 uint3 tgpig, 521 ushort tiisg, 522 ushort sgitg) { 523 const short NSG = FC_mul_mv_nsg; 524 525 constexpr short NW = N_SIMDWIDTH; 526 constexpr short NQ = 8; 527 528 const int nb = args.ne00/QK8_0; 529 530 const int r0 = tgpig.x*NR0; 531 const int r1 = tgpig.y; 532 const int im = tgpig.z; 533 534 const uint i12 = im%FC_mul_mv_ne12; 535 const uint i13 = im/FC_mul_mv_ne12; 536 537 //const uint64_t offset0 = r0*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 538 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 539 540 //device const block_q8_0 * x = (device const block_q8_0 *) (src0 + offset0); 541 device const float * y = (device const float *) (src1 + offset1); 542 543 // pointers to src0 rows 544 device const block_q8_0 * ax[NR0]; 545 FOR_UNROLL (short row = 0; row < NR0; ++row) { 546 const uint64_t offset0 = (r0 + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 547 548 ax[row] = (device const block_q8_0 *) ((device char *) src0 + offset0); 549 } 550 551 float sumf[NR0] = { 0.f }; 552 553 const short ix = tiisg/(NW/NQ); 554 const short il = tiisg%(NW/NQ); 555 556 const int ib0 = sgitg*NQ + ix; 557 558 float yl[NQ]; 559 560 device const float * yb = y + ib0*QK8_0 + il*NQ; 561 562 // each thread in a SIMD group deals with NQ quants at a time 563 for (int ib = ib0; ib < nb; ib += NSG*NQ) { 564 for (short i = 0; i < NQ; ++i) { 565 yl[i] = yb[i]; 566 } 567 568 for (short row = 0; row < NR0; row++) { 569 device const int8_t * qs = ax[row][ib].qs + il*NQ; 570 571 float sumq = 0.f; 572 FOR_UNROLL (short i = 0; i < NQ; ++i) { 573 sumq += qs[i] * yl[i]; 574 } 575 576 sumf[row] += sumq*ax[row][ib].d; 577 } 578 579 yb += NSG*NQ*QK8_0; 580 } 581 582 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 583 584 helper_mv_reduce_and_write<NR0>(dst_f32, sumf, r0, args.ne01, tiisg, sgitg, shmem); 585} 586 587[[host_name("kernel_mul_mv_q8_0_f32")]] 588kernel void kernel_mul_mv_q8_0_f32( 589 constant ggml_metal_kargs_mul_mv & args, 590 device const char * src0, 591 device const char * src1, 592 device char * dst, 593 threadgroup char * shmem [[threadgroup(0)]], 594 uint3 tgpig[[threadgroup_position_in_grid]], 595 ushort tiisg[[thread_index_in_simdgroup]], 596 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 597 kernel_mul_mv_q8_0_f32_impl<N_R0_Q8_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 598} 599 600// mat-vec kernel processing in chunks of float4 601// chpb - chunks per quantization block 602template<short r1ptg, typename q_t, short chpb, void (*deq_t4)(device const q_t *, short, thread float4 &) > 603void kernel_mul_mv_ext_q4_f32_impl( 604 constant ggml_metal_kargs_mul_mv_ext & args, 605 device const char * src0, 606 device const char * src1, 607 device char * dst, 608 uint3 tgpig[[threadgroup_position_in_grid]], 609 ushort tiisg[[thread_index_in_simdgroup]], 610 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 611 const short NSG = FC_mul_mv_nsg; 612 const short nxpsg = FC_mul_mv_nxpsg; 613 614 const short chpt = 4; // chunks per thread 615 616 //const short nxpsg = (32); 617 const short nypsg = (32/nxpsg); 618 619 const short tx = tiisg%nxpsg; 620 const short ty = tiisg/nxpsg; 621 622 const int i01 = tgpig.x*(nypsg*NSG) + nypsg*sgitg + ty; 623 const int i11 = tgpig.y*r1ptg; 624 const int i1m = tgpig.z; 625 626 const int i12 = i1m%FC_mul_mv_ne12; 627 const int i13 = i1m/FC_mul_mv_ne12; 628 629 const uint64_t offset0 = i01*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 630 const uint64_t offset1 = i11*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 631 632 device const q_t * xq = (i01 < args.ne01) ? (device const q_t *) (src0 + offset0) + tx/chpb : (device const q_t *) src0; 633 634 device const float4 * y4[r1ptg]; 635 636 for (int ir1 = 0; ir1 < r1ptg; ++ir1) { 637 y4[ir1] = (i11 + ir1 < args.ne11) ? (device const float4 *) (src1 + offset1 + ir1*args.nb11) + tx : (device const float4 *) src1; 638 } 639 640 float sumf[r1ptg] = { [ 0 ... r1ptg - 1 ] = 0.0f }; 641 642 short cch = tx%chpb; // current chunk index 643 644 for (int ich = tx; 4*ich < args.ne00; ich += chpt*nxpsg) { 645 float4 lx[chpt]; 646 647#pragma unroll(chpt) 648 for (short ch = 0; ch < chpt; ++ch) { 649 deq_t4(xq, cch, lx[ch]); 650 651 cch += nxpsg; 652 if (cch >= chpb) { 653 xq += cch/chpb; 654 cch %= chpb; 655 } 656 } 657 658#pragma unroll(chpt) 659 for (short ch = 0; ch < chpt; ++ch) { 660#pragma unroll(r1ptg) 661 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 662 sumf[ir1] += dot(lx[ch], y4[ir1][ch*nxpsg]); 663 } 664 } 665 666#pragma unroll(r1ptg) 667 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 668 y4[ir1] += chpt*nxpsg; 669 } 670 } 671 672 // reduce only the threads in each row 673 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 674 if (nxpsg >= 32) { 675 sumf[ir1] += simd_shuffle_down(sumf[ir1], 16); 676 } 677 if (nxpsg >= 16) { 678 sumf[ir1] += simd_shuffle_down(sumf[ir1], 8); 679 } 680 if (nxpsg >= 8) { 681 sumf[ir1] += simd_shuffle_down(sumf[ir1], 4); 682 } 683 if (nxpsg >= 4) { 684 sumf[ir1] += simd_shuffle_down(sumf[ir1], 2); 685 } 686 if (nxpsg >= 2) { 687 sumf[ir1] += simd_shuffle_down(sumf[ir1], 1); 688 } 689 690 //sumf[ir1] = simd_sum(sumf[ir1]); 691 } 692 693 if (tx == 0) { 694 for (short ir1 = 0; ir1 < r1ptg && i11 + ir1 < args.ne11; ++ir1) { 695 device float * dst_f32 = (device float *) dst + (uint64_t)i1m*args.ne0*args.ne1 + (uint64_t)(i11 + ir1)*args.ne0; 696 697 if (i01 < args.ne01) { 698 dst_f32[i01] = sumf[ir1]; 699 } 700 } 701 } 702} 703 704// mat-vec kernel processing in chunks of float4x4 705template<short r1ptg, typename q_t, short chpb, void (*deq_t4x4)(device const q_t *, short, thread float4x4 &) > 706void kernel_mul_mv_ext_q4x4_f32_impl( 707 constant ggml_metal_kargs_mul_mv_ext & args, 708 device const char * src0, 709 device const char * src1, 710 device char * dst, 711 uint3 tgpig[[threadgroup_position_in_grid]], 712 ushort tiisg[[thread_index_in_simdgroup]], 713 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 714 const short NSG = FC_mul_mv_nsg; 715 const short nxpsg = FC_mul_mv_nxpsg; 716 717 const short chpt = 1; 718 719 //const short nxpsg = (32); 720 const short nypsg = (32/nxpsg); 721 722 const short tx = tiisg%nxpsg; 723 const short ty = tiisg/nxpsg; 724 725 const int i01 = tgpig.x*(nypsg*NSG) + nypsg*sgitg + ty; 726 const int i11 = tgpig.y*r1ptg; 727 const int i1m = tgpig.z; 728 729 const int i12 = i1m%FC_mul_mv_ne12; 730 const int i13 = i1m/FC_mul_mv_ne12; 731 732 const uint64_t offset0 = i01*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 733 const uint64_t offset1 = i11*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 734 735 device const q_t * xq = (i01 < args.ne01) ? (device const q_t *) (src0 + offset0) + tx/chpb : (device const q_t *) src0; 736 737 device const float4x4 * y4x4[r1ptg]; 738 739 for (int ir1 = 0; ir1 < r1ptg; ++ir1) { 740 y4x4[ir1] = (i11 + ir1 < args.ne11) ? (device const float4x4 *) (src1 + offset1 + ir1*args.nb11) + tx : (device const float4x4 *) src1; 741 } 742 743 float sumf[r1ptg] = { [ 0 ... r1ptg - 1 ] = 0.0f }; 744 745 short cch = tx%chpb; 746 747 for (int ich = tx; 16*ich < args.ne00; ich += chpt*nxpsg) { 748 float4x4 lx[chpt]; 749 750#pragma unroll(chpt) 751 for (short ch = 0; ch < chpt; ++ch) { 752 deq_t4x4(xq, cch, lx[ch]); 753 754 cch += nxpsg; 755 if (cch >= chpb) { 756 xq += cch/chpb; 757 cch %= chpb; 758 } 759 } 760 761#pragma unroll(chpt) 762 for (short ch = 0; ch < chpt; ++ch) { 763#pragma unroll(r1ptg) 764 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 765 sumf[ir1] += 766 dot(lx[ch][0], y4x4[ir1][ch*nxpsg][0]) + 767 dot(lx[ch][1], y4x4[ir1][ch*nxpsg][1]) + 768 dot(lx[ch][2], y4x4[ir1][ch*nxpsg][2]) + 769 dot(lx[ch][3], y4x4[ir1][ch*nxpsg][3]); 770 771 } 772 } 773 774#pragma unroll(r1ptg) 775 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 776 y4x4[ir1] += chpt*nxpsg; 777 } 778 } 779 780 for (short ir1 = 0; ir1 < r1ptg; ++ir1) { 781 if (nxpsg >= 32) { 782 sumf[ir1] += simd_shuffle_down(sumf[ir1], 16); 783 } 784 if (nxpsg >= 16) { 785 sumf[ir1] += simd_shuffle_down(sumf[ir1], 8); 786 } 787 if (nxpsg >= 8) { 788 sumf[ir1] += simd_shuffle_down(sumf[ir1], 4); 789 } 790 if (nxpsg >= 4) { 791 sumf[ir1] += simd_shuffle_down(sumf[ir1], 2); 792 } 793 if (nxpsg >= 2) { 794 sumf[ir1] += simd_shuffle_down(sumf[ir1], 1); 795 } 796 797 //sumf[ir1] = simd_sum(sumf[ir1]); 798 } 799 800 if (tx == 0) { 801 for (short ir1 = 0; ir1 < r1ptg && i11 + ir1 < args.ne11; ++ir1) { 802 device float * dst_f32 = (device float *) dst + (uint64_t)i1m*args.ne0*args.ne1 + (uint64_t)(i11 + ir1)*args.ne0; 803 804 if (i01 < args.ne01) { 805 dst_f32[i01] = sumf[ir1]; 806 } 807 } 808 } 809} 810 811// dispatchers needed for compile-time nxpsg 812// epb - elements per quantization block 813template<short r1ptg, typename q_t, short epb, void (*deq_t4)(device const q_t *, short, thread float4 &)> 814kernel void kernel_mul_mv_ext_q4_f32_disp( 815 constant ggml_metal_kargs_mul_mv_ext & args, 816 device const char * src0, 817 device const char * src1, 818 device char * dst, 819 uint3 tgpig[[threadgroup_position_in_grid]], 820 ushort tiisg[[thread_index_in_simdgroup]], 821 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 822 kernel_mul_mv_ext_q4_f32_impl<r1ptg, q_t, epb/4, deq_t4>(args, src0, src1, dst, tgpig, tiisg, sgitg); 823} 824 825template<short r1ptg, typename q_t, short epb, void (*deq_t4x4)(device const q_t *, short, thread float4x4 &)> 826kernel void kernel_mul_mv_ext_q4x4_f32_disp( 827 constant ggml_metal_kargs_mul_mv_ext & args, 828 device const char * src0, 829 device const char * src1, 830 device char * dst, 831 uint3 tgpig[[threadgroup_position_in_grid]], 832 ushort tiisg[[thread_index_in_simdgroup]], 833 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 834 kernel_mul_mv_ext_q4x4_f32_impl<r1ptg, q_t, epb/16, deq_t4x4>(args, src0, src1, dst, tgpig, tiisg, sgitg); 835} 836 837typedef decltype(kernel_mul_mv_ext_q4_f32_disp <2, block_q8_0, 32, dequantize_q8_0_t4>) mul_mv_ext_q4_f32_t; 838typedef decltype(kernel_mul_mv_ext_q4x4_f32_disp<2, block_q4_K, 256, dequantize_q4_K>) mul_mv_ext_q4x4_f32_t; 839 840template [[host_name("kernel_mul_mv_ext_f32_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, float4, 4, dequantize_f32_t4>; 841template [[host_name("kernel_mul_mv_ext_f32_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, float4, 4, dequantize_f32_t4>; 842template [[host_name("kernel_mul_mv_ext_f32_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, float4, 4, dequantize_f32_t4>; 843template [[host_name("kernel_mul_mv_ext_f32_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, float4, 4, dequantize_f32_t4>; 844 845template [[host_name("kernel_mul_mv_ext_f16_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, half4, 4, dequantize_f16_t4>; 846template [[host_name("kernel_mul_mv_ext_f16_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, half4, 4, dequantize_f16_t4>; 847template [[host_name("kernel_mul_mv_ext_f16_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, half4, 4, dequantize_f16_t4>; 848template [[host_name("kernel_mul_mv_ext_f16_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, half4, 4, dequantize_f16_t4>; 849 850#if defined(GGML_METAL_HAS_BF16) 851template [[host_name("kernel_mul_mv_ext_bf16_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, bfloat4, 4, dequantize_bf16_t4>; 852template [[host_name("kernel_mul_mv_ext_bf16_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, bfloat4, 4, dequantize_bf16_t4>; 853template [[host_name("kernel_mul_mv_ext_bf16_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, bfloat4, 4, dequantize_bf16_t4>; 854template [[host_name("kernel_mul_mv_ext_bf16_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, bfloat4, 4, dequantize_bf16_t4>; 855#endif 856 857template [[host_name("kernel_mul_mv_ext_q1_0_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q1_0, 128, dequantize_q1_0_t4>; 858template [[host_name("kernel_mul_mv_ext_q1_0_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q1_0, 128, dequantize_q1_0_t4>; 859template [[host_name("kernel_mul_mv_ext_q1_0_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q1_0, 128, dequantize_q1_0_t4>; 860template [[host_name("kernel_mul_mv_ext_q1_0_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q1_0, 128, dequantize_q1_0_t4>; 861 862template [[host_name("kernel_mul_mv_ext_q2_0_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q2_0, 64, dequantize_q2_0_t4>; 863template [[host_name("kernel_mul_mv_ext_q2_0_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q2_0, 64, dequantize_q2_0_t4>; 864template [[host_name("kernel_mul_mv_ext_q2_0_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q2_0, 64, dequantize_q2_0_t4>; 865template [[host_name("kernel_mul_mv_ext_q2_0_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q2_0, 64, dequantize_q2_0_t4>; 866 867template [[host_name("kernel_mul_mv_ext_q4_0_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q4_0, 32, dequantize_q4_0_t4>; 868template [[host_name("kernel_mul_mv_ext_q4_0_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q4_0, 32, dequantize_q4_0_t4>; 869template [[host_name("kernel_mul_mv_ext_q4_0_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q4_0, 32, dequantize_q4_0_t4>; 870template [[host_name("kernel_mul_mv_ext_q4_0_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q4_0, 32, dequantize_q4_0_t4>; 871 872template [[host_name("kernel_mul_mv_ext_q4_1_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q4_1, 32, dequantize_q4_1_t4>; 873template [[host_name("kernel_mul_mv_ext_q4_1_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q4_1, 32, dequantize_q4_1_t4>; 874template [[host_name("kernel_mul_mv_ext_q4_1_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q4_1, 32, dequantize_q4_1_t4>; 875template [[host_name("kernel_mul_mv_ext_q4_1_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q4_1, 32, dequantize_q4_1_t4>; 876 877template [[host_name("kernel_mul_mv_ext_q5_0_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q5_0, 32, dequantize_q5_0_t4>; 878template [[host_name("kernel_mul_mv_ext_q5_0_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q5_0, 32, dequantize_q5_0_t4>; 879template [[host_name("kernel_mul_mv_ext_q5_0_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q5_0, 32, dequantize_q5_0_t4>; 880template [[host_name("kernel_mul_mv_ext_q5_0_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q5_0, 32, dequantize_q5_0_t4>; 881 882template [[host_name("kernel_mul_mv_ext_q5_1_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q5_1, 32, dequantize_q5_1_t4>; 883template [[host_name("kernel_mul_mv_ext_q5_1_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q5_1, 32, dequantize_q5_1_t4>; 884template [[host_name("kernel_mul_mv_ext_q5_1_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q5_1, 32, dequantize_q5_1_t4>; 885template [[host_name("kernel_mul_mv_ext_q5_1_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q5_1, 32, dequantize_q5_1_t4>; 886 887template [[host_name("kernel_mul_mv_ext_q8_0_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_q8_0, 32, dequantize_q8_0_t4>; 888template [[host_name("kernel_mul_mv_ext_q8_0_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_q8_0, 32, dequantize_q8_0_t4>; 889template [[host_name("kernel_mul_mv_ext_q8_0_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_q8_0, 32, dequantize_q8_0_t4>; 890template [[host_name("kernel_mul_mv_ext_q8_0_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_q8_0, 32, dequantize_q8_0_t4>; 891 892template [[host_name("kernel_mul_mv_ext_mxfp4_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_mxfp4, 32, dequantize_mxfp4_t4>; 893template [[host_name("kernel_mul_mv_ext_mxfp4_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_mxfp4, 32, dequantize_mxfp4_t4>; 894template [[host_name("kernel_mul_mv_ext_mxfp4_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_mxfp4, 32, dequantize_mxfp4_t4>; 895template [[host_name("kernel_mul_mv_ext_mxfp4_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_mxfp4, 32, dequantize_mxfp4_t4>; 896 897template [[host_name("kernel_mul_mv_ext_iq4_nl_f32_r1_2")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<2, block_iq4_nl, 32, dequantize_iq4_nl_t4>; 898template [[host_name("kernel_mul_mv_ext_iq4_nl_f32_r1_3")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<3, block_iq4_nl, 32, dequantize_iq4_nl_t4>; 899template [[host_name("kernel_mul_mv_ext_iq4_nl_f32_r1_4")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<4, block_iq4_nl, 32, dequantize_iq4_nl_t4>; 900template [[host_name("kernel_mul_mv_ext_iq4_nl_f32_r1_5")]] kernel mul_mv_ext_q4_f32_t kernel_mul_mv_ext_q4_f32_disp<5, block_iq4_nl, 32, dequantize_iq4_nl_t4>; 901 902template [[host_name("kernel_mul_mv_ext_q4_K_f32_r1_2")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<2, block_q4_K, 256, dequantize_q4_K>; 903template [[host_name("kernel_mul_mv_ext_q4_K_f32_r1_3")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<3, block_q4_K, 256, dequantize_q4_K>; 904template [[host_name("kernel_mul_mv_ext_q4_K_f32_r1_4")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<4, block_q4_K, 256, dequantize_q4_K>; 905template [[host_name("kernel_mul_mv_ext_q4_K_f32_r1_5")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<5, block_q4_K, 256, dequantize_q4_K>; 906 907template [[host_name("kernel_mul_mv_ext_q5_K_f32_r1_2")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<2, block_q5_K, 256, dequantize_q5_K>; 908template [[host_name("kernel_mul_mv_ext_q5_K_f32_r1_3")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<3, block_q5_K, 256, dequantize_q5_K>; 909template [[host_name("kernel_mul_mv_ext_q5_K_f32_r1_4")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<4, block_q5_K, 256, dequantize_q5_K>; 910template [[host_name("kernel_mul_mv_ext_q5_K_f32_r1_5")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<5, block_q5_K, 256, dequantize_q5_K>; 911 912template [[host_name("kernel_mul_mv_ext_q6_K_f32_r1_2")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<2, block_q6_K, 256, dequantize_q6_K>; 913template [[host_name("kernel_mul_mv_ext_q6_K_f32_r1_3")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<3, block_q6_K, 256, dequantize_q6_K>; 914template [[host_name("kernel_mul_mv_ext_q6_K_f32_r1_4")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<4, block_q6_K, 256, dequantize_q6_K>; 915template [[host_name("kernel_mul_mv_ext_q6_K_f32_r1_5")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<5, block_q6_K, 256, dequantize_q6_K>; 916 917template [[host_name("kernel_mul_mv_ext_q2_K_f32_r1_2")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<2, block_q2_K, 256, dequantize_q2_K>; 918template [[host_name("kernel_mul_mv_ext_q2_K_f32_r1_3")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<3, block_q2_K, 256, dequantize_q2_K>; 919template [[host_name("kernel_mul_mv_ext_q2_K_f32_r1_4")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<4, block_q2_K, 256, dequantize_q2_K>; 920template [[host_name("kernel_mul_mv_ext_q2_K_f32_r1_5")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<5, block_q2_K, 256, dequantize_q2_K>; 921 922template [[host_name("kernel_mul_mv_ext_q3_K_f32_r1_2")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<2, block_q3_K, 256, dequantize_q3_K>; 923template [[host_name("kernel_mul_mv_ext_q3_K_f32_r1_3")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<3, block_q3_K, 256, dequantize_q3_K>; 924template [[host_name("kernel_mul_mv_ext_q3_K_f32_r1_4")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<4, block_q3_K, 256, dequantize_q3_K>; 925template [[host_name("kernel_mul_mv_ext_q3_K_f32_r1_5")]] kernel mul_mv_ext_q4x4_f32_t kernel_mul_mv_ext_q4x4_f32_disp<5, block_q3_K, 256, dequantize_q3_K>; 926 927template<typename T0, typename T1, short NR0, typename args_t> 928void kernel_mul_mv_t_t_impl( 929 args_t args, 930 device const char * src0, 931 device const char * src1, 932 device char * dst, 933 threadgroup char * shmem, 934 uint3 tgpig, 935 ushort tiisg, 936 ushort sgitg) { 937 const short NSG = FC_mul_mv_nsg; 938 939 constexpr short NW = N_SIMDWIDTH; 940 constexpr short NB = 32; 941 constexpr short NF = 8; 942 943 const int nb = args.ne00/NB; 944 945 const int r0 = tgpig.x*NR0; 946 const int r1 = tgpig.y; 947 const int im = tgpig.z; 948 949 const uint i12 = im%FC_mul_mv_ne12; 950 const uint i13 = im/FC_mul_mv_ne12; 951 952 //const uint64_t offset0 = r0*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 953 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 954 955 //device const T0 * x = (device const T0 *) (src0 + offset0); 956 device const T1 * y = (device const T1 *) (src1 + offset1); 957 958 // pointers to src0 rows 959 device const T0 * ax [NR0]; 960 FOR_UNROLL (short row = 0; row < NR0; ++row) { 961 const uint64_t offset0 = (r0 + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 962 963 ax[row] = (device const T0 *) ((device char *) src0 + offset0); 964 } 965 966 float sumf[NR0] = { 0.f }; 967 968 const short ix = tiisg/(NW/NF); 969 const short il = tiisg%(NW/NF); 970 971 const int ib0 = sgitg*NF + ix; 972 973 T1 yl[NF]; 974 975 device const T1 * yb = y + (ib0*NB + il*NF); 976 977 for (int ib = ib0; ib < nb; ib += NSG*NF) { 978 for (short i = 0; i < NF; ++i) { 979 yl[i] = yb[i]; 980 } 981 982 for (short row = 0; row < NR0; row++) { 983 device const T0 * xb = ax[row] + (ib*NB + il*NF); 984 985 float sumq = 0.f; 986 FOR_UNROLL (short i = 0; i < NF; ++i) { 987 sumq += xb[i] * yl[i]; 988 } 989 990 sumf[row] += sumq; 991 } 992 993 yb += NSG*NF*NW; 994 } 995 996 for (int i = nb*NB + sgitg*NW + tiisg; i < args.ne00; i += NW*NSG) { 997 for (short row = 0; row < NR0; row++) { 998 sumf[row] += ax[row][i] * y[i]; 999 } 1000 } 1001 1002 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1003 1004 helper_mv_reduce_and_write<NR0>(dst_f32, sumf, r0, args.ne01, tiisg, sgitg, shmem); 1005} 1006 1007template<typename T0, typename T1, typename args_t> 1008void kernel_mul_mv_t_t_disp( 1009 args_t args, 1010 device const char * src0, 1011 device const char * src1, 1012 device char * dst, 1013 threadgroup char * shmem, 1014 uint3 tgpig, 1015 ushort tiisg, 1016 ushort sgitg) { 1017 switch (args.nr0) { 1018 //case 1: kernel_mul_mv_t_t_impl<T0, T1, 1, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1019 case 2: kernel_mul_mv_t_t_impl<T0, T1, 2, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1020 //case 3: kernel_mul_mv_t_t_impl<T0, T1, 3, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1021 //case 4: kernel_mul_mv_t_t_impl<T0, T1, 4, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1022 } 1023} 1024 1025template<typename T0, typename T1> 1026kernel void kernel_mul_mv_t_t( 1027 constant ggml_metal_kargs_mul_mv & args, 1028 device const char * src0, 1029 device const char * src1, 1030 device char * dst, 1031 threadgroup char * shmem [[threadgroup(0)]], 1032 uint3 tgpig[[threadgroup_position_in_grid]], 1033 ushort tiisg[[thread_index_in_simdgroup]], 1034 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1035 kernel_mul_mv_t_t_disp<T0, T1, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 1036} 1037 1038typedef decltype(kernel_mul_mv_t_t<half, half>) mul_mv_t_t; 1039 1040template [[host_name("kernel_mul_mv_f32_f32")]] kernel mul_mv_t_t kernel_mul_mv_t_t<float, float>; 1041template [[host_name("kernel_mul_mv_f16_f32")]] kernel mul_mv_t_t kernel_mul_mv_t_t<half, float>; 1042template [[host_name("kernel_mul_mv_f16_f16")]] kernel mul_mv_t_t kernel_mul_mv_t_t<half, half>; 1043#if defined(GGML_METAL_HAS_BF16) 1044template [[host_name("kernel_mul_mv_bf16_f32")]] kernel mul_mv_t_t kernel_mul_mv_t_t<bfloat, float>; 1045template [[host_name("kernel_mul_mv_bf16_bf16")]] kernel mul_mv_t_t kernel_mul_mv_t_t<bfloat, bfloat>; 1046#endif 1047 1048template<typename T0, typename T04, typename T1, typename T14, short NR0, typename args_t> 1049void kernel_mul_mv_t_t_4_impl( 1050 args_t args, 1051 device const char * src0, 1052 device const char * src1, 1053 device char * dst, 1054 threadgroup char * shmem, 1055 uint3 tgpig, 1056 ushort tiisg, 1057 ushort sgitg) { 1058 const short NSG = FC_mul_mv_nsg; 1059 1060 constexpr short NW = N_SIMDWIDTH; 1061 constexpr short NB = 32; 1062 constexpr short NF = 16; 1063 constexpr short NF4 = NF/4; 1064 1065 const int nb = args.ne00/NB; 1066 1067 const int r0 = tgpig.x*NR0; 1068 const int r1 = tgpig.y; 1069 const int im = tgpig.z; 1070 1071 const uint i12 = im%FC_mul_mv_ne12; 1072 const uint i13 = im/FC_mul_mv_ne12; 1073 1074 //const uint64_t offset0 = r0*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1075 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1076 1077 device const T1 * y = (device const T1 *) (src1 + offset1); 1078 device const T14 * y4 = (device const T14 *) (src1 + offset1); 1079 1080 // pointers to src0 rows 1081 device const T0 * ax [NR0]; 1082 device const T04 * ax4[NR0]; 1083 FOR_UNROLL (short row = 0; row < NR0; ++row) { 1084 const uint64_t offset0 = (r0 + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1085 1086 ax [row] = (device const T0 *) ((device char *) src0 + offset0); 1087 ax4[row] = (device const T04 *) ((device char *) src0 + offset0); 1088 } 1089 1090 float sumf[NR0] = { 0.f }; 1091 1092 const short ix = tiisg/(NW/NF); 1093 const short il = tiisg%(NW/NF); 1094 1095 const int ib0 = sgitg*NF + ix; 1096 1097 T14 yl4[NF4]; 1098 1099 device const T14 * yb4 = y4 + (ib0*NB + il*NF)/4; 1100 1101 for (int ib = ib0; ib < nb; ib += NSG*NF) { 1102 for (short i = 0; i < NF4; ++i) { 1103 yl4[i] = yb4[i]; 1104 } 1105 1106 for (short row = 0; row < NR0; row++) { 1107 device const T04 * xb4 = ax4[row] + (ib*NB + il*NF)/4; 1108 1109 float sumq = 0.f; 1110 FOR_UNROLL (short i = 0; i < NF4; ++i) { 1111 sumq += dot(float4(xb4[i]), float4(yl4[i])); 1112 } 1113 1114 sumf[row] += sumq; 1115 } 1116 1117 yb4 += NSG*NF*NW/4; 1118 } 1119 1120 for (int i = nb*NB + sgitg*NW + tiisg; i < args.ne00; i += NW*NSG) { 1121 for (short row = 0; row < NR0; row++) { 1122 sumf[row] += ax[row][i] * y[i]; 1123 } 1124 } 1125 1126 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1127 1128 helper_mv_reduce_and_write<NR0>(dst_f32, sumf, r0, args.ne01, tiisg, sgitg, shmem); 1129} 1130 1131template<typename T0, typename T04, typename T1, typename T14, typename args_t> 1132void kernel_mul_mv_t_t_4_disp( 1133 args_t args, 1134 device const char * src0, 1135 device const char * src1, 1136 device char * dst, 1137 threadgroup char * shmem, 1138 uint3 tgpig, 1139 ushort tiisg, 1140 ushort sgitg) { 1141 switch (args.nr0) { 1142 //case 1: kernel_mul_mv_t_t_4_impl<T0, T04, T1, T14, 1, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1143 case 2: kernel_mul_mv_t_t_4_impl<T0, T04, T1, T14, 2, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1144 //case 3: kernel_mul_mv_t_t_4_impl<T0, T04, T1, T14, 3, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1145 //case 4: kernel_mul_mv_t_t_4_impl<T0, T04, T1, T14, 4, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); break; 1146 }; 1147} 1148 1149template<typename T0, typename T04, typename T1, typename T14> 1150kernel void kernel_mul_mv_t_t_4( 1151 constant ggml_metal_kargs_mul_mv & args, 1152 device const char * src0, 1153 device const char * src1, 1154 device char * dst, 1155 threadgroup char * shmem [[threadgroup(0)]], 1156 uint3 tgpig[[threadgroup_position_in_grid]], 1157 ushort tiisg[[thread_index_in_simdgroup]], 1158 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1159 kernel_mul_mv_t_t_4_disp<T0, T04, T1, T14, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 1160} 1161 1162typedef decltype(kernel_mul_mv_t_t_4<half, half4, half, half4>) mul_mv_t_t_4; 1163 1164template [[host_name("kernel_mul_mv_f32_f32_4")]] kernel mul_mv_t_t_4 kernel_mul_mv_t_t_4<float, float4, float, float4>; 1165template [[host_name("kernel_mul_mv_f16_f32_4")]] kernel mul_mv_t_t_4 kernel_mul_mv_t_t_4<half, half4, float, float4>; 1166template [[host_name("kernel_mul_mv_f16_f16_4")]] kernel mul_mv_t_t_4 kernel_mul_mv_t_t_4<half, half4, half, half4>; 1167#if defined(GGML_METAL_HAS_BF16) 1168template [[host_name("kernel_mul_mv_bf16_f32_4")]] kernel mul_mv_t_t_4 kernel_mul_mv_t_t_4<bfloat, bfloat4, float, float4>; 1169template [[host_name("kernel_mul_mv_bf16_bf16_4")]] kernel mul_mv_t_t_4 kernel_mul_mv_t_t_4<bfloat, bfloat4, bfloat, bfloat4>; 1170#endif 1171 1172template<typename T0, typename T1, typename args_t> 1173void kernel_mul_mv_t_t_short_impl( 1174 args_t args, 1175 device const char * src0, 1176 device const char * src1, 1177 device char * dst, 1178 uint3 tgpig, 1179 ushort tiisg) { 1180 const int r0 = tgpig.x*32 + tiisg; 1181 const int r1 = tgpig.y; 1182 const int im = tgpig.z; 1183 1184 if (r0 >= args.ne01) { 1185 return; 1186 } 1187 1188 const uint i12 = im%FC_mul_mv_ne12; 1189 const uint i13 = im/FC_mul_mv_ne12; 1190 1191 const uint64_t offset0 = r0*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1192 1193 device const T0 * x = (device const T0 *) (src0 + offset0); 1194 1195 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1; 1196 1197 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1198 1199 device const T1 * y = (device const T1 *) (src1 + offset1); 1200 1201 float res = 0.0f; 1202 1203 for (int i = 0; i < args.ne00; ++i) { 1204 res += (float) x[i] * (float) y[i]; 1205 } 1206 1207 dst_f32[(uint64_t)r1*args.ne0 + r0] = res; 1208} 1209 1210template<typename T0, typename T1> 1211kernel void kernel_mul_mv_t_t_short( 1212 constant ggml_metal_kargs_mul_mv & args, 1213 device const char * src0, 1214 device const char * src1, 1215 device char * dst, 1216 uint3 tgpig[[threadgroup_position_in_grid]], 1217 ushort tiisg[[thread_index_in_simdgroup]]) { 1218 kernel_mul_mv_t_t_short_impl<T0, T1, constant ggml_metal_kargs_mul_mv &>( 1219 args, 1220 src0, 1221 src1, 1222 dst, 1223 tgpig, 1224 tiisg); 1225} 1226 1227typedef decltype(kernel_mul_mv_t_t_short<half, half>) mul_mv_t_t_short_t; 1228 1229template [[host_name("kernel_mul_mv_f32_f32_short")]] kernel mul_mv_t_t_short_t kernel_mul_mv_t_t_short<float, float>; 1230template [[host_name("kernel_mul_mv_f16_f32_short")]] kernel mul_mv_t_t_short_t kernel_mul_mv_t_t_short<half, float>; 1231template [[host_name("kernel_mul_mv_f16_f16_short")]] kernel mul_mv_t_t_short_t kernel_mul_mv_t_t_short<half, half>; 1232#if defined(GGML_METAL_HAS_BF16) 1233template [[host_name("kernel_mul_mv_bf16_f32_short")]] kernel mul_mv_t_t_short_t kernel_mul_mv_t_t_short<bfloat, float>; 1234template [[host_name("kernel_mul_mv_bf16_bf16_short")]] kernel mul_mv_t_t_short_t kernel_mul_mv_t_t_short<bfloat, bfloat>; 1235#endif 1236 1237template<int nr0, typename args_t> 1238void kernel_mul_mv_q2_K_f32_impl( 1239 args_t args, 1240 device const char * src0, 1241 device const char * src1, 1242 device char * dst, 1243 threadgroup char * shmem, 1244 uint3 tgpig, 1245 ushort tiisg, 1246 ushort sgitg) { 1247 const short NSG = FC_mul_mv_nsg; 1248 1249 const int nb = args.ne00/QK_K; 1250 1251 const int r0 = tgpig.x; 1252 const int r1 = tgpig.y; 1253 const int im = tgpig.z; 1254 1255 const int first_row = (r0 * NSG + sgitg) * nr0; 1256 1257 const uint i12 = im%FC_mul_mv_ne12; 1258 const uint i13 = im/FC_mul_mv_ne12; 1259 1260 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1261 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1262 1263 device const block_q2_K * x = (device const block_q2_K *) (src0 + offset0); 1264 device const float * y = (device const float *) (src1 + offset1); 1265 1266 float yl[32]; 1267 float sumf[nr0]={0.f}; 1268 1269 const short ix = tiisg/8; // 0...3 1270 const short it = tiisg%8; // 0...7 1271 const short iq = it/4; // 0 or 1 1272 const short ir = it%4; // 0...3 1273 const short is = (8*ir)/16;// 0 or 1 1274 1275 device const float * y4 = y + ix * QK_K + 128 * iq + 8 * ir; 1276 1277 for (int ib = ix; ib < nb; ib += 4) { 1278 float4 sumy = {0.f, 0.f, 0.f, 0.f}; 1279 for (short i = 0; i < 8; ++i) { 1280 yl[i+ 0] = y4[i+ 0]; sumy[0] += yl[i+ 0]; 1281 yl[i+ 8] = y4[i+32]; sumy[1] += yl[i+ 8]; 1282 yl[i+16] = y4[i+64]; sumy[2] += yl[i+16]; 1283 yl[i+24] = y4[i+96]; sumy[3] += yl[i+24]; 1284 } 1285 1286 device const uint8_t * sc = (device const uint8_t *)x[ib].scales + 8*iq + is; 1287 device const uint16_t * qs = (device const uint16_t *)x[ib].qs + 16 * iq + 4 * ir; 1288 device const half * dh = &x[ib].d; 1289 1290 for (short row = 0; row < nr0; row++) { 1291 float4 acc1 = {0.f, 0.f, 0.f, 0.f}; 1292 float4 acc2 = {0.f, 0.f, 0.f, 0.f}; 1293 for (int i = 0; i < 8; i += 2) { 1294 acc1[0] += yl[i+ 0] * (qs[i/2] & 0x0003); 1295 acc2[0] += yl[i+ 1] * (qs[i/2] & 0x0300); 1296 acc1[1] += yl[i+ 8] * (qs[i/2] & 0x000c); 1297 acc2[1] += yl[i+ 9] * (qs[i/2] & 0x0c00); 1298 acc1[2] += yl[i+16] * (qs[i/2] & 0x0030); 1299 acc2[2] += yl[i+17] * (qs[i/2] & 0x3000); 1300 acc1[3] += yl[i+24] * (qs[i/2] & 0x00c0); 1301 acc2[3] += yl[i+25] * (qs[i/2] & 0xc000); 1302 } 1303 float dall = dh[0]; 1304 float dmin = dh[1] * 1.f/16.f; 1305 sumf[row] += dall * ((acc1[0] + 1.f/256.f * acc2[0]) * (sc[0] & 0xF) * 1.f/ 1.f + 1306 (acc1[1] + 1.f/256.f * acc2[1]) * (sc[2] & 0xF) * 1.f/ 4.f + 1307 (acc1[2] + 1.f/256.f * acc2[2]) * (sc[4] & 0xF) * 1.f/16.f + 1308 (acc1[3] + 1.f/256.f * acc2[3]) * (sc[6] & 0xF) * 1.f/64.f) - 1309 dmin * (sumy[0] * (sc[0] & 0xF0) + sumy[1] * (sc[2] & 0xF0) + sumy[2] * (sc[4] & 0xF0) + sumy[3] * (sc[6] & 0xF0)); 1310 1311 qs += args.nb01/2; 1312 sc += args.nb01; 1313 dh += args.nb01/2; 1314 } 1315 1316 y4 += 4 * QK_K; 1317 } 1318 1319 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1320 1321 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1322 float sum_all = simd_sum(sumf[row]); 1323 if (tiisg == 0) { 1324 dst_f32[first_row + row] = sum_all; 1325 } 1326 } 1327} 1328 1329[[host_name("kernel_mul_mv_q2_K_f32")]] 1330kernel void kernel_mul_mv_q2_K_f32( 1331 constant ggml_metal_kargs_mul_mv & args, 1332 device const char * src0, 1333 device const char * src1, 1334 device char * dst, 1335 uint3 tgpig[[threadgroup_position_in_grid]], 1336 ushort tiisg[[thread_index_in_simdgroup]], 1337 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1338 1339 kernel_mul_mv_q2_K_f32_impl<N_R0_Q2_K, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 1340} 1341 1342template<int nr0, typename args_t> 1343void kernel_mul_mv_q3_K_f32_impl( 1344 args_t args, 1345 device const char * src0, 1346 device const char * src1, 1347 device char * dst, 1348 threadgroup char * shmem, 1349 uint3 tgpig, 1350 ushort tiisg, 1351 ushort sgitg) { 1352 const short NSG = FC_mul_mv_nsg; 1353 1354 const int nb = args.ne00/QK_K; 1355 1356 const int r0 = tgpig.x; 1357 const int r1 = tgpig.y; 1358 const int im = tgpig.z; 1359 1360 const int first_row = (r0 * NSG + sgitg) * nr0; 1361 1362 const uint i12 = im%FC_mul_mv_ne12; 1363 const uint i13 = im/FC_mul_mv_ne12; 1364 1365 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1366 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1367 1368 device const block_q3_K * x = (device const block_q3_K *) (src0 + offset0); 1369 device const float * yy = (device const float *) (src1 + offset1); 1370 1371 float yl[32]; 1372 1373 //const uint16_t kmask1 = 0x3030; 1374 //const uint16_t kmask2 = 0x0f0f; 1375 1376 const short tid = tiisg/4; 1377 const short ix = tiisg%4; 1378 const short ip = tid/4; // 0 or 1 1379 const short il = 2*((tid%4)/2); // 0 or 2 1380 const short ir = tid%2; 1381 const short l0 = 8*ir; 1382 1383 // One would think that the Metal compiler would figure out that ip and il can only have 1384 // 4 possible states, and optimize accordingly. Well, no. It needs help, and we do it 1385 // with these two tales. 1386 // 1387 // Possible masks for the high bit 1388 const ushort4 mm[4] = {{0x0001, 0x0100, 0x0002, 0x0200}, // ip = 0, il = 0 1389 {0x0004, 0x0400, 0x0008, 0x0800}, // ip = 0, il = 2 1390 {0x0010, 0x1000, 0x0020, 0x2000}, // ip = 1, il = 0 1391 {0x0040, 0x4000, 0x0080, 0x8000}}; // ip = 1, il = 2 1392 1393 // Possible masks for the low 2 bits 1394 const int4 qm[2] = {{0x0003, 0x0300, 0x000c, 0x0c00}, {0x0030, 0x3000, 0x00c0, 0xc000}}; 1395 1396 const ushort4 hm = mm[2*ip + il/2]; 1397 1398 const short shift = 2*il; 1399 1400 const float v1 = il == 0 ? 4.f : 64.f; 1401 const float v2 = 4.f * v1; 1402 1403 const uint16_t s_shift1 = 4*ip; 1404 const uint16_t s_shift2 = s_shift1 + il; 1405 1406 const short q_offset = 32*ip + l0; 1407 const short y_offset = 128*ip + 32*il + l0; 1408 1409 device const float * y1 = yy + ix*QK_K + y_offset; 1410 1411 uint32_t scales32, aux32; 1412 thread uint16_t * scales16 = (thread uint16_t *)&scales32; 1413 thread const int8_t * scales = (thread const int8_t *)&scales32; 1414 1415 float sumf1[nr0] = {0.f}; 1416 float sumf2[nr0] = {0.f}; 1417 1418 for (int i = ix; i < nb; i += 4) { 1419 for (short l = 0; l < 8; ++l) { 1420 yl[l+ 0] = y1[l+ 0]; 1421 yl[l+ 8] = y1[l+16]; 1422 yl[l+16] = y1[l+32]; 1423 yl[l+24] = y1[l+48]; 1424 } 1425 1426 device const uint16_t * q = (device const uint16_t *)(x[i].qs + q_offset); 1427 device const uint16_t * h = (device const uint16_t *)(x[i].hmask + l0); 1428 device const uint16_t * a = (device const uint16_t *)(x[i].scales); 1429 device const half * dh = &x[i].d; 1430 1431 for (short row = 0; row < nr0; ++row) { 1432 const float d_all = (float)dh[0]; 1433 1434 scales16[0] = a[4]; 1435 scales16[1] = a[5]; 1436 aux32 = ((scales32 >> s_shift2) << 4) & 0x30303030; 1437 scales16[0] = a[il+0]; 1438 scales16[1] = a[il+1]; 1439 scales32 = ((scales32 >> s_shift1) & 0x0f0f0f0f) | aux32; 1440 1441 float s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0, s6 = 0; 1442 for (short l = 0; l < 8; l += 2) { 1443 const int32_t qs = q[l/2]; 1444 s1 += yl[l+0] * (qs & qm[il/2][0]); 1445 s2 += yl[l+1] * (qs & qm[il/2][1]); 1446 s3 += ((h[l/2] & hm[0]) ? 0.f : yl[l+0]) + ((h[l/2] & hm[1]) ? 0.f : yl[l+1]); 1447 s4 += yl[l+16] * (qs & qm[il/2][2]); 1448 s5 += yl[l+17] * (qs & qm[il/2][3]); 1449 s6 += ((h[l/2] & hm[2]) ? 0.f : yl[l+16]) + ((h[l/2] & hm[3]) ? 0.f : yl[l+17]); 1450 } 1451 float d1 = d_all * (s1 + 1.f/256.f * s2 - s3*v1); 1452 float d2 = d_all * (s4 + 1.f/256.f * s5 - s6*v2); 1453 sumf1[row] += d1 * (scales[0] - 32); 1454 sumf2[row] += d2 * (scales[2] - 32); 1455 1456 s1 = s2 = s3 = s4 = s5 = s6 = 0; 1457 for (short l = 0; l < 8; l += 2) { 1458 const int32_t qs = q[l/2+8]; 1459 s1 += yl[l+8] * (qs & qm[il/2][0]); 1460 s2 += yl[l+9] * (qs & qm[il/2][1]); 1461 s3 += ((h[l/2+8] & hm[0]) ? 0.f : yl[l+8]) + ((h[l/2+8] & hm[1]) ? 0.f : yl[l+9]); 1462 s4 += yl[l+24] * (qs & qm[il/2][2]); 1463 s5 += yl[l+25] * (qs & qm[il/2][3]); 1464 s6 += ((h[l/2+8] & hm[2]) ? 0.f : yl[l+24]) + ((h[l/2+8] & hm[3]) ? 0.f : yl[l+25]); 1465 } 1466 d1 = d_all * (s1 + 1.f/256.f * s2 - s3*v1); 1467 d2 = d_all * (s4 + 1.f/256.f * s5 - s6*v2); 1468 sumf1[row] += d1 * (scales[1] - 32); 1469 sumf2[row] += d2 * (scales[3] - 32); 1470 1471 q += args.nb01/2; 1472 h += args.nb01/2; 1473 a += args.nb01/2; 1474 dh += args.nb01/2; 1475 } 1476 1477 y1 += 4 * QK_K; 1478 } 1479 1480 for (int row = 0; row < nr0; ++row) { 1481 const float sumf = (sumf1[row] + 0.25f * sumf2[row]) / (1 << shift); 1482 sumf1[row] = simd_sum(sumf); 1483 } 1484 1485 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1486 1487 if (tiisg == 0) { 1488 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1489 dst_f32[first_row + row] = sumf1[row]; 1490 } 1491 } 1492} 1493 1494[[host_name("kernel_mul_mv_q3_K_f32")]] 1495kernel void kernel_mul_mv_q3_K_f32( 1496 constant ggml_metal_kargs_mul_mv & args, 1497 device const char * src0, 1498 device const char * src1, 1499 device char * dst, 1500 uint3 tgpig[[threadgroup_position_in_grid]], 1501 ushort tiisg[[thread_index_in_simdgroup]], 1502 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1503 1504 kernel_mul_mv_q3_K_f32_impl<N_R0_Q3_K, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 1505} 1506 1507template<int nr0, typename args_t> 1508void kernel_mul_mv_q4_K_f32_impl( 1509 args_t args, 1510 device const char * src0, 1511 device const char * src1, 1512 device char * dst, 1513 threadgroup char * shmem, 1514 uint3 tgpig, 1515 ushort tiisg, 1516 ushort sgitg) { 1517 const short NSG = FC_mul_mv_nsg; 1518 1519 constexpr uint16_t kmask1 = 0x3f3f; 1520 constexpr uint16_t kmask2 = 0x0f0f; 1521 constexpr uint16_t kmask3 = 0xc0c0; 1522 1523 const short ix = tiisg/8; // 0...3 1524 const short it = tiisg%8; // 0...7 1525 const short iq = it/4; // 0 or 1 1526 const short ir = it%4; // 0...3 1527 1528 const int nb = args.ne00/QK_K; 1529 1530 const int r0 = tgpig.x; 1531 const int r1 = tgpig.y; 1532 const int im = tgpig.z; 1533 1534 const int first_row = (r0 * NSG + sgitg) * nr0; 1535 1536 const uint i12 = im%FC_mul_mv_ne12; 1537 const uint i13 = im/FC_mul_mv_ne12; 1538 1539 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1540 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1541 1542 device const block_q4_K * x = (device const block_q4_K *) (src0 + offset0); 1543 device const float * y = (device const float *) (src1 + offset1); 1544 1545 float yl[16]; 1546 float yh[16]; 1547 1548 float sumf[nr0]={0.f}; 1549 1550 device const float * y4 = y + ix * QK_K + 64 * iq + 8 * ir; 1551 1552 uint16_t sc16[4]; 1553 thread const uint8_t * sc8 = (thread const uint8_t *)sc16; 1554 1555 for (int ib = ix; ib < nb; ib += 4) { 1556 float4 sumy = {0.f, 0.f, 0.f, 0.f}; 1557 1558 for (short i = 0; i < 8; ++i) { 1559 yl[i+0] = y4[i+ 0]; sumy[0] += yl[i+0]; 1560 yl[i+8] = y4[i+ 32]; sumy[1] += yl[i+8]; 1561 yh[i+0] = y4[i+128]; sumy[2] += yh[i+0]; 1562 yh[i+8] = y4[i+160]; sumy[3] += yh[i+8]; 1563 } 1564 1565 device const uint16_t * sc = (device const uint16_t *)x[ib].scales + iq; 1566 device const uint16_t * q1 = (device const uint16_t *)x[ib].qs + 16 * iq + 4 * ir; 1567 device const half * dh = &x[ib].d; 1568 1569 for (short row = 0; row < nr0; row++) { 1570 sc16[0] = sc[0] & kmask1; 1571 sc16[1] = sc[2] & kmask1; 1572 sc16[2] = ((sc[4] >> 0) & kmask2) | ((sc[0] & kmask3) >> 2); 1573 sc16[3] = ((sc[4] >> 4) & kmask2) | ((sc[2] & kmask3) >> 2); 1574 1575 device const uint16_t * q2 = q1 + 32; 1576 1577 float4 acc1 = {0.f, 0.f, 0.f, 0.f}; 1578 float4 acc2 = {0.f, 0.f, 0.f, 0.f}; 1579 1580 FOR_UNROLL (short i = 0; i < 4; ++i) { 1581 acc1[0] += yl[2*i + 0] * (q1[i] & 0x000F); 1582 acc1[1] += yl[2*i + 1] * (q1[i] & 0x0F00); 1583 acc1[2] += yl[2*i + 8] * (q1[i] & 0x00F0); 1584 acc1[3] += yl[2*i + 9] * (q1[i] & 0xF000); 1585 acc2[0] += yh[2*i + 0] * (q2[i] & 0x000F); 1586 acc2[1] += yh[2*i + 1] * (q2[i] & 0x0F00); 1587 acc2[2] += yh[2*i + 8] * (q2[i] & 0x00F0); 1588 acc2[3] += yh[2*i + 9] * (q2[i] & 0xF000); 1589 } 1590 1591 sumf[row] += dh[0] * ((acc1[0] + 1.f/256.f * acc1[1]) * sc8[0] + 1592 (acc1[2] + 1.f/256.f * acc1[3]) * sc8[1] * 1.f/16.f + 1593 (acc2[0] + 1.f/256.f * acc2[1]) * sc8[4] + 1594 (acc2[2] + 1.f/256.f * acc2[3]) * sc8[5] * 1.f/16.f) - 1595 dh[1] * (sumy[0] * sc8[2] + sumy[1] * sc8[3] + sumy[2] * sc8[6] + sumy[3] * sc8[7]); 1596 1597 q1 += args.nb01/2; 1598 sc += args.nb01/2; 1599 dh += args.nb01/2; 1600 } 1601 1602 y4 += 4 * QK_K; 1603 } 1604 1605 device float * dst_f32 = (device float *) dst + (int64_t)im*args.ne0*args.ne1 + (int64_t)r1*args.ne0; 1606 1607 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1608 float sum_all = simd_sum(sumf[row]); 1609 if (tiisg == 0) { 1610 dst_f32[first_row + row] = sum_all; 1611 } 1612 } 1613} 1614 1615[[host_name("kernel_mul_mv_q4_K_f32")]] 1616kernel void kernel_mul_mv_q4_K_f32( 1617 constant ggml_metal_kargs_mul_mv & args, 1618 device const char * src0, 1619 device const char * src1, 1620 device char * dst, 1621 uint3 tgpig[[threadgroup_position_in_grid]], 1622 ushort tiisg[[thread_index_in_simdgroup]], 1623 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1624 1625 kernel_mul_mv_q4_K_f32_impl<N_R0_Q4_K, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 1626} 1627 1628template<int nr0, typename args_t> 1629void kernel_mul_mv_q5_K_f32_impl( 1630 args_t args, 1631 device const char * src0, 1632 device const char * src1, 1633 device char * dst, 1634 threadgroup char * shmem, 1635 uint3 tgpig, 1636 ushort tiisg, 1637 ushort sgitg) { 1638 const short NSG = FC_mul_mv_nsg; 1639 1640 const int nb = args.ne00/QK_K; 1641 1642 const int r0 = tgpig.x; 1643 const int r1 = tgpig.y; 1644 const int im = tgpig.z; 1645 1646 const int first_row = (r0 * NSG + sgitg) * nr0; 1647 1648 const uint i12 = im%FC_mul_mv_ne12; 1649 const uint i13 = im/FC_mul_mv_ne12; 1650 1651 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1652 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1653 1654 device const block_q5_K * x = (device const block_q5_K *) (src0 + offset0); 1655 device const float * yy = (device const float *) (src1 + offset1); 1656 1657 float sumf[nr0]={0.f}; 1658 1659 float yl[16], yh[16]; 1660 1661 constexpr uint16_t kmask1 = 0x3f3f; 1662 constexpr uint16_t kmask2 = 0x0f0f; 1663 constexpr uint16_t kmask3 = 0xc0c0; 1664 1665 const short tid = tiisg/4; 1666 const short ix = tiisg%4; 1667 const short iq = tid/4; 1668 const short ir = tid%4; 1669 1670 const short l0 = 8*ir; 1671 const short q_offset = 32*iq + l0; 1672 const short y_offset = 64*iq + l0; 1673 1674 const uint8_t hm1 = 1u << (2*iq); 1675 const uint8_t hm2 = hm1 << 1; 1676 const uint8_t hm3 = hm1 << 4; 1677 const uint8_t hm4 = hm2 << 4; 1678 1679 uint16_t sc16[4]; 1680 thread const uint8_t * sc8 = (thread const uint8_t *)sc16; 1681 1682 device const float * y1 = yy + ix*QK_K + y_offset; 1683 1684 for (int i = ix; i < nb; i += 4) { 1685 device const uint8_t * q1 = x[i].qs + q_offset; 1686 device const uint8_t * qh = x[i].qh + l0; 1687 device const half * dh = &x[i].d; 1688 device const uint16_t * a = (device const uint16_t *)x[i].scales + iq; 1689 1690 device const float * y2 = y1 + 128; 1691 float4 sumy = {0.f, 0.f, 0.f, 0.f}; 1692 for (short l = 0; l < 8; ++l) { 1693 yl[l+0] = y1[l+ 0]; sumy[0] += yl[l+0]; 1694 yl[l+8] = y1[l+32]; sumy[1] += yl[l+8]; 1695 yh[l+0] = y2[l+ 0]; sumy[2] += yh[l+0]; 1696 yh[l+8] = y2[l+32]; sumy[3] += yh[l+8]; 1697 } 1698 1699 for (short row = 0; row < nr0; ++row) { 1700 device const uint8_t * q2 = q1 + 64; 1701 1702 sc16[0] = a[0] & kmask1; 1703 sc16[1] = a[2] & kmask1; 1704 sc16[2] = ((a[4] >> 0) & kmask2) | ((a[0] & kmask3) >> 2); 1705 sc16[3] = ((a[4] >> 4) & kmask2) | ((a[2] & kmask3) >> 2); 1706 1707 float4 acc1 = {0.f}; 1708 float4 acc2 = {0.f}; 1709 FOR_UNROLL (short l = 0; l < 8; ++l) { 1710 uint8_t h = qh[l]; 1711 acc1[0] += yl[l+0] * (q1[l] & 0x0F); 1712 acc1[1] += yl[l+8] * (q1[l] & 0xF0); 1713 acc1[2] += yh[l+0] * (q2[l] & 0x0F); 1714 acc1[3] += yh[l+8] * (q2[l] & 0xF0); 1715 acc2[0] += h & hm1 ? yl[l+0] : 0.f; 1716 acc2[1] += h & hm2 ? yl[l+8] : 0.f; 1717 acc2[2] += h & hm3 ? yh[l+0] : 0.f; 1718 acc2[3] += h & hm4 ? yh[l+8] : 0.f; 1719 } 1720 1721 sumf[row] += dh[0] * (sc8[0] * (acc1[0] + 16.f*acc2[0]) + 1722 sc8[1] * (acc1[1]/16.f + 16.f*acc2[1]) + 1723 sc8[4] * (acc1[2] + 16.f*acc2[2]) + 1724 sc8[5] * (acc1[3]/16.f + 16.f*acc2[3])) - 1725 dh[1] * (sumy[0] * sc8[2] + sumy[1] * sc8[3] + sumy[2] * sc8[6] + sumy[3] * sc8[7]); 1726 1727 q1 += args.nb01; 1728 qh += args.nb01; 1729 dh += args.nb01/2; 1730 a += args.nb01/2; 1731 } 1732 1733 y1 += 4 * QK_K; 1734 } 1735 1736 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1737 1738 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1739 const float tot = simd_sum(sumf[row]); 1740 if (tiisg == 0) { 1741 dst_f32[first_row + row] = tot; 1742 } 1743 } 1744} 1745 1746[[host_name("kernel_mul_mv_q5_K_f32")]] 1747kernel void kernel_mul_mv_q5_K_f32( 1748 constant ggml_metal_kargs_mul_mv & args, 1749 device const char * src0, 1750 device const char * src1, 1751 device char * dst, 1752 uint3 tgpig[[threadgroup_position_in_grid]], 1753 ushort tiisg[[thread_index_in_simdgroup]], 1754 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1755 1756 kernel_mul_mv_q5_K_f32_impl<N_R0_Q5_K, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 1757} 1758 1759template<int nr0, typename args_t> 1760void kernel_mul_mv_q6_K_f32_impl( 1761 args_t args, 1762 device const char * src0, 1763 device const char * src1, 1764 device char * dst, 1765 threadgroup char * shmem, 1766 uint3 tgpig, 1767 ushort tiisg, 1768 ushort sgitg) { 1769 const short NSG = FC_mul_mv_nsg; 1770 1771 constexpr uint8_t kmask1 = 0x03; 1772 constexpr uint8_t kmask2 = 0x0C; 1773 constexpr uint8_t kmask3 = 0x30; 1774 constexpr uint8_t kmask4 = 0xC0; 1775 1776 const int nb = args.ne00/QK_K; 1777 1778 const int r0 = tgpig.x; 1779 const int r1 = tgpig.y; 1780 const int im = tgpig.z; 1781 1782 const int first_row = (r0 * NSG + sgitg) * nr0; 1783 1784 const uint i12 = im%FC_mul_mv_ne12; 1785 const uint i13 = im/FC_mul_mv_ne12; 1786 1787 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1788 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1789 1790 device const block_q6_K * x = (device const block_q6_K *) (src0 + offset0); 1791 device const float * yy = (device const float *) (src1 + offset1); 1792 1793 float sumf[nr0] = { 0.f }; 1794 1795 float yl[16]; 1796 1797 const short tid = tiisg/2; 1798 const short ix = tiisg%2; 1799 const short ip = tid/8; // 0 or 1 1800 const short il = tid%8; 1801 const short l0 = 4*il; 1802 const short is = 8*ip + l0/16; 1803 1804 const short y_offset = 128*ip + l0; 1805 const short q_offset_l = 64*ip + l0; 1806 const short q_offset_h = 32*ip + l0; 1807 1808 for (int i = ix; i < nb; i += 2) { 1809 device const uint8_t * q1 = x[i].ql + q_offset_l; 1810 device const uint8_t * q2 = q1 + 32; 1811 device const uint8_t * qh = x[i].qh + q_offset_h; 1812 device const int8_t * sc = x[i].scales + is; 1813 device const half * dh = &x[i].d; 1814 1815 device const float * y = yy + i * QK_K + y_offset; 1816 1817 for (short l = 0; l < 4; ++l) { 1818 yl[4*l + 0] = y[l + 0]; 1819 yl[4*l + 1] = y[l + 32]; 1820 yl[4*l + 2] = y[l + 64]; 1821 yl[4*l + 3] = y[l + 96]; 1822 } 1823 1824 for (short row = 0; row < nr0; ++row) { 1825 float4 sums = {0.f, 0.f, 0.f, 0.f}; 1826 1827 FOR_UNROLL (short l = 0; l < 4; ++l) { 1828 sums[0] += yl[4*l + 0] * ((int8_t)((q1[l] & 0xF) | ((qh[l] & kmask1) << 4)) - 32); 1829 sums[1] += yl[4*l + 1] * ((int8_t)((q2[l] & 0xF) | ((qh[l] & kmask2) << 2)) - 32); 1830 sums[2] += yl[4*l + 2] * ((int8_t)((q1[l] >> 4) | ((qh[l] & kmask3) << 0)) - 32); 1831 sums[3] += yl[4*l + 3] * ((int8_t)((q2[l] >> 4) | ((qh[l] & kmask4) >> 2)) - 32); 1832 } 1833 1834 sumf[row] += dh[0] * (sums[0] * sc[0] + sums[1] * sc[2] + sums[2] * sc[4] + sums[3] * sc[6]); 1835 1836 q1 += args.nb01; 1837 q2 += args.nb01; 1838 qh += args.nb01; 1839 sc += args.nb01; 1840 dh += args.nb01/2; 1841 } 1842 } 1843 1844 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1845 1846 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1847 float sum_all = simd_sum(sumf[row]); 1848 if (tiisg == 0) { 1849 dst_f32[first_row + row] = sum_all; 1850 } 1851 } 1852} 1853 1854[[host_name("kernel_mul_mv_q6_K_f32")]] 1855kernel void kernel_mul_mv_q6_K_f32( 1856 constant ggml_metal_kargs_mul_mv & args, 1857 device const char * src0, 1858 device const char * src1, 1859 device char * dst, 1860 uint3 tgpig[[threadgroup_position_in_grid]], 1861 ushort tiisg[[thread_index_in_simdgroup]], 1862 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1863 1864 kernel_mul_mv_q6_K_f32_impl<N_R0_Q6_K, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 1865} 1866 1867// ======================= "True" 2-bit 1868 1869template<int nr0, typename args_t> 1870void kernel_mul_mv_iq2_xxs_f32_impl( 1871 args_t args, 1872 device const char * src0, 1873 device const char * src1, 1874 device char * dst, 1875 threadgroup char * shmem, 1876 uint3 tgpig, 1877 ushort tiisg, 1878 ushort sgitg) { 1879 const short NSG = FC_mul_mv_nsg; 1880 1881 const int nb = args.ne00/QK_K; 1882 1883 const int r0 = tgpig.x; 1884 const int r1 = tgpig.y; 1885 const int im = tgpig.z; 1886 1887 const int first_row = (r0 * NSG + sgitg) * nr0; 1888 1889 const uint i12 = im%FC_mul_mv_ne12; 1890 const uint i13 = im/FC_mul_mv_ne12; 1891 1892 const int nb32 = nb * (QK_K / 32); 1893 1894 const short ntx = FC_mul_mv_split ? nb32 : 32; 1895 const short nrep = 32 / ntx; 1896 1897 const short ix = tiisg % ntx; 1898 const short irep = tiisg / ntx; 1899 1900 const short row0 = (nr0 * irep ) / nrep; 1901 const short row1 = (nr0 * (irep + 1)) / nrep; 1902 1903 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 1904 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 1905 1906 device const block_iq2_xxs * x = (device const block_iq2_xxs *) (src0 + offset0); 1907 device const float * y = (device const float *) (src1 + offset1); 1908 1909 float yl[32]; 1910 float sumf[nr0]={0.f}; 1911 1912 threadgroup uint64_t * svalues = (threadgroup uint64_t *)(shmem); 1913 threadgroup uint8_t * ssigns = (threadgroup uint8_t *)(svalues + 256); 1914 { 1915 int nval = 4; 1916 int pos = (32*sgitg + tiisg)*nval; 1917 for (int i = 0; i < nval; ++i) svalues[pos + i] = iq2xxs_grid[pos + i]; 1918 nval = 2; 1919 pos = (32*sgitg + tiisg)*nval; 1920 for (int i = 0; i < nval; ++i) ssigns[pos+i] = ksigns_iq2xs[pos+i]; 1921 threadgroup_barrier(mem_flags::mem_threadgroup); 1922 } 1923 1924 device const float * y4 = y + 32 * ix; 1925 1926 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 1927 for (short i = 0; i < 32; ++i) { 1928 yl[i] = y4[i]; 1929 } 1930 1931 const int ibl = ib32 / (QK_K / 32); 1932 const int ib = ib32 % (QK_K / 32); 1933 1934 device const block_iq2_xxs * xr = x + ibl; 1935 device const uint16_t * q2 = xr->qs + 4 * ib; 1936 device const half * dh = &xr->d; 1937 1938 for (short row = row0; row < row1; row++) { 1939 const float db = dh[0]; 1940 device const uint8_t * aux8 = (device const uint8_t *)q2; 1941 const uint32_t aux32 = q2[2] | (q2[3] << 16); 1942 const float d = db * (0.5f + (aux32 >> 28)); 1943 1944 float sum = 0; 1945 for (short l = 0; l < 4; ++l) { 1946 const threadgroup uint8_t * grid = (const threadgroup uint8_t *)(svalues + aux8[l]); 1947 const uint8_t signs = ssigns[(aux32 >> 7*l) & 127]; 1948 for (short j = 0; j < 8; ++j) { 1949 sum += yl[8*l + j] * grid[j] * (signs & kmask_iq2xs[j] ? -1.f : 1.f); 1950 } 1951 } 1952 sumf[row] += d * sum; 1953 1954 dh += args.nb01/2; 1955 q2 += args.nb01/2; 1956 } 1957 1958 y4 += 32 * ntx; 1959 } 1960 1961 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 1962 1963 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 1964 float sum_all = simd_sum(sumf[row]); 1965 if (tiisg == 0) { 1966 dst_f32[first_row + row] = sum_all * 0.25f; 1967 } 1968 } 1969} 1970 1971template<typename args_t> 1972void kernel_mul_mv_iq2_xxs_f32_disp( 1973 args_t args, 1974 device const char * src0, 1975 device const char * src1, 1976 device char * dst, 1977 threadgroup char * shmem, 1978 uint3 tgpig, 1979 ushort tiisg, 1980 ushort sgitg) { 1981 if (FC_mul_mv_split) { 1982 kernel_mul_mv_iq2_xxs_f32_impl<N_R0_IQ2_XXS_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 1983 } else { 1984 kernel_mul_mv_iq2_xxs_f32_impl<N_R0_IQ2_XXS, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 1985 } 1986} 1987 1988[[host_name("kernel_mul_mv_iq2_xxs_f32")]] 1989kernel void kernel_mul_mv_iq2_xxs_f32( 1990 constant ggml_metal_kargs_mul_mv & args, 1991 device const char * src0, 1992 device const char * src1, 1993 device char * dst, 1994 threadgroup char * shmem [[threadgroup(0)]], 1995 uint3 tgpig[[threadgroup_position_in_grid]], 1996 ushort tiisg[[thread_index_in_simdgroup]], 1997 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 1998 kernel_mul_mv_iq2_xxs_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 1999} 2000 2001template<int nr0, typename args_t> 2002void kernel_mul_mv_iq2_xs_f32_impl( 2003 args_t args, 2004 device const char * src0, 2005 device const char * src1, 2006 device char * dst, 2007 threadgroup char * shmem, 2008 uint3 tgpig, 2009 ushort tiisg, 2010 ushort sgitg) { 2011 const short NSG = FC_mul_mv_nsg; 2012 2013 const int nb = args.ne00/QK_K; 2014 2015 const int r0 = tgpig.x; 2016 const int r1 = tgpig.y; 2017 const int im = tgpig.z; 2018 2019 const int first_row = (r0 * NSG + sgitg) * nr0; 2020 2021 const uint i12 = im%FC_mul_mv_ne12; 2022 const uint i13 = im/FC_mul_mv_ne12; 2023 2024 const int nb32 = nb * (QK_K / 32); 2025 2026 const short ntx = FC_mul_mv_split ? nb32 : 32; 2027 const short nrep = 32 / ntx; 2028 2029 const short ix = tiisg % ntx; 2030 const short irep = tiisg / ntx; 2031 2032 const short row0 = (nr0 * irep ) / nrep; 2033 const short row1 = (nr0 * (irep + 1)) / nrep; 2034 2035 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2036 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2037 2038 device const block_iq2_xs * x = (device const block_iq2_xs *) (src0 + offset0); 2039 device const float * y = (device const float *) (src1 + offset1); 2040 2041 float yl[32]; 2042 float sumf[nr0]={0.f}; 2043 2044 threadgroup uint64_t * svalues = (threadgroup uint64_t *)(shmem); 2045 threadgroup uint8_t * ssigns = (threadgroup uint8_t *)(svalues + 512); 2046 { 2047 int nval = 8; 2048 int pos = (32*sgitg + tiisg)*nval; 2049 for (int i = 0; i < nval; ++i) svalues[pos + i] = iq2xs_grid[pos + i]; 2050 nval = 2; 2051 pos = (32*sgitg + tiisg)*nval; 2052 for (int i = 0; i < nval; ++i) ssigns[pos+i] = ksigns_iq2xs[pos+i]; 2053 threadgroup_barrier(mem_flags::mem_threadgroup); 2054 } 2055 2056 device const float * y4 = y + 32 * ix; 2057 2058 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2059 for (short i = 0; i < 32; ++i) { 2060 yl[i] = y4[i]; 2061 } 2062 2063 const int ibl = ib32 / (QK_K / 32); 2064 const int ib = ib32 % (QK_K / 32); 2065 2066 device const block_iq2_xs * xr = x + ibl; 2067 device const uint16_t * q2 = xr->qs + 4 * ib; 2068 device const uint8_t * sc = xr->scales + ib; 2069 device const half * dh = &xr->d; 2070 2071 for (short row = row0; row < row1; row++) { 2072 const float db = dh[0]; 2073 const uint8_t ls1 = sc[0] & 0xf; 2074 const uint8_t ls2 = sc[0] >> 4; 2075 const float d1 = db * (0.5f + ls1); 2076 const float d2 = db * (0.5f + ls2); 2077 2078 float sum1 = 0, sum2 = 0; 2079 for (short l = 0; l < 2; ++l) { 2080 const threadgroup uint8_t * grid = (const threadgroup uint8_t *)(svalues + (q2[l] & 511)); 2081 const uint8_t signs = ssigns[(q2[l] >> 9)]; 2082 for (short j = 0; j < 8; ++j) { 2083 sum1 += yl[8*l + j] * grid[j] * (signs & kmask_iq2xs[j] ? -1.f : 1.f); 2084 } 2085 } 2086 for (short l = 2; l < 4; ++l) { 2087 const threadgroup uint8_t * grid = (const threadgroup uint8_t *)(svalues + (q2[l] & 511)); 2088 const uint8_t signs = ssigns[(q2[l] >> 9)]; 2089 for (short j = 0; j < 8; ++j) { 2090 sum2 += yl[8*l + j] * grid[j] * (signs & kmask_iq2xs[j] ? -1.f : 1.f); 2091 } 2092 } 2093 sumf[row] += d1 * sum1 + d2 * sum2; 2094 2095 dh += args.nb01/2; 2096 q2 += args.nb01/2; 2097 sc += args.nb01; 2098 } 2099 2100 y4 += 32 * ntx; 2101 } 2102 2103 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2104 2105 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2106 float sum_all = simd_sum(sumf[row]); 2107 if (tiisg == 0) { 2108 dst_f32[first_row + row] = sum_all * 0.25f; 2109 } 2110 } 2111} 2112 2113template<typename args_t> 2114void kernel_mul_mv_iq2_xs_f32_disp( 2115 args_t args, 2116 device const char * src0, 2117 device const char * src1, 2118 device char * dst, 2119 threadgroup char * shmem, 2120 uint3 tgpig, 2121 ushort tiisg, 2122 ushort sgitg) { 2123 if (FC_mul_mv_split) { 2124 kernel_mul_mv_iq2_xs_f32_impl<N_R0_IQ2_XS_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2125 } else { 2126 kernel_mul_mv_iq2_xs_f32_impl<N_R0_IQ2_XS, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2127 } 2128} 2129 2130[[host_name("kernel_mul_mv_iq2_xs_f32")]] 2131kernel void kernel_mul_mv_iq2_xs_f32( 2132 constant ggml_metal_kargs_mul_mv & args, 2133 device const char * src0, 2134 device const char * src1, 2135 device char * dst, 2136 threadgroup char * shmem [[threadgroup(0)]], 2137 uint3 tgpig[[threadgroup_position_in_grid]], 2138 ushort tiisg[[thread_index_in_simdgroup]], 2139 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2140 2141 kernel_mul_mv_iq2_xs_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2142} 2143 2144// FC_mul_mv_split: for nb32 < 32 (nb32 divides 32), 32/nb32 threads share each chunk and each takes a slice of the rows 2145template<int nr0, typename args_t> 2146void kernel_mul_mv_iq3_xxs_f32_impl( 2147 args_t args, 2148 device const char * src0, 2149 device const char * src1, 2150 device char * dst, 2151 threadgroup char * shmem, 2152 uint3 tgpig, 2153 ushort tiisg, 2154 ushort sgitg) { 2155 const short NSG = FC_mul_mv_nsg; 2156 2157 const int nb = args.ne00/QK_K; 2158 2159 const int r0 = tgpig.x; 2160 const int r1 = tgpig.y; 2161 const int im = tgpig.z; 2162 2163 const int first_row = (r0 * NSG + sgitg) * nr0; 2164 2165 const uint i12 = im%FC_mul_mv_ne12; 2166 const uint i13 = im/FC_mul_mv_ne12; 2167 2168 const int nb32 = nb * (QK_K / 32); 2169 2170 const short ntx = FC_mul_mv_split ? nb32 : 32; 2171 const short nrep = 32 / ntx; 2172 2173 const short ix = tiisg % ntx; 2174 const short irep = tiisg / ntx; 2175 2176 const short row0 = (nr0 * irep ) / nrep; 2177 const short row1 = (nr0 * (irep + 1)) / nrep; 2178 2179 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2180 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2181 2182 device const block_iq3_xxs * x = (device const block_iq3_xxs *) (src0 + offset0); 2183 device const float * y = (device const float *) (src1 + offset1); 2184 2185 float yl[32]; 2186 float sumf[nr0]={0.f}; 2187 2188 threadgroup uint32_t * svalues = (threadgroup uint32_t *)(shmem); 2189 threadgroup uint8_t * ssigns = (threadgroup uint8_t *)(svalues + 256); 2190 { 2191 int nval = 4; 2192 int pos = (32*sgitg + tiisg)*nval; 2193 for (int i = 0; i < nval; ++i) svalues[pos + i] = iq3xxs_grid[pos + i]; 2194 nval = 2; 2195 pos = (32*sgitg + tiisg)*nval; 2196 for (int i = 0; i < nval; ++i) ssigns[pos+i] = ksigns_iq2xs[pos+i]; 2197 threadgroup_barrier(mem_flags::mem_threadgroup); 2198 } 2199 2200 device const float * y4 = y + 32 * ix; 2201 2202 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2203 for (short i = 0; i < 32; ++i) { 2204 yl[i] = y4[i]; 2205 } 2206 2207 const int ibl = ib32 / (QK_K / 32); 2208 const int ib = ib32 % (QK_K / 32); 2209 2210 device const block_iq3_xxs * xr = x + ibl; 2211 device const uint8_t * q3 = xr->qs + 8 * ib; 2212 device const uint16_t * gas = (device const uint16_t *)(xr->qs + QK_K/4) + 2 * ib; 2213 device const half * dh = &xr->d; 2214 2215 for (short row = row0; row < row1; row++) { 2216 const float db = dh[0]; 2217 const uint32_t aux32 = gas[0] | (gas[1] << 16); 2218 const float d = db * (0.5f + (aux32 >> 28)); 2219 2220 float2 sum = {0}; 2221 for (short l = 0; l < 4; ++l) { 2222 const threadgroup uint8_t * grid1 = (const threadgroup uint8_t *)(svalues + q3[2*l+0]); 2223 const threadgroup uint8_t * grid2 = (const threadgroup uint8_t *)(svalues + q3[2*l+1]); 2224 const uint8_t signs = ssigns[(aux32 >> 7*l) & 127]; 2225 for (short j = 0; j < 4; ++j) { 2226 sum[0] += yl[8*l + j + 0] * grid1[j] * (signs & kmask_iq2xs[j+0] ? -1.f : 1.f); 2227 sum[1] += yl[8*l + j + 4] * grid2[j] * (signs & kmask_iq2xs[j+4] ? -1.f : 1.f); 2228 } 2229 } 2230 sumf[row] += d * (sum[0] + sum[1]); 2231 2232 dh += args.nb01/2; 2233 q3 += args.nb01; 2234 gas += args.nb01/2; 2235 } 2236 2237 y4 += 32 * ntx; 2238 } 2239 2240 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2241 2242 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2243 float sum_all = simd_sum(sumf[row]); 2244 if (tiisg == 0) { 2245 dst_f32[first_row + row] = sum_all * 0.5f; 2246 } 2247 } 2248} 2249 2250template<typename args_t> 2251void kernel_mul_mv_iq3_xxs_f32_disp( 2252 args_t args, 2253 device const char * src0, 2254 device const char * src1, 2255 device char * dst, 2256 threadgroup char * shmem, 2257 uint3 tgpig, 2258 ushort tiisg, 2259 ushort sgitg) { 2260 if (FC_mul_mv_split) { 2261 kernel_mul_mv_iq3_xxs_f32_impl<N_R0_IQ3_XXS_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2262 } else { 2263 kernel_mul_mv_iq3_xxs_f32_impl<N_R0_IQ3_XXS, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2264 } 2265} 2266 2267[[host_name("kernel_mul_mv_iq3_xxs_f32")]] 2268kernel void kernel_mul_mv_iq3_xxs_f32( 2269 constant ggml_metal_kargs_mul_mv & args, 2270 device const char * src0, 2271 device const char * src1, 2272 device char * dst, 2273 threadgroup char * shmem [[threadgroup(0)]], 2274 uint3 tgpig[[threadgroup_position_in_grid]], 2275 ushort tiisg[[thread_index_in_simdgroup]], 2276 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2277 2278 kernel_mul_mv_iq3_xxs_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2279} 2280 2281template<int nr0, typename args_t> 2282void kernel_mul_mv_iq3_s_f32_impl( 2283 args_t args, 2284 device const char * src0, 2285 device const char * src1, 2286 device char * dst, 2287 threadgroup char * shmem, 2288 uint3 tgpig, 2289 ushort tiisg, 2290 ushort sgitg) { 2291 const short NSG = FC_mul_mv_nsg; 2292 2293 const int nb = args.ne00/QK_K; 2294 2295 const int r0 = tgpig.x; 2296 const int r1 = tgpig.y; 2297 const int im = tgpig.z; 2298 2299 const int first_row = (r0 * NSG + sgitg) * nr0; 2300 2301 const uint i12 = im%FC_mul_mv_ne12; 2302 const uint i13 = im/FC_mul_mv_ne12; 2303 2304 const int nb32 = nb * (QK_K / 32); 2305 2306 const short ntx = FC_mul_mv_split ? nb32 : 32; 2307 const short nrep = 32 / ntx; 2308 2309 const short ix = tiisg % ntx; 2310 const short irep = tiisg / ntx; 2311 2312 const short row0 = (nr0 * irep ) / nrep; 2313 const short row1 = (nr0 * (irep + 1)) / nrep; 2314 2315 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2316 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2317 2318 device const block_iq3_s * x = (device const block_iq3_s *) (src0 + offset0); 2319 device const float * y = (device const float *) (src1 + offset1); 2320 2321 float yl[32]; 2322 float sumf[nr0]={0.f}; 2323 2324 threadgroup uint32_t * svalues = (threadgroup uint32_t *) shmem; 2325 { 2326 int nval = 8; 2327 int pos = (32*sgitg + tiisg)*nval; 2328 for (int i = 0; i < nval; ++i) svalues[pos + i] = iq3s_grid[pos + i]; 2329 threadgroup_barrier(mem_flags::mem_threadgroup); 2330 } 2331 2332 device const float * y4 = y + 32 * ix; 2333 2334 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2335 for (short i = 0; i < 32; ++i) { 2336 yl[i] = y4[i]; 2337 } 2338 2339 const int ibl = ib32 / (QK_K / 32); 2340 const int ib = ib32 % (QK_K / 32); 2341 2342 device const block_iq3_s * xr = x + ibl; 2343 device const uint8_t * qs = xr->qs + 8 * ib; 2344 device const uint8_t * qh = xr->qh + ib; 2345 device const uint8_t * sc = xr->scales + (ib/2); 2346 device const uint8_t * signs = xr->signs + 4 * ib; 2347 device const half * dh = &xr->d; 2348 2349 for (short row = row0; row < row1; row++) { 2350 const float db = dh[0]; 2351 const float d = db * (1 + 2*((sc[0] >> 4*(ib%2)) & 0xf)); 2352 2353 float2 sum = {0}; 2354 for (short l = 0; l < 4; ++l) { 2355 const threadgroup uint32_t * table1 = qh[0] & kmask_iq2xs[2*l+0] ? svalues + 256 : svalues; 2356 const threadgroup uint32_t * table2 = qh[0] & kmask_iq2xs[2*l+1] ? svalues + 256 : svalues; 2357 const threadgroup uint8_t * grid1 = (const threadgroup uint8_t *)(table1 + qs[2*l+0]); 2358 const threadgroup uint8_t * grid2 = (const threadgroup uint8_t *)(table2 + qs[2*l+1]); 2359 for (short j = 0; j < 4; ++j) { 2360 sum[0] += yl[8*l + j + 0] * grid1[j] * select(1, -1, signs[l] & kmask_iq2xs[j+0]); 2361 sum[1] += yl[8*l + j + 4] * grid2[j] * select(1, -1, signs[l] & kmask_iq2xs[j+4]); 2362 } 2363 } 2364 sumf[row] += d * (sum[0] + sum[1]); 2365 2366 dh += args.nb01/2; 2367 qs += args.nb01; 2368 qh += args.nb01; 2369 sc += args.nb01; 2370 signs += args.nb01; 2371 } 2372 2373 y4 += 32 * ntx; 2374 } 2375 2376 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2377 2378 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2379 float sum_all = simd_sum(sumf[row]); 2380 if (tiisg == 0) { 2381 dst_f32[first_row + row] = sum_all; 2382 } 2383 } 2384} 2385 2386template<typename args_t> 2387void kernel_mul_mv_iq3_s_f32_disp( 2388 args_t args, 2389 device const char * src0, 2390 device const char * src1, 2391 device char * dst, 2392 threadgroup char * shmem, 2393 uint3 tgpig, 2394 ushort tiisg, 2395 ushort sgitg) { 2396 if (FC_mul_mv_split) { 2397 kernel_mul_mv_iq3_s_f32_impl<N_R0_IQ3_S_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2398 } else { 2399 kernel_mul_mv_iq3_s_f32_impl<N_R0_IQ3_S, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2400 } 2401} 2402 2403[[host_name("kernel_mul_mv_iq3_s_f32")]] 2404kernel void kernel_mul_mv_iq3_s_f32( 2405 constant ggml_metal_kargs_mul_mv & args, 2406 device const char * src0, 2407 device const char * src1, 2408 device char * dst, 2409 threadgroup char * shmem [[threadgroup(0)]], 2410 uint3 tgpig[[threadgroup_position_in_grid]], 2411 ushort tiisg[[thread_index_in_simdgroup]], 2412 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2413 2414 kernel_mul_mv_iq3_s_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2415} 2416 2417template<int nr0, typename args_t> 2418void kernel_mul_mv_iq2_s_f32_impl( 2419 args_t args, 2420 device const char * src0, 2421 device const char * src1, 2422 device char * dst, 2423 threadgroup char * shmem, 2424 uint3 tgpig, 2425 ushort tiisg, 2426 ushort sgitg) { 2427 const short NSG = FC_mul_mv_nsg; 2428 2429 const int nb = args.ne00/QK_K; 2430 2431 const int r0 = tgpig.x; 2432 const int r1 = tgpig.y; 2433 const int im = tgpig.z; 2434 2435 const int first_row = (r0 * NSG + sgitg) * nr0; 2436 2437 const uint i12 = im%FC_mul_mv_ne12; 2438 const uint i13 = im/FC_mul_mv_ne12; 2439 2440 const int nb32 = nb * (QK_K / 32); 2441 2442 const short ntx = FC_mul_mv_split ? nb32 : 32; 2443 const short nrep = 32 / ntx; 2444 2445 const short ix = tiisg % ntx; 2446 const short irep = tiisg / ntx; 2447 2448 const short row0 = (nr0 * irep ) / nrep; 2449 const short row1 = (nr0 * (irep + 1)) / nrep; 2450 2451 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2452 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2453 2454 device const block_iq2_s * x = (device const block_iq2_s *) (src0 + offset0); 2455 device const float * y = (device const float *) (src1 + offset1); 2456 2457 float yl[32]; 2458 float sumf[nr0]={0.f}; 2459 2460 //threadgroup uint64_t * svalues = (threadgroup uint64_t *) shmem; 2461 //{ 2462 // int nval = 32; 2463 // int pos = (32*sgitg + tiisg)*nval; 2464 // for (int i = 0; i < nval; ++i) svalues[pos + i] = iq2s_grid[pos + i]; 2465 // threadgroup_barrier(mem_flags::mem_threadgroup); 2466 //} 2467 2468 device const float * y4 = y + 32 * ix; 2469 2470 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2471 for (short i = 0; i < 32; ++i) { 2472 yl[i] = y4[i]; 2473 } 2474 2475 const int ibl = ib32 / (QK_K / 32); 2476 const int ib = ib32 % (QK_K / 32); 2477 2478 device const block_iq2_s * xr = x + ibl; 2479 device const uint8_t * qs = xr->qs + 4 * ib; 2480 device const uint8_t * qh = xr->qh + ib; 2481 device const uint8_t * sc = xr->scales + ib; 2482 device const uint8_t * signs = qs + QK_K/8; 2483 device const half * dh = &xr->d; 2484 2485 for (short row = row0; row < row1; row++) { 2486 const float db = dh[0]; 2487 const float d1 = db * (0.5f + (sc[0] & 0xf)); 2488 const float d2 = db * (0.5f + (sc[0] >> 4)); 2489 2490 float2 sum = {0}; 2491 for (short l = 0; l < 2; ++l) { 2492 //const threadgroup uint8_t * grid1 = (const threadgroup uint8_t *)(svalues + (qs[l+0] | ((qh[0] << (8-2*l)) & 0x300))); 2493 //const threadgroup uint8_t * grid2 = (const threadgroup uint8_t *)(svalues + (qs[l+2] | ((qh[0] << (4-2*l)) & 0x300))); 2494 constant uint8_t * grid1 = (constant uint8_t *)(iq2s_grid + (qs[l+0] | ((qh[0] << (8-2*l)) & 0x300))); 2495 constant uint8_t * grid2 = (constant uint8_t *)(iq2s_grid + (qs[l+2] | ((qh[0] << (4-2*l)) & 0x300))); 2496 for (short j = 0; j < 8; ++j) { 2497 sum[0] += yl[8*l + j + 0] * grid1[j] * select(1, -1, signs[l+0] & kmask_iq2xs[j]); 2498 sum[1] += yl[8*l + j + 16] * grid2[j] * select(1, -1, signs[l+2] & kmask_iq2xs[j]); 2499 } 2500 } 2501 sumf[row] += d1 * sum[0] + d2 * sum[1]; 2502 2503 dh += args.nb01/2; 2504 qs += args.nb01; 2505 qh += args.nb01; 2506 sc += args.nb01; 2507 signs += args.nb01; 2508 } 2509 2510 y4 += 32 * ntx; 2511 } 2512 2513 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2514 2515 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2516 float sum_all = simd_sum(sumf[row]); 2517 if (tiisg == 0) { 2518 dst_f32[first_row + row] = sum_all * 0.25f; 2519 } 2520 } 2521} 2522 2523template<typename args_t> 2524void kernel_mul_mv_iq2_s_f32_disp( 2525 args_t args, 2526 device const char * src0, 2527 device const char * src1, 2528 device char * dst, 2529 threadgroup char * shmem, 2530 uint3 tgpig, 2531 ushort tiisg, 2532 ushort sgitg) { 2533 if (FC_mul_mv_split) { 2534 kernel_mul_mv_iq2_s_f32_impl<N_R0_IQ2_S_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2535 } else { 2536 kernel_mul_mv_iq2_s_f32_impl<N_R0_IQ2_S, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2537 } 2538} 2539 2540[[host_name("kernel_mul_mv_iq2_s_f32")]] 2541kernel void kernel_mul_mv_iq2_s_f32( 2542 constant ggml_metal_kargs_mul_mv & args, 2543 device const char * src0, 2544 device const char * src1, 2545 device char * dst, 2546 threadgroup char * shmem [[threadgroup(0)]], 2547 uint3 tgpig[[threadgroup_position_in_grid]], 2548 ushort tiisg[[thread_index_in_simdgroup]], 2549 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2550 2551 kernel_mul_mv_iq2_s_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2552} 2553 2554template<int nr0, typename args_t> 2555void kernel_mul_mv_iq1_s_f32_impl( 2556 args_t args, 2557 device const char * src0, 2558 device const char * src1, 2559 device char * dst, 2560 threadgroup char * shmem, 2561 uint3 tgpig, 2562 ushort tiisg, 2563 ushort sgitg) { 2564 const short NSG = FC_mul_mv_nsg; 2565 2566 const int nb = args.ne00/QK_K; 2567 2568 const int r0 = tgpig.x; 2569 const int r1 = tgpig.y; 2570 const int im = tgpig.z; 2571 2572 const int first_row = (r0 * NSG + sgitg) * nr0; 2573 2574 const uint i12 = im%FC_mul_mv_ne12; 2575 const uint i13 = im/FC_mul_mv_ne12; 2576 2577 const int nb32 = nb * (QK_K / 32); 2578 2579 const short ntx = FC_mul_mv_split ? nb32 : 32; 2580 const short nrep = 32 / ntx; 2581 2582 const short ix = tiisg % ntx; 2583 const short irep = tiisg / ntx; 2584 2585 const short row0 = (nr0 * irep ) / nrep; 2586 const short row1 = (nr0 * (irep + 1)) / nrep; 2587 2588 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2589 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2590 2591 device const block_iq1_s * x = (device const block_iq1_s *) (src0 + offset0); 2592 device const float * y = (device const float *) (src1 + offset1); 2593 2594 float yl[32]; 2595 float sumf[nr0]={0.f}; 2596 2597 device const float * y4 = y + 32 * ix; 2598 2599 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2600 float sumy = 0; 2601 for (short i = 0; i < 32; ++i) { 2602 yl[i] = y4[i]; 2603 sumy += yl[i]; 2604 } 2605 2606 const int ibl = ib32 / (QK_K / 32); 2607 const int ib = ib32 % (QK_K / 32); 2608 2609 device const block_iq1_s * xr = x + ibl; 2610 device const uint8_t * qs = xr->qs + 4 * ib; 2611 device const uint16_t * qh = xr->qh + ib; 2612 device const half * dh = &xr->d; 2613 2614 for (short row = row0; row < row1; row++) { 2615 constant uint8_t * grid1 = (constant uint8_t *)(iq1s_grid_gpu + (qs[0] | ((qh[0] << 8) & 0x700))); 2616 constant uint8_t * grid2 = (constant uint8_t *)(iq1s_grid_gpu + (qs[1] | ((qh[0] << 5) & 0x700))); 2617 constant uint8_t * grid3 = (constant uint8_t *)(iq1s_grid_gpu + (qs[2] | ((qh[0] << 2) & 0x700))); 2618 constant uint8_t * grid4 = (constant uint8_t *)(iq1s_grid_gpu + (qs[3] | ((qh[0] >> 1) & 0x700))); 2619 2620 float sum = 0; 2621 for (short j = 0; j < 4; ++j) { 2622 sum += yl[j+ 0] * (grid1[j] & 0xf) + yl[j+ 4] * (grid1[j] >> 4) 2623 + yl[j+ 8] * (grid2[j] & 0xf) + yl[j+12] * (grid2[j] >> 4) 2624 + yl[j+16] * (grid3[j] & 0xf) + yl[j+20] * (grid3[j] >> 4) 2625 + yl[j+24] * (grid4[j] & 0xf) + yl[j+28] * (grid4[j] >> 4); 2626 } 2627 sumf[row] += (float)dh[0] * (sum + sumy * (qh[0] & 0x8000 ? -1 - IQ1S_DELTA : -1 + IQ1S_DELTA)) * (2*((qh[0] >> 12) & 7) + 1); 2628 2629 dh += args.nb01/2; 2630 qs += args.nb01; 2631 qh += args.nb01/2; 2632 } 2633 2634 y4 += 32 * ntx; 2635 } 2636 2637 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2638 2639 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2640 float sum_all = simd_sum(sumf[row]); 2641 if (tiisg == 0) { 2642 dst_f32[first_row + row] = sum_all; 2643 } 2644 } 2645} 2646 2647template<typename args_t> 2648void kernel_mul_mv_iq1_s_f32_disp( 2649 args_t args, 2650 device const char * src0, 2651 device const char * src1, 2652 device char * dst, 2653 threadgroup char * shmem, 2654 uint3 tgpig, 2655 ushort tiisg, 2656 ushort sgitg) { 2657 if (FC_mul_mv_split) { 2658 kernel_mul_mv_iq1_s_f32_impl<N_R0_IQ1_S_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2659 } else { 2660 kernel_mul_mv_iq1_s_f32_impl<N_R0_IQ1_S, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2661 } 2662} 2663 2664[[host_name("kernel_mul_mv_iq1_s_f32")]] 2665kernel void kernel_mul_mv_iq1_s_f32( 2666 constant ggml_metal_kargs_mul_mv & args, 2667 device const char * src0, 2668 device const char * src1, 2669 device char * dst, 2670 uint3 tgpig[[threadgroup_position_in_grid]], 2671 ushort tiisg[[thread_index_in_simdgroup]], 2672 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2673 2674 kernel_mul_mv_iq1_s_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 2675} 2676 2677template<int nr0, typename args_t> 2678void kernel_mul_mv_iq1_m_f32_impl( 2679 args_t args, 2680 device const char * src0, 2681 device const char * src1, 2682 device char * dst, 2683 threadgroup char * shmem, 2684 uint3 tgpig, 2685 ushort tiisg, 2686 ushort sgitg) { 2687 const short NSG = FC_mul_mv_nsg; 2688 2689 const int nb = args.ne00/QK_K; 2690 2691 const int r0 = tgpig.x; 2692 const int r1 = tgpig.y; 2693 const int im = tgpig.z; 2694 2695 const int first_row = (r0 * NSG + sgitg) * nr0; 2696 2697 const uint i12 = im%FC_mul_mv_ne12; 2698 const uint i13 = im/FC_mul_mv_ne12; 2699 2700 const int nb32 = nb * (QK_K / 32); 2701 2702 const short ntx = FC_mul_mv_split ? nb32 : 32; 2703 const short nrep = 32 / ntx; 2704 2705 const short ix = tiisg % ntx; 2706 const short irep = tiisg / ntx; 2707 2708 const short row0 = (nr0 * irep ) / nrep; 2709 const short row1 = (nr0 * (irep + 1)) / nrep; 2710 2711 const uint64_t offset0 = (first_row + row0)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2712 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2713 2714 device const block_iq1_m * x = (device const block_iq1_m *) (src0 + offset0); 2715 device const float * y = (device const float *) (src1 + offset1); 2716 2717 float yl[32]; 2718 float sumf[nr0]={0.f}; 2719 2720 device const float * y4 = y + 32 * ix; 2721 2722 iq1m_scale_t scale; 2723 2724 for (int ib32 = ix; ib32 < nb32; ib32 += ntx) { 2725 float4 sumy = {0.f}; 2726 for (short i = 0; i < 8; ++i) { 2727 yl[i+ 0] = y4[i+ 0]; sumy[0] += yl[i+ 0]; 2728 yl[i+ 8] = y4[i+ 8]; sumy[1] += yl[i+ 8]; 2729 yl[i+16] = y4[i+16]; sumy[2] += yl[i+16]; 2730 yl[i+24] = y4[i+24]; sumy[3] += yl[i+24]; 2731 } 2732 2733 const int ibl = ib32 / (QK_K / 32); 2734 const int ib = ib32 % (QK_K / 32); 2735 2736 device const block_iq1_m * xr = x + ibl; 2737 device const uint8_t * qs = xr->qs + 4 * ib; 2738 device const uint8_t * qh = xr->qh + 2 * ib; 2739 device const uint16_t * sc = (device const uint16_t *)xr->scales; 2740 2741 for (short row = row0; row < row1; row++) { 2742 scale.u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000); 2743 2744 constant uint8_t * grid1 = (constant uint8_t *)(iq1s_grid_gpu + (qs[0] | ((qh[0] << 8) & 0x700))); 2745 constant uint8_t * grid2 = (constant uint8_t *)(iq1s_grid_gpu + (qs[1] | ((qh[0] << 4) & 0x700))); 2746 constant uint8_t * grid3 = (constant uint8_t *)(iq1s_grid_gpu + (qs[2] | ((qh[1] << 8) & 0x700))); 2747 constant uint8_t * grid4 = (constant uint8_t *)(iq1s_grid_gpu + (qs[3] | ((qh[1] << 4) & 0x700))); 2748 2749 float2 sum = {0.f}; 2750 for (short j = 0; j < 4; ++j) { 2751 sum[0] += yl[j+ 0] * (grid1[j] & 0xf) + yl[j+ 4] * (grid1[j] >> 4) 2752 + yl[j+ 8] * (grid2[j] & 0xf) + yl[j+12] * (grid2[j] >> 4); 2753 sum[1] += yl[j+16] * (grid3[j] & 0xf) + yl[j+20] * (grid3[j] >> 4) 2754 + yl[j+24] * (grid4[j] & 0xf) + yl[j+28] * (grid4[j] >> 4); 2755 } 2756 const float delta1 = sumy[0] * (qh[0] & 0x08 ? -1 - IQ1M_DELTA : -1 + IQ1M_DELTA) + sumy[1] * (qh[0] & 0x80 ? -1 - IQ1M_DELTA : -1 + IQ1M_DELTA); 2757 const float delta2 = sumy[2] * (qh[1] & 0x08 ? -1 - IQ1M_DELTA : -1 + IQ1M_DELTA) + sumy[3] * (qh[1] & 0x80 ? -1 - IQ1M_DELTA : -1 + IQ1M_DELTA); 2758 2759 sumf[row] += (float)scale.f16 * ((sum[0] + delta1) * (2*((sc[ib/2] >> (6*(ib%2)+0)) & 7) + 1) + 2760 (sum[1] + delta2) * (2*((sc[ib/2] >> (6*(ib%2)+3)) & 7) + 1)); 2761 2762 sc += args.nb01/2; 2763 qs += args.nb01; 2764 qh += args.nb01; 2765 } 2766 2767 y4 += 32 * ntx; 2768 } 2769 2770 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2771 2772 for (int row = 0; row < nr0 && first_row + row < args.ne0; ++row) { 2773 float sum_all = simd_sum(sumf[row]); 2774 if (tiisg == 0) { 2775 dst_f32[first_row + row] = sum_all; 2776 } 2777 } 2778} 2779 2780template<typename args_t> 2781void kernel_mul_mv_iq1_m_f32_disp( 2782 args_t args, 2783 device const char * src0, 2784 device const char * src1, 2785 device char * dst, 2786 threadgroup char * shmem, 2787 uint3 tgpig, 2788 ushort tiisg, 2789 ushort sgitg) { 2790 if (FC_mul_mv_split) { 2791 kernel_mul_mv_iq1_m_f32_impl<N_R0_IQ1_M_SPLIT, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2792 } else { 2793 kernel_mul_mv_iq1_m_f32_impl<N_R0_IQ1_M, args_t>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2794 } 2795} 2796 2797[[host_name("kernel_mul_mv_iq1_m_f32")]] 2798kernel void kernel_mul_mv_iq1_m_f32( 2799 constant ggml_metal_kargs_mul_mv & args, 2800 device const char * src0, 2801 device const char * src1, 2802 device char * dst, 2803 uint3 tgpig[[threadgroup_position_in_grid]], 2804 ushort tiisg[[thread_index_in_simdgroup]], 2805 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2806 2807 kernel_mul_mv_iq1_m_f32_disp<constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 2808} 2809 2810template<int NR0, typename args_t> 2811void kernel_mul_mv_iq4_nl_f32_impl( 2812 args_t args, 2813 device const char * src0, 2814 device const char * src1, 2815 device char * dst, 2816 threadgroup char * shmem, 2817 uint3 tgpig, 2818 ushort tiisg, 2819 ushort sgitg) { 2820 const short NSG = FC_mul_mv_nsg; 2821 2822 threadgroup float * shmem_f32 = (threadgroup float *) shmem; 2823 2824 const int r0 = tgpig.x; 2825 const int r1 = tgpig.y; 2826 const int im = tgpig.z; 2827 2828 const int first_row = (r0 * NSG + sgitg) * NR0; 2829 2830 const uint i12 = im%FC_mul_mv_ne12; 2831 const uint i13 = im/FC_mul_mv_ne12; 2832 2833 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2834 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2835 2836 device const block_iq4_nl * x = (device const block_iq4_nl *) (src0 + offset0); 2837 device const float * y = (device const float *) (src1 + offset1); 2838 2839 const int nb = args.ne00/QK4_NL; 2840 const int ns01 = args.nb01/args.nb00; 2841 2842 const short ix = tiisg/2; // 0...15 2843 const short it = tiisg%2; // 0 or 1 2844 2845 shmem_f32[tiisg] = kvalues_iq4nl_f[tiisg%16]; 2846 threadgroup_barrier(mem_flags::mem_threadgroup); 2847 2848 float4 yl[4]; 2849 float sumf[NR0]={0.f}; 2850 2851 device const float * yb = y + ix*QK4_NL + it*8; 2852 2853 uint32_t aux32[2]; 2854 thread const uint8_t * q8 = (thread const uint8_t *)aux32; 2855 2856 float4 qf1, qf2; 2857 2858 // [TAG_MUL_MV_WEIRD] 2859 for (int ib = ix; ib < nb && ib < ns01; ib += 16) { 2860 device const float4 * y4 = (device const float4 *)yb; 2861 yl[0] = y4[0]; 2862 yl[1] = y4[4]; 2863 yl[2] = y4[1]; 2864 yl[3] = y4[5]; 2865 2866 for (short row = 0; row < NR0; row++) { 2867 device const block_iq4_nl & xb = x[row*ns01 + ib]; 2868 device const uint16_t * q4 = (device const uint16_t *)(xb.qs + 8*it); 2869 2870 float4 acc1 = {0.f}, acc2 = {0.f}; 2871 2872 aux32[0] = q4[0] | (q4[1] << 16); 2873 aux32[1] = (aux32[0] >> 4) & 0x0f0f0f0f; 2874 aux32[0] &= 0x0f0f0f0f; 2875 qf1 = {shmem_f32[q8[0]], shmem_f32[q8[1]], shmem_f32[q8[2]], shmem_f32[q8[3]]}; 2876 qf2 = {shmem_f32[q8[4]], shmem_f32[q8[5]], shmem_f32[q8[6]], shmem_f32[q8[7]]}; 2877 acc1 += yl[0] * qf1; 2878 acc2 += yl[1] * qf2; 2879 2880 aux32[0] = q4[2] | (q4[3] << 16); 2881 aux32[1] = (aux32[0] >> 4) & 0x0f0f0f0f; 2882 aux32[0] &= 0x0f0f0f0f; 2883 qf1 = {shmem_f32[q8[0]], shmem_f32[q8[1]], shmem_f32[q8[2]], shmem_f32[q8[3]]}; 2884 qf2 = {shmem_f32[q8[4]], shmem_f32[q8[5]], shmem_f32[q8[6]], shmem_f32[q8[7]]}; 2885 acc1 += yl[2] * qf1; 2886 acc2 += yl[3] * qf2; 2887 2888 acc1 += acc2; 2889 2890 sumf[row] += (float)xb.d * (acc1[0] + acc1[1] + acc1[2] + acc1[3]); 2891 } 2892 2893 yb += 16 * QK4_NL; 2894 } 2895 2896 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 2897 2898 for (int row = 0; row < NR0 && first_row + row < args.ne0; ++row) { 2899 float sum_all = simd_sum(sumf[row]); 2900 if (tiisg == 0) { 2901 dst_f32[first_row + row] = sum_all; 2902 } 2903 } 2904} 2905 2906[[host_name("kernel_mul_mv_iq4_nl_f32")]] 2907kernel void kernel_mul_mv_iq4_nl_f32( 2908 constant ggml_metal_kargs_mul_mv & args, 2909 device const char * src0, 2910 device const char * src1, 2911 device char * dst, 2912 threadgroup char * shmem [[threadgroup(0)]], 2913 uint3 tgpig[[threadgroup_position_in_grid]], 2914 ushort tiisg[[thread_index_in_simdgroup]], 2915 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 2916 2917 kernel_mul_mv_iq4_nl_f32_impl<N_R0_IQ4_NL, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 2918} 2919 2920template<int NR0, typename args_t> 2921void kernel_mul_mv_iq4_xs_f32_impl( 2922 args_t args, 2923 device const char * src0, 2924 device const char * src1, 2925 device char * dst, 2926 threadgroup char * shmem, 2927 uint3 tgpig, 2928 ushort tiisg, 2929 ushort sgitg) { 2930 const short NSG = FC_mul_mv_nsg; 2931 2932 threadgroup float * shmem_f32 = (threadgroup float *) shmem; 2933 2934 const int r0 = tgpig.x; 2935 const int r1 = tgpig.y; 2936 const int im = tgpig.z; 2937 const int first_row = (r0 * NSG + sgitg) * NR0; 2938 2939 const uint i12 = im%FC_mul_mv_ne12; 2940 const uint i13 = im/FC_mul_mv_ne12; 2941 2942 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 2943 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 2944 2945 device const block_iq4_xs * x = (device const block_iq4_xs *) (src0 + offset0); 2946 device const float * y = (device const float *) (src1 + offset1); 2947 2948 const int nb = args.ne00/QK_K; 2949 const int ns01 = args.nb01/args.nb00; 2950 2951 const short ix = tiisg/16; // 0 or 1 2952 const short it = tiisg%16; // 0...15 2953 const short ib = it/2; 2954 const short il = it%2; 2955 2956 shmem_f32[tiisg] = kvalues_iq4nl_f[tiisg%16]; 2957 threadgroup_barrier(mem_flags::mem_threadgroup); 2958 2959 float4 yl[4]; 2960 float sumf[NR0]={0.f}; 2961 2962 device const float * yb = y + ix * QK_K + ib * 32 + il * 8; 2963 2964 uint32_t aux32[2]; 2965 thread const uint8_t * q8 = (thread const uint8_t *)aux32; 2966 2967 float4 qf1, qf2; 2968 2969 // [TAG_MUL_MV_WEIRD] 2970 for (int ibl = ix; ibl < nb && ibl < ns01; ibl += 2) { 2971 device const float4 * y4 = (device const float4 *)yb; 2972 yl[0] = y4[0]; 2973 yl[1] = y4[4]; 2974 yl[2] = y4[1]; 2975 yl[3] = y4[5]; 2976 2977 for (short row = 0; row < NR0; ++row) { 2978 device const block_iq4_xs & xb = x[row*ns01 + ibl]; 2979 device const uint32_t * q4 = (device const uint32_t *)(xb.qs + 16*ib + 8*il); 2980 2981 float4 acc1 = {0.f}, acc2 = {0.f}; 2982 2983 aux32[0] = (q4[0] ) & 0x0f0f0f0f; 2984 aux32[1] = (q4[0] >> 4) & 0x0f0f0f0f; 2985 qf1 = {shmem_f32[q8[0]], shmem_f32[q8[1]], shmem_f32[q8[2]], shmem_f32[q8[3]]}; 2986 qf2 = {shmem_f32[q8[4]], shmem_f32[q8[5]], shmem_f32[q8[6]], shmem_f32[q8[7]]}; 2987 acc1 += yl[0] * qf1; 2988 acc2 += yl[1] * qf2; 2989 2990 aux32[0] = (q4[1] ) & 0x0f0f0f0f; 2991 aux32[1] = (q4[1] >> 4) & 0x0f0f0f0f; 2992 qf1 = {shmem_f32[q8[0]], shmem_f32[q8[1]], shmem_f32[q8[2]], shmem_f32[q8[3]]}; 2993 qf2 = {shmem_f32[q8[4]], shmem_f32[q8[5]], shmem_f32[q8[6]], shmem_f32[q8[7]]}; 2994 acc1 += yl[2] * qf1; 2995 acc2 += yl[3] * qf2; 2996 2997 acc1 += acc2; 2998 2999 const int ls = (((xb.scales_l[ib/2] >> 4*(ib%2)) & 0xf) | (((xb.scales_h >> 2*ib) & 3) << 4)) - 32; 3000 sumf[row] += (float)xb.d * ls * (acc1[0] + acc1[1] + acc1[2] + acc1[3]); 3001 } 3002 3003 yb += 2 * QK_K; 3004 } 3005 3006 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 3007 3008 for (int row = 0; row < NR0 && first_row + row < args.ne0; ++row) { 3009 float sum_all = simd_sum(sumf[row]); 3010 if (tiisg == 0) { 3011 dst_f32[first_row + row] = sum_all; 3012 } 3013 } 3014} 3015 3016[[host_name("kernel_mul_mv_iq4_xs_f32")]] 3017kernel void kernel_mul_mv_iq4_xs_f32( 3018 constant ggml_metal_kargs_mul_mv & args, 3019 device const char * src0, 3020 device const char * src1, 3021 device char * dst, 3022 threadgroup char * shmem [[threadgroup(0)]], 3023 uint3 tgpig[[threadgroup_position_in_grid]], 3024 ushort tiisg[[thread_index_in_simdgroup]], 3025 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 3026 3027 kernel_mul_mv_iq4_xs_f32_impl<N_R0_IQ4_XS, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 3028} 3029 3030template<int NR0, typename args_t> 3031void kernel_mul_mv_mxfp4_f32_impl( 3032 args_t args, 3033 device const char * src0, 3034 device const char * src1, 3035 device char * dst, 3036 threadgroup char * shmem, 3037 uint3 tgpig, 3038 ushort tiisg, 3039 ushort sgitg) { 3040 const short NSG = FC_mul_mv_nsg; 3041 3042 threadgroup float * shmem_f32 = (threadgroup float *) shmem; 3043 3044 const int r0 = tgpig.x; 3045 const int r1 = tgpig.y; 3046 const int im = tgpig.z; 3047 3048 const int first_row = (r0 * NSG + sgitg) * NR0; 3049 3050 const uint i12 = im%FC_mul_mv_ne12; 3051 const uint i13 = im/FC_mul_mv_ne12; 3052 3053 const uint64_t offset0 = first_row*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 3054 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 3055 3056 device const block_mxfp4 * x = (device const block_mxfp4 *) (src0 + offset0); 3057 device const float * y = (device const float *) (src1 + offset1); 3058 3059 const int nb = args.ne00/QK_MXFP4; 3060 const int ns01 = args.nb01/args.nb00; // this can be larger than nb for permuted src0 tensors 3061 3062 const short ix = tiisg/2; // 0...15 3063 const short it = tiisg%2; // 0 or 1 3064 3065 shmem_f32[tiisg] = kvalues_mxfp4_f[tiisg%16]; 3066 threadgroup_barrier(mem_flags::mem_threadgroup); 3067 3068 float4 yl[4]; 3069 float sumf[NR0]={0.f}; 3070 3071 device const float * yb = y + ix*QK_MXFP4 + it*8; 3072 3073 // note: just the check `ib < nb` is enough, but adding the redundant `&& ib < ns01` check makes the kernel a bit faster 3074 // no idea why that is - needs some deeper investigation [TAG_MUL_MV_WEIRD] 3075 for (int ib = ix; ib < nb && ib < ns01; ib += 16) { 3076 device const float4 * y4 = (device const float4 *) yb; 3077 3078 yl[0] = y4[0]; 3079 yl[1] = y4[4]; 3080 yl[2] = y4[1]; 3081 yl[3] = y4[5]; 3082 3083 FOR_UNROLL (short row = 0; row < NR0; row++) { 3084 device const block_mxfp4 & xb = x[row*ns01 + ib]; 3085 device const uint8_t * q2 = (device const uint8_t *)(xb.qs + 8*it); 3086 3087 float4 acc1 = yl[0]*float4(shmem_f32[q2[0] & 0x0F], shmem_f32[q2[1] & 0x0F], shmem_f32[q2[2] & 0x0F], shmem_f32[q2[3] & 0x0F]); 3088 float4 acc2 = yl[1]*float4(shmem_f32[q2[0] >> 4 ], shmem_f32[q2[1] >> 4 ], shmem_f32[q2[2] >> 4 ], shmem_f32[q2[3] >> 4 ]); 3089 float4 acc3 = yl[2]*float4(shmem_f32[q2[4] & 0x0F], shmem_f32[q2[5] & 0x0F], shmem_f32[q2[6] & 0x0F], shmem_f32[q2[7] & 0x0F]); 3090 float4 acc4 = yl[3]*float4(shmem_f32[q2[4] >> 4 ], shmem_f32[q2[5] >> 4 ], shmem_f32[q2[6] >> 4 ], shmem_f32[q2[7] >> 4 ]); 3091 3092 acc1 = (acc1 + acc3) + (acc2 + acc4); 3093 3094 sumf[row] += e8m0_to_fp32(xb.e) * ((acc1[0] + acc1[1]) + (acc1[2] + acc1[3])); 3095 } 3096 3097 yb += 16 * QK_MXFP4; 3098 } 3099 3100 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 3101 3102 for (int row = 0; row < NR0 && first_row + row < args.ne0; ++row) { 3103 float sum_all = simd_sum(sumf[row]); 3104 if (tiisg == 0) { 3105 dst_f32[first_row + row] = sum_all; 3106 } 3107 } 3108} 3109 3110[[host_name("kernel_mul_mv_mxfp4_f32")]] 3111kernel void kernel_mul_mv_mxfp4_f32( 3112 constant ggml_metal_kargs_mul_mv & args, 3113 device const char * src0, 3114 device const char * src1, 3115 device char * dst, 3116 threadgroup char * shmem [[threadgroup(0)]], 3117 uint3 tgpig[[threadgroup_position_in_grid]], 3118 ushort tiisg[[thread_index_in_simdgroup]], 3119 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 3120 3121 kernel_mul_mv_mxfp4_f32_impl<N_R0_MXFP4, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 3122} 3123 3124template<int nr0, typename args_t> 3125void kernel_mul_mv_tq2_0_f32_impl( 3126 args_t args, 3127 device const char * src0, 3128 device const char * src1, 3129 device char * dst, 3130 threadgroup char * shmem, 3131 uint3 tgpig, 3132 ushort tiisg, 3133 ushort sgitg) { 3134 const short NSG = FC_mul_mv_nsg; 3135 3136 const int nb = args.ne00/QK_K; 3137 3138 const int r0 = tgpig.x; 3139 const int r1 = tgpig.y; 3140 const int im = tgpig.z; 3141 3142 const int first_row = (r0 * NSG + sgitg) * nr0; 3143 3144 const uint i12 = im%FC_mul_mv_ne12; 3145 const uint i13 = im/FC_mul_mv_ne12; 3146 3147 const uint64_t offset1 = r1*args.nb11 + (i12 )*args.nb12 + (i13 )*args.nb13; 3148 3149 device const float * y = (device const float *) (src1 + offset1); 3150 3151 device const block_tq2_0 * ax[nr0]; 3152 for (int row = 0; row < nr0; ++row) { 3153 const uint64_t offset0 = (first_row + row)*args.nb01 + (i12/FC_mul_mv_r2)*args.nb02 + (i13/FC_mul_mv_r3)*args.nb03; 3154 ax[row] = (device const block_tq2_0 *) ((device char *) src0 + offset0); 3155 } 3156 3157 float sumf[nr0] = {0.f}; 3158 3159 // 8 threads per block, NBLOCK blocks per pass, 2 halves per block per pass 3160 constexpr short NBLOCK = 4; 3161 3162 constexpr short NB = N_SIMDWIDTH/NBLOCK; // threads per block 3163 3164 const short blk = tiisg / NB; // 0..NBLOCK-1, block handled by this thread 3165 const short htg = tiisg % NB; // 0..NB-1, thread within block (0..7) 3166 3167 // byte and y base offsets within the block (32 elements per thread, 4 per byte) 3168 device const float4 * yb4 = (device const float4 *)(y + 4*htg + blk*QK_K); 3169 3170 // hoisted per-byte coefficients (from y) and total y-sum, shared across rows 3171 // ref: https://github.com/ggml-org/llama.cpp/pull/26980 3172 float4 coef[4]; 3173 3174 for (int ib = blk; ib < nb; ib += NBLOCK) { 3175 FOR_UNROLL (short h0 = 0; h0 < 2; ++h0) { 3176 const float4 y0 = yb4[ 0 + 32*h0]; 3177 const float4 y1 = yb4[ 8 + 32*h0]; 3178 const float4 y2 = yb4[16 + 32*h0]; 3179 const float4 y3 = yb4[24 + 32*h0]; 3180 3181 float sumy = 0.f; 3182 FOR_UNROLL (short j = 0; j < 4; ++j) { 3183 coef[j] = float4( 3184 y0[j], 3185 y1[j] - 4.0f*y0[j], 3186 y2[j] - 4.0f*y1[j], 3187 y3[j] - 4.0f*y2[j]); 3188 3189 sumy += (y0[j] + y1[j]) + (y2[j] + y3[j]); 3190 } 3191 3192 FOR_UNROLL (short row = 0; row < nr0; ++row) { 3193 device const block_tq2_0 & xb = ax[row][ib]; 3194 device const uchar * qs = xb.qs + 4*htg + 32*h0; 3195 3196 float sum = -sumy; 3197 FOR_UNROLL (short j = 0; j < 4; ++j) { 3198 // express the 2-bit field shifts (v>>2, v>>4, v>>6) as float floor ops 3199 const float v = (float)qs[j]; 3200 3201 const float f0 = v; 3202 const float f1 = floor(v*0.25f); // v>>2 3203 const float f2 = floor(v*0.0625); // v>>4 3204 const float f3 = floor(v*0.015625); // v>>6 3205 3206 sum += coef[j][0]*f0 + coef[j][1]*f1 + coef[j][2]*f2 + coef[j][3]*f3; 3207 } 3208 3209 sumf[row] += xb.d * sum; 3210 } 3211 } 3212 3213 yb4 += QK_K * NBLOCK / 4; 3214 } 3215 3216 device float * dst_f32 = (device float *) dst + (uint64_t)im*args.ne0*args.ne1 + (uint64_t)r1*args.ne0; 3217 3218 for (int row = 0; row < nr0; ++row) { 3219 const float tot = simd_sum(sumf[row]); 3220 if (tiisg == 0 && first_row + row < args.ne01) { 3221 dst_f32[first_row + row] = tot; 3222 } 3223 } 3224} 3225 3226[[host_name("kernel_mul_mv_tq2_0_f32")]] 3227kernel void kernel_mul_mv_tq2_0_f32( 3228 constant ggml_metal_kargs_mul_mv & args, 3229 device const char * src0, 3230 device const char * src1, 3231 device char * dst, 3232 uint3 tgpig[[threadgroup_position_in_grid]], 3233 ushort tiisg[[thread_index_in_simdgroup]], 3234 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 3235 3236 kernel_mul_mv_tq2_0_f32_impl<N_R0_TQ2_0, constant ggml_metal_kargs_mul_mv &>(args, src0, src1, dst, nullptr, tgpig, tiisg, sgitg); 3237} 3238 3239// 3240// matrix-vector multiplication 3241// 3242 3243typedef void (kernel_mul_mv_disp_t)( 3244 ggml_metal_kargs_mul_mv args, 3245 device const char * src0, 3246 device const char * src1, 3247 device char * dst, 3248 uint3 tgpig, 3249 ushort tiisg); 3250 3251typedef void (kernel_mul_mv2_disp_t)( 3252 ggml_metal_kargs_mul_mv args, 3253 device const char * src0, 3254 device const char * src1, 3255 device char * dst, 3256 threadgroup char * shmem, 3257 uint3 tgpig, 3258 ushort tiisg, 3259 ushort sgitg); 3260 3261template<kernel_mul_mv_disp_t disp_fn> 3262void mmv_fn( 3263 ggml_metal_kargs_mul_mv args, 3264 device const char * src0, 3265 device const char * src1, 3266 device char * dst, 3267 threadgroup char * shmem, 3268 uint3 tgpig, 3269 ushort tiitg, 3270 ushort tiisg, 3271 ushort sgitg) { 3272 disp_fn(args, src0, src1, dst, tgpig, tiisg); 3273} 3274 3275template<kernel_mul_mv2_disp_t disp_fn> 3276void mmv_fn( 3277 ggml_metal_kargs_mul_mv args, 3278 device const char * src0, 3279 device const char * src1, 3280 device char * dst, 3281 threadgroup char * shmem, 3282 uint3 tgpig, 3283 ushort tiitg, 3284 ushort tiisg, 3285 ushort sgitg) { 3286 disp_fn(args, src0, src1, dst, shmem, tgpig, tiisg, sgitg); 3287} 3288 3289typedef decltype(mmv_fn<kernel_mul_mv_t_t_disp<half, half, ggml_metal_kargs_mul_mv>>) mul_mv_disp_fn_t; 3290 3291template<mul_mv_disp_fn_t disp_fn> 3292kernel void kernel_mul_mv_id( 3293 constant ggml_metal_kargs_mul_mv_id & args, 3294 device const char * src0s, 3295 device const char * src1, 3296 device char * dst, 3297 device const char * ids, 3298 threadgroup char * shmem [[threadgroup(0)]], 3299 uint3 tgpig[[threadgroup_position_in_grid]], 3300 ushort tiitg[[thread_index_in_threadgroup]], 3301 ushort tiisg[[thread_index_in_simdgroup]], 3302 ushort sgitg[[simdgroup_index_in_threadgroup]]) { 3303 const int iid1 = tgpig.z/args.nei0; 3304 const int idx = tgpig.z%args.nei0; 3305 3306 tgpig.z = 0; 3307 3308 const int32_t i02 = ((device const int32_t *) (ids + iid1*args.nbi1))[idx]; 3309 3310 const int64_t i11 = idx % args.ne11; 3311 const int64_t i12 = iid1; 3312 3313 const int64_t i1 = idx; 3314 const int64_t i2 = i12; 3315 3316 device const char * src0_cur = src0s + i02*args.nb02; 3317 device const char * src1_cur = src1 + i11*args.nb11 + i12*args.nb12; 3318 3319 device char * dst_cur = dst + (i1*args.ne0 + i2*args.ne1*args.ne0)*sizeof(float); 3320 3321 ggml_metal_kargs_mul_mv args0 = { 3322 /*.ne00 =*/ args.ne00, 3323 /*.ne01 =*/ args.ne01, 3324 /*.ne02 =*/ 1, // args.ne02, 3325 /*.nb00 =*/ args.nb00, 3326 /*.nb01 =*/ args.nb01, 3327 /*.nb02 =*/ args.nb02, 3328 /*.nb03 =*/ args.nb02, // args.ne02 == 1 3329 /*.ne10 =*/ args.ne10, 3330 /*.ne11 =*/ 1, // args.ne11, 3331 /*.ne12 =*/ 1, // args.ne12, 3332 /*.nb10 =*/ args.nb10, 3333 /*.nb11 =*/ args.nb11, 3334 /*.nb12 =*/ args.nb12, 3335 /*.nb13 =*/ args.nb12, // ne12 == 1 3336 /*.ne0 =*/ args.ne0, 3337 /*.ne1 =*/ 1, // args.ne1, 3338 /*.nr0 =*/ args.nr0, 3339 /*.r2 =*/ 1, 3340 /*.r3 =*/ 1, 3341 }; 3342 3343 disp_fn( 3344 args0, 3345 /* src0 */ src0_cur, 3346 /* src1 */ src1_cur, 3347 /* dst */ dst_cur, 3348 shmem, 3349 tgpig, 3350 tiitg, 3351 tiisg, 3352 sgitg); 3353} 3354 3355typedef decltype(kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_disp<float, float>>>) kernel_mul_mv_id_t; 3356 3357typedef decltype(kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_4_disp<float, float4, float, float4>>>) kernel_mul_mv_id_4_t; 3358 3359template [[host_name("kernel_mul_mv_id_f32_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_disp<float, float>>>; 3360template [[host_name("kernel_mul_mv_id_f16_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_disp<half, float>>>; 3361#if defined(GGML_METAL_HAS_BF16) 3362template [[host_name("kernel_mul_mv_id_bf16_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_disp<bfloat, float>>>; 3363#endif 3364template [[host_name("kernel_mul_mv_id_f32_f32_4")]] kernel kernel_mul_mv_id_4_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_4_disp<float, float4, float, float4>>>; 3365template [[host_name("kernel_mul_mv_id_f16_f32_4")]] kernel kernel_mul_mv_id_4_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_4_disp<half, half4, float, float4>>>; 3366#if defined(GGML_METAL_HAS_BF16) 3367template [[host_name("kernel_mul_mv_id_bf16_f32_4")]] kernel kernel_mul_mv_id_4_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_t_t_4_disp<bfloat, bfloat4, float, float4>>>; 3368#endif 3369 3370template [[host_name("kernel_mul_mv_id_q8_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q8_0_f32_impl<N_R0_Q8_0>>>; 3371 3372template [[host_name("kernel_mul_mv_id_q1_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q1_0_f32_impl<N_R0_Q1_0>>>; 3373template [[host_name("kernel_mul_mv_id_q2_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q2_0_f32_impl<N_R0_Q2_0>>>; 3374template [[host_name("kernel_mul_mv_id_q4_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<mul_vec_q_n_f32_impl<block_q4_0, N_R0_Q4_0>>>; 3375template [[host_name("kernel_mul_mv_id_q4_1_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<mul_vec_q_n_f32_impl<block_q4_1, N_R0_Q4_1>>>; 3376template [[host_name("kernel_mul_mv_id_q5_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<mul_vec_q_n_f32_impl<block_q5_0, N_R0_Q5_0>>>; 3377template [[host_name("kernel_mul_mv_id_q5_1_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<mul_vec_q_n_f32_impl<block_q5_1, N_R0_Q5_1>>>; 3378 3379template [[host_name("kernel_mul_mv_id_mxfp4_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_mxfp4_f32_impl<N_R0_MXFP4>>>; 3380 3381template [[host_name("kernel_mul_mv_id_q2_K_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q2_K_f32_impl <N_R0_Q2_K>>>; 3382template [[host_name("kernel_mul_mv_id_q3_K_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q3_K_f32_impl <N_R0_Q3_K>>>; 3383template [[host_name("kernel_mul_mv_id_q4_K_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q4_K_f32_impl <N_R0_Q4_K>>>; 3384template [[host_name("kernel_mul_mv_id_q5_K_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q5_K_f32_impl <N_R0_Q5_K>>>; 3385template [[host_name("kernel_mul_mv_id_q6_K_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_q6_K_f32_impl <N_R0_Q6_K>>>; 3386template [[host_name("kernel_mul_mv_id_iq1_s_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq1_s_f32_disp<ggml_metal_kargs_mul_mv>>>; 3387template [[host_name("kernel_mul_mv_id_iq1_m_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq1_m_f32_disp<ggml_metal_kargs_mul_mv>>>; 3388template [[host_name("kernel_mul_mv_id_iq2_xxs_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq2_xxs_f32_disp<ggml_metal_kargs_mul_mv>>>; 3389template [[host_name("kernel_mul_mv_id_iq2_xs_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq2_xs_f32_disp<ggml_metal_kargs_mul_mv>>>; 3390template [[host_name("kernel_mul_mv_id_iq3_xxs_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq3_xxs_f32_disp<ggml_metal_kargs_mul_mv>>>; 3391template [[host_name("kernel_mul_mv_id_iq3_s_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq3_s_f32_disp<ggml_metal_kargs_mul_mv>>>; 3392template [[host_name("kernel_mul_mv_id_iq2_s_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq2_s_f32_disp<ggml_metal_kargs_mul_mv>>>; 3393template [[host_name("kernel_mul_mv_id_iq4_nl_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq4_nl_f32_impl <N_R0_IQ4_NL>>>; 3394template [[host_name("kernel_mul_mv_id_iq4_xs_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_iq4_xs_f32_impl <N_R0_IQ4_XS>>>; 3395template [[host_name("kernel_mul_mv_id_tq2_0_f32")]] kernel kernel_mul_mv_id_t kernel_mul_mv_id<mmv_fn<kernel_mul_mv_tq2_0_f32_impl <N_R0_TQ2_0>>>;