char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
d48a56eff
char/aliceai-t5-moe
1#define GGML_COMMON_IMPL_C 2#include "ggml-common.h" 3#include "ggml-quants.h" 4#include "ggml-impl.h" 5#include "ggml-cpu.h" 6#include "simd-mappings.h" 7 8#include "../../quants.h" 9#include "../../ggml-cpu-impl.h" 10 11#include <math.h> 12#include <string.h> 13#include <assert.h> 14#include <float.h> 15#include <stdlib.h> // for qsort 16#include <stdio.h> // for GGML_ASSERT 17 18#define GROUP_MAX_EPS 1e-15f 19#define GROUP_MAX_EPS_IQ3_XXS 1e-8f 20#define GROUP_MAX_EPS_IQ2_S 1e-8f 21#define GROUP_MAX_EPS_IQ1_M 1e-7f 22#define GROUP_MAX_EPS_IQ1_S 1e-12f 23 24#define UNUSED GGML_UNUSED 25 26#if defined(__loongarch_sx ) 27 28static __m128i lsx_packs_w (__m128i a ,__m128i b ) { 29__m128i tmp ,tmp1 ; 30tmp = __lsx_vsat_w (a ,15 ); 31tmp1 = __lsx_vsat_w (b ,15 ); 32return __lsx_vpickev_h (tmp1 ,tmp ); 33} 34 35static __m128i lsx_packs_h (__m128i a ,__m128i b ) { 36__m128i tmp ,tmp1 ; 37tmp = __lsx_vsat_h (a ,7 ); 38tmp1 = __lsx_vsat_h (b ,7 ); 39return __lsx_vpickev_b (tmp1 ,tmp ); 40} 41 42static __m128i lsx_packus_h (__m128i a ,__m128i b ) { 43__m128i tmp ,tmp1 ; 44tmp = __lsx_vsat_hu (a ,7 ); 45tmp1 = __lsx_vsat_hu (b ,7 ); 46return __lsx_vpickev_b (tmp1 ,tmp ); 47} 48 49static __m128i lsx_maddubs_h (__m128i a ,__m128i b ) { 50__m128i tmp1 ,tmp2 ; 51tmp1 = __lsx_vmulwev_h_b (a ,b ); 52tmp2 = __lsx_vmulwod_h_b (a ,b ); 53return __lsx_vsadd_h (tmp1 ,tmp2 ); 54} 55 56static __m128i lsx_madd_h (__m128i a ,__m128i b ) { 57__m128i tmp1 ,tmp2 ; 58tmp1 = __lsx_vmulwev_w_h (a ,b ); 59tmp2 = __lsx_vmulwod_w_h (a ,b ); 60return __lsx_vadd_w (tmp1 ,tmp2 ); 61} 62 63static __m128i lsx_set_w (int32_t a ,int32_t b ,int32_t c ,int32_t d ) { 64v4i32 __ret = {d ,c ,b ,a }; 65return (__m128i )__ret ; 66} 67 68static __m128i lsx_shuffle_b (__m128i a ,__m128i b ) { 69__m128i mask_f ,zero ,tmp0 ,tmp2 ,mask ; 70int f = 0x8f ; 71mask_f = __lsx_vreplgr2vr_b (f ); 72zero = __lsx_vldi (0 ); 73tmp0 = __lsx_vand_v (b ,mask_f );// get mask with low 4 bit and sign bits 74tmp0 = __lsx_vori_b (tmp0 ,0x10 );// make each mask or with 0x10 prepare for positive 75mask = __lsx_vsle_b (zero ,tmp0 );// if mask >= 0, set mask 76tmp2 = __lsx_vand_v (tmp0 ,mask );// maskout the in2 < ones 77return __lsx_vshuf_b (a ,zero ,tmp2 ); 78} 79 80static __m128i lsx_hadd_h (__m128i a ,__m128i b ) { 81__m128i tmp1 = __lsx_vpickev_h (b ,a ); 82__m128i tmp2 = __lsx_vpickod_h (b ,a ); 83return __lsx_vadd_h (tmp1 ,tmp2 ); 84} 85 86static __m128i lsx_hadd_w (__m128i a ,__m128i b ) { 87__m128i tmp1 = __lsx_vpickev_w (b ,a ); 88__m128i tmp2 = __lsx_vpickod_w (b ,a ); 89return __lsx_vadd_w (tmp1 ,tmp2 ); 90} 91 92static __m128 lsx_hadd_s (__m128 a ,__m128 b ) { 93__m128 tmp1 = (__m128 )__lsx_vpickev_w ((__m128i )b , (__m128i )a ); 94__m128 tmp2 = (__m128 )__lsx_vpickod_w ((__m128i )b , (__m128i )a ); 95 96return __lsx_vfadd_s (tmp1 ,tmp2 ); 97} 98 99static inline float hsum_float_4x4 (const __m128 a ,const __m128 b ,const __m128 c ,const __m128 d ) { 100__m128 res_0 = lsx_hadd_s (a ,b ); 101__m128 res_1 = lsx_hadd_s (c ,d ); 102__m128 res = lsx_hadd_s (res_0 ,res_1 ); 103res = lsx_hadd_s (res ,res ); 104res = lsx_hadd_s (res ,res ); 105 106return ((v4f32 )res )[0 ]; 107} 108 109// multiply int8_t, add results pairwise twice 110static inline __m128i mul_sum_i8_pairs (const __m128i x ,const __m128i y ) { 111// Get absolute values of x vectors 112const __m128i ax = __lsx_vsigncov_b (x ,x ); 113// Sign the values of the y vectors 114const __m128i sy = __lsx_vsigncov_b (x ,y ); 115// Perform multiplication and create 16-bit values 116const __m128i dot = lsx_maddubs_h (ax ,sy ); 117const __m128i ones = __lsx_vreplgr2vr_h (1 ); 118return lsx_madd_h (ones ,dot ); 119} 120#endif 121 122#if defined(__loongarch_asx ) 123 124#ifdef __clang__ 125#define VREGS_PREFIX "$vr" 126#define XREGS_PREFIX "$xr" 127#else // GCC 128#define VREGS_PREFIX "$f" 129#define XREGS_PREFIX "$f" 130#endif 131#define __ALL_REGS "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" 132// Convert __m128i to __m256i 133static inline __m256i ____m256i (__m128i in ) { 134__m256i out = __lasx_xvldi (0 ); 135 __asm__volatile ( 136".irp i," __ALL_REGS "\n\t" 137" .ifc %[out], " XREGS_PREFIX "\\i \n\t" 138" .irp j," __ALL_REGS "\n\t" 139" .ifc %[in], " VREGS_PREFIX "\\j \n\t" 140" xvpermi.q $xr\\i, $xr\\j, 0x20 \n\t" 141" .endif \n\t" 142" .endr \n\t" 143" .endif \n\t" 144".endr \n\t" 145 : [out ]"+f" (out ) : [in ]"f" (in ) 146 ); 147return out ; 148} 149// Convert two __m128i to __m256i 150static inline __m256i lasx_set_q (__m128i inhi ,__m128i inlo ) { 151__m256i out ; 152 __asm__volatile ( 153".irp i," __ALL_REGS "\n\t" 154" .ifc %[hi], " VREGS_PREFIX "\\i \n\t" 155" .irp j," __ALL_REGS "\n\t" 156" .ifc %[lo], " VREGS_PREFIX "\\j \n\t" 157" xvpermi.q $xr\\i, $xr\\j, 0x20 \n\t" 158" .endif \n\t" 159" .endr \n\t" 160" .endif \n\t" 161".endr \n\t" 162".ifnc %[out], %[hi] \n\t" 163".irp i," __ALL_REGS "\n\t" 164" .ifc %[out], " XREGS_PREFIX "\\i \n\t" 165" .irp j," __ALL_REGS "\n\t" 166" .ifc %[hi], " VREGS_PREFIX "\\j \n\t" 167" xvori.b $xr\\i, $xr\\j, 0 \n\t" 168" .endif \n\t" 169" .endr \n\t" 170" .endif \n\t" 171".endr \n\t" 172".endif \n\t" 173 : [out ]"=f" (out ), [hi ]"+f" (inhi ) 174 : [lo ]"f" (inlo ) 175 ); 176return out ; 177} 178// Convert __m256i low part to __m128i 179static inline __m128i lasx_extracti128_lo (__m256i in ) { 180__m128i out ; 181 __asm__volatile ( 182".ifnc %[out], %[in] \n\t" 183".irp i," __ALL_REGS "\n\t" 184" .ifc %[out], " VREGS_PREFIX "\\i \n\t" 185" .irp j," __ALL_REGS "\n\t" 186" .ifc %[in], " XREGS_PREFIX "\\j \n\t" 187" vori.b $vr\\i, $vr\\j, 0 \n\t" 188" .endif \n\t" 189" .endr \n\t" 190" .endif \n\t" 191".endr \n\t" 192".endif \n\t" 193 : [out ]"=f" (out ) : [in ]"f" (in ) 194 ); 195return out ; 196} 197// Convert __m256i high part to __m128i 198static inline __m128i lasx_extracti128_hi (__m256i in ) { 199__m128i out ; 200 __asm__volatile ( 201".irp i," __ALL_REGS "\n\t" 202" .ifc %[out], " VREGS_PREFIX "\\i \n\t" 203" .irp j," __ALL_REGS "\n\t" 204" .ifc %[in], " XREGS_PREFIX "\\j \n\t" 205" xvpermi.q $xr\\i, $xr\\j, 0x11 \n\t" 206" .endif \n\t" 207" .endr \n\t" 208" .endif \n\t" 209".endr \n\t" 210 : [out ]"=f" (out ) : [in ]"f" (in ) 211 ); 212return out ; 213} 214 215static __m256i lasx_set_w (int e7 ,int e6 ,int e5 ,int e4 ,int e3 ,int e2 ,int e1 ,int e0 ) { 216v8i32 __ret = {e0 ,e1 ,e2 ,e3 ,e4 ,e5 ,e6 ,e7 }; 217return (__m256i )__ret ; 218} 219 220static __m256i lasx_set_d (int64_t a ,int64_t b ,int64_t c ,int64_t d ) { 221v4i64 __ret = {d ,c ,b ,a }; 222return (__m256i )__ret ; 223} 224 225static __m256i lasx_insertf128 (__m128i x ,__m128i y ) { 226return lasx_set_q (x ,y ); 227} 228 229static __m256i lasx_shuffle_b (__m256i a ,__m256i b ) { 230__m256i mask_f ,zero ,tmp0 ,tmp2 ,mask ; 231int f = 0x8f ; 232mask_f = __lasx_xvreplgr2vr_b (f ); 233zero = __lasx_xvldi (0 ); 234tmp0 = __lasx_xvand_v (b ,mask_f );// get mask with low 4 bit and sign bits 235tmp0 = __lasx_xvori_b (tmp0 ,0x10 );// make each mask or with 0x10 prepare for positive 236mask = __lasx_xvsle_b (zero ,tmp0 );// if mask >= 0, set mask 237tmp2 = __lasx_xvand_v (tmp0 ,mask );// maskout the in2 < ones 238return __lasx_xvshuf_b (a ,zero ,tmp2 ); 239} 240 241static __m256i lasx_extu8_16 (__m128i a ) { 242return __lasx_vext2xv_hu_bu (____m256i (a )); 243} 244 245static __m256i lasx_ext8_16 (__m128i a ) { 246return __lasx_vext2xv_h_b (____m256i (a )); 247} 248 249static __m256i lasx_ext16_32 (__m128i a ) { 250return __lasx_vext2xv_w_h (____m256i (a )); 251} 252 253static __m128i lasx_extracti128 (__m256i a ,int pos ) { 254__m128i ret ; 255if (pos == 0 ) 256 { 257ret = lasx_extracti128_lo (a ); 258 }else { 259ret = lasx_extracti128_hi (a ); 260 } 261return ret ; 262} 263 264static __m128 lasx_extractf128 (__m256 a ,int pos ) { 265__m128 ret ; 266if (pos == 0 ) 267 { 268ret = (__m128 )lasx_extracti128_lo ((__m256i )a ); 269 }else { 270ret = (__m128 )lasx_extracti128_hi ((__m256i )a ); 271 } 272return ret ; 273} 274 275static __m256i lasx_maddubs_h (__m256i a ,__m256i b ) { 276__m256i tmp1 ,tmp2 ; 277tmp1 = __lasx_xvmulwev_h_b (a ,b ); 278tmp2 = __lasx_xvmulwod_h_b (a ,b ); 279return __lasx_xvsadd_h (tmp1 ,tmp2 ); 280} 281 282static __m256i lasx_madd_h (__m256i a ,__m256i b ) { 283__m256i tmp1 ,tmp2 ; 284tmp1 = __lasx_xvmulwev_w_h (a ,b ); 285tmp2 = __lasx_xvmulwod_w_h (a ,b ); 286return __lasx_xvadd_w (tmp1 ,tmp2 ); 287} 288 289static __m256i lasx_packs_w (__m256i a ,__m256i b ) { 290__m256i tmp ,tmp1 ; 291tmp = __lasx_xvsat_w (a ,15 ); 292tmp1 = __lasx_xvsat_w (b ,15 ); 293return __lasx_xvpickev_h (tmp1 ,tmp ); 294} 295 296static __m256i lasx_packs_h (__m256i a ,__m256i b ) { 297__m256i tmp ,tmp1 ; 298tmp = __lasx_xvsat_h (a ,7 ); 299tmp1 = __lasx_xvsat_h (b ,7 ); 300return __lasx_xvpickev_b (tmp1 ,tmp ); 301} 302 303static inline __m256i lasx_madd_h_b (__m256i a ,__m256i b ) { 304__m256i tmp1 ,tmp2 ; 305tmp1 = __lasx_xvmulwev_h_b (a ,b ); 306tmp2 = __lasx_xvmulwod_h_b (a ,b ); 307return __lasx_xvadd_h (tmp1 ,tmp2 ); 308} 309 310static inline __m256i lasx_xvrepl128vei_h (__m256i a ,const unsigned int b ) { 311switch (b ) { 312case 0 :return __lasx_xvrepl128vei_h (a ,0 ); 313case 1 :return __lasx_xvrepl128vei_h (a ,1 ); 314case 2 :return __lasx_xvrepl128vei_h (a ,2 ); 315case 3 :return __lasx_xvrepl128vei_h (a ,3 ); 316case 4 :return __lasx_xvrepl128vei_h (a ,4 ); 317case 5 :return __lasx_xvrepl128vei_h (a ,5 ); 318case 6 :return __lasx_xvrepl128vei_h (a ,6 ); 319case 7 :return __lasx_xvrepl128vei_h (a ,7 ); 320default :__builtin_unreachable (); 321 } 322} 323 324static inline __m256i lasx_xvandi_b_bit (__m256i a ,const unsigned int b ) { 325switch (b ) { 326case 0 :return __lasx_xvandi_b (a ,1 <<0 ); 327case 1 :return __lasx_xvandi_b (a ,1 <<1 ); 328case 2 :return __lasx_xvandi_b (a ,1 <<2 ); 329case 3 :return __lasx_xvandi_b (a ,1 <<3 ); 330case 4 :return __lasx_xvandi_b (a ,1 <<4 ); 331case 5 :return __lasx_xvandi_b (a ,1 <<5 ); 332case 6 :return __lasx_xvandi_b (a ,1 <<6 ); 333case 7 :return __lasx_xvandi_b (a ,1 <<7 ); 334default :__builtin_unreachable (); 335 } 336} 337 338// horizontally add 8 floats 339static inline float hsum_float_8 (const __m256 x ) { 340__m128 res = lasx_extractf128 (x ,1 ); 341res = __lsx_vfadd_s (res ,lasx_extractf128 (x ,0 )); 342res = __lsx_vfadd_s (res , (__m128 )__lsx_vpickod_d ((__m128i )res , (__m128i )res )); 343res = __lsx_vfadd_s (res , (__m128 )__lsx_vinsgr2vr_w (__lsx_vldi (0 ),__lsx_vpickve2gr_w (res ,1 ),0 )); 344return ((v4f32 )res )[0 ]; 345} 346 347// horizontally add 8 int32_t 348static inline int hsum_i32_8 (const __m256i a ) { 349 350__m256i tmp1 = __lasx_xvpermi_q (a ,a ,0x11 ); 351__m256i tmp2 = __lasx_xvpermi_q (a ,a ,0x00 ); 352 353__m128i tmp1_128 = lasx_extracti128_lo (tmp1 ); 354__m128i tmp2_128 = lasx_extracti128_lo (tmp2 ); 355 356__m128i sum128 = __lsx_vadd_w (tmp1_128 ,tmp2_128 ); 357 358__m128i ev = __lsx_vpickev_w (sum128 ,sum128 ); 359__m128i od = __lsx_vpickod_w (sum128 ,sum128 ); 360__m128i sum64 = __lsx_vadd_w (ev ,od ); 361 362int sum64_1 ,sum64_2 ; 363sum64_1 = __lsx_vpickve2gr_w (sum64 ,0 ); 364sum64_2 = __lsx_vpickve2gr_w (sum64 ,1 ); 365 366return sum64_1 + sum64_2 ; 367} 368 369// horizontally add 4 int32_t 370static inline int hsum_i32_4 (const __m128i a ) { 371__m128i ev = __lsx_vpickev_w (a ,a ); 372__m128i od = __lsx_vpickod_w (a ,a ); 373__m128i sum64 = __lsx_vadd_w (ev ,od ); 374 375int sum64_1 ,sum64_2 ; 376sum64_1 = __lsx_vpickve2gr_w (sum64 ,0 ); 377sum64_2 = __lsx_vpickve2gr_w (sum64 ,1 ); 378 379return sum64_1 + sum64_2 ; 380} 381 382// spread 32 bits to 32 bytes { 0x00, 0xFF } 383static inline __m256i bytes_from_bits_32 (const uint8_t * x ) { 384 385uint32_t x32 ; 386memcpy (& x32 ,x ,sizeof (uint32_t )); 387const __m256i shuf_mask = lasx_set_d ( 3880x0303030303030303 ,0x0202020202020202 , 3890x0101010101010101 ,0x0000000000000000 ); 390 391__m256i bytes = lasx_shuffle_b (__lasx_xvreplgr2vr_w (x32 ),shuf_mask ); 392const __m256i bit_mask = __lasx_xvreplgr2vr_d (0x7fbfdfeff7fbfdfe ); 393bytes = __lasx_xvor_v (bytes ,bit_mask ); 394return __lasx_xvseq_b (bytes ,__lasx_xvreplgr2vr_d (-1 )); 395} 396 397// Unpack 32 4-bit fields into 32 bytes 398// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval 399static inline __m256i bytes_from_nibbles_32 (const uint8_t * rsi ) { 400const __m128i lo = __lsx_vld ((const __m128i * )rsi ,0 ); 401__m128i hi = __lsx_vsrli_h (lo ,4 ); 402return __lasx_xvandi_b (lasx_insertf128 (hi ,lo ),0xf ); 403} 404 405// add int16_t pairwise and return as float vector 406static inline __m256 sum_i16_pairs_float (const __m256i x ) { 407__m256i v = __lasx_xvpackod_h (x ,x ); 408__m256i summed_pairs = __lasx_xvaddwev_w_h (x ,v ); 409return __lasx_xvffint_s_w (summed_pairs ); 410} 411 412static inline __m256 mul_sum_us8_pairs_float (const __m256i ax ,const __m256i sy ) { 413// Perform multiplication and create 16-bit values 414const __m256i dot = lasx_maddubs_h (ax ,sy ); 415return sum_i16_pairs_float (dot ); 416} 417 418// multiply int8_t, add results pairwise twice and return as float vector 419static inline __m256 mul_sum_i8_pairs_float (const __m256i x ,const __m256i y ) { 420const __m256i dot = lasx_madd_h_b (x ,y ); 421return sum_i16_pairs_float (dot ); 422} 423 424static inline __m128i packNibbles (__m256i bytes ) { 425// Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh 426const __m256i lowByte = __lasx_xvreplgr2vr_h (0xFF ); 427__m256i high = __lasx_xvandn_v (lowByte ,bytes ); 428__m256i low = __lasx_xvand_v (lowByte ,bytes ); 429high = __lasx_xvsrli_h (high ,4 ); 430bytes = __lasx_xvor_v (low ,high ); 431// Compress uint16_t lanes into bytes 432__m128i * r0 = (__m128i * )& bytes ; 433__m256i tmp_h128 = __lasx_xvpermi_q (bytes ,bytes ,0x11 ); 434__m128i * r1 = (__m128i * )& tmp_h128 ; 435 436__m128i zero = __lsx_vldi (0 ); 437__m128i tmp ,tmp2 ,tmp3 ; 438 439tmp = __lsx_vmax_h (zero ,* r0 ); 440tmp2 = __lsx_vsat_hu (tmp ,7 ); 441 442tmp = __lsx_vmax_h (zero ,* r1 ); 443tmp3 = __lsx_vsat_hu (tmp ,7 ); 444return __lsx_vpickev_b (tmp3 ,tmp2 ); 445} 446#endif //__loongarch_asx 447 448void quantize_row_q8_0 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 449assert (QK8_0 == 32 ); 450assert (k %QK8_0 == 0 ); 451const int nb = k /QK8_0 ; 452 453block_q8_0 * GGML_RESTRICT y = vy ; 454 455#if defined(__loongarch_asx ) 456for (int i = 0 ;i < nb ;i ++ ) { 457__m256 v0 = (__m256 )__lasx_xvld (x ,0 ); 458__m256 v1 = (__m256 )__lasx_xvld (x ,32 ); 459__m256 v2 = (__m256 )__lasx_xvld (x ,64 ); 460__m256 v3 = (__m256 )__lasx_xvld (x ,96 ); 461x += 32 ; 462 463// Compute max(abs(e)) for the block 464const __m256 sign_bit = __lasx_xvreplfr2vr_s (-0.0f ); 465__m256 max_abs = (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v0 ); 466max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v1 ) ); 467max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v2 ) ); 468max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v3 ) ); 469 470__m128 max4 = __lsx_vfmax_s (lasx_extractf128 (max_abs ,1 ),lasx_extractf128 (max_abs ,0 ) ); 471max4 = __lsx_vfmax_s (max4 , (__m128 )__lsx_vpickod_d ((__m128i )max4 , (__m128i )max4 ) ); 472__m128 tmp = max4 ; 473max4 = __lsx_vfmax_s (max4 , (__m128 )__lsx_vinsgr2vr_w (tmp ,__lsx_vpickve2gr_w (max4 ,1 ),0 )); 474const float max_scalar = ((v4f32 )max4 )[0 ]; 475 476// Quantize these floats 477const float d = max_scalar /127.f ; 478y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 479const float id = (max_scalar != 0.0f ) ?127.f /max_scalar :0.0f ; 480const __m256 mul = (__m256 )__lasx_xvreplfr2vr_s (id ); 481 482// Apply the multiplier 483v0 = __lasx_xvfmul_s (v0 ,mul ); 484v1 = __lasx_xvfmul_s (v1 ,mul ); 485v2 = __lasx_xvfmul_s (v2 ,mul ); 486v3 = __lasx_xvfmul_s (v3 ,mul ); 487 488// Round to nearest integer 489__m256i i0 = __lasx_xvftintrne_w_s (v0 ); 490__m256i i1 = __lasx_xvftintrne_w_s (v1 ); 491__m256i i2 = __lasx_xvftintrne_w_s (v2 ); 492__m256i i3 = __lasx_xvftintrne_w_s (v3 ); 493 494__m128i ni0 = lasx_extracti128 (i0 ,0 ); 495__m128i ni1 = lasx_extracti128 (i0 ,1 ); 496__m128i ni2 = lasx_extracti128 (i1 ,0 ); 497__m128i ni3 = lasx_extracti128 (i1 ,1 ); 498__m128i ni4 = lasx_extracti128 (i2 ,0 ); 499__m128i ni5 = lasx_extracti128 (i2 ,1 ); 500__m128i ni6 = lasx_extracti128 (i3 ,0 ); 501__m128i ni7 = lasx_extracti128 (i3 ,1 ); 502 503// Convert int32 to int16 504ni0 = lsx_packs_w (ni0 ,ni1 ); 505ni2 = lsx_packs_w (ni2 ,ni3 ); 506ni4 = lsx_packs_w (ni4 ,ni5 ); 507ni6 = lsx_packs_w (ni6 ,ni7 ); 508// Convert int16 to int8 509ni0 = lsx_packs_h (ni0 ,ni2 ); 510ni4 = lsx_packs_h (ni4 ,ni6 ); 511 512__lsx_vst (ni0 , (__m128i * )(y [i ].qs + 0 ),0 ); 513__lsx_vst (ni4 , (__m128i * )(y [i ].qs + 16 ),0 ); 514 515 } 516#else 517GGML_UNUSED (nb ); 518// scalar 519quantize_row_q8_0_ref (x ,y ,k ); 520#endif 521} 522 523void quantize_row_q8_1 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 524assert (k %QK8_1 == 0 ); 525const int nb = k /QK8_1 ; 526 527block_q8_1 * GGML_RESTRICT y = vy ; 528 529#if defined(__loongarch_asx ) 530for (int i = 0 ;i < nb ;i ++ ) { 531__m256 v0 = (__m256 )__lasx_xvld (x ,0 ); 532__m256 v1 = (__m256 )__lasx_xvld (x ,32 ); 533__m256 v2 = (__m256 )__lasx_xvld (x ,64 ); 534__m256 v3 = (__m256 )__lasx_xvld (x ,96 ); 535x += 32 ; 536 537// Compute max(abs(e)) for the block 538const __m256 sign_bit = __lasx_xvreplfr2vr_s (-0.0f ); 539__m256 max_abs = (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v0 ); 540max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v1 ) ); 541max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v2 ) ); 542max_abs = __lasx_xvfmax_s (max_abs , (__m256 )__lasx_xvandn_v ( (__m256i )sign_bit , (__m256i )v3 ) ); 543 544__m128 max4 = __lsx_vfmax_s (lasx_extractf128 (max_abs ,1 ),lasx_extractf128 (max_abs ,0 ) ); 545max4 = __lsx_vfmax_s (max4 , (__m128 )__lsx_vpickod_d ((__m128i )max4 , (__m128i )max4 ) ); 546__m128 tmp = max4 ; 547max4 = __lsx_vfmax_s (max4 , (__m128 )__lsx_vextrins_w ((__m128i )tmp , (__m128i )max4 ,0x1 )); 548const float max_scalar = ((v4f32 )max4 )[0 ]; 549 550// Quantize these floats 551const float d = max_scalar /127.f ; 552y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 553const float id = (max_scalar != 0.0f ) ?127.f /max_scalar :0.0f ; 554const __m256 mul = __lasx_xvreplfr2vr_s (id ); 555 556// Apply the multiplier 557v0 = __lasx_xvfmul_s (v0 ,mul ); 558v1 = __lasx_xvfmul_s (v1 ,mul ); 559v2 = __lasx_xvfmul_s (v2 ,mul ); 560v3 = __lasx_xvfmul_s (v3 ,mul ); 561 562// Round to nearest integer 563__m256i i0 = __lasx_xvftintrne_w_s (v0 ); 564__m256i i1 = __lasx_xvftintrne_w_s (v1 ); 565__m256i i2 = __lasx_xvftintrne_w_s (v2 ); 566__m256i i3 = __lasx_xvftintrne_w_s (v3 ); 567 568__m128i ni0 = lasx_extracti128 (i0 ,0 ); 569__m128i ni1 = lasx_extracti128 (i0 ,1 ); 570__m128i ni2 = lasx_extracti128 (i1 ,0 ); 571__m128i ni3 = lasx_extracti128 (i1 ,1 ); 572__m128i ni4 = lasx_extracti128 (i2 ,0 ); 573__m128i ni5 = lasx_extracti128 (i2 ,1 ); 574__m128i ni6 = lasx_extracti128 (i3 ,0 ); 575__m128i ni7 = lasx_extracti128 (i3 ,1 ); 576 577// Compute the sum of the quants and set y[i].s 578const __m128i s0 = __lsx_vadd_w (__lsx_vadd_w (ni0 ,ni1 ),__lsx_vadd_w (ni2 ,ni3 )); 579const __m128i s1 = __lsx_vadd_w (__lsx_vadd_w (ni4 ,ni5 ),__lsx_vadd_w (ni6 ,ni7 )); 580y [i ].s = GGML_CPU_FP32_TO_FP16 (d * hsum_i32_4 (__lsx_vadd_w (s0 ,s1 ))); 581 582// Convert int32 to int16 583ni0 = lsx_packs_w (ni0 ,ni1 ); 584ni2 = lsx_packs_w (ni2 ,ni3 ); 585ni4 = lsx_packs_w (ni4 ,ni5 ); 586ni6 = lsx_packs_w (ni6 ,ni7 ); 587// Convert int16 to int8 588ni0 = lsx_packs_h (ni0 ,ni2 ); 589ni4 = lsx_packs_h (ni4 ,ni6 ); 590 591__lsx_vst (ni0 , (__m128i * )(y [i ].qs + 0 ),0 ); 592__lsx_vst (ni4 , (__m128i * )(y [i ].qs + 16 ),0 ); 593 } 594#else 595GGML_UNUSED (nb ); 596// scalar 597quantize_row_q8_1_ref (x ,y ,k ); 598#endif 599} 600 601 602//===================================== Dot products ================================= 603 604// 605// Helper functions 606// 607 608#if defined(__loongarch_asx ) 609// shuffles to pick the required scales in dot products 610static inline __m256i get_scale_shuffle_q3k (int i ) { 611static const uint8_t k_shuffle [128 ]= { 6120 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 , 6134 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 , 6148 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 , 61512 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 , 616 }; 617return __lasx_xvld ((const __m256i * )k_shuffle + i ,0 ); 618} 619static inline __m256i get_scale_shuffle_k4 (int i ) { 620static const uint8_t k_shuffle [256 ]= { 6210 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 , 6222 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 ,2 ,3 , 6234 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 ,4 ,5 , 6246 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 ,6 ,7 , 6258 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 ,8 ,9 , 62610 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 ,10 ,11 , 62712 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 ,12 ,13 , 62814 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 ,14 ,15 629 }; 630return __lasx_xvld ((const __m256i * )k_shuffle + i ,0 ); 631} 632static inline __m128i get_scale_shuffle (int i ) { 633static const uint8_t k_shuffle [128 ]= { 6340 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 , 6352 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 , 6364 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 , 6376 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 , 6388 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 , 63910 ,10 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,11 ,11 ,11 ,11 ,11 ,11 ,11 , 64012 ,12 ,12 ,12 ,12 ,12 ,12 ,12 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,13 , 64114 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,15 ,15 ,15 ,15 ,15 ,15 ,15 ,15 642 }; 643return __lsx_vld ((const __m128i * )k_shuffle + i ,0 ); 644} 645#endif 646 647void ggml_vec_dot_q4_0_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 648const int qk = QK8_0 ; 649const int nb = n /qk ; 650 651assert (n %qk == 0 ); 652assert (nrc == 1 ); 653UNUSED (nrc ); 654UNUSED (bx ); 655UNUSED (by ); 656UNUSED (bs ); 657 658const block_q4_0 * GGML_RESTRICT x = vx ; 659const block_q8_0 * GGML_RESTRICT y = vy ; 660 661int ib = 0 ; 662float sumf = 0 ; 663 664#if defined(__loongarch_asx ) 665// Initialize accumulator with zeros 666__m256 acc = (__m256 )__lasx_xvldi (0 ); 667 668// Main loop 669for (;ib < nb ;++ ib ) { 670/* Compute combined scale for the block */ 671const __m256 d = __lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ) ); 672 673__m256i qx = bytes_from_nibbles_32 (x [ib ].qs ); 674 675// Now we have a vector with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. 676const __m256i off = __lasx_xvreplgr2vr_b (8 ); 677qx = __lasx_xvsub_b (qx ,off ); 678 679__m256i qy = __lasx_xvld ((const __m256i * )y [ib ].qs ,0 ); 680 681const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 682 683/* Multiply q with scale and accumulate */ 684acc = __lasx_xvfmadd_s (d ,q ,acc ); 685 } 686 687sumf = hsum_float_8 (acc ); 688 689#elif defined(__loongarch_sx ) 690// set constants 691const __m128i low_mask = __lsx_vreplgr2vr_b (0xF ); 692const __m128i off = __lsx_vreplgr2vr_b (8 ); 693 694// Initialize accumulator with zeros 695__m128 acc_0 = (__m128 )__lsx_vldi (0 ); 696__m128 acc_1 = (__m128 )__lsx_vldi (0 ); 697__m128 acc_2 = (__m128 )__lsx_vldi (0 ); 698__m128 acc_3 = (__m128 )__lsx_vldi (0 ); 699 700for (;ib + 1 < nb ;ib += 2 ) { 701 702// Compute combined scale for the block 0 and 1 703const float ft0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 704const __m128 d_0_1 = (__m128 )(v4f32 ){ft0 ,ft0 ,ft0 ,ft0 }; 705 706const __m128i tmp_0_1 = __lsx_vld ((const __m128i * )x [ib ].qs ,0 ); 707 708__m128i bx_0 = __lsx_vand_v (low_mask ,tmp_0_1 ); 709__m128i by_0 = __lsx_vld ((const __m128i * )y [ib ].qs ,0 ); 710bx_0 = __lsx_vsub_b (bx_0 ,off ); 711const __m128i i32_0 = mul_sum_i8_pairs (bx_0 ,by_0 ); 712 713__m128i bx_1 = __lsx_vand_v (low_mask ,__lsx_vsrli_d (tmp_0_1 ,4 )); 714__m128i by_1 = __lsx_vld ((const __m128i * )(y [ib ].qs + 16 ),0 ); 715bx_1 = __lsx_vsub_b (bx_1 ,off ); 716const __m128i i32_1 = mul_sum_i8_pairs (bx_1 ,by_1 ); 717 718// Compute combined scale for the block 2 and 3 719const float ft1 = GGML_CPU_FP16_TO_FP32 (x [ib + 1 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d ); 720const __m128 d_2_3 = (__m128 )(v4f32 ){ft1 ,ft1 ,ft1 ,ft1 }; 721 722const __m128i tmp_2_3 = __lsx_vld ((const __m128i * )x [ib + 1 ].qs ,0 ); 723 724__m128i bx_2 = __lsx_vand_v (low_mask ,tmp_2_3 ); 725__m128i by_2 = __lsx_vld ((const __m128i * )y [ib + 1 ].qs ,0 ); 726bx_2 = __lsx_vsub_b (bx_2 ,off ); 727const __m128i i32_2 = mul_sum_i8_pairs (bx_2 ,by_2 ); 728 729__m128i bx_3 = __lsx_vand_v (low_mask ,__lsx_vsrli_d (tmp_2_3 ,4 )); 730__m128i by_3 = __lsx_vld ((const __m128i * )(y [ib + 1 ].qs + 16 ),0 ); 731bx_3 = __lsx_vsub_b (bx_3 ,off ); 732const __m128i i32_3 = mul_sum_i8_pairs (bx_3 ,by_3 ); 733 734// Convert int32_t to float 735__m128 p0 = __lsx_vffint_s_w (i32_0 ); 736__m128 p1 = __lsx_vffint_s_w (i32_1 ); 737__m128 p2 = __lsx_vffint_s_w (i32_2 ); 738__m128 p3 = __lsx_vffint_s_w (i32_3 ); 739 740// Apply the scale 741__m128 p0_d = __lsx_vfmul_s (d_0_1 ,p0 ); 742__m128 p1_d = __lsx_vfmul_s (d_0_1 ,p1 ); 743__m128 p2_d = __lsx_vfmul_s (d_2_3 ,p2 ); 744__m128 p3_d = __lsx_vfmul_s (d_2_3 ,p3 ); 745 746// Acummulate 747acc_0 = __lsx_vfadd_s (p0_d ,acc_0 ); 748acc_1 = __lsx_vfadd_s (p1_d ,acc_1 ); 749acc_2 = __lsx_vfadd_s (p2_d ,acc_2 ); 750acc_3 = __lsx_vfadd_s (p3_d ,acc_3 ); 751 } 752 753sumf = hsum_float_4x4 (acc_0 ,acc_1 ,acc_2 ,acc_3 ); 754 755#endif 756for (;ib < nb ;++ ib ) { 757int sumi0 = 0 ; 758int sumi1 = 0 ; 759 760for (int j = 0 ;j < qk /2 ;++ j ) { 761const int v0 = (x [ib ].qs [j ]& 0x0F )- 8 ; 762const int v1 = (x [ib ].qs [j ] >>4 )- 8 ; 763 764sumi0 += (v0 * y [ib ].qs [j ]); 765sumi1 += (v1 * y [ib ].qs [j + qk /2 ]); 766 } 767 768int sumi = sumi0 + sumi1 ; 769sumf += sumi * GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 770 } 771 772* s = sumf ; 773} 774 775void ggml_vec_dot_q4_1_q8_1 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 776const int qk = QK8_1 ; 777const int nb = n /qk ; 778 779assert (n %qk == 0 ); 780assert (nrc == 1 ); 781UNUSED (nrc ); 782UNUSED (bx ); 783UNUSED (by ); 784UNUSED (bs ); 785 786const block_q4_1 * GGML_RESTRICT x = vx ; 787const block_q8_1 * GGML_RESTRICT y = vy ; 788 789int ib = 0 ; 790float sumf = 0 ; 791 792#if defined(__loongarch_asx ) 793// Initialize accumulator with zeros 794__m256 acc = (__m256 )__lasx_xvldi (0 ); 795 796float summs = 0 ; 797 798// Main loop 799for (;ib < nb ;++ ib ) { 800const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 801const float d1 = GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 802 803summs += GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 804 805const __m256 d0v = __lasx_xvreplfr2vr_s (d0 ); 806const __m256 d1v = __lasx_xvreplfr2vr_s (d1 ); 807 808// Compute combined scales 809const __m256 d0d1 = __lasx_xvfmul_s (d0v ,d1v ); 810 811// Load 16 bytes, and unpack 4 bit fields into bytes, making 32 bytes 812const __m256i qx = bytes_from_nibbles_32 (x [ib ].qs ); 813const __m256i qy = __lasx_xvld ( (const __m256i * )y [ib ].qs ,0 ); 814 815const __m256 xy = mul_sum_us8_pairs_float (qx ,qy ); 816 817// Accumulate d0*d1*x*y 818acc = __lasx_xvfmadd_s (d0d1 ,xy ,acc ); 819 } 820 821sumf = hsum_float_8 (acc )+ summs ; 822 823* s = sumf ; 824#else 825UNUSED (nb ); 826UNUSED (x ); 827UNUSED (y ); 828UNUSED (ib ); 829UNUSED (sumf ); 830ggml_vec_dot_q4_1_q8_1_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 831#endif 832} 833 834void ggml_vec_dot_q5_0_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 835const int qk = QK8_0 ; 836const int nb = n /qk ; 837 838int ib = 0 ; 839float sumf = 0 ; 840 841assert (n %qk == 0 ); 842assert (qk == QK5_0 ); 843assert (nrc == 1 ); 844UNUSED (nrc ); 845UNUSED (bx ); 846UNUSED (by ); 847UNUSED (bs ); 848 849const block_q5_0 * GGML_RESTRICT x = vx ; 850const block_q8_0 * GGML_RESTRICT y = vy ; 851 852#if defined(__loongarch_asx ) 853// Initialize accumulator with zeros 854__m256 acc = (__m256 )__lasx_xvldi (0 ); 855 856// Main loop 857for (;ib < nb ;++ ib ) { 858/* Compute combined scale for the block */ 859const __m256 d = __lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ));//FIXME 860 861__m256i qx = bytes_from_nibbles_32 (x [ib ].qs ); 862__m256i bxhi = bytes_from_bits_32 (x [ib ].qh ); 863bxhi = __lasx_xvandn_v (bxhi ,__lasx_xvreplgr2vr_b ((char )0xF0 )); 864qx = __lasx_xvor_v (qx ,bxhi ); 865 866__m256i qy = __lasx_xvld ((const __m256i * )y [ib ].qs ,0 ); 867 868const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 869 870/* Multiply q with scale and accumulate */ 871acc = __lasx_xvfmadd_s (d ,q ,acc ); 872 } 873 874sumf = hsum_float_8 (acc ); 875 876* s = sumf ; 877#else 878UNUSED (nb ); 879UNUSED (ib ); 880UNUSED (sumf ); 881UNUSED (x ); 882UNUSED (y ); 883ggml_vec_dot_q5_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 884#endif 885} 886 887void ggml_vec_dot_q5_1_q8_1 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 888const int qk = QK8_1 ; 889const int nb = n /qk ; 890 891int ib = 0 ; 892float sumf = 0 ; 893 894assert (n %qk == 0 ); 895assert (qk == QK5_1 ); 896assert (nrc == 1 ); 897UNUSED (nrc ); 898UNUSED (bx ); 899UNUSED (by ); 900UNUSED (bs ); 901 902const block_q5_1 * GGML_RESTRICT x = vx ; 903const block_q8_1 * GGML_RESTRICT y = vy ; 904 905#if defined(__loongarch_asx ) 906// Initialize accumulator with zeros 907__m256 acc = (__m256 )__lasx_xvldi (0 ); 908 909float summs = 0.0f ; 910 911// Main loop 912for (;ib < nb ;++ ib ) { 913const __m256 dx = __lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (x [ib ].d )); 914 915summs += GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 916 917__m256i qx = bytes_from_nibbles_32 (x [ib ].qs ); 918__m256i bxhi = bytes_from_bits_32 (x [ib ].qh ); 919bxhi = __lasx_xvand_v (bxhi ,__lasx_xvreplgr2vr_b (0x10 )); 920qx = __lasx_xvor_v (qx ,bxhi ); 921 922const __m256 dy = __lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 923const __m256i qy = __lasx_xvld ((const __m256i * )y [ib ].qs ,0 ); 924 925const __m256 q = mul_sum_us8_pairs_float (qx ,qy ); 926 927acc = __lasx_xvfmadd_s (q ,__lasx_xvfmul_s (dx ,dy ),acc ); 928 } 929 930sumf = hsum_float_8 (acc )+ summs ; 931 932* s = sumf ; 933#else 934UNUSED (nb ); 935UNUSED (ib ); 936UNUSED (sumf ); 937UNUSED (x ); 938UNUSED (y ); 939ggml_vec_dot_q5_1_q8_1_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 940#endif 941} 942 943void ggml_vec_dot_q8_0_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 944const int qk = QK8_0 ; 945const int nb = n /qk ; 946 947assert (n %qk == 0 ); 948assert (nrc == 1 ); 949UNUSED (nrc ); 950UNUSED (bx ); 951UNUSED (by ); 952UNUSED (bs ); 953 954const block_q8_0 * GGML_RESTRICT x = vx ; 955const block_q8_0 * GGML_RESTRICT y = vy ; 956 957int ib = 0 ; 958float sumf = 0 ; 959 960#if defined(__loongarch_asx ) 961// Initialize accumulator with zeros 962__m256 acc = (__m256 )__lasx_xvldi (0 ); 963 964// Main loop 965for (;ib < nb ;++ ib ) { 966// Compute combined scale for the block 967const __m256 d = __lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 968__m256i qx = __lasx_xvld ((const __m256i * )x [ib ].qs ,0 ); 969__m256i qy = __lasx_xvld ((const __m256i * )y [ib ].qs ,0 ); 970 971const __m256 q = mul_sum_i8_pairs_float (qx ,qy ); 972 973// Multiply q with scale and accumulate 974acc = __lasx_xvfmadd_s (d ,q ,acc ); 975 } 976 977sumf = hsum_float_8 (acc ); 978 979* s = sumf ; 980 981#elif defined(__loongarch_sx ) 982 983__m128 acc = (__m128 )__lsx_vldi (0 ); 984 985for (;ib < nb ;++ ib ) { 986const float d = GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 987const __m128i qx_0 = __lsx_vld ((const __m128i * )x [ib ].qs ,0 ); 988const __m128i qx_1 = __lsx_vld ((const __m128i * )x [ib ].qs + 1 ,0 ); 989const __m128i qy_0 = __lsx_vld ((const __m128i * )y [ib ].qs ,0 ); 990const __m128i qy_1 = __lsx_vld ((const __m128i * )y [ib ].qs + 1 ,0 ); 991 992const __m128i p16_0 = lsx_maddubs_h (qx_0 ,qy_0 ); 993const __m128i p16_1 = lsx_maddubs_h (qx_1 ,qy_1 ); 994 995// Sum int16 pairs → int32 996const __m128i s_0 = __lsx_vaddwev_w_h (p16_0 ,p16_1 ); 997const __m128i s_1 = __lsx_vaddwod_w_h (p16_0 ,p16_1 ); 998 999const __m128 q = __lsx_vffint_s_w (__lsx_vadd_w (s_0 ,s_1 )); 1000acc = __lsx_vfmadd_s (__lsx_vreplfr2vr_s (d ),q ,acc ); 1001 } 1002 1003__m128 res = lsx_hadd_s (acc ,acc ); 1004res = lsx_hadd_s (res ,res ); 1005sumf = ((v4f32 )res )[0 ]; 1006 1007* s = sumf ; 1008 1009#else 1010UNUSED (nb ); 1011UNUSED (ib ); 1012UNUSED (sumf ); 1013UNUSED (x ); 1014UNUSED (y ); 1015ggml_vec_dot_q8_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1016#endif 1017} 1018 1019void ggml_vec_dot_q2_K_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1020assert (nrc == 1 ); 1021UNUSED (nrc ); 1022UNUSED (bx ); 1023UNUSED (by ); 1024UNUSED (bs ); 1025 1026const block_q2_K * GGML_RESTRICT x = vx ; 1027const block_q8_K * GGML_RESTRICT y = vy ; 1028 1029const int nb = n /QK_K ; 1030 1031#if defined__loongarch_asx 1032 1033__m256 acc = (__m256 )__lasx_xvldi (0 ); 1034 1035for (int i = 0 ;i < nb ;++ i ) { 1036 1037const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1038const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1039 1040const uint8_t * GGML_RESTRICT q2 = x [i ].qs ; 1041const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1042 1043const __m128i mins_and_scales128 = __lsx_vld ((const __m128i * )x [i ].scales ,0 ); 1044const __m128i scales128 = __lsx_vandi_b (mins_and_scales128 ,0xf ); 1045const __m256i mins = lasx_ext8_16 (__lsx_vsrli_b (mins_and_scales128 ,4 )); 1046const __m256i prod = lasx_madd_h (mins ,__lasx_xvld ((const __m256i * )y [i ].bsums ,0 )); 1047 1048acc = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (dmin ),__lasx_xvffint_s_w (prod ),acc ); 1049 1050const v16i8 shuffle_mask = {0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,1 ,3 ,5 ,7 ,9 ,11 ,13 ,15 }; 1051const __m256i scales_shuffled = lasx_ext8_16 (__lsx_vshuf_b (scales128 ,scales128 , (__m128i )shuffle_mask )); 1052 1053__m256i sumi = __lasx_xvldi (0 ); 1054 1055for (int j = 0 ;j < QK_K /128 ;++ j ) { 1056 1057const __m256i q2bits = __lasx_xvld ((const __m256i * )q2 ,0 );q2 += 32 ; 1058 1059const __m256i q8_0 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1060const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1061const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1062const __m256i q8_3 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1063 1064const __m256i q2_0 = __lasx_xvandi_b (q2bits ,3 ); 1065const __m256i q2_1 = __lasx_xvandi_b (__lasx_xvsrli_b (q2bits ,2 ),3 ); 1066const __m256i q2_2 = __lasx_xvandi_b (__lasx_xvsrli_b (q2bits ,4 ),3 ); 1067const __m256i q2_3 = __lasx_xvsrli_b (q2bits ,6 ); 1068 1069__m256i p0 = lasx_madd_h_b (q2_0 ,q8_0 ); 1070__m256i p1 = lasx_madd_h_b (q2_1 ,q8_1 ); 1071__m256i p2 = lasx_madd_h_b (q2_2 ,q8_2 ); 1072__m256i p3 = lasx_madd_h_b (q2_3 ,q8_3 ); 1073 1074p0 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 0 ),p0 ); 1075p1 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 1 ),p1 ); 1076p2 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 2 ),p2 ); 1077p3 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 3 ),p3 ); 1078 1079p0 = __lasx_xvadd_w (p0 ,p1 ); 1080p2 = __lasx_xvadd_w (p2 ,p3 ); 1081 1082sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p0 ,p2 )); 1083 } 1084 1085acc = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (sumi ),acc ); 1086 1087 } 1088 1089* s = hsum_float_8 (acc ); 1090 1091#else 1092UNUSED (x ); 1093UNUSED (y ); 1094UNUSED (nb ); 1095ggml_vec_dot_q2_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1096#endif 1097} 1098 1099void ggml_vec_dot_q3_K_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1100assert (n %QK_K == 0 ); 1101assert (nrc == 1 ); 1102UNUSED (nrc ); 1103UNUSED (bx ); 1104UNUSED (by ); 1105UNUSED (bs ); 1106 1107const uint32_t kmask1 = 0x03030303 ; 1108const uint32_t kmask2 = 0x0f0f0f0f ; 1109 1110const block_q3_K * GGML_RESTRICT x = vx ; 1111const block_q8_K * GGML_RESTRICT y = vy ; 1112 1113const int nb = n /QK_K ; 1114 1115#if defined__loongarch_asx 1116 1117const __m128i m32 = __lsx_vreplgr2vr_b (32 ); 1118 1119__m256 acc = (__m256 )__lasx_xvldi (0 ); 1120 1121uint32_t aux [3 ]; 1122 1123for (int i = 0 ;i < nb ;++ i ) { 1124 1125const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1126const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1127const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1128// Set up scales 1129memcpy (aux ,x [i ].scales ,12 ); 1130__m128i scales128 = lsx_set_w ( 1131 ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ), 1132 ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ), 1133 (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ), 1134 (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 )); 1135scales128 = __lsx_vsub_b (scales128 ,m32 ); 1136 1137const v16i8 shuffle_mask = {0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,1 ,3 ,5 ,7 ,9 ,11 ,13 ,15 }; 1138const __m256i scales_shuffled = lasx_ext8_16 (__lsx_vshuf_b (scales128 ,scales128 , (__m128i )shuffle_mask )); 1139 1140// high bit 1141const __m256i hbits = __lasx_xvld ((const __m256i * )x [i ].hmask ,0 ); 1142 1143// integer accumulator 1144__m256i sumi = __lasx_xvldi (0 ); 1145 1146for (int j = 0 ;j < QK_K /128 ;++ j ) { 1147// load low 2 bits 1148const __m256i q3bits = __lasx_xvld ((const __m256i * )q3 ,0 );q3 += 32 ; 1149 1150// prepare low and high bits 1151const __m256i q3l_0 = __lasx_xvandi_b (q3bits ,3 ); 1152const __m256i q3l_1 = __lasx_xvandi_b (__lasx_xvsrli_b (q3bits ,2 ),3 ); 1153const __m256i q3l_2 = __lasx_xvandi_b (__lasx_xvsrli_b (q3bits ,4 ),3 ); 1154const __m256i q3l_3 = __lasx_xvsrli_b (q3bits ,6 ); 1155const __m256i q3h_0 = __lasx_xvslli_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,4 * j + 0 ),0 ),2 ); 1156const __m256i q3h_1 = __lasx_xvslli_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,4 * j + 1 ),0 ),2 ); 1157const __m256i q3h_2 = __lasx_xvslli_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,4 * j + 2 ),0 ),2 ); 1158const __m256i q3h_3 = __lasx_xvslli_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,4 * j + 3 ),0 ),2 ); 1159const __m256i q3_0 = __lasx_xvor_v (q3h_0 ,q3l_0 ); 1160const __m256i q3_1 = __lasx_xvor_v (q3h_1 ,q3l_1 ); 1161const __m256i q3_2 = __lasx_xvor_v (q3h_2 ,q3l_2 ); 1162const __m256i q3_3 = __lasx_xvor_v (q3h_3 ,q3l_3 ); 1163 1164// load Q8 quants 1165const __m256i q8_0 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1166const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1167const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1168const __m256i q8_3 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1169 1170__m256i p16_0 = lasx_madd_h_b (q8_0 ,q3_0 ); 1171__m256i p16_1 = lasx_madd_h_b (q8_1 ,q3_1 ); 1172__m256i p16_2 = lasx_madd_h_b (q8_2 ,q3_2 ); 1173__m256i p16_3 = lasx_madd_h_b (q8_3 ,q3_3 ); 1174 1175// multiply with scales 1176p16_0 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 0 ),p16_0 ); 1177p16_1 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 1 ),p16_1 ); 1178p16_2 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 2 ),p16_2 ); 1179p16_3 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 3 ),p16_3 ); 1180 1181// accumulate 1182p16_0 = __lasx_xvadd_w (p16_0 ,p16_1 ); 1183p16_2 = __lasx_xvadd_w (p16_2 ,p16_3 ); 1184sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p16_0 ,p16_2 )); 1185 } 1186// multiply with block scale and accumulate 1187acc = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (sumi ),acc ); 1188 } 1189 1190* s = hsum_float_8 (acc ); 1191 1192#else 1193UNUSED (kmask1 ); 1194UNUSED (kmask2 ); 1195UNUSED (x ); 1196UNUSED (y ); 1197UNUSED (nb ); 1198ggml_vec_dot_q3_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1199#endif 1200} 1201 1202void ggml_vec_dot_q4_K_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1203assert (n %QK_K == 0 ); 1204assert (nrc == 1 ); 1205UNUSED (nrc ); 1206UNUSED (bx ); 1207UNUSED (by ); 1208UNUSED (bs ); 1209 1210const block_q4_K * GGML_RESTRICT x = vx ; 1211const block_q8_K * GGML_RESTRICT y = vy ; 1212 1213const int nb = n /QK_K ; 1214 1215static const uint32_t kmask1 = 0x3f3f3f3f ; 1216static const uint32_t kmask2 = 0x0f0f0f0f ; 1217static const uint32_t kmask3 = 0x03030303 ; 1218 1219uint32_t utmp [4 ]; 1220 1221#if defined__loongarch_asx 1222 1223__m256 acc = (__m256 )__lasx_xvldi (0 ); 1224__m128 acc_m = (__m128 )__lsx_vldi (0 ); 1225 1226for (int i = 0 ;i < nb ;++ i ) { 1227 1228const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1229const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1230 1231memcpy (utmp ,x [i ].scales ,12 ); 1232utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 1233const uint32_t uaux = utmp [1 ]& kmask1 ; 1234utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 1235utmp [2 ]= uaux ; 1236utmp [0 ] &=kmask1 ; 1237 1238const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 1239const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1240 1241const __m128i mins_and_scales128 = lsx_set_w (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ]); 1242const __m128i mins128 = __lsx_vexth_h_b (mins_and_scales128 ); 1243const __m128i scales128 = __lsx_vsllwil_h_b (mins_and_scales128 ,0 ); 1244 1245const __m256i q8sums = __lasx_xvld ((const __m256i * )y [i ].bsums ,0 ); 1246const __m128i q8s = lsx_hadd_h (lasx_extracti128 (q8sums ,0 ),lasx_extracti128 (q8sums ,1 )); 1247const __m128i prod = lsx_madd_h (mins128 ,q8s ); 1248acc_m = __lsx_vfmadd_s (__lsx_vreplfr2vr_s (dmin ),__lsx_vffint_s_w (prod ),acc_m ); 1249 1250const __m256i scales = lasx_insertf128 (scales128 ,scales128 ); 1251 1252__m256i sumi = __lasx_xvldi (0 ); 1253 1254for (int j = 0 ;j < QK_K /64 ;++ j ) { 1255 1256const __m256i scale_l = lasx_xvrepl128vei_h (scales ,2 * j + 0 ); 1257const __m256i scale_h = lasx_xvrepl128vei_h (scales ,2 * j + 1 ); 1258 1259const __m256i q4bits = __lasx_xvld ((const __m256i * )q4 ,0 );q4 += 32 ; 1260const __m256i q4l = __lasx_xvandi_b (q4bits ,0xf ); 1261const __m256i q4h = __lasx_xvsrli_b (q4bits ,4 ); 1262 1263const __m256i q8l = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1264__m256i p16l = lasx_madd_h_b (q4l ,q8l ); 1265p16l = lasx_madd_h (scale_l ,p16l ); 1266 1267const __m256i q8h = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1268__m256i p16h = lasx_madd_h_b (q4h ,q8h ); 1269p16h = lasx_madd_h (scale_h ,p16h ); 1270const __m256i sumj = __lasx_xvadd_w (p16l ,p16h ); 1271 1272sumi = __lasx_xvadd_w (sumi ,sumj ); 1273 } 1274 1275__m256 vd = __lasx_xvreplfr2vr_s (d ); 1276acc = __lasx_xvfmadd_s (vd ,__lasx_xvffint_s_w (sumi ),acc ); 1277 1278 } 1279 1280acc_m = __lsx_vfadd_s (acc_m , (__m128 )__lsx_vpermi_w ((__m128i )acc_m , (__m128i )acc_m ,0xee )); 1281__m128i tmp1 = __lsx_vinsgr2vr_w (__lsx_vldi (0 ),__lsx_vpickve2gr_w ((__m128i )acc_m ,1 ),0 ); 1282acc_m = __lsx_vfadd_s (acc_m , (__m128 )tmp1 ); 1283 1284 1285* s = hsum_float_8 (acc )+ ((v4f32 )acc_m )[0 ]; 1286 1287#else 1288UNUSED (x ); 1289UNUSED (y ); 1290UNUSED (nb ); 1291UNUSED (kmask1 ); 1292UNUSED (kmask2 ); 1293UNUSED (kmask3 ); 1294UNUSED (utmp ); 1295ggml_vec_dot_q4_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1296#endif 1297} 1298 1299void ggml_vec_dot_q5_K_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1300assert (n %QK_K == 0 ); 1301assert (nrc == 1 ); 1302UNUSED (nrc ); 1303UNUSED (bx ); 1304UNUSED (by ); 1305UNUSED (bs ); 1306 1307const block_q5_K * GGML_RESTRICT x = vx ; 1308const block_q8_K * GGML_RESTRICT y = vy ; 1309 1310const int nb = n /QK_K ; 1311 1312static const uint32_t kmask1 = 0x3f3f3f3f ; 1313static const uint32_t kmask2 = 0x0f0f0f0f ; 1314static const uint32_t kmask3 = 0x03030303 ; 1315 1316uint32_t utmp [4 ]; 1317 1318#if defined__loongarch_asx 1319 1320__m256 acc = (__m256 )__lasx_xvldi (0 ); 1321__m128 acc_m = (__m128 )__lsx_vldi (0 ); 1322 1323for (int i = 0 ;i < nb ;++ i ) { 1324 1325const uint8_t * GGML_RESTRICT q5 = x [i ].qs ; 1326const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1327 1328const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1329const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1330 1331memcpy (utmp ,x [i ].scales ,12 ); 1332utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 1333const uint32_t uaux = utmp [1 ]& kmask1 ; 1334utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 1335utmp [2 ]= uaux ; 1336utmp [0 ] &=kmask1 ; 1337 1338const __m128i mins_and_scales128 = lsx_set_w (utmp [3 ],utmp [2 ],utmp [1 ],utmp [0 ]); 1339const __m128i mins128 = __lsx_vexth_h_b (mins_and_scales128 ); 1340const __m128i scales128 = __lsx_vsllwil_h_b (mins_and_scales128 ,0 ); 1341 1342const __m256i q8sums = __lasx_xvld ((const __m256i * )y [i ].bsums ,0 ); 1343const __m128i q8s = lsx_hadd_h (lasx_extracti128 (q8sums ,0 ),lasx_extracti128 (q8sums ,1 )); 1344const __m128i prod = lsx_madd_h (mins128 ,q8s ); 1345acc_m = __lsx_vfmadd_s (__lsx_vreplfr2vr_s (dmin ),__lsx_vffint_s_w (prod ),acc_m ); 1346 1347const __m256i scales = lasx_insertf128 (scales128 ,scales128 ); 1348 1349const __m256i hbits = __lasx_xvld ((const __m256i * )x [i ].qh ,0 ); 1350 1351__m256i sumi = __lasx_xvldi (0 ); 1352 1353for (int j = 0 ;j < QK_K /64 ;++ j ) { 1354 1355const __m256i scale_0 = lasx_xvrepl128vei_h (scales ,2 * j + 0 ); 1356const __m256i scale_1 = lasx_xvrepl128vei_h (scales ,2 * j + 1 ); 1357 1358const __m256i q5bits = __lasx_xvld ((const __m256i * )q5 ,0 );q5 += 32 ; 1359 1360const __m256i q5l_0 = __lasx_xvandi_b (q5bits ,0xf ); 1361const __m256i q5l_1 = __lasx_xvsrli_b (q5bits ,4 ); 1362const __m256i q5h_0 = __lasx_xvnori_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,2 * j + 0 ),0 ),0xef ); 1363const __m256i q5h_1 = __lasx_xvnori_b (__lasx_xvseqi_b (lasx_xvandi_b_bit (hbits ,2 * j + 1 ),0 ),0xef ); 1364const __m256i q5_0 = __lasx_xvor_v (q5l_0 ,q5h_0 ); 1365const __m256i q5_1 = __lasx_xvor_v (q5l_1 ,q5h_1 ); 1366 1367const __m256i q8_0 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1368const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1369 1370__m256i p16_0 = lasx_madd_h_b (q5_0 ,q8_0 ); 1371__m256i p16_1 = lasx_madd_h_b (q5_1 ,q8_1 ); 1372 1373p16_0 = lasx_madd_h (scale_0 ,p16_0 ); 1374p16_1 = lasx_madd_h (scale_1 ,p16_1 ); 1375 1376sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p16_0 ,p16_1 )); 1377 1378 } 1379 1380__m256 vd = __lasx_xvreplfr2vr_s (d ); 1381acc = __lasx_xvfmadd_s (vd ,__lasx_xvffint_s_w (sumi ),acc ); 1382 1383 } 1384 1385acc_m = __lsx_vfadd_s (acc_m , (__m128 )__lsx_vbsrl_v (acc_m ,8 )); 1386acc_m = __lsx_vfadd_s (acc_m , (__m128 )__lsx_vbsrl_v (acc_m ,4 )); 1387 1388* s = hsum_float_8 (acc )+ ((v4f32 )acc_m )[0 ]; 1389 1390#else 1391UNUSED (x ); 1392UNUSED (y ); 1393UNUSED (nb ); 1394UNUSED (kmask1 ); 1395UNUSED (kmask2 ); 1396UNUSED (kmask3 ); 1397UNUSED (utmp ); 1398ggml_vec_dot_q5_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1399#endif 1400} 1401 1402void ggml_vec_dot_q6_K_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1403assert (n %QK_K == 0 ); 1404assert (nrc == 1 ); 1405UNUSED (nrc ); 1406UNUSED (bx ); 1407UNUSED (by ); 1408UNUSED (bs ); 1409 1410const block_q6_K * GGML_RESTRICT x = vx ; 1411const block_q8_K * GGML_RESTRICT y = vy ; 1412 1413const int nb = n /QK_K ; 1414 1415#if defined__loongarch_asx 1416 1417const __m256i m32s = __lasx_xvreplgr2vr_b (32 ); 1418 1419__m256 acc = (__m256 )__lasx_xvldi (0 ); 1420 1421for (int i = 0 ;i < nb ;++ i ) { 1422 1423const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1424 1425const uint8_t * GGML_RESTRICT q4 = x [i ].ql ; 1426const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 1427const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1428 1429const __m128i scales128 = __lsx_vld ((const __m128i * )x [i ].scales ,0 ); 1430const v16i8 shuffle_mask = {0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,1 ,3 ,5 ,7 ,9 ,11 ,13 ,15 }; 1431const __m256i scales_shuffled = lasx_ext8_16 (__lsx_vshuf_b (scales128 ,scales128 , (__m128i )shuffle_mask )); 1432 1433__m256i sumi = __lasx_xvldi (0 ); 1434 1435for (int j = 0 ;j < QK_K /128 ;++ j ) { 1436 1437const __m256i q4bits1 = __lasx_xvld ((const __m256i * )q4 ,0 );q4 += 32 ; 1438const __m256i q4bits2 = __lasx_xvld ((const __m256i * )q4 ,0 );q4 += 32 ; 1439const __m256i q4bitsH = __lasx_xvld ((const __m256i * )qh ,0 );qh += 32 ; 1440 1441const __m256i q4h_0 = __lasx_xvslli_b (__lasx_xvandi_b (q4bitsH ,3 ),4 ); 1442const __m256i q4h_1 = __lasx_xvslli_b (__lasx_xvandi_b (q4bitsH ,3 <<2 ),2 ); 1443const __m256i q4h_2 = __lasx_xvandi_b (q4bitsH ,3 <<4 ); 1444const __m256i q4h_3 = __lasx_xvsrli_b (__lasx_xvandi_b (q4bitsH ,3 <<6 ),2 ); 1445 1446const __m256i q4_0 = __lasx_xvor_v (__lasx_xvandi_b (q4bits1 ,0xf ),q4h_0 ); 1447const __m256i q4_1 = __lasx_xvor_v (__lasx_xvandi_b (q4bits2 ,0xf ),q4h_1 ); 1448const __m256i q4_2 = __lasx_xvor_v (__lasx_xvsrli_b (q4bits1 ,4 ),q4h_2 ); 1449const __m256i q4_3 = __lasx_xvor_v (__lasx_xvsrli_b (q4bits2 ,4 ),q4h_3 ); 1450 1451const __m256i q8_0 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1452const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1453const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1454const __m256i q8_3 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1455 1456__m256i p16_0 = lasx_madd_h_b (__lasx_xvsub_b (q4_0 ,m32s ),q8_0 ); 1457__m256i p16_1 = lasx_madd_h_b (__lasx_xvsub_b (q4_1 ,m32s ),q8_1 ); 1458__m256i p16_2 = lasx_madd_h_b (__lasx_xvsub_b (q4_2 ,m32s ),q8_2 ); 1459__m256i p16_3 = lasx_madd_h_b (__lasx_xvsub_b (q4_3 ,m32s ),q8_3 ); 1460 1461p16_0 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 0 ),p16_0 ); 1462p16_1 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 1 ),p16_1 ); 1463p16_2 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 2 ),p16_2 ); 1464p16_3 = lasx_madd_h (lasx_xvrepl128vei_h (scales_shuffled ,4 * j + 3 ),p16_3 ); 1465 1466sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p16_0 ,p16_1 )); 1467sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p16_2 ,p16_3 )); 1468 } 1469 1470acc = __lasx_xvfmadd_s ((__m256 )__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (sumi ),acc ); 1471 } 1472 1473* s = hsum_float_8 (acc ); 1474 1475#elif defined(__loongarch_sx ) 1476 1477const __m128i m32s = __lsx_vreplgr2vr_b (32 ); 1478 1479__m128 acc_0 = (__m128 )__lsx_vldi (0 ); 1480__m128 acc_1 = (__m128 )__lsx_vldi (0 ); 1481 1482for (int i = 0 ;i < nb ;++ i ) { 1483 1484const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1485 1486const uint8_t * GGML_RESTRICT q4 = x [i ].ql ; 1487const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 1488const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1489 1490const __m128i scale_i8 = __lsx_vld (x [i ].scales ,0 ); 1491const __m128i scales_lo = __lsx_vsllwil_h_b (scale_i8 ,0 ); 1492const __m128i scales_hi = __lsx_vsllwil_h_b (__lsx_vbsrl_v (scale_i8 ,8 ),0 ); 1493 1494__m128i sumi_0 = __lsx_vldi (0 ); 1495__m128i sumi_1 = __lsx_vldi (0 ); 1496 1497for (int j = 0 ;j < QK_K /128 ;++ j ) { 1498 1499const __m128i q4bitsH_0 = __lsx_vld ((const __m128i * )qh ,0 );qh += 16 ; 1500const __m128i q4bitsH_1 = __lsx_vld ((const __m128i * )qh ,0 );qh += 16 ; 1501 1502const __m128i q4h_0 = __lsx_vslli_b (__lsx_vandi_b (q4bitsH_0 ,3 ),4 ); 1503const __m128i q4h_1 = __lsx_vslli_b (__lsx_vandi_b (q4bitsH_1 ,3 ),4 ); 1504const __m128i q4h_2 = __lsx_vslli_b (__lsx_vandi_b (q4bitsH_0 ,3 <<2 ),2 ); 1505const __m128i q4h_3 = __lsx_vslli_b (__lsx_vandi_b (q4bitsH_1 ,3 <<2 ),2 ); 1506const __m128i q4h_4 = __lsx_vandi_b (q4bitsH_0 ,3 <<4 ); 1507const __m128i q4h_5 = __lsx_vandi_b (q4bitsH_1 ,3 <<4 ); 1508const __m128i q4h_6 = __lsx_vsrli_b (__lsx_vandi_b (q4bitsH_0 ,3 <<6 ),2 ); 1509const __m128i q4h_7 = __lsx_vsrli_b (__lsx_vandi_b (q4bitsH_1 ,3 <<6 ),2 ); 1510 1511const __m128i q4bits1_0 = __lsx_vld ((const __m128i * )q4 ,0 );q4 += 16 ; 1512const __m128i q4bits1_1 = __lsx_vld ((const __m128i * )q4 ,0 );q4 += 16 ; 1513const __m128i q4bits2_0 = __lsx_vld ((const __m128i * )q4 ,0 );q4 += 16 ; 1514const __m128i q4bits2_1 = __lsx_vld ((const __m128i * )q4 ,0 );q4 += 16 ; 1515 1516const __m128i q4_0 = __lsx_vor_v (__lsx_vandi_b (q4bits1_0 ,0xf ),q4h_0 ); 1517const __m128i q4_1 = __lsx_vor_v (__lsx_vandi_b (q4bits1_1 ,0xf ),q4h_1 ); 1518const __m128i q4_2 = __lsx_vor_v (__lsx_vandi_b (q4bits2_0 ,0xf ),q4h_2 ); 1519const __m128i q4_3 = __lsx_vor_v (__lsx_vandi_b (q4bits2_1 ,0xf ),q4h_3 ); 1520const __m128i q4_4 = __lsx_vor_v (__lsx_vsrli_b (q4bits1_0 ,4 ),q4h_4 ); 1521const __m128i q4_5 = __lsx_vor_v (__lsx_vsrli_b (q4bits1_1 ,4 ),q4h_5 ); 1522const __m128i q4_6 = __lsx_vor_v (__lsx_vsrli_b (q4bits2_0 ,4 ),q4h_6 ); 1523const __m128i q4_7 = __lsx_vor_v (__lsx_vsrli_b (q4bits2_1 ,4 ),q4h_7 ); 1524 1525const __m128i q8_0 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1526const __m128i q8_1 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1527const __m128i q8_2 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1528const __m128i q8_3 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1529const __m128i q8_4 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1530const __m128i q8_5 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1531const __m128i q8_6 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1532const __m128i q8_7 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 1533 1534__m128i p16_0 = lsx_maddubs_h (__lsx_vsub_b (q4_0 ,m32s ),q8_0 ); 1535__m128i p16_1 = lsx_maddubs_h (__lsx_vsub_b (q4_1 ,m32s ),q8_1 ); 1536__m128i p16_2 = lsx_maddubs_h (__lsx_vsub_b (q4_2 ,m32s ),q8_2 ); 1537__m128i p16_3 = lsx_maddubs_h (__lsx_vsub_b (q4_3 ,m32s ),q8_3 ); 1538__m128i p16_4 = lsx_maddubs_h (__lsx_vsub_b (q4_4 ,m32s ),q8_4 ); 1539__m128i p16_5 = lsx_maddubs_h (__lsx_vsub_b (q4_5 ,m32s ),q8_5 ); 1540__m128i p16_6 = lsx_maddubs_h (__lsx_vsub_b (q4_6 ,m32s ),q8_6 ); 1541__m128i p16_7 = lsx_maddubs_h (__lsx_vsub_b (q4_7 ,m32s ),q8_7 ); 1542 1543const __m128i sc_vec = j == 0 ?scales_lo :scales_hi ; 1544 1545p16_0 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,0 ),p16_0 ); 1546p16_1 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,1 ),p16_1 ); 1547p16_2 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,2 ),p16_2 ); 1548p16_3 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,3 ),p16_3 ); 1549p16_4 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,4 ),p16_4 ); 1550p16_5 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,5 ),p16_5 ); 1551p16_6 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,6 ),p16_6 ); 1552p16_7 = lsx_madd_h (__lsx_vreplvei_h (sc_vec ,7 ),p16_7 ); 1553 1554sumi_0 = __lsx_vadd_w (sumi_0 ,__lsx_vadd_w (p16_0 ,p16_2 )); 1555sumi_1 = __lsx_vadd_w (sumi_1 ,__lsx_vadd_w (p16_1 ,p16_3 )); 1556sumi_0 = __lsx_vadd_w (sumi_0 ,__lsx_vadd_w (p16_4 ,p16_6 )); 1557sumi_1 = __lsx_vadd_w (sumi_1 ,__lsx_vadd_w (p16_5 ,p16_7 )); 1558 } 1559 1560__m128 p_0 = __lsx_vfmul_s (__lsx_vreplfr2vr_s (d ),__lsx_vffint_s_w (sumi_0 )); 1561__m128 p_1 = __lsx_vfmul_s (__lsx_vreplfr2vr_s (d ),__lsx_vffint_s_w (sumi_1 )); 1562acc_0 = __lsx_vfadd_s (p_0 ,acc_0 ); 1563acc_1 = __lsx_vfadd_s (p_1 ,acc_1 ); 1564 } 1565 1566* s = hsum_float_4x4 (acc_0 ,acc_1 , (__m128 )__lsx_vldi (0 ), (__m128 )__lsx_vldi (0 )); 1567 1568#else 1569UNUSED (x ); 1570UNUSED (y ); 1571UNUSED (nb ); 1572ggml_vec_dot_q6_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1573#endif 1574} 1575 1576#if defined(__loongarch_asx ) 1577static const int8_t keven_signs_q2xs [1024 ]= { 15781 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 , 15791 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 , 15801 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 , 15811 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 , 15821 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 , 15831 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 , 15841 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 , 15851 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 , 15861 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 , 15871 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 , 15881 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 , 15891 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 , 15901 ,1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 , 15911 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 , 15921 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 , 15931 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 , 15941 ,1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 , 15951 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,1 , 15961 ,1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 , 15971 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 , 15981 ,1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 , 15991 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 , 16001 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 , 16011 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 , 16021 ,1 ,1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,1 , 16031 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 , 16041 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 , 16051 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 , 16061 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 , 16071 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,1 , 16081 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,1 , 16091 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 ,-1 , 1610}; 1611#endif 1612 1613void ggml_vec_dot_iq2_xxs_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1614assert (n %QK_K == 0 ); 1615assert (nrc == 1 ); 1616UNUSED (nrc ); 1617UNUSED (bx ); 1618UNUSED (by ); 1619UNUSED (bs ); 1620 1621const block_iq2_xxs * GGML_RESTRICT x = vx ; 1622const block_q8_K * GGML_RESTRICT y = vy ; 1623 1624const int nb = n /QK_K ; 1625 1626#if defined(__loongarch_asx ) 1627 1628const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 1629 1630uint32_t aux32 [4 ]; 1631const uint8_t * aux8 = (const uint8_t * )aux32 ; 1632 1633__m256 accumf = (__m256 )__lasx_xvldi (0 ); 1634for (int i = 0 ;i < nb ;++ i ) { 1635const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1636const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 1637const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1638__m256i sumi1 = __lasx_xvldi (0 ); 1639__m256i sumi2 = __lasx_xvldi (0 ); 1640for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 1641const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1642const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1643memcpy (aux32 ,q2 ,4 * sizeof (uint32_t ));q2 += 8 ; 1644 1645const __m256i q2_1 = lasx_set_d (iq2xxs_grid [aux8 [3 ]],iq2xxs_grid [aux8 [2 ]],iq2xxs_grid [aux8 [1 ]],iq2xxs_grid [aux8 [0 ]]); 1646const __m256i q2_2 = lasx_set_d (iq2xxs_grid [aux8 [11 ]],iq2xxs_grid [aux8 [10 ]],iq2xxs_grid [aux8 [9 ]],iq2xxs_grid [aux8 [8 ]]); 1647const __m256i s2_1 = lasx_set_d (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ], 1648signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 1649const __m256i s2_2 = lasx_set_d (signs64 [(aux32 [3 ] >>21 )& 127 ],signs64 [(aux32 [3 ] >>14 )& 127 ], 1650signs64 [(aux32 [3 ] >>7 )& 127 ],signs64 [(aux32 [3 ] >>0 )& 127 ]); 1651const __m256i q8s_1 = __lasx_xvsigncov_b (s2_1 ,q8_1 ); 1652const __m256i q8s_2 = __lasx_xvsigncov_b (s2_2 ,q8_2 ); 1653const __m256i dot1 = lasx_maddubs_h (q2_1 ,q8s_1 ); 1654const __m256i dot2 = lasx_maddubs_h (q2_2 ,q8s_2 ); 1655const uint16_t ls1 = aux32 [1 ] >>28 ; 1656const uint16_t ls2 = aux32 [3 ] >>28 ; 1657const __m256i p1 = lasx_madd_h (dot1 ,__lasx_xvreplgr2vr_h (2 * ls1 + 1 )); 1658const __m256i p2 = lasx_madd_h (dot2 ,__lasx_xvreplgr2vr_h (2 * ls2 + 1 )); 1659sumi1 = __lasx_xvadd_w (sumi1 ,p1 ); 1660sumi2 = __lasx_xvadd_w (sumi2 ,p2 ); 1661 } 1662 1663accumf = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accumf ); 1664 } 1665 1666* s = 0.125f * hsum_float_8 (accumf ); 1667 1668#else 1669UNUSED (x ); 1670UNUSED (y ); 1671UNUSED (nb ); 1672ggml_vec_dot_iq2_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1673#endif 1674} 1675 1676void ggml_vec_dot_iq2_xs_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1677assert (n %QK_K == 0 ); 1678assert (nrc == 1 ); 1679UNUSED (nrc ); 1680UNUSED (bx ); 1681UNUSED (by ); 1682UNUSED (bs ); 1683 1684const block_iq2_xs * GGML_RESTRICT x = vx ; 1685const block_q8_K * GGML_RESTRICT y = vy ; 1686 1687const int nb = n /QK_K ; 1688 1689#if defined(__loongarch_asx ) 1690 1691const __m256i mone = __lasx_xvreplgr2vr_b (1 ); 1692static const char block_sign_shuffle_mask_1 [32 ]= { 16930x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 , 16940x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x04 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 ,0x06 , 1695 }; 1696static const char block_sign_shuffle_mask_2 [32 ]= { 16970x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x08 ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a ,0x0a , 16980x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0c ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e ,0x0e , 1699 }; 1700static const uint8_t bit_selector_mask_bytes [32 ]= { 17010x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 17020x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 1703 }; 1704 1705const __m256i bit_selector_mask = __lasx_xvld ((const __m256i * )bit_selector_mask_bytes ,0 ); 1706const __m256i block_sign_shuffle_1 = __lasx_xvld ((const __m256i * )block_sign_shuffle_mask_1 ,0 ); 1707const __m256i block_sign_shuffle_2 = __lasx_xvld ((const __m256i * )block_sign_shuffle_mask_2 ,0 ); 1708 1709static const uint8_t k_bit_helper [32 ]= { 17100x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 17110x00 ,0x80 ,0x80 ,0x00 ,0x80 ,0x00 ,0x00 ,0x80 ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x80 ,0x80 ,0x00 , 1712 }; 1713const __m256i bit_helper = __lasx_xvld ((const __m256i * )k_bit_helper ,0 ); 1714const __m256i m511 = __lasx_xvreplgr2vr_h (511 ); 1715const __m128i m4 = __lsx_vreplgr2vr_b (0xf ); 1716const __m128i m1 = __lsx_vreplgr2vr_b (1 ); 1717 1718uint64_t aux64 ; 1719 1720// somewhat hacky, but gives a significant boost in performance 1721__m256i aux_gindex ; 1722const uint16_t * gindex = (const uint16_t * )& aux_gindex ; 1723 1724__m256 accumf = (__m256 )__lasx_xvldi (0 ); 1725for (int i = 0 ;i < nb ;++ i ) { 1726const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1727const uint16_t * GGML_RESTRICT q2 = x [i ].qs ; 1728const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1729 1730memcpy (& aux64 ,x [i ].scales ,8 ); 1731__m128i stmp = __lsx_vreplgr2vr_d (aux64 ); 1732stmp = __lsx_vilvl_b (__lsx_vand_v (__lsx_vsrli_h (stmp ,4 ),m4 ),__lsx_vand_v (stmp ,m4 )); 1733const __m128i scales = __lsx_vadd_b (__lsx_vslli_h (stmp ,1 ),m1 ); 1734 1735__m256i sumi1 = __lasx_xvldi (0 ); 1736__m256i sumi2 = __lasx_xvldi (0 ); 1737for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 4 ) { 1738 1739const __m256i q2_data = __lasx_xvld ((const __m256i * )q2 ,0 );q2 += 16 ; 1740aux_gindex = __lasx_xvand_v (q2_data ,m511 ); 1741 1742const __m256i partial_sign_bits = __lasx_xvsrli_h (q2_data ,9 ); 1743const __m256i partial_sign_bits_upper = __lasx_xvsrli_h (q2_data ,13 ); 1744const __m256i partial_sign_bits_for_counting = __lasx_xvxor_v (partial_sign_bits ,partial_sign_bits_upper ); 1745 1746const __m256i odd_bits = lasx_shuffle_b (bit_helper ,partial_sign_bits_for_counting ); 1747const __m256i full_sign_bits = __lasx_xvor_v (partial_sign_bits ,odd_bits ); 1748 1749const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1750const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1751const __m256i q8_3 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1752const __m256i q8_4 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1753 1754const __m256i q2_1 = lasx_set_d (iq2xs_grid [gindex [3 ]],iq2xs_grid [gindex [2 ]], 1755iq2xs_grid [gindex [1 ]],iq2xs_grid [gindex [0 ]]); 1756const __m256i q2_2 = lasx_set_d (iq2xs_grid [gindex [7 ]],iq2xs_grid [gindex [6 ]], 1757iq2xs_grid [gindex [5 ]],iq2xs_grid [gindex [4 ]]); 1758const __m256i q2_3 = lasx_set_d (iq2xs_grid [gindex [11 ]],iq2xs_grid [gindex [10 ]], 1759iq2xs_grid [gindex [9 ]],iq2xs_grid [gindex [8 ]]); 1760const __m256i q2_4 = lasx_set_d (iq2xs_grid [gindex [15 ]],iq2xs_grid [gindex [14 ]], 1761iq2xs_grid [gindex [13 ]],iq2xs_grid [gindex [12 ]]); 1762 1763const __m128i full_signs_l = lasx_extracti128 (full_sign_bits ,0 ); 1764const __m128i full_signs_h = lasx_extracti128 (full_sign_bits ,1 ); 1765const __m256i full_signs_1 = lasx_insertf128 (full_signs_l ,full_signs_l ); 1766const __m256i full_signs_2 = lasx_insertf128 (full_signs_h ,full_signs_h ); 1767 1768__m256i signs ; 1769signs = lasx_shuffle_b (full_signs_1 ,block_sign_shuffle_1 ); 1770signs = __lasx_xvseq_b (__lasx_xvand_v (signs ,bit_selector_mask ),bit_selector_mask ); 1771const __m256i q8s_1 = __lasx_xvsigncov_b (__lasx_xvor_v (signs ,mone ),q8_1 ); 1772 1773signs = lasx_shuffle_b (full_signs_1 ,block_sign_shuffle_2 ); 1774signs = __lasx_xvseq_b (__lasx_xvand_v (signs ,bit_selector_mask ),bit_selector_mask ); 1775const __m256i q8s_2 = __lasx_xvsigncov_b (__lasx_xvor_v (signs ,mone ),q8_2 ); 1776 1777signs = lasx_shuffle_b (full_signs_2 ,block_sign_shuffle_1 ); 1778signs = __lasx_xvseq_b (__lasx_xvand_v (signs ,bit_selector_mask ),bit_selector_mask ); 1779const __m256i q8s_3 = __lasx_xvsigncov_b (__lasx_xvor_v (signs ,mone ),q8_3 ); 1780 1781signs = lasx_shuffle_b (full_signs_2 ,block_sign_shuffle_2 ); 1782signs = __lasx_xvseq_b (__lasx_xvand_v (signs ,bit_selector_mask ),bit_selector_mask ); 1783const __m256i q8s_4 = __lasx_xvsigncov_b (__lasx_xvor_v (signs ,mone ),q8_4 ); 1784 1785const __m256i dot1 = lasx_maddubs_h (q2_1 ,q8s_1 ); 1786const __m256i dot2 = lasx_maddubs_h (q2_2 ,q8s_2 ); 1787const __m256i dot3 = lasx_maddubs_h (q2_3 ,q8s_3 ); 1788const __m256i dot4 = lasx_maddubs_h (q2_4 ,q8s_4 ); 1789 1790const __m256i sc1 = lasx_ext8_16 (lsx_shuffle_b (scales ,get_scale_shuffle (ib32 + 0 ))); 1791const __m256i sc2 = lasx_ext8_16 (lsx_shuffle_b (scales ,get_scale_shuffle (ib32 + 1 ))); 1792const __m256i sc3 = lasx_ext8_16 (lsx_shuffle_b (scales ,get_scale_shuffle (ib32 + 2 ))); 1793const __m256i sc4 = lasx_ext8_16 (lsx_shuffle_b (scales ,get_scale_shuffle (ib32 + 3 ))); 1794 1795sumi1 = __lasx_xvadd_w (sumi1 ,lasx_madd_h (dot1 ,sc1 )); 1796sumi2 = __lasx_xvadd_w (sumi2 ,lasx_madd_h (dot2 ,sc2 )); 1797sumi1 = __lasx_xvadd_w (sumi1 ,lasx_madd_h (dot3 ,sc3 )); 1798sumi2 = __lasx_xvadd_w (sumi2 ,lasx_madd_h (dot4 ,sc4 )); 1799 } 1800 1801accumf = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accumf ); 1802 1803 } 1804 1805* s = 0.125f * hsum_float_8 (accumf ); 1806 1807#else 1808UNUSED (x ); 1809UNUSED (y ); 1810UNUSED (nb ); 1811ggml_vec_dot_iq2_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1812#endif 1813} 1814 1815void ggml_vec_dot_iq2_s_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1816assert (n %QK_K == 0 ); 1817assert (nrc == 1 ); 1818UNUSED (nrc ); 1819UNUSED (bx ); 1820UNUSED (by ); 1821UNUSED (bs ); 1822 1823const block_iq2_s * GGML_RESTRICT x = vx ; 1824const block_q8_K * GGML_RESTRICT y = vy ; 1825 1826const int nb = n /QK_K ; 1827 1828#if defined(__loongarch_asx ) 1829 1830static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 18310x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 1832 }; 1833 1834static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 18350x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 1836 }; 1837 1838 1839const __m128i m4 = __lsx_vreplgr2vr_b (0xf ); 1840const __m128i m1 = __lsx_vreplgr2vr_b (1 ); 1841 1842const __m256i mask1 = __lasx_xvld ((const __m256i * )k_mask1 ,0 ); 1843const __m256i mask2 = __lasx_xvld ((const __m256i * )k_mask2 ,0 ); 1844uint64_t aux64 ; 1845 1846__m256 accumf = (__m256 )__lasx_xvldi (0 ); 1847for (int i = 0 ;i < nb ;++ i ) { 1848const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1849const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 1850const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 1851const uint16_t * GGML_RESTRICT signs = (const uint16_t * )(x [i ].qs + QK_K /8 ); 1852const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1853 1854__m128i tmp1 ; 1855memcpy (& aux64 ,x [i ].scales ,8 ); 1856tmp1 = __lsx_vinsgr2vr_d (tmp1 ,aux64 ,0 ); 1857tmp1 = __lsx_vinsgr2vr_d (tmp1 ,aux64 >>4 ,1 ); 1858const __m128i scales8 = __lsx_vadd_b (__lsx_vslli_h (__lsx_vand_v (tmp1 ,m4 ),1 ),m1 ); 1859const __m256i scales16 = lasx_ext8_16 (scales8 );// 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 1860 1861__m256i sumi1 = __lasx_xvldi (0 ); 1862__m256i sumi2 = __lasx_xvldi (0 ); 1863for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 1864const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1865const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1866const __m256i q2_1 = lasx_set_d (iq2s_grid [qs [3 ] | ((qh [ib32 + 0 ] <<2 )& 0x300 )], 1867iq2s_grid [qs [2 ] | ((qh [ib32 + 0 ] <<4 )& 0x300 )], 1868iq2s_grid [qs [1 ] | ((qh [ib32 + 0 ] <<6 )& 0x300 )], 1869iq2s_grid [qs [0 ] | ((qh [ib32 + 0 ] <<8 )& 0x300 )]); 1870const __m256i q2_2 = lasx_set_d (iq2s_grid [qs [7 ] | ((qh [ib32 + 1 ] <<2 )& 0x300 )], 1871iq2s_grid [qs [6 ] | ((qh [ib32 + 1 ] <<4 )& 0x300 )], 1872iq2s_grid [qs [5 ] | ((qh [ib32 + 1 ] <<6 )& 0x300 )], 1873iq2s_grid [qs [4 ] | ((qh [ib32 + 1 ] <<8 )& 0x300 )]); 1874qs += 8 ; 1875 1876__m256i aux256 = __lasx_xvreplgr2vr_w (signs [0 ] | ((uint32_t )signs [1 ] <<16 )); 1877aux256 = __lasx_xvand_v (lasx_shuffle_b (aux256 ,mask1 ),mask2 ); 1878const __m256i s2_1 = __lasx_xvseq_b (aux256 ,mask2 ); 1879const __m256i q8s_1 = __lasx_xvsub_b (__lasx_xvxor_v (s2_1 ,q8_1 ),s2_1 ); 1880 1881aux256 = __lasx_xvreplgr2vr_w (signs [2 ] | ((uint32_t )signs [3 ] <<16 )); 1882aux256 = __lasx_xvand_v (lasx_shuffle_b (aux256 ,mask1 ),mask2 ); 1883const __m256i s2_2 = __lasx_xvseq_b (aux256 ,mask2 ); 1884const __m256i q8s_2 = __lasx_xvsub_b (__lasx_xvxor_v (s2_2 ,q8_2 ),s2_2 ); 1885 1886signs += 4 ; 1887 1888const __m256i dot1 = lasx_maddubs_h (q2_1 ,q8s_1 );// blocks 2*ib32+0, 2*ib32+1 1889const __m256i dot2 = lasx_maddubs_h (q2_2 ,q8s_2 );// blocks 2*ib32+2, 2*ib32+3 1890 1891const __m256i p1 = lasx_madd_h (dot1 ,lasx_shuffle_b (scales16 ,get_scale_shuffle_k4 (ib32 + 0 ))); 1892const __m256i p2 = lasx_madd_h (dot2 ,lasx_shuffle_b (scales16 ,get_scale_shuffle_k4 (ib32 + 1 ))); 1893sumi1 = __lasx_xvadd_w (sumi1 ,p1 ); 1894sumi2 = __lasx_xvadd_w (sumi2 ,p2 ); 1895 } 1896 1897accumf = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accumf ); 1898 } 1899 1900* s = 0.125f * hsum_float_8 (accumf ); 1901 1902#else 1903UNUSED (x ); 1904UNUSED (y ); 1905UNUSED (nb ); 1906ggml_vec_dot_iq2_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1907#endif 1908} 1909 1910void ggml_vec_dot_iq3_xxs_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1911assert (n %QK_K == 0 ); 1912assert (nrc == 1 ); 1913UNUSED (nrc ); 1914UNUSED (bx ); 1915UNUSED (by ); 1916UNUSED (bs ); 1917 1918const block_iq3_xxs * GGML_RESTRICT x = vx ; 1919const block_q8_K * GGML_RESTRICT y = vy ; 1920 1921const int nb = n /QK_K ; 1922 1923#if defined(__loongarch_asx ) 1924 1925const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 1926 1927uint32_t aux32 [2 ]; 1928 1929__m256 accumf = (__m256 )__lasx_xvldi (0 ); 1930for (int i = 0 ;i < nb ;++ i ) { 1931const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1932const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1933const uint8_t * GGML_RESTRICT gas = x [i ].qs + QK_K /4 ; 1934const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1935__m256i sumi1 = __lasx_xvldi (0 ); 1936__m256i sumi2 = __lasx_xvldi (0 ); 1937for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 1938const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1939const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 1940const __m256i q2_1 = lasx_set_w (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]], 1941iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 1942q3 += 8 ; 1943const __m256i q2_2 = lasx_set_w (iq3xxs_grid [q3 [7 ]],iq3xxs_grid [q3 [6 ]],iq3xxs_grid [q3 [5 ]],iq3xxs_grid [q3 [4 ]], 1944iq3xxs_grid [q3 [3 ]],iq3xxs_grid [q3 [2 ]],iq3xxs_grid [q3 [1 ]],iq3xxs_grid [q3 [0 ]]); 1945q3 += 8 ; 1946memcpy (aux32 ,gas ,8 );gas += 8 ; 1947 1948const __m256i s2_1 = lasx_set_d (signs64 [(aux32 [0 ] >>21 )& 127 ],signs64 [(aux32 [0 ] >>14 )& 127 ], 1949signs64 [(aux32 [0 ] >>7 )& 127 ],signs64 [(aux32 [0 ] >>0 )& 127 ]); 1950const __m256i s2_2 = lasx_set_d (signs64 [(aux32 [1 ] >>21 )& 127 ],signs64 [(aux32 [1 ] >>14 )& 127 ], 1951signs64 [(aux32 [1 ] >>7 )& 127 ],signs64 [(aux32 [1 ] >>0 )& 127 ]); 1952const __m256i q8s_1 = __lasx_xvsigncov_b (s2_1 ,q8_1 ); 1953const __m256i q8s_2 = __lasx_xvsigncov_b (s2_2 ,q8_2 ); 1954const __m256i dot1 = lasx_maddubs_h (q2_1 ,q8s_1 ); 1955const __m256i dot2 = lasx_maddubs_h (q2_2 ,q8s_2 ); 1956const uint16_t ls1 = aux32 [0 ] >>28 ; 1957const uint16_t ls2 = aux32 [1 ] >>28 ; 1958 1959const __m256i p1 = lasx_madd_h (dot1 ,__lasx_xvreplgr2vr_h (2 * ls1 + 1 )); 1960const __m256i p2 = lasx_madd_h (dot2 ,__lasx_xvreplgr2vr_h (2 * ls2 + 1 )); 1961sumi1 = __lasx_xvadd_w (sumi1 ,p1 ); 1962sumi2 = __lasx_xvadd_w (sumi2 ,p2 ); 1963 } 1964 1965accumf = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accumf ); 1966 } 1967 1968* s = 0.25f * hsum_float_8 (accumf ); 1969 1970#else 1971UNUSED (x ); 1972UNUSED (y ); 1973UNUSED (nb ); 1974ggml_vec_dot_iq3_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1975#endif 1976} 1977 1978void ggml_vec_dot_iq3_s_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 1979assert (n %QK_K == 0 ); 1980assert (nrc == 1 ); 1981UNUSED (nrc ); 1982UNUSED (bx ); 1983UNUSED (by ); 1984UNUSED (bs ); 1985 1986const block_iq3_s * GGML_RESTRICT x = vx ; 1987const block_q8_K * GGML_RESTRICT y = vy ; 1988 1989const int nb = n /QK_K ; 1990 1991#if defined(__loongarch_asx ) 1992 1993static const uint8_t k_mask1 [32 ]= {0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 ,0x01 , 19940x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x02 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 ,0x03 1995 }; 1996 1997static const uint8_t k_mask2 [32 ]= {0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 19980x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 ,0x01 ,0x02 ,0x04 ,0x08 ,0x10 ,0x20 ,0x40 ,0x80 , 1999 }; 2000 2001const __m256i mask1 = __lasx_xvld ((const __m256i * )k_mask1 ,0 ); 2002const __m256i mask2 = __lasx_xvld ((const __m256i * )k_mask2 ,0 ); 2003 2004__m256i idx_shift = lasx_set_w (1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ); 2005const __m256i idx_mask = __lasx_xvreplgr2vr_w (256 ); 2006 2007typedef union { 2008__m256i vec [2 ]; 2009uint32_t index [16 ]; 2010 }index_t ; 2011 2012index_t idx ; 2013 2014__m256 accumf = (__m256 )__lasx_xvldi (0 ); 2015for (int i = 0 ;i < nb ;++ i ) { 2016const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2017const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 2018const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2019const uint16_t * GGML_RESTRICT signs = (const uint16_t * )x [i ].signs ; 2020const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2021__m256i sumi1 = __lasx_xvldi (0 ); 2022__m256i sumi2 = __lasx_xvldi (0 ); 2023for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 2024const __m256i q8_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2025const __m256i q8_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2026const __m256i idx_l = lasx_extu8_16 (__lsx_vld (qs ,0 ));qs += 16 ; 2027idx .vec [0 ]= __lasx_xvreplgr2vr_w (qh [ib32 + 0 ]); 2028idx .vec [1 ]= __lasx_xvreplgr2vr_w (qh [ib32 + 1 ]); 2029idx .vec [0 ]= __lasx_xvand_v (__lasx_xvsll_w (idx .vec [0 ],idx_shift ),idx_mask ); 2030idx .vec [1 ]= __lasx_xvand_v (__lasx_xvsll_w (idx .vec [1 ],idx_shift ),idx_mask ); 2031idx .vec [0 ]= __lasx_xvor_v (idx .vec [0 ],lasx_ext16_32 (lasx_extracti128 (idx_l ,0 ))); 2032idx .vec [1 ]= __lasx_xvor_v (idx .vec [1 ],lasx_ext16_32 (lasx_extracti128 (idx_l ,1 ))); 2033 2034// At leat on my CPU (Ryzen 7950X), using _mm256_i32gather_epi32 is slower than _mm256_set_epi32. Strange. 2035//const __m256i q2_1 = _mm256_i32gather_epi32((const int *)iq3s_grid, idx.vec[0], 4); 2036//const __m256i q2_2 = _mm256_i32gather_epi32((const int *)iq3s_grid, idx.vec[1], 4); 2037const __m256i q2_1 = lasx_set_w ( 2038iq3s_grid [idx .index [7 ]],iq3s_grid [idx .index [6 ]],iq3s_grid [idx .index [5 ]],iq3s_grid [idx .index [4 ]], 2039iq3s_grid [idx .index [3 ]],iq3s_grid [idx .index [2 ]],iq3s_grid [idx .index [1 ]],iq3s_grid [idx .index [0 ]] 2040 ); 2041const __m256i q2_2 = lasx_set_w ( 2042iq3s_grid [idx .index [15 ]],iq3s_grid [idx .index [14 ]],iq3s_grid [idx .index [13 ]],iq3s_grid [idx .index [12 ]], 2043iq3s_grid [idx .index [11 ]],iq3s_grid [idx .index [10 ]],iq3s_grid [idx .index [9 ]],iq3s_grid [idx .index [8 ]] 2044 ); 2045 2046__m256i aux256 = __lasx_xvreplgr2vr_w (signs [0 ] | (signs [1 ] <<16 )); 2047aux256 = __lasx_xvand_v (lasx_shuffle_b (aux256 ,mask1 ),mask2 ); 2048const __m256i s2_1 = __lasx_xvseq_b (aux256 ,mask2 ); 2049const __m256i q8s_1 = __lasx_xvsub_b (__lasx_xvxor_v (s2_1 ,q8_1 ),s2_1 ); 2050 2051aux256 = __lasx_xvreplgr2vr_w (signs [2 ] | (signs [3 ] <<16 )); 2052aux256 = __lasx_xvand_v (lasx_shuffle_b (aux256 ,mask1 ),mask2 ); 2053const __m256i s2_2 = __lasx_xvseq_b (aux256 ,mask2 ); 2054const __m256i q8s_2 = __lasx_xvsub_b (__lasx_xvxor_v (s2_2 ,q8_2 ),s2_2 ); 2055 2056signs += 4 ; 2057 2058const __m256i dot1 = lasx_maddubs_h (q2_1 ,q8s_1 ); 2059const __m256i dot2 = lasx_maddubs_h (q2_2 ,q8s_2 ); 2060const uint16_t ls1 = x [i ].scales [ib32 /2 ]& 0xf ; 2061const uint16_t ls2 = x [i ].scales [ib32 /2 ] >>4 ; 2062const __m256i p1 = lasx_madd_h (dot1 ,__lasx_xvreplgr2vr_h (2 * ls1 + 1 )); 2063const __m256i p2 = lasx_madd_h (dot2 ,__lasx_xvreplgr2vr_h (2 * ls2 + 1 )); 2064sumi1 = __lasx_xvadd_w (sumi1 ,p1 ); 2065sumi2 = __lasx_xvadd_w (sumi2 ,p2 ); 2066 } 2067 2068accumf = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accumf ); 2069 } 2070 2071* s = hsum_float_8 (accumf ); 2072 2073#else 2074UNUSED (x ); 2075UNUSED (y ); 2076UNUSED (nb ); 2077ggml_vec_dot_iq3_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2078#endif 2079} 2080 2081#if defined(__loongarch_asx ) 2082static inline __m256i mul_add_epi8 (const __m256i x ,const __m256i y ) { 2083const __m256i a = __lasx_xvmulwev_h_b (x ,y ); 2084const __m256i b = __lasx_xvmulwod_h_b (x ,y ); 2085return __lasx_xvadd_h (a ,b ); 2086} 2087#endif 2088 2089void ggml_vec_dot_iq1_s_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 2090assert (n %QK_K == 0 ); 2091assert (nrc == 1 ); 2092UNUSED (nrc ); 2093UNUSED (bx ); 2094UNUSED (by ); 2095UNUSED (bs ); 2096 2097const block_iq1_s * GGML_RESTRICT x = vx ; 2098const block_q8_K * GGML_RESTRICT y = vy ; 2099 2100const int nb = n /QK_K ; 2101 2102#if defined(__loongarch_asx ) 2103 2104__m256 accum = (__m256 )__lasx_xvldi (0 ); 2105float accum1 = 0 ; 2106for (int i = 0 ;i < nb ;++ i ) { 2107 2108const int8_t * q8 = y [i ].qs ; 2109const uint8_t * qs = x [i ].qs ; 2110const uint16_t * qh = x [i ].qh ; 2111 2112__m256i sumi = __lasx_xvldi (0 ); 2113int sumi1 = 0 ; 2114for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 2115__m256i q1b_1 = __lasx_xvinsgr2vr_d (q1b_1 ,iq1s_grid [qs [0 ] | ((qh [ib + 0 ] <<8 )& 0x700 )],0 ); 2116q1b_1 = __lasx_xvinsgr2vr_d (q1b_1 ,iq1s_grid [qs [1 ] | ((qh [ib + 0 ] <<5 )& 0x700 )],1 ); 2117q1b_1 = __lasx_xvinsgr2vr_d (q1b_1 ,iq1s_grid [qs [2 ] | ((qh [ib + 0 ] <<2 )& 0x700 )],2 ); 2118q1b_1 = __lasx_xvinsgr2vr_d (q1b_1 ,iq1s_grid [qs [3 ] | ((qh [ib + 0 ] >>1 )& 0x700 )],3 ); 2119 2120__m256i q1b_2 = __lasx_xvinsgr2vr_d (q1b_2 ,iq1s_grid [qs [4 ] | ((qh [ib + 1 ] <<8 )& 0x700 )],0 ); 2121q1b_2 = __lasx_xvinsgr2vr_d (q1b_2 ,iq1s_grid [qs [5 ] | ((qh [ib + 1 ] <<5 )& 0x700 )],1 ); 2122q1b_2 = __lasx_xvinsgr2vr_d (q1b_2 ,iq1s_grid [qs [6 ] | ((qh [ib + 1 ] <<2 )& 0x700 )],2 ); 2123q1b_2 = __lasx_xvinsgr2vr_d (q1b_2 ,iq1s_grid [qs [7 ] | ((qh [ib + 1 ] >>1 )& 0x700 )],3 ); 2124 2125qs += 8 ; 2126const __m256i q8b_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2127const __m256i q8b_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2128 2129const __m256i dot1 = mul_add_epi8 (q1b_1 ,q8b_1 ); 2130const __m256i dot2 = mul_add_epi8 (q1b_2 ,q8b_2 ); 2131const int16_t ls1 = 2 * ((qh [ib + 0 ] >>12 )& 7 )+ 1 ; 2132const int16_t ls2 = 2 * ((qh [ib + 1 ] >>12 )& 7 )+ 1 ; 2133 2134__m256i tmp1 ,tmp5 ,tmp6 ; 2135tmp1 = __lasx_xvreplgr2vr_h (ls1 ); 2136tmp5 = __lasx_xvmulwev_w_h (dot1 ,tmp1 ); 2137tmp6 = __lasx_xvmulwod_w_h (dot1 ,tmp1 ); 2138const __m256i p1 = __lasx_xvadd_w (tmp5 ,tmp6 ); 2139 2140tmp1 = __lasx_xvreplgr2vr_h (ls2 ); 2141tmp5 = __lasx_xvmulwev_w_h (dot2 ,tmp1 ); 2142tmp6 = __lasx_xvmulwod_w_h (dot2 ,tmp1 ); 2143const __m256i p2 = __lasx_xvadd_w (tmp5 ,tmp6 ); 2144 2145sumi = __lasx_xvadd_w (sumi ,__lasx_xvadd_w (p1 ,p2 )); 2146sumi1 += (y [i ].bsums [2 * ib + 0 ]+ y [i ].bsums [2 * ib + 1 ])* (qh [ib + 0 ]& 0x8000 ?-1 :1 )* ls1 2147+ (y [i ].bsums [2 * ib + 2 ]+ y [i ].bsums [2 * ib + 3 ])* (qh [ib + 1 ]& 0x8000 ?-1 :1 )* ls2 ; 2148 } 2149 2150const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2151accum = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (d ),__lasx_xvffint_s_w (sumi ),accum ); 2152accum1 += d * sumi1 ; 2153 } 2154 2155* s = hsum_float_8 (accum )+ IQ1S_DELTA * accum1 ; 2156 2157#else 2158UNUSED (x ); 2159UNUSED (y ); 2160UNUSED (nb ); 2161ggml_vec_dot_iq1_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2162#endif 2163} 2164 2165void ggml_vec_dot_iq4_nl_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 2166assert (nrc == 1 ); 2167UNUSED (nrc ); 2168UNUSED (bx ); 2169UNUSED (by ); 2170UNUSED (bs ); 2171assert (n %QK4_NL == 0 ); 2172static_assert (QK4_NL == QK8_0 ,"QK4_NL and QK8_0 must be the same" ); 2173 2174const block_iq4_nl * GGML_RESTRICT x = vx ; 2175const block_q8_0 * GGML_RESTRICT y = vy ; 2176 2177const int nb = n /QK4_NL ; 2178 2179int ib = 0 ; 2180float sumf = 0 ; 2181 2182#if defined (__loongarch_asx ) 2183 2184const __m128i values128 = __lsx_vld ((const __m128i * )kvalues_iq4nl ,0 ); 2185const __m128i m4b = __lsx_vreplgr2vr_b (0x0f ); 2186const __m256i mone = __lasx_xvreplgr2vr_h (1 ); 2187 2188__m256 accum1 = (__m256 )__lasx_xvldi (0 ); 2189__m256 accum2 = (__m256 )__lasx_xvldi (0 ); 2190for (;ib + 1 < nb ;ib += 2 ) { 2191const __m128i q4bits_1 = __lsx_vld ((const __m128i * )x [ib + 0 ].qs ,0 ); 2192const __m128i q4bits_2 = __lsx_vld ((const __m128i * )x [ib + 1 ].qs ,0 ); 2193const __m256i q8b_1 = __lasx_xvld ((const __m256i * )y [ib + 0 ].qs ,0 ); 2194const __m256i q8b_2 = __lasx_xvld ((const __m256i * )y [ib + 1 ].qs ,0 ); 2195const __m256i q4b_1 = lasx_insertf128 (lsx_shuffle_b (values128 ,__lsx_vand_v (__lsx_vsrli_h (q4bits_1 ,4 ),m4b )), 2196lsx_shuffle_b (values128 ,__lsx_vand_v (q4bits_1 ,m4b ))); 2197const __m256i q4b_2 = lasx_insertf128 (lsx_shuffle_b (values128 ,__lsx_vand_v (__lsx_vsrli_h (q4bits_2 ,4 ),m4b )), 2198lsx_shuffle_b (values128 ,__lsx_vand_v (q4bits_2 ,m4b ))); 2199const __m256i p16_1 = mul_add_epi8 (q4b_1 ,q8b_1 ); 2200const __m256i p16_2 = mul_add_epi8 (q4b_2 ,q8b_2 ); 2201const __m256i p_1 = lasx_madd_h (p16_1 ,mone ); 2202const __m256i p_2 = lasx_madd_h (p16_2 ,mone ); 2203accum1 = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* GGML_CPU_FP16_TO_FP32 (x [ib + 0 ].d )), 2204__lasx_xvffint_s_w (p_1 ),accum1 ); 2205accum2 = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* GGML_CPU_FP16_TO_FP32 (x [ib + 1 ].d )), 2206__lasx_xvffint_s_w (p_2 ),accum2 ); 2207 } 2208 2209sumf = hsum_float_8 (__lasx_xvfadd_s (accum1 ,accum2 )); 2210 2211#endif 2212for (;ib < nb ;++ ib ) { 2213const float d = GGML_CPU_FP16_TO_FP32 (y [ib ].d )* GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 2214int sumi1 = 0 ,sumi2 = 0 ; 2215for (int j = 0 ;j < QK4_NL /2 ;++ j ) { 2216sumi1 += y [ib ].qs [j + 0 ]* kvalues_iq4nl [x [ib ].qs [j ]& 0xf ]; 2217sumi2 += y [ib ].qs [j + QK4_NL /2 ]* kvalues_iq4nl [x [ib ].qs [j ] >>4 ]; 2218 } 2219sumf += d * (sumi1 + sumi2 ); 2220 } 2221* s = sumf ; 2222} 2223 2224void ggml_vec_dot_iq4_xs_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,size_t bx ,const void * GGML_RESTRICT vy ,size_t by ,int nrc ) { 2225assert (nrc == 1 ); 2226UNUSED (nrc ); 2227UNUSED (bx ); 2228UNUSED (by ); 2229UNUSED (bs ); 2230assert (n %QK_K == 0 ); 2231 2232const block_iq4_xs * GGML_RESTRICT x = vx ; 2233const block_q8_K * GGML_RESTRICT y = vy ; 2234 2235const int nb = n /QK_K ; 2236 2237#if defined(__loongarch_asx ) 2238 2239const __m128i values128 = __lsx_vld ((const __m128i * )kvalues_iq4nl ,0 ); 2240 2241__m256 accum = (__m256 )__lasx_xvldi (0 ); 2242 2243for (int ibl = 0 ;ibl < nb ;++ ibl ) { 2244const uint8_t * qs = x [ibl ].qs ; 2245const int8_t * q8 = y [ibl ].qs ; 2246uint16_t sh = x [ibl ].scales_h ; 2247__m256i sumi1 = __lasx_xvldi (0 ); 2248__m256i sumi2 = __lasx_xvldi (0 ); 2249for (int ib = 0 ;ib < QK_K /32 ;ib += 2 ) { 2250const __m128i q4bits_1 = __lsx_vld ((const __m128i * )qs ,0 );qs += 16 ; 2251const __m128i q4bits_2 = __lsx_vld ((const __m128i * )qs ,0 );qs += 16 ; 2252const __m256i q8b_1 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2253const __m256i q8b_2 = __lasx_xvld ((const __m256i * )q8 ,0 );q8 += 32 ; 2254const __m256i q4b_1 = lasx_insertf128 (__lsx_vshuf_b (values128 ,values128 ,__lsx_vsrli_b (q4bits_1 ,4 )), 2255__lsx_vshuf_b (values128 ,values128 ,__lsx_vandi_b (q4bits_1 ,0xf ))); 2256const __m256i q4b_2 = lasx_insertf128 (__lsx_vshuf_b (values128 ,values128 ,__lsx_vsrli_b (q4bits_2 ,4 )), 2257__lsx_vshuf_b (values128 ,values128 ,__lsx_vandi_b (q4bits_2 ,0xf ))); 2258const __m256i p16_1 = mul_add_epi8 (q4b_1 ,q8b_1 ); 2259const __m256i p16_2 = mul_add_epi8 (q4b_2 ,q8b_2 ); 2260const int16_t ls1 = ((x [ibl ].scales_l [ib /2 ]& 0xf ) | ((sh <<4 )& 0x30 ))- 32 ; 2261const int16_t ls2 = ((x [ibl ].scales_l [ib /2 ] >>4 ) | ((sh <<2 )& 0x30 ))- 32 ; 2262sh >>=4 ; 2263const __m256i p_1 = lasx_madd_h (p16_1 ,__lasx_xvreplgr2vr_h (ls1 )); 2264const __m256i p_2 = lasx_madd_h (p16_2 ,__lasx_xvreplgr2vr_h (ls2 )); 2265sumi1 = __lasx_xvadd_w (p_1 ,sumi1 ); 2266sumi2 = __lasx_xvadd_w (p_2 ,sumi2 ); 2267 } 2268accum = __lasx_xvfmadd_s (__lasx_xvreplfr2vr_s (GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d ), 2269__lasx_xvffint_s_w (__lasx_xvadd_w (sumi1 ,sumi2 )),accum ); 2270 } 2271 2272* s = hsum_float_8 (accum ); 2273 2274#elif defined(__loongarch_sx ) 2275 2276const __m128i values128 = __lsx_vld ((const __m128i * )kvalues_iq4nl ,0 ); 2277 2278__m128 accum = (__m128 )__lsx_vldi (0 ); 2279for (int ibl = 0 ;ibl < nb ;++ ibl ) { 2280const uint8_t * qs = x [ibl ].qs ; 2281const int8_t * q8 = y [ibl ].qs ; 2282uint16_t sh = x [ibl ].scales_h ; 2283__m128i sumi = __lsx_vldi (0 ); 2284for (int ib = 0 ;ib < QK_K /32 ;++ ib ) { 2285const __m128i q4bits = __lsx_vld ((const __m128i * )qs ,0 );qs += 16 ; 2286const __m128i q8b_0 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 2287const __m128i q8b_1 = __lsx_vld ((const __m128i * )q8 ,0 );q8 += 16 ; 2288const __m128i q4b_0 = __lsx_vshuf_b (values128 ,values128 ,__lsx_vandi_b (q4bits ,0xf )); 2289const __m128i q4b_1 = __lsx_vshuf_b (values128 ,values128 ,__lsx_vsrli_b (q4bits ,4 )); 2290const __m128i p16_0 = lsx_maddubs_h (q4b_0 ,q8b_0 ); 2291const __m128i p16_1 = lsx_maddubs_h (q4b_1 ,q8b_1 ); 2292const int16_t ls = (((x [ibl ].scales_l [ib /2 ] >> ((ib & 1 )* 4 ))& 0xf ) | ((sh & 0x3 ) <<4 ))- 32 ; 2293sh >>=2 ; 2294sumi = __lsx_vadd_w (lsx_madd_h (p16_0 ,__lsx_vreplgr2vr_h (ls )),sumi ); 2295sumi = __lsx_vadd_w (lsx_madd_h (p16_1 ,__lsx_vreplgr2vr_h (ls )),sumi ); 2296 } 2297const float ds = GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d ; 2298accum = __lsx_vfadd_s (__lsx_vfmul_s (__lsx_vreplfr2vr_s (ds ),__lsx_vffint_s_w (sumi )),accum ); 2299 } 2300 2301* s = ((v4f32 )lsx_hadd_s (lsx_hadd_s (accum ,accum ),lsx_hadd_s (accum ,accum )))[0 ]; 2302 2303#else 2304UNUSED (x ); 2305UNUSED (y ); 2306UNUSED (nb ); 2307ggml_vec_dot_iq4_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2308#endif 2309}