char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
704d90c98
char/aliceai-t5-moe
1// 2// MIT license 3// Copyright (C) 2024 Intel Corporation 4// SPDX-License-Identifier: MIT 5// 6 7// 8// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 9// See https://llvm.org/LICENSE.txt for license information. 10// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 11// 12 13#include "mmq.hpp" 14#include "vecdotq.hpp" 15 16typedef void (* allocate_tiles_sycl_t )( 17int ** x_ql , 18 sycl::half2 ** x_dm , 19int ** x_qh , 20int ** x_sc ); 21typedef void (* load_tiles_sycl_t )( 22const void * __restrict__vx , 23int * __restrict__x_ql , 24 sycl::half2 * __restrict__x_dm , 25int * __restrict__x_qh , 26int * __restrict__x_sc , 27const int & i_offset , 28const int & i_max , 29const int & k , 30const int & blocks_per_row ); 31typedef float (* vec_dot_q_mul_mat_sycl_t )( 32const int * __restrict__x_ql , 33const sycl::half2 * __restrict__x_dm , 34const int * __restrict__x_qh , 35const int * __restrict__x_sc , 36const int * __restrict__y_qs , 37const sycl::half2 * __restrict__y_ms , 38const int & i , 39const int & j , 40const int & k ); 41 42 43template < int mmq_y > 44static __dpct_inline__ void 45allocate_tiles_q4_0 (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 46int * tile_x_qs_q4_0 ,float * tile_x_d_q4_0 ) { 47 (void )x_qh ; (void )x_sc ; 48 49* x_ql = tile_x_qs_q4_0 ; 50* x_dm = (sycl::half2 * )tile_x_d_q4_0 ; 51} 52 53template < int mmq_y ,int nwarps ,bool need_check > 54static __dpct_inline__ void 55load_tiles_q4_0 (const void * __restrict__vx ,int * __restrict__x_ql , 56 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 57int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 58const int & k ,const int & blocks_per_row ) { 59 (void )x_qh ; (void )x_sc ; 60GGML_SYCL_ASSUME (i_offset >=0 ); 61GGML_SYCL_ASSUME (i_offset < nwarps ); 62GGML_SYCL_ASSUME (k >=0 ); 63GGML_SYCL_ASSUME (k < WARP_SIZE ); 64 65const int kbx = k /QI4_0 ; 66const int kqsx = k %QI4_0 ; 67 68const block_q4_0 * bx0 = (const block_q4_0 * )vx ; 69 70float * x_dmf = (float * )x_dm ; 71 72#pragma unroll 73for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 74int i = i0 + i_offset ; 75 76if (need_check ) { 77i = sycl::min (i ,i_max ); 78 } 79 80const block_q4_0 * bxi = bx0 + i * blocks_per_row + kbx ; 81 82x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_uint8 (bxi -> qs ,kqsx ); 83// x_dmf[i * (WARP_SIZE/QI4_0) + i / QI4_0 + kbx] = bxi->d; 84 } 85 86const int blocks_per_tile_x_row = WARP_SIZE /QI4_0 ; 87const int kbxd = k %blocks_per_tile_x_row ; 88 89#pragma unroll 90for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI4_0 ) { 91int i = i0 + i_offset * QI4_0 + k /blocks_per_tile_x_row ; 92 93if (need_check ) { 94i = sycl::min (i ,i_max ); 95 } 96 97const block_q4_0 * bxi = bx0 + i * blocks_per_row + kbxd ; 98 99x_dmf [i * (WARP_SIZE /QI4_0 )+ i /QI4_0 + kbxd ]= bxi -> d ; 100 } 101} 102 103static __dpct_inline__ float vec_dot_q4_0_q8_1_mul_mat ( 104const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 105const int * __restrict__x_qh ,const int * __restrict__x_sc , 106const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 107const int & i ,const int & j ,const int & k ) { 108 (void )x_qh ; (void )x_sc ; 109 110const int kyqs = k % (QI8_1 /2 )+ QI8_1 * (k / (QI8_1 /2 )); 111const float * x_dmf = (const float * )x_dm ; 112 113int u [2 * VDR_Q4_0_Q8_1_MMQ ]; 114 115#pragma unroll 116for (int l = 0 ;l < VDR_Q4_0_Q8_1_MMQ ;++ l ) { 117u [2 * l + 0 ]= y_qs [j * WARP_SIZE + (kyqs + l ) %WARP_SIZE ]; 118u [2 * l + 1 ]= y_qs [j * WARP_SIZE + (kyqs + l + QI4_0 ) %WARP_SIZE ]; 119 } 120 121return vec_dot_q4_0_q8_1_impl < VDR_Q4_0_Q8_1_MMQ > 122 (& x_ql [i * (WARP_SIZE + 1 )+ k ],u ,x_dmf [i * (WARP_SIZE /QI4_0 )+ i /QI4_0 + k /QI4_0 ], 123y_ds [j * (WARP_SIZE /QI8_1 )+ (2 * k /QI8_1 ) % (WARP_SIZE /QI8_1 )]); 124} 125 126template < int mmq_y > 127static __dpct_inline__ void 128allocate_tiles_q4_1 (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 129int * tile_x_qs_q4_1 , sycl::half2 * tile_x_dm_q4_1 ) { 130 (void )x_qh ; (void )x_sc ; 131 132* x_ql = tile_x_qs_q4_1 ; 133* x_dm = tile_x_dm_q4_1 ; 134} 135 136 137template < int mmq_y ,int nwarps ,bool need_check > 138static __dpct_inline__ void 139load_tiles_q4_1 (const void * __restrict__vx ,int * __restrict__x_ql , 140 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 141int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 142const int & k ,const int & blocks_per_row ) { 143 (void )x_qh ; (void )x_sc ; 144 145GGML_SYCL_ASSUME (i_offset >=0 ); 146GGML_SYCL_ASSUME (i_offset < nwarps ); 147GGML_SYCL_ASSUME (k >=0 ); 148GGML_SYCL_ASSUME (k < WARP_SIZE ); 149 150const int kbx = k /QI4_1 ; 151const int kqsx = k %QI4_1 ; 152 153const block_q4_1 * bx0 = (const block_q4_1 * )vx ; 154 155#pragma unroll 156for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 157int i = i0 + i_offset ; 158 159if (need_check ) { 160i = sycl::min (i ,i_max ); 161 } 162 163const block_q4_1 * bxi = bx0 + i * blocks_per_row + kbx ; 164 165x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_uint8_aligned (bxi -> qs ,kqsx ); 166 } 167 168const int blocks_per_tile_x_row = WARP_SIZE /QI4_1 ; 169const int kbxd = k %blocks_per_tile_x_row ; 170 171#pragma unroll 172for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI4_1 ) { 173int i = i0 + i_offset * QI4_1 + k /blocks_per_tile_x_row ; 174 175if (need_check ) { 176i = sycl::min (i ,i_max ); 177 } 178 179const block_q4_1 * bxi = bx0 + i * blocks_per_row + kbxd ; 180 181x_dm [i * (WARP_SIZE /QI4_1 )+ i /QI4_1 + kbxd ]= bxi -> dm ; 182 } 183} 184 185static __dpct_inline__ float vec_dot_q4_1_q8_1_mul_mat ( 186const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 187const int * __restrict__x_qh ,const int * __restrict__x_sc , 188const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 189const int & i ,const int & j ,const int & k ) { 190 (void )x_qh ; (void )x_sc ; 191 192const int kyqs = k % (QI8_1 /2 )+ QI8_1 * (k / (QI8_1 /2 )); 193 194int u [2 * VDR_Q4_1_Q8_1_MMQ ]; 195 196#pragma unroll 197for (int l = 0 ;l < VDR_Q4_1_Q8_1_MMQ ;++ l ) { 198u [2 * l + 0 ]= y_qs [j * WARP_SIZE + (kyqs + l ) %WARP_SIZE ]; 199u [2 * l + 1 ]= y_qs [j * WARP_SIZE + (kyqs + l + QI4_1 ) %WARP_SIZE ]; 200 } 201 202return vec_dot_q4_1_q8_1_impl < VDR_Q4_1_Q8_1_MMQ > 203 (& x_ql [i * (WARP_SIZE + 1 )+ k ],u ,x_dm [i * (WARP_SIZE /QI4_1 )+ i /QI4_1 + k /QI4_1 ], 204y_ds [j * (WARP_SIZE /QI8_1 )+ (2 * k /QI8_1 ) % (WARP_SIZE /QI8_1 )]); 205} 206 207template < int mmq_y > 208static __dpct_inline__ void 209allocate_tiles_q5_0 (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 210int * tile_x_ql_q5_0 ,float * tile_x_d_q5_0 ) { 211 (void )x_qh ; (void )x_sc ; 212 213* x_ql = tile_x_ql_q5_0 ; 214* x_dm = (sycl::half2 * )tile_x_d_q5_0 ; 215} 216 217template < int mmq_y ,int nwarps ,bool need_check > 218static __dpct_inline__ void 219load_tiles_q5_0 (const void * __restrict__vx ,int * __restrict__x_ql , 220 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 221int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 222const int & k ,const int & blocks_per_row ) { 223 (void )x_qh ; (void )x_sc ; 224 225GGML_SYCL_ASSUME (i_offset >=0 ); 226GGML_SYCL_ASSUME (i_offset < nwarps ); 227GGML_SYCL_ASSUME (k >=0 ); 228GGML_SYCL_ASSUME (k < WARP_SIZE ); 229 230const int kbx = k /QI5_0 ; 231const int kqsx = k %QI5_0 ; 232 233const block_q5_0 * bx0 = (const block_q5_0 * )vx ; 234 235#pragma unroll 236for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 237int i = i0 + i_offset ; 238 239if (need_check ) { 240i = sycl::min (i ,i_max ); 241 } 242 243const block_q5_0 * bxi = bx0 + i * blocks_per_row + kbx ; 244 245const int ql = get_int_from_uint8 (bxi -> qs ,kqsx ); 246const int qh = get_int_from_uint8 (bxi -> qh ,0 ) >> (4 * (k %QI5_0 )); 247 248int qs0 = (ql >>0 )& 0x0F0F0F0F ; 249qs0 |= (qh <<4 )& 0x00000010 ;// 0 -> 4 250qs0 |= (qh <<11 )& 0x00001000 ;// 1 -> 12 251qs0 |= (qh <<18 )& 0x00100000 ;// 2 -> 20 252qs0 |= (qh <<25 )& 0x10000000 ;// 3 -> 28 253qs0 = dpct::vectorized_binary < sycl::char4 > ( 254qs0 ,0x10101010 , dpct::sub_sat ());// subtract 16 255 256x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k + 0 ]= qs0 ; 257 258int qs1 = (ql >>4 )& 0x0F0F0F0F ; 259qs1 |= (qh >>12 )& 0x00000010 ;// 16 -> 4 260qs1 |= (qh >>5 )& 0x00001000 ;// 17 -> 12 261qs1 |= (qh <<2 )& 0x00100000 ;// 18 -> 20 262qs1 |= (qh <<9 )& 0x10000000 ;// 19 -> 28 263qs1 = dpct::vectorized_binary < sycl::char4 > ( 264qs1 ,0x10101010 , dpct::sub_sat ());// subtract 16 265 266x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k + 1 ]= qs1 ; 267 } 268 269const int blocks_per_tile_x_row = WARP_SIZE /QI5_0 ; 270const int kbxd = k %blocks_per_tile_x_row ; 271float * x_dmf = (float * )x_dm ; 272 273#pragma unroll 274for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI5_0 ) { 275int i = i0 + i_offset * QI5_0 + k /blocks_per_tile_x_row ; 276 277if (need_check ) { 278i = sycl::min (i ,i_max ); 279 } 280 281const block_q5_0 * bxi = bx0 + i * blocks_per_row + kbxd ; 282 283x_dmf [i * (WARP_SIZE /QI5_0 )+ i /QI5_0 + kbxd ]= bxi -> d ; 284 } 285} 286 287static __dpct_inline__ float vec_dot_q5_0_q8_1_mul_mat ( 288const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 289const int * __restrict__x_qh ,const int * __restrict__x_sc , 290const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 291const int & i ,const int & j ,const int & k ) { 292 (void )x_qh ; (void )x_sc ; 293 294const int kyqs = k % (QI8_1 /2 )+ QI8_1 * (k / (QI8_1 /2 )); 295const int index_bx = i * (WARP_SIZE /QI5_0 )+ i /QI5_0 + k /QI5_0 ; 296const float * x_dmf = (const float * )x_dm ; 297const float * y_df = (const float * )y_ds ; 298 299int u [2 * VDR_Q5_0_Q8_1_MMQ ]; 300 301#pragma unroll 302for (int l = 0 ;l < VDR_Q5_0_Q8_1_MMQ ;++ l ) { 303u [2 * l + 0 ]= y_qs [j * WARP_SIZE + (kyqs + l ) %WARP_SIZE ]; 304u [2 * l + 1 ]= y_qs [j * WARP_SIZE + (kyqs + l + QI5_0 ) %WARP_SIZE ]; 305 } 306 307return vec_dot_q8_0_q8_1_impl < QR5_0 * VDR_Q5_0_Q8_1_MMQ > 308 (& x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k ],u ,x_dmf [index_bx ],y_df [j * (WARP_SIZE /QI8_1 )+ (2 * k /QI8_1 ) % (WARP_SIZE /QI8_1 )]); 309} 310 311template < int mmq_y > 312static __dpct_inline__ void 313allocate_tiles_q5_1 (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 314int * tile_x_ql_q5_1 , sycl::half2 * tile_x_dm_q5_1 ) { 315 (void )x_qh ; (void )x_sc ; 316 317* x_ql = tile_x_ql_q5_1 ; 318* x_dm = tile_x_dm_q5_1 ; 319} 320 321template < int mmq_y ,int nwarps ,bool need_check > 322static __dpct_inline__ void 323load_tiles_q5_1 (const void * __restrict__vx ,int * __restrict__x_ql , 324 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 325int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 326const int & k ,const int & blocks_per_row ) { 327 (void )x_qh ; (void )x_sc ; 328 329GGML_SYCL_ASSUME (i_offset >=0 ); 330GGML_SYCL_ASSUME (i_offset < nwarps ); 331GGML_SYCL_ASSUME (k >=0 ); 332GGML_SYCL_ASSUME (k < WARP_SIZE ); 333 334const int kbx = k /QI5_1 ; 335const int kqsx = k %QI5_1 ; 336 337const block_q5_1 * bx0 = (const block_q5_1 * )vx ; 338 339#pragma unroll 340for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 341int i = i0 + i_offset ; 342 343if (need_check ) { 344i = sycl::min (i ,i_max ); 345 } 346 347const block_q5_1 * bxi = bx0 + i * blocks_per_row + kbx ; 348 349const int ql = get_int_from_uint8_aligned (bxi -> qs ,kqsx ); 350const int qh = get_int_from_uint8_aligned (bxi -> qh ,0 ) >> (4 * (k %QI5_1 )); 351 352int qs0 = (ql >>0 )& 0x0F0F0F0F ; 353qs0 |= (qh <<4 )& 0x00000010 ;// 0 -> 4 354qs0 |= (qh <<11 )& 0x00001000 ;// 1 -> 12 355qs0 |= (qh <<18 )& 0x00100000 ;// 2 -> 20 356qs0 |= (qh <<25 )& 0x10000000 ;// 3 -> 28 357 358x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k + 0 ]= qs0 ; 359 360int qs1 = (ql >>4 )& 0x0F0F0F0F ; 361qs1 |= (qh >>12 )& 0x00000010 ;// 16 -> 4 362qs1 |= (qh >>5 )& 0x00001000 ;// 17 -> 12 363qs1 |= (qh <<2 )& 0x00100000 ;// 18 -> 20 364qs1 |= (qh <<9 )& 0x10000000 ;// 19 -> 28 365 366x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k + 1 ]= qs1 ; 367 } 368 369const int blocks_per_tile_x_row = WARP_SIZE /QI5_1 ; 370const int kbxd = k %blocks_per_tile_x_row ; 371 372#pragma unroll 373for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI5_1 ) { 374int i = i0 + i_offset * QI5_1 + k /blocks_per_tile_x_row ; 375 376if (need_check ) { 377i = sycl::min (i ,i_max ); 378 } 379 380const block_q5_1 * bxi = bx0 + i * blocks_per_row + kbxd ; 381 382x_dm [i * (WARP_SIZE /QI5_1 )+ i /QI5_1 + kbxd ]= bxi -> dm ; 383 } 384} 385 386static __dpct_inline__ float vec_dot_q5_1_q8_1_mul_mat ( 387const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 388const int * __restrict__x_qh ,const int * __restrict__x_sc , 389const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 390const int & i ,const int & j ,const int & k ) { 391 (void )x_qh ; (void )x_sc ; 392 393const int kyqs = k % (QI8_1 /2 )+ QI8_1 * (k / (QI8_1 /2 )); 394const int index_bx = i * (WARP_SIZE /QI5_1 )+ + i /QI5_1 + k /QI5_1 ; 395 396int u [2 * VDR_Q5_1_Q8_1_MMQ ]; 397 398#pragma unroll 399for (int l = 0 ;l < VDR_Q5_1_Q8_1_MMQ ;++ l ) { 400u [2 * l + 0 ]= y_qs [j * WARP_SIZE + (kyqs + l ) %WARP_SIZE ]; 401u [2 * l + 1 ]= y_qs [j * WARP_SIZE + (kyqs + l + QI5_1 ) %WARP_SIZE ]; 402 } 403 404return vec_dot_q8_1_q8_1_impl < QR5_1 * VDR_Q5_1_Q8_1_MMQ > 405 (& x_ql [i * (2 * WARP_SIZE + 1 )+ 2 * k ],u ,x_dm [index_bx ],y_ds [j * (WARP_SIZE /QI8_1 )+ (2 * k /QI8_1 ) % (WARP_SIZE /QI8_1 )]); 406} 407 408template < int mmq_y > 409static __dpct_inline__ void 410allocate_tiles_q8_0 (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 411int * tile_x_qs_q8_0 ,float * tile_x_d_q8_0 ) { 412 (void )x_qh ; (void )x_sc ; 413 414* x_ql = tile_x_qs_q8_0 ; 415* x_dm = (sycl::half2 * )tile_x_d_q8_0 ; 416} 417 418template < int mmq_y ,int nwarps ,bool need_check > 419static __dpct_inline__ void 420load_tiles_q8_0 (const void * __restrict__vx ,int * __restrict__x_ql , 421 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 422int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 423const int & k ,const int & blocks_per_row ) { 424 (void )x_qh ; (void )x_sc ; 425 426GGML_SYCL_ASSUME (i_offset >=0 ); 427GGML_SYCL_ASSUME (i_offset < nwarps ); 428GGML_SYCL_ASSUME (k >=0 ); 429GGML_SYCL_ASSUME (k < WARP_SIZE ); 430 431const int kbx = k /QI8_0 ; 432const int kqsx = k %QI8_0 ; 433float * x_dmf = (float * )x_dm ; 434 435const block_q8_0 * bx0 = (const block_q8_0 * )vx ; 436 437#pragma unroll 438for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 439int i = i0 + i_offset ; 440 441if (need_check ) { 442i = sycl::min (i ,i_max ); 443 } 444 445const block_q8_0 * bxi = bx0 + i * blocks_per_row + kbx ; 446 447x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_int8 (bxi -> qs ,kqsx ); 448 } 449 450const int blocks_per_tile_x_row = WARP_SIZE /QI8_0 ; 451const int kbxd = k %blocks_per_tile_x_row ; 452 453#pragma unroll 454for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI8_0 ) { 455int i = i0 + i_offset * QI8_0 + k /blocks_per_tile_x_row ; 456 457if (need_check ) { 458i = sycl::min (i ,i_max ); 459 } 460 461const block_q8_0 * bxi = bx0 + i * blocks_per_row + kbxd ; 462 463x_dmf [i * (WARP_SIZE /QI8_0 )+ i /QI8_0 + kbxd ]= bxi -> d ; 464 } 465} 466 467static __dpct_inline__ float vec_dot_q8_0_q8_1_mul_mat ( 468const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 469const int * __restrict__x_qh ,const int * __restrict__x_sc , 470const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 471const int & i ,const int & j ,const int & k ) { 472 (void )x_qh ; (void )x_sc ; 473 474const float * x_dmf = (const float * )x_dm ; 475const float * y_df = (const float * )y_ds ; 476 477return vec_dot_q8_0_q8_1_impl < VDR_Q8_0_Q8_1_MMQ > 478 (& x_ql [i * (WARP_SIZE + 1 )+ k ],& y_qs [j * WARP_SIZE + k ],x_dmf [i * (WARP_SIZE /QI8_0 )+ i /QI8_0 + k /QI8_0 ], 479y_df [j * (WARP_SIZE /QI8_1 )+ k /QI8_1 ]); 480} 481 482template < int mmq_y > 483static __dpct_inline__ void 484allocate_tiles_q2_K (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 485int * tile_x_ql_q2_K , sycl::half2 * tile_x_dm_q2_K , 486int * tile_x_sc_q2_K ) { 487 (void )x_qh ; 488 489* x_ql = tile_x_ql_q2_K ; 490* x_dm = tile_x_dm_q2_K ; 491* x_sc = tile_x_sc_q2_K ; 492} 493 494template < int mmq_y ,int nwarps ,bool need_check > 495static __dpct_inline__ void 496load_tiles_q2_K (const void * __restrict__vx ,int * __restrict__x_ql , 497 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 498int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 499const int & k ,const int & blocks_per_row ) { 500 (void )x_qh ; 501 502GGML_SYCL_ASSUME (i_offset >=0 ); 503GGML_SYCL_ASSUME (i_offset < nwarps ); 504GGML_SYCL_ASSUME (k >=0 ); 505GGML_SYCL_ASSUME (k < WARP_SIZE ); 506 507const int kbx = k /QI2_K ; 508const int kqsx = k %QI2_K ; 509 510const block_q2_K * bx0 = (const block_q2_K * )vx ; 511 512#pragma unroll 513for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 514int i = i0 + i_offset ; 515 516if (need_check ) { 517i = sycl::min (i ,i_max ); 518 } 519 520const block_q2_K * bxi = bx0 + i * blocks_per_row + kbx ; 521 522x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_uint8_aligned (bxi -> qs ,kqsx ); 523 } 524 525const int blocks_per_tile_x_row = WARP_SIZE /QI2_K ; 526const int kbxd = k %blocks_per_tile_x_row ; 527 528#pragma unroll 529for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI2_K ) { 530int i = (i0 + i_offset * QI2_K + k /blocks_per_tile_x_row ) %mmq_y ; 531 532if (need_check ) { 533i = sycl::min (i ,i_max ); 534 } 535 536const block_q2_K * bxi = bx0 + i * blocks_per_row + kbxd ; 537 538x_dm [i * (WARP_SIZE /QI2_K )+ i /QI2_K + kbxd ]= bxi -> dm ; 539 } 540 541#pragma unroll 542for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 4 ) { 543int i = i0 + i_offset * 4 + k / (WARP_SIZE /4 ); 544 545if (need_check ) { 546i = sycl::min (i ,i_max ); 547 } 548 549const block_q2_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /4 )) / (QI2_K /4 ); 550 551x_sc [i * (WARP_SIZE /4 )+ i /4 + k % (WARP_SIZE /4 )]= get_int_from_uint8_aligned (bxi -> scales ,k % (QI2_K /4 )); 552 } 553} 554 555#define VDR_Q2_K_Q8_1_MMQ 2 556// contiguous u/y values 557static __dpct_inline__ float 558vec_dot_q2_K_q8_1_impl_mmq (const int * __restrict__v ,const int * __restrict__u , 559const uint8_t * __restrict__scales , 560const sycl::half2 & dm2 ,const float & d8 ) { 561 562int sumi_d = 0 ; 563int sumi_m = 0 ; 564 565#pragma unroll 566for (int i0 = 0 ;i0 < QI8_1 ;i0 += QI8_1 /2 ) { 567int sumi_d_sc = 0 ; 568 569const int sc = scales [i0 / (QI8_1 /2 )]; 570 571// fill int with 4x m 572int m = sc >>4 ; 573m |=m <<8 ; 574m |=m <<16 ; 575 576#pragma unroll 577for (int i = i0 ;i < i0 + QI8_1 /2 ;++ i ) { 578sumi_d_sc = dpct::dp4a (v [i ],u [i ],sumi_d_sc );// SIMD dot product 579sumi_m = dpct::dp4a (m ,u [i ], 580sumi_m );// multiply sum of q8_1 values with m 581 } 582 583sumi_d += sumi_d_sc * (sc & 0xF ); 584 } 585 586const sycl::float2 dm2f = 587dm2 .convert < float , sycl::rounding_mode::automatic > (); 588 589return d8 * (dm2f .x ()* sumi_d - dm2f .y ()* sumi_m ); 590} 591 592static __dpct_inline__ float vec_dot_q2_K_q8_1_mul_mat ( 593const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 594const int * __restrict__x_qh ,const int * __restrict__x_sc , 595const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 596const int & i ,const int & j ,const int & k ) { 597 (void )x_qh ; 598 599const int kbx = k /QI2_K ; 600const int ky = (k %QI2_K )* QR2_K ; 601const float * y_df = (const float * )y_ds ; 602 603int v [QR2_K * VDR_Q2_K_Q8_1_MMQ ]; 604 605const int kqsx = i * (WARP_SIZE + 1 )+ kbx * QI2_K + (QI2_K /2 )* (ky /(2 * QI2_K ))+ ky % (QI2_K /2 ); 606const int shift = 2 * ((ky % (2 * QI2_K )) / (QI2_K /2 )); 607 608#pragma unroll 609for (int l = 0 ;l < QR2_K * VDR_Q2_K_Q8_1_MMQ ;++ l ) { 610v [l ]= (x_ql [kqsx + l ] >>shift )& 0x03030303 ; 611 } 612 613const uint8_t * scales = ((const uint8_t * )& x_sc [i * (WARP_SIZE /4 )+ i /4 + kbx * 4 ])+ ky /4 ; 614 615const int index_y = j * WARP_SIZE + (QR2_K * k ) %WARP_SIZE ; 616return vec_dot_q2_K_q8_1_impl_mmq (v ,& y_qs [index_y ],scales ,x_dm [i * (WARP_SIZE /QI2_K )+ i /QI2_K + kbx ],y_df [index_y /QI8_1 ]); 617} 618 619template < int mmq_y > 620static __dpct_inline__ void 621allocate_tiles_q3_K (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 622int * tile_x_ql_q3_K , sycl::half2 * tile_x_dm_q3_K , 623int * tile_x_qh_q3_K ,int * tile_x_sc_q3_K ) { 624 625* x_ql = tile_x_ql_q3_K ; 626* x_dm = tile_x_dm_q3_K ; 627* x_qh = tile_x_qh_q3_K ; 628* x_sc = tile_x_sc_q3_K ; 629} 630 631template < int mmq_y ,int nwarps ,bool need_check > 632static __dpct_inline__ void 633load_tiles_q3_K (const void * __restrict__vx ,int * __restrict__x_ql , 634 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 635int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 636const int & k ,const int & blocks_per_row ) { 637 638GGML_SYCL_ASSUME (i_offset >=0 ); 639GGML_SYCL_ASSUME (i_offset < nwarps ); 640GGML_SYCL_ASSUME (k >=0 ); 641GGML_SYCL_ASSUME (k < WARP_SIZE ); 642 643const int kbx = k /QI3_K ; 644const int kqsx = k %QI3_K ; 645 646const block_q3_K * bx0 = (const block_q3_K * )vx ; 647 648#pragma unroll 649for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 650int i = i0 + i_offset ; 651 652if (need_check ) { 653i = sycl::min (i ,i_max ); 654 } 655 656const block_q3_K * bxi = bx0 + i * blocks_per_row + kbx ; 657 658x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_uint8 (bxi -> qs ,kqsx ); 659 } 660 661const int blocks_per_tile_x_row = WARP_SIZE /QI3_K ; 662const int kbxd = k %blocks_per_tile_x_row ; 663float * x_dmf = (float * )x_dm ; 664 665#pragma unroll 666for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI3_K ) { 667int i = (i0 + i_offset * QI3_K + k /blocks_per_tile_x_row ) %mmq_y ; 668 669if (need_check ) { 670i = sycl::min (i ,i_max ); 671 } 672 673const block_q3_K * bxi = bx0 + i * blocks_per_row + kbxd ; 674 675x_dmf [i * (WARP_SIZE /QI3_K )+ i /QI3_K + kbxd ]= bxi -> d ; 676 } 677 678#pragma unroll 679for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 2 ) { 680int i = i0 + i_offset * 2 + k / (WARP_SIZE /2 ); 681 682if (need_check ) { 683i = sycl::min (i ,i_max ); 684 } 685 686const block_q3_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /2 )) / (QI3_K /2 ); 687 688// invert the mask with ~ so that a 0/1 results in 4/0 being subtracted 689x_qh [i * (WARP_SIZE /2 )+ i /2 + k % (WARP_SIZE /2 )]= ~get_int_from_uint8 (bxi -> hmask ,k % (QI3_K /2 )); 690 } 691 692#pragma unroll 693for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 4 ) { 694int i = i0 + i_offset * 4 + k / (WARP_SIZE /4 ); 695 696if (need_check ) { 697i = sycl::min (i ,i_max ); 698 } 699 700const block_q3_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /4 )) / (QI3_K /4 ); 701 702const int ksc = k % (QI3_K /4 ); 703 704const int ksc_low = ksc % (QI3_K /8 ); 705const int shift_low = 4 * (ksc / (QI3_K /8 )); 706const int sc_low = (get_int_from_uint8 (bxi -> scales ,ksc_low ) >>shift_low )& 0x0F0F0F0F ; 707 708const int ksc_high = QI3_K /8 ; 709const int shift_high = 2 * ksc ; 710const int sc_high = ((get_int_from_uint8 (bxi -> scales ,ksc_high ) >>shift_high ) <<4 )& 0x30303030 ; 711 712const int sc = dpct::vectorized_binary < sycl::char4 > ( 713sc_low |sc_high ,0x20202020 , dpct::sub_sat ()); 714 715x_sc [i * (WARP_SIZE /4 )+ i /4 + k % (WARP_SIZE /4 )]= sc ; 716 } 717} 718 719#define VDR_Q3_K_Q8_1_MMQ 2 720// contiguous u/y values 721static __dpct_inline__ float 722vec_dot_q3_K_q8_1_impl_mmq (const int * __restrict__v ,const int * __restrict__u , 723const int8_t * __restrict__scales ,const float & d3 , 724const float & d8 ) { 725 726int sumi = 0 ; 727 728#pragma unroll 729for (int i0 = 0 ;i0 < QR3_K * VDR_Q3_K_Q8_1_MMQ ;i0 += QI8_1 /2 ) { 730int sumi_sc = 0 ; 731 732for (int i = i0 ;i < i0 + QI8_1 /2 ;++ i ) { 733sumi_sc = dpct::dp4a (v [i ],u [i ],sumi_sc );// SIMD dot product 734 } 735 736sumi += sumi_sc * scales [i0 / (QI8_1 /2 )]; 737 } 738 739return d3 * d8 * sumi ; 740} 741 742static __dpct_inline__ float vec_dot_q3_K_q8_1_mul_mat ( 743const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 744const int * __restrict__x_qh ,const int * __restrict__x_sc , 745const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 746const int & i ,const int & j ,const int & k ) { 747 748const int kbx = k /QI3_K ; 749const int ky = (k %QI3_K )* QR3_K ; 750const float * x_dmf = (const float * )x_dm ; 751const float * y_df = (const float * )y_ds ; 752 753const int8_t * scales = ((const int8_t * ) (x_sc + i * (WARP_SIZE /4 )+ i /4 + kbx * 4 ))+ ky /4 ; 754 755int v [QR3_K * VDR_Q3_K_Q8_1_MMQ ]; 756 757#pragma unroll 758for (int l = 0 ;l < QR3_K * VDR_Q3_K_Q8_1_MMQ ;++ l ) { 759const int kqsx = i * (WARP_SIZE + 1 )+ kbx * QI3_K + (QI3_K /2 )* (ky /(2 * QI3_K ))+ ky % (QI3_K /2 ); 760const int shift = 2 * ((ky %32 ) /8 ); 761const int vll = (x_ql [kqsx + l ] >>shift )& 0x03030303 ; 762 763const int vh = x_qh [i * (WARP_SIZE /2 )+ i /2 + kbx * (QI3_K /2 )+ (ky + l )%8 ] >> ((ky + l ) /8 ); 764const int vlh = (vh <<2 )& 0x04040404 ; 765 766v [l ]= dpct::vectorized_binary < sycl::char4 > (vll ,vlh , dpct::sub_sat ()); 767 } 768 769const int index_y = j * WARP_SIZE + (k * QR3_K ) %WARP_SIZE ; 770return vec_dot_q3_K_q8_1_impl_mmq (v ,& y_qs [index_y ],scales ,x_dmf [i * (WARP_SIZE /QI3_K )+ i /QI3_K + kbx ],y_df [index_y /QI8_1 ]); 771} 772 773template < int mmq_y > 774static __dpct_inline__ void 775allocate_tiles_q4_K (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 776int * tile_x_ql_q4_K , sycl::half2 * tile_x_dm_q4_K , 777int * tile_x_sc_q4_K ) { 778 (void )x_qh ; 779 780* x_ql = tile_x_ql_q4_K ; 781* x_dm = tile_x_dm_q4_K ; 782* x_sc = tile_x_sc_q4_K ; 783} 784 785template < int mmq_y ,int nwarps ,bool need_check > 786static __dpct_inline__ void 787load_tiles_q4_K (const void * __restrict__vx ,int * __restrict__x_ql , 788 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 789int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 790const int & k ,const int & blocks_per_row ) { 791 (void )x_qh ; 792 793GGML_SYCL_ASSUME (i_offset >=0 ); 794GGML_SYCL_ASSUME (i_offset < nwarps ); 795GGML_SYCL_ASSUME (k >=0 ); 796GGML_SYCL_ASSUME (k < WARP_SIZE ); 797 798const int kbx = k /QI4_K ;// == 0 if QK_K == 256 799const int kqsx = k %QI4_K ;// == k if QK_K == 256 800 801const block_q4_K * bx0 = (const block_q4_K * )vx ; 802 803#pragma unroll 804for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 805int i = i0 + i_offset ; 806 807if (need_check ) { 808i = sycl::min (i ,i_max ); 809 } 810 811const block_q4_K * bxi = bx0 + i * blocks_per_row + kbx ; 812 813x_ql [i * (WARP_SIZE + 1 )+ k ]= get_int_from_uint8_aligned (bxi -> qs ,kqsx ); 814 } 815 816constexpr int blocks_per_tile_x_row = QI4_K > WARP_SIZE ?1 :WARP_SIZE /QI4_K ;// == 1 if QK_K == 256 817const int kbxd = k %blocks_per_tile_x_row ;// == 0 if QK_K == 256 818 819#pragma unroll 820for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI4_K ) { 821int i = (i0 + i_offset * QI4_K + k /blocks_per_tile_x_row ) %mmq_y ; 822 823if (need_check ) { 824i = sycl::min (i ,i_max ); 825 } 826 827const block_q4_K * bxi = bx0 + i * blocks_per_row + kbxd ; 828 829#if QK_K == 256 830x_dm [i * (WARP_SIZE /QI4_K )+ i /QI4_K + kbxd ]= bxi -> dm ; 831#else 832x_dm [i * (WARP_SIZE /QI4_K )+ i /QI4_K + kbxd ]= {bxi -> dm [0 ],bxi -> dm [1 ]}; 833#endif 834 } 835 836#pragma unroll 837for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 8 ) { 838int i = (i0 + i_offset * 8 + k / (WARP_SIZE /8 )) %mmq_y ; 839 840if (need_check ) { 841i = sycl::min (i ,i_max ); 842 } 843 844const block_q4_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /8 )) / (QI4_K /8 ); 845 846const int * scales = (const int * )bxi -> scales ; 847 848const int ksc = k % (WARP_SIZE /8 ); 849 850// scale arrangement after the following two lines: sc0,...,sc3, sc4,...,sc7, m0,...,m3, m4,...,m8 851int scales8 = (scales [(ksc %2 )+ (ksc != 0 )] >> (4 * (ksc & (ksc /2 ))))& 0x0F0F0F0F ;// lower 4 bits 852scales8 |= (scales [ksc /2 ] >> (2 * (ksc %2 )))& 0x30303030 ;// upper 2 bits 853 854x_sc [i * (WARP_SIZE /8 )+ i /8 + ksc ]= scales8 ; 855 } 856} 857 858 859#define VDR_Q4_K_Q8_1_MMQ 8 860 861// contiguous u/y values 862static __dpct_inline__ float vec_dot_q4_K_q8_1_impl_mmq ( 863const int * __restrict__v ,const int * __restrict__u , 864const uint8_t * __restrict__sc ,const uint8_t * __restrict__m , 865const sycl::half2 & dm4 ,const sycl::half2 * __restrict__ds8 ) { 866 867float sumf_d = 0.0f ; 868float sumf_m = 0.0f ; 869 870#pragma unroll 871for (int i = 0 ;i < QR4_K * VDR_Q4_K_Q8_1_MMQ /QI8_1 ;++ i ) { 872int sumi_d = 0 ; 873 874#pragma unroll 875for (int j = 0 ;j < QI8_1 ;++ j ) { 876sumi_d = dpct::dp4a ((v [j ] >> (4 * i ))& 0x0F0F0F0F , 877u [i * QI8_1 + j ],sumi_d );// SIMD dot product 878 } 879 880const sycl::float2 ds8f = 881ds8 [i ].convert < float , sycl::rounding_mode::automatic > (); 882 883sumf_d += ds8f .x ()* (sc [i ]* sumi_d ); 884sumf_m += ds8f .y ()* m [i ];// sum of q8_1 block * q4_K min val 885 } 886 887const sycl::float2 dm4f = 888dm4 .convert < float , sycl::rounding_mode::automatic > (); 889 890return dm4f .x ()* sumf_d - dm4f .y ()* sumf_m ; 891} 892 893 894static __dpct_inline__ float vec_dot_q4_K_q8_1_mul_mat ( 895const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 896const int * __restrict__x_qh ,const int * __restrict__x_sc , 897const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 898const int & i ,const int & j ,const int & k ) { 899 (void )x_qh ; 900 901const uint8_t * sc = ((const uint8_t * )& x_sc [i * (WARP_SIZE /8 )+ i /8 + k /16 ])+ 2 * ((k %16 ) /8 ); 902 903const int index_y = j * WARP_SIZE + (QR4_K * k ) %WARP_SIZE ; 904return vec_dot_q4_K_q8_1_impl_mmq (& x_ql [i * (WARP_SIZE + 1 )+ k ],& y_qs [index_y ],sc ,sc + 8 , 905x_dm [i * (WARP_SIZE /QI4_K )+ i /QI4_K ],& y_ds [index_y /QI8_1 ]); 906} 907 908template < int mmq_y > 909static __dpct_inline__ void 910allocate_tiles_q5_K (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 911int * tile_x_ql_q5_K , sycl::half2 * tile_x_dm_q5_K , 912int * tile_x_sc_q5_K ) { 913 (void )x_qh ; 914 915* x_ql = tile_x_ql_q5_K ; 916* x_dm = tile_x_dm_q5_K ; 917* x_sc = tile_x_sc_q5_K ; 918} 919 920template < int mmq_y ,int nwarps ,bool need_check > 921static __dpct_inline__ void 922load_tiles_q5_K (const void * __restrict__vx ,int * __restrict__x_ql , 923 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 924int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 925const int & k ,const int & blocks_per_row ) { 926 (void )x_qh ; 927 928GGML_SYCL_ASSUME (i_offset >=0 ); 929GGML_SYCL_ASSUME (i_offset < nwarps ); 930GGML_SYCL_ASSUME (k >=0 ); 931GGML_SYCL_ASSUME (k < WARP_SIZE ); 932 933const int kbx = k /QI5_K ;// == 0 if QK_K == 256 934const int kqsx = k %QI5_K ;// == k if QK_K == 256 935 936const block_q5_K * bx0 = (const block_q5_K * )vx ; 937 938#pragma unroll 939for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 940int i = i0 + i_offset ; 941 942if (need_check ) { 943i = sycl::min (i ,i_max ); 944 } 945 946const block_q5_K * bxi = bx0 + i * blocks_per_row + kbx ; 947const int ky = QR5_K * kqsx ; 948 949const int ql = get_int_from_uint8_aligned (bxi -> qs ,kqsx ); 950const int ql0 = (ql >>0 )& 0x0F0F0F0F ; 951const int ql1 = (ql >>4 )& 0x0F0F0F0F ; 952 953const int qh = get_int_from_uint8_aligned (bxi -> qh ,kqsx % (QI5_K /4 )); 954const int qh0 = ((qh >> (2 * (kqsx / (QI5_K /4 ))+ 0 )) <<4 )& 0x10101010 ; 955const int qh1 = ((qh >> (2 * (kqsx / (QI5_K /4 ))+ 1 )) <<4 )& 0x10101010 ; 956 957const int kq0 = ky - ky % (QI5_K /2 )+ k % (QI5_K /4 )+ 0 ; 958const int kq1 = ky - ky % (QI5_K /2 )+ k % (QI5_K /4 )+ (QI5_K /4 ); 959 960x_ql [i * (2 * WARP_SIZE + 1 )+ kq0 ]= ql0 |qh0 ; 961x_ql [i * (2 * WARP_SIZE + 1 )+ kq1 ]= ql1 |qh1 ; 962 } 963 964constexpr int blocks_per_tile_x_row = QI5_K > WARP_SIZE ?1 :WARP_SIZE /QI5_K ;// == 1 if QK_K == 256 965const int kbxd = k %blocks_per_tile_x_row ;// == 0 if QK_K == 256 966 967#pragma unroll 968for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI5_K ) { 969int i = (i0 + i_offset * QI5_K + k /blocks_per_tile_x_row ) %mmq_y ; 970 971if (need_check ) { 972i = sycl::min (i ,i_max ); 973 } 974 975const block_q5_K * bxi = bx0 + i * blocks_per_row + kbxd ; 976 977#if QK_K == 256 978x_dm [i * (WARP_SIZE /QI5_K )+ i /QI5_K + kbxd ]= bxi -> dm ; 979#endif 980 } 981 982#pragma unroll 983for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 8 ) { 984int i = (i0 + i_offset * 8 + k / (WARP_SIZE /8 )) %mmq_y ; 985 986if (need_check ) { 987i = sycl::min (i ,i_max ); 988 } 989 990const block_q5_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /8 )) / (QI5_K /8 ); 991 992const int * scales = (const int * )bxi -> scales ; 993 994const int ksc = k % (WARP_SIZE /8 ); 995 996// scale arrangement after the following two lines: sc0,...,sc3, sc4,...,sc7, m0,...,m3, m4,...,m8 997int scales8 = (scales [(ksc %2 )+ (ksc != 0 )] >> (4 * (ksc & (ksc /2 ))))& 0x0F0F0F0F ;// lower 4 bits 998scales8 |= (scales [ksc /2 ] >> (2 * (ksc %2 )))& 0x30303030 ;// upper 2 bits 999 1000x_sc [i * (WARP_SIZE /8 )+ i /8 + ksc ]= scales8 ; 1001 } 1002} 1003 1004#define VDR_Q5_K_Q8_1_MMQ 8 1005 1006// contiguous u/y values 1007static __dpct_inline__ float vec_dot_q5_K_q8_1_impl_mmq ( 1008const int * __restrict__v ,const int * __restrict__u , 1009const uint8_t * __restrict__sc ,const uint8_t * __restrict__m , 1010const sycl::half2 & dm4 ,const sycl::half2 * __restrict__ds8 ) { 1011 1012float sumf_d = 0.0f ; 1013float sumf_m = 0.0f ; 1014 1015#pragma unroll 1016for (int i = 0 ;i < QR5_K * VDR_Q5_K_Q8_1_MMQ /QI8_1 ;++ i ) { 1017int sumi_d = 0 ; 1018 1019#pragma unroll 1020for (int j = 0 ;j < QI8_1 ;++ j ) { 1021sumi_d = dpct::dp4a (v [i * QI8_1 + j ],u [i * QI8_1 + j ], 1022sumi_d );// SIMD dot product 1023 } 1024 1025const sycl::float2 ds8f = 1026ds8 [i ].convert < float , sycl::rounding_mode::automatic > (); 1027 1028sumf_d += ds8f .x ()* (sc [i ]* sumi_d ); 1029sumf_m += ds8f .y ()* m [i ];// sum of q8_1 block * q4_K min val 1030 } 1031 1032const sycl::float2 dm4f = 1033dm4 .convert < float , sycl::rounding_mode::automatic > (); 1034 1035return dm4f .x ()* sumf_d - dm4f .y ()* sumf_m ; 1036} 1037 1038static __dpct_inline__ float vec_dot_q5_K_q8_1_mul_mat ( 1039const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 1040const int * __restrict__x_qh ,const int * __restrict__x_sc , 1041const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 1042const int & i ,const int & j ,const int & k ) { 1043 (void )x_qh ; 1044 1045const uint8_t * sc = ((const uint8_t * )& x_sc [i * (WARP_SIZE /8 )+ i /8 + k /16 ])+ 2 * ((k %16 ) /8 ); 1046 1047const int index_x = i * (QR5_K * WARP_SIZE + 1 )+ QR5_K * k ; 1048const int index_y = j * WARP_SIZE + (QR5_K * k ) %WARP_SIZE ; 1049return vec_dot_q5_K_q8_1_impl_mmq (& x_ql [index_x ],& y_qs [index_y ],sc ,sc + 8 , 1050x_dm [i * (WARP_SIZE /QI5_K )+ i /QI5_K ],& y_ds [index_y /QI8_1 ]); 1051} 1052 1053template < int mmq_y > 1054static __dpct_inline__ void 1055allocate_tiles_q6_K (int ** x_ql , sycl::half2 ** x_dm ,int ** x_qh ,int ** x_sc , 1056int * tile_x_ql , sycl::half2 * tile_x_dm ,int * tile_x_sc ) { 1057 (void )x_qh ; 1058 1059* x_ql = tile_x_ql ; 1060* x_dm = tile_x_dm ; 1061* x_sc = tile_x_sc ; 1062} 1063 1064template < int mmq_y ,int nwarps ,bool need_check > 1065static __dpct_inline__ void 1066load_tiles_q6_K (const void * __restrict__vx ,int * __restrict__x_ql , 1067 sycl::half2 * __restrict__x_dm ,int * __restrict__x_qh , 1068int * __restrict__x_sc ,const int & i_offset ,const int & i_max , 1069const int & k ,const int & blocks_per_row ) { 1070 (void )x_qh ; 1071 1072GGML_SYCL_ASSUME (i_offset >=0 ); 1073GGML_SYCL_ASSUME (i_offset < nwarps ); 1074GGML_SYCL_ASSUME (k >=0 ); 1075GGML_SYCL_ASSUME (k < WARP_SIZE ); 1076 1077const int kbx = k /QI6_K ;// == 0 if QK_K == 256 1078const int kqsx = k %QI6_K ;// == k if QK_K == 256 1079 1080const block_q6_K * bx0 = (const block_q6_K * )vx ; 1081 1082#pragma unroll 1083for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps ) { 1084int i = i0 + i_offset ; 1085 1086if (need_check ) { 1087i = sycl::min (i ,i_max ); 1088 } 1089 1090const block_q6_K * bxi = bx0 + i * blocks_per_row + kbx ; 1091const int ky = QR6_K * kqsx ; 1092 1093const int ql = get_int_from_uint8 (bxi -> ql ,kqsx ); 1094const int ql0 = (ql >>0 )& 0x0F0F0F0F ; 1095const int ql1 = (ql >>4 )& 0x0F0F0F0F ; 1096 1097const int qh = get_int_from_uint8 (bxi -> qh , (QI6_K /4 )* (kqsx / (QI6_K /2 ))+ kqsx % (QI6_K /4 )); 1098const int qh0 = ((qh >> (2 * ((kqsx % (QI6_K /2 )) / (QI6_K /4 )))) <<4 )& 0x30303030 ; 1099const int qh1 = (qh >> (2 * ((kqsx % (QI6_K /2 )) / (QI6_K /4 ))))& 0x30303030 ; 1100 1101const int kq0 = ky - ky %QI6_K + k % (QI6_K /2 )+ 0 ; 1102const int kq1 = ky - ky %QI6_K + k % (QI6_K /2 )+ (QI6_K /2 ); 1103 1104x_ql [i * (2 * WARP_SIZE + 1 )+ kq0 ]= 1105 dpct::vectorized_binary < sycl::char4 > (ql0 |qh0 ,0x20202020 , 1106 dpct::sub_sat ()); 1107x_ql [i * (2 * WARP_SIZE + 1 )+ kq1 ]= 1108 dpct::vectorized_binary < sycl::char4 > (ql1 |qh1 ,0x20202020 , 1109 dpct::sub_sat ()); 1110 } 1111 1112constexpr int blocks_per_tile_x_row = QI6_K > WARP_SIZE ?1 :WARP_SIZE /QI6_K ;// == 1 if QK_K == 256 1113const int kbxd = k %blocks_per_tile_x_row ;// == 0 if QK_K == 256 1114float * x_dmf = (float * )x_dm ; 1115 1116#pragma unroll 1117for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * QI6_K ) { 1118int i = (i0 + i_offset * QI6_K + k /blocks_per_tile_x_row ) %mmq_y ; 1119 1120if (need_check ) { 1121i = sycl::min (i ,i_max ); 1122 } 1123 1124const block_q6_K * bxi = bx0 + i * blocks_per_row + kbxd ; 1125 1126x_dmf [i * (WARP_SIZE /QI6_K )+ i /QI6_K + kbxd ]= bxi -> d ; 1127 } 1128 1129#pragma unroll 1130for (int i0 = 0 ;i0 < mmq_y ;i0 += nwarps * 8 ) { 1131int i = (i0 + i_offset * 8 + k / (WARP_SIZE /8 )) %mmq_y ; 1132 1133if (need_check ) { 1134i = sycl::min (i ,i_max ); 1135 } 1136 1137const block_q6_K * bxi = bx0 + i * blocks_per_row + (k % (WARP_SIZE /8 )) /4 ; 1138 1139x_sc [i * (WARP_SIZE /8 )+ i /8 + k % (WARP_SIZE /8 )]= get_int_from_int8 (bxi -> scales ,k % (QI6_K /8 )); 1140 } 1141} 1142 1143#define VDR_Q6_K_Q8_1_MMQ 8 1144 1145// contiguous u/y values 1146static __dpct_inline__ float 1147vec_dot_q6_K_q8_1_impl_mmq (const int * __restrict__v ,const int * __restrict__u , 1148const int8_t * __restrict__sc ,const float & d6 , 1149const float * __restrict__d8 ) { 1150 1151float sumf_d = 0.0f ; 1152 1153#pragma unroll 1154for (int i0 = 0 ;i0 < VDR_Q6_K_Q8_1_MMQ ;i0 += 4 ) { 1155 sycl::int2 sumi_d = {0 ,0 };// 2 q6_K scales per q8_1 scale 1156 1157#pragma unroll 1158for (int i = i0 ;i < i0 + 2 ;++ i ) { 1159sumi_d .x ()= dpct::dp4a (v [2 * i + 0 ],u [2 * i + 0 ], 1160sumi_d .x ());// SIMD dot product 1161sumi_d .x ()= dpct::dp4a (v [2 * i + 1 ],u [2 * i + 1 ], 1162sumi_d .x ());// SIMD dot product 1163 1164sumi_d .y ()= dpct::dp4a (v [2 * i + 4 ],u [2 * i + 4 ], 1165sumi_d .y ());// SIMD dot product 1166sumi_d .y ()= dpct::dp4a (v [2 * i + 5 ],u [2 * i + 5 ], 1167sumi_d .y ());// SIMD dot product 1168 } 1169 1170sumf_d += d8 [i0 /4 ]* 1171 (sc [i0 /2 + 0 ]* sumi_d .x ()+ sc [i0 /2 + 1 ]* sumi_d .y ()); 1172 } 1173 1174return d6 * sumf_d ; 1175} 1176 1177static __dpct_inline__ float vec_dot_q6_K_q8_1_mul_mat ( 1178const int * __restrict__x_ql ,const sycl::half2 * __restrict__x_dm , 1179const int * __restrict__x_qh ,const int * __restrict__x_sc , 1180const int * __restrict__y_qs ,const sycl::half2 * __restrict__y_ds , 1181const int & i ,const int & j ,const int & k ) { 1182 (void )x_qh ; 1183 1184const float * x_dmf = (const float * )x_dm ; 1185const float * y_df = (const float * )y_ds ; 1186 1187const int8_t * sc = ((const int8_t * )& x_sc [i * (WARP_SIZE /8 )+ i /8 + k /8 ]); 1188 1189const int index_x = i * (QR6_K * WARP_SIZE + 1 )+ QR6_K * k ; 1190const int index_y = j * WARP_SIZE + (QR6_K * k ) %WARP_SIZE ; 1191return vec_dot_q6_K_q8_1_impl_mmq (& x_ql [index_x ],& y_qs [index_y ],sc ,x_dmf [i * (WARP_SIZE /QI6_K )+ i /QI6_K ],& y_df [index_y /QI8_1 ]); 1192} 1193 1194template < int qk ,int qr ,int qi ,bool need_sum ,typename block_q_t ,int mmq_x , 1195int mmq_y ,int nwarps ,load_tiles_sycl_t load_tiles ,int vdr , 1196vec_dot_q_mul_mat_sycl_t vec_dot > 1197/* 1198DPCT1110:8: The total declared local variable size in device function mul_mat_q 1199exceeds 128 bytes and may cause high register pressure. Consult with your 1200hardware vendor to find the total register size available and adjust the code, 1201or use smaller sub-group size to avoid high register pressure. 1202*/ 1203static __dpct_inline__ void 1204mul_mat_q (const void * __restrict__vx ,const void * __restrict__vy , 1205float * __restrict__dst ,const int ncols_x ,const int nrows_x , 1206const int ncols_y ,const int nrows_y ,const int nrows_dst , 1207int * tile_x_ql , sycl::half2 * tile_x_dm ,int * tile_x_qh , 1208int * tile_x_sc ,const sycl::nd_item < 3 > & item_ct1 ,int * tile_y_qs , 1209 sycl::half2 * tile_y_ds ) { 1210 1211const block_q_t * x = (const block_q_t * )vx ; 1212const block_q8_1 * y = (const block_q8_1 * )vy ; 1213 1214const int blocks_per_row_x = ncols_x /qk ; 1215const int blocks_per_col_y = nrows_y /QK8_1 ; 1216const int blocks_per_warp = WARP_SIZE /qi ; 1217 1218const int & ncols_dst = ncols_y ; 1219 1220const int row_dst_0 = item_ct1 .get_group (2 )* mmq_y ; 1221const int & row_x_0 = row_dst_0 ; 1222 1223const int col_dst_0 = item_ct1 .get_group (1 )* mmq_x ; 1224const int & col_y_0 = col_dst_0 ; 1225 1226float sum [mmq_y /WARP_SIZE ][mmq_x /nwarps ]= {{0.0f }}; 1227 1228for (int ib0 = 0 ;ib0 < blocks_per_row_x ;ib0 += blocks_per_warp ) { 1229 1230load_tiles (x + row_x_0 * blocks_per_row_x + ib0 ,tile_x_ql ,tile_x_dm , 1231tile_x_qh ,tile_x_sc ,item_ct1 .get_local_id (1 ), 1232nrows_x - row_x_0 - 1 ,item_ct1 .get_local_id (2 ), 1233blocks_per_row_x ); 1234 1235#pragma unroll 1236for (int ir = 0 ;ir < qr ;++ ir ) { 1237const int kqs = ir * WARP_SIZE + item_ct1 .get_local_id (2 ); 1238const int kbxd = kqs /QI8_1 ; 1239 1240#pragma unroll 1241for (int i = 0 ;i < mmq_x ;i += nwarps ) { 1242const int col_y_eff = dpct::min ( 1243 (unsigned int )(col_y_0 + item_ct1 .get_local_id (1 )+ i ), 1244ncols_y - 1 );// to prevent out-of-bounds memory accesses 1245 1246const block_q8_1 * by0 = & y [col_y_eff * blocks_per_col_y + ib0 * (qk /QK8_1 )+ kbxd ]; 1247 1248const int index_y = (item_ct1 .get_local_id (1 )+ i )* WARP_SIZE + 1249kqs %WARP_SIZE ; 1250tile_y_qs [index_y ]= get_int_from_int8_aligned ( 1251by0 -> qs ,item_ct1 .get_local_id (2 ) %QI8_1 ); 1252 } 1253 1254#pragma unroll 1255for (int ids0 = 0 ;ids0 < mmq_x ;ids0 += nwarps * QI8_1 ) { 1256const int ids = 1257 (ids0 + item_ct1 .get_local_id (1 )* QI8_1 + 1258item_ct1 .get_local_id (2 ) / (WARP_SIZE /QI8_1 )) % 1259mmq_x ; 1260const int kby = item_ct1 .get_local_id (2 ) % (WARP_SIZE /QI8_1 ); 1261const int col_y_eff = sycl::min (col_y_0 + ids ,ncols_y - 1 ); 1262 1263// if the sum is not needed it's faster to transform the scale to f32 ahead of time 1264const sycl::half2 * dsi_src = 1265& y [col_y_eff * blocks_per_col_y + ib0 * (qk /QK8_1 )+ 1266ir * (WARP_SIZE /QI8_1 )+ kby ] 1267 .ds ; 1268 sycl::half2 * dsi_dst = 1269& tile_y_ds [ids * (WARP_SIZE /QI8_1 )+ kby ]; 1270if (need_sum ) { 1271* dsi_dst = * dsi_src ; 1272 }else { 1273float * dfi_dst = (float * )dsi_dst ; 1274* dfi_dst = (* dsi_src )[0 ]; 1275 } 1276 } 1277 1278/* 1279DPCT1118:9: SYCL group functions and algorithms must be encountered 1280in converged control flow. You may need to adjust the code. 1281*/ 1282/* 1283DPCT1065:56: Consider replacing sycl::nd_item::barrier() with 1284sycl::nd_item::barrier(sycl::access::fence_space::local_space) for 1285better performance if there is no access to global memory. 1286*/ 1287item_ct1 .barrier (); 1288 1289// #pragma unroll // unrolling this loop causes too much register pressure 1290for (int k = ir * WARP_SIZE /qr ;k < (ir + 1 )* WARP_SIZE /qr ;k += vdr ) { 1291#pragma unroll 1292for (int j = 0 ;j < mmq_x ;j += nwarps ) { 1293#pragma unroll 1294for (int i = 0 ;i < mmq_y ;i += WARP_SIZE ) { 1295sum [i /WARP_SIZE ][j /nwarps ]+= vec_dot ( 1296tile_x_ql ,tile_x_dm ,tile_x_qh ,tile_x_sc , 1297tile_y_qs ,tile_y_ds ,item_ct1 .get_local_id (2 )+ i , 1298item_ct1 .get_local_id (1 )+ j ,k ); 1299 } 1300 } 1301 } 1302 1303/* 1304DPCT1118:10: SYCL group functions and algorithms must be encountered 1305in converged control flow. You may need to adjust the code. 1306*/ 1307/* 1308DPCT1065:57: Consider replacing sycl::nd_item::barrier() with 1309sycl::nd_item::barrier(sycl::access::fence_space::local_space) for 1310better performance if there is no access to global memory. 1311*/ 1312item_ct1 .barrier (); 1313 } 1314 } 1315 1316#pragma unroll 1317for (int j = 0 ;j < mmq_x ;j += nwarps ) { 1318const int col_dst = col_dst_0 + j + item_ct1 .get_local_id (1 ); 1319 1320if (col_dst >=ncols_dst ) { 1321return ; 1322 } 1323 1324#pragma unroll 1325for (int i = 0 ;i < mmq_y ;i += WARP_SIZE ) { 1326const int row_dst = row_dst_0 + item_ct1 .get_local_id (2 )+ i ; 1327 1328if (row_dst >=nrows_dst ) { 1329continue ; 1330 } 1331 1332dst [col_dst * nrows_dst + row_dst ]= sum [i /WARP_SIZE ][j /nwarps ]; 1333 } 1334 } 1335} 1336 1337#define MMQ_X_Q4_0_RDNA2 64 1338#define MMQ_Y_Q4_0_RDNA2 128 1339#define NWARPS_Q4_0_RDNA2 8 1340#define MMQ_X_Q4_0_RDNA1 64 1341#define MMQ_Y_Q4_0_RDNA1 64 1342#define NWARPS_Q4_0_RDNA1 8 1343#if defined(SYCL_USE_XMX ) 1344#define MMQ_X_Q4_0_AMPERE 4 1345#define MMQ_Y_Q4_0_AMPERE 32 1346#define NWARPS_Q4_0_AMPERE 4 1347#else 1348#define MMQ_X_Q4_0_AMPERE 64 1349#define MMQ_Y_Q4_0_AMPERE 128 1350#define NWARPS_Q4_0_AMPERE 4 1351#endif 1352#define MMQ_X_Q4_0_PASCAL 64 1353#define MMQ_Y_Q4_0_PASCAL 64 1354#define NWARPS_Q4_0_PASCAL 8 1355 1356template < bool need_check > static void 1357mul_mat_q4_0 ( 1358const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1359const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1360const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_qs_q4_0 ,float * tile_x_d_q4_0 , 1361int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1362int * tile_x_ql = nullptr ; 1363 sycl::half2 * tile_x_dm = nullptr ; 1364int * tile_x_qh = nullptr ; 1365int * tile_x_sc = nullptr ; 1366 1367//sycl_todo: change according to hardware 1368 1369const int mmq_x = MMQ_X_Q4_0_AMPERE ; 1370const int mmq_y = MMQ_Y_Q4_0_AMPERE ; 1371const int nwarps = NWARPS_Q4_0_AMPERE ; 1372allocate_tiles_q4_0 < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1373tile_x_qs_q4_0 ,tile_x_d_q4_0 ); 1374mul_mat_q < QK4_0 ,QR4_0 ,QI4_0 , true,block_q4_0 ,mmq_x ,mmq_y ,nwarps , 1375load_tiles_q4_0 < mmq_y ,nwarps ,need_check > ,VDR_Q4_0_Q8_1_MMQ , 1376vec_dot_q4_0_q8_1_mul_mat > ( 1377vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1378tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1379} 1380 1381#define MMQ_X_Q4_1_RDNA2 64 1382#define MMQ_Y_Q4_1_RDNA2 128 1383#define NWARPS_Q4_1_RDNA2 8 1384#define MMQ_X_Q4_1_RDNA1 64 1385#define MMQ_Y_Q4_1_RDNA1 64 1386#define NWARPS_Q4_1_RDNA1 8 1387#if defined(SYCL_USE_XMX ) 1388#define MMQ_X_Q4_1_AMPERE 4 1389#define MMQ_Y_Q4_1_AMPERE 32 1390#define NWARPS_Q4_1_AMPERE 4 1391#else 1392#define MMQ_X_Q4_1_AMPERE 64 1393#define MMQ_Y_Q4_1_AMPERE 128 1394#define NWARPS_Q4_1_AMPERE 4 1395#endif 1396#define MMQ_X_Q4_1_PASCAL 64 1397#define MMQ_Y_Q4_1_PASCAL 64 1398#define NWARPS_Q4_1_PASCAL 8 1399 1400template < bool need_check > static void 1401mul_mat_q4_1 ( 1402const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1403const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1404const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_qs_q4_1 , 1405 sycl::half2 * tile_x_dm_q4_1 ,int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1406int * tile_x_ql = nullptr ; 1407 sycl::half2 * tile_x_dm = nullptr ; 1408int * tile_x_qh = nullptr ; 1409int * tile_x_sc = nullptr ; 1410 1411//sycl_todo: change according to hardware 1412const int mmq_x = MMQ_X_Q4_1_AMPERE ; 1413const int mmq_y = MMQ_Y_Q4_1_AMPERE ; 1414const int nwarps = NWARPS_Q4_1_AMPERE ; 1415allocate_tiles_q4_1 < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1416tile_x_qs_q4_1 ,tile_x_dm_q4_1 ); 1417mul_mat_q < QK4_1 ,QR4_1 ,QI4_1 , true,block_q4_1 ,mmq_x ,mmq_y ,nwarps , 1418load_tiles_q4_1 < mmq_y ,nwarps ,need_check > ,VDR_Q4_1_Q8_1_MMQ , 1419vec_dot_q4_1_q8_1_mul_mat > ( 1420vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1421tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1422} 1423 1424#define MMQ_X_Q5_0_RDNA2 64 1425#define MMQ_Y_Q5_0_RDNA2 128 1426#define NWARPS_Q5_0_RDNA2 8 1427#define MMQ_X_Q5_0_RDNA1 64 1428#define MMQ_Y_Q5_0_RDNA1 64 1429#define NWARPS_Q5_0_RDNA1 8 1430#if defined(SYCL_USE_XMX ) 1431#define MMQ_X_Q5_0_AMPERE 4 1432#define MMQ_Y_Q5_0_AMPERE 32 1433#define NWARPS_Q5_0_AMPERE 4 1434#else 1435#define MMQ_X_Q5_0_AMPERE 128 1436#define MMQ_Y_Q5_0_AMPERE 64 1437#define NWARPS_Q5_0_AMPERE 4 1438#endif 1439#define MMQ_X_Q5_0_PASCAL 64 1440#define MMQ_Y_Q5_0_PASCAL 64 1441#define NWARPS_Q5_0_PASCAL 8 1442 1443template < bool need_check > static void 1444mul_mat_q5_0 ( 1445const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1446const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1447const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q5_0 ,float * tile_x_d_q5_0 , 1448int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1449int * tile_x_ql = nullptr ; 1450 sycl::half2 * tile_x_dm = nullptr ; 1451int * tile_x_qh = nullptr ; 1452int * tile_x_sc = nullptr ; 1453 1454//sycl_todo: change according to hardware 1455const int mmq_x = MMQ_X_Q5_0_AMPERE ; 1456const int mmq_y = MMQ_Y_Q5_0_AMPERE ; 1457const int nwarps = NWARPS_Q5_0_AMPERE ; 1458allocate_tiles_q5_0 < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1459tile_x_ql_q5_0 ,tile_x_d_q5_0 ); 1460mul_mat_q < QK5_0 ,QR5_0 ,QI5_0 , false,block_q5_0 ,mmq_x ,mmq_y ,nwarps , 1461load_tiles_q5_0 < mmq_y ,nwarps ,need_check > ,VDR_Q5_0_Q8_1_MMQ , 1462vec_dot_q5_0_q8_1_mul_mat > ( 1463vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1464tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1465} 1466 1467#define MMQ_X_Q5_1_RDNA2 64 1468#define MMQ_Y_Q5_1_RDNA2 128 1469#define NWARPS_Q5_1_RDNA2 8 1470#define MMQ_X_Q5_1_RDNA1 64 1471#define MMQ_Y_Q5_1_RDNA1 64 1472#define NWARPS_Q5_1_RDNA1 8 1473#if defined(SYCL_USE_XMX ) 1474#define MMQ_X_Q5_1_AMPERE 4 1475#define MMQ_Y_Q5_1_AMPERE 32 1476#define NWARPS_Q5_1_AMPERE 4 1477#else 1478#define MMQ_X_Q5_1_AMPERE 128 1479#define MMQ_Y_Q5_1_AMPERE 64 1480#define NWARPS_Q5_1_AMPERE 4 1481#endif 1482#define MMQ_X_Q5_1_PASCAL 64 1483#define MMQ_Y_Q5_1_PASCAL 64 1484#define NWARPS_Q5_1_PASCAL 8 1485 1486template < bool need_check > static void 1487mul_mat_q5_1 ( 1488const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1489const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1490const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q5_1 , 1491 sycl::half2 * tile_x_dm_q5_1 ,int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1492int * tile_x_ql = nullptr ; 1493 sycl::half2 * tile_x_dm = nullptr ; 1494int * tile_x_qh = nullptr ; 1495int * tile_x_sc = nullptr ; 1496 1497//sycl_todo: change according to hardware 1498const int mmq_x = MMQ_X_Q5_1_AMPERE ; 1499const int mmq_y = MMQ_Y_Q5_1_AMPERE ; 1500const int nwarps = NWARPS_Q5_1_AMPERE ; 1501allocate_tiles_q5_1 < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1502tile_x_ql_q5_1 ,tile_x_dm_q5_1 ); 1503mul_mat_q < QK5_1 ,QR5_1 ,QI5_1 , true,block_q5_1 ,mmq_x ,mmq_y ,nwarps , 1504load_tiles_q5_1 < mmq_y ,nwarps ,need_check > ,VDR_Q5_1_Q8_1_MMQ , 1505vec_dot_q5_1_q8_1_mul_mat > ( 1506vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1507tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1508} 1509 1510#define MMQ_X_Q8_0_RDNA2 64 1511#define MMQ_Y_Q8_0_RDNA2 128 1512#define NWARPS_Q8_0_RDNA2 8 1513#define MMQ_X_Q8_0_RDNA1 64 1514#define MMQ_Y_Q8_0_RDNA1 64 1515#define NWARPS_Q8_0_RDNA1 8 1516#if defined(SYCL_USE_XMX ) 1517#define MMQ_X_Q8_0_AMPERE 4 1518#define MMQ_Y_Q8_0_AMPERE 32 1519#define NWARPS_Q8_0_AMPERE 4 1520#else 1521#define MMQ_X_Q8_0_AMPERE 128 1522#define MMQ_Y_Q8_0_AMPERE 64 1523#define NWARPS_Q8_0_AMPERE 4 1524#endif 1525#define MMQ_X_Q8_0_PASCAL 64 1526#define MMQ_Y_Q8_0_PASCAL 64 1527#define NWARPS_Q8_0_PASCAL 8 1528 1529template < bool need_check > static void 1530mul_mat_q8_0 ( 1531const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1532const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1533const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_qs_q8_0 ,float * tile_x_d_q8_0 , 1534int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1535int * tile_x_ql = nullptr ; 1536 sycl::half2 * tile_x_dm = nullptr ; 1537int * tile_x_qh = nullptr ; 1538int * tile_x_sc = nullptr ; 1539 1540//sycl_todo: change according to hardware 1541const int mmq_x = MMQ_X_Q8_0_AMPERE ; 1542const int mmq_y = MMQ_Y_Q8_0_AMPERE ; 1543const int nwarps = NWARPS_Q8_0_AMPERE ; 1544allocate_tiles_q8_0 < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1545tile_x_qs_q8_0 ,tile_x_d_q8_0 ); 1546mul_mat_q < QK8_0 ,QR8_0 ,QI8_0 , false,block_q8_0 ,mmq_x ,mmq_y ,nwarps , 1547load_tiles_q8_0 < mmq_y ,nwarps ,need_check > ,VDR_Q8_0_Q8_1_MMQ , 1548vec_dot_q8_0_q8_1_mul_mat > ( 1549vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1550tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1551} 1552 1553#define MMQ_X_Q2_K_RDNA2 64 1554#define MMQ_Y_Q2_K_RDNA2 128 1555#define NWARPS_Q2_K_RDNA2 8 1556#define MMQ_X_Q2_K_RDNA1 128 1557#define MMQ_Y_Q2_K_RDNA1 32 1558#define NWARPS_Q2_K_RDNA1 8 1559#if defined(SYCL_USE_XMX ) 1560#define MMQ_X_Q2_K_AMPERE 4 1561#define MMQ_Y_Q2_K_AMPERE 32 1562#define NWARPS_Q2_K_AMPERE 4 1563#else 1564#define MMQ_X_Q2_K_AMPERE 64 1565#define MMQ_Y_Q2_K_AMPERE 128 1566#define NWARPS_Q2_K_AMPERE 4 1567#endif 1568#define MMQ_X_Q2_K_PASCAL 64 1569#define MMQ_Y_Q2_K_PASCAL 64 1570#define NWARPS_Q2_K_PASCAL 8 1571 1572template < bool need_check > static void 1573mul_mat_q2_K ( 1574const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1575const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1576const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q2_K , 1577 sycl::half2 * tile_x_dm_q2_K ,int * tile_x_sc_q2_K ,int * tile_y_qs , 1578 sycl::half2 * tile_y_ds ) { 1579int * tile_x_ql = nullptr ; 1580 sycl::half2 * tile_x_dm = nullptr ; 1581int * tile_x_qh = nullptr ; 1582int * tile_x_sc = nullptr ; 1583 1584//sycl_todo: change according to hardware 1585const int mmq_x = MMQ_X_Q2_K_AMPERE ; 1586const int mmq_y = MMQ_Y_Q2_K_AMPERE ; 1587const int nwarps = NWARPS_Q2_K_AMPERE ; 1588allocate_tiles_q2_K < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1589tile_x_ql_q2_K ,tile_x_dm_q2_K ,tile_x_sc_q2_K ); 1590mul_mat_q < QK_K ,QR2_K ,QI2_K , false,block_q2_K ,mmq_x ,mmq_y ,nwarps , 1591load_tiles_q2_K < mmq_y ,nwarps ,need_check > ,VDR_Q2_K_Q8_1_MMQ , 1592vec_dot_q2_K_q8_1_mul_mat > ( 1593vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1594tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1595} 1596 1597#define MMQ_X_Q3_K_RDNA2 128 1598#define MMQ_Y_Q3_K_RDNA2 64 1599#define NWARPS_Q3_K_RDNA2 8 1600#define MMQ_X_Q3_K_RDNA1 32 1601#define MMQ_Y_Q3_K_RDNA1 128 1602#define NWARPS_Q3_K_RDNA1 8 1603#if defined(SYCL_USE_XMX ) 1604#define MMQ_X_Q3_K_AMPERE 4 1605#define MMQ_Y_Q3_K_AMPERE 32 1606#define NWARPS_Q3_K_AMPERE 4 1607#else 1608#define MMQ_X_Q3_K_AMPERE 128 1609#define MMQ_Y_Q3_K_AMPERE 128 1610#define NWARPS_Q3_K_AMPERE 4 1611#endif 1612#define MMQ_X_Q3_K_PASCAL 64 1613#define MMQ_Y_Q3_K_PASCAL 64 1614#define NWARPS_Q3_K_PASCAL 8 1615 1616template < bool need_check > static void 1617mul_mat_q3_K ( 1618const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1619const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1620const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q3_K , 1621 sycl::half2 * tile_x_dm_q3_K ,int * tile_x_qh_q3_K ,int * tile_x_sc_q3_K , 1622int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1623int * tile_x_ql = nullptr ; 1624 sycl::half2 * tile_x_dm = nullptr ; 1625int * tile_x_qh = nullptr ; 1626int * tile_x_sc = nullptr ; 1627 1628//sycl_todo: change according to hardware 1629const int mmq_x = MMQ_X_Q3_K_AMPERE ; 1630const int mmq_y = MMQ_Y_Q3_K_AMPERE ; 1631const int nwarps = NWARPS_Q3_K_AMPERE ; 1632allocate_tiles_q3_K < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1633tile_x_ql_q3_K ,tile_x_dm_q3_K ,tile_x_qh_q3_K , 1634tile_x_sc_q3_K ); 1635mul_mat_q < QK_K ,QR3_K ,QI3_K , false,block_q3_K ,mmq_x ,mmq_y ,nwarps , 1636load_tiles_q3_K < mmq_y ,nwarps ,need_check > ,VDR_Q3_K_Q8_1_MMQ , 1637vec_dot_q3_K_q8_1_mul_mat > ( 1638vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1639tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1640} 1641 1642#define MMQ_X_Q4_K_RDNA2 64 1643#define MMQ_Y_Q4_K_RDNA2 128 1644#define NWARPS_Q4_K_RDNA2 8 1645#define MMQ_X_Q4_K_RDNA1 32 1646#define MMQ_Y_Q4_K_RDNA1 64 1647#define NWARPS_Q4_K_RDNA1 8 1648#if defined(SYCL_USE_XMX ) 1649#define MMQ_X_Q4_K_AMPERE 4 1650#define MMQ_Y_Q4_K_AMPERE 32 1651#define NWARPS_Q4_K_AMPERE 4 1652#else 1653#define MMQ_X_Q4_K_AMPERE 64 1654#define MMQ_Y_Q4_K_AMPERE 128 1655#define NWARPS_Q4_K_AMPERE 4 1656#endif 1657#define MMQ_X_Q4_K_PASCAL 64 1658#define MMQ_Y_Q4_K_PASCAL 64 1659#define NWARPS_Q4_K_PASCAL 8 1660 1661template < bool need_check > static void 1662mul_mat_q4_K ( 1663const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1664const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1665const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q4_K , 1666 sycl::half2 * tile_x_dm_q4_K ,int * tile_x_sc_q4_K ,int * tile_y_qs , 1667 sycl::half2 * tile_y_ds ) { 1668int * tile_x_ql = nullptr ; 1669 sycl::half2 * tile_x_dm = nullptr ; 1670int * tile_x_qh = nullptr ; 1671int * tile_x_sc = nullptr ; 1672 1673//sycl_todo: change according to hardware 1674const int mmq_x = MMQ_X_Q4_K_AMPERE ; 1675const int mmq_y = MMQ_Y_Q4_K_AMPERE ; 1676const int nwarps = NWARPS_Q4_K_AMPERE ; 1677allocate_tiles_q4_K < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1678tile_x_ql_q4_K ,tile_x_dm_q4_K ,tile_x_sc_q4_K ); 1679mul_mat_q < QK_K ,QR4_K ,QI4_K , true,block_q4_K ,mmq_x ,mmq_y ,nwarps , 1680load_tiles_q4_K < mmq_y ,nwarps ,need_check > ,VDR_Q4_K_Q8_1_MMQ , 1681vec_dot_q4_K_q8_1_mul_mat > ( 1682vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1683tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1684} 1685 1686#define MMQ_X_Q5_K_RDNA2 64 1687#define MMQ_Y_Q5_K_RDNA2 128 1688#define NWARPS_Q5_K_RDNA2 8 1689#define MMQ_X_Q5_K_RDNA1 32 1690#define MMQ_Y_Q5_K_RDNA1 64 1691#define NWARPS_Q5_K_RDNA1 8 1692#if defined(SYCL_USE_XMX ) 1693#define MMQ_X_Q5_K_AMPERE 4 1694#define MMQ_Y_Q5_K_AMPERE 32 1695#define NWARPS_Q5_K_AMPERE 4 1696#else 1697#define MMQ_X_Q5_K_AMPERE 64 1698#define MMQ_Y_Q5_K_AMPERE 128 1699#define NWARPS_Q5_K_AMPERE 4 1700#endif 1701#define MMQ_X_Q5_K_PASCAL 64 1702#define MMQ_Y_Q5_K_PASCAL 64 1703#define NWARPS_Q5_K_PASCAL 8 1704 1705template < bool need_check > static void 1706mul_mat_q5_K ( 1707const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1708const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1709const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql_q5_K , 1710 sycl::half2 * tile_x_dm_q5_K ,int * tile_x_sc_q5_K ,int * tile_y_qs , 1711 sycl::half2 * tile_y_ds ) { 1712int * tile_x_ql = nullptr ; 1713 sycl::half2 * tile_x_dm = nullptr ; 1714int * tile_x_qh = nullptr ; 1715int * tile_x_sc = nullptr ; 1716 1717//sycl_todo: change according to hardware 1718const int mmq_x = MMQ_X_Q5_K_AMPERE ; 1719const int mmq_y = MMQ_Y_Q5_K_AMPERE ; 1720const int nwarps = NWARPS_Q5_K_AMPERE ; 1721allocate_tiles_q5_K < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1722tile_x_ql_q5_K ,tile_x_dm_q5_K ,tile_x_sc_q5_K ); 1723mul_mat_q < QK_K ,QR5_K ,QI5_K , true,block_q5_K ,mmq_x ,mmq_y ,nwarps , 1724load_tiles_q5_K < mmq_y ,nwarps ,need_check > ,VDR_Q5_K_Q8_1_MMQ , 1725vec_dot_q5_K_q8_1_mul_mat > ( 1726vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1727tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1728} 1729 1730#define MMQ_X_Q6_K_RDNA2 64 1731#define MMQ_Y_Q6_K_RDNA2 128 1732#define NWARPS_Q6_K_RDNA2 8 1733#define MMQ_X_Q6_K_RDNA1 32 1734#define MMQ_Y_Q6_K_RDNA1 64 1735#define NWARPS_Q6_K_RDNA1 8 1736#if defined(SYCL_USE_XMX ) 1737#define MMQ_X_Q6_K_AMPERE 4 1738#define MMQ_Y_Q6_K_AMPERE 32 1739#define NWARPS_Q6_K_AMPERE 4 1740#else 1741#define MMQ_X_Q6_K_AMPERE 64 1742#define MMQ_Y_Q6_K_AMPERE 64 1743#define NWARPS_Q6_K_AMPERE 4 1744#endif 1745#define MMQ_X_Q6_K_PASCAL 64 1746#define MMQ_Y_Q6_K_PASCAL 64 1747#define NWARPS_Q6_K_PASCAL 8 1748 1749template < bool need_check > static void 1750mul_mat_q6_K ( 1751const void * __restrict__vx ,const void * __restrict__vy ,float * __restrict__dst , 1752const int ncols_x ,const int nrows_x ,const int ncols_y ,const int nrows_y ,const int nrows_dst , 1753const sycl::nd_item < 3 > & item_ct1 ,int * tile_x_ql , sycl::half2 * tile_x_dm , 1754int * tile_x_sc ,int * tile_y_qs , sycl::half2 * tile_y_ds ) { 1755// int * tile_x_ql = nullptr; 1756// sycl::half2 *tile_x_dm = nullptr; 1757int * tile_x_qh = nullptr ; 1758// int * tile_x_sc = nullptr; 1759 1760//sycl_todo: change according to hardware 1761const int mmq_x = MMQ_X_Q6_K_AMPERE ; 1762const int mmq_y = MMQ_Y_Q6_K_AMPERE ; 1763const int nwarps = NWARPS_Q6_K_AMPERE ; 1764allocate_tiles_q6_K < mmq_y > (& tile_x_ql ,& tile_x_dm ,& tile_x_qh ,& tile_x_sc , 1765tile_x_ql ,tile_x_dm ,tile_x_sc ); 1766mul_mat_q < QK_K ,QR6_K ,QI6_K , false,block_q6_K ,mmq_x ,mmq_y ,nwarps , 1767load_tiles_q6_K < mmq_y ,nwarps ,need_check > ,VDR_Q6_K_Q8_1_MMQ , 1768vec_dot_q6_K_q8_1_mul_mat > ( 1769vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y ,nrows_dst ,tile_x_ql , 1770tile_x_dm ,tile_x_qh ,tile_x_sc ,item_ct1 ,tile_y_qs ,tile_y_ds ); 1771} 1772 1773static void ggml_mul_mat_q4_0_q8_1_sycl (const void * vx ,const void * vy , 1774float * dst ,const int ncols_x , 1775const int nrows_x ,const int ncols_y , 1776const int nrows_y ,const int nrows_dst , 1777 dpct::queue_ptr stream )try { 1778 1779int id ; 1780SYCL_CHECK ( 1781CHECK_TRY_ERROR (id = get_current_device_id ())); 1782const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 1783 1784int mmq_x ,mmq_y ,nwarps ; 1785if (compute_capability >=VER_GEN13 ) { 1786mmq_x = MMQ_X_Q4_0_RDNA2 ; 1787mmq_y = MMQ_Y_Q4_0_RDNA2 ; 1788nwarps = NWARPS_Q4_0_RDNA2 ; 1789 }else if (compute_capability >=VER_GEN12 ) { 1790mmq_x = MMQ_X_Q4_0_RDNA1 ; 1791mmq_y = MMQ_Y_Q4_0_RDNA1 ; 1792nwarps = NWARPS_Q4_0_RDNA1 ; 1793 }else if (compute_capability >=VER_GEN9 ) { 1794mmq_x = MMQ_X_Q4_0_AMPERE ; 1795mmq_y = MMQ_Y_Q4_0_AMPERE ; 1796nwarps = NWARPS_Q4_0_AMPERE ; 1797 }else if (compute_capability >=VER_4VEC ) { 1798mmq_x = MMQ_X_Q4_0_PASCAL ; 1799mmq_y = MMQ_Y_Q4_0_PASCAL ; 1800nwarps = NWARPS_Q4_0_PASCAL ; 1801 }else { 1802GGML_ABORT ("fatal error" ); 1803 } 1804 1805const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 1806const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 1807const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 1808const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 1809 1810if (nrows_x %mmq_y == 0 ) { 1811const bool need_check = false; 1812/* 1813DPCT1049:20: The work-group size passed to the SYCL kernel may exceed 1814the limit. To get the device limit, query 1815info::device::max_work_group_size. Adjust the work-group size if needed. 1816*/ 1817 { 1818 dpct::has_capability_or_fail (stream -> get_device (), 1819 {sycl::aspect::fp16 }); 1820 1821stream -> submit ([& ](sycl::handler & cgh ) { 1822 sycl::local_accessor < int ,1 > tile_x_qs_q4_0_acc_ct1 ( 1823 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 1824 sycl::local_accessor < float ,1 > tile_x_d_q4_0_acc_ct1 ( 1825 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_0 )+ mmq_y /QI4_0 ), 1826cgh ); 1827 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 1828 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 1829 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 1830 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 1831 1832cgh .parallel_for ( 1833 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1834 [= ](sycl::nd_item < 3 > item_ct1 ) { 1835mul_mat_q4_0 < need_check > ( 1836vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 1837nrows_dst ,item_ct1 , 1838get_pointer (tile_x_qs_q4_0_acc_ct1 ), 1839get_pointer (tile_x_d_q4_0_acc_ct1 ), 1840get_pointer (tile_y_qs_acc_ct1 ), 1841get_pointer (tile_y_ds_acc_ct1 )); 1842 }); 1843 }); 1844 } 1845 }else { 1846const bool need_check = true; 1847/* 1848DPCT1049:21: The work-group size passed to the SYCL kernel may exceed 1849the limit. To get the device limit, query 1850info::device::max_work_group_size. Adjust the work-group size if needed. 1851*/ 1852 { 1853 dpct::has_capability_or_fail (stream -> get_device (), 1854 {sycl::aspect::fp16 }); 1855 1856stream -> submit ([& ](sycl::handler & cgh ) { 1857 sycl::local_accessor < int ,1 > tile_x_qs_q4_0_acc_ct1 ( 1858 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 1859 sycl::local_accessor < float ,1 > tile_x_d_q4_0_acc_ct1 ( 1860 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_0 )+ mmq_y /QI4_0 ), 1861cgh ); 1862 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 1863 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 1864 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 1865 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 1866 1867cgh .parallel_for ( 1868 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1869 [= ](sycl::nd_item < 3 > item_ct1 ) { 1870mul_mat_q4_0 < need_check > ( 1871vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 1872nrows_dst ,item_ct1 , 1873get_pointer (tile_x_qs_q4_0_acc_ct1 ), 1874get_pointer (tile_x_d_q4_0_acc_ct1 ), 1875get_pointer (tile_y_qs_acc_ct1 ), 1876get_pointer (tile_y_ds_acc_ct1 )); 1877 }); 1878 }); 1879 } 1880 } 1881} 1882catch (sycl::exception const & exc ) { 1883 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 1884 <<", line:" <<__LINE__ << std::endl ; 1885 std::exit (1 ); 1886} 1887 1888static void ggml_mul_mat_q4_1_q8_1_sycl (const void * vx ,const void * vy , 1889float * dst ,const int ncols_x , 1890const int nrows_x ,const int ncols_y , 1891const int nrows_y ,const int nrows_dst , 1892 dpct::queue_ptr stream )try { 1893 1894int id ; 1895SYCL_CHECK ( 1896CHECK_TRY_ERROR (id = get_current_device_id ())); 1897const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 1898 1899int mmq_x ,mmq_y ,nwarps ; 1900if (compute_capability >=VER_GEN13 ) { 1901mmq_x = MMQ_X_Q4_1_RDNA2 ; 1902mmq_y = MMQ_Y_Q4_1_RDNA2 ; 1903nwarps = NWARPS_Q4_1_RDNA2 ; 1904 }else if (compute_capability >=VER_GEN12 ) { 1905mmq_x = MMQ_X_Q4_1_RDNA1 ; 1906mmq_y = MMQ_Y_Q4_1_RDNA1 ; 1907nwarps = NWARPS_Q4_1_RDNA1 ; 1908 }else if (compute_capability >=VER_GEN9 ) { 1909mmq_x = MMQ_X_Q4_1_AMPERE ; 1910mmq_y = MMQ_Y_Q4_1_AMPERE ; 1911nwarps = NWARPS_Q4_1_AMPERE ; 1912 }else if (compute_capability >=VER_4VEC ) { 1913mmq_x = MMQ_X_Q4_1_PASCAL ; 1914mmq_y = MMQ_Y_Q4_1_PASCAL ; 1915nwarps = NWARPS_Q4_1_PASCAL ; 1916 }else { 1917GGML_ABORT ("fatal error" ); 1918 } 1919 1920const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 1921const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 1922const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 1923const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 1924 1925if (nrows_x %mmq_y == 0 ) { 1926const bool need_check = false; 1927/* 1928DPCT1049:22: The work-group size passed to the SYCL kernel may exceed 1929the limit. To get the device limit, query 1930info::device::max_work_group_size. Adjust the work-group size if needed. 1931*/ 1932 { 1933 dpct::has_capability_or_fail (stream -> get_device (), 1934 {sycl::aspect::fp16 }); 1935 1936stream -> submit ([& ](sycl::handler & cgh ) { 1937 sycl::local_accessor < int ,1 > tile_x_qs_q4_1_acc_ct1 ( 1938 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ + mmq_y ),cgh ); 1939 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q4_1_acc_ct1 ( 1940 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_1 )+ mmq_y /QI4_1 ), 1941cgh ); 1942 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 1943 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 1944 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 1945 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 1946 1947cgh .parallel_for ( 1948 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1949 [= ](sycl::nd_item < 3 > item_ct1 ) { 1950mul_mat_q4_1 < need_check > ( 1951vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 1952nrows_dst ,item_ct1 , 1953get_pointer (tile_x_qs_q4_1_acc_ct1 ), 1954get_pointer (tile_x_dm_q4_1_acc_ct1 ), 1955get_pointer (tile_y_qs_acc_ct1 ), 1956get_pointer (tile_y_ds_acc_ct1 )); 1957 }); 1958 }); 1959 } 1960 }else { 1961const bool need_check = true; 1962/* 1963DPCT1049:23: The work-group size passed to the SYCL kernel may exceed 1964the limit. To get the device limit, query 1965info::device::max_work_group_size. Adjust the work-group size if needed. 1966*/ 1967 { 1968 dpct::has_capability_or_fail (stream -> get_device (), 1969 {sycl::aspect::fp16 }); 1970 1971stream -> submit ([& ](sycl::handler & cgh ) { 1972 sycl::local_accessor < int ,1 > tile_x_qs_q4_1_acc_ct1 ( 1973 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ + mmq_y ),cgh ); 1974 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q4_1_acc_ct1 ( 1975 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_1 )+ mmq_y /QI4_1 ), 1976cgh ); 1977 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 1978 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 1979 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 1980 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 1981 1982cgh .parallel_for ( 1983 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 1984 [= ](sycl::nd_item < 3 > item_ct1 ) { 1985mul_mat_q4_1 < need_check > ( 1986vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 1987nrows_dst ,item_ct1 , 1988get_pointer (tile_x_qs_q4_1_acc_ct1 ), 1989get_pointer (tile_x_dm_q4_1_acc_ct1 ), 1990get_pointer (tile_y_qs_acc_ct1 ), 1991get_pointer (tile_y_ds_acc_ct1 )); 1992 }); 1993 }); 1994 } 1995 } 1996} 1997catch (sycl::exception const & exc ) { 1998 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 1999 <<", line:" <<__LINE__ << std::endl ; 2000 std::exit (1 ); 2001} 2002 2003static void ggml_mul_mat_q5_0_q8_1_sycl (const void * vx ,const void * vy , 2004float * dst ,const int ncols_x , 2005const int nrows_x ,const int ncols_y , 2006const int nrows_y ,const int nrows_dst , 2007 dpct::queue_ptr stream )try { 2008 2009int id ; 2010SYCL_CHECK ( 2011CHECK_TRY_ERROR (id = get_current_device_id ())); 2012const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2013 2014int mmq_x ,mmq_y ,nwarps ; 2015if (compute_capability >=VER_GEN13 ) { 2016mmq_x = MMQ_X_Q5_0_RDNA2 ; 2017mmq_y = MMQ_Y_Q5_0_RDNA2 ; 2018nwarps = NWARPS_Q5_0_RDNA2 ; 2019 }else if (compute_capability >=VER_GEN12 ) { 2020mmq_x = MMQ_X_Q5_0_RDNA1 ; 2021mmq_y = MMQ_Y_Q5_0_RDNA1 ; 2022nwarps = NWARPS_Q5_0_RDNA1 ; 2023 }else if (compute_capability >=VER_GEN9 ) { 2024mmq_x = MMQ_X_Q5_0_AMPERE ; 2025mmq_y = MMQ_Y_Q5_0_AMPERE ; 2026nwarps = NWARPS_Q5_0_AMPERE ; 2027 }else if (compute_capability >=VER_4VEC ) { 2028mmq_x = MMQ_X_Q5_0_PASCAL ; 2029mmq_y = MMQ_Y_Q5_0_PASCAL ; 2030nwarps = NWARPS_Q5_0_PASCAL ; 2031 }else { 2032GGML_ABORT ("fatal error" ); 2033 } 2034 2035const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2036const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2037const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2038const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2039 2040if (nrows_x %mmq_y == 0 ) { 2041const bool need_check = false; 2042/* 2043DPCT1049:24: The work-group size passed to the SYCL kernel may exceed 2044the limit. To get the device limit, query 2045info::device::max_work_group_size. Adjust the work-group size if needed. 2046*/ 2047 { 2048 dpct::has_capability_or_fail (stream -> get_device (), 2049 {sycl::aspect::fp16 }); 2050 2051stream -> submit ([& ](sycl::handler & cgh ) { 2052 sycl::local_accessor < int ,1 > tile_x_ql_q5_0_acc_ct1 ( 2053 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2054 sycl::local_accessor < float ,1 > tile_x_d_q5_0_acc_ct1 ( 2055 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_0 )+ mmq_y /QI5_0 ), 2056cgh ); 2057 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2058 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2059 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2060 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2061 2062cgh .parallel_for ( 2063 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2064 [= ](sycl::nd_item < 3 > item_ct1 ) { 2065mul_mat_q5_0 < need_check > ( 2066vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2067nrows_dst ,item_ct1 , 2068get_pointer (tile_x_ql_q5_0_acc_ct1 ), 2069get_pointer (tile_x_d_q5_0_acc_ct1 ), 2070get_pointer (tile_y_qs_acc_ct1 ), 2071get_pointer (tile_y_ds_acc_ct1 )); 2072 }); 2073 }); 2074 } 2075 }else { 2076const bool need_check = true; 2077/* 2078DPCT1049:25: The work-group size passed to the SYCL kernel may exceed 2079the limit. To get the device limit, query 2080info::device::max_work_group_size. Adjust the work-group size if needed. 2081*/ 2082 { 2083 dpct::has_capability_or_fail (stream -> get_device (), 2084 {sycl::aspect::fp16 }); 2085 2086stream -> submit ([& ](sycl::handler & cgh ) { 2087 sycl::local_accessor < int ,1 > tile_x_ql_q5_0_acc_ct1 ( 2088 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2089 sycl::local_accessor < float ,1 > tile_x_d_q5_0_acc_ct1 ( 2090 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_0 )+ mmq_y /QI5_0 ), 2091cgh ); 2092 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2093 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2094 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2095 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2096 2097cgh .parallel_for ( 2098 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2099 [= ](sycl::nd_item < 3 > item_ct1 ) { 2100mul_mat_q5_0 < need_check > ( 2101vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2102nrows_dst ,item_ct1 , 2103get_pointer (tile_x_ql_q5_0_acc_ct1 ), 2104get_pointer (tile_x_d_q5_0_acc_ct1 ), 2105get_pointer (tile_y_qs_acc_ct1 ), 2106get_pointer (tile_y_ds_acc_ct1 )); 2107 }); 2108 }); 2109 } 2110 } 2111} 2112catch (sycl::exception const & exc ) { 2113 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2114 <<", line:" <<__LINE__ << std::endl ; 2115 std::exit (1 ); 2116} 2117 2118static void ggml_mul_mat_q5_1_q8_1_sycl (const void * vx ,const void * vy , 2119float * dst ,const int ncols_x , 2120const int nrows_x ,const int ncols_y , 2121const int nrows_y ,const int nrows_dst , 2122 dpct::queue_ptr stream )try { 2123 2124int id ; 2125SYCL_CHECK ( 2126CHECK_TRY_ERROR (id = get_current_device_id ())); 2127const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2128 2129int mmq_x ,mmq_y ,nwarps ; 2130if (compute_capability >=VER_GEN13 ) { 2131mmq_x = MMQ_X_Q5_1_RDNA2 ; 2132mmq_y = MMQ_Y_Q5_1_RDNA2 ; 2133nwarps = NWARPS_Q5_1_RDNA2 ; 2134 }else if (compute_capability >=VER_GEN12 ) { 2135mmq_x = MMQ_X_Q5_1_RDNA1 ; 2136mmq_y = MMQ_Y_Q5_1_RDNA1 ; 2137nwarps = NWARPS_Q5_1_RDNA1 ; 2138 }else if (compute_capability >=VER_GEN9 ) { 2139mmq_x = MMQ_X_Q5_1_AMPERE ; 2140mmq_y = MMQ_Y_Q5_1_AMPERE ; 2141nwarps = NWARPS_Q5_1_AMPERE ; 2142 }else if (compute_capability >=VER_4VEC ) { 2143mmq_x = MMQ_X_Q5_1_PASCAL ; 2144mmq_y = MMQ_Y_Q5_1_PASCAL ; 2145nwarps = NWARPS_Q5_1_PASCAL ; 2146 }else { 2147GGML_ABORT ("fatal error" ); 2148 } 2149 2150const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2151const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2152const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2153const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2154 2155if (nrows_x %mmq_y == 0 ) { 2156const bool need_check = false; 2157/* 2158DPCT1049:26: The work-group size passed to the SYCL kernel may exceed 2159the limit. To get the device limit, query 2160info::device::max_work_group_size. Adjust the work-group size if needed. 2161*/ 2162 { 2163 dpct::has_capability_or_fail (stream -> get_device (), 2164 {sycl::aspect::fp16 }); 2165 2166stream -> submit ([& ](sycl::handler & cgh ) { 2167 sycl::local_accessor < int ,1 > tile_x_ql_q5_1_acc_ct1 ( 2168 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2169 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q5_1_acc_ct1 ( 2170 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_1 )+ mmq_y /QI5_1 ), 2171cgh ); 2172 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2173 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2174 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2175 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2176 2177cgh .parallel_for ( 2178 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2179 [= ](sycl::nd_item < 3 > item_ct1 ) { 2180mul_mat_q5_1 < need_check > ( 2181vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2182nrows_dst ,item_ct1 , 2183get_pointer (tile_x_ql_q5_1_acc_ct1 ), 2184get_pointer (tile_x_dm_q5_1_acc_ct1 ), 2185get_pointer (tile_y_qs_acc_ct1 ), 2186get_pointer (tile_y_ds_acc_ct1 )); 2187 }); 2188 }); 2189 } 2190 }else { 2191const bool need_check = true; 2192/* 2193DPCT1049:27: The work-group size passed to the SYCL kernel may exceed 2194the limit. To get the device limit, query 2195info::device::max_work_group_size. Adjust the work-group size if needed. 2196*/ 2197 { 2198 dpct::has_capability_or_fail (stream -> get_device (), 2199 {sycl::aspect::fp16 }); 2200 2201stream -> submit ([& ](sycl::handler & cgh ) { 2202 sycl::local_accessor < int ,1 > tile_x_ql_q5_1_acc_ct1 ( 2203 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2204 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q5_1_acc_ct1 ( 2205 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_1 )+ mmq_y /QI5_1 ), 2206cgh ); 2207 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2208 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2209 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2210 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2211 2212cgh .parallel_for ( 2213 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2214 [= ](sycl::nd_item < 3 > item_ct1 ) { 2215mul_mat_q5_1 < need_check > ( 2216vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2217nrows_dst ,item_ct1 , 2218get_pointer (tile_x_ql_q5_1_acc_ct1 ), 2219get_pointer (tile_x_dm_q5_1_acc_ct1 ), 2220get_pointer (tile_y_qs_acc_ct1 ), 2221get_pointer (tile_y_ds_acc_ct1 )); 2222 }); 2223 }); 2224 } 2225 } 2226} 2227catch (sycl::exception const & exc ) { 2228 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2229 <<", line:" <<__LINE__ << std::endl ; 2230 std::exit (1 ); 2231} 2232 2233static void ggml_mul_mat_q8_0_q8_1_sycl (const void * vx ,const void * vy , 2234float * dst ,const int ncols_x , 2235const int nrows_x ,const int ncols_y , 2236const int nrows_y ,const int nrows_dst , 2237 dpct::queue_ptr stream )try { 2238 2239int id ; 2240SYCL_CHECK ( 2241CHECK_TRY_ERROR (id = get_current_device_id ())); 2242const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2243 2244int mmq_x ,mmq_y ,nwarps ; 2245if (compute_capability >=VER_GEN13 ) { 2246mmq_x = MMQ_X_Q8_0_RDNA2 ; 2247mmq_y = MMQ_Y_Q8_0_RDNA2 ; 2248nwarps = NWARPS_Q8_0_RDNA2 ; 2249 }else if (compute_capability >=VER_GEN12 ) { 2250mmq_x = MMQ_X_Q8_0_RDNA1 ; 2251mmq_y = MMQ_Y_Q8_0_RDNA1 ; 2252nwarps = NWARPS_Q8_0_RDNA1 ; 2253 }else if (compute_capability >=VER_GEN9 ) { 2254mmq_x = MMQ_X_Q8_0_AMPERE ; 2255mmq_y = MMQ_Y_Q8_0_AMPERE ; 2256nwarps = NWARPS_Q8_0_AMPERE ; 2257 }else if (compute_capability >=VER_4VEC ) { 2258mmq_x = MMQ_X_Q8_0_PASCAL ; 2259mmq_y = MMQ_Y_Q8_0_PASCAL ; 2260nwarps = NWARPS_Q8_0_PASCAL ; 2261 }else { 2262GGML_ABORT ("fatal error" ); 2263 } 2264 2265const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2266const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2267const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2268const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2269 2270if (nrows_x %mmq_y == 0 ) { 2271const bool need_check = false; 2272/* 2273DPCT1049:28: The work-group size passed to the SYCL kernel may exceed 2274the limit. To get the device limit, query 2275info::device::max_work_group_size. Adjust the work-group size if needed. 2276*/ 2277 { 2278 dpct::has_capability_or_fail (stream -> get_device (), 2279 {sycl::aspect::fp16 }); 2280 2281stream -> submit ([& ](sycl::handler & cgh ) { 2282 sycl::local_accessor < int ,1 > tile_x_qs_q8_0_acc_ct1 ( 2283 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2284 sycl::local_accessor < float ,1 > tile_x_d_q8_0_acc_ct1 ( 2285 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI8_0 )+ mmq_y /QI8_0 ), 2286cgh ); 2287 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2288 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2289 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2290 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2291 2292cgh .parallel_for ( 2293 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2294 [= ](sycl::nd_item < 3 > item_ct1 ) { 2295mul_mat_q8_0 < need_check > ( 2296vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2297nrows_dst ,item_ct1 , 2298get_pointer (tile_x_qs_q8_0_acc_ct1 ), 2299get_pointer (tile_x_d_q8_0_acc_ct1 ), 2300get_pointer (tile_y_qs_acc_ct1 ), 2301get_pointer (tile_y_ds_acc_ct1 )); 2302 }); 2303 }); 2304 } 2305 }else { 2306const bool need_check = true; 2307/* 2308DPCT1049:29: The work-group size passed to the SYCL kernel may exceed 2309the limit. To get the device limit, query 2310info::device::max_work_group_size. Adjust the work-group size if needed. 2311*/ 2312 { 2313 dpct::has_capability_or_fail (stream -> get_device (), 2314 {sycl::aspect::fp16 }); 2315 2316stream -> submit ([& ](sycl::handler & cgh ) { 2317 sycl::local_accessor < int ,1 > tile_x_qs_q8_0_acc_ct1 ( 2318 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2319 sycl::local_accessor < float ,1 > tile_x_d_q8_0_acc_ct1 ( 2320 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI8_0 )+ mmq_y /QI8_0 ), 2321cgh ); 2322 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2323 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2324 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2325 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2326 2327cgh .parallel_for ( 2328 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2329 [= ](sycl::nd_item < 3 > item_ct1 ) { 2330mul_mat_q8_0 < need_check > ( 2331vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2332nrows_dst ,item_ct1 , 2333get_pointer (tile_x_qs_q8_0_acc_ct1 ), 2334get_pointer (tile_x_d_q8_0_acc_ct1 ), 2335get_pointer (tile_y_qs_acc_ct1 ), 2336get_pointer (tile_y_ds_acc_ct1 )); 2337 }); 2338 }); 2339 } 2340 } 2341} 2342catch (sycl::exception const & exc ) { 2343 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2344 <<", line:" <<__LINE__ << std::endl ; 2345 std::exit (1 ); 2346} 2347 2348static void ggml_mul_mat_q2_K_q8_1_sycl (const void * vx ,const void * vy , 2349float * dst ,const int ncols_x , 2350const int nrows_x ,const int ncols_y , 2351const int nrows_y ,const int nrows_dst , 2352 dpct::queue_ptr stream )try { 2353 2354int id ; 2355SYCL_CHECK ( 2356CHECK_TRY_ERROR (id = get_current_device_id ())); 2357const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2358 2359int mmq_x ,mmq_y ,nwarps ; 2360if (compute_capability >=VER_GEN13 ) { 2361mmq_x = MMQ_X_Q2_K_RDNA2 ; 2362mmq_y = MMQ_Y_Q2_K_RDNA2 ; 2363nwarps = NWARPS_Q2_K_RDNA2 ; 2364 }else if (compute_capability >=VER_GEN12 ) { 2365mmq_x = MMQ_X_Q2_K_RDNA1 ; 2366mmq_y = MMQ_Y_Q2_K_RDNA1 ; 2367nwarps = NWARPS_Q2_K_RDNA1 ; 2368 }else if (compute_capability >=VER_GEN9 ) { 2369mmq_x = MMQ_X_Q2_K_AMPERE ; 2370mmq_y = MMQ_Y_Q2_K_AMPERE ; 2371nwarps = NWARPS_Q2_K_AMPERE ; 2372 }else if (compute_capability >=VER_4VEC ) { 2373mmq_x = MMQ_X_Q2_K_PASCAL ; 2374mmq_y = MMQ_Y_Q2_K_PASCAL ; 2375nwarps = NWARPS_Q2_K_PASCAL ; 2376 }else { 2377GGML_ABORT ("fatal error" ); 2378 } 2379 2380const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2381const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2382const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2383const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2384 2385if (nrows_x %mmq_y == 0 ) { 2386const bool need_check = false; 2387/* 2388DPCT1049:30: The work-group size passed to the SYCL kernel may exceed 2389the limit. To get the device limit, query 2390info::device::max_work_group_size. Adjust the work-group size if needed. 2391*/ 2392 { 2393 dpct::has_capability_or_fail (stream -> get_device (), 2394 {sycl::aspect::fp16 }); 2395 2396stream -> submit ([& ](sycl::handler & cgh ) { 2397 sycl::local_accessor < int ,1 > tile_x_ql_q2_K_acc_ct1 ( 2398 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2399 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q2_K_acc_ct1 ( 2400 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI2_K )+ mmq_y /QI2_K ), 2401cgh ); 2402 sycl::local_accessor < int ,1 > tile_x_sc_q2_K_acc_ct1 ( 2403 sycl::range < 1 > (mmq_y * (WARP_SIZE /4 )+ mmq_y /4 ),cgh ); 2404 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2405 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2406 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2407 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2408 2409cgh .parallel_for ( 2410 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2411 [= ](sycl::nd_item < 3 > item_ct1 ) { 2412mul_mat_q2_K < need_check > ( 2413vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2414nrows_dst ,item_ct1 , 2415get_pointer (tile_x_ql_q2_K_acc_ct1 ), 2416get_pointer (tile_x_dm_q2_K_acc_ct1 ), 2417get_pointer (tile_x_sc_q2_K_acc_ct1 ), 2418get_pointer (tile_y_qs_acc_ct1 ), 2419get_pointer (tile_y_ds_acc_ct1 )); 2420 }); 2421 }); 2422 } 2423 }else { 2424const bool need_check = true; 2425/* 2426DPCT1049:31: The work-group size passed to the SYCL kernel may exceed 2427the limit. To get the device limit, query 2428info::device::max_work_group_size. Adjust the work-group size if needed. 2429*/ 2430 { 2431 dpct::has_capability_or_fail (stream -> get_device (), 2432 {sycl::aspect::fp16 }); 2433 2434stream -> submit ([& ](sycl::handler & cgh ) { 2435 sycl::local_accessor < int ,1 > tile_x_ql_q2_K_acc_ct1 ( 2436 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2437 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q2_K_acc_ct1 ( 2438 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI2_K )+ mmq_y /QI2_K ), 2439cgh ); 2440 sycl::local_accessor < int ,1 > tile_x_sc_q2_K_acc_ct1 ( 2441 sycl::range < 1 > (mmq_y * (WARP_SIZE /4 )+ mmq_y /4 ),cgh ); 2442 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2443 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2444 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2445 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2446 2447cgh .parallel_for ( 2448 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2449 [= ](sycl::nd_item < 3 > item_ct1 ) { 2450mul_mat_q2_K < need_check > ( 2451vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2452nrows_dst ,item_ct1 , 2453get_pointer (tile_x_ql_q2_K_acc_ct1 ), 2454get_pointer (tile_x_dm_q2_K_acc_ct1 ), 2455get_pointer (tile_x_sc_q2_K_acc_ct1 ), 2456get_pointer (tile_y_qs_acc_ct1 ), 2457get_pointer (tile_y_ds_acc_ct1 )); 2458 }); 2459 }); 2460 } 2461 } 2462} 2463catch (sycl::exception const & exc ) { 2464 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2465 <<", line:" <<__LINE__ << std::endl ; 2466 std::exit (1 ); 2467} 2468 2469static void ggml_mul_mat_q3_K_q8_1_sycl (const void * vx ,const void * vy , 2470float * dst ,const int ncols_x , 2471const int nrows_x ,const int ncols_y , 2472const int nrows_y ,const int nrows_dst , 2473 dpct::queue_ptr stream )try { 2474 2475#if QK_K == 256 2476 2477int id ; 2478SYCL_CHECK ( 2479CHECK_TRY_ERROR (id = get_current_device_id ())); 2480const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2481 2482int mmq_x ,mmq_y ,nwarps ; 2483if (compute_capability >=VER_GEN13 ) { 2484mmq_x = MMQ_X_Q3_K_RDNA2 ; 2485mmq_y = MMQ_Y_Q3_K_RDNA2 ; 2486nwarps = NWARPS_Q3_K_RDNA2 ; 2487 }else if (compute_capability >=VER_GEN12 ) { 2488mmq_x = MMQ_X_Q3_K_RDNA1 ; 2489mmq_y = MMQ_Y_Q3_K_RDNA1 ; 2490nwarps = NWARPS_Q3_K_RDNA1 ; 2491 }else if (compute_capability >=VER_GEN9 ) { 2492mmq_x = MMQ_X_Q3_K_AMPERE ; 2493mmq_y = MMQ_Y_Q3_K_AMPERE ; 2494nwarps = NWARPS_Q3_K_AMPERE ; 2495 }else if (compute_capability >=VER_4VEC ) { 2496mmq_x = MMQ_X_Q3_K_PASCAL ; 2497mmq_y = MMQ_Y_Q3_K_PASCAL ; 2498nwarps = NWARPS_Q3_K_PASCAL ; 2499 }else { 2500GGML_ABORT ("fatal error" ); 2501 } 2502 2503const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2504const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2505const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2506const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2507 2508if (nrows_x %mmq_y == 0 ) { 2509const bool need_check = false; 2510/* 2511DPCT1049:32: The work-group size passed to the SYCL kernel may exceed 2512the limit. To get the device limit, query 2513info::device::max_work_group_size. Adjust the work-group size if needed. 2514*/ 2515 { 2516 dpct::has_capability_or_fail (stream -> get_device (), 2517 {sycl::aspect::fp16 }); 2518 2519stream -> submit ([& ](sycl::handler & cgh ) { 2520 sycl::local_accessor < int ,1 > tile_x_ql_q3_K_acc_ct1 ( 2521 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2522 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q3_K_acc_ct1 ( 2523 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI3_K )+ mmq_y /QI3_K ), 2524cgh ); 2525 sycl::local_accessor < int ,1 > tile_x_qh_q3_K_acc_ct1 ( 2526 sycl::range < 1 > (mmq_y * (WARP_SIZE /2 )+ mmq_y /2 ),cgh ); 2527 sycl::local_accessor < int ,1 > tile_x_sc_q3_K_acc_ct1 ( 2528 sycl::range < 1 > (mmq_y * (WARP_SIZE /4 )+ mmq_y /4 ),cgh ); 2529 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2530 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2531 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2532 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2533 2534cgh .parallel_for ( 2535 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2536 [= ](sycl::nd_item < 3 > item_ct1 ) { 2537mul_mat_q3_K < need_check > ( 2538vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2539nrows_dst ,item_ct1 , 2540get_pointer (tile_x_ql_q3_K_acc_ct1 ), 2541get_pointer (tile_x_dm_q3_K_acc_ct1 ), 2542get_pointer (tile_x_qh_q3_K_acc_ct1 ), 2543get_pointer (tile_x_sc_q3_K_acc_ct1 ), 2544get_pointer (tile_y_qs_acc_ct1 ), 2545get_pointer (tile_y_ds_acc_ct1 )); 2546 }); 2547 }); 2548 } 2549 }else { 2550const bool need_check = true; 2551/* 2552DPCT1049:33: The work-group size passed to the SYCL kernel may exceed 2553the limit. To get the device limit, query 2554info::device::max_work_group_size. Adjust the work-group size if needed. 2555*/ 2556 { 2557 dpct::has_capability_or_fail (stream -> get_device (), 2558 {sycl::aspect::fp16 }); 2559 2560stream -> submit ([& ](sycl::handler & cgh ) { 2561 sycl::local_accessor < int ,1 > tile_x_ql_q3_K_acc_ct1 ( 2562 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2563 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q3_K_acc_ct1 ( 2564 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI3_K )+ mmq_y /QI3_K ), 2565cgh ); 2566 sycl::local_accessor < int ,1 > tile_x_qh_q3_K_acc_ct1 ( 2567 sycl::range < 1 > (mmq_y * (WARP_SIZE /2 )+ mmq_y /2 ),cgh ); 2568 sycl::local_accessor < int ,1 > tile_x_sc_q3_K_acc_ct1 ( 2569 sycl::range < 1 > (mmq_y * (WARP_SIZE /4 )+ mmq_y /4 ),cgh ); 2570 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2571 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2572 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2573 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2574 2575cgh .parallel_for ( 2576 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2577 [= ](sycl::nd_item < 3 > item_ct1 ) { 2578mul_mat_q3_K < need_check > ( 2579vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2580nrows_dst ,item_ct1 , 2581get_pointer (tile_x_ql_q3_K_acc_ct1 ), 2582get_pointer (tile_x_dm_q3_K_acc_ct1 ), 2583get_pointer (tile_x_qh_q3_K_acc_ct1 ), 2584get_pointer (tile_x_sc_q3_K_acc_ct1 ), 2585get_pointer (tile_y_qs_acc_ct1 ), 2586get_pointer (tile_y_ds_acc_ct1 )); 2587 }); 2588 }); 2589 } 2590 } 2591#endif 2592} 2593catch (sycl::exception const & exc ) { 2594 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2595 <<", line:" <<__LINE__ << std::endl ; 2596 std::exit (1 ); 2597} 2598 2599static void ggml_mul_mat_q4_K_q8_1_sycl (const void * vx ,const void * vy , 2600float * dst ,const int ncols_x , 2601const int nrows_x ,const int ncols_y , 2602const int nrows_y ,const int nrows_dst , 2603 dpct::queue_ptr stream )try { 2604 2605int id ; 2606SYCL_CHECK ( 2607CHECK_TRY_ERROR (id = get_current_device_id ())); 2608const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2609 2610int mmq_x ,mmq_y ,nwarps ; 2611if (compute_capability >=VER_GEN13 ) { 2612mmq_x = MMQ_X_Q4_K_RDNA2 ; 2613mmq_y = MMQ_Y_Q4_K_RDNA2 ; 2614nwarps = NWARPS_Q4_K_RDNA2 ; 2615 }else if (compute_capability >=VER_GEN12 ) { 2616mmq_x = MMQ_X_Q4_K_RDNA1 ; 2617mmq_y = MMQ_Y_Q4_K_RDNA1 ; 2618nwarps = NWARPS_Q4_K_RDNA1 ; 2619 }else if (compute_capability >=VER_GEN9 ) { 2620mmq_x = MMQ_X_Q4_K_AMPERE ; 2621mmq_y = MMQ_Y_Q4_K_AMPERE ; 2622nwarps = NWARPS_Q4_K_AMPERE ; 2623 }else if (compute_capability >=VER_4VEC ) { 2624mmq_x = MMQ_X_Q4_K_PASCAL ; 2625mmq_y = MMQ_Y_Q4_K_PASCAL ; 2626nwarps = NWARPS_Q4_K_PASCAL ; 2627 }else { 2628GGML_ABORT ("fatal error" ); 2629 } 2630 2631const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2632const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2633const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2634const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2635 2636if (nrows_x %mmq_y == 0 ) { 2637const bool need_check = false; 2638/* 2639DPCT1049:34: The work-group size passed to the SYCL kernel may exceed 2640the limit. To get the device limit, query 2641info::device::max_work_group_size. Adjust the work-group size if needed. 2642*/ 2643 { 2644 dpct::has_capability_or_fail (stream -> get_device (), 2645 {sycl::aspect::fp16 }); 2646 2647stream -> submit ([& ](sycl::handler & cgh ) { 2648 sycl::local_accessor < int ,1 > tile_x_ql_q4_K_acc_ct1 ( 2649 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2650 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q4_K_acc_ct1 ( 2651 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_K )+ mmq_y /QI4_K ), 2652cgh ); 2653 sycl::local_accessor < int ,1 > tile_x_sc_q4_K_acc_ct1 ( 2654 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2655 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2656 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2657 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2658 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2659 2660cgh .parallel_for ( 2661 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2662 [= ](sycl::nd_item < 3 > item_ct1 ) { 2663mul_mat_q4_K < need_check > ( 2664vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2665nrows_dst ,item_ct1 , 2666get_pointer (tile_x_ql_q4_K_acc_ct1 ), 2667get_pointer (tile_x_dm_q4_K_acc_ct1 ), 2668get_pointer (tile_x_sc_q4_K_acc_ct1 ), 2669get_pointer (tile_y_qs_acc_ct1 ), 2670get_pointer (tile_y_ds_acc_ct1 )); 2671 }); 2672 }); 2673 } 2674 }else { 2675const bool need_check = true; 2676/* 2677DPCT1049:35: The work-group size passed to the SYCL kernel may exceed 2678the limit. To get the device limit, query 2679info::device::max_work_group_size. Adjust the work-group size if needed. 2680*/ 2681 { 2682 dpct::has_capability_or_fail (stream -> get_device (), 2683 {sycl::aspect::fp16 }); 2684 2685stream -> submit ([& ](sycl::handler & cgh ) { 2686 sycl::local_accessor < int ,1 > tile_x_ql_q4_K_acc_ct1 ( 2687 sycl::range < 1 > (mmq_y * (WARP_SIZE )+ mmq_y ),cgh ); 2688 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q4_K_acc_ct1 ( 2689 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI4_K )+ mmq_y /QI4_K ), 2690cgh ); 2691 sycl::local_accessor < int ,1 > tile_x_sc_q4_K_acc_ct1 ( 2692 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2693 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2694 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2695 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2696 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2697 2698cgh .parallel_for ( 2699 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2700 [= ](sycl::nd_item < 3 > item_ct1 ) { 2701mul_mat_q4_K < need_check > ( 2702vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2703nrows_dst ,item_ct1 , 2704get_pointer (tile_x_ql_q4_K_acc_ct1 ), 2705get_pointer (tile_x_dm_q4_K_acc_ct1 ), 2706get_pointer (tile_x_sc_q4_K_acc_ct1 ), 2707get_pointer (tile_y_qs_acc_ct1 ), 2708get_pointer (tile_y_ds_acc_ct1 )); 2709 }); 2710 }); 2711 } 2712 } 2713} 2714catch (sycl::exception const & exc ) { 2715 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2716 <<", line:" <<__LINE__ << std::endl ; 2717 std::exit (1 ); 2718} 2719 2720static void ggml_mul_mat_q5_K_q8_1_sycl (const void * vx ,const void * vy , 2721float * dst ,const int ncols_x , 2722const int nrows_x ,const int ncols_y , 2723const int nrows_y ,const int nrows_dst , 2724 dpct::queue_ptr stream )try { 2725 2726int id ; 2727SYCL_CHECK ( 2728CHECK_TRY_ERROR (id = get_current_device_id ())); 2729const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2730 2731int mmq_x ,mmq_y ,nwarps ; 2732if (compute_capability >=VER_GEN13 ) { 2733mmq_x = MMQ_X_Q5_K_RDNA2 ; 2734mmq_y = MMQ_Y_Q5_K_RDNA2 ; 2735nwarps = NWARPS_Q5_K_RDNA2 ; 2736 }else if (compute_capability >=VER_GEN12 ) { 2737mmq_x = MMQ_X_Q5_K_RDNA1 ; 2738mmq_y = MMQ_Y_Q5_K_RDNA1 ; 2739nwarps = NWARPS_Q5_K_RDNA1 ; 2740 }else if (compute_capability >=VER_GEN9 ) { 2741mmq_x = MMQ_X_Q5_K_AMPERE ; 2742mmq_y = MMQ_Y_Q5_K_AMPERE ; 2743nwarps = NWARPS_Q5_K_AMPERE ; 2744 }else if (compute_capability >=VER_4VEC ) { 2745mmq_x = MMQ_X_Q5_K_PASCAL ; 2746mmq_y = MMQ_Y_Q5_K_PASCAL ; 2747nwarps = NWARPS_Q5_K_PASCAL ; 2748 }else { 2749GGML_ABORT ("fatal error" ); 2750 } 2751 2752const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2753const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2754const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2755const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2756 2757if (nrows_x %mmq_y == 0 ) { 2758const bool need_check = false; 2759/* 2760DPCT1049:36: The work-group size passed to the SYCL kernel may exceed 2761the limit. To get the device limit, query 2762info::device::max_work_group_size. Adjust the work-group size if needed. 2763*/ 2764 { 2765 dpct::has_capability_or_fail (stream -> get_device (), 2766 {sycl::aspect::fp16 }); 2767 2768stream -> submit ([& ](sycl::handler & cgh ) { 2769 sycl::local_accessor < int ,1 > tile_x_ql_q5_K_acc_ct1 ( 2770 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2771 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q5_K_acc_ct1 ( 2772 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_K )+ mmq_y /QI5_K ), 2773cgh ); 2774 sycl::local_accessor < int ,1 > tile_x_sc_q5_K_acc_ct1 ( 2775 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2776 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2777 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2778 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2779 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2780 2781cgh .parallel_for ( 2782 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2783 [= ](sycl::nd_item < 3 > item_ct1 ) { 2784mul_mat_q5_K < need_check > ( 2785vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2786nrows_dst ,item_ct1 , 2787get_pointer (tile_x_ql_q5_K_acc_ct1 ), 2788get_pointer (tile_x_dm_q5_K_acc_ct1 ), 2789get_pointer (tile_x_sc_q5_K_acc_ct1 ), 2790get_pointer (tile_y_qs_acc_ct1 ), 2791get_pointer (tile_y_ds_acc_ct1 )); 2792 }); 2793 }); 2794 } 2795 }else { 2796const bool need_check = true; 2797/* 2798DPCT1049:37: The work-group size passed to the SYCL kernel may exceed 2799the limit. To get the device limit, query 2800info::device::max_work_group_size. Adjust the work-group size if needed. 2801*/ 2802 { 2803 dpct::has_capability_or_fail (stream -> get_device (), 2804 {sycl::aspect::fp16 }); 2805 2806stream -> submit ([& ](sycl::handler & cgh ) { 2807 sycl::local_accessor < int ,1 > tile_x_ql_q5_K_acc_ct1 ( 2808 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2809 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_q5_K_acc_ct1 ( 2810 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI5_K )+ mmq_y /QI5_K ), 2811cgh ); 2812 sycl::local_accessor < int ,1 > tile_x_sc_q5_K_acc_ct1 ( 2813 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2814 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2815 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2816 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2817 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2818 2819cgh .parallel_for ( 2820 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2821 [= ](sycl::nd_item < 3 > item_ct1 ) { 2822mul_mat_q5_K < need_check > ( 2823vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2824nrows_dst ,item_ct1 , 2825get_pointer (tile_x_ql_q5_K_acc_ct1 ), 2826get_pointer (tile_x_dm_q5_K_acc_ct1 ), 2827get_pointer (tile_x_sc_q5_K_acc_ct1 ), 2828get_pointer (tile_y_qs_acc_ct1 ), 2829get_pointer (tile_y_ds_acc_ct1 )); 2830 }); 2831 }); 2832 } 2833 } 2834} 2835catch (sycl::exception const & exc ) { 2836 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2837 <<", line:" <<__LINE__ << std::endl ; 2838 std::exit (1 ); 2839} 2840 2841static void ggml_mul_mat_q6_K_q8_1_sycl (const void * vx ,const void * vy , 2842float * dst ,const int ncols_x , 2843const int nrows_x ,const int ncols_y , 2844const int nrows_y ,const int nrows_dst , 2845 dpct::queue_ptr stream )try { 2846 2847int id ; 2848SYCL_CHECK ( 2849CHECK_TRY_ERROR (id = get_current_device_id ())); 2850const int compute_capability = ggml_sycl_info ().devices [id ].cc ; 2851 2852int mmq_x ,mmq_y ,nwarps ; 2853if (compute_capability >=VER_GEN13 ) { 2854mmq_x = MMQ_X_Q6_K_RDNA2 ; 2855mmq_y = MMQ_Y_Q6_K_RDNA2 ; 2856nwarps = NWARPS_Q6_K_RDNA2 ; 2857 }else if (compute_capability >=VER_GEN12 ) { 2858mmq_x = MMQ_X_Q6_K_RDNA1 ; 2859mmq_y = MMQ_Y_Q6_K_RDNA1 ; 2860nwarps = NWARPS_Q6_K_RDNA1 ; 2861 }else if (compute_capability >=VER_GEN9 ) { 2862mmq_x = MMQ_X_Q6_K_AMPERE ; 2863mmq_y = MMQ_Y_Q6_K_AMPERE ; 2864nwarps = NWARPS_Q6_K_AMPERE ; 2865 }else if (compute_capability >=VER_4VEC ) { 2866mmq_x = MMQ_X_Q6_K_PASCAL ; 2867mmq_y = MMQ_Y_Q6_K_PASCAL ; 2868nwarps = NWARPS_Q6_K_PASCAL ; 2869 }else { 2870GGML_ABORT ("fatal error" ); 2871 } 2872 2873const int block_num_x = (nrows_x + mmq_y - 1 ) /mmq_y ; 2874const int block_num_y = (ncols_y + mmq_x - 1 ) /mmq_x ; 2875const sycl::range < 3 > block_nums (1 ,block_num_y ,block_num_x ); 2876const sycl::range < 3 > block_dims (1 ,nwarps ,WARP_SIZE ); 2877 2878if (nrows_x %mmq_y == 0 ) { 2879const bool need_check = false; 2880/* 2881DPCT1049:38: The work-group size passed to the SYCL kernel may exceed 2882the limit. To get the device limit, query 2883info::device::max_work_group_size. Adjust the work-group size if needed. 2884*/ 2885 { 2886 dpct::has_capability_or_fail (stream -> get_device (), 2887 {sycl::aspect::fp16 }); 2888 2889stream -> submit ([& ](sycl::handler & cgh ) { 2890 sycl::local_accessor < int ,1 > tile_x_ql_acc_ct1 ( 2891 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2892 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_acc_ct1 ( 2893 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI6_K )+ mmq_y /QI6_K ), 2894cgh ); 2895 sycl::local_accessor < int ,1 > tile_x_sc_acc_ct1 ( 2896 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2897 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2898 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2899 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2900 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2901 2902cgh .parallel_for ( 2903 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2904 [= ](sycl::nd_item < 3 > item_ct1 ) { 2905mul_mat_q6_K < need_check > ( 2906vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2907nrows_dst ,item_ct1 , 2908get_pointer (tile_x_ql_acc_ct1 ), 2909get_pointer (tile_x_dm_acc_ct1 ), 2910get_pointer (tile_x_sc_acc_ct1 ), 2911get_pointer (tile_y_qs_acc_ct1 ), 2912get_pointer (tile_y_ds_acc_ct1 )); 2913 }); 2914 }); 2915 } 2916 }else { 2917const bool need_check = true; 2918/* 2919DPCT1049:39: The work-group size passed to the SYCL kernel may exceed 2920the limit. To get the device limit, query 2921info::device::max_work_group_size. Adjust the work-group size if needed. 2922*/ 2923 { 2924 dpct::has_capability_or_fail (stream -> get_device (), 2925 {sycl::aspect::fp16 }); 2926 2927stream -> submit ([& ](sycl::handler & cgh ) { 2928 sycl::local_accessor < int ,1 > tile_x_ql_acc_ct1 ( 2929 sycl::range < 1 > (mmq_y * (2 * WARP_SIZE )+ mmq_y ),cgh ); 2930 sycl::local_accessor < sycl::half2 ,1 > tile_x_dm_acc_ct1 ( 2931 sycl::range < 1 > (mmq_y * (WARP_SIZE /QI6_K )+ mmq_y /QI6_K ), 2932cgh ); 2933 sycl::local_accessor < int ,1 > tile_x_sc_acc_ct1 ( 2934 sycl::range < 1 > (mmq_y * (WARP_SIZE /8 )+ mmq_y /8 ),cgh ); 2935 sycl::local_accessor < int ,1 > tile_y_qs_acc_ct1 ( 2936 sycl::range < 1 > (mmq_x * WARP_SIZE ),cgh ); 2937 sycl::local_accessor < sycl::half2 ,1 > tile_y_ds_acc_ct1 ( 2938 sycl::range < 1 > (mmq_x * WARP_SIZE /QI8_1 ),cgh ); 2939 2940cgh .parallel_for ( 2941 sycl::nd_range < 3 > (block_nums * block_dims ,block_dims ), 2942 [= ](sycl::nd_item < 3 > item_ct1 ) { 2943mul_mat_q6_K < need_check > ( 2944vx ,vy ,dst ,ncols_x ,nrows_x ,ncols_y ,nrows_y , 2945nrows_dst ,item_ct1 , 2946get_pointer (tile_x_ql_acc_ct1 ), 2947get_pointer (tile_x_dm_acc_ct1 ), 2948get_pointer (tile_x_sc_acc_ct1 ), 2949get_pointer (tile_y_qs_acc_ct1 ), 2950get_pointer (tile_y_ds_acc_ct1 )); 2951 }); 2952 }); 2953 } 2954 } 2955} 2956catch (sycl::exception const & exc ) { 2957 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 2958 <<", line:" <<__LINE__ << std::endl ; 2959 std::exit (1 ); 2960} 2961 2962void ggml_sycl_op_mul_mat_q ( 2963ggml_backend_sycl_context & ctx , 2964const ggml_tensor * src0 ,const ggml_tensor * src1 ,ggml_tensor * dst , 2965const char * src0_dd_i ,const float * src1_ddf_i ,const char * src1_ddq_i , 2966float * dst_dd_i ,const int64_t row_low ,const int64_t row_high , 2967const int64_t src1_ncols ,const int64_t src1_padded_row_size , 2968const dpct::queue_ptr & stream )try { 2969 2970const int64_t ne00 = src0 -> ne [0 ]; 2971 2972const int64_t ne10 = src1 -> ne [0 ]; 2973GGML_ASSERT (ne10 %QK8_1 == 0 ); 2974 2975const int64_t ne0 = dst -> ne [0 ]; 2976 2977const int64_t row_diff = row_high - row_low ; 2978 2979int device_id ; 2980SYCL_CHECK ( 2981CHECK_TRY_ERROR (device_id = get_current_device_id ())); 2982 2983// the main device has a larger memory buffer to hold the results from all GPUs 2984// nrows_dst == nrows of the matrix that the dequantize_mul_mat kernel writes into 2985const int64_t nrows_dst = device_id == ctx .device ?ne0 :row_diff ; 2986 2987switch (src0 -> type ) { 2988case GGML_TYPE_Q4_0 : 2989ggml_mul_mat_q4_0_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 2990break ; 2991case GGML_TYPE_Q4_1 : 2992ggml_mul_mat_q4_1_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 2993break ; 2994case GGML_TYPE_Q5_0 : 2995ggml_mul_mat_q5_0_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 2996break ; 2997case GGML_TYPE_Q5_1 : 2998ggml_mul_mat_q5_1_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 2999break ; 3000case GGML_TYPE_Q8_0 : 3001ggml_mul_mat_q8_0_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3002break ; 3003case GGML_TYPE_Q2_K : 3004ggml_mul_mat_q2_K_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3005break ; 3006case GGML_TYPE_Q3_K : 3007ggml_mul_mat_q3_K_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3008break ; 3009case GGML_TYPE_Q4_K : 3010ggml_mul_mat_q4_K_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3011break ; 3012case GGML_TYPE_Q5_K : 3013ggml_mul_mat_q5_K_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3014break ; 3015case GGML_TYPE_Q6_K : 3016ggml_mul_mat_q6_K_q8_1_sycl (src0_dd_i ,src1_ddq_i ,dst_dd_i ,ne00 ,row_diff ,src1_ncols ,src1_padded_row_size ,nrows_dst ,stream ); 3017break ; 3018default : 3019GGML_ABORT ("fatal error" ); 3020 } 3021 3022GGML_UNUSED (src1 ); 3023GGML_UNUSED (dst ); 3024GGML_UNUSED (src1_ddf_i ); 3025} 3026catch (sycl::exception const & exc ) { 3027 std::cerr <<exc .what () <<"Exception caught at file:" <<__FILE__ 3028 <<", line:" <<__LINE__ << std::endl ; 3029 std::exit (1 ); 3030}