char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
867229003
char/aliceai-t5-moe
1#include "convert.hpp" 2#include "dmmv.hpp" 3#include "dequantize.hpp" 4#include "presets.hpp" 5 6#if defined(__INTEL_LLVM_COMPILER ) 7#if __has_include (< sycl /ext /oneapi /bfloat16 .hpp > ) 8#include <sycl/ext/oneapi/bfloat16.hpp> 9#define GGML_SYCL_DMMV_HAS_BF16 10#endif 11#include <sycl/ext/intel/esimd.hpp> 12#include "esimd.hpp" 13#define GGML_SYCL_DMMV_HAS_ESIMD 14#endif 15 16static void convert_f16 (const void * vx ,const int64_t ib ,const int iqs ,dfloat2 & v ){ 17const sycl::half * x = (const sycl::half * )vx ; 18 19// automatic half -> float type cast if dfloat == float 20v .x ()= x [ib + iqs + 0 ]; 21v .y ()= x [ib + iqs + 1 ]; 22} 23 24#ifdef GGML_SYCL_DMMV_HAS_BF16 25static void convert_bf16 (const void * vx ,const int64_t ib ,const int iqs ,dfloat2 & v ){ 26const sycl::ext::oneapi::bfloat16 * x = (const sycl::ext::oneapi::bfloat16 * )vx ; 27 28// automatic bfloat16 -> float type cast if dfloat == float 29v .x ()= x [ib + iqs + 0 ]; 30v .y ()= x [ib + iqs + 1 ]; 31} 32#endif 33 34static void convert_f32 (const void * vx ,const int64_t ib ,const int iqs ,dfloat2 & v ){ 35const float * x = (const float * )vx ; 36 37// automatic half -> float type cast if dfloat == float 38v .x ()= x [ib + iqs + 0 ]; 39v .y ()= x [ib + iqs + 1 ]; 40} 41 42template < int qk ,int qr ,dequantize_kernel_t dequantize_kernel > 43static void dequantize_mul_mat_vec (const void * __restrict__vx ,const dfloat * __restrict__y ,float * __restrict__dst ,const int ncols ,const int nrows , 44const sycl::nd_item < 3 > & item_ct1 ) { 45// qk = quantized weights per x block 46// qr = number of quantized weights per data value in x block 47const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 48item_ct1 .get_local_id (1 ); 49 50if (row >=nrows ) { 51return ; 52 } 53 54const int tid = item_ct1 .get_local_id (2 ); 55 56const int iter_stride = 2 * GGML_SYCL_DMMV_X ; 57const int vals_per_iter = iter_stride /WARP_SIZE ;// num quantized vals per thread and i iter 58const int y_offset = qr == 1 ?1 :qk /2 ; 59 60// partial sum for each thread 61#ifdef GGML_SYCL_F16 62 sycl::half2 tmp = {0.0f ,0.0f };// two sums for f16 to take advantage of half2 intrinsics 63#else 64float tmp = 0.0f ; 65#endif // GGML_SYCL_F16 66 67for (int i = 0 ;i < ncols ;i += iter_stride ) { 68const int col = i + vals_per_iter * tid ; 69const int ib = (row * ncols + col )/qk ;// x block index 70const int iqs = (col %qk )/qr ;// x quant index 71const int iybs = col - col %qk ;// y block start index 72 73// processing >2 values per i iter is faster for fast GPUs 74#pragma unroll 75for (int j = 0 ;j < vals_per_iter ;j += 2 ) { 76// process 2 vals per j iter 77 78// dequantize 79// for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val 80dfloat2 v ; 81dequantize_kernel (vx ,ib ,iqs + j /qr ,v ); 82 83// matrix multiplication 84// for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2 85#ifdef GGML_SYCL_F16 86dfloat2 t1 {y [iybs + iqs + j /qr + 0 ], 87y [iybs + iqs + j /qr + y_offset ]}; 88 89tmp += v * t1 ; 90#else 91tmp += v .x ()* y [iybs + iqs + j /qr + 0 ]; 92tmp += v .y ()* y [iybs + iqs + j /qr + y_offset ]; 93#endif // GGML_SYCL_F16 94 } 95 } 96 97// sum up partial sums and write back result 98const int mask_start = ncols > GGML_SYCL_DMMV_X ?WARP_SIZE >>1 :WARP_SIZE >>2 ; 99for (int mask = mask_start ;mask > 0 ;mask >>=1 ) { 100tmp += 101 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 102 } 103 104if (tid == 0 ) { 105#ifdef GGML_SYCL_F16 106dst [row ]= tmp .x ()+ tmp .y (); 107#else 108dst [row ]= tmp ; 109#endif // GGML_SYCL_F16 110 } 111} 112 113template < int qk ,int qr ,dequantize_kernel_t_reorder dequantize_kernel_reorder > 114static void dequantize_mul_mat_vec_reorder (const void * __restrict__vx ,const dfloat * __restrict__y ,float * __restrict__dst ,const int ncols ,const int nrows , 115const sycl::nd_item < 3 > & item_ct1 ) { 116// qk = quantized weights per x block 117// qr = number of quantized weights per data value in x block 118const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 119item_ct1 .get_local_id (1 ); 120 121if (row >=nrows ) { 122return ; 123 } 124 125const int tid = item_ct1 .get_local_id (2 ); 126 127 128const int ncols_left = ncols % (QK4_0 * WARP_SIZE ); 129const int ncols_align = ncols - ncols_left ; 130const int iter_stride = 8 * 2 * GGML_SYCL_DMMV_X ; 131const int vals_per_iter = iter_stride /WARP_SIZE ;// num quantized vals per thread and i iter //64/16=4, 512/16/2= 16 132const int y_offset = qr == 1 ?1 :qk /2 ; 133 134// partial sum for each thread 135#ifdef GGML_SYCL_F16 136 sycl::half2 tmp = {0.0f ,0.0f };// two sums for f16 to take advantage of half2 intrinsics 137#else 138float tmp = 0.0f ; 139#endif // GGML_SYCL_F16 140const char * d_ptr = (const char * )vx + ncols * nrows /2 ; 141int i = 0 ; 142for (i = 0 ;i < ncols_align ;i += iter_stride ) { 143const int col = i + vals_per_iter * tid ; 144const int ib = (row * ncols + col )/qk ;// x block index 145const int iqs = (col %qk )/qr ;// x quant index 146const int iybs = col - col %qk ;// y block start index 147 148// processing >2 values per i iter is faster for fast GPUs 149#pragma unroll 150for (int j = 0 ;j < vals_per_iter ;j += 2 ) { 151// process 2 vals per j iter 152 153// dequantize 154// for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val 155dfloat2 v ; 156dequantize_kernel_reorder ((const void * )d_ptr ,ib , (const void * )vx ,ib * QK4_0 /2 + iqs + j /qr ,v ); 157 158// matrix multiplication 159// for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2 160#ifdef GGML_SYCL_F16 161dfloat2 t1 {y [iybs + iqs + j /qr + 0 ], 162y [iybs + iqs + j /qr + y_offset ]}; 163 164tmp += v * t1 ; 165#else 166tmp += v .x ()* y [iybs + iqs + j /qr + 0 ]; 167tmp += v .y ()* y [iybs + iqs + j /qr + y_offset ]; 168#endif // GGML_SYCL_F16 169 } 170 } 171 172for (;i < ncols ;i += iter_stride ) { 173if (tid >=ncols_left /QK4_0 )continue ; 174const int col = i + vals_per_iter * tid ; 175const int ib = (row * ncols + col )/qk ;// x block index 176const int iqs = (col %qk )/qr ;// x quant index 177const int iybs = col - col %qk ;// y block start index 178 179// processing >2 values per i iter is faster for fast GPUs 180#pragma unroll 181for (int j = 0 ;j < vals_per_iter ;j += 2 ) { 182// process 2 vals per j iter 183 184// dequantize 185// for qr = 2 the iqs needs to increase by 1 per j iter because 2 weights per data val 186dfloat2 v ; 187dequantize_kernel_reorder ((const void * )d_ptr ,ib , (const void * )vx ,ib * QK4_0 /2 + iqs + j /qr ,v ); 188 189// matrix multiplication 190// for qr = 2 the y index needs to increase by 1 per j iter because of y_offset = qk/2 191#ifdef GGML_SYCL_F16 192dfloat2 t1 {y [iybs + iqs + j /qr + 0 ], 193y [iybs + iqs + j /qr + y_offset ]}; 194 195tmp += v * t1 ; 196#else 197tmp += v .x ()* y [iybs + iqs + j /qr + 0 ]; 198tmp += v .y ()* y [iybs + iqs + j /qr + y_offset ]; 199#endif // GGML_SYCL_F16 200 } 201 } 202 203// sum up partial sums and write back result 204const int mask_start = ncols > GGML_SYCL_DMMV_X ?WARP_SIZE >>1 :WARP_SIZE >>2 ; 205for (int mask = mask_start ;mask > 0 ;mask >>=1 ) { 206tmp += 207 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 208 } 209 210if (tid == 0 ) { 211#ifdef GGML_SYCL_F16 212dst [row ]= tmp .x ()+ tmp .y (); 213#else 214dst [row ]= tmp ; 215#endif // GGML_SYCL_F16 216 } 217} 218 219static void convert_mul_mat_vec_f16_sycl (const void * vx ,const dfloat * y , 220float * dst ,const int ncols , 221const int nrows , 222 dpct::queue_ptr stream ) { 223GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 224const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 225const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 226const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 227 { 228 dpct::has_capability_or_fail (stream -> get_device (), 229 {sycl::aspect::fp16 }); 230 231stream -> parallel_for ( 232 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 233 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 234dequantize_mul_mat_vec < 1 ,1 ,convert_f16 > (vx ,y ,dst ,ncols , 235nrows ,item_ct1 ); 236 }); 237 } 238} 239 240#ifdef GGML_SYCL_DMMV_HAS_BF16 241static void convert_mul_mat_vec_bf16_sycl (const void * vx ,const dfloat * y , 242float * dst ,const int ncols , 243const int nrows , 244 dpct::queue_ptr stream ) { 245// The qk=1 kernel iterates with stride 2*GGML_SYCL_DMMV_X, so ncols must be a 246// multiple of that — not just GGML_SYCL_DMMV_X — to avoid out-of-bounds reads. 247GGML_ASSERT (ncols % (2 * GGML_SYCL_DMMV_X )== 0 ); 248const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 249const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 250const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 251 { 252stream -> parallel_for ( 253 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 254 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 255dequantize_mul_mat_vec < 1 ,1 ,convert_bf16 > (vx ,y ,dst ,ncols , 256nrows ,item_ct1 ); 257 }); 258 } 259} 260#endif 261 262static void dequantize_mul_mat_vec_q2_k (const void * __restrict__vx , 263const float * __restrict__yy , 264float * __restrict__dst , 265const int ncols ,int nrows , 266const sycl::nd_item < 3 > & item_ct1 ) { 267 268 static_assert(16 %K_QUANTS_PER_ITERATION == 0 ,"16 must be divisible by K_QUANTS_PER_ITERATION" ); 269 270const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 271item_ct1 .get_local_id (1 ); 272if (row >=nrows )return ; 273 274const int num_blocks_per_row = ncols /QK_K ; 275const int ib0 = row * num_blocks_per_row ; 276 277const block_q2_K * x = (const block_q2_K * )vx + ib0 ; 278 279float tmp = 0 ;// partial sum for thread in warp 280 281#if QK_K == 256 282const int tid = 283item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 284const int ix = 285item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 286 287const int step = 16 /K_QUANTS_PER_ITERATION ; 288 289const int in = tid %step ;// 0...15 or 0...7 290 291const int l0 = K_QUANTS_PER_ITERATION * in ;// 0...15 or 0...14 in steps of 2 292 293uint32_t aux [4 ]; 294const uint8_t * d = (const uint8_t * )aux ; 295const uint8_t * m = (const uint8_t * )(aux + 2 ); 296 297for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 298 299const float dall = x [i ].dm [0 ]; 300const float dmin = x [i ].dm [1 ]; 301 302for (int im = 0 ;im < 2 ;++ im ) { 303const int q_offset = 32 * im + l0 ; 304const int s_offset = 8 * im ; 305const int y_offset = 128 * im + l0 ; 306 307const float * y = yy + i * QK_K + y_offset ; 308const uint8_t * q = x [i ].qs + q_offset ; 309 310const uint32_t * a = (const uint32_t * )(x [i ].scales + s_offset ); 311aux [0 ]= a [0 ]& 0x0f0f0f0f ; 312aux [1 ]= a [1 ]& 0x0f0f0f0f ; 313aux [2 ]= (a [0 ] >>4 )& 0x0f0f0f0f ; 314aux [3 ]= (a [1 ] >>4 )& 0x0f0f0f0f ; 315 316float sum1 = 0 ,sum2 = 0 ; 317for (int l = 0 ;l < K_QUANTS_PER_ITERATION ;++ l ) { 318sum1 += y [l + 0 ]* d [0 ]* ((q [l + 0 ] >>0 )& 3 ) 319+ y [l + 32 ]* d [2 ]* ((q [l + 0 ] >>2 )& 3 ) 320+ y [l + 64 ]* d [4 ]* ((q [l + 0 ] >>4 )& 3 ) 321+ y [l + 96 ]* d [6 ]* ((q [l + 0 ] >>6 )& 3 ) 322+ y [l + 16 ]* d [1 ]* ((q [l + 16 ] >>0 )& 3 ) 323+ y [l + 48 ]* d [3 ]* ((q [l + 16 ] >>2 )& 3 ) 324+ y [l + 80 ]* d [5 ]* ((q [l + 16 ] >>4 )& 3 ) 325+ y [l + 112 ]* d [7 ]* ((q [l + 16 ] >>6 )& 3 ); 326sum2 += y [l + 0 ]* m [0 ]+ y [l + 32 ]* m [2 ]+ y [l + 64 ]* m [4 ]+ y [l + 96 ]* m [6 ] 327+ y [l + 16 ]* m [1 ]+ y [l + 48 ]* m [3 ]+ y [l + 80 ]* m [5 ]+ y [l + 112 ]* m [7 ]; 328 329 } 330tmp += dall * sum1 - dmin * sum2 ; 331 } 332 333 } 334#else 335const int tid = item_ct1 .get_local_id (2 ) / 336 (2 * K_QUANTS_PER_ITERATION );// 0...15 or 0...7 337const int ix = item_ct1 .get_local_id (2 ) % 338 (2 * K_QUANTS_PER_ITERATION );// 0....1 or 0...3 339const int offset = tid * K_QUANTS_PER_ITERATION ; 340 341uint32_t uaux [2 ]; 342const uint8_t * d = (const uint8_t * )uaux ; 343 344 345for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 346 347const float * y = yy + i * QK_K + offset ; 348const uint8_t * q = x [i ].qs + offset ; 349const uint32_t * s = (const uint32_t * )x [i ].scales ; 350 351uaux [0 ]= s [0 ]& 0x0f0f0f0f ; 352uaux [1 ]= (s [0 ] >>4 )& 0x0f0f0f0f ; 353 354const sycl::float2 dall = 355x [i ].dm .convert < float , sycl::rounding_mode::automatic > (); 356 357float sum1 = 0 ,sum2 = 0 ; 358for (int l = 0 ;l < K_QUANTS_PER_ITERATION ;++ l ) { 359const uint8_t ql = q [l ]; 360sum1 += y [l + 0 ]* d [0 ]* ((ql >>0 )& 3 ) 361+ y [l + 16 ]* d [1 ]* ((ql >>2 )& 3 ) 362+ y [l + 32 ]* d [2 ]* ((ql >>4 )& 3 ) 363+ y [l + 48 ]* d [3 ]* ((ql >>6 )& 3 ); 364sum2 += y [l + 0 ]* d [4 ]+ y [l + 16 ]* d [5 ]+ y [l + 32 ]* d [6 ]+ y [l + 48 ]* d [7 ]; 365 } 366tmp += dall .x ()* sum1 - dall .y ()* sum2 ; 367 } 368 369#endif 370 371// sum up partial sums and write back result 372#pragma unroll 373for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 374tmp += 375 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 376 } 377 378if (item_ct1 .get_local_id (2 )== 0 ) { 379dst [row ]= tmp ; 380 } 381} 382 383static void dequantize_mul_mat_vec_q2_k_reorder (const void * __restrict__vx , 384const float * __restrict__yy , 385float * __restrict__dst , 386const int ncols ,int nrows , 387const sycl::nd_item < 3 > & item_ct1 ) { 388 389 static_assert(16 %K_QUANTS_PER_ITERATION == 0 ,"16 must be divisible by K_QUANTS_PER_ITERATION" ); 390 391const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 392item_ct1 .get_local_id (1 ); 393if (row >=nrows )return ; 394 395const int num_blocks_per_row = ncols /QK_K ; 396const int ib0 = row * num_blocks_per_row ; 397 398// SOA base pointers for the reordered layout: 399// [qs: nb * (QK_K/4)] [scales: nb * (QK_K/16)] [dm: nb * sizeof(half2)] 400const int nb = nrows * num_blocks_per_row ; 401const uint8_t * qs_base = (const uint8_t * )vx ; 402const uint8_t * scales_base = qs_base + (size_t )nb * (QK_K /4 ); 403const sycl::half2 * dm_base = (const sycl::half2 * )(scales_base + (size_t )nb * (QK_K /16 )); 404 405float tmp = 0 ;// partial sum for thread in warp 406 407#if QK_K == 256 408const int tid = 409item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 410const int ix = 411item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 412 413const int step = 16 /K_QUANTS_PER_ITERATION ; 414 415const int in = tid %step ;// 0...15 or 0...7 416 417const int l0 = K_QUANTS_PER_ITERATION * in ;// 0...15 or 0...14 in steps of 2 418 419uint32_t aux [4 ]; 420const uint8_t * d = (const uint8_t * )aux ; 421const uint8_t * m = (const uint8_t * )(aux + 2 ); 422 423for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 424const int bi = ib0 + i ; 425 426const sycl::half2 dm_val = dm_base [bi ]; 427const float dall = dm_val [0 ]; 428const float dmin = dm_val [1 ]; 429 430for (int im = 0 ;im < 2 ;++ im ) { 431const int q_offset = 32 * im + l0 ; 432const int s_offset = 8 * im ; 433const int y_offset = 128 * im + l0 ; 434 435const float * y = yy + i * QK_K + y_offset ; 436const uint8_t * q = qs_base + bi * (QK_K /4 )+ q_offset ; 437 438const uint32_t * a = (const uint32_t * )(scales_base + bi * (QK_K /16 )+ s_offset ); 439aux [0 ]= a [0 ]& 0x0f0f0f0f ; 440aux [1 ]= a [1 ]& 0x0f0f0f0f ; 441aux [2 ]= (a [0 ] >>4 )& 0x0f0f0f0f ; 442aux [3 ]= (a [1 ] >>4 )& 0x0f0f0f0f ; 443 444float sum1 = 0 ,sum2 = 0 ; 445for (int l = 0 ;l < K_QUANTS_PER_ITERATION ;++ l ) { 446sum1 += y [l + 0 ]* d [0 ]* ((q [l + 0 ] >>0 )& 3 ) 447+ y [l + 32 ]* d [2 ]* ((q [l + 0 ] >>2 )& 3 ) 448+ y [l + 64 ]* d [4 ]* ((q [l + 0 ] >>4 )& 3 ) 449+ y [l + 96 ]* d [6 ]* ((q [l + 0 ] >>6 )& 3 ) 450+ y [l + 16 ]* d [1 ]* ((q [l + 16 ] >>0 )& 3 ) 451+ y [l + 48 ]* d [3 ]* ((q [l + 16 ] >>2 )& 3 ) 452+ y [l + 80 ]* d [5 ]* ((q [l + 16 ] >>4 )& 3 ) 453+ y [l + 112 ]* d [7 ]* ((q [l + 16 ] >>6 )& 3 ); 454sum2 += y [l + 0 ]* m [0 ]+ y [l + 32 ]* m [2 ]+ y [l + 64 ]* m [4 ]+ y [l + 96 ]* m [6 ] 455+ y [l + 16 ]* m [1 ]+ y [l + 48 ]* m [3 ]+ y [l + 80 ]* m [5 ]+ y [l + 112 ]* m [7 ]; 456 457 } 458tmp += dall * sum1 - dmin * sum2 ; 459 } 460 } 461#else 462GGML_UNUSED (vx ); 463GGML_UNUSED (yy ); 464GGML_UNUSED (ncols ); 465GGML_UNUSED (item_ct1 ); 466GGML_ABORT ("Q2_K reorder DMMV not supported for QK_K != 256" ); 467#endif 468 469// sum up partial sums and write back result 470#pragma unroll 471for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 472tmp += 473 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 474 } 475 476if (item_ct1 .get_local_id (2 )== 0 ) { 477dst [row ]= tmp ; 478 } 479} 480 481static void dequantize_mul_mat_vec_q3_k (const void * __restrict__vx , 482const float * __restrict__yy , 483float * __restrict__dst , 484const int ncols ,int nrows , 485const sycl::nd_item < 3 > & item_ct1 ) { 486 487const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 488item_ct1 .get_local_id (1 ); 489if (row >=nrows )return ; 490 491const int num_blocks_per_row = ncols /QK_K ; 492const int ib0 = row * num_blocks_per_row ; 493 494const block_q3_K * x = (const block_q3_K * )vx + ib0 ; 495 496float tmp = 0 ;// partial sum for thread in warp 497 498#if QK_K == 256 499 500const uint16_t kmask1 = 0x0303 ; 501const uint16_t kmask2 = 0x0f0f ; 502 503const int tid = 504item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 505const int ix = 506item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 507 508const int n = K_QUANTS_PER_ITERATION ;// iterations in the inner loop 509const int step = 16 /K_QUANTS_PER_ITERATION ; 510const int in = tid %step ;// 0...15 or 0...7 511 512const int l0 = n * in ;// 0...15 or 0...14 in steps of 2 513 514uint16_t utmp [4 ]; 515const int8_t * s = (const int8_t * )utmp ; 516 517for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 518 519const uint8_t * h = x [i ].hmask + l0 ; 520const float d = x [i ].d ; 521 522for (int im = 0 ;im < 2 ;++ im ) { 523const int q_offset = 32 * im + l0 ; 524const int y_offset = 128 * im + l0 ; 525const uint16_t s_shift = 4 * im ; 526const uint8_t m = 1 << (4 * im ); 527 528const float * y = yy + i * QK_K + y_offset ; 529const uint8_t * q = x [i ].qs + q_offset ; 530 531const uint16_t * a = (const uint16_t * )x [i ].scales ; 532utmp [0 ]= ((a [0 ] >>s_shift )& kmask2 ) | (((a [4 ] >> (s_shift + 0 ))& kmask1 ) <<4 ); 533utmp [1 ]= ((a [1 ] >>s_shift )& kmask2 ) | (((a [5 ] >> (s_shift + 0 ))& kmask1 ) <<4 ); 534utmp [2 ]= ((a [2 ] >>s_shift )& kmask2 ) | (((a [4 ] >> (s_shift + 2 ))& kmask1 ) <<4 ); 535utmp [3 ]= ((a [3 ] >>s_shift )& kmask2 ) | (((a [5 ] >> (s_shift + 2 ))& kmask1 ) <<4 ); 536 537float sum = 0 ; 538for (int l = 0 ;l < n ;++ l ) { 539sum += y [l + 0 ]* (s [0 ]- 32 )* (((q [l ] >>0 )& 3 )- (h [l ]& (m <<0 ) ?0 :4 )) 540+ y [l + 32 ]* (s [2 ]- 32 )* (((q [l ] >>2 )& 3 )- (h [l ]& (m <<1 ) ?0 :4 )) 541+ y [l + 64 ]* (s [4 ]- 32 )* (((q [l ] >>4 )& 3 )- (h [l ]& (m <<2 ) ?0 :4 )) 542+ y [l + 96 ]* (s [6 ]- 32 )* (((q [l ] >>6 )& 3 )- (h [l ]& (m <<3 ) ?0 :4 )); 543sum += y [l + 16 ]* (s [1 ]- 32 )* (((q [l + 16 ] >>0 )& 3 )- (h [l + 16 ]& (m <<0 ) ?0 :4 )) 544+ y [l + 48 ]* (s [3 ]- 32 )* (((q [l + 16 ] >>2 )& 3 )- (h [l + 16 ]& (m <<1 ) ?0 :4 )) 545+ y [l + 80 ]* (s [5 ]- 32 )* (((q [l + 16 ] >>4 )& 3 )- (h [l + 16 ]& (m <<2 ) ?0 :4 )) 546+ y [l + 112 ]* (s [7 ]- 32 )* (((q [l + 16 ] >>6 )& 3 )- (h [l + 16 ]& (m <<3 ) ?0 :4 )); 547 } 548tmp += d * sum ; 549 } 550 551 } 552#else 553 554const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...15 or 0...7 555const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION );// 0....1 or 0...3 556const int offset = tid * K_QUANTS_PER_ITERATION ;// 0...15 or 0...14 557const int in = offset /8 ;// 0 or 1 558const int im = offset %8 ;// 0...7 559 560for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 561 562const float * y = yy + i * QK_K + offset ; 563const uint8_t * q = x [i ].qs + offset ; 564const uint8_t * s = x [i ].scales ; 565 566const float dall = (float )x [i ].d ; 567 568float sum = 0 ; 569for (int l = 0 ;l < K_QUANTS_PER_ITERATION ;++ l ) { 570const uint8_t hl = x [i ].hmask [im + l ] >>in ; 571const uint8_t ql = q [l ]; 572sum += y [l + 0 ]* dall * ((s [0 ]& 0xF )- 8 )* ((int8_t )((ql >>0 )& 3 )- ((hl >>0 )& 1 ?0 :4 )) 573+ y [l + 16 ]* dall * ((s [0 ] >>4 )- 8 )* ((int8_t )((ql >>2 )& 3 )- ((hl >>2 )& 1 ?0 :4 )) 574+ y [l + 32 ]* dall * ((s [1 ]& 0xF )- 8 )* ((int8_t )((ql >>4 )& 3 )- ((hl >>4 )& 1 ?0 :4 )) 575+ y [l + 48 ]* dall * ((s [1 ] >>4 )- 8 )* ((int8_t )((ql >>6 )& 3 )- ((hl >>6 )& 1 ?0 :4 )); 576 } 577tmp += sum ; 578 } 579#endif 580 581// sum up partial sums and write back result 582#pragma unroll 583for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 584tmp += 585 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 586 } 587 588if (item_ct1 .get_local_id (2 )== 0 ) { 589dst [row ]= tmp ; 590 } 591} 592 593static void dequantize_mul_mat_vec_q3_k_reorder (const void * __restrict__vx , 594const float * __restrict__yy , 595float * __restrict__dst , 596const int ncols ,int nrows , 597const sycl::nd_item < 3 > & item_ct1 ) { 598 599const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 600item_ct1 .get_local_id (1 ); 601if (row >=nrows )return ; 602 603const int num_blocks_per_row = ncols /QK_K ; 604const int ib0 = row * num_blocks_per_row ; 605 606// SOA base pointers for the reordered layout: 607// [qs: nb * (QK_K/4)] [hmask: nb * (QK_K/8)] [scales: nb * 12] [d: nb * sizeof(half)] 608const int nb = nrows * num_blocks_per_row ; 609const uint8_t * qs_base = (const uint8_t * )vx ; 610const uint8_t * hmask_base = qs_base + (size_t )nb * (QK_K /4 ); 611const uint8_t * scales_base = hmask_base + (size_t )nb * (QK_K /8 ); 612const sycl::half * d_base = (const sycl::half * )(scales_base + (size_t )nb * 12 ); 613 614float tmp = 0 ;// partial sum for thread in warp 615 616#if QK_K == 256 617 618const uint16_t kmask1 = 0x0303 ; 619const uint16_t kmask2 = 0x0f0f ; 620 621const int tid = 622item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 623const int ix = 624item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 625 626const int n = K_QUANTS_PER_ITERATION ;// iterations in the inner loop 627const int step = 16 /K_QUANTS_PER_ITERATION ; 628const int in = tid %step ;// 0...15 or 0...7 629 630const int l0 = n * in ;// 0...15 or 0...14 in steps of 2 631 632uint16_t utmp [4 ]; 633const int8_t * s = (const int8_t * )utmp ; 634 635for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 636const int bi = ib0 + i ; 637 638const uint8_t * h = hmask_base + bi * (QK_K /8 )+ l0 ; 639 640const float d = d_base [bi ]; 641 642for (int im = 0 ;im < 2 ;++ im ) { 643const int q_offset = 32 * im + l0 ; 644const int y_offset = 128 * im + l0 ; 645const uint16_t s_shift = 4 * im ; 646const uint8_t m = 1 << (4 * im ); 647 648const float * y = yy + i * QK_K + y_offset ; 649const uint8_t * q = qs_base + bi * (QK_K /4 )+ q_offset ; 650 651const uint16_t * a = (const uint16_t * )(scales_base + bi * 12 ); 652utmp [0 ]= ((a [0 ] >>s_shift )& kmask2 ) | (((a [4 ] >> (s_shift + 0 ))& kmask1 ) <<4 ); 653utmp [1 ]= ((a [1 ] >>s_shift )& kmask2 ) | (((a [5 ] >> (s_shift + 0 ))& kmask1 ) <<4 ); 654utmp [2 ]= ((a [2 ] >>s_shift )& kmask2 ) | (((a [4 ] >> (s_shift + 2 ))& kmask1 ) <<4 ); 655utmp [3 ]= ((a [3 ] >>s_shift )& kmask2 ) | (((a [5 ] >> (s_shift + 2 ))& kmask1 ) <<4 ); 656 657float sum = 0 ; 658for (int l = 0 ;l < n ;++ l ) { 659sum += y [l + 0 ]* (s [0 ]- 32 )* (((q [l ] >>0 )& 3 )- (h [l ]& (m <<0 ) ?0 :4 )) 660+ y [l + 32 ]* (s [2 ]- 32 )* (((q [l ] >>2 )& 3 )- (h [l ]& (m <<1 ) ?0 :4 )) 661+ y [l + 64 ]* (s [4 ]- 32 )* (((q [l ] >>4 )& 3 )- (h [l ]& (m <<2 ) ?0 :4 )) 662+ y [l + 96 ]* (s [6 ]- 32 )* (((q [l ] >>6 )& 3 )- (h [l ]& (m <<3 ) ?0 :4 )); 663sum += y [l + 16 ]* (s [1 ]- 32 )* (((q [l + 16 ] >>0 )& 3 )- (h [l + 16 ]& (m <<0 ) ?0 :4 )) 664+ y [l + 48 ]* (s [3 ]- 32 )* (((q [l + 16 ] >>2 )& 3 )- (h [l + 16 ]& (m <<1 ) ?0 :4 )) 665+ y [l + 80 ]* (s [5 ]- 32 )* (((q [l + 16 ] >>4 )& 3 )- (h [l + 16 ]& (m <<2 ) ?0 :4 )) 666+ y [l + 112 ]* (s [7 ]- 32 )* (((q [l + 16 ] >>6 )& 3 )- (h [l + 16 ]& (m <<3 ) ?0 :4 )); 667 } 668tmp += d * sum ; 669 } 670 } 671#else 672GGML_UNUSED (vx ); 673GGML_UNUSED (yy ); 674GGML_UNUSED (ncols ); 675GGML_UNUSED (item_ct1 ); 676GGML_ABORT ("Q3_K reorder DMMV not supported for QK_K != 256" ); 677#endif 678 679// sum up partial sums and write back result 680#pragma unroll 681for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 682tmp += 683 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 684 } 685 686if (item_ct1 .get_local_id (2 )== 0 ) { 687dst [row ]= tmp ; 688 } 689} 690 691static void dequantize_mul_mat_vec_q4_k (const void * __restrict__vx , 692const float * __restrict__yy , 693float * __restrict__dst , 694const int ncols ,int nrows , 695const sycl::nd_item < 3 > & item_ct1 ) { 696 697const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 698item_ct1 .get_local_id (1 ); 699if (row >=nrows )return ; 700const int num_blocks_per_row = ncols /QK_K ; 701const int ib0 = row * num_blocks_per_row ; 702 703const block_q4_K * x = (const block_q4_K * )vx + ib0 ; 704 705#if QK_K == 256 706const uint16_t kmask1 = 0x3f3f ; 707const uint16_t kmask2 = 0x0f0f ; 708const uint16_t kmask3 = 0xc0c0 ; 709 710const int tid = 711item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 712const int ix = 713item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 714 715const int step = 8 /K_QUANTS_PER_ITERATION ;// 8 or 4 716 717const int il_base = tid /step ;// 0 or 1 (was 0...3) 718const int ir = tid - step * il_base ;// 0...7 or 0...3 719const int n = 2 * K_QUANTS_PER_ITERATION ;// 2 or 4 720 721const int in = il_base %2 ; 722 723const int l0 = n * (2 * ir + in ); 724 725uint16_t aux [4 ]; 726const uint8_t * sc = (const uint8_t * )aux ; 727 728#if K_QUANTS_PER_ITERATION == 2 729uint32_t q32 [4 ]; 730const uint8_t * q4 = (const uint8_t * )q32 ; 731#else 732uint16_t q16 [4 ]; 733const uint8_t * q4 = (const uint8_t * )q16 ; 734#endif 735 736float tmp = 0 ;// partial sum for thread in warp 737 738for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 739 740const float dall = x [i ].dm [0 ]; 741const float dmin = x [i ].dm [1 ]; 742 743for (int im = 0 ;im < 2 ;++ im ) { 744const int q_offset = 32 * im + l0 ; 745const int y_offset = 64 * im + l0 ; 746 747const float * y1 = yy + i * QK_K + y_offset ; 748const float * y2 = y1 + 128 ; 749 750const uint16_t * a = (const uint16_t * )x [i ].scales ; 751aux [0 ]= a [im + 0 ]& kmask1 ; 752aux [1 ]= a [im + 2 ]& kmask1 ; 753aux [2 ]= ((a [im + 4 ] >>0 )& kmask2 ) | ((a [im + 0 ]& kmask3 ) >>2 ); 754aux [3 ]= ((a [im + 4 ] >>4 )& kmask2 ) | ((a [im + 2 ]& kmask3 ) >>2 ); 755 756#if K_QUANTS_PER_ITERATION == 2 757const uint32_t * q1 = (const uint32_t * )(x [i ].qs + q_offset ); 758const uint32_t * q2 = q1 + 16 ; 759 760q32 [0 ]= q1 [0 ]& 0x0f0f0f0f ; 761q32 [1 ]= q1 [0 ]& 0xf0f0f0f0 ; 762q32 [2 ]= q2 [0 ]& 0x0f0f0f0f ; 763q32 [3 ]= q2 [0 ]& 0xf0f0f0f0 ; 764 765 sycl::float4 s = {0.f ,0.f ,0.f ,0.f }; 766float smin = 0 ; 767for (int l = 0 ;l < 4 ;++ l ) { 768s .x ()+= y1 [l ]* q4 [l + 0 ];s .y ()+= y1 [l + 32 ]* q4 [l + 4 ]; 769s .z ()+= y2 [l ]* q4 [l + 8 ];s .w ()+= y2 [l + 32 ]* q4 [l + 12 ]; 770smin += y1 [l ]* sc [2 ]+ y1 [l + 32 ]* sc [3 ]+ y2 [l ]* sc [6 ]+ y2 [l + 32 ]* sc [7 ]; 771 } 772tmp += dall * (s .x ()* sc [0 ]+ s .y ()* sc [1 ]* 1.f /16.f + 773s .z ()* sc [4 ]+ s .w ()* sc [5 ]* 1.f /16.f )- 774dmin * smin ; 775#else 776const uint16_t * q1 = (const uint16_t * )(x [i ].qs + q_offset ); 777const uint16_t * q2 = q1 + 32 ; 778 779q16 [0 ]= q1 [0 ]& 0x0f0f ; 780q16 [1 ]= q1 [0 ]& 0xf0f0 ; 781q16 [2 ]= q2 [0 ]& 0x0f0f ; 782q16 [3 ]= q2 [0 ]& 0xf0f0 ; 783 784 sycl::float4 s = {0.f ,0.f ,0.f ,0.f }; 785float smin = 0 ; 786for (int l = 0 ;l < 2 ;++ l ) { 787s .x ()+= y1 [l ]* q4 [l + 0 ];s .y ()+= y1 [l + 32 ]* q4 [l + 2 ]; 788s .z ()+= y2 [l ]* q4 [l + 4 ];s .w ()+= y2 [l + 32 ]* q4 [l + 6 ]; 789smin += y1 [l ]* sc [2 ]+ y1 [l + 32 ]* sc [3 ]+ y2 [l ]* sc [6 ]+ y2 [l + 32 ]* sc [7 ]; 790 } 791tmp += dall * (s .x ()* sc [0 ]+ s .y ()* sc [1 ]* 1.f /16.f + s .z ()* sc [4 ]+ s .w ()* sc [5 ]* 1.f /16.f )- dmin * smin ; 792#endif 793 } 794 795 } 796#else 797const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...15 798const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION ); 799 800const int step = tid * K_QUANTS_PER_ITERATION ; 801 802uint16_t aux16 [2 ]; 803const uint8_t * s = (const uint8_t * )aux16 ; 804 805float tmp = 0 ; 806 807for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 808const uint8_t * q = x [i ].qs + step ; 809const float * y = yy + i * QK_K + step ; 810const uint16_t * a = (const uint16_t * )x [i ].scales ; 811aux16 [0 ]= a [0 ]& 0x0f0f ; 812aux16 [1 ]= (a [0 ] >>4 )& 0x0f0f ; 813const float d = (float )x [i ].dm [0 ]; 814const float m = (float )x [i ].dm [1 ]; 815float sum = 0.f ; 816for (int j = 0 ;j < K_QUANTS_PER_ITERATION ;++ j ) { 817sum += y [j + 0 ]* (d * s [0 ]* (q [j + 0 ]& 0xF )- m * s [2 ]) 818+ y [j + 16 ]* (d * s [0 ]* (q [j + 16 ]& 0xF )- m * s [2 ]) 819+ y [j + 32 ]* (d * s [1 ]* (q [j + 0 ] >>4 )- m * s [3 ]) 820+ y [j + 48 ]* (d * s [1 ]* (q [j + 16 ] >>4 )- m * s [3 ]); 821 } 822tmp += sum ; 823 } 824 825#endif 826 827// sum up partial sums and write back result 828#pragma unroll 829for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 830tmp += 831 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 832 } 833 834if (tid == 0 ) { 835dst [row ]= tmp ; 836 } 837} 838 839static void dequantize_mul_mat_vec_q4_k_reorder (const void * __restrict__vx , 840const float * __restrict__yy , 841float * __restrict__dst , 842const int ncols ,int nrows , 843const sycl::nd_item < 3 > & item_ct1 ) { 844 845const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 846item_ct1 .get_local_id (1 ); 847if (row >=nrows )return ; 848const int num_blocks_per_row = ncols /QK_K ; 849const int ib0 = row * num_blocks_per_row ; 850 851// SOA base pointers for the reordered layout: 852// [qs: nb * QK_K/2] [scales: nb * K_SCALE_SIZE] [dm: nb * sizeof(half2)] 853const int nb = nrows * num_blocks_per_row ; 854const uint8_t * qs_base = (const uint8_t * )vx ; 855const uint8_t * scales_base = qs_base + (size_t )nb * (QK_K /2 ); 856const sycl::half2 * dm_base = (const sycl::half2 * )(scales_base + (size_t )nb * K_SCALE_SIZE ); 857 858#if QK_K == 256 859const uint16_t kmask1 = 0x3f3f ; 860const uint16_t kmask2 = 0x0f0f ; 861const uint16_t kmask3 = 0xc0c0 ; 862 863const int tid = 864item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 865const int ix = 866item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0,1 867 868const int step = 8 /K_QUANTS_PER_ITERATION ;// 8 or 4 869 870const int il_base = tid /step ;// 0 or 1 (was 0...3) 871const int ir = tid - step * il_base ;// 0...7 or 0...3 872const int n = 2 * K_QUANTS_PER_ITERATION ;// 2 or 4 873 874const int in = il_base %2 ; 875 876const int l0 = n * (2 * ir + in ); 877 878uint16_t aux [4 ]; 879const uint8_t * sc = (const uint8_t * )aux ; 880 881#if K_QUANTS_PER_ITERATION == 2 882uint32_t q32 [4 ]; 883const uint8_t * q4 = (const uint8_t * )q32 ; 884#else 885uint16_t q16 [4 ]; 886const uint8_t * q4 = (const uint8_t * )q16 ; 887#endif 888 889float tmp = 0 ;// partial sum for thread in warp 890 891for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 892const int bi = ib0 + i ; 893 894const sycl::half2 dm_val = dm_base [bi ]; 895const float dall = dm_val [0 ]; 896const float dmin = dm_val [1 ]; 897 898for (int im = 0 ;im < 2 ;++ im ) { 899const int q_offset = 32 * im + l0 ; 900const int y_offset = 64 * im + l0 ; 901 902const float * y1 = yy + i * QK_K + y_offset ; 903const float * y2 = y1 + 128 ; 904 905const uint16_t * a = (const uint16_t * )(scales_base + bi * K_SCALE_SIZE ); 906aux [0 ]= a [im + 0 ]& kmask1 ; 907aux [1 ]= a [im + 2 ]& kmask1 ; 908aux [2 ]= ((a [im + 4 ] >>0 )& kmask2 ) | ((a [im + 0 ]& kmask3 ) >>2 ); 909aux [3 ]= ((a [im + 4 ] >>4 )& kmask2 ) | ((a [im + 2 ]& kmask3 ) >>2 ); 910 911#if K_QUANTS_PER_ITERATION == 2 912const uint32_t * q1 = (const uint32_t * )(qs_base + bi * (QK_K /2 )+ q_offset ); 913const uint32_t * q2 = q1 + 16 ; 914 915q32 [0 ]= q1 [0 ]& 0x0f0f0f0f ; 916q32 [1 ]= q1 [0 ]& 0xf0f0f0f0 ; 917q32 [2 ]= q2 [0 ]& 0x0f0f0f0f ; 918q32 [3 ]= q2 [0 ]& 0xf0f0f0f0 ; 919 920 sycl::float4 s = {0.f ,0.f ,0.f ,0.f }; 921float smin = 0 ; 922for (int l = 0 ;l < 4 ;++ l ) { 923s .x ()+= y1 [l ]* q4 [l + 0 ];s .y ()+= y1 [l + 32 ]* q4 [l + 4 ]; 924s .z ()+= y2 [l ]* q4 [l + 8 ];s .w ()+= y2 [l + 32 ]* q4 [l + 12 ]; 925smin += y1 [l ]* sc [2 ]+ y1 [l + 32 ]* sc [3 ]+ y2 [l ]* sc [6 ]+ y2 [l + 32 ]* sc [7 ]; 926 } 927tmp += dall * (s .x ()* sc [0 ]+ s .y ()* sc [1 ]* 1.f /16.f + 928s .z ()* sc [4 ]+ s .w ()* sc [5 ]* 1.f /16.f )- 929dmin * smin ; 930#else 931const uint16_t * q1 = (const uint16_t * )(qs_base + bi * (QK_K /2 )+ q_offset ); 932const uint16_t * q2 = q1 + 32 ; 933 934q16 [0 ]= q1 [0 ]& 0x0f0f ; 935q16 [1 ]= q1 [0 ]& 0xf0f0 ; 936q16 [2 ]= q2 [0 ]& 0x0f0f ; 937q16 [3 ]= q2 [0 ]& 0xf0f0 ; 938 939 sycl::float4 s = {0.f ,0.f ,0.f ,0.f }; 940float smin = 0 ; 941for (int l = 0 ;l < 2 ;++ l ) { 942s .x ()+= y1 [l ]* q4 [l + 0 ];s .y ()+= y1 [l + 32 ]* q4 [l + 2 ]; 943s .z ()+= y2 [l ]* q4 [l + 4 ];s .w ()+= y2 [l + 32 ]* q4 [l + 6 ]; 944smin += y1 [l ]* sc [2 ]+ y1 [l + 32 ]* sc [3 ]+ y2 [l ]* sc [6 ]+ y2 [l + 32 ]* sc [7 ]; 945 } 946tmp += dall * (s .x ()* sc [0 ]+ s .y ()* sc [1 ]* 1.f /16.f + s .z ()* sc [4 ]+ s .w ()* sc [5 ]* 1.f /16.f )- dmin * smin ; 947#endif 948 } 949 950 } 951#else 952const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...15 953const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION ); 954 955const int step = tid * K_QUANTS_PER_ITERATION ; 956 957uint16_t aux16 [2 ]; 958const uint8_t * s = (const uint8_t * )aux16 ; 959 960float tmp = 0 ; 961 962for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 963const int bi = ib0 + i ; 964 965const uint8_t * q = qs_base + bi * (QK_K /2 )+ step ; 966const float * y = yy + i * QK_K + step ; 967const uint16_t * a = (const uint16_t * )(scales_base + bi * K_SCALE_SIZE ); 968aux16 [0 ]= a [0 ]& 0x0f0f ; 969aux16 [1 ]= (a [0 ] >>4 )& 0x0f0f ; 970const sycl::half2 dm_val = dm_base [bi ]; 971const float d = (float )dm_val [0 ]; 972const float m = (float )dm_val [1 ]; 973float sum = 0.f ; 974for (int j = 0 ;j < K_QUANTS_PER_ITERATION ;++ j ) { 975sum += y [j + 0 ]* (d * s [0 ]* (q [j + 0 ]& 0xF )- m * s [2 ]) 976+ y [j + 16 ]* (d * s [0 ]* (q [j + 16 ]& 0xF )- m * s [2 ]) 977+ y [j + 32 ]* (d * s [1 ]* (q [j + 0 ] >>4 )- m * s [3 ]) 978+ y [j + 48 ]* (d * s [1 ]* (q [j + 16 ] >>4 )- m * s [3 ]); 979 } 980tmp += sum ; 981 } 982 983#endif 984 985// sum up partial sums and write back result 986#pragma unroll 987for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 988tmp += 989 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 990 } 991 992if (tid == 0 ) { 993dst [row ]= tmp ; 994 } 995} 996 997static void dequantize_mul_mat_vec_q5_k (const void * __restrict__vx , 998const float * __restrict__yy , 999float * __restrict__dst , 1000const int ncols ,int nrows , 1001const sycl::nd_item < 3 > & item_ct1 ) { 1002 1003const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 1004item_ct1 .get_local_id (1 ); 1005if (row >=nrows )return ; 1006const int num_blocks_per_row = ncols /QK_K ; 1007const int ib0 = row * num_blocks_per_row ; 1008 1009const block_q5_K * x = (const block_q5_K * )vx + ib0 ; 1010 1011float tmp = 0 ;// partial sum for thread in warp 1012 1013#if QK_K == 256 1014const uint16_t kmask1 = 0x3f3f ; 1015const uint16_t kmask2 = 0x0f0f ; 1016const uint16_t kmask3 = 0xc0c0 ; 1017 1018const int tid = item_ct1 .get_local_id (2 ) /2 ;// 0...7 1019const int ix = item_ct1 .get_local_id (2 ) %2 ; 1020 1021const int il_base = tid /4 ;// 0 or 1 (was 0...3) 1022const int ir = tid - 4 * il_base ;// 0...3 1023const int n = 2 ; 1024 1025const int in = il_base %2 ; 1026 1027const int l0 = n * (2 * ir + in ); 1028 1029uint16_t aux [4 ]; 1030const uint8_t * sc = (const uint8_t * )aux ; 1031 1032uint16_t q16 [8 ]; 1033const uint8_t * q4 = (const uint8_t * )q16 ; 1034 1035for (int i = ix ;i < num_blocks_per_row ;i += 2 ) { 1036 1037const uint8_t * qh = x [i ].qh + l0 ; 1038const float dall = x [i ].dm [0 ]; 1039const float dmin = x [i ].dm [1 ]; 1040 1041for (int im = 0 ;im < 2 ;++ im ) { 1042const int q_offset = 32 * im + l0 ; 1043const int y_offset = 64 * im + l0 ; 1044 1045const uint8_t hm1 = 1 << (2 * im ); 1046const uint8_t hm2 = hm1 <<4 ; 1047 1048const uint8_t * ql1 = x [i ].qs + q_offset ; 1049const float * y1 = yy + i * QK_K + y_offset ; 1050const float * y2 = y1 + 128 ; 1051 1052const uint16_t * a = (const uint16_t * )x [i ].scales ; 1053aux [0 ]= a [im + 0 ]& kmask1 ; 1054aux [1 ]= a [im + 2 ]& kmask1 ; 1055aux [2 ]= ((a [im + 4 ] >>0 )& kmask2 ) | ((a [im + 0 ]& kmask3 ) >>2 ); 1056aux [3 ]= ((a [im + 4 ] >>4 )& kmask2 ) | ((a [im + 2 ]& kmask3 ) >>2 ); 1057 1058 sycl::float4 sum = {0.f ,0.f ,0.f ,0.f }; 1059float smin = 0 ; 1060const uint16_t * q1 = (const uint16_t * )ql1 ; 1061const uint16_t * q2 = q1 + 32 ; 1062q16 [0 ]= q1 [0 ]& 0x0f0f ; 1063q16 [1 ]= q1 [8 ]& 0x0f0f ; 1064q16 [2 ]= (q1 [0 ] >>4 )& 0x0f0f ; 1065q16 [3 ]= (q1 [8 ] >>4 )& 0x0f0f ; 1066q16 [4 ]= q2 [0 ]& 0x0f0f ; 1067q16 [5 ]= q2 [8 ]& 0x0f0f ; 1068q16 [6 ]= (q2 [0 ] >>4 )& 0x0f0f ; 1069q16 [7 ]= (q2 [8 ] >>4 )& 0x0f0f ; 1070for (int l = 0 ;l < n ;++ l ) { 1071sum .x ()+= 1072y1 [l + 0 ]* (q4 [l + 0 ]+ (qh [l + 0 ]& (hm1 <<0 ) ?16 :0 ))+ 1073y1 [l + 16 ]* (q4 [l + 2 ]+ (qh [l + 16 ]& (hm1 <<0 ) ?16 :0 )); 1074sum .y ()+= 1075y1 [l + 32 ]* (q4 [l + 4 ]+ (qh [l + 0 ]& (hm1 <<1 ) ?16 :0 ))+ 1076y1 [l + 48 ]* (q4 [l + 6 ]+ (qh [l + 16 ]& (hm1 <<1 ) ?16 :0 )); 1077sum .z ()+= 1078y2 [l + 0 ]* (q4 [l + 8 ]+ (qh [l + 0 ]& (hm2 <<0 ) ?16 :0 ))+ 1079y2 [l + 16 ]* (q4 [l + 10 ]+ (qh [l + 16 ]& (hm2 <<0 ) ?16 :0 )); 1080sum .w ()+= 1081y2 [l + 32 ]* (q4 [l + 12 ]+ (qh [l + 0 ]& (hm2 <<1 ) ?16 :0 ))+ 1082y2 [l + 48 ]* (q4 [l + 14 ]+ (qh [l + 16 ]& (hm2 <<1 ) ?16 :0 )); 1083smin += (y1 [l ]+ y1 [l + 16 ])* sc [2 ]+ (y1 [l + 32 ]+ y1 [l + 48 ])* sc [3 ] 1084+ (y2 [l ]+ y2 [l + 16 ])* sc [6 ]+ (y2 [l + 32 ]+ y2 [l + 48 ])* sc [7 ]; 1085 } 1086tmp += dall * (sum .x ()* sc [0 ]+ sum .y ()* sc [1 ]+ sum .z ()* sc [4 ]+ 1087sum .w ()* sc [5 ])- 1088dmin * smin ; 1089 } 1090 } 1091 1092#else 1093const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...15 1094const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION ); 1095const int step = tid * K_QUANTS_PER_ITERATION ; 1096const int im = step /8 ; 1097const int in = step %8 ; 1098 1099for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 1100const uint8_t * q = x [i ].qs + step ; 1101const int8_t * s = x [i ].scales ; 1102const float * y = yy + i * QK_K + step ; 1103const float d = x [i ].d ; 1104float sum = 0.f ; 1105for (int j = 0 ;j < K_QUANTS_PER_ITERATION ;++ j ) { 1106const uint8_t h = x [i ].qh [in + j ] >>im ; 1107sum += y [j + 0 ]* d * s [0 ]* ((q [j + 0 ]& 0xF )- ((h >>0 )& 1 ?0 :16 )) 1108+ y [j + 16 ]* d * s [1 ]* ((q [j + 16 ]& 0xF )- ((h >>2 )& 1 ?0 :16 )) 1109+ y [j + 32 ]* d * s [2 ]* ((q [j + 0 ] >>4 )- ((h >>4 )& 1 ?0 :16 )) 1110+ y [j + 48 ]* d * s [3 ]* ((q [j + 16 ] >>4 )- ((h >>6 )& 1 ?0 :16 )); 1111 } 1112tmp += sum ; 1113 } 1114#endif 1115 1116// sum up partial sums and write back result 1117#pragma unroll 1118for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 1119tmp += 1120 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 1121 } 1122 1123if (item_ct1 .get_local_id (2 )== 0 ) { 1124dst [row ]= tmp ; 1125 } 1126} 1127 1128static void dequantize_mul_mat_vec_q5_k_reorder (const void * __restrict__vx , 1129const float * __restrict__yy , 1130float * __restrict__dst , 1131const int ncols ,int nrows , 1132const sycl::nd_item < 3 > & item_ct1 ) { 1133 1134const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 1135item_ct1 .get_local_id (1 ); 1136if (row >=nrows )return ; 1137const int num_blocks_per_row = ncols /QK_K ; 1138const int ib0 = row * num_blocks_per_row ; 1139 1140// SOA base pointers for the reordered layout: 1141// [qs: nb * QK_K/2] [qh: nb * QK_K/8] [scales: nb * K_SCALE_SIZE] [dm: nb * sizeof(half2)] 1142const int nb = nrows * num_blocks_per_row ; 1143const uint8_t * qs_base = (const uint8_t * )vx ; 1144const uint8_t * qh_base = qs_base + (size_t )nb * (QK_K /2 ); 1145const uint8_t * scales_base = qh_base + (size_t )nb * (QK_K /8 ); 1146const sycl::half2 * dm_base = (const sycl::half2 * )(scales_base + (size_t )nb * K_SCALE_SIZE ); 1147 1148float tmp = 0 ;// partial sum for thread in warp 1149 1150#if QK_K == 256 1151const uint16_t kmask1 = 0x3f3f ; 1152const uint16_t kmask2 = 0x0f0f ; 1153const uint16_t kmask3 = 0xc0c0 ; 1154 1155const int tid = item_ct1 .get_local_id (2 ) /2 ;// 0...15 1156const int ix = item_ct1 .get_local_id (2 ) %2 ; 1157 1158const int il_base = tid /4 ;// 0...3 1159const int ir = tid - 4 * il_base ;// 0...3 1160const int n = 2 ; 1161 1162const int in = il_base %2 ; 1163 1164const int l0 = n * (2 * ir + in ); 1165 1166uint16_t aux [4 ]; 1167const uint8_t * sc = (const uint8_t * )aux ; 1168 1169uint16_t q16 [8 ]; 1170const uint8_t * q4 = (const uint8_t * )q16 ; 1171 1172for (int i = ix ;i < num_blocks_per_row ;i += 2 ) { 1173const int bi = ib0 + i ; 1174 1175const uint8_t * qh = qh_base + bi * (QK_K /8 )+ l0 ; 1176const sycl::half2 dm_val = dm_base [bi ]; 1177const float dall = dm_val [0 ]; 1178const float dmin = dm_val [1 ]; 1179 1180for (int im = 0 ;im < 2 ;++ im ) { 1181const int q_offset = 32 * im + l0 ; 1182const int y_offset = 64 * im + l0 ; 1183 1184const uint8_t hm1 = 1 << (2 * im ); 1185const uint8_t hm2 = hm1 <<4 ; 1186 1187const uint8_t * ql1 = qs_base + bi * (QK_K /2 )+ q_offset ; 1188const float * y1 = yy + i * QK_K + y_offset ; 1189const float * y2 = y1 + 128 ; 1190 1191const uint16_t * a = (const uint16_t * )(scales_base + bi * K_SCALE_SIZE ); 1192aux [0 ]= a [im + 0 ]& kmask1 ; 1193aux [1 ]= a [im + 2 ]& kmask1 ; 1194aux [2 ]= ((a [im + 4 ] >>0 )& kmask2 ) | ((a [im + 0 ]& kmask3 ) >>2 ); 1195aux [3 ]= ((a [im + 4 ] >>4 )& kmask2 ) | ((a [im + 2 ]& kmask3 ) >>2 ); 1196 1197 sycl::float4 sum = {0.f ,0.f ,0.f ,0.f }; 1198float smin = 0 ; 1199const uint16_t * q1 = (const uint16_t * )ql1 ; 1200const uint16_t * q2 = q1 + 32 ; 1201q16 [0 ]= q1 [0 ]& 0x0f0f ; 1202q16 [1 ]= q1 [8 ]& 0x0f0f ; 1203q16 [2 ]= (q1 [0 ] >>4 )& 0x0f0f ; 1204q16 [3 ]= (q1 [8 ] >>4 )& 0x0f0f ; 1205q16 [4 ]= q2 [0 ]& 0x0f0f ; 1206q16 [5 ]= q2 [8 ]& 0x0f0f ; 1207q16 [6 ]= (q2 [0 ] >>4 )& 0x0f0f ; 1208q16 [7 ]= (q2 [8 ] >>4 )& 0x0f0f ; 1209for (int l = 0 ;l < n ;++ l ) { 1210sum .x ()+= 1211y1 [l + 0 ]* (q4 [l + 0 ]+ (qh [l + 0 ]& (hm1 <<0 ) ?16 :0 ))+ 1212y1 [l + 16 ]* (q4 [l + 2 ]+ (qh [l + 16 ]& (hm1 <<0 ) ?16 :0 )); 1213sum .y ()+= 1214y1 [l + 32 ]* (q4 [l + 4 ]+ (qh [l + 0 ]& (hm1 <<1 ) ?16 :0 ))+ 1215y1 [l + 48 ]* (q4 [l + 6 ]+ (qh [l + 16 ]& (hm1 <<1 ) ?16 :0 )); 1216sum .z ()+= 1217y2 [l + 0 ]* (q4 [l + 8 ]+ (qh [l + 0 ]& (hm2 <<0 ) ?16 :0 ))+ 1218y2 [l + 16 ]* (q4 [l + 10 ]+ (qh [l + 16 ]& (hm2 <<0 ) ?16 :0 )); 1219sum .w ()+= 1220y2 [l + 32 ]* (q4 [l + 12 ]+ (qh [l + 0 ]& (hm2 <<1 ) ?16 :0 ))+ 1221y2 [l + 48 ]* (q4 [l + 14 ]+ (qh [l + 16 ]& (hm2 <<1 ) ?16 :0 )); 1222smin += (y1 [l ]+ y1 [l + 16 ])* sc [2 ]+ (y1 [l + 32 ]+ y1 [l + 48 ])* sc [3 ] 1223+ (y2 [l ]+ y2 [l + 16 ])* sc [6 ]+ (y2 [l + 32 ]+ y2 [l + 48 ])* sc [7 ]; 1224 } 1225tmp += dall * (sum .x ()* sc [0 ]+ sum .y ()* sc [1 ]+ sum .z ()* sc [4 ]+ 1226sum .w ()* sc [5 ])- 1227dmin * smin ; 1228 } 1229 } 1230#else 1231// The reordered Q5_K layout is only produced for QK_K == 256. 1232#endif 1233 1234// sum up partial sums and write back result 1235#pragma unroll 1236for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 1237tmp += 1238 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 1239 } 1240 1241if (item_ct1 .get_local_id (2 )== 0 ) { 1242dst [row ]= tmp ; 1243 } 1244} 1245 1246static void dequantize_mul_mat_vec_q6_k (const void * __restrict__vx ,const float * __restrict__yy ,float * __restrict__dst ,const int ncols ,int nrows , 1247const sycl::nd_item < 3 > & item_ct1 ) { 1248 1249 static_assert(16 %K_QUANTS_PER_ITERATION == 0 ,"16 must be divisible by K_QUANTS_PER_ITERATION" ); 1250 1251const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 1252item_ct1 .get_local_id (1 ); 1253if (row >=nrows )return ; 1254 1255const int num_blocks_per_row = ncols /QK_K ; 1256const int ib0 = row * num_blocks_per_row ; 1257 1258const block_q6_K * x = (const block_q6_K * )vx + ib0 ; 1259 1260#if QK_K == 256 1261 1262const int tid = 1263item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 1264const int ix = 1265item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0, 1 1266 1267const int step = 16 /K_QUANTS_PER_ITERATION ;// 16 or 8 1268 1269const int in = tid %step ;// 0...15 or 0...7 1270 1271#if K_QUANTS_PER_ITERATION == 1 1272const int l0 = K_QUANTS_PER_ITERATION * in ;// 0...15 1273const int is = 0 ; 1274#else 1275const int l0 = 4 * in ;// 0, 4, 8, ..., 28 1276const int is = in /4 ; 1277#endif 1278 1279float tmp = 0 ;// partial sum for thread in warp 1280 1281for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 1282 1283const float d = x [i ].d ; 1284 1285for (int im = 0 ;im < 2 ;++ im ) { 1286const int ql_offset = 64 * im + l0 ; 1287const int qh_offset = 32 * im + l0 ; 1288const int s_offset = 8 * im + is ; 1289const int y_offset = 128 * im + l0 ; 1290 1291const float * y = yy + i * QK_K + y_offset ; 1292const uint8_t * ql = x [i ].ql + ql_offset ; 1293const uint8_t * qh = x [i ].qh + qh_offset ; 1294const int8_t * s = x [i ].scales + s_offset ; 1295 1296#if K_QUANTS_PER_ITERATION == 1 1297float sum = y [0 ]* s [0 ]* d * ((int8_t )((ql [0 ]& 0xF ) | ((qh [0 ]& 0x03 ) <<4 ))- 32 ) 1298+ y [16 ]* s [1 ]* d * ((int8_t )((ql [16 ]& 0xF ) | ((qh [16 ]& 0x03 ) <<4 ))- 32 ) 1299+ y [32 ]* s [2 ]* d * ((int8_t )((ql [32 ]& 0xF ) | ((qh [0 ]& 0x0c ) <<2 ))- 32 ) 1300+ y [48 ]* s [3 ]* d * ((int8_t )((ql [48 ]& 0xF ) | ((qh [16 ]& 0x0c ) <<2 ))- 32 ) 1301+ y [64 ]* s [4 ]* d * ((int8_t )((ql [0 ] >>4 ) | ((qh [0 ]& 0x30 ) >>0 ))- 32 ) 1302+ y [80 ]* s [5 ]* d * ((int8_t )((ql [16 ] >>4 ) | ((qh [16 ]& 0x30 ) >>0 ))- 32 ) 1303+ y [96 ]* s [6 ]* d * ((int8_t )((ql [32 ] >>4 ) | ((qh [0 ]& 0xc0 ) >>2 ))- 32 ) 1304+ y [112 ]* s [7 ]* d * ((int8_t )((ql [48 ] >>4 ) | ((qh [16 ]& 0xc0 ) >>2 ))- 32 ); 1305tmp += sum ; 1306#else 1307float sum = 0 ; 1308for (int l = 0 ;l < 4 ;++ l ) { 1309sum += y [l + 0 ]* s [0 ]* d * ((int8_t )((ql [l + 0 ]& 0xF ) | (((qh [l ] >>0 )& 3 ) <<4 ))- 32 ) 1310+ y [l + 32 ]* s [2 ]* d * ((int8_t )((ql [l + 32 ]& 0xF ) | (((qh [l ] >>2 )& 3 ) <<4 ))- 32 ) 1311+ y [l + 64 ]* s [4 ]* d * ((int8_t )((ql [l + 0 ] >>4 ) | (((qh [l ] >>4 )& 3 ) <<4 ))- 32 ) 1312+ y [l + 96 ]* s [6 ]* d * ((int8_t )((ql [l + 32 ] >>4 ) | (((qh [l ] >>6 )& 3 ) <<4 ))- 32 ); 1313 } 1314tmp += sum ; 1315#endif 1316 } 1317 1318 } 1319 1320#else 1321 1322const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...7 1323const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION );// 0...3 1324 1325const int step = tid * K_QUANTS_PER_ITERATION ; 1326 1327float tmp = 0 ;// partial sum for thread in warp 1328 1329for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 1330 1331const float * y = yy + i * QK_K + step ; 1332const uint8_t * ql = x [i ].ql + step ; 1333const uint8_t * qh = x [i ].qh + step ; 1334const int8_t * s = x [i ].scales ; 1335 1336const float d = x [i + 0 ].d ; 1337 1338float sum = 0 ; 1339for (int j = 0 ;j < K_QUANTS_PER_ITERATION ;++ j ) { 1340sum += y [j + 0 ]* s [0 ]* d * ((int8_t )((ql [j + 0 ]& 0xF ) | ((qh [j ]& 0x03 ) <<4 ))- 32 ) 1341+ y [j + 16 ]* s [1 ]* d * ((int8_t )((ql [j + 16 ]& 0xF ) | ((qh [j ]& 0x0c ) <<2 ))- 32 ) 1342+ y [j + 32 ]* s [2 ]* d * ((int8_t )((ql [j + 0 ] >>4 ) | ((qh [j ]& 0x30 ) >>0 ))- 32 ) 1343+ y [j + 48 ]* s [3 ]* d * ((int8_t )((ql [j + 16 ] >>4 ) | ((qh [j ]& 0xc0 ) >>2 ))- 32 ); 1344 } 1345tmp += sum ; 1346 1347 } 1348 1349#endif 1350 1351// sum up partial sums and write back result 1352#pragma unroll 1353for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 1354tmp += 1355 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 1356 } 1357 1358if (tid == 0 ) { 1359dst [row ]= tmp ; 1360 } 1361} 1362 1363static void dequantize_mul_mat_vec_q6_k_reorder (const void * __restrict__vx ,const float * __restrict__yy ,float * __restrict__dst ,const int ncols ,int nrows , 1364const sycl::nd_item < 3 > & item_ct1 ) { 1365 1366 static_assert(16 %K_QUANTS_PER_ITERATION == 0 ,"16 must be divisible by K_QUANTS_PER_ITERATION" ); 1367 1368const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 1369item_ct1 .get_local_id (1 ); 1370if (row >=nrows )return ; 1371 1372const int num_blocks_per_row = ncols /QK_K ; 1373const int ib0 = row * num_blocks_per_row ; 1374 1375// SOA base pointers for the reordered layout: 1376// [ql: nb * QK_K/2] [qh: nb * QK_K/4] [scales: nb * QK_K/16] [d: nb * sizeof(half)] 1377const int nb = nrows * num_blocks_per_row ; 1378const uint8_t * ql_base = (const uint8_t * )vx ; 1379const uint8_t * qh_base = ql_base + (size_t )nb * (QK_K /2 ); 1380const int8_t * scales_base = (const int8_t * )(qh_base + (size_t )nb * (QK_K /4 )); 1381const sycl::half * d_base = (const sycl::half * )((const uint8_t * )scales_base + (size_t )nb * (QK_K /16 )); 1382 1383#if QK_K == 256 1384 1385const int tid = 1386item_ct1 .get_local_id (2 ) /K_QUANTS_PER_ITERATION ;// 0...7 or 0...15 1387const int ix = 1388item_ct1 .get_local_id (2 ) %K_QUANTS_PER_ITERATION ;// 0 or 0, 1 1389 1390const int step = 16 /K_QUANTS_PER_ITERATION ;// 16 or 8 1391 1392const int in = tid %step ;// 0...15 or 0...7 1393 1394#if K_QUANTS_PER_ITERATION == 1 1395const int l0 = K_QUANTS_PER_ITERATION * in ;// 0...15 1396const int is = 0 ; 1397#else 1398const int l0 = 4 * in ;// 0, 4, 8, ..., 28 1399const int is = in /4 ; 1400#endif 1401 1402float tmp = 0 ;// partial sum for thread in warp 1403 1404for (int i = ix ;i < num_blocks_per_row ;i += K_QUANTS_PER_ITERATION ) { 1405const int bi = ib0 + i ; 1406 1407const float d = d_base [bi ]; 1408 1409for (int im = 0 ;im < 2 ;++ im ) { 1410const int ql_offset = 64 * im + l0 ; 1411const int qh_offset = 32 * im + l0 ; 1412const int s_offset = 8 * im + is ; 1413const int y_offset = 128 * im + l0 ; 1414 1415const float * y = yy + i * QK_K + y_offset ; 1416const uint8_t * ql = ql_base + bi * (QK_K /2 )+ ql_offset ; 1417const uint8_t * qh = qh_base + bi * (QK_K /4 )+ qh_offset ; 1418const int8_t * s = scales_base + bi * (QK_K /16 )+ s_offset ; 1419 1420#if K_QUANTS_PER_ITERATION == 1 1421float sum = y [0 ]* s [0 ]* d * ((int8_t )((ql [0 ]& 0xF ) | ((qh [0 ]& 0x03 ) <<4 ))- 32 ) 1422+ y [16 ]* s [1 ]* d * ((int8_t )((ql [16 ]& 0xF ) | ((qh [16 ]& 0x03 ) <<4 ))- 32 ) 1423+ y [32 ]* s [2 ]* d * ((int8_t )((ql [32 ]& 0xF ) | ((qh [0 ]& 0x0c ) <<2 ))- 32 ) 1424+ y [48 ]* s [3 ]* d * ((int8_t )((ql [48 ]& 0xF ) | ((qh [16 ]& 0x0c ) <<2 ))- 32 ) 1425+ y [64 ]* s [4 ]* d * ((int8_t )((ql [0 ] >>4 ) | ((qh [0 ]& 0x30 ) >>0 ))- 32 ) 1426+ y [80 ]* s [5 ]* d * ((int8_t )((ql [16 ] >>4 ) | ((qh [16 ]& 0x30 ) >>0 ))- 32 ) 1427+ y [96 ]* s [6 ]* d * ((int8_t )((ql [32 ] >>4 ) | ((qh [0 ]& 0xc0 ) >>2 ))- 32 ) 1428+ y [112 ]* s [7 ]* d * ((int8_t )((ql [48 ] >>4 ) | ((qh [16 ]& 0xc0 ) >>2 ))- 32 ); 1429tmp += sum ; 1430#else 1431float sum = 0 ; 1432for (int l = 0 ;l < 4 ;++ l ) { 1433sum += y [l + 0 ]* s [0 ]* d * ((int8_t )((ql [l + 0 ]& 0xF ) | (((qh [l ] >>0 )& 3 ) <<4 ))- 32 ) 1434+ y [l + 32 ]* s [2 ]* d * ((int8_t )((ql [l + 32 ]& 0xF ) | (((qh [l ] >>2 )& 3 ) <<4 ))- 32 ) 1435+ y [l + 64 ]* s [4 ]* d * ((int8_t )((ql [l + 0 ] >>4 ) | (((qh [l ] >>4 )& 3 ) <<4 ))- 32 ) 1436+ y [l + 96 ]* s [6 ]* d * ((int8_t )((ql [l + 32 ] >>4 ) | (((qh [l ] >>6 )& 3 ) <<4 ))- 32 ); 1437 } 1438tmp += sum ; 1439#endif 1440 } 1441 1442 } 1443 1444#else 1445 1446const int tid = item_ct1 .get_local_id (2 )/(2 * K_QUANTS_PER_ITERATION );// 0...7 1447const int ix = item_ct1 .get_local_id (2 )%(2 * K_QUANTS_PER_ITERATION );// 0...3 1448 1449const int step = tid * K_QUANTS_PER_ITERATION ; 1450 1451float tmp = 0 ;// partial sum for thread in warp 1452 1453for (int i = ix ;i < num_blocks_per_row ;i += 2 * K_QUANTS_PER_ITERATION ) { 1454const int bi = ib0 + i ; 1455 1456const float * y = yy + i * QK_K + step ; 1457const uint8_t * ql = ql_base + bi * (QK_K /2 )+ step ; 1458const uint8_t * qh = qh_base + bi * (QK_K /4 )+ step ; 1459const int8_t * s = scales_base + bi * (QK_K /16 ); 1460 1461const float d = d_base [bi ]; 1462 1463float sum = 0 ; 1464for (int j = 0 ;j < K_QUANTS_PER_ITERATION ;++ j ) { 1465sum += y [j + 0 ]* s [0 ]* d * ((int8_t )((ql [j + 0 ]& 0xF ) | ((qh [j ]& 0x03 ) <<4 ))- 32 ) 1466+ y [j + 16 ]* s [1 ]* d * ((int8_t )((ql [j + 16 ]& 0xF ) | ((qh [j ]& 0x0c ) <<2 ))- 32 ) 1467+ y [j + 32 ]* s [2 ]* d * ((int8_t )((ql [j + 0 ] >>4 ) | ((qh [j ]& 0x30 ) >>0 ))- 32 ) 1468+ y [j + 48 ]* s [3 ]* d * ((int8_t )((ql [j + 16 ] >>4 ) | ((qh [j ]& 0xc0 ) >>2 ))- 32 ); 1469 } 1470tmp += sum ; 1471 1472 } 1473 1474#endif 1475 1476// sum up partial sums and write back result 1477#pragma unroll 1478for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 1479tmp += 1480 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 1481 } 1482 1483if (tid == 0 ) { 1484dst [row ]= tmp ; 1485 } 1486} 1487 1488static void dequantize_mul_mat_vec_q4_0_sycl_reorder (const void * vx ,const dfloat * y , 1489float * dst ,const int ncols , 1490const int nrows , 1491 dpct::queue_ptr stream ) { 1492GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1493const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1494// the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead 1495const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1496const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1497 { 1498 dpct::has_capability_or_fail (stream -> get_device (), 1499 {sycl::aspect::fp16 }); 1500 1501stream -> parallel_for ( 1502 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1503 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1504dequantize_mul_mat_vec_reorder < QK4_0 ,QR4_0 ,dequantize_q4_0_reorder > ( 1505vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1506 }); 1507 } 1508} 1509 1510 1511static void dequantize_mul_mat_vec_q4_0_sycl (const void * vx ,const dfloat * y , 1512float * dst ,const int ncols , 1513const int nrows , 1514 dpct::queue_ptr stream ) { 1515GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1516const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1517// the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead 1518const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1519const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1520 { 1521 dpct::has_capability_or_fail (stream -> get_device (), 1522 {sycl::aspect::fp16 }); 1523 1524stream -> parallel_for ( 1525 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1526 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1527dequantize_mul_mat_vec < QK4_0 ,QR4_0 ,dequantize_q4_0 > ( 1528vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1529 }); 1530 } 1531} 1532 1533static void dequantize_mul_mat_vec_q1_0_sycl_reorder (const void * vx ,const dfloat * y , 1534float * dst ,const int ncols , 1535const int nrows , 1536 dpct::queue_ptr stream ) { 1537GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1538const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1539// the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead 1540const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1541const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1542 { 1543 dpct::has_capability_or_fail (stream -> get_device (), 1544 {sycl::aspect::fp16 }); 1545 1546stream -> parallel_for ( 1547 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1548 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1549dequantize_mul_mat_vec_reorder < QK1_0 ,QR1_0 ,dequantize_q1_0_reorder > ( 1550vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1551 }); 1552 } 1553} 1554 1555static void dequantize_mul_mat_vec_q1_0_sycl (const void * vx ,const dfloat * y , 1556float * dst ,const int ncols , 1557const int nrows , 1558 dpct::queue_ptr stream ) { 1559GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1560const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1561// the number of rows may exceed maximum grid size in the y or z dimensions, use the x dimension instead 1562const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1563const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1564 { 1565 dpct::has_capability_or_fail (stream -> get_device (), 1566 {sycl::aspect::fp16 }); 1567 1568stream -> parallel_for ( 1569 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1570 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1571dequantize_mul_mat_vec < QK1_0 ,QR1_0 ,dequantize_q1_0 > ( 1572vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1573 }); 1574 } 1575} 1576 1577static void dequantize_mul_mat_vec_q4_1_sycl (const void * vx ,const dfloat * y , 1578float * dst ,const int ncols , 1579const int nrows , 1580 dpct::queue_ptr stream ) { 1581GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1582const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1583const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1584const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1585 { 1586 dpct::has_capability_or_fail (stream -> get_device (), 1587 {sycl::aspect::fp16 }); 1588 1589stream -> parallel_for ( 1590 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1591 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1592dequantize_mul_mat_vec < QK4_1 ,QR4_1 ,dequantize_q4_1 > ( 1593vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1594 }); 1595 } 1596} 1597 1598static void dequantize_mul_mat_vec_q5_0_sycl (const void * vx ,const dfloat * y , 1599float * dst ,const int ncols , 1600const int nrows , 1601 dpct::queue_ptr stream ) { 1602GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1603const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1604const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1605const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1606 { 1607 dpct::has_capability_or_fail (stream -> get_device (), 1608 {sycl::aspect::fp16 }); 1609 1610stream -> parallel_for ( 1611 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1612 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1613dequantize_mul_mat_vec < QK5_0 ,QR5_0 ,dequantize_q5_0 > ( 1614vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1615 }); 1616 } 1617} 1618 1619static void dequantize_mul_mat_vec_q5_1_sycl (const void * vx ,const dfloat * y , 1620float * dst ,const int ncols , 1621const int nrows , 1622 dpct::queue_ptr stream ) { 1623GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1624const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1625const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1626const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1627 { 1628 dpct::has_capability_or_fail (stream -> get_device (), 1629 {sycl::aspect::fp16 }); 1630 1631stream -> parallel_for ( 1632 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1633 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1634dequantize_mul_mat_vec < QK5_1 ,QR5_1 ,dequantize_q5_1 > ( 1635vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1636 }); 1637 } 1638} 1639 1640static void dequantize_mul_mat_vec_q8_0_sycl_reorder (const void * vx ,const dfloat * y , 1641float * dst ,const int ncols , 1642const int nrows , 1643 dpct::queue_ptr stream ) { 1644GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1645const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1646const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1647const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1648 { 1649 dpct::has_capability_or_fail (stream -> get_device (), 1650 {sycl::aspect::fp16 }); 1651 1652stream -> parallel_for ( 1653 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1654 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1655// Q8_0 reorder layout: [all qs (ncols*nrows bytes)][all d values] 1656// Cannot reuse dequantize_mul_mat_vec_reorder template because it has 1657// Q4_0-specific constants hardcoded (d_ptr offset and qs stride). 1658const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 1659item_ct1 .get_local_id (1 ); 1660if (row >=nrows )return ; 1661 1662const int tid = item_ct1 .get_local_id (2 ); 1663const int iter_stride = 8 * 2 * GGML_SYCL_DMMV_X ; 1664const int vals_per_iter = iter_stride /WARP_SIZE ; 1665const int ncols_left = ncols % (QK8_0 * WARP_SIZE ); 1666const int ncols_align = ncols - ncols_left ; 1667 1668#ifdef GGML_SYCL_F16 1669 sycl::half2 tmp = {0.0f ,0.0f }; 1670#else 1671float tmp = 0.0f ; 1672#endif 1673const char * d_ptr = (const char * )vx + ncols * nrows ;// d after all qs 1674 1675int i = 0 ; 1676for (i = 0 ;i < ncols_align ;i += iter_stride ) { 1677const int col = i + vals_per_iter * tid ; 1678const int ib = (row * ncols + col )/QK8_0 ; 1679const int iqs = col %QK8_0 ; 1680 1681#pragma unroll 1682for (int j = 0 ;j < vals_per_iter ;j += 2 ) { 1683dfloat2 v ; 1684dequantize_q8_0_reorder ((const void * )d_ptr ,ib , (const void * )vx , 1685ib * QK8_0 + iqs + j ,v ); 1686 1687#ifdef GGML_SYCL_F16 1688dfloat2 t1 {y [col + j + 0 ],y [col + j + 1 ]}; 1689tmp += v * t1 ; 1690#else 1691tmp += v .x ()* y [col + j + 0 ]; 1692tmp += v .y ()* y [col + j + 1 ]; 1693#endif 1694 } 1695 } 1696 1697// handle remaining columns 1698for (;i < ncols ;i += iter_stride ) { 1699if (tid >=ncols_left /QK8_0 )continue ; 1700const int col = i + vals_per_iter * tid ; 1701const int ib = (row * ncols + col )/QK8_0 ; 1702const int iqs = col %QK8_0 ; 1703 1704#pragma unroll 1705for (int j = 0 ;j < vals_per_iter ;j += 2 ) { 1706dfloat2 v ; 1707dequantize_q8_0_reorder ((const void * )d_ptr ,ib , (const void * )vx , 1708ib * QK8_0 + iqs + j ,v ); 1709 1710#ifdef GGML_SYCL_F16 1711dfloat2 t1 {y [col + j + 0 ],y [col + j + 1 ]}; 1712tmp += v * t1 ; 1713#else 1714tmp += v .x ()* y [col + j + 0 ]; 1715tmp += v .y ()* y [col + j + 1 ]; 1716#endif 1717 } 1718 } 1719 1720// reduce 1721const int mask_start = ncols > GGML_SYCL_DMMV_X ?WARP_SIZE >>1 :WARP_SIZE >>2 ; 1722for (int mask = mask_start ;mask > 0 ;mask >>=1 ) { 1723tmp += dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 1724 } 1725 1726if (tid == 0 ) { 1727#ifdef GGML_SYCL_F16 1728dst [row ]= tmp .x ()+ tmp .y (); 1729#else 1730dst [row ]= tmp ; 1731#endif 1732 } 1733 }); 1734 } 1735} 1736 1737static void dequantize_mul_mat_vec_q8_0_sycl (const void * vx ,const dfloat * y , 1738float * dst ,const int ncols , 1739const int nrows , 1740 dpct::queue_ptr stream ) { 1741GGML_ASSERT (ncols %GGML_SYCL_DMMV_X == 0 ); 1742const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1743const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1744const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1745 { 1746 dpct::has_capability_or_fail (stream -> get_device (), 1747 {sycl::aspect::fp16 }); 1748 1749stream -> parallel_for ( 1750 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1751 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1752dequantize_mul_mat_vec < QK8_0 ,QR8_0 ,dequantize_q8_0 > ( 1753vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1754 }); 1755 } 1756} 1757 1758static void dequantize_mul_mat_vec_q2_K_sycl (const void * vx ,const float * y , 1759float * dst ,const int ncols , 1760const int nrows , 1761 dpct::queue_ptr stream ) { 1762GGML_ASSERT (ncols %QK_K == 0 ); 1763const int ny = 2 ;// very slightly faster than 1 even when K_QUANTS_PER_ITERATION = 2 1764const int block_num_y = (nrows + ny - 1 ) /ny ; 1765const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1766const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1767stream -> parallel_for ( 1768 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1769 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1770dequantize_mul_mat_vec_q2_k (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1771 }); 1772} 1773 1774static void dequantize_mul_mat_vec_q2_K_sycl_reorder (const void * vx ,const float * y , 1775float * dst ,const int ncols , 1776const int nrows , 1777 dpct::queue_ptr stream ) { 1778GGML_ASSERT (ncols %QK_K == 0 ); 1779const int ny = 2 /K_QUANTS_PER_ITERATION ; 1780const int block_num_y = (nrows + ny - 1 ) /ny ; 1781const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1782const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1783stream -> parallel_for ( 1784 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1785 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1786dequantize_mul_mat_vec_q2_k_reorder (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1787 }); 1788} 1789 1790static void dequantize_mul_mat_vec_q3_K_sycl (const void * vx ,const float * y , 1791float * dst ,const int ncols , 1792const int nrows , 1793 dpct::queue_ptr stream ) { 1794GGML_ASSERT (ncols %QK_K == 0 ); 1795const int ny = 2 /K_QUANTS_PER_ITERATION ; 1796const int block_num_y = (nrows + ny - 1 ) /ny ; 1797const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1798const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1799stream -> parallel_for ( 1800 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1801 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1802dequantize_mul_mat_vec_q3_k (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1803 }); 1804} 1805 1806static void dequantize_mul_mat_vec_q3_K_sycl_reorder (const void * vx ,const float * y , 1807float * dst ,const int ncols , 1808const int nrows , 1809 dpct::queue_ptr stream ) { 1810GGML_ASSERT (ncols %QK_K == 0 ); 1811const int ny = 2 /K_QUANTS_PER_ITERATION ; 1812const int block_num_y = (nrows + ny - 1 ) /ny ; 1813const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1814const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1815stream -> parallel_for ( 1816 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1817 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1818dequantize_mul_mat_vec_q3_k_reorder (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1819 }); 1820} 1821 1822static void dequantize_mul_mat_vec_q4_K_sycl (const void * vx ,const float * y , 1823float * dst ,const int ncols , 1824const int nrows , 1825 dpct::queue_ptr stream ) { 1826GGML_ASSERT (ncols %QK_K == 0 ); 1827const int ny = 2 /K_QUANTS_PER_ITERATION ; 1828const int block_num_y = (nrows + ny - 1 ) /ny ; 1829const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1830const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1831stream -> parallel_for ( 1832 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1833 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1834dequantize_mul_mat_vec_q4_k (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1835 }); 1836} 1837 1838static void dequantize_mul_mat_vec_q5_K_sycl (const void * vx ,const float * y , 1839float * dst ,const int ncols , 1840const int nrows , 1841 dpct::queue_ptr stream ) { 1842GGML_ASSERT (ncols %QK_K == 0 ); 1843const int ny = 2 /K_QUANTS_PER_ITERATION ; 1844const int block_num_y = (nrows + ny - 1 ) /ny ; 1845const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1846const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1847stream -> parallel_for ( 1848 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1849 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1850dequantize_mul_mat_vec_q5_k (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1851 }); 1852} 1853 1854static void dequantize_mul_mat_vec_q6_K_sycl (const void * vx ,const float * y , 1855float * dst ,const int ncols , 1856const int nrows , 1857 dpct::queue_ptr stream ) { 1858GGML_ASSERT (ncols %QK_K == 0 ); 1859const int ny = 2 /K_QUANTS_PER_ITERATION ; 1860const int block_num_y = (nrows + ny - 1 ) /ny ; 1861const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1862const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 1863stream -> parallel_for ( 1864 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1865 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1866dequantize_mul_mat_vec_q6_k (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 1867 }); 1868} 1869 1870#ifdef GGML_SYCL_DMMV_HAS_ESIMD 1871using ggml_sycl_esimd::GGML_SYCL_DMMV_ESIMD_WG_SIZE ; 1872 1873// generic reordered dequantize-matvec: each work-group owns a pair of 1874// consecutive output rows and updates one 32-wide accumulator per row 1875template < ggml_type T > 1876ESIMD_INLINE void dequantize_mul_mat_vec_reorder_esimd ( 1877const void * vx ,const float * y ,float * dst , 1878const int ncols ,const int nrows , 1879 sycl::local_accessor < float ,1 > lmem , 1880const sycl::nd_item < 1 > & it ) { 1881using namespace sycl::ext::intel::esimd ; 1882using traits = ggml_sycl_esimd::esimd_reorder_q_traits < T > ; 1883 1884const int num_blocks_per_row = ncols /QK_K ; 1885const size_t nb = (size_t )nrows * num_blocks_per_row ; 1886const auto ps = traits::make_ptrs (vx ,nb ); 1887 1888const int tid = it .get_local_id (0 ); 1889const int row_pair = it .get_group (0 ); 1890const int row0 = row_pair * 2 ;// two consecutive output rows 1891const bool has_row1 = row0 + 1 < nrows ; 1892 1893// one 32-wide accumulator per output row (small footprint, no spill) 1894simd < float ,32 > acc0 = 0.0f ; 1895simd < float ,32 > acc1 = 0.0f ; 1896 1897for (int ib = tid ;ib < num_blocks_per_row ;ib += GGML_SYCL_DMMV_ESIMD_WG_SIZE ) { 1898simd < float ,256 > y_vec = block_load < float ,256 > (y + (size_t )ib * QK_K ); 1899 1900const size_t bi0 = (size_t ) (row0 + 0 )* num_blocks_per_row + ib ; 1901const size_t bi1 = (size_t ) (row0 + 1 )* num_blocks_per_row + ib ; 1902 1903 traits::mac_pair (ps ,bi0 ,ps ,bi1 ,has_row1 ,y_vec ,acc0 ,acc1 ); 1904 } 1905 1906lmem [tid * 2 + 0 ]= reduce < float > (acc0 , std::plus <> {}); 1907lmem [tid * 2 + 1 ]= reduce < float > (acc1 , std::plus <> {}); 1908it .barrier (sycl::access::fence_space::local_space ); 1909 1910if (tid == 0 ) { 1911float sum0 = 0.0f ; 1912float sum1 = 0.0f ; 1913for (int p = 0 ;p < GGML_SYCL_DMMV_ESIMD_WG_SIZE ;++ p ) { 1914sum0 += lmem [p * 2 + 0 ]; 1915sum1 += lmem [p * 2 + 1 ]; 1916 } 1917dst [row0 + 0 ]= sum0 ; 1918if (has_row1 ) { 1919dst [row0 + 1 ]= sum1 ; 1920 } 1921 } 1922} 1923 1924static void dequantize_mul_mat_vec_q2_K_sycl_reorder_esimd (const void * vx ,const float * y , 1925float * dst ,const int ncols , 1926const int nrows , 1927 dpct::queue_ptr stream ) { 1928GGML_ASSERT (ncols %QK_K == 0 ); 1929const int workgroups = (nrows + 1 ) /2 ; 1930stream -> submit ([& ](sycl::handler & h ) { 1931 sycl::local_accessor < float ,1 > lmem (sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE * 2 ),h ); 1932h .parallel_for ( 1933 sycl::nd_range < 1 > (sycl::range < 1 > ((size_t )workgroups * GGML_SYCL_DMMV_ESIMD_WG_SIZE ), sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE )), 1934 [= ](sycl::nd_item < 1 > it ) [[intel ::sycl_explicit_simd ]] { 1935dequantize_mul_mat_vec_reorder_esimd < GGML_TYPE_Q2_K > ( 1936vx ,y ,dst ,ncols ,nrows ,lmem ,it ); 1937 }); 1938 }); 1939} 1940 1941static void dequantize_mul_mat_vec_q3_K_sycl_reorder_esimd (const void * vx ,const float * y , 1942float * dst ,const int ncols , 1943const int nrows , 1944 dpct::queue_ptr stream ) { 1945GGML_ASSERT (ncols %QK_K == 0 ); 1946const int workgroups = (nrows + 1 ) /2 ; 1947stream -> submit ([& ](sycl::handler & h ) { 1948 sycl::local_accessor < float ,1 > lmem (sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE * 2 ),h ); 1949h .parallel_for ( 1950 sycl::nd_range < 1 > (sycl::range < 1 > ((size_t )workgroups * GGML_SYCL_DMMV_ESIMD_WG_SIZE ), sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE )), 1951 [= ](sycl::nd_item < 1 > it ) [[intel ::sycl_explicit_simd ]] { 1952dequantize_mul_mat_vec_reorder_esimd < GGML_TYPE_Q3_K > ( 1953vx ,y ,dst ,ncols ,nrows ,lmem ,it ); 1954 }); 1955 }); 1956} 1957 1958static void dequantize_mul_mat_vec_q4_K_sycl_reorder_esimd (const void * vx ,const float * y , 1959float * dst ,const int ncols , 1960const int nrows , 1961 dpct::queue_ptr stream ) { 1962GGML_ASSERT (ncols %QK_K == 0 ); 1963const int workgroups = (nrows + 1 ) /2 ; 1964stream -> submit ([& ](sycl::handler & h ) { 1965 sycl::local_accessor < float ,1 > lmem (sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE * 2 ),h ); 1966h .parallel_for ( 1967 sycl::nd_range < 1 > (sycl::range < 1 > ((size_t )workgroups * GGML_SYCL_DMMV_ESIMD_WG_SIZE ), sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE )), 1968 [= ](sycl::nd_item < 1 > it ) [[intel ::sycl_explicit_simd ]] { 1969dequantize_mul_mat_vec_reorder_esimd < GGML_TYPE_Q4_K > ( 1970vx ,y ,dst ,ncols ,nrows ,lmem ,it ); 1971 }); 1972 }); 1973} 1974 1975static void dequantize_mul_mat_vec_q5_K_sycl_reorder_esimd (const void * vx ,const float * y , 1976float * dst ,const int ncols , 1977const int nrows , 1978 dpct::queue_ptr stream ) { 1979GGML_ASSERT (ncols %QK_K == 0 ); 1980const int workgroups = (nrows + 1 ) /2 ; 1981stream -> submit ([& ](sycl::handler & h ) { 1982 sycl::local_accessor < float ,1 > lmem (sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE * 2 ),h ); 1983h .parallel_for ( 1984 sycl::nd_range < 1 > (sycl::range < 1 > ((size_t )workgroups * GGML_SYCL_DMMV_ESIMD_WG_SIZE ), sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE )), 1985 [= ](sycl::nd_item < 1 > it ) [[intel ::sycl_explicit_simd ]] { 1986dequantize_mul_mat_vec_reorder_esimd < GGML_TYPE_Q5_K > ( 1987vx ,y ,dst ,ncols ,nrows ,lmem ,it ); 1988 }); 1989 }); 1990} 1991 1992static void dequantize_mul_mat_vec_q6_K_sycl_reorder_esimd (const void * vx ,const float * y , 1993float * dst ,const int ncols , 1994const int nrows , 1995 dpct::queue_ptr stream ) { 1996GGML_ASSERT (ncols %QK_K == 0 ); 1997const int workgroups = (nrows + 1 ) /2 ; 1998stream -> submit ([& ](sycl::handler & h ) { 1999 sycl::local_accessor < float ,1 > lmem (sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE * 2 ),h ); 2000h .parallel_for ( 2001 sycl::nd_range < 1 > (sycl::range < 1 > ((size_t )workgroups * GGML_SYCL_DMMV_ESIMD_WG_SIZE ), sycl::range < 1 > (GGML_SYCL_DMMV_ESIMD_WG_SIZE )), 2002 [= ](sycl::nd_item < 1 > it ) [[intel ::sycl_explicit_simd ]] { 2003dequantize_mul_mat_vec_reorder_esimd < GGML_TYPE_Q6_K > ( 2004vx ,y ,dst ,ncols ,nrows ,lmem ,it ); 2005 }); 2006 }); 2007} 2008 2009#endif // GGML_SYCL_DMMV_HAS_ESIMD 2010 2011static void dequantize_mul_mat_vec_q4_K_sycl_reorder (const void * vx ,const float * y , 2012float * dst ,const int ncols , 2013const int nrows , 2014 dpct::queue_ptr stream ) { 2015GGML_ASSERT (ncols %QK_K == 0 ); 2016const int ny = 2 /K_QUANTS_PER_ITERATION ; 2017const int block_num_y = (nrows + ny - 1 ) /ny ; 2018const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2019const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 2020stream -> parallel_for ( 2021 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2022 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2023dequantize_mul_mat_vec_q4_k_reorder (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 2024 }); 2025} 2026 2027static void dequantize_mul_mat_vec_q5_K_sycl_reorder (const void * vx ,const float * y , 2028float * dst ,const int ncols , 2029const int nrows , 2030 dpct::queue_ptr stream ) { 2031GGML_ASSERT (ncols %QK_K == 0 ); 2032const int ny = 2 /K_QUANTS_PER_ITERATION ; 2033const int block_num_y = (nrows + ny - 1 ) /ny ; 2034const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2035const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 2036stream -> parallel_for ( 2037 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2038 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2039dequantize_mul_mat_vec_q5_k_reorder (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 2040 }); 2041} 2042 2043static void dequantize_mul_mat_vec_q6_K_sycl_reorder (const void * vx ,const float * y , 2044float * dst ,const int ncols , 2045const int nrows , 2046 dpct::queue_ptr stream ) { 2047GGML_ASSERT (ncols %QK_K == 0 ); 2048const int ny = 2 /K_QUANTS_PER_ITERATION ; 2049const int block_num_y = (nrows + ny - 1 ) /ny ; 2050const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2051const sycl::range < 3 > block_dims (1 ,ny ,WARP_SIZE ); 2052stream -> parallel_for ( 2053 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2054 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2055dequantize_mul_mat_vec_q6_k_reorder (vx ,y ,dst ,ncols ,nrows ,item_ct1 ); 2056 }); 2057} 2058 2059void ggml_sycl_op_dequantize_mul_mat_vec ( 2060ggml_backend_sycl_context & ctx , 2061const ggml_tensor * src0 ,const ggml_tensor * src1 ,ggml_tensor * dst , 2062const char * src0_dd_i ,const float * src1_ddf_i ,const char * src1_ddq_i , 2063float * dst_dd_i ,const int64_t row_low ,const int64_t row_high , 2064const int64_t src1_ncols ,const int64_t src1_padded_row_size , 2065const dpct::queue_ptr & stream ) { 2066 2067const int64_t ne00 = src0 -> ne [0 ]; 2068const int64_t row_diff = row_high - row_low ; 2069GGML_ASSERT (src1 -> type == GGML_TYPE_F32 ); 2070// on some GPUs it is faster to convert src1 to half and to use half precision intrinsics 2071#ifdef GGML_SYCL_F16 2072ggml_sycl_pool_alloc < sycl::half > src1_dfloat_a (ctx .pool ()); 2073 sycl::half * src1_dfloat = nullptr ;// dfloat == half 2074 2075bool src1_convert_f16 = 2076src0 -> type == GGML_TYPE_Q1_0 || 2077src0 -> type == GGML_TYPE_Q4_0 || src0 -> type == GGML_TYPE_Q4_1 || 2078src0 -> type == GGML_TYPE_Q5_0 || src0 -> type == GGML_TYPE_Q5_1 || 2079src0 -> type == GGML_TYPE_Q8_0 || src0 -> type == GGML_TYPE_F16 || 2080src0 -> type == GGML_TYPE_BF16 ; 2081 2082if (src1_convert_f16 ) { 2083scope_op_debug_print scope_dbg_print (__func__ ,"/to_fp16_sycl" ,dst ,/*num_src=*/ 2 , 2084" : converting src1 to fp16" ); 2085src1_dfloat = src1_dfloat_a .alloc (ne00 ); 2086const to_fp16_sycl_t to_fp16_sycl = ggml_get_to_fp16_sycl (src1 -> type ,dst ); 2087GGML_ASSERT (to_fp16_sycl != nullptr ); 2088to_fp16_sycl (src1_ddf_i ,src1_dfloat ,ne00 ,stream ); 2089 } 2090#else 2091const dfloat * src1_dfloat = (const dfloat * )src1_ddf_i ;// dfloat == float, no conversion 2092#endif // GGML_SYCL_F16 2093 2094switch (src0 -> type ) { 2095case GGML_TYPE_Q1_0 : 2096if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2097 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2098dequantize_mul_mat_vec_q1_0_sycl_reorder (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2099 }else { 2100dequantize_mul_mat_vec_q1_0_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2101 } 2102break ; 2103case GGML_TYPE_Q4_0 : 2104if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2105 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2106dequantize_mul_mat_vec_q4_0_sycl_reorder (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2107 }else { 2108dequantize_mul_mat_vec_q4_0_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2109 } 2110break ; 2111case GGML_TYPE_Q4_1 : 2112dequantize_mul_mat_vec_q4_1_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2113break ; 2114case GGML_TYPE_Q5_0 : 2115dequantize_mul_mat_vec_q5_0_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2116break ; 2117case GGML_TYPE_Q5_1 : 2118dequantize_mul_mat_vec_q5_1_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2119break ; 2120case GGML_TYPE_Q8_0 : 2121if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2122 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2123dequantize_mul_mat_vec_q8_0_sycl_reorder (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2124 }else { 2125dequantize_mul_mat_vec_q8_0_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2126 } 2127break ; 2128case GGML_TYPE_Q2_K : 2129if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2130 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2131#ifdef GGML_SYCL_DMMV_HAS_ESIMD 2132if (g_ggml_sycl_enable_esimd ) { 2133dequantize_mul_mat_vec_q2_K_sycl_reorder_esimd (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2134 } 2135else 2136#endif 2137 { 2138dequantize_mul_mat_vec_q2_K_sycl_reorder (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2139 } 2140 }else { 2141dequantize_mul_mat_vec_q2_K_sycl (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2142 } 2143break ; 2144case GGML_TYPE_Q3_K : 2145if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2146 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2147#ifdef GGML_SYCL_DMMV_HAS_ESIMD 2148if (g_ggml_sycl_enable_esimd ) { 2149dequantize_mul_mat_vec_q3_K_sycl_reorder_esimd (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2150 } 2151else 2152#endif 2153 { 2154dequantize_mul_mat_vec_q3_K_sycl_reorder (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2155 } 2156 }else { 2157dequantize_mul_mat_vec_q3_K_sycl (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2158 } 2159break ; 2160case GGML_TYPE_Q4_K : 2161if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2162 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2163#ifdef GGML_SYCL_DMMV_HAS_ESIMD 2164if (g_ggml_sycl_enable_esimd ) { 2165dequantize_mul_mat_vec_q4_K_sycl_reorder_esimd (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2166 } 2167else 2168#endif 2169 { 2170dequantize_mul_mat_vec_q4_K_sycl_reorder (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2171 } 2172 }else { 2173dequantize_mul_mat_vec_q4_K_sycl (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2174 } 2175break ; 2176case GGML_TYPE_Q5_K : 2177if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2178 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2179#ifdef GGML_SYCL_DMMV_HAS_ESIMD 2180if (g_ggml_sycl_enable_esimd ) { 2181dequantize_mul_mat_vec_q5_K_sycl_reorder_esimd (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2182 } 2183else 2184#endif 2185 { 2186dequantize_mul_mat_vec_q5_K_sycl_reorder (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2187 } 2188 }else { 2189dequantize_mul_mat_vec_q5_K_sycl (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2190 } 2191break ; 2192case GGML_TYPE_Q6_K : 2193if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2194 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2195#ifdef GGML_SYCL_DMMV_HAS_ESIMD 2196if (g_ggml_sycl_enable_esimd ) { 2197dequantize_mul_mat_vec_q6_K_sycl_reorder_esimd (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2198 } 2199else 2200#endif 2201 { 2202dequantize_mul_mat_vec_q6_K_sycl_reorder (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2203 } 2204 }else { 2205dequantize_mul_mat_vec_q6_K_sycl (src0_dd_i ,src1_ddf_i ,dst_dd_i ,ne00 ,row_diff ,stream ); 2206 } 2207break ; 2208case GGML_TYPE_F16 : 2209convert_mul_mat_vec_f16_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2210break ; 2211#ifdef GGML_SYCL_DMMV_HAS_BF16 2212case GGML_TYPE_BF16 : 2213convert_mul_mat_vec_bf16_sycl (src0_dd_i ,src1_dfloat ,dst_dd_i ,ne00 ,row_diff ,stream ); 2214break ; 2215#endif 2216default : 2217printf ("ggml_sycl_op_dequantize_mul_mat_vec unsupported GGML_TYPE %d\n" ,src0 -> type ); 2218GGML_ABORT ("fatal error" ); 2219 } 2220 2221GGML_UNUSED (src1 ); 2222GGML_UNUSED (dst ); 2223GGML_UNUSED (src1_ddq_i ); 2224GGML_UNUSED (src1_ncols ); 2225GGML_UNUSED (src1_padded_row_size ); 2226GGML_UNUSED (ctx ); 2227}