char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
054d8b0f2
char/aliceai-t5-moe
1#define GGML_COMMON_IMPL_CPP 2#define GGML_COMMON_DECL_CPP 3#include "ggml-common.h" 4#include "ggml-backend-impl.h" 5 6#include "ggml-impl.h" 7#include "ggml-cpu.h" 8#include "ggml-cpu-impl.h" 9#include "simd-mappings.h" 10#include "traits.h" 11 12#include <cmath> 13#include <cstring> 14#include <cassert> 15#include <cstdlib> // for qsort 16#include <cstdio> // for GGML_ASSERT 17 18#define GGML_CPU_CLANG_WORKAROUND 19#include "../../repack.h" 20 21#if defined(__GNUC__ ) 22#pragma GCC diagnostic ignored "-Woverlength-strings" 23#endif 24 25#define UNUSED GGML_UNUSED 26 27void ggml_quantize_mat_q8_0_4x8 (const float * GGML_RESTRICT x ,void * GGML_RESTRICT vy ,int64_t k ) { 28assert (QK8_0 == 32 ); 29assert (k %QK8_0 == 0 ); 30const int nb = k /QK8_0 ; 31 32#if defined(__riscv_v_intrinsic ) 33block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 * )vy ; 34const size_t vl_calc = __riscv_vsetvl_e32m8 (QK8_0 ); 35const size_t vl_save = __riscv_vsetvl_e64m2 (4 ); 36vfloat32m1_t v_scalar_zero = __riscv_vfmv_s_f_f32m1 (0.0f ,__riscv_vsetvl_e32m1 (1 )); 37 38for (int i = 0 ;i < nb ;i ++ ) { 39const float * x_block_base = x + i * QK8_0 ; 40vint8m2_t q_r0 ,q_r1 ,q_r2 ,q_r3 ; 41 { 42vfloat32m8_t v_src = __riscv_vle32_v_f32m8 (x_block_base + 0 * k ,vl_calc ); 43vfloat32m8_t v_abs = __riscv_vfabs_v_f32m8 (v_src ,vl_calc ); 44vfloat32m1_t v_max = __riscv_vfredmax_vs_f32m8_f32m1 (v_abs ,v_scalar_zero ,vl_calc ); 45float amax = __riscv_vfmv_f_s_f32m1_f32 (v_max ); 46 47float d = amax /127.0f ; 48y [i ].d [0 ]= GGML_CPU_FP32_TO_FP16 (d ); 49 50float id = d ?1.0f /d :0.0f ; 51vfloat32m8_t v_scaled = __riscv_vfmul_vf_f32m8 (v_src ,id ,vl_calc ); 52vint16m4_t v_i16 = __riscv_vfncvt_x_f_w_i16m4_rm (v_scaled ,4 ,vl_calc ); 53q_r0 = __riscv_vncvt_x_x_w_i8m2 (v_i16 ,vl_calc ); 54 } 55 asmvolatile ("" :::"memory" ); 56 57 { 58vfloat32m8_t v_src = __riscv_vle32_v_f32m8 (x_block_base + 1 * k ,vl_calc ); 59vfloat32m8_t v_abs = __riscv_vfabs_v_f32m8 (v_src ,vl_calc ); 60vfloat32m1_t v_max = __riscv_vfredmax_vs_f32m8_f32m1 (v_abs ,v_scalar_zero ,vl_calc ); 61float amax = __riscv_vfmv_f_s_f32m1_f32 (v_max ); 62 63float d = amax /127.0f ; 64y [i ].d [1 ]= GGML_CPU_FP32_TO_FP16 (d ); 65float id = d ?1.0f /d :0.0f ; 66 67vfloat32m8_t v_scaled = __riscv_vfmul_vf_f32m8 (v_src ,id ,vl_calc ); 68vint16m4_t v_i16 = __riscv_vfncvt_x_f_w_i16m4_rm (v_scaled ,4 ,vl_calc ); 69q_r1 = __riscv_vncvt_x_x_w_i8m2 (v_i16 ,vl_calc ); 70 } 71 asmvolatile ("" :::"memory" ); 72 { 73vfloat32m8_t v_src = __riscv_vle32_v_f32m8 (x_block_base + 2 * k ,vl_calc ); 74vfloat32m8_t v_abs = __riscv_vfabs_v_f32m8 (v_src ,vl_calc ); 75vfloat32m1_t v_max = __riscv_vfredmax_vs_f32m8_f32m1 (v_abs ,v_scalar_zero ,vl_calc ); 76float amax = __riscv_vfmv_f_s_f32m1_f32 (v_max ); 77 78float d = amax /127.0f ; 79y [i ].d [2 ]= GGML_CPU_FP32_TO_FP16 (d ); 80float id = d ?1.0f /d :0.0f ; 81 82vfloat32m8_t v_scaled = __riscv_vfmul_vf_f32m8 (v_src ,id ,vl_calc ); 83vint16m4_t v_i16 = __riscv_vfncvt_x_f_w_i16m4_rm (v_scaled ,4 ,vl_calc ); 84q_r2 = __riscv_vncvt_x_x_w_i8m2 (v_i16 ,vl_calc ); 85 } 86 asmvolatile ("" :::"memory" ); 87 { 88vfloat32m8_t v_src = __riscv_vle32_v_f32m8 (x_block_base + 3 * k ,vl_calc ); 89vfloat32m8_t v_abs = __riscv_vfabs_v_f32m8 (v_src ,vl_calc ); 90vfloat32m1_t v_max = __riscv_vfredmax_vs_f32m8_f32m1 (v_abs ,v_scalar_zero ,vl_calc ); 91float amax = __riscv_vfmv_f_s_f32m1_f32 (v_max ); 92 93float d = amax /127.0f ; 94y [i ].d [3 ]= GGML_CPU_FP32_TO_FP16 (d ); 95float id = d ?1.0f /d :0.0f ; 96 97vfloat32m8_t v_scaled = __riscv_vfmul_vf_f32m8 (v_src ,id ,vl_calc ); 98vint16m4_t v_i16 = __riscv_vfncvt_x_f_w_i16m4_rm (v_scaled ,4 ,vl_calc ); 99q_r3 = __riscv_vncvt_x_x_w_i8m2 (v_i16 ,vl_calc ); 100 } 101vint64m2_t v_q64_r0 = __riscv_vreinterpret_v_i8m2_i64m2 (q_r0 ); 102vint64m2_t v_q64_r1 = __riscv_vreinterpret_v_i8m2_i64m2 (q_r1 ); 103vint64m2_t v_q64_r2 = __riscv_vreinterpret_v_i8m2_i64m2 (q_r2 ); 104vint64m2_t v_q64_r3 = __riscv_vreinterpret_v_i8m2_i64m2 (q_r3 ); 105vint64m2x4_t v_quant_tuple = __riscv_vcreate_v_i64m2x4 (v_q64_r0 ,v_q64_r1 ,v_q64_r2 ,v_q64_r3 ); 106__riscv_vsseg4e64_v_i64m2x4 ((int64_t * )y [i ].qs ,v_quant_tuple ,vl_save ); 107 } 108#else 109UNUSED (nb ); 110ggml_quantize_mat_q8_0_4x8_generic (x ,vy ,k ); 111#endif 112} 113 114void ggml_gemv_q4_0_8x8_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 115const int qk = QK8_0 ; 116const int nb = n /qk ; 117const int ncols_interleaved = 8 ; 118const int blocklen = 8 ; 119 120assert (n %qk == 0 ); 121assert (nc %ncols_interleaved == 0 ); 122 123UNUSED (s ); 124UNUSED (bs ); 125UNUSED (vx ); 126UNUSED (vy ); 127UNUSED (nr ); 128UNUSED (nc ); 129UNUSED (nb ); 130UNUSED (ncols_interleaved ); 131UNUSED (blocklen ); 132 133#if defined__riscv_v 134if (__riscv_vlenb () >=QK4_0 ) { 135const size_t vl = QK4_0 ; 136 137const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 138for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 139const block_q4_0x8 * b_ptr = (const block_q4_0x8 * )vx + (x * nb ); 140 141vfloat32m1_t sumf = __riscv_vfmv_v_f_f32m1 (0.0 ,vl /4 ); 142for (int l = 0 ;l < nb ;l ++ ) { 143const int64_t a0 = * (const int64_t * )& a_ptr [l ].qs [0 ]; 144const int64_t a1 = * (const int64_t * )& a_ptr [l ].qs [8 ]; 145const int64_t a2 = * (const int64_t * )& a_ptr [l ].qs [16 ]; 146const int64_t a3 = * (const int64_t * )& a_ptr [l ].qs [24 ]; 147 __asm__ __volatile__("" :::"memory" );// prevent gcc from emitting fused vlse64, violating alignment constraints 148const vint8m2_t lhs_0_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (a0 ,vl /4 )); 149const vint8m2_t lhs_1_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (a1 ,vl /4 )); 150const vint8m2_t lhs_2_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (a2 ,vl /4 )); 151const vint8m2_t lhs_3_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (a3 ,vl /4 )); 152 153const vint8m4_t rhs_raw_vec = __riscv_vle8_v_i8m4 ((const int8_t * )b_ptr [l ].qs ,vl * 4 ); 154const vint8m4_t rhs_vec_lo = __riscv_vsra_vx_i8m4 (__riscv_vsll_vx_i8m4 (rhs_raw_vec ,4 ,vl * 4 ),4 ,vl * 4 ); 155const vint8m4_t rhs_vec_hi = __riscv_vsra_vx_i8m4 (rhs_raw_vec ,4 ,vl * 4 ); 156const vint8m2_t rhs_vec_lo_0 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_lo ,0 ); 157const vint8m2_t rhs_vec_lo_1 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_lo ,1 ); 158const vint8m2_t rhs_vec_hi_0 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_hi ,0 ); 159const vint8m2_t rhs_vec_hi_1 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_hi ,1 ); 160 161const vint16m4_t sumi_lo_0 = __riscv_vwmul_vv_i16m4 (rhs_vec_lo_0 ,lhs_0_8 ,vl * 2 ); 162const vint16m4_t sumi_lo_1 = __riscv_vwmacc_vv_i16m4 (sumi_lo_0 ,rhs_vec_lo_1 ,lhs_1_8 ,vl * 2 ); 163const vint16m4_t sumi_hi_0 = __riscv_vwmacc_vv_i16m4 (sumi_lo_1 ,rhs_vec_hi_0 ,lhs_2_8 ,vl * 2 ); 164const vint16m4_t sumi_hi_m = __riscv_vwmacc_vv_i16m4 (sumi_hi_0 ,rhs_vec_hi_1 ,lhs_3_8 ,vl * 2 ); 165 166const vuint32m4_t sumi_i32 = __riscv_vreinterpret_v_i32m4_u32m4 (__riscv_vreinterpret_v_i16m4_i32m4 (sumi_hi_m )); 167const vuint16m2_t sumi_h2_0 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,0 ,vl ); 168const vuint16m2_t sumi_h2_1 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,16 ,vl ); 169const vuint16m2_t sumi_h2 = __riscv_vadd_vv_u16m2 (sumi_h2_0 ,sumi_h2_1 ,vl ); 170const vuint32m2_t sumi_h2_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (sumi_h2 ); 171const vuint16m1_t sumi_h4_0 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,0 ,vl /2 ); 172const vuint16m1_t sumi_h4_1 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,16 ,vl /2 ); 173const vuint16m1_t sumi_h4 = __riscv_vadd_vv_u16m1 (sumi_h4_0 ,sumi_h4_1 ,vl /2 ); 174const vuint32m1_t sumi_h4_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (sumi_h4 ); 175const vint16mf2_t sumi_h8_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,0 ,vl /4 )); 176const vint16mf2_t sumi_h8_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,16 ,vl /4 )); 177const vint32m1_t sumi_h8 = __riscv_vwadd_vv_i32m1 (sumi_h8_0 ,sumi_h8_1 ,vl /4 ); 178const vfloat32m1_t facc = __riscv_vfcvt_f_x_v_f32m1 (sumi_h8 ,vl /4 ); 179 180// vector version needs Zvfhmin extension 181const float a_scale = GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d ); 182const float b_scales [8 ]= { 183GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [0 ]), 184GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [1 ]), 185GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [2 ]), 186GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [3 ]), 187GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [4 ]), 188GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [5 ]), 189GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [6 ]), 190GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [7 ]) 191 }; 192const vfloat32m1_t b_scales_vec = __riscv_vle32_v_f32m1 (b_scales ,vl /4 ); 193const vfloat32m1_t tmp1 = __riscv_vfmul_vf_f32m1 (facc ,a_scale ,vl /4 ); 194sumf = __riscv_vfmacc_vv_f32m1 (sumf ,tmp1 ,b_scales_vec ,vl /4 ); 195 } 196__riscv_vse32_v_f32m1 (s + x * ncols_interleaved ,sumf ,vl /4 ); 197 } 198return ; 199 } 200 201#endif 202ggml_gemv_q4_0_8x8_q8_0_generic (n ,s ,bs ,vx ,vy ,nr ,nc ); 203} 204 205#if defined__riscv_zvfh 206void ggml_gemv_q4_0_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 207const int qk = QK8_0 ; 208const int nb = n /qk ; 209const int ncols_interleaved = 16 ; 210const int blocklen = 1 ; 211 212assert (n %qk == 0 ); 213assert (nc %ncols_interleaved == 0 ); 214 215UNUSED (s ); 216UNUSED (bs ); 217UNUSED (vx ); 218UNUSED (vy ); 219UNUSED (nr ); 220UNUSED (nc ); 221UNUSED (nb ); 222UNUSED (ncols_interleaved ); 223UNUSED (blocklen ); 224 225const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 226for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 227const block_q4_0x16 * b_ptr = (const block_q4_0x16 * )vx + (x * nb ); 228 229// 1x16 Accumulator 230vfloat32m2_t sumf = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 231 232for (int l = 0 ;l < nb ;l ++ ) { 233// 1x16 Integer Accumulator 234vint16m1_t sumi_0_lo_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 235vint16m1_t sumi_0_hi_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 236 237// Accumulation loop. 238for (int i = 0 ;i < QK4_0 /2 ;i ++ ) { 239// Load `b_ptr`. 240const vint8mf2_t b_0_packed = __riscv_vle8_v_i8mf2 ((const int8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 241const vint8mf2_t b_0_lo = __riscv_vsra_vx_i8mf2 (__riscv_vsll_vx_i8mf2 (b_0_packed ,4 ,16 ),4 ,16 ); 242const vint8mf2_t b_0_hi = __riscv_vsra_vx_i8mf2 (b_0_packed ,4 ,16 ); 243 244sumi_0_lo_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_lo_16 ,a_ptr [l ].qs [i ],b_0_lo ,16 ); 245sumi_0_hi_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_hi_16 ,a_ptr [l ].qs [16 + i ],b_0_hi ,16 ); 246 } 247 248const vint32m2_t sumi = __riscv_vwadd_vv_i32m2 (sumi_0_lo_16 ,sumi_0_hi_16 ,16 ); 249 250const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 251const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d ,16 ); 252 253sumf = __riscv_vfmacc_vv_f32m2 (sumf ,__riscv_vfcvt_f_x_v_f32m2 (sumi ,16 ),d_0 ,16 ); 254 } 255 256__riscv_vse32_v_f32m2 (s + x * 16 ,sumf ,16 ); 257 } 258} 259 260void ggml_gemv_q4_K_16x1_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 261const int qk = QK_K ; 262const int nb = n /qk ; 263const int ncols_interleaved = 16 ; 264const int blocklen = 1 ; 265 266assert (n %qk == 0 ); 267assert (nc %ncols_interleaved == 0 ); 268 269UNUSED (s ); 270UNUSED (bs ); 271UNUSED (vx ); 272UNUSED (vy ); 273UNUSED (nr ); 274UNUSED (nc ); 275UNUSED (nb ); 276UNUSED (ncols_interleaved ); 277UNUSED (blocklen ); 278 279const block_q8_K * a_ptr = (const block_q8_K * )vy ; 280 281for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 282const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 * )vx + (x * nb ); 283 284// 1x16 Accumulator 285vfloat32m2_t sumf = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 286 287for (int l = 0 ;l < nb ;l ++ ) { 288vint32m2_t sumi = __riscv_vmv_v_x_i32m2 (0 ,16 ); 289 290// Load `dmin`. 291const vfloat32m2_t dmins_d = __riscv_vfmul_vf_f32m2 ( 292__riscv_vfwcvt_f_f_v_f32m2 (__riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].dmin ,16 ),16 ),a_ptr [l ].d ,16 ); 293 294// We process 4 sub-blocks at once. 295for (int j = 0 ;j < QK_K /128 ;j ++ ) { 296// Extract the scales and the mins. 297// 298// Low bits. 299vuint8m2_t scales_mins_lo = __riscv_vle8_v_u8m2 (& b_ptr [l ].scales [j * 64 ],64 ); 300vuint8m2_t scales_lo = __riscv_vand_vx_u8m2 (scales_mins_lo ,0x0F ,64 ); 301vuint8m2_t mins_lo = __riscv_vsrl_vx_u8m2 (scales_mins_lo ,4 ,64 ); 302 303// High bits. 304vuint8m2_t scales_mins_hi = __riscv_vle8_v_u8m2 (& b_ptr [l ].scales [128 ],64 ); 305vuint8m2_t scales_hi ; 306vuint8m2_t mins_hi ; 307if (!j ) { 308scales_hi = __riscv_vsll_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0x03 ,64 ),4 ,64 ); 309mins_hi = __riscv_vsll_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0x0C ,64 ),2 ,64 ); 310 }else { 311scales_hi = __riscv_vand_vx_u8m2 (scales_mins_hi ,0x30 ,64 ); 312mins_hi = __riscv_vsrl_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0xC0 ,64 ),2 ,64 ); 313 } 314vuint16m4_t scales = __riscv_vzext_vf2_u16m4 (__riscv_vor_vv_u8m2 (scales_hi ,scales_lo ,64 ),64 ); 315vint16m4_t mins = __riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vzext_vf2_u16m4 (__riscv_vor_vv_u8m2 (mins_hi ,mins_lo ,64 ),64 )); 316 317// Reduce the mins and multiply with `dmin`. 318// 319// Correct in `sumf`. 320vint32m2_t bsums = __riscv_vmv_v_x_i32m2 (0 ,16 ); 321bsums = __riscv_vwmacc_vx_i32m2 (bsums ,a_ptr [l ].bsums [j * 8 ]+ a_ptr [l ].bsums [j * 8 + 1 ],__riscv_vget_v_i16m4_i16m1 (mins ,0 ),16 ); 322bsums = __riscv_vwmacc_vx_i32m2 (bsums ,a_ptr [l ].bsums [j * 8 + 2 ]+ a_ptr [l ].bsums [j * 8 + 3 ],__riscv_vget_v_i16m4_i16m1 (mins ,1 ),16 ); 323bsums = __riscv_vwmacc_vx_i32m2 (bsums ,a_ptr [l ].bsums [j * 8 + 4 ]+ a_ptr [l ].bsums [j * 8 + 5 ],__riscv_vget_v_i16m4_i16m1 (mins ,2 ),16 ); 324bsums = __riscv_vwmacc_vx_i32m2 (bsums ,a_ptr [l ].bsums [j * 8 + 6 ]+ a_ptr [l ].bsums [j * 8 + 7 ],__riscv_vget_v_i16m4_i16m1 (mins ,3 ),16 ); 325 326sumf = __riscv_vfsub_vv_f32m2 (sumf ,__riscv_vfmul_vv_f32m2 (dmins_d ,__riscv_vfcvt_f_x_v_f32m2 (bsums ,16 ),16 ),16 ); 327 328// Accumulation for 2 sub-blocks. 329// 330// This might overflow, so we accumulate in two steps. 331// 332// Recheck. 333for (int k = 0 ;k < 2 ;k ++ ) { 334vint16m1_t sumi_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 335vint16m1_t sumi_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 336 337for (int i = k * 16 ;i < k * 16 + QK4_0 /2 ;i ++ ) { 338// Load `b_ptr`. 339const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 (& b_ptr [l ].qs [j * 1024 + i * 16 ],16 ); 340const vint8mf2_t b_s_0 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (b_0_packed ,0xF ,16 )); 341const vint8mf2_t b_s_1 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 )); 342 343sumi_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_s_0_16 ,a_ptr [l ].qs [j * 128 + i ],b_s_0 ,16 ); 344sumi_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_s_1_16 ,a_ptr [l ].qs [j * 128 + 32 + i ],b_s_1 ,16 ); 345 } 346 347sumi = __riscv_vwmacc_vv_i32m2 (sumi , 348__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,0 )), 349sumi_s_0_16 ,16 ); 350sumi = __riscv_vwmacc_vv_i32m2 (sumi , 351__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,1 )), 352sumi_s_1_16 ,16 ); 353 } 354// Accumulation for 2 sub-blocks. 355// 356// This might overflow, so we accumulate in two steps. 357// 358// Recheck. 359for (int k = 0 ;k < 2 ;k ++ ) { 360vint16m1_t sumi_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 361vint16m1_t sumi_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 362 363for (int i = k * 16 ;i < k * 16 + QK4_0 /2 ;i ++ ) { 364// Load `b_ptr`. 365const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 (& b_ptr [l ].qs [j * 1024 + 512 + i * 16 ],16 ); 366const vint8mf2_t b_s_0 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (b_0_packed ,0xF ,16 )); 367const vint8mf2_t b_s_1 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 )); 368 369sumi_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_s_0_16 ,a_ptr [l ].qs [j * 128 + 64 + i ],b_s_0 ,16 ); 370sumi_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_s_1_16 ,a_ptr [l ].qs [j * 128 + 96 + i ],b_s_1 ,16 ); 371 } 372 373sumi = __riscv_vwmacc_vv_i32m2 (sumi , 374__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,2 )), 375sumi_s_0_16 ,16 ); 376sumi = __riscv_vwmacc_vv_i32m2 (sumi , 377__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,3 )), 378sumi_s_1_16 ,16 ); 379 } 380 } 381 382const vfloat32m2_t b_d = __riscv_vfwcvt_f_f_v_f32m2 (__riscv_vle16_v_f16m1 ((const _Float16 * )& b_ptr [l ].d [0 ],16 ),16 ); 383const vfloat32m2_t d_0 = __riscv_vfmul_vf_f32m2 (b_d ,a_ptr [l ].d ,16 ); 384 385sumf = __riscv_vfmacc_vv_f32m2 (sumf ,__riscv_vfcvt_f_x_v_f32m2 (sumi ,16 ),d_0 ,16 ); 386 } 387 388__riscv_vse32_v_f32m2 (s + x * 16 ,sumf ,16 ); 389 } 390} 391 392void ggml_gemv_iq4_nl_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 393const int qk = QK8_0 ; 394const int nb = n /qk ; 395const int ncols_interleaved = 16 ; 396const int blocklen = 1 ; 397 398assert (n %qk == 0 ); 399assert (nc %ncols_interleaved == 0 ); 400 401UNUSED (s ); 402UNUSED (bs ); 403UNUSED (vx ); 404UNUSED (vy ); 405UNUSED (nr ); 406UNUSED (nc ); 407UNUSED (nb ); 408UNUSED (ncols_interleaved ); 409UNUSED (blocklen ); 410 411const vint8mf2_t values = __riscv_vle8_v_i8mf2 (kvalues_iq4nl ,16 ); 412const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 413for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 414const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 * )vx + (x * nb ); 415 416// 1x16 Accumulator1 417vfloat32m2_t sumf = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 418 419for (int l = 0 ;l < nb ;l ++ ) { 420// 1x16 integer accumulator 421vint32m2_t sumi = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 422 423// Accumulation loop. 424for (int i = 0 ;i < QK4_NL /2 ;i ++ ) { 425// Load `b_ptr`. 426const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 ((const uint8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 427const vint8mf2_t b_0_lo = __riscv_vrgather_vv_i8mf2 (values ,__riscv_vand_vx_u8mf2 (b_0_packed ,0xf ,16 ),16 ); 428const vint8mf2_t b_0_hi = __riscv_vrgather_vv_i8mf2 (values ,__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 ),16 ); 429// const vint16m1_t b_0_lo_16 = __riscv_vwcvt_x_x_v_i16m1(b_0_lo, 16); 430// const vint16m1_t b_0_hi_16 = __riscv_vwcvt_x_x_v_i16m1(b_0_hi, 16); 431 432const vint16m1_t sumi_lo = __riscv_vwmul_vx_i16m1 (b_0_lo ,a_ptr [l ].qs [i ],16 ); 433const vint16m1_t sumi_hi = __riscv_vwmul_vx_i16m1 (b_0_hi ,a_ptr [l ].qs [16 + i ],16 ); 434sumi = __riscv_vadd_vv_i32m2 (sumi ,__riscv_vwadd_vv_i32m2 (sumi_lo ,sumi_hi ,16 ),16 ); 435 } 436 437const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 438const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d ,16 ); 439 440sumf = __riscv_vfmacc_vv_f32m2 (sumf ,__riscv_vfcvt_f_x_v_f32m2 (sumi ,16 ),d_0 ,16 ); 441 } 442 443__riscv_vse32_v_f32m2 (s + x * 16 ,sumf ,16 ); 444 } 445} 446 447void ggml_gemv_q8_0_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 448const int qk = QK8_0 ; 449const int nb = n /qk ; 450const int ncols_interleaved = 16 ; 451const int blocklen = 1 ; 452 453assert (n %qk == 0 ); 454assert (nc %ncols_interleaved == 0 ); 455 456UNUSED (s ); 457UNUSED (bs ); 458UNUSED (vx ); 459UNUSED (vy ); 460UNUSED (nr ); 461UNUSED (nc ); 462UNUSED (nb ); 463UNUSED (ncols_interleaved ); 464UNUSED (blocklen ); 465UNUSED (bs ); 466 467const block_q8_0 * a_ptr = (const block_q8_0 * )vy ; 468for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 469const block_q8_0x16 * b_ptr = (const block_q8_0x16 * )vx + (x * nb ); 470 471// 1x16 Accumulator 472vfloat32m2_t sumf = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 473 474for (int l = 0 ;l < nb ;l ++ ) { 475// 1x16 Integer Accumulator 476vint32m2_t sumi = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 477 478// Accumulation loop. 479for (int i = 0 ;i < QK8_0 ;i ++ ) { 480// Load `b_ptr`. 481const vint8mf2_t b_0 = __riscv_vle8_v_i8mf2 ((const int8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 482// const vint16m1_t b_0_16 = __riscv_vwcvt_x_x_v_i16m1(b_0, 16); 483 484sumi = __riscv_vwadd_wv_i32m2 (sumi ,__riscv_vwmul_vx_i16m1 (b_0 ,a_ptr [l ].qs [i ],16 ),16 ); 485 } 486 487const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 488const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d ,16 ); 489 490sumf = __riscv_vfmacc_vv_f32m2 (sumf ,__riscv_vfcvt_f_x_v_f32m2 (sumi ,16 ),d_0 ,16 ); 491 } 492 493__riscv_vse32_v_f32m2 (s + x * 16 ,sumf ,16 ); 494 } 495} 496 497void ggml_gemv_q2_K_16x1_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 498assert (n %QK_K == 0 ); 499assert (nr == 1 ); 500assert (nc %16 == 0 ); 501 502UNUSED (bs ); 503 504const int N_COLS_TILE = 16 ; 505const int num_k_blocks = n /QK_K ; 506 507const size_t vl = __riscv_vsetvl_e32m2 (N_COLS_TILE ); 508for (int col_tile = 0 ;col_tile < nc ;col_tile += N_COLS_TILE ) { 509 510const block_q8_K * lhs_base_ptr = (const block_q8_K * )vy ; 511const block_q2_Kx16 * rhs_base_ptr = (const block_q2_Kx16 * )vx + (col_tile /N_COLS_TILE )* num_k_blocks ; 512 513vfloat32m2_t v_sumf = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 514 515for (int k_block = 0 ;k_block < num_k_blocks ;++ k_block ) { 516const block_q8_K * lhs_current = & lhs_base_ptr [k_block ]; 517const block_q2_Kx16 * rhs_current = & rhs_base_ptr [k_block ]; 518 519// 1. Prepare Global Min Scales 520vfloat16m1_t v_g_min_f16 = __riscv_vle16_v_f16m1 ((const _Float16 * )rhs_current -> dmin ,vl ); 521vfloat32m2_t v_g_min_base = __riscv_vfwcvt_f_f_v_f32m2 (v_g_min_f16 ,vl ); 522 523vfloat32m2_t v_g_min_final = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d ,vl ); 524 525vint32m2_t v_isum = __riscv_vmv_v_x_i32m2 (0 ,vl ); 526 527const uint8_t * rhs_qs_ptr = rhs_current -> qs ; 528const uint8_t * rhs_sc_ptr = rhs_current -> scales ; 529const int8_t * lhs_qs_ptr = lhs_current -> qs ; 530 531// --- Phase Loop (4 phases x 64 elements) --- 532for (int phase = 0 ;phase < 4 ;++ phase ) { 533 534// A. Load Scales/Mins 535vuint16m1_t v_d_sb_0 ,v_d_sb_1 ,v_d_sb_2 ,v_d_sb_3 ; 536vuint16m1_t v_m_sb_0 ,v_m_sb_1 ,v_m_sb_2 ,v_m_sb_3 ; 537 538 { 539vuint8mf2_t v_raw ; 540// Sub-block 0 541v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 0 ,vl ); 542v_d_sb_0 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 543v_m_sb_0 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 544 545// Sub-block 1 546v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 16 ,vl ); 547v_d_sb_1 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 548v_m_sb_1 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 549 550// Sub-block 2 551v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 32 ,vl ); 552v_d_sb_2 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 553v_m_sb_2 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 554 555// Sub-block 3 556v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 48 ,vl ); 557v_d_sb_3 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 558v_m_sb_3 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 559 560rhs_sc_ptr += 64 ; 561 } 562 563int base_k_phase = (phase < 2 ) ? (phase * 16 ) : (128 + (phase - 2 )* 16 ); 564int k_offsets [4 ]= {0 ,32 ,64 ,96 }; 565 566// B. Inner Dot Product Loop 567for (int l = 0 ;l < 16 ;++ l ) { 568vuint8mf2_t v_rhs_data = __riscv_vle8_v_u8mf2 (rhs_qs_ptr ,vl ); 569rhs_qs_ptr += 16 ; 570 571// Sub-block 0 572 { 573vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (v_rhs_data ,3 ,vl ); 574vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 575__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 576__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_0 ),vl ); 577 578int8_t q8 = lhs_qs_ptr [base_k_phase + k_offsets [0 ]+ l ]; 579v_isum = __riscv_vwmacc_vx_i32m2 (v_isum , (int16_t )q8 ,v_w ,vl ); 580 } 581// Sub-block 1 582 { 583vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,2 ,vl ),3 ,vl ); 584vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 585__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 586__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_1 ),vl ); 587 588int8_t q8 = lhs_qs_ptr [base_k_phase + k_offsets [1 ]+ l ]; 589v_isum = __riscv_vwmacc_vx_i32m2 (v_isum , (int16_t )q8 ,v_w ,vl ); 590 } 591// Sub-block 2 592 { 593vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,4 ,vl ),3 ,vl ); 594vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 595__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 596__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_2 ),vl ); 597 598int8_t q8 = lhs_qs_ptr [base_k_phase + k_offsets [2 ]+ l ]; 599v_isum = __riscv_vwmacc_vx_i32m2 (v_isum , (int16_t )q8 ,v_w ,vl ); 600 } 601// Sub-block 3 602 { 603vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,6 ,vl ),3 ,vl ); 604vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 605__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 606__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_3 ),vl ); 607 608int8_t q8 = lhs_qs_ptr [base_k_phase + k_offsets [3 ]+ l ]; 609v_isum = __riscv_vwmacc_vx_i32m2 (v_isum , (int16_t )q8 ,v_w ,vl ); 610 } 611 } 612 613// correction 614int sb_base_abs = base_k_phase /16 ; 615 616// Sub-block 0 617 { 618int sb_idx = sb_base_abs + (k_offsets [0 ] /16 ); 619int16_t bsum = lhs_current -> bsums [sb_idx ]; 620vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_0 ); 621vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,bsum ,vl ); 622vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min_final ,vl ); 623v_sumf = __riscv_vfsub_vv_f32m2 (v_sumf ,vf_c ,vl ); 624 } 625// Sub-block 1 626 { 627int sb_idx = sb_base_abs + (k_offsets [1 ] /16 ); 628int16_t bsum = lhs_current -> bsums [sb_idx ]; 629vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_1 ); 630vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,bsum ,vl ); 631vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min_final ,vl ); 632v_sumf = __riscv_vfsub_vv_f32m2 (v_sumf ,vf_c ,vl ); 633 } 634// Sub-block 2 635 { 636int sb_idx = sb_base_abs + (k_offsets [2 ] /16 ); 637int16_t bsum = lhs_current -> bsums [sb_idx ]; 638vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_2 ); 639vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,bsum ,vl ); 640vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min_final ,vl ); 641v_sumf = __riscv_vfsub_vv_f32m2 (v_sumf ,vf_c ,vl ); 642 } 643// Sub-block 3 644 { 645int sb_idx = sb_base_abs + (k_offsets [3 ] /16 ); 646int16_t bsum = lhs_current -> bsums [sb_idx ]; 647vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_3 ); 648vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,bsum ,vl ); 649vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min_final ,vl ); 650v_sumf = __riscv_vfsub_vv_f32m2 (v_sumf ,vf_c ,vl ); 651 } 652 653 }// End Phase Loop 654 655// Apply global Scales 656vfloat16m1_t v_g_all_f16 = __riscv_vle16_v_f16m1 ((const _Float16 * )rhs_current -> d ,vl ); 657vfloat32m2_t v_g_all_base = __riscv_vfwcvt_f_f_v_f32m2 (v_g_all_f16 ,vl ); 658 659vfloat32m2_t v_g_all_final = __riscv_vfmul_vf_f32m2 (v_g_all_base ,lhs_current -> d ,vl ); 660vfloat32m2_t v_sum = __riscv_vfcvt_f_x_v_f32m2 (v_isum ,vl ); 661v_sum = __riscv_vfmul_vv_f32m2 (v_sum ,v_g_all_final ,vl ); 662v_sumf = __riscv_vfadd_vv_f32m2 (v_sumf ,v_sum ,vl ); 663 664 }// End K-Block 665__riscv_vse32_v_f32m2 (s + col_tile ,v_sumf ,vl ); 666 } 667} 668#endif 669 670void ggml_gemm_q4_0_8x8_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 671const int qk = QK8_0 ; 672const int nb = n /qk ; 673const int ncols_interleaved = 8 ; 674const int blocklen = 8 ; 675 676assert (n %qk == 0 ); 677assert (nr %4 == 0 ); 678assert (nc %ncols_interleaved == 0 ); 679 680UNUSED (s ); 681UNUSED (bs ); 682UNUSED (vx ); 683UNUSED (vy ); 684UNUSED (nr ); 685UNUSED (nc ); 686UNUSED (nb ); 687UNUSED (ncols_interleaved ); 688UNUSED (blocklen ); 689 690#if defined__riscv_v 691if (__riscv_vlenb () >=QK4_0 ) { 692const size_t vl = QK4_0 ; 693 694for (int y = 0 ;y < nr /4 ;y ++ ) { 695const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 696for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 697const block_q4_0x8 * b_ptr = (const block_q4_0x8 * )vx + (x * nb ); 698vfloat32m1_t sumf0 = __riscv_vfmv_v_f_f32m1 (0.0 ,vl /4 ); 699vfloat32m1_t sumf1 = __riscv_vfmv_v_f_f32m1 (0.0 ,vl /4 ); 700vfloat32m1_t sumf2 = __riscv_vfmv_v_f_f32m1 (0.0 ,vl /4 ); 701vfloat32m1_t sumf3 = __riscv_vfmv_v_f_f32m1 (0.0 ,vl /4 ); 702for (int l = 0 ;l < nb ;l ++ ) { 703const vint8m4_t rhs_raw_vec = __riscv_vle8_v_i8m4 ((const int8_t * )b_ptr [l ].qs ,vl * 4 ); 704const vint8m4_t rhs_vec_lo = __riscv_vsra_vx_i8m4 (__riscv_vsll_vx_i8m4 (rhs_raw_vec ,4 ,vl * 4 ),4 ,vl * 4 ); 705const vint8m4_t rhs_vec_hi = __riscv_vsra_vx_i8m4 (rhs_raw_vec ,4 ,vl * 4 ); 706const vint8m2_t rhs_vec_lo_0 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_lo ,0 ); 707const vint8m2_t rhs_vec_lo_1 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_lo ,1 ); 708const vint8m2_t rhs_vec_hi_0 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_hi ,0 ); 709const vint8m2_t rhs_vec_hi_1 = __riscv_vget_v_i8m4_i8m2 (rhs_vec_hi ,1 ); 710 711// vector version needs Zvfhmin extension 712const float a_scales [4 ]= { 713GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [0 ]), 714GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [1 ]), 715GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [2 ]), 716GGML_CPU_FP16_TO_FP32 (a_ptr [l ].d [3 ]) 717 }; 718const float b_scales [8 ]= { 719GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [0 ]), 720GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [1 ]), 721GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [2 ]), 722GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [3 ]), 723GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [4 ]), 724GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [5 ]), 725GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [6 ]), 726GGML_CPU_FP16_TO_FP32 (b_ptr [l ].d [7 ]) 727 }; 728const vfloat32m1_t b_scales_vec = __riscv_vle32_v_f32m1 (b_scales ,vl /4 ); 729 730const int64_t A0 = * (const int64_t * )& a_ptr [l ].qs [0 ]; 731const int64_t A4 = * (const int64_t * )& a_ptr [l ].qs [32 ]; 732const int64_t A8 = * (const int64_t * )& a_ptr [l ].qs [64 ]; 733const int64_t Ac = * (const int64_t * )& a_ptr [l ].qs [96 ]; 734 __asm__ __volatile__("" :::"memory" );// prevent gcc from emitting fused vlse64, violating alignment 735vint16m4_t sumi_l0 ; 736 { 737const vint8m2_t lhs_0_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A0 ,vl /4 )); 738const vint8m2_t lhs_1_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A4 ,vl /4 )); 739const vint8m2_t lhs_2_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A8 ,vl /4 )); 740const vint8m2_t lhs_3_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Ac ,vl /4 )); 741const vint16m4_t sumi_lo_0 = __riscv_vwmul_vv_i16m4 (rhs_vec_lo_0 ,lhs_0_8 ,vl * 2 ); 742const vint16m4_t sumi_lo_1 = __riscv_vwmacc_vv_i16m4 (sumi_lo_0 ,rhs_vec_lo_1 ,lhs_1_8 ,vl * 2 ); 743const vint16m4_t sumi_hi_0 = __riscv_vwmacc_vv_i16m4 (sumi_lo_1 ,rhs_vec_hi_0 ,lhs_2_8 ,vl * 2 ); 744const vint16m4_t sumi_hi_m = __riscv_vwmacc_vv_i16m4 (sumi_hi_0 ,rhs_vec_hi_1 ,lhs_3_8 ,vl * 2 ); 745 746sumi_l0 = sumi_hi_m ; 747 } 748 749 { 750const vuint32m4_t sumi_i32 = __riscv_vreinterpret_v_i32m4_u32m4 (__riscv_vreinterpret_v_i16m4_i32m4 (sumi_l0 )); 751const vuint16m2_t sumi_h2_0 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,0 ,vl ); 752const vuint16m2_t sumi_h2_1 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,16 ,vl ); 753const vuint16m2_t sumi_h2 = __riscv_vadd_vv_u16m2 (sumi_h2_0 ,sumi_h2_1 ,vl ); 754const vuint32m2_t sumi_h2_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (sumi_h2 ); 755const vuint16m1_t sumi_h4_0 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,0 ,vl /2 ); 756const vuint16m1_t sumi_h4_1 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,16 ,vl /2 ); 757const vuint16m1_t sumi_h4 = __riscv_vadd_vv_u16m1 (sumi_h4_0 ,sumi_h4_1 ,vl /2 ); 758const vuint32m1_t sumi_h4_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (sumi_h4 ); 759const vint16mf2_t sumi_h8_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,0 ,vl /4 )); 760const vint16mf2_t sumi_h8_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,16 ,vl /4 )); 761const vint32m1_t sumi_h8 = __riscv_vwadd_vv_i32m1 (sumi_h8_0 ,sumi_h8_1 ,vl /4 ); 762const vfloat32m1_t facc = __riscv_vfcvt_f_x_v_f32m1 (sumi_h8 ,vl /4 ); 763 764const vfloat32m1_t tmp1 = __riscv_vfmul_vf_f32m1 (facc ,a_scales [0 ],vl /4 ); 765sumf0 = __riscv_vfmacc_vv_f32m1 (sumf0 ,tmp1 ,b_scales_vec ,vl /4 ); 766 } 767 768const int64_t A1 = * (const int64_t * )& a_ptr [l ].qs [8 ]; 769const int64_t A5 = * (const int64_t * )& a_ptr [l ].qs [40 ]; 770const int64_t A9 = * (const int64_t * )& a_ptr [l ].qs [72 ]; 771const int64_t Ad = * (const int64_t * )& a_ptr [l ].qs [104 ]; 772 __asm__ __volatile__("" :::"memory" );// prevent gcc from emitting fused vlse64, violating alignment 773vint16m4_t sumi_l1 ; 774 { 775const vint8m2_t lhs_0_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A1 ,vl /4 )); 776const vint8m2_t lhs_1_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A5 ,vl /4 )); 777const vint8m2_t lhs_2_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A9 ,vl /4 )); 778const vint8m2_t lhs_3_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Ad ,vl /4 )); 779const vint16m4_t sumi_lo_0 = __riscv_vwmul_vv_i16m4 (rhs_vec_lo_0 ,lhs_0_8 ,vl * 2 ); 780const vint16m4_t sumi_lo_1 = __riscv_vwmacc_vv_i16m4 (sumi_lo_0 ,rhs_vec_lo_1 ,lhs_1_8 ,vl * 2 ); 781const vint16m4_t sumi_hi_0 = __riscv_vwmacc_vv_i16m4 (sumi_lo_1 ,rhs_vec_hi_0 ,lhs_2_8 ,vl * 2 ); 782const vint16m4_t sumi_hi_m = __riscv_vwmacc_vv_i16m4 (sumi_hi_0 ,rhs_vec_hi_1 ,lhs_3_8 ,vl * 2 ); 783 784sumi_l1 = sumi_hi_m ; 785 } 786 787 { 788const vuint32m4_t sumi_i32 = __riscv_vreinterpret_v_i32m4_u32m4 (__riscv_vreinterpret_v_i16m4_i32m4 (sumi_l1 )); 789const vuint16m2_t sumi_h2_0 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,0 ,vl ); 790const vuint16m2_t sumi_h2_1 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,16 ,vl ); 791const vuint16m2_t sumi_h2 = __riscv_vadd_vv_u16m2 (sumi_h2_0 ,sumi_h2_1 ,vl ); 792const vuint32m2_t sumi_h2_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (sumi_h2 ); 793const vuint16m1_t sumi_h4_0 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,0 ,vl /2 ); 794const vuint16m1_t sumi_h4_1 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,16 ,vl /2 ); 795const vuint16m1_t sumi_h4 = __riscv_vadd_vv_u16m1 (sumi_h4_0 ,sumi_h4_1 ,vl /2 ); 796const vuint32m1_t sumi_h4_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (sumi_h4 ); 797const vint16mf2_t sumi_h8_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,0 ,vl /4 )); 798const vint16mf2_t sumi_h8_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,16 ,vl /4 )); 799const vint32m1_t sumi_h8 = __riscv_vwadd_vv_i32m1 (sumi_h8_0 ,sumi_h8_1 ,vl /4 ); 800const vfloat32m1_t facc = __riscv_vfcvt_f_x_v_f32m1 (sumi_h8 ,vl /4 ); 801 802const vfloat32m1_t tmp1 = __riscv_vfmul_vf_f32m1 (facc ,a_scales [1 ],vl /4 ); 803sumf1 = __riscv_vfmacc_vv_f32m1 (sumf1 ,tmp1 ,b_scales_vec ,vl /4 ); 804 } 805 806const int64_t A2 = * (const int64_t * )& a_ptr [l ].qs [16 ]; 807const int64_t A6 = * (const int64_t * )& a_ptr [l ].qs [48 ]; 808const int64_t Aa = * (const int64_t * )& a_ptr [l ].qs [80 ]; 809const int64_t Ae = * (const int64_t * )& a_ptr [l ].qs [112 ]; 810 __asm__ __volatile__("" :::"memory" );// prevent gcc from emitting fused vlse64, violating alignment 811vint16m4_t sumi_l2 ; 812 { 813const vint8m2_t lhs_0_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A2 ,vl /4 )); 814const vint8m2_t lhs_1_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A6 ,vl /4 )); 815const vint8m2_t lhs_2_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Aa ,vl /4 )); 816const vint8m2_t lhs_3_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Ae ,vl /4 )); 817const vint16m4_t sumi_lo_0 = __riscv_vwmul_vv_i16m4 (rhs_vec_lo_0 ,lhs_0_8 ,vl * 2 ); 818const vint16m4_t sumi_lo_1 = __riscv_vwmacc_vv_i16m4 (sumi_lo_0 ,rhs_vec_lo_1 ,lhs_1_8 ,vl * 2 ); 819const vint16m4_t sumi_hi_0 = __riscv_vwmacc_vv_i16m4 (sumi_lo_1 ,rhs_vec_hi_0 ,lhs_2_8 ,vl * 2 ); 820const vint16m4_t sumi_hi_m = __riscv_vwmacc_vv_i16m4 (sumi_hi_0 ,rhs_vec_hi_1 ,lhs_3_8 ,vl * 2 ); 821 822sumi_l2 = sumi_hi_m ; 823 } 824 825 { 826const vuint32m4_t sumi_i32 = __riscv_vreinterpret_v_i32m4_u32m4 (__riscv_vreinterpret_v_i16m4_i32m4 (sumi_l2 )); 827const vuint16m2_t sumi_h2_0 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,0 ,vl ); 828const vuint16m2_t sumi_h2_1 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,16 ,vl ); 829const vuint16m2_t sumi_h2 = __riscv_vadd_vv_u16m2 (sumi_h2_0 ,sumi_h2_1 ,vl ); 830const vuint32m2_t sumi_h2_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (sumi_h2 ); 831const vuint16m1_t sumi_h4_0 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,0 ,vl /2 ); 832const vuint16m1_t sumi_h4_1 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,16 ,vl /2 ); 833const vuint16m1_t sumi_h4 = __riscv_vadd_vv_u16m1 (sumi_h4_0 ,sumi_h4_1 ,vl /2 ); 834const vuint32m1_t sumi_h4_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (sumi_h4 ); 835const vint16mf2_t sumi_h8_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,0 ,vl /4 )); 836const vint16mf2_t sumi_h8_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,16 ,vl /4 )); 837const vint32m1_t sumi_h8 = __riscv_vwadd_vv_i32m1 (sumi_h8_0 ,sumi_h8_1 ,vl /4 ); 838const vfloat32m1_t facc = __riscv_vfcvt_f_x_v_f32m1 (sumi_h8 ,vl /4 ); 839 840const vfloat32m1_t tmp1 = __riscv_vfmul_vf_f32m1 (facc ,a_scales [2 ],vl /4 ); 841sumf2 = __riscv_vfmacc_vv_f32m1 (sumf2 ,tmp1 ,b_scales_vec ,vl /4 ); 842 } 843 844const int64_t A3 = * (const int64_t * )& a_ptr [l ].qs [24 ]; 845const int64_t A7 = * (const int64_t * )& a_ptr [l ].qs [56 ]; 846const int64_t Ab = * (const int64_t * )& a_ptr [l ].qs [88 ]; 847const int64_t Af = * (const int64_t * )& a_ptr [l ].qs [120 ]; 848 __asm__ __volatile__("" :::"memory" );// prevent gcc from emitting fused vlse64, violating alignment 849vint16m4_t sumi_l3 ; 850 { 851const vint8m2_t lhs_0_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A3 ,vl /4 )); 852const vint8m2_t lhs_1_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (A7 ,vl /4 )); 853const vint8m2_t lhs_2_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Ab ,vl /4 )); 854const vint8m2_t lhs_3_8 = __riscv_vreinterpret_v_i64m2_i8m2 (__riscv_vmv_v_x_i64m2 (Af ,vl /4 )); 855const vint16m4_t sumi_lo_0 = __riscv_vwmul_vv_i16m4 (rhs_vec_lo_0 ,lhs_0_8 ,vl * 2 ); 856const vint16m4_t sumi_lo_1 = __riscv_vwmacc_vv_i16m4 (sumi_lo_0 ,rhs_vec_lo_1 ,lhs_1_8 ,vl * 2 ); 857const vint16m4_t sumi_hi_0 = __riscv_vwmacc_vv_i16m4 (sumi_lo_1 ,rhs_vec_hi_0 ,lhs_2_8 ,vl * 2 ); 858const vint16m4_t sumi_hi_m = __riscv_vwmacc_vv_i16m4 (sumi_hi_0 ,rhs_vec_hi_1 ,lhs_3_8 ,vl * 2 ); 859 860sumi_l3 = sumi_hi_m ; 861 } 862 863 { 864const vuint32m4_t sumi_i32 = __riscv_vreinterpret_v_i32m4_u32m4 (__riscv_vreinterpret_v_i16m4_i32m4 (sumi_l3 )); 865const vuint16m2_t sumi_h2_0 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,0 ,vl ); 866const vuint16m2_t sumi_h2_1 = __riscv_vnsrl_wx_u16m2 (sumi_i32 ,16 ,vl ); 867const vuint16m2_t sumi_h2 = __riscv_vadd_vv_u16m2 (sumi_h2_0 ,sumi_h2_1 ,vl ); 868const vuint32m2_t sumi_h2_i32 = __riscv_vreinterpret_v_u16m2_u32m2 (sumi_h2 ); 869const vuint16m1_t sumi_h4_0 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,0 ,vl /2 ); 870const vuint16m1_t sumi_h4_1 = __riscv_vnsrl_wx_u16m1 (sumi_h2_i32 ,16 ,vl /2 ); 871const vuint16m1_t sumi_h4 = __riscv_vadd_vv_u16m1 (sumi_h4_0 ,sumi_h4_1 ,vl /2 ); 872const vuint32m1_t sumi_h4_i32 = __riscv_vreinterpret_v_u16m1_u32m1 (sumi_h4 ); 873const vint16mf2_t sumi_h8_0 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,0 ,vl /4 )); 874const vint16mf2_t sumi_h8_1 = __riscv_vreinterpret_v_u16mf2_i16mf2 (__riscv_vnsrl_wx_u16mf2 (sumi_h4_i32 ,16 ,vl /4 )); 875const vint32m1_t sumi_h8 = __riscv_vwadd_vv_i32m1 (sumi_h8_0 ,sumi_h8_1 ,vl /4 ); 876const vfloat32m1_t facc = __riscv_vfcvt_f_x_v_f32m1 (sumi_h8 ,vl /4 ); 877 878const vfloat32m1_t tmp1 = __riscv_vfmul_vf_f32m1 (facc ,a_scales [3 ],vl /4 ); 879sumf3 = __riscv_vfmacc_vv_f32m1 (sumf3 ,tmp1 ,b_scales_vec ,vl /4 ); 880 } 881 } 882__riscv_vse32_v_f32m1 (& s [(y * 4 + 0 )* bs + x * ncols_interleaved ],sumf0 ,vl /4 ); 883__riscv_vse32_v_f32m1 (& s [(y * 4 + 1 )* bs + x * ncols_interleaved ],sumf1 ,vl /4 ); 884__riscv_vse32_v_f32m1 (& s [(y * 4 + 2 )* bs + x * ncols_interleaved ],sumf2 ,vl /4 ); 885__riscv_vse32_v_f32m1 (& s [(y * 4 + 3 )* bs + x * ncols_interleaved ],sumf3 ,vl /4 ); 886 } 887 } 888 889return ; 890 } 891 892#endif 893ggml_gemm_q4_0_8x8_q8_0_generic (n ,s ,bs ,vx ,vy ,nr ,nc ); 894} 895 896#if defined__riscv_zvfh 897void ggml_gemm_q4_0_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 898const int qk = QK8_0 ; 899const int nb = n /qk ; 900const int ncols_interleaved = 16 ; 901const int blocklen = 1 ; 902 903assert (n %qk == 0 ); 904assert (nr %4 == 0 ); 905assert (nc %ncols_interleaved == 0 ); 906 907UNUSED (s ); 908UNUSED (bs ); 909UNUSED (vx ); 910UNUSED (vy ); 911UNUSED (nr ); 912UNUSED (nc ); 913UNUSED (nb ); 914UNUSED (ncols_interleaved ); 915UNUSED (blocklen ); 916 917for (int y = 0 ;y < nr /4 ;y ++ ) { 918const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 919for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 920const block_q4_0x16 * b_ptr = (const block_q4_0x16 * )vx + (x * nb ); 921 922// 4x16 Accumulators 923vfloat32m2_t sumf_0 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 924vfloat32m2_t sumf_1 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 925vfloat32m2_t sumf_2 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 926vfloat32m2_t sumf_3 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 927 928for (int l = 0 ;l < nb ;l ++ ) { 929// 4x16 integer accumulators 930vint16m1_t sumi_0_lo_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 931vint16m1_t sumi_1_lo_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 932vint16m1_t sumi_2_lo_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 933vint16m1_t sumi_3_lo_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 934vint16m1_t sumi_0_hi_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 935vint16m1_t sumi_1_hi_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 936vint16m1_t sumi_2_hi_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 937vint16m1_t sumi_3_hi_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 938 939// Accumulation loop. 940for (int i = 0 ;i < QK4_0 /2 ;i ++ ) { 941// Load `b_ptr`. 942const vint8mf2_t b_0_packed = __riscv_vle8_v_i8mf2 ((const int8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 943const vint8mf2_t b_0_lo = __riscv_vsra_vx_i8mf2 (__riscv_vsll_vx_i8mf2 (b_0_packed ,4 ,16 ),4 ,16 ); 944const vint8mf2_t b_0_hi = __riscv_vsra_vx_i8mf2 (b_0_packed ,4 ,16 ); 945 946sumi_0_lo_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_lo_16 ,a_ptr [l ].qs [i * 4 ],b_0_lo ,16 ); 947sumi_1_lo_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_lo_16 ,a_ptr [l ].qs [i * 4 + 1 ],b_0_lo ,16 ); 948sumi_2_lo_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_lo_16 ,a_ptr [l ].qs [i * 4 + 2 ],b_0_lo ,16 ); 949sumi_3_lo_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_lo_16 ,a_ptr [l ].qs [i * 4 + 3 ],b_0_lo ,16 ); 950 951sumi_0_hi_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_hi_16 ,a_ptr [l ].qs [64 + i * 4 ],b_0_hi ,16 ); 952sumi_1_hi_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_hi_16 ,a_ptr [l ].qs [64 + i * 4 + 1 ],b_0_hi ,16 ); 953sumi_2_hi_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_hi_16 ,a_ptr [l ].qs [64 + i * 4 + 2 ],b_0_hi ,16 ); 954sumi_3_hi_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_hi_16 ,a_ptr [l ].qs [64 + i * 4 + 3 ],b_0_hi ,16 ); 955 } 956 957// Do the final accumulation in i32 to prevent overflow. 958const vint32m2_t sumi_0 = __riscv_vwadd_vv_i32m2 (sumi_0_lo_16 ,sumi_0_hi_16 ,16 ); 959const vint32m2_t sumi_1 = __riscv_vwadd_vv_i32m2 (sumi_1_lo_16 ,sumi_1_hi_16 ,16 ); 960const vint32m2_t sumi_2 = __riscv_vwadd_vv_i32m2 (sumi_2_lo_16 ,sumi_2_hi_16 ,16 ); 961const vint32m2_t sumi_3 = __riscv_vwadd_vv_i32m2 (sumi_3_lo_16 ,sumi_3_hi_16 ,16 ); 962 963const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 964const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [0 ],16 ); 965const vfloat32m2_t d_1 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [1 ],16 ); 966const vfloat32m2_t d_2 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [2 ],16 ); 967const vfloat32m2_t d_3 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [3 ],16 ); 968 969sumf_0 = __riscv_vfmacc_vv_f32m2 (sumf_0 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_0 ,16 ),d_0 ,16 ); 970sumf_1 = __riscv_vfmacc_vv_f32m2 (sumf_1 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_1 ,16 ),d_1 ,16 ); 971sumf_2 = __riscv_vfmacc_vv_f32m2 (sumf_2 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_2 ,16 ),d_2 ,16 ); 972sumf_3 = __riscv_vfmacc_vv_f32m2 (sumf_3 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_3 ,16 ),d_3 ,16 ); 973 } 974 975__riscv_vse32_v_f32m2 (s + (y * 4 + 0 )* bs + x * 16 ,sumf_0 ,16 ); 976__riscv_vse32_v_f32m2 (s + (y * 4 + 1 )* bs + x * 16 ,sumf_1 ,16 ); 977__riscv_vse32_v_f32m2 (s + (y * 4 + 2 )* bs + x * 16 ,sumf_2 ,16 ); 978__riscv_vse32_v_f32m2 (s + (y * 4 + 3 )* bs + x * 16 ,sumf_3 ,16 ); 979 } 980 } 981} 982 983void ggml_gemm_q4_K_16x1_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 984const int qk = QK_K ; 985const int nb = n /qk ; 986const int ncols_interleaved = 16 ; 987const int blocklen = 1 ; 988 989assert (n %qk == 0 ); 990assert (nr %4 == 0 ); 991assert (nc %ncols_interleaved == 0 ); 992 993UNUSED (s ); 994UNUSED (bs ); 995UNUSED (vx ); 996UNUSED (vy ); 997UNUSED (nr ); 998UNUSED (nc ); 999UNUSED (nb ); 1000UNUSED (ncols_interleaved ); 1001UNUSED (blocklen ); 1002 1003for (int y = 0 ;y < nr /4 ;y ++ ) { 1004const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 * )vy + (y * nb ); 1005for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1006const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 * )vx + (x * nb ); 1007 1008// 4x16 Accumulators 1009vfloat32m2_t sumf_0 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1010vfloat32m2_t sumf_1 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1011vfloat32m2_t sumf_2 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1012vfloat32m2_t sumf_3 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1013 1014for (int l = 0 ;l < nb ;l ++ ) { 1015vint32m2_t sumi_0 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1016vint32m2_t sumi_1 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1017vint32m2_t sumi_2 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1018vint32m2_t sumi_3 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1019 1020// Load `dmin`. 1021const vfloat32m2_t dmins = __riscv_vfwcvt_f_f_v_f32m2 (__riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].dmin ,16 ),16 ); 1022 1023// We process 4 sub-blocks at once. 1024for (int j = 0 ;j < QK_K /128 ;j ++ ) { 1025// Extract the scales and the mins. 1026// 1027// Low bits. 1028vuint8m2_t scales_mins_lo = __riscv_vle8_v_u8m2 (& b_ptr [l ].scales [j * 64 ],64 ); 1029vuint8m2_t scales_lo = __riscv_vand_vx_u8m2 (scales_mins_lo ,0x0F ,64 ); 1030vuint8m2_t mins_lo = __riscv_vsrl_vx_u8m2 (scales_mins_lo ,4 ,64 ); 1031 1032// High bits. 1033vuint8m2_t scales_mins_hi = __riscv_vle8_v_u8m2 (& b_ptr [l ].scales [128 ],64 ); 1034vuint8m2_t scales_hi ; 1035vuint8m2_t mins_hi ; 1036if (!j ) { 1037scales_hi = __riscv_vsll_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0x03 ,64 ),4 ,64 ); 1038mins_hi = __riscv_vsll_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0x0C ,64 ),2 ,64 ); 1039 }else { 1040scales_hi = __riscv_vand_vx_u8m2 (scales_mins_hi ,0x30 ,64 ); 1041mins_hi = __riscv_vsrl_vx_u8m2 (__riscv_vand_vx_u8m2 (scales_mins_hi ,0xC0 ,64 ),2 ,64 ); 1042 } 1043vuint16m4_t scales = __riscv_vzext_vf2_u16m4 (__riscv_vor_vv_u8m2 (scales_hi ,scales_lo ,64 ),64 ); 1044vint16m4_t mins = __riscv_vreinterpret_v_u16m4_i16m4 (__riscv_vzext_vf2_u16m4 (__riscv_vor_vv_u8m2 (mins_hi ,mins_lo ,64 ),64 )); 1045 1046// Reduce the mins and multiply with `dmin`. 1047// 1048// Correct in `sumf`. 1049vint32m2_t bsums_0 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1050vint32m2_t bsums_1 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1051vint32m2_t bsums_2 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1052vint32m2_t bsums_3 = __riscv_vmv_v_x_i32m2 (0 ,16 ); 1053 1054bsums_0 = __riscv_vwmacc_vx_i32m2 (bsums_0 , 1055a_ptr [l ].bsums [j * 32 ]+ a_ptr [l ].bsums [j * 32 + 4 ], 1056__riscv_vget_v_i16m4_i16m1 (mins ,0 ),16 ); 1057bsums_1 = __riscv_vwmacc_vx_i32m2 (bsums_1 , 1058a_ptr [l ].bsums [j * 32 + 1 ]+ a_ptr [l ].bsums [j * 32 + 5 ], 1059__riscv_vget_v_i16m4_i16m1 (mins ,0 ),16 ); 1060bsums_2 = __riscv_vwmacc_vx_i32m2 (bsums_2 , 1061a_ptr [l ].bsums [j * 32 + 2 ]+ a_ptr [l ].bsums [j * 32 + 6 ], 1062__riscv_vget_v_i16m4_i16m1 (mins ,0 ),16 ); 1063bsums_3 = __riscv_vwmacc_vx_i32m2 (bsums_3 , 1064a_ptr [l ].bsums [j * 32 + 3 ]+ a_ptr [l ].bsums [j * 32 + 7 ], 1065__riscv_vget_v_i16m4_i16m1 (mins ,0 ),16 ); 1066bsums_0 = __riscv_vwmacc_vx_i32m2 (bsums_0 , 1067a_ptr [l ].bsums [j * 32 + 8 ]+ a_ptr [l ].bsums [j * 32 + 8 + 4 ], 1068__riscv_vget_v_i16m4_i16m1 (mins ,1 ),16 ); 1069bsums_1 = __riscv_vwmacc_vx_i32m2 (bsums_1 , 1070a_ptr [l ].bsums [j * 32 + 8 + 1 ]+ a_ptr [l ].bsums [j * 32 + 8 + 5 ], 1071__riscv_vget_v_i16m4_i16m1 (mins ,1 ),16 ); 1072bsums_2 = __riscv_vwmacc_vx_i32m2 (bsums_2 , 1073a_ptr [l ].bsums [j * 32 + 8 + 2 ]+ a_ptr [l ].bsums [j * 32 + 8 + 6 ], 1074__riscv_vget_v_i16m4_i16m1 (mins ,1 ),16 ); 1075bsums_3 = __riscv_vwmacc_vx_i32m2 (bsums_3 , 1076a_ptr [l ].bsums [j * 32 + 8 + 3 ]+ a_ptr [l ].bsums [j * 32 + 8 + 7 ], 1077__riscv_vget_v_i16m4_i16m1 (mins ,1 ),16 ); 1078bsums_0 = __riscv_vwmacc_vx_i32m2 (bsums_0 , 1079a_ptr [l ].bsums [j * 32 + 16 ]+ a_ptr [l ].bsums [j * 32 + 16 + 4 ], 1080__riscv_vget_v_i16m4_i16m1 (mins ,2 ),16 ); 1081bsums_1 = __riscv_vwmacc_vx_i32m2 (bsums_1 , 1082a_ptr [l ].bsums [j * 32 + 16 + 1 ]+ a_ptr [l ].bsums [j * 32 + 16 + 5 ], 1083__riscv_vget_v_i16m4_i16m1 (mins ,2 ),16 ); 1084bsums_2 = __riscv_vwmacc_vx_i32m2 (bsums_2 , 1085a_ptr [l ].bsums [j * 32 + 16 + 2 ]+ a_ptr [l ].bsums [j * 32 + 16 + 6 ], 1086__riscv_vget_v_i16m4_i16m1 (mins ,2 ),16 ); 1087bsums_3 = __riscv_vwmacc_vx_i32m2 (bsums_3 , 1088a_ptr [l ].bsums [j * 32 + 16 + 3 ]+ a_ptr [l ].bsums [j * 32 + 16 + 7 ], 1089__riscv_vget_v_i16m4_i16m1 (mins ,2 ),16 ); 1090bsums_0 = __riscv_vwmacc_vx_i32m2 (bsums_0 , 1091a_ptr [l ].bsums [j * 32 + 24 + 0 ]+ a_ptr [l ].bsums [j * 32 + 24 + 4 ], 1092__riscv_vget_v_i16m4_i16m1 (mins ,3 ),16 ); 1093bsums_1 = __riscv_vwmacc_vx_i32m2 (bsums_1 , 1094a_ptr [l ].bsums [j * 32 + 24 + 1 ]+ a_ptr [l ].bsums [j * 32 + 24 + 5 ], 1095__riscv_vget_v_i16m4_i16m1 (mins ,3 ),16 ); 1096bsums_2 = __riscv_vwmacc_vx_i32m2 (bsums_2 , 1097a_ptr [l ].bsums [j * 32 + 24 + 2 ]+ a_ptr [l ].bsums [j * 32 + 24 + 6 ], 1098__riscv_vget_v_i16m4_i16m1 (mins ,3 ),16 ); 1099bsums_3 = __riscv_vwmacc_vx_i32m2 (bsums_3 , 1100a_ptr [l ].bsums [j * 32 + 24 + 3 ]+ a_ptr [l ].bsums [j * 32 + 24 + 7 ], 1101__riscv_vget_v_i16m4_i16m1 (mins ,3 ),16 ); 1102 1103const vfloat32m2_t dmins_d_0 = __riscv_vfmul_vf_f32m2 (dmins ,a_ptr [l ].d [0 ],16 ); 1104const vfloat32m2_t dmins_d_1 = __riscv_vfmul_vf_f32m2 (dmins ,a_ptr [l ].d [1 ],16 ); 1105const vfloat32m2_t dmins_d_2 = __riscv_vfmul_vf_f32m2 (dmins ,a_ptr [l ].d [2 ],16 ); 1106const vfloat32m2_t dmins_d_3 = __riscv_vfmul_vf_f32m2 (dmins ,a_ptr [l ].d [3 ],16 ); 1107 1108sumf_0 = __riscv_vfsub_vv_f32m2 (sumf_0 ,__riscv_vfmul_vv_f32m2 (dmins_d_0 ,__riscv_vfcvt_f_x_v_f32m2 (bsums_0 ,16 ),16 ),16 ); 1109sumf_1 = __riscv_vfsub_vv_f32m2 (sumf_1 ,__riscv_vfmul_vv_f32m2 (dmins_d_1 ,__riscv_vfcvt_f_x_v_f32m2 (bsums_1 ,16 ),16 ),16 ); 1110sumf_2 = __riscv_vfsub_vv_f32m2 (sumf_2 ,__riscv_vfmul_vv_f32m2 (dmins_d_2 ,__riscv_vfcvt_f_x_v_f32m2 (bsums_2 ,16 ),16 ),16 ); 1111sumf_3 = __riscv_vfsub_vv_f32m2 (sumf_3 ,__riscv_vfmul_vv_f32m2 (dmins_d_3 ,__riscv_vfcvt_f_x_v_f32m2 (bsums_3 ,16 ),16 ),16 ); 1112 1113 1114// Accumulation for 2 sub-blocks. 1115// 1116// This might overflow, so we accumulate in two steps. 1117// 1118// Recheck. 1119for (int k = 0 ;k < 2 ;k ++ ) { 1120// 4x16 integer accumulators 1121vint16m1_t sumi_0_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1122vint16m1_t sumi_1_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1123vint16m1_t sumi_2_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1124vint16m1_t sumi_3_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1125vint16m1_t sumi_0_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1126vint16m1_t sumi_1_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1127vint16m1_t sumi_2_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1128vint16m1_t sumi_3_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1129 1130for (int i = k * 16 ;i < k * 16 + QK4_0 /2 ;i ++ ) { 1131// Load `b_ptr`. 1132const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 (& b_ptr [l ].qs [j * 1024 + i * 16 ],16 ); 1133const vint8mf2_t b_s_0 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (b_0_packed ,0xF ,16 )); 1134const vint8mf2_t b_s_1 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 )); 1135 1136sumi_0_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_s_0_16 ,a_ptr [l ].qs [j * 512 + i * 4 ],b_s_0 ,16 ); 1137sumi_1_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_s_0_16 ,a_ptr [l ].qs [j * 512 + i * 4 + 1 ],b_s_0 ,16 ); 1138sumi_2_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_s_0_16 ,a_ptr [l ].qs [j * 512 + i * 4 + 2 ],b_s_0 ,16 ); 1139sumi_3_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_s_0_16 ,a_ptr [l ].qs [j * 512 + i * 4 + 3 ],b_s_0 ,16 ); 1140 1141sumi_0_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_s_1_16 ,a_ptr [l ].qs [j * 512 + 128 + i * 4 ],b_s_1 ,16 ); 1142sumi_1_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_s_1_16 ,a_ptr [l ].qs [j * 512 + 128 + i * 4 + 1 ],b_s_1 ,16 ); 1143sumi_2_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_s_1_16 ,a_ptr [l ].qs [j * 512 + 128 + i * 4 + 2 ],b_s_1 ,16 ); 1144sumi_3_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_s_1_16 ,a_ptr [l ].qs [j * 512 + 128 + i * 4 + 3 ],b_s_1 ,16 ); 1145 } 1146 1147sumi_0 = __riscv_vwmacc_vv_i32m2 (sumi_0 , 1148__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,0 )), 1149sumi_0_s_0_16 ,16 ); 1150sumi_0 = __riscv_vwmacc_vv_i32m2 (sumi_0 , 1151__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,1 )), 1152sumi_0_s_1_16 ,16 ); 1153sumi_1 = __riscv_vwmacc_vv_i32m2 (sumi_1 , 1154__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,0 )), 1155sumi_1_s_0_16 ,16 ); 1156sumi_1 = __riscv_vwmacc_vv_i32m2 (sumi_1 , 1157__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,1 )), 1158sumi_1_s_1_16 ,16 ); 1159sumi_2 = __riscv_vwmacc_vv_i32m2 (sumi_2 , 1160__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,0 )), 1161sumi_2_s_0_16 ,16 ); 1162sumi_2 = __riscv_vwmacc_vv_i32m2 (sumi_2 , 1163__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,1 )), 1164sumi_2_s_1_16 ,16 ); 1165sumi_3 = __riscv_vwmacc_vv_i32m2 (sumi_3 , 1166__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,0 )), 1167sumi_3_s_0_16 ,16 ); 1168sumi_3 = __riscv_vwmacc_vv_i32m2 (sumi_3 , 1169__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,1 )), 1170sumi_3_s_1_16 ,16 ); 1171 } 1172// Accumulation for 2 sub-blocks. 1173// 1174// This might overflow, so we accumulate in two steps. 1175// 1176// Recheck. 1177for (int k = 0 ;k < 2 ;k ++ ) { 1178// 4x16 integer accumulators 1179vint16m1_t sumi_0_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1180vint16m1_t sumi_1_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1181vint16m1_t sumi_2_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1182vint16m1_t sumi_3_s_0_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1183vint16m1_t sumi_0_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1184vint16m1_t sumi_1_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1185vint16m1_t sumi_2_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1186vint16m1_t sumi_3_s_1_16 = __riscv_vmv_v_x_i16m1 (0.0f ,16 ); 1187 1188for (int i = k * 16 ;i < k * 16 + QK4_0 /2 ;i ++ ) { 1189// Load `b_ptr`. 1190const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 (& b_ptr [l ].qs [j * 1024 + 512 + i * 16 ],16 ); 1191const vint8mf2_t b_s_0 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vand_vx_u8mf2 (b_0_packed ,0xF ,16 )); 1192const vint8mf2_t b_s_1 = __riscv_vreinterpret_v_u8mf2_i8mf2 (__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 )); 1193 1194sumi_0_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_s_0_16 ,a_ptr [l ].qs [j * 512 + 256 + i * 4 ],b_s_0 ,16 ); 1195sumi_1_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_s_0_16 ,a_ptr [l ].qs [j * 512 + 256 + i * 4 + 1 ],b_s_0 ,16 ); 1196sumi_2_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_s_0_16 ,a_ptr [l ].qs [j * 512 + 256 + i * 4 + 2 ],b_s_0 ,16 ); 1197sumi_3_s_0_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_s_0_16 ,a_ptr [l ].qs [j * 512 + 256 + i * 4 + 3 ],b_s_0 ,16 ); 1198 1199sumi_0_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_0_s_1_16 ,a_ptr [l ].qs [j * 512 + 384 + i * 4 ],b_s_1 ,16 ); 1200sumi_1_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_1_s_1_16 ,a_ptr [l ].qs [j * 512 + 384 + i * 4 + 1 ],b_s_1 ,16 ); 1201sumi_2_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_2_s_1_16 ,a_ptr [l ].qs [j * 512 + 384 + i * 4 + 2 ],b_s_1 ,16 ); 1202sumi_3_s_1_16 = __riscv_vwmacc_vx_i16m1 (sumi_3_s_1_16 ,a_ptr [l ].qs [j * 512 + 384 + i * 4 + 3 ],b_s_1 ,16 ); 1203 } 1204 1205sumi_0 = __riscv_vwmacc_vv_i32m2 (sumi_0 , 1206__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,2 )), 1207sumi_0_s_0_16 ,16 ); 1208sumi_0 = __riscv_vwmacc_vv_i32m2 (sumi_0 , 1209__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,3 )), 1210sumi_0_s_1_16 ,16 ); 1211sumi_1 = __riscv_vwmacc_vv_i32m2 (sumi_1 , 1212__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,2 )), 1213sumi_1_s_0_16 ,16 ); 1214sumi_1 = __riscv_vwmacc_vv_i32m2 (sumi_1 , 1215__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,3 )), 1216sumi_1_s_1_16 ,16 ); 1217sumi_2 = __riscv_vwmacc_vv_i32m2 (sumi_2 , 1218__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,2 )), 1219sumi_2_s_0_16 ,16 ); 1220sumi_2 = __riscv_vwmacc_vv_i32m2 (sumi_2 , 1221__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,3 )), 1222sumi_2_s_1_16 ,16 ); 1223sumi_3 = __riscv_vwmacc_vv_i32m2 (sumi_3 , 1224__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,2 )), 1225sumi_3_s_0_16 ,16 ); 1226sumi_3 = __riscv_vwmacc_vv_i32m2 (sumi_3 , 1227__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vget_v_u16m4_u16m1 (scales ,3 )), 1228sumi_3_s_1_16 ,16 ); 1229 } 1230 } 1231 1232const vfloat32m2_t b_d = __riscv_vfwcvt_f_f_v_f32m2 (__riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ),16 ); 1233const vfloat32m2_t d_0 = __riscv_vfmul_vf_f32m2 (b_d ,a_ptr [l ].d [0 ],16 ); 1234const vfloat32m2_t d_1 = __riscv_vfmul_vf_f32m2 (b_d ,a_ptr [l ].d [1 ],16 ); 1235const vfloat32m2_t d_2 = __riscv_vfmul_vf_f32m2 (b_d ,a_ptr [l ].d [2 ],16 ); 1236const vfloat32m2_t d_3 = __riscv_vfmul_vf_f32m2 (b_d ,a_ptr [l ].d [3 ],16 ); 1237 1238sumf_0 = __riscv_vfmacc_vv_f32m2 (sumf_0 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_0 ,16 ),d_0 ,16 ); 1239sumf_1 = __riscv_vfmacc_vv_f32m2 (sumf_1 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_1 ,16 ),d_1 ,16 ); 1240sumf_2 = __riscv_vfmacc_vv_f32m2 (sumf_2 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_2 ,16 ),d_2 ,16 ); 1241sumf_3 = __riscv_vfmacc_vv_f32m2 (sumf_3 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_3 ,16 ),d_3 ,16 ); 1242 } 1243 1244__riscv_vse32_v_f32m2 (s + (y * 4 + 0 )* bs + x * 16 ,sumf_0 ,16 ); 1245__riscv_vse32_v_f32m2 (s + (y * 4 + 1 )* bs + x * 16 ,sumf_1 ,16 ); 1246__riscv_vse32_v_f32m2 (s + (y * 4 + 2 )* bs + x * 16 ,sumf_2 ,16 ); 1247__riscv_vse32_v_f32m2 (s + (y * 4 + 3 )* bs + x * 16 ,sumf_3 ,16 ); 1248 } 1249 } 1250} 1251 1252void ggml_gemm_iq4_nl_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1253const int qk = QK8_0 ; 1254const int nb = n /qk ; 1255const int ncols_interleaved = 16 ; 1256const int blocklen = 1 ; 1257 1258assert (n %qk == 0 ); 1259assert (nr %4 == 0 ); 1260assert (nc %ncols_interleaved == 0 ); 1261 1262UNUSED (s ); 1263UNUSED (bs ); 1264UNUSED (vx ); 1265UNUSED (vy ); 1266UNUSED (nr ); 1267UNUSED (nc ); 1268UNUSED (nb ); 1269UNUSED (ncols_interleaved ); 1270UNUSED (blocklen ); 1271 1272const vint8mf2_t values = __riscv_vle8_v_i8mf2 (kvalues_iq4nl ,16 ); 1273for (int y = 0 ;y < nr /4 ;y ++ ) { 1274const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 1275for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1276const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 * )vx + (x * nb ); 1277 1278// 4x16 Accumulators 1279vfloat32m2_t sumf_0 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1280vfloat32m2_t sumf_1 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1281vfloat32m2_t sumf_2 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1282vfloat32m2_t sumf_3 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1283 1284for (int l = 0 ;l < nb ;l ++ ) { 1285// 4x16 integer accumulators 1286vint32m2_t sumi_0 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1287vint32m2_t sumi_1 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1288vint32m2_t sumi_2 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1289vint32m2_t sumi_3 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1290 1291// Accumulation loop. 1292for (int i = 0 ;i < QK4_NL /2 ;i ++ ) { 1293// Load `b_ptr`. 1294const vuint8mf2_t b_0_packed = __riscv_vle8_v_u8mf2 ((const uint8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 1295const vint8mf2_t b_0_lo = __riscv_vrgather_vv_i8mf2 (values ,__riscv_vand_vx_u8mf2 (b_0_packed ,0xf ,16 ),16 ); 1296const vint8mf2_t b_0_hi = __riscv_vrgather_vv_i8mf2 (values ,__riscv_vsrl_vx_u8mf2 (b_0_packed ,4 ,16 ),16 ); 1297// const vint16m1_t b_0_lo_16 = __riscv_vwcvt_x_x_v_i16m1(b_0_lo, 16); 1298// const vint16m1_t b_0_hi_16 = __riscv_vwcvt_x_x_v_i16m1(b_0_hi, 16); 1299 1300const vint16m1_t sumi_0_lo = __riscv_vwmul_vx_i16m1 (b_0_lo ,a_ptr [l ].qs [i * 4 ],16 ); 1301const vint16m1_t sumi_1_lo = __riscv_vwmul_vx_i16m1 (b_0_lo ,a_ptr [l ].qs [i * 4 + 1 ],16 ); 1302const vint16m1_t sumi_2_lo = __riscv_vwmul_vx_i16m1 (b_0_lo ,a_ptr [l ].qs [i * 4 + 2 ],16 ); 1303const vint16m1_t sumi_3_lo = __riscv_vwmul_vx_i16m1 (b_0_lo ,a_ptr [l ].qs [i * 4 + 3 ],16 ); 1304 1305const vint16m1_t sumi_0_hi = __riscv_vwmul_vx_i16m1 (b_0_hi ,a_ptr [l ].qs [64 + i * 4 ],16 ); 1306const vint16m1_t sumi_1_hi = __riscv_vwmul_vx_i16m1 (b_0_hi ,a_ptr [l ].qs [64 + i * 4 + 1 ],16 ); 1307const vint16m1_t sumi_2_hi = __riscv_vwmul_vx_i16m1 (b_0_hi ,a_ptr [l ].qs [64 + i * 4 + 2 ],16 ); 1308const vint16m1_t sumi_3_hi = __riscv_vwmul_vx_i16m1 (b_0_hi ,a_ptr [l ].qs [64 + i * 4 + 3 ],16 ); 1309 1310sumi_0 = __riscv_vadd_vv_i32m2 (sumi_0 ,__riscv_vwadd_vv_i32m2 (sumi_0_lo ,sumi_0_hi ,16 ),16 ); 1311sumi_1 = __riscv_vadd_vv_i32m2 (sumi_1 ,__riscv_vwadd_vv_i32m2 (sumi_1_lo ,sumi_1_hi ,16 ),16 ); 1312sumi_2 = __riscv_vadd_vv_i32m2 (sumi_2 ,__riscv_vwadd_vv_i32m2 (sumi_2_lo ,sumi_2_hi ,16 ),16 ); 1313sumi_3 = __riscv_vadd_vv_i32m2 (sumi_3 ,__riscv_vwadd_vv_i32m2 (sumi_3_lo ,sumi_3_hi ,16 ),16 ); 1314 } 1315 1316const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 1317const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [0 ],16 ); 1318const vfloat32m2_t d_1 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [1 ],16 ); 1319const vfloat32m2_t d_2 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [2 ],16 ); 1320const vfloat32m2_t d_3 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [3 ],16 ); 1321 1322sumf_0 = __riscv_vfmacc_vv_f32m2 (sumf_0 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_0 ,16 ),d_0 ,16 ); 1323sumf_1 = __riscv_vfmacc_vv_f32m2 (sumf_1 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_1 ,16 ),d_1 ,16 ); 1324sumf_2 = __riscv_vfmacc_vv_f32m2 (sumf_2 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_2 ,16 ),d_2 ,16 ); 1325sumf_3 = __riscv_vfmacc_vv_f32m2 (sumf_3 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_3 ,16 ),d_3 ,16 ); 1326 } 1327 1328__riscv_vse32_v_f32m2 (s + (y * 4 + 0 )* bs + x * 16 ,sumf_0 ,16 ); 1329__riscv_vse32_v_f32m2 (s + (y * 4 + 1 )* bs + x * 16 ,sumf_1 ,16 ); 1330__riscv_vse32_v_f32m2 (s + (y * 4 + 2 )* bs + x * 16 ,sumf_2 ,16 ); 1331__riscv_vse32_v_f32m2 (s + (y * 4 + 3 )* bs + x * 16 ,sumf_3 ,16 ); 1332 } 1333 } 1334} 1335 1336void ggml_gemm_q8_0_16x1_q8_0 (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1337const int qk = QK8_0 ; 1338const int nb = n /qk ; 1339const int ncols_interleaved = 16 ; 1340const int blocklen = 1 ; 1341 1342assert (n %qk == 0 ); 1343assert (nr %4 == 0 ); 1344assert (nc %ncols_interleaved == 0 ); 1345 1346UNUSED (s ); 1347UNUSED (bs ); 1348UNUSED (vx ); 1349UNUSED (vy ); 1350UNUSED (nr ); 1351UNUSED (nc ); 1352UNUSED (nb ); 1353UNUSED (ncols_interleaved ); 1354UNUSED (blocklen ); 1355 1356for (int y = 0 ;y < nr /4 ;y ++ ) { 1357const block_q8_0x4 * a_ptr = (const block_q8_0x4 * )vy + (y * nb ); 1358for (int x = 0 ;x < nc /ncols_interleaved ;x ++ ) { 1359const block_q8_0x16 * b_ptr = (const block_q8_0x16 * )vx + (x * nb ); 1360 1361// 4x16 Accumulators 1362vfloat32m2_t sumf_0 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1363vfloat32m2_t sumf_1 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1364vfloat32m2_t sumf_2 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1365vfloat32m2_t sumf_3 = __riscv_vfmv_v_f_f32m2 (0.0f ,16 ); 1366 1367for (int l = 0 ;l < nb ;l ++ ) { 1368// 4x16 Integer Accumulators 1369vint32m2_t sumi_0 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1370vint32m2_t sumi_1 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1371vint32m2_t sumi_2 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1372vint32m2_t sumi_3 = __riscv_vmv_v_x_i32m2 (0.0f ,16 ); 1373 1374// Accumulation loop. 1375for (int i = 0 ;i < QK8_0 ;i ++ ) { 1376// Load `b_ptr`. 1377const vint8mf2_t b_0 = __riscv_vle8_v_i8mf2 ((const int8_t * )& b_ptr [l ].qs [i * 16 ],16 ); 1378// const vint16m1_t b_0_16 = __riscv_vwcvt_x_x_v_i16m1(b_0, 16); 1379 1380sumi_0 = __riscv_vwadd_wv_i32m2 (sumi_0 ,__riscv_vwmul_vx_i16m1 (b_0 ,a_ptr [l ].qs [i * 4 + 0 ],16 ),16 ); 1381sumi_1 = __riscv_vwadd_wv_i32m2 (sumi_1 ,__riscv_vwmul_vx_i16m1 (b_0 ,a_ptr [l ].qs [i * 4 + 1 ],16 ),16 ); 1382sumi_2 = __riscv_vwadd_wv_i32m2 (sumi_2 ,__riscv_vwmul_vx_i16m1 (b_0 ,a_ptr [l ].qs [i * 4 + 2 ],16 ),16 ); 1383sumi_3 = __riscv_vwadd_wv_i32m2 (sumi_3 ,__riscv_vwmul_vx_i16m1 (b_0 ,a_ptr [l ].qs [i * 4 + 3 ],16 ),16 ); 1384 } 1385 1386const vfloat16m1_t b_d = __riscv_vle16_v_f16m1 ((const _Float16 * )b_ptr [l ].d ,16 ); 1387const vfloat32m2_t d_0 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [0 ],16 ); 1388const vfloat32m2_t d_1 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [1 ],16 ); 1389const vfloat32m2_t d_2 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [2 ],16 ); 1390const vfloat32m2_t d_3 = __riscv_vfwmul_vf_f32m2 (b_d ,* (const _Float16 * )& a_ptr [l ].d [3 ],16 ); 1391 1392sumf_0 = __riscv_vfmacc_vv_f32m2 (sumf_0 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_0 ,16 ),d_0 ,16 ); 1393sumf_1 = __riscv_vfmacc_vv_f32m2 (sumf_1 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_1 ,16 ),d_1 ,16 ); 1394sumf_2 = __riscv_vfmacc_vv_f32m2 (sumf_2 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_2 ,16 ),d_2 ,16 ); 1395sumf_3 = __riscv_vfmacc_vv_f32m2 (sumf_3 ,__riscv_vfcvt_f_x_v_f32m2 (sumi_3 ,16 ),d_3 ,16 ); 1396 } 1397 1398__riscv_vse32_v_f32m2 (s + (y * 4 + 0 )* bs + x * 16 ,sumf_0 ,16 ); 1399__riscv_vse32_v_f32m2 (s + (y * 4 + 1 )* bs + x * 16 ,sumf_1 ,16 ); 1400__riscv_vse32_v_f32m2 (s + (y * 4 + 2 )* bs + x * 16 ,sumf_2 ,16 ); 1401__riscv_vse32_v_f32m2 (s + (y * 4 + 3 )* bs + x * 16 ,sumf_3 ,16 ); 1402 } 1403 } 1404} 1405 1406void ggml_gemm_q2_K_16x1_q8_K (int n ,float * GGML_RESTRICT s ,size_t bs ,const void * GGML_RESTRICT vx ,const void * GGML_RESTRICT vy ,int nr ,int nc ) { 1407assert (n %QK_K == 0 ); 1408const int num_k_blocks = n /QK_K ; 1409const int N_ROWS_TILE = 4 ; 1410const int N_COLS_TILE = 16 ; 1411assert (nr %N_ROWS_TILE == 0 ); 1412assert (nc %N_COLS_TILE == 0 ); 1413 1414const size_t vl = __riscv_vsetvl_e32m2 (N_COLS_TILE ); 1415// --- Tiling Loops --- 1416#pragma GCC unroll 1 1417for (int row_tile = 0 ;row_tile < nr ;row_tile += N_ROWS_TILE ) { 1418#pragma GCC unroll 1 1419for (int col_tile = 0 ;col_tile < nc ;col_tile += N_COLS_TILE ) { 1420// Base Pointers 1421const block_q8_Kx4 * lhs_base_ptr = (const block_q8_Kx4 * )vy + (row_tile /N_ROWS_TILE )* num_k_blocks ; 1422const block_q2_Kx16 * rhs_base_ptr = (const block_q2_Kx16 * )vx + (col_tile /N_COLS_TILE )* num_k_blocks ; 1423 1424// Persistent Float Accumulators 1425vfloat32m2_t v_sumf_0 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 1426vfloat32m2_t v_sumf_1 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 1427vfloat32m2_t v_sumf_2 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 1428vfloat32m2_t v_sumf_3 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 1429 1430// --- Super-Block Loop (K=0..255) --- 1431#pragma GCC unroll 1 1432for (int k_block = 0 ;k_block < num_k_blocks ;++ k_block ) { 1433const block_q8_Kx4 * lhs_current = & lhs_base_ptr [k_block ]; 1434const block_q2_Kx16 * rhs_current = & rhs_base_ptr [k_block ]; 1435 1436// 1. Load Global Min Scales (Keep as F16/LMUL=1 to save registers) 1437vfloat16m1_t v_g_min_f16 = __riscv_vle16_v_f16m1 ((const _Float16 * )rhs_current -> dmin ,vl ); 1438vfloat32m2_t v_g_min_base = __riscv_vfwcvt_f_f_v_f32m2 (v_g_min_f16 ,vl ); 1439 1440// 2. Initialize Integer Accumulators 1441vint32m2_t v_isum_0 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1442vint32m2_t v_isum_1 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1443vint32m2_t v_isum_2 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1444vint32m2_t v_isum_3 = __riscv_vmv_v_x_i32m2 (0 ,vl ); 1445 1446const uint8_t * rhs_qs_ptr = rhs_current -> qs ; 1447const uint8_t * rhs_sc_ptr = rhs_current -> scales ; 1448const int8_t * lhs_qs_ptr = lhs_current -> qs ; 1449 1450// --- Phase Loop (4 phases x 64 elements) --- 1451#pragma GCC unroll 1 1452for (int phase = 0 ;phase < 4 ;++ phase ) { 1453 1454// A. Load Scales/Mins for the 4 interleaved sub-blocks 1455vuint16m1_t v_d_sb_0 ,v_d_sb_1 ,v_d_sb_2 ,v_d_sb_3 ; 1456vuint16m1_t v_m_sb_0 ,v_m_sb_1 ,v_m_sb_2 ,v_m_sb_3 ; 1457 1458// Unrolled Load Logic 1459 { 1460vuint8mf2_t v_raw ; 1461// Sub-block 0 1462v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 0 ,vl ); 1463v_d_sb_0 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 1464v_m_sb_0 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 1465 1466// Sub-block 1 1467v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 16 ,vl ); 1468v_d_sb_1 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 1469v_m_sb_1 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 1470 1471// Sub-block 2 1472v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 32 ,vl ); 1473v_d_sb_2 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 1474v_m_sb_2 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 1475 1476// Sub-block 3 1477v_raw = __riscv_vle8_v_u8mf2 (rhs_sc_ptr + 48 ,vl ); 1478v_d_sb_3 = __riscv_vzext_vf2_u16m1 (__riscv_vand_vx_u8mf2 (v_raw ,0xF ,vl ),vl ); 1479v_m_sb_3 = __riscv_vzext_vf2_u16m1 (__riscv_vsrl_vx_u8mf2 (v_raw ,4 ,vl ),vl ); 1480 1481rhs_sc_ptr += 64 ; 1482 } 1483 1484int base_k_phase = (phase < 2 ) ? (phase * 16 ) : (128 + (phase - 2 )* 16 ); 1485int k_offsets [4 ]= {0 ,32 ,64 ,96 }; 1486 1487// B. Inner Dot Product Loop 1488#pragma GCC unroll 1 1489for (int l = 0 ;l < 16 ;++ l ) { 1490vuint8mf2_t v_rhs_data = __riscv_vle8_v_u8mf2 (rhs_qs_ptr ,vl ); 1491rhs_qs_ptr += 16 ; 1492 1493// Unroll over 4 sub-blocks (0, 1, 2, 3 relative to phase) 1494 1495// --- Sub-block 0 --- 1496 { 1497vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (v_rhs_data ,3 ,vl ); 1498vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 1499__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 1500__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_0 ),vl ); 1501 1502const int8_t * q8 = & lhs_qs_ptr [(base_k_phase + k_offsets [0 ]+ l )* 4 ]; 1503v_isum_0 = __riscv_vwmacc_vx_i32m2 (v_isum_0 , (int16_t )q8 [0 ],v_w ,vl ); 1504v_isum_1 = __riscv_vwmacc_vx_i32m2 (v_isum_1 , (int16_t )q8 [1 ],v_w ,vl ); 1505v_isum_2 = __riscv_vwmacc_vx_i32m2 (v_isum_2 , (int16_t )q8 [2 ],v_w ,vl ); 1506v_isum_3 = __riscv_vwmacc_vx_i32m2 (v_isum_3 , (int16_t )q8 [3 ],v_w ,vl ); 1507 } 1508// --- Sub-block 1 --- 1509 { 1510vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,2 ,vl ),3 ,vl ); 1511vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 1512__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 1513__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_1 ),vl ); 1514 1515const int8_t * q8 = & lhs_qs_ptr [(base_k_phase + k_offsets [1 ]+ l )* 4 ]; 1516v_isum_0 = __riscv_vwmacc_vx_i32m2 (v_isum_0 , (int16_t )q8 [0 ],v_w ,vl ); 1517v_isum_1 = __riscv_vwmacc_vx_i32m2 (v_isum_1 , (int16_t )q8 [1 ],v_w ,vl ); 1518v_isum_2 = __riscv_vwmacc_vx_i32m2 (v_isum_2 , (int16_t )q8 [2 ],v_w ,vl ); 1519v_isum_3 = __riscv_vwmacc_vx_i32m2 (v_isum_3 , (int16_t )q8 [3 ],v_w ,vl ); 1520 } 1521// --- Sub-block 2 --- 1522 { 1523vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,4 ,vl ),3 ,vl ); 1524vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 1525__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 1526__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_2 ),vl ); 1527 1528const int8_t * q8 = & lhs_qs_ptr [(base_k_phase + k_offsets [2 ]+ l )* 4 ]; 1529v_isum_0 = __riscv_vwmacc_vx_i32m2 (v_isum_0 , (int16_t )q8 [0 ],v_w ,vl ); 1530v_isum_1 = __riscv_vwmacc_vx_i32m2 (v_isum_1 , (int16_t )q8 [1 ],v_w ,vl ); 1531v_isum_2 = __riscv_vwmacc_vx_i32m2 (v_isum_2 , (int16_t )q8 [2 ],v_w ,vl ); 1532v_isum_3 = __riscv_vwmacc_vx_i32m2 (v_isum_3 , (int16_t )q8 [3 ],v_w ,vl ); 1533 } 1534// --- Sub-block 3 --- 1535 { 1536vuint8mf2_t v_q2 = __riscv_vand_vx_u8mf2 (__riscv_vsrl_vx_u8mf2 (v_rhs_data ,6 ,vl ),3 ,vl ); 1537vint16m1_t v_w = __riscv_vmul_vv_i16m1 ( 1538__riscv_vreinterpret_v_u16m1_i16m1 (__riscv_vzext_vf2_u16m1 (v_q2 ,vl )), 1539__riscv_vreinterpret_v_u16m1_i16m1 (v_d_sb_3 ),vl ); 1540 1541const int8_t * q8 = & lhs_qs_ptr [(base_k_phase + k_offsets [3 ]+ l )* 4 ]; 1542v_isum_0 = __riscv_vwmacc_vx_i32m2 (v_isum_0 , (int16_t )q8 [0 ],v_w ,vl ); 1543v_isum_1 = __riscv_vwmacc_vx_i32m2 (v_isum_1 , (int16_t )q8 [1 ],v_w ,vl ); 1544v_isum_2 = __riscv_vwmacc_vx_i32m2 (v_isum_2 , (int16_t )q8 [2 ],v_w ,vl ); 1545v_isum_3 = __riscv_vwmacc_vx_i32m2 (v_isum_3 , (int16_t )q8 [3 ],v_w ,vl ); 1546 } 1547 } 1548 1549// C CORRECTION 1550int sb_base_abs = base_k_phase /16 ; 1551 1552// --- Correction Sub-block 0 --- 1553 { 1554int sb_abs = sb_base_abs + (k_offsets [0 ] /16 ); 1555vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_0 ); 1556 1557// Row 0 1558vfloat32m2_t v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [0 ],vl ); 1559vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 0 ],vl ); 1560vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1561v_sumf_0 = __riscv_vfsub_vv_f32m2 (v_sumf_0 ,vf_c ,vl ); 1562 1563// Row 1 1564v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [1 ],vl ); 1565v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 1 ],vl ); 1566vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1567v_sumf_1 = __riscv_vfsub_vv_f32m2 (v_sumf_1 ,vf_c ,vl ); 1568 1569// Row 2 1570v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [2 ],vl ); 1571v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 2 ],vl ); 1572vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1573v_sumf_2 = __riscv_vfsub_vv_f32m2 (v_sumf_2 ,vf_c ,vl ); 1574 1575// Row 3 1576v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [3 ],vl ); 1577v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 3 ],vl ); 1578vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1579v_sumf_3 = __riscv_vfsub_vv_f32m2 (v_sumf_3 ,vf_c ,vl ); 1580 } 1581 1582// --- Correction Sub-block 1 --- 1583 { 1584int sb_abs = sb_base_abs + (k_offsets [1 ] /16 ); 1585vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_1 ); 1586 1587vfloat32m2_t v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [0 ],vl ); 1588vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 0 ],vl ); 1589vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1590v_sumf_0 = __riscv_vfsub_vv_f32m2 (v_sumf_0 ,vf_c ,vl ); 1591 1592v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [1 ],vl ); 1593v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 1 ],vl ); 1594vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1595v_sumf_1 = __riscv_vfsub_vv_f32m2 (v_sumf_1 ,vf_c ,vl ); 1596 1597v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [2 ],vl ); 1598v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 2 ],vl ); 1599vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1600v_sumf_2 = __riscv_vfsub_vv_f32m2 (v_sumf_2 ,vf_c ,vl ); 1601 1602v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [3 ],vl ); 1603v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 3 ],vl ); 1604vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1605v_sumf_3 = __riscv_vfsub_vv_f32m2 (v_sumf_3 ,vf_c ,vl ); 1606 } 1607 1608// --- Correction Sub-block 2 --- 1609 { 1610int sb_abs = sb_base_abs + (k_offsets [2 ] /16 ); 1611vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_2 ); 1612 1613vfloat32m2_t v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [0 ],vl ); 1614vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 0 ],vl ); 1615vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1616v_sumf_0 = __riscv_vfsub_vv_f32m2 (v_sumf_0 ,vf_c ,vl ); 1617 1618v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [1 ],vl ); 1619v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 1 ],vl ); 1620vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1621v_sumf_1 = __riscv_vfsub_vv_f32m2 (v_sumf_1 ,vf_c ,vl ); 1622 1623v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [2 ],vl ); 1624v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 2 ],vl ); 1625vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1626v_sumf_2 = __riscv_vfsub_vv_f32m2 (v_sumf_2 ,vf_c ,vl ); 1627 1628v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [3 ],vl ); 1629v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 3 ],vl ); 1630vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1631v_sumf_3 = __riscv_vfsub_vv_f32m2 (v_sumf_3 ,vf_c ,vl ); 1632 } 1633 1634// --- Correction Sub-block 3 --- 1635 { 1636int sb_abs = sb_base_abs + (k_offsets [3 ] /16 ); 1637vint16m1_t v_min = __riscv_vreinterpret_v_u16m1_i16m1 (v_m_sb_3 ); 1638 1639vfloat32m2_t v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [0 ],vl ); 1640vint32m2_t v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 0 ],vl ); 1641vfloat32m2_t vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1642v_sumf_0 = __riscv_vfsub_vv_f32m2 (v_sumf_0 ,vf_c ,vl ); 1643 1644v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [1 ],vl ); 1645v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 1 ],vl ); 1646vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1647v_sumf_1 = __riscv_vfsub_vv_f32m2 (v_sumf_1 ,vf_c ,vl ); 1648 1649v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [2 ],vl ); 1650v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 2 ],vl ); 1651vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1652v_sumf_2 = __riscv_vfsub_vv_f32m2 (v_sumf_2 ,vf_c ,vl ); 1653 1654v_g_min = __riscv_vfmul_vf_f32m2 (v_g_min_base ,lhs_current -> d [3 ],vl ); 1655v_c = __riscv_vwmul_vx_i32m2 (v_min ,lhs_current -> bsums [sb_abs * 4 + 3 ],vl ); 1656vf_c = __riscv_vfmul_vv_f32m2 (__riscv_vfcvt_f_x_v_f32m2 (v_c ,vl ),v_g_min ,vl ); 1657v_sumf_3 = __riscv_vfsub_vv_f32m2 (v_sumf_3 ,vf_c ,vl ); 1658 } 1659 1660 }// End Phase Loop 1661 1662// --- Apply Main Scales --- 1663vfloat16m1_t v_g_all_f16 = __riscv_vle16_v_f16m1 ((const _Float16 * )rhs_current -> d ,vl ); 1664vfloat32m2_t v_g_all_base = __riscv_vfwcvt_f_f_v_f32m2 (v_g_all_f16 ,vl ); 1665 1666 { 1667vfloat32m2_t v_g_all = __riscv_vfmul_vf_f32m2 (v_g_all_base ,lhs_current -> d [0 ],vl ); 1668vfloat32m2_t v_sum = __riscv_vfcvt_f_x_v_f32m2 (v_isum_0 ,vl ); 1669v_sum = __riscv_vfmul_vv_f32m2 (v_sum ,v_g_all ,vl ); 1670v_sumf_0 = __riscv_vfadd_vv_f32m2 (v_sumf_0 ,v_sum ,vl ); 1671 } 1672// Row 1 1673 { 1674vfloat32m2_t v_g_all = __riscv_vfmul_vf_f32m2 (v_g_all_base ,lhs_current -> d [1 ],vl ); 1675vfloat32m2_t v_sum = __riscv_vfcvt_f_x_v_f32m2 (v_isum_1 ,vl ); 1676v_sum = __riscv_vfmul_vv_f32m2 (v_sum ,v_g_all ,vl ); 1677v_sumf_1 = __riscv_vfadd_vv_f32m2 (v_sumf_1 ,v_sum ,vl ); 1678 } 1679// Row 2 1680 { 1681vfloat32m2_t v_g_all = __riscv_vfmul_vf_f32m2 (v_g_all_base ,lhs_current -> d [2 ],vl ); 1682vfloat32m2_t v_sum = __riscv_vfcvt_f_x_v_f32m2 (v_isum_2 ,vl ); 1683v_sum = __riscv_vfmul_vv_f32m2 (v_sum ,v_g_all ,vl ); 1684v_sumf_2 = __riscv_vfadd_vv_f32m2 (v_sumf_2 ,v_sum ,vl ); 1685 } 1686// Row 3 1687 { 1688vfloat32m2_t v_g_all = __riscv_vfmul_vf_f32m2 (v_g_all_base ,lhs_current -> d [3 ],vl ); 1689vfloat32m2_t v_sum = __riscv_vfcvt_f_x_v_f32m2 (v_isum_3 ,vl ); 1690v_sum = __riscv_vfmul_vv_f32m2 (v_sum ,v_g_all ,vl ); 1691v_sumf_3 = __riscv_vfadd_vv_f32m2 (v_sumf_3 ,v_sum ,vl ); 1692 } 1693 1694 }// End K-Block 1695 1696__riscv_vse32_v_f32m2 (s + (row_tile + 0 )* bs + col_tile ,v_sumf_0 ,vl ); 1697__riscv_vse32_v_f32m2 (s + (row_tile + 1 )* bs + col_tile ,v_sumf_1 ,vl ); 1698__riscv_vse32_v_f32m2 (s + (row_tile + 2 )* bs + col_tile ,v_sumf_2 ,vl ); 1699__riscv_vse32_v_f32m2 (s + (row_tile + 3 )* bs + col_tile ,v_sumf_3 ,vl ); 1700 } 1701 } 1702} 1703#endif