char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
304665fe7
char/aliceai-t5-moe
1// 2// MIT license 3// Copyright (C) 2025 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#ifndef GGML_SYCL_VECDOTQ_HPP 14#define GGML_SYCL_VECDOTQ_HPP 15 16#include "dpct/helper.hpp" 17#include "ggml.h" 18#include "type.hpp" 19#include "quants.hpp" 20 21typedef float (* vec_dot_q_sycl_t )(const void * __restrict__vbq ,const block_q8_1 * __restrict__bq8_1 , 22const int & iqs ); 23 24static __dpct_inline__ int get_int_b1 (const void * x ,const int & i32 ) { 25const uint8_t * x8 = (const uint8_t * )x ; 26 27int x32 = x8 [4 * i32 + 0 ] <<0 ; 28x32 |=x8 [4 * i32 + 1 ] <<8 ; 29x32 |=x8 [4 * i32 + 2 ] <<16 ; 30x32 |=x8 [4 * i32 + 3 ] <<24 ; 31 32return x32 ; 33} 34 35static __dpct_inline__ int get_int_b2 (const void * x ,const int & i32 ) { 36const uint16_t * x16 = (const uint16_t * )x ;// assume at least 2 byte alignment 37 38int x32 = x16 [2 * i32 + 0 ] <<0 ; 39x32 |=x16 [2 * i32 + 1 ] <<16 ; 40 41return x32 ; 42} 43 44static __dpct_inline__ int get_int_b4 (const void * x ,const int & i32 ) { 45return ((const int * )x )[i32 ];// assume at least 4 byte alignment 46} 47 48static __dpct_inline__ int get_int_from_int8 (const int8_t * x8 ,const int & i32 ) { 49const uint16_t * x16 = 50 (const uint16_t * )(x8 + sizeof (int )* i32 );// assume at least 2 byte 51// alignment 52 53int x32 = 0 ; 54x32 |=x16 [0 ] <<0 ; 55x32 |=x16 [1 ] <<16 ; 56 57return x32 ; 58} 59 60static __dpct_inline__ int get_int_from_uint8 ( 61const uint8_t * x8 , 62const int & i32 ) { 63const uint16_t * x16 = 64 (const uint16_t * )(x8 + sizeof (int )* i32 );// assume at least 2 byte 65// alignment 66 67int x32 = 0 ; 68x32 |=x16 [0 ] <<0 ; 69x32 |=x16 [1 ] <<16 ; 70 71return x32 ; 72} 73 74static __dpct_inline__ int get_int_from_int8_aligned ( 75const int8_t * x8 , 76const int & i32 ) { 77return * ( 78 (const int * )(x8 + sizeof (int )* i32 ));// assume at least 4 byte alignment 79} 80 81static __dpct_inline__ int get_int_from_uint8_aligned ( 82const uint8_t * x8 , 83const int & i32 ) { 84return * ( 85 (const int * )(x8 + sizeof (int )* i32 ));// assume at least 4 byte alignment 86} 87 88static __dpct_inline__ int byte_sub_4 (const int a ,const int b ) { 89const uint32_t ua = static_cast < uint32_t > (a ); 90const uint32_t ub = static_cast < uint32_t > (b ); 91return static_cast < int > (((ua |0x80808080u )- ub ) ^0x80808080u ); 92} 93 94static __dpct_inline__ float vec_dot_q6_K_q8_1_impl_mmvq_scalar ( 95const int vl ,const int vh ,const int u0 ,const int u1 ,const int8_t sc0 , 96const int8_t sc1 ,const float d ,const float d80 ,const float d81 ) { 97 static_assert(QR6_K == 2 ,"q6_K MMVQ scalar fast path assumes QR6_K == 2" ); 98 99const int vil0 = (vl >>0 )& 0x0F0F0F0F ; 100const int vih0 = ((vh >>0 ) <<4 )& 0x30303030 ; 101const int vi0 = byte_sub_4 (vil0 |vih0 ,0x20202020 ); 102 103const int vil1 = (vl >>4 )& 0x0F0F0F0F ; 104const int vih1 = ((vh >>4 ) <<4 )& 0x30303030 ; 105const int vi1 = byte_sub_4 (vil1 |vih1 ,0x20202020 ); 106 107const float sumf = 108d80 * (dpct::dp4a (vi0 ,u0 ,0 )* sc0 )+ 109d81 * (dpct::dp4a (vi1 ,u1 ,0 )* sc1 ); 110 111return d * sumf ; 112} 113 114static __dpct_inline__ void get_int_from_table_16 (const uint32_t & q4 , 115const uint8_t * values , 116int & val1 ,int & val2 ) { 117 118uint32_t aux32 ;const uint8_t * q8 = (const uint8_t * )& aux32 ; 119aux32 = q4 & 0x0f0f0f0f ; 120uint16_t v1 = values [q8 [0 ]] | (values [q8 [1 ]] <<8 ); 121uint16_t v2 = values [q8 [2 ]] | (values [q8 [3 ]] <<8 ); 122val1 = v1 | (v2 <<16 ); 123aux32 = (q4 >>4 )& 0x0f0f0f0f ; 124v1 = values [q8 [0 ]] | (values [q8 [1 ]] <<8 ); 125v2 = values [q8 [2 ]] | (values [q8 [3 ]] <<8 ); 126val2 = v1 | (v2 <<16 ); 127} 128 129static __dpct_inline__ sycl::int2 get_int_from_table_16 ( 130const int & q4 ,const int8_t * table ) { 131const uint32_t * table32 = (const uint32_t * )table ; 132uint32_t tmp [2 ]; 133const uint32_t low_high_selection_indices = 134 (0x32103210 | ((q4 & 0x88888888 ) >>1 )); 135#pragma unroll 136for (uint32_t i = 0 ;i < 2 ;++ i ) { 137const uint32_t shift = 16 * i ; 138 139const uint32_t low = 140 dpct::byte_level_permute (table32 [0 ],table32 [1 ],q4 >>shift ); 141const uint32_t high = 142 dpct::byte_level_permute (table32 [2 ],table32 [3 ],q4 >>shift ); 143tmp [i ]= dpct::byte_level_permute ( 144low ,high ,low_high_selection_indices >>shift ); 145 } 146return sycl::int2 ( 147 dpct::byte_level_permute (tmp [0 ],tmp [1 ],0x6420 ), 148 dpct::byte_level_permute (tmp [0 ],tmp [1 ],0x7531 )); 149} 150 151#define VDR_Q2_K_Q8_1_MMVQ 1 152 153// contiguous v/x values 154static __dpct_inline__ float vec_dot_q2_K_q8_1_impl_mmvq ( 155const int & v ,const int * __restrict__u ,const uint8_t * __restrict__scales , 156const sycl::half2 & dm2 ,const float * __restrict__d8 ) { 157 158float sumf_d = 0.0f ; 159float sumf_m = 0.0f ; 160 161#pragma unroll 162for (int i = 0 ;i < QR2_K ;++ i ) { 163const int sc = scales [2 * i ]; 164 165const int vi = (v >> (2 * i ))& 0x03030303 ; 166 167sumf_d += 168d8 [i ]* (dpct::dp4a (vi ,u [i ],0 )* (sc & 0xF ));// SIMD dot product 169 170// fill int with 4x m 171int m = sc >>4 ; 172m |=m <<8 ; 173m |=m <<16 ; 174sumf_m += d8 [i ]* 175 dpct::dp4a ( 176m ,u [i ], 1770 );// multiply constant q2_K part with sum of q8_1 values 178 } 179 180const sycl::float2 dm2f = 181dm2 .convert < float , sycl::rounding_mode::automatic > (); 182 183return dm2f .x ()* sumf_d - dm2f .y ()* sumf_m ; 184} 185 186 187#define VDR_Q3_K_Q8_1_MMVQ 1 188 189// contiguous v/x values 190static __dpct_inline__ float vec_dot_q3_K_q8_1_impl_mmvq ( 191const int & vl ,const int & vh ,const int * __restrict__u , 192const uint8_t * __restrict__scales ,const int & scale_offset , 193const float & d3 ,const float * __restrict__d8 ) { 194 195float sumf = 0.0f ; 196 197#pragma unroll 198for (int i = 0 ;i < QR3_K ;++ i ) { 199const int isc = scale_offset + 2 * i ; 200 201const int isc_low = isc % (QK_K /32 ); 202const int sc_shift_low = 4 * (isc / (QK_K /32 )); 203const int sc_low = (scales [isc_low ] >>sc_shift_low )& 0xF ; 204 205const int isc_high = isc % (QK_K /64 ); 206const int sc_shift_high = 2 * (isc / (QK_K /64 )); 207const int sc_high = ((scales [(QK_K /32 )+ isc_high ] >>sc_shift_high )& 3 ) <<4 ; 208 209const int sc = (sc_low |sc_high )- 32 ; 210 211const int vil = (vl >> (2 * i ))& 0x03030303 ; 212 213const int vih = ((vh >>i ) <<2 )& 0x04040404 ; 214 215const int vi = 216 dpct::vectorized_binary < sycl::char4 > (vil ,vih , dpct::sub_sat ()); 217 218sumf += d8 [i ]* (dpct::dp4a (vi ,u [i ],0 )* sc );// SIMD dot product 219 } 220 221return d3 * sumf ; 222} 223 224#define VDR_Q4_K_Q8_1_MMVQ 2 225 226// contiguous v/x values 227static __dpct_inline__ float vec_dot_q4_K_q8_1_impl_vmmq ( 228const int * __restrict__v ,const int * __restrict__u , 229const uint8_t * __restrict__sc ,const uint8_t * __restrict__m , 230const sycl::half2 & dm4 ,const float * __restrict__d8 ) { 231 232float sumf_d = 0.0f ; 233float sumf_m = 0.0f ; 234 235#pragma unroll 236for (int i = 0 ;i < QR4_K ;++ i ) { 237const int v0i = (v [0 ] >> (4 * i ))& 0x0F0F0F0F ; 238const int v1i = (v [1 ] >> (4 * i ))& 0x0F0F0F0F ; 239 240const int dot1 = 241 dpct::dp4a (v1i ,u [2 * i + 1 ], 242 dpct::dp4a (v0i ,u [2 * i + 0 ],0 ));// SIMD dot product 243const int dot2 = 244 dpct::dp4a (0x01010101 ,u [2 * i + 1 ], 245 dpct::dp4a (0x01010101 ,u [2 * i + 0 ],0 ));// sum of u 246 247sumf_d += d8 [i ]* (dot1 * sc [i ]); 248sumf_m += d8 [i ]* (dot2 * m [i ]);// multiply constant part of q4_K with sum of q8_1 values 249 } 250 251const sycl::float2 dm4f = 252dm4 .convert < float , sycl::rounding_mode::automatic > (); 253 254return dm4f .x ()* sumf_d - dm4f .y ()* sumf_m ; 255} 256 257 258#define VDR_Q5_K_Q8_1_MMVQ 2 259 260// contiguous v/x values 261static __dpct_inline__ float vec_dot_q5_K_q8_1_impl_vmmq ( 262const int * __restrict__vl ,const int * __restrict__vh , 263const int * __restrict__u ,const uint8_t * __restrict__sc , 264const uint8_t * __restrict__m ,const sycl::half2 & dm5 , 265const float * __restrict__d8 ) { 266 267float sumf_d = 0.0f ; 268float sumf_m = 0.0f ; 269 270#pragma unroll 271for (int i = 0 ;i < QR5_K ;++ i ) { 272const int vl0i = (vl [0 ] >> (4 * i ))& 0x0F0F0F0F ; 273const int vl1i = (vl [1 ] >> (4 * i ))& 0x0F0F0F0F ; 274 275const int vh0i = ((vh [0 ] >>i ) <<4 )& 0x10101010 ; 276const int vh1i = ((vh [1 ] >>i ) <<4 )& 0x10101010 ; 277 278const int v0i = vl0i |vh0i ; 279const int v1i = vl1i |vh1i ; 280 281const int dot1 = 282 dpct::dp4a (v0i ,u [2 * i + 0 ], 283 dpct::dp4a (v1i ,u [2 * i + 1 ],0 ));// SIMD dot product 284const int dot2 = 285 dpct::dp4a (0x01010101 ,u [2 * i + 0 ], 286 dpct::dp4a (0x01010101 ,u [2 * i + 1 ],0 ));// sum of u 287 288sumf_d += d8 [i ]* (dot1 * sc [i ]); 289sumf_m += d8 [i ]* (dot2 * m [i ]); 290 291 } 292 293const sycl::float2 dm5f = 294dm5 .convert < float , sycl::rounding_mode::automatic > (); 295 296return dm5f .x ()* sumf_d - dm5f .y ()* sumf_m ; 297} 298 299 300#define VDR_Q6_K_Q8_1_MMVQ 1 301 302// contiguous v/x values 303static __dpct_inline__ float 304vec_dot_q6_K_q8_1_impl_mmvq (const int & vl ,const int & vh , 305const int * __restrict__u , 306const int8_t * __restrict__scales ,const float & d , 307const float * __restrict__d8 ) { 308return vec_dot_q6_K_q8_1_impl_mmvq_scalar ( 309vl ,vh ,u [0 ],u [1 ],scales [0 ],scales [4 ],d ,d8 [0 ],d8 [1 ]); 310} 311 312#define VDR_Q1_0_Q8_1_MMVQ 1 313#define VDR_Q1_0_Q8_1_MMQ 4 314 315static __dpct_inline__ float 316vec_dot_q1_0_q8_1 (const void * __restrict__vbq , 317const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 318 319const block_q1_0 * bq1_0 = (const block_q1_0 * )vbq ; 320 321const block_q8_1 * bq8_1_chunk = bq8_1 + iqs ; 322const float d1 = bq1_0 -> d ; 323const int v = get_int_from_uint8_aligned (bq1_0 -> qs ,iqs ); 324 325int vi_bytes [8 ]; 326#pragma unroll 327for (int j = 0 ;j < 8 ;++ j ) { 328const int shift = j * 4 ; 329const int bits4 = (v >>shift )& 0x0F ; 330const int b0 = (bits4 & 0x01 ) ?1 :-1 ; 331const int b1 = (bits4 & 0x02 ) ?1 :-1 ; 332const int b2 = (bits4 & 0x04 ) ?1 :-1 ; 333const int b3 = (bits4 & 0x08 ) ?1 :-1 ; 334vi_bytes [j ]= (b0 & 0xFF ) | ((b1 & 0xFF ) <<8 ) | ((b2 & 0xFF ) <<16 ) | ((b3 & 0xFF ) <<24 ); 335 } 336 337int sumi = 0 ; 338#pragma unroll 339for (int j = 0 ;j < 8 ;++ j ) { 340const int u = get_int_from_int8_aligned (bq8_1_chunk -> qs ,j ); 341sumi = ggml_sycl_dp4a (vi_bytes [j ],u ,sumi ); 342 } 343 344return d1 * bq8_1_chunk -> ds [0 ]* sumi ; 345} 346 347// VDR = vec dot ratio, how many contiguous integers each thread processes when the vec dot kernel is called 348// MMVQ = mul_mat_vec_q, MMQ = mul_mat_q 349 350template < ggml_type T > struct reorder_vec_dot_q_sycl { 351 static_assert(T != T ,"ggml_type for reorder vecdot not implemented" ); 352}; 353 354// For some types the weight side of the dot product does not depend on the destination column, so a 355// multi-column mul_mat_vec can unpack it once per block instead of once per column. Such a type adds 356// load() and dot() next to operator() and opts in here. See reorder_vec_dot_q_sycl<GGML_TYPE_Q4_K>. 357template < ggml_type T > struct reorder_vec_dot_shared_weights { 358static constexpr bool value = false; 359}; 360 361template <> struct reorder_vec_dot_shared_weights < GGML_TYPE_Q4_K > { 362static constexpr bool value = true; 363}; 364 365template < ggml_type T > struct reorder_vec_dot_shared_activations { 366static constexpr bool value = false; 367}; 368 369template <> struct reorder_vec_dot_shared_activations < GGML_TYPE_Q4_K > { 370static constexpr bool value = true; 371}; 372 373template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q4_0 > { 374static constexpr ggml_type gtype = GGML_TYPE_Q4_0 ; 375 376using q4_0_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q4_0 > ; 377using q4_0_traits = typename q4_0_block::traits ; 378 379__dpct_inline__ float vec_dot_q4_0_q8_1_impl (const int * v ,const int * u ,const float & d4 ,const sycl::half2 & ds8 ) { 380int sumi = 0 ; 381 382#pragma unroll 383for (size_t i = 0 ;i < q4_0_traits::vdr_mmvq ;++ i ) { 384const int vi0 = (v [i ] >>0 )& 0x0F0F0F0F ; 385const int vi1 = (v [i ] >>4 )& 0x0F0F0F0F ; 386 387// SIMD dot product of quantized values 388sumi = dpct::dp4a (vi0 ,u [2 * i + 0 ],sumi ); 389sumi = dpct::dp4a (vi1 ,u [2 * i + 1 ],sumi ); 390 } 391 392const sycl::float2 ds8f = ds8 .convert < float , sycl::rounding_mode::automatic > (); 393 394// second part effectively subtracts 8 from each quant value 395return d4 * (sumi * ds8f .x ()- (8 * q4_0_traits::vdr_mmvq / q4_0_traits::qi )* ds8f .y ()); 396 } 397 398__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 399const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 400const sycl::half2 * q8_1_ds ,const int & iqs ) { 401const uint8_t * bq4_0 = static_cast < const uint8_t *> (vbq )+ ibx_offset .first ; 402const ggml_half d = * (reinterpret_cast < const ggml_half *> (static_cast < const uint8_t *> (vbq )+ d_offset .first )); 403int v [q4_0_traits::vdr_mmvq ]; 404int u [2 * q4_0_traits::vdr_mmvq ]; 405 406 407#pragma unroll 408for (size_t i = 0 ;i < q4_0_traits::vdr_mmvq ;++ i ) { 409v [i ]= get_int_from_uint8 (bq4_0 ,iqs + i ); 410u [2 * i + 0 ]= get_int_from_int8_aligned (q8_1_quant_ptr ,iqs + i ); 411u [2 * i + 1 ]= get_int_from_int8_aligned (q8_1_quant_ptr ,iqs + i + q4_0_traits::qi ); 412 } 413 414return vec_dot_q4_0_q8_1_impl (v ,u ,d ,* q8_1_ds ); 415 }; 416}; 417 418template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q8_0 > { 419static constexpr ggml_type gtype = GGML_TYPE_Q8_0 ; 420 421using q8_0_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q8_0 > ; 422using q8_0_traits = typename q8_0_block::traits ; 423 424__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 425const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 426const sycl::half2 * q8_1_ds ,const int & iqs ) { 427const uint8_t * base = static_cast < const uint8_t *> (vbq ); 428const int8_t * qs = reinterpret_cast < const int8_t *> (base + ibx_offset .first ); 429const ggml_half d = * reinterpret_cast < const ggml_half *> (base + d_offset .first ); 430 431int v [q8_0_traits::vdr_mmvq ]; 432int u [q8_0_traits::vdr_mmvq ]; 433 434#pragma unroll 435for (size_t i = 0 ;i < q8_0_traits::vdr_mmvq ;++ i ) { 436v [i ]= get_int_from_int8 (qs ,iqs + i ); 437u [i ]= get_int_from_int8_aligned (q8_1_quant_ptr ,iqs + i ); 438 } 439 440int sumi = 0 ; 441#pragma unroll 442for (size_t i = 0 ;i < q8_0_traits::vdr_mmvq ;++ i ) { 443sumi = dpct::dp4a (v [i ],u [i ],sumi ); 444 } 445 446const sycl::half2 ds_values = * q8_1_ds ; 447return static_cast < float > (d )* static_cast < float > (ds_values [0 ])* sumi ; 448 } 449}; 450 451template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q2_K > { 452static constexpr ggml_type gtype = GGML_TYPE_Q2_K ; 453 454using q2_k_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q2_K > ; 455using q2_k_traits = typename q2_k_block::traits ; 456 457__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 458const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 459const sycl::half2 * q8_1_ds ,const int & iqs ) { 460const uint8_t * base = static_cast < const uint8_t *> (vbq ); 461const uint8_t * qs = base + ibx_offset .first ; 462const uint8_t * scales = base + d_offset .first ; 463const ggml_half2 * dm = reinterpret_cast < const ggml_half2 *> (base + d_offset .second ); 464 465const int bq8_offset = QR2_K * (iqs /QI8_1 ); 466const int scale_offset = iqs - iqs %QI8_1 + (iqs %QI8_1 ) / (QI8_1 /2 ); 467 468const int v = get_int_from_uint8_aligned (qs ,iqs ); 469 470int u [QR2_K ]; 471float d8 [QR2_K ]; 472 473#pragma unroll 474for (int i = 0 ;i < QR2_K ;++ i ) { 475const int8_t * quant_base_ptr = q8_1_quant_ptr + (bq8_offset + i )* QK8_1 ; 476u [i ]= get_int_from_int8_aligned (quant_base_ptr ,iqs %QI8_1 ); 477d8 [i ]= (* (q8_1_ds + bq8_offset + i ))[0 ]; 478 } 479 480return vec_dot_q2_K_q8_1_impl_mmvq (v ,u ,scales + scale_offset ,* dm ,d8 ); 481 } 482}; 483 484template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q3_K > { 485static constexpr ggml_type gtype = GGML_TYPE_Q3_K ; 486 487using q3_k_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q3_K > ; 488using q3_k_traits = typename q3_k_block::traits ; 489 490__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 491const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 492const sycl::half2 * q8_1_ds ,const int & iqs ) { 493const uint8_t * base = static_cast < const uint8_t *> (vbq ); 494const uint8_t * qs = base + ibx_offset .first ; 495const uint8_t * hmask = base + ibx_offset .second ; 496const uint8_t * scales = base + d_offset .first ; 497const ggml_half d = * reinterpret_cast < const ggml_half *> (base + d_offset .second ); 498 499const int bq8_offset = QR3_K * (iqs / (QI3_K /2 )); 500const int scale_offset = iqs - iqs %QI8_1 + (iqs %QI8_1 ) / (QI8_1 /2 ); 501 502const int vl = get_int_from_uint8 (qs ,iqs ); 503const int vh = ~get_int_from_uint8 (hmask ,iqs % (QI3_K /2 )) >>bq8_offset ; 504 505int u [QR3_K ]; 506float d8 [QR3_K ]; 507 508#pragma unroll 509for (int i = 0 ;i < QR3_K ;++ i ) { 510const int8_t * quant_base_ptr = q8_1_quant_ptr + (bq8_offset + i )* QK8_1 ; 511u [i ]= get_int_from_int8_aligned (quant_base_ptr ,iqs %QI8_1 ); 512d8 [i ]= (* (q8_1_ds + bq8_offset + i ))[0 ]; 513 } 514 515return vec_dot_q3_K_q8_1_impl_mmvq (vl ,vh ,u ,scales ,scale_offset ,static_cast < float > (d ),d8 ); 516 } 517}; 518 519static inline float vec_dot_q4_K_q8_1_common (const int * __restrict__q4 ,const uint16_t * __restrict__scales , 520const ggml_half2 & dm ,const block_q8_1 * __restrict__bq8_1 , 521const int & iqs ) { 522int v [2 ]; 523int u [2 * QR4_K ]; 524float d8 [QR4_K ]; 525 526v [0 ]= q4 [0 ]; 527v [1 ]= q4 [4 ]; 528 529uint16_t aux [2 ]; 530const int j = (QR4_K * ((iqs /2 ) / (QI8_1 /2 ))) /2 ; 531if (j < 2 ) { 532aux [0 ]= scales [j + 0 ]& 0x3f3f ; 533aux [1 ]= scales [j + 2 ]& 0x3f3f ; 534 }else { 535aux [0 ]= ((scales [j + 2 ] >>0 )& 0x0f0f ) | ((scales [j - 2 ]& 0xc0c0 ) >>2 ); 536aux [1 ]= ((scales [j + 2 ] >>4 )& 0x0f0f ) | ((scales [j - 0 ]& 0xc0c0 ) >>2 ); 537 } 538 539const uint8_t * sc = (const uint8_t * )aux ; 540const uint8_t * m = sc + 2 ; 541 542const int bq8_offset = QR4_K * ((iqs /2 ) / (QI8_1 /2 )); 543 544for (int i = 0 ;i < QR4_K ;++ i ) { 545const block_q8_1 * bq8i = bq8_1 + bq8_offset + i ; 546d8 [i ]= bq8i -> ds [0 ]; 547 548const int * q8 = (const int * )bq8i -> qs + ((iqs /2 ) %4 ); 549u [2 * i + 0 ]= q8 [0 ]; 550u [2 * i + 1 ]= q8 [4 ]; 551 } 552 553return vec_dot_q4_K_q8_1_impl_vmmq (v ,u ,sc ,m ,dm ,d8 ); 554} 555 556template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q4_K > { 557static constexpr ggml_type gtype = GGML_TYPE_Q4_K ; 558 559using q4_k_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q4_K > ; 560using q4_k_traits = typename q4_k_block::traits ; 561 562struct weights { 563int v [2 ]; 564uint16_t aux [2 ]; 565ggml_half2 dm ; 566int bq8_offset ; 567 }; 568 569struct activations { 570int u [2 * QR4_K ]; 571float d8 [QR4_K ]; 572 }; 573 574__dpct_inline__ static weights load (const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 575const std::pair < int ,int > d_offset ,const int & iqs ) { 576const uint8_t * base = static_cast < const uint8_t *> (vbq ); 577const uint8_t * qs = base + ibx_offset .first ; 578const uint8_t * scs = base + d_offset .first ; 579const ggml_half2 * dms = reinterpret_cast < const ggml_half2 *> (base + d_offset .second ); 580 581weights w ; 582w .bq8_offset = QR4_K * ((iqs /2 ) / (QI8_1 /2 )); 583 584const int * q4 = (const int * ) (qs + 16 * w .bq8_offset + 4 * ((iqs /2 ) %4 )); 585const uint16_t * scales = (const uint16_t * )scs ; 586 587w .v [0 ]= q4 [0 ]; 588w .v [1 ]= q4 [4 ]; 589 590const int j = (QR4_K * ((iqs /2 ) / (QI8_1 /2 ))) /2 ; 591if (j < 2 ) { 592w .aux [0 ]= scales [j + 0 ]& 0x3f3f ; 593w .aux [1 ]= scales [j + 2 ]& 0x3f3f ; 594 }else { 595w .aux [0 ]= ((scales [j + 2 ] >>0 )& 0x0f0f ) | ((scales [j - 2 ]& 0xc0c0 ) >>2 ); 596w .aux [1 ]= ((scales [j + 2 ] >>4 )& 0x0f0f ) | ((scales [j - 0 ]& 0xc0c0 ) >>2 ); 597 } 598 599w .dm = * dms ; 600 601return w ; 602 } 603 604__dpct_inline__ static activations load_activations (const int8_t * q8_1_quant_ptr , 605const sycl::half2 * q8_1_ds ,const int & iqs ) { 606activations a ; 607const int bq8_offset = QR4_K * ((iqs /2 ) / (QI8_1 /2 )); 608for (int i = 0 ;i < QR4_K ;++ i ) { 609const int8_t * quant_base_ptr = q8_1_quant_ptr + (bq8_offset + i )* QK8_1 ; 610 sycl::half2 ds_values = * (q8_1_ds + bq8_offset + i ); 611 612a .d8 [i ]= ds_values [0 ]; 613 614const int * q8 = (const int * )quant_base_ptr + ((iqs /2 ) %4 ); 615a .u [2 * i + 0 ]= q8 [0 ]; 616a .u [2 * i + 1 ]= q8 [4 ]; 617 } 618 619return a ; 620 } 621 622__dpct_inline__ static float apply (const weights & w ,const activations & a ) { 623const uint8_t * sc = (const uint8_t * )w .aux ; 624const uint8_t * m = sc + 2 ; 625 626return vec_dot_q4_K_q8_1_impl_vmmq (w .v ,a .u ,sc ,m ,w .dm ,a .d8 ); 627 } 628 629__dpct_inline__ static float dot (const weights & w ,const int8_t * q8_1_quant_ptr , 630const sycl::half2 * q8_1_ds ,const int & iqs ) { 631const auto a = load_activations (q8_1_quant_ptr ,q8_1_ds ,iqs ); 632 633return apply (w ,a ); 634 } 635 636__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 637const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 638const sycl::half2 * q8_1_ds ,const int & iqs ) { 639return dot (load (vbq ,ibx_offset ,d_offset ,iqs ),q8_1_quant_ptr ,q8_1_ds ,iqs ); 640 } 641}; 642 643template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q5_K > { 644static constexpr ggml_type gtype = GGML_TYPE_Q5_K ; 645 646using q5_k_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q5_K > ; 647using q5_k_traits = typename q5_k_block::traits ; 648 649__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 650const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr , 651const sycl::half2 * q8_1_ds ,const int & iqs ) { 652const uint8_t * base = static_cast < const uint8_t *> (vbq ); 653const uint8_t * qs = base + ibx_offset .first ;// low 4 bits 654const uint8_t * qh_base = base + ibx_offset .second ;// high bit 655const uint8_t * scs = base + d_offset .first ; 656const ggml_half2 * dms = reinterpret_cast < const ggml_half2 *> (base + d_offset .second ); 657 658const int bq8_offset = QR5_K * ((iqs /2 ) / (QI8_1 /2 )); 659const int * ql_ptr = (const int * ) (qs + 16 * bq8_offset + 4 * ((iqs /2 ) %4 )); 660const int * qh_ptr = (const int * ) (qh_base + 4 * ((iqs /2 ) %4 )); 661const uint16_t * scales = (const uint16_t * )scs ; 662 663int vl [2 ]; 664int vh [2 ]; 665int u [2 * QR5_K ]; 666float d8 [QR5_K ]; 667 668vl [0 ]= ql_ptr [0 ]; 669vl [1 ]= ql_ptr [4 ]; 670 671vh [0 ]= qh_ptr [0 ] >>bq8_offset ; 672vh [1 ]= qh_ptr [4 ] >>bq8_offset ; 673 674uint16_t aux [2 ]; 675const int j = (QR5_K * ((iqs /2 ) / (QI8_1 /2 ))) /2 ; 676if (j < 2 ) { 677aux [0 ]= scales [j + 0 ]& 0x3f3f ; 678aux [1 ]= scales [j + 2 ]& 0x3f3f ; 679 }else { 680aux [0 ]= ((scales [j + 2 ] >>0 )& 0x0f0f ) | ((scales [j - 2 ]& 0xc0c0 ) >>2 ); 681aux [1 ]= ((scales [j + 2 ] >>4 )& 0x0f0f ) | ((scales [j - 0 ]& 0xc0c0 ) >>2 ); 682 } 683 684const uint8_t * sc = (const uint8_t * )aux ; 685const uint8_t * m = sc + 2 ; 686 687for (int i = 0 ;i < QR5_K ;++ i ) { 688const int8_t * quant_base_ptr = q8_1_quant_ptr + (bq8_offset + i )* QK8_1 ; 689 sycl::half2 ds_values = * (q8_1_ds + bq8_offset + i ); 690 691d8 [i ]= ds_values [0 ]; 692 693const int * q8 = (const int * )quant_base_ptr + ((iqs /2 ) %4 ); 694u [2 * i + 0 ]= q8 [0 ]; 695u [2 * i + 1 ]= q8 [4 ]; 696 } 697 698return vec_dot_q5_K_q8_1_impl_vmmq (vl ,vh ,u ,sc ,m ,* dms ,d8 ); 699 } 700}; 701 702template <> struct reorder_vec_dot_q_sycl < GGML_TYPE_Q6_K > { 703static constexpr ggml_type gtype = GGML_TYPE_Q6_K ; 704 705using q6_k_block = ggml_sycl_reordered::block_q_t < GGML_TYPE_Q6_K > ; 706using q6_k_traits = typename q6_k_block::traits ; 707 708__dpct_inline__ float vec_dot_q6_K_q8_1_impl_mmvq (const int vl ,const int vh ,const int * __restrict__u , 709const int8_t * __restrict__scales ,const float d , 710const float * __restrict__d8 ) { 711return vec_dot_q6_K_q8_1_impl_mmvq_scalar ( 712vl ,vh ,u [0 ],u [1 ],scales [0 ],scales [4 ],d ,d8 [0 ],d8 [1 ]); 713 } 714 715__dpct_inline__ float operator()(const void * __restrict__vbq ,const std::pair < int ,int > ibx_offset , 716const std::pair < int ,int > d_offset ,const int8_t * q8_1_quant_ptr ,const sycl::half2 * q8_1_ds , 717const int iqs ) { 718const uint8_t * base = static_cast < const uint8_t *> (vbq ); 719const uint8_t * ql = base + ibx_offset .first ; 720const uint8_t * qh = base + ibx_offset .second ; 721const int8_t * scales = reinterpret_cast < const int8_t *> (base + d_offset .first ); 722const ggml_half * d = (const ggml_half * ) (base + d_offset .second ); 723 724const int bq8_offset = 2 * QR6_K * (iqs / (QI6_K /2 ))+ (iqs % (QI6_K /2 )) / (QI6_K /4 ); 725const int scale_offset = (QI6_K /4 )* (iqs / (QI6_K /2 ))+ (iqs % (QI6_K /2 )) / (QI6_K /8 ); 726const int vh_shift = 2 * ((iqs % (QI6_K /2 )) / (QI6_K /4 )); 727 728const int vl = get_int_from_uint8 (ql ,iqs ); 729const int vh = get_int_from_uint8 (qh , (QI6_K /4 )* (iqs / (QI6_K /2 ))+ iqs % (QI6_K /4 )) >>vh_shift ; 730 731const int8_t * scs = scales + scale_offset ; 732 733const int u0 = get_int_from_int8_aligned ( 734q8_1_quant_ptr + bq8_offset * QK8_1 ,iqs %QI8_1 ); 735const int u1 = get_int_from_int8_aligned ( 736q8_1_quant_ptr + (bq8_offset + 2 )* QK8_1 ,iqs %QI8_1 ); 737const float d80 = (* (q8_1_ds + bq8_offset + 0 ))[0 ]; 738const float d81 = (* (q8_1_ds + bq8_offset + 2 ))[0 ]; 739 740return vec_dot_q6_K_q8_1_impl_mmvq_scalar ( 741vl ,vh ,u0 ,u1 ,scs [0 ],scs [4 ],* d ,d80 ,d81 ); 742 } 743}; 744#define VDR_Q4_0_Q8_1_MMVQ 2 745#define VDR_Q4_0_Q8_1_MMQ 4 746 747#define VDR_Q2_0_Q8_1_MMVQ 1 748 749template < int vdr > 750static __dpct_inline__ float vec_dot_q2_0_q8_1_impl ( 751const int * v , 752const int * u , 753const float & d2 , 754const sycl::half2 & ds8 ) { 755int sumi = 0 ; 756 757#pragma unroll 758for (int i = 0 ;i < vdr ;++ i ) { 759#pragma unroll 760for (int j = 0 ;j < 4 ;++ j ) { 761const uint8_t q = (uint8_t ) ((uint32_t )v [i ] >> (8 * j )); 762 763// unpack 2-bit values to byte lanes (0..3), then apply zero-point 764// correction with ds8f.y() below, mirroring the q4_0 style. 765int vi = 0 ; 766vi |= (((q >>0 )& 0x3 )& 0xFF ) <<0 ; 767vi |= (((q >>2 )& 0x3 )& 0xFF ) <<8 ; 768vi |= (((q >>4 )& 0x3 )& 0xFF ) <<16 ; 769vi |= (((q >>6 )& 0x3 )& 0xFF ) <<24 ; 770 771sumi = dpct::dp4a (vi ,u [4 * i + j ],sumi ); 772 } 773 } 774 775const sycl::float2 ds8f = ds8 .convert < float , sycl::rounding_mode::automatic > (); 776// q2_0 has zero-point 1. Scale ds8f.y() by processed-lane ratio, 777// consistent with q4_0's explicit zero-point subtraction style. 778return d2 * (sumi * ds8f .x ()- ((float )vdr / (float )QI2_0 )* ds8f .y ()); 779} 780 781template < int vdr > 782static __dpct_inline__ float vec_dot_q4_0_q8_1_impl (const int * v ,const int * u ,const float & d4 , 783const sycl::half2 & ds8 ) { 784int sumi = 0 ; 785#pragma unroll 786for (int i = 0 ;i < vdr ;++ i ) { 787const int vi0 = (v [i ] >>0 )& 0x0F0F0F0F ; 788const int vi1 = (v [i ] >>4 )& 0x0F0F0F0F ; 789 790// SIMD dot product of quantized values 791sumi = dpct::dp4a (vi0 ,u [2 * i + 0 ],sumi ); 792sumi = dpct::dp4a (vi1 ,u [2 * i + 1 ],sumi ); 793 } 794 795const sycl::float2 ds8f = ds8 .convert < float , sycl::rounding_mode::automatic > (); 796 797// second part effectively subtracts 8 from each quant value 798return d4 * (sumi * ds8f .x ()- (8 * vdr /QI4_0 )* ds8f .y ()); 799} 800 801#define VDR_Q4_1_Q8_1_MMVQ 2 802#define VDR_Q4_1_Q8_1_MMQ 4 803 804template < int vdr > 805static __dpct_inline__ float vec_dot_q4_1_q8_1_impl (const int * v ,const int * u , 806const sycl::half2 & dm4 , 807const sycl::half2 & ds8 ) { 808 809int sumi = 0 ; 810 811#pragma unroll 812for (int i = 0 ;i < vdr ;++ i ) { 813const int vi0 = (v [i ] >>0 )& 0x0F0F0F0F ; 814const int vi1 = (v [i ] >>4 )& 0x0F0F0F0F ; 815 816// SIMD dot product of quantized values 817sumi = dpct::dp4a (vi0 ,u [2 * i + 0 ],sumi ); 818sumi = dpct::dp4a (vi1 ,u [2 * i + 1 ],sumi ); 819 } 820 821#ifdef GGML_SYCL_F16 822const sycl::float2 tmp = 823 (dm4 * ds8 ).convert < float , sycl::rounding_mode::automatic > (); 824const float d4d8 = tmp .x (); 825const float m4s8 = tmp .y (); 826#else 827const sycl::float2 dm4f = 828dm4 .convert < float , sycl::rounding_mode::automatic > (); 829const sycl::float2 ds8f = 830ds8 .convert < float , sycl::rounding_mode::automatic > (); 831const float d4d8 = dm4f .x ()* ds8f .x (); 832const float m4s8 = dm4f .y ()* ds8f .y (); 833#endif // GGML_SYCL_F16 834 835// scale second part of sum by QI8_1/(vdr * QR4_1) to compensate for multiple threads adding it 836return sumi * d4d8 + m4s8 / (QI8_1 / (vdr * QR4_1 )); 837} 838 839#define VDR_Q5_0_Q8_1_MMVQ 2 840#define VDR_Q5_0_Q8_1_MMQ 4 841 842template < int vdr > 843static __dpct_inline__ float 844vec_dot_q5_0_q8_1_impl (const int * vl ,const int * vh ,const int * u , 845const float & d5 ,const sycl::half2 & ds8 ) { 846int sumi = 0 ; 847 848#pragma unroll 849for (int i = 0 ;i < vdr ;++ i ) { 850int vi0 = (vl [i ] >>0 )& 0x0F0F0F0F ;// lower 4 qs bits, still need qh as 5th bits 851vi0 |= (vh [i ] <<4 )& 0x00000010 ;// 0 -> 4 852vi0 |= (vh [i ] <<11 )& 0x00001000 ;// 1 -> 12 853vi0 |= (vh [i ] <<18 )& 0x00100000 ;// 2 -> 20 854vi0 |= (vh [i ] <<25 )& 0x10000000 ;// 3 -> 28 855sumi = dpct::dp4a (vi0 ,u [2 * i + 0 ], 856sumi );// SIMD dot product of quantized values 857 858int vi1 = (vl [i ] >>4 )& 0x0F0F0F0F ;// upper 4 qs bits, still need qh as 5th bits 859vi1 |= (vh [i ] >>12 )& 0x00000010 ;// 16 -> 4 860vi1 |= (vh [i ] >>5 )& 0x00001000 ;// 17 -> 12 861vi1 |= (vh [i ] <<2 )& 0x00100000 ;// 18 -> 20 862vi1 |= (vh [i ] <<9 )& 0x10000000 ;// 19 -> 28 863sumi = dpct::dp4a (vi1 ,u [2 * i + 1 ], 864sumi );// SIMD dot product of quantized values 865 } 866 867const sycl::float2 ds8f = 868ds8 .convert < float , sycl::rounding_mode::automatic > (); 869 870// second part effectively subtracts 16 from each quant value 871return d5 * (sumi * ds8f .x ()- (16 * vdr /QI5_0 )* ds8f .y ()); 872} 873 874#define VDR_Q5_1_Q8_1_MMVQ 2 875#define VDR_Q5_1_Q8_1_MMQ 4 876 877template < int vdr > 878static __dpct_inline__ float 879vec_dot_q5_1_q8_1_impl (const int * vl ,const int * vh ,const int * u , 880const sycl::half2 & dm5 ,const sycl::half2 & ds8 ) { 881 882int sumi = 0 ; 883 884#pragma unroll 885for (int i = 0 ;i < vdr ;++ i ) { 886int vi0 = (vl [i ] >>0 )& 0x0F0F0F0F ;// lower 4 qs bits, still need qh as 5th bits 887vi0 |= (vh [i ] <<4 )& 0x00000010 ;// 0 -> 4 888vi0 |= (vh [i ] <<11 )& 0x00001000 ;// 1 -> 12 889vi0 |= (vh [i ] <<18 )& 0x00100000 ;// 2 -> 20 890vi0 |= (vh [i ] <<25 )& 0x10000000 ;// 3 -> 28 891sumi = dpct::dp4a (vi0 ,u [2 * i + 0 ], 892sumi );// SIMD dot product of quantized values 893 894int vi1 = (vl [i ] >>4 )& 0x0F0F0F0F ;// upper 4 qs bits, still need qh as 5th bits 895vi1 |= (vh [i ] >>12 )& 0x00000010 ;// 16 -> 4 896vi1 |= (vh [i ] >>5 )& 0x00001000 ;// 17 -> 12 897vi1 |= (vh [i ] <<2 )& 0x00100000 ;// 18 -> 20 898vi1 |= (vh [i ] <<9 )& 0x10000000 ;// 19 -> 28 899sumi = dpct::dp4a (vi1 ,u [2 * i + 1 ], 900sumi );// SIMD dot product of quantized values 901 } 902 903#ifdef GGML_SYCL_F16 904const sycl::float2 tmp = 905 (dm5 * ds8 ).convert < float , sycl::rounding_mode::automatic > (); 906const float d5d8 = tmp .x (); 907const float m5s8 = tmp .y (); 908 909 910#else 911const sycl::float2 dm5f = 912dm5 .convert < float , sycl::rounding_mode::automatic > (); 913const sycl::float2 ds8f = 914ds8 .convert < float , sycl::rounding_mode::automatic > (); 915const float d5d8 = dm5f .x ()* ds8f .x (); 916const float m5s8 = dm5f .y ()* ds8f .y (); 917#endif // GGML_SYCL_F16 918 919// scale second part of sum by QI5_1 / vdr to compensate for multiple threads adding it 920return sumi * d5d8 + m5s8 / (QI5_1 /vdr ); 921} 922 923#define VDR_Q8_0_Q8_1_MMVQ 2 924#define VDR_Q8_0_Q8_1_MMQ 8 925 926template < int vdr > 927static __dpct_inline__ float vec_dot_q8_0_q8_1_impl (const int * v ,const int * u , 928const float & d8_0 , 929const float & d8_1 ) { 930 931int sumi = 0 ; 932 933#pragma unroll 934for (int i = 0 ;i < vdr ;++ i ) { 935// SIMD dot product of quantized values 936sumi = dpct::dp4a (v [i ],u [i ],sumi ); 937 } 938 939return d8_0 * d8_1 * sumi ; 940} 941 942template < typename T ,int vdr > 943static __dpct_inline__ T vec_dot_q8_0_q8_1_impl (const int * v ,const int * u ,const T & d8_0 ,const T & d8_1 ) { 944int sumi = 0 ; 945 946#pragma unroll 947for (int i = 0 ;i < vdr ;++ i ) { 948// SIMD dot product of quantized values 949sumi = ggml_sycl_dp4a (v [i ],u [i ],sumi ); 950 } 951 952return d8_0 * d8_1 * ((T )sumi ); 953} 954 955template < int vdr > 956static __dpct_inline__ float vec_dot_q8_1_q8_1_impl (const int * v ,const int * u , 957const sycl::half2 & dm8 , 958const sycl::half2 & ds8 ) { 959 960int sumi = 0 ; 961 962#pragma unroll 963for (int i = 0 ;i < vdr ;++ i ) { 964// SIMD dot product of quantized values 965sumi = dpct::dp4a (v [i ],u [i ],sumi ); 966 } 967 968#ifdef GGML_SYCL_F16 969const sycl::float2 tmp = 970 (dm8 * ds8 ).convert < float , sycl::rounding_mode::automatic > (); 971const float d8d8 = tmp .x (); 972const float m8s8 = tmp .y (); 973#else 974const sycl::float2 dm8f = 975dm8 .convert < float , sycl::rounding_mode::automatic > (); 976const sycl::float2 ds8f = 977ds8 .convert < float , sycl::rounding_mode::automatic > (); 978const float d8d8 = dm8f .x ()* ds8f .x (); 979const float m8s8 = dm8f .y ()* ds8f .y (); 980#endif // GGML_SYCL_F16 981 982// scale second part of sum by QI8_1/ vdr to compensate for multiple threads adding it 983return sumi * d8d8 + m8s8 / (QI8_1 /vdr ); 984} 985 986static __dpct_inline__ float 987vec_dot_q4_0_q8_1 (const void * __restrict__vbq , 988const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 989 990const block_q4_0 * bq4_0 = (const block_q4_0 * )vbq ; 991 992int v [VDR_Q4_0_Q8_1_MMVQ ]; 993int u [2 * VDR_Q4_0_Q8_1_MMVQ ]; 994 995#pragma unroll 996for (int i = 0 ;i < VDR_Q4_0_Q8_1_MMVQ ;++ i ) { 997v [i ]= get_int_from_uint8 (bq4_0 -> qs ,iqs + i ); 998u [2 * i + 0 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i ); 999u [2 * i + 1 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i + QI4_0 ); 1000 } 1001 1002return vec_dot_q4_0_q8_1_impl < VDR_Q4_0_Q8_1_MMVQ > (v ,u ,bq4_0 -> d ,bq8_1 -> ds ); 1003} 1004 1005static __dpct_inline__ float 1006vec_dot_q2_0_q8_1 (const void * __restrict__vbq , 1007const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1008 1009const block_q2_0 * bq2_0 = (const block_q2_0 * )vbq ; 1010 1011int v [2 * VDR_Q2_0_Q8_1_MMVQ ]; 1012int u [8 * VDR_Q2_0_Q8_1_MMVQ ]; 1013 1014#pragma unroll 1015for (int i = 0 ;i < VDR_Q2_0_Q8_1_MMVQ ;++ i ) { 1016const int base = 4 * (iqs + i ); 1017 1018// Q2_0 has QK2_0 = 64 and uses 2 x QK8_1 blocks on the RHS. 1019v [2 * i + 0 ]= get_int_from_uint8 (bq2_0 -> qs ,iqs + i ); 1020v [2 * i + 1 ]= get_int_from_uint8 (bq2_0 -> qs ,iqs + i + QI2_0 ); 1021 1022u [8 * i + 0 ]= get_int_from_int8_aligned (bq8_1 [0 ].qs ,base + 0 ); 1023u [8 * i + 1 ]= get_int_from_int8_aligned (bq8_1 [0 ].qs ,base + 1 ); 1024u [8 * i + 2 ]= get_int_from_int8_aligned (bq8_1 [0 ].qs ,base + 2 ); 1025u [8 * i + 3 ]= get_int_from_int8_aligned (bq8_1 [0 ].qs ,base + 3 ); 1026 1027u [8 * i + 4 ]= get_int_from_int8_aligned (bq8_1 [1 ].qs ,base + 0 ); 1028u [8 * i + 5 ]= get_int_from_int8_aligned (bq8_1 [1 ].qs ,base + 1 ); 1029u [8 * i + 6 ]= get_int_from_int8_aligned (bq8_1 [1 ].qs ,base + 2 ); 1030u [8 * i + 7 ]= get_int_from_int8_aligned (bq8_1 [1 ].qs ,base + 3 ); 1031 } 1032 1033const float sum0 = vec_dot_q2_0_q8_1_impl < VDR_Q2_0_Q8_1_MMVQ > ( 1034v + 0 ,u + 0 ,bq2_0 -> d ,bq8_1 [0 ].ds ); 1035const float sum1 = vec_dot_q2_0_q8_1_impl < VDR_Q2_0_Q8_1_MMVQ > ( 1036v + VDR_Q2_0_Q8_1_MMVQ ,u + 4 * VDR_Q2_0_Q8_1_MMVQ ,bq2_0 -> d ,bq8_1 [1 ].ds ); 1037return sum0 + sum1 ; 1038} 1039 1040static __dpct_inline__ float 1041vec_dot_q4_1_q8_1 (const void * __restrict__vbq , 1042const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1043 1044const block_q4_1 * bq4_1 = (const block_q4_1 * )vbq ; 1045 1046int v [VDR_Q4_1_Q8_1_MMVQ ]; 1047int u [2 * VDR_Q4_1_Q8_1_MMVQ ]; 1048 1049#pragma unroll 1050for (int i = 0 ;i < VDR_Q4_1_Q8_1_MMVQ ;++ i ) { 1051v [i ]= get_int_from_uint8_aligned (bq4_1 -> qs ,iqs + i ); 1052u [2 * i + 0 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i ); 1053u [2 * i + 1 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i + QI4_1 ); 1054 } 1055 1056return vec_dot_q4_1_q8_1_impl < VDR_Q4_1_Q8_1_MMVQ > (v ,u ,bq4_1 -> dm ,bq8_1 -> ds ); 1057} 1058 1059#define VDR_MXFP4_Q8_1_MMVQ 2 1060#define VDR_MXFP4_Q8_1_MMQ 4 1061 1062static __dpct_inline__ float vec_dot_mxfp4_q8_1 (const void * __restrict__vbq , 1063const block_q8_1 * __restrict__bq8_1 , 1064const int & iqs ) { 1065const block_mxfp4 * bq4 = (const block_mxfp4 * )vbq ; 1066 1067const int * q8 = (const int * )bq8_1 -> qs + iqs ; 1068 1069int sumi = 0 ; 1070#pragma unroll 1071for (int l = 0 ;l < VDR_MXFP4_Q8_1_MMVQ ;++ l ) { 1072const int aux_q4 = get_int_b1 (bq4 -> qs ,iqs + l ); 1073const sycl::int2 v = get_int_from_table_16 (aux_q4 ,kvalues_mxfp4 ); 1074sumi = ggml_sycl_dp4a (v .x (),q8 [l + 0 ],sumi ); 1075sumi = ggml_sycl_dp4a (v .y (),q8 [l + 4 ],sumi ); 1076 } 1077 1078const float d = ggml_sycl_e8m0_to_fp32 (bq4 -> e )* 0.5f * (bq8_1 -> ds )[0 ]; 1079return d * sumi ; 1080} 1081 1082#define VDR_NVFP4_Q8_1_MMVQ 4 1083#define VDR_NVFP4_Q8_1_MMQ 8 1084 1085static __dpct_inline__ float vec_dot_nvfp4_q8_1 (const void * __restrict__vbq , 1086const block_q8_1 * __restrict__bq8_1 , 1087const int32_t & iqs ) { 1088const block_nvfp4 * bq4 = (const block_nvfp4 * )vbq ; 1089float sum = 0.0f ; 1090#pragma unroll 1091for (int i = 0 ;i < VDR_NVFP4_Q8_1_MMVQ /2 ;i ++ ) { 1092const int32_t iqs0 = iqs + 2 * i ; 1093const int32_t iqs1 = iqs0 + 1 ; 1094const int32_t is = iqs0 >>1 ; 1095const sycl::int2 v0 = get_int_from_table_16 (get_int_b4 (bq4 -> qs ,iqs0 ),kvalues_mxfp4 ); 1096const sycl::int2 v1 = get_int_from_table_16 (get_int_b4 (bq4 -> qs ,iqs1 ),kvalues_mxfp4 ); 1097const block_q8_1 * bq8 = bq8_1 + (is >>1 ); 1098const int32_t i8 = ((is & 1 ) <<2 ); 1099 1100int sumi = ggml_sycl_dp4a (v0 .x (),get_int_b4 (bq8 -> qs ,i8 + 0 ),0 ); 1101sumi = ggml_sycl_dp4a (v0 .y (),get_int_b4 (bq8 -> qs ,i8 + 2 ),sumi ); 1102sumi = ggml_sycl_dp4a (v1 .x (),get_int_b4 (bq8 -> qs ,i8 + 1 ),sumi ); 1103sumi = ggml_sycl_dp4a (v1 .y (),get_int_b4 (bq8 -> qs ,i8 + 3 ),sumi ); 1104 1105const float d = ggml_sycl_ue4m3_to_fp32 (bq4 -> d [is ])* (bq8 -> ds )[0 ]; 1106sum += d * float (sumi ); 1107 } 1108 1109return sum ; 1110} 1111 1112static __dpct_inline__ float 1113vec_dot_q5_0_q8_1 (const void * __restrict__vbq , 1114const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1115 1116const block_q5_0 * bq5_0 = (const block_q5_0 * )vbq ; 1117 1118int vl [VDR_Q5_0_Q8_1_MMVQ ]; 1119int vh [VDR_Q5_0_Q8_1_MMVQ ]; 1120int u [2 * VDR_Q5_0_Q8_1_MMVQ ]; 1121 1122#pragma unroll 1123for (int i = 0 ;i < VDR_Q5_0_Q8_1_MMVQ ;++ i ) { 1124vl [i ]= get_int_from_uint8 (bq5_0 -> qs ,iqs + i ); 1125vh [i ]= get_int_from_uint8 (bq5_0 -> qh ,0 ) >> (4 * (iqs + i )); 1126u [2 * i + 0 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i ); 1127u [2 * i + 1 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i + QI5_0 ); 1128 } 1129 1130return vec_dot_q5_0_q8_1_impl < VDR_Q5_0_Q8_1_MMVQ > (vl ,vh ,u ,bq5_0 -> d ,bq8_1 -> ds ); 1131} 1132 1133static __dpct_inline__ float 1134vec_dot_q5_1_q8_1 (const void * __restrict__vbq , 1135const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1136 1137const block_q5_1 * bq5_1 = (const block_q5_1 * )vbq ; 1138 1139int vl [VDR_Q5_1_Q8_1_MMVQ ]; 1140int vh [VDR_Q5_1_Q8_1_MMVQ ]; 1141int u [2 * VDR_Q5_1_Q8_1_MMVQ ]; 1142 1143#pragma unroll 1144for (int i = 0 ;i < VDR_Q5_1_Q8_1_MMVQ ;++ i ) { 1145vl [i ]= get_int_from_uint8_aligned (bq5_1 -> qs ,iqs + i ); 1146vh [i ]= get_int_from_uint8_aligned (bq5_1 -> qh ,0 ) >> (4 * (iqs + i )); 1147u [2 * i + 0 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i ); 1148u [2 * i + 1 ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i + QI5_1 ); 1149 } 1150 1151return vec_dot_q5_1_q8_1_impl < VDR_Q5_1_Q8_1_MMVQ > (vl ,vh ,u ,bq5_1 -> dm ,bq8_1 -> ds ); 1152} 1153 1154static __dpct_inline__ float 1155vec_dot_q8_0_q8_1 (const void * __restrict__vbq , 1156const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1157 1158const block_q8_0 * bq8_0 = (const block_q8_0 * )vbq ; 1159 1160int v [VDR_Q8_0_Q8_1_MMVQ ]; 1161int u [VDR_Q8_0_Q8_1_MMVQ ]; 1162 1163#pragma unroll 1164for (int i = 0 ;i < VDR_Q8_0_Q8_1_MMVQ ;++ i ) { 1165v [i ]= get_int_from_int8 (bq8_0 -> qs ,iqs + i ); 1166u [i ]= get_int_from_int8_aligned (bq8_1 -> qs ,iqs + i ); 1167 } 1168 1169return vec_dot_q8_0_q8_1_impl < VDR_Q8_0_Q8_1_MMVQ > (v ,u ,bq8_0 -> d , 1170bq8_1 -> ds [0 ]); 1171} 1172 1173static __dpct_inline__ float 1174vec_dot_q2_K_q8_1 (const void * __restrict__vbq , 1175const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1176 1177const block_q2_K * bq2_K = (const block_q2_K * )vbq ; 1178 1179const int bq8_offset = QR2_K * (iqs /QI8_1 ); 1180const int scale_offset = iqs - iqs %QI8_1 + (iqs %QI8_1 ) / (QI8_1 /2 ); 1181 1182const uint8_t * scales = bq2_K -> scales + scale_offset ; 1183 1184const int v = get_int_from_uint8_aligned (bq2_K -> qs ,iqs ); 1185int u [QR2_K ]; 1186float d8 [QR2_K ]; 1187 1188#pragma unroll 1189for (int i = 0 ;i < QR2_K ;++ i ) { 1190u [i ]= get_int_from_int8_aligned (bq8_1 [bq8_offset + i ].qs ,iqs %QI8_1 ); 1191d8 [i ]= bq8_1 [bq8_offset + i ].ds [0 ]; 1192 } 1193 1194return vec_dot_q2_K_q8_1_impl_mmvq (v ,u ,scales ,bq2_K -> dm ,d8 ); 1195} 1196 1197static __dpct_inline__ float 1198vec_dot_q3_K_q8_1 (const void * __restrict__vbq , 1199const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1200 1201const block_q3_K * bq3_K = (const block_q3_K * )vbq ; 1202 1203const int bq8_offset = QR3_K * (iqs / (QI3_K /2 )); 1204const int scale_offset = iqs - iqs %QI8_1 + (iqs %QI8_1 ) / (QI8_1 /2 ); 1205 1206const float d = bq3_K -> d ; 1207 1208const int vl = get_int_from_uint8 (bq3_K -> qs ,iqs ); 1209 1210// invert the mask with ~ so that a 0/1 results in 4/0 being subtracted 1211const int vh = ~get_int_from_uint8 (bq3_K -> hmask ,iqs % (QI3_K /2 )) >>bq8_offset ; 1212 1213int u [QR3_K ]; 1214float d8 [QR3_K ]; 1215 1216#pragma unroll 1217for (int i = 0 ;i < QR3_K ;++ i ) { 1218u [i ]= get_int_from_int8_aligned (bq8_1 [bq8_offset + i ].qs ,iqs %QI8_1 ); 1219d8 [i ]= bq8_1 [bq8_offset + i ].ds [0 ]; 1220 } 1221 1222return vec_dot_q3_K_q8_1_impl_mmvq (vl ,vh ,u ,bq3_K -> scales ,scale_offset ,d ,d8 ); 1223} 1224 1225static __dpct_inline__ float vec_dot_q4_K_q8_1 (const void * __restrict__vbq ,const block_q8_1 * __restrict__bq8_1 , 1226const int & iqs ) { 1227#ifndef GGML_QKK_64 1228 1229const block_q4_K * bq4_K = (const block_q4_K * )vbq ; 1230 1231const int bq8_offset = QR4_K * ((iqs /2 ) / (QI8_1 /2 )); 1232const int * q4 = (const int * ) (bq4_K -> qs + 16 * bq8_offset + 4 * ((iqs /2 ) %4 )); 1233const uint16_t * scales = (const uint16_t * )bq4_K -> scales ; 1234 1235return vec_dot_q4_K_q8_1_common (q4 ,scales ,bq4_K -> dm ,bq8_1 ,iqs ); 1236 1237#else 1238 1239#if __SYCL_ARCH__ >=VER_4VEC // lowest compute capability for integer intrinsics 1240const block_q4_K * bq4_K = (const block_q4_K * )vbq ; 1241 1242float sumf_d = 0.0f ; 1243float sumf_m = 0.0f ; 1244 1245uint16_t aux16 [2 ]; 1246const uint8_t * s = (const uint8_t * )aux16 ; 1247 1248const uint16_t * a = (const uint16_t * )bq4_K -> scales ; 1249aux16 [0 ]= a [0 ]& 0x0f0f ; 1250aux16 [1 ]= (a [0 ] >>4 )& 0x0f0f ; 1251 1252const float dall = bq4_K -> dm [0 ]; 1253const float dmin = bq4_K -> dm [1 ]; 1254 1255const float d8_1 = bq8_1 [0 ].ds [0 ]; 1256const float d8_2 = bq8_1 [1 ].ds [1 ]; 1257 1258const int ui1 = * ((const int * )bq8_1 [0 ].qs + (iqs /2 )); 1259const int ui2 = * ((const int * )bq8_1 [0 ].qs + (iqs /2 )+ 4 ); 1260const int ui3 = * ((const int * )bq8_1 [1 ].qs + (iqs /2 )); 1261const int ui4 = * ((const int * )bq8_1 [1 ].qs + (iqs /2 )+ 4 ); 1262 1263const int * q4 = (const int * )bq4_K -> qs + (iqs /2 ); 1264const int v1 = q4 [0 ]; 1265const int v2 = q4 [4 ]; 1266 1267const int dot1 = dpct::dp4a (ui2 ,v2 & 0x0f0f0f0f , dpct::dp4a (ui1 ,v1 & 0x0f0f0f0f ,0 )); 1268const int dot2 = dpct::dp4a (ui4 , (v2 >>4 )& 0x0f0f0f0f , dpct::dp4a (ui3 , (v1 >>4 )& 0x0f0f0f0f ,0 )); 1269const int dot3 = dpct::dp4a (0x01010101 ,ui2 , dpct::dp4a (0x01010101 ,ui1 ,0 )); 1270const int dot4 = dpct::dp4a (0x01010101 ,ui4 , dpct::dp4a (0x01010101 ,ui3 ,0 )); 1271 1272sumf_d += d8_1 * (dot1 * s [0 ])+ d8_2 * (dot2 * s [1 ]); 1273sumf_m += d8_1 * (dot3 * s [2 ])+ d8_2 * (dot4 * s [3 ]); 1274 1275return dall * sumf_d - dmin * sumf_m ; 1276 1277#else 1278bad_arch (); 1279#endif // __SYCL_ARCH__ >= VER_4VEC 1280 1281#endif 1282} 1283 1284static __dpct_inline__ float 1285vec_dot_q5_K_q8_1 (const void * __restrict__vbq , 1286const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1287 1288#ifndef GGML_QKK_64 1289const block_q5_K * bq5_K = (const block_q5_K * )vbq ; 1290 1291int vl [2 ]; 1292int vh [2 ]; 1293int u [2 * QR5_K ]; 1294float d8 [QR5_K ]; 1295 1296const int bq8_offset = QR5_K * ((iqs /2 ) / (QI8_1 /2 )); 1297const int * ql = (const int * )(bq5_K -> qs + 16 * bq8_offset + 4 * ((iqs /2 )%4 )); 1298const int * qh = (const int * )(bq5_K -> qh + 4 * ((iqs /2 )%4 )); 1299 1300vl [0 ]= ql [0 ]; 1301vl [1 ]= ql [4 ]; 1302 1303vh [0 ]= qh [0 ] >>bq8_offset ; 1304vh [1 ]= qh [4 ] >>bq8_offset ; 1305 1306const uint16_t * scales = (const uint16_t * )bq5_K -> scales ; 1307uint16_t aux [2 ]; 1308const int j = bq8_offset /2 ; 1309if (j < 2 ) { 1310aux [0 ]= scales [j + 0 ]& 0x3f3f ; 1311aux [1 ]= scales [j + 2 ]& 0x3f3f ; 1312 }else { 1313aux [0 ]= ((scales [j + 2 ] >>0 )& 0x0f0f ) | ((scales [j - 2 ]& 0xc0c0 ) >>2 ); 1314aux [1 ]= ((scales [j + 2 ] >>4 )& 0x0f0f ) | ((scales [j - 0 ]& 0xc0c0 ) >>2 ); 1315 } 1316const uint8_t * sc = (const uint8_t * )aux ; 1317const uint8_t * m = sc + 2 ; 1318 1319#pragma unroll 1320for (int i = 0 ;i < QR5_K ;++ i ) { 1321const block_q8_1 * bq8i = bq8_1 + bq8_offset + i ; 1322d8 [i ]= bq8i -> ds [0 ]; 1323 1324const int * q8 = (const int * )bq8i -> qs + ((iqs /2 )%4 ); 1325u [2 * i + 0 ]= q8 [0 ]; 1326u [2 * i + 1 ]= q8 [4 ]; 1327 } 1328 1329return vec_dot_q5_K_q8_1_impl_vmmq (vl ,vh ,u ,sc ,m ,bq5_K -> dm ,d8 ); 1330 1331#else 1332 1333#if __SYCL_ARCH__ >=VER_4VEC // lowest compute capability for integer intrinsics 1334const block_q5_K * bq5_K = (const block_q5_K * )vbq ; 1335 1336const int8_t * s = bq5_K -> scales ; 1337 1338const float d = bq5_K -> d ; 1339 1340const float d8_1 = bq8_1 [0 ].ds [0 ]; 1341const float d8_2 = bq8_1 [1 ].ds [1 ]; 1342 1343const int ui1 = * ((const int * )bq8_1 [0 ].qs + (iqs /2 )); 1344const int ui2 = * ((const int * )bq8_1 [0 ].qs + (iqs /2 )+ 4 ); 1345const int ui3 = * ((const int * )bq8_1 [1 ].qs + (iqs /2 )); 1346const int ui4 = * ((const int * )bq8_1 [1 ].qs + (iqs /2 )+ 4 ); 1347 1348const int * ql = (const int * )bq5_K -> qs + (iqs /2 ); 1349const int vl1 = ql [0 ]; 1350const int vl2 = ql [4 ]; 1351 1352const int step = 4 * (iqs /2 );// 0, 4, 8, 12 1353const int im = step /8 ;// = 0 for iqs = 0, 2, = 1 for iqs = 4, 6 1354const int in = step %8 ;// 0, 4, 0, 4 1355const int vh = (* ((const int * )(bq5_K -> qh + in ))) >>im ; 1356 1357const int v1 = (((vh <<4 )& 0x10101010 ) ^0x10101010 ) | ((vl1 >>0 )& 0x0f0f0f0f ); 1358const int v2 = (((vh <<2 )& 0x10101010 ) ^0x10101010 ) | ((vl2 >>0 )& 0x0f0f0f0f ); 1359const int v3 = (((vh >>0 )& 0x10101010 ) ^0x10101010 ) | ((vl1 >>4 )& 0x0f0f0f0f ); 1360const int v4 = (((vh >>2 )& 0x10101010 ) ^0x10101010 ) | ((vl2 >>4 )& 0x0f0f0f0f ); 1361 1362const float sumf_d = d8_1 * (dpct::dp4a (ui1 ,v1 ,0 )* s [0 ]+ dpct::dp4a (ui2 ,v2 ,0 )* s [1 ]) 1363+ d8_2 * (dpct::dp4a (ui3 ,v3 ,0 )* s [2 ]+ dpct::dp4a (ui4 ,v4 ,0 )* s [3 ]); 1364 1365return d * sumf_d ; 1366 1367#else 1368bad_arch (); 1369#endif // __SYCL_ARCH__ >= VER_4VEC 1370 1371#endif 1372} 1373 1374static __dpct_inline__ float 1375vec_dot_q6_K_q8_1 (const void * __restrict__vbq , 1376const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1377 1378const block_q6_K * bq6_K = (const block_q6_K * )vbq ; 1379 1380const int bq8_offset = 2 * QR6_K * (iqs / (QI6_K /2 ))+ (iqs % (QI6_K /2 )) / (QI6_K /4 ); 1381const int scale_offset = (QI6_K /4 )* (iqs / (QI6_K /2 ))+ (iqs % (QI6_K /2 )) / (QI6_K /8 ); 1382const int vh_shift = 2 * ((iqs % (QI6_K /2 )) / (QI6_K /4 )); 1383 1384const int vl = get_int_from_uint8 (bq6_K -> ql ,iqs ); 1385const int vh = get_int_from_uint8 (bq6_K -> qh , (QI6_K /4 )* (iqs / (QI6_K /2 ))+ iqs % (QI6_K /4 )) >>vh_shift ; 1386 1387const int8_t * scales = bq6_K -> scales + scale_offset ; 1388 1389const int u0 = get_int_from_int8_aligned ( 1390bq8_1 [bq8_offset + 0 ].qs ,iqs %QI8_1 ); 1391const int u1 = get_int_from_int8_aligned ( 1392bq8_1 [bq8_offset + 2 ].qs ,iqs %QI8_1 ); 1393const float d80 = bq8_1 [bq8_offset + 0 ].ds [0 ]; 1394const float d81 = bq8_1 [bq8_offset + 2 ].ds [0 ]; 1395 1396return vec_dot_q6_K_q8_1_impl_mmvq_scalar ( 1397vl ,vh ,u0 ,u1 ,scales [0 ],scales [4 ],bq6_K -> d ,d80 ,d81 ); 1398} 1399 1400 1401// NOTE: the VDR_IQ*_Q8_1_MMVQ values deliberately differ from the identically named CUDA constants 1402// (vecdotq.cuh): the SYCL kernels pair them with a halved qi (e.g. QI3_S/2), so the values are not 1403// interchangeable and must not be copied across backends. 1404#define VDR_IQ2_XXS_Q8_1_MMVQ 1 1405 1406static __dpct_inline__ float 1407vec_dot_iq2_xxs_q8_1 (const void * __restrict__vbq , 1408const block_q8_1 * __restrict__bq8_1 ,const int & iqs , 1409const uint64_t * iq2xxs_grid ,const uint8_t * ksigns_iq2xs , 1410const uint8_t * kmask_iq2xs ) { 1411#if QK_K == 256 1412const block_iq2_xxs * bq2 = (const block_iq2_xxs * )vbq ; 1413 1414const int ib32 = iqs ; 1415const uint16_t * q2 = bq2 -> qs + 4 * ib32 ; 1416const uint8_t * aux8 = (const uint8_t * )q2 ; 1417const int8_t * q8 = bq8_1 [ib32 ].qs ; 1418uint32_t aux32 = q2 [2 ] | (q2 [3 ] <<16 ); 1419int sumi = 0 ; 1420for (int l = 0 ;l < 4 ;++ l ) { 1421const uint8_t * grid = (const uint8_t * )(iq2xxs_grid + aux8 [l ]); 1422const uint8_t signs = ksigns_iq2xs [aux32 & 127 ]; 1423for (int j = 0 ;j < 8 ;++ j ) { 1424sumi += q8 [j ]* grid [j ]* (signs & kmask_iq2xs [j ] ?-1 :1 ); 1425 } 1426q8 += 8 ; 1427aux32 >>=7 ; 1428 } 1429const float d = (float )bq2 -> d * (0.5f + aux32 )* bq8_1 [ib32 ].ds [0 ]* 0.25f ; 1430return d * sumi ; 1431#else 1432assert (false); 1433return 0.f ; 1434#endif 1435} 1436 1437#define VDR_IQ2_XS_Q8_1_MMVQ 1 1438 1439static __dpct_inline__ float 1440vec_dot_iq2_xs_q8_1 (const void * __restrict__vbq , 1441const block_q8_1 * __restrict__bq8_1 ,const int & iqs , 1442const uint64_t * iq2xs_grid ,const uint64_t * ksigns64 ) { 1443#if DPCT_COMPATIBILITY_TEMP >= \ 1444MIN_CC_DP4A // lowest compute capability for integer intrinsics 1445#if QK_K == 256 1446const block_iq2_xs * bq2 = (const block_iq2_xs * )vbq ; 1447 1448const int ib32 = iqs ; 1449const uint16_t * q2 = bq2 -> qs + 4 * ib32 ; 1450const int8_t * q8 = bq8_1 [ib32 ].qs ; 1451const uint8_t ls1 = bq2 -> scales [ib32 ]& 0xf ; 1452const uint8_t ls2 = bq2 -> scales [ib32 ] >>4 ; 1453int sumi1 = 0 ; 1454for (int l = 0 ;l < 2 ;++ l ) { 1455const uint32_t * grid = (const uint32_t * )(iq2xs_grid + (q2 [l ]& 511 )); 1456const uint32_t * signs = (const uint32_t * )(ksigns64 + (q2 [l ] >>9 )); 1457const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1458grid [0 ] ^signs [0 ],signs [0 ], std::minus <> ()); 1459const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1460grid [1 ] ^signs [1 ],signs [1 ], std::minus <> ()); 1461sumi1 = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi1 ); 1462sumi1 = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi1 ); 1463q8 += 8 ; 1464 } 1465int sumi2 = 0 ; 1466for (int l = 2 ;l < 4 ;++ l ) { 1467const uint32_t * grid = (const uint32_t * )(iq2xs_grid + (q2 [l ]& 511 )); 1468const uint32_t * signs = (const uint32_t * )(ksigns64 + (q2 [l ] >>9 )); 1469const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1470grid [0 ] ^signs [0 ],signs [0 ], std::minus <> ()); 1471const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1472grid [1 ] ^signs [1 ],signs [1 ], std::minus <> ()); 1473sumi2 = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi2 ); 1474sumi2 = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi2 ); 1475q8 += 8 ; 1476 } 1477const float d = (float )bq2 -> d * bq8_1 [ib32 ].ds [0 ]* 0.25f ; 1478return d * ((0.5f + ls1 )* sumi1 + (0.5f + ls2 )* sumi2 ); 1479#else 1480assert (false); 1481return 0.f ; 1482#endif 1483#else 1484assert (false); 1485return 0.f ; 1486#endif 1487} 1488 1489#define VDR_IQ2_S_Q8_1_MMVQ 1 1490 1491static __dpct_inline__ float 1492vec_dot_iq2_s_q8_1 (const void * __restrict__vbq , 1493const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1494#if QK_K == 256 1495const block_iq2_s * bq2 = (const block_iq2_s * )vbq ; 1496 1497const int ib32 = iqs ; 1498const int8_t * q8 = bq8_1 [ib32 ].qs ; 1499const uint8_t * signs = bq2 -> qs + QK_K /8 + 4 * ib32 ; 1500const uint8_t ls1 = bq2 -> scales [ib32 ]& 0xf ; 1501const uint8_t ls2 = bq2 -> scales [ib32 ] >>4 ; 1502int sumi1 = 0 ; 1503for (int l = 0 ;l < 2 ;++ l ) { 1504const uint32_t * grid = (const uint32_t * )(iq2s_grid + (bq2 -> qs [4 * ib32 + l ] | ((bq2 -> qh [ib32 ] << (8 - 2 * l ))& 0x300 ))); 1505const uint32_t signs0 = dpct::vectorized_binary < sycl::uchar4 > ( 1506 ((signs [l ]& 0xf )* 0x01010101 )& 0x08040201 ,0x08040201 , 1507 std::equal_to <> ()); 1508const uint32_t signs1 = dpct::vectorized_binary < sycl::uchar4 > ( 1509 ((signs [l ] >>4 )* 0x01010101 )& 0x08040201 ,0x08040201 , 1510 std::equal_to <> ()); 1511const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1512grid [0 ] ^signs0 ,signs0 , std::minus <> ()); 1513const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1514grid [1 ] ^signs1 ,signs1 , std::minus <> ()); 1515sumi1 = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi1 ); 1516sumi1 = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi1 ); 1517q8 += 8 ; 1518 } 1519int sumi2 = 0 ; 1520for (int l = 2 ;l < 4 ;++ l ) { 1521const uint32_t * grid = (const uint32_t * )(iq2s_grid + (bq2 -> qs [4 * ib32 + l ] | ((bq2 -> qh [ib32 ] << (8 - 2 * l ))& 0x300 ))); 1522const uint32_t signs0 = dpct::vectorized_binary < sycl::uchar4 > ( 1523 ((signs [l ]& 0xf )* 0x01010101 )& 0x08040201 ,0x08040201 , 1524 std::equal_to <> ()); 1525const uint32_t signs1 = dpct::vectorized_binary < sycl::uchar4 > ( 1526 ((signs [l ] >>4 )* 0x01010101 )& 0x08040201 ,0x08040201 , 1527 std::equal_to <> ()); 1528const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1529grid [0 ] ^signs0 ,signs0 , std::minus <> ()); 1530const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1531grid [1 ] ^signs1 ,signs1 , std::minus <> ()); 1532sumi2 = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi2 ); 1533sumi2 = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi2 ); 1534q8 += 8 ; 1535 } 1536const float d = (float )bq2 -> d * bq8_1 [ib32 ].ds [0 ]* 0.25f ; 1537return d * ((0.5f + ls1 )* sumi1 + (0.5f + ls2 )* sumi2 ); 1538#else 1539assert (false); 1540#endif 1541} 1542 1543#define VDR_IQ3_XXS_Q8_1_MMVQ 1 1544 1545static __dpct_inline__ float 1546vec_dot_iq3_xxs_q8_1 (const void * __restrict__vbq , 1547const block_q8_1 * __restrict__bq8_1 ,const int & iqs , 1548const uint32_t * iq3xxs_grid ,const uint64_t * ksigns64 ) { 1549#if DPCT_COMPATIBILITY_TEMP >= \ 1550MIN_CC_DP4A // lowest compute capability for integer intrinsics 1551#if QK_K == 256 1552const block_iq3_xxs * bq2 = (const block_iq3_xxs * )vbq ; 1553 1554const int ib32 = iqs ; 1555const uint8_t * q3 = bq2 -> qs + 8 * ib32 ; 1556const uint16_t * gas = (const uint16_t * )(bq2 -> qs + QK_K /4 )+ 2 * ib32 ; 1557const int8_t * q8 = bq8_1 [ib32 ].qs ; 1558uint32_t aux32 = gas [0 ] | (gas [1 ] <<16 ); 1559int sumi = 0 ; 1560for (int l = 0 ;l < 4 ;++ l ) { 1561const uint32_t * grid1 = iq3xxs_grid + q3 [2 * l + 0 ]; 1562const uint32_t * grid2 = iq3xxs_grid + q3 [2 * l + 1 ]; 1563const uint32_t * signs = (const uint32_t * )(ksigns64 + (aux32 & 127 )); 1564const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1565grid1 [0 ] ^signs [0 ],signs [0 ], std::minus <> ()); 1566const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1567grid2 [0 ] ^signs [1 ],signs [1 ], std::minus <> ()); 1568sumi = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi ); 1569sumi = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi ); 1570q8 += 8 ; 1571aux32 >>=7 ; 1572 } 1573const float d = (float )bq2 -> d * (0.5f + aux32 )* bq8_1 [ib32 ].ds [0 ]* 0.5f ; 1574return d * sumi ; 1575#else 1576assert (false); 1577return 0.f ; 1578#endif 1579#else 1580assert (false); 1581return 0.f ; 1582#endif 1583} 1584 1585#define VDR_IQ3_S_Q8_1_MMVQ 1 1586 1587static __dpct_inline__ float 1588vec_dot_iq3_s_q8_1 (const void * __restrict__vbq , 1589const block_q8_1 * __restrict__bq8_1 ,const int & iqs , 1590const uint32_t * iq3s_grid ) { 1591#if QK_K == 256 1592const block_iq3_s * bq2 = (const block_iq3_s * )vbq ; 1593 1594const int ib32 = iqs ; 1595const uint8_t * qs = bq2 -> qs + 8 * ib32 ; 1596const int8_t * q8 = bq8_1 [ib32 ].qs ; 1597int sumi = 0 ; 1598for (int l = 0 ;l < 4 ;++ l ) { 1599const uint32_t * grid1 = iq3s_grid + (qs [2 * l + 0 ] | ((bq2 -> qh [ib32 ] << (8 - 2 * l ))& 256 )); 1600const uint32_t * grid2 = iq3s_grid + (qs [2 * l + 1 ] | ((bq2 -> qh [ib32 ] << (7 - 2 * l ))& 256 )); 1601uint32_t signs0 = dpct::vectorized_binary < sycl::uchar4 > ( 1602 ((bq2 -> signs [4 * ib32 + l ]& 0xf )* 0x01010101 )& 0x08040201 , 16030x08040201 , std::equal_to <> ()); 1604uint32_t signs1 = dpct::vectorized_binary < sycl::uchar4 > ( 1605 ((bq2 -> signs [4 * ib32 + l ] >>4 )* 0x01010101 )& 0x08040201 , 16060x08040201 , std::equal_to <> ()); 1607const int grid_l = dpct::vectorized_binary < sycl::uchar4 > ( 1608grid1 [0 ] ^signs0 ,signs0 , std::minus <> ()); 1609const int grid_h = dpct::vectorized_binary < sycl::uchar4 > ( 1610grid2 [0 ] ^signs1 ,signs1 , std::minus <> ()); 1611sumi = dpct::dp4a (grid_l ,* ((const int * )q8 + 0 ),sumi ); 1612sumi = dpct::dp4a (grid_h ,* ((const int * )q8 + 1 ),sumi ); 1613q8 += 8 ; 1614 } 1615const float d = 1616 (float )bq2 -> d * 1617 (1 + 2 * ((bq2 -> scales [ib32 /2 ] >>4 * (ib32 %2 ))& 0xf ))* 1618bq8_1 [ib32 ].ds [0 ]; 1619return d * sumi ; 1620#else 1621assert (false); 1622#endif 1623} 1624 1625#define VDR_IQ1_S_Q8_1_MMVQ 1 1626 1627static __dpct_inline__ float 1628vec_dot_iq1_s_q8_1 (const void * __restrict__vbq , 1629const block_q8_1 * __restrict__bq8_1 ,const int & iqs , 1630const uint32_t * iq1s_grid_gpu ) { 1631#if QK_K == 256 1632const block_iq1_s * bq1 = (const block_iq1_s * )vbq ; 1633 1634const int ib32 = iqs ; 1635int sumi = 0 ; 1636const int * q8 = (const int * )bq8_1 [ib32 ].qs ; 1637for (int l = 0 ;l < 4 ;++ l ) { 1638const int * grid = (const int * )(iq1s_grid_gpu + (bq1 -> qs [4 * ib32 + l ] | (((bq1 -> qh [ib32 ] >>3 * l )& 7 ) <<8 ))); 1639int grid0 = grid [0 ]& 0x0f0f0f0f ; 1640int grid1 = (grid [0 ] >>4 )& 0x0f0f0f0f ; 1641sumi = dpct::dp4a (q8 [2 * l + 1 ],grid1 , 1642 dpct::dp4a (q8 [2 * l + 0 ],grid0 ,sumi )); 1643 } 1644 1645const float delta = bq1 -> qh [ib32 ]& 0x8000 ?-1 - IQ1S_DELTA :-1 + IQ1S_DELTA ; 1646const float d1q = (float )bq1 -> d * (2 * ((bq1 -> qh [ib32 ] >>12 )& 7 )+ 1 ); 1647const float d = d1q * bq8_1 [ib32 ].ds [0 ]; 1648const float m = d1q * bq8_1 [ib32 ].ds [1 ]; 1649return d * sumi + m * delta ; 1650#else 1651assert (false); 1652#endif 1653} 1654 1655#define VDR_IQ1_M_Q8_1_MMVQ 1 1656 1657static __dpct_inline__ float 1658vec_dot_iq1_m_q8_1 (const void * __restrict__vbq , 1659const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1660#if QK_K == 256 1661const block_iq1_m * bq1 = (const block_iq1_m * )vbq ; 1662 1663const int ib32 = iqs ; 1664int sumi [2 ]= {0 ,0 }; 1665float sumf [2 ]= {0.f ,0.f }; 1666 1667const int * q8 = (const int * )bq8_1 [ib32 ].qs ; 1668for (int l = 0 ;l < 4 ;++ l ) { 1669const int * grid = (const int * )(iq1s_grid_gpu + (bq1 -> qs [4 * ib32 + l ] | (((bq1 -> qh [2 * ib32 + l /2 ] >>4 * (l %2 ))& 7 ) <<8 ))); 1670int grid0 = grid [0 ]& 0x0f0f0f0f ; 1671int grid1 = (grid [0 ] >>4 )& 0x0f0f0f0f ; 1672sumi [l /2 ]= dpct::dp4a (q8 [2 * l + 1 ],grid1 , 1673 dpct::dp4a (q8 [2 * l + 0 ],grid0 ,sumi [l /2 ])); 1674const float delta = (bq1 -> qh [2 * ib32 + l /2 ] >>4 * (l %2 ))& 0x08 ?-1 - IQ1M_DELTA :-1 + IQ1M_DELTA ; 1675const int sumy = dpct::dp4a (q8 [2 * l + 1 ],0x01010101 , 1676 dpct::dp4a (q8 [2 * l + 0 ],0x01010101 ,0 )); 1677sumf [l /2 ]+= delta * sumy ; 1678 } 1679 1680iq1m_scale_t scale ; 1681const uint16_t * sc = (const uint16_t * )bq1 -> scales ; 1682scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 1683const float d = (float )scale .f16 * bq8_1 [ib32 ].ds [0 ]; 1684return d * ((sumi [0 ]+ sumf [0 ])* (2 * ((sc [ib32 /2 ] >>6 * (ib32 %2 ))& 0x7 )+ 1 )+ (sumi [1 ]+ sumf [1 ])* (2 * ((sc [ib32 /2 ] >> (6 * (ib32 %2 )+ 3 ))& 0x7 )+ 1 )); 1685#else 1686assert (false); 1687#endif 1688} 1689 1690 1691#define VDR_IQ4_NL_Q8_1_MMVQ 2 1692 1693static __dpct_inline__ float 1694vec_dot_iq4_nl_q8_1 (const void * __restrict__vbq , 1695const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1696 1697const block_iq4_nl * bq = (const block_iq4_nl * )vbq ; 1698 1699const uint16_t * q4 = (const uint16_t * )bq -> qs + 2 * iqs ; 1700const int32_t * q8 = (const int32_t * )bq8_1 -> qs + iqs ; 1701 1702const uint8_t * values = (const uint8_t * )kvalues_iq4nl ; 1703 1704int v1 ,v2 ; 1705int sumi1 = 0 ,sumi2 = 0 ; 1706for (int l = 0 ;l < VDR_Q4_0_Q8_1_MMVQ ;++ l ) { 1707const uint32_t aux = q4 [2 * l ] | (q4 [2 * l + 1 ] <<16 ); 1708get_int_from_table_16 (aux ,values ,v1 ,v2 ); 1709sumi1 = dpct::dp4a (v1 ,q8 [l + 0 ],sumi1 ); 1710sumi2 = dpct::dp4a (v2 ,q8 [l + 4 ],sumi2 ); 1711 } 1712 1713const float d = (float )bq -> d * bq8_1 -> ds [0 ]; 1714return d * (sumi1 + sumi2 ); 1715} 1716 1717 1718#define VDR_IQ4_XS_Q8_1_MMVQ 1 1719 1720static __dpct_inline__ float 1721vec_dot_iq4_xs_q8_1 (const void * __restrict__vbq , 1722const block_q8_1 * __restrict__bq8_1 ,const int & iqs ) { 1723 1724#if QK_K == 256 1725const block_iq4_xs * bq4 = (const block_iq4_xs * )vbq ; 1726const uint8_t * values = (const uint8_t * )kvalues_iq4nl ; 1727 1728// iqs is 0...7 1729const int ib32 = iqs ; 1730const int32_t * q8 = (const int * )bq8_1 [ib32 ].qs ; 1731const uint32_t * q4 = (const uint32_t * )bq4 -> qs + 4 * ib32 ; 1732const int8_t ls = ((bq4 -> scales_l [ib32 /2 ] >>4 * (ib32 %2 ))& 0xf ) | (((bq4 -> scales_h >>2 * ib32 )& 3 ) <<4 ); 1733const float d = (float )bq4 -> d * (ls - 32 )* bq8_1 [ib32 ].ds [0 ]; 1734int v1 ,v2 ; 1735int sumi1 = 0 ,sumi2 = 0 ; 1736for (int j = 0 ;j < 4 ;++ j ) { 1737get_int_from_table_16 (q4 [j ],values ,v1 ,v2 ); 1738sumi1 = dpct::dp4a (v1 ,q8 [j + 0 ],sumi1 ); 1739sumi2 = dpct::dp4a (v2 ,q8 [j + 4 ],sumi2 ); 1740 } 1741return d * (sumi1 + sumi2 ); 1742#else 1743assert (false); 1744#endif 1745} 1746 1747#endif // GGML_SYCL_VECDOTQ_HPP