char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
304665fe7
char/aliceai-t5-moe
1#include "mmvq.hpp" 2 3#include "ggml.h" 4#include "common.hpp" 5#include "element_wise.hpp" 6#include "quants.hpp" 7#include "vecdotq.hpp" 8 9// Minimum weight-row count at which the Q4_K multi-column MMVQ kernel handles two output rows per 10// subgroup (rows_per_sg == 2) instead of one, when ncols_dst == 2. 11// 12// Pairing rows lets a subgroup load each activation block once and apply it to two rows, at the cost 13// of halving the number of subgroups in the launch. With only two destination columns there is too 14// little work per row to hide that loss of parallelism, so pairing only pays off once there are 15// enough rows to keep the device occupied. This is a measured performance crossover, not a 16// correctness or hardware limit - both variants compute the same result for any nrows. 17// 18// Derived on Intel Arc Pro B70 with `test-backend-ops perf -o MUL_MAT` (Q4_K, ncols_dst == 2), 19// sweeping nrows over 5120..6912 at ncols 17408 and 19968: one row per subgroup was up to 9% faster 20// below the crossover, two rows per subgroup 8-15% faster above it, and the crossover fell inside 21// (6144, 6272] for both ncols with no measurable ncols dependence. A later 32-row granularity sweep 22// narrowed it to (6144, 6176], so 6272 is a conservative gate rather than the exact crossover. 23// ncols_dst >= 3 amortizes the activation loads over more columns and is faster with two rows at 24// every row count, so it does not consult this threshold. 25static constexpr int Q4_K_MMVQ_ROW_PAIR_MIN_NROWS = 6272 ; 26 27template < typename reorder_vec_dot_q_sycl > 28static void mul_mat_vec_q_reorder (const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 29const int ncols ,const int nrows ,const sycl::nd_item < 3 > & nd_item ) { 30using block_type = ggml_sycl_reordered::block_q_t < reorder_vec_dot_q_sycl::gtype > ; 31using block_traits = typename block_type::traits ; 32 33const auto sg = nd_item .get_sub_group (); 34const int sg_range = sg .get_group_linear_range (); 35const int workgroup_id = nd_item .get_group_linear_id (); 36const int sg_id = sg .get_group_linear_id (); 37const int row = workgroup_id * sg_range + sg_id ; 38 39if (row >=nrows ) { 40return ; 41 } 42 43const int blocks_per_row = ncols / block_traits::qk ; 44constexpr int blocks_per_subgroup = ceil_div (block_traits::vdr_mmvq * WARP_SIZE , block_traits::qi ); 45constexpr int block_elements_per_subgroup = block_traits::qi / block_traits::vdr_mmvq ; 46const int nblocks = nrows * (ncols / block_traits::qk ); 47 48 static_assert(blocks_per_subgroup > 0 ); 49 static_assert(block_elements_per_subgroup > 0 ); 50 51float partial_sum = 0.0f ; 52for (int i = sg .get_local_linear_id () /block_elements_per_subgroup ;i < blocks_per_row ;i += blocks_per_subgroup ) { 53const int ibx = row * blocks_per_row + i ;// x block index 54 55const auto bx_offset = block_type::get_block_offset (ibx ,nblocks ); 56const auto d_offset = block_type::get_d_offset (nrows ,ncols ,ibx ); 57// Y block index that aligns with ibx 58const int iby = i * block_type::block_to_q8_1_ratio (); 59const int8_t * q8_1_quant_ptr = (const int8_t * )vy + iby * QK8_1 ; 60const sycl::half2 * q8_1_ds_ptr = (const sycl::half2 * )((const char * )vy + ncols + iby * sizeof (sycl::half2 )); 61 62#pragma unroll 63for (int elem = 0 ;elem < block_elements_per_subgroup ;elem += WARP_SIZE ) { 64// x block quant index when casting the quants to int 65const int iqs = elem + block_traits::vdr_mmvq * (sg .get_local_linear_id () %block_elements_per_subgroup ); 66 67partial_sum += reorder_vec_dot_q_sycl ()(vx ,bx_offset ,d_offset ,q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 68 } 69 } 70 71auto sum = sycl::reduce_over_group (nd_item .get_sub_group (),partial_sum , std::plus <> ()); 72 73if (sg .leader ()) { 74dst [row ]= sum ; 75 } 76} 77 78// With has_fusion, `vgate` is a second weight matrix sharing vx's shape, stride and reorder 79// layout: one pass computes both row dot products and the epilogue writes glu(gate, up). 80template < typename reorder_vec_dot_q_sycl ,int ncols_dst ,bool has_fusion = false,int rows_per_sg = 1 > 81static void mul_mat_vec_q_reorder_ncols (const void * __restrict__vx ,const void * __restrict__vgate , 82const void * __restrict__vy ,float * __restrict__dst ,const int ncols , 83const int nrows ,const int stride_col_y_bytes ,const int stride_col_dst , 84const ggml_glu_op glu_op ,const sycl::nd_item < 3 > & nd_item ) { 85using block_type = ggml_sycl_reordered::block_q_t < reorder_vec_dot_q_sycl::gtype > ; 86using block_traits = typename block_type::traits ; 87 88const auto sg = nd_item .get_sub_group (); 89const int sg_range = sg .get_group_linear_range (); 90const int workgroup_id = nd_item .get_group_linear_id (); 91const int sg_id = sg .get_group_linear_id (); 92const int row0 = (workgroup_id * sg_range + sg_id )* rows_per_sg ; 93 94// row is sub-group uniform, so this retires whole sub-groups and the collectives below 95// stay convergent 96if (row0 >=nrows ) { 97return ; 98 } 99 100 static_assert(rows_per_sg == 1 || 101reorder_vec_dot_shared_activations < reorder_vec_dot_q_sycl::gtype > ::value ); 102 103const int blocks_per_row = ncols / block_traits::qk ; 104constexpr int blocks_per_subgroup = ceil_div (block_traits::vdr_mmvq * WARP_SIZE , block_traits::qi ); 105constexpr int block_elements_per_subgroup = block_traits::qi / block_traits::vdr_mmvq ; 106const int nblocks = nrows * (ncols / block_traits::qk ); 107 108 static_assert(blocks_per_subgroup > 0 ); 109 static_assert(block_elements_per_subgroup > 0 ); 110 111float partial_sum [ncols_dst ][rows_per_sg ]= {}; 112// sized 1 rather than 0 when unused: zero-length arrays are not standard C++, and the 113// array is dead and eliminated in that case 114 [[maybe_unused ]]float partial_gate [has_fusion ?ncols_dst :1 ][has_fusion ?rows_per_sg :1 ]= {}; 115for (int i = sg .get_local_linear_id () /block_elements_per_subgroup ;i < blocks_per_row ;i += blocks_per_subgroup ) { 116const int iby = i * block_type::block_to_q8_1_ratio (); 117 118#pragma unroll 119for (int elem = 0 ;elem < block_elements_per_subgroup ;elem += WARP_SIZE ) { 120const int iqs = elem + block_traits::vdr_mmvq * (sg .get_local_linear_id () %block_elements_per_subgroup ); 121 122if constexpr (rows_per_sg > 1 ) { 123typename reorder_vec_dot_q_sycl::weights wx [rows_per_sg ]; 124 [[maybe_unused ]]typename reorder_vec_dot_q_sycl::weights wg [rows_per_sg ]; 125#pragma unroll 126for (int r = 0 ;r < rows_per_sg ;++ r ) { 127const int row = sycl::min (row0 + r ,nrows - 1 ); 128const int ibx = row * blocks_per_row + i ; 129const auto bx_offset = block_type::get_block_offset (ibx ,nblocks ); 130const auto d_offset = block_type::get_d_offset (nrows ,ncols ,ibx ); 131wx [r ]= reorder_vec_dot_q_sycl::load (vx ,bx_offset ,d_offset ,iqs ); 132if constexpr (has_fusion ) { 133wg [r ]= reorder_vec_dot_q_sycl::load (vgate ,bx_offset ,d_offset ,iqs ); 134 } 135 } 136#pragma unroll 137for (int j = 0 ;j < ncols_dst ;++ j ) { 138const char * vy_j = (const char * )vy + j * stride_col_y_bytes ; 139const int8_t * q8_1_quant_ptr = (const int8_t * )vy_j + iby * QK8_1 ; 140const sycl::half2 * q8_1_ds_ptr = 141 (const sycl::half2 * ) (vy_j + ncols + iby * sizeof (sycl::half2 )); 142const auto a = reorder_vec_dot_q_sycl::load_activations (q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 143#pragma unroll 144for (int r = 0 ;r < rows_per_sg ;++ r ) { 145partial_sum [j ][r ]+= reorder_vec_dot_q_sycl::apply (wx [r ],a ); 146if constexpr (has_fusion ) { 147partial_gate [j ][r ]+= reorder_vec_dot_q_sycl::apply (wg [r ],a ); 148 } 149 } 150 } 151 }else if constexpr (reorder_vec_dot_shared_weights < reorder_vec_dot_q_sycl::gtype > ::value ) { 152const int ibx = row0 * blocks_per_row + i ; 153const auto bx_offset = block_type::get_block_offset (ibx ,nblocks ); 154const auto d_offset = block_type::get_d_offset (nrows ,ncols ,ibx ); 155const auto wx = reorder_vec_dot_q_sycl::load (vx ,bx_offset ,d_offset ,iqs ); 156if constexpr (has_fusion ) { 157const auto wg = reorder_vec_dot_q_sycl::load (vgate ,bx_offset ,d_offset ,iqs ); 158 159#pragma unroll 160for (int j = 0 ;j < ncols_dst ;++ j ) { 161const char * vy_j = (const char * )vy + j * stride_col_y_bytes ; 162const int8_t * q8_1_quant_ptr = (const int8_t * )vy_j + iby * QK8_1 ; 163const sycl::half2 * q8_1_ds_ptr = 164 (const sycl::half2 * ) (vy_j + ncols + iby * sizeof (sycl::half2 )); 165 166// up and gate share the activation, so load it once and apply it twice 167const auto a = reorder_vec_dot_q_sycl::load_activations (q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 168 169partial_sum [j ][0 ]+= reorder_vec_dot_q_sycl::apply (wx ,a ); 170partial_gate [j ][0 ]+= reorder_vec_dot_q_sycl::apply (wg ,a ); 171 } 172 }else { 173#pragma unroll 174for (int j = 0 ;j < ncols_dst ;++ j ) { 175const char * vy_j = (const char * )vy + j * stride_col_y_bytes ; 176const int8_t * q8_1_quant_ptr = (const int8_t * )vy_j + iby * QK8_1 ; 177const sycl::half2 * q8_1_ds_ptr = 178 (const sycl::half2 * ) (vy_j + ncols + iby * sizeof (sycl::half2 )); 179 180partial_sum [j ][0 ]+= reorder_vec_dot_q_sycl::dot (wx ,q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 181 } 182 } 183 }else { 184const int ibx = row0 * blocks_per_row + i ; 185const auto bx_offset = block_type::get_block_offset (ibx ,nblocks ); 186const auto d_offset = block_type::get_d_offset (nrows ,ncols ,ibx ); 187#pragma unroll 188for (int j = 0 ;j < ncols_dst ;++ j ) { 189const char * vy_j = (const char * )vy + j * stride_col_y_bytes ; 190const int8_t * q8_1_quant_ptr = (const int8_t * )vy_j + iby * QK8_1 ; 191const sycl::half2 * q8_1_ds_ptr = 192 (const sycl::half2 * ) (vy_j + ncols + iby * sizeof (sycl::half2 )); 193 194partial_sum [j ][0 ]+= 195reorder_vec_dot_q_sycl ()(vx ,bx_offset ,d_offset ,q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 196 197if constexpr (has_fusion ) { 198partial_gate [j ][0 ]+= 199reorder_vec_dot_q_sycl ()(vgate ,bx_offset ,d_offset ,q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 200 } 201 } 202 } 203 } 204 } 205 206#pragma unroll 207for (int j = 0 ;j < ncols_dst ;++ j ) { 208#pragma unroll 209for (int r = 0 ;r < rows_per_sg ;++ r ) { 210float sum = sycl::reduce_over_group (nd_item .get_sub_group (),partial_sum [j ][r ], std::plus <> ()); 211 212if constexpr (has_fusion ) { 213const float gate = sycl::reduce_over_group (nd_item .get_sub_group (),partial_gate [j ][r ], std::plus <> ()); 214 215// uniform across the launch; the launcher only instantiates SWIGLU and GEGLU 216sum *=glu_op == GGML_GLU_OP_SWIGLU ?op_silu (gate ) :op_gelu (gate ); 217 } 218 219if (sg .leader ()&& row0 + r < nrows ) { 220dst [j * stride_col_dst + row0 + r ]= sum ; 221 } 222 } 223 } 224} 225 226template < int qk ,int qi ,typename block_q_t ,int vdr ,vec_dot_q_sycl_t vec_dot_q_sycl > 227static void mul_mat_vec_q (const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 228const int ncols ,const int nrows ,const sycl::nd_item < 3 > & item_ct1 ) { 229const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ item_ct1 .get_local_id (1 ); 230 231if (row >=nrows ) { 232return ; 233 } 234 235const int blocks_per_row = ncols /qk ; 236constexpr int blocks_per_warp = (vdr * WARP_SIZE + qi - 1 ) /qi ;// Ensuring blocks_per_warp > 0 237 238assert (blocks_per_warp > 0 ); 239 240// partial sum for each thread 241float tmp = 0.0f ; 242 243const block_q_t * x = (const block_q_t * )vx ; 244const block_q8_1 * y = (const block_q8_1 * )vy ; 245 246for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ;i += blocks_per_warp ) { 247const int ibx = row * blocks_per_row + i ;// x block index 248 249const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 250 251for (size_t elem = 0 ;elem < qi /vdr ;elem += WARP_SIZE ) { 252const int iqs = elem + vdr * (item_ct1 .get_local_id (2 ) % 253 (qi /vdr ));// x block quant index when casting the quants to int 254 255tmp += vec_dot_q_sycl (& x [ibx ],& y [iby ],iqs ); 256 } 257 } 258 259// sum up partial sums and write back result 260#pragma unroll 261for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 262tmp += dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 263 } 264 265if (item_ct1 .get_local_id (2 )== 0 ) { 266dst [row ]= tmp ; 267 } 268} 269 270template < int qk ,int qi ,typename block_q_t ,int vdr , 271vec_dot_q_sycl_t vec_dot_q_sycl ,int ncols_dst > 272static void mul_mat_vec_q_ncols ( 273const void * __restrict__vx , 274const void * __restrict__vy , 275float * __restrict__dst , 276const int ncols , 277const int nrows , 278const int stride_col_y , 279const int stride_col_dst , 280const sycl::nd_item < 3 > & item_ct1 ) { 281 282const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 ) 283+ item_ct1 .get_local_id (1 ); 284 285if (row >=nrows ) { 286return ; 287 } 288 289const int blocks_per_row = ncols /qk ; 290constexpr int blocks_per_warp = (vdr * WARP_SIZE + qi - 1 ) /qi ; 291 292// partial sums: one per output column 293float tmp [ncols_dst ]= {0.0f }; 294 295const block_q_t * x = (const block_q_t * )vx ; 296const block_q8_1 * y = (const block_q8_1 * )vy ; 297 298for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr ); 299i < blocks_per_row ; 300i += blocks_per_warp ) { 301 302const int ibx = row * blocks_per_row + i ; 303const int iby = i * (qk /QK8_1 ); 304 305// read weight block once, dot against all columns 306for (size_t elem = 0 ;elem < qi /vdr ;elem += WARP_SIZE ) { 307const int iqs = elem + vdr * (item_ct1 .get_local_id (2 ) % (qi /vdr )); 308 309#pragma unroll 310for (int j = 0 ;j < ncols_dst ;++ j ) { 311tmp [j ]+= vec_dot_q_sycl (& x [ibx ],& y [j * stride_col_y + iby ],iqs ); 312 } 313 } 314 } 315 316// reduce within subgroup 317#pragma unroll 318for (int j = 0 ;j < ncols_dst ;++ j ) { 319#pragma unroll 320for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 321tmp [j ]+= dpct::permute_sub_group_by_xor ( 322item_ct1 .get_sub_group (),tmp [j ],mask ); 323 } 324 } 325 326if (item_ct1 .get_local_id (2 )== 0 ) { 327#pragma unroll 328for (int j = 0 ;j < ncols_dst ;++ j ) { 329dst [j * stride_col_dst + row ]= tmp [j ]; 330 } 331 } 332} 333 334template < int qk ,int qi ,typename block_q_t ,int vdr > 335static void mul_mat_vec_q_iq2_xxs_q8_1 (const void * __restrict__vx , 336const void * __restrict__vy , 337float * __restrict__dst ,const int ncols , 338const int nrows , 339const sycl::nd_item < 3 > & item_ct1 ) { 340const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 341item_ct1 .get_local_id (1 ); 342 343if (row >=nrows ) { 344return ; 345 } 346 347const int blocks_per_row = ncols /qk ; 348const int blocks_per_warp = vdr * WARP_SIZE /qi ; 349assert (blocks_per_warp > 0 ); 350 351// partial sum for each thread 352float tmp = 0.0f ; 353 354const block_q_t * x = (const block_q_t * )vx ; 355const block_q8_1 * y = (const block_q8_1 * )vy ; 356 357for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 358i += blocks_per_warp ) { 359const int ibx = row * blocks_per_row + i ;// x block index 360 361const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 362 363const int iqs = 364vdr * 365 (item_ct1 .get_local_id (2 ) % 366 (qi /vdr ));// x block quant index when casting the quants to int 367 368tmp += vec_dot_iq2_xxs_q8_1 (& x [ibx ],& y [iby ],iqs ,iq2xxs_grid ,ksigns_iq2xs ,kmask_iq2xs ); 369 } 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 383template < int qk ,int qi ,typename block_q_t ,int vdr > 384static void mul_mat_vec_q_iq2_xs_q8_1 (const void * __restrict__vx , 385const void * __restrict__vy , 386float * __restrict__dst ,const int ncols , 387const int nrows , 388const sycl::nd_item < 3 > & item_ct1 ) { 389const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 390item_ct1 .get_local_id (1 ); 391 392if (row >=nrows ) { 393return ; 394 } 395 396const int blocks_per_row = ncols /qk ; 397const int blocks_per_warp = vdr * WARP_SIZE /qi ; 398assert (blocks_per_warp > 0 ); 399// partial sum for each thread 400float tmp = 0.0f ; 401 402const block_q_t * x = (const block_q_t * )vx ; 403const block_q8_1 * y = (const block_q8_1 * )vy ; 404 405for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 406i += blocks_per_warp ) { 407const int ibx = row * blocks_per_row + i ;// x block index 408 409const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 410 411const int iqs = 412vdr * 413 (item_ct1 .get_local_id (2 ) % 414 (qi /vdr ));// x block quant index when casting the quants to int 415 416tmp += vec_dot_iq2_xs_q8_1 (& x [ibx ],& y [iby ],iqs ,iq2xs_grid ,ksigns64 ); 417 } 418 419// sum up partial sums and write back result 420#pragma unroll 421for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 422tmp += 423 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 424 } 425 426if (item_ct1 .get_local_id (2 )== 0 ) { 427dst [row ]= tmp ; 428 } 429} 430 431template < int qk ,int qi ,typename block_q_t ,int vdr > 432static void mul_mat_vec_q_iq2_s_q8_1 (const void * __restrict__vx , 433const void * __restrict__vy , 434float * __restrict__dst ,const int ncols , 435const int nrows , 436const sycl::nd_item < 3 > & item_ct1 ) { 437const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 438item_ct1 .get_local_id (1 ); 439 440if (row >=nrows ) { 441return ; 442 } 443 444const int blocks_per_row = ncols /qk ; 445const int blocks_per_warp = vdr * WARP_SIZE /qi ; 446assert (blocks_per_warp > 0 ); 447// partial sum for each thread 448float tmp = 0.0f ; 449 450const block_q_t * x = (const block_q_t * )vx ; 451const block_q8_1 * y = (const block_q8_1 * )vy ; 452 453for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 454i += blocks_per_warp ) { 455const int ibx = row * blocks_per_row + i ;// x block index 456 457const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 458 459const int iqs = 460vdr * 461 (item_ct1 .get_local_id (2 ) % 462 (qi /vdr ));// x block quant index when casting the quants to int 463 464tmp += vec_dot_iq2_s_q8_1 (& x [ibx ],& y [iby ],iqs ); 465 } 466 467// sum up partial sums and write back result 468#pragma unroll 469for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 470tmp += 471 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 472 } 473 474if (item_ct1 .get_local_id (2 )== 0 ) { 475dst [row ]= tmp ; 476 } 477} 478 479template < int qk ,int qi ,typename block_q_t ,int vdr > 480static void mul_mat_vec_q_iq3_xxs_q8_1 (const void * __restrict__vx , 481const void * __restrict__vy , 482float * __restrict__dst ,const int ncols , 483const int nrows , 484const sycl::nd_item < 3 > & item_ct1 ) { 485const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 486item_ct1 .get_local_id (1 ); 487 488if (row >=nrows ) { 489return ; 490 } 491 492const int blocks_per_row = ncols /qk ; 493const int blocks_per_warp = vdr * WARP_SIZE /qi ; 494assert (blocks_per_warp > 0 ); 495// partial sum for each thread 496float tmp = 0.0f ; 497 498const block_q_t * x = (const block_q_t * )vx ; 499const block_q8_1 * y = (const block_q8_1 * )vy ; 500 501for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 502i += blocks_per_warp ) { 503const int ibx = row * blocks_per_row + i ;// x block index 504 505const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 506 507const int iqs = 508vdr * 509 (item_ct1 .get_local_id (2 ) % 510 (qi /vdr ));// x block quant index when casting the quants to int 511 512tmp += vec_dot_iq3_xxs_q8_1 (& x [ibx ],& y [iby ],iqs ,iq3xxs_grid ,ksigns64 ); 513 } 514 515// sum up partial sums and write back result 516#pragma unroll 517for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 518tmp += 519 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 520 } 521 522if (item_ct1 .get_local_id (2 )== 0 ) { 523dst [row ]= tmp ; 524 } 525} 526 527template < int qk ,int qi ,typename block_q_t ,int vdr > 528static void mul_mat_vec_q_iq3_s_q8_1 (const void * __restrict__vx , 529const void * __restrict__vy , 530float * __restrict__dst ,const int ncols , 531const int nrows , 532const sycl::nd_item < 3 > & item_ct1 ) { 533const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 534item_ct1 .get_local_id (1 ); 535 536if (row >=nrows ) { 537return ; 538 } 539 540const int blocks_per_row = ncols /qk ; 541const int blocks_per_warp = vdr * WARP_SIZE /qi ; 542assert (blocks_per_warp > 0 ); 543// partial sum for each thread 544float tmp = 0.0f ; 545 546const block_q_t * x = (const block_q_t * )vx ; 547const block_q8_1 * y = (const block_q8_1 * )vy ; 548 549for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 550i += blocks_per_warp ) { 551const int ibx = row * blocks_per_row + i ;// x block index 552 553const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 554 555const int iqs = 556vdr * 557 (item_ct1 .get_local_id (2 ) % 558 (qi /vdr ));// x block quant index when casting the quants to int 559 560tmp += vec_dot_iq3_s_q8_1 (& x [ibx ],& y [iby ],iqs ,iq3s_grid ); 561 } 562 563// sum up partial sums and write back result 564#pragma unroll 565for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 566tmp += 567 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 568 } 569 570if (item_ct1 .get_local_id (2 )== 0 ) { 571dst [row ]= tmp ; 572 } 573} 574 575template < int qk ,int qi ,typename block_q_t ,int vdr > 576static void mul_mat_vec_q_iq1_s_q8_1 (const void * __restrict__vx , 577const void * __restrict__vy , 578float * __restrict__dst ,const int ncols , 579const int nrows , 580const sycl::nd_item < 3 > & item_ct1 ) { 581const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 582item_ct1 .get_local_id (1 ); 583 584if (row >=nrows ) { 585return ; 586 } 587 588const int blocks_per_row = ncols /qk ; 589const int blocks_per_warp = vdr * WARP_SIZE /qi ; 590assert (blocks_per_warp > 0 ); 591// partial sum for each thread 592float tmp = 0.0f ; 593 594const block_q_t * x = (const block_q_t * )vx ; 595const block_q8_1 * y = (const block_q8_1 * )vy ; 596 597for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 598i += blocks_per_warp ) { 599const int ibx = row * blocks_per_row + i ;// x block index 600 601const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 602 603const int iqs = 604vdr * 605 (item_ct1 .get_local_id (2 ) % 606 (qi /vdr ));// x block quant index when casting the quants to int 607 608tmp += vec_dot_iq1_s_q8_1 (& x [ibx ],& y [iby ],iqs ,iq1s_grid_gpu ); 609 } 610 611// sum up partial sums and write back result 612#pragma unroll 613for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 614tmp += 615 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 616 } 617 618if (item_ct1 .get_local_id (2 )== 0 ) { 619dst [row ]= tmp ; 620 } 621} 622 623template < int qk ,int qi ,typename block_q_t ,int vdr > 624static void mul_mat_vec_q_iq1_m_q8_1 (const void * __restrict__vx , 625const void * __restrict__vy , 626float * __restrict__dst ,const int ncols , 627const int nrows , 628const sycl::nd_item < 3 > & item_ct1 ) { 629const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 630item_ct1 .get_local_id (1 ); 631 632if (row >=nrows ) { 633return ; 634 } 635 636const int blocks_per_row = ncols /qk ; 637const int blocks_per_warp = vdr * WARP_SIZE /qi ; 638assert (blocks_per_warp > 0 ); 639// partial sum for each thread 640float tmp = 0.0f ; 641 642const block_q_t * x = (const block_q_t * )vx ; 643const block_q8_1 * y = (const block_q8_1 * )vy ; 644 645for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 646i += blocks_per_warp ) { 647const int ibx = row * blocks_per_row + i ;// x block index 648 649const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 650 651const int iqs = 652vdr * 653 (item_ct1 .get_local_id (2 ) % 654 (qi /vdr ));// x block quant index when casting the quants to int 655 656tmp += vec_dot_iq1_m_q8_1 (& x [ibx ],& y [iby ],iqs ); 657 } 658 659// sum up partial sums and write back result 660#pragma unroll 661for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 662tmp += 663 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 664 } 665 666if (item_ct1 .get_local_id (2 )== 0 ) { 667dst [row ]= tmp ; 668 } 669} 670 671template < int qk ,int qi ,typename block_q_t ,int vdr > 672static void mul_mat_vec_q_iq4_nl_q8_1 (const void * __restrict__vx , 673const void * __restrict__vy , 674float * __restrict__dst ,const int ncols , 675const int nrows , 676const sycl::nd_item < 3 > & item_ct1 ) { 677const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 678item_ct1 .get_local_id (1 ); 679 680if (row >=nrows ) { 681return ; 682 } 683 684const int blocks_per_row = ncols /qk ; 685const int blocks_per_warp = vdr * WARP_SIZE /qi ; 686assert (blocks_per_warp > 0 ); 687// partial sum for each thread 688float tmp = 0.0f ; 689 690const block_q_t * x = (const block_q_t * )vx ; 691const block_q8_1 * y = (const block_q8_1 * )vy ; 692 693for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 694i += blocks_per_warp ) { 695const int ibx = row * blocks_per_row + i ;// x block index 696 697const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 698 699const int iqs = 700vdr * 701 (item_ct1 .get_local_id (2 ) % 702 (qi /vdr ));// x block quant index when casting the quants to int 703 704tmp += vec_dot_iq4_nl_q8_1 (& x [ibx ],& y [iby ],iqs ); 705 } 706 707// sum up partial sums and write back result 708#pragma unroll 709for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 710tmp += 711 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 712 } 713 714if (item_ct1 .get_local_id (2 )== 0 ) { 715dst [row ]= tmp ; 716 } 717} 718 719 720template < int qk ,int qi ,typename block_q_t ,int vdr > 721static void mul_mat_vec_q_iq4_xs_q8_1 (const void * __restrict__vx , 722const void * __restrict__vy , 723float * __restrict__dst ,const int ncols , 724const int nrows , 725const sycl::nd_item < 3 > & item_ct1 ) { 726const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ 727item_ct1 .get_local_id (1 ); 728 729if (row >=nrows ) { 730return ; 731 } 732 733const int blocks_per_row = ncols /qk ; 734const int blocks_per_warp = vdr * WARP_SIZE /qi ; 735assert (blocks_per_warp > 0 ); 736// partial sum for each thread 737float tmp = 0.0f ; 738 739const block_q_t * x = (const block_q_t * )vx ; 740const block_q8_1 * y = (const block_q8_1 * )vy ; 741 742for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ; 743i += blocks_per_warp ) { 744const int ibx = row * blocks_per_row + i ;// x block index 745 746const int iby = i * (qk /QK8_1 );// y block index that aligns with ibx 747 748const int iqs = 749vdr * 750 (item_ct1 .get_local_id (2 ) % 751 (qi /vdr ));// x block quant index when casting the quants to int 752 753tmp += vec_dot_iq4_xs_q8_1 (& x [ibx ],& y [iby ],iqs ); 754 } 755 756// sum up partial sums and write back result 757#pragma unroll 758for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 759tmp += 760 dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 761 } 762 763if (item_ct1 .get_local_id (2 )== 0 ) { 764dst [row ]= tmp ; 765 } 766} 767 768static void reorder_mul_mat_vec_q4_0_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 769const int nrows , dpct::queue_ptr stream ) { 770GGML_ASSERT (ncols %QK4_0 == 0 ); 771// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 772constexpr size_t num_subgroups = WARP_SIZE ; 773const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 774const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 775const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 776 777stream -> submit ([& ](sycl::handler & cgh ) { 778cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 779 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 780mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q4_0 >> (vx ,vy ,dst ,ncols ,nrows , 781nd_item ); 782 }); 783 }); 784} 785 786template < int ncols_dst > 787static void reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols ( 788const void * vx ,const void * vy ,float * dst , 789const int ncols ,const int nrows , 790const int stride_col_y_bytes ,const int stride_col_dst , 791 dpct::queue_ptr stream ) { 792GGML_ASSERT (ncols %QK4_0 == 0 ); 793constexpr size_t num_subgroups = WARP_SIZE ; 794const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 795const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 796const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 797 798stream -> submit ([& ](sycl::handler & cgh ) { 799cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 800 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 801mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q4_0 > ,ncols_dst > ( 802vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 803/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 804 }); 805 }); 806} 807 808static void reorder_mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ( 809const void * vx ,const void * vy ,float * dst , 810const int ncols ,const int nrows ,const int ncols_dst , 811const int stride_col_y_bytes ,const int stride_col_dst , 812 dpct::queue_ptr stream ) { 813switch (ncols_dst ) { 814case 1 :reorder_mul_mat_vec_q4_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 815case 2 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 816case 3 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 817case 4 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 818case 5 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 819case 6 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 820case 7 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 821case 8 :reorder_mul_mat_vec_q4_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 822default :GGML_ABORT ("unsupported ncols_dst=%d for Q4_0 reorder multi-col MMVQ" ,ncols_dst ); 823 } 824} 825 826static void mul_mat_vec_q4_0_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols ,const int nrows , 827 dpct::queue_ptr stream ) { 828GGML_ASSERT (ncols %QK4_0 == 0 ); 829const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 830const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 831const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 832 833 { 834stream -> submit ([& ](sycl::handler & cgh ) { 835cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 836 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 837mul_mat_vec_q < QK4_0 ,QI4_0 ,block_q4_0 ,VDR_Q4_0_Q8_1_MMVQ ,vec_dot_q4_0_q8_1 > ( 838vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 839 }); 840 }); 841 } 842} 843 844template < int ncols_dst > 845static void mul_mat_vec_q4_0_q8_1_sycl_ncols ( 846const void * vx ,const void * vy ,float * dst , 847const int ncols ,const int nrows , 848const int stride_col_y ,const int stride_col_dst , 849 dpct::queue_ptr stream ) { 850GGML_ASSERT (ncols %QK4_0 == 0 ); 851const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 852const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 853const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 854stream -> submit ([& ](sycl::handler & cgh ) { 855cgh .parallel_for ( 856 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 857 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 858mul_mat_vec_q_ncols < QK4_0 ,QI4_0 ,block_q4_0 , 859VDR_Q4_0_Q8_1_MMVQ ,vec_dot_q4_0_q8_1 ,ncols_dst > ( 860vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 861 }); 862 }); 863} 864 865static void mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ( 866const void * vx ,const void * vy ,float * dst , 867const int ncols ,const int nrows ,const int ncols_dst , 868const int stride_col_y ,const int stride_col_dst , 869 dpct::queue_ptr stream ) { 870switch (ncols_dst ) { 871case 1 :mul_mat_vec_q4_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 872case 2 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 873case 3 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 874case 4 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 875case 5 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 876case 6 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 877case 7 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 878case 8 :mul_mat_vec_q4_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 879default :GGML_ABORT ("unsupported ncols_dst=%d for Q4_0 multi-col MMVQ" ,ncols_dst ); 880 } 881} 882 883static void mul_mat_vec_q4_1_q8_1_sycl (const void * vx ,const void * vy , 884float * dst ,const int ncols , 885const int nrows , 886 dpct::queue_ptr stream ) { 887GGML_ASSERT (ncols %QK4_1 == 0 ); 888const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 889const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 890const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 891 { 892 893stream -> submit ([& ](sycl::handler & cgh ) { 894 895cgh .parallel_for ( 896 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 897 [= ](sycl::nd_item < 3 > item_ct1 ) 898 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 899mul_mat_vec_q < QK4_0 ,QI4_1 ,block_q4_1 , 900VDR_Q4_1_Q8_1_MMVQ ,vec_dot_q4_1_q8_1 > ( 901vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 902 }); 903 }); 904 } 905} 906 907template < int ncols_dst > 908static void mul_mat_vec_q4_1_q8_1_sycl_ncols ( 909const void * vx ,const void * vy ,float * dst , 910const int ncols ,const int nrows , 911const int stride_col_y ,const int stride_col_dst , 912 dpct::queue_ptr stream ) { 913GGML_ASSERT (ncols %QK4_1 == 0 ); 914const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 915const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 916const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 917stream -> submit ([& ](sycl::handler & cgh ) { 918cgh .parallel_for ( 919 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 920 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 921mul_mat_vec_q_ncols < QK4_0 ,QI4_1 ,block_q4_1 , 922VDR_Q4_1_Q8_1_MMVQ ,vec_dot_q4_1_q8_1 ,ncols_dst > ( 923vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 924 }); 925 }); 926} 927 928static void mul_mat_vec_q4_1_q8_1_sycl_switch_ncols ( 929const void * vx ,const void * vy ,float * dst , 930const int ncols ,const int nrows ,const int ncols_dst , 931const int stride_col_y ,const int stride_col_dst , 932 dpct::queue_ptr stream ) { 933switch (ncols_dst ) { 934case 1 :mul_mat_vec_q4_1_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 935case 2 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 936case 3 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 937case 4 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 938case 5 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 939case 6 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 940case 7 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 941case 8 :mul_mat_vec_q4_1_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 942default :GGML_ABORT ("unsupported ncols_dst=%d for Q4_1 multi-col MMVQ" ,ncols_dst ); 943 } 944} 945 946static void mul_mat_vec_mxfp4_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols ,const int nrows , 947 dpct::queue_ptr stream ) { 948GGML_ASSERT (ncols %QK_MXFP4 == 0 ); 949const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 950const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 951const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 952 953 { 954stream -> submit ([& ](sycl::handler & cgh ) { 955cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 956 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 957mul_mat_vec_q < QK_MXFP4 ,QI_MXFP4 ,block_mxfp4 ,VDR_MXFP4_Q8_1_MMVQ ,vec_dot_mxfp4_q8_1 > ( 958vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 959 }); 960 }); 961 } 962} 963 964template < int ncols_dst > 965static void mul_mat_vec_mxfp4_q8_1_sycl_ncols ( 966const void * vx ,const void * vy ,float * dst , 967const int ncols ,const int nrows , 968const int stride_col_y ,const int stride_col_dst , 969 dpct::queue_ptr stream ) { 970GGML_ASSERT (ncols %QK_MXFP4 == 0 ); 971const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 972const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 973const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 974stream -> submit ([& ](sycl::handler & cgh ) { 975cgh .parallel_for ( 976 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 977 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 978mul_mat_vec_q_ncols < QK_MXFP4 ,QI_MXFP4 ,block_mxfp4 , 979VDR_MXFP4_Q8_1_MMVQ ,vec_dot_mxfp4_q8_1 ,ncols_dst > ( 980vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 981 }); 982 }); 983} 984 985static void mul_mat_vec_mxfp4_q8_1_sycl_switch_ncols ( 986const void * vx ,const void * vy ,float * dst , 987const int ncols ,const int nrows ,const int ncols_dst , 988const int stride_col_y ,const int stride_col_dst , 989 dpct::queue_ptr stream ) { 990switch (ncols_dst ) { 991case 1 :mul_mat_vec_mxfp4_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 992case 2 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 993case 3 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 994case 4 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 995case 5 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 996case 6 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 997case 7 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 998case 8 :mul_mat_vec_mxfp4_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 999default :GGML_ABORT ("unsupported ncols_dst=%d for MXFP4 multi-col MMVQ" ,ncols_dst ); 1000 } 1001} 1002 1003static void mul_mat_vec_nvfp4_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols ,const int nrows , 1004 dpct::queue_ptr stream ) { 1005GGML_ASSERT (ncols %QK_NVFP4 == 0 ); 1006const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1007const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1008const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1009 1010 { 1011stream -> submit ([& ](sycl::handler & cgh ) { 1012cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1013 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1014mul_mat_vec_q < QK_NVFP4 ,QI_NVFP4 ,block_nvfp4 ,VDR_NVFP4_Q8_1_MMVQ ,vec_dot_nvfp4_q8_1 > ( 1015vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1016 }); 1017 }); 1018 } 1019} 1020 1021template < int ncols_dst > 1022static void mul_mat_vec_nvfp4_q8_1_sycl_ncols ( 1023const void * vx ,const void * vy ,float * dst , 1024const int ncols ,const int nrows , 1025const int stride_col_y ,const int stride_col_dst , 1026 dpct::queue_ptr stream ) { 1027GGML_ASSERT (ncols %QK_NVFP4 == 0 ); 1028const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1029const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1030const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1031stream -> submit ([& ](sycl::handler & cgh ) { 1032cgh .parallel_for ( 1033 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1034 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1035mul_mat_vec_q_ncols < QK_NVFP4 ,QI_NVFP4 ,block_nvfp4 , 1036VDR_NVFP4_Q8_1_MMVQ ,vec_dot_nvfp4_q8_1 ,ncols_dst > ( 1037vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1038 }); 1039 }); 1040} 1041 1042static void mul_mat_vec_nvfp4_q8_1_sycl_switch_ncols ( 1043const void * vx ,const void * vy ,float * dst , 1044const int ncols ,const int nrows ,const int ncols_dst , 1045const int stride_col_y ,const int stride_col_dst , 1046 dpct::queue_ptr stream ) { 1047switch (ncols_dst ) { 1048case 1 :mul_mat_vec_nvfp4_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1049case 2 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1050case 3 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1051case 4 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1052case 5 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1053case 6 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1054case 7 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1055case 8 :mul_mat_vec_nvfp4_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1056default :GGML_ABORT ("unsupported ncols_dst=%d for NVFP4 multi-col MMVQ" ,ncols_dst ); 1057 } 1058} 1059 1060static void mul_mat_vec_q5_0_q8_1_sycl (const void * vx ,const void * vy , 1061float * dst ,const int ncols , 1062const int nrows , 1063 dpct::queue_ptr stream ) { 1064GGML_ASSERT (ncols %QK5_0 == 0 ); 1065const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1066const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1067const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1068 { 1069 1070stream -> submit ([& ](sycl::handler & cgh ) { 1071 1072cgh .parallel_for ( 1073 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1074 [= ](sycl::nd_item < 3 > item_ct1 ) 1075 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1076mul_mat_vec_q < QK5_0 ,QI5_0 ,block_q5_0 , 1077VDR_Q5_0_Q8_1_MMVQ ,vec_dot_q5_0_q8_1 > ( 1078vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1079 }); 1080 }); 1081 } 1082} 1083 1084template < int ncols_dst > 1085static void mul_mat_vec_q5_0_q8_1_sycl_ncols ( 1086const void * vx ,const void * vy ,float * dst , 1087const int ncols ,const int nrows , 1088const int stride_col_y ,const int stride_col_dst , 1089 dpct::queue_ptr stream ) { 1090GGML_ASSERT (ncols %QK5_0 == 0 ); 1091const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1092const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1093const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1094stream -> submit ([& ](sycl::handler & cgh ) { 1095cgh .parallel_for ( 1096 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1097 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1098mul_mat_vec_q_ncols < QK5_0 ,QI5_0 ,block_q5_0 , 1099VDR_Q5_0_Q8_1_MMVQ ,vec_dot_q5_0_q8_1 ,ncols_dst > ( 1100vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1101 }); 1102 }); 1103} 1104 1105static void mul_mat_vec_q5_0_q8_1_sycl_switch_ncols ( 1106const void * vx ,const void * vy ,float * dst , 1107const int ncols ,const int nrows ,const int ncols_dst , 1108const int stride_col_y ,const int stride_col_dst , 1109 dpct::queue_ptr stream ) { 1110switch (ncols_dst ) { 1111case 1 :mul_mat_vec_q5_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1112case 2 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1113case 3 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1114case 4 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1115case 5 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1116case 6 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1117case 7 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1118case 8 :mul_mat_vec_q5_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1119default :GGML_ABORT ("unsupported ncols_dst=%d for Q5_0 multi-col MMVQ" ,ncols_dst ); 1120 } 1121} 1122 1123static void mul_mat_vec_q5_1_q8_1_sycl (const void * vx ,const void * vy , 1124float * dst ,const int ncols , 1125const int nrows , 1126 dpct::queue_ptr stream ) { 1127GGML_ASSERT (ncols %QK5_1 == 0 ); 1128const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1129const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1130const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1131 { 1132 1133stream -> submit ([& ](sycl::handler & cgh ) { 1134 1135cgh .parallel_for ( 1136 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1137 [= ](sycl::nd_item < 3 > item_ct1 ) 1138 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1139mul_mat_vec_q < QK5_1 ,QI5_1 ,block_q5_1 , 1140VDR_Q5_1_Q8_1_MMVQ ,vec_dot_q5_1_q8_1 > ( 1141vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1142 }); 1143 }); 1144 } 1145} 1146 1147template < int ncols_dst > 1148static void mul_mat_vec_q5_1_q8_1_sycl_ncols ( 1149const void * vx ,const void * vy ,float * dst , 1150const int ncols ,const int nrows , 1151const int stride_col_y ,const int stride_col_dst , 1152 dpct::queue_ptr stream ) { 1153GGML_ASSERT (ncols %QK5_1 == 0 ); 1154const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1155const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1156const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1157stream -> submit ([& ](sycl::handler & cgh ) { 1158cgh .parallel_for ( 1159 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1160 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1161mul_mat_vec_q_ncols < QK5_1 ,QI5_1 ,block_q5_1 , 1162VDR_Q5_1_Q8_1_MMVQ ,vec_dot_q5_1_q8_1 ,ncols_dst > ( 1163vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1164 }); 1165 }); 1166} 1167 1168static void mul_mat_vec_q5_1_q8_1_sycl_switch_ncols ( 1169const void * vx ,const void * vy ,float * dst , 1170const int ncols ,const int nrows ,const int ncols_dst , 1171const int stride_col_y ,const int stride_col_dst , 1172 dpct::queue_ptr stream ) { 1173switch (ncols_dst ) { 1174case 1 :mul_mat_vec_q5_1_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1175case 2 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1176case 3 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1177case 4 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1178case 5 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1179case 6 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1180case 7 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1181case 8 :mul_mat_vec_q5_1_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1182default :GGML_ABORT ("unsupported ncols_dst=%d for Q5_1 multi-col MMVQ" ,ncols_dst ); 1183 } 1184} 1185 1186static void reorder_mul_mat_vec_q8_0_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1187const int nrows , dpct::queue_ptr stream ) { 1188GGML_ASSERT (ncols %QK8_0 == 0 ); 1189// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 1190constexpr size_t num_subgroups = WARP_SIZE ; 1191const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1192const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1193const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1194 1195stream -> submit ([& ](sycl::handler & cgh ) { 1196cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1197 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1198mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q8_0 >> (vx ,vy ,dst ,ncols ,nrows , 1199nd_item ); 1200 }); 1201 }); 1202} 1203 1204template < int ncols_dst > 1205static void reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols ( 1206const void * vx ,const void * vy ,float * dst , 1207const int ncols ,const int nrows , 1208const int stride_col_y_bytes ,const int stride_col_dst , 1209 dpct::queue_ptr stream ) { 1210GGML_ASSERT (ncols %QK8_0 == 0 ); 1211constexpr size_t num_subgroups = WARP_SIZE ; 1212const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1213const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1214const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1215 1216stream -> submit ([& ](sycl::handler & cgh ) { 1217cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1218 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1219mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q8_0 > ,ncols_dst > ( 1220vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1221/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1222 }); 1223 }); 1224} 1225 1226static void reorder_mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ( 1227const void * vx ,const void * vy ,float * dst , 1228const int ncols ,const int nrows ,const int ncols_dst , 1229const int stride_col_y_bytes ,const int stride_col_dst , 1230 dpct::queue_ptr stream ) { 1231switch (ncols_dst ) { 1232case 1 :reorder_mul_mat_vec_q8_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1233case 2 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1234case 3 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1235case 4 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1236case 5 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1237case 6 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1238case 7 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1239case 8 :reorder_mul_mat_vec_q8_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1240default :GGML_ABORT ("unsupported ncols_dst=%d for Q8_0 reorder multi-col MMVQ" ,ncols_dst ); 1241 } 1242} 1243 1244static void mul_mat_vec_q8_0_q8_1_sycl (const void * vx ,const void * vy , 1245float * dst ,const int ncols , 1246const int nrows , 1247 dpct::queue_ptr stream ) { 1248GGML_ASSERT (ncols %QK8_0 == 0 ); 1249const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1250const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1251const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1252 { 1253 1254stream -> submit ([& ](sycl::handler & cgh ) { 1255 1256cgh .parallel_for ( 1257 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1258 [= ](sycl::nd_item < 3 > item_ct1 ) 1259 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1260mul_mat_vec_q < QK8_0 ,QI8_0 ,block_q8_0 , 1261VDR_Q8_0_Q8_1_MMVQ ,vec_dot_q8_0_q8_1 > ( 1262vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1263 }); 1264 }); 1265 } 1266} 1267 1268template < int ncols_dst > 1269static void mul_mat_vec_q8_0_q8_1_sycl_ncols ( 1270const void * vx ,const void * vy ,float * dst , 1271const int ncols ,const int nrows , 1272const int stride_col_y ,const int stride_col_dst , 1273 dpct::queue_ptr stream ) { 1274GGML_ASSERT (ncols %QK8_0 == 0 ); 1275const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1276const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1277const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1278stream -> submit ([& ](sycl::handler & cgh ) { 1279cgh .parallel_for ( 1280 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1281 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1282mul_mat_vec_q_ncols < QK8_0 ,QI8_0 ,block_q8_0 , 1283VDR_Q8_0_Q8_1_MMVQ ,vec_dot_q8_0_q8_1 ,ncols_dst > ( 1284vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1285 }); 1286 }); 1287} 1288 1289static void mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ( 1290const void * vx ,const void * vy ,float * dst , 1291const int ncols ,const int nrows ,const int ncols_dst , 1292const int stride_col_y ,const int stride_col_dst , 1293 dpct::queue_ptr stream ) { 1294switch (ncols_dst ) { 1295case 1 :mul_mat_vec_q8_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1296case 2 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1297case 3 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1298case 4 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1299case 5 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1300case 6 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1301case 7 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1302case 8 :mul_mat_vec_q8_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1303default :GGML_ABORT ("unsupported ncols_dst=%d for Q8_0 multi-col MMVQ" ,ncols_dst ); 1304 } 1305} 1306 1307static void mul_mat_vec_q1_0_q8_1_sycl (const void * vx ,const void * vy , 1308float * dst ,const int ncols , 1309const int nrows , 1310 dpct::queue_ptr stream ) { 1311GGML_ASSERT (ncols %QK1_0 == 0 ); 1312const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1313const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1314const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1315 1316stream -> submit ([& ](sycl::handler & cgh ) { 1317cgh .parallel_for ( 1318 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1319 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1320mul_mat_vec_q < QK1_0 ,QI1_0 ,block_q1_0 , 1321VDR_Q1_0_Q8_1_MMVQ ,vec_dot_q1_0_q8_1 > ( 1322vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1323 }); 1324 }); 1325} 1326 1327template < int ncols_dst > 1328static void mul_mat_vec_q1_0_q8_1_sycl_ncols ( 1329const void * vx ,const void * vy ,float * dst , 1330const int ncols ,const int nrows , 1331const int stride_col_y ,const int stride_col_dst , 1332 dpct::queue_ptr stream ) { 1333GGML_ASSERT (ncols %QK1_0 == 0 ); 1334const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1335const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1336const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1337 1338stream -> submit ([& ](sycl::handler & cgh ) { 1339cgh .parallel_for ( 1340 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1341 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1342mul_mat_vec_q_ncols < QK1_0 ,QI1_0 ,block_q1_0 , 1343VDR_Q1_0_Q8_1_MMVQ ,vec_dot_q1_0_q8_1 ,ncols_dst > ( 1344vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1345 }); 1346 }); 1347} 1348 1349static void mul_mat_vec_q1_0_q8_1_sycl_switch_ncols ( 1350const void * vx ,const void * vy ,float * dst , 1351const int ncols ,const int nrows ,const int ncols_dst , 1352const int stride_col_y ,const int stride_col_dst , 1353 dpct::queue_ptr stream ) { 1354switch (ncols_dst ) { 1355case 1 :mul_mat_vec_q1_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1356case 2 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1357case 3 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1358case 4 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1359case 5 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1360case 6 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1361case 7 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1362case 8 :mul_mat_vec_q1_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1363default :GGML_ABORT ("unsupported ncols_dst=%d for Q1_0 multi-col MMVQ" ,ncols_dst ); 1364 } 1365} 1366 1367static void mul_mat_vec_q2_0_q8_1_sycl (const void * vx ,const void * vy , 1368float * dst ,const int ncols , 1369const int nrows , 1370 dpct::queue_ptr stream ) { 1371GGML_ASSERT (ncols %QK2_0 == 0 ); 1372const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1373const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1374const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1375 1376stream -> submit ([& ](sycl::handler & cgh ) { 1377cgh .parallel_for ( 1378 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1379 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1380mul_mat_vec_q < QK2_0 ,QI2_0 ,block_q2_0 , 1381VDR_Q2_0_Q8_1_MMVQ ,vec_dot_q2_0_q8_1 > ( 1382vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1383 }); 1384 }); 1385} 1386 1387template < int ncols_dst > 1388static void mul_mat_vec_q2_0_q8_1_sycl_ncols ( 1389const void * vx ,const void * vy ,float * dst , 1390const int ncols ,const int nrows , 1391const int stride_col_y ,const int stride_col_dst , 1392 dpct::queue_ptr stream ) { 1393GGML_ASSERT (ncols %QK2_0 == 0 ); 1394const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1395const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1396const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1397 1398stream -> submit ([& ](sycl::handler & cgh ) { 1399cgh .parallel_for ( 1400 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1401 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1402mul_mat_vec_q_ncols < QK2_0 ,QI2_0 ,block_q2_0 , 1403VDR_Q2_0_Q8_1_MMVQ ,vec_dot_q2_0_q8_1 ,ncols_dst > ( 1404vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1405 }); 1406 }); 1407} 1408 1409static void mul_mat_vec_q2_0_q8_1_sycl_switch_ncols ( 1410const void * vx ,const void * vy ,float * dst , 1411const int ncols ,const int nrows ,const int ncols_dst , 1412const int stride_col_y ,const int stride_col_dst , 1413 dpct::queue_ptr stream ) { 1414switch (ncols_dst ) { 1415case 1 :mul_mat_vec_q2_0_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1416case 2 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1417case 3 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1418case 4 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1419case 5 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1420case 6 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1421case 7 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1422case 8 :mul_mat_vec_q2_0_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1423default :GGML_ABORT ("unsupported ncols_dst=%d for Q2_0 multi-col MMVQ" ,ncols_dst ); 1424 } 1425} 1426 1427static void mul_mat_vec_q2_K_q8_1_sycl (const void * vx ,const void * vy , 1428float * dst ,const int ncols , 1429const int nrows , 1430 dpct::queue_ptr stream ) { 1431GGML_ASSERT (ncols %QK_K == 0 ); 1432const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1433const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1434const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1435 { 1436 1437stream -> submit ([& ](sycl::handler & cgh ) { 1438 1439cgh .parallel_for ( 1440 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1441 [= ](sycl::nd_item < 3 > item_ct1 ) 1442 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1443mul_mat_vec_q < QK_K ,QI2_K ,block_q2_K , 1444VDR_Q2_K_Q8_1_MMVQ ,vec_dot_q2_K_q8_1 > ( 1445vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1446 }); 1447 }); 1448 } 1449} 1450 1451template < int ncols_dst > 1452static void mul_mat_vec_q2_K_q8_1_sycl_ncols ( 1453const void * vx ,const void * vy ,float * dst , 1454const int ncols ,const int nrows , 1455const int stride_col_y ,const int stride_col_dst , 1456 dpct::queue_ptr stream ) { 1457GGML_ASSERT (ncols %QK_K == 0 ); 1458const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1459const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1460const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1461stream -> submit ([& ](sycl::handler & cgh ) { 1462cgh .parallel_for ( 1463 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1464 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1465mul_mat_vec_q_ncols < QK_K ,QI2_K ,block_q2_K , 1466VDR_Q2_K_Q8_1_MMVQ ,vec_dot_q2_K_q8_1 ,ncols_dst > ( 1467vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1468 }); 1469 }); 1470} 1471 1472static void mul_mat_vec_q2_K_q8_1_sycl_switch_ncols ( 1473const void * vx ,const void * vy ,float * dst , 1474const int ncols ,const int nrows ,const int ncols_dst , 1475const int stride_col_y ,const int stride_col_dst , 1476 dpct::queue_ptr stream ) { 1477switch (ncols_dst ) { 1478case 1 :mul_mat_vec_q2_K_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1479case 2 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1480case 3 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1481case 4 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1482case 5 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1483case 6 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1484case 7 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1485case 8 :mul_mat_vec_q2_K_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1486default :GGML_ABORT ("unsupported ncols_dst=%d for Q2_K multi-col MMVQ" ,ncols_dst ); 1487 } 1488} 1489 1490static void reorder_mul_mat_vec_q2_k_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1491const int nrows , dpct::queue_ptr stream ) { 1492GGML_ASSERT (ncols %QK_K == 0 ); 1493 1494// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 1495constexpr size_t num_subgroups = WARP_SIZE ; 1496const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1497const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1498const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1499 1500stream -> submit ([& ](sycl::handler & cgh ) { 1501cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1502 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1503mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q2_K >> (vx ,vy ,dst ,ncols ,nrows , 1504nd_item ); 1505 }); 1506 }); 1507} 1508 1509template < int ncols_dst > 1510static void reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols ( 1511const void * vx ,const void * vy ,float * dst , 1512const int ncols ,const int nrows , 1513const int stride_col_y_bytes ,const int stride_col_dst , 1514 dpct::queue_ptr stream ) { 1515GGML_ASSERT (ncols %QK_K == 0 ); 1516constexpr size_t num_subgroups = WARP_SIZE ; 1517const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1518const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1519const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1520 1521stream -> submit ([& ](sycl::handler & cgh ) { 1522cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1523 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1524mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q2_K > ,ncols_dst > ( 1525vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1526/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1527 }); 1528 }); 1529} 1530 1531static void reorder_mul_mat_vec_q2_k_q8_1_sycl_switch_ncols ( 1532const void * vx ,const void * vy ,float * dst , 1533const int ncols ,const int nrows ,const int ncols_dst , 1534const int stride_col_y_bytes ,const int stride_col_dst , 1535 dpct::queue_ptr stream ) { 1536switch (ncols_dst ) { 1537case 1 :reorder_mul_mat_vec_q2_k_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1538case 2 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1539case 3 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1540case 4 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1541case 5 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1542case 6 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1543case 7 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1544case 8 :reorder_mul_mat_vec_q2_k_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1545default :GGML_ABORT ("unsupported ncols_dst=%d for Q2_K reorder multi-col MMVQ" ,ncols_dst ); 1546 } 1547} 1548 1549static void mul_mat_vec_q3_K_q8_1_sycl (const void * vx ,const void * vy , 1550float * dst ,const int ncols , 1551const int nrows , 1552 dpct::queue_ptr stream ) { 1553GGML_ASSERT (ncols %QK_K == 0 ); 1554const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1555const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1556const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1557 { 1558 1559stream -> submit ([& ](sycl::handler & cgh ) { 1560 1561cgh .parallel_for ( 1562 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1563 [= ](sycl::nd_item < 3 > item_ct1 ) 1564 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1565mul_mat_vec_q < QK_K ,QI3_K ,block_q3_K , 1566VDR_Q3_K_Q8_1_MMVQ ,vec_dot_q3_K_q8_1 > ( 1567vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1568 }); 1569 }); 1570 } 1571} 1572 1573static void reorder_mul_mat_vec_q3_k_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1574const int nrows , dpct::queue_ptr stream ) { 1575GGML_ASSERT (ncols %QK_K == 0 ); 1576 1577// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 1578constexpr size_t num_subgroups = WARP_SIZE ; 1579const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1580const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1581const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1582 1583stream -> submit ([& ](sycl::handler & cgh ) { 1584cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1585 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1586mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q3_K >> (vx ,vy ,dst ,ncols ,nrows , 1587nd_item ); 1588 }); 1589 }); 1590} 1591 1592template < int ncols_dst > 1593static void reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols ( 1594const void * vx ,const void * vy ,float * dst , 1595const int ncols ,const int nrows , 1596const int stride_col_y_bytes ,const int stride_col_dst , 1597 dpct::queue_ptr stream ) { 1598GGML_ASSERT (ncols %QK_K == 0 ); 1599constexpr size_t num_subgroups = WARP_SIZE ; 1600const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1601const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1602const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1603 1604stream -> submit ([& ](sycl::handler & cgh ) { 1605cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1606 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1607mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q3_K > ,ncols_dst > ( 1608vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1609/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1610 }); 1611 }); 1612} 1613 1614static void reorder_mul_mat_vec_q3_k_q8_1_sycl_switch_ncols ( 1615const void * vx ,const void * vy ,float * dst , 1616const int ncols ,const int nrows ,const int ncols_dst , 1617const int stride_col_y_bytes ,const int stride_col_dst , 1618 dpct::queue_ptr stream ) { 1619switch (ncols_dst ) { 1620case 1 :reorder_mul_mat_vec_q3_k_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1621case 2 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1622case 3 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1623case 4 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1624case 5 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1625case 6 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1626case 7 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1627case 8 :reorder_mul_mat_vec_q3_k_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1628default :GGML_ABORT ("unsupported ncols_dst=%d for Q3_K reorder multi-col MMVQ" ,ncols_dst ); 1629 } 1630} 1631 1632template < int ncols_dst > 1633static void mul_mat_vec_q3_K_q8_1_sycl_ncols ( 1634const void * vx ,const void * vy ,float * dst , 1635const int ncols ,const int nrows , 1636const int stride_col_y ,const int stride_col_dst , 1637 dpct::queue_ptr stream ) { 1638GGML_ASSERT (ncols %QK_K == 0 ); 1639const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1640const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1641const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1642stream -> submit ([& ](sycl::handler & cgh ) { 1643cgh .parallel_for ( 1644 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1645 [= ](sycl::nd_item < 3 > item_ct1 ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1646mul_mat_vec_q_ncols < QK_K ,QI3_K ,block_q3_K , 1647VDR_Q3_K_Q8_1_MMVQ ,vec_dot_q3_K_q8_1 ,ncols_dst > ( 1648vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,item_ct1 ); 1649 }); 1650 }); 1651} 1652 1653static void mul_mat_vec_q3_K_q8_1_sycl_switch_ncols ( 1654const void * vx ,const void * vy ,float * dst , 1655const int ncols ,const int nrows ,const int ncols_dst , 1656const int stride_col_y ,const int stride_col_dst , 1657 dpct::queue_ptr stream ) { 1658switch (ncols_dst ) { 1659case 1 :mul_mat_vec_q3_K_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1660case 2 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1661case 3 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1662case 4 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1663case 5 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1664case 6 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1665case 7 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1666case 8 :mul_mat_vec_q3_K_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1667default :GGML_ABORT ("unsupported ncols_dst=%d for Q3_K multi-col MMVQ" ,ncols_dst ); 1668 } 1669} 1670 1671 1672static void mul_mat_vec_q4_K_q8_1_sycl (const void * vx ,const void * vy , 1673float * dst ,const int ncols , 1674const int nrows , 1675 dpct::queue_ptr stream ) { 1676GGML_ASSERT (ncols %QK_K == 0 ); 1677const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1678const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1679const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1680 { 1681 1682stream -> submit ([& ](sycl::handler & cgh ) { 1683 1684cgh .parallel_for ( 1685 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1686 [= ](sycl::nd_item < 3 > item_ct1 ) 1687 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1688mul_mat_vec_q < QK_K ,QI4_K ,block_q4_K , 1689VDR_Q4_K_Q8_1_MMVQ ,vec_dot_q4_K_q8_1 > ( 1690vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1691 }); 1692 }); 1693 } 1694} 1695 1696template < int ncols_dst > 1697static void mul_mat_vec_q4_K_q8_1_sycl_ncols ( 1698const void * vx ,const void * vy ,float * dst , 1699const int ncols ,const int nrows , 1700const int stride_col_y ,const int stride_col_dst , 1701 dpct::queue_ptr stream ) { 1702GGML_ASSERT (ncols %QK_K == 0 ); 1703const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1704const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1705const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1706 1707stream -> submit ([& ](sycl::handler & cgh ) { 1708cgh .parallel_for ( 1709 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1710 [= ](sycl::nd_item < 3 > item_ct1 ) 1711 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1712mul_mat_vec_q_ncols < QK_K ,QI4_K ,block_q4_K , 1713VDR_Q4_K_Q8_1_MMVQ , 1714vec_dot_q4_K_q8_1 , 1715ncols_dst > ( 1716vx ,vy ,dst ,ncols ,nrows , 1717stride_col_y ,stride_col_dst ,item_ct1 ); 1718 }); 1719 }); 1720} 1721 1722static void mul_mat_vec_q4_K_q8_1_sycl_switch_ncols ( 1723const void * vx ,const void * vy ,float * dst , 1724const int ncols ,const int nrows , 1725const int ncols_dst , 1726const int stride_col_y ,const int stride_col_dst , 1727 dpct::queue_ptr stream ) { 1728switch (ncols_dst ) { 1729case 1 :mul_mat_vec_q4_K_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1730case 2 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1731case 3 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1732case 4 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1733case 5 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1734case 6 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1735case 7 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1736case 8 :mul_mat_vec_q4_K_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1737default :GGML_ABORT ("unsupported ncols_dst=%d for Q4_K multi-col MMVQ" ,ncols_dst ); 1738 } 1739} 1740 1741static void reorder_mul_mat_vec_q4_k_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1742const int nrows , dpct::queue_ptr stream ) { 1743GGML_ASSERT (ncols %QK_K == 0 ); 1744 1745// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 1746constexpr size_t num_subgroups = WARP_SIZE ; 1747const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1748const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1749const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1750 1751stream -> submit ([& ](sycl::handler & cgh ) { 1752cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1753 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1754mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q4_K >> (vx ,vy ,dst ,ncols , 1755nrows ,nd_item ); 1756 }); 1757 }); 1758} 1759 1760template < int ncols_dst ,int rows_per_sg > 1761static void reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols_impl ( 1762const void * vx ,const void * vy ,float * dst , 1763const int ncols ,const int nrows , 1764const int stride_col_y_bytes ,const int stride_col_dst , 1765 dpct::queue_ptr stream ) { 1766GGML_ASSERT (ncols %QK_K == 0 ); 1767 1768constexpr size_t num_subgroups = WARP_SIZE ; 1769const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups * rows_per_sg ); 1770const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1771const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1772 1773stream -> submit ([& ](sycl::handler & cgh ) { 1774cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1775 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1776mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q4_K > ,ncols_dst , 1777/*has_fusion=*/ false,rows_per_sg > ( 1778vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1779/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1780 }); 1781 }); 1782} 1783 1784template < int ncols_dst > 1785static void reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols ( 1786const void * vx ,const void * vy ,float * dst , 1787const int ncols ,const int nrows , 1788const int stride_col_y_bytes ,const int stride_col_dst , 1789 dpct::queue_ptr stream ) { 1790constexpr int rows_per_sg = ncols_dst >=3 && ncols_dst <=4 ?2 :1 ; 1791reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols_impl < ncols_dst ,rows_per_sg > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream ); 1792} 1793 1794static void reorder_mul_mat_vec_q4_k_q8_1_sycl_switch_ncols ( 1795const void * vx ,const void * vy ,float * dst , 1796const int ncols ,const int nrows ,const int ncols_dst , 1797const int stride_col_y_bytes ,const int stride_col_dst , 1798 dpct::queue_ptr stream ) { 1799switch (ncols_dst ) { 1800case 1 :reorder_mul_mat_vec_q4_k_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1801case 2 : 1802if (nrows >=Q4_K_MMVQ_ROW_PAIR_MIN_NROWS ) { 1803reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols_impl < 2 ,2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream ); 1804 }else { 1805reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols_impl < 2 ,1 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream ); 1806 } 1807break ; 1808case 3 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1809case 4 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1810case 5 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1811case 6 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1812case 7 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1813case 8 :reorder_mul_mat_vec_q4_k_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1814default :GGML_ABORT ("unsupported ncols_dst=%d for Q4_K reorder multi-col MMVQ" ,ncols_dst ); 1815 } 1816} 1817 1818static void mul_mat_vec_q5_K_q8_1_sycl (const void * vx ,const void * vy , 1819float * dst ,const int ncols , 1820const int nrows , 1821 dpct::queue_ptr stream ) { 1822GGML_ASSERT (ncols %QK_K == 0 ); 1823const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1824const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1825const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1826 { 1827 1828stream -> submit ([& ](sycl::handler & cgh ) { 1829 1830cgh .parallel_for ( 1831 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1832 [= ](sycl::nd_item < 3 > item_ct1 ) 1833 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1834mul_mat_vec_q < QK_K ,QI5_K ,block_q5_K , 1835VDR_Q5_K_Q8_1_MMVQ ,vec_dot_q5_K_q8_1 > ( 1836vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 1837 }); 1838 }); 1839 } 1840} 1841 1842template < int ncols_dst > 1843static void mul_mat_vec_q5_K_q8_1_sycl_ncols ( 1844const void * vx ,const void * vy ,float * dst , 1845const int ncols ,const int nrows , 1846const int stride_col_y ,const int stride_col_dst , 1847 dpct::queue_ptr stream ) { 1848GGML_ASSERT (ncols %QK_K == 0 ); 1849const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 1850const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1851const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 1852 1853stream -> submit ([& ](sycl::handler & cgh ) { 1854cgh .parallel_for ( 1855 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1856 [= ](sycl::nd_item < 3 > item_ct1 ) 1857 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1858mul_mat_vec_q_ncols < QK_K ,QI5_K ,block_q5_K , 1859VDR_Q5_K_Q8_1_MMVQ , 1860vec_dot_q5_K_q8_1 , 1861ncols_dst > ( 1862vx ,vy ,dst ,ncols ,nrows , 1863stride_col_y ,stride_col_dst ,item_ct1 ); 1864 }); 1865 }); 1866} 1867 1868static void mul_mat_vec_q5_K_q8_1_sycl_switch_ncols ( 1869const void * vx ,const void * vy ,float * dst , 1870const int ncols ,const int nrows , 1871const int ncols_dst , 1872const int stride_col_y ,const int stride_col_dst , 1873 dpct::queue_ptr stream ) { 1874switch (ncols_dst ) { 1875case 1 :mul_mat_vec_q5_K_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1876case 2 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1877case 3 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1878case 4 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1879case 5 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1880case 6 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1881case 7 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1882case 8 :mul_mat_vec_q5_K_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 1883default :GGML_ABORT ("unsupported ncols_dst=%d for Q5_K multi-col MMVQ" ,ncols_dst ); 1884 } 1885} 1886 1887static void reorder_mul_mat_vec_q5_k_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1888const int nrows , dpct::queue_ptr stream ) { 1889GGML_ASSERT (ncols %QK_K == 0 ); 1890 1891constexpr size_t num_subgroups = WARP_SIZE ; 1892const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1893const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1894const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1895 1896stream -> submit ([& ](sycl::handler & cgh ) { 1897cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1898 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1899mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q5_K >> (vx ,vy ,dst ,ncols , 1900nrows ,nd_item ); 1901 }); 1902 }); 1903} 1904 1905template < int ncols_dst > 1906static void reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols ( 1907const void * vx ,const void * vy ,float * dst , 1908const int ncols ,const int nrows , 1909const int stride_col_y_bytes ,const int stride_col_dst , 1910 dpct::queue_ptr stream ) { 1911GGML_ASSERT (ncols %QK_K == 0 ); 1912 1913constexpr size_t num_subgroups = WARP_SIZE ; 1914const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1915const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1916const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1917 1918stream -> submit ([& ](sycl::handler & cgh ) { 1919cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1920 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1921mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q5_K > ,ncols_dst > ( 1922vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1923/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1924 }); 1925 }); 1926} 1927 1928static void reorder_mul_mat_vec_q5_k_q8_1_sycl_switch_ncols ( 1929const void * vx ,const void * vy ,float * dst , 1930const int ncols ,const int nrows ,const int ncols_dst , 1931const int stride_col_y_bytes ,const int stride_col_dst , 1932 dpct::queue_ptr stream ) { 1933switch (ncols_dst ) { 1934case 1 :reorder_mul_mat_vec_q5_k_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1935case 2 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1936case 3 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1937case 4 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1938case 5 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1939case 6 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1940case 7 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1941case 8 :reorder_mul_mat_vec_q5_k_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1942default :GGML_ABORT ("unsupported ncols_dst=%d for Q5_K reorder multi-col MMVQ" ,ncols_dst ); 1943 } 1944} 1945 1946static void reorder_mul_mat_vec_q6_k_q8_1_sycl (const void * vx ,const void * vy ,float * dst ,const int ncols , 1947const int nrows , dpct::queue_ptr stream ) { 1948GGML_ASSERT (ncols %QK_K == 0 ); 1949// Round up to a whole number of subgroup-sized workgroups; out-of-range rows are skipped inside the kernel. 1950constexpr size_t num_subgroups = WARP_SIZE ; 1951const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1952const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1953const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1954 1955 1956stream -> submit ([& ](sycl::handler & cgh ) { 1957cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1958 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1959mul_mat_vec_q_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q6_K >> (vx ,vy ,dst ,ncols ,nrows , 1960nd_item ); 1961 }); 1962 }); 1963} 1964 1965template < int ncols_dst > 1966static void reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols ( 1967const void * vx ,const void * vy ,float * dst , 1968const int ncols ,const int nrows , 1969const int stride_col_y_bytes ,const int stride_col_dst , 1970 dpct::queue_ptr stream ) { 1971GGML_ASSERT (ncols %QK_K == 0 ); 1972constexpr size_t num_subgroups = WARP_SIZE ; 1973const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups ); 1974const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 1975const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 1976 1977stream -> submit ([& ](sycl::handler & cgh ) { 1978cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1979 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 1980mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl < GGML_TYPE_Q6_K > ,ncols_dst > ( 1981vx ,/*vgate=*/ nullptr ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst , 1982/*glu_op=*/ GGML_GLU_OP_SWIGLU ,nd_item ); 1983 }); 1984 }); 1985} 1986 1987static void reorder_mul_mat_vec_q6_k_q8_1_sycl_switch_ncols ( 1988const void * vx ,const void * vy ,float * dst , 1989const int ncols ,const int nrows ,const int ncols_dst , 1990const int stride_col_y_bytes ,const int stride_col_dst , 1991 dpct::queue_ptr stream ) { 1992switch (ncols_dst ) { 1993case 1 :reorder_mul_mat_vec_q6_k_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 1994case 2 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1995case 3 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1996case 4 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1997case 5 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1998case 6 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 1999case 7 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 2000case 8 :reorder_mul_mat_vec_q6_k_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,stream );break ; 2001default :GGML_ABORT ("unsupported ncols_dst=%d for Q6_K reorder multi-col MMVQ" ,ncols_dst ); 2002 } 2003} 2004 2005static void mul_mat_vec_q6_K_q8_1_sycl (const void * vx ,const void * vy , 2006float * dst ,const int ncols , 2007const int nrows , 2008 dpct::queue_ptr stream ) { 2009GGML_ASSERT (ncols %QK_K == 0 ); 2010const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2011const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2012const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2013 { 2014 2015stream -> submit ([& ](sycl::handler & cgh ) { 2016 2017cgh .parallel_for ( 2018 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2019 [= ](sycl::nd_item < 3 > item_ct1 ) 2020 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2021mul_mat_vec_q < QK_K ,QI6_K ,block_q6_K , 2022VDR_Q6_K_Q8_1_MMVQ ,vec_dot_q6_K_q8_1 > ( 2023vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2024 }); 2025 }); 2026 } 2027} 2028 2029template < int ncols_dst > 2030static void mul_mat_vec_q6_K_q8_1_sycl_ncols ( 2031const void * vx ,const void * vy ,float * dst , 2032const int ncols ,const int nrows , 2033const int stride_col_y ,const int stride_col_dst , 2034 dpct::queue_ptr stream ) { 2035GGML_ASSERT (ncols %QK_K == 0 ); 2036const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2037const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2038const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2039 2040stream -> submit ([& ](sycl::handler & cgh ) { 2041cgh .parallel_for ( 2042 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2043 [= ](sycl::nd_item < 3 > item_ct1 ) 2044 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2045mul_mat_vec_q_ncols < QK_K ,QI6_K ,block_q6_K , 2046VDR_Q6_K_Q8_1_MMVQ , 2047vec_dot_q6_K_q8_1 , 2048ncols_dst > ( 2049vx ,vy ,dst ,ncols ,nrows , 2050stride_col_y ,stride_col_dst ,item_ct1 ); 2051 }); 2052 }); 2053} 2054 2055static void mul_mat_vec_q6_K_q8_1_sycl_switch_ncols ( 2056const void * vx ,const void * vy ,float * dst , 2057const int ncols ,const int nrows , 2058const int ncols_dst , 2059const int stride_col_y ,const int stride_col_dst , 2060 dpct::queue_ptr stream ) { 2061switch (ncols_dst ) { 2062case 1 :mul_mat_vec_q6_K_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 2063case 2 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2064case 3 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2065case 4 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2066case 5 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2067case 6 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2068case 7 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2069case 8 :mul_mat_vec_q6_K_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2070default :GGML_ABORT ("unsupported ncols_dst=%d for Q6_K multi-col MMVQ" ,ncols_dst ); 2071 } 2072} 2073 2074 2075static void mul_mat_vec_iq2_xxs_q8_1_sycl (const void * vx ,const void * vy , 2076float * dst ,const int ncols , 2077const int nrows , 2078 dpct::queue_ptr stream ) { 2079GGML_ASSERT (ncols %QK_K == 0 ); 2080const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2081const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2082const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2083 { 2084stream -> submit ([& ](sycl::handler & cgh ) { 2085cgh .parallel_for ( 2086 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2087 [= ](sycl::nd_item < 3 > item_ct1 ) 2088 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2089mul_mat_vec_q_iq2_xxs_q8_1 < QK_K ,QI2_XXS /2 ,block_iq2_xxs ,1 > ( 2090vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2091 }); 2092 }); 2093 } 2094} 2095 2096static void mul_mat_vec_iq2_xs_q8_1_sycl (const void * vx ,const void * vy , 2097float * dst ,const int ncols , 2098const int nrows , 2099 dpct::queue_ptr stream ) { 2100GGML_ASSERT (ncols %QK_K == 0 ); 2101const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2102const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2103const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2104 { 2105stream -> submit ([& ](sycl::handler & cgh ) { 2106cgh .parallel_for ( 2107 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2108 [= ](sycl::nd_item < 3 > item_ct1 ) 2109 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2110mul_mat_vec_q_iq2_xs_q8_1 < QK_K ,QI2_XS /2 ,block_iq2_xs ,1 > ( 2111vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2112 }); 2113 }); 2114 } 2115} 2116 2117static void mul_mat_vec_iq2_s_q8_1_sycl (const void * vx ,const void * vy , 2118float * dst ,const int ncols , 2119const int nrows , 2120 dpct::queue_ptr stream ) { 2121GGML_ASSERT (ncols %QK_K == 0 ); 2122const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2123const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2124const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2125 { 2126 2127stream -> submit ([& ](sycl::handler & cgh ) { 2128cgh .parallel_for ( 2129 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2130 [= ](sycl::nd_item < 3 > item_ct1 ) 2131 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2132mul_mat_vec_q_iq2_s_q8_1 < QK_K ,QI2_S /2 ,block_iq2_s ,1 > ( 2133vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2134 }); 2135 }); 2136 } 2137} 2138 2139static void mul_mat_vec_iq3_xxs_q8_1_sycl (const void * vx ,const void * vy , 2140float * dst ,const int ncols , 2141const int nrows , 2142 dpct::queue_ptr stream ) { 2143GGML_ASSERT (ncols %QK_K == 0 ); 2144const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2145const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2146const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2147 { 2148 2149stream -> submit ([& ](sycl::handler & cgh ) { 2150cgh .parallel_for ( 2151 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2152 [= ](sycl::nd_item < 3 > item_ct1 ) 2153 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2154mul_mat_vec_q_iq3_xxs_q8_1 < QK_K ,QI3_XXS /2 ,block_iq3_xxs ,1 > ( 2155vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2156 }); 2157 }); 2158 } 2159} 2160 2161static void mul_mat_vec_iq3_s_q8_1_sycl (const void * vx ,const void * vy , 2162float * dst ,const int ncols , 2163const int nrows , 2164 dpct::queue_ptr stream ) { 2165GGML_ASSERT (ncols %QK_K == 0 ); 2166const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2167const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2168const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2169 { 2170 2171stream -> submit ([& ](sycl::handler & cgh ) { 2172cgh .parallel_for ( 2173 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2174 [= ](sycl::nd_item < 3 > item_ct1 ) 2175 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2176mul_mat_vec_q_iq3_s_q8_1 < QK_K ,QI3_S /2 ,block_iq3_s ,1 > ( 2177vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2178 }); 2179 }); 2180 } 2181} 2182 2183static void mul_mat_vec_iq1_s_q8_1_sycl (const void * vx ,const void * vy , 2184float * dst ,const int ncols , 2185const int nrows , 2186 dpct::queue_ptr stream ) { 2187GGML_ASSERT (ncols %QK_K == 0 ); 2188const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2189const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2190const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2191 { 2192 2193stream -> submit ([& ](sycl::handler & cgh ) { 2194cgh .parallel_for ( 2195 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2196 [= ](sycl::nd_item < 3 > item_ct1 ) 2197 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2198mul_mat_vec_q_iq1_s_q8_1 < QK_K ,QI1_S ,block_iq1_s ,1 > ( 2199vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2200 }); 2201 }); 2202 } 2203} 2204 2205static void mul_mat_vec_iq1_m_q8_1_sycl (const void * vx ,const void * vy , 2206float * dst ,const int ncols , 2207const int nrows , 2208 dpct::queue_ptr stream ) { 2209GGML_ASSERT (ncols %QK_K == 0 ); 2210const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2211const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2212const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2213 { 2214stream -> submit ([& ](sycl::handler & cgh ) { 2215cgh .parallel_for ( 2216 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2217 [= ](sycl::nd_item < 3 > item_ct1 ) 2218 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2219mul_mat_vec_q_iq1_m_q8_1 < QK_K ,QI1_S ,block_iq1_m ,1 > ( 2220vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2221 }); 2222 }); 2223 } 2224} 2225 2226static void mul_mat_vec_iq4_nl_q8_1_sycl (const void * vx ,const void * vy , 2227float * dst ,const int ncols , 2228const int nrows , 2229 dpct::queue_ptr stream ) { 2230GGML_ASSERT (ncols %QK4_NL == 0 ); 2231const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2232const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2233const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2234 { 2235 2236stream -> submit ([& ](sycl::handler & cgh ) { 2237cgh .parallel_for ( 2238 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2239 [= ](sycl::nd_item < 3 > item_ct1 ) 2240 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2241mul_mat_vec_q_iq4_nl_q8_1 < QK4_NL ,QI4_NL ,block_iq4_nl ,2 > ( 2242vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2243 }); 2244 }); 2245 } 2246} 2247 2248static void mul_mat_vec_iq4_xs_q8_1_sycl (const void * vx ,const void * vy , 2249float * dst ,const int ncols , 2250const int nrows , 2251 dpct::queue_ptr stream ) { 2252GGML_ASSERT (ncols %QK_K == 0 ); 2253const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2254const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2255const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2256 { 2257 2258stream -> submit ([& ](sycl::handler & cgh ) { 2259cgh .parallel_for ( 2260 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2261 [= ](sycl::nd_item < 3 > item_ct1 ) 2262 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2263mul_mat_vec_q_iq4_xs_q8_1 < QK_K ,QI4_XS /4 ,block_iq4_xs ,1 > ( 2264vx ,vy ,dst ,ncols ,nrows ,item_ct1 ); 2265 }); 2266 }); 2267 } 2268} 2269 2270template < int ncols_dst > 2271static void mul_mat_vec_iq4_xs_q8_1_sycl_ncols ( 2272const void * vx ,const void * vy ,float * dst , 2273const int ncols ,const int nrows , 2274const int stride_col_y ,const int stride_col_dst , 2275 dpct::queue_ptr stream ) { 2276GGML_ASSERT (ncols %QK_K == 0 ); 2277const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2278const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 2279const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2280 2281stream -> submit ([& ](sycl::handler & cgh ) { 2282cgh .parallel_for ( 2283 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2284 [= ](sycl::nd_item < 3 > item_ct1 ) 2285 [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2286mul_mat_vec_q_ncols < QK_K ,QI4_XS /4 ,block_iq4_xs , 22871 , 2288vec_dot_iq4_xs_q8_1 , 2289ncols_dst > ( 2290vx ,vy ,dst ,ncols ,nrows , 2291stride_col_y ,stride_col_dst ,item_ct1 ); 2292 }); 2293 }); 2294} 2295 2296static void mul_mat_vec_iq4_xs_q8_1_sycl_switch_ncols ( 2297const void * vx ,const void * vy ,float * dst , 2298const int ncols ,const int nrows , 2299const int ncols_dst , 2300const int stride_col_y ,const int stride_col_dst , 2301 dpct::queue_ptr stream ) { 2302switch (ncols_dst ) { 2303case 1 :mul_mat_vec_iq4_xs_q8_1_sycl (vx ,vy ,dst ,ncols ,nrows ,stream );break ; 2304case 2 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 2 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2305case 3 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 3 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2306case 4 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 4 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2307case 5 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 5 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2308case 6 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 6 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2309case 7 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 7 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2310case 8 :mul_mat_vec_iq4_xs_q8_1_sycl_ncols < 8 > (vx ,vy ,dst ,ncols ,nrows ,stride_col_y ,stride_col_dst ,stream );break ; 2311default :GGML_ABORT ("unsupported ncols_dst=%d for IQ4_XS multi-col MMVQ" ,ncols_dst ); 2312 } 2313} 2314 2315void ggml_sycl_op_mul_mat_vec_q (ggml_backend_sycl_context & ctx ,const ggml_tensor * src0 ,const ggml_tensor * src1 , 2316ggml_tensor * dst ,const char * src0_dd_i ,const float * src1_ddf_i , 2317const char * src1_ddq_i ,float * dst_dd_i ,const int64_t row_low , 2318const int64_t row_high ,const int64_t src1_ncols ,const int64_t src1_padded_col_size , 2319const dpct::queue_ptr & stream ) { 2320const int64_t ne10 = src1 -> ne [0 ]; 2321GGML_ASSERT (ne10 %QK8_1 == 0 ); 2322 2323const int64_t ne00 = src0 -> ne [0 ]; 2324const int64_t row_diff = row_high - row_low ; 2325 2326int id ; 2327SYCL_CHECK (CHECK_TRY_ERROR (id = get_current_device_id ())); 2328const size_t q8_1_ts = sizeof (block_q8_1 ); 2329const size_t q8_1_bs = QK8_1 ; 2330// the main device has a larger memory buffer to hold the results from all GPUs 2331// nrows_dst == nrows of the matrix that the kernel writes into 2332 2333for (int i = 0 ;i < src1_ncols ;i ++ ) { 2334const size_t src1_ddq_i_offset = i * src1_padded_col_size * q8_1_ts /q8_1_bs ; 2335const char * src1_ddq_i_bs = src1_ddq_i + src1_ddq_i_offset ; 2336float * dst_dd_i_bs = dst_dd_i + i * dst -> ne [0 ]; 2337switch (src0 -> type ) { 2338case GGML_TYPE_Q4_0 : 2339if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2340 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2341if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2342const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2343const int stride_col_dst = dst -> ne [0 ]; 2344GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2345reorder_mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ( 2346src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2347src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2348return ; 2349 }else { 2350GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q4_0_q8_1_sycl\n" ); 2351reorder_mul_mat_vec_q4_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2352 } 2353 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2354const int stride_col_y = src1_padded_col_size /QK8_1 ; 2355const int stride_col_dst = dst -> ne [0 ]; 2356GGML_SYCL_DEBUG ("Calling mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2357mul_mat_vec_q4_0_q8_1_sycl_switch_ncols ( 2358src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2359src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2360return ; 2361 }else if (i == 0 || src1_ncols == 1 ) { 2362GGML_SYCL_DEBUG ("Calling mul_mat_vec_q4_0_q8_1_sycl\n" ); 2363mul_mat_vec_q4_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2364 } 2365break ; 2366case GGML_TYPE_Q4_1 : 2367if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2368const int stride_col_y = src1_padded_col_size /QK8_1 ; 2369const int stride_col_dst = dst -> ne [0 ]; 2370GGML_SYCL_DEBUG ("Calling mul_mat_vec_q4_1_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2371mul_mat_vec_q4_1_q8_1_sycl_switch_ncols ( 2372src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2373src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2374return ; 2375 }else if (i == 0 || src1_ncols == 1 ) { 2376mul_mat_vec_q4_1_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2377 } 2378break ; 2379case GGML_TYPE_Q5_0 : 2380if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2381const int stride_col_y = src1_padded_col_size /QK8_1 ; 2382const int stride_col_dst = dst -> ne [0 ]; 2383GGML_SYCL_DEBUG ("Calling mul_mat_vec_q5_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2384mul_mat_vec_q5_0_q8_1_sycl_switch_ncols ( 2385src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2386src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2387return ; 2388 }else if (i == 0 || src1_ncols == 1 ) { 2389mul_mat_vec_q5_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2390 } 2391break ; 2392case GGML_TYPE_Q5_1 : 2393if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2394const int stride_col_y = src1_padded_col_size /QK8_1 ; 2395const int stride_col_dst = dst -> ne [0 ]; 2396GGML_SYCL_DEBUG ("Calling mul_mat_vec_q5_1_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2397mul_mat_vec_q5_1_q8_1_sycl_switch_ncols ( 2398src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2399src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2400return ; 2401 }else if (i == 0 || src1_ncols == 1 ) { 2402mul_mat_vec_q5_1_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2403 } 2404break ; 2405case GGML_TYPE_Q8_0 : 2406if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2407 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2408if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2409const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2410const int stride_col_dst = dst -> ne [0 ]; 2411GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2412reorder_mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ( 2413src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2414src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2415return ; 2416 }else { 2417GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q8_0_q8_1_sycl\n" ); 2418reorder_mul_mat_vec_q8_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2419 } 2420 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2421const int stride_col_y = src1_padded_col_size /QK8_1 ; 2422const int stride_col_dst = dst -> ne [0 ]; 2423GGML_SYCL_DEBUG ("Calling mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2424mul_mat_vec_q8_0_q8_1_sycl_switch_ncols ( 2425src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2426src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2427return ; 2428 }else if (i == 0 || src1_ncols == 1 ) { 2429GGML_SYCL_DEBUG ("Calling mul_mat_vec_q8_0_q8_1_sycl\n" ); 2430mul_mat_vec_q8_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2431 } 2432break ; 2433case GGML_TYPE_Q1_0 : 2434if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2435const int stride_col_y = src1_padded_col_size /QK8_1 ; 2436const int stride_col_dst = dst -> ne [0 ]; 2437GGML_SYCL_DEBUG ("Calling mul_mat_vec_q1_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2438mul_mat_vec_q1_0_q8_1_sycl_switch_ncols ( 2439src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2440src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2441return ; 2442 }else if (i == 0 || src1_ncols == 1 ) { 2443GGML_SYCL_DEBUG ("Calling mul_mat_vec_q1_0_q8_1_sycl\n" ); 2444mul_mat_vec_q1_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2445 } 2446break ; 2447case GGML_TYPE_Q2_0 : 2448if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2449const int stride_col_y = src1_padded_col_size /QK8_1 ; 2450const int stride_col_dst = dst -> ne [0 ]; 2451GGML_SYCL_DEBUG ("Calling mul_mat_vec_q2_0_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2452mul_mat_vec_q2_0_q8_1_sycl_switch_ncols ( 2453src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2454src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2455return ; 2456 }else if (i == 0 || src1_ncols == 1 ) { 2457GGML_SYCL_DEBUG ("Calling mul_mat_vec_q2_0_q8_1_sycl\n" ); 2458mul_mat_vec_q2_0_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2459 } 2460break ; 2461case GGML_TYPE_Q2_K : 2462if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2463 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2464if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2465const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2466const int stride_col_dst = dst -> ne [0 ]; 2467GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q2_k_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2468reorder_mul_mat_vec_q2_k_q8_1_sycl_switch_ncols ( 2469src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2470src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2471return ; 2472 }else { 2473GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q2_k_q8_1_sycl\n" ); 2474reorder_mul_mat_vec_q2_k_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2475 } 2476 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2477const int stride_col_y = src1_padded_col_size /QK8_1 ; 2478const int stride_col_dst = dst -> ne [0 ]; 2479GGML_SYCL_DEBUG ("Calling mul_mat_vec_q2_K_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2480mul_mat_vec_q2_K_q8_1_sycl_switch_ncols ( 2481src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2482src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2483return ; 2484 }else if (i == 0 || src1_ncols == 1 ) { 2485GGML_SYCL_DEBUG ("Calling mul_mat_vec_q2_K_q8_1_sycl\n" ); 2486mul_mat_vec_q2_K_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2487 } 2488break ; 2489case GGML_TYPE_Q3_K : 2490if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2491 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2492if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2493const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2494const int stride_col_dst = dst -> ne [0 ]; 2495GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q3_k_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2496reorder_mul_mat_vec_q3_k_q8_1_sycl_switch_ncols ( 2497src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2498src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2499return ; 2500 }else { 2501GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q3_k_q8_1_sycl\n" ); 2502reorder_mul_mat_vec_q3_k_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2503 } 2504 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2505const int stride_col_y = src1_padded_col_size /QK8_1 ; 2506const int stride_col_dst = dst -> ne [0 ]; 2507GGML_SYCL_DEBUG ("Calling mul_mat_vec_q3_K_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2508mul_mat_vec_q3_K_q8_1_sycl_switch_ncols ( 2509src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2510src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2511return ; 2512 }else if (i == 0 || src1_ncols == 1 ) { 2513GGML_SYCL_DEBUG ("Calling mul_mat_vec_q3_K_q8_1_sycl\n" ); 2514mul_mat_vec_q3_K_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2515 } 2516break ; 2517case GGML_TYPE_Q4_K : 2518if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2519 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2520if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2521const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2522const int stride_col_dst = dst -> ne [0 ]; 2523GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q4_k_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2524reorder_mul_mat_vec_q4_k_q8_1_sycl_switch_ncols ( 2525src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2526src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2527return ; 2528 }else { 2529GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q4_k_q8_1_sycl\n" ); 2530reorder_mul_mat_vec_q4_k_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2531 } 2532 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2533const int stride_col_y = src1_padded_col_size /QK8_1 ; 2534const int stride_col_dst = dst -> ne [0 ]; 2535GGML_SYCL_DEBUG ("Calling mul_mat_vec_q4_K_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2536mul_mat_vec_q4_K_q8_1_sycl_switch_ncols ( 2537src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2538src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2539return ; 2540 }else if (i == 0 || src1_ncols == 1 ) { 2541GGML_SYCL_DEBUG ("Calling mul_mat_vec_q4_K_q8_1_sycl\n" ); 2542mul_mat_vec_q4_K_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2543 } 2544break ; 2545case GGML_TYPE_Q5_K : 2546if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2547 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2548if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2549const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2550const int stride_col_dst = dst -> ne [0 ]; 2551GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q5_k_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2552reorder_mul_mat_vec_q5_k_q8_1_sycl_switch_ncols ( 2553src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2554src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2555return ; 2556 }else { 2557GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q5_k_q8_1_sycl\n" ); 2558reorder_mul_mat_vec_q5_k_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2559 } 2560 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2561const int stride_col_y = src1_padded_col_size /QK8_1 ; 2562const int stride_col_dst = dst -> ne [0 ]; 2563GGML_SYCL_DEBUG ("Calling mul_mat_vec_q5_K_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2564mul_mat_vec_q5_K_q8_1_sycl_switch_ncols ( 2565src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2566src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2567return ; 2568 }else if (i == 0 || src1_ncols == 1 ) { 2569GGML_SYCL_DEBUG ("Calling mul_mat_vec_q5_K_q8_1_sycl\n" ); 2570mul_mat_vec_q5_K_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2571 } 2572break ; 2573case GGML_TYPE_Q6_K : 2574if ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra && 2575 ((ggml_tensor_extra_gpu * )dst -> src [0 ]-> extra )-> optimized_feature .reorder ) { 2576if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2577const int stride_col_y_bytes = src1_padded_col_size * q8_1_ts /q8_1_bs ; 2578const int stride_col_dst = dst -> ne [0 ]; 2579GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q6_k_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2580reorder_mul_mat_vec_q6_k_q8_1_sycl_switch_ncols ( 2581src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2582src1_ncols ,stride_col_y_bytes ,stride_col_dst ,stream ); 2583return ; 2584 }else { 2585GGML_SYCL_DEBUG ("Calling reorder_mul_mat_vec_q6_k_q8_1_sycl\n" ); 2586reorder_mul_mat_vec_q6_k_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2587 } 2588 }else if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2589const int stride_col_y = src1_padded_col_size /QK8_1 ; 2590const int stride_col_dst = dst -> ne [0 ]; 2591GGML_SYCL_DEBUG ("Calling mul_mat_vec_q6_K_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2592mul_mat_vec_q6_K_q8_1_sycl_switch_ncols ( 2593src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2594src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2595return ; 2596 }else if (i == 0 || src1_ncols == 1 ) { 2597GGML_SYCL_DEBUG ("Calling mul_mat_vec_q6_k_q8_1_sycl\n" ); 2598mul_mat_vec_q6_K_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2599 } 2600break ; 2601case GGML_TYPE_IQ1_S : 2602mul_mat_vec_iq1_s_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2603break ; 2604case GGML_TYPE_IQ1_M : 2605mul_mat_vec_iq1_m_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2606break ; 2607case GGML_TYPE_IQ2_XXS : 2608mul_mat_vec_iq2_xxs_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2609break ; 2610case GGML_TYPE_IQ2_XS : 2611mul_mat_vec_iq2_xs_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2612break ; 2613case GGML_TYPE_IQ2_S : 2614mul_mat_vec_iq2_s_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2615break ; 2616case GGML_TYPE_IQ3_XXS : 2617mul_mat_vec_iq3_xxs_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2618break ; 2619case GGML_TYPE_IQ3_S : 2620mul_mat_vec_iq3_s_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2621break ; 2622case GGML_TYPE_IQ4_NL : 2623mul_mat_vec_iq4_nl_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2624break ; 2625case GGML_TYPE_IQ4_XS : 2626if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2627const int stride_col_y = src1_padded_col_size /QK8_1 ; 2628const int stride_col_dst = dst -> ne [0 ]; 2629GGML_SYCL_DEBUG ("Calling mul_mat_vec_iq4_xs_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2630mul_mat_vec_iq4_xs_q8_1_sycl_switch_ncols ( 2631src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2632src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2633return ; 2634 }else if (i == 0 || src1_ncols == 1 ) { 2635mul_mat_vec_iq4_xs_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2636 } 2637break ; 2638case GGML_TYPE_MXFP4 : 2639if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2640const int stride_col_y = src1_padded_col_size /QK8_1 ; 2641const int stride_col_dst = dst -> ne [0 ]; 2642GGML_SYCL_DEBUG ("Calling mul_mat_vec_mxfp4_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2643mul_mat_vec_mxfp4_q8_1_sycl_switch_ncols ( 2644src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2645src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2646return ; 2647 }else if (i == 0 || src1_ncols == 1 ) { 2648mul_mat_vec_mxfp4_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2649 } 2650break ; 2651case GGML_TYPE_NVFP4 : 2652if (i == 0 && src1_ncols > 1 && src1_ncols <=8 ) { 2653const int stride_col_y = src1_padded_col_size /QK8_1 ; 2654const int stride_col_dst = dst -> ne [0 ]; 2655GGML_SYCL_DEBUG ("Calling mul_mat_vec_nvfp4_q8_1_sycl_switch_ncols ncols=%d\n" , (int )src1_ncols ); 2656mul_mat_vec_nvfp4_q8_1_sycl_switch_ncols ( 2657src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff , 2658src1_ncols ,stride_col_y ,stride_col_dst ,stream ); 2659return ; 2660 }else if (i == 0 || src1_ncols == 1 ) { 2661mul_mat_vec_nvfp4_q8_1_sycl (src0_dd_i ,src1_ddq_i_bs ,dst_dd_i_bs ,ne00 ,row_diff ,stream ); 2662 } 2663break ; 2664default : 2665GGML_ABORT ("fatal error: unsupport src0 data type %s\n" ,ggml_type_name (src0 -> type )); 2666 } 2667 } 2668GGML_UNUSED (src1 ); 2669GGML_UNUSED (dst ); 2670GGML_UNUSED (src1_ddf_i ); 2671GGML_UNUSED (ctx ); 2672} 2673 2674// vec_dot_q_sycl_t adapters for the IQ vec_dots that take their codebook tables as extra 2675// arguments: bind the constant tables here (as vec_dot_iq2_s_q8_1 / vec_dot_iq1_m_q8_1 already do 2676// internally) so they can be used as template arguments of mul_mat_vec_q_moe. 2677static __dpct_inline__ float vec_dot_iq2_xxs_q8_1_moe (const void * __restrict__vbq , 2678const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 2679return vec_dot_iq2_xxs_q8_1 (vbq ,bq8_1 ,iqs ,iq2xxs_grid ,ksigns_iq2xs ,kmask_iq2xs ); 2680} 2681 2682static __dpct_inline__ float vec_dot_iq2_xs_q8_1_moe (const void * __restrict__vbq , 2683const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 2684return vec_dot_iq2_xs_q8_1 (vbq ,bq8_1 ,iqs ,iq2xs_grid ,ksigns64 ); 2685} 2686 2687static __dpct_inline__ float vec_dot_iq3_xxs_q8_1_moe (const void * __restrict__vbq , 2688const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 2689return vec_dot_iq3_xxs_q8_1 (vbq ,bq8_1 ,iqs ,iq3xxs_grid ,ksigns64 ); 2690} 2691 2692static __dpct_inline__ float vec_dot_iq3_s_q8_1_moe (const void * __restrict__vbq , 2693const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 2694return vec_dot_iq3_s_q8_1 (vbq ,bq8_1 ,iqs ,iq3s_grid ); 2695} 2696 2697static __dpct_inline__ float vec_dot_iq1_s_q8_1_moe (const void * __restrict__vbq , 2698const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 2699return vec_dot_iq1_s_q8_1 (vbq ,bq8_1 ,iqs ,iq1s_grid_gpu ); 2700} 2701 2702// src1_row_stride: 0 for shared src1 (gate/up proj), else per-expert stride (down proj). 2703template < int qk ,int qi ,typename block_q_t ,int vdr ,vec_dot_q_sycl_t vec_dot_q_sycl > 2704static void mul_mat_vec_q_moe ( 2705const void * __restrict__vx_base ,const void * __restrict__vy_base , 2706float * __restrict__dst_base ,const int32_t * __restrict__ids_dev , 2707const int ncols ,const int nrows , 2708const size_t expert_weight_stride ,const size_t dst_row_stride , 2709const size_t src1_row_stride , 2710const sycl::nd_item < 3 > & item_ct1 ) { 2711 2712const int expert_idx = item_ct1 .get_group (1 ); 2713const int i02 = ids_dev [expert_idx ]; 2714 2715const char * vx = (const char * )vx_base + (size_t )i02 * expert_weight_stride ; 2716const char * vy = (const char * )vy_base + (size_t )expert_idx * src1_row_stride ; 2717float * dst = (float * ) ((char * )dst_base + (size_t )expert_idx * dst_row_stride ); 2718 2719const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ item_ct1 .get_local_id (1 ); 2720 2721if (row >=nrows ) { 2722return ; 2723 } 2724 2725const int blocks_per_row = ncols /qk ; 2726constexpr int blocks_per_warp = (vdr * WARP_SIZE + qi - 1 ) /qi ; 2727 2728float tmp = 0.0f ; 2729 2730const block_q_t * x = (const block_q_t * )vx ; 2731const block_q8_1 * y = (const block_q8_1 * )vy ; 2732 2733for (int i = item_ct1 .get_local_id (2 ) / (qi /vdr );i < blocks_per_row ;i += blocks_per_warp ) { 2734const int ibx = row * blocks_per_row + i ; 2735const int iby = i * (qk /QK8_1 ); 2736 2737for (size_t elem = 0 ;elem < qi /vdr ;elem += WARP_SIZE ) { 2738const int iqs = elem + vdr * (item_ct1 .get_local_id (2 ) % (qi /vdr )); 2739tmp += vec_dot_q_sycl (& x [ibx ],& y [iby ],iqs ); 2740 } 2741 } 2742 2743#pragma unroll 2744for (int mask = WARP_SIZE /2 ;mask > 0 ;mask >>=1 ) { 2745tmp += dpct::permute_sub_group_by_xor (item_ct1 .get_sub_group (),tmp ,mask ); 2746 } 2747 2748if (item_ct1 .get_local_id (2 )== 0 ) { 2749dst [row ]= tmp ; 2750 } 2751} 2752 2753template < int qk ,int qi ,typename block_q_t ,int vdr ,vec_dot_q_sycl_t vec_dot_q_sycl > 2754static void launch_mul_mat_vec_q_moe ( 2755const void * vx_base ,const void * vy ,const int32_t * ids_dev , 2756float * dst_base ,const int ncols ,const int nrows ,const int n_experts_used , 2757const size_t expert_weight_stride ,const size_t dst_row_stride , 2758const size_t src1_row_stride , 2759 dpct::queue_ptr stream ) { 2760const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2761const sycl::range < 3 > block_nums (1 , (unsigned )n_experts_used , (unsigned )block_num_y ); 2762const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2763stream -> submit ([& ](sycl::handler & cgh ) { 2764cgh .parallel_for ( 2765 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2766 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2767mul_mat_vec_q_moe < qk ,qi ,block_q_t ,vdr ,vec_dot_q_sycl > ( 2768vx_base ,vy ,dst_base ,ids_dev ,ncols ,nrows , 2769expert_weight_stride ,dst_row_stride ,src1_row_stride ,item ); 2770 }); 2771 }); 2772} 2773 2774bool ggml_sycl_mul_mat_vec_q_id ( 2775enum ggml_type src0_type , 2776const void * vx_base , 2777const void * vy , 2778const int32_t * ids_dev , 2779float * dst_base , 2780int ncols , 2781int nrows , 2782int n_experts_used , 2783size_t expert_weight_stride , 2784size_t dst_row_stride , 2785size_t src1_row_stride , 2786 dpct::queue_ptr stream ) { 2787switch (src0_type ) { 2788case GGML_TYPE_Q4_0 : 2789launch_mul_mat_vec_q_moe < QK4_0 ,QI4_0 ,block_q4_0 ,VDR_Q4_0_Q8_1_MMVQ ,vec_dot_q4_0_q8_1 > ( 2790vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2791expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2792return true; 2793case GGML_TYPE_Q4_1 : 2794launch_mul_mat_vec_q_moe < QK4_1 ,QI4_1 ,block_q4_1 ,VDR_Q4_1_Q8_1_MMVQ ,vec_dot_q4_1_q8_1 > ( 2795vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2796expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2797return true; 2798case GGML_TYPE_Q5_0 : 2799launch_mul_mat_vec_q_moe < QK5_0 ,QI5_0 ,block_q5_0 ,VDR_Q5_0_Q8_1_MMVQ ,vec_dot_q5_0_q8_1 > ( 2800vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2801expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2802return true; 2803case GGML_TYPE_Q5_1 : 2804launch_mul_mat_vec_q_moe < QK5_1 ,QI5_1 ,block_q5_1 ,VDR_Q5_1_Q8_1_MMVQ ,vec_dot_q5_1_q8_1 > ( 2805vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2806expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2807return true; 2808case GGML_TYPE_Q8_0 : 2809launch_mul_mat_vec_q_moe < QK8_0 ,QI8_0 ,block_q8_0 ,VDR_Q8_0_Q8_1_MMVQ ,vec_dot_q8_0_q8_1 > ( 2810vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2811expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2812return true; 2813case GGML_TYPE_Q2_0 : 2814launch_mul_mat_vec_q_moe < QK2_0 ,QI2_0 ,block_q2_0 ,VDR_Q2_0_Q8_1_MMVQ ,vec_dot_q2_0_q8_1 > ( 2815vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2816expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2817return true; 2818case GGML_TYPE_Q2_K : 2819launch_mul_mat_vec_q_moe < QK_K ,QI2_K ,block_q2_K ,VDR_Q2_K_Q8_1_MMVQ ,vec_dot_q2_K_q8_1 > ( 2820vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2821expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2822return true; 2823case GGML_TYPE_Q3_K : 2824launch_mul_mat_vec_q_moe < QK_K ,QI3_K ,block_q3_K ,VDR_Q3_K_Q8_1_MMVQ ,vec_dot_q3_K_q8_1 > ( 2825vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2826expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2827return true; 2828case GGML_TYPE_Q4_K : 2829launch_mul_mat_vec_q_moe < QK_K ,QI4_K ,block_q4_K ,VDR_Q4_K_Q8_1_MMVQ ,vec_dot_q4_K_q8_1 > ( 2830vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2831expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2832return true; 2833case GGML_TYPE_Q5_K : 2834launch_mul_mat_vec_q_moe < QK_K ,QI5_K ,block_q5_K ,VDR_Q5_K_Q8_1_MMVQ ,vec_dot_q5_K_q8_1 > ( 2835vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2836expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2837return true; 2838case GGML_TYPE_Q6_K : 2839launch_mul_mat_vec_q_moe < QK_K ,QI6_K ,block_q6_K ,VDR_Q6_K_Q8_1_MMVQ ,vec_dot_q6_K_q8_1 > ( 2840vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2841expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2842return true; 2843case GGML_TYPE_MXFP4 : 2844launch_mul_mat_vec_q_moe < QK_MXFP4 ,QI_MXFP4 ,block_mxfp4 ,VDR_MXFP4_Q8_1_MMVQ ,vec_dot_mxfp4_q8_1 > ( 2845vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2846expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2847return true; 2848case GGML_TYPE_NVFP4 : 2849launch_mul_mat_vec_q_moe < QK_NVFP4 ,QI_NVFP4 ,block_nvfp4 ,VDR_NVFP4_Q8_1_MMVQ ,vec_dot_nvfp4_q8_1 > ( 2850vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2851expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2852return true; 2853case GGML_TYPE_IQ2_XXS : 2854launch_mul_mat_vec_q_moe < QK_K ,QI2_XXS /2 ,block_iq2_xxs ,VDR_IQ2_XXS_Q8_1_MMVQ ,vec_dot_iq2_xxs_q8_1_moe > ( 2855vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2856expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2857return true; 2858case GGML_TYPE_IQ2_XS : 2859launch_mul_mat_vec_q_moe < QK_K ,QI2_XS /2 ,block_iq2_xs ,VDR_IQ2_XS_Q8_1_MMVQ ,vec_dot_iq2_xs_q8_1_moe > ( 2860vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2861expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2862return true; 2863case GGML_TYPE_IQ2_S : 2864launch_mul_mat_vec_q_moe < QK_K ,QI2_S /2 ,block_iq2_s ,VDR_IQ2_S_Q8_1_MMVQ ,vec_dot_iq2_s_q8_1 > ( 2865vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2866expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2867return true; 2868case GGML_TYPE_IQ3_XXS : 2869launch_mul_mat_vec_q_moe < QK_K ,QI3_XXS /2 ,block_iq3_xxs ,VDR_IQ3_XXS_Q8_1_MMVQ ,vec_dot_iq3_xxs_q8_1_moe > ( 2870vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2871expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2872return true; 2873case GGML_TYPE_IQ3_S : 2874launch_mul_mat_vec_q_moe < QK_K ,QI3_S /2 ,block_iq3_s ,VDR_IQ3_S_Q8_1_MMVQ ,vec_dot_iq3_s_q8_1_moe > ( 2875vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2876expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2877return true; 2878case GGML_TYPE_IQ1_S : 2879launch_mul_mat_vec_q_moe < QK_K ,QI1_S ,block_iq1_s ,VDR_IQ1_S_Q8_1_MMVQ ,vec_dot_iq1_s_q8_1_moe > ( 2880vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2881expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2882return true; 2883case GGML_TYPE_IQ1_M : 2884launch_mul_mat_vec_q_moe < QK_K ,QI1_S ,block_iq1_m ,VDR_IQ1_M_Q8_1_MMVQ ,vec_dot_iq1_m_q8_1 > ( 2885vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2886expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2887return true; 2888case GGML_TYPE_IQ4_NL : 2889launch_mul_mat_vec_q_moe < QK4_NL ,QI4_NL ,block_iq4_nl ,VDR_IQ4_NL_Q8_1_MMVQ ,vec_dot_iq4_nl_q8_1 > ( 2890vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2891expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2892return true; 2893case GGML_TYPE_IQ4_XS : 2894launch_mul_mat_vec_q_moe < QK_K ,QI4_XS /4 ,block_iq4_xs ,VDR_IQ4_XS_Q8_1_MMVQ ,vec_dot_iq4_xs_q8_1 > ( 2895vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 2896expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 2897return true; 2898default : 2899return false; 2900 } 2901} 2902 2903// Reorder (SoA) MoE expert GEMV: MoE expert/row/lane indexing (from mul_mat_vec_q_moe) with the 2904// dense-reorder per-block reads (from mul_mat_vec_q_reorder). Each expert slice in vx_base is a 2905// self-contained SoA, so nblocks = nrows*(ncols/qk) per expert and the constant expert stride holds. 2906template < typename reorder_vec_dot_q_sycl > 2907static void mul_mat_vec_q_moe_reorder ( 2908const void * __restrict__vx_base ,const void * __restrict__vy_base , 2909float * __restrict__dst_base ,const int32_t * __restrict__ids_dev , 2910const int ncols ,const int nrows , 2911const size_t expert_weight_stride ,const size_t dst_row_stride , 2912const size_t src1_row_stride , 2913const sycl::nd_item < 3 > & item_ct1 ) { 2914using block_type = ggml_sycl_reordered::block_q_t < reorder_vec_dot_q_sycl::gtype > ; 2915using block_traits = typename block_type::traits ; 2916 2917const int expert_idx = item_ct1 .get_group (1 ); 2918const int i02 = ids_dev [expert_idx ]; 2919 2920const char * vx = (const char * )vx_base + (size_t )i02 * expert_weight_stride ; 2921const char * vy = (const char * )vy_base + (size_t )expert_idx * src1_row_stride ; 2922float * dst = (float * ) ((char * )dst_base + (size_t )expert_idx * dst_row_stride ); 2923 2924const int row = item_ct1 .get_group (2 )* item_ct1 .get_local_range (1 )+ item_ct1 .get_local_id (1 ); 2925if (row >=nrows ) { 2926return ; 2927 } 2928 2929const auto sg = item_ct1 .get_sub_group (); 2930 2931const int blocks_per_row = ncols / block_traits::qk ; 2932constexpr int blocks_per_subgroup = ceil_div (block_traits::vdr_mmvq * WARP_SIZE , block_traits::qi ); 2933constexpr int block_elements_per_subgroup = block_traits::qi / block_traits::vdr_mmvq ; 2934const int nblocks = nrows * (ncols / block_traits::qk ); 2935 2936 static_assert(blocks_per_subgroup > 0 ); 2937 static_assert(block_elements_per_subgroup > 0 ); 2938 2939float partial_sum = 0.0f ; 2940for (int i = sg .get_local_linear_id () /block_elements_per_subgroup ;i < blocks_per_row ;i += blocks_per_subgroup ) { 2941const int ibx = row * blocks_per_row + i ; 2942 2943const auto bx_offset = block_type::get_block_offset (ibx ,nblocks ); 2944const auto d_offset = block_type::get_d_offset (nrows ,ncols ,ibx ); 2945 2946const int iby = i * block_type::block_to_q8_1_ratio (); 2947const int8_t * q8_1_quant_ptr = (const int8_t * )vy + iby * QK8_1 ; 2948const sycl::half2 * q8_1_ds_ptr = (const sycl::half2 * ) ((const char * )vy + ncols + iby * sizeof (sycl::half2 )); 2949 2950#pragma unroll 2951for (int elem = 0 ;elem < block_elements_per_subgroup ;elem += WARP_SIZE ) { 2952const int iqs = elem + block_traits::vdr_mmvq * (sg .get_local_linear_id () %block_elements_per_subgroup ); 2953partial_sum += reorder_vec_dot_q_sycl ()(vx ,bx_offset ,d_offset ,q8_1_quant_ptr ,q8_1_ds_ptr ,iqs ); 2954 } 2955 } 2956 2957auto sum = sycl::reduce_over_group (sg ,partial_sum , std::plus <> ()); 2958if (sg .leader ()) { 2959dst [row ]= sum ; 2960 } 2961} 2962 2963template < typename reorder_vec_dot_q_sycl > 2964static void launch_mul_mat_vec_q_moe_reorder ( 2965const void * vx_base ,const void * vy ,const int32_t * ids_dev , 2966float * dst_base ,const int ncols ,const int nrows ,const int n_experts_used , 2967const size_t expert_weight_stride ,const size_t dst_row_stride , 2968const size_t src1_row_stride , 2969 dpct::queue_ptr stream ) { 2970const int block_num_y = (nrows + GGML_SYCL_MMV_Y - 1 ) /GGML_SYCL_MMV_Y ; 2971const sycl::range < 3 > block_nums (1 , (unsigned )n_experts_used , (unsigned )block_num_y ); 2972const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,WARP_SIZE ); 2973stream -> submit ([& ](sycl::handler & cgh ) { 2974cgh .parallel_for ( 2975 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2976 [= ](sycl::nd_item < 3 > item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 2977mul_mat_vec_q_moe_reorder < reorder_vec_dot_q_sycl > ( 2978vx_base ,vy ,dst_base ,ids_dev ,ncols ,nrows , 2979expert_weight_stride ,dst_row_stride ,src1_row_stride ,item ); 2980 }); 2981 }); 2982} 2983 2984bool ggml_sycl_mul_mat_vec_q_id_reorder ( 2985enum ggml_type src0_type , 2986const void * vx_base , 2987const void * vy , 2988const int32_t * ids_dev , 2989float * dst_base , 2990int ncols , 2991int nrows , 2992int n_experts_used , 2993size_t expert_weight_stride , 2994size_t dst_row_stride , 2995size_t src1_row_stride , 2996 dpct::queue_ptr stream ) { 2997switch (src0_type ) { 2998case GGML_TYPE_Q4_K : 2999launch_mul_mat_vec_q_moe_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q4_K >> ( 3000vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 3001expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 3002return true; 3003case GGML_TYPE_Q5_K : 3004launch_mul_mat_vec_q_moe_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q5_K >> ( 3005vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 3006expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 3007return true; 3008case GGML_TYPE_Q6_K : 3009launch_mul_mat_vec_q_moe_reorder < reorder_vec_dot_q_sycl < GGML_TYPE_Q6_K >> ( 3010vx_base ,vy ,ids_dev ,dst_base ,ncols ,nrows ,n_experts_used , 3011expert_weight_stride ,dst_row_stride ,src1_row_stride ,stream ); 3012return true; 3013default : 3014return false; 3015 } 3016} 3017 3018template < typename reorder_vec_dot_q_sycl ,int ncols_dst ,int rows_per_sg > 3019static void launch_mul_mat_vec_q_reorder_glu_impl (const void * vx ,const void * vgate ,const void * vy ,float * dst , 3020const int ncols ,const int nrows ,const int stride_col_y_bytes , 3021const int stride_col_dst ,const ggml_glu_op glu_op , 3022 dpct::queue_ptr stream ) { 3023GGML_ASSERT (ncols %QK_K == 0 ); 3024 3025constexpr size_t num_subgroups = WARP_SIZE ; 3026 3027const int block_num_y = ceil_div (nrows ,GGML_SYCL_MMV_Y * (int )num_subgroups * rows_per_sg ); 3028const sycl::range < 3 > block_nums (1 ,1 ,block_num_y ); 3029const sycl::range < 3 > block_dims (1 ,GGML_SYCL_MMV_Y ,num_subgroups * WARP_SIZE ); 3030 3031stream -> submit ([& ](sycl::handler & cgh ) { 3032cgh .parallel_for (sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 3033 [= ](sycl::nd_item < 3 > nd_item ) [[sycl ::reqd_sub_group_size (WARP_SIZE )]] { 3034mul_mat_vec_q_reorder_ncols < reorder_vec_dot_q_sycl ,ncols_dst ,/*has_fusion=*/ true, 3035rows_per_sg > ( 3036vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,glu_op , 3037nd_item ); 3038 }); 3039 }); 3040} 3041 3042template < typename reorder_vec_dot_q_sycl ,int ncols_dst > 3043static void launch_mul_mat_vec_q_reorder_glu (const void * vx ,const void * vgate ,const void * vy ,float * dst , 3044const int ncols ,const int nrows ,const int stride_col_y_bytes , 3045const int stride_col_dst ,const ggml_glu_op glu_op , 3046 dpct::queue_ptr stream ) { 3047constexpr int rows_per_sg = 3048reorder_vec_dot_shared_activations < reorder_vec_dot_q_sycl::gtype > ::value && ncols_dst >=3 && ncols_dst <=4 3049 ?2 3050 :1 ; 3051launch_mul_mat_vec_q_reorder_glu_impl < reorder_vec_dot_q_sycl ,ncols_dst ,rows_per_sg > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,glu_op ,stream ); 3052} 3053 3054bool ggml_sycl_mul_mat_vec_q_glu_reorder (enum ggml_type src0_type ,enum ggml_glu_op glu_op ,const void * vx , 3055const void * vgate ,const void * vy ,float * dst ,int ncols ,int nrows , 3056int ncols_dst ,int stride_col_y_bytes ,int stride_col_dst , 3057 dpct::queue_ptr stream ) { 3058if (src0_type != GGML_TYPE_Q4_K ) { 3059return false; 3060 } 3061if (glu_op != GGML_GLU_OP_SWIGLU && glu_op != GGML_GLU_OP_GEGLU ) { 3062return false; 3063 } 3064 3065using vec_dot = reorder_vec_dot_q_sycl < GGML_TYPE_Q4_K > ; 3066 3067switch (ncols_dst ) { 3068case 1 : 3069launch_mul_mat_vec_q_reorder_glu < vec_dot ,1 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3070stride_col_dst ,glu_op ,stream ); 3071return true; 3072case 2 : 3073if (nrows >=Q4_K_MMVQ_ROW_PAIR_MIN_NROWS ) { 3074launch_mul_mat_vec_q_reorder_glu_impl < vec_dot ,2 ,2 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,glu_op ,stream ); 3075 }else { 3076launch_mul_mat_vec_q_reorder_glu_impl < vec_dot ,2 ,1 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes ,stride_col_dst ,glu_op ,stream ); 3077 } 3078return true; 3079case 3 : 3080launch_mul_mat_vec_q_reorder_glu < vec_dot ,3 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3081stride_col_dst ,glu_op ,stream ); 3082return true; 3083case 4 : 3084launch_mul_mat_vec_q_reorder_glu < vec_dot ,4 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3085stride_col_dst ,glu_op ,stream ); 3086return true; 3087case 5 : 3088launch_mul_mat_vec_q_reorder_glu < vec_dot ,5 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3089stride_col_dst ,glu_op ,stream ); 3090return true; 3091case 6 : 3092launch_mul_mat_vec_q_reorder_glu < vec_dot ,6 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3093stride_col_dst ,glu_op ,stream ); 3094return true; 3095case 7 : 3096launch_mul_mat_vec_q_reorder_glu < vec_dot ,7 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3097stride_col_dst ,glu_op ,stream ); 3098return true; 3099case 8 : 3100launch_mul_mat_vec_q_reorder_glu < vec_dot ,8 > (vx ,vgate ,vy ,dst ,ncols ,nrows ,stride_col_y_bytes , 3101stride_col_dst ,glu_op ,stream ); 3102return true; 3103default : 3104return false; 3105 } 3106}