char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
3c7450cee
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#ifdef _MSC_VER 19#define NOINLINE __declspec(noinline) 20#else 21#define NOINLINE __attribute__((__noinline__)) 22#endif 23 24#define GROUP_MAX_EPS 1e-15f 25#define GROUP_MAX_EPS_IQ3_XXS 1e-8f 26#define GROUP_MAX_EPS_IQ2_S 1e-8f 27#define GROUP_MAX_EPS_IQ1_M 1e-7f 28#define GROUP_MAX_EPS_IQ1_S 1e-12f 29 30#define UNUSED GGML_UNUSED 31 32void quantize_row_q8_0 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 33assert (QK8_0 == 32 ); 34assert (k %QK8_0 == 0 ); 35const int nb = k /QK8_0 ; 36 37block_q8_0 * GGML_RESTRICT y = vy ; 38 39#if defined(__riscv_v ) 40 41size_t vl = QK8_0 ; 42 43for (int i = 0 ;i < nb ;i ++ ) { 44// load elements 45vfloat32m8_t v_x = __riscv_vle32_v_f32m8 (x + i * QK8_0 ,vl ); 46 47vfloat32m8_t vfabs = __riscv_vfabs_v_f32m8 (v_x ,vl ); 48vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 49vfloat32m1_t vmax = __riscv_vfredmax_vs_f32m8_f32m1 (vfabs ,tmp ,vl ); 50float amax = __riscv_vfmv_f_s_f32m1_f32 (vmax ); 51 52const float d = amax / ((1 <<7 )- 1 ); 53const float id = d ?1.0f /d :0.0f ; 54 55y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 56 57vfloat32m8_t x0 = __riscv_vfmul_vf_f32m8 (v_x ,id ,vl ); 58 59// convert to integer 60vint16m4_t vi = __riscv_vfncvt_x_f_w_i16m4 (x0 ,vl ); 61vint8m2_t vs = __riscv_vncvt_x_x_w_i8m2 (vi ,vl ); 62 63// store result 64__riscv_vse8_v_i8m2 (y [i ].qs ,vs ,vl ); 65 } 66#else 67GGML_UNUSED (nb ); 68// scalar 69quantize_row_q8_0_ref (x ,y ,k ); 70#endif 71} 72 73void quantize_row_q8_1 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 74assert (k %QK8_1 == 0 ); 75const int nb = k /QK8_1 ; 76 77block_q8_1 * GGML_RESTRICT y = vy ; 78 79#if defined(__riscv_v ) 80 81size_t vl = QK8_1 ; 82 83for (int i = 0 ;i < nb ;i ++ ) { 84// load elements 85vfloat32m8_t v_x = __riscv_vle32_v_f32m8 (x + i * QK8_1 ,vl ); 86 87vfloat32m8_t vfabs = __riscv_vfabs_v_f32m8 (v_x ,vl ); 88vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0 ,vl ); 89vfloat32m1_t vmax = __riscv_vfredmax_vs_f32m8_f32m1 (vfabs ,tmp ,vl ); 90float amax = __riscv_vfmv_f_s_f32m1_f32 (vmax ); 91 92const float d = amax / ((1 <<7 )- 1 ); 93const float id = d ?1.0f /d :0.0f ; 94 95y [i ].d = GGML_CPU_FP32_TO_FP16 (d ); 96 97vfloat32m8_t x0 = __riscv_vfmul_vf_f32m8 (v_x ,id ,vl ); 98 99// convert to integer 100vint16m4_t vi = __riscv_vfncvt_x_f_w_i16m4 (x0 ,vl ); 101vint8m2_t vs = __riscv_vncvt_x_x_w_i8m2 (vi ,vl ); 102 103// store result 104__riscv_vse8_v_i8m2 (y [i ].qs ,vs ,vl ); 105 106// compute sum for y[i].s 107vint16m1_t tmp2 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 108vint16m1_t vwrs = __riscv_vwredsum_vs_i8m2_i16m1 (vs ,tmp2 ,vl ); 109 110// set y[i].s 111int sum = __riscv_vmv_x_s_i16m1_i16 (vwrs ); 112y [i ].s = GGML_CPU_FP32_TO_FP16 (sum * d ); 113 } 114 115#else 116GGML_UNUSED (nb ); 117// scalar 118quantize_row_q8_1_ref (x ,y ,k ); 119#endif 120} 121 122void quantize_row_q8_K (const float * GGML_RESTRICT x ,void * GGML_RESTRICT y ,int64_t k ) { 123assert (k %QK_K == 0 ); 124size_t nb = k /QK_K ; 125 126#if defined__riscv_v 127block_q8_K * y_blocks = (block_q8_K * )y ; 128const size_t vlmax_f32m8 = __riscv_vsetvlmax_e32m8 (); 129 130for (size_t i = 0 ;i < nb ;i ++ ) { 131const float * x_block = x + i * QK_K ; 132block_q8_K * y_block = & y_blocks [i ]; 133 134// 1. Calculate Min/Max 135vfloat32m8_t max_v = __riscv_vfmv_v_f_f32m8 (- __builtin_inff (),vlmax_f32m8 ); 136vfloat32m8_t min_v = __riscv_vfmv_v_f_f32m8 (__builtin_inff (),vlmax_f32m8 ); 137 138size_t rem = QK_K ; 139size_t offset = 0 ; 140while (rem > 0 ) { 141size_t vl = __riscv_vsetvl_e32m8 (rem ); 142vfloat32m8_t v_curr = __riscv_vle32_v_f32m8 (x_block + offset ,vl ); 143max_v = __riscv_vfmax_vv_f32m8 (max_v ,v_curr ,vl ); 144min_v = __riscv_vfmin_vv_f32m8 (min_v ,v_curr ,vl ); 145rem -= vl ; 146offset += vl ; 147 } 148 149vfloat32m1_t v_init_max = __riscv_vfmv_s_f_f32m1 (- __builtin_inff (),1 ); 150vfloat32m1_t v_init_min = __riscv_vfmv_s_f_f32m1 (__builtin_inff (),1 ); 151 152vfloat32m1_t v_scalar_max = __riscv_vfredmax_vs_f32m8_f32m1 (max_v ,v_init_max ,vlmax_f32m8 ); 153vfloat32m1_t v_scalar_min = __riscv_vfredmin_vs_f32m8_f32m1 (min_v ,v_init_min ,vlmax_f32m8 ); 154 155float max_val = __riscv_vfmv_f_s_f32m1_f32 (v_scalar_max ); 156float min_val = __riscv_vfmv_f_s_f32m1_f32 (v_scalar_min ); 157 158float amax = fabsf (max_val )> fabsf (min_val ) ?fabsf (max_val ) :fabsf (min_val ); 159 160if (amax == 0.0f ) { 161y_block -> d = 0.0f ; 162memset (y_block -> qs ,0 ,QK_K ); 163memset (y_block -> bsums ,0 ,sizeof (y_block -> bsums )); 164continue ; 165 } 166 167const float iscale = -127.f / (fabsf (max_val )> fabsf (min_val ) ?max_val :min_val ); 168y_block -> d = 1.0f /iscale ; 169 170// 2. Quantize and Calculate Sums 171offset = 0 ; 172rem = QK_K ; 173vint16m1_t v_zero_sum = __riscv_vmv_v_x_i16m1 (0 ,1 ); 174 175while (rem > 0 ) { 176size_t vl = __riscv_vsetvl_e32m8 (rem ); 177vfloat32m8_t v_f = __riscv_vle32_v_f32m8 (x_block + offset ,vl ); 178 179v_f = __riscv_vfmul_vf_f32m8 (v_f ,iscale ,vl ); 180 181vint32m8_t v_i32 = __riscv_vfcvt_x_f_v_i32m8_rm (v_f ,__RISCV_FRM_RNE ,vl ); 182vint16m4_t v_i16 = __riscv_vnclip_wx_i16m4 (v_i32 ,0 ,__RISCV_VXRM_RNE ,vl ); 183vint8m2_t v_q = __riscv_vnclip_wx_i8m2 (v_i16 ,0 ,__RISCV_VXRM_RNE ,vl ); 184 185__riscv_vse8_v_i8m2 (y_block -> qs + offset ,v_q ,vl ); 186 187// first iteration clear 188 189int sum_idx ; 190vint8m1_t chunk_m1 ; 191vint16m1_t v_sum ; 192sum_idx = offset /16 ; 193chunk_m1 = __riscv_vget_v_i8m2_i8m1 (v_q ,0 ); 194v_sum = __riscv_vwredsum_vs_i8m1_i16m1 (chunk_m1 ,v_zero_sum ,16 ); 195y_block -> bsums [sum_idx ]= (int16_t )__riscv_vmv_x_s_i16m1_i16 (v_sum ); 196 197// remaining iterations 198vint8m2_t slid_q = v_q ; 199for (size_t k = 16 ;k < vl ;k += 16 ) { 200slid_q = __riscv_vslidedown_vx_i8m2 (slid_q ,16 ,vl ); 201 202sum_idx = (offset + k ) /16 ; 203chunk_m1 = __riscv_vget_v_i8m2_i8m1 (slid_q ,0 ); 204 205v_sum = __riscv_vwredsum_vs_i8m1_i16m1 (chunk_m1 ,v_zero_sum ,16 ); 206y_block -> bsums [sum_idx ]= (int16_t )__riscv_vmv_x_s_i16m1_i16 (v_sum ); 207 } 208 209rem -= vl ; 210offset += vl ; 211 } 212 } 213#else 214GGML_UNUSED (nb ); 215// scalar 216quantize_row_q8_K_ref (x ,y ,k ); 217#endif 218} 219 220//===================================== Dot products ================================= 221 222void 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 ) { 223#if defined(__riscv_v ) 224const int qk = QK8_0 ; 225const int nb = n /qk ; 226 227assert (n %qk == 0 ); 228assert (nrc == 1 ); 229UNUSED (nrc ); 230UNUSED (bx ); 231UNUSED (by ); 232UNUSED (bs ); 233 234const block_q4_0 * GGML_RESTRICT x = vx ; 235const block_q8_0 * GGML_RESTRICT y = vy ; 236 237int ib = 0 ; 238float sumf = 0 ; 239 240size_t vl = qk /2 ; 241 242for (;ib < nb ;++ ib ) { 243// load elements 244vuint8m1_t tx = __riscv_vle8_v_u8m1 (x [ib ].qs ,vl ); 245 246vint8m1_t y0 = __riscv_vle8_v_i8m1 (y [ib ].qs ,vl ); 247vint8m1_t y1 = __riscv_vle8_v_i8m1 (y [ib ].qs + 16 ,vl ); 248 249// mask and store lower part of x, and then upper part 250vuint8m1_t x_a = __riscv_vand_vx_u8m1 (tx ,0x0F ,vl ); 251vuint8m1_t x_l = __riscv_vsrl_vx_u8m1 (tx ,0x04 ,vl ); 252 253vint8m1_t x_ai = __riscv_vreinterpret_v_u8m1_i8m1 (x_a ); 254vint8m1_t x_li = __riscv_vreinterpret_v_u8m1_i8m1 (x_l ); 255 256// subtract offset 257vint8m1_t v0 = __riscv_vsub_vx_i8m1 (x_ai ,8 ,vl ); 258vint8m1_t v1 = __riscv_vsub_vx_i8m1 (x_li ,8 ,vl ); 259 260vint16m2_t vec_mul1 = __riscv_vwmul_vv_i16m2 (v0 ,y0 ,vl ); 261vint16m2_t vec_mul2 = __riscv_vwmacc_vv_i16m2 (vec_mul1 ,v1 ,y1 ,vl ); 262 263vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1 (0 ,vl ); 264vint32m1_t vs2 = __riscv_vwredsum_vs_i16m2_i32m1 (vec_mul2 ,vec_zero ,vl ); 265 266int sumi = __riscv_vmv_x_s_i32m1_i32 (vs2 ); 267 268sumf += sumi * GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ); 269 } 270 271* s = sumf ; 272#else 273ggml_vec_dot_q4_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 274#endif 275} 276 277void 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 ) { 278#if defined(__riscv_v ) 279const int qk = QK8_1 ; 280const int nb = n /qk ; 281 282assert (n %qk == 0 ); 283assert (nrc == 1 ); 284UNUSED (nrc ); 285UNUSED (bx ); 286UNUSED (by ); 287UNUSED (bs ); 288 289const block_q4_1 * GGML_RESTRICT x = vx ; 290const block_q8_1 * GGML_RESTRICT y = vy ; 291 292int ib = 0 ; 293float sumf = 0 ; 294 295size_t vl = qk /2 ; 296 297for (;ib < nb ;++ ib ) { 298// load elements 299vuint8m1_t tx = __riscv_vle8_v_u8m1 (x [ib ].qs ,vl ); 300 301vint8m1_t y0 = __riscv_vle8_v_i8m1 (y [ib ].qs ,vl ); 302vint8m1_t y1 = __riscv_vle8_v_i8m1 (y [ib ].qs + 16 ,vl ); 303 304// mask and store lower part of x, and then upper part 305vuint8m1_t x_a = __riscv_vand_vx_u8m1 (tx ,0x0F ,vl ); 306vuint8m1_t x_l = __riscv_vsrl_vx_u8m1 (tx ,0x04 ,vl ); 307 308vint8m1_t v0 = __riscv_vreinterpret_v_u8m1_i8m1 (x_a ); 309vint8m1_t v1 = __riscv_vreinterpret_v_u8m1_i8m1 (x_l ); 310 311vint16m2_t vec_mul1 = __riscv_vwmul_vv_i16m2 (v0 ,y0 ,vl ); 312vint16m2_t vec_mul2 = __riscv_vwmacc_vv_i16m2 (vec_mul1 ,v1 ,y1 ,vl ); 313 314vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1 (0 ,vl ); 315vint32m1_t vs2 = __riscv_vwredsum_vs_i16m2_i32m1 (vec_mul2 ,vec_zero ,vl ); 316 317int sumi = __riscv_vmv_x_s_i32m1_i32 (vs2 ); 318 319sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi + GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 320 } 321 322* s = sumf ; 323#else 324ggml_vec_dot_q4_1_q8_1_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 325#endif 326} 327 328void 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 ) { 329#if defined(__riscv_v ) 330const int qk = QK8_0 ; 331const int nb = n /qk ; 332 333int ib = 0 ; 334float sumf = 0 ; 335 336assert (n %qk == 0 ); 337assert (qk == QK5_0 ); 338assert (nrc == 1 ); 339UNUSED (nrc ); 340UNUSED (bx ); 341UNUSED (by ); 342UNUSED (bs ); 343 344const block_q5_0 * GGML_RESTRICT x = vx ; 345const block_q8_0 * GGML_RESTRICT y = vy ; 346 347size_t vl ; 348size_t vlenb = __riscv_vlenb (); 349 350for (;ib < nb ;++ ib ) { 351vl = qk /2 ; 352vuint8m1_t v0 = __riscv_vle8_v_u8m1 (x [ib ].qs ,vl ); 353vint8m1_t v0l = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (v0 ,0x0F ,vl )); 354vint8m1_t v0h = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vsrl_vx_u8m1 (v0 ,4 ,vl )); 355vint8m2_t v0c ; 356if (vlenb == 16 ) { 357v0c = __riscv_vcreate_v_i8m1_i8m2 (v0l ,v0h ); 358 }else { 359v0l = __riscv_vslideup_vx_i8m1 (v0l ,v0h ,16 ,32 ); 360v0c = __riscv_vlmul_ext_v_i8m1_i8m2 (v0l ); 361 } 362 363vl = qk ; 364vbool4_t qh = __riscv_vlm_v_b4 (x [ib ].qh ,vl ); 365qh = __riscv_vmnand_mm_b4 (qh ,qh ,vl ); 366vint8m2_t v0f = __riscv_vsub_vx_i8m2_mu (qh ,v0c ,v0c ,0x10 ,vl ); 367vint8m2_t v1 = __riscv_vle8_v_i8m2 (y [ib ].qs ,vl ); 368vint16m4_t mul = __riscv_vwmul_vv_i16m4 (v0f ,v1 ,vl ); 369vint32m1_t zero = __riscv_vmv_v_x_i32m1 (0 ,vl ); 370vint32m1_t sum = __riscv_vwredsum_vs_i16m4_i32m1 (mul ,zero ,vl ); 371int32_t sumi = __riscv_vmv_x_s_i32m1_i32 (sum ); 372 373sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi ; 374 } 375 376* s = sumf ; 377#else 378ggml_vec_dot_q5_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 379#endif 380} 381 382void 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 ) { 383#if defined(__riscv_v ) 384const int qk = QK8_1 ; 385const int nb = n /qk ; 386 387int ib = 0 ; 388float sumf = 0 ; 389 390assert (n %qk == 0 ); 391assert (qk == QK5_1 ); 392assert (nrc == 1 ); 393UNUSED (nrc ); 394UNUSED (bx ); 395UNUSED (by ); 396UNUSED (bs ); 397 398const block_q5_1 * GGML_RESTRICT x = vx ; 399const block_q8_1 * GGML_RESTRICT y = vy ; 400 401size_t vl ; 402size_t vlenb = __riscv_vlenb (); 403 404for (;ib < nb ;++ ib ) { 405vl = qk /2 ; 406vuint8m1_t v0 = __riscv_vle8_v_u8m1 (x [ib ].qs ,vl ); 407vint8m1_t v0l = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (v0 ,0x0F ,vl )); 408vint8m1_t v0h = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vsrl_vx_u8m1 (v0 ,4 ,vl )); 409vint8m2_t v0c ; 410if (vlenb == 16 ) { 411v0c = __riscv_vcreate_v_i8m1_i8m2 (v0l ,v0h ); 412 }else { 413v0l = __riscv_vslideup_vx_i8m1 (v0l ,v0h ,16 ,32 ); 414v0c = __riscv_vlmul_ext_v_i8m1_i8m2 (v0l ); 415 } 416 417vl = qk ; 418vbool4_t qh = __riscv_vlm_v_b4 (x [ib ].qh ,vl ); 419vint8m2_t v0f = __riscv_vor_vx_i8m2_mu (qh ,v0c ,v0c ,0x10 ,vl ); 420vint8m2_t v1 = __riscv_vle8_v_i8m2 (y [ib ].qs ,vl ); 421vint16m4_t mul = __riscv_vwmul_vv_i16m4 (v0f ,v1 ,vl ); 422vint32m1_t zero = __riscv_vmv_v_x_i32m1 (0 ,vl ); 423vint32m1_t sum = __riscv_vwredsum_vs_i16m4_i32m1 (mul ,zero ,vl ); 424int32_t sumi = __riscv_vmv_x_s_i32m1_i32 (sum ); 425 426sumf += (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d ))* sumi + GGML_CPU_FP16_TO_FP32 (x [ib ].m )* GGML_CPU_FP16_TO_FP32 (y [ib ].s ); 427 } 428 429* s = sumf ; 430#else 431ggml_vec_dot_q5_1_q8_1_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 432#endif 433} 434 435void 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 ) { 436const int qk = QK8_0 ; 437const int nb = n /qk ; 438 439assert (n %qk == 0 ); 440assert (nrc == 1 ); 441UNUSED (nrc ); 442UNUSED (bx ); 443UNUSED (by ); 444UNUSED (bs ); 445 446const block_q8_0 * GGML_RESTRICT x = vx ; 447const block_q8_0 * GGML_RESTRICT y = vy ; 448 449int ib = 0 ; 450float sumf = 0 ; 451 452#if defined(__riscv_v ) 453size_t vl = qk ; 454 455for (;ib < nb ;++ ib ) { 456// load elements 457vint8m2_t bx_0 = __riscv_vle8_v_i8m2 (x [ib ].qs ,vl ); 458vint8m2_t by_0 = __riscv_vle8_v_i8m2 (y [ib ].qs ,vl ); 459 460vint16m4_t vw_mul = __riscv_vwmul_vv_i16m4 (bx_0 ,by_0 ,vl ); 461 462vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,vl ); 463vint32m1_t v_sum = __riscv_vwredsum_vs_i16m4_i32m1 (vw_mul ,v_zero ,vl ); 464 465int sumi = __riscv_vmv_x_s_i32m1_i32 (v_sum ); 466 467sumf += sumi * (GGML_CPU_FP16_TO_FP32 (x [ib ].d )* GGML_CPU_FP16_TO_FP32 (y [ib ].d )); 468 } 469 470* s = sumf ; 471#else 472 473UNUSED (nb ); 474UNUSED (x ); 475UNUSED (y ); 476UNUSED (ib ); 477UNUSED (sumf ); 478 479ggml_vec_dot_q8_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 480#endif 481} 482 483#if defined(__riscv_v ) 484static NOINLINE void ggml_vec_dot_q1_0_q8_0_vl256 (const int n ,float * GGML_RESTRICT s ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ) { 485const int qk = QK1_0 ; 486const int nb = n /qk ; 487assert (n %qk == 0 ); 488 489const block_q1_0 * GGML_RESTRICT x = vx ; 490const block_q8_0 * GGML_RESTRICT y = vy ; 491 492//LMUL = 1, VLMAX = 32 493const size_t vl32 = __riscv_vsetvl_e8m1 (32 ); 494assert (vl32 == 32 ); 495 496const vint16m1_t zero = __riscv_vmv_v_x_i16m1 (0 ,1 ); 497 498float sumf = 0 ; 499 500for (int ib = 0 ;ib < nb ;++ ib ) { 501const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 502 503float acc = 0 ; 504 505for (int k = 0 ;k < 4 ;++ k ) { 506const block_q8_0 * GGML_RESTRICT yb = & y [ib * 4 + k ]; 507const vbool8_t is_not_zero = __riscv_vlm_v_b8 (x [ib ].qs + 4 * k ,vl32 ); 508 509const vint8m1_t qy = __riscv_vle8_v_i8m1 (yb -> qs ,vl32 ); 510const vint8m1_t neg_qy = __riscv_vneg_v_i8m1 (qy ,vl32 ); 511const vint8m1_t sy = __riscv_vmerge_vvm_i8m1 (neg_qy ,qy ,is_not_zero ,vl32 ); 512 513const vint16m1_t red = __riscv_vwredsum_vs_i8m1_i16m1 (sy ,zero ,vl32 ); 514acc += GGML_CPU_FP16_TO_FP32 (yb -> d )* (float )__riscv_vmv_x_s_i16m1_i16 (red ); 515 } 516 517sumf += d0 * acc ; 518 } 519 520* s = sumf ; 521} 522 523static NOINLINE void ggml_vec_dot_q1_0_q8_0_vl128 (const int n ,float * GGML_RESTRICT s ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ) { 524const int qk = QK1_0 ; 525const int nb = n /qk ; 526assert (n %qk == 0 ); 527 528const block_q1_0 * GGML_RESTRICT x = vx ; 529const block_q8_0 * GGML_RESTRICT y = vy ; 530 531//LMUL = 2, VLMAX = 32 532const size_t vl32 = __riscv_vsetvl_e8m2 (32 ); 533assert (vl32 == 32 ); 534 535const vint16m1_t zero = __riscv_vmv_v_x_i16m1 (0 ,1 ); 536 537float sumf = 0 ; 538 539for (int ib = 0 ;ib < nb ;++ ib ) { 540const float d0 = GGML_CPU_FP16_TO_FP32 (x [ib ].d ); 541 542float acc = 0 ; 543 544for (int k = 0 ;k < 4 ;++ k ) { 545const block_q8_0 * GGML_RESTRICT yb = & y [ib * 4 + k ]; 546const vbool4_t is_not_zero = __riscv_vlm_v_b4 (x [ib ].qs + 4 * k ,vl32 ); 547 548const vint8m2_t qy = __riscv_vle8_v_i8m2 (yb -> qs ,vl32 ); 549const vint8m2_t neg_qy = __riscv_vneg_v_i8m2 (qy ,vl32 ); 550const vint8m2_t sy = __riscv_vmerge_vvm_i8m2 (neg_qy ,qy ,is_not_zero ,vl32 ); 551 552const vint16m1_t red = __riscv_vwredsum_vs_i8m2_i16m1 (sy ,zero ,vl32 ); 553acc += GGML_CPU_FP16_TO_FP32 (yb -> d )* (float )__riscv_vmv_x_s_i16m1_i16 (red ); 554 } 555 556sumf += d0 * acc ; 557 } 558 559* s = sumf ; 560} 561#endif 562 563void ggml_vec_dot_q1_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 ) { 564#if defined(__riscv_v ) 565assert (nrc == 1 ); 566 567const size_t vlen_bits = __riscv_vlenb ()* 8 ; 568 569if (vlen_bits >=256 ) { 570ggml_vec_dot_q1_0_q8_0_vl256 (n ,s ,vx ,vy ); 571 }else if (vlen_bits >=128 ) { 572ggml_vec_dot_q1_0_q8_0_vl128 (n ,s ,vx ,vy ); 573 }else { 574ggml_vec_dot_q1_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 575 } 576#else 577ggml_vec_dot_q1_0_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 578#endif 579} 580 581#if defined__riscv_xtheadvector 582void ggml_vec_dot_q2_K_q8_K_xtheadvector (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 ) { 583assert (nrc == 1 ); 584UNUSED (nrc ); 585UNUSED (bx ); 586UNUSED (by ); 587UNUSED (bs ); 588 589const block_q2_K * GGML_RESTRICT x = vx ; 590const block_q8_K * GGML_RESTRICT y = vy ; 591 592const int nb = n /QK_K ; 593 594float sumf = 0 ; 595uint8_t atmp [16 ]; 596 597for (int i = 0 ;i < nb ;++ i ) { 598const uint8_t * q2 = x [i ].qs ; 599const int8_t * q8 = y [i ].qs ; 600const uint8_t * sc = x [i ].scales ; 601const float dall = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 602const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 603uint8_t * patmp = atmp ; 604int vsums ; 605int tmp ; 606 __asm__ __volatile__( 607"th.vsetvli zero, %[vl16], e8, m1\n\t" 608"th.vmv.v.x v8, zero\n\t" 609"th.vlb.v v1, (%[sc])\n\t" 610"th.vand.vi v0, v1, 0xF\n\t" 611"th.vsrl.vi v1, v1, 4\n\t" 612"th.vsb.v v0, (%[scale])\n\t" 613"th.vwaddu.vx v16, v1, zero\n\t" 614"th.vsetvli zero, %[vl16], e16, m2\n\t" 615"th.vlh.v v2, (%[bsums])\n\t" 616"th.vwmul.vv v4, v16, v2\n\t" 617"th.vsetvli zero, %[vl16], e32, m4\n\t" 618"th.vredsum.vs v8, v4, v8\n\t" 619"th.vmv.x.s %[vsums], v8" 620 : [tmp ]"=&r" (tmp ), [vsums ]"=&r" (vsums ) 621 : [sc ]"r" (sc ), [scale ]"r" (atmp ), [bsums ]"r" (y [i ].bsums ) 622 , [vl16 ]"r" (16 ) 623 :"memory" 624 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 625 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 626 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 627 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 628 ); 629sumf += dmin * vsums ; 630int isum = 0 ; 631 632for (int j = 0 ;j < QK_K /128 ;++ j ) { 633 __asm__ __volatile__( 634"th.vsetvli zero, %[vl32], e8, m2\n\t" 635"th.vlb.v v0, (%[q2])\n\t" 636"th.vsrl.vi v2, v0, 2\n\t" 637"th.vsrl.vi v4, v0, 4\n\t" 638"th.vsrl.vi v6, v0, 6\n\t" 639"th.vand.vi v0, v0, 0x3\n\t" 640"th.vand.vi v2, v2, 0x3\n\t" 641"th.vand.vi v4, v4, 0x3\n\t" 642"th.vsetvli zero, %[vl128], e8, m8\n\t" 643"th.vlb.v v8, (%[q8])\n\t" 644"th.vsetvli zero, %[vl64], e8, m4\n\t" 645"th.vwmul.vv v16, v0, v8\n\t" 646"th.vwmul.vv v24, v4, v12\n\t" 647"th.vsetvli zero, %[vl16], e16, m2\n\t" 648"th.vmv.v.x v0, zero\n\t" 649"th.vwredsum.vs v10, v16, v0\n\t" 650"th.vwredsum.vs v9, v18, v0\n\t" 651"th.vwredsum.vs v8, v20, v0\n\t" 652"th.vwredsum.vs v7, v22, v0\n\t" 653"th.vwredsum.vs v11, v24, v0\n\t" 654"th.vwredsum.vs v12, v26, v0\n\t" 655"th.vwredsum.vs v13, v28, v0\n\t" 656"th.vwredsum.vs v14, v30, v0\n\t" 657"li %[tmp], 4\n\t" 658"th.vsetvli zero, %[tmp], e32, m1\n\t" 659"th.vslideup.vi v10, v9, 1\n\t" 660"th.vslideup.vi v8, v7, 1\n\t" 661"th.vslideup.vi v11, v12, 1\n\t" 662"th.vslideup.vi v13, v14, 1\n\t" 663"th.vslideup.vi v10, v8, 2\n\t" 664"th.vslideup.vi v11, v13, 2\n\t" 665"li %[tmp], 8\n\t" 666"th.vsetvli zero, %[tmp], e32, m2\n\t" 667"th.vlbu.v v12, (%[scale])\n\t" 668"th.vmul.vv v10, v10, v12\n\t" 669"th.vredsum.vs v0, v10, v0\n\t" 670"th.vmv.x.s %[tmp], v0\n\t" 671"add %[isum], %[isum], %[tmp]" 672 : [tmp ]"=&r" (tmp ), [isum ]"+&r" (isum ) 673 : [q2 ]"r" (q2 ), [scale ]"r" (patmp ), [q8 ]"r" (q8 ) 674 , [vl16 ]"r" (16 ), [vl32 ]"r" (32 ), [vl64 ]"r" (64 ), [vl128 ]"r" (128 ) 675 :"memory" 676 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 677 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 678 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 679 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 680 ); 681q2 += 32 ;q8 += 128 ;patmp += 8 ; 682 } 683 684sumf += dall * isum ; 685 } 686 687* s = sumf ; 688} 689#endif 690 691#if defined__riscv_v 692void ggml_vec_dot_q2_K_q8_K_vl128 (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 ) { 693assert (nrc == 1 ); 694UNUSED (nrc ); 695UNUSED (bx ); 696UNUSED (by ); 697UNUSED (bs ); 698 699const block_q2_K * GGML_RESTRICT x = vx ; 700const block_q8_K * GGML_RESTRICT y = vy ; 701 702const int nb = n /QK_K ; 703 704float sumf = 0 ; 705uint8_t atmp [16 ]; 706 707uint8_t temp_01 [32 ]= {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 7081 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 }; 709 710for (int i = 0 ;i < nb ;++ i ) { 711const uint8_t * q2 = x [i ].qs ; 712const int8_t * q8 = y [i ].qs ; 713const uint8_t * sc = x [i ].scales ; 714const float dall = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 715const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 716uint8_t * patmp = atmp ; 717int vsums ; 718int tmp ,t1 ,t2 ,t3 ,t4 ,t5 ,t6 ,t7 ; 719 __asm__ __volatile__( 720"vsetivli zero, 16, e8, m1\n\t" 721"vmv.v.x v8, zero\n\t" 722"lb zero, 15(%[sc])\n\t" 723"vle8.v v1, (%[sc])\n\t" 724"vle8.v v2, (%[bsums])\n\t" 725"addi %[tmp], %[bsums], 16\n\t" 726"vand.vi v0, v1, 0xF\n\t" 727"vsrl.vi v1, v1, 4\n\t" 728"vle8.v v3, (%[tmp])\n\t" 729"vse8.v v0, (%[scale])\n\t" 730"vsetivli zero, 16, e16, m2\n\t" 731"vzext.vf2 v0, v1\n\t" 732"vwmul.vv v4, v0, v2\n\t" 733"vsetivli zero, 16, e32, m4\n\t" 734"vredsum.vs v8, v4, v8\n\t" 735"vmv.x.s %[vsums], v8" 736 : [tmp ]"=&r" (tmp ), [vsums ]"=&r" (vsums ) 737 : [sc ]"r" (sc ), [scale ]"r" (atmp ), [bsums ]"r" (y [i ].bsums ) 738 :"memory" 739 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 740 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 741 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 742 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 743 ); 744sumf += dmin * vsums ; 745int isum = 0 ; 746 747for (int j = 0 ;j < QK_K /128 ;++ j ) { 748 __asm__ __volatile__( 749"lb zero, 31(%[q2])\n\t" 750"addi %[tmp], %[q2], 16\n\t" 751"addi %[t1], %[q8], 16\n\t" 752"vsetivli zero, 16, e8, m1\n\t" 753"vle8.v v0, (%[q2])\n\t" 754"vle8.v v1, (%[tmp])\n\t" 755"vsrl.vi v2, v0, 2\n\t" 756"vsrl.vi v3, v1, 2\n\t" 757"vsrl.vi v4, v0, 4\n\t" 758"addi %[tmp], %[q8], 32\n\t" 759"vle8.v v8, (%[q8])\n\t" 760"vle8.v v9, (%[t1])\n\t" 761"addi %[t1], %[t1], 32\n\t" 762"vsrl.vi v5, v1, 4\n\t" 763"vsrl.vi v6, v0, 6\n\t" 764"vsrl.vi v7, v1, 6\n\t" 765"vle8.v v10, (%[tmp])\n\t" 766"vle8.v v11, (%[t1])\n\t" 767"addi %[tmp], %[tmp], 32\n\t" 768"addi %[t1], %[t1], 32\n\t" 769"vand.vi v0, v0, 0x3\n\t" 770"vand.vi v1, v1, 0x3\n\t" 771"vand.vi v2, v2, 0x3\n\t" 772"vle8.v v12, (%[tmp])\n\t" 773"vle8.v v13, (%[t1])\n\t" 774"addi %[tmp], %[tmp], 32\n\t" 775"addi %[t1], %[t1], 32\n\t" 776"vand.vi v3, v3, 0x3\n\t" 777"vand.vi v4, v4, 0x3\n\t" 778"vand.vi v5, v5, 0x3\n\t" 779"vle8.v v14, (%[tmp])\n\t" 780"vle8.v v15, (%[t1])\n\t" 781"vwmul.vv v16, v0, v8\n\t" 782"vwmul.vv v18, v1, v9\n\t" 783"vwmul.vv v20, v2, v10\n\t" 784"vwmul.vv v22, v3, v11\n\t" 785"vwmul.vv v24, v4, v12\n\t" 786"vwmul.vv v26, v5, v13\n\t" 787"vwmul.vv v28, v6, v14\n\t" 788"vwmul.vv v30, v7, v15\n\t" 789"vsetivli zero, 8, e16, m1\n\t" 790"vmv.v.x v0, zero\n\t" 791"lbu %[tmp], 0(%[scale])\n\t" 792"vwredsum.vs v8, v16, v0\n\t" 793"vwredsum.vs v9, v18, v0\n\t" 794"lbu %[t1], 1(%[scale])\n\t" 795"vwredsum.vs v10, v20, v0\n\t" 796"vwredsum.vs v11, v22, v0\n\t" 797"lbu %[t2], 2(%[scale])\n\t" 798"vwredsum.vs v12, v24, v0\n\t" 799"vwredsum.vs v13, v26, v0\n\t" 800"lbu %[t3], 3(%[scale])\n\t" 801"vwredsum.vs v14, v28, v0\n\t" 802"vwredsum.vs v15, v30, v0\n\t" 803"lbu %[t4], 4(%[scale])\n\t" 804"vwredsum.vs v8, v17, v8\n\t" 805"vwredsum.vs v9, v19, v9\n\t" 806"lbu %[t5], 5(%[scale])\n\t" 807"vwredsum.vs v10, v21, v10\n\t" 808"vwredsum.vs v11, v23, v11\n\t" 809"lbu %[t6], 6(%[scale])\n\t" 810"vwredsum.vs v12, v25, v12\n\t" 811"vwredsum.vs v13, v27, v13\n\t" 812"lbu %[t7], 7(%[scale])\n\t" 813"vwredsum.vs v14, v29, v14\n\t" 814"vwredsum.vs v15, v31, v15\n\t" 815"vsetivli zero, 4, e32, m1\n\t" 816"vmul.vx v0, v8, %[tmp]\n\t" 817"vmul.vx v1, v9, %[t1]\n\t" 818"vmacc.vx v0, %[t2], v10\n\t" 819"vmacc.vx v1, %[t3], v11\n\t" 820"vmacc.vx v0, %[t4], v12\n\t" 821"vmacc.vx v1, %[t5], v13\n\t" 822"vmacc.vx v0, %[t6], v14\n\t" 823"vmacc.vx v1, %[t7], v15\n\t" 824"vmv.x.s %[tmp], v0\n\t" 825"vmv.x.s %[t1], v1\n\t" 826"add %[isum], %[isum], %[tmp]\n\t" 827"add %[isum], %[isum], %[t1]" 828 : [tmp ]"=&r" (tmp ), [t1 ]"=&r" (t1 ), [t2 ]"=&r" (t2 ), [t3 ]"=&r" (t3 ) 829 , [t4 ]"=&r" (t4 ), [t5 ]"=&r" (t5 ), [t6 ]"=&r" (t6 ), [t7 ]"=&r" (t7 ) 830 , [isum ]"+&r" (isum ) 831 : [q2 ]"r" (q2 ), [scale ]"r" (patmp ), [q8 ]"r" (q8 ) 832 :"memory" 833 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 834 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 835 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 836 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 837 ); 838q2 += 32 ;q8 += 128 ;patmp += 8 ; 839 } 840 841sumf += dall * isum ; 842 } 843 844* s = sumf ; 845} 846 847void ggml_vec_dot_q2_K_q8_K_vl256 (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 ) { 848assert (nrc == 1 ); 849UNUSED (nrc ); 850UNUSED (bx ); 851UNUSED (by ); 852UNUSED (bs ); 853 854const block_q2_K * GGML_RESTRICT x = vx ; 855const block_q8_K * GGML_RESTRICT y = vy ; 856 857const int nb = n /QK_K ; 858 859float sumf = 0 ; 860uint8_t atmp [16 ]; 861 862uint8_t temp_01 [32 ]= {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , 8631 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 }; 864 865for (int i = 0 ;i < nb ;++ i ) { 866const uint8_t * q2 = x [i ].qs ; 867const int8_t * q8 = y [i ].qs ; 868const uint8_t * sc = x [i ].scales ; 869 870const float dall = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 871const float dmin = - y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 872 873size_t vl = 16 ; 874 875vuint8m1_t scales = __riscv_vle8_v_u8m1 (sc ,vl ); 876vuint8m1_t aux = __riscv_vand_vx_u8m1 (scales ,0x0F ,vl ); 877 878vint16m1_t q8sums = __riscv_vle16_v_i16m1 (y [i ].bsums ,vl ); 879 880vuint8mf2_t scales_2 = __riscv_vle8_v_u8mf2 (sc ,vl ); 881vuint8mf2_t mins8 = __riscv_vsrl_vx_u8mf2 (scales_2 ,0x4 ,vl ); 882vint16m1_t mins = __riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (mins8 ,vl )); 883vint32m2_t prod = __riscv_vwmul_vv_i32m2 (q8sums ,mins ,vl ); 884vint32m1_t vsums = __riscv_vredsum_vs_i32m2_i32m1 (prod ,__riscv_vmv_v_x_i32m1 (0 ,1 ),vl ); 885 886sumf += dmin * __riscv_vmv_x_s_i32m1_i32 (vsums ); 887 888vl = 32 ; 889 890vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 891vuint8m1_t v_b = __riscv_vle8_v_u8m1 (temp_01 ,vl ); 892 893uint8_t is = 0 ; 894int isum = 0 ; 895 896for (int j = 0 ;j < QK_K /128 ;++ j ) { 897// load Q2 898vuint8m1_t q2_x = __riscv_vle8_v_u8m1 (q2 ,vl ); 899 900vuint8m1_t q2_0 = __riscv_vand_vx_u8m1 (q2_x ,0x03 ,vl ); 901vuint8m1_t q2_1 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q2_x ,0x2 ,vl ),0x03 ,vl ); 902vuint8m1_t q2_2 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q2_x ,0x4 ,vl ),0x03 ,vl ); 903vuint8m1_t q2_3 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q2_x ,0x6 ,vl ),0x03 ,vl ); 904 905// duplicate scale elements for product 906vuint8m1_t sc0 = __riscv_vrgather_vv_u8m1 (aux ,__riscv_vadd_vx_u8m1 (v_b ,0 + is ,vl ),vl ); 907vuint8m1_t sc1 = __riscv_vrgather_vv_u8m1 (aux ,__riscv_vadd_vx_u8m1 (v_b ,2 + is ,vl ),vl ); 908vuint8m1_t sc2 = __riscv_vrgather_vv_u8m1 (aux ,__riscv_vadd_vx_u8m1 (v_b ,4 + is ,vl ),vl ); 909vuint8m1_t sc3 = __riscv_vrgather_vv_u8m1 (aux ,__riscv_vadd_vx_u8m1 (v_b ,6 + is ,vl ),vl ); 910 911vint16m2_t p0 = __riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vwmulu_vv_u16m2 (q2_0 ,sc0 ,vl )); 912vint16m2_t p1 = __riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vwmulu_vv_u16m2 (q2_1 ,sc1 ,vl )); 913vint16m2_t p2 = __riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vwmulu_vv_u16m2 (q2_2 ,sc2 ,vl )); 914vint16m2_t p3 = __riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vwmulu_vv_u16m2 (q2_3 ,sc3 ,vl )); 915 916// load Q8 917vint8m1_t q8_0 = __riscv_vle8_v_i8m1 (q8 ,vl ); 918vint8m1_t q8_1 = __riscv_vle8_v_i8m1 (q8 + 32 ,vl ); 919vint8m1_t q8_2 = __riscv_vle8_v_i8m1 (q8 + 64 ,vl ); 920vint8m1_t q8_3 = __riscv_vle8_v_i8m1 (q8 + 96 ,vl ); 921 922vint32m4_t s0 = __riscv_vwmul_vv_i32m4 (p0 ,__riscv_vwcvt_x_x_v_i16m2 (q8_0 ,vl ),vl ); 923vint32m4_t s1 = __riscv_vwmul_vv_i32m4 (p1 ,__riscv_vwcvt_x_x_v_i16m2 (q8_1 ,vl ),vl ); 924vint32m4_t s2 = __riscv_vwmul_vv_i32m4 (p2 ,__riscv_vwcvt_x_x_v_i16m2 (q8_2 ,vl ),vl ); 925vint32m4_t s3 = __riscv_vwmul_vv_i32m4 (p3 ,__riscv_vwcvt_x_x_v_i16m2 (q8_3 ,vl ),vl ); 926 927vint32m1_t isum0 = __riscv_vredsum_vs_i32m4_i32m1 (__riscv_vadd_vv_i32m4 (s0 ,s1 ,vl ),vzero ,vl ); 928vint32m1_t isum1 = __riscv_vredsum_vs_i32m4_i32m1 (__riscv_vadd_vv_i32m4 (s2 ,s3 ,vl ),isum0 ,vl ); 929 930isum += __riscv_vmv_x_s_i32m1_i32 (isum1 ); 931 932q2 += 32 ; 933q8 += 128 ; 934is = 8 ; 935 } 936 937sumf += dall * isum ; 938 } 939 940* s = sumf ; 941} 942#endif 943 944void 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 ) { 945#if defined__riscv_xtheadvector 946ggml_vec_dot_q2_K_q8_K_xtheadvector (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 947#elif defined__riscv_v 948switch (__riscv_vlenb ()* 8 ) { 949case 128 : 950ggml_vec_dot_q2_K_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 951break ; 952default : 953ggml_vec_dot_q2_K_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 954break ; 955 } 956#else 957ggml_vec_dot_q2_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 958#endif 959} 960 961#if defined__riscv_xtheadvector 962void ggml_vec_dot_q3_K_q8_K_xtheadvector (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 ) { 963assert (n %QK_K == 0 ); 964assert (nrc == 1 ); 965UNUSED (nrc ); 966UNUSED (bx ); 967UNUSED (by ); 968UNUSED (bs ); 969 970const uint32_t kmask1 = 0x03030303 ; 971const uint32_t kmask2 = 0x0f0f0f0f ; 972 973const block_q3_K * GGML_RESTRICT x = vx ; 974const block_q8_K * GGML_RESTRICT y = vy ; 975 976const int nb = n /QK_K ; 977 978uint32_t utmp [4 ]; 979float sumf = 0 ; 980 981for (int i = 0 ;i < nb ;++ i ) { 982const uint8_t * restrictq3 = x [i ].qs ; 983const uint8_t * restrictqh = x [i ].hmask ; 984const int8_t * restrictq8 = y [i ].qs ; 985 986int8_t * scale = (int8_t * )utmp ; 987int tmp ; 988 __asm__ __volatile__( 989"li %[tmp], 12\n\t" 990"th.vsetvli zero, %[tmp], e8, m1\n\t" 991"th.vlb.v v0, (%[s6b])\n\t" 992"th.vmv.v.v v2, v0\n\t" 993"li %[tmp], 2\n\t" 994"th.vsetvli zero, %[tmp], e64, m1\n\t" 995"th.vmv.v.x v9, %[sh]\n\t" \ 996"th.vslidedown.vi v1, v0, 1\n\t" 997"th.vslide1up.vx v8, v9, zero\n\t" // {0, 0, 4, 4} 998"th.vslideup.vi v0, v2, 1\n\t" // {aux[0], aux[1], aux[0], aux[1]} 999"li %[tmp], 4\n\t" 1000"th.vsetvli zero, %[tmp], e32, m1\n\t" 1001"th.vid.v v9\n\t" 1002"th.vmv.x.s %[tmp], v1\n\t" 1003"th.vsll.vi v9, v9, 1\n\t" // {0, 2, 4, 6} 1004"th.vmv.v.x v1, %[tmp]\n\t" // {aux[2], aux[2], aux[2], aux[2]} 1005"th.vsrl.vv v4, v1, v9\n\t" 1006"th.vsrl.vv v2, v0, v8\n\t" 1007"th.vand.vx v5, v4, %[kmask1]\n\t" 1008"th.vand.vx v3, v2, %[kmask2]\n\t" 1009"th.vsll.vi v6, v5, 4\n\t" 1010"th.vor.vv v7, v6, v3\n\t" 1011"li %[tmp], 16\n\t" 1012"th.vsetvli zero, %[tmp], e8, m1\n\t" 1013"th.vsub.vx v0, v7, %[c]\n\t" 1014"th.vsb.v v0, (%[scale])" 1015 : [tmp ]"=&r" (tmp ) 1016 : [sh ]"r" (0x0000000400000004 ), [s6b ]"r" (x [i ].scales ), [c ]"r" (32 ) 1017 , [scale ]"r" (scale ), [kmask1 ]"r" (kmask1 ), [kmask2 ]"r" (kmask2 ) 1018 :"memory" 1019 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1020 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1021 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1022 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1023 ); 1024 1025uint8_t m = 1 ; 1026int isum = 0 ; 1027for (int j = 0 ;j < QK_K ;j += 128 ) { 1028 __asm__ __volatile__( 1029// fixme: use v0p7 mask layout directly 1030"th.vsetvli zero, %[vl32], e8, m2\n\t" 1031"th.vlb.v v8, (%[q3])\n\t" 1032"th.vsrl.vi v10, v8, 2\n\t" 1033"th.vsrl.vi v12, v8, 4\n\t" 1034"th.vsrl.vi v14, v8, 6\n\t" 1035"th.vand.vi v8, v8, 3\n\t" 1036"th.vand.vi v10, v10, 3\n\t" 1037"th.vand.vi v12, v12, 3\n\t" 1038"th.vlb.v v2, (%[qh])\n\t" 1039"th.vand.vx v4, v2, %[m]\n\t" 1040"slli %[m], %[m], 1\n\t" 1041"th.vmseq.vx v0, v4, zero\n\t" 1042"th.vadd.vi v8, v8, -4, v0.t\n\t" 1043"th.vand.vx v4, v2, %[m]\n\t" 1044"slli %[m], %[m], 1\n\t" 1045"th.vmseq.vx v0, v4, zero\n\t" 1046"th.vadd.vi v10, v10, -4, v0.t\n\t" 1047"th.vand.vx v4, v2, %[m]\n\t" 1048"slli %[m], %[m], 1\n\t" 1049"th.vmseq.vx v0, v4, zero\n\t" 1050"th.vadd.vi v12, v12, -4, v0.t\n\t" 1051"th.vand.vx v4, v2, %[m]\n\t" 1052"slli %[m], %[m], 1\n\t" 1053"th.vmseq.vx v0, v4, zero\n\t" 1054"th.vadd.vi v14, v14, -4, v0.t\n\t" 1055"th.vsetvli zero, %[vl128], e8, m8\n\t" 1056"th.vlb.v v0, (%[q8])\n\t" 1057"th.vsetvli zero, %[vl64], e8, m4\n\t" 1058"th.vwmul.vv v16, v0, v8\n\t" 1059"th.vwmul.vv v24, v4, v12\n\t" 1060"li %[tmp], 16\n\t" 1061"th.vsetvli zero, %[tmp], e16, m2\n\t" 1062"th.vmv.v.x v0, zero\n\t" 1063"th.vwredsum.vs v10, v16, v0\n\t" 1064"th.vwredsum.vs v9, v18, v0\n\t" 1065"th.vwredsum.vs v8, v20, v0\n\t" 1066"th.vwredsum.vs v7, v22, v0\n\t" 1067"th.vwredsum.vs v11, v24, v0\n\t" 1068"th.vwredsum.vs v12, v26, v0\n\t" 1069"th.vwredsum.vs v13, v28, v0\n\t" 1070"th.vwredsum.vs v14, v30, v0\n\t" 1071"li %[tmp], 4\n\t" 1072"th.vsetvli zero, %[tmp], e32, m1\n\t" 1073"th.vslideup.vi v10, v9, 1\n\t" 1074"th.vslideup.vi v8, v7, 1\n\t" 1075"th.vslideup.vi v11, v12, 1\n\t" 1076"th.vslideup.vi v13, v14, 1\n\t" 1077"th.vslideup.vi v10, v8, 2\n\t" 1078"th.vslideup.vi v11, v13, 2\n\t" 1079"li %[tmp], 8\n\t" 1080"th.vsetvli zero, %[tmp], e32, m2\n\t" 1081"th.vlb.v v12, (%[scale])\n\t" 1082"th.vmul.vv v10, v10, v12\n\t" 1083"th.vredsum.vs v0, v10, v0\n\t" 1084"th.vmv.x.s %[tmp], v0\n\t" 1085"add %[isum], %[isum], %[tmp]" 1086 : [tmp ]"=&r" (tmp ), [m ]"+&r" (m ), [isum ]"+&r" (isum ) 1087 : [vl128 ]"r" (128 ), [vl64 ]"r" (64 ), [vl32 ]"r" (32 ) 1088 , [q3 ]"r" (q3 ), [qh ]"r" (qh ), [scale ]"r" (scale ), [q8 ]"r" (q8 ) 1089 :"memory" 1090 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1091 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1092 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1093 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1094 ); 1095q3 += 32 ;q8 += 128 ;scale += 8 ; 1096 } 1097 1098const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1099sumf += d * isum ; 1100 } 1101 1102* s = sumf ; 1103} 1104#endif 1105 1106#if defined__riscv_v 1107void ggml_vec_dot_q3_K_q8_K_vl128 (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 ) { 1108assert (n %QK_K == 0 ); 1109assert (nrc == 1 ); 1110UNUSED (nrc ); 1111UNUSED (bx ); 1112UNUSED (by ); 1113UNUSED (bs ); 1114 1115const uint32_t kmask1 = 0x03030303 ; 1116const uint32_t kmask2 = 0x0f0f0f0f ; 1117 1118const block_q3_K * GGML_RESTRICT x = vx ; 1119const block_q8_K * GGML_RESTRICT y = vy ; 1120 1121const int nb = n /QK_K ; 1122 1123uint32_t utmp [4 ]; 1124float sumf = 0 ; 1125uint32_t aux [3 ]; 1126 1127for (int i = 0 ;i < nb ;++ i ) { 1128const uint8_t * restrictq3 = x [i ].qs ; 1129const uint8_t * restrictqh = x [i ].hmask ; 1130const int8_t * restrictq8 = y [i ].qs ; 1131 1132int8_t * scale = (int8_t * )utmp ; 1133int tmp ,t1 ,t2 ,t3 ,t4 ,t5 ,t6 ,t7 ; 1134 __asm__ __volatile__( 1135"vsetivli zero, 12, e8, m1\n\t" 1136"vle8.v v0, (%[s6b])\n\t" 1137"vmv1r.v v2, v0\n\t" 1138"vsetivli zero, 2, e64, m1\n\t" 1139"vmv.v.x v9, %[sh]\n\t" \ 1140"vslidedown.vi v1, v0, 1\n\t" 1141"vslide1up.vx v8, v9, zero\n\t" // {0, 0, 4, 4} 1142"vslideup.vi v0, v2, 1\n\t" // {aux[0], aux[1], aux[0], aux[1]} 1143"vsetivli zero, 4, e32, m1\n\t" 1144"vid.v v9\n\t" 1145"vmv.x.s %[tmp], v1\n\t" 1146"vsll.vi v9, v9, 1\n\t" // {0, 2, 4, 6} 1147"vmv.v.x v1, %[tmp]\n\t" // {aux[2], aux[2], aux[2], aux[2]} 1148"vsrl.vv v4, v1, v9\n\t" 1149"vsrl.vv v2, v0, v8\n\t" 1150"vand.vx v5, v4, %[kmask1]\n\t" 1151"vand.vx v3, v2, %[kmask2]\n\t" 1152"vsll.vi v6, v5, 4\n\t" 1153"vor.vv v7, v6, v3\n\t" 1154"vsetivli zero, 16, e8, m1\n\t" 1155"vsub.vx v0, v7, %[c]\n\t" 1156"vse8.v v0, (%[scale])" 1157 : [tmp ]"=&r" (tmp ) 1158 : [sh ]"r" (0x0000000400000004 ), [s6b ]"r" (x [i ].scales ), [c ]"r" (32 ) 1159 , [scale ]"r" (scale ), [kmask1 ]"r" (kmask1 ), [kmask2 ]"r" (kmask2 ) 1160 :"memory" 1161 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1162 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1163 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1164 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1165 ); 1166 1167uint8_t m = 1 ; 1168int isum = 0 ; 1169for (int j = 0 ;j < QK_K ;j += 128 ) { 1170 __asm__ __volatile__( 1171"lb zero, 31(%[q3])\n\t" 1172"vsetvli zero, %[vl32], e8, m2, ta, mu\n\t" 1173"vle8.v v8, (%[q3])\n\t" 1174"vsrl.vi v10, v8, 2\n\t" 1175"vsrl.vi v12, v8, 4\n\t" 1176"vsrl.vi v14, v8, 6\n\t" 1177"lb zero, 64(%[q8])\n\t" 1178"vand.vi v8, v8, 3\n\t" 1179"vand.vi v10, v10, 3\n\t" 1180"vand.vi v12, v12, 3\n\t" 1181"vle8.v v2, (%[qh])\n\t" 1182"lb zero, 127(%[q8])\n\t" 1183"vand.vx v4, v2, %[m]\n\t" 1184"slli %[m], %[m], 1\n\t" 1185"vmseq.vx v0, v4, zero\n\t" 1186"vadd.vi v8, v8, -4, v0.t\n\t" 1187"lb zero, 0(%[q8])\n\t" 1188"vand.vx v4, v2, %[m]\n\t" 1189"slli %[m], %[m], 1\n\t" 1190"vmseq.vx v0, v4, zero\n\t" 1191"vadd.vi v10, v10, -4, v0.t\n\t" 1192"vand.vx v4, v2, %[m]\n\t" 1193"slli %[m], %[m], 1\n\t" 1194"vmseq.vx v0, v4, zero\n\t" 1195"vadd.vi v12, v12, -4, v0.t\n\t" 1196"vand.vx v4, v2, %[m]\n\t" 1197"slli %[m], %[m], 1\n\t" 1198"vmseq.vx v0, v4, zero\n\t" 1199"vadd.vi v14, v14, -4, v0.t\n\t" 1200"vsetvli zero, %[vl128], e8, m8\n\t" 1201"vle8.v v0, (%[q8])\n\t" 1202"lb %[tmp], 0(%[scale])\n\t" 1203"lb %[t1], 1(%[scale])\n\t" 1204"lb %[t2], 2(%[scale])\n\t" 1205"lb %[t3], 3(%[scale])\n\t" 1206"vsetvli zero, %[vl64], e8, m4\n\t" 1207"vwmul.vv v16, v0, v8\n\t" 1208"vwmul.vv v24, v4, v12\n\t" 1209"vsetivli zero, 16, e16, m2\n\t" 1210"vmv.v.x v0, zero\n\t" 1211"vwredsum.vs v8, v16, v0\n\t" 1212"lb %[t4], 4(%[scale])\n\t" 1213"lb %[t5], 5(%[scale])\n\t" 1214"vwredsum.vs v9, v18, v0\n\t" 1215"vwredsum.vs v10, v20, v0\n\t" 1216"vwredsum.vs v11, v22, v0\n\t" 1217"vwredsum.vs v12, v24, v0\n\t" 1218"lb %[t6], 6(%[scale])\n\t" 1219"lb %[t7], 7(%[scale])\n\t" 1220"vwredsum.vs v13, v26, v0\n\t" 1221"vwredsum.vs v14, v28, v0\n\t" 1222"vwredsum.vs v15, v30, v0\n\t" 1223"vsetivli zero, 4, e32, m1\n\t" 1224"vmul.vx v0, v8, %[tmp]\n\t" 1225"vmul.vx v1, v9, %[t1]\n\t" 1226"vmacc.vx v0, %[t2], v10\n\t" 1227"vmacc.vx v1, %[t3], v11\n\t" 1228"vmacc.vx v0, %[t4], v12\n\t" 1229"vmacc.vx v1, %[t5], v13\n\t" 1230"vmacc.vx v0, %[t6], v14\n\t" 1231"vmacc.vx v1, %[t7], v15\n\t" 1232"vmv.x.s %[tmp], v0\n\t" 1233"vmv.x.s %[t1], v1\n\t" 1234"add %[isum], %[isum], %[tmp]\n\t" 1235"add %[isum], %[isum], %[t1]" 1236 : [tmp ]"=&r" (tmp ), [t1 ]"=&r" (t1 ), [t2 ]"=&r" (t2 ), [t3 ]"=&r" (t3 ) 1237 , [t4 ]"=&r" (t4 ), [t5 ]"=&r" (t5 ), [t6 ]"=&r" (t6 ), [t7 ]"=&r" (t7 ) 1238 , [m ]"+&r" (m ), [isum ]"+&r" (isum ) 1239 : [vl128 ]"r" (128 ), [vl64 ]"r" (64 ), [vl32 ]"r" (32 ) 1240 , [q3 ]"r" (q3 ), [qh ]"r" (qh ), [scale ]"r" (scale ), [q8 ]"r" (q8 ) 1241 :"memory" 1242 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1243 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1244 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1245 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1246 ); 1247q3 += 32 ;q8 += 128 ;scale += 8 ; 1248 } 1249 1250const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1251sumf += d * isum ; 1252 } 1253 1254* s = sumf ; 1255} 1256 1257void ggml_vec_dot_q3_K_q8_K_vl256 (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 ) { 1258assert (n %QK_K == 0 ); 1259assert (nrc == 1 ); 1260UNUSED (nrc ); 1261UNUSED (bx ); 1262UNUSED (by ); 1263UNUSED (bs ); 1264 1265const uint32_t kmask1 = 0x03030303 ; 1266const uint32_t kmask2 = 0x0f0f0f0f ; 1267 1268const block_q3_K * GGML_RESTRICT x = vx ; 1269const block_q8_K * GGML_RESTRICT y = vy ; 1270 1271const int nb = n /QK_K ; 1272uint32_t utmp [4 ]; 1273float sumf = 0 ; 1274uint32_t aux [3 ]; 1275 1276for (int i = 0 ;i < nb ;++ i ) { 1277const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1278const uint8_t * GGML_RESTRICT qh = x [i ].hmask ; 1279const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1280 1281memcpy (aux ,x [i ].scales ,12 ); 1282utmp [3 ]= ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ); 1283utmp [2 ]= ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ); 1284utmp [1 ]= (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ); 1285utmp [0 ]= (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 ); 1286 1287int8_t * scale = (int8_t * )utmp ; 1288for (int j = 0 ;j < 16 ;++ j )scale [j ]-= 32 ; 1289 1290 1291size_t vl = 32 ; 1292uint8_t m = 1 ; 1293 1294vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 1295vuint8m1_t vqh = __riscv_vle8_v_u8m1 (qh ,vl ); 1296 1297int sum_t = 0 ; 1298 1299for (int j = 0 ;j < QK_K ;j += 128 ) { 1300 1301vl = 32 ; 1302 1303// load Q3 1304vuint8m1_t q3_x = __riscv_vle8_v_u8m1 (q3 ,vl ); 1305 1306vint8m1_t q3_0 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (q3_x ,0x03 ,vl )); 1307vint8m1_t q3_1 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q3_x ,0x2 ,vl ),0x03 ,vl )); 1308vint8m1_t q3_2 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q3_x ,0x4 ,vl ),0x03 ,vl )); 1309vint8m1_t q3_3 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (q3_x ,0x6 ,vl ),0x03 ,vl )); 1310 1311// compute mask for subtraction 1312vuint8m1_t qh_m0 = __riscv_vand_vx_u8m1 (vqh ,m ,vl ); 1313vbool8_t vmask_0 = __riscv_vmseq_vx_u8m1_b8 (qh_m0 ,0 ,vl ); 1314vint8m1_t q3_m0 = __riscv_vsub_vx_i8m1_mu (vmask_0 ,q3_0 ,q3_0 ,0x4 ,vl ); 1315m <<=1 ; 1316 1317vuint8m1_t qh_m1 = __riscv_vand_vx_u8m1 (vqh ,m ,vl ); 1318vbool8_t vmask_1 = __riscv_vmseq_vx_u8m1_b8 (qh_m1 ,0 ,vl ); 1319vint8m1_t q3_m1 = __riscv_vsub_vx_i8m1_mu (vmask_1 ,q3_1 ,q3_1 ,0x4 ,vl ); 1320m <<=1 ; 1321 1322vuint8m1_t qh_m2 = __riscv_vand_vx_u8m1 (vqh ,m ,vl ); 1323vbool8_t vmask_2 = __riscv_vmseq_vx_u8m1_b8 (qh_m2 ,0 ,vl ); 1324vint8m1_t q3_m2 = __riscv_vsub_vx_i8m1_mu (vmask_2 ,q3_2 ,q3_2 ,0x4 ,vl ); 1325m <<=1 ; 1326 1327vuint8m1_t qh_m3 = __riscv_vand_vx_u8m1 (vqh ,m ,vl ); 1328vbool8_t vmask_3 = __riscv_vmseq_vx_u8m1_b8 (qh_m3 ,0 ,vl ); 1329vint8m1_t q3_m3 = __riscv_vsub_vx_i8m1_mu (vmask_3 ,q3_3 ,q3_3 ,0x4 ,vl ); 1330m <<=1 ; 1331 1332// load Q8 and take product with Q3 1333vint16m2_t a0 = __riscv_vwmul_vv_i16m2 (q3_m0 ,__riscv_vle8_v_i8m1 (q8 ,vl ),vl ); 1334vint16m2_t a1 = __riscv_vwmul_vv_i16m2 (q3_m1 ,__riscv_vle8_v_i8m1 (q8 + 32 ,vl ),vl ); 1335vint16m2_t a2 = __riscv_vwmul_vv_i16m2 (q3_m2 ,__riscv_vle8_v_i8m1 (q8 + 64 ,vl ),vl ); 1336vint16m2_t a3 = __riscv_vwmul_vv_i16m2 (q3_m3 ,__riscv_vle8_v_i8m1 (q8 + 96 ,vl ),vl ); 1337 1338vl = 16 ; 1339 1340// retrieve lane to multiply with scale 1341vint32m2_t aux0_0 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a0 ,0 ), (scale [0 ]),vl ); 1342vint32m2_t aux0_1 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a0 ,1 ), (scale [1 ]),vl ); 1343vint32m2_t aux1_0 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a1 ,0 ), (scale [2 ]),vl ); 1344vint32m2_t aux1_1 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a1 ,1 ), (scale [3 ]),vl ); 1345vint32m2_t aux2_0 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a2 ,0 ), (scale [4 ]),vl ); 1346vint32m2_t aux2_1 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a2 ,1 ), (scale [5 ]),vl ); 1347vint32m2_t aux3_0 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a3 ,0 ), (scale [6 ]),vl ); 1348vint32m2_t aux3_1 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (a3 ,1 ), (scale [7 ]),vl ); 1349 1350vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (aux0_0 ,aux0_1 ,vl ),vzero ,vl ); 1351vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (aux1_0 ,aux1_1 ,vl ),isum0 ,vl ); 1352vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (aux2_0 ,aux2_1 ,vl ),isum1 ,vl ); 1353vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (aux3_0 ,aux3_1 ,vl ),isum2 ,vl ); 1354 1355sum_t += __riscv_vmv_x_s_i32m1_i32 (isum3 ); 1356 1357q3 += 32 ;q8 += 128 ;scale += 8 ; 1358 1359 } 1360 1361const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1362 1363sumf += d * sum_t ; 1364 1365 } 1366 1367* s = sumf ; 1368} 1369 1370void ggml_vec_dot_q3_K_q8_K_vl512 (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 ) { 1371assert (n %QK_K == 0 ); 1372assert (nrc == 1 ); 1373UNUSED (nrc ); 1374UNUSED (bx ); 1375UNUSED (by ); 1376UNUSED (bs ); 1377 1378const uint32_t kmask1 = 0x03030303 ; 1379const uint32_t kmask2 = 0x0f0f0f0f ; 1380 1381const block_q3_K * GGML_RESTRICT x = vx ; 1382const block_q8_K * GGML_RESTRICT y = vy ; 1383 1384const int nb = n /QK_K ; 1385 1386// mask for processing 16 elements per prod register 1387const vuint16m1_t va_index = __riscv_vid_v_u16m1 (32 ); 1388const vbool16_t va_mask = __riscv_vmsgtu_vx_u16m1_b16 (va_index ,15 ,32 ); 1389 1390uint32_t utmp [4 ]; 1391float sumf = 0 ; 1392uint32_t aux [3 ]; 1393 1394for (int i = 0 ;i < nb ;++ i ) { 1395const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1396const uint8_t * GGML_RESTRICT qh = x [i ].hmask ; 1397const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1398 1399memcpy (aux ,x [i ].scales ,12 ); 1400utmp [3 ]= ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ); 1401utmp [2 ]= ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ); 1402utmp [1 ]= (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ); 1403utmp [0 ]= (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 ); 1404 1405int8_t * scale = (int8_t * )utmp ; 1406for (int j = 0 ;j < 16 ;++ j )scale [j ]-= 32 ; 1407 1408 1409size_t vl = 32 ; 1410uint8_t m = 1 ; 1411 1412vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 1413vuint8mf2_t vqh = __riscv_vle8_v_u8mf2 (qh ,vl ); 1414 1415int sum_t = 0 ; 1416 1417vint32m2_t vaux_0 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1418vint32m2_t vaux_1 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1419vint32m2_t vaux_2 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1420vint32m2_t vaux_3 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1421 1422for (int j = 0 ;j < QK_K ;j += 128 ) { 1423 1424vl = 32 ; 1425 1426// load Q3 1427vuint8mf2_t q3_x = __riscv_vle8_v_u8mf2 (q3 ,vl ); 1428 1429vint8mf2_t q3_0 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (q3_x ,0x03 ,vl )); 1430vint8mf2_t q3_1 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (q3_x ,0x2 ,vl ),0x03 ,vl )); 1431vint8mf2_t q3_2 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (q3_x ,0x4 ,vl ),0x03 ,vl )); 1432vint8mf2_t q3_3 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (q3_x ,0x6 ,vl ),0x03 ,vl )); 1433 1434// compute mask for subtraction 1435vuint8mf2_t qh_m0 = __riscv_vand_vx_u8mf2 (vqh ,m ,vl ); 1436vbool16_t vmask_0 = __riscv_vmseq_vx_u8mf2_b16 (qh_m0 ,0 ,vl ); 1437vint8mf2_t q3_m0 = __riscv_vsub_vx_i8mf2_mu (vmask_0 ,q3_0 ,q3_0 ,0x4 ,vl ); 1438m <<=1 ; 1439 1440vuint8mf2_t qh_m1 = __riscv_vand_vx_u8mf2 (vqh ,m ,vl ); 1441vbool16_t vmask_1 = __riscv_vmseq_vx_u8mf2_b16 (qh_m1 ,0 ,vl ); 1442vint8mf2_t q3_m1 = __riscv_vsub_vx_i8mf2_mu (vmask_1 ,q3_1 ,q3_1 ,0x4 ,vl ); 1443m <<=1 ; 1444 1445vuint8mf2_t qh_m2 = __riscv_vand_vx_u8mf2 (vqh ,m ,vl ); 1446vbool16_t vmask_2 = __riscv_vmseq_vx_u8mf2_b16 (qh_m2 ,0 ,vl ); 1447vint8mf2_t q3_m2 = __riscv_vsub_vx_i8mf2_mu (vmask_2 ,q3_2 ,q3_2 ,0x4 ,vl ); 1448m <<=1 ; 1449 1450vuint8mf2_t qh_m3 = __riscv_vand_vx_u8mf2 (vqh ,m ,vl ); 1451vbool16_t vmask_3 = __riscv_vmseq_vx_u8mf2_b16 (qh_m3 ,0 ,vl ); 1452vint8mf2_t q3_m3 = __riscv_vsub_vx_i8mf2_mu (vmask_3 ,q3_3 ,q3_3 ,0x4 ,vl ); 1453m <<=1 ; 1454 1455// load Q8 and take product 1456vint16m1_t va_q_0 = __riscv_vwmul_vv_i16m1 (q3_m0 ,__riscv_vle8_v_i8mf2 (q8 ,vl ),vl ); 1457vint16m1_t va_q_1 = __riscv_vwmul_vv_i16m1 (q3_m1 ,__riscv_vle8_v_i8mf2 (q8 + 32 ,vl ),vl ); 1458vint16m1_t va_q_2 = __riscv_vwmul_vv_i16m1 (q3_m2 ,__riscv_vle8_v_i8mf2 (q8 + 64 ,vl ),vl ); 1459vint16m1_t va_q_3 = __riscv_vwmul_vv_i16m1 (q3_m3 ,__riscv_vle8_v_i8mf2 (q8 + 96 ,vl ),vl ); 1460 1461// accumulate 1462vaux_0 = __riscv_vwmacc_vx_i32m2 (vaux_0 ,scale [0 ],va_q_0 ,16 ); 1463vaux_1 = __riscv_vwmacc_vx_i32m2 (vaux_1 ,scale [2 ],va_q_1 ,16 ); 1464vaux_2 = __riscv_vwmacc_vx_i32m2 (vaux_2 ,scale [4 ],va_q_2 ,16 ); 1465vaux_3 = __riscv_vwmacc_vx_i32m2 (vaux_3 ,scale [6 ],va_q_3 ,16 ); 1466// 1467vaux_0 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_0 ,scale [1 ],va_q_0 ,vl ); 1468vaux_1 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_1 ,scale [3 ],va_q_1 ,vl ); 1469vaux_2 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_2 ,scale [5 ],va_q_2 ,vl ); 1470vaux_3 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_3 ,scale [7 ],va_q_3 ,vl ); 1471 1472q3 += 32 ;q8 += 128 ;scale += 8 ; 1473 } 1474 1475vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_0 ,vaux_1 ,vl ),vzero ,vl ); 1476vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_2 ,vaux_3 ,vl ),isum0 ,vl ); 1477 1478sum_t += __riscv_vmv_x_s_i32m1_i32 (isum1 ); 1479 1480const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1481 1482sumf += d * sum_t ; 1483 } 1484 1485* s = sumf ; 1486} 1487 1488void ggml_vec_dot_q3_K_q8_K_vl1024 (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 ) { 1489assert (n %QK_K == 0 ); 1490assert (nrc == 1 ); 1491UNUSED (nrc ); 1492UNUSED (bx ); 1493UNUSED (by ); 1494UNUSED (bs ); 1495 1496const uint32_t kmask1 = 0x03030303 ; 1497const uint32_t kmask2 = 0x0f0f0f0f ; 1498 1499const block_q3_K * GGML_RESTRICT x = vx ; 1500const block_q8_K * GGML_RESTRICT y = vy ; 1501 1502const int nb = n /QK_K ; 1503 1504// mask for processing 16 elements per prod register 1505const vuint16mf2_t va_index = __riscv_vid_v_u16mf2 (32 ); 1506const vbool32_t va_mask = __riscv_vmsgtu_vx_u16mf2_b32 (va_index ,15 ,32 ); 1507 1508uint32_t utmp [4 ]; 1509float sumf = 0 ; 1510uint32_t aux [3 ]; 1511 1512for (int i = 0 ;i < nb ;++ i ) { 1513const uint8_t * GGML_RESTRICT q3 = x [i ].qs ; 1514const uint8_t * GGML_RESTRICT qh = x [i ].hmask ; 1515const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 1516 1517memcpy (aux ,x [i ].scales ,12 ); 1518utmp [3 ]= ((aux [1 ] >>4 )& kmask2 ) | (((aux [2 ] >>6 )& kmask1 ) <<4 ); 1519utmp [2 ]= ((aux [0 ] >>4 )& kmask2 ) | (((aux [2 ] >>4 )& kmask1 ) <<4 ); 1520utmp [1 ]= (aux [1 ]& kmask2 ) | (((aux [2 ] >>2 )& kmask1 ) <<4 ); 1521utmp [0 ]= (aux [0 ]& kmask2 ) | (((aux [2 ] >>0 )& kmask1 ) <<4 ); 1522 1523int8_t * scale = (int8_t * )utmp ; 1524for (int j = 0 ;j < 16 ;++ j )scale [j ]-= 32 ; 1525 1526 1527size_t vl = 32 ; 1528uint8_t m = 1 ; 1529 1530vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 1531vuint8mf4_t vqh = __riscv_vle8_v_u8mf4 (qh ,vl ); 1532 1533int sum_t = 0 ; 1534 1535vint32m1_t vaux_0 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 1536vint32m1_t vaux_1 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 1537vint32m1_t vaux_2 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 1538vint32m1_t vaux_3 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 1539 1540for (int j = 0 ;j < QK_K ;j += 128 ) { 1541 1542vl = 32 ; 1543 1544// load Q3 1545vuint8mf4_t q3_x = __riscv_vle8_v_u8mf4 (q3 ,vl ); 1546 1547vint8mf4_t q3_0 = __riscv_vreinterpret_v_u8mf4_i8mf4 (__riscv_vand_vx_u8mf4 (q3_x ,0x03 ,vl )); 1548vint8mf4_t q3_1 = __riscv_vreinterpret_v_u8mf4_i8mf4 (__riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (q3_x ,0x2 ,vl ),0x03 ,vl )); 1549vint8mf4_t q3_2 = __riscv_vreinterpret_v_u8mf4_i8mf4 (__riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (q3_x ,0x4 ,vl ),0x03 ,vl )); 1550vint8mf4_t q3_3 = __riscv_vreinterpret_v_u8mf4_i8mf4 (__riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (q3_x ,0x6 ,vl ),0x03 ,vl )); 1551 1552// compute mask for subtraction 1553vuint8mf4_t qh_m0 = __riscv_vand_vx_u8mf4 (vqh ,m ,vl ); 1554vbool32_t vmask_0 = __riscv_vmseq_vx_u8mf4_b32 (qh_m0 ,0 ,vl ); 1555vint8mf4_t q3_m0 = __riscv_vsub_vx_i8mf4_mu (vmask_0 ,q3_0 ,q3_0 ,0x4 ,vl ); 1556m <<=1 ; 1557 1558vuint8mf4_t qh_m1 = __riscv_vand_vx_u8mf4 (vqh ,m ,vl ); 1559vbool32_t vmask_1 = __riscv_vmseq_vx_u8mf4_b32 (qh_m1 ,0 ,vl ); 1560vint8mf4_t q3_m1 = __riscv_vsub_vx_i8mf4_mu (vmask_1 ,q3_1 ,q3_1 ,0x4 ,vl ); 1561m <<=1 ; 1562 1563vuint8mf4_t qh_m2 = __riscv_vand_vx_u8mf4 (vqh ,m ,vl ); 1564vbool32_t vmask_2 = __riscv_vmseq_vx_u8mf4_b32 (qh_m2 ,0 ,vl ); 1565vint8mf4_t q3_m2 = __riscv_vsub_vx_i8mf4_mu (vmask_2 ,q3_2 ,q3_2 ,0x4 ,vl ); 1566m <<=1 ; 1567 1568vuint8mf4_t qh_m3 = __riscv_vand_vx_u8mf4 (vqh ,m ,vl ); 1569vbool32_t vmask_3 = __riscv_vmseq_vx_u8mf4_b32 (qh_m3 ,0 ,vl ); 1570vint8mf4_t q3_m3 = __riscv_vsub_vx_i8mf4_mu (vmask_3 ,q3_3 ,q3_3 ,0x4 ,vl ); 1571m <<=1 ; 1572 1573// load Q8 and take product 1574vint16mf2_t va_q_0 = __riscv_vwmul_vv_i16mf2 (q3_m0 ,__riscv_vle8_v_i8mf4 (q8 ,vl ),vl ); 1575vint16mf2_t va_q_1 = __riscv_vwmul_vv_i16mf2 (q3_m1 ,__riscv_vle8_v_i8mf4 (q8 + 32 ,vl ),vl ); 1576vint16mf2_t va_q_2 = __riscv_vwmul_vv_i16mf2 (q3_m2 ,__riscv_vle8_v_i8mf4 (q8 + 64 ,vl ),vl ); 1577vint16mf2_t va_q_3 = __riscv_vwmul_vv_i16mf2 (q3_m3 ,__riscv_vle8_v_i8mf4 (q8 + 96 ,vl ),vl ); 1578 1579// accumulate 1580vaux_0 = __riscv_vwmacc_vx_i32m1 (vaux_0 ,scale [0 ],va_q_0 ,16 ); 1581vaux_1 = __riscv_vwmacc_vx_i32m1 (vaux_1 ,scale [2 ],va_q_1 ,16 ); 1582vaux_2 = __riscv_vwmacc_vx_i32m1 (vaux_2 ,scale [4 ],va_q_2 ,16 ); 1583vaux_3 = __riscv_vwmacc_vx_i32m1 (vaux_3 ,scale [6 ],va_q_3 ,16 ); 1584// 1585vaux_0 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_0 ,scale [1 ],va_q_0 ,vl ); 1586vaux_1 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_1 ,scale [3 ],va_q_1 ,vl ); 1587vaux_2 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_2 ,scale [5 ],va_q_2 ,vl ); 1588vaux_3 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_3 ,scale [7 ],va_q_3 ,vl ); 1589 1590q3 += 32 ;q8 += 128 ;scale += 8 ; 1591 } 1592 1593vint32m1_t isum0 = __riscv_vredsum_vs_i32m1_i32m1 (__riscv_vadd_vv_i32m1 (vaux_0 ,vaux_1 ,vl ),vzero ,vl ); 1594vint32m1_t isum1 = __riscv_vredsum_vs_i32m1_i32m1 (__riscv_vadd_vv_i32m1 (vaux_2 ,vaux_3 ,vl ),isum0 ,vl ); 1595 1596sum_t += __riscv_vmv_x_s_i32m1_i32 (isum1 ); 1597 1598const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 1599 1600sumf += d * sum_t ; 1601 } 1602 1603* s = sumf ; 1604} 1605#endif 1606 1607void 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 ) { 1608#if defined__riscv_xtheadvector 1609ggml_vec_dot_q3_K_q8_K_xtheadvector (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1610#elif defined__riscv_v 1611switch (__riscv_vlenb ()* 8 ) { 1612case 128 : 1613ggml_vec_dot_q3_K_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1614break ; 1615case 256 : 1616ggml_vec_dot_q3_K_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1617break ; 1618case 512 : 1619ggml_vec_dot_q3_K_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1620break ; 1621case 1024 : 1622ggml_vec_dot_q3_K_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1623break ; 1624default : 1625ggml_vec_dot_q3_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1626break ; 1627 } 1628#else 1629ggml_vec_dot_q3_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 1630#endif 1631} 1632 1633#if defined__riscv_xtheadvector 1634static NOINLINE void ggml_vec_dot_q4_K_q8_K_xtheadvector (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 ) { 1635assert (n %QK_K == 0 ); 1636assert (nrc == 1 ); 1637UNUSED (nrc ); 1638UNUSED (bx ); 1639UNUSED (by ); 1640UNUSED (bs ); 1641 1642const block_q4_K * GGML_RESTRICT x = vx ; 1643const block_q8_K * GGML_RESTRICT y = vy ; 1644 1645const int nb = n /QK_K ; 1646 1647static const uint32_t kmask1 = 0x3f3f3f3f ; 1648static const uint32_t kmask2 = 0x0f0f0f0f ; 1649static const uint32_t kmask3 = 0x03030303 ; 1650 1651uint32_t utmp [4 ]; 1652 1653const uint8_t * scales = (const uint8_t * )& utmp [0 ]; 1654const uint8_t * mins = (const uint8_t * )& utmp [2 ]; 1655 1656float sumf = 0 ; 1657 1658for (int i = 0 ;i < nb ;++ i ) { 1659const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1660const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1661 1662int tmp ,tmp2 ,sumi ; 1663 __asm__ __volatile__( 1664"li %[t1], 12\n\t" 1665"th.vsetvli zero, %[t1], e8, m1\n\t" 1666"th.vlb.v v1, (%[s6b])\n\t" // {aux[0], aux[1], aux[2]} 1667"li %[t1], 4\n\t" 1668"th.vsetvli zero, %[t1], e32, m1\n\t" 1669"th.vslidedown.vi v2, v1, 2\n\t" 1670"th.vmv.v.v v3, v2\n\t" 1671"th.vslideup.vi v2, v3, 1\n\t" // {aux[2], aux[2]} 1672"li %[t1], 2\n\t" 1673"th.vsetvli zero, %[t1], e32, m1\n\t" 1674"th.vmv.v.i v4, 4\n\t" 1675"th.vand.vx v8, v1, %[kmask1]\n\t" 1676"th.vslide1up.vx v5, v4, zero\n\t" // {0, 4} 1677"th.vsrl.vi v6, v1, 6\n\t" 1678"th.vsrl.vv v7, v2, v5\n\t" 1679"th.vand.vx v0, v6, %[kmask3]\n\t" 1680"th.vand.vx v2, v7, %[kmask2]\n\t" 1681"th.vsll.vi v6, v0, 4\n\t" 1682"li %[t2], 8\n\t" 1683"addi %[t1], %[utmp], 4\n\t" 1684"th.vor.vv v1, v6, v2\n\t" 1685"th.vssw.v v8, (%[utmp]), %[t2]\n\t" 1686"th.vssw.v v1, (%[t1]), %[t2]\n\t" 1687"th.vsetvli zero, zero, e32, m2\n\t" // vl == 8 1688"th.vlw.v v2, (%[bsums])\n\t" 1689"th.vsetvli zero, %[t2], e16, m1\n\t" 1690"th.vnsrl.vi v0, v2, 0\n\t" 1691"th.vnsrl.vi v1, v2, 16\n\t" 1692"th.vadd.vv v2, v0, v1\n\t" 1693"th.vlbu.v v4, (%[mins])\n\t" 1694"th.vwmul.vv v6, v4, v2\n\t" 1695"th.vmv.v.x v0, zero\n\t" 1696"th.vsetvli zero, %[t2], e32, m2\n\t" 1697"th.vredsum.vs v0, v6, v0\n\t" 1698"th.vmv.x.s %[sumi], v0" 1699 : [t1 ]"=&r" (tmp ), [t2 ]"=&r" (tmp2 ), [sumi ]"=&r" (sumi ) 1700 : [bsums ]"r" (y [i ].bsums ), [mins ]"r" (mins ), [utmp ]"r" (utmp ) 1701 , [s6b ]"r" (x [i ].scales ), [kmask1 ]"r" (kmask1 ) 1702 , [kmask2 ]"r" (kmask2 ), [kmask3 ]"r" (kmask3 ) 1703 :"memory" 1704 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1705 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1706 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1707 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1708 ); 1709sumf -= dmin * sumi ; 1710 1711const uint8_t * restrictq4 = x [i ].qs ; 1712const int8_t * restrictq8 = y [i ].qs ; 1713 1714sumi = 0 ; 1715const uint8_t * scale = scales ; 1716 1717for (int j = 0 ;j < QK_K /128 ;++ j ) { 1718int vl128 = 128 ,vl64 = 64 ,vl32 = 32 ; 1719 __asm__ __volatile__( 1720"th.vsetvli zero, %[vl128], e8, m8\n\t" 1721"th.vlb.v v8, (%[q8])\n\t" 1722"th.vsetvli zero, %[vl64], e8, m4\n\t" 1723"th.vlb.v v0, (%[q4])\n\t" 1724"th.vsrl.vi v4, v0, 4\n\t" 1725"th.vand.vi v0, v0, 0xF\n\t" 1726"th.vsetvli zero, %[vl32], e8, m2\n\t" 1727"th.vwmul.vv v28, v6, v14\n\t" 1728"th.vwmul.vv v20, v4, v10\n\t" 1729"th.vwmul.vv v24, v2, v12\n\t" 1730"th.vwmul.vv v16, v0, v8\n\t" 1731"li %[tmp], 4\n\t" 1732"th.vsetvli zero, %[tmp], e32, m1\n\t" 1733"th.vlbu.v v1, (%[scale])\n\t" 1734"th.vmv.v.x v0, zero\n\t" 1735"th.vsetvli zero, %[vl32], e16, m4\n\t" 1736"th.vwredsum.vs v6, v24, v0\n\t" 1737"th.vwredsum.vs v7, v28, v0\n\t" 1738"th.vwredsum.vs v4, v16, v0\n\t" 1739"th.vwredsum.vs v5, v20, v0\n\t" 1740"th.vsetvli zero, %[tmp], e32, m1\n\t" 1741"th.vslideup.vi v6, v7, 1\n\t" 1742"th.vslideup.vi v4, v5, 1\n\t" 1743"th.vslideup.vi v4, v6, 2\n\t" 1744"th.vmul.vv v8, v4, v1\n\t" 1745"th.vredsum.vs v0, v8, v0\n\t" 1746"th.vmv.x.s %[tmp], v0\n\t" 1747"add %[sumi], %[sumi], %[tmp]" 1748 : [tmp ]"=&r" (tmp ), [sumi ]"+&r" (sumi ) 1749 : [vl128 ]"r" (vl128 ), [vl64 ]"r" (vl64 ), [vl32 ]"r" (vl32 ) 1750 , [q4 ]"r" (q4 ), [q8 ]"r" (q8 ), [scale ]"r" (scale ) 1751 :"memory" 1752 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1753 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1754 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1755 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1756 ); 1757 1758q4 += 64 ;q8 += 128 ;scale += 4 ; 1759 } 1760 1761sumf += d * sumi ; 1762 1763 } 1764 1765* s = sumf ; 1766} 1767#endif 1768 1769#if defined__riscv_v 1770static NOINLINE void ggml_vec_dot_q4_K_q8_K_vl128 (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 ) { 1771assert (n %QK_K == 0 ); 1772assert (nrc == 1 ); 1773UNUSED (nrc ); 1774UNUSED (bx ); 1775UNUSED (by ); 1776UNUSED (bs ); 1777 1778const block_q4_K * GGML_RESTRICT x = vx ; 1779const block_q8_K * GGML_RESTRICT y = vy ; 1780 1781const int nb = n /QK_K ; 1782 1783static const uint32_t kmask1 = 0x3f3f3f3f ; 1784static const uint32_t kmask2 = 0x0f0f0f0f ; 1785static const uint32_t kmask3 = 0x03030303 ; 1786 1787uint32_t utmp [4 ]; 1788 1789const uint8_t * scales = (const uint8_t * )& utmp [0 ]; 1790const uint8_t * mins = (const uint8_t * )& utmp [2 ]; 1791 1792float sumf = 0 ; 1793for (int i = 0 ;i < nb ;++ i ) { 1794const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 1795const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 1796 1797float ftmp ,ft2 ; 1798const uint8_t * restrictq40 ; 1799const uint8_t * restrictq41 ; 1800const uint8_t * restrictq42 ; 1801const uint8_t * restrictq43 ; 1802const int8_t * restrictq80 ; 1803const int8_t * restrictq81 ; 1804const int8_t * restrictq82 ; 1805const int8_t * restrictq83 ; 1806int s0 ,s1 ,s2 ,s3 ; 1807 1808 __asm__ __volatile__( 1809"li %[s1], 8\n\t" 1810"vsetivli zero, 4, e32, m1, ta, ma\n\t" 1811"vle32.v v1, (%[s6b])\n\t" 1812"vslide1down.vx v1, v1, zero\n\t" 1813"vmv.v.x v16, zero\n\t" 1814"vslidedown.vi v2, v1, 2\n\t" 1815"vmv1r.v v3, v2\n\t" 1816"vslideup.vi v2, v3, 1\n\t" // {aux[2], aux[2]} 1817"vsetivli zero, 2, e32, m1, ta, ma\n\t" 1818"vmv.v.i v4, 4\n\t" 1819"vand.vx v8, v1, %[kmask1]\n\t" 1820"vslide1up.vx v5, v4, zero\n\t" // {0, 4} 1821"vsrl.vi v6, v1, 6\n\t" 1822"vsrl.vv v7, v2, v5\n\t" 1823"vsse32.v v8, (%[utmp]), %[s1]\n\t" 1824"vand.vx v0, v6, %[kmask3]\n\t" 1825"vand.vx v2, v7, %[kmask2]\n\t" 1826"vsll.vi v6, v0, 4\n\t" 1827"addi %[s0], %[utmp], 4\n\t" 1828"vor.vv v1, v6, v2\n\t" 1829"vsse32.v v1, (%[s0]), %[s1]\n\t" 1830"vsetivli zero, 8, e16, m1, ta, ma\n\t" 1831"vle32.v v2, (%[bsums])\n\t" 1832"vnsrl.wi v0, v2, 0\n\t" 1833"vnsrl.wi v1, v2, 16\n\t" 1834"vadd.vv v2, v0, v1\n\t" 1835"vle8.v v3, (%[mins])\n\t" 1836"vzext.vf2 v4, v3\n\t" 1837"vwmul.vv v6, v4, v2\n\t" 1838"vsetivli zero, 4, e32, m1, ta, ma\n\t" 1839"vredsum.vs v0, v6, v16\n\t" 1840"vredsum.vs v0, v7, v0\n\t" 1841"vfcvt.f.x.v v0, v0\n\t" 1842"vfmv.f.s %[ftmp], v0\n\t" 1843"vsetivli zero, 16, e8, m1, ta, ma\n\t" 1844"vle8.v v0, (%[xs])\n\t" 1845"fnmsub.s %[sumf], %[dmin], %[ftmp], %[sumf]\n\t" 1846"addi %[q40], %[xs], 64\n\t" 1847"addi %[q41], %[xs], 16\n\t" 1848"addi %[q42], %[xs], 32\n\t" 1849"addi %[q43], %[xs], 48\n\t" 1850"addi %[q80], %[ys], 64\n\t" 1851"vle8.v v1, (%[q41])\n\t" 1852"vle8.v v2, (%[q42])\n\t" 1853"addi %[q81], %[ys], 16\n\t" 1854"addi %[q41], %[q41], 64\n\t" 1855"addi %[q82], %[ys], 32\n\t" 1856"vle8.v v3, (%[q43])\n\t" 1857"vle8.v v8, (%[ys])\n\t" 1858"addi %[q42], %[q42], 64\n\t" 1859"addi %[q83], %[ys], 48\n\t" 1860"addi %[q43], %[q43], 64\n\t" 1861"vsrl.vi v4, v0, 4\n\t" 1862"vle8.v v9, (%[q81])\n\t" 1863"vle8.v v10, (%[q82])\n\t" 1864"vand.vi v0, v0, 0xF\n\t" 1865"addi %[q81], %[q81], 64\n\t" 1866"vsrl.vi v5, v1, 4\n\t" 1867"addi %[q82], %[q82], 64\n\t" 1868"vle8.v v11, (%[q83])\n\t" 1869"vle8.v v12, (%[q80])\n\t" 1870"vand.vi v1, v1, 0xF\n\t" 1871"addi %[q83], %[q83], 64\n\t" 1872"vsrl.vi v6, v2, 4\n\t" 1873"addi %[q80], %[q80], 64\n\t" 1874"vle8.v v13, (%[q81])\n\t" 1875"vle8.v v14, (%[q82])\n\t" 1876"vand.vi v2, v2, 0xF\n\t" 1877"addi %[q81], %[q81], 64\n\t" 1878"vsrl.vi v7, v3, 4\n\t" 1879"addi %[q82], %[q82], 64\n\t" 1880"vwmul.vv v16, v0, v8\n\t" 1881"vle8.v v15, (%[q83])\n\t" 1882"vle8.v v0, (%[q40])\n\t" 1883"vand.vi v3, v3, 0xF\n\t" 1884"addi %[q83], %[q83], 64\n\t" 1885"vwmul.vv v24, v2, v12\n\t" 1886"vwmul.vv v20, v4, v10\n\t" 1887"vwmul.vv v28, v6, v14\n\t" 1888"vwmacc.vv v16, v1, v9\n\t" 1889"vle8.v v1, (%[q41])\n\t" 1890"vle8.v v2, (%[q42])\n\t" 1891"vwmacc.vv v24, v3, v13\n\t" 1892"vwmacc.vv v20, v5, v11\n\t" 1893"vwmacc.vv v28, v7, v15\n\t" 1894"addi %[q40], %[q80], 64\n\t" 1895"addi %[q41], %[q81], 64\n\t" 1896"vle8.v v3, (%[q43])\n\t" 1897"vle8.v v8, (%[q80])\n\t" 1898"addi %[q42], %[q82], 64\n\t" 1899"addi %[q43], %[q83], 64\n\t" 1900"vsrl.vi v4, v0, 4\n\t" 1901"vle8.v v9, (%[q81])\n\t" 1902"vle8.v v10, (%[q82])\n\t" 1903"vand.vi v0, v0, 0xF\n\t" 1904"vsrl.vi v5, v1, 4\n\t" 1905"vsrl.vi v7, v3, 4\n\t" 1906"vand.vi v3, v3, 0xF\n\t" 1907"vle8.v v11, (%[q83])\n\t" 1908"vle8.v v12, (%[q40])\n\t" 1909"vand.vi v1, v1, 0xF\n\t" 1910"vsrl.vi v6, v2, 4\n\t" 1911"vand.vi v2, v2, 0xF\n\t" 1912"vwmul.vv v18, v0, v8\n\t" 1913"vle8.v v13, (%[q41])\n\t" 1914"vle8.v v14, (%[q42])\n\t" 1915"vwmul.vv v26, v2, v12\n\t" 1916"vwmul.vv v22, v4, v10\n\t" 1917"vwmul.vv v30, v6, v14\n\t" 1918"vwmacc.vv v18, v1, v9\n\t" 1919"vle8.v v15, (%[q43])\n\t" 1920"vwmacc.vv v26, v3, v13\n\t" 1921"vwmacc.vv v22, v5, v11\n\t" 1922"vwmacc.vv v30, v7, v15\n\t" 1923"vmv.v.x v0, zero\n\t" 1924"vsetivli zero, 16, e16, m2, ta, ma\n\t" 1925"vwredsum.vs v4, v16, v0\n\t" 1926"lbu %[s0], 0(%[scale])\n\t" 1927"vwredsum.vs v5, v20, v0\n\t" 1928"lbu %[s1], 1(%[scale])\n\t" 1929"vwredsum.vs v6, v24, v0\n\t" 1930"lbu %[s2], 2(%[scale])\n\t" 1931"vwredsum.vs v7, v28, v0\n\t" 1932"lbu %[s3], 3(%[scale])\n\t" 1933"vwredsum.vs v8, v18, v0\n\t" 1934"lbu %[q40], 4(%[scale])\n\t" 1935"vwredsum.vs v9, v22, v0\n\t" 1936"lbu %[q41], 5(%[scale])\n\t" 1937"vwredsum.vs v10, v26, v0\n\t" 1938"lbu %[q42], 6(%[scale])\n\t" 1939"vwredsum.vs v11, v30, v0\n\t" 1940"lbu %[q43], 7(%[scale])\n\t" 1941"vsetivli zero, 4, e32, m1, ta, ma\n\t" 1942"vmul.vx v0, v4, %[s0]\n\t" 1943"vmul.vx v1, v8, %[q40]\n\t" 1944"vmacc.vx v0, %[s1], v5\n\t" 1945"vmacc.vx v1, %[q41], v9\n\t" 1946"vmacc.vx v0, %[s2], v6\n\t" 1947"vmacc.vx v1, %[q42], v10\n\t" 1948"vmacc.vx v0, %[s3], v7\n\t" 1949"vmacc.vx v1, %[q43], v11\n\t" 1950"vfcvt.f.x.v v0, v0\n\t" 1951"vfcvt.f.x.v v1, v1\n\t" 1952"vfmv.f.s %[ft2], v0\n\t" 1953"vfmv.f.s %[ftmp], v1\n\t" 1954"fadd.s %[ft2], %[ft2], %[ftmp]\n\t" 1955"fmadd.s %[sumf], %[d], %[ft2], %[sumf]" 1956 : [ftmp ]"=&f" (ftmp ), [sumf ]"+&f" (sumf ), [ft2 ]"=&f" (ft2 ) 1957 , [s0 ]"=&r" (s0 ), [s1 ]"=&r" (s1 ), [s2 ]"=&r" (s2 ), [s3 ]"=&r" (s3 ) 1958 , [q40 ]"=&r" (q40 ), [q41 ]"=&r" (q41 ), [q42 ]"=&r" (q42 ), [q43 ]"=&r" (q43 ) 1959 , [q80 ]"=&r" (q80 ), [q81 ]"=&r" (q81 ), [q82 ]"=&r" (q82 ), [q83 ]"=&r" (q83 ) 1960 : [d ]"f" (d ), [ys ]"r" (y [i ].qs ), [xs ]"r" (x [i ].qs ), [scale ]"r" (scales ) 1961 , [bsums ]"r" (y [i ].bsums ), [mins ]"r" (mins ), [utmp ]"r" (utmp ) 1962 , [s6b ]"r" (& x [i ]), [kmask1 ]"r" (kmask1 ), [dmin ]"f" (dmin ) 1963 , [kmask2 ]"r" (kmask2 ), [kmask3 ]"r" (kmask3 ) 1964 :"memory" 1965 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 1966 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 1967 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 1968 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 1969 ); 1970 } 1971 1972* s = sumf ; 1973} 1974 1975static NOINLINE void ggml_vec_dot_q4_K_q8_K_vl256 (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 ) { 1976assert (n %QK_K == 0 ); 1977assert (nrc == 1 ); 1978UNUSED (nrc ); 1979UNUSED (bx ); 1980UNUSED (by ); 1981UNUSED (bs ); 1982 1983const block_q4_K * GGML_RESTRICT x = vx ; 1984const block_q8_K * GGML_RESTRICT y = vy ; 1985 1986const int nb = n /QK_K ; 1987 1988static const uint32_t kmask1 = 0x3f3f3f3f ; 1989static const uint32_t kmask2 = 0x0f0f0f0f ; 1990static const uint32_t kmask3 = 0x03030303 ; 1991 1992uint32_t utmp [4 ]; 1993 1994const uint8_t * scales = (const uint8_t * )& utmp [0 ]; 1995const uint8_t * mins = (const uint8_t * )& utmp [2 ]; 1996 1997float sumf = 0 ; 1998for (int i = 0 ;i < nb ;++ i ) { 1999size_t vl = 8 ; 2000 2001const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 2002const float dmin = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].dmin ); 2003 2004vint16mf2_t q8sums_0 = __riscv_vlse16_v_i16mf2 (y [i ].bsums ,4 ,vl ); 2005vint16mf2_t q8sums_1 = __riscv_vlse16_v_i16mf2 (y [i ].bsums + 1 ,4 ,vl ); 2006vint16mf2_t q8sums = __riscv_vadd_vv_i16mf2 (q8sums_0 ,q8sums_1 ,vl ); 2007 2008memcpy (utmp ,x [i ].scales ,12 ); 2009utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2010const uint32_t uaux = utmp [1 ]& kmask1 ; 2011utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2012utmp [2 ]= uaux ; 2013utmp [0 ] &=kmask1 ; 2014 2015vuint8mf4_t mins8 = __riscv_vle8_v_u8mf4 (mins ,vl ); 2016vint16mf2_t v_mins = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vzext_vf2_u16mf2 (mins8 ,vl )); 2017vint32m1_t prod = __riscv_vwmul_vv_i32m1 (q8sums ,v_mins ,vl ); 2018 2019vint32m1_t sumi = __riscv_vredsum_vs_i32m1_i32m1 (prod ,__riscv_vmv_v_x_i32m1 (0 ,1 ),vl ); 2020sumf -= dmin * __riscv_vmv_x_s_i32m1_i32 (sumi ); 2021 2022const uint8_t * GGML_RESTRICT q4 = x [i ].qs ; 2023const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2024 2025vl = 32 ; 2026 2027int32_t sum_1 = 0 ; 2028int32_t sum_2 = 0 ; 2029 2030vint16m1_t vzero = __riscv_vmv_v_x_i16m1 (0 ,1 ); 2031 2032for (int j = 0 ;j < QK_K /64 ;++ j ) { 2033// load Q4 2034vuint8m1_t q4_x = __riscv_vle8_v_u8m1 (q4 ,vl ); 2035 2036// load Q8 and multiply it with lower Q4 nibble 2037vint8m1_t q8_0 = __riscv_vle8_v_i8m1 (q8 ,vl ); 2038vint8m1_t q4_0 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vand_vx_u8m1 (q4_x ,0x0F ,vl )); 2039vint16m2_t qv_0 = __riscv_vwmul_vv_i16m2 (q4_0 ,q8_0 ,vl ); 2040vint16m1_t vs_0 = __riscv_vredsum_vs_i16m2_i16m1 (qv_0 ,vzero ,vl ); 2041 2042sum_1 += __riscv_vmv_x_s_i16m1_i16 (vs_0 )* scales [2 * j + 0 ]; 2043 2044// load Q8 and multiply it with upper Q4 nibble 2045vint8m1_t q8_1 = __riscv_vle8_v_i8m1 (q8 + 32 ,vl ); 2046vint8m1_t q4_1 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vsrl_vx_u8m1 (q4_x ,0x04 ,vl )); 2047vint16m2_t qv_1 = __riscv_vwmul_vv_i16m2 (q4_1 ,q8_1 ,vl ); 2048vint16m1_t vs_1 = __riscv_vredsum_vs_i16m2_i16m1 (qv_1 ,vzero ,vl ); 2049 2050sum_2 += __riscv_vmv_x_s_i16m1_i16 (vs_1 )* scales [2 * j + 1 ]; 2051 2052q4 += 32 ;q8 += 64 ; 2053 2054 } 2055 2056sumf += d * (sum_1 + sum_2 ); 2057 2058 } 2059 2060* s = sumf ; 2061} 2062#endif 2063 2064void 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 ) { 2065#if defined__riscv_xtheadvector 2066ggml_vec_dot_q4_K_q8_K_xtheadvector (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2067#elif defined__riscv_v 2068switch (__riscv_vlenb ()* 8 ) { 2069case 128 : 2070ggml_vec_dot_q4_K_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2071break ; 2072default :// 256 and above 2073ggml_vec_dot_q4_K_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2074break ; 2075 } 2076#else 2077ggml_vec_dot_q4_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2078#endif 2079} 2080 2081void 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 ) { 2082assert (n %QK_K == 0 ); 2083assert (nrc == 1 ); 2084UNUSED (nrc ); 2085UNUSED (bx ); 2086UNUSED (by ); 2087UNUSED (bs ); 2088 2089const block_q5_K * GGML_RESTRICT x = vx ; 2090const block_q8_K * GGML_RESTRICT y = vy ; 2091 2092const int nb = n /QK_K ; 2093 2094static const uint32_t kmask1 = 0x3f3f3f3f ; 2095static const uint32_t kmask2 = 0x0f0f0f0f ; 2096static const uint32_t kmask3 = 0x03030303 ; 2097 2098uint32_t utmp [4 ]; 2099 2100#if defined__riscv_v 2101 2102const uint8_t * scales = (const uint8_t * )& utmp [0 ]; 2103const uint8_t * mins = (const uint8_t * )& utmp [2 ]; 2104 2105float sumf = 0 ; 2106float sums = 0.0 ; 2107 2108size_t vl ; 2109 2110for (int i = 0 ;i < nb ;++ i ) { 2111 2112vl = 8 ; 2113 2114const uint8_t * GGML_RESTRICT q5 = x [i ].qs ; 2115const uint8_t * GGML_RESTRICT hm = x [i ].qh ; 2116const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2117 2118const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2119const float dmin = GGML_CPU_FP16_TO_FP32 (x [i ].dmin )* y [i ].d ; 2120 2121vint16m1_t q8sums_0 = __riscv_vlse16_v_i16m1 (y [i ].bsums ,4 ,vl ); 2122vint16m1_t q8sums_1 = __riscv_vlse16_v_i16m1 (y [i ].bsums + 1 ,4 ,vl ); 2123vint16m1_t q8sums = __riscv_vadd_vv_i16m1 (q8sums_0 ,q8sums_1 ,vl ); 2124 2125memcpy (utmp ,x [i ].scales ,12 ); 2126utmp [3 ]= ((utmp [2 ] >>4 )& kmask2 ) | (((utmp [1 ] >>6 )& kmask3 ) <<4 ); 2127const uint32_t uaux = utmp [1 ]& kmask1 ; 2128utmp [1 ]= (utmp [2 ]& kmask2 ) | (((utmp [0 ] >>6 )& kmask3 ) <<4 ); 2129utmp [2 ]= uaux ; 2130utmp [0 ] &=kmask1 ; 2131 2132vuint8mf2_t mins8 = __riscv_vle8_v_u8mf2 (mins ,vl ); 2133vint16m1_t v_mins = __riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (mins8 ,vl )); 2134vint32m2_t prod = __riscv_vwmul_vv_i32m2 (q8sums ,v_mins ,vl ); 2135 2136vint32m1_t sumi = __riscv_vredsum_vs_i32m2_i32m1 (prod ,__riscv_vmv_v_x_i32m1 (0 ,1 ),vl ); 2137sumf -= dmin * __riscv_vmv_x_s_i32m1_i32 (sumi ); 2138 2139vl = 32 ; 2140int32_t aux32 = 0 ; 2141int is = 0 ; 2142 2143uint8_t m = 1 ; 2144vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2145vuint8m2_t vqh = __riscv_vle8_v_u8m2 (hm ,vl ); 2146 2147for (int j = 0 ;j < QK_K /64 ;++ j ) { 2148// load Q5 and Q8 2149vuint8m2_t q5_x = __riscv_vle8_v_u8m2 (q5 ,vl ); 2150vint8m2_t q8_y1 = __riscv_vle8_v_i8m2 (q8 ,vl ); 2151vint8m2_t q8_y2 = __riscv_vle8_v_i8m2 (q8 + 32 ,vl ); 2152 2153// compute mask for addition 2154vint8m2_t q5_a = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vand_vx_u8m2 (q5_x ,0x0F ,vl )); 2155vuint8m2_t qh_m1 = __riscv_vand_vx_u8m2 (vqh ,m ,vl ); 2156vbool4_t vmask_1 = __riscv_vmsne_vx_u8m2_b4 (qh_m1 ,0 ,vl ); 2157vint8m2_t q5_m1 = __riscv_vadd_vx_i8m2_mu (vmask_1 ,q5_a ,q5_a ,16 ,vl ); 2158m <<=1 ; 2159 2160vint8m2_t q5_l = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vsrl_vx_u8m2 (q5_x ,0x04 ,vl )); 2161vuint8m2_t qh_m2 = __riscv_vand_vx_u8m2 (vqh ,m ,vl ); 2162vbool4_t vmask_2 = __riscv_vmsne_vx_u8m2_b4 (qh_m2 ,0 ,vl ); 2163vint8m2_t q5_m2 = __riscv_vadd_vx_i8m2_mu (vmask_2 ,q5_l ,q5_l ,16 ,vl ); 2164m <<=1 ; 2165 2166vint16m4_t v0 = __riscv_vwmul_vv_i16m4 (q5_m1 ,q8_y1 ,vl ); 2167vint16m4_t v1 = __riscv_vwmul_vv_i16m4 (q5_m2 ,q8_y2 ,vl ); 2168 2169vint32m8_t vs1 = __riscv_vwmul_vx_i32m8 (v0 ,scales [is ++ ],vl ); 2170vint32m8_t vs2 = __riscv_vwmul_vx_i32m8 (v1 ,scales [is ++ ],vl ); 2171 2172vint32m1_t vacc1 = __riscv_vredsum_vs_i32m8_i32m1 (vs1 ,vzero ,vl ); 2173vint32m1_t vacc2 = __riscv_vredsum_vs_i32m8_i32m1 (vs2 ,vacc1 ,vl ); 2174 2175aux32 += __riscv_vmv_x_s_i32m1_i32 (vacc2 ); 2176q5 += 32 ;q8 += 64 ; 2177 } 2178 2179sums += aux32 * d ; 2180 2181 } 2182 2183* s = sumf + sums ; 2184 2185#else 2186 2187UNUSED (x ); 2188UNUSED (y ); 2189UNUSED (kmask1 ); 2190UNUSED (kmask2 ); 2191UNUSED (kmask3 ); 2192UNUSED (nb ); 2193UNUSED (utmp ); 2194 2195ggml_vec_dot_q5_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2196#endif 2197} 2198 2199#if defined__riscv_xtheadvector 2200static NOINLINE void ggml_vec_dot_q6_K_q8_K_xtheadvector (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 ) { 2201assert (n %QK_K == 0 ); 2202assert (nrc == 1 ); 2203UNUSED (nrc ); 2204UNUSED (bx ); 2205UNUSED (by ); 2206UNUSED (bs ); 2207 2208const block_q6_K * GGML_RESTRICT x = vx ; 2209const block_q8_K * GGML_RESTRICT y = vy ; 2210 2211const int nb = n /QK_K ; 2212 2213float sumf = 0 ; 2214 2215for (int i = 0 ;i < nb ;++ i ) { 2216 2217const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2218 2219const uint8_t * restrictq6 = x [i ].ql ; 2220const uint8_t * restrictqh = x [i ].qh ; 2221const int8_t * restrictq8 = y [i ].qs ; 2222 2223const int8_t * restrictscale = x [i ].scales ; 2224 2225int sum_t = 0 ; 2226int t0 ; 2227 2228for (int j = 0 ;j < QK_K /128 ;++ j ) { 2229 __asm__ __volatile__( 2230"th.vsetvli zero, %[vl32], e8, m2\n\t" // vl == 32 2231"th.vlb.v v4, (%[qh])\n\t" 2232"th.vsll.vi v0, v4, 4\n\t" 2233"th.vsll.vi v2, v4, 2\n\t" 2234"th.vsrl.vi v6, v4, 2\n\t" 2235"th.vsetvli zero, %[vl64], e8, m4\n\t" // vl == 64 2236"th.vlb.v v8, (%[q6])\n\t" 2237"th.vsrl.vi v12, v8, 4\n\t" 2238"th.vand.vi v8, v8, 0xF\n\t" 2239"th.vsetvli zero, %[vl128], e8, m8\n\t" // vl == 128 2240"th.vand.vx v0, v0, %[mask]\n\t" 2241"th.vor.vv v8, v8, v0\n\t" 2242"th.vlb.v v0, (%[q8])\n\t" 2243"th.vsub.vx v8, v8, %[vl32]\n\t" 2244"th.vsetvli zero, %[vl64], e8, m4\n\t" // vl == 64 2245"th.vwmul.vv v16, v0, v8\n\t" 2246"th.vwmul.vv v24, v4, v12\n\t" 2247"li %[t0], 16\n\t" 2248"th.vsetvli zero, %[t0], e16, m2\n\t" // vl == 16 2249"th.vmv.v.x v0, zero\n\t" 2250"th.vwredsum.vs v10, v16, v0\n\t" 2251"th.vwredsum.vs v9, v18, v0\n\t" 2252"th.vwredsum.vs v8, v20, v0\n\t" 2253"th.vwredsum.vs v7, v22, v0\n\t" 2254"th.vwredsum.vs v11, v24, v0\n\t" 2255"th.vwredsum.vs v12, v26, v0\n\t" 2256"th.vwredsum.vs v13, v28, v0\n\t" 2257"th.vwredsum.vs v14, v30, v0\n\t" 2258"li %[t0], 4\n\t" 2259"th.vsetvli zero, %[t0], e32, m1\n\t" // vl == 4 2260"th.vslideup.vi v10, v9, 1\n\t" 2261"th.vslideup.vi v8, v7, 1\n\t" 2262"th.vslideup.vi v11, v12, 1\n\t" 2263"th.vslideup.vi v13, v14, 1\n\t" 2264"th.vslideup.vi v10, v8, 2\n\t" 2265"th.vslideup.vi v11, v13, 2\n\t" 2266"li %[t0], 8\n\t" 2267"th.vsetvli zero, %[t0], e32, m2\n\t" // vl == 8 2268"th.vlb.v v4, (%[scale])\n\t" 2269"th.vmul.vv v2, v4, v10\n\t" 2270"th.vredsum.vs v0, v2, v0\n\t" 2271"th.vmv.x.s %[t0], v0\n\t" 2272"add %[sumi], %[sumi], %[t0]" 2273 : [sumi ]"+&r" (sum_t ), [t0 ]"=&r" (t0 ) 2274 : [qh ]"r" (qh ), [q6 ]"r" (q6 ), [q8 ]"r" (q8 ), [scale ]"r" (scale ) 2275 , [vl32 ]"r" (32 ), [vl64 ]"r" (64 ), [vl128 ]"r" (128 ) 2276 , [mask ]"r" (0x30 ) 2277 :"memory" 2278 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 2279 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 2280 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 2281 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 2282 ); 2283q6 += 64 ;qh += 32 ;q8 += 128 ;scale += 8 ; 2284 } 2285 2286sumf += d * sum_t ; 2287 2288 } 2289 2290* s = sumf ; 2291} 2292#endif 2293 2294#if defined__riscv_v 2295static NOINLINE void ggml_vec_dot_q6_K_q8_K_vl128 (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 ) { 2296assert (n %QK_K == 0 ); 2297assert (nrc == 1 ); 2298UNUSED (nrc ); 2299UNUSED (bx ); 2300UNUSED (by ); 2301UNUSED (bs ); 2302 2303const block_q6_K * GGML_RESTRICT x = vx ; 2304const block_q8_K * GGML_RESTRICT y = vy ; 2305 2306const int nb = n /QK_K ; 2307 2308float sumf = 0.0f ; 2309for (int i = 0 ;i < nb ;++ i ) { 2310__builtin_prefetch (& x [i + 1 ].d ,0 ,1 ); 2311 2312const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2313 2314const uint8_t * restrictq6 = x [i ].ql ; 2315const uint8_t * restrictqh = x [i ].qh ; 2316const int8_t * restrictq8 = y [i ].qs ; 2317 2318const int8_t * restrictscale = x [i ].scales ; 2319 2320int q6h ; 2321float ftmp ; 2322 2323for (int j = 0 ;j < QK_K /128 ;++ j ) { 2324 __asm__ __volatile__( 2325"addi %[q6h], %[q6], 32\n\t" 2326"ld t0, 0(%[scale])\n\t" 2327"addi %[scale], %[scale], 8\n\t" 2328"slli t6, t0, 1 * 8\n\t" 2329"lb zero, 0(%[q6])\n\t" 2330"slli t5, t0, 2 * 8\n\t" 2331"slli t4, t0, 3 * 8\n\t" 2332"lb zero, 0(%[q6h])\n\t" 2333"slli t3, t0, 4 * 8\n\t" 2334"slli t2, t0, 5 * 8\n\t" 2335"lb zero, 0(%[qh])\n\t" 2336"lb zero, 31(%[q6h])\n\t" 2337"slli t1, t0, 6 * 8\n\t" 2338"srai a7, t0, 56\n\t" 2339"vsetvli zero, %[vl32], e8, m2\n\t" 2340"vle8.v v8, (%[q6])\n\t" 2341"srai t6, t6, 56\n\t" 2342"srai t5, t5, 56\n\t" 2343"srai t4, t4, 56\n\t" 2344"srai t3, t3, 56\n\t" 2345"vle8.v v10, (%[q6h])\n\t" 2346"addi %[q6], %[q6], 64\n\t" 2347"slli t0, t0, 7 * 8\n\t" 2348"srai t2, t2, 56\n\t" 2349"srai t1, t1, 56\n\t" 2350"srai t0, t0, 56\n\t" 2351"vle8.v v4, (%[qh])\n\t" 2352"vsrl.vi v12, v8, 4\n\t" 2353"vsrl.vi v14, v10, 4\n\t" 2354"lb zero, 0(%[q8])\n\t" 2355"vand.vi v8, v8, 0xF\n\t" 2356"vand.vi v10, v10, 0xF\n\t" 2357"lb zero, 32(%[q8])\n\t" 2358"vsll.vi v0, v4, 4\n\t" 2359"vsll.vi v2, v4, 2\n\t" 2360"lb zero, 64(%[q8])\n\t" 2361"vsrl.vi v6, v4, 2\n\t" 2362"vand.vx v0, v0, %[mask]\n\t" 2363"lb zero, 96(%[q8])\n\t" 2364"vand.vx v2, v2, %[mask]\n\t" 2365"vand.vx v4, v4, %[mask]\n\t" 2366"vand.vx v6, v6, %[mask]\n\t" 2367"vor.vv v8, v8, v0\n\t" 2368"lb zero, 127(%[q8])\n\t" 2369"vor.vv v10, v10, v2\n\t" 2370"vor.vv v12, v12, v4\n\t" 2371"vor.vv v14, v14, v6\n\t" 2372"vsetvli zero, %[vl128], e8, m8\n\t" 2373"vle8.v v0, (%[q8])\n\t" 2374"vsub.vx v8, v8, %[vl32]\n\t" 2375"vsetvli zero, %[vl64], e8, m4\n\t" 2376"vwmul.vv v16, v0, v8\n\t" 2377"vwmul.vv v24, v4, v12\n\t" 2378"vsetivli zero, 16, e16, m2\n\t" 2379"vmv.v.x v0, zero\n\t" 2380"vwredsum.vs v10, v16, v0\n\t" 2381"vwredsum.vs v9, v18, v0\n\t" 2382"vwredsum.vs v8, v20, v0\n\t" 2383"vwredsum.vs v7, v22, v0\n\t" 2384"vwredsum.vs v11, v24, v0\n\t" 2385"vwredsum.vs v12, v26, v0\n\t" 2386"vwredsum.vs v13, v28, v0\n\t" 2387"vwredsum.vs v14, v30, v0\n\t" 2388"vsetivli zero, 4, e32, m1\n\t" 2389"vmul.vx v0, v10, t0\n\t" 2390"vmul.vx v1, v9, t1\n\t" 2391"vmacc.vx v0, t2, v8\n\t" 2392"vmacc.vx v1, t3, v7\n\t" 2393"vmacc.vx v0, t4, v11\n\t" 2394"vmacc.vx v1, t5, v12\n\t" 2395"vmacc.vx v0, t6, v13\n\t" 2396"vmacc.vx v1, a7, v14\n\t" 2397"vadd.vv v0, v0, v1\n\t" 2398"vfcvt.f.x.v v0, v0\n\t" 2399"vfmv.f.s %[ftmp], v0\n\t" 2400"fmadd.s %[sumf], %[d], %[ftmp], %[sumf]" 2401 : [q6 ]"+&r" (q6 ), [q6h ]"=&r" (q6h ) 2402 , [scale ]"+&r" (scale ) 2403 , [sumf ]"+&f" (sumf ), [ftmp ]"=&f" (ftmp ) 2404 : [qh ]"r" (qh ), [q8 ]"r" (q8 ) 2405 , [vl32 ]"r" (32 ), [vl64 ]"r" (64 ), [vl128 ]"r" (128 ) 2406 , [mask ]"r" (0x30 ), [d ]"f" (d ) 2407 :"memory" 2408 ,"v0" ,"v1" ,"v2" ,"v3" ,"v4" ,"v5" ,"v6" ,"v7" 2409 ,"v8" ,"v9" ,"v10" ,"v11" ,"v12" ,"v13" ,"v14" ,"v15" 2410 ,"v16" ,"v17" ,"v18" ,"v19" ,"v20" ,"v21" ,"v22" ,"v23" 2411 ,"v24" ,"v25" ,"v26" ,"v27" ,"v28" ,"v29" ,"v30" ,"v31" 2412 ,"t0" ,"t1" ,"t2" ,"t3" ,"t4" ,"t5" ,"t6" ,"a7" 2413 ,"a6" ,"a5" ,"a4" ,"a3" 2414 ); 2415qh += 32 ;q8 += 128 ; 2416 } 2417 } 2418 2419* s = sumf ; 2420} 2421 2422static NOINLINE void ggml_vec_dot_q6_K_q8_K_vl256 (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 ) { 2423assert (n %QK_K == 0 ); 2424assert (nrc == 1 ); 2425UNUSED (nrc ); 2426UNUSED (bx ); 2427UNUSED (by ); 2428UNUSED (bs ); 2429 2430const block_q6_K * GGML_RESTRICT x = vx ; 2431const block_q8_K * GGML_RESTRICT y = vy ; 2432 2433const int nb = n /QK_K ; 2434 2435float sumf = 0 ; 2436for (int i = 0 ;i < nb ;++ i ) { 2437const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2438 2439const uint8_t * GGML_RESTRICT q6 = x [i ].ql ; 2440const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2441const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2442 2443const int8_t * GGML_RESTRICT scale = x [i ].scales ; 2444 2445size_t vl ; 2446 2447vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2448 2449int sum_t = 0 ; 2450int is = 0 ; 2451 2452for (int j = 0 ;j < QK_K /128 ;++ j ) { 2453 2454vl = 32 ; 2455 2456// load qh 2457vuint8m1_t qh_x = __riscv_vle8_v_u8m1 (qh ,vl ); 2458 2459// load Q6 2460vuint8m1_t q6_0 = __riscv_vle8_v_u8m1 (q6 ,vl ); 2461vuint8m1_t q6_1 = __riscv_vle8_v_u8m1 (q6 + 32 ,vl ); 2462 2463vuint8m1_t q6a_0 = __riscv_vand_vx_u8m1 (q6_0 ,0x0F ,vl ); 2464vuint8m1_t q6a_1 = __riscv_vand_vx_u8m1 (q6_1 ,0x0F ,vl ); 2465vuint8m1_t q6s_0 = __riscv_vsrl_vx_u8m1 (q6_0 ,0x04 ,vl ); 2466vuint8m1_t q6s_1 = __riscv_vsrl_vx_u8m1 (q6_1 ,0x04 ,vl ); 2467 2468vuint8m1_t qh_0 = __riscv_vand_vx_u8m1 (qh_x ,0x03 ,vl ); 2469vuint8m1_t qh_1 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (qh_x ,0x2 ,vl ),0x03 ,vl ); 2470vuint8m1_t qh_2 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (qh_x ,0x4 ,vl ),0x03 ,vl ); 2471vuint8m1_t qh_3 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (qh_x ,0x6 ,vl ),0x03 ,vl ); 2472 2473vuint8m1_t qhi_0 = __riscv_vor_vv_u8m1 (q6a_0 ,__riscv_vsll_vx_u8m1 (qh_0 ,0x04 ,vl ),vl ); 2474vuint8m1_t qhi_1 = __riscv_vor_vv_u8m1 (q6a_1 ,__riscv_vsll_vx_u8m1 (qh_1 ,0x04 ,vl ),vl ); 2475vuint8m1_t qhi_2 = __riscv_vor_vv_u8m1 (q6s_0 ,__riscv_vsll_vx_u8m1 (qh_2 ,0x04 ,vl ),vl ); 2476vuint8m1_t qhi_3 = __riscv_vor_vv_u8m1 (q6s_1 ,__riscv_vsll_vx_u8m1 (qh_3 ,0x04 ,vl ),vl ); 2477 2478vint8m1_t a_0 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (qhi_0 ),32 ,vl ); 2479vint8m1_t a_1 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (qhi_1 ),32 ,vl ); 2480vint8m1_t a_2 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (qhi_2 ),32 ,vl ); 2481vint8m1_t a_3 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (qhi_3 ),32 ,vl ); 2482 2483// load Q8 and take product 2484vint16m2_t va_q_0 = __riscv_vwmul_vv_i16m2 (a_0 ,__riscv_vle8_v_i8m1 (q8 ,vl ),vl ); 2485vint16m2_t va_q_1 = __riscv_vwmul_vv_i16m2 (a_1 ,__riscv_vle8_v_i8m1 (q8 + 32 ,vl ),vl ); 2486vint16m2_t va_q_2 = __riscv_vwmul_vv_i16m2 (a_2 ,__riscv_vle8_v_i8m1 (q8 + 64 ,vl ),vl ); 2487vint16m2_t va_q_3 = __riscv_vwmul_vv_i16m2 (a_3 ,__riscv_vle8_v_i8m1 (q8 + 96 ,vl ),vl ); 2488 2489vl = 16 ; 2490 2491vint32m2_t vaux_0 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_0 ,0 ),scale [is + 0 ],vl ); 2492vint32m2_t vaux_1 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_0 ,1 ),scale [is + 1 ],vl ); 2493vint32m2_t vaux_2 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_1 ,0 ),scale [is + 2 ],vl ); 2494vint32m2_t vaux_3 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_1 ,1 ),scale [is + 3 ],vl ); 2495vint32m2_t vaux_4 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_2 ,0 ),scale [is + 4 ],vl ); 2496vint32m2_t vaux_5 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_2 ,1 ),scale [is + 5 ],vl ); 2497vint32m2_t vaux_6 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_3 ,0 ),scale [is + 6 ],vl ); 2498vint32m2_t vaux_7 = __riscv_vwmul_vx_i32m2 (__riscv_vget_v_i16m2_i16m1 (va_q_3 ,1 ),scale [is + 7 ],vl ); 2499 2500vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_0 ,vaux_1 ,vl ),vzero ,vl ); 2501vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_2 ,vaux_3 ,vl ),isum0 ,vl ); 2502vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_4 ,vaux_5 ,vl ),isum1 ,vl ); 2503vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_6 ,vaux_7 ,vl ),isum2 ,vl ); 2504 2505sum_t += __riscv_vmv_x_s_i32m1_i32 (isum3 ); 2506 2507q6 += 64 ;qh += 32 ;q8 += 128 ;is = 8 ; 2508 2509 } 2510 2511sumf += d * sum_t ; 2512 2513 } 2514 2515* s = sumf ; 2516} 2517 2518static NOINLINE void ggml_vec_dot_q6_K_q8_K_vl512 (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 ) { 2519assert (n %QK_K == 0 ); 2520assert (nrc == 1 ); 2521UNUSED (nrc ); 2522UNUSED (bx ); 2523UNUSED (by ); 2524UNUSED (bs ); 2525 2526const block_q6_K * GGML_RESTRICT x = vx ; 2527const block_q8_K * GGML_RESTRICT y = vy ; 2528 2529const int nb = n /QK_K ; 2530 2531// mask for processing 16 elements per prod register 2532const vuint16m1_t va_index = __riscv_vid_v_u16m1 (32 ); 2533const vbool16_t va_mask = __riscv_vmsgtu_vx_u16m1_b16 (va_index ,15 ,32 ); 2534 2535float sumf = 0 ; 2536 2537for (int i = 0 ;i < nb ;++ i ) { 2538const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2539 2540const uint8_t * GGML_RESTRICT q6 = x [i ].ql ; 2541const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2542const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2543 2544const int8_t * GGML_RESTRICT scale = x [i ].scales ; 2545 2546size_t vl = 32 ; 2547 2548vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2549 2550int sum_t = 0 ; 2551int is = 0 ; 2552 2553vint32m2_t vaux_0 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 2554vint32m2_t vaux_1 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 2555vint32m2_t vaux_2 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 2556vint32m2_t vaux_3 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 2557 2558for (int j = 0 ;j < QK_K /128 ;++ j ) { 2559// load qh 2560vuint8mf2_t qh_x = __riscv_vle8_v_u8mf2 (qh ,vl ); 2561 2562// load Q6 2563vuint8mf2_t q6_0 = __riscv_vle8_v_u8mf2 (q6 ,vl ); 2564vuint8mf2_t q6_1 = __riscv_vle8_v_u8mf2 (q6 + 32 ,vl ); 2565 2566vuint8mf2_t q6a_0 = __riscv_vand_vx_u8mf2 (q6_0 ,0x0F ,vl ); 2567vuint8mf2_t q6a_1 = __riscv_vand_vx_u8mf2 (q6_1 ,0x0F ,vl ); 2568vuint8mf2_t q6s_0 = __riscv_vsrl_vx_u8mf2 (q6_0 ,0x04 ,vl ); 2569vuint8mf2_t q6s_1 = __riscv_vsrl_vx_u8mf2 (q6_1 ,0x04 ,vl ); 2570 2571vuint8mf2_t qh_0 = __riscv_vand_vx_u8mf2 (qh_x ,0x03 ,vl ); 2572vuint8mf2_t qh_1 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (qh_x ,0x2 ,vl ),0x03 ,vl ); 2573vuint8mf2_t qh_2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (qh_x ,0x4 ,vl ),0x03 ,vl ); 2574vuint8mf2_t qh_3 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (qh_x ,0x6 ,vl ),0x03 ,vl ); 2575 2576vuint8mf2_t qhi_0 = __riscv_vor_vv_u8mf2 (q6a_0 ,__riscv_vsll_vx_u8mf2 (qh_0 ,0x04 ,vl ),vl ); 2577vuint8mf2_t qhi_1 = __riscv_vor_vv_u8mf2 (q6a_1 ,__riscv_vsll_vx_u8mf2 (qh_1 ,0x04 ,vl ),vl ); 2578vuint8mf2_t qhi_2 = __riscv_vor_vv_u8mf2 (q6s_0 ,__riscv_vsll_vx_u8mf2 (qh_2 ,0x04 ,vl ),vl ); 2579vuint8mf2_t qhi_3 = __riscv_vor_vv_u8mf2 (q6s_1 ,__riscv_vsll_vx_u8mf2 (qh_3 ,0x04 ,vl ),vl ); 2580 2581vint8mf2_t a_0 = __riscv_vsub_vx_i8mf2 (__riscv_vreinterpret_v_u8mf2_i8mf2 (qhi_0 ),32 ,vl ); 2582vint8mf2_t a_1 = __riscv_vsub_vx_i8mf2 (__riscv_vreinterpret_v_u8mf2_i8mf2 (qhi_1 ),32 ,vl ); 2583vint8mf2_t a_2 = __riscv_vsub_vx_i8mf2 (__riscv_vreinterpret_v_u8mf2_i8mf2 (qhi_2 ),32 ,vl ); 2584vint8mf2_t a_3 = __riscv_vsub_vx_i8mf2 (__riscv_vreinterpret_v_u8mf2_i8mf2 (qhi_3 ),32 ,vl ); 2585 2586// load Q8 and take product 2587vint16m1_t va_q_0 = __riscv_vwmul_vv_i16m1 (a_0 ,__riscv_vle8_v_i8mf2 (q8 ,vl ),vl ); 2588vint16m1_t va_q_1 = __riscv_vwmul_vv_i16m1 (a_1 ,__riscv_vle8_v_i8mf2 (q8 + 32 ,vl ),vl ); 2589vint16m1_t va_q_2 = __riscv_vwmul_vv_i16m1 (a_2 ,__riscv_vle8_v_i8mf2 (q8 + 64 ,vl ),vl ); 2590vint16m1_t va_q_3 = __riscv_vwmul_vv_i16m1 (a_3 ,__riscv_vle8_v_i8mf2 (q8 + 96 ,vl ),vl ); 2591 2592// accumulate 2593vaux_0 = __riscv_vwmacc_vx_i32m2 (vaux_0 ,scale [is + 0 ],va_q_0 ,16 ); 2594vaux_1 = __riscv_vwmacc_vx_i32m2 (vaux_1 ,scale [is + 2 ],va_q_1 ,16 ); 2595vaux_2 = __riscv_vwmacc_vx_i32m2 (vaux_2 ,scale [is + 4 ],va_q_2 ,16 ); 2596vaux_3 = __riscv_vwmacc_vx_i32m2 (vaux_3 ,scale [is + 6 ],va_q_3 ,16 ); 2597// 2598vaux_0 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_0 ,scale [is + 1 ],va_q_0 ,vl ); 2599vaux_1 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_1 ,scale [is + 3 ],va_q_1 ,vl ); 2600vaux_2 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_2 ,scale [is + 5 ],va_q_2 ,vl ); 2601vaux_3 = __riscv_vwmacc_vx_i32m2_m (va_mask ,vaux_3 ,scale [is + 7 ],va_q_3 ,vl ); 2602 2603q6 += 64 ;qh += 32 ;q8 += 128 ;is = 8 ; 2604 } 2605 2606vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_0 ,vaux_1 ,vl ),vzero ,vl ); 2607vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1 (__riscv_vadd_vv_i32m2 (vaux_2 ,vaux_3 ,vl ),isum0 ,vl ); 2608 2609sum_t += __riscv_vmv_x_s_i32m1_i32 (isum1 ); 2610 2611sumf += d * sum_t ; 2612 2613 } 2614 2615* s = sumf ; 2616} 2617 2618static NOINLINE void ggml_vec_dot_q6_K_q8_K_vl1024 (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 ) { 2619assert (n %QK_K == 0 ); 2620assert (nrc == 1 ); 2621UNUSED (nrc ); 2622UNUSED (bx ); 2623UNUSED (by ); 2624UNUSED (bs ); 2625 2626const block_q6_K * GGML_RESTRICT x = vx ; 2627const block_q8_K * GGML_RESTRICT y = vy ; 2628 2629const int nb = n /QK_K ; 2630 2631// mask for processing 16 elements per prod register 2632const vuint16mf2_t va_index = __riscv_vid_v_u16mf2 (32 ); 2633const vbool32_t va_mask = __riscv_vmsgtu_vx_u16mf2_b32 (va_index ,15 ,32 ); 2634 2635float sumf = 0 ; 2636 2637for (int i = 0 ;i < nb ;++ i ) { 2638const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 2639 2640const uint8_t * GGML_RESTRICT q6 = x [i ].ql ; 2641const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 2642const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 2643 2644const int8_t * GGML_RESTRICT scale = x [i ].scales ; 2645 2646size_t vl = 32 ; 2647 2648vint32m1_t vzero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2649 2650int sum_t = 0 ; 2651int is = 0 ; 2652 2653vint32m1_t vaux_0 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 2654vint32m1_t vaux_1 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 2655vint32m1_t vaux_2 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 2656vint32m1_t vaux_3 = __riscv_vmv_v_x_i32m1 (0 ,vl ); 2657 2658for (int j = 0 ;j < QK_K /128 ;++ j ) { 2659// load qh 2660vuint8mf4_t qh_x = __riscv_vle8_v_u8mf4 (qh ,vl ); 2661 2662// load Q6 2663vuint8mf4_t q6_0 = __riscv_vle8_v_u8mf4 (q6 ,vl ); 2664vuint8mf4_t q6_1 = __riscv_vle8_v_u8mf4 (q6 + 32 ,vl ); 2665 2666vuint8mf4_t q6a_0 = __riscv_vand_vx_u8mf4 (q6_0 ,0x0F ,vl ); 2667vuint8mf4_t q6a_1 = __riscv_vand_vx_u8mf4 (q6_1 ,0x0F ,vl ); 2668vuint8mf4_t q6s_0 = __riscv_vsrl_vx_u8mf4 (q6_0 ,0x04 ,vl ); 2669vuint8mf4_t q6s_1 = __riscv_vsrl_vx_u8mf4 (q6_1 ,0x04 ,vl ); 2670 2671vuint8mf4_t qh_0 = __riscv_vand_vx_u8mf4 (qh_x ,0x03 ,vl ); 2672vuint8mf4_t qh_1 = __riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (qh_x ,0x2 ,vl ),0x03 ,vl ); 2673vuint8mf4_t qh_2 = __riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (qh_x ,0x4 ,vl ),0x03 ,vl ); 2674vuint8mf4_t qh_3 = __riscv_vand_vx_u8mf4 (__riscv_vsrl_vx_u8mf4 (qh_x ,0x6 ,vl ),0x03 ,vl ); 2675 2676vuint8mf4_t qhi_0 = __riscv_vor_vv_u8mf4 (q6a_0 ,__riscv_vsll_vx_u8mf4 (qh_0 ,0x04 ,vl ),vl ); 2677vuint8mf4_t qhi_1 = __riscv_vor_vv_u8mf4 (q6a_1 ,__riscv_vsll_vx_u8mf4 (qh_1 ,0x04 ,vl ),vl ); 2678vuint8mf4_t qhi_2 = __riscv_vor_vv_u8mf4 (q6s_0 ,__riscv_vsll_vx_u8mf4 (qh_2 ,0x04 ,vl ),vl ); 2679vuint8mf4_t qhi_3 = __riscv_vor_vv_u8mf4 (q6s_1 ,__riscv_vsll_vx_u8mf4 (qh_3 ,0x04 ,vl ),vl ); 2680 2681vint8mf4_t a_0 = __riscv_vsub_vx_i8mf4 (__riscv_vreinterpret_v_u8mf4_i8mf4 (qhi_0 ),32 ,vl ); 2682vint8mf4_t a_1 = __riscv_vsub_vx_i8mf4 (__riscv_vreinterpret_v_u8mf4_i8mf4 (qhi_1 ),32 ,vl ); 2683vint8mf4_t a_2 = __riscv_vsub_vx_i8mf4 (__riscv_vreinterpret_v_u8mf4_i8mf4 (qhi_2 ),32 ,vl ); 2684vint8mf4_t a_3 = __riscv_vsub_vx_i8mf4 (__riscv_vreinterpret_v_u8mf4_i8mf4 (qhi_3 ),32 ,vl ); 2685 2686// load Q8 and take product 2687vint16mf2_t va_q_0 = __riscv_vwmul_vv_i16mf2 (a_0 ,__riscv_vle8_v_i8mf4 (q8 ,vl ),vl ); 2688vint16mf2_t va_q_1 = __riscv_vwmul_vv_i16mf2 (a_1 ,__riscv_vle8_v_i8mf4 (q8 + 32 ,vl ),vl ); 2689vint16mf2_t va_q_2 = __riscv_vwmul_vv_i16mf2 (a_2 ,__riscv_vle8_v_i8mf4 (q8 + 64 ,vl ),vl ); 2690vint16mf2_t va_q_3 = __riscv_vwmul_vv_i16mf2 (a_3 ,__riscv_vle8_v_i8mf4 (q8 + 96 ,vl ),vl ); 2691 2692// accumulate 2693vaux_0 = __riscv_vwmacc_vx_i32m1 (vaux_0 ,scale [is + 0 ],va_q_0 ,16 ); 2694vaux_1 = __riscv_vwmacc_vx_i32m1 (vaux_1 ,scale [is + 2 ],va_q_1 ,16 ); 2695vaux_2 = __riscv_vwmacc_vx_i32m1 (vaux_2 ,scale [is + 4 ],va_q_2 ,16 ); 2696vaux_3 = __riscv_vwmacc_vx_i32m1 (vaux_3 ,scale [is + 6 ],va_q_3 ,16 ); 2697// 2698vaux_0 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_0 ,scale [is + 1 ],va_q_0 ,vl ); 2699vaux_1 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_1 ,scale [is + 3 ],va_q_1 ,vl ); 2700vaux_2 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_2 ,scale [is + 5 ],va_q_2 ,vl ); 2701vaux_3 = __riscv_vwmacc_vx_i32m1_m (va_mask ,vaux_3 ,scale [is + 7 ],va_q_3 ,vl ); 2702 2703q6 += 64 ;qh += 32 ;q8 += 128 ;is = 8 ; 2704 2705 } 2706 2707vint32m1_t isum0 = __riscv_vredsum_vs_i32m1_i32m1 (__riscv_vadd_vv_i32m1 (vaux_0 ,vaux_1 ,vl ),vzero ,vl ); 2708vint32m1_t isum1 = __riscv_vredsum_vs_i32m1_i32m1 (__riscv_vadd_vv_i32m1 (vaux_2 ,vaux_3 ,vl ),isum0 ,vl ); 2709 2710sum_t += __riscv_vmv_x_s_i32m1_i32 (isum1 ); 2711 2712sumf += d * sum_t ; 2713 2714 } 2715 2716* s = sumf ; 2717} 2718#endif 2719 2720void 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 ) { 2721#if defined__riscv_xtheadvector 2722ggml_vec_dot_q6_K_q8_K_xtheadvector (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2723#elif defined__riscv_v 2724switch (__riscv_vlenb ()* 8 ) { 2725case 128 : 2726ggml_vec_dot_q6_K_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2727break ; 2728case 256 : 2729ggml_vec_dot_q6_K_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2730break ; 2731case 512 : 2732ggml_vec_dot_q6_K_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2733break ; 2734case 1024 : 2735ggml_vec_dot_q6_K_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2736break ; 2737default : 2738ggml_vec_dot_q6_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2739break ; 2740 } 2741#else 2742ggml_vec_dot_q6_K_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 2743#endif 2744} 2745 2746#if defined__riscv_v 2747static NOINLINE void ggml_vec_dot_iq1_s_q8_K_vl128 (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 ) { 2748assert (n %QK_K == 0 ); 2749assert (nrc == 1 ); 2750UNUSED (nrc ); 2751UNUSED (bx ); 2752UNUSED (by ); 2753UNUSED (bs ); 2754 2755const block_iq1_s * GGML_RESTRICT x = vx ; 2756const block_q8_K * GGML_RESTRICT y = vy ; 2757 2758const int nb = n /QK_K ; 2759 2760float sumf = 0 ; 2761for (int i = 0 ;i < nb ;++ i ) { 2762// Load qh once for the entire superblock. 2763vuint16m1_t qh = __riscv_vle16_v_u16m1 (x [i ].qh ,8 ); 2764 2765// Calculate ls. 2766vuint16m1_t temp = __riscv_vsrl_vx_u16m1 (qh ,12 ,8 ); 2767temp = __riscv_vand_vx_u16m1 (temp ,7 ,8 ); 2768vint32m2_t ls = __riscv_vreinterpret_v_u32m2_i32m2 (__riscv_vwmulu_vx_u32m2 (temp ,2 ,8 )); 2769ls = __riscv_vadd_vx_i32m2 (ls ,1 ,8 ); 2770 2771// Calculate delta. 2772vbool16_t mask = __riscv_vmseq_vx_u16m1_b16 (__riscv_vand_vx_u16m1 (qh ,0x8000 ,8 ),0 ,8 ); 2773vint32m2_t delta_neg = __riscv_vmv_v_x_i32m2 (-1 ,8 ); 2774vint32m2_t delta_pos = __riscv_vmv_v_x_i32m2 (1 ,8 ); 2775vint32m2_t delta = __riscv_vmerge_vvm_i32m2 (delta_neg ,delta_pos ,mask ,8 ); 2776 2777// Load qs. 2778vuint8m2_t qs = __riscv_vle8_v_u8m2 (x [i ].qs ,32 ); 2779 2780// Prepare the indices. 2781const uint64_t shift = 0x0009000600030000 ; 2782vuint16m4_t qh_shift = __riscv_vreinterpret_v_u64m4_u16m4 (__riscv_vmv_v_x_u64m4 (shift ,8 )); 2783vuint16m4_t qh_gather_index = __riscv_vreinterpret_v_i16m4_u16m4 ( 2784__riscv_vdiv_vx_i16m4 (__riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vid_v_u16m4 (32 )),4 ,32 )); 2785vuint16m4_t qh_ext = __riscv_vlmul_ext_v_u16m2_u16m4 (__riscv_vlmul_ext_v_u16m1_u16m2 (qh )); 2786vuint16m4_t qh_index = __riscv_vrgather_vv_u16m4 (qh_ext ,qh_gather_index ,32 ); 2787qh_index = __riscv_vsrl_vv_u16m4 (qh_index ,qh_shift ,32 ); 2788qh_index = __riscv_vand_vx_u16m4 (qh_index ,7 ,32 ); 2789qh_index = __riscv_vsll_vx_u16m4 (qh_index ,8 ,32 ); 2790qh_index = __riscv_vor_vv_u16m4 (qh_index ,__riscv_vzext_vf2_u16m4 (qs ,32 ),32 ); 2791vuint16m4_t index = __riscv_vsll_vx_u16m4 (qh_index ,3 ,32 ); 2792 2793// Final lsums. 2794int32_t lsums_s [8 ]; 2795vint32m1_t one_scalar = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2796 2797// Sub-blocks 1-2 2798 { 2799vuint16m1_t grid_index0 = __riscv_vget_v_u16m4_u16m1 (index ,0 ); 2800vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index0 ,8 )); 2801vint8m4_t q80 = __riscv_vle8_v_i8m4 (& y [i ].qs [0 ],64 ); 2802vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,128 ); 2803lsums_s [0 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,0 ),one_scalar ,32 )); 2804lsums_s [1 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,1 ),one_scalar ,32 )); 2805 } 2806 __asm__ __volatile__("" :::"memory" ); 2807// Sub-blocks 3-4 2808 { 2809vuint16m1_t grid_index0 = __riscv_vget_v_u16m4_u16m1 (index ,1 ); 2810vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index0 ,8 )); 2811vint8m4_t q80 = __riscv_vle8_v_i8m4 (& y [i ].qs [64 ],64 ); 2812vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,128 ); 2813lsums_s [2 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,0 ),one_scalar ,32 )); 2814lsums_s [3 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,1 ),one_scalar ,32 )); 2815 } 2816 __asm__ __volatile__("" :::"memory" ); 2817// Sub-blocks 5-6 2818 { 2819vuint16m1_t grid_index0 = __riscv_vget_v_u16m4_u16m1 (index ,2 ); 2820vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index0 ,8 )); 2821vint8m4_t q80 = __riscv_vle8_v_i8m4 (& y [i ].qs [128 ],64 ); 2822vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,128 ); 2823lsums_s [4 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,0 ),one_scalar ,32 )); 2824lsums_s [5 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,1 ),one_scalar ,32 )); 2825 } 2826 __asm__ __volatile__("" :::"memory" ); 2827// Sub-blocks 7-8 2828 { 2829vuint16m1_t grid_index0 = __riscv_vget_v_u16m4_u16m1 (index ,3 ); 2830vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index0 ,8 )); 2831vint8m4_t q80 = __riscv_vle8_v_i8m4 (& y [i ].qs [192 ],64 ); 2832vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,128 ); 2833lsums_s [6 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,0 ),one_scalar ,32 )); 2834lsums_s [7 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (lsum0 ,1 ),one_scalar ,32 )); 2835 } 2836 __asm__ __volatile__("" :::"memory" ); 2837vint32m2_t lsums = __riscv_vle32_v_i32m2 (& lsums_s [0 ],8 ); 2838 2839// Calculate the bsums. 2840vint16m2_t bsums_0 = __riscv_vle16_v_i16m2 (y [i ].bsums ,16 ); 2841const vuint32m2_t bsums_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (__riscv_vreinterpret_v_i16m2_u16m2 (bsums_0 )); 2842const vint16m1_t bsums_i32_0 = __riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vnsrl_wx_u16m1 (bsums_i32 ,0 ,8 )); 2843const vint16m1_t bsums_i32_1 = __riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vnsrl_wx_u16m1 (bsums_i32 ,16 ,8 )); 2844const vint32m2_t bsums = __riscv_vwadd_vv_i32m2 (bsums_i32_0 ,bsums_i32_1 ,8 ); 2845 2846// Accumulation. 2847vint32m2_t sumi_v = __riscv_vmul_vv_i32m2 (ls ,lsums ,8 ); 2848vint32m2_t sumi1_v = __riscv_vmul_vv_i32m2 (__riscv_vmul_vv_i32m2 (ls ,delta ,8 ),bsums ,8 ); 2849 2850// Update sumf. 2851int sumi = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (sumi_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 2852int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (sumi1_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 2853sumf += GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d * (sumi + IQ1S_DELTA * sumi1 ); 2854 } 2855 2856* s = sumf ; 2857} 2858 2859static NOINLINE void ggml_vec_dot_iq1_s_q8_K_vl256 (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 ) { 2860assert (n %QK_K == 0 ); 2861assert (nrc == 1 ); 2862UNUSED (nrc ); 2863UNUSED (bx ); 2864UNUSED (by ); 2865UNUSED (bs ); 2866 2867const block_iq1_s * GGML_RESTRICT x = vx ; 2868const block_q8_K * GGML_RESTRICT y = vy ; 2869 2870const int nb = n /QK_K ; 2871 2872float sumf = 0 ; 2873for (int i = 0 ;i < nb ;++ i ) { 2874// Load qh once for the entire superblock. 2875vuint16mf2_t qh = __riscv_vle16_v_u16mf2 (x [i ].qh ,8 ); 2876 2877// Calculate ls. 2878vuint16mf2_t temp = __riscv_vsrl_vx_u16mf2 (qh ,12 ,8 ); 2879temp = __riscv_vand_vx_u16mf2 (temp ,7 ,8 ); 2880vint32m1_t ls = __riscv_vreinterpret_v_u32m1_i32m1 (__riscv_vwmulu_vx_u32m1 (temp ,2 ,8 )); 2881ls = __riscv_vadd_vx_i32m1 (ls ,1 ,8 ); 2882 2883// Calculate delta. 2884vbool32_t mask = __riscv_vmseq_vx_u16mf2_b32 (__riscv_vand_vx_u16mf2 (qh ,0x8000 ,8 ),0 ,8 ); 2885vint32m1_t delta_neg = __riscv_vmv_v_x_i32m1 (-1 ,8 ); 2886vint32m1_t delta_pos = __riscv_vmv_v_x_i32m1 (1 ,8 ); 2887vint32m1_t delta = __riscv_vmerge_vvm_i32m1 (delta_neg ,delta_pos ,mask ,8 ); 2888 2889// Load qs. 2890vuint8m1_t qs = __riscv_vle8_v_u8m1 (x [i ].qs ,32 ); 2891 2892// Prepare the indices. 2893const uint64_t shift = 0x0009000600030000 ; 2894vuint16m2_t qh_shift = __riscv_vreinterpret_v_u64m2_u16m2 (__riscv_vmv_v_x_u64m2 (shift ,8 )); 2895vuint16m2_t qh_gather_index = __riscv_vreinterpret_v_i16m2_u16m2 ( 2896__riscv_vdiv_vx_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vid_v_u16m2 (32 )),4 ,32 )); 2897vuint16m2_t qh_ext = __riscv_vlmul_ext_v_u16m1_u16m2 (__riscv_vlmul_ext_v_u16mf2_u16m1 (qh )); 2898vuint16m2_t qh_index = __riscv_vrgather_vv_u16m2 (qh_ext ,qh_gather_index ,32 ); 2899qh_index = __riscv_vsrl_vv_u16m2 (qh_index ,qh_shift ,32 ); 2900qh_index = __riscv_vand_vx_u16m2 (qh_index ,7 ,32 ); 2901qh_index = __riscv_vsll_vx_u16m2 (qh_index ,8 ,32 ); 2902qh_index = __riscv_vor_vv_u16m2 (qh_index ,__riscv_vzext_vf2_u16m2 (qs ,32 ),32 ); 2903vuint16m2_t index = __riscv_vsll_vx_u16m2 (qh_index ,3 ,32 ); 2904 2905// Final lsums. 2906int32_t lsums_s [8 ]; 2907vint32m1_t one_scalar = __riscv_vmv_v_x_i32m1 (0 ,1 ); 2908 2909// Sub-blocks 1-4 2910 { 2911vuint16m1_t grid_index0 = __riscv_vget_v_u16m2_u16m1 (index ,0 ); 2912vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index0 ,16 )); 2913vint8m4_t q80 = __riscv_vle8_v_i8m4 (y [i ].qs ,128 ); 2914vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,128 ); 2915lsums_s [0 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum0 ,0 ),one_scalar ,32 )); 2916lsums_s [1 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum0 ,1 ),one_scalar ,32 )); 2917lsums_s [2 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum0 ,2 ),one_scalar ,32 )); 2918lsums_s [3 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum0 ,3 ),one_scalar ,32 )); 2919 } 2920 __asm__ __volatile__("" :::"memory" ); 2921// Sub-blocks 5-8 2922 { 2923vuint16m1_t grid_index1 = __riscv_vget_v_u16m2_u16m1 (index ,1 ); 2924vint8m4_t grid1 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,grid_index1 ,16 )); 2925vint8m4_t q81 = __riscv_vle8_v_i8m4 (& y [i ].qs [128 ],128 ); 2926vint16m8_t lsum1 = __riscv_vwmul_vv_i16m8 (grid1 ,q81 ,128 ); 2927lsums_s [4 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum1 ,0 ),one_scalar ,32 )); 2928lsums_s [5 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum1 ,1 ),one_scalar ,32 )); 2929lsums_s [6 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum1 ,2 ),one_scalar ,32 )); 2930lsums_s [7 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (lsum1 ,3 ),one_scalar ,32 )); 2931 } 2932 __asm__ __volatile__("" :::"memory" ); 2933vint32m1_t lsums = __riscv_vle32_v_i32m1 (& lsums_s [0 ],8 ); 2934 2935// Calculate the bsums. 2936vint16m1_t bsums_0 = __riscv_vle16_v_i16m1 (y [i ].bsums ,16 ); 2937const vuint32m1_t bsums_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (__riscv_vreinterpret_v_i16m1_u16m1 (bsums_0 )); 2938const vint16mf2_t bsums_i32_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (bsums_i32 ,0 ,8 )); 2939const vint16mf2_t bsums_i32_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (bsums_i32 ,16 ,8 )); 2940const vint32m1_t bsums = __riscv_vwadd_vv_i32m1 (bsums_i32_0 ,bsums_i32_1 ,8 ); 2941 2942// Accumulation. 2943vint32m1_t sumi_v = __riscv_vmul_vv_i32m1 (ls ,lsums ,8 ); 2944vint32m1_t sumi1_v = __riscv_vmul_vv_i32m1 (__riscv_vmul_vv_i32m1 (ls ,delta ,8 ),bsums ,8 ); 2945 2946// Update sumf. 2947int sumi = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m1_i32m1 (sumi_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 2948int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m1_i32m1 (sumi1_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 2949sumf += GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d * (sumi + IQ1S_DELTA * sumi1 ); 2950 } 2951 2952* s = sumf ; 2953} 2954 2955static NOINLINE void ggml_vec_dot_iq1_s_q8_K_vl512 (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 ) { 2956assert (n %QK_K == 0 ); 2957assert (nrc == 1 ); 2958UNUSED (nrc ); 2959UNUSED (bx ); 2960UNUSED (by ); 2961UNUSED (bs ); 2962 2963const block_iq1_s * GGML_RESTRICT x = vx ; 2964const block_q8_K * GGML_RESTRICT y = vy ; 2965 2966const int nb = n /QK_K ; 2967 2968float sumf = 0 ; 2969for (int i = 0 ;i < nb ;++ i ) { 2970// Load qh once for the entire superblock. 2971vuint16mf4_t qh = __riscv_vle16_v_u16mf4 (x [i ].qh ,8 ); 2972 2973// Calculate ls. 2974vuint16mf4_t temp = __riscv_vsrl_vx_u16mf4 (qh ,12 ,8 ); 2975temp = __riscv_vand_vx_u16mf4 (temp ,7 ,8 ); 2976vint32mf2_t ls = __riscv_vreinterpret_v_u32mf2_i32mf2 (__riscv_vwmulu_vx_u32mf2 (temp ,2 ,8 )); 2977ls = __riscv_vadd_vx_i32mf2 (ls ,1 ,8 ); 2978 2979// Calculate delta. 2980vbool64_t mask = __riscv_vmseq_vx_u16mf4_b64 (__riscv_vand_vx_u16mf4 (qh ,0x8000 ,8 ),0 ,8 ); 2981vint32mf2_t delta_neg = __riscv_vmv_v_x_i32mf2 (-1 ,8 ); 2982vint32mf2_t delta_pos = __riscv_vmv_v_x_i32mf2 (1 ,8 ); 2983vint32mf2_t delta = __riscv_vmerge_vvm_i32mf2 (delta_neg ,delta_pos ,mask ,8 ); 2984 2985// Load qs. 2986vuint8mf2_t qs = __riscv_vle8_v_u8mf2 (x [i ].qs ,32 ); 2987 2988// Prepare the indices. 2989const uint64_t shift = 0x0009000600030000 ; 2990vuint16m1_t qh_shift = __riscv_vreinterpret_v_u64m1_u16m1 (__riscv_vmv_v_x_u64m1 (shift ,8 )); 2991vuint16m1_t qh_gather_index = __riscv_vreinterpret_v_i16m1_u16m1 ( 2992__riscv_vdiv_vx_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vid_v_u16m1 (32 )),4 ,32 )); 2993vuint16m1_t qh_ext = __riscv_vlmul_ext_v_u16mf2_u16m1 (__riscv_vlmul_ext_v_u16mf4_u16mf2 (qh )); 2994vuint16m1_t qh_index = __riscv_vrgather_vv_u16m1 (qh_ext ,qh_gather_index ,32 ); 2995qh_index = __riscv_vsrl_vv_u16m1 (qh_index ,qh_shift ,32 ); 2996qh_index = __riscv_vand_vx_u16m1 (qh_index ,7 ,32 ); 2997qh_index = __riscv_vsll_vx_u16m1 (qh_index ,8 ,32 ); 2998qh_index = __riscv_vor_vv_u16m1 (qh_index ,__riscv_vzext_vf2_u16m1 (qs ,32 ),32 ); 2999vuint16m1_t index = __riscv_vsll_vx_u16m1 (qh_index ,3 ,32 ); 3000 3001// Final lsums. 3002int32_t lsums_s [8 ]; 3003vint32m1_t one_scalar = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3004 3005// Sub-blocks 1-8 3006 { 3007vint8m4_t grid0 = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vluxei16_v_i64m4 ((const int64_t * )iq1s_grid ,index ,32 )); 3008vint8m4_t q80 = __riscv_vle8_v_i8m4 (y [i ].qs ,256 ); 3009vint16m8_t lsum0 = __riscv_vwmul_vv_i16m8 (grid0 ,q80 ,256 ); 3010lsums_s [0 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,0 ),one_scalar ,32 )); 3011lsums_s [1 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,1 ),one_scalar ,32 )); 3012lsums_s [2 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,2 ),one_scalar ,32 )); 3013lsums_s [3 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,3 ),one_scalar ,32 )); 3014lsums_s [4 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,4 ),one_scalar ,32 )); 3015lsums_s [5 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,5 ),one_scalar ,32 )); 3016lsums_s [6 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,6 ),one_scalar ,32 )); 3017lsums_s [7 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (lsum0 ,7 ),one_scalar ,32 )); 3018 } 3019 __asm__ __volatile__("" :::"memory" ); 3020vint32mf2_t lsums = __riscv_vle32_v_i32mf2 (& lsums_s [0 ],8 ); 3021 3022// Calculate the bsums. 3023vint16mf2_t bsums_0 = __riscv_vle16_v_i16mf2 (y [i ].bsums ,16 ); 3024const vuint32mf2_t bsums_i32 = __riscv_vreinterpret_v_u16mf2_u32mf2 (__riscv_vreinterpret_v_i16mf2_u16mf2 (bsums_0 )); 3025const vint16mf4_t bsums_i32_0 = __riscv_vreinterpret_v_u16mf4_i16mf4 (__riscv_vnsrl_wx_u16mf4 (bsums_i32 ,0 ,8 )); 3026const vint16mf4_t bsums_i32_1 = __riscv_vreinterpret_v_u16mf4_i16mf4 (__riscv_vnsrl_wx_u16mf4 (bsums_i32 ,16 ,8 )); 3027const vint32mf2_t bsums = __riscv_vwadd_vv_i32mf2 (bsums_i32_0 ,bsums_i32_1 ,8 ); 3028 3029// Accumulation. 3030vint32mf2_t sumi_v = __riscv_vmul_vv_i32mf2 (ls ,lsums ,8 ); 3031vint32mf2_t sumi1_v = __riscv_vmul_vv_i32mf2 (__riscv_vmul_vv_i32mf2 (ls ,delta ,8 ),bsums ,8 ); 3032 3033// Update sumf. 3034int sumi = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32mf2_i32m1 (sumi_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 3035int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32mf2_i32m1 (sumi1_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 3036sumf += GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d * (sumi + IQ1S_DELTA * sumi1 ); 3037 } 3038 3039* s = sumf ; 3040} 3041 3042static NOINLINE void ggml_vec_dot_iq1_s_q8_K_vl1024 (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 ) { 3043assert (n %QK_K == 0 ); 3044assert (nrc == 1 ); 3045UNUSED (nrc ); 3046UNUSED (bx ); 3047UNUSED (by ); 3048UNUSED (bs ); 3049 3050const block_iq1_s * GGML_RESTRICT x = vx ; 3051const block_q8_K * GGML_RESTRICT y = vy ; 3052 3053const int nb = n /QK_K ; 3054 3055// Mask for processing 32 elements per lsum register. 3056vuint16m1_t l_index = __riscv_vid_v_u16m1 (64 ); 3057vbool16_t l_mask = __riscv_vmsgtu_vx_u16m1_b16 (l_index ,31 ,64 ); 3058 3059float sumf = 0 ; 3060for (int i = 0 ;i < nb ;++ i ) { 3061// Load qh once for the entire superblock. 3062vuint16mf4_t qh = __riscv_vle16_v_u16mf4 (x [i ].qh ,8 ); 3063 3064// Calculate ls. 3065vuint16mf4_t temp = __riscv_vsrl_vx_u16mf4 (qh ,12 ,8 ); 3066temp = __riscv_vand_vx_u16mf4 (temp ,7 ,8 ); 3067vint32mf2_t ls = __riscv_vreinterpret_v_u32mf2_i32mf2 (__riscv_vwmulu_vx_u32mf2 (temp ,2 ,8 )); 3068ls = __riscv_vadd_vx_i32mf2 (ls ,1 ,8 ); 3069 3070// Calculate delta. 3071vbool64_t mask = __riscv_vmseq_vx_u16mf4_b64 (__riscv_vand_vx_u16mf4 (qh ,0x8000 ,8 ),0 ,8 ); 3072vint32mf2_t delta_neg = __riscv_vmv_v_x_i32mf2 (-1 ,8 ); 3073vint32mf2_t delta_pos = __riscv_vmv_v_x_i32mf2 (1 ,8 ); 3074vint32mf2_t delta = __riscv_vmerge_vvm_i32mf2 (delta_neg ,delta_pos ,mask ,8 ); 3075 3076// Load qs. 3077vuint8mf2_t qs = __riscv_vle8_v_u8mf2 (x [i ].qs ,32 ); 3078 3079// Prepare the indices. 3080const uint64_t shift = 0x0009000600030000 ; 3081vuint16m1_t qh_shift = __riscv_vreinterpret_v_u64m1_u16m1 (__riscv_vmv_v_x_u64m1 (shift ,8 )); 3082vuint16m1_t qh_gather_index = __riscv_vreinterpret_v_i16m1_u16m1 ( 3083__riscv_vdiv_vx_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vid_v_u16m1 (32 )),4 ,32 )); 3084vuint16m1_t qh_ext = __riscv_vlmul_ext_v_u16mf2_u16m1 (__riscv_vlmul_ext_v_u16mf4_u16mf2 (qh )); 3085vuint16m1_t qh_index = __riscv_vrgather_vv_u16m1 (qh_ext ,qh_gather_index ,32 ); 3086qh_index = __riscv_vsrl_vv_u16m1 (qh_index ,qh_shift ,32 ); 3087qh_index = __riscv_vand_vx_u16m1 (qh_index ,7 ,32 ); 3088qh_index = __riscv_vsll_vx_u16m1 (qh_index ,8 ,32 ); 3089qh_index = __riscv_vor_vv_u16m1 (qh_index ,__riscv_vzext_vf2_u16m1 (qs ,32 ),32 ); 3090vuint16mf2_t index = __riscv_vlmul_trunc_v_u16m1_u16mf2 (__riscv_vsll_vx_u16m1 (qh_index ,3 ,32 )); 3091 3092// Final lsums. 3093int32_t lsums_s [8 ]; 3094vint32m1_t one_scalar = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3095 3096// Sub-blocks 1-8 3097 { 3098vint8m2_t grid0 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vluxei16_v_i64m2 ((const int64_t * )iq1s_grid ,index ,32 )); 3099vint8m2_t q80 = __riscv_vle8_v_i8m2 (y [i ].qs ,256 ); 3100vint16m4_t lsum0 = __riscv_vwmul_vv_i16m4 (grid0 ,q80 ,256 ); 3101 3102// Reduce. 3103lsums_s [0 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (lsum0 ,0 ),one_scalar ,32 )); 3104lsums_s [1 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (l_mask ,__riscv_vget_v_i16m4_i16m1 (lsum0 ,0 ),one_scalar ,64 )); 3105lsums_s [2 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (lsum0 ,1 ),one_scalar ,32 )); 3106lsums_s [3 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (l_mask ,__riscv_vget_v_i16m4_i16m1 (lsum0 ,1 ),one_scalar ,64 )); 3107lsums_s [4 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (lsum0 ,2 ),one_scalar ,32 )); 3108lsums_s [5 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (l_mask ,__riscv_vget_v_i16m4_i16m1 (lsum0 ,2 ),one_scalar ,64 )); 3109lsums_s [6 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (lsum0 ,3 ),one_scalar ,32 )); 3110lsums_s [7 ]= __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (l_mask ,__riscv_vget_v_i16m4_i16m1 (lsum0 ,3 ),one_scalar ,64 )); 3111 } 3112 __asm__ __volatile__("" :::"memory" ); 3113vint32mf2_t lsums = __riscv_vle32_v_i32mf2 (& lsums_s [0 ],8 ); 3114 3115// Calculate the bsums. 3116vint16mf2_t bsums_0 = __riscv_vle16_v_i16mf2 (y [i ].bsums ,16 ); 3117const vuint32mf2_t bsums_i32 = __riscv_vreinterpret_v_u16mf2_u32mf2 (__riscv_vreinterpret_v_i16mf2_u16mf2 (bsums_0 )); 3118const vint16mf4_t bsums_i32_0 = __riscv_vreinterpret_v_u16mf4_i16mf4 (__riscv_vnsrl_wx_u16mf4 (bsums_i32 ,0 ,8 )); 3119const vint16mf4_t bsums_i32_1 = __riscv_vreinterpret_v_u16mf4_i16mf4 (__riscv_vnsrl_wx_u16mf4 (bsums_i32 ,16 ,8 )); 3120const vint32mf2_t bsums = __riscv_vwadd_vv_i32mf2 (bsums_i32_0 ,bsums_i32_1 ,8 ); 3121 3122// Accumulation. 3123vint32mf2_t sumi_v = __riscv_vmul_vv_i32mf2 (ls ,lsums ,8 ); 3124vint32mf2_t sumi1_v = __riscv_vmul_vv_i32mf2 (__riscv_vmul_vv_i32mf2 (ls ,delta ,8 ),bsums ,8 ); 3125 3126// Update sumf. 3127int sumi = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32mf2_i32m1 (sumi_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 3128int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32mf2_i32m1 (sumi1_v ,__riscv_vmv_v_x_i32m1 (0.0f ,1 ),8 )); 3129sumf += GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d * (sumi + IQ1S_DELTA * sumi1 ); 3130 } 3131 3132* s = sumf ; 3133} 3134#endif 3135 3136void 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 ) { 3137#if defined__riscv_v 3138switch (__riscv_vlenb ()* 8 ) { 3139case 128 : 3140ggml_vec_dot_iq1_s_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3141break ; 3142case 256 : 3143ggml_vec_dot_iq1_s_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3144break ; 3145case 512 : 3146ggml_vec_dot_iq1_s_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3147break ; 3148case 1024 : 3149ggml_vec_dot_iq1_s_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3150break ; 3151default : 3152ggml_vec_dot_iq1_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3153break ; 3154 } 3155#else 3156ggml_vec_dot_iq1_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3157#endif 3158} 3159 3160#if defined__riscv_v 3161static NOINLINE void ggml_vec_dot_iq1_m_q8_K_vl128 (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 ) { 3162assert (n %QK_K == 0 ); 3163assert (nrc == 1 ); 3164UNUSED (nrc ); 3165UNUSED (bx ); 3166UNUSED (by ); 3167UNUSED (bs ); 3168 3169const block_iq1_m * GGML_RESTRICT x = vx ; 3170const block_q8_K * GGML_RESTRICT y = vy ; 3171 3172const int nb = n /QK_K ; 3173 3174iq1m_scale_t scale ; 3175float sumf = 0.0f ; 3176for (int i = 0 ;i < nb ;++ i ) { 3177const int8_t * q8 = y [i ].qs ; 3178const uint8_t * qs = x [i ].qs ; 3179const uint8_t * qh = x [i ].qh ; 3180const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3181 3182scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 3183 3184// Accumulators. 3185vint32m4_t acc1 = __riscv_vmv_v_x_i32m4 (0 ,16 ); 3186vint32m4_t acc2 = __riscv_vmv_v_x_i32m4 (0 ,16 ); 3187 3188// We process 8 16-element sub-blocks together. 3189#pragma GCC unroll 1 3190for (int ib = 0 ;ib < QK_K /128 ;ib ++ ) { 3191// Load qh for 8 sub-blocks. 3192const vuint8mf2_t qh_8 = __riscv_vle8_v_u8mf2 (qh ,8 ); 3193const vuint16m1_t qh_16_lo = __riscv_vzext_vf2_u16m1 (qh_8 ,8 ); 3194const vuint16m1_t qh_16_hi = __riscv_vsll_vx_u16m1 (qh_16_lo ,8 ,8 ); 3195const vuint16m2_t qhb = __riscv_vzext_vf2_u16m2 ( 3196__riscv_vreinterpret_v_u16m1_u8m1 (__riscv_vor_vv_u16m1 (qh_16_lo ,qh_16_hi ,8 )),16 ); 3197qh += 8 ; 3198 3199// Prepare grid indices. 3200const vuint16m2_t qsb = __riscv_vzext_vf2_u16m2 (__riscv_vle8_v_u8m1 (& qs [0 ],16 ),16 ); 3201const vuint16m2_t shift = __riscv_vreinterpret_v_u32m2_u16m2 (__riscv_vmv_v_x_u32m2 (0x00040008 ,8 )); 3202vuint16m2_t index = __riscv_vor_vv_u16m2 (qsb ,__riscv_vand_vx_u16m2 (__riscv_vsll_vv_u16m2 (qhb ,shift ,16 ),0x700 ,16 ),16 ); 3203index = __riscv_vsll_vx_u16m2 (index ,3 ,16 ); 3204qs += 16 ; 3205 3206// Prepare the deltas. 3207const vbool8_t mask = __riscv_vmsgtu_vx_u16m2_b8 ( 3208__riscv_vand_vv_u16m2 (qhb ,__riscv_vreinterpret_v_u32m2_u16m2 (__riscv_vmv_v_x_u32m2 (0x00800008 ,8 )),16 ),0 ,16 ); 3209const vint64m8_t delta_pos = __riscv_vmv_v_x_i64m8 (0x0101010101010101 ,16 ); 3210const vint8m8_t delta = __riscv_vreinterpret_v_i64m8_i8m8 ( 3211__riscv_vmerge_vxm_i64m8 (delta_pos ,0xffffffffffffffff ,mask ,16 )); 3212 3213// Sub-blocks 0-3 3214 { 3215// Load the grid. 3216const vint8m4_t iq1b = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vreinterpret_v_u64m4_i64m4 ( 3217__riscv_vluxei16_v_u64m4 (iq1s_grid ,__riscv_vget_v_u16m2_u16m1 (index ,0 ),8 ))); 3218 3219// Calculate the lsums. 3220// 3221// Sub-block 0, 1 3222 { 3223// Load q8 for each sub-block. 3224const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,32 ); 3225q8 += 32 ; 3226 3227// Calculate the lsums. 3228const vint16m4_t lsum1 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m4_i8m2 (iq1b ,0 ),q8b ,32 ); 3229const vint16m4_t lsum2 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m8_i8m2 (delta ,0 ),q8b ,32 ); 3230 3231// Prepare the scales. 3232const int16_t ls_0 = 2 * ((sc [0 ] >>0 )& 0x7 )+ 1 ; 3233const int16_t ls_1 = 2 * ((sc [0 ] >>3 )& 0x7 )+ 1 ; 3234 3235// Accumulate in acc0 and acc1 for each sub-block. 3236acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,0 ),16 ); 3237acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,1 ),16 ); 3238acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,0 ),16 ); 3239acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,1 ),16 ); 3240 } 3241 __asm__ __volatile__("" :::"memory" ); 3242// Sub-block 2, 3 3243 { 3244// Load q8 for each sub-block. 3245const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,32 ); 3246q8 += 32 ; 3247 3248// Calculate the lsums. 3249const vint16m4_t lsum1 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m4_i8m2 (iq1b ,1 ),q8b ,32 ); 3250const vint16m4_t lsum2 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m8_i8m2 (delta ,1 ),q8b ,32 ); 3251 3252// Prepare the scales. 3253const int16_t ls_0 = 2 * ((sc [0 ] >>6 )& 0x7 )+ 1 ; 3254const int16_t ls_1 = 2 * ((sc [0 ] >>9 )& 0x7 )+ 1 ; 3255 3256// Accumulate in acc0 and acc1 for each sub-block. 3257acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,0 ),16 ); 3258acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,1 ),16 ); 3259acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,0 ),16 ); 3260acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,1 ),16 ); 3261 } 3262sc += 1 ; 3263 } 3264 __asm__ __volatile__("" :::"memory" ); 3265// Sub-blocks 4-7 3266 { 3267// Load the grid. 3268const vint8m4_t iq1b = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vreinterpret_v_u64m4_i64m4 ( 3269__riscv_vluxei16_v_u64m4 (iq1s_grid ,__riscv_vget_v_u16m2_u16m1 (index ,1 ),8 ))); 3270 3271// Calculate the lsums. 3272// 3273// Sub-block 4, 5 3274 { 3275// Load q8 for each sub-block. 3276const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,32 ); 3277q8 += 32 ; 3278 3279// Calculate the lsums. 3280const vint16m4_t lsum1 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m4_i8m2 (iq1b ,0 ),q8b ,32 ); 3281const vint16m4_t lsum2 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m8_i8m2 (delta ,2 ),q8b ,32 ); 3282 3283// Prepare the scales. 3284const int16_t ls_0 = 2 * ((sc [0 ] >>0 )& 0x7 )+ 1 ; 3285const int16_t ls_1 = 2 * ((sc [0 ] >>3 )& 0x7 )+ 1 ; 3286 3287// Accumulate in acc0 and acc1 for each sub-block. 3288acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,0 ),16 ); 3289acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,1 ),16 ); 3290acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,0 ),16 ); 3291acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,1 ),16 ); 3292 } 3293 __asm__ __volatile__("" :::"memory" ); 3294// Sub-block 6, 7 3295 { 3296// Load q8 for each sub-block. 3297const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,32 ); 3298q8 += 32 ; 3299 3300// Calculate the lsums. 3301const vint16m4_t lsum1 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m4_i8m2 (iq1b ,1 ),q8b ,32 ); 3302const vint16m4_t lsum2 = __riscv_vwmul_vv_i16m4 (__riscv_vget_v_i8m8_i8m2 (delta ,3 ),q8b ,32 ); 3303 3304// Prepare the scales. 3305const int16_t ls_0 = 2 * ((sc [0 ] >>6 )& 0x7 )+ 1 ; 3306const int16_t ls_1 = 2 * ((sc [0 ] >>9 )& 0x7 )+ 1 ; 3307 3308// Accumulate in acc0 and acc1 for each sub-block. 3309acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,0 ),16 ); 3310acc1 = __riscv_vwmacc_vx_i32m4 (acc1 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum1 ,1 ),16 ); 3311acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_0 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,0 ),16 ); 3312acc2 = __riscv_vwmacc_vx_i32m4 (acc2 ,ls_1 ,__riscv_vget_v_i16m4_i16m2 (lsum2 ,1 ),16 ); 3313 } 3314sc += 1 ; 3315 } 3316 } 3317 3318// Reduce and accumulate in `sumf`. 3319vint32m1_t one = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3320int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m4_i32m1 (acc1 ,one ,16 )); 3321int sumi2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m4_i32m1 (acc2 ,one ,16 )); 3322sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )* (sumi1 + IQ1M_DELTA * sumi2 ); 3323 } 3324 3325* s = sumf ; 3326} 3327 3328static NOINLINE void ggml_vec_dot_iq1_m_q8_K_vl256 (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 ) { 3329assert (n %QK_K == 0 ); 3330assert (nrc == 1 ); 3331UNUSED (nrc ); 3332UNUSED (bx ); 3333UNUSED (by ); 3334UNUSED (bs ); 3335 3336const block_iq1_m * GGML_RESTRICT x = vx ; 3337const block_q8_K * GGML_RESTRICT y = vy ; 3338 3339const int nb = n /QK_K ; 3340 3341iq1m_scale_t scale ; 3342float sumf = 0.0f ; 3343for (int i = 0 ;i < nb ;++ i ) { 3344const int8_t * q8 = y [i ].qs ; 3345const uint8_t * qs = x [i ].qs ; 3346const uint8_t * qh = x [i ].qh ; 3347const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3348 3349scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 3350 3351// Accumulators. 3352vint32m2_t acc1 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 3353vint32m2_t acc2 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 3354 3355// We process 8 16-element sub-blocks together. 3356#pragma GCC unroll 1 3357for (int ib = 0 ;ib < QK_K /128 ;ib ++ ) { 3358// Load qh for 8 sub-blocks. 3359const vuint8mf4_t qh_8 = __riscv_vle8_v_u8mf4 (qh ,8 ); 3360const vuint16mf2_t qh_16_lo = __riscv_vzext_vf2_u16mf2 (qh_8 ,8 ); 3361const vuint16mf2_t qh_16_hi = __riscv_vsll_vx_u16mf2 (qh_16_lo ,8 ,8 ); 3362const vuint16m1_t qhb = __riscv_vzext_vf2_u16m1 ( 3363__riscv_vreinterpret_v_u16mf2_u8mf2 (__riscv_vor_vv_u16mf2 (qh_16_lo ,qh_16_hi ,8 )),16 ); 3364qh += 8 ; 3365 3366 __asm__ __volatile__("" :::"memory" ); 3367 3368// Prepare grid indices. 3369const vuint16m1_t qsb = __riscv_vzext_vf2_u16m1 (__riscv_vle8_v_u8mf2 (& qs [0 ],16 ),16 ); 3370const vuint16m1_t shift = __riscv_vreinterpret_v_u32m1_u16m1 (__riscv_vmv_v_x_u32m1 (0x00040008 ,8 )); 3371vuint16m1_t index = __riscv_vor_vv_u16m1 (qsb ,__riscv_vand_vx_u16m1 (__riscv_vsll_vv_u16m1 (qhb ,shift ,16 ),0x700 ,16 ),16 ); 3372index = __riscv_vsll_vx_u16m1 (index ,3 ,16 ); 3373qs += 16 ; 3374 3375 __asm__ __volatile__("" :::"memory" ); 3376 3377// Load the grid. 3378const vint8m4_t iq1b = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vreinterpret_v_u64m4_i64m4 ( 3379__riscv_vluxei16_v_u64m4 (iq1s_grid ,index ,16 ))); 3380 3381// Prepare the deltas. 3382const vbool16_t mask = __riscv_vmsgtu_vx_u16m1_b16 ( 3383__riscv_vand_vv_u16m1 (qhb ,__riscv_vreinterpret_v_u32m1_u16m1 (__riscv_vmv_v_x_u32m1 (0x00800008 ,8 )),16 ),0 ,16 ); 3384const vint64m4_t delta_pos = __riscv_vmv_v_x_i64m4 (0x0101010101010101 ,16 ); 3385const vint8m4_t delta = __riscv_vreinterpret_v_i64m4_i8m4 ( 3386__riscv_vmerge_vxm_i64m4 (delta_pos ,0xffffffffffffffff ,mask ,16 )); 3387 3388// Load q8 for sub-blocks. 3389const vint8m4_t q8b = __riscv_vle8_v_i8m4 (q8 ,128 ); 3390q8 += 128 ; 3391 3392// Calculate the lsums. 3393const vint16m8_t lsum1 = __riscv_vwmul_vv_i16m8 (iq1b ,q8b ,128 ); 3394const vint16m8_t lsum2 = __riscv_vwmul_vv_i16m8 (delta ,q8b ,128 ); 3395 3396// Prepare the scales. 3397const int16_t ls_0_0 = 2 * ((sc [0 ] >>0 )& 0x7 )+ 1 ; 3398const int16_t ls_0_1 = 2 * ((sc [0 ] >>3 )& 0x7 )+ 1 ; 3399const int16_t ls_1_0 = 2 * ((sc [0 ] >>6 )& 0x7 )+ 1 ; 3400const int16_t ls_1_1 = 2 * ((sc [0 ] >>9 )& 0x7 )+ 1 ; 3401const int16_t ls_2_0 = 2 * ((sc [1 ] >>0 )& 0x7 )+ 1 ; 3402const int16_t ls_2_1 = 2 * ((sc [1 ] >>3 )& 0x7 )+ 1 ; 3403const int16_t ls_3_0 = 2 * ((sc [1 ] >>6 )& 0x7 )+ 1 ; 3404const int16_t ls_3_1 = 2 * ((sc [1 ] >>9 )& 0x7 )+ 1 ; 3405sc += 2 ; 3406 3407// Accumulate in acc0 and acc1 for each sub-block. 3408acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_0_0 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,0 ),16 ); 3409acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_0_1 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,1 ),16 ); 3410acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_0_0 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,0 ),16 ); 3411acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_0_1 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,1 ),16 ); 3412// 3413acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_1_0 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,2 ),16 ); 3414acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_1_1 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,3 ),16 ); 3415acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_1_0 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,2 ),16 ); 3416acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_1_1 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,3 ),16 ); 3417// 3418acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_2_0 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,4 ),16 ); 3419acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_2_1 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,5 ),16 ); 3420acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_2_0 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,4 ),16 ); 3421acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_2_1 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,5 ),16 ); 3422// 3423acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_3_0 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,6 ),16 ); 3424acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_3_1 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,7 ),16 ); 3425acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_3_0 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,6 ),16 ); 3426acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_3_1 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,7 ),16 ); 3427 3428 __asm__ __volatile__("" :::"memory" ); 3429 } 3430 3431// Reduce and accumulate in `sumf`. 3432vint32m1_t one = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3433int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc1 ,one ,16 )); 3434int sumi2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc2 ,one ,16 )); 3435sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )* (sumi1 + IQ1M_DELTA * sumi2 ); 3436 } 3437 3438* s = sumf ; 3439} 3440 3441static NOINLINE void ggml_vec_dot_iq1_m_q8_K_vl512 (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 ) { 3442assert (n %QK_K == 0 ); 3443assert (nrc == 1 ); 3444UNUSED (nrc ); 3445UNUSED (bx ); 3446UNUSED (by ); 3447UNUSED (bs ); 3448 3449const block_iq1_m * GGML_RESTRICT x = vx ; 3450const block_q8_K * GGML_RESTRICT y = vy ; 3451 3452const int nb = n /QK_K ; 3453 3454iq1m_scale_t scale ; 3455 3456// Mask for processing 16 elements per lsum register. 3457const vuint16m1_t l_index = __riscv_vid_v_u16m1 (32 ); 3458const vbool16_t l_mask = __riscv_vmsgtu_vx_u16m1_b16 (l_index ,15 ,32 ); 3459 3460float sumf = 0.0f ; 3461for (int i = 0 ;i < nb ;++ i ) { 3462const int8_t * q8 = y [i ].qs ; 3463const uint8_t * qs = x [i ].qs ; 3464const uint8_t * qh = x [i ].qh ; 3465const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3466 3467scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 3468 3469// Accumulators. 3470vint32m2_t acc1 = __riscv_vmv_v_x_i32m2 (0 ,32 ); 3471vint32m2_t acc2 = __riscv_vmv_v_x_i32m2 (0 ,32 ); 3472 3473// We process all the sub-blocks together. 3474#pragma GCC unroll 1 3475for (int ib = 0 ;ib < QK_K /256 ;ib ++ ) { 3476// Load qh for all 16 sub-blocks. 3477const vuint8mf4_t qh_8 = __riscv_vle8_v_u8mf4 (qh ,16 ); 3478const vuint16mf2_t qh_16_lo = __riscv_vzext_vf2_u16mf2 (qh_8 ,16 ); 3479const vuint16mf2_t qh_16_hi = __riscv_vsll_vx_u16mf2 (qh_16_lo ,8 ,16 ); 3480const vuint16m1_t qhb = __riscv_vzext_vf2_u16m1 ( 3481__riscv_vreinterpret_v_u16mf2_u8mf2 (__riscv_vor_vv_u16mf2 (qh_16_lo ,qh_16_hi ,16 )),32 ); 3482 __asm__ __volatile__("" :::"memory" ); 3483 3484// Prepare grid indices. 3485const vuint16m1_t qsb = __riscv_vzext_vf2_u16m1 (__riscv_vle8_v_u8mf2 (& qs [0 ],32 ),32 ); 3486const vuint16m1_t shift = __riscv_vreinterpret_v_u32m1_u16m1 (__riscv_vmv_v_x_u32m1 (0x00040008 ,16 )); 3487vuint16m1_t index = __riscv_vor_vv_u16m1 (qsb ,__riscv_vand_vx_u16m1 (__riscv_vsll_vv_u16m1 (qhb ,shift ,32 ),0x700 ,32 ),32 ); 3488index = __riscv_vsll_vx_u16m1 (index ,3 ,32 ); 3489 __asm__ __volatile__("" :::"memory" ); 3490 3491// Load the grid. 3492const vint8m4_t iq1b = __riscv_vreinterpret_v_i64m4_i8m4 (__riscv_vreinterpret_v_u64m4_i64m4 ( 3493__riscv_vluxei16_v_u64m4 (iq1s_grid ,index ,32 ))); 3494 3495// Prepare the deltas. 3496const vbool16_t mask = __riscv_vmsgtu_vx_u16m1_b16 ( 3497__riscv_vand_vv_u16m1 (qhb ,__riscv_vreinterpret_v_u32m1_u16m1 (__riscv_vmv_v_x_u32m1 (0x00800008 ,16 )),32 ),0 ,32 ); 3498const vint64m4_t delta_pos = __riscv_vmv_v_x_i64m4 (0x0101010101010101 ,32 ); 3499const vint8m4_t delta = __riscv_vreinterpret_v_i64m4_i8m4 ( 3500__riscv_vmerge_vxm_i64m4 (delta_pos ,0xffffffffffffffff ,mask ,32 )); 3501 3502// Load q8 for sub-blocks. 3503const vint8m4_t q8b = __riscv_vle8_v_i8m4 (q8 ,256 ); 3504 3505// Calculate the lsums. 3506const vint16m8_t lsum1 = __riscv_vwmul_vv_i16m8 (iq1b ,q8b ,256 ); 3507const vint16m8_t lsum2 = __riscv_vwmul_vv_i16m8 (delta ,q8b ,256 ); 3508 3509// Prepare the scales. 3510const int16_t ls_0 = 2 * ((sc [0 ] >>0 )& 0x7 )+ 1 ; 3511const int16_t ls_1 = 2 * ((sc [0 ] >>3 )& 0x7 )+ 1 ; 3512const int16_t ls_2 = 2 * ((sc [0 ] >>6 )& 0x7 )+ 1 ; 3513const int16_t ls_3 = 2 * ((sc [0 ] >>9 )& 0x7 )+ 1 ; 3514const int16_t ls_4 = 2 * ((sc [1 ] >>0 )& 0x7 )+ 1 ; 3515const int16_t ls_5 = 2 * ((sc [1 ] >>3 )& 0x7 )+ 1 ; 3516const int16_t ls_6 = 2 * ((sc [1 ] >>6 )& 0x7 )+ 1 ; 3517const int16_t ls_7 = 2 * ((sc [1 ] >>9 )& 0x7 )+ 1 ; 3518const int16_t ls_8 = 2 * ((sc [2 ] >>0 )& 0x7 )+ 1 ; 3519const int16_t ls_9 = 2 * ((sc [2 ] >>3 )& 0x7 )+ 1 ; 3520const int16_t ls_10 = 2 * ((sc [2 ] >>6 )& 0x7 )+ 1 ; 3521const int16_t ls_11 = 2 * ((sc [2 ] >>9 )& 0x7 )+ 1 ; 3522const int16_t ls_12 = 2 * ((sc [3 ] >>0 )& 0x7 )+ 1 ; 3523const int16_t ls_13 = 2 * ((sc [3 ] >>3 )& 0x7 )+ 1 ; 3524const int16_t ls_14 = 2 * ((sc [3 ] >>6 )& 0x7 )+ 1 ; 3525const int16_t ls_15 = 2 * ((sc [3 ] >>9 )& 0x7 )+ 1 ; 3526 3527// Accumulate in acc0 and acc1 for each sub-block. 3528acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_0 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,0 ),16 ); 3529acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_1 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,0 ),32 ); 3530acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_0 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,0 ),16 ); 3531acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_1 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,0 ),32 ); 3532// 3533acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_2 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,1 ),16 ); 3534acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_3 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,1 ),32 ); 3535acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_2 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,1 ),16 ); 3536acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_3 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,1 ),32 ); 3537// 3538acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_4 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,2 ),16 ); 3539acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_5 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,2 ),32 ); 3540acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_4 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,2 ),16 ); 3541acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_5 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,2 ),32 ); 3542// 3543acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_6 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,3 ),16 ); 3544acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_7 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,3 ),32 ); 3545acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_6 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,3 ),16 ); 3546acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_7 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,3 ),32 ); 3547// 3548acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_8 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,4 ),16 ); 3549acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_9 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,4 ),32 ); 3550acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_8 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,4 ),16 ); 3551acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_9 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,4 ),32 ); 3552// 3553acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_10 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,5 ),16 ); 3554acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_11 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,5 ),32 ); 3555acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_10 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,5 ),16 ); 3556acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_11 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,5 ),32 ); 3557// 3558acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_12 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,6 ),16 ); 3559acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_13 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,6 ),32 ); 3560acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_12 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,6 ),16 ); 3561acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_13 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,6 ),32 ); 3562// 3563acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_14 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,7 ),16 ); 3564acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc1 ,ls_15 ,__riscv_vget_v_i16m8_i16m1 (lsum1 ,7 ),32 ); 3565acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_14 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,7 ),16 ); 3566acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask ,acc2 ,ls_15 ,__riscv_vget_v_i16m8_i16m1 (lsum2 ,7 ),32 ); 3567 3568 __asm__ __volatile__("" :::"memory" ); 3569 } 3570 3571// Reduce and accumulate in `sumf`. 3572vint32m1_t one = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3573int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc1 ,one ,32 )); 3574int sumi2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc2 ,one ,32 )); 3575sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )* (sumi1 + IQ1M_DELTA * sumi2 ); 3576 } 3577 3578* s = sumf ; 3579} 3580 3581static NOINLINE void ggml_vec_dot_iq1_m_q8_K_vl1024 (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 ) { 3582assert (n %QK_K == 0 ); 3583assert (nrc == 1 ); 3584UNUSED (nrc ); 3585UNUSED (bx ); 3586UNUSED (by ); 3587UNUSED (bs ); 3588 3589const block_iq1_m * GGML_RESTRICT x = vx ; 3590const block_q8_K * GGML_RESTRICT y = vy ; 3591 3592const int nb = n /QK_K ; 3593 3594iq1m_scale_t scale ; 3595float sumf = 0.0f ; 3596for (int i = 0 ;i < nb ;++ i ) { 3597const int8_t * q8 = y [i ].qs ; 3598const uint8_t * qs = x [i ].qs ; 3599const uint8_t * qh = x [i ].qh ; 3600const uint16_t * sc = (const uint16_t * )x [i ].scales ; 3601 3602scale .u16 = (sc [0 ] >>12 ) | ((sc [1 ] >>8 )& 0x00f0 ) | ((sc [2 ] >>4 )& 0x0f00 ) | (sc [3 ]& 0xf000 ); 3603 3604// Accumulators. 3605vint32m2_t acc1 = __riscv_vmv_v_x_i32m2 (0 ,64 ); 3606vint32m2_t acc2 = __riscv_vmv_v_x_i32m2 (0 ,64 ); 3607 3608// We process all the sub-blocks together. 3609#pragma GCC unroll 1 3610for (int ib = 0 ;ib < QK_K /256 ;ib ++ ) { 3611// Load qh for all 16 sub-blocks. 3612const vuint8mf8_t qh_8 = __riscv_vle8_v_u8mf8 (qh ,16 ); 3613const vuint16mf4_t qh_16_lo = __riscv_vzext_vf2_u16mf4 (qh_8 ,16 ); 3614const vuint16mf4_t qh_16_hi = __riscv_vsll_vx_u16mf4 (qh_16_lo ,8 ,16 ); 3615const vuint16mf2_t qhb = __riscv_vzext_vf2_u16mf2 ( 3616__riscv_vreinterpret_v_u16mf4_u8mf4 (__riscv_vor_vv_u16mf4 (qh_16_lo ,qh_16_hi ,16 )),32 ); 3617 __asm__ __volatile__("" :::"memory" ); 3618 3619// Prepare grid indices. 3620const vuint16mf2_t qsb = __riscv_vzext_vf2_u16mf2 (__riscv_vle8_v_u8mf4 (& qs [0 ],32 ),32 ); 3621const vuint16mf2_t shift = __riscv_vreinterpret_v_u32mf2_u16mf2 (__riscv_vmv_v_x_u32mf2 (0x00040008 ,16 )); 3622vuint16mf2_t index = __riscv_vor_vv_u16mf2 (qsb ,__riscv_vand_vx_u16mf2 (__riscv_vsll_vv_u16mf2 (qhb ,shift ,32 ),0x700 ,32 ),32 ); 3623index = __riscv_vsll_vx_u16mf2 (index ,3 ,32 ); 3624 __asm__ __volatile__("" :::"memory" ); 3625 3626// Load the grid. 3627const vint8m2_t iq1b = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vreinterpret_v_u64m2_i64m2 ( 3628__riscv_vluxei16_v_u64m2 (iq1s_grid ,index ,32 ))); 3629 3630// Prepare the deltas. 3631const vbool32_t mask = __riscv_vmsgtu_vx_u16mf2_b32 ( 3632__riscv_vand_vv_u16mf2 (qhb ,__riscv_vreinterpret_v_u32mf2_u16mf2 (__riscv_vmv_v_x_u32mf2 (0x00800008 ,16 )),32 ),0 ,32 ); 3633const vint64m2_t delta_pos = __riscv_vmv_v_x_i64m2 (0x0101010101010101 ,32 ); 3634const vint8m2_t delta = __riscv_vreinterpret_v_i64m2_i8m2 ( 3635__riscv_vmerge_vxm_i64m2 (delta_pos ,0xffffffffffffffff ,mask ,32 )); 3636 3637// Load q8 for sub-blocks. 3638const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,256 ); 3639 3640// Calculate the lsums. 3641const vint16m4_t lsum1 = __riscv_vwmul_vv_i16m4 (iq1b ,q8b ,256 ); 3642const vint16m4_t lsum2 = __riscv_vwmul_vv_i16m4 (delta ,q8b ,256 ); 3643 3644// Prepare the scales. 3645const int16_t ls_0 = 2 * ((sc [0 ] >>0 )& 0x7 )+ 1 ; 3646const int16_t ls_1 = 2 * ((sc [0 ] >>3 )& 0x7 )+ 1 ; 3647const int16_t ls_2 = 2 * ((sc [0 ] >>6 )& 0x7 )+ 1 ; 3648const int16_t ls_3 = 2 * ((sc [0 ] >>9 )& 0x7 )+ 1 ; 3649const int16_t ls_4 = 2 * ((sc [1 ] >>0 )& 0x7 )+ 1 ; 3650const int16_t ls_5 = 2 * ((sc [1 ] >>3 )& 0x7 )+ 1 ; 3651const int16_t ls_6 = 2 * ((sc [1 ] >>6 )& 0x7 )+ 1 ; 3652const int16_t ls_7 = 2 * ((sc [1 ] >>9 )& 0x7 )+ 1 ; 3653const int16_t ls_8 = 2 * ((sc [2 ] >>0 )& 0x7 )+ 1 ; 3654const int16_t ls_9 = 2 * ((sc [2 ] >>3 )& 0x7 )+ 1 ; 3655const int16_t ls_10 = 2 * ((sc [2 ] >>6 )& 0x7 )+ 1 ; 3656const int16_t ls_11 = 2 * ((sc [2 ] >>9 )& 0x7 )+ 1 ; 3657const int16_t ls_12 = 2 * ((sc [3 ] >>0 )& 0x7 )+ 1 ; 3658const int16_t ls_13 = 2 * ((sc [3 ] >>3 )& 0x7 )+ 1 ; 3659const int16_t ls_14 = 2 * ((sc [3 ] >>6 )& 0x7 )+ 1 ; 3660const int16_t ls_15 = 2 * ((sc [3 ] >>9 )& 0x7 )+ 1 ; 3661 3662// Mask for processing 16 elements per lsum register. 3663const vuint16m1_t l_index = __riscv_vid_v_u16m1 (64 ); 3664 3665// Accumulate in acc1 and acc2 for each sub-block. 3666acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_0 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,0 ),16 ); 3667acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_0 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,0 ),16 ); 3668acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_4 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,1 ),16 ); 3669acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_4 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,1 ),16 ); 3670acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_8 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,2 ),16 ); 3671acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_8 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,2 ),16 ); 3672acc1 = __riscv_vwmacc_vx_i32m2 (acc1 ,ls_12 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,3 ),16 ); 3673acc2 = __riscv_vwmacc_vx_i32m2 (acc2 ,ls_12 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,3 ),16 ); 3674// 3675const vbool16_t l_mask_16_32 = __riscv_vmsgtu_vx_u16m1_b16 (l_index ,15 ,64 ); 3676acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc1 ,ls_1 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,0 ),32 ); 3677acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc2 ,ls_1 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,0 ),32 ); 3678acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc1 ,ls_5 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,1 ),32 ); 3679acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc2 ,ls_5 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,1 ),32 ); 3680acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc1 ,ls_9 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,2 ),32 ); 3681acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc2 ,ls_9 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,2 ),32 ); 3682acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc1 ,ls_13 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,3 ),32 ); 3683acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_16_32 ,acc2 ,ls_13 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,3 ),32 ); 3684// 3685const vbool16_t l_mask_32_48 = __riscv_vmsgtu_vx_u16m1_b16 (l_index ,31 ,64 ); 3686acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc1 ,ls_2 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,0 ),48 ); 3687acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc2 ,ls_2 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,0 ),48 ); 3688acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc1 ,ls_6 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,1 ),48 ); 3689acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc2 ,ls_6 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,1 ),48 ); 3690acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc1 ,ls_10 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,2 ),48 ); 3691acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc2 ,ls_10 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,2 ),48 ); 3692acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc1 ,ls_14 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,3 ),48 ); 3693acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_32_48 ,acc2 ,ls_14 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,3 ),48 ); 3694// 3695const vbool16_t l_mask_48_64 = __riscv_vmsgtu_vx_u16m1_b16 (l_index ,47 ,64 ); 3696acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc1 ,ls_3 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,0 ),64 ); 3697acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc2 ,ls_3 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,0 ),64 ); 3698acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc1 ,ls_7 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,1 ),64 ); 3699acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc2 ,ls_7 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,1 ),64 ); 3700acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc1 ,ls_11 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,2 ),64 ); 3701acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc2 ,ls_11 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,2 ),64 ); 3702acc1 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc1 ,ls_15 ,__riscv_vget_v_i16m4_i16m1 (lsum1 ,3 ),64 ); 3703acc2 = __riscv_vwmacc_vx_i32m2_m (l_mask_48_64 ,acc2 ,ls_15 ,__riscv_vget_v_i16m4_i16m1 (lsum2 ,3 ),64 ); 3704 3705 __asm__ __volatile__("" :::"memory" ); 3706 } 3707 3708// Reduce and accumulate in `sumf`. 3709vint32m1_t one = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3710int sumi1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc1 ,one ,64 )); 3711int sumi2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m2_i32m1 (acc2 ,one ,64 )); 3712sumf += y [i ].d * GGML_CPU_FP16_TO_FP32 (scale .f16 )* (sumi1 + IQ1M_DELTA * sumi2 ); 3713 } 3714 3715* s = sumf ; 3716} 3717#endif 3718 3719void ggml_vec_dot_iq1_m_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 ) { 3720#if defined__riscv_v 3721switch (__riscv_vlenb ()* 8 ) { 3722case 128 : 3723ggml_vec_dot_iq1_m_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3724break ; 3725case 256 : 3726ggml_vec_dot_iq1_m_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3727break ; 3728case 512 : 3729ggml_vec_dot_iq1_m_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3730break ; 3731case 1024 : 3732ggml_vec_dot_iq1_m_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3733break ; 3734default : 3735ggml_vec_dot_iq1_m_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3736break ; 3737 } 3738#else 3739ggml_vec_dot_iq1_m_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 3740#endif 3741} 3742 3743#if defined__riscv_v 3744static const uint8_t sign_gather_indices_arr [64 ]= { 37450 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 ,3 ,3 ,3 ,3 , 37464 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 ,7 ,7 ,7 ,7 3747}; 3748 3749static const uint8_t sign_bit_masks_arr [64 ]= { 37501 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 , 37511 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 3752}; 3753 3754static NOINLINE void ggml_vec_dot_iq2_s_q8_K_vl128 (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 ) { 3755assert (n %QK_K == 0 ); 3756UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 3757 3758const block_iq2_s * GGML_RESTRICT x = vx ; 3759const block_q8_K * GGML_RESTRICT y = vy ; 3760 3761const int nb = n /QK_K ; 3762const uint64_t * grid64 = (const uint64_t * )iq2s_grid ; 3763 3764// Pre-load Constants 3765vuint8m2_t v_ids = __riscv_vid_v_u8m2 (32 ); 3766vuint8m2_t v_sign_gather_indices = __riscv_vsrl_vx_u8m2 (v_ids ,3 ,32 ); 3767vuint8m2_t v_ones = __riscv_vmv_v_x_u8m2 (1 ,32 ); 3768vuint8m2_t v_shift_amts = __riscv_vand_vx_u8m2 (v_ids ,7 ,32 ); 3769vuint8m2_t v_sign_masks = __riscv_vsll_vv_u8m2 (v_ones ,v_shift_amts ,32 ); 3770uint16_t shift_qh_arr [4 ]= {11 ,9 ,7 ,5 }; 3771vuint16mf2_t v_shift_qh = __riscv_vle16_v_u16mf2 (shift_qh_arr ,4 ); 3772 3773float sumf = 0.0f ; 3774 3775for (int i = 0 ;i < nb ;++ i ) { 3776const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3777 3778const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3779const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3780const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 3781const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3782 3783const uint8_t * signs_ptr = qs + 32 ; 3784float sum_block = 0.0f ; 3785 3786for (int ib = 0 ;ib < 8 ;++ ib ) { 3787 3788// Load Low Bits [4 bytes] 3789vuint8mf4_t v_qs_u8 = __riscv_vle8_v_u8mf4 (qs ,4 ); 3790qs += 4 ; 3791 3792// Load 1 byte. It contains bits for 4 mini-blocks. 3793uint8_t qh_val = * qh ++ ; 3794 3795// Combine Low + High bits of 10bit indices 3796vuint8mf4_t v_qh_raw = __riscv_vmv_v_x_u8mf4 (qh_val ,4 ); 3797vuint16mf2_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16mf2 (v_qh_raw ,4 ); 3798vuint16mf2_t v_qh_mf2 = __riscv_vsll_vv_u16mf2 (v_qh_u16 ,v_shift_qh ,4 ); 3799v_qh_mf2 = __riscv_vand_vx_u16mf2 (v_qh_mf2 ,0x1800 ,4 ); 3800vuint16mf2_t v_qs_u16_mf2 = __riscv_vwcvtu_x_x_v_u16mf2 (v_qs_u8 ,4 ); 3801vuint16mf2_t v_qs_u16 = __riscv_vsll_vx_u16mf2 (v_qs_u16_mf2 ,3 ,4 ); 3802vuint16mf2_t v_grid_offsets = __riscv_vor_vv_u16mf2 (v_qs_u16 ,v_qh_mf2 ,4 ); 3803 3804// Lookup Grid 3805vint8m2_t v_grid_i8 = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (__riscv_vluxei16_v_u64m2 (grid64 ,v_grid_offsets ,4 ))); 3806 3807vuint8mf4_t v_signs_raw = __riscv_vle8_v_u8mf4 (signs_ptr ,4 ); 3808signs_ptr += 4 ; 3809vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf4_u8m2 (v_signs_raw ); 3810vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,32 ); 3811 3812// generating sign mask 3813vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,32 ); 3814vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,32 ); 3815 3816vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,32 ); 3817q8 += 32 ; 3818 3819// apply signs 3820vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,32 ); 3821vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_grid_i8 ,v_q8_signed ,32 ); 3822 3823// Reduction 3824vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3825 3826// Reduce 0-15 (First Half) 3827int32_t s0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 3828__riscv_vget_v_i16m4_i16m2 (v_dot ,0 ),v_zero ,16 )); 3829 3830// Reduce 16-31 (Second Half) 3831int32_t s1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 3832__riscv_vget_v_i16m4_i16m2 (v_dot ,1 ),v_zero ,16 )); 3833 3834// Apply sub Scales 3835uint8_t sc = * scales ++ ; 3836 3837sum_block += s0 * (2 * (sc & 0xF )+ 1 ); 3838sum_block += s1 * (2 * (sc >>4 )+ 1 ); 3839 } 3840sumf += sum_block * combined_scale ; 3841 } 3842* s = 0.125f * sumf ; 3843} 3844 3845static NOINLINE void ggml_vec_dot_iq2_s_q8_K_vl256 (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 ) { 3846assert (n %QK_K == 0 ); 3847UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 3848 3849const block_iq2_s * GGML_RESTRICT x = vx ; 3850const block_q8_K * GGML_RESTRICT y = vy ; 3851 3852const int nb = n /QK_K ; 3853const uint64_t * grid64 = (const uint64_t * )iq2s_grid ; 3854 3855// --- Pre-load Constants --- 3856uint16_t gather_qh_arr [8 ]= {0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 }; 3857vuint16mf2_t v_gather_qh = __riscv_vle16_v_u16mf2 (gather_qh_arr ,8 ); 3858uint16_t shift_qh_arr [8 ]= {11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 }; 3859vuint16mf2_t v_shift_qh = __riscv_vle16_v_u16mf2 (shift_qh_arr ,8 ); 3860 3861// Constants for sign extraction 3862vuint8m2_t v_sign_gather_indices = __riscv_vle8_v_u8m2 (sign_gather_indices_arr ,64 ); 3863vuint8m2_t v_sign_masks = __riscv_vle8_v_u8m2 (sign_bit_masks_arr ,64 ); 3864 3865float sumf = 0.0f ; 3866 3867for (int i = 0 ;i < nb ;++ i ) { 3868const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3869 3870const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3871const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3872const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 3873const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3874 3875const uint8_t * signs_ptr = qs + 32 ; 3876 3877float sum_block = 0.0f ; 3878 3879for (int ib = 0 ;ib < 4 ;++ ib ) { 3880// Combine low + high bits 3881vuint8mf4_t v_qs_u8 = __riscv_vle8_v_u8mf4 (qs ,8 ); 3882qs += 8 ; 3883uint16_t qh_val ; 3884memcpy (& qh_val ,qh ,2 ); 3885qh += 2 ; 3886vuint8mf8_t v_qh_raw = __riscv_vle8_v_u8mf8 ((const uint8_t * )& qh_val ,2 ); 3887vuint16mf4_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16mf4 (v_qh_raw ,2 ); 3888vuint16mf2_t v_qh_u16_ext = __riscv_vlmul_ext_v_u16mf4_u16mf2 (v_qh_u16 ); 3889vuint16mf2_t v_qh_expanded = __riscv_vrgather_vv_u16mf2 (v_qh_u16_ext ,v_gather_qh ,8 ); 3890v_qh_expanded = __riscv_vsll_vv_u16mf2 (v_qh_expanded ,v_shift_qh ,8 ); 3891 3892// Mask: We want bits 11-12. 0x1800 = 0001 1000 0000 0000 3893v_qh_expanded = __riscv_vand_vx_u16mf2 (v_qh_expanded ,0x1800 ,8 ); 3894vuint16mf2_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16mf2 (v_qs_u8 ,8 ); 3895 3896// Multiply by 8 to get byte offset, instead of element offset 3897v_qs_u16 = __riscv_vsll_vx_u16mf2 (v_qs_u16 ,3 ,8 ); 3898vuint16mf2_t v_grid_offsets = __riscv_vor_vv_u16mf2 (v_qs_u16 ,v_qh_expanded ,8 ); 3899 3900// Lookup Grid using Byte Offsets 3901vuint64m2_t v_grid_vals = __riscv_vluxei16_v_u64m2 (grid64 ,v_grid_offsets ,8 ); 3902 3903vuint8m2_t v_grid_u8 = __riscv_vreinterpret_v_u64m2_u8m2 (v_grid_vals ); 3904vint8m2_t v_grid_i8 = __riscv_vreinterpret_v_u8m2_i8m2 (v_grid_u8 ); 3905 3906// Load signs and generate sign mask 3907vuint8mf4_t v_signs_raw = __riscv_vle8_v_u8mf4 (signs_ptr ,8 ); 3908signs_ptr += 8 ; 3909 3910vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf4_u8m2 (v_signs_raw ); 3911vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,64 ); 3912 3913vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,64 ); 3914vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,64 ); 3915 3916vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,64 ); 3917q8 += 64 ; 3918 3919vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,64 ); 3920vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_grid_i8 ,v_q8_signed ,64 ); 3921 3922vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 3923 3924int32_t s0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 3925__riscv_vget_v_i16m4_i16m1 (v_dot ,0 ),v_zero ,16 )); 3926int32_t s1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 3927__riscv_vget_v_i16m4_i16m1 (v_dot ,1 ),v_zero ,16 )); 3928int32_t s2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 3929__riscv_vget_v_i16m4_i16m1 (v_dot ,2 ),v_zero ,16 )); 3930int32_t s3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 3931__riscv_vget_v_i16m4_i16m1 (v_dot ,3 ),v_zero ,16 )); 3932 3933uint8_t sc0 = scales [0 ]; 3934uint8_t sc1 = scales [1 ]; 3935scales += 2 ; 3936 3937sum_block += s0 * (2 * (sc0 & 0xF )+ 1 ); 3938sum_block += s1 * (2 * (sc0 >>4 )+ 1 ); 3939sum_block += s2 * (2 * (sc1 & 0xF )+ 1 ); 3940sum_block += s3 * (2 * (sc1 >>4 )+ 1 ); 3941 } 3942sumf += sum_block * combined_scale ; 3943 } 3944* s = 0.125f * sumf ; 3945} 3946 3947static NOINLINE void ggml_vec_dot_iq2_s_q8_K_vl512 (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 ) { 3948assert (n %QK_K == 0 ); 3949UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 3950 3951const block_iq2_s * GGML_RESTRICT x = vx ; 3952const block_q8_K * GGML_RESTRICT y = vy ; 3953 3954const int nb = n /QK_K ; 3955const uint64_t * grid64 = (const uint64_t * )iq2s_grid ; 3956 3957vuint8m2_t v_ids = __riscv_vid_v_u8m2 (128 ); 3958vuint8m2_t v_sign_gather_indices = __riscv_vsrl_vx_u8m2 (v_ids ,3 ,128 ); 3959 3960vuint8m2_t v_ones = __riscv_vmv_v_x_u8m2 (1 ,128 ); 3961vuint8m2_t v_shift_amts = __riscv_vand_vx_u8m2 (v_ids ,7 ,128 ); 3962vuint8m2_t v_sign_masks = __riscv_vsll_vv_u8m2 (v_ones ,v_shift_amts ,128 ); 3963 3964uint16_t gather_qh_arr [16 ]= {0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 }; 3965vuint16mf2_t v_gather_qh = __riscv_vle16_v_u16mf2 (gather_qh_arr ,16 ); 3966 3967uint16_t shift_qh_arr [16 ]= {11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 }; 3968vuint16mf2_t v_shift_qh = __riscv_vle16_v_u16mf2 (shift_qh_arr ,16 ); 3969 3970// Masks for selecting lower/upper 16 lanes within a 32-lane i16m1 register 3971vuint16m1_t v_ids16 = __riscv_vid_v_u16m1 (32 ); 3972vbool16_t m_hi16 = __riscv_vmsgeu_vx_u16m1_b16 (v_ids16 ,16 ,32 ); 3973float sumf = 0.0f ; 3974 3975for (int i = 0 ;i < nb ;++ i ) { 3976const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 3977 3978const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 3979const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 3980const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 3981const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 3982 3983const uint8_t * signs_ptr = qs + 32 ; 3984 3985float sum_block = 0.0f ; 3986 3987for (int ib = 0 ;ib < 2 ;++ ib ) { 3988vuint8mf4_t v_qs_u8 = __riscv_vle8_v_u8mf4 (qs ,16 ); 3989qs += 16 ; 3990 3991vuint8mf8_t v_qh_raw = __riscv_vle8_v_u8mf8 (qh ,4 ); 3992qh += 4 ; 3993 3994vuint16mf4_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16mf4 (v_qh_raw ,4 ); 3995vuint16mf2_t v_qh_u16_ext = __riscv_vlmul_ext_v_u16mf4_u16mf2 (v_qh_u16 ); 3996vuint16mf2_t v_qh_expanded = __riscv_vrgather_vv_u16mf2 (v_qh_u16_ext ,v_gather_qh ,16 ); 3997v_qh_expanded = __riscv_vsll_vv_u16mf2 (v_qh_expanded ,v_shift_qh ,16 ); 3998v_qh_expanded = __riscv_vand_vx_u16mf2 (v_qh_expanded ,0x1800 ,16 ); 3999 4000vuint16mf2_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16mf2 (v_qs_u8 ,16 ); 4001v_qs_u16 = __riscv_vsll_vx_u16mf2 (v_qs_u16 ,3 ,16 ); 4002 4003vuint16mf2_t v_grid_offsets = __riscv_vor_vv_u16mf2 (v_qs_u16 ,v_qh_expanded ,16 ); 4004vuint64m2_t v_grid_vals = __riscv_vluxei16_v_u64m2 (grid64 ,v_grid_offsets ,16 ); 4005vuint8m2_t v_grid_u8 = __riscv_vreinterpret_v_u64m2_u8m2 (v_grid_vals ); 4006vint8m2_t v_grid_i8 = __riscv_vreinterpret_v_u8m2_i8m2 (v_grid_u8 ); 4007 4008vuint8mf4_t v_signs_raw = __riscv_vle8_v_u8mf4 (signs_ptr ,16 ); 4009signs_ptr += 16 ; 4010 4011vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf4_u8m2 (v_signs_raw ); 4012vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,128 ); 4013vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,128 ); 4014vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,128 ); 4015vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,128 ); 4016q8 += 128 ; 4017 4018vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,128 ); 4019vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_grid_i8 ,v_q8_signed ,128 ); 4020 4021vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4022vint16m1_t v0 = __riscv_vget_v_i16m4_i16m1 (v_dot ,0 ); 4023vint16m1_t v1 = __riscv_vget_v_i16m4_i16m1 (v_dot ,1 ); 4024vint16m1_t v2 = __riscv_vget_v_i16m4_i16m1 (v_dot ,2 ); 4025vint16m1_t v3 = __riscv_vget_v_i16m4_i16m1 (v_dot ,3 ); 4026 4027int32_t s0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (v0 ,v_zero ,16 )); 4028int32_t s1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (m_hi16 ,v0 ,v_zero ,32 )); 4029int32_t s2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (v1 ,v_zero ,16 )); 4030int32_t s3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (m_hi16 ,v1 ,v_zero ,32 )); 4031int32_t s4 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (v2 ,v_zero ,16 )); 4032int32_t s5 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (m_hi16 ,v2 ,v_zero ,32 )); 4033int32_t s6 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (v3 ,v_zero ,16 )); 4034int32_t s7 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (m_hi16 ,v3 ,v_zero ,32 )); 4035 4036uint8_t sc0 = scales [0 ]; 4037uint8_t sc1 = scales [1 ]; 4038uint8_t sc2 = scales [2 ]; 4039uint8_t sc3 = scales [3 ]; 4040scales += 4 ; 4041 4042sum_block += s0 * (2 * (sc0 & 0xF )+ 1 ); 4043sum_block += s1 * (2 * (sc0 >>4 )+ 1 ); 4044sum_block += s2 * (2 * (sc1 & 0xF )+ 1 ); 4045sum_block += s3 * (2 * (sc1 >>4 )+ 1 ); 4046sum_block += s4 * (2 * (sc2 & 0xF )+ 1 ); 4047sum_block += s5 * (2 * (sc2 >>4 )+ 1 ); 4048sum_block += s6 * (2 * (sc3 & 0xF )+ 1 ); 4049sum_block += s7 * (2 * (sc3 >>4 )+ 1 ); 4050 } 4051 4052sumf += sum_block * combined_scale ; 4053 } 4054* s = 0.125f * sumf ; 4055} 4056 4057static NOINLINE void ggml_vec_dot_iq2_s_q8_K_vl1024 (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 ) { 4058assert (n %QK_K == 0 ); 4059UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 4060 4061const block_iq2_s * GGML_RESTRICT x = vx ; 4062const block_q8_K * GGML_RESTRICT y = vy ; 4063 4064const int nb = n /QK_K ; 4065const uint64_t * grid64 = (const uint64_t * )iq2s_grid ; 4066vuint8m2_t v_ids = __riscv_vid_v_u8m2 (256 ); 4067vuint8m2_t v_sign_gather_indices = __riscv_vsrl_vx_u8m2 (v_ids ,3 ,256 ); 4068 4069vuint8m2_t v_ones = __riscv_vmv_v_x_u8m2 (1 ,256 ); 4070vuint8m2_t v_shift_amts = __riscv_vand_vx_u8m2 (v_ids ,7 ,256 ); 4071vuint8m2_t v_sign_masks = __riscv_vsll_vv_u8m2 (v_ones ,v_shift_amts ,256 ); 4072 4073uint16_t gather_qh_arr [32 ]= { 40740 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 , 40754 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 4076 }; 4077vuint16mf2_t v_gather_qh = __riscv_vle16_v_u16mf2 (gather_qh_arr ,32 ); 4078 4079uint16_t shift_qh_arr [32 ]= { 408011 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 , 408111 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 ,11 ,9 ,7 ,5 4082 }; 4083vuint16mf2_t v_shift_qh = __riscv_vle16_v_u16mf2 (shift_qh_arr ,32 ); 4084 4085// Masks for 4 groups of 16 lanes within a 64-lane i16m4 chunk 4086vuint16m4_t v_ids64 = __riscv_vid_v_u16m4 (64 ); 4087vbool4_t m_g0 = __riscv_vmsltu_vx_u16m4_b4 (v_ids64 ,16 ,64 ); 4088vbool4_t m_g1 = __riscv_vmand_mm_b4 ( 4089__riscv_vmsgeu_vx_u16m4_b4 (v_ids64 ,16 ,64 ), 4090__riscv_vmsltu_vx_u16m4_b4 (v_ids64 ,32 ,64 ),64 ); 4091vbool4_t m_g2 = __riscv_vmand_mm_b4 ( 4092__riscv_vmsgeu_vx_u16m4_b4 (v_ids64 ,32 ,64 ), 4093__riscv_vmsltu_vx_u16m4_b4 (v_ids64 ,48 ,64 ),64 ); 4094vbool4_t m_g3 = __riscv_vmsgeu_vx_u16m4_b4 (v_ids64 ,48 ,64 ); 4095 4096float sumf = 0.0f ; 4097 4098for (int i = 0 ;i < nb ;++ i ) { 4099const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4100 4101const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 4102const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 4103const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4104const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4105 4106const uint8_t * signs_ptr = qs + 32 ; 4107 4108float sum_block = 0.0f ; 4109 4110vuint8mf4_t v_qs_u8 = __riscv_vle8_v_u8mf4 (qs ,32 ); 4111qs += 32 ; 4112 4113vuint8mf8_t v_qh_raw = __riscv_vle8_v_u8mf8 (qh ,8 ); 4114qh += 8 ; 4115 4116vuint16mf4_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16mf4 (v_qh_raw ,8 ); 4117vuint16mf2_t v_qh_u16_ext = __riscv_vlmul_ext_v_u16mf4_u16mf2 (v_qh_u16 ); 4118vuint16mf2_t v_qh_expanded = __riscv_vrgather_vv_u16mf2 (v_qh_u16_ext ,v_gather_qh ,32 ); 4119v_qh_expanded = __riscv_vsll_vv_u16mf2 (v_qh_expanded ,v_shift_qh ,32 ); 4120v_qh_expanded = __riscv_vand_vx_u16mf2 (v_qh_expanded ,0x1800 ,32 ); 4121 4122vuint16mf2_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16mf2 (v_qs_u8 ,32 ); 4123v_qs_u16 = __riscv_vsll_vx_u16mf2 (v_qs_u16 ,3 ,32 ); 4124 4125vuint16mf2_t v_grid_offsets = __riscv_vor_vv_u16mf2 (v_qs_u16 ,v_qh_expanded ,32 ); 4126vuint64m2_t v_grid_vals = __riscv_vluxei16_v_u64m2 (grid64 ,v_grid_offsets ,32 ); 4127vuint8m2_t v_grid_u8 = __riscv_vreinterpret_v_u64m2_u8m2 (v_grid_vals ); 4128vint8m2_t v_grid_i8 = __riscv_vreinterpret_v_u8m2_i8m2 (v_grid_u8 ); 4129 4130//loading signs 4131vuint8mf2_t v_signs_raw = __riscv_vle8_v_u8mf2 (signs_ptr ,32 ); 4132signs_ptr += 32 ; 4133 4134vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf2_u8m2 (v_signs_raw ); 4135vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,256 ); 4136vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,256 ); 4137vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,256 ); 4138 4139vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,256 ); 4140q8 += 256 ; 4141 4142vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,256 ); 4143vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_grid_i8 ,v_q8_signed ,256 ); 4144 4145vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4146 4147vint16m4_t c = v_dot ; 4148 4149int32_t s0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g0 ,c ,v_zero ,64 )); 4150int32_t s1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g1 ,c ,v_zero ,64 )); 4151int32_t s2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g2 ,c ,v_zero ,64 )); 4152int32_t s3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g3 ,c ,v_zero ,64 )); 4153 4154c = __riscv_vslidedown_vx_i16m4 (c ,64 ,256 ); 4155int32_t s4 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g0 ,c ,v_zero ,64 )); 4156int32_t s5 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g1 ,c ,v_zero ,64 )); 4157int32_t s6 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g2 ,c ,v_zero ,64 )); 4158int32_t s7 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g3 ,c ,v_zero ,64 )); 4159 4160c = __riscv_vslidedown_vx_i16m4 (c ,64 ,256 ); 4161int32_t s8 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g0 ,c ,v_zero ,64 )); 4162int32_t s9 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g1 ,c ,v_zero ,64 )); 4163int32_t s10 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g2 ,c ,v_zero ,64 )); 4164int32_t s11 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g3 ,c ,v_zero ,64 )); 4165 4166c = __riscv_vslidedown_vx_i16m4 (c ,64 ,256 ); 4167int32_t s12 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g0 ,c ,v_zero ,64 )); 4168int32_t s13 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g1 ,c ,v_zero ,64 )); 4169int32_t s14 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g2 ,c ,v_zero ,64 )); 4170int32_t s15 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1_m (m_g3 ,c ,v_zero ,64 )); 4171 4172int32_t sums_arr [16 ]= {s0 ,s1 ,s2 ,s3 ,s4 ,s5 ,s6 ,s7 ,s8 ,s9 ,s10 ,s11 ,s12 ,s13 ,s14 ,s15 }; 4173 4174// Load 8 scale bytes and split into 16 nibbles 4175vuint8mf2_t v_sc8 = __riscv_vle8_v_u8mf2 (scales ,8 ); 4176scales += 8 ; 4177 4178vuint8mf2_t v_lo8 = __riscv_vand_vx_u8mf2 (v_sc8 ,0x0F ,8 ); 4179vuint8mf2_t v_hi8 = __riscv_vsrl_vx_u8mf2 (v_sc8 ,4 ,8 ); 4180 4181vuint8m1_t v_idx16 = __riscv_vid_v_u8m1 (16 ); 4182vuint8m1_t v_half = __riscv_vsrl_vx_u8m1 (v_idx16 ,1 ,16 ); 4183vbool8_t m_even = __riscv_vmseq_vx_u8m1_b8 (__riscv_vand_vx_u8m1 (v_idx16 ,1 ,16 ),0 ,16 ); 4184 4185vuint8m1_t v_lo_ext = __riscv_vlmul_ext_v_u8mf2_u8m1 (v_lo8 ); 4186vuint8m1_t v_hi_ext = __riscv_vlmul_ext_v_u8mf2_u8m1 (v_hi8 ); 4187vuint8m1_t v_lo_g = __riscv_vrgather_vv_u8m1 (v_lo_ext ,v_half ,16 ); 4188vuint8m1_t v_hi_g = __riscv_vrgather_vv_u8m1 (v_hi_ext ,v_half ,16 ); 4189vuint8m1_t v_nib = __riscv_vmerge_vvm_u8m1 (v_lo_g ,v_hi_g ,m_even ,16 ); 4190 4191static const uint8_t iq2s_scale_lut_16_local [16 ]= { 41921 ,3 ,5 ,7 ,9 ,11 ,13 ,15 ,17 ,19 ,21 ,23 ,25 ,27 ,29 ,31 4193 }; 4194vuint8m1_t v_lut = __riscv_vle8_v_u8m1 (iq2s_scale_lut_16_local ,16 ); 4195vuint8m1_t v_sc8v = __riscv_vrgather_vv_u8m1 (v_lut ,v_nib ,16 ); 4196 4197vint32m4_t v_sums = __riscv_vle32_v_i32m4 (sums_arr ,16 ); 4198vuint16m2_t v_sc16 = __riscv_vwcvtu_x_x_v_u16m2 (v_sc8v ,16 ); 4199vuint32m4_t v_sc32u = __riscv_vwcvtu_x_x_v_u32m4 (v_sc16 ,16 ); 4200vint32m4_t v_sc32 = __riscv_vreinterpret_v_u32m4_i32m4 (v_sc32u ); 4201vint32m4_t v_prod = __riscv_vmul_vv_i32m4 (v_sums ,v_sc32 ,16 ); 4202 4203vint32m1_t v_zero32 = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4204int32_t sum_part = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m4_i32m1 (v_prod ,v_zero32 ,16 )); 4205sum_block += sum_part ; 4206 4207sumf += sum_block * combined_scale ; 4208 } 4209* s = 0.125f * sumf ; 4210} 4211#endif 4212 4213void 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 ) { 4214#if defined__riscv_v 4215switch (__riscv_vlenb ()* 8 ) { 4216case 128 : 4217ggml_vec_dot_iq2_s_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4218break ; 4219case 256 : 4220ggml_vec_dot_iq2_s_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4221break ; 4222case 512 : 4223ggml_vec_dot_iq2_s_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4224break ; 4225default : 4226ggml_vec_dot_iq2_s_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4227break ; 4228 } 4229#else 4230ggml_vec_dot_iq2_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4231#endif 4232} 4233 4234#if defined__riscv_v 4235static const int8_t keven_signs_q2xs [1024 ]= { 42361 ,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 , 42371 ,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 , 42381 ,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 , 42391 ,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 , 42401 ,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 , 42411 ,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 , 42421 ,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 , 42431 ,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 , 42441 ,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 , 42451 ,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 , 42461 ,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 , 42471 ,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 , 42481 ,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 , 42491 ,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 , 42501 ,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 , 42511 ,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 , 42521 ,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 , 42531 ,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 , 42541 ,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 , 42551 ,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 , 42561 ,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 , 42571 ,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 , 42581 ,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 , 42591 ,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 , 42601 ,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 , 42611 ,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 , 42621 ,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 , 42631 ,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 , 42641 ,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 , 42651 ,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 , 42661 ,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 , 42671 ,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 , 4268}; 4269 4270static NOINLINE void ggml_vec_dot_iq2_xs_q8_K_vl128 (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 ) { 4271assert (n %QK_K == 0 ); 4272assert (nrc == 1 ); 4273UNUSED (nrc ); 4274UNUSED (bx ); 4275UNUSED (by ); 4276UNUSED (bs ); 4277 4278const block_iq2_xs * GGML_RESTRICT x = vx ; 4279const block_q8_K * GGML_RESTRICT y = vy ; 4280 4281const int nb = n /QK_K ; 4282const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4283const uint64_t * grid64 = (const uint64_t * )iq2xs_grid ; 4284 4285float sumf = 0.0f ; 4286#pragma GCC unroll 1 4287for (int i = 0 ;i < nb ;++ i ) { 4288const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4289const uint16_t * GGML_RESTRICT qs = x [i ].qs ; 4290const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4291const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4292 4293int32_t sum_int = 0 ; 4294 4295// Loop over 4 subblocks of 64 elements 4296for (int ib64 = 0 ;ib64 < QK_K /64 ;++ ib64 ) { 4297 4298// Load indices. 4299vuint16m1_t v_qs = __riscv_vle16_v_u16m1 (qs ,8 ); 4300qs += 8 ; 4301 4302// Prepare offsets 4303vuint16m1_t vidx_grid = __riscv_vsll_vx_u16m1 (__riscv_vand_vx_u16m1 (v_qs ,511 ,8 ),3 ,8 ); 4304vuint16m1_t vidx_sign = __riscv_vsll_vx_u16m1 (__riscv_vsrl_vx_u16m1 (v_qs ,9 ,8 ),3 ,8 ); 4305 4306// load values and signs from the lookup tables 4307vuint64m4_t vq2_64 = __riscv_vluxei16_v_u64m4 (grid64 ,vidx_grid ,8 ); 4308vuint64m4_t vs2_64 = __riscv_vluxei16_v_u64m4 (signs64 ,vidx_sign ,8 ); 4309vint8m4_t q2u = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vq2_64 )); 4310vint8m4_t q2s = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vs2_64 )); 4311vint8m4_t q2_final = __riscv_vmul_vv_i8m4 (q2u ,q2s ,64 ); 4312 asmvolatile ("" :::"memory" ); 4313vint8m4_t q8v = __riscv_vle8_v_i8m4 (q8 ,64 ); 4314q8 += 64 ; 4315 4316vint16m8_t prod = __riscv_vwmul_vv_i16m8 (q2_final ,q8v ,64 ); 4317 asmvolatile ("" :::"memory" ); 4318vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4319 4320int32_t sum0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 4321__riscv_vget_v_i16m8_i16m2 (prod ,0 ),zero_vec ,16 )); 4322 4323int32_t sum1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 4324__riscv_vget_v_i16m8_i16m2 (prod ,1 ),zero_vec ,16 )); 4325 4326int32_t sum2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 4327__riscv_vget_v_i16m8_i16m2 (prod ,2 ),zero_vec ,16 )); 4328 4329int32_t sum3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 ( 4330__riscv_vget_v_i16m8_i16m2 (prod ,3 ),zero_vec ,16 )); 4331 4332const uint8_t scale_byte_1 = scales [0 ]; 4333const uint8_t scale_byte_2 = scales [1 ]; 4334scales += 2 ; 4335 4336sum_int += sum0 * ((scale_byte_1 & 0x0F )* 2 + 1 ); 4337sum_int += sum1 * ((scale_byte_1 >>4 )* 2 + 1 ); 4338sum_int += sum2 * ((scale_byte_2 & 0x0F )* 2 + 1 ); 4339sum_int += sum3 * ((scale_byte_2 >>4 )* 2 + 1 ); 4340 } 4341 4342sumf += d * sum_int ; 4343 } 4344* s = 0.125f * sumf ; 4345} 4346 4347static NOINLINE void ggml_vec_dot_iq2_xs_q8_K_vl256 (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 ) { 4348assert (n %QK_K == 0 ); 4349assert (nrc == 1 ); 4350UNUSED (nrc ); 4351UNUSED (bx ); 4352UNUSED (by ); 4353UNUSED (bs ); 4354 4355const block_iq2_xs * GGML_RESTRICT x = vx ; 4356const block_q8_K * GGML_RESTRICT y = vy ; 4357 4358const int nb = n /QK_K ; 4359const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4360const uint64_t * grid64 = (const uint64_t * )iq2xs_grid ; 4361 4362float sumf = 0.0f ; 4363 4364for (int i = 0 ;i < nb ;++ i ) { 4365const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4366const uint16_t * GGML_RESTRICT qs = x [i ].qs ; 4367const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4368const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4369 4370int32_t sum_int = 0 ; 4371 4372for (int ib128 = 0 ;ib128 < 2 ;++ ib128 ) { 4373 4374vuint16m1_t v_qs = __riscv_vle16_v_u16m1 (qs ,16 ); 4375qs += 16 ; 4376 4377// Prepare offsets for grid and signs 4378vuint16m1_t vidx_grid = __riscv_vsll_vx_u16m1 (__riscv_vand_vx_u16m1 (v_qs ,511 ,16 ),3 ,16 ); 4379vuint16m1_t vidx_sign = __riscv_vsll_vx_u16m1 (__riscv_vsrl_vx_u16m1 (v_qs ,9 ,16 ),3 ,16 ); 4380 4381// Indexed load 128 weights (16 x 8-byte chunks) 4382vuint64m4_t vq2_64 = __riscv_vluxei16_v_u64m4 (grid64 ,vidx_grid ,16 ); 4383vuint64m4_t vs2_64 = __riscv_vluxei16_v_u64m4 (signs64 ,vidx_sign ,16 ); 4384 4385vint8m4_t q2u = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vq2_64 )); 4386vint8m4_t q2s = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vs2_64 )); 4387 4388// Apply signs to get dequantized IQ2 values 4389vint8m4_t q2_final = __riscv_vmul_vv_i8m4 (q2u ,q2s ,128 ); 4390 asmvolatile ("" :::"memory" ); 4391 4392// Load corresponding Q8 weights 4393vint8m4_t q8v = __riscv_vle8_v_i8m4 (q8 ,128 ); 4394q8 += 128 ; 4395 4396vint16m8_t prod = __riscv_vwmul_vv_i16m8 (q2_final ,q8v ,128 ); 4397 asmvolatile ("" :::"memory" ); 4398 4399uint8_t sc0 = scales [0 ]; 4400uint8_t sc1 = scales [1 ]; 4401uint8_t sc2 = scales [2 ]; 4402uint8_t sc3 = scales [3 ]; 4403scales += 4 ; 4404 4405vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4406 4407// 9. Reduce each 16-element chunk and apply corresponding nibble scale 4408 4409int32_t s0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,0 ),zero_vec ,16 )); 4410sum_int += s0 * ((sc0 & 0x0F )* 2 + 1 ); 4411 4412int32_t s1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,1 ),zero_vec ,16 )); 4413sum_int += s1 * ((sc0 >>4 )* 2 + 1 ); 4414 4415int32_t s2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,2 ),zero_vec ,16 )); 4416sum_int += s2 * ((sc1 & 0x0F )* 2 + 1 ); 4417 4418int32_t s3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,3 ),zero_vec ,16 )); 4419sum_int += s3 * ((sc1 >>4 )* 2 + 1 ); 4420 4421int32_t s4 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,4 ),zero_vec ,16 )); 4422sum_int += s4 * ((sc2 & 0x0F )* 2 + 1 ); 4423 4424int32_t s5 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,5 ),zero_vec ,16 )); 4425sum_int += s5 * ((sc2 >>4 )* 2 + 1 ); 4426 4427int32_t s6 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,6 ),zero_vec ,16 )); 4428sum_int += s6 * ((sc3 & 0x0F )* 2 + 1 ); 4429 4430int32_t s7 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,7 ),zero_vec ,16 )); 4431sum_int += s7 * ((sc3 >>4 )* 2 + 1 ); 4432 } 4433 4434sumf += d * (float )sum_int ; 4435 } 4436* s = 0.125f * sumf ; 4437} 4438 4439static NOINLINE void ggml_vec_dot_iq2_xs_q8_K_vl512 (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 ) { 4440assert (n %QK_K == 0 ); 4441assert (nrc == 1 ); 4442UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 4443 4444const block_iq2_xs * GGML_RESTRICT x = vx ; 4445const block_q8_K * GGML_RESTRICT y = vy ; 4446 4447const int nb = n /QK_K ; 4448const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4449const uint64_t * grid64 = (const uint64_t * )iq2xs_grid ; 4450 4451float sumf = 0.0f ; 4452for (int i = 0 ;i < nb ;++ i ) { 4453const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4454 4455const uint16_t * GGML_RESTRICT qs = x [i ].qs ; 4456const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4457const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4458 4459vint8m4_t q8_all = __riscv_vle8_v_i8m4 (q8 ,256 ); 4460 4461// Load indices --- 4462vuint16m1_t v_qs = __riscv_vle16_v_u16m1 (qs ,32 ); 4463 4464// Extract low 9 bits and multiply by 8 (shift left 3) for byte offset into uint64 table 4465vuint16m1_t vidx_grid = __riscv_vsll_vx_u16m1 (__riscv_vand_vx_u16m1 (v_qs ,511 ,32 ),3 ,32 ); 4466 4467// Extract high 7 bits (shift right 9) and multiply by 8 (shift left 3) for byte offset 4468vuint16m1_t vidx_sign = __riscv_vsll_vx_u16m1 (__riscv_vsrl_vx_u16m1 (v_qs ,9 ,32 ),3 ,32 ); 4469 4470vuint64m4_t vq2_64 = __riscv_vluxei16_v_u64m4 (grid64 ,vidx_grid ,32 ); 4471vuint64m4_t vs2_64 = __riscv_vluxei16_v_u64m4 (signs64 ,vidx_sign ,32 ); 4472 4473vint8m4_t q2_all = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vq2_64 )); 4474vint8m4_t s2_all = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vs2_64 )); 4475 4476vint8m4_t q2_signed = __riscv_vmul_vv_i8m4 (q2_all ,s2_all ,256 ); 4477vint16m8_t dot_all = __riscv_vwmul_vv_i16m8 (q2_signed ,q8_all ,256 ); 4478float sum = 0.0f ; 4479vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4480 4481#pragma GCC unroll 1 4482for (int j = 0 ;j < 8 ;++ j ) { 4483uint8_t sc = scales [j ]; 4484int16_t sc_lo = 2 * (sc & 0x0F )+ 1 ; 4485int16_t sc_hi = 2 * (sc >>4 )+ 1 ; 4486 4487vint32m1_t sum_v0 = __riscv_vwredsum_vs_i16m8_i32m1 ( 4488__riscv_vslidedown_vx_i16m8 (dot_all ,j * 32 ,16 ),zero_vec ,16 ); 4489int32_t isum0 = __riscv_vmv_x_s_i32m1_i32 (sum_v0 ); 4490 4491vint32m1_t sum_v1 = __riscv_vwredsum_vs_i16m8_i32m1 ( 4492__riscv_vslidedown_vx_i16m8 (dot_all ,j * 32 + 16 ,16 ),zero_vec ,16 ); 4493int32_t isum1 = __riscv_vmv_x_s_i32m1_i32 (sum_v1 ); 4494 4495sum += (float )isum0 * sc_lo + (float )isum1 * sc_hi ; 4496 } 4497 4498sumf += sum * combined_scale ; 4499 } 4500* s = 0.125f * sumf ; 4501} 4502#endif 4503 4504void 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 ) { 4505#if defined__riscv_v 4506switch (__riscv_vlenb ()* 8 ) { 4507case 128 : 4508ggml_vec_dot_iq2_xs_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4509break ; 4510case 256 : 4511ggml_vec_dot_iq2_xs_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4512break ; 4513default :// 512 and above 4514ggml_vec_dot_iq2_xs_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4515break ; 4516 } 4517#else 4518ggml_vec_dot_iq2_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4519#endif 4520} 4521 4522#if defined__riscv_v 4523static NOINLINE void ggml_vec_dot_iq2_xxs_q8_K_vl128 (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 ) { 4524assert (n %QK_K == 0 ); 4525assert (nrc == 1 ); 4526UNUSED (nrc ); 4527UNUSED (bx ); 4528UNUSED (by ); 4529UNUSED (bs ); 4530 4531const block_iq2_xxs * GGML_RESTRICT x = vx ; 4532const block_q8_K * GGML_RESTRICT y = vy ; 4533 4534const int nb = n /QK_K ; 4535const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4536const uint64_t * grid64 = (const uint64_t * )iq2xxs_grid ; 4537 4538uint32_t shift_constants [4 ]= {0 ,7 ,14 ,21 }; 4539vuint32m1_t v_shifts = __riscv_vle32_v_u32m1 (shift_constants ,4 ); 4540 4541float sumf = 0.0f ; 4542for (int i = 0 ;i < nb ;++ i ) { 4543const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4544 4545const uint8_t * GGML_RESTRICT q2_ptr = (const uint8_t * )x [i ].qs ; 4546const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4547 4548float sum = 0.0f ; 4549 4550#pragma GCC unroll 1 4551for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 4552vint8m2_t q8_1 = __riscv_vle8_v_i8m2 (q8 ,32 );q8 += 32 ; 4553vint8m2_t q8_2 = __riscv_vle8_v_i8m2 (q8 ,32 );q8 += 32 ; 4554 4555vuint8mf4_t v_raw_q2_1 = __riscv_vle8_v_u8mf4 (q2_ptr ,4 ); 4556vuint8mf4_t v_raw_q2_2 = __riscv_vle8_v_u8mf4 (q2_ptr + 8 ,4 ); 4557 4558vuint16mf2_t vidx_q2_1 = __riscv_vwcvtu_x_x_v_u16mf2 (v_raw_q2_1 ,4 ); 4559vuint16mf2_t vidx_q2_2 = __riscv_vwcvtu_x_x_v_u16mf2 (v_raw_q2_2 ,4 ); 4560 4561vidx_q2_1 = __riscv_vsll_vx_u16mf2 (vidx_q2_1 ,3 ,4 ); 4562vidx_q2_2 = __riscv_vsll_vx_u16mf2 (vidx_q2_2 ,3 ,4 ); 4563 4564uint32_t s_packed_1 ,s_packed_2 ; 4565memcpy (& s_packed_1 ,q2_ptr + 4 ,4 ); 4566memcpy (& s_packed_2 ,q2_ptr + 12 ,4 ); 4567 4568vuint32m1_t v_s_1 = __riscv_vmv_v_x_u32m1 (s_packed_1 ,4 ); 4569vuint32m1_t v_s_2 = __riscv_vmv_v_x_u32m1 (s_packed_2 ,4 ); 4570v_s_1 = __riscv_vsrl_vv_u32m1 (v_s_1 ,v_shifts ,4 ); 4571v_s_2 = __riscv_vsrl_vv_u32m1 (v_s_2 ,v_shifts ,4 ); 4572 4573v_s_1 = __riscv_vand_vx_u32m1 (v_s_1 ,127 ,4 ); 4574v_s_2 = __riscv_vand_vx_u32m1 (v_s_2 ,127 ,4 ); 4575 4576vuint16mf2_t vidx_s2_1 = __riscv_vsll_vx_u16mf2 (__riscv_vncvt_x_x_w_u16mf2 (v_s_1 ,4 ),3 ,4 ); 4577vuint16mf2_t vidx_s2_2 = __riscv_vsll_vx_u16mf2 (__riscv_vncvt_x_x_w_u16mf2 (v_s_2 ,4 ),3 ,4 ); 4578 4579vuint64m2_t vq2_64_1 = __riscv_vluxei16_v_u64m2 (grid64 ,vidx_q2_1 ,4 ); 4580vuint64m2_t vq2_64_2 = __riscv_vluxei16_v_u64m2 (grid64 ,vidx_q2_2 ,4 ); 4581 4582vint8m2_t q2_1 = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (vq2_64_1 )); 4583vint8m2_t q2_2 = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (vq2_64_2 )); 4584 4585vuint64m2_t vs2_64_1 = __riscv_vluxei16_v_u64m2 (signs64 ,vidx_s2_1 ,4 ); 4586vuint64m2_t vs2_64_2 = __riscv_vluxei16_v_u64m2 (signs64 ,vidx_s2_2 ,4 ); 4587vint8m2_t s2_1 = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (vs2_64_1 )); 4588vint8m2_t s2_2 = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (vs2_64_2 )); 4589 4590vint8m2_t q8s_1 = __riscv_vmul_vv_i8m2 (q8_1 ,s2_1 ,32 ); 4591vint8m2_t q8s_2 = __riscv_vmul_vv_i8m2 (q8_2 ,s2_2 ,32 ); 4592 4593vint16m4_t dot1 = __riscv_vwmul_vv_i16m4 (q8s_1 ,q2_1 ,32 ); 4594vint16m4_t dot2 = __riscv_vwmul_vv_i16m4 (q8s_2 ,q2_2 ,32 ); 4595 4596vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4597vint32m1_t sumv1 = __riscv_vwredsum_vs_i16m4_i32m1 (dot1 ,zero_vec ,32 ); 4598vint32m1_t sumv2 = __riscv_vwredsum_vs_i16m4_i32m1 (dot2 ,zero_vec ,32 ); 4599 4600int32_t scalar_sum1 = __riscv_vmv_x_s_i32m1_i32 (sumv1 ); 4601int32_t scalar_sum2 = __riscv_vmv_x_s_i32m1_i32 (sumv2 ); 4602 4603int16_t scale1 = 2 * ((s_packed_1 >>28 )& 0xF )+ 1 ; 4604int16_t scale2 = 2 * ((s_packed_2 >>28 )& 0xF )+ 1 ; 4605 4606sum += scalar_sum1 * scale1 + scalar_sum2 * scale2 ; 4607q2_ptr += 16 ; 4608 } 4609sumf += sum * combined_scale ; 4610 } 4611* s = 0.125f * sumf ; 4612} 4613 4614static NOINLINE void ggml_vec_dot_iq2_xxs_q8_K_vl256 (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 ) { 4615assert (n %QK_K == 0 ); 4616assert (nrc == 1 ); 4617UNUSED (nrc ); 4618UNUSED (bx ); 4619UNUSED (by ); 4620UNUSED (bs ); 4621 4622const block_iq2_xxs * GGML_RESTRICT x = vx ; 4623const block_q8_K * GGML_RESTRICT y = vy ; 4624 4625const int nb = n /QK_K ; 4626const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4627const uint64_t * grid64 = (const uint64_t * )iq2xxs_grid ; 4628 4629uint32_t shift_constants [4 ]= {0 ,7 ,14 ,21 }; 4630vuint32mf2_t v_shifts = __riscv_vle32_v_u32mf2 (shift_constants ,4 ); 4631 4632float sumf = 0.0f ; 4633 4634for (int i = 0 ;i < nb ;++ i ) { 4635const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4636 4637const uint8_t * GGML_RESTRICT q2_ptr = (const uint8_t * )x [i ].qs ; 4638const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4639 4640float sum = 0.0f ; 4641 4642for (int ib32 = 0 ;ib32 < QK_K /32 ;ib32 += 2 ) { 4643vint8m1_t q8_1 = __riscv_vle8_v_i8m1 (q8 ,32 );q8 += 32 ; 4644vint8m1_t q8_2 = __riscv_vle8_v_i8m1 (q8 ,32 );q8 += 32 ; 4645 4646vuint8mf8_t v_raw_q2_1 = __riscv_vle8_v_u8mf8 (q2_ptr ,4 ); 4647vuint8mf8_t v_raw_q2_2 = __riscv_vle8_v_u8mf8 (q2_ptr + 8 ,4 ); 4648 4649vuint16mf4_t vidx_q2_1 = __riscv_vwcvtu_x_x_v_u16mf4 (v_raw_q2_1 ,4 ); 4650vuint16mf4_t vidx_q2_2 = __riscv_vwcvtu_x_x_v_u16mf4 (v_raw_q2_2 ,4 ); 4651 4652vidx_q2_1 = __riscv_vsll_vx_u16mf4 (vidx_q2_1 ,3 ,4 ); 4653vidx_q2_2 = __riscv_vsll_vx_u16mf4 (vidx_q2_2 ,3 ,4 ); 4654 4655uint32_t s_packed_1 ,s_packed_2 ; 4656memcpy (& s_packed_1 ,q2_ptr + 4 ,4 ); 4657memcpy (& s_packed_2 ,q2_ptr + 12 ,4 ); 4658 4659vuint32mf2_t v_s_1 = __riscv_vmv_v_x_u32mf2 (s_packed_1 ,4 ); 4660vuint32mf2_t v_s_2 = __riscv_vmv_v_x_u32mf2 (s_packed_2 ,4 ); 4661 4662v_s_1 = __riscv_vsrl_vv_u32mf2 (v_s_1 ,v_shifts ,4 ); 4663v_s_2 = __riscv_vsrl_vv_u32mf2 (v_s_2 ,v_shifts ,4 ); 4664 4665v_s_1 = __riscv_vand_vx_u32mf2 (v_s_1 ,127 ,4 ); 4666v_s_2 = __riscv_vand_vx_u32mf2 (v_s_2 ,127 ,4 ); 4667 4668// Narrow u32 -> u16 (vncvt) and Scale by 8 to get byte offsets 4669vuint16mf4_t vidx_s2_1 = __riscv_vsll_vx_u16mf4 (__riscv_vncvt_x_x_w_u16mf4 (v_s_1 ,4 ),3 ,4 ); 4670vuint16mf4_t vidx_s2_2 = __riscv_vsll_vx_u16mf4 (__riscv_vncvt_x_x_w_u16mf4 (v_s_2 ,4 ),3 ,4 ); 4671 4672// Load q2 values from lookup grid 4673vuint64m1_t vq2_64_1 = __riscv_vluxei16_v_u64m1 (grid64 ,vidx_q2_1 ,4 ); 4674vuint64m1_t vq2_64_2 = __riscv_vluxei16_v_u64m1 (grid64 ,vidx_q2_2 ,4 ); 4675vint8m1_t q2_1 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vreinterpret_v_u64m1_u8m1 (vq2_64_1 )); 4676vint8m1_t q2_2 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vreinterpret_v_u64m1_u8m1 (vq2_64_2 )); 4677 4678// Load sign values 4679vuint64m1_t vs2_64_1 = __riscv_vluxei16_v_u64m1 (signs64 ,vidx_s2_1 ,4 ); 4680vuint64m1_t vs2_64_2 = __riscv_vluxei16_v_u64m1 (signs64 ,vidx_s2_2 ,4 ); 4681vint8m1_t s2_1 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vreinterpret_v_u64m1_u8m1 (vs2_64_1 )); 4682vint8m1_t s2_2 = __riscv_vreinterpret_v_u8m1_i8m1 (__riscv_vreinterpret_v_u64m1_u8m1 (vs2_64_2 )); 4683 4684// Apply signs to q8 4685vint8m1_t q8s_1 = __riscv_vmul_vv_i8m1 (q8_1 ,s2_1 ,32 ); 4686vint8m1_t q8s_2 = __riscv_vmul_vv_i8m1 (q8_2 ,s2_2 ,32 ); 4687 4688// multiplying q2 with q8 4689vint16m2_t dot1 = __riscv_vwmul_vv_i16m2 (q8s_1 ,q2_1 ,32 ); 4690vint16m2_t dot2 = __riscv_vwmul_vv_i16m2 (q8s_2 ,q2_2 ,32 ); 4691 4692vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4693vint32m1_t sumv1 = __riscv_vwredsum_vs_i16m2_i32m1 (dot1 ,zero_vec ,32 ); 4694vint32m1_t sumv2 = __riscv_vwredsum_vs_i16m2_i32m1 (dot2 ,zero_vec ,32 ); 4695int32_t scalar_sum1 = __riscv_vmv_x_s_i32m1_i32 (sumv1 ); 4696int32_t scalar_sum2 = __riscv_vmv_x_s_i32m1_i32 (sumv2 ); 4697int16_t scale1 = 2 * ((s_packed_1 >>28 )& 0xF )+ 1 ; 4698int16_t scale2 = 2 * ((s_packed_2 >>28 )& 0xF )+ 1 ; 4699 4700sum += scalar_sum1 * scale1 + scalar_sum2 * scale2 ; 4701q2_ptr += 16 ; 4702 } 4703sumf += sum * combined_scale ; 4704 } 4705* s = 0.125f * sumf ; 4706} 4707 4708static NOINLINE void ggml_vec_dot_iq2_xxs_q8_K_vl512 (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 ) { 4709assert (n %QK_K == 0 ); 4710assert (nrc == 1 ); 4711UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 4712 4713const block_iq2_xxs * GGML_RESTRICT x = vx ; 4714const block_q8_K * GGML_RESTRICT y = vy ; 4715 4716const int nb = n /QK_K ; 4717const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 4718const uint64_t * grid64 = (const uint64_t * )iq2xxs_grid ; 4719// Shift pattern {0,7,14,21} repeated 8 times for all 8 sub-blocks 4720uint8_t shift_arr [32 ]= { 47210 ,7 ,14 ,21 ,0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 , 47220 ,7 ,14 ,21 ,0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 4723 }; 4724vuint8mf2_t v_shifts = __riscv_vle8_v_u8mf2 (shift_arr ,32 ); 4725 4726// Gather pattern to broadcast the 8 sub-block scales across the 32 lookup slots 4727uint8_t gather_arr [32 ]= { 47280 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,2 ,2 ,3 ,3 ,3 ,3 , 47294 ,4 ,4 ,4 ,5 ,5 ,5 ,5 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,7 4730 }; 4731vuint8mf2_t v_sign_gather_idx = __riscv_vle8_v_u8mf2 (gather_arr ,32 ); 4732 4733float sumf = 0.0f ; 4734for (int i = 0 ;i < nb ;++ i ) { 4735const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 4736 4737const uint8_t * GGML_RESTRICT q2_ptr = (const uint8_t * )x [i ].qs ; 4738const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4739vint8m4_t q8_all = __riscv_vle8_v_i8m4 (q8 ,256 ); 4740 4741// De-interleave all 8 Index/Scale pairs for the 8x32-element sub-blocks 4742vuint32mf2x2_t tuple = __riscv_vlseg2e32_v_u32mf2x2 ((const uint32_t * )q2_ptr ,8 ); 4743vuint32mf2_t v_ind32 = __riscv_vget_v_u32mf2x2_u32mf2 (tuple ,0 ); 4744vuint32mf2_t v_sc32 = __riscv_vget_v_u32mf2x2_u32mf2 (tuple ,1 ); 4745 4746vuint8mf2_t v_raw_q2 = __riscv_vreinterpret_v_u32mf2_u8mf2 (v_ind32 ); 4747vuint16m1_t vidx_q2 = __riscv_vwcvtu_x_x_v_u16m1 (v_raw_q2 ,32 ); 4748vidx_q2 = __riscv_vsll_vx_u16m1 (vidx_q2 ,3 ,32 ); 4749 4750vuint32m2_t v_s = __riscv_vrgatherei16_vv_u32m2 (__riscv_vlmul_ext_v_u32mf2_u32m2 (v_sc32 ),__riscv_vwcvtu_x_x_v_u16m1 (v_sign_gather_idx ,32 ),32 ); 4751v_s = __riscv_vsrl_vv_u32m2 (v_s ,__riscv_vwcvtu_x_x_v_u32m2 (__riscv_vwcvtu_x_x_v_u16m1 (v_shifts ,32 ),32 ),32 ); 4752v_s = __riscv_vand_vx_u32m2 (v_s ,127 ,32 ); 4753vuint16m1_t vidx_s2 = __riscv_vsll_vx_u16m1 (__riscv_vncvt_x_x_w_u16m1 (v_s ,32 ),3 ,32 ); 4754 4755vuint64m4_t vq2_64 = __riscv_vluxei16_v_u64m4 (grid64 ,vidx_q2 ,32 ); 4756vuint64m4_t vs2_64 = __riscv_vluxei16_v_u64m4 (signs64 ,vidx_s2 ,32 ); 4757vint8m4_t q2_all = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vq2_64 )); 4758vint8m4_t s2_all = __riscv_vreinterpret_v_u8m4_i8m4 (__riscv_vreinterpret_v_u64m4_u8m4 (vs2_64 )); 4759 4760vint8m4_t q8s_all = __riscv_vmul_vv_i8m4 (q8_all ,s2_all ,256 ); 4761vint16m8_t dot_all = __riscv_vwmul_vv_i16m8 (q8s_all ,q2_all ,256 ); 4762 4763float sum = 0.0f ; 4764vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4765 4766for (int j = 0 ;j < 8 ;++ j ) { 4767uint32_t s_p = __riscv_vmv_x_s_u32mf2_u32 (__riscv_vslidedown_vx_u32mf2 (v_sc32 ,j ,8 )); 4768int16_t sc = 2 * ((s_p >>28 )& 0xF )+ 1 ; 4769dot_all = __riscv_vslidedown_vx_i16m8 (dot_all ,j * 32 ,32 ); 4770vint32m1_t sum_v = __riscv_vwredsum_vs_i16m8_i32m1 (dot_all ,zero_vec ,32 ); 4771int32_t isum = __riscv_vmv_x_s_i32m1_i32 (sum_v ); 4772sum += (float )isum * sc ; 4773 } 4774 4775sumf += sum * combined_scale ; 4776 } 4777* s = 0.125f * sumf ; 4778} 4779#endif 4780 4781void 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 ) { 4782#if defined__riscv_v 4783switch (__riscv_vlenb ()* 8 ) { 4784case 128 : 4785ggml_vec_dot_iq2_xxs_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4786break ; 4787case 256 : 4788ggml_vec_dot_iq2_xxs_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4789break ; 4790default :// 512 and above 4791ggml_vec_dot_iq2_xxs_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4792break ; 4793 } 4794#else 4795ggml_vec_dot_iq2_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 4796#endif 4797} 4798 4799#if defined__riscv_v 4800static NOINLINE void ggml_vec_dot_iq3_s_q8_K_vl128 (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 ) { 4801assert (n %QK_K == 0 ); 4802UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 4803const block_iq3_s * GGML_RESTRICT x = vx ; 4804const block_q8_K * GGML_RESTRICT y = vy ; 4805 4806const int nb = n /QK_K ; 4807const uint32_t * grid32 = (const uint32_t * )iq3s_grid ; 4808 4809vuint8mf2_t v_id_8 = __riscv_vid_v_u8mf2 (8 ); 4810vuint8m2_t v_id_32 = __riscv_vid_v_u8m2 (32 ); 4811 4812// Keeping these in a tight scope to hint they're only needed for the mask computation. 4813vuint8m2_t v_sign_gather_indices ,v_sign_masks ; 4814 { 4815vuint8m2_t v_shifts = __riscv_vand_vx_u8m2 (v_id_32 ,7 ,32 ); 4816vuint8m2_t v_one_32 = __riscv_vmv_v_x_u8m2 (1 ,32 ); 4817v_sign_gather_indices = __riscv_vsrl_vx_u8m2 (v_id_32 ,3 ,32 ); 4818v_sign_masks = __riscv_vsll_vv_u8m2 (v_one_32 ,v_shifts ,32 ); 4819 } 4820 4821float sumf = 0.0f ; 4822 4823for (int i = 0 ;i < nb ;++ i ) { 4824const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 4825const float combined_scale = d * y [i ].d ; 4826 4827const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 4828const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 4829const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4830const uint8_t * GGML_RESTRICT signs = x [i ].signs ; 4831const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4832 4833float sum_block = 0.0f ; 4834 4835for (int ib = 0 ;ib < 8 ;++ ib ) { 4836 4837// Grid lookup 4838vuint8m2_t v_grid_u8 ; 4839 { 4840vuint8mf2_t v_qs_u8 = __riscv_vle8_v_u8mf2 (qs ,8 ); 4841qs += 8 ; 4842 4843uint8_t qh_val = * qh ++ ; 4844vuint8mf2_t v_qh_val = __riscv_vmv_v_x_u8mf2 (qh_val ,8 ); 4845v_qh_val = __riscv_vsrl_vv_u8mf2 (v_qh_val ,v_id_8 ,8 ); 4846v_qh_val = __riscv_vand_vx_u8mf2 (v_qh_val ,1 ,8 ); 4847 4848vuint16m1_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16m1 (v_qs_u8 ,8 ); 4849v_qs_u16 = __riscv_vsll_vx_u16m1 (v_qs_u16 ,2 ,8 ); 4850 4851vuint16m1_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16m1 (v_qh_val ,8 ); 4852v_qh_u16 = __riscv_vsll_vx_u16m1 (v_qh_u16 ,10 ,8 ); 4853 4854vuint16m1_t v_grid_offsets = __riscv_vor_vv_u16m1 (v_qs_u16 ,v_qh_u16 ,8 ); 4855 4856vuint32m2_t v_grid_packed = __riscv_vluxei16_v_u32m2 (grid32 ,v_grid_offsets ,8 ); 4857v_grid_u8 = __riscv_vreinterpret_v_u32m2_u8m2 (v_grid_packed ); 4858 } 4859 __asm__volatile ("" :::"memory" ); 4860 4861//Sign application and dot product 4862int32_t s_val ; 4863 { 4864vuint8mf4_t v_signs_raw = __riscv_vle8_v_u8mf4 (signs ,4 ); 4865signs += 4 ; 4866 4867vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf4_u8m2 (v_signs_raw ); 4868vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,32 ); 4869vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,32 ); 4870vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,32 ); 4871 4872vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,32 ); 4873q8 += 32 ; 4874 4875vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,32 ); 4876vint16m4_t v_dot = __riscv_vwmulsu_vv_i16m4 (v_q8_signed ,v_grid_u8 ,32 ); 4877 4878vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4879s_val = __riscv_vmv_x_s_i32m1_i32 ( 4880__riscv_vwredsum_vs_i16m4_i32m1 (v_dot ,v_zero ,32 )); 4881 } 4882 __asm__volatile ("" :::"memory" ); 4883 { 4884uint8_t sc_byte = scales [ib >>1 ]; 4885int sc_val = (ib & 1 ) ? (sc_byte >>4 ) : (sc_byte & 0xF ); 4886sc_val = sc_val * 2 + 1 ; 4887sum_block += (float )(s_val * sc_val ); 4888 } 4889 } 4890sumf += sum_block * combined_scale ; 4891 } 4892* s = sumf ; 4893} 4894 4895static NOINLINE void ggml_vec_dot_iq3_s_q8_K_vl256 (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 ) { 4896assert (n %QK_K == 0 ); 4897UNUSED (nrc ); 4898UNUSED (bx ); 4899UNUSED (by ); 4900UNUSED (bs ); 4901 4902const block_iq3_s * GGML_RESTRICT x = vx ; 4903const block_q8_K * GGML_RESTRICT y = vy ; 4904 4905const int nb = n /QK_K ; 4906 4907const uint64_t * grid64 = (const uint64_t * )iq3s_grid ; 4908 4909// --- Pre-load Constants --- 4910const uint16_t qh_bit_shifts_arr [16 ]= { 49110 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 4912 }; 4913vuint8m2_t v_sign_gather_indices = __riscv_vle8_v_u8m2 (sign_gather_indices_arr ,64 ); 4914vuint8m2_t v_sign_masks = __riscv_vle8_v_u8m2 (sign_bit_masks_arr ,64 ); 4915vuint16m1_t v_qh_shifts = __riscv_vle16_v_u16m1 (qh_bit_shifts_arr ,16 ); 4916 4917float sumf = 0.0f ; 4918 4919for (int i = 0 ;i < nb ;++ i ) { 4920const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d ); 4921const float combined_scale = d * y [i ].d ; 4922 4923const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 4924const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 4925const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 4926const uint8_t * GGML_RESTRICT signs = x [i ].signs ; 4927const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 4928 4929float sum_block = 0.0f ; 4930 4931// Loop: Process 64 weights (16 mini-blocks of 4) per iteration 4932for (int ib = 0 ;ib < 4 ;++ ib ) { 4933 4934vuint8mf2_t v_qs_u8 = __riscv_vle8_v_u8mf2 (qs ,16 ); 4935qs += 16 ; 4936 4937uint16_t qh_val ; 4938memcpy (& qh_val ,qh ,2 ); 4939qh += 2 ; 4940 4941vuint16m1_t v_qh_val = __riscv_vmv_v_x_u16m1 (qh_val ,16 ); 4942// Extract bits: (qh >> i) & 1 4943v_qh_val = __riscv_vsrl_vv_u16m1 (v_qh_val ,v_qh_shifts ,16 ); 4944v_qh_val = __riscv_vand_vx_u16m1 (v_qh_val ,1 ,16 ); 4945 4946vuint16m1_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16m1 (v_qs_u8 ,16 ); 4947v_qs_u16 = __riscv_vsll_vx_u16m1 (v_qs_u16 ,2 ,16 ); 4948v_qh_val = __riscv_vsll_vx_u16m1 (v_qh_val ,10 ,16 ); 4949vuint16m1_t v_grid_offsets = __riscv_vor_vv_u16m1 (v_qs_u16 ,v_qh_val ,16 ); 4950 4951// Grid value is 4xuint8 4952vuint32m2_t v_grid_packed = __riscv_vluxei16_v_u32m2 ((const uint32_t * )grid64 ,v_grid_offsets ,16 ); 4953vuint8m2_t v_grid_u8 = __riscv_vreinterpret_v_u32m2_u8m2 (v_grid_packed ); 4954vuint8mf4_t v_signs_raw = __riscv_vle8_v_u8mf4 (signs ,8 ); 4955signs += 8 ; 4956 4957// Generate sign mask 4958vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf4_u8m2 (v_signs_raw ); 4959vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather_indices ,64 ); 4960vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,64 ); 4961vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,64 ); 4962 4963vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,64 ); 4964q8 += 64 ; 4965 4966// Apply Signs 4967vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,64 ); 4968vint16m4_t v_dot = __riscv_vwmulsu_vv_i16m4 (v_q8_signed ,v_grid_u8 ,64 ); 4969 4970// Reduction 4971vint16m2_t v_dot_lo = __riscv_vget_v_i16m4_i16m2 (v_dot ,0 ); 4972vint16m2_t v_dot_hi = __riscv_vget_v_i16m4_i16m2 (v_dot ,1 ); 4973vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 4974 4975int32_t s_lo = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (v_dot_lo ,v_zero ,32 )); 4976int32_t s_hi = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (v_dot_hi ,v_zero ,32 )); 4977 4978// Apply sub-scales 4979uint8_t sc_byte = * scales ++ ; 4980int sc_lo = (sc_byte & 0xF )* 2 + 1 ; 4981int sc_hi = (sc_byte >>4 )* 2 + 1 ; 4982 4983sum_block += s_lo * sc_lo + s_hi * sc_hi ; 4984 } 4985sumf += sum_block * combined_scale ; 4986 } 4987* s = sumf ; 4988} 4989 4990static NOINLINE void ggml_vec_dot_iq3_s_q8_K_vl512 (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 ) { 4991assert (n %QK_K == 0 ); 4992UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 4993const block_iq3_s * GGML_RESTRICT x = vx ; 4994const block_q8_K * GGML_RESTRICT y = vy ; 4995 4996const int nb = n /QK_K ; 4997const uint32_t * grid32 = (const uint32_t * )iq3s_grid ; 4998 4999// Generate Constants 5000vuint8mf2_t v_id_32 = __riscv_vid_v_u8mf2 (32 ); 5001vuint8mf2_t v_qh_gather = __riscv_vsrl_vx_u8mf2 (v_id_32 ,3 ,32 ); 5002vuint8mf2_t v_qh_shifts = __riscv_vand_vx_u8mf2 (v_id_32 ,7 ,32 ); 5003vuint8m2_t v_id_128 = __riscv_vid_v_u8m2 (128 ); 5004vuint8m2_t v_sign_gather = __riscv_vsrl_vx_u8m2 (v_id_128 ,3 ,128 );// byte index 5005vuint8m2_t v_sign_shift_amts = __riscv_vand_vx_u8m2 (v_id_128 ,7 ,128 );// bit shift 5006vuint8m2_t v_one_128 = __riscv_vmv_v_x_u8m2 (1 ,128 ); 5007vuint8m2_t v_sign_masks = __riscv_vsll_vv_u8m2 (v_one_128 ,v_sign_shift_amts ,128 ); 5008vuint8m2_t v_scale_indices = __riscv_vsrl_vx_u8m2 (v_id_128 ,5 ,128 ); 5009 5010float sumf = 0.0f ; 5011 5012for (int i = 0 ;i < nb ;++ i ) { 5013const float combined_scale = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 5014 5015const uint8_t * GGML_RESTRICT qs = x [i ].qs ; 5016const uint8_t * GGML_RESTRICT qh = x [i ].qh ; 5017const uint8_t * GGML_RESTRICT scales = x [i ].scales ; 5018const uint8_t * GGML_RESTRICT signs = x [i ].signs ; 5019const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5020 5021float sum_block = 0.0f ; 5022for (int ib = 0 ;ib < 2 ;++ ib ) { 5023vuint8mf2_t v_qs_u8 = __riscv_vle8_v_u8mf2 (qs ,32 ); 5024qs += 32 ; 5025vuint8mf2_t v_qh_loaded = __riscv_vle8_v_u8mf2 (qh ,4 ); 5026qh += 4 ; 5027vuint8mf2_t v_qh_expanded = __riscv_vrgather_vv_u8mf2 (v_qh_loaded ,v_qh_gather ,32 ); 5028v_qh_expanded = __riscv_vsrl_vv_u8mf2 (v_qh_expanded ,v_qh_shifts ,32 ); 5029v_qh_expanded = __riscv_vand_vx_u8mf2 (v_qh_expanded ,1 ,32 ); 5030vuint16m1_t v_qs_u16 = __riscv_vwcvtu_x_x_v_u16m1 (v_qs_u8 ,32 ); 5031v_qs_u16 = __riscv_vsll_vx_u16m1 (v_qs_u16 ,2 ,32 );// * 4 5032 5033vuint16m1_t v_qh_u16 = __riscv_vwcvtu_x_x_v_u16m1 (v_qh_expanded ,32 ); 5034v_qh_u16 = __riscv_vsll_vx_u16m1 (v_qh_u16 ,10 ,32 );// * 256 * 4 5035 5036vuint16m1_t v_grid_offsets = __riscv_vor_vv_u16m1 (v_qs_u16 ,v_qh_u16 ,32 ); 5037vuint32m2_t v_grid_packed = __riscv_vluxei16_v_u32m2 (grid32 ,v_grid_offsets ,32 ); 5038vuint8m2_t v_grid_u8 = __riscv_vreinterpret_v_u32m2_u8m2 (v_grid_packed ); 5039vuint8mf2_t v_signs_raw = __riscv_vle8_v_u8mf2 (signs ,16 ); 5040signs += 16 ; 5041 5042vuint8m2_t v_signs_source = __riscv_vlmul_ext_v_u8mf2_u8m2 (v_signs_raw ); 5043vuint8m2_t v_signs_bcast = __riscv_vrgather_vv_u8m2 (v_signs_source ,v_sign_gather ,128 ); 5044vuint8m2_t v_sign_bits = __riscv_vand_vv_u8m2 (v_signs_bcast ,v_sign_masks ,128 ); 5045vbool4_t m_negative = __riscv_vmsne_vx_u8m2_b4 (v_sign_bits ,0 ,128 ); 5046 5047vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,128 ); 5048q8 += 128 ; 5049 5050vint8m2_t v_q8_signed = __riscv_vrsub_vx_i8m2_mu (m_negative ,v_q8 ,v_q8 ,0 ,128 ); 5051vint16m4_t v_dot = __riscv_vwmulsu_vv_i16m4 (v_q8_signed ,v_grid_u8 ,128 ); 5052uint16_t sc_raw ; 5053memcpy (& sc_raw ,scales ,2 ); 5054scales += 2 ;// Advance 2 bytes 5055 5056uint8_t sc_unpacked [4 ]; 5057sc_unpacked [0 ]= (sc_raw & 0xF ); 5058sc_unpacked [1 ]= (sc_raw >>4 )& 0xF ; 5059sc_unpacked [2 ]= (sc_raw >>8 )& 0xF ; 5060sc_unpacked [3 ]= (sc_raw >>12 )& 0xF ; 5061 5062vuint8mf2_t v_sc_4 = __riscv_vle8_v_u8mf2 (sc_unpacked ,4 ); 5063v_sc_4 = __riscv_vmul_vx_u8mf2 (v_sc_4 ,2 ,4 ); 5064v_sc_4 = __riscv_vadd_vx_u8mf2 (v_sc_4 ,1 ,4 ); 5065vuint8m2_t v_sc_4_expanded = __riscv_vlmul_ext_v_u8mf2_u8m2 (v_sc_4 ); 5066vuint8m2_t v_scales_bcast = __riscv_vrgather_vv_u8m2 (v_sc_4_expanded ,v_scale_indices ,128 ); 5067vint16m4_t v_scales_i16 = __riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vwcvtu_x_x_v_u16m4 (v_scales_bcast ,128 )); 5068vint32m8_t v_weighted_sum = __riscv_vwmul_vv_i32m8 (v_dot ,v_scales_i16 ,128 ); 5069vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 5070int32_t s_val = __riscv_vmv_x_s_i32m1_i32 (__riscv_vredsum_vs_i32m8_i32m1 (v_weighted_sum ,v_zero ,128 )); 5071 5072sum_block += s_val ; 5073 } 5074sumf += sum_block * combined_scale ; 5075 } 5076* s = sumf ; 5077} 5078#endif 5079 5080void 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 ) { 5081#if defined__riscv_v 5082switch (__riscv_vlenb ()* 8 ) { 5083case 128 : 5084ggml_vec_dot_iq3_s_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5085break ; 5086case 256 : 5087ggml_vec_dot_iq3_s_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5088break ; 5089default :// 512 and above 5090ggml_vec_dot_iq3_s_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5091break ; 5092 } 5093#else 5094ggml_vec_dot_iq3_s_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5095#endif 5096} 5097 5098#if defined__riscv_v 5099static NOINLINE void ggml_vec_dot_iq3_xxs_q8_K_vl128 (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 ) { 5100assert (n %QK_K == 0 ); 5101UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 5102 5103const block_iq3_xxs * GGML_RESTRICT x = vx ; 5104const block_q8_K * GGML_RESTRICT y = vy ; 5105const int nb = n /QK_K ; 5106 5107const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 5108const uint32_t * grid32 = (const uint32_t * )iq3xxs_grid ; 5109 5110// constants for unpacking logic 5111const uint32_t shifts_val [8 ]= {0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 }; 5112vuint32m2_t v_shifts = __riscv_vle32_v_u32m2 (shifts_val ,8 ); 5113 5114const uint32_t gather_idx_val [8 ]= {0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 }; 5115vuint32m2_t v_gather_idx = __riscv_vle32_v_u32m2 (gather_idx_val ,8 ); 5116 5117uint32_t aux32 [2 ]; 5118float sumf = 0.0f ; 5119 5120for (int i = 0 ;i < nb ;++ i ) { 5121const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 5122 5123const uint8_t * GGML_RESTRICT q3_indices = x [i ].qs ; 5124const uint8_t * GGML_RESTRICT metadata = x [i ].qs + QK_K /4 ; 5125const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5126 5127float block_sum = 0.0f ; 5128 5129// Process 64 weights per loop 5130for (int ib = 0 ;ib < QK_K /64 ;++ ib ) { 5131 5132// load of metadata via memcpy 5133memcpy (aux32 ,metadata ,2 * sizeof (uint32_t )); 5134metadata += 2 * sizeof (uint32_t ); 5135 5136vuint8m1_t v_q3_idx_u8 = __riscv_vle8_v_u8m1 (q3_indices ,16 ); 5137q3_indices += 16 ; 5138 5139vuint16m2_t v_q3_idx_u16 = __riscv_vwmulu_vx_u16m2 (v_q3_idx_u8 ,4 ,16 ); 5140 5141vuint32m4_t v_q3_magnitudes_u32 = __riscv_vluxei16_v_u32m4 (grid32 ,v_q3_idx_u16 ,16 ); 5142 5143vint8m4_t v_q3_magnitudes = __riscv_vreinterpret_v_u8m4_i8m4 ( 5144__riscv_vreinterpret_v_u32m4_u8m4 (v_q3_magnitudes_u32 )); 5145 5146vuint32m2_t v_aux = __riscv_vle32_v_u32m2 (aux32 ,2 ); 5147 5148vuint32m2_t v_aux_expanded = __riscv_vrgather_vv_u32m2 (v_aux ,v_gather_idx ,8 ); 5149 5150vuint32m2_t v_s_vals_raw = __riscv_vand_vx_u32m2 ( 5151__riscv_vsrl_vv_u32m2 (v_aux_expanded ,v_shifts ,8 ),127 ,8 ); 5152 5153vuint16m1_t sign_indices_byte_offset = __riscv_vsll_vx_u16m1 ( 5154__riscv_vncvt_x_x_w_u16m1 (v_s_vals_raw ,8 ),3 ,8 ); 5155 5156vuint64m4_t v_s_vals_u64 = __riscv_vluxei16_v_u64m4 (signs64 ,sign_indices_byte_offset ,8 ); 5157 5158vint8m4_t v_s_vals = __riscv_vreinterpret_v_u8m4_i8m4 ( 5159__riscv_vreinterpret_v_u64m4_u8m4 (v_s_vals_u64 )); 5160 5161vint8m4_t v_q3_signed = __riscv_vmul_vv_i8m4 (v_q3_magnitudes ,v_s_vals ,64 ); 5162 asmvolatile ("" :::"memory" ); 5163vint8m4_t v_q8 = __riscv_vle8_v_i8m4 (q8 ,64 ); 5164q8 += 64 ; 5165 5166vint16m8_t v_dot = __riscv_vwmul_vv_i16m8 (v_q8 ,v_q3_signed ,64 ); 5167 5168 asmvolatile ("" :::"memory" ); 5169 5170vint16m4_t v_dot_1 = __riscv_vget_v_i16m8_i16m4 (v_dot ,0 ); 5171vint16m4_t v_dot_2 = __riscv_vget_v_i16m8_i16m4 (v_dot ,1 ); 5172 5173vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 5174 5175vint32m1_t v_sum_1 = __riscv_vwredsum_vs_i16m4_i32m1 (v_dot_1 ,v_zero ,32 ); 5176vint32m1_t v_sum_2 = __riscv_vwredsum_vs_i16m4_i32m1 (v_dot_2 ,v_zero ,32 ); 5177 5178int32_t sum1_i = __riscv_vmv_x_s_i32m1_i32 (v_sum_1 ); 5179int32_t sum2_i = __riscv_vmv_x_s_i32m1_i32 (v_sum_2 ); 5180 5181const float scale1_f = (float )(2 * (aux32 [0 ] >>28 )+ 1 ); 5182const float scale2_f = (float )(2 * (aux32 [1 ] >>28 )+ 1 ); 5183 5184block_sum += sum1_i * scale1_f + sum2_i * scale2_f ; 5185 } 5186 5187sumf += d * block_sum ; 5188 } 5189* s = 0.25f * sumf ; 5190} 5191 5192static NOINLINE void ggml_vec_dot_iq3_xxs_q8_K_vl256 (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 ) { 5193assert (n %QK_K == 0 ); 5194assert (nrc == 1 ); 5195UNUSED (nrc ); 5196UNUSED (bx ); 5197UNUSED (by ); 5198UNUSED (bs ); 5199 5200const block_iq3_xxs * GGML_RESTRICT x = vx ; 5201const block_q8_K * GGML_RESTRICT y = vy ; 5202const int nb = n /QK_K ; 5203 5204const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 5205const uint32_t * grid32 = (const uint32_t * )iq3xxs_grid ; 5206 5207// constants for unpacking logic 5208const uint32_t shifts_val [8 ]= {0 ,7 ,14 ,21 ,0 ,7 ,14 ,21 }; 5209vuint32m1_t v_shifts = __riscv_vle32_v_u32m1 (shifts_val ,8 ); 5210 5211const uint32_t gather_idx_val [8 ]= {0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 }; 5212vuint32m1_t v_gather_idx = __riscv_vle32_v_u32m1 (gather_idx_val ,8 ); 5213 5214uint32_t aux32 [2 ]; 5215float sumf = 0.0f ; 5216 5217for (int i = 0 ;i < nb ;++ i ) { 5218const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 5219 5220const uint8_t * GGML_RESTRICT q3_indices = x [i ].qs ; 5221const uint8_t * GGML_RESTRICT metadata = x [i ].qs + QK_K /4 ; 5222const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5223 5224float block_sum = 0.0f ; 5225 5226for (int ib = 0 ;ib < QK_K /64 ;++ ib ) { 5227// Load q8 (64 bytes) 5228vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,64 ); 5229q8 += 64 ; 5230 5231// load of metadata via memcpy 5232memcpy (aux32 ,metadata ,2 * sizeof (uint32_t )); 5233metadata += 2 * sizeof (uint32_t ); 5234 5235// Load q3 indices and gather magnitudes 5236vuint8mf2_t v_q3_idx_u8 = __riscv_vle8_v_u8mf2 (q3_indices ,16 ); 5237q3_indices += 16 ; 5238 5239vuint16m1_t v_q3_idx_u16 = __riscv_vwmulu_vx_u16m1 (v_q3_idx_u8 ,4 ,16 ); 5240vuint32m2_t v_q3_magnitudes_u32 = __riscv_vluxei16_v_u32m2 (grid32 ,v_q3_idx_u16 ,16 ); 5241vint8m2_t v_q3_magnitudes = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u32m2_u8m2 (v_q3_magnitudes_u32 )); 5242 5243// --- Unpacking of Sign Indices --- 5244 5245// 1. Load the 2 auxiliary 32-bit integers into a vector 5246vuint32m1_t v_aux = __riscv_vle32_v_u32m1 (aux32 ,2 ); 5247 5248// 2. Broadcast/Gather: replicate aux[0] to first 4 lanes, aux[1] to next 4 lanes 5249vuint32m1_t v_aux_expanded = __riscv_vrgather_vv_u32m1 (v_aux ,v_gather_idx ,8 ); 5250 5251// 3. Apply Shifts and Mask: ((val >> shift) & 127) 5252vuint32m1_t v_s_vals_raw = __riscv_vand_vx_u32m1 (__riscv_vsrl_vv_u32m1 (v_aux_expanded ,v_shifts ,8 ),127 ,8 ); 5253 5254// 4. Narrow to u16 (required for vluxei index) and multiply by 8 (byte offset for u64 table) 5255vuint16mf2_t sign_indices_byte_offset = __riscv_vsll_vx_u16mf2 (__riscv_vncvt_x_x_w_u16mf2 (v_s_vals_raw ,8 ),3 ,8 ); 5256 5257// 5. Gather Signs 5258vuint64m2_t v_s_vals_u64 = __riscv_vluxei16_v_u64m2 (signs64 ,sign_indices_byte_offset ,8 ); 5259vint8m2_t v_s_vals = __riscv_vreinterpret_v_u8m2_i8m2 (__riscv_vreinterpret_v_u64m2_u8m2 (v_s_vals_u64 )); 5260 5261vint8m2_t v_q3_signed = __riscv_vmul_vv_i8m2 (v_q3_magnitudes ,v_s_vals ,64 ); 5262vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_q8 ,v_q3_signed ,64 ); 5263 5264vint16m2_t v_dot_1 = __riscv_vget_v_i16m4_i16m2 (v_dot ,0 ); 5265vint16m2_t v_dot_2 = __riscv_vget_v_i16m4_i16m2 (v_dot ,1 ); 5266 5267vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 5268vint32m1_t v_sum_1 = __riscv_vwredsum_vs_i16m2_i32m1 (v_dot_1 ,v_zero ,32 ); 5269vint32m1_t v_sum_2 = __riscv_vwredsum_vs_i16m2_i32m1 (v_dot_2 ,v_zero ,32 ); 5270 5271int32_t sum1_i = __riscv_vmv_x_s_i32m1_i32 (v_sum_1 ); 5272int32_t sum2_i = __riscv_vmv_x_s_i32m1_i32 (v_sum_2 ); 5273 5274const float scale1_f = (float )(2 * (aux32 [0 ] >>28 )+ 1 ); 5275const float scale2_f = (float )(2 * (aux32 [1 ] >>28 )+ 1 ); 5276 5277block_sum += sum1_i * scale1_f + sum2_i * scale2_f ; 5278 } 5279 5280sumf += d * block_sum ; 5281 } 5282* s = 0.25f * sumf ; 5283} 5284 5285static NOINLINE void ggml_vec_dot_iq3_xxs_q8_K_vl512 (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 ) { 5286assert (n %QK_K == 0 ); 5287assert (nrc == 1 ); 5288UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 5289const block_iq3_xxs * GGML_RESTRICT x = vx ; 5290const block_q8_K * GGML_RESTRICT y = vy ; 5291const int nb = n /QK_K ; 5292 5293const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 5294const uint32_t * grid32 = (const uint32_t * )iq3xxs_grid ; 5295 5296// generate constants for unpacking metadata words into sign indices 5297vuint32m1_t v_shifts ; 5298 { 5299vuint32m1_t v_base = __riscv_vid_v_u32m1 (16 ); 5300vuint32m1_t v_mod4 = __riscv_vand_vx_u32m1 (v_base ,3 ,16 ); 5301v_shifts = __riscv_vmul_vx_u32m1 (v_mod4 ,7 ,16 ); 5302 } 5303 5304vuint16mf2_t v_gather_idx ; 5305 { 5306vuint16mf2_t v_idx = __riscv_vid_v_u16mf2 (16 ); 5307v_gather_idx = __riscv_vsrl_vx_u16mf2 (v_idx ,2 ,16 ); 5308 } 5309 5310float sumf = 0.0f ; 5311 5312for (int i = 0 ;i < nb ;++ i ) { 5313const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 5314 5315const uint8_t * GGML_RESTRICT q3_indices = x [i ].qs ; 5316const uint8_t * GGML_RESTRICT metadata = x [i ].qs + QK_K /4 ; 5317const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5318 5319float block_sum = 0.0f ; 5320for (int ib128 = 0 ;ib128 < 2 ;++ ib128 ) { 5321 5322vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,128 ); 5323q8 += 128 ; 5324vuint8mf2_t v_q3_idx_u8 = __riscv_vle8_v_u8mf2 (q3_indices ,32 ); 5325q3_indices += 32 ; 5326 5327vuint16m1_t v_q3_idx_u16 = __riscv_vwmulu_vx_u16m1 (v_q3_idx_u8 ,4 ,32 ); 5328vuint32m2_t v_q3_mag_u32 = __riscv_vluxei16_v_u32m2 (grid32 ,v_q3_idx_u16 ,32 ); 5329vint8m2_t v_q3_magnitudes = __riscv_vreinterpret_v_u8m2_i8m2 ( 5330__riscv_vreinterpret_v_u32m2_u8m2 (v_q3_mag_u32 )); 5331vuint32m1_t v_aux = __riscv_vreinterpret_v_u8m1_u32m1 (__riscv_vle8_v_u8m1 (metadata ,16 )); 5332metadata += 4 * sizeof (uint32_t ); 5333 5334vuint32m1_t v_aux_expanded = __riscv_vrgatherei16_vv_u32m1 (v_aux ,v_gather_idx ,16 ); 5335 5336vuint32m1_t v_s_raw = __riscv_vand_vx_u32m1 ( 5337__riscv_vsrl_vv_u32m1 (v_aux_expanded ,v_shifts ,16 ),127 ,16 ); 5338vuint16mf2_t sign_byte_offset = __riscv_vsll_vx_u16mf2 ( 5339__riscv_vncvt_x_x_w_u16mf2 (v_s_raw ,16 ),3 ,16 ); 5340vuint64m2_t v_s_u64 = __riscv_vluxei16_v_u64m2 (signs64 ,sign_byte_offset ,16 ); 5341vint8m2_t v_signs = __riscv_vreinterpret_v_u8m2_i8m2 ( 5342__riscv_vreinterpret_v_u64m2_u8m2 (v_s_u64 )); 5343vint8m2_t v_q3_signed = __riscv_vmul_vv_i8m2 (v_q3_magnitudes ,v_signs ,128 ); 5344vint16m4_t prod = __riscv_vwmul_vv_i16m4 (v_q3_signed ,v_q8 ,128 ); 5345 5346vint32m1_t zero_vec = __riscv_vmv_v_x_i32m1 (0 ,1 ); 5347int32_t group0_sum = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 5348__riscv_vget_v_i16m4_i16m1 (prod ,0 ),zero_vec ,32 )); 5349int32_t group1_sum = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 5350__riscv_vget_v_i16m4_i16m1 (prod ,1 ),zero_vec ,32 )); 5351int32_t group2_sum = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 5352__riscv_vget_v_i16m4_i16m1 (prod ,2 ),zero_vec ,32 )); 5353int32_t group3_sum = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 ( 5354__riscv_vget_v_i16m4_i16m1 (prod ,3 ),zero_vec ,32 )); 5355 5356vuint32m1_t v_scales_raw = __riscv_vsrl_vx_u32m1 (v_aux ,28 ,4 ); 5357vuint32m1_t v_scales = __riscv_vadd_vx_u32m1 ( 5358__riscv_vsll_vx_u32m1 (v_scales_raw ,1 ,4 ), 53591 ,4 ); 5360int32_t scale0 = (int32_t )__riscv_vmv_x_s_u32m1_u32 (v_scales ); 5361int32_t scale1 = (int32_t )__riscv_vmv_x_s_u32m1_u32 (__riscv_vslidedown_vx_u32m1 (v_scales ,1 ,4 )); 5362int32_t scale2 = (int32_t )__riscv_vmv_x_s_u32m1_u32 (__riscv_vslidedown_vx_u32m1 (v_scales ,2 ,4 )); 5363int32_t scale3 = (int32_t )__riscv_vmv_x_s_u32m1_u32 (__riscv_vslidedown_vx_u32m1 (v_scales ,3 ,4 )); 5364 5365block_sum += (float )(group0_sum * scale0 + group1_sum * scale1 + 5366group2_sum * scale2 + group3_sum * scale3 ); 5367 } 5368 5369sumf += d * block_sum ; 5370 } 5371* s = 0.25f * sumf ; 5372} 5373 5374static NOINLINE void ggml_vec_dot_iq3_xxs_q8_K_vl1024 (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 ) { 5375assert (n %QK_K == 0 ); 5376assert (nrc == 1 ); 5377UNUSED (nrc );UNUSED (bx );UNUSED (by );UNUSED (bs ); 5378 5379const block_iq3_xxs * GGML_RESTRICT x = vx ; 5380const block_q8_K * GGML_RESTRICT y = vy ; 5381const int nb = n /QK_K ; 5382 5383const uint64_t * signs64 = (const uint64_t * )keven_signs_q2xs ; 5384const uint32_t * grid32 = (const uint32_t * )iq3xxs_grid ; 5385 5386vuint32m1_t v_shifts ; 5387 { 5388vuint32m1_t v_id = __riscv_vid_v_u32m1 (32 ); 5389vuint32m1_t v_mod4 = __riscv_vand_vx_u32m1 (v_id ,3 ,32 ); 5390v_shifts = __riscv_vmul_vx_u32m1 (v_mod4 ,7 ,32 ); 5391 } 5392vuint16mf2_t v_gather_idx ; 5393 { 5394vuint16mf2_t v_id_16 = __riscv_vid_v_u16mf2 (32 ); 5395v_gather_idx = __riscv_vsrl_vx_u16mf2 (v_id_16 ,2 ,32 ); 5396 } 5397 5398float sumf = 0.0f ; 5399uint32_t aux32 [8 ];// Buffer for block metadata 5400 5401for (int i = 0 ;i < nb ;++ i ) { 5402const float d = GGML_CPU_FP16_TO_FP32 (x [i ].d )* y [i ].d ; 5403 5404const uint8_t * GGML_RESTRICT q3_indices = x [i ].qs ; 5405const uint8_t * GGML_RESTRICT metadata = x [i ].qs + QK_K /4 ; 5406const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5407 5408vint8m2_t v_q8 = __riscv_vle8_v_i8m2 (q8 ,256 ); 5409vuint8mf2_t v_q3_idx_raw = __riscv_vle8_v_u8mf2 (q3_indices ,64 ); 5410vuint16m1_t v_q3_idx_u16 = __riscv_vwmulu_vx_u16m1 (v_q3_idx_raw ,4 ,64 ); 5411 5412vuint32m2_t v_q3_grid_vals = __riscv_vluxei16_v_u32m2 (grid32 ,v_q3_idx_u16 ,64 ); 5413 5414vint8m2_t v_q3_mags = __riscv_vreinterpret_v_u8m2_i8m2 ( 5415__riscv_vreinterpret_v_u32m2_u8m2 (v_q3_grid_vals )); 5416 5417memcpy (aux32 ,metadata ,8 * sizeof (uint32_t )); 5418vuint32m1_t v_aux_8 = __riscv_vle32_v_u32m1 (aux32 ,8 ); 5419 5420vuint32m1_t v_aux_32 = __riscv_vrgatherei16_vv_u32m1 (v_aux_8 ,v_gather_idx ,32 ); 5421 5422vuint32m1_t v_sign_idx_raw = __riscv_vand_vx_u32m1 ( 5423__riscv_vsrl_vv_u32m1 (v_aux_32 ,v_shifts ,32 ),127 ,32 ); 5424 5425vuint16mf2_t v_sign_offsets = __riscv_vsll_vx_u16mf2 ( 5426__riscv_vncvt_x_x_w_u16mf2 (v_sign_idx_raw ,32 ),3 ,32 ); 5427 5428vuint64m2_t v_signs_u64 = __riscv_vluxei16_v_u64m2 (signs64 ,v_sign_offsets ,32 ); 5429 5430vint8m2_t v_signs = __riscv_vreinterpret_v_u8m2_i8m2 ( 5431__riscv_vreinterpret_v_u64m2_u8m2 (v_signs_u64 )); 5432 5433vint8m2_t v_q3_final = __riscv_vmul_vv_i8m2 (v_q3_mags ,v_signs ,256 ); 5434 5435vint16m4_t v_dot = __riscv_vwmul_vv_i16m4 (v_q8 ,v_q3_final ,256 ); 5436float block_sum = 0.0f ; 5437vint32m1_t v_zero = __riscv_vmv_v_x_i32m1 (0 ,1 ); 5438vint16m4_t v_accum = v_dot ; 5439 5440for (int j = 0 ;j < 8 ;++ j ) { 5441float scale = (float )(2 * (aux32 [j ] >>28 )+ 1 ); 5442 5443vint32m1_t v_partial_sum = __riscv_vwredsum_vs_i16m4_i32m1 (v_accum ,v_zero ,32 ); 5444 5445int32_t partial_sum_i = __riscv_vmv_x_s_i32m1_i32 (v_partial_sum ); 5446block_sum += partial_sum_i * scale ; 5447v_accum = __riscv_vslidedown_vx_i16m4 (v_accum ,32 ,32 ); 5448 5449 } 5450 5451sumf += d * block_sum ; 5452 } 5453* s = 0.25f * sumf ; 5454} 5455#endif 5456 5457void 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 ) { 5458#if defined__riscv_v 5459switch (__riscv_vlenb ()* 8 ) { 5460case 128 : 5461ggml_vec_dot_iq3_xxs_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5462break ; 5463case 256 : 5464ggml_vec_dot_iq3_xxs_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5465break ; 5466case 512 : 5467ggml_vec_dot_iq3_xxs_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5468break ; 5469default :// 1024 and above 5470ggml_vec_dot_iq3_xxs_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5471break ; 5472 } 5473#else 5474ggml_vec_dot_iq3_xxs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5475#endif 5476} 5477 5478#if defined__riscv_v 5479static NOINLINE void ggml_vec_dot_iq4_nl_q8_0_vl128 (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 ) { 5480assert (nrc == 1 ); 5481UNUSED (nrc ); 5482UNUSED (bx ); 5483UNUSED (by ); 5484UNUSED (bs ); 5485assert (n %QK4_NL == 0 ); 5486static_assert (QK4_NL == QK8_0 ,"QK4_NL and QK8_0 must be the same" ); 5487 5488const block_iq4_nl * GGML_RESTRICT x = vx ; 5489const block_q8_0 * GGML_RESTRICT y = vy ; 5490 5491const int nb = n /QK4_NL ; 5492 5493int ib = 0 ; 5494float sumf = 0 ; 5495 5496// Load the lookup table once. 5497const vint8m2_t values = __riscv_vle8_v_i8m2 (kvalues_iq4nl ,16 ); 5498int acc1 ,acc2 ; 5499 5500// We process 2 blocks at once. 5501for (;ib + 1 < nb ;ib += 2 ) { 5502// Weights and activations. 5503vuint8m1_t iq4_packed1 = __riscv_vle8_v_u8m1 (x [ib + 0 ].qs ,16 ); 5504vint8m2_t q8b1 = __riscv_vle8_v_i8m2 (y [ib + 0 ].qs ,32 ); 5505vuint8m1_t iq4_packed2 = __riscv_vle8_v_u8m1 (x [ib + 1 ].qs ,16 ); 5506vint8m2_t q8b2 = __riscv_vle8_v_i8m2 (y [ib + 1 ].qs ,32 ); 5507 5508// Unpack the weight blocks. 5509vuint8m2_t iq4bits1 = __riscv_vcreate_v_u8m1_u8m2 ( 5510__riscv_vand_vx_u8m1 (iq4_packed1 ,0xf ,16 ), 5511__riscv_vsrl_vx_u8m1 (iq4_packed1 ,4 ,16 ) 5512 ); 5513vuint8m2_t iq4bits2 = __riscv_vcreate_v_u8m1_u8m2 ( 5514__riscv_vand_vx_u8m1 (iq4_packed2 ,0xf ,16 ), 5515__riscv_vsrl_vx_u8m1 (iq4_packed2 ,4 ,16 ) 5516 ); 5517 5518// Gather values from the lookup table. 5519vint8m2_t iq4b1 = __riscv_vrgather_vv_i8m2 (values ,iq4bits1 ,32 ); 5520vint8m2_t iq4b2 = __riscv_vrgather_vv_i8m2 (values ,iq4bits2 ,32 ); 5521 5522// Accumulation. 5523vint16m4_t sum1 = __riscv_vwmul_vv_i16m4 (q8b1 ,iq4b1 ,32 ); 5524vint16m4_t sum2 = __riscv_vwmul_vv_i16m4 (q8b2 ,iq4b2 ,32 ); 5525__riscv_vse32_v_i32m1 (& acc1 ,__riscv_vwredsum_vs_i16m4_i32m1 (sum1 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),32 ),1 ); 5526__riscv_vse32_v_i32m1 (& acc2 ,__riscv_vwredsum_vs_i16m4_i32m1 (sum2 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),32 ),1 ); 5527sumf += ((GGML_CPU_FP16_TO_FP32 (x [ib + 0 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* acc1 )); 5528sumf += ((GGML_CPU_FP16_TO_FP32 (x [ib + 1 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* acc2 )); 5529 } 5530 5531* s = sumf ; 5532} 5533 5534static NOINLINE void ggml_vec_dot_iq4_nl_q8_0_vl256 (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 ) { 5535assert (nrc == 1 ); 5536UNUSED (nrc ); 5537UNUSED (bx ); 5538UNUSED (by ); 5539UNUSED (bs ); 5540assert (n %QK4_NL == 0 ); 5541static_assert (QK4_NL == QK8_0 ,"QK4_NL and QK8_0 must be the same" ); 5542 5543const block_iq4_nl * GGML_RESTRICT x = vx ; 5544const block_q8_0 * GGML_RESTRICT y = vy ; 5545 5546const int nb = n /QK4_NL ; 5547 5548int ib = 0 ; 5549float sumf = 0 ; 5550 5551// Load the lookup table once. 5552const vint8mf2_t values = __riscv_vle8_v_i8mf2 (kvalues_iq4nl ,16 ); 5553int acc1 ,acc2 ; 5554 5555// We process 2 blocks at once. 5556for (;ib + 1 < nb ;ib += 2 ) { 5557// Weights and activations. 5558vuint8mf2_t iq4_packed1 = __riscv_vle8_v_u8mf2 (x [ib + 0 ].qs ,16 ); 5559vint8mf2_t q8b_lo1 = __riscv_vle8_v_i8mf2 (y [ib + 0 ].qs ,16 ); 5560vint8mf2_t q8b_hi1 = __riscv_vle8_v_i8mf2 (y [ib + 0 ].qs + 16 ,16 ); 5561vuint8mf2_t iq4_packed2 = __riscv_vle8_v_u8mf2 (x [ib + 1 ].qs ,16 ); 5562vint8mf2_t q8b_lo2 = __riscv_vle8_v_i8mf2 (y [ib + 1 ].qs ,16 ); 5563vint8mf2_t q8b_hi2 = __riscv_vle8_v_i8mf2 (y [ib + 1 ].qs + 16 ,16 ); 5564 5565// Unpack the weight blocks. 5566vuint8mf2_t iq4bits_lo1 = __riscv_vand_vx_u8mf2 (iq4_packed1 ,0xf ,16 ); 5567vuint8mf2_t iq4bits_hi1 = __riscv_vsrl_vx_u8mf2 (iq4_packed1 ,4 ,16 ); 5568vuint8mf2_t iq4bits_lo2 = __riscv_vand_vx_u8mf2 (iq4_packed2 ,0xf ,16 ); 5569vuint8mf2_t iq4bits_hi2 = __riscv_vsrl_vx_u8mf2 (iq4_packed2 ,4 ,16 ); 5570 5571// Gather values from the lookup table. 5572vint8mf2_t iq4b_lo1 = __riscv_vrgather_vv_i8mf2 (values ,iq4bits_lo1 ,16 ); 5573vint8mf2_t iq4b_hi1 = __riscv_vrgather_vv_i8mf2 (values ,iq4bits_hi1 ,16 ); 5574vint8mf2_t iq4b_lo2 = __riscv_vrgather_vv_i8mf2 (values ,iq4bits_lo2 ,16 ); 5575vint8mf2_t iq4b_hi2 = __riscv_vrgather_vv_i8mf2 (values ,iq4bits_hi2 ,16 ); 5576 5577// Accumulation. 5578vint16m1_t sum1 = __riscv_vwmul_vv_i16m1 (q8b_lo1 ,iq4b_lo1 ,16 ); 5579sum1 = __riscv_vwmacc_vv_i16m1 (sum1 ,q8b_hi1 ,iq4b_hi1 ,16 ); 5580vint16m1_t sum2 = __riscv_vwmul_vv_i16m1 (q8b_lo2 ,iq4b_lo2 ,16 ); 5581sum2 = __riscv_vwmacc_vv_i16m1 (sum2 ,q8b_hi2 ,iq4b_hi2 ,16 ); 5582__riscv_vse32_v_i32m1 (& acc1 ,__riscv_vwredsum_vs_i16m1_i32m1 (sum1 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ),1 ); 5583__riscv_vse32_v_i32m1 (& acc2 ,__riscv_vwredsum_vs_i16m1_i32m1 (sum2 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ),1 ); 5584sumf += ((GGML_CPU_FP16_TO_FP32 (x [ib + 0 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* acc1 )); 5585sumf += ((GGML_CPU_FP16_TO_FP32 (x [ib + 1 ].d )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* acc2 )); 5586 } 5587 5588* s = sumf ; 5589} 5590#endif 5591 5592void 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 ) { 5593#if defined__riscv_v 5594switch (__riscv_vlenb ()* 8 ) { 5595case 128 : 5596ggml_vec_dot_iq4_nl_q8_0_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5597break ; 5598default :// 256 and above 5599ggml_vec_dot_iq4_nl_q8_0_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5600break ; 5601 } 5602#else 5603ggml_vec_dot_iq4_nl_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5604#endif 5605} 5606 5607#if defined__riscv_v 5608static NOINLINE void ggml_vec_dot_iq4_xs_q8_K_vl128 (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 ) { 5609assert (nrc == 1 ); 5610UNUSED (nrc ); 5611UNUSED (bx ); 5612UNUSED (by ); 5613UNUSED (bs ); 5614assert (n %QK_K == 0 ); 5615 5616const block_iq4_xs * GGML_RESTRICT x = vx ; 5617const block_q8_K * GGML_RESTRICT y = vy ; 5618 5619const int nb = n /QK_K ; 5620 5621const vint8m4_t values = __riscv_vle8_v_i8m4 (kvalues_iq4nl ,16 ); 5622float sumf = 0 ; 5623 5624for (int ibl = 0 ;ibl < nb ;++ ibl ) { 5625const int8_t * q8 = y [ibl ].qs ; 5626const uint8_t * iq4 = x [ibl ].qs ; 5627uint16_t h = x [ibl ].scales_h ; 5628 5629// We process 2 sub-blocks together. 5630int sumi1 = 0 ,sumi2 = 0 ; 5631#pragma GCC unroll 1 5632for (int ib = 0 ;ib < QK_K /64 ;++ ib ) { 5633// Load the packed weights. 5634const vuint8m2_t iq4_packed = __riscv_vle8_v_u8m2 (iq4 ,32 ); 5635iq4 += 32 ; 5636 5637// Unpack the weight blocks. 5638const vuint8m2_t iq4bits_lo = __riscv_vand_vx_u8m2 (iq4_packed ,0xf ,32 ); 5639const vuint8m2_t iq4bits_hi = __riscv_vsrl_vx_u8m2 (iq4_packed ,4 ,32 ); 5640const vuint8m4_t iq4bits = __riscv_vcreate_v_u8m2_u8m4 (iq4bits_lo ,iq4bits_hi ); 5641const vuint8m4_t iq4bits_reorder = __riscv_vcreate_v_u8m1_u8m4 ( 5642__riscv_vmv_v_v_u8m1 (__riscv_vget_v_u8m4_u8m1 (iq4bits ,0 ),16 ), 5643__riscv_vmv_v_v_u8m1 (__riscv_vget_v_u8m4_u8m1 (iq4bits ,2 ),16 ), 5644__riscv_vmv_v_v_u8m1 (__riscv_vget_v_u8m4_u8m1 (iq4bits ,1 ),16 ), 5645__riscv_vmv_v_v_u8m1 (__riscv_vget_v_u8m4_u8m1 (iq4bits ,3 ),16 ) 5646 ); 5647const vint8m4_t iq4b = __riscv_vrgather_vv_i8m4 (values ,iq4bits_reorder ,64 ); 5648 5649// Multiply with activations. 5650const vint8m4_t q8b = __riscv_vle8_v_i8m4 (q8 ,64 ); 5651q8 += 64 ; 5652const vint16m8_t prod = __riscv_vwmul_vv_i16m8 (iq4b ,q8b ,64 ); 5653 5654// Reduce separately. 5655const int acc0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (prod ,0 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5656const int acc1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m4_i32m1 (__riscv_vget_v_i16m8_i16m4 (prod ,1 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5657 5658const int ls1 = ((x [ibl ].scales_l [ib ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5659const int ls2 = ((x [ibl ].scales_l [ib ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5660h >>=4 ; 5661 5662sumi1 += acc0 * ls1 ; 5663sumi2 += acc1 * ls2 ; 5664 5665 __asm__ __volatile__("" :::"memory" ); 5666 } 5667 5668sumf += GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d * (sumi1 + sumi2 ); 5669 } 5670 5671* s = sumf ; 5672} 5673 5674static NOINLINE void ggml_vec_dot_iq4_xs_q8_K_vl256 (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 ) { 5675assert (nrc == 1 ); 5676UNUSED (nrc ); 5677UNUSED (bx ); 5678UNUSED (by ); 5679UNUSED (bs ); 5680assert (n %QK_K == 0 ); 5681 5682const block_iq4_xs * GGML_RESTRICT x = vx ; 5683const block_q8_K * GGML_RESTRICT y = vy ; 5684 5685const int nb = n /QK_K ; 5686 5687const vint8m4_t values = __riscv_vle8_v_i8m4 (kvalues_iq4nl ,16 ); 5688float sumf = 0 ; 5689 5690// Indices for re-ordering IQ4 data. 5691uint16_t index [16 ]= { 56920 ,1 ,8 ,9 , 56932 ,3 ,10 ,11 , 56944 ,5 ,12 ,13 , 56956 ,7 ,14 ,15 , 5696 }; 5697vuint16m1_t i_vec = __riscv_vle16_v_u16m1 (index ,16 ); 5698 5699for (int ibl = 0 ;ibl < nb ;++ ibl ) { 5700const int8_t * q8 = y [ibl ].qs ; 5701const uint8_t * iq4 = x [ibl ].qs ; 5702uint16_t h = x [ibl ].scales_h ; 5703 5704int sumi1 = 0 ,sumi2 = 0 ,sumi3 = 0 ,sumi4 = 0 ; 5705 5706#pragma GCC unroll 1 5707for (int ib = 0 ;ib < QK_K /128 ;++ ib ) { 5708// Weights and activations. 5709vuint8m2_t iq4_packed = __riscv_vle8_v_u8m2 (iq4 ,64 ); 5710iq4 += 64 ; 5711 5712// Unpack the weight blocks. 5713vuint8m2_t iq4bits_lo = __riscv_vand_vx_u8m2 (iq4_packed ,0xf ,64 ); 5714vuint8m2_t iq4bits_hi = __riscv_vsrl_vx_u8m2 (iq4_packed ,4 ,64 ); 5715vuint8m4_t iq4bits = __riscv_vcreate_v_u8m2_u8m4 (iq4bits_lo ,iq4bits_hi ); 5716vuint8m4_t iq4bits_reorder = __riscv_vreinterpret_v_u64m4_u8m4 (__riscv_vrgatherei16_vv_u64m4 (__riscv_vreinterpret_v_u8m4_u64m4 (iq4bits ),i_vec ,16 )); 5717vint8m4_t iq4b = __riscv_vrgather_vv_i8m4 (values ,iq4bits_reorder ,128 ); 5718 5719 __asm__ __volatile__("" :::"memory" ); 5720 5721// Multiply with activations. 5722vint8m4_t q8b = __riscv_vle8_v_i8m4 (q8 ,128 ); 5723vint16m8_t prod = __riscv_vwmul_vv_i16m8 (iq4b ,q8b ,128 ); 5724q8 += 128 ; 5725 5726 __asm__ __volatile__("" :::"memory" ); 5727 5728// Reduce separately. 5729int acc0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (prod ,0 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5730int acc1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (prod ,1 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5731int acc2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (prod ,2 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5732int acc3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m2_i32m1 (__riscv_vget_v_i16m8_i16m2 (prod ,3 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5733 5734int ls1 = ((x [ibl ].scales_l [ib * 2 + 0 ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5735int ls2 = ((x [ibl ].scales_l [ib * 2 + 0 ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5736int ls3 = ((x [ibl ].scales_l [ib * 2 + 1 ]& 0xf ) | ((h <<0 )& 0x30 ))- 32 ; 5737int ls4 = ((x [ibl ].scales_l [ib * 2 + 1 ] >>4 ) | ((h >>2 )& 0x30 ))- 32 ; 5738h >>=8 ; 5739 5740sumi1 += acc0 * ls1 ; 5741sumi2 += acc1 * ls2 ; 5742sumi3 += acc2 * ls3 ; 5743sumi4 += acc3 * ls4 ; 5744 5745 __asm__ __volatile__("" :::"memory" ); 5746 } 5747 5748sumf += GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d * (sumi1 + sumi2 + sumi3 + sumi4 ); 5749 } 5750 5751* s = sumf ; 5752} 5753 5754static NOINLINE void ggml_vec_dot_iq4_xs_q8_K_vl512 (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 ) { 5755assert (nrc == 1 ); 5756UNUSED (nrc ); 5757UNUSED (bx ); 5758UNUSED (by ); 5759UNUSED (bs ); 5760assert (n %QK_K == 0 ); 5761 5762const block_iq4_xs * GGML_RESTRICT x = vx ; 5763const block_q8_K * GGML_RESTRICT y = vy ; 5764 5765const int nb = n /QK_K ; 5766 5767const vint8m4_t values = __riscv_vle8_v_i8m4 (kvalues_iq4nl ,16 ); 5768float sumf = 0 ; 5769 5770// Indices for re-ordering IQ4 data. 5771const uint16_t index [32 ]= { 57720 ,1 ,16 ,17 , 57732 ,3 ,18 ,19 , 57744 ,5 ,20 ,21 , 57756 ,7 ,22 ,23 , 57768 ,9 ,24 ,25 , 577710 ,11 ,26 ,27 , 577812 ,13 ,28 ,29 , 577914 ,15 ,30 ,31 , 5780 }; 5781const vuint16m1_t i_vec = __riscv_vle16_v_u16m1 (index ,32 ); 5782 5783for (int ibl = 0 ;ibl < nb ;++ ibl ) { 5784const int8_t * q8 = y [ibl ].qs ; 5785const uint8_t * iq4 = x [ibl ].qs ; 5786uint16_t h = x [ibl ].scales_h ; 5787 5788int sumi = 0 ; 5789 5790#pragma GCC unroll 1 5791// Process the entire super-block together. 5792for (int ib = 0 ;ib < QK_K /256 ;++ ib ) { 5793// Weights and activations. 5794const vuint8m2_t iq4_packed = __riscv_vle8_v_u8m2 (iq4 ,128 ); 5795iq4 += 128 ; 5796 5797// Unpack the weight blocks. 5798const vuint8m2_t iq4bits_lo = __riscv_vand_vx_u8m2 (iq4_packed ,0xf ,128 ); 5799const vuint8m2_t iq4bits_hi = __riscv_vsrl_vx_u8m2 (iq4_packed ,4 ,128 ); 5800const vuint8m4_t iq4bits = __riscv_vcreate_v_u8m2_u8m4 (iq4bits_lo ,iq4bits_hi ); 5801const vuint8m4_t iq4bits_reorder = __riscv_vreinterpret_v_u64m4_u8m4 (__riscv_vrgatherei16_vv_u64m4 (__riscv_vreinterpret_v_u8m4_u64m4 (iq4bits ),i_vec ,32 )); 5802const vint8m4_t iq4b = __riscv_vrgather_vv_i8m4 (values ,iq4bits_reorder ,256 ); 5803 5804 __asm__ __volatile__("" :::"memory" ); 5805 5806// Multiply with activations. 5807const vint8m4_t q8b = __riscv_vle8_v_i8m4 (q8 ,256 ); 5808const vint16m8_t prod = __riscv_vwmul_vv_i16m8 (iq4b ,q8b ,256 ); 5809q8 += 256 ; 5810 5811// Reduce separately. 5812const int acc0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,0 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5813const int acc1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,1 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5814const int acc2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,2 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5815const int acc3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,3 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5816const int acc4 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,4 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5817const int acc5 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,5 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5818const int acc6 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,6 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5819const int acc7 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m8_i16m1 (prod ,7 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5820 5821 5822const int ls0 = ((x [ibl ].scales_l [0 ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5823const int ls1 = ((x [ibl ].scales_l [0 ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5824const int ls2 = ((x [ibl ].scales_l [1 ]& 0xf ) | ((h <<0 )& 0x30 ))- 32 ; 5825const int ls3 = ((x [ibl ].scales_l [1 ] >>4 ) | ((h >>2 )& 0x30 ))- 32 ; 5826h >>=8 ; 5827const int ls4 = ((x [ibl ].scales_l [2 ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5828const int ls5 = ((x [ibl ].scales_l [2 ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5829const int ls6 = ((x [ibl ].scales_l [3 ]& 0xf ) | ((h <<0 )& 0x30 ))- 32 ; 5830const int ls7 = ((x [ibl ].scales_l [3 ] >>4 ) | ((h >>2 )& 0x30 ))- 32 ; 5831 5832sumi += acc0 * ls0 ; 5833sumi += acc1 * ls1 ; 5834sumi += acc2 * ls2 ; 5835sumi += acc3 * ls3 ; 5836sumi += acc4 * ls4 ; 5837sumi += acc5 * ls5 ; 5838sumi += acc6 * ls6 ; 5839sumi += acc7 * ls7 ; 5840 5841 __asm__ __volatile__("" :::"memory" ); 5842 } 5843 5844sumf += GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d * (sumi ); 5845 } 5846 5847* s = sumf ; 5848} 5849 5850static NOINLINE void ggml_vec_dot_iq4_xs_q8_K_vl1024 (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 ) { 5851assert (nrc == 1 ); 5852UNUSED (nrc ); 5853UNUSED (bx ); 5854UNUSED (by ); 5855UNUSED (bs ); 5856assert (n %QK_K == 0 ); 5857 5858const block_iq4_xs * GGML_RESTRICT x = vx ; 5859const block_q8_K * GGML_RESTRICT y = vy ; 5860 5861const int nb = n /QK_K ; 5862 5863const vint8m2_t values = __riscv_vle8_v_i8m2 (kvalues_iq4nl ,16 ); 5864float sumf = 0 ; 5865 5866// Indices for re-ordering IQ4 data. 5867const uint16_t index [32 ]= { 58680 ,1 ,16 ,17 , 58692 ,3 ,18 ,19 , 58704 ,5 ,20 ,21 , 58716 ,7 ,22 ,23 , 58728 ,9 ,24 ,25 , 587310 ,11 ,26 ,27 , 587412 ,13 ,28 ,29 , 587514 ,15 ,30 ,31 , 5876 }; 5877const vuint16mf2_t i_vec = __riscv_vle16_v_u16mf2 (index ,32 ); 5878 5879for (int ibl = 0 ;ibl < nb ;++ ibl ) { 5880const int8_t * q8 = y [ibl ].qs ; 5881const uint8_t * iq4 = x [ibl ].qs ; 5882uint16_t h = x [ibl ].scales_h ; 5883 5884int sumi = 0 ; 5885 5886#pragma GCC unroll 1 5887// Process the entire super-block together. 5888for (int ib = 0 ;ib < QK_K /256 ;++ ib ) { 5889// Weights and activations. 5890const vuint8m1_t iq4_packed = __riscv_vle8_v_u8m1 (iq4 ,128 ); 5891iq4 += 128 ; 5892 5893// Unpack the weight blocks. 5894const vuint8m1_t iq4bits_lo = __riscv_vand_vx_u8m1 (iq4_packed ,0xf ,128 ); 5895const vuint8m1_t iq4bits_hi = __riscv_vsrl_vx_u8m1 (iq4_packed ,4 ,128 ); 5896const vuint8m2_t iq4bits = __riscv_vcreate_v_u8m1_u8m2 (iq4bits_lo ,iq4bits_hi ); 5897const vuint8m2_t iq4bits_reorder = __riscv_vreinterpret_v_u64m2_u8m2 (__riscv_vrgatherei16_vv_u64m2 (__riscv_vreinterpret_v_u8m2_u64m2 (iq4bits ),i_vec ,32 )); 5898const vint8m2_t iq4b = __riscv_vrgather_vv_i8m2 (values ,iq4bits_reorder ,256 ); 5899 5900 __asm__ __volatile__("" :::"memory" ); 5901 5902// Multiply with activations. 5903const vint8m2_t q8b = __riscv_vle8_v_i8m2 (q8 ,256 ); 5904const vint16m4_t prod = __riscv_vwmul_vv_i16m4 (iq4b ,q8b ,256 ); 5905q8 += 256 ; 5906 5907// Mask for processing 32 elements per prod register. 5908const vuint16m1_t p_index = __riscv_vid_v_u16m1 (64 ); 5909const vbool16_t p_mask = __riscv_vmsgtu_vx_u16m1_b16 (p_index ,31 ,64 ); 5910 5911// Reduce separately. 5912const int acc0 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (prod ,0 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5913const int acc1 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (p_mask ,__riscv_vget_v_i16m4_i16m1 (prod ,0 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),64 )); 5914const int acc2 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (prod ,1 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5915const int acc3 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (p_mask ,__riscv_vget_v_i16m4_i16m1 (prod ,1 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),64 )); 5916const int acc4 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (prod ,2 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5917const int acc5 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (p_mask ,__riscv_vget_v_i16m4_i16m1 (prod ,2 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),64 )); 5918const int acc6 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1 (__riscv_vget_v_i16m4_i16m1 (prod ,3 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),32 )); 5919const int acc7 = __riscv_vmv_x_s_i32m1_i32 (__riscv_vwredsum_vs_i16m1_i32m1_m (p_mask ,__riscv_vget_v_i16m4_i16m1 (prod ,3 ),__riscv_vmv_v_x_i32m1 (0 ,1 ),64 )); 5920 5921const int ls0 = ((x [ibl ].scales_l [0 ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5922const int ls1 = ((x [ibl ].scales_l [0 ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5923const int ls2 = ((x [ibl ].scales_l [1 ]& 0xf ) | ((h <<0 )& 0x30 ))- 32 ; 5924const int ls3 = ((x [ibl ].scales_l [1 ] >>4 ) | ((h >>2 )& 0x30 ))- 32 ; 5925h >>=8 ; 5926const int ls4 = ((x [ibl ].scales_l [2 ]& 0xf ) | ((h <<4 )& 0x30 ))- 32 ; 5927const int ls5 = ((x [ibl ].scales_l [2 ] >>4 ) | ((h <<2 )& 0x30 ))- 32 ; 5928const int ls6 = ((x [ibl ].scales_l [3 ]& 0xf ) | ((h <<0 )& 0x30 ))- 32 ; 5929const int ls7 = ((x [ibl ].scales_l [3 ] >>4 ) | ((h >>2 )& 0x30 ))- 32 ; 5930 5931sumi += acc0 * ls0 ; 5932sumi += acc1 * ls1 ; 5933sumi += acc2 * ls2 ; 5934sumi += acc3 * ls3 ; 5935sumi += acc4 * ls4 ; 5936sumi += acc5 * ls5 ; 5937sumi += acc6 * ls6 ; 5938sumi += acc7 * ls7 ; 5939 5940 __asm__ __volatile__("" :::"memory" ); 5941 } 5942 5943sumf += GGML_CPU_FP16_TO_FP32 (x [ibl ].d )* y [ibl ].d * (sumi ); 5944 } 5945 5946* s = sumf ; 5947} 5948#endif 5949 5950void 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 ) { 5951#if defined__riscv_v 5952switch (__riscv_vlenb ()* 8 ) { 5953case 128 : 5954ggml_vec_dot_iq4_xs_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5955break ; 5956case 256 : 5957ggml_vec_dot_iq4_xs_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5958break ; 5959case 512 : 5960ggml_vec_dot_iq4_xs_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5961break ; 5962case 1024 : 5963ggml_vec_dot_iq4_xs_q8_K_vl1024 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5964break ; 5965default : 5966ggml_vec_dot_iq4_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5967break ; 5968 } 5969#else 5970ggml_vec_dot_iq4_xs_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 5971#endif 5972} 5973 5974#if defined__riscv_v 5975static NOINLINE void ggml_vec_dot_tq1_0_q8_K_vl128 (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 ) { 5976assert (nrc == 1 ); 5977UNUSED (nrc ); 5978UNUSED (bx ); 5979UNUSED (by ); 5980UNUSED (bs ); 5981 5982const block_tq1_0 * GGML_RESTRICT x = vx ; 5983const block_q8_K * GGML_RESTRICT y = vy ; 5984 5985const int nb = n /QK_K ; 5986 5987float sumf = 0.0f ; 5988uint8_t pow [16 ]= {1 ,1 ,1 ,1 ,3 ,3 ,3 ,3 ,9 ,9 ,9 ,9 ,27 ,27 ,27 ,27 }; 5989 5990for (int i = 0 ;i < nb ;i ++ ) { 5991const uint8_t * GGML_RESTRICT tq = x [i ].qs ; 5992const int8_t * GGML_RESTRICT q8 = y [i ].qs ; 5993 5994// First loop. 5995vint16m4_t suml1 ; 5996 { 5997const int vl = 32 ; 5998const vuint8m2_t tqb = __riscv_vle8_v_u8m2 (tq ,vl ); 5999tq += 32 ; 6000 6001 { 6002const vuint16m4_t tq0 = __riscv_vsrl_vx_u16m4 (__riscv_vwmulu_vx_u16m4 (tqb ,3 ,vl ),8 ,vl ); 6003const vint16m4_t q80 = __riscv_vwcvt_x_x_v_i16m4 (__riscv_vle8_v_i8m2 (q8 ,vl ),vl ); 6004suml1 = __riscv_vmul_vv_i16m4 (__riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vsub_vx_u16m4 (tq0 ,1 ,vl )),q80 ,vl ); 6005q8 += 32 ; 6006 } 6007 6008uint8_t pow3 = 3 ; 6009#pragma GCC unroll 1 6010for (int t = 0 ;t < 4 ;t ++ ) { 6011const vuint16m4_t tqn = __riscv_vsrl_vx_u16m4 (__riscv_vwmulu_vx_u16m4 (__riscv_vmul_vx_u8m2 (tqb ,pow3 ,vl ),3 ,vl ),8 ,vl ); 6012const vint16m4_t q8n = __riscv_vwcvt_x_x_v_i16m4 (__riscv_vle8_v_i8m2 (q8 ,vl ),vl ); 6013suml1 = __riscv_vmacc_vv_i16m4 (suml1 ,__riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vsub_vx_u16m4 (tqn ,1 ,vl )),q8n ,vl ); 6014pow3 *=3 ; 6015q8 += 32 ; 6016 } 6017 } 6018 6019// Second loop. 6020vint16m2_t suml2 ; 6021 { 6022const int vl = 16 ; 6023const vuint8m1_t tqb = __riscv_vle8_v_u8m1 (tq ,vl ); 6024 6025 { 6026const vuint16m2_t tq0 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (tqb ,3 ,vl ),8 ,vl ); 6027const vint16m2_t q80 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (q8 ,vl ),vl ); 6028suml2 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq0 ,1 ,vl )),q80 ,vl ); 6029q8 += 16 ; 6030 } 6031 6032uint8_t pow3 = 3 ; 6033#pragma GCC unroll 1 6034for (int t = 0 ;t < 4 ;t ++ ) { 6035const vuint16m2_t tqn = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vx_u8m1 (tqb ,pow3 ,vl ),3 ,vl ),8 ,vl ); 6036const vint16m2_t q8n = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (q8 ,vl ),vl ); 6037suml2 = __riscv_vmacc_vv_i16m2 (suml2 ,__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tqn ,1 ,vl )),q8n ,vl ); 6038pow3 *=3 ; 6039q8 += 16 ; 6040 } 6041 } 6042 6043// Third loop. 6044vint16m2_t suml3 ; 6045 { 6046const int vl = 16 ; 6047 6048uint32_t qh ; 6049memcpy (& qh ,& x [i ].qh [0 ],4 ); 6050// Prevent fusion with vmv. 6051 __asm__ __volatile__("" :"+r" (qh )); 6052const vuint8m1_t tqb = __riscv_vreinterpret_v_u32m1_u8m1 (__riscv_vmv_v_x_u32m1 (qh ,vl /4 )); 6053 6054const vuint8m1_t p = __riscv_vle8_v_u8m1 (pow ,vl ); 6055 6056const vuint16m2_t tq0 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vv_u8m1 (tqb ,p ,vl ),3 ,vl ),8 ,vl ); 6057 6058const vint16m2_t q80 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (q8 ,vl ),vl ); 6059 6060suml3 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq0 ,1 ,vl )),q80 ,vl ); 6061 } 6062 6063vint16m2_t sumb = __riscv_vadd_vv_i16m2 (__riscv_vget_v_i16m4_i16m2 (suml1 ,0 ),__riscv_vget_v_i16m4_i16m2 (suml1 ,1 ),16 ); 6064sumb = __riscv_vadd_vv_i16m2 (sumb ,suml2 ,16 ); 6065sumb = __riscv_vadd_vv_i16m2 (sumb ,suml3 ,16 ); 6066 6067vint32m1_t sum = __riscv_vwredsum_vs_i16m2_i32m1 (sumb ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ); 6068sumf += __riscv_vmv_x_s_i32m1_i32 (sum )* y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 6069 } 6070 6071* s = sumf ; 6072} 6073 6074static NOINLINE void ggml_vec_dot_tq1_0_q8_K_vl256 (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 ) { 6075assert (nrc == 1 ); 6076UNUSED (nrc ); 6077UNUSED (bx ); 6078UNUSED (by ); 6079UNUSED (bs ); 6080 6081const block_tq1_0 * GGML_RESTRICT x = vx ; 6082const block_q8_K * GGML_RESTRICT y = vy ; 6083 6084const int nb = n /QK_K ; 6085 6086float sumf = 0.0f ; 6087uint8_t pow [16 ]= {1 ,1 ,1 ,1 ,3 ,3 ,3 ,3 ,9 ,9 ,9 ,9 ,27 ,27 ,27 ,27 }; 6088 6089for (int i = 0 ;i < nb ;i ++ ) { 6090// First loop. 6091vint16m2_t suml1 ; 6092 { 6093const int vl = 32 ; 6094vuint8m1_t tq = __riscv_vle8_v_u8m1 (x [i ].qs ,vl ); 6095 6096vuint16m2_t tq0 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (tq ,3 ,vl ),8 ,vl ); 6097vuint16m2_t tq1 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vx_u8m1 (tq ,3 ,vl ),3 ,vl ),8 ,vl ); 6098vuint16m2_t tq2 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vx_u8m1 (tq ,9 ,vl ),3 ,vl ),8 ,vl ); 6099vuint16m2_t tq3 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vx_u8m1 (tq ,27 ,vl ),3 ,vl ),8 ,vl ); 6100vuint16m2_t tq4 = __riscv_vsrl_vx_u16m2 (__riscv_vwmulu_vx_u16m2 (__riscv_vmul_vx_u8m1 (tq ,81 ,vl ),3 ,vl ),8 ,vl ); 6101 6102vint16m2_t q80 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (y [i ].qs + 0 ,vl ),vl ); 6103vint16m2_t q81 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (y [i ].qs + 32 ,vl ),vl ); 6104vint16m2_t q82 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (y [i ].qs + 64 ,vl ),vl ); 6105vint16m2_t q83 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (y [i ].qs + 96 ,vl ),vl ); 6106vint16m2_t q84 = __riscv_vwcvt_x_x_v_i16m2 (__riscv_vle8_v_i8m1 (y [i ].qs + 128 ,vl ),vl ); 6107 6108vint16m2_t sum0 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq0 ,1 ,vl )),q80 ,vl ); 6109vint16m2_t sum1 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq1 ,1 ,vl )),q81 ,vl ); 6110vint16m2_t sum2 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq2 ,1 ,vl )),q82 ,vl ); 6111vint16m2_t sum3 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq3 ,1 ,vl )),q83 ,vl ); 6112vint16m2_t sum4 = __riscv_vmul_vv_i16m2 (__riscv_vreinterpret_v_u16m2_i16m2 (__riscv_vsub_vx_u16m2 (tq4 ,1 ,vl )),q84 ,vl ); 6113 6114vint16m2_t sumi0 = __riscv_vadd_vv_i16m2 (sum0 ,sum1 ,vl ); 6115vint16m2_t sumi1 = __riscv_vadd_vv_i16m2 (sum2 ,sum3 ,vl ); 6116suml1 = __riscv_vadd_vv_i16m2 (sum4 ,__riscv_vadd_vv_i16m2 (sumi0 ,sumi1 ,vl ),vl ); 6117 } 6118 6119// Second loop. 6120vint16m1_t suml2 ; 6121 { 6122const int vl = 16 ; 6123vuint8mf2_t tq = __riscv_vle8_v_u8mf2 (x [i ].qs + 32 ,vl ); 6124 6125vuint16m1_t tq0 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (tq ,3 * 1 ,vl ),8 ,vl ); 6126vuint16m1_t tq1 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,3 ,vl ),3 ,vl ),8 ,vl ); 6127vuint16m1_t tq2 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,9 ,vl ),3 ,vl ),8 ,vl ); 6128vuint16m1_t tq3 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,27 ,vl ),3 ,vl ),8 ,vl ); 6129vuint16m1_t tq4 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,81 ,vl ),3 ,vl ),8 ,vl ); 6130 6131vint16m1_t q80 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 160 ,vl ),vl ); 6132vint16m1_t q81 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 176 ,vl ),vl ); 6133vint16m1_t q82 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 192 ,vl ),vl ); 6134vint16m1_t q83 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 208 ,vl ),vl ); 6135vint16m1_t q84 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 224 ,vl ),vl ); 6136 6137vint16m1_t sum0 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq0 ,1 ,vl )),q80 ,vl ); 6138vint16m1_t sum1 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq1 ,1 ,vl )),q81 ,vl ); 6139vint16m1_t sum2 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq2 ,1 ,vl )),q82 ,vl ); 6140vint16m1_t sum3 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq3 ,1 ,vl )),q83 ,vl ); 6141vint16m1_t sum4 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq4 ,1 ,vl )),q84 ,vl ); 6142 6143vint16m1_t sumi0 = __riscv_vadd_vv_i16m1 (sum0 ,sum1 ,vl ); 6144vint16m1_t sumi1 = __riscv_vadd_vv_i16m1 (sum2 ,sum3 ,vl ); 6145suml2 = __riscv_vadd_vv_i16m1 (sum4 ,__riscv_vadd_vv_i16m1 (sumi0 ,sumi1 ,vl ),vl ); 6146 } 6147 6148// Third loop. 6149vint16m1_t suml3 ; 6150 { 6151const int vl = 16 ; 6152 6153uint32_t qh ; 6154memcpy (& qh ,& x [i ].qh [0 ],4 ); 6155// Prevent fusion with vmv. 6156 __asm__ __volatile__("" :"+r" (qh )); 6157vuint8mf2_t tq = __riscv_vreinterpret_v_u32mf2_u8mf2 (__riscv_vmv_v_x_u32mf2 (qh ,vl /4 )); 6158 6159vuint8mf2_t p = __riscv_vle8_v_u8mf2 (pow ,vl ); 6160 6161vuint16m1_t tq0 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vv_u8mf2 (tq ,p ,vl ),3 ,vl ),8 ,vl ); 6162 6163vint16m1_t q80 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 240 ,vl ),vl ); 6164 6165suml3 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq0 ,1 ,vl )),q80 ,vl ); 6166 } 6167 6168vint16m1_t sumb = __riscv_vadd_vv_i16m1 (__riscv_vget_v_i16m2_i16m1 (suml1 ,0 ),__riscv_vget_v_i16m2_i16m1 (suml1 ,1 ),16 ); 6169sumb = __riscv_vadd_vv_i16m1 (sumb ,__riscv_vadd_vv_i16m1 (suml2 ,suml3 ,16 ),16 ); 6170 6171vint32m1_t sum = __riscv_vwredsum_vs_i16m1_i32m1 (sumb ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ); 6172sumf += __riscv_vmv_x_s_i32m1_i32 (sum )* y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 6173 } 6174 6175* s = sumf ; 6176} 6177 6178static NOINLINE void ggml_vec_dot_tq1_0_q8_K_vl512 (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 ) { 6179assert (nrc == 1 ); 6180UNUSED (nrc ); 6181UNUSED (bx ); 6182UNUSED (by ); 6183UNUSED (bs ); 6184 6185const block_tq1_0 * GGML_RESTRICT x = vx ; 6186const block_q8_K * GGML_RESTRICT y = vy ; 6187 6188const int nb = n /QK_K ; 6189 6190float sumf = 0.0f ; 6191uint8_t pow [16 ]= {1 ,1 ,1 ,1 ,3 ,3 ,3 ,3 ,9 ,9 ,9 ,9 ,27 ,27 ,27 ,27 }; 6192 6193for (int i = 0 ;i < nb ;i ++ ) { 6194// First loop. 6195vint16m1_t suml1 ; 6196 { 6197const int vl = 32 ; 6198vuint8mf2_t tq = __riscv_vle8_v_u8mf2 (x [i ].qs ,vl ); 6199 6200vuint16m1_t tq0 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (tq ,3 ,vl ),8 ,vl ); 6201vuint16m1_t tq1 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,3 ,vl ),3 ,vl ),8 ,vl ); 6202vuint16m1_t tq2 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,9 ,vl ),3 ,vl ),8 ,vl ); 6203vuint16m1_t tq3 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,27 ,vl ),3 ,vl ),8 ,vl ); 6204vuint16m1_t tq4 = __riscv_vsrl_vx_u16m1 (__riscv_vwmulu_vx_u16m1 (__riscv_vmul_vx_u8mf2 (tq ,81 ,vl ),3 ,vl ),8 ,vl ); 6205 6206vint16m1_t q80 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 0 ,vl ),vl ); 6207vint16m1_t q81 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 32 ,vl ),vl ); 6208vint16m1_t q82 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 64 ,vl ),vl ); 6209vint16m1_t q83 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 96 ,vl ),vl ); 6210vint16m1_t q84 = __riscv_vwcvt_x_x_v_i16m1 (__riscv_vle8_v_i8mf2 (y [i ].qs + 128 ,vl ),vl ); 6211 6212vint16m1_t sum0 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq0 ,1 ,vl )),q80 ,vl ); 6213vint16m1_t sum1 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq1 ,1 ,vl )),q81 ,vl ); 6214vint16m1_t sum2 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq2 ,1 ,vl )),q82 ,vl ); 6215vint16m1_t sum3 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq3 ,1 ,vl )),q83 ,vl ); 6216vint16m1_t sum4 = __riscv_vmul_vv_i16m1 (__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vsub_vx_u16m1 (tq4 ,1 ,vl )),q84 ,vl ); 6217 6218vint16m1_t sumi0 = __riscv_vadd_vv_i16m1 (sum0 ,sum1 ,vl ); 6219vint16m1_t sumi1 = __riscv_vadd_vv_i16m1 (sum2 ,sum3 ,vl ); 6220suml1 = __riscv_vadd_vv_i16m1 (sum4 ,__riscv_vadd_vv_i16m1 (sumi0 ,sumi1 ,vl ),vl ); 6221 } 6222 6223// Second loop. 6224vint16mf2_t suml2 ; 6225 { 6226const int vl = 16 ; 6227vuint8mf4_t tq = __riscv_vle8_v_u8mf4 (x [i ].qs + 32 ,vl ); 6228 6229vuint16mf2_t tq0 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (tq ,3 * 1 ,vl ),8 ,vl ); 6230vuint16mf2_t tq1 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (__riscv_vmul_vx_u8mf4 (tq ,3 ,vl ),3 ,vl ),8 ,vl ); 6231vuint16mf2_t tq2 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (__riscv_vmul_vx_u8mf4 (tq ,9 ,vl ),3 ,vl ),8 ,vl ); 6232vuint16mf2_t tq3 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (__riscv_vmul_vx_u8mf4 (tq ,27 ,vl ),3 ,vl ),8 ,vl ); 6233vuint16mf2_t tq4 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (__riscv_vmul_vx_u8mf4 (tq ,81 ,vl ),3 ,vl ),8 ,vl ); 6234 6235vint16mf2_t q80 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 160 ,vl ),vl ); 6236vint16mf2_t q81 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 176 ,vl ),vl ); 6237vint16mf2_t q82 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 192 ,vl ),vl ); 6238vint16mf2_t q83 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 208 ,vl ),vl ); 6239vint16mf2_t q84 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 224 ,vl ),vl ); 6240 6241vint16mf2_t sum0 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq0 ,1 ,vl )),q80 ,vl ); 6242vint16mf2_t sum1 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq1 ,1 ,vl )),q81 ,vl ); 6243vint16mf2_t sum2 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq2 ,1 ,vl )),q82 ,vl ); 6244vint16mf2_t sum3 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq3 ,1 ,vl )),q83 ,vl ); 6245vint16mf2_t sum4 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq4 ,1 ,vl )),q84 ,vl ); 6246 6247vint16mf2_t sumi0 = __riscv_vadd_vv_i16mf2 (sum0 ,sum1 ,vl ); 6248vint16mf2_t sumi1 = __riscv_vadd_vv_i16mf2 (sum2 ,sum3 ,vl ); 6249suml2 = __riscv_vadd_vv_i16mf2 (sum4 ,__riscv_vadd_vv_i16mf2 (sumi0 ,sumi1 ,vl ),vl ); 6250 } 6251 6252// Third loop. 6253vint16mf2_t suml3 ; 6254 { 6255const int vl = 16 ; 6256 6257uint32_t qh ; 6258memcpy (& qh ,& x [i ].qh [0 ],4 ); 6259// Prevent fusion with vmv. 6260 __asm__ __volatile__("" :"+r" (qh )); 6261vuint8mf4_t tq = __riscv_vlmul_trunc_v_u8mf2_u8mf4 (__riscv_vreinterpret_v_u32mf2_u8mf2 (__riscv_vmv_v_x_u32mf2 (qh ,vl /4 ))); 6262 6263vuint8mf4_t p = __riscv_vle8_v_u8mf4 (pow ,vl ); 6264 6265vuint16mf2_t tq0 = __riscv_vsrl_vx_u16mf2 (__riscv_vwmulu_vx_u16mf2 (__riscv_vmul_vv_u8mf4 (tq ,p ,vl ),3 ,vl ),8 ,vl ); 6266 6267vint16mf2_t q80 = __riscv_vwcvt_x_x_v_i16mf2 (__riscv_vle8_v_i8mf4 (y [i ].qs + 240 ,vl ),vl ); 6268 6269suml3 = __riscv_vmul_vv_i16mf2 (__riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vsub_vx_u16mf2 (tq0 ,1 ,vl )),q80 ,vl ); 6270 } 6271 6272vint32m1_t sum = __riscv_vwredsum_vs_i16m1_i32m1 (suml1 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),32 ); 6273sum = __riscv_vwredsum_vs_i16mf2_i32m1 (__riscv_vadd_vv_i16mf2 (suml2 ,suml3 ,16 ),sum ,16 ); 6274sumf += __riscv_vmv_x_s_i32m1_i32 (sum )* y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 6275 } 6276 6277* s = sumf ; 6278} 6279#endif 6280 6281void ggml_vec_dot_tq1_0_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 ) { 6282#if defined__riscv_v 6283switch (__riscv_vlenb ()* 8 ) { 6284case 128 : 6285ggml_vec_dot_tq1_0_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6286break ; 6287case 256 : 6288ggml_vec_dot_tq1_0_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6289break ; 6290default :// 512 and above 6291ggml_vec_dot_tq1_0_q8_K_vl512 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6292break ; 6293 } 6294#else 6295ggml_vec_dot_tq1_0_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6296#endif 6297} 6298 6299#if defined__riscv_v 6300static NOINLINE void ggml_vec_dot_tq2_0_q8_K_vl128 (const 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 ) { 6301assert (n %QK_K == 0 ); 6302assert (nrc == 1 ); 6303UNUSED (nrc ); 6304UNUSED (bx ); 6305UNUSED (by ); 6306UNUSED (bs ); 6307 6308const block_tq2_0 * GGML_RESTRICT x = vx ; 6309const block_q8_K * GGML_RESTRICT y = vy ; 6310 6311const int nb = n /QK_K ; 6312float sumf = 0.0f ; 6313for (int i = 0 ;i < nb ;++ i ) { 6314int32_t sumi = 0 ; 6315 6316for (size_t j = 0 ;j < sizeof (x [0 ].qs );j += 32 ) { 6317const int8_t * py0 = & y [i ].qs [j * 4 + 0 * 32 ]; 6318const int8_t * py1 = & y [i ].qs [j * 4 + 1 * 32 ]; 6319const int8_t * py2 = & y [i ].qs [j * 4 + 2 * 32 ]; 6320const int8_t * py3 = & y [i ].qs [j * 4 + 3 * 32 ]; 6321const uint8_t * px = & x [i ].qs [j ]; 6322 6323size_t vl = __riscv_vsetvl_e16m4 (32 ); 6324vint16m4_t vacc16 = __riscv_vmv_v_x_i16m4 (0 ,vl ); 6325 6326// Load Raw Packed elements 6327vl = __riscv_vsetvl_e8m2 (32 ); 6328vuint8m2_t vx_u8 = __riscv_vle8_v_u8m2 (px ,vl ); 6329 6330// Process bits 1:0 6331 { 6332// Unpack 6333vuint8m2_t t0 = __riscv_vand_vx_u8m2 (vx_u8 ,0x03 ,vl ); 6334vint8m2_t vq = __riscv_vsub_vx_i8m2 (__riscv_vreinterpret_v_u8m2_i8m2 (t0 ),1 ,vl ); 6335vint8m2_t vy = __riscv_vle8_v_i8m2 (py0 ,vl ); 6336// Accumulate 6337vacc16 = __riscv_vwmacc_vv_i16m4 (vacc16 ,vq ,vy ,vl ); 6338 } 6339 __asm__volatile ("" :::"memory" ); 6340// Process bits 3:2 6341 { 6342vuint8m2_t t1 = __riscv_vsrl_vx_u8m2 (vx_u8 ,2 ,vl ); 6343t1 = __riscv_vand_vx_u8m2 (t1 ,0x03 ,vl ); 6344vint8m2_t vq = __riscv_vsub_vx_i8m2 (__riscv_vreinterpret_v_u8m2_i8m2 (t1 ),1 ,vl ); 6345 6346vint8m2_t vy = __riscv_vle8_v_i8m2 (py1 ,vl ); 6347vacc16 = __riscv_vwmacc_vv_i16m4 (vacc16 ,vq ,vy ,vl ); 6348 } 6349 __asm__volatile ("" :::"memory" ); 6350// Process bits 5:4 6351 { 6352vuint8m2_t t2 = __riscv_vsrl_vx_u8m2 (vx_u8 ,4 ,vl ); 6353t2 = __riscv_vand_vx_u8m2 (t2 ,0x03 ,vl ); 6354vint8m2_t vq = __riscv_vsub_vx_i8m2 (__riscv_vreinterpret_v_u8m2_i8m2 (t2 ),1 ,vl ); 6355 6356vint8m2_t vy = __riscv_vle8_v_i8m2 (py2 ,vl ); 6357vacc16 = __riscv_vwmacc_vv_i16m4 (vacc16 ,vq ,vy ,vl ); 6358 } 6359 __asm__volatile ("" :::"memory" ); 6360// Process bits 7:6 6361 { 6362vuint8m2_t t3 = __riscv_vsrl_vx_u8m2 (vx_u8 ,6 ,vl ); 6363vint8m2_t vq = __riscv_vsub_vx_i8m2 (__riscv_vreinterpret_v_u8m2_i8m2 (t3 ),1 ,vl ); 6364 6365vint8m2_t vy = __riscv_vle8_v_i8m2 (py3 ,vl ); 6366vacc16 = __riscv_vwmacc_vv_i16m4 (vacc16 ,vq ,vy ,vl ); 6367 } 6368 __asm__volatile ("" :::"memory" ); 6369vl = __riscv_vsetvl_e16m4 (32 ); 6370vint32m1_t vzero32 = __riscv_vmv_v_x_i32m1 (0 ,1 ); 6371vint32m1_t vred32 = __riscv_vwredsum_vs_i16m4_i32m1 (vacc16 ,vzero32 ,vl ); 6372sumi += __riscv_vmv_x_s_i32m1_i32 (vred32 ); 6373 } 6374 6375const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 6376sumf += (float )sumi * d ; 6377 } 6378 6379* s = sumf ; 6380} 6381 6382static NOINLINE void ggml_vec_dot_tq2_0_q8_K_vl256 (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 ) { 6383assert (n %QK_K == 0 ); 6384assert (nrc == 1 ); 6385UNUSED (nrc ); 6386UNUSED (bx ); 6387UNUSED (by ); 6388UNUSED (bs ); 6389 6390const block_tq2_0 * GGML_RESTRICT x = vx ; 6391const block_q8_K * GGML_RESTRICT y = vy ; 6392 6393const int nb = n /QK_K ; 6394 6395float sumf = 0.0f ; 6396for (int i = 0 ;i < nb ;++ i ) { 6397int32_t sumi = 0 ; 6398 6399for (size_t j = 0 ;j < sizeof (x [0 ].qs );j += 32 ) { 6400const int8_t * py0 = & y [i ].qs [j * 4 + 0 * 32 ]; 6401const int8_t * py1 = & y [i ].qs [j * 4 + 1 * 32 ]; 6402const int8_t * py2 = & y [i ].qs [j * 4 + 2 * 32 ]; 6403const int8_t * py3 = & y [i ].qs [j * 4 + 3 * 32 ]; 6404const uint8_t * px = & x [i ].qs [j ]; 6405 6406size_t vlmax_16m2 = __riscv_vsetvl_e16m2 (32 ); 6407vint16m2_t vacc16 = __riscv_vmv_v_x_i16m2 (0 ,vlmax_16m2 ); 6408 6409size_t vl = __riscv_vsetvl_e8m1 (32 ); 6410 6411vuint8m1_t vx_u8 = __riscv_vle8_v_u8m1 (px ,vl ); 6412 6413vint8m1_t vy0 = __riscv_vle8_v_i8m1 (py0 ,vl ); 6414vint8m1_t vy1 = __riscv_vle8_v_i8m1 (py1 ,vl ); 6415vint8m1_t vy2 = __riscv_vle8_v_i8m1 (py2 ,vl ); 6416vint8m1_t vy3 = __riscv_vle8_v_i8m1 (py3 ,vl ); 6417 6418// l=0 (bits 1:0) 6419vuint8m1_t t0 = __riscv_vand_vx_u8m1 (vx_u8 ,0x03 ,vl ); 6420vint8m1_t vq0 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (t0 ),1 ,vl ); 6421 6422// l=1 (bits 3:2) 6423vuint8m1_t t1 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (vx_u8 ,2 ,vl ),0x03 ,vl ); 6424vint8m1_t vq1 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (t1 ),1 ,vl ); 6425 6426// l=2 (bits 5:4) 6427vuint8m1_t t2 = __riscv_vand_vx_u8m1 (__riscv_vsrl_vx_u8m1 (vx_u8 ,4 ,vl ),0x03 ,vl ); 6428vint8m1_t vq2 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (t2 ),1 ,vl ); 6429 6430// l=3 (bits 7:6) 6431vuint8m1_t t3 = __riscv_vsrl_vx_u8m1 (vx_u8 ,6 ,vl );// No final AND needed as vsrl shifts in zeros 6432vint8m1_t vq3 = __riscv_vsub_vx_i8m1 (__riscv_vreinterpret_v_u8m1_i8m1 (t3 ),1 ,vl ); 6433 6434// 4. Multiply and accumulate 6435vacc16 = __riscv_vwmacc_vv_i16m2 (vacc16 ,vq0 ,vy0 ,vl ); 6436vacc16 = __riscv_vwmacc_vv_i16m2 (vacc16 ,vq1 ,vy1 ,vl ); 6437vacc16 = __riscv_vwmacc_vv_i16m2 (vacc16 ,vq2 ,vy2 ,vl ); 6438vacc16 = __riscv_vwmacc_vv_i16m2 (vacc16 ,vq3 ,vy3 ,vl ); 6439 6440vlmax_16m2 = __riscv_vsetvl_e16m2 (32 ); 6441vint32m1_t vzero32 = __riscv_vmv_v_x_i32m1 (0 ,1 ); 6442vint32m1_t vred32 = __riscv_vwredsum_vs_i16m2_i32m1 (vacc16 ,vzero32 ,vlmax_16m2 ); 6443 6444sumi += __riscv_vmv_x_s_i32m1_i32 (vred32 ); 6445 } 6446const float d = y [i ].d * GGML_CPU_FP16_TO_FP32 (x [i ].d ); 6447sumf += (float )sumi * d ; 6448 } 6449 6450* s = sumf ; 6451} 6452#endif 6453 6454void ggml_vec_dot_tq2_0_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 ) { 6455#if defined__riscv_v 6456switch (__riscv_vlenb ()* 8 ) { 6457case 128 : 6458ggml_vec_dot_tq2_0_q8_K_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6459break ; 6460default :// 256 and above 6461ggml_vec_dot_tq2_0_q8_K_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6462break ; 6463 } 6464#else 6465ggml_vec_dot_tq2_0_q8_K_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6466#endif 6467} 6468 6469#if defined__riscv_v 6470static NOINLINE void ggml_vec_dot_mxfp4_q8_0_vl128 (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 ) { 6471assert (nrc == 1 ); 6472UNUSED (nrc ); 6473UNUSED (bx ); 6474UNUSED (by ); 6475UNUSED (bs ); 6476assert (n %QK_MXFP4 == 0 ); 6477static_assert (QK_MXFP4 == QK8_0 ,"QK_MXFP4 and QK8_0 must be the same" ); 6478 6479const block_mxfp4 * GGML_RESTRICT x = vx ; 6480const block_q8_0 * GGML_RESTRICT y = vy ; 6481 6482const int nb = n /QK_MXFP4 ; 6483 6484int ib = 0 ; 6485float sumf = 0 ; 6486 6487// Load the lookup table once. 6488const vint8m2_t values = __riscv_vle8_v_i8m2 (kvalues_mxfp4 ,16 ); 6489int acc1 ,acc2 ; 6490 6491// We process 2 blocks at once. 6492for (;ib + 1 < nb ;ib += 2 ) { 6493// Weights and activations. 6494vuint8m1_t mx_packed1 = __riscv_vle8_v_u8m1 (x [ib + 0 ].qs ,16 ); 6495vint8m2_t q8b1 = __riscv_vle8_v_i8m2 (y [ib + 0 ].qs ,32 ); 6496vuint8m1_t mx_packed2 = __riscv_vle8_v_u8m1 (x [ib + 1 ].qs ,16 ); 6497vint8m2_t q8b2 = __riscv_vle8_v_i8m2 (y [ib + 1 ].qs ,32 ); 6498 6499// Unpack the weight blocks. 6500vuint8m2_t mxbits1 = __riscv_vcreate_v_u8m1_u8m2 ( 6501__riscv_vand_vx_u8m1 (mx_packed1 ,0xf ,16 ), 6502__riscv_vsrl_vx_u8m1 (mx_packed1 ,4 ,16 ) 6503 ); 6504vuint8m2_t mxbits2 = __riscv_vcreate_v_u8m1_u8m2 ( 6505__riscv_vand_vx_u8m1 (mx_packed2 ,0xf ,16 ), 6506__riscv_vsrl_vx_u8m1 (mx_packed2 ,4 ,16 ) 6507 ); 6508 6509// Gather values from the lookup table. 6510vint8m2_t mxb1 = __riscv_vrgather_vv_i8m2 (values ,mxbits1 ,32 ); 6511vint8m2_t mxb2 = __riscv_vrgather_vv_i8m2 (values ,mxbits2 ,32 ); 6512 6513// Accumulation. 6514vint16m4_t sum1 = __riscv_vwmul_vv_i16m4 (q8b1 ,mxb1 ,32 ); 6515vint16m4_t sum2 = __riscv_vwmul_vv_i16m4 (q8b2 ,mxb2 ,32 ); 6516__riscv_vse32_v_i32m1 (& acc1 ,__riscv_vwredsum_vs_i16m4_i32m1 (sum1 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),32 ),1 ); 6517__riscv_vse32_v_i32m1 (& acc2 ,__riscv_vwredsum_vs_i16m4_i32m1 (sum2 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),32 ),1 ); 6518sumf += ((GGML_E8M0_TO_FP32_HALF (x [ib + 0 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* acc1 )); 6519sumf += ((GGML_E8M0_TO_FP32_HALF (x [ib + 1 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* acc2 )); 6520 } 6521 6522* s = sumf ; 6523} 6524 6525static NOINLINE void ggml_vec_dot_mxfp4_q8_0_vl256 (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 ) { 6526assert (nrc == 1 ); 6527UNUSED (nrc ); 6528UNUSED (bx ); 6529UNUSED (by ); 6530UNUSED (bs ); 6531assert (n %QK_MXFP4 == 0 ); 6532static_assert (QK_MXFP4 == QK8_0 ,"QK_MXFP4 and QK8_0 must be the same" ); 6533 6534const block_mxfp4 * GGML_RESTRICT x = vx ; 6535const block_q8_0 * GGML_RESTRICT y = vy ; 6536 6537const int nb = n /QK_MXFP4 ; 6538 6539int ib = 0 ; 6540float sumf = 0 ; 6541 6542// Load the lookup table once. 6543const vint8mf2_t values = __riscv_vle8_v_i8mf2 (kvalues_mxfp4 ,16 ); 6544int acc1 ,acc2 ; 6545 6546// We process 2 blocks at once. 6547for (;ib + 1 < nb ;ib += 2 ) { 6548// Weights and activations. 6549vuint8mf2_t mx_packed1 = __riscv_vle8_v_u8mf2 (x [ib + 0 ].qs ,16 ); 6550vint8mf2_t q8b_lo1 = __riscv_vle8_v_i8mf2 (y [ib + 0 ].qs ,16 ); 6551vint8mf2_t q8b_hi1 = __riscv_vle8_v_i8mf2 (y [ib + 0 ].qs + 16 ,16 ); 6552vuint8mf2_t mx_packed2 = __riscv_vle8_v_u8mf2 (x [ib + 1 ].qs ,16 ); 6553vint8mf2_t q8b_lo2 = __riscv_vle8_v_i8mf2 (y [ib + 1 ].qs ,16 ); 6554vint8mf2_t q8b_hi2 = __riscv_vle8_v_i8mf2 (y [ib + 1 ].qs + 16 ,16 ); 6555 6556// Unpack the weight blocks. 6557vuint8mf2_t mxbits_lo1 = __riscv_vand_vx_u8mf2 (mx_packed1 ,0xf ,16 ); 6558vuint8mf2_t mxbits_hi1 = __riscv_vsrl_vx_u8mf2 (mx_packed1 ,4 ,16 ); 6559vuint8mf2_t mxbits_lo2 = __riscv_vand_vx_u8mf2 (mx_packed2 ,0xf ,16 ); 6560vuint8mf2_t mxbits_hi2 = __riscv_vsrl_vx_u8mf2 (mx_packed2 ,4 ,16 ); 6561 6562// Gather values from the lookup table. 6563vint8mf2_t mxb_lo1 = __riscv_vrgather_vv_i8mf2 (values ,mxbits_lo1 ,16 ); 6564vint8mf2_t mxb_hi1 = __riscv_vrgather_vv_i8mf2 (values ,mxbits_hi1 ,16 ); 6565vint8mf2_t mxb_lo2 = __riscv_vrgather_vv_i8mf2 (values ,mxbits_lo2 ,16 ); 6566vint8mf2_t mxb_hi2 = __riscv_vrgather_vv_i8mf2 (values ,mxbits_hi2 ,16 ); 6567 6568// Accumulation. 6569vint16m1_t sum1 = __riscv_vwmul_vv_i16m1 (q8b_lo1 ,mxb_lo1 ,16 ); 6570sum1 = __riscv_vwmacc_vv_i16m1 (sum1 ,q8b_hi1 ,mxb_hi1 ,16 ); 6571vint16m1_t sum2 = __riscv_vwmul_vv_i16m1 (q8b_lo2 ,mxb_lo2 ,16 ); 6572sum2 = __riscv_vwmacc_vv_i16m1 (sum2 ,q8b_hi2 ,mxb_hi2 ,16 ); 6573__riscv_vse32_v_i32m1 (& acc1 ,__riscv_vwredsum_vs_i16m1_i32m1 (sum1 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ),1 ); 6574__riscv_vse32_v_i32m1 (& acc2 ,__riscv_vwredsum_vs_i16m1_i32m1 (sum2 ,__riscv_vmv_v_x_i32m1 (0 ,1 ),16 ),1 ); 6575sumf += ((GGML_E8M0_TO_FP32_HALF (x [ib + 0 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 0 ].d )* acc1 )); 6576sumf += ((GGML_E8M0_TO_FP32_HALF (x [ib + 1 ].e )* GGML_CPU_FP16_TO_FP32 (y [ib + 1 ].d )* acc2 )); 6577 } 6578 6579* s = sumf ; 6580} 6581#endif 6582 6583void ggml_vec_dot_mxfp4_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 ) { 6584#if defined__riscv_v 6585switch (__riscv_vlenb ()* 8 ) { 6586case 128 : 6587ggml_vec_dot_mxfp4_q8_0_vl128 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6588break ; 6589default :// 256 and above 6590ggml_vec_dot_mxfp4_q8_0_vl256 (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6591break ; 6592 } 6593#else 6594ggml_vec_dot_mxfp4_q8_0_generic (n ,s ,bs ,vx ,bx ,vy ,by ,nrc ); 6595#endif 6596}