char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
81b0d882a
char/aliceai-t5-moe
1#include "rvv_kernels.h" 2 3#include "common.h" 4#include "ggml.h" 5#include "ops.h" 6#include "string.h" 7 8#include <algorithm> 9#include <cmath> 10#include <cstdint> 11#include <stdexcept> 12 13#if !defined(__riscv_v )|| !defined(__riscv_v_intrinsic ) 14# error "riscv v extension or v_intrinsic not enabled" 15#else 16# include <riscv_vector.h> 17#endif 18 19#if !defined(__riscv_zfh ) 20# error "riscv zfh extension not enabled" 21#endif 22 23#if defined(__GNUC__ ) 24# pragma GCC diagnostic ignored "-Woverlength-strings" 25# pragma GCC diagnostic ignored "-Wcast-qual" 26# pragma GCC diagnostic ignored "-Wunused-parameter" 27#endif 28 29namespace spacemit_kernels::rvv { 30 31namespace { 32 33auto align_up (size_t value ,size_t alignment ) { 34return (value + alignment - 1 ) /alignment * alignment ; 35} 36 37static inline bool flash_attn_ext_supported_d_vlen1024_vf16 (int64_t d ) { 38return d > 0 && d <=128 ; 39} 40 41static inline bool flash_attn_ext_supported_shape_vlen1024_vf16 (int64_t DK ,int64_t DV ) { 42return flash_attn_ext_supported_d_vlen1024_vf16 (DK )&& flash_attn_ext_supported_d_vlen1024_vf16 (DV ); 43} 44 45static inline float reduce_sum_f32m4_vlen1024 (vfloat32m4_t v ,size_t vl ) { 46vfloat32m1_t s_v = __riscv_vfmv_v_f_f32m1 (0.0f ,1 ); 47s_v = __riscv_vfredusum_vs_f32m4_f32m1 (v ,s_v ,vl ); 48return __riscv_vfmv_f_s_f32m1_f32 (s_v ); 49} 50 51static inline float reduce_sum_f32m2_vlen1024 (vfloat32m2_t v ,size_t vl ) { 52vfloat32m1_t s_v = __riscv_vfmv_v_f_f32m1 (0.0f ,1 ); 53s_v = __riscv_vfredusum_vs_f32m2_f32m1 (v ,s_v ,vl ); 54return __riscv_vfmv_f_s_f32m1_f32 (s_v ); 55} 56 57// Adapted from ggml_v_expf_m2 in vec.h. This is accurate enough for softmax. 58static inline vfloat32m2_t rvv_expf_approx_f32m2 (vfloat32m2_t x ,size_t vl ) { 59const vfloat32m2_t r = __riscv_vfmv_v_f_f32m2 (0x1.8p23f ,vl ); 60const vfloat32m2_t z = __riscv_vfmacc_vf_f32m2 (r ,0x1.715476p+0f ,x ,vl ); 61const vfloat32m2_t n = __riscv_vfsub_vv_f32m2 (z ,r ,vl ); 62const vfloat32m2_t b = 63__riscv_vfnmsac_vf_f32m2 (__riscv_vfnmsac_vf_f32m2 (x ,0x1.62e4p-1f ,n ,vl ),0x1.7f7d1cp-20f ,n ,vl ); 64const vuint32m2_t e = __riscv_vsll_vx_u32m2 (__riscv_vreinterpret_v_f32m2_u32m2 (z ),23 ,vl ); 65const vfloat32m2_t k = __riscv_vreinterpret_v_u32m2_f32m2 (__riscv_vadd_vx_u32m2 (e ,0x3f800000 ,vl )); 66const vbool16_t c = __riscv_vmfgt_vf_f32m2_b16 (__riscv_vfabs_v_f32m2 (n ,vl ),126.0f ,vl ); 67const vfloat32m2_t u = __riscv_vfmul_vv_f32m2 (b ,b ,vl ); 68const vfloat32m2_t j = __riscv_vfmacc_vv_f32m2 ( 69__riscv_vfmul_vf_f32m2 (b ,0x1.ffffecp-1f ,vl ), 70__riscv_vfmacc_vv_f32m2 ( 71__riscv_vfmacc_vf_f32m2 (__riscv_vfmv_v_f_f32m2 (0x1.fffdb6p-2f ,vl ),0x1.555e66p-3f ,b ,vl ), 72__riscv_vfmacc_vf_f32m2 (__riscv_vfmv_v_f_f32m2 (0x1.573e2ep-5f ,vl ),0x1.0e4020p-7f ,b ,vl ),u ,vl ), 73u ,vl ); 74 75if (!__riscv_vcpop_m_b16 (c ,vl )) { 76return __riscv_vfmacc_vv_f32m2 (k ,j ,k ,vl ); 77 } 78 79const vbool16_t dm = __riscv_vmfle_vf_f32m2_b16 (n ,0.0f ,vl ); 80const vuint32m2_t d = __riscv_vmerge_vxm_u32m2 (__riscv_vmv_v_x_u32m2 (0 ,vl ),0x82000000 ,dm ,vl ); 81const vfloat32m2_t s1 = __riscv_vreinterpret_v_u32m2_f32m2 (__riscv_vadd_vx_u32m2 (d ,0x7f000000 ,vl )); 82const vfloat32m2_t s2 = __riscv_vreinterpret_v_u32m2_f32m2 (__riscv_vsub_vv_u32m2 (e ,d ,vl )); 83const vfloat32m2_t r1 = 84__riscv_vmerge_vvm_f32m2 (__riscv_vfmacc_vv_f32m2 (k ,k ,j ,vl ), 85__riscv_vfmul_vv_f32m2 (__riscv_vfmacc_vv_f32m2 (s2 ,s2 ,j ,vl ),s1 ,vl ),c ,vl ); 86return __riscv_vmerge_vvm_f32m2 (r1 ,__riscv_vfmul_vv_f32m2 (s1 ,s1 ,vl ), 87__riscv_vmfgt_vf_f32m2_b16 (__riscv_vfabs_v_f32m2 (n ,vl ),192.0f ,vl ),vl ); 88} 89 90static inline vfloat32m2_t rvv_tanh_approx_f32m2 (vfloat32m2_t x ,size_t vl ) { 91const vfloat32m2_t abs_x = __riscv_vfabs_v_f32m2 (x ,vl ); 92const vfloat32m2_t neg_2_abs = __riscv_vfmul_vf_f32m2 (abs_x ,-2.0f ,vl ); 93const vfloat32m2_t exp_term = rvv_expf_approx_f32m2 (neg_2_abs ,vl ); 94const vfloat32m2_t numerator = __riscv_vfsub_vf_f32m2 (exp_term ,1.0f ,vl ); 95const vfloat32m2_t denominator = __riscv_vfadd_vf_f32m2 (exp_term ,1.0f ,vl ); 96const vfloat32m2_t tanh_abs = __riscv_vfneg_v_f32m2 (__riscv_vfdiv_vv_f32m2 (numerator ,denominator ,vl ),vl ); 97const vbool16_t neg_mask = __riscv_vmflt_vf_f32m2_b16 (x ,0.0f ,vl ); 98const vfloat32m2_t tanh_neg = __riscv_vfneg_v_f32m2 (tanh_abs ,vl ); 99return __riscv_vmerge_vvm_f32m2 (tanh_abs ,tanh_neg ,neg_mask ,vl ); 100} 101 102static void rvv_softcap_tanh_inplace_f32 (float * dst ,int64_t dst_stride ,int64_t tile_rows ,int64_t n ,float softcap ) { 103for (int tq = 0 ;tq < tile_rows ;++ tq ,dst += dst_stride ) { 104float * dst_row = dst ; 105int64_t remaining = n ; 106while (remaining > 0 ) { 107const size_t vl = __riscv_vsetvl_e32m2 (remaining ); 108vfloat32m2_t v = __riscv_vle32_v_f32m2 (dst_row ,vl ); 109v = rvv_tanh_approx_f32m2 (v ,vl ); 110v = __riscv_vfmul_vf_f32m2 (v ,softcap ,vl ); 111__riscv_vse32_v_f32m2 (dst_row ,v ,vl ); 112dst_row += vl ; 113remaining -= vl ; 114 } 115 } 116} 117 118static inline float rvv_softmax_exp_inplace_f32 (float * dst ,int64_t n ,float max_value ) { 119float row_sum = 0.0f ; 120while (n > 0 ) { 121const size_t vl = __riscv_vsetvl_e32m2 (n ); 122vfloat32m2_t v = __riscv_vle32_v_f32m2 (dst ,vl ); 123v = __riscv_vfsub_vf_f32m2 (v ,max_value ,vl ); 124v = rvv_expf_approx_f32m2 (v ,vl ); 125__riscv_vse32_v_f32m2 (dst ,v ,vl ); 126row_sum += reduce_sum_f32m2_vlen1024 (v ,vl ); 127dst += vl ; 128n -= vl ; 129 } 130return row_sum ; 131} 132 133static inline float rvv_add_max_inplace_f32 (float * dst ,const float * src ,int64_t n ) { 134float max_val = - INFINITY ; 135while (n > 0 ) { 136const size_t vl = __riscv_vsetvl_e32m4 (n ); 137vfloat32m4_t vdst = __riscv_vle32_v_f32m4 (dst ,vl ); 138vfloat32m4_t vsrc = __riscv_vle32_v_f32m4 (src ,vl ); 139vdst = __riscv_vfadd_vv_f32m4 (vdst ,vsrc ,vl ); 140__riscv_vse32_v_f32m4 (dst ,vdst ,vl ); 141 142vfloat32m1_t seed = __riscv_vfmv_v_f_f32m1 (max_val ,1 ); 143seed = __riscv_vfredmax_vs_f32m4_f32m1 (vdst ,seed ,vl ); 144max_val = __riscv_vfmv_f_s_f32m1_f32 (seed ); 145 146dst += vl ; 147src += vl ; 148n -= vl ; 149 } 150return max_val ; 151} 152 153static inline float rvv_softcap_add_max_inplace_f32 (float * dst ,const float * src ,int64_t n ,float softcap ) { 154if (softcap == 0.0f ) { 155return rvv_add_max_inplace_f32 (dst ,src ,n ); 156 } 157 158float max_val = - INFINITY ; 159while (n > 0 ) { 160const size_t vl = __riscv_vsetvl_e32m2 (n ); 161vfloat32m2_t vdst = __riscv_vle32_v_f32m2 (dst ,vl ); 162vfloat32m2_t vsrc = __riscv_vle32_v_f32m2 (src ,vl ); 163vdst = rvv_tanh_approx_f32m2 (vdst ,vl ); 164vdst = __riscv_vfmul_vf_f32m2 (vdst ,softcap ,vl ); 165vdst = __riscv_vfadd_vv_f32m2 (vdst ,vsrc ,vl ); 166__riscv_vse32_v_f32m2 (dst ,vdst ,vl ); 167 168vfloat32m1_t seed = __riscv_vfmv_v_f_f32m1 (max_val ,1 ); 169seed = __riscv_vfredmax_vs_f32m2_f32m1 (vdst ,seed ,vl ); 170max_val = __riscv_vfmv_f_s_f32m1_f32 (seed ); 171 172dst += vl ; 173src += vl ; 174n -= vl ; 175 } 176return max_val ; 177} 178 179static inline void rvv_zero_f32 (float * dst ,int64_t n ) { 180while (n > 0 ) { 181const size_t vl = __riscv_vsetvl_e32m4 (n ); 182const vfloat32m4_t z = __riscv_vfmv_v_f_f32m4 (0.0f ,vl ); 183__riscv_vse32_v_f32m4 (dst ,z ,vl ); 184dst += vl ; 185n -= vl ; 186 } 187} 188 189static inline void rvv_scale_f32 (float * dst ,float scale ,int64_t n ) { 190while (n > 0 ) { 191const size_t vl = __riscv_vsetvl_e32m4 (n ); 192vfloat32m4_t v = __riscv_vle32_v_f32m4 (dst ,vl ); 193v = __riscv_vfmul_vf_f32m4 (v ,scale ,vl ); 194__riscv_vse32_v_f32m4 (dst ,v ,vl ); 195dst += vl ; 196n -= vl ; 197 } 198} 199 200static inline void rvv_add_inplace_f32 (float * dst , 201int64_t dst_stride , 202const float * src , 203int64_t src_stride , 204int64_t tile_rows , 205int64_t n ) { 206for (int tq = 0 ;tq < tile_rows ;++ tq ,dst += dst_stride ,src += src_stride ) { 207int64_t remaining = n ; 208float * dst_row = dst ; 209const float * src_row = src ; 210while (remaining > 0 ) { 211const size_t vl = __riscv_vsetvl_e32m4 (remaining ); 212vfloat32m4_t vdst = __riscv_vle32_v_f32m4 (dst_row ,vl ); 213vfloat32m4_t vsrc = __riscv_vle32_v_f32m4 (src_row ,vl ); 214vdst = __riscv_vfadd_vv_f32m4 (vdst ,vsrc ,vl ); 215__riscv_vse32_v_f32m4 (dst_row ,vdst ,vl ); 216dst_row += vl ; 217src_row += vl ; 218remaining -= vl ; 219 } 220 } 221} 222 223static inline float rvv_max_f32 (const float * src ,int64_t n ) { 224float max_val = - INFINITY ; 225while (n > 0 ) { 226const size_t vl = __riscv_vsetvl_e32m4 (n ); 227const vfloat32m4_t v = __riscv_vle32_v_f32m4 (src ,vl ); 228vfloat32m1_t seed = __riscv_vfmv_v_f_f32m1 (max_val ,1 ); 229seed = __riscv_vfredmax_vs_f32m4_f32m1 (v ,seed ,vl ); 230max_val = __riscv_vfmv_f_s_f32m1_f32 (seed ); 231src += vl ; 232n -= vl ; 233 } 234return max_val ; 235} 236 237static void rvv_pack_f32_as_scaled_f16 (void * dst , 238int64_t dst_row_stride , 239const void * src , 240int64_t src_row_stride , 241int64_t tile_rows , 242int64_t n , 243float scale ) { 244for (int tq = 0 ;tq < tile_rows ;++ tq ) { 245const float * row_ptr = (const float * ) ((const char * )src + tq * src_row_stride ); 246_Float16 * dst_row_ptr = (_Float16 * ) ((char * )dst + tq * dst_row_stride ); 247int64_t remaining = n ; 248while (remaining > 0 ) { 249const size_t vl = __riscv_vsetvl_e32m4 (remaining ); 250vfloat32m4_t v32 = __riscv_vle32_v_f32m4 (row_ptr ,vl ); 251v32 = __riscv_vfmul_vf_f32m4 (v32 ,scale ,vl ); 252const vfloat16m2_t v16 = __riscv_vfncvt_f_f_w_f16m2 (v32 ,vl ); 253__riscv_vse16_v_f16m2 (dst_row_ptr ,v16 ,vl ); 254dst_row_ptr += vl ; 255row_ptr += vl ; 256remaining -= vl ; 257 } 258 } 259} 260 261static void rvv_pack_scaled_f16_as_f32 (void * dst , 262int64_t dst_row_stride , 263const void * src , 264int64_t src_row_stride , 265int64_t tile_rows , 266int64_t n , 267float scale ) { 268for (int tq = 0 ;tq < tile_rows ;++ tq ) { 269const _Float16 * row_ptr = (const _Float16 * ) ((const char * )src + tq * src_row_stride ); 270float * dst_row_ptr = (float * ) ((char * )dst + tq * dst_row_stride ); 271int64_t remaining = n ; 272while (remaining > 0 ) { 273const size_t vl = __riscv_vsetvl_e16m2 (remaining ); 274const vfloat16m2_t v16 = __riscv_vle16_v_f16m2 (row_ptr ,vl ); 275vfloat32m4_t v32 = __riscv_vfwcvt_f_f_v_f32m4 (v16 ,vl ); 276v32 = __riscv_vfmul_vf_f32m4 (v32 ,scale ,vl ); 277__riscv_vse32_v_f32m4 (dst_row_ptr ,v32 ,vl ); 278dst_row_ptr += vl ; 279row_ptr += vl ; 280remaining -= vl ; 281 } 282 } 283} 284 285static void rvv_pack_scaled_f32_as_f32 (void * dst , 286int64_t dst_row_stride , 287const void * src , 288int64_t src_row_stride , 289int64_t tile_rows , 290int64_t n , 291float * scale ) { 292for (int tq = 0 ;tq < tile_rows ;++ tq ) { 293const float * row_ptr = (const float * ) ((const char * )src + tq * src_row_stride ); 294float * dst_row_ptr = (float * ) ((char * )dst + tq * dst_row_stride ); 295int64_t remaining = n ; 296while (remaining > 0 ) { 297const size_t vl = __riscv_vsetvl_e32m4 (remaining ); 298vfloat32m4_t v32 = __riscv_vle32_v_f32m4 (row_ptr ,vl ); 299v32 = __riscv_vfmul_vf_f32m4 (v32 ,scale [tq ],vl ); 300__riscv_vse32_v_f32m4 (dst_row_ptr ,v32 ,vl ); 301dst_row_ptr += vl ; 302row_ptr += vl ; 303remaining -= vl ; 304 } 305 } 306} 307 308static inline void rvv_transposed_s32_mn_to_nm (int8_t * dst , 309int64_t n_dst_stride , 310int8_t * src , 311int64_t m_src_stride , 312int64_t m , 313int64_t n ) { 314int8_t * in = src ; 315int8_t * out = dst ; 316 317 __asm__volatile ( 318"vsetvli t0, zero, e32, m1, tu, mu \n\t" 319"mul t3, t0, %[os0] \n\t" 320"srli t2, %[isz0], 3 \n\t" 321"blez t2, M1%= \n\t" 322 323"LOOP_M8%=: \n\t" 324"addi a1, %[dst], 0 \n\t" 325"addi s1, %[src], 0 \n\t" 326"add s2, %[src], %[is0] \n\t" 327"add s3, s2, %[is0] \n\t" 328"add s4, s3, %[is0] \n\t" 329"add s5, s4, %[is0] \n\t" 330"add s6, s5, %[is0] \n\t" 331"add s7, s6, %[is0] \n\t" 332"add s8, s7, %[is0] \n\t" 333"addi t1, %[isz1], 0 \n\t" 334 335"LOOP_M8N%=: \n\t" 336"vsetvli t0, t1, e32, m1, tu, mu \n\t" 337"sub t1, t1, t0 \n\t" 338"vle32.v v0, (s1) \n\t" 339"sh2add s1, t0, s1 \n\t" 340"vle32.v v1, (s2) \n\t" 341"sh2add s2, t0, s2 \n\t" 342"vle32.v v2, (s3) \n\t" 343"sh2add s3, t0, s3 \n\t" 344"vle32.v v3, (s4) \n\t" 345"sh2add s4, t0, s4 \n\t" 346"vle32.v v4, (s5) \n\t" 347"sh2add s5, t0, s5 \n\t" 348"vle32.v v5, (s6) \n\t" 349"sh2add s6, t0, s6 \n\t" 350"vle32.v v6, (s7) \n\t" 351"sh2add s7, t0, s7 \n\t" 352"vle32.v v7, (s8) \n\t" 353"sh2add s8, t0, s8 \n\t" 354"vssseg8e32.v v0, (a1), %[os0] \n\t" 355"add a1, a1, t3 \n\t" 356"bnez t1, LOOP_M8N%= \n\t" 357"sh3add %[src], %[is0], %[src] \n\t" 358"addi %[dst], %[dst], 32 \n\t" 359"addi t2, t2, -1 \n\t" 360"bnez t2, LOOP_M8%= \n\t" 361 362"M1%=: \n\t" 363"andi t2, %[isz0], 7 \n\t" 364"blez t2, END%= \n\t" 365 366"LOOP_M1%=: \n\t" 367"addi a1, %[dst], 0 \n\t" 368"addi s1, %[src], 0 \n\t" 369"addi t1, %[isz1], 0 \n\t" 370 371"LOOP_M1N%=: \n\t" 372"vsetvli t0, t1, e32, m1, tu, mu \n\t" 373"sub t1, t1, t0 \n\t" 374"vle32.v v0, (s1) \n\t" 375"sh2add s1, t0, s1 \n\t" 376"vsse32.v v0, (a1), %[os0] \n\t" 377"add a1, a1, t3 \n\t" 378"bnez t1, LOOP_M1N%= \n\t" 379"add %[src], %[is0], %[src] \n\t" 380"addi %[dst], %[dst], 4 \n\t" 381"addi t2, t2, -1 \n\t" 382"bnez t2, LOOP_M1%= \n\t" 383"END%=: \n\t" 384 385 : [src ]"+r" (in ), [dst ]"+r" (out ), [isz0 ]"+r" (m ) 386 : [isz1 ]"r" (n ), [is0 ]"r" (m_src_stride ), [os0 ]"r" (n_dst_stride ) 387 :"cc" ,"t0" ,"t1" ,"t2" ,"t3" ,"s1" ,"s2" ,"s3" ,"s4" ,"s5" ,"s6" ,"s7" ,"s8" ,"a1" ); 388} 389 390static inline void rvv_transposed_s16_mn_to_nm (int8_t * dst , 391int64_t n_dst_stride , 392int8_t * src , 393int64_t m_src_stride , 394int64_t m , 395int64_t n ) { 396int8_t * in = src ; 397int8_t * out = dst ; 398 399 __asm__volatile ( 400"vsetvli t0, zero, e16, m1, tu, mu \n\t" 401"mul t3, t0, %[os0] \n\t" 402"srli t2, %[isz0], 3 \n\t" 403"blez t2, M1%= \n\t" 404 405"LOOP_M8%=: \n\t" 406"addi a1, %[dst], 0 \n\t" 407"addi s1, %[src], 0 \n\t" 408"add s2, %[src], %[is0] \n\t" 409"add s3, s2, %[is0] \n\t" 410"add s4, s3, %[is0] \n\t" 411"add s5, s4, %[is0] \n\t" 412"add s6, s5, %[is0] \n\t" 413"add s7, s6, %[is0] \n\t" 414"add s8, s7, %[is0] \n\t" 415"addi t1, %[isz1], 0 \n\t" 416 417"LOOP_M8N%=: \n\t" 418"vsetvli t0, t1, e16, m1, tu, mu \n\t" 419"sub t1, t1, t0 \n\t" 420"vle16.v v0, (s1) \n\t" 421"sh1add s1, t0, s1 \n\t" 422"vle16.v v1, (s2) \n\t" 423"sh1add s2, t0, s2 \n\t" 424"vle16.v v2, (s3) \n\t" 425"sh1add s3, t0, s3 \n\t" 426"vle16.v v3, (s4) \n\t" 427"sh1add s4, t0, s4 \n\t" 428"vle16.v v4, (s5) \n\t" 429"sh1add s5, t0, s5 \n\t" 430"vle16.v v5, (s6) \n\t" 431"sh1add s6, t0, s6 \n\t" 432"vle16.v v6, (s7) \n\t" 433"sh1add s7, t0, s7 \n\t" 434"vle16.v v7, (s8) \n\t" 435"sh1add s8, t0, s8 \n\t" 436"vssseg8e16.v v0, (a1), %[os0] \n\t" 437"add a1, a1, t3 \n\t" 438"bnez t1, LOOP_M8N%= \n\t" 439"sh3add %[src], %[is0], %[src] \n\t" 440"addi %[dst], %[dst], 16 \n\t" 441"addi t2, t2, -1 \n\t" 442"bnez t2, LOOP_M8%= \n\t" 443 444"M1%=: \n\t" 445"andi t2, %[isz0], 7 \n\t" 446"blez t2, END%= \n\t" 447 448"LOOP_M1%=: \n\t" 449"addi a1, %[dst], 0 \n\t" 450"addi s1, %[src], 0 \n\t" 451"addi t1, %[isz1], 0 \n\t" 452 453"LOOP_M1N%=: \n\t" 454"vsetvli t0, t1, e16, m1, tu, mu \n\t" 455"sub t1, t1, t0 \n\t" 456"vle16.v v0, (s1) \n\t" 457"sh1add s1, t0, s1 \n\t" 458"vsse16.v v0, (a1), %[os0] \n\t" 459"add a1, a1, t3 \n\t" 460"bnez t1, LOOP_M1N%= \n\t" 461"add %[src], %[is0], %[src] \n\t" 462"addi %[dst], %[dst], 2 \n\t" 463"addi t2, t2, -1 \n\t" 464"bnez t2, LOOP_M1%= \n\t" 465"END%=: \n\t" 466 467 : [src ]"+r" (in ), [dst ]"+r" (out ), [isz0 ]"+r" (m ) 468 : [isz1 ]"r" (n ), [is0 ]"r" (m_src_stride ), [os0 ]"r" (n_dst_stride ) 469 :"cc" ,"t0" ,"t1" ,"t2" ,"t3" ,"s1" ,"s2" ,"s3" ,"s4" ,"s5" ,"s6" ,"s7" ,"s8" ,"a1" ); 470} 471 472static inline void rvv_qk_dot_tile_f16_x1 (float * dst , 473const _Float16 * q_row , 474const _Float16 * k_pack , 475int64_t dk , 476int64_t kv_tile ) { 477const size_t vl = __riscv_vsetvl_e16m1 (kv_tile ); 478vfloat32m2_t acc = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 479 480for (int64_t d = 0 ;d < dk ;++ d ) { 481const vfloat16m1_t k_vec = __riscv_vle16_v_f16m1 (k_pack + d * ggml_fa_tile_config::KV ,vl ); 482acc = __riscv_vfwmacc_vf_f32m2 (acc ,q_row [d ],k_vec ,vl ); 483 } 484 485__riscv_vse32_v_f32m2 (dst ,acc ,vl ); 486} 487 488static inline void rvv_qk_dot_tile_f16_x4 (float * dst0 , 489float * dst1 , 490float * dst2 , 491float * dst3 , 492const _Float16 * q0 , 493const _Float16 * q1 , 494const _Float16 * q2 , 495const _Float16 * q3 , 496const _Float16 * k_pack , 497int64_t dk , 498int64_t kv_tile ) { 499const size_t vl = __riscv_vsetvl_e16m1 (kv_tile ); 500vfloat32m2_t acc0 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 501vfloat32m2_t acc1 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 502vfloat32m2_t acc2 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 503vfloat32m2_t acc3 = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 504 505for (int64_t d = 0 ;d < dk ;++ d ) { 506const vfloat16m1_t k_vec = __riscv_vle16_v_f16m1 (k_pack + d * ggml_fa_tile_config::KV ,vl ); 507acc0 = __riscv_vfwmacc_vf_f32m2 (acc0 ,q0 [d ],k_vec ,vl ); 508acc1 = __riscv_vfwmacc_vf_f32m2 (acc1 ,q1 [d ],k_vec ,vl ); 509acc2 = __riscv_vfwmacc_vf_f32m2 (acc2 ,q2 [d ],k_vec ,vl ); 510acc3 = __riscv_vfwmacc_vf_f32m2 (acc3 ,q3 [d ],k_vec ,vl ); 511 } 512 513__riscv_vse32_v_f32m2 (dst0 ,acc0 ,vl ); 514__riscv_vse32_v_f32m2 (dst1 ,acc1 ,vl ); 515__riscv_vse32_v_f32m2 (dst2 ,acc2 ,vl ); 516__riscv_vse32_v_f32m2 (dst3 ,acc3 ,vl ); 517} 518 519static inline void rvv_pv_accumulate_f16_x1 (float * dst , 520const float * prob , 521const _Float16 * v_pack , 522int64_t kv_tile , 523int64_t dv ) { 524int64_t d_left = dv ; 525int64_t d_off = 0 ; 526 527while (d_left > 0 ) { 528const size_t vl = __riscv_vsetvl_e16m2 (d_left ); 529vfloat32m4_t acc = __riscv_vle32_v_f32m4 (dst + d_off ,vl ); 530 531for (int64_t tk = 0 ;tk < kv_tile ;++ tk ) { 532const vfloat16m2_t v16 = __riscv_vle16_v_f16m2 (v_pack + tk * dv + d_off ,vl ); 533const vfloat32m4_t v32 = __riscv_vfwcvt_f_f_v_f32m4 (v16 ,vl ); 534acc = __riscv_vfmacc_vf_f32m4 (acc ,prob [tk ],v32 ,vl ); 535 } 536 537__riscv_vse32_v_f32m4 (dst + d_off ,acc ,vl ); 538d_left -= vl ; 539d_off += vl ; 540 } 541} 542 543static inline void rvv_pv_accumulate_f16_x4 (float * dst0 , 544float * dst1 , 545float * dst2 , 546float * dst3 , 547const float * prob0 , 548const float * prob1 , 549const float * prob2 , 550const float * prob3 , 551const _Float16 * v_pack , 552int64_t kv_tile , 553int64_t dv ) { 554int64_t d_left = dv ; 555int64_t d_off = 0 ; 556 557while (d_left > 0 ) { 558const size_t vl = __riscv_vsetvl_e16m2 (d_left ); 559vfloat32m4_t acc0 = __riscv_vle32_v_f32m4 (dst0 + d_off ,vl ); 560vfloat32m4_t acc1 = __riscv_vle32_v_f32m4 (dst1 + d_off ,vl ); 561vfloat32m4_t acc2 = __riscv_vle32_v_f32m4 (dst2 + d_off ,vl ); 562vfloat32m4_t acc3 = __riscv_vle32_v_f32m4 (dst3 + d_off ,vl ); 563 564for (int64_t tk = 0 ;tk < kv_tile ;++ tk ) { 565const vfloat16m2_t v16 = __riscv_vle16_v_f16m2 (v_pack + tk * dv + d_off ,vl ); 566const vfloat32m4_t v32 = __riscv_vfwcvt_f_f_v_f32m4 (v16 ,vl ); 567acc0 = __riscv_vfmacc_vf_f32m4 (acc0 ,prob0 [tk ],v32 ,vl ); 568acc1 = __riscv_vfmacc_vf_f32m4 (acc1 ,prob1 [tk ],v32 ,vl ); 569acc2 = __riscv_vfmacc_vf_f32m4 (acc2 ,prob2 [tk ],v32 ,vl ); 570acc3 = __riscv_vfmacc_vf_f32m4 (acc3 ,prob3 [tk ],v32 ,vl ); 571 } 572 573__riscv_vse32_v_f32m4 (dst0 + d_off ,acc0 ,vl ); 574__riscv_vse32_v_f32m4 (dst1 + d_off ,acc1 ,vl ); 575__riscv_vse32_v_f32m4 (dst2 + d_off ,acc2 ,vl ); 576__riscv_vse32_v_f32m4 (dst3 + d_off ,acc3 ,vl ); 577d_left -= vl ; 578d_off += vl ; 579 } 580} 581 582static inline void rvv_qk_dot_tile (float * dst , 583const float * q_row , 584const float * k_pack , 585int64_t dk , 586int64_t kv_tile , 587float scale ) { 588const size_t vl = __riscv_vsetvl_e32m4 (kv_tile ); 589vfloat32m4_t acc = __riscv_vfmv_v_f_f32m4 (0.0f ,vl ); 590 591for (int64_t d = 0 ;d < dk ;++ d ) { 592const vfloat32m4_t k_vec = __riscv_vle32_v_f32m4 (k_pack + d * kv_tile ,vl ); 593acc = __riscv_vfmacc_vf_f32m4 (acc ,q_row [d ]* scale ,k_vec ,vl ); 594 } 595 596__riscv_vse32_v_f32m4 (dst ,acc ,vl ); 597} 598 599static inline void rvv_pv_accumulate (float * dst , 600const float * prob , 601const float * v_pack , 602int64_t kv_tile , 603int64_t dv ) { 604int64_t d_left = dv ; 605int64_t d_off = 0 ; 606 607while (d_left > 0 ) { 608const size_t vl = __riscv_vsetvl_e32m4 (d_left ); 609vfloat32m4_t acc = __riscv_vle32_v_f32m4 (dst + d_off ,vl ); 610 611for (int64_t tk = 0 ;tk < kv_tile ;++ tk ) { 612const vfloat32m4_t v_vec = __riscv_vle32_v_f32m4 (v_pack + tk * dv + d_off ,vl ); 613acc = __riscv_vfmacc_vf_f32m4 (acc ,prob [tk ],v_vec ,vl ); 614 } 615 616__riscv_vse32_v_f32m4 (dst + d_off ,acc ,vl ); 617d_left -= vl ; 618d_off += vl ; 619 } 620} 621 622static void permute_transpose_impl (const ggml_tensor * src0 , 623ggml_tensor * dst , 624int64_t batch , 625int64_t m , 626int64_t n , 627int64_t batch_stride , 628int64_t m_src_stride , 629int64_t n_src_stride , 630int64_t n_dst_stride , 631int ith , 632int nth ) { 633GGML_ASSERT (n_src_stride == sizeof (int32_t )|| n_src_stride == sizeof (int16_t )); 634 635if (n_src_stride == sizeof (int32_t )) { 636for (int64_t bi = ith ;bi < batch ;bi += nth ) { 637rvv_transposed_s32_mn_to_nm ((int8_t * ) ((char * )dst -> data + bi * batch_stride ),n_dst_stride , 638 (int8_t * ) ((char * )src0 -> data + bi * batch_stride ),m_src_stride ,m ,n ); 639 } 640 }else if (n_src_stride == sizeof (int16_t )) { 641for (int64_t bi = ith ;bi < batch ;bi += nth ) { 642rvv_transposed_s32_mn_to_nm ((int8_t * ) ((char * )dst -> data + bi * batch_stride ),n_dst_stride , 643 (int8_t * ) ((char * )src0 -> data + bi * batch_stride ),m_src_stride ,m ,n ); 644 } 645 }else { 646GGML_ABORT ("not implemented" ); 647 } 648} 649 650template < size_t QLEN > 651static void flash_attn_ext_f16_one_chunk_inner_vlen1024_vf16_mrow (float ** pq , 652const char * k_data_row , 653const char * v_data_row , 654const ggml_fp16_t * mp , 655float ** sinks , 656float ** dst , 657float scale , 658float logit_softcap , 659float slope , 660int64_t nek1 , 661int64_t nbk1 , 662int64_t nbv1 , 663int64_t DV , 664int64_t DK , 665void * tcm_buffer , 666size_t tcm_buffer_size ) { 667GGML_ASSERT (flash_attn_ext_supported_shape_vlen1024_vf16 (DK ,DV )); 668float S [QLEN ]= {0.0f };// sum 669float M [QLEN ]= {- INFINITY };// maximum KQ value 670 671_Float16 * kq16_buffer = (_Float16 * )tcm_buffer ; 672_Float16 * qv_buffer = kq16_buffer + QLEN * DV ; 673const size_t qkv_temp_buffer_size = (QLEN * DV + QLEN * DK )* sizeof (_Float16 ); 674char * kv_tile_buffer = (char * ) (qv_buffer + QLEN * DK ); 675 676 { 677vfloat16m2_t VKQ16_v = __riscv_vfmv_v_f_f16m2 (0.0f ,DV ); 678for (int64_t i = 0 ;i < QLEN ;++ i ) { 679__riscv_vse16_v_f16m2 (kq16_buffer + i * DV ,VKQ16_v ,DV ); 680vfloat16m2_t Q_q_v = __riscv_vfncvt_f_f_w_f16m2 (__riscv_vle32_v_f32m4 (pq [i ],DK ),DK ); 681__riscv_vse16_v_f16m2 (qv_buffer + i * DK ,Q_q_v ,DK ); 682 } 683 } 684 685const uintptr_t scratch_addr = reinterpret_cast < uintptr_t > (kv_tile_buffer ); 686const size_t scratch_size = tcm_buffer_size > qkv_temp_buffer_size ?tcm_buffer_size - qkv_temp_buffer_size :0 ; 687const uintptr_t kq_tile_addr = align_up (scratch_addr , alignof(float )); 688const size_t scratch_prefix = kq_tile_addr - scratch_addr ; 689const size_t packed_tile_size = 690QLEN * sizeof (float )+ DK * sizeof (_Float16 )+ DV * sizeof (_Float16 )+ sizeof (float ); 691const int64_t max_ic_tile_step = ((int64_t )__riscv_vsetvlmax_e16m1 ())& ~((int64_t )7 ); 692const int64_t max_fit_by_tcm = 693scratch_size > scratch_prefix ? (int64_t ) ((scratch_size - scratch_prefix ) /packed_tile_size ) :0 ; 694const int64_t ic_tile_step = std::min (max_ic_tile_step ,max_fit_by_tcm )& ~((int64_t )7 ); 695 696const uintptr_t k_tile_addr = kq_tile_addr + QLEN * ic_tile_step * sizeof (float ); 697const uintptr_t v_tile_addr = k_tile_addr + DK * ic_tile_step * sizeof (_Float16 ); 698const uintptr_t mv_tile_addr = v_tile_addr + ic_tile_step * DV * sizeof (_Float16 ); 699 700if (ic_tile_step >=8 ) { 701float * kq_tile_buffer = reinterpret_cast < float *> (kq_tile_addr ); 702_Float16 * k_tile_pack = reinterpret_cast < _Float16 *> (k_tile_addr ); 703_Float16 * v_tile_pack = reinterpret_cast < _Float16 *> (v_tile_addr ); 704float * mv_tile_pack = reinterpret_cast < float *> (mv_tile_addr ); 705 706const int64_t k_tile_byte_stride = ic_tile_step * (int64_t )sizeof (_Float16 ); 707 708int64_t ic_step = 0 ; 709for (int64_t ic = 0 ;ic < nek1 ;++ ic ) { 710const float mv = mp ?slope * ((_Float16 * )mp )[ic ] :0.0f ; 711 712if (mv != - INFINITY ) { 713const _Float16 * k_data = (const _Float16 * ) (k_data_row + ic * nbk1 ); 714const _Float16 * v_data = (const _Float16 * ) (v_data_row + ic * nbv1 ); 715 716const vfloat16m2_t k_data_v = __riscv_vle16_v_f16m2 (k_data ,DK ); 717const vfloat16m2_t v_data_v = __riscv_vle16_v_f16m2 (v_data ,DV ); 718__riscv_vsse16_v_f16m2 (k_tile_pack + ic_step ,k_tile_byte_stride ,k_data_v ,DK ); 719__riscv_vse16_v_f16m2 (v_tile_pack + ic_step * DV ,v_data_v ,DV ); 720mv_tile_pack [ic_step ]= mv ; 721ic_step ++ ; 722 } 723 724if (ic_step > 0 && (ic_step == ic_tile_step || ic == (nek1 - 1 ))) { 725if constexpr (QLEN == 4 ) { 726const size_t qk_vl = __riscv_vsetvl_e16m1 (ic_step ); 727vfloat32m2_t qk_acc0 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 728vfloat32m2_t qk_acc1 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 729vfloat32m2_t qk_acc2 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 730vfloat32m2_t qk_acc3 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 731 732for (int64_t d = 0 ;d < DK ;++ d ) { 733const vfloat16m1_t k_vec = __riscv_vle16_v_f16m1 (k_tile_pack + d * ic_tile_step ,qk_vl ); 734qk_acc0 = __riscv_vfwmacc_vf_f32m2 (qk_acc0 ,qv_buffer [0 * DK + d ],k_vec ,qk_vl ); 735qk_acc1 = __riscv_vfwmacc_vf_f32m2 (qk_acc1 ,qv_buffer [1 * DK + d ],k_vec ,qk_vl ); 736qk_acc2 = __riscv_vfwmacc_vf_f32m2 (qk_acc2 ,qv_buffer [2 * DK + d ],k_vec ,qk_vl ); 737qk_acc3 = __riscv_vfwmacc_vf_f32m2 (qk_acc3 ,qv_buffer [3 * DK + d ],k_vec ,qk_vl ); 738 } 739 740qk_acc0 = __riscv_vfmul_vf_f32m2 (qk_acc0 ,scale ,qk_vl ); 741qk_acc1 = __riscv_vfmul_vf_f32m2 (qk_acc1 ,scale ,qk_vl ); 742qk_acc2 = __riscv_vfmul_vf_f32m2 (qk_acc2 ,scale ,qk_vl ); 743qk_acc3 = __riscv_vfmul_vf_f32m2 (qk_acc3 ,scale ,qk_vl ); 744 745__riscv_vse32_v_f32m2 (kq_tile_buffer + 0 * ic_tile_step ,qk_acc0 ,qk_vl ); 746__riscv_vse32_v_f32m2 (kq_tile_buffer + 1 * ic_tile_step ,qk_acc1 ,qk_vl ); 747__riscv_vse32_v_f32m2 (kq_tile_buffer + 2 * ic_tile_step ,qk_acc2 ,qk_vl ); 748__riscv_vse32_v_f32m2 (kq_tile_buffer + 3 * ic_tile_step ,qk_acc3 ,qk_vl ); 749 }else { 750 static_assert(QLEN == 2 ,"unsupported QLEN" ); 751 752const size_t qk_vl = __riscv_vsetvl_e16m1 (ic_step ); 753vfloat32m2_t qk_acc0 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 754vfloat32m2_t qk_acc1 = __riscv_vfmv_v_f_f32m2 (0.0f ,qk_vl ); 755 756for (int64_t d = 0 ;d < DK ;++ d ) { 757const vfloat16m1_t k_vec = __riscv_vle16_v_f16m1 (k_tile_pack + d * ic_tile_step ,qk_vl ); 758qk_acc0 = __riscv_vfwmacc_vf_f32m2 (qk_acc0 ,qv_buffer [0 * DK + d ],k_vec ,qk_vl ); 759qk_acc1 = __riscv_vfwmacc_vf_f32m2 (qk_acc1 ,qv_buffer [1 * DK + d ],k_vec ,qk_vl ); 760 } 761 762qk_acc0 = __riscv_vfmul_vf_f32m2 (qk_acc0 ,scale ,qk_vl ); 763qk_acc1 = __riscv_vfmul_vf_f32m2 (qk_acc1 ,scale ,qk_vl ); 764 765__riscv_vse32_v_f32m2 (kq_tile_buffer + 0 * ic_tile_step ,qk_acc0 ,qk_vl ); 766__riscv_vse32_v_f32m2 (kq_tile_buffer + 1 * ic_tile_step ,qk_acc1 ,qk_vl ); 767 } 768 769for (int i = 0 ;i < QLEN ;++ i ) { 770float * row_ptr = kq_tile_buffer + i * ic_tile_step ; 771const float tile_max = 772rvv_softcap_add_max_inplace_f32 (row_ptr ,mv_tile_pack ,ic_step ,logit_softcap ); 773 774const float Mold = M [i ]; 775 776if (tile_max > Mold ) { 777const float ms = expf (Mold - tile_max ); 778M [i ]= tile_max ; 779S [i ] *=ms ; 780 781vfloat16m2_t VKQ16_v = __riscv_vle16_v_f16m2 (kq16_buffer + i * DV ,DV ); 782VKQ16_v = __riscv_vfmul_vf_f16m2 (VKQ16_v , (_Float16 )ms ,DV ); 783__riscv_vse16_v_f16m2 (kq16_buffer + i * DV ,VKQ16_v ,DV ); 784 } 785 786S [i ]+= rvv_softmax_exp_inplace_f32 (row_ptr ,ic_step ,M [i ]); 787 } 788 789if constexpr (QLEN == 4 ) { 790vfloat16m2_t pv_acc0 = __riscv_vle16_v_f16m2 (kq16_buffer + 0 * DV ,DV ); 791vfloat16m2_t pv_acc1 = __riscv_vle16_v_f16m2 (kq16_buffer + 1 * DV ,DV ); 792vfloat16m2_t pv_acc2 = __riscv_vle16_v_f16m2 (kq16_buffer + 2 * DV ,DV ); 793vfloat16m2_t pv_acc3 = __riscv_vle16_v_f16m2 (kq16_buffer + 3 * DV ,DV ); 794 795for (int64_t tk = 0 ;tk < ic_step ;++ tk ) { 796const vfloat16m2_t v16 = __riscv_vle16_v_f16m2 (v_tile_pack + tk * DV ,DV ); 797pv_acc0 = 798__riscv_vfmacc_vf_f16m2 (pv_acc0 , (_Float16 )kq_tile_buffer [0 * ic_tile_step + tk ],v16 ,DV ); 799pv_acc1 = 800__riscv_vfmacc_vf_f16m2 (pv_acc1 , (_Float16 )kq_tile_buffer [1 * ic_tile_step + tk ],v16 ,DV ); 801pv_acc2 = 802__riscv_vfmacc_vf_f16m2 (pv_acc2 , (_Float16 )kq_tile_buffer [2 * ic_tile_step + tk ],v16 ,DV ); 803pv_acc3 = 804__riscv_vfmacc_vf_f16m2 (pv_acc3 , (_Float16 )kq_tile_buffer [3 * ic_tile_step + tk ],v16 ,DV ); 805 } 806 807__riscv_vse16_v_f16m2 (kq16_buffer + 0 * DV ,pv_acc0 ,DV ); 808__riscv_vse16_v_f16m2 (kq16_buffer + 1 * DV ,pv_acc1 ,DV ); 809__riscv_vse16_v_f16m2 (kq16_buffer + 2 * DV ,pv_acc2 ,DV ); 810__riscv_vse16_v_f16m2 (kq16_buffer + 3 * DV ,pv_acc3 ,DV ); 811 }else { 812 static_assert(QLEN == 2 ,"unsupported QLEN" ); 813vfloat16m2_t pv_acc0 = __riscv_vle16_v_f16m2 (kq16_buffer + 0 * DV ,DV ); 814vfloat16m2_t pv_acc1 = __riscv_vle16_v_f16m2 (kq16_buffer + 1 * DV ,DV ); 815 816for (int64_t tk = 0 ;tk < ic_step ;++ tk ) { 817const vfloat16m2_t v16 = __riscv_vle16_v_f16m2 (v_tile_pack + tk * DV ,DV ); 818pv_acc0 = 819__riscv_vfmacc_vf_f16m2 (pv_acc0 , (_Float16 )kq_tile_buffer [0 * ic_tile_step + tk ],v16 ,DV ); 820pv_acc1 = 821__riscv_vfmacc_vf_f16m2 (pv_acc1 , (_Float16 )kq_tile_buffer [1 * ic_tile_step + tk ],v16 ,DV ); 822 } 823 824__riscv_vse16_v_f16m2 (kq16_buffer + 0 * DV ,pv_acc0 ,DV ); 825__riscv_vse16_v_f16m2 (kq16_buffer + 1 * DV ,pv_acc1 ,DV ); 826 } 827 828ic_step = 0 ; 829 } 830 } 831 }else { 832for (int64_t ic = 0 ;ic < nek1 ;++ ic ) { 833const float mv = mp ?slope * ((_Float16 * )mp )[ic ] :0.0f ; 834 835const char * k_data = k_data_row + ic * nbk1 ; 836const char * v_data = v_data_row + ic * nbv1 ; 837 838vfloat16m2_t k_data_v ; 839vfloat16m2_t v_data_v ; 840 841if (mv != - INFINITY ) { 842k_data_v = __riscv_vle16_v_f16m2 ((_Float16 * )k_data ,DK ); 843v_data_v = __riscv_vle16_v_f16m2 ((_Float16 * )v_data ,DV ); 844 }else { 845continue ; 846 } 847 848for (int i = 0 ;i < QLEN ;++ i ) { 849vfloat16m2_t Q_q_v = __riscv_vle16_v_f16m2 (qv_buffer + i * DK ,DK ); 850vfloat32m4_t qk_acc_v = __riscv_vfwmul_vv_f32m4 (k_data_v ,Q_q_v ,DK ); 851float s = reduce_sum_f32m4_vlen1024 (qk_acc_v ,DK ); 852s = s * scale ; 853if (logit_softcap != 0.0f ) { 854s = logit_softcap * tanhf (s ); 855 } 856s += mv ; 857 858const float Mold = M [i ]; 859 860float ms = 1.0f ;// upon new higher max val, scale VKQ and KQ sum with this value 861float vs = 1.0f ;// post-softmax KQ value, expf(s - M) 862 863vfloat16m2_t VKQ16_v = __riscv_vle16_v_f16m2 (kq16_buffer + i * DV ,DV ); 864if (s > M [i ]) { 865// s is new maximum, ms < 1.0f, vs == expf(s - s) == 1.0f 866M [i ]= s ; 867ms = expf (Mold - M [i ]); 868 869// V = V*expf(Mold - M) 870VKQ16_v = __riscv_vfmul_vf_f16m2 (VKQ16_v ,ms ,DV ); 871 }else { 872// no new maximum, ms == 1.0f, vs != 1.0f 873vs = expf (s - M [i ]); 874 } 875VKQ16_v = __riscv_vfmacc_vf_f16m2 (VKQ16_v ,vs ,v_data_v ,DV ); 876__riscv_vse16_v_f16m2 (kq16_buffer + i * DV ,VKQ16_v ,DV ); 877S [i ]= S [i ]* ms + vs ;// scale and increment sum with partial sum 878 } 879 } 880 } 881 882for (int i = 0 ;i < QLEN ;++ i ) { 883vfloat16m2_t VKQ16_v = __riscv_vle16_v_f16m2 (kq16_buffer + i * DV ,DV ); 884vfloat32m4_t VKQ32_v = __riscv_vfwcvt_f_f_v_f32m4 (VKQ16_v ,DV ); 885 886// sinks 887if (sinks [i ]) { 888const float s = * (sinks [i ]); 889 890float ms = 1.0f ; 891float vs = 1.0f ; 892 893if (s > M [i ]) { 894ms = expf (M [i ]- s ); 895M [i ]= s ; 896VKQ32_v = __riscv_vfmul_vf_f32m4 (VKQ32_v ,ms ,DV ); 897 }else { 898vs = expf (s - M [i ]); 899 } 900 901S [i ]= S [i ]* ms + vs ; 902 } 903 904// V /= S 905const float S_inv = S [i ]== 0.0f ?0.0f :1.0f /S [i ]; 906 907VKQ32_v = __riscv_vfmul_vf_f32m4 (VKQ32_v ,S_inv ,DV ); 908 909__riscv_vse32_v_f32m4 (dst [i ],VKQ32_v ,DV ); 910 } 911} 912 913static void flash_attn_ext_f16_one_chunk_inner_vlen1024_vf16_m1 (const float * pq , 914const char * k_data_row , 915const char * v_data_row , 916const ggml_fp16_t * mp , 917const float * sinks , 918float * dst , 919float scale , 920float logit_softcap , 921float slope , 922int64_t nek1 , 923int64_t nbk1 , 924int64_t nbv1 , 925int64_t DV , 926int64_t DK ) { 927GGML_ASSERT (flash_attn_ext_supported_shape_vlen1024_vf16 (DK ,DV )); 928 929float S = 0.0f ;// sum 930float M = - INFINITY ;// maximum KQ value 931 932vfloat16m2_t VKQ16_v = __riscv_vfmv_v_f_f16m2 (0.0f ,DV ); 933 934vfloat16m2_t Q_q_v = __riscv_vfncvt_f_f_w_f16m2 (__riscv_vle32_v_f32m4 (pq ,DK ),DK ); 935 936for (int64_t ic = 0 ;ic < nek1 ;++ ic ) { 937const float mv = mp ?slope * ((_Float16 * )mp )[ic ] :0.0f ; 938if (mv == - INFINITY ) { 939continue ; 940 } 941 942const char * k_data = k_data_row + ic * nbk1 ; 943 944vfloat16m2_t k_data_v = __riscv_vle16_v_f16m2 ((_Float16 * )k_data ,DK ); 945 946vfloat32m4_t qk_acc_v = __riscv_vfwmul_vv_f32m4 (k_data_v ,Q_q_v ,DK ); 947float s = reduce_sum_f32m4_vlen1024 (qk_acc_v ,DK ); 948 949s = s * scale ;// scale KQ value 950 951if (logit_softcap != 0.0f ) { 952s = logit_softcap * tanhf (s ); 953 } 954 955s += mv ;// apply mask 956 957const float Mold = M ; 958 959float ms = 1.0f ;// upon new higher max val, scale VKQ and KQ sum with this value 960float vs = 1.0f ;// post-softmax KQ value, expf(s - M) 961 962const char * v_data = v_data_row + ic * nbv1 ; 963 964vfloat16m2_t v_data_v = __riscv_vle16_v_f16m2 ((_Float16 * )v_data ,DV ); 965 966if (s > M ) { 967// s is new maximum, ms < 1.0f, vs == expf(s - s) == 1.0f 968M = s ; 969ms = expf (Mold - M ); 970 971// V = V*expf(Mold - M) 972VKQ16_v = __riscv_vfmul_vf_f16m2 (VKQ16_v ,ms ,DV ); 973 }else { 974// no new maximum, ms == 1.0f, vs != 1.0f 975vs = expf (s - M ); 976 } 977 978VKQ16_v = __riscv_vfmacc_vf_f16m2 (VKQ16_v ,vs ,v_data_v ,DV ); 979 980S = S * ms + vs ;// scale and increment sum with partial sum 981 } 982 983vfloat32m4_t VKQ32_v = __riscv_vfwcvt_f_f_v_f32m4 (VKQ16_v ,DV ); 984 985// sinks 986if (sinks ) { 987const float s = * sinks ; 988 989float ms = 1.0f ; 990float vs = 1.0f ; 991 992if (s > M ) { 993ms = expf (M - s ); 994M = s ; 995VKQ32_v = __riscv_vfmul_vf_f32m4 (VKQ32_v ,ms ,DV ); 996 }else { 997vs = expf (s - M ); 998 } 999 1000S = S * ms + vs ; 1001 } 1002 1003// V /= S 1004const float S_inv = S == 0.0f ?0.0f :1.0f /S ; 1005 1006VKQ32_v = __riscv_vfmul_vf_f32m4 (VKQ32_v ,S_inv ,DV ); 1007 1008__riscv_vse32_v_f32m4 (dst ,VKQ32_v ,DV ); 1009} 1010 1011}// namespace 1012 1013void memcpy1d (void * dst ,const void * src ,int64_t size ) { 1014size_t byte_size_all = size ; 1015size_t vlen = __riscv_vlenb ()* 8 ; 1016if (vlen == 256 ) { 1017// 1024 bytes 1018 __asm__volatile ( 1019// 1020"srli t0, %[size], 10 \n\t" 1021"blez t0, memcpy_tail%= \n\t" 1022"vsetvli t1, x0, e8, m8, tu, mu \n\t" 1023"memcpy_main_loop%=: \n\t" 1024"addi t0, t0, -1 \n\t" 1025"vle8.v v0, (%[s]) \n\t" 1026"addi %[s], %[s], 256 \n\t" 1027"vle8.v v8, (%[s]) \n\t" 1028"addi %[s], %[s], 256 \n\t" 1029"vle8.v v16, (%[s]) \n\t" 1030"addi %[s], %[s], 256 \n\t" 1031"vle8.v v24, (%[s]) \n\t" 1032"addi %[s], %[s], 256 \n\t" 1033// 1034"vse8.v v0, (%[d]) \n\t" 1035"addi %[d], %[d], 256 \n\t" 1036"vse8.v v8, (%[d]) \n\t" 1037"addi %[d], %[d], 256 \n\t" 1038"vse8.v v16, (%[d]) \n\t" 1039"addi %[d], %[d], 256 \n\t" 1040"vse8.v v24, (%[d]) \n\t" 1041"addi %[d], %[d], 256 \n\t" 1042// 1043"bnez t0, memcpy_main_loop%= \n\t" 1044"memcpy_tail%=: \n\t" 1045"andi t1, %[size], 1023 \n\t" 1046"blez t1, out%= \n\t" 1047"memcpy_tail_loop%=: \n\t" 1048"vsetvli t0, t1, e8, m8, tu, mu \n\t" 1049"sub t1, t1, t0 \n\t" 1050"vle8.v v0, (%[s]) \n\t" 1051"add %[s], %[s], t0 \n\t" 1052"vse8.v v0, (%[d]) \n\t" 1053"add %[d], %[d], t0 \n\t" 1054"bnez t1, memcpy_tail_loop%= \n\t" 1055"out%=: \n\t" 1056 : [s ]"+r" (src ), [d ]"+r" (dst ) 1057 : [size ]"r" (byte_size_all ) 1058 :"cc" ,"t0" ,"t1" ); 1059 }else if (vlen == 1024 ) { 1060// 2048 bytes 1061 __asm__volatile ( 1062// 1063"srli t0, %[size], 11 \n\t" 1064"blez t0, memcpy_tail%= \n\t" 1065"vsetvli t1, x0, e8, m8, tu, mu \n\t" 1066"addi t2, %[s], 1024 \n\t" 1067"addi t3, %[d], 1024 \n\t" 1068"li t5, 2048 \n\t" 1069"memcpy_main_loop%=: \n\t" 1070"addi t0, t0, -1 \n\t" 1071"vle8.v v0, (%[s]) \n\t" 1072"add %[s], %[s], t5 \n\t" 1073"vle8.v v8, (t2) \n\t" 1074"add t2, t2, t5 \n\t" 1075// 1076"vse8.v v0, (%[d]) \n\t" 1077"add %[d], %[d], t5 \n\t" 1078"vse8.v v8, (t3) \n\t" 1079"add t3, t3, t5 \n\t" 1080// 1081"bnez t0, memcpy_main_loop%= \n\t" 1082"memcpy_tail%=: \n\t" 1083"andi t1, %[size], 2047 \n\t" 1084"blez t1, out%= \n\t" 1085"memcpy_tail_loop%=: \n\t" 1086"vsetvli t0, t1, e8, m2, tu, mu \n\t" 1087"sub t1, t1, t0 \n\t" 1088"vle8.v v0, (%[s]) \n\t" 1089"add %[s], %[s], t0 \n\t" 1090"vse8.v v0, (%[d]) \n\t" 1091"add %[d], %[d], t0 \n\t" 1092"bnez t1, memcpy_tail_loop%= \n\t" 1093"out%=: \n\t" 1094 : [s ]"+r" (src ), [d ]"+r" (dst ) 1095 : [size ]"r" (byte_size_all ) 1096 :"cc" ,"t0" ,"t1" ,"t2" ,"t3" ,"t5" ); 1097 }else { 1098 __asm__volatile ( 1099// 1100"add t1, %[size], zero \n\t" 1101"memcpy_tail_loop%=: \n\t" 1102"vsetvli t0, t1, e8, m8, tu, mu \n\t" 1103"sub t1, t1, t0 \n\t" 1104"vle8.v v0, (%[s]) \n\t" 1105"add %[s], %[s], t0 \n\t" 1106"vse8.v v0, (%[d]) \n\t" 1107"add %[d], %[d], t0 \n\t" 1108"bnez t1, memcpy_tail_loop%= \n\t" 1109 : [s ]"+r" (src ), [d ]"+r" (dst ) 1110 : [size ]"r" (byte_size_all ) 1111 :"cc" ,"t0" ,"t1" ,"t2" ,"t4" ,"t3" ); 1112 } 1113} 1114 1115void memcpy2d (void * dst ,int64_t dst_stride ,const void * src ,int64_t src_stride ,int64_t tile_rows ,int64_t size ) { 1116for (int64_t i = 0 ;i < tile_rows ;++ i ) { 1117memcpy1d ((char * )dst + i * dst_stride , (const char * )src + i * src_stride ,size ); 1118 } 1119} 1120 1121void forward_flash_attn_ext_f16_one_chunk_vlen1024_vf16 (const ggml_compute_params * params , 1122ggml_tensor * dst , 1123int ir0 , 1124int ir1 , 1125void * tcm_buffer , 1126size_t tcm_buffer_size ) { 1127const ggml_tensor * q = dst -> src [0 ]; 1128const ggml_tensor * k = dst -> src [1 ]; 1129const ggml_tensor * v = dst -> src [2 ]; 1130const ggml_tensor * mask = dst -> src [3 ]; 1131const ggml_tensor * sinks = dst -> src [4 ]; 1132 1133GGML_TENSOR_LOCALS (int64_t ,neq ,q ,ne ) 1134GGML_TENSOR_LOCALS (size_t ,nbq ,q ,nb ) 1135GGML_TENSOR_LOCALS (int64_t ,nek ,k ,ne ) 1136GGML_TENSOR_LOCALS (size_t ,nbk ,k ,nb ) 1137GGML_TENSOR_LOCALS (int64_t ,nev ,v ,ne ) 1138GGML_TENSOR_LOCALS (size_t ,nbv ,v ,nb ) 1139GGML_TENSOR_LOCALS (int64_t ,ne ,dst ,ne ) 1140GGML_TENSOR_LOCALS (size_t ,nb ,dst ,nb ) 1141 1142const int64_t DK = nek0 ; 1143const int64_t DV = nev0 ; 1144const int64_t N = neq1 ; 1145 1146GGML_ASSERT (flash_attn_ext_supported_shape_vlen1024_vf16 (DK ,DV )); 1147 1148// broadcast factors 1149const int64_t rk2 = neq2 /nek2 ; 1150const int64_t rk3 = neq3 /nek3 ; 1151 1152const int64_t rv2 = neq2 /nev2 ; 1153const int64_t rv3 = neq3 /nev3 ; 1154 1155// parallelize by q rows using ggml_vec_dot_f32 1156 1157float scale = * ((float * )dst -> op_params + 0 ); 1158float max_bias = * ((float * )dst -> op_params + 1 ); 1159float logit_softcap = * ((float * )dst -> op_params + 2 ); 1160 1161if (logit_softcap != 0 ) { 1162scale /=logit_softcap ; 1163 } 1164 1165const uint32_t n_head = neq2 ; 1166const uint32_t n_head_log2 = 1u << (uint32_t )floor (log2 (n_head )); 1167 1168const float m0 = powf (2.0f ,- (max_bias ) /n_head_log2 ); 1169const float m1 = powf (2.0f ,- (max_bias /2.0f ) /n_head_log2 ); 1170 1171const int KV_row_size = DK * sizeof (_Float16 )+ DV * sizeof (_Float16 ); 1172 1173int ith = params -> ith ; 1174int ir_step = 1 ; 1175for (int ir = ir0 ;ir < ir1 ;ir += ir_step ) { 1176// q indices 1177const int iq3 = ir / (neq2 * neq1 ); 1178const int iq2 = (ir - iq3 * neq2 * neq1 ) /neq1 ; 1179const int iq1 = (ir - iq3 * neq2 * neq1 - iq2 * neq1 ); 1180 1181const int iq3_1 = (ir + 1 ) / (neq2 * neq1 ); 1182const int iq2_1 = (ir + 1 - iq3_1 * neq2 * neq1 ) /neq1 ; 1183const int iq1_1 = (ir + 1 - iq3_1 * neq2 * neq1 - iq2_1 * neq1 ); 1184 1185const int iq3_2 = (ir + 2 ) / (neq2 * neq1 ); 1186const int iq2_2 = (ir + 2 - iq3_2 * neq2 * neq1 ) /neq1 ; 1187const int iq1_2 = (ir + 2 - iq3_2 * neq2 * neq1 - iq2_2 * neq1 ); 1188 1189const int iq3_3 = (ir + 3 ) / (neq2 * neq1 ); 1190const int iq2_3 = (ir + 3 - iq3_3 * neq2 * neq1 ) /neq1 ; 1191const int iq1_3 = (ir + 3 - iq3_3 * neq2 * neq1 - iq2_3 * neq1 ); 1192 1193const uint32_t h = iq2 ;// head index 1194const float slope = 1195 (max_bias > 0.0f ) ?h < n_head_log2 ?powf (m0 ,h + 1 ) :powf (m1 ,2 * (h - n_head_log2 )+ 1 ) :1.0f ; 1196 1197const ggml_fp16_t * mp = 1198mask ? (ggml_fp16_t * ) ((char * )mask -> data + iq1 * mask -> nb [1 ]+ (iq2 %mask -> ne [2 ])* mask -> nb [2 ]+ 1199 (iq3 %mask -> ne [3 ])* mask -> nb [3 ]) : 1200NULL ; 1201 1202const bool mp_equal_2 = iq1_1 == iq1 && (iq2 %mask -> ne [2 ])== (iq2_1 %mask -> ne [2 ])&& 1203 (iq3 %mask -> ne [3 ])== (iq3_1 %mask -> ne [3 ]); 1204 1205const bool mp_equal_4 = mp_equal_2 && iq1_2 == iq1 && (iq2 %mask -> ne [2 ])== (iq2_2 %mask -> ne [2 ])&& 1206 (iq3 %mask -> ne [3 ])== (iq3_2 %mask -> ne [3 ])&& iq1_3 == iq1 && 1207 (iq2 %mask -> ne [2 ])== (iq2_3 %mask -> ne [2 ])&& 1208 (iq3 %mask -> ne [3 ])== (iq3_3 %mask -> ne [3 ]); 1209 1210// k indices 1211const int ik3 = iq3 /rk3 ; 1212const int ik2 = iq2 /rk2 ; 1213 1214const int ik3_1 = iq3_1 /rk3 ; 1215const int ik2_1 = iq2_1 /rk2 ; 1216 1217const int ik3_2 = iq3_2 /rk3 ; 1218const int ik2_2 = iq2_2 /rk2 ; 1219 1220const int ik3_3 = iq3_3 /rk3 ; 1221const int ik2_3 = iq2_3 /rk2 ; 1222 1223// v indices 1224const int iv3 = iq3 /rv3 ; 1225const int iv2 = iq2 /rv2 ; 1226 1227const int iv3_1 = iq3_1 /rv3 ; 1228const int iv2_1 = iq2_1 /rv2 ; 1229 1230const int iv3_2 = iq3_2 /rv3 ; 1231const int iv2_2 = iq2_2 /rv2 ; 1232 1233const int iv3_3 = iq3_3 /rv3 ; 1234const int iv2_3 = iq2_3 /rv2 ; 1235 1236const float * pq = (const float * ) ((char * )q -> data + (iq1 * nbq1 + iq2 * nbq2 + iq3 * nbq3 )); 1237 1238 std::array < float * ,4 > pq_buffer ; 1239 std::array < float * ,4 > sinks_buffer ; 1240 std::array < float * ,4 > dst_buffer ; 1241 1242if (tcm_buffer != nullptr && 4 * KV_row_size < tcm_buffer_size && ir < (ir1 - 3 )&& mp_equal_4 && 1243ik3_3 == ik3 && ik2_3 == ik2 && iv3_3 == iv3 && iv2_3 == iv2 && ik3_2 == ik3 && ik2_2 == ik2 && 1244iv3_2 == iv3 && iv2_2 == iv2 && ik3_1 == ik3 && ik2_1 == ik2 && iv3_1 == iv3 && iv2_1 == iv2 ) { 1245ir_step = 4 ; 1246 1247pq_buffer [0 ]= (float * ) ((char * )q -> data + (iq1 * nbq1 + iq2 * nbq2 + iq3 * nbq3 )); 1248pq_buffer [1 ]= (float * ) ((char * )q -> data + (iq1_1 * nbq1 + iq2_1 * nbq2 + iq3_1 * nbq3 )); 1249pq_buffer [2 ]= (float * ) ((char * )q -> data + (iq1_2 * nbq1 + iq2_2 * nbq2 + iq3_2 * nbq3 )); 1250pq_buffer [3 ]= (float * ) ((char * )q -> data + (iq1_3 * nbq1 + iq2_3 * nbq2 + iq3_3 * nbq3 )); 1251 1252sinks_buffer [0 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2 :nullptr ; 1253sinks_buffer [1 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2_1 :nullptr ; 1254sinks_buffer [2 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2_2 :nullptr ; 1255sinks_buffer [3 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2_3 :nullptr ; 1256 1257dst_buffer [0 ]= (float * ) ((char * )dst -> data + (iq3 * ne2 * ne1 + iq2 + iq1 * ne1 )* nb1 ); 1258dst_buffer [1 ]= (float * ) ((char * )dst -> data + (iq3_1 * ne2 * ne1 + iq2_1 + iq1_1 * ne1 )* nb1 ); 1259dst_buffer [2 ]= (float * ) ((char * )dst -> data + (iq3_2 * ne2 * ne1 + iq2_2 + iq1_2 * ne1 )* nb1 ); 1260dst_buffer [3 ]= (float * ) ((char * )dst -> data + (iq3_3 * ne2 * ne1 + iq2_3 + iq1_3 * ne1 )* nb1 ); 1261 1262flash_attn_ext_f16_one_chunk_inner_vlen1024_vf16_mrow < 4 > (// 1263pq_buffer .data (),// 1264 (const char * )k -> data + (ik2 * nbk2 + ik3 * nbk3 ),// 1265 (const char * )v -> data + (iv2 * nbv2 + iv3 * nbv3 ),// 1266mp ,// 1267sinks_buffer .data (),// 1268dst_buffer .data (),// 1269scale ,logit_softcap ,slope ,nek1 ,nbk1 ,nbv1 ,DV ,DK ,tcm_buffer ,tcm_buffer_size ); 1270 }else if (tcm_buffer != nullptr && 2 * KV_row_size < tcm_buffer_size && ir < (ir1 - 1 )&& mp_equal_2 && 1271ik3_1 == ik3 && ik2_1 == ik2 && iv3_1 == iv3 && iv2_1 == iv2 ) { 1272ir_step = 2 ; 1273 1274pq_buffer [0 ]= (float * ) ((char * )q -> data + (iq1 * nbq1 + iq2 * nbq2 + iq3 * nbq3 )); 1275pq_buffer [1 ]= (float * ) ((char * )q -> data + (iq1_1 * nbq1 + iq2_1 * nbq2 + iq3_1 * nbq3 )); 1276 1277sinks_buffer [0 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2 :nullptr ; 1278sinks_buffer [1 ]= sinks ? ((float * ) ((char * )sinks -> data ))+ iq2_1 :nullptr ; 1279 1280dst_buffer [0 ]= (float * ) ((char * )dst -> data + (iq3 * ne2 * ne1 + iq2 + iq1 * ne1 )* nb1 ); 1281dst_buffer [1 ]= (float * ) ((char * )dst -> data + (iq3_1 * ne2 * ne1 + iq2_1 + iq1_1 * ne1 )* nb1 ); 1282 1283flash_attn_ext_f16_one_chunk_inner_vlen1024_vf16_mrow < 2 > (// 1284pq_buffer .data (),// 1285 (const char * )k -> data + (ik2 * nbk2 + ik3 * nbk3 ),// 1286 (const char * )v -> data + (iv2 * nbv2 + iv3 * nbv3 ),// 1287mp ,// 1288sinks_buffer .data (),// 1289dst_buffer .data (),// 1290scale ,logit_softcap ,slope ,nek1 ,nbk1 ,nbv1 ,DV ,DK ,tcm_buffer ,tcm_buffer_size ); 1291 }else { 1292ir_step = 1 ; 1293flash_attn_ext_f16_one_chunk_inner_vlen1024_vf16_m1 (// 1294pq ,// 1295 (const char * )k -> data + (ik2 * nbk2 + ik3 * nbk3 ),// 1296 (const char * )v -> data + (iv2 * nbv2 + iv3 * nbv3 ),// 1297mp ,// 1298sinks ? ((float * ) ((char * )sinks -> data ))+ h :nullptr ,// 1299 (float * ) ((char * )dst -> data + (iq3 * ne2 * ne1 + iq2 + iq1 * ne1 )* nb1 ),// 1300scale ,logit_softcap ,slope ,nek1 ,nbk1 ,nbv1 ,DV ,DK ); 1301 } 1302 } 1303} 1304 1305void forward_flash_attn_ext_f16_tiled_vlen1024_vf16 (const ggml_compute_params * params , 1306ggml_tensor * dst , 1307int ir0 , 1308int ir1 , 1309void * tcm_buffer , 1310size_t tcm_buffer_size ) { 1311const ggml_tensor * q = dst -> src [0 ]; 1312const ggml_tensor * k = dst -> src [1 ]; 1313const ggml_tensor * v = dst -> src [2 ]; 1314const ggml_tensor * mask = dst -> src [3 ]; 1315const ggml_tensor * sinks = dst -> src [4 ]; 1316 1317GGML_TENSOR_LOCALS (int64_t ,neq ,q ,ne ) 1318GGML_TENSOR_LOCALS (size_t ,nbq ,q ,nb ) 1319GGML_TENSOR_LOCALS (int64_t ,nek ,k ,ne ) 1320GGML_TENSOR_LOCALS (size_t ,nbk ,k ,nb ) 1321GGML_TENSOR_LOCALS (int64_t ,nev ,v ,ne ) 1322GGML_TENSOR_LOCALS (size_t ,nbv ,v ,nb ) 1323GGML_TENSOR_LOCALS (int64_t ,ne ,dst ,ne ) 1324GGML_TENSOR_LOCALS (size_t ,nb ,dst ,nb ) 1325 1326const int64_t DK = nek0 ; 1327const int64_t DV = nev0 ; 1328const int64_t N = neq1 ; 1329 1330GGML_ASSERT (flash_attn_ext_supported_shape_vlen1024_vf16 (DK ,DV )); 1331 1332GGML_ASSERT (ne0 == DV ); 1333GGML_ASSERT (ne2 == N ); 1334 1335// input tensor rows must be contiguous 1336GGML_ASSERT (nbq0 == ggml_type_size (q -> type )); 1337GGML_ASSERT (nbk0 == ggml_type_size (k -> type )); 1338GGML_ASSERT (nbv0 == ggml_type_size (v -> type )); 1339 1340GGML_ASSERT (neq0 == DK ); 1341GGML_ASSERT (nek0 == DK ); 1342GGML_ASSERT (nev0 == DV ); 1343 1344GGML_ASSERT (neq1 == N ); 1345 1346// dst cannot be transposed or permuted 1347GGML_ASSERT (nb0 == sizeof (float )); 1348GGML_ASSERT (nb0 <=nb1 ); 1349GGML_ASSERT (nb1 <=nb2 ); 1350GGML_ASSERT (nb2 <=nb3 ); 1351 1352GGML_ASSERT (k -> type == v -> type ); 1353const ggml_type kv_type = k -> type ; 1354 1355// broadcast factors 1356const int64_t rk2 = neq2 /nek2 ; 1357const int64_t rk3 = neq3 /nek3 ; 1358 1359const int64_t rv2 = neq2 /nev2 ; 1360const int64_t rv3 = neq3 /nev3 ; 1361 1362float * param_list = (float * )dst -> op_params ; 1363float scale = param_list [0 ]; 1364float max_bias = param_list [1 ]; 1365float logit_softcap = param_list [2 ]; 1366 1367if (logit_softcap != 0 ) { 1368scale /=logit_softcap ; 1369 } 1370 1371const uint32_t n_head = neq2 ; 1372const uint32_t n_head_log2 = 1u << (uint32_t )floor (log2 (n_head )); 1373 1374const float m0 = powf (2.0f ,- (max_bias ) /n_head_log2 ); 1375const float m1 = powf (2.0f ,- (max_bias /2.0f ) /n_head_log2 ); 1376 1377int ith = params -> ith ; 1378 1379static constexpr int Q_TILE_SZ = ggml_fa_tile_config::Q ; 1380static constexpr int KV_TILE_SZ = ggml_fa_tile_config::KV ; 1381 1382// Per-thread scratch layout: 1383// Q_f32: Q_TILE_SZ * DK 1384// KQ: Q_TILE_SZ * KV_TILE_SZ 1385// mask32: Q_TILE_SZ * KV_TILE_SZ 1386// VKQ32: Q_TILE_SZ * DV 1387// V32: KV_TILE_SZ * DV 1388// K_f32: DK * KV_TILE_SZ (transposed K tile) 1389float * base = (float * )params -> wdata + ith * (Q_TILE_SZ * DK + 2 * Q_TILE_SZ * KV_TILE_SZ + Q_TILE_SZ * DV + 1390KV_TILE_SZ * DV + KV_TILE_SZ * DK + CACHE_LINE_SIZE_F32 ); 1391const size_t base_size = 1392 (Q_TILE_SZ * DK + 2 * Q_TILE_SZ * KV_TILE_SZ + Q_TILE_SZ * DV + KV_TILE_SZ * DV + KV_TILE_SZ * DK )* 1393sizeof (float )+ 1394CACHE_LINE_SIZE_F32 ; 1395 1396if (base_size <=tcm_buffer_size && tcm_buffer != nullptr ) { 1397base = (float * )tcm_buffer ; 1398 } 1399 1400float S_M_Buf [Q_TILE_SZ * 2 ];// buffer to hold S, M, bias for one tile to reduce register pressure in main loop 1401float * S = S_M_Buf ; 1402float * M = S_M_Buf + Q_TILE_SZ ; 1403 1404int ir = ir0 ; 1405while (ir < ir1 ) { 1406// q indices for the start of this tile 1407const int iq3 = ir / (neq2 * neq1 ); 1408const int iq2 = (ir - iq3 * neq2 * neq1 ) /neq1 ; 1409const int iq1 = (ir - iq3 * neq2 * neq1 - iq2 * neq1 ); 1410 1411// Number of valid rows in this tile: 1412// - limited by tile size (Q_TILE_SZ) 1413// - limited by chunk boundary (ir1 - ir) 1414// - limited by head boundary (neq1 - iq1) to avoid crossing into next head 1415const int tile_rows = MIN (Q_TILE_SZ ,MIN ((int ) (ir1 - ir ), (int ) (neq1 - iq1 ))); 1416GGML_ASSERT (tile_rows > 0 ); 1417 1418const uint32_t h = iq2 ;// head index 1419const float slope = 1420 (max_bias > 0.0f ) ?h < n_head_log2 ?powf (m0 ,h + 1 ) :powf (m1 ,2 * (h - n_head_log2 )+ 1 ) :1.0f ; 1421 1422for (int i = 0 ;i < Q_TILE_SZ ;++ i ) { 1423S [i ]= 0. ; 1424M [i ]= - INFINITY ; 1425 } 1426 1427float * Q_f32 = base ; 1428float * KQ = (float * ) ((char * )base + Q_TILE_SZ * DK * sizeof (float )); 1429float * mask32 = KQ + Q_TILE_SZ * KV_TILE_SZ ; 1430float * VKQ32 = mask32 + Q_TILE_SZ * KV_TILE_SZ ; 1431float * V32 = VKQ32 + Q_TILE_SZ * DV ; 1432float * K_f32 = V32 + KV_TILE_SZ * DV ; 1433_Float16 * Q_f16 = (_Float16 * )Q_f32 ; 1434_Float16 * V_f16 = (_Float16 * )V32 ; 1435_Float16 * K_f16 = (_Float16 * )K_f32 ; 1436 1437rvv_zero_f32 (VKQ32 ,Q_TILE_SZ * DV ); 1438 1439// k indices 1440const int ik3 = iq3 /rk3 ; 1441const int ik2 = iq2 /rk2 ; 1442 1443// v indices 1444const int iv3 = iq3 /rv3 ; 1445const int iv2 = iq2 /rv2 ; 1446 1447const float * pq = (const float * ) ((char * )q -> data + (iq1 * nbq1 + iq2 * nbq2 + iq3 * nbq3 )); 1448if (kv_type == GGML_TYPE_F16 ) { 1449rvv_pack_f32_as_scaled_f16 ((uint8_t * )Q_f16 ,DK * sizeof (_Float16 ), (uint8_t * )pq ,nbq1 ,tile_rows ,DK , 1450scale ); 1451 }else { 1452memcpy2d (Q_f32 ,DK * sizeof (float ),pq ,nbq1 ,tile_rows ,DK * sizeof (float )); 1453 } 1454 1455for (int64_t ic = 0 ;ic < nek1 ;ic += KV_TILE_SZ ) { 1456const int kv_tile = (int ) std::min ((int64_t )KV_TILE_SZ ,nek1 - ic ); 1457 1458rvv_zero_f32 (K_f32 ,DK * KV_TILE_SZ ); 1459rvv_zero_f32 (V32 ,KV_TILE_SZ * DV ); 1460 1461// skip the tile entirely if all the masks are -inf 1462if (mask ) { 1463bool can_skip = true; 1464const ggml_fp16_t * mp_row = 1465 (const ggml_fp16_t * ) ((const char * )mask -> data + iq1 * mask -> nb [1 ]+ 1466 (iq2 %mask -> ne [2 ])* mask -> nb [2 ]+ (iq3 %mask -> ne [3 ])* mask -> nb [3 ]); 1467rvv_pack_scaled_f16_as_f32 (mask32 ,KV_TILE_SZ * sizeof (float ),mp_row + ic ,mask -> nb [1 ],tile_rows , 1468kv_tile ,slope ); 1469 1470for (int tq = 0 ;tq < tile_rows ;tq ++ ) { 1471for (int tk = 0 ;tk < kv_tile ;tk ++ ) { 1472if (mask32 [tq * KV_TILE_SZ + tk ]!= - INFINITY ) { 1473can_skip = false; 1474 } 1475 } 1476// Pad remaining mask entries with -inf 1477for (int tk = kv_tile ;tk < KV_TILE_SZ ;tk ++ ) { 1478mask32 [tq * KV_TILE_SZ + tk ]= - INFINITY ; 1479 } 1480 } 1481 1482if (can_skip ) { 1483continue ; 1484 } 1485 } 1486 1487if (kv_type == GGML_TYPE_F16 ) { 1488rvv_transposed_s16_mn_to_nm ((int8_t * )K_f16 ,KV_TILE_SZ * sizeof (_Float16 ), 1489 (int8_t * )k -> data + ic * nbk1 + ik2 * nbk2 + ik3 * nbk3 ,nbk1 ,kv_tile , 1490DK ); 1491 1492int tq = 0 ; 1493for (;tq + 3 < tile_rows ;tq += 4 ) { 1494rvv_qk_dot_tile_f16_x4 (KQ + (tq + 0 )* KV_TILE_SZ ,KQ + (tq + 1 )* KV_TILE_SZ , 1495KQ + (tq + 2 )* KV_TILE_SZ ,KQ + (tq + 3 )* KV_TILE_SZ , 1496Q_f16 + (tq + 0 )* DK ,Q_f16 + (tq + 1 )* DK ,Q_f16 + (tq + 2 )* DK , 1497Q_f16 + (tq + 3 )* DK ,K_f16 ,DK ,kv_tile ); 1498 } 1499for (;tq < tile_rows ;++ tq ) { 1500rvv_qk_dot_tile_f16_x1 (KQ + tq * KV_TILE_SZ ,Q_f16 + tq * DK ,K_f16 ,DK ,kv_tile ); 1501 } 1502 }else { 1503for (int tk = 0 ;tk < kv_tile ;tk ++ ) { 1504const char * k_data = (const char * )k -> data + (ic + tk )* nbk1 + ik2 * nbk2 + ik3 * nbk3 ; 1505float * k_col = K_f32 + tk ; 1506const float * k_src = (const float * )k_data ; 1507for (int64_t dk = 0 ;dk < DK ;++ dk ) { 1508k_col [dk * KV_TILE_SZ ]= k_src [dk ]; 1509 } 1510 } 1511 1512for (int tq = 0 ;tq < tile_rows ;++ tq ) { 1513rvv_qk_dot_tile (KQ + tq * KV_TILE_SZ ,Q_f32 + tq * DK ,K_f32 ,DK ,KV_TILE_SZ ,scale ); 1514 } 1515 } 1516 1517// Set padded KQ entries to -inf so softmax gives them zero weight 1518if (kv_tile < KV_TILE_SZ ) { 1519for (int tq = 0 ;tq < tile_rows ;tq ++ ) { 1520for (int tk = kv_tile ;tk < KV_TILE_SZ ;tk ++ ) { 1521KQ [tq * KV_TILE_SZ + tk ]= - INFINITY ; 1522 } 1523 } 1524 } 1525 1526if (logit_softcap != 0.0f ) { 1527rvv_softcap_tanh_inplace_f32 (KQ ,KV_TILE_SZ ,tile_rows ,KV_TILE_SZ ,logit_softcap ); 1528 } 1529 1530if (mask ) { 1531rvv_add_inplace_f32 (KQ ,KV_TILE_SZ ,mask32 ,KV_TILE_SZ ,tile_rows ,KV_TILE_SZ ); 1532 } 1533 1534bool skip [Q_TILE_SZ ]= {}; 1535 1536for (int tq = 0 ;tq < tile_rows ;tq ++ ) { 1537float * kq_row = KQ + tq * KV_TILE_SZ ; 1538 1539const float tile_max = rvv_max_f32 (kq_row ,KV_TILE_SZ ); 1540 1541if (tile_max == - INFINITY ) { 1542skip [tq ]= true; 1543continue ; 1544 } 1545 1546const float Mold = M [tq ]; 1547const float Mnew = fmaxf (Mold ,tile_max ); 1548 1549if (Mnew > Mold ) { 1550const float ms = expf (Mold - Mnew ); 1551rvv_scale_f32 (VKQ32 + tq * DV ,ms ,DV ); 1552S [tq ] *=ms ; 1553 } 1554M [tq ]= Mnew ; 1555 1556S [tq ]+= rvv_softmax_exp_inplace_f32 (kq_row ,KV_TILE_SZ ,Mnew ); 1557 } 1558 1559// Pack V as contiguous [KV_TILE_SZ][DV]. 1560if (kv_type == GGML_TYPE_F16 ) { 1561const char * v_data = (const char * )v -> data + ic * nbv1 + iv2 * nbv2 + iv3 * nbv3 ; 1562memcpy2d (V_f16 ,DV * sizeof (_Float16 ),v_data ,nbv1 ,kv_tile ,DV * sizeof (_Float16 )); 1563 1564int tq = 0 ; 1565for (;tq + 3 < tile_rows ;tq += 4 ) { 1566if (skip [tq + 0 ]|| skip [tq + 1 ]|| skip [tq + 2 ]|| skip [tq + 3 ]) { 1567for (int i = 0 ;i < 4 ;++ i ) { 1568if (!skip [tq + i ]) { 1569rvv_pv_accumulate_f16_x1 (VKQ32 + (tq + i )* DV ,KQ + (tq + i )* KV_TILE_SZ ,V_f16 , 1570KV_TILE_SZ ,DV ); 1571 } 1572 } 1573continue ; 1574 } 1575 1576rvv_pv_accumulate_f16_x4 (VKQ32 + (tq + 0 )* DV ,VKQ32 + (tq + 1 )* DV ,VKQ32 + (tq + 2 )* DV , 1577VKQ32 + (tq + 3 )* DV ,KQ + (tq + 0 )* KV_TILE_SZ , 1578KQ + (tq + 1 )* KV_TILE_SZ ,KQ + (tq + 2 )* KV_TILE_SZ , 1579KQ + (tq + 3 )* KV_TILE_SZ ,V_f16 ,KV_TILE_SZ ,DV ); 1580 } 1581for (;tq < tile_rows ;++ tq ) { 1582if (!skip [tq ]) { 1583rvv_pv_accumulate_f16_x1 (VKQ32 + tq * DV ,KQ + tq * KV_TILE_SZ ,V_f16 ,KV_TILE_SZ ,DV ); 1584 } 1585 } 1586 }else { 1587const char * v_data = (const char * )v -> data + ic * nbv1 + iv2 * nbv2 + iv3 * nbv3 ; 1588memcpy2d (V32 ,DV * sizeof (float ),v_data ,nbv1 ,kv_tile ,DV * sizeof (float )); 1589 1590for (int tq = 0 ;tq < tile_rows ;++ tq ) { 1591if (!skip [tq ]) { 1592rvv_pv_accumulate (VKQ32 + tq * DV ,KQ + tq * KV_TILE_SZ ,V32 ,KV_TILE_SZ ,DV ); 1593 } 1594 } 1595 } 1596 } 1597 1598// sinks (apply only to valid rows in the tile) 1599if (sinks ) { 1600const float s = ((float * ) ((char * )sinks -> data ))[h ]; 1601 1602for (int tq = 0 ;tq < tile_rows ;tq ++ ) { 1603float ms = 1.0f ; 1604float vs = 1.0f ; 1605 1606if (s > M [tq ]) { 1607ms = expf (M [tq ]- s ); 1608rvv_scale_f32 (VKQ32 + tq * DV ,ms ,DV ); 1609 }else { 1610vs = expf (s - M [tq ]); 1611 } 1612 1613float S_temp = S [tq ]* ms + vs ; 1614S [tq ]= S_temp == 0.0f ?0.0f :1.0f /S_temp ; 1615 } 1616 }else { 1617for (int tq = 0 ;tq < tile_rows ;tq ++ ) { 1618const float S_inv = S [tq ]== 0.0f ?0.0f :1.0f /S [tq ]; 1619S [tq ]= S_inv ; 1620 } 1621 } 1622 1623float * dst_ptr = (float * ) ((char * )dst -> data + (iq3 * ne2 * ne1 + iq2 + (iq1 )* ne1 )* nb1 ); 1624rvv_pack_scaled_f32_as_f32 (dst_ptr ,nb1 * ne1 ,VKQ32 ,DV * sizeof (float ),tile_rows ,DV ,S ); 1625 1626ir += tile_rows ; 1627 } 1628} 1629 1630void forward_rms_norm_f32 (ggml_compute_params * params ,ggml_tensor * op ) { 1631const ggml_tensor * src0 = op -> src [0 ]; 1632ggml_tensor * dst = op ; 1633GGML_ASSERT (ggml_are_same_shape (src0 ,dst )); 1634GGML_ASSERT (src0 -> nb [0 ]== sizeof (float )); 1635 1636int ith = params -> ith ; 1637int nth = params -> nth ; 1638 1639GGML_TENSOR_UNARY_OP_LOCALS 1640 1641float epsilon = * ((float * )dst -> op_params ); 1642 1643GGML_ASSERT (epsilon > 0.0f ); 1644 1645auto * input = (char * )src0 -> data ; 1646auto * output = (char * )dst -> data ; 1647 1648const auto hidden_size = ne00 ; 1649const auto task_count = ne01 * ne02 * ne03 ; 1650const auto task_per_thread = (task_count + nth - 1 ) /nth ; 1651 1652const auto task_begin = ith * task_per_thread ; 1653const auto task_end = std::min ((ith + 1 )* task_per_thread ,task_count ); 1654 1655for (auto task_idx = task_begin ;task_idx < task_end ;task_idx ++ ) { 1656int64_t i03 = task_idx / (ne02 * ne01 ); 1657int64_t i02 = (task_idx - i03 * ne02 * ne01 ) /ne01 ; 1658int64_t i01 = (task_idx - i03 * ne02 * ne01 - i02 * ne01 ); 1659 1660auto * p_input = (float * ) (input + i01 * nb01 + i02 * nb02 + i03 * nb03 ); 1661auto * p_output = (float * ) (output + i01 * nb1 + i02 * nb2 + i03 * nb3 ); 1662auto * p_temp_output = p_output ; 1663 1664size_t gvl = __riscv_vsetvlmax_e32m4 (); 1665vfloat32m4_t sum_sq = __riscv_vfmv_v_f_f32m4 (0.f ,gvl ); 1666int64_t length = hidden_size ; 1667while (length > 0 ) { 1668gvl = __riscv_vsetvl_e32m4 (length ); 1669vfloat32m4_t src_data = __riscv_vle32_v_f32m4 (p_input ,gvl ); 1670sum_sq = __riscv_vfmacc_vv_f32m4 (sum_sq ,src_data ,src_data ,gvl ); 1671__riscv_vse32_v_f32m4 (p_temp_output ,src_data ,gvl ); 1672 1673p_input += gvl ; 1674p_temp_output += gvl ; 1675length -= gvl ; 1676 } 1677 1678gvl = __riscv_vsetvlmax_e32m1 (); 1679vfloat32m1_t zero_v = __riscv_vfmv_v_f_f32m1 (0.f ,gvl ); 1680vfloat32m1_t mean_square_v = 1681__riscv_vfadd_vv_f32m1 (__riscv_vget_v_f32m4_f32m1 (sum_sq ,0 ),__riscv_vget_v_f32m4_f32m1 (sum_sq ,1 ),gvl ); 1682 1683mean_square_v = __riscv_vfadd_vv_f32m1 (mean_square_v ,__riscv_vget_v_f32m4_f32m1 (sum_sq ,2 ),gvl ); 1684mean_square_v = __riscv_vfadd_vv_f32m1 (mean_square_v ,__riscv_vget_v_f32m4_f32m1 (sum_sq ,3 ),gvl ); 1685mean_square_v = __riscv_vfredusum_vs_f32m1_f32m1 (mean_square_v ,zero_v ,gvl ); 1686 1687float mean_square = __riscv_vfmv_f_s_f32m1_f32 (mean_square_v ); 1688mean_square /=hidden_size ; 1689 1690mean_square = sqrt (mean_square + epsilon ); 1691 1692mean_square = 1.0f /mean_square ; 1693length = hidden_size ; 1694p_temp_output = p_output ; 1695 1696while (length > 0 ) { 1697gvl = __riscv_vsetvl_e32m4 (length ); 1698vfloat32m4_t src_data = __riscv_vle32_v_f32m4 (p_temp_output ,gvl ); 1699src_data = __riscv_vfmul_vf_f32m4 (src_data ,mean_square ,gvl ); 1700__riscv_vse32_v_f32m4 (p_output ,src_data ,gvl ); 1701p_temp_output += gvl ; 1702p_output += gvl ; 1703length -= gvl ; 1704 } 1705 } 1706} 1707 1708template < size_t MB_ROWS > 1709void quantize_a_nrow_i8_ref (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1710int64_t a_blk_stride = q8_blk_size (blk_len , true); 1711int64_t a_nrow_block_stride = a_blk_stride * MB_ROWS ; 1712for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 1713float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1714int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* MB_ROWS ); 1715int8_t * quant_a_blk = 1716reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* MB_ROWS + sizeof (int16_t )* MB_ROWS ); 1717 1718for (size_t row = 0 ;row < MB_ROWS ;row ++ ) { 1719float max_abs_a = 0.0f ; 1720for (size_t bk = 0 ;bk < blk_len ;bk ++ ) { 1721max_abs_a = std::max (max_abs_a , std::abs (a_ptr [row * count_k + k + bk ])); 1722 } 1723 1724float rep_scale_a = ((1 <<7 )- 1 ) /max_abs_a ; 1725scale_a_ptr [row ]= 1 /rep_scale_a ; 1726 1727int16_t a_sum = 0 ; 1728for (size_t bk = 0 ;bk < blk_len ;bk ++ ) { 1729const int8_t quantized = static_cast < int8_t > ( 1730 std::clamp (std::nearbyintf (a_ptr [row * count_k + k + bk ]* rep_scale_a ),-128.0f ,127.0f )); 1731quant_a_blk [row * blk_len + bk ]= quantized ; 1732a_sum += quantized ; 1733 } 1734a_sum_ptr [row ]= - a_sum ; 1735 } 1736 } 1737} 1738 1739template < size_t MB_ROWS > 1740void quantize_a_nrow_i8_hp_ref (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1741constexpr size_t k_subblk_len = 32 ; 1742const size_t subblk_count = blk_len /k_subblk_len ; 1743 1744GGML_ASSERT (blk_len == 256 ); 1745 1746float scale_temp [8 ]= {0.0f }; 1747int64_t a_blk_stride = q8_hp_blk_size (blk_len , true, true); 1748int64_t a_nrow_block_stride = a_blk_stride * MB_ROWS ; 1749int64_t a_subblk_stride = q8_hp_blk_size (k_subblk_len , false, false)* MB_ROWS ; 1750 1751for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 1752_Float16 * a_sum_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_subblk_stride * subblk_count ); 1753 1754float scale_avg = 0.0f ; 1755for (size_t kk = 0 ;kk < subblk_count ;kk ++ ) { 1756float max_abs_a = 0.0f ; 1757for (size_t row = 0 ;row < MB_ROWS ;row ++ ) { 1758for (size_t bk = 0 ;bk < k_subblk_len ;bk ++ ) { 1759max_abs_a = std::max (max_abs_a , std::abs (a_ptr [row * count_k + k + bk + kk * k_subblk_len ])); 1760 } 1761 } 1762scale_temp [kk ]= max_abs_a / ((1 <<7 )- 1 ); 1763scale_avg += scale_temp [kk ]; 1764 } 1765 1766scale_avg /=subblk_count ; 1767float scale_factor = 1.0f /scale_avg ; 1768 1769_Float16 * scale_avg_ptr = 1770reinterpret_cast < _Float16 *> (quant_a_ptr + a_nrow_block_stride - sizeof (_Float16 )* MB_ROWS ); 1771scale_avg_ptr [0 ]= scale_avg ; 1772 1773for (size_t kk = 0 ;kk < subblk_count ;kk ++ ) { 1774uint8_t * a_subblk_base = quant_a_ptr + kk * a_subblk_stride ; 1775_Float16 * scale_a_ptr = reinterpret_cast < _Float16 *> (a_subblk_base ); 1776int8_t * quant_a_blk = reinterpret_cast < int8_t *> (a_subblk_base + sizeof (_Float16 )* MB_ROWS ); 1777 1778scale_a_ptr [0 ]= static_cast < _Float16 > (scale_temp [kk ]* scale_factor ); 1779 1780const float rep_scale_a = 1.0f /scale_temp [kk ]; 1781 1782for (size_t row = 0 ;row < MB_ROWS ;row ++ ) { 1783int16_t a_sum = 0 ; 1784for (size_t bk = 0 ;bk < k_subblk_len ;bk ++ ) { 1785const int8_t quantized = static_cast < int8_t > ( 1786 std::clamp (std::nearbyintf (a_ptr [row * count_k + k + bk + kk * k_subblk_len ]* rep_scale_a ), 1787-128.0f ,127.0f )); 1788quant_a_blk [row * k_subblk_len + bk ]= quantized ; 1789a_sum += quantized ; 1790 } 1791a_sum_ptr [row * subblk_count + kk ]= static_cast < _Float16 > (- a_sum )* static_cast < _Float16 > (8.0f ); 1792 } 1793 } 1794 } 1795} 1796 1797template < size_t MB_ROWS > 1798void quantize_a_nrow_i8k_ref (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1799int64_t a_blk_stride = q8k_blk_size (256 ); 1800int64_t a_nrow_block_stride = a_blk_stride * MB_ROWS ; 1801int64_t a_sum_size = 256 /16 ; 1802 1803for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 1804float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1805int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* MB_ROWS ); 1806int8_t * quant_a_blk = 1807reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* MB_ROWS + sizeof (int16_t )* a_sum_size * MB_ROWS ); 1808 1809for (size_t row = 0 ;row < MB_ROWS ;row ++ ) { 1810float max_a = 0.0f ; 1811float max_abs_a = 0.0f ; 1812for (size_t bk = 0 ;bk < blk_len ;bk ++ ) { 1813float ax = std::abs (a_ptr [row * count_k + k + bk ]); 1814if (ax > max_abs_a ) { 1815max_abs_a = ax ; 1816max_a = a_ptr [row * count_k + k + bk ]; 1817 } 1818 } 1819 1820if (!max_abs_a ) { 1821scale_a_ptr [row ]= 0 ; 1822for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 1823for (size_t bk = bki * 16 ;bk < (bki + 1 )* 16 ;bk ++ ) { 1824quant_a_blk [row * blk_len + bk ]= 0 ; 1825 } 1826a_sum_ptr [row * a_sum_size + bki ]= 0 ; 1827 } 1828continue ; 1829 } 1830 1831float rep_scale_a = ((1 <<7 )- 1 ) /max_abs_a ; 1832scale_a_ptr [row ]= 1 /rep_scale_a ; 1833 1834for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 1835int16_t a_sum = 0 ; 1836for (size_t bk = bki * 16 ;bk < (bki + 1 )* 16 ;bk ++ ) { 1837const int8_t quantized = static_cast < int8_t > ( 1838 std::clamp (std::nearbyintf (a_ptr [row * count_k + k + bk ]* rep_scale_a ),-128.0f ,127.0f )); 1839quant_a_blk [row * blk_len + bk ]= quantized ; 1840a_sum += quantized ; 1841 } 1842a_sum_ptr [row * a_sum_size + bki ]= - a_sum ; 1843 } 1844 } 1845 } 1846} 1847 1848void quantize_a_row_i8 (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1849GGML_ASSERT (blk_len == 32 ); 1850int64_t a_blk_stride = q8_blk_size (blk_len , true); 1851size_t vlenb = __riscv_vlenb (); 1852 1853if (vlenb == 128 ) { 1854for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 1855float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1856int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )); 1857int8_t * quant_a_blk = reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )+ sizeof (int16_t )); 1858 1859size_t vl = __riscv_vsetvl_e32m1 (blk_len ); 1860vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + k ,vl ); 1861vfloat32m1_t v_a_abs = __riscv_vfabs_v_f32m1 (v_a ,vl ); 1862 1863vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 1864vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_a_abs ,tmp ,vl ); 1865float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 1866 1867float scale_a = max_abs_a / ((1 <<7 )- 1 ); 1868float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 1869scale_a_ptr [0 ]= scale_a ; 1870 1871vfloat32m1_t v_a_scale = __riscv_vfmul_vf_f32m1 (v_a ,rep_scale_a ,vl ); 1872vint16mf2_t v_a_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a_scale ,vl ); 1873vint8mf4_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a_quant ,vl ); 1874 1875vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 1876vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 1877int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 1878a_sum_ptr [0 ]= - a_sum ; 1879 1880__riscv_vse8_v_i8mf4 (quant_a_blk ,v_a_quant_i8 ,vl ); 1881 } 1882 }else if (vlenb == 32 ) { 1883for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 1884float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1885int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )); 1886int8_t * quant_a_blk = reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )+ sizeof (int16_t )); 1887 1888size_t vl = __riscv_vsetvl_e32m4 (blk_len ); 1889vfloat32m4_t v_a = __riscv_vle32_v_f32m4 (a_ptr + k ,vl ); 1890vfloat32m4_t v_a_abs = __riscv_vfabs_v_f32m4 (v_a ,vl ); 1891 1892vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 1893vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m4_f32m1 (v_a_abs ,tmp ,vl ); 1894float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 1895 1896float scale_a = max_abs_a / ((1 <<7 )- 1 ); 1897float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 1898scale_a_ptr [0 ]= scale_a ; 1899 1900vfloat32m4_t v_a_scale = __riscv_vfmul_vf_f32m4 (v_a ,rep_scale_a ,vl ); 1901vint16m2_t v_a_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a_scale ,vl ); 1902vint8m1_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a_quant ,vl ); 1903 1904vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 1905vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 1906int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 1907a_sum_ptr [0 ]= - a_sum ; 1908 1909__riscv_vse8_v_i8m1 (quant_a_blk ,v_a_quant_i8 ,vl ); 1910 } 1911 }else { 1912quantize_a_nrow_i8_ref < 1 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 1913 } 1914} 1915 1916void quantize_a_4row_i8 (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1917GGML_ASSERT (blk_len == 32 ); 1918int64_t a_blk_stride = q8_blk_size (blk_len , true); 1919int64_t a_nrow_block_stride = a_blk_stride * 4 ; 1920size_t vlenb = __riscv_vlenb (); 1921 1922if (vlenb == 128 ) { 1923for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 1924float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1925int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* 4 ); 1926int8_t * quant_a_blk = reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* 4 + sizeof (int16_t )* 4 ); 1927 1928for (size_t mi = 0 ;mi < 4 ;mi ++ ) { 1929size_t vl = __riscv_vsetvl_e32m1 (blk_len ); 1930vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + mi * count_k + k ,vl ); 1931vfloat32m1_t v_a_abs = __riscv_vfabs_v_f32m1 (v_a ,vl ); 1932 1933vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 1934vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_a_abs ,tmp ,vl ); 1935float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 1936 1937float scale_a = max_abs_a / ((1 <<7 )- 1 ); 1938float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 1939scale_a_ptr [mi ]= scale_a ; 1940 1941vfloat32m1_t v_a_scale = __riscv_vfmul_vf_f32m1 (v_a ,rep_scale_a ,vl ); 1942vint16mf2_t v_a_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a_scale ,vl ); 1943vint8mf4_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a_quant ,vl ); 1944 1945vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 1946vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 1947int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 1948a_sum_ptr [mi ]= - a_sum ; 1949 1950__riscv_vse8_v_i8mf4 (quant_a_blk + mi * blk_len ,v_a_quant_i8 ,vl ); 1951 } 1952 } 1953 }else if (vlenb == 32 ) { 1954for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 1955float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 1956int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* 4 ); 1957int8_t * quant_a_blk = reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* 4 + sizeof (int16_t )* 4 ); 1958 1959for (size_t mi = 0 ;mi < 4 ;mi ++ ) { 1960size_t vl = __riscv_vsetvl_e32m4 (blk_len ); 1961vfloat32m4_t v_a = __riscv_vle32_v_f32m4 (a_ptr + mi * count_k + k ,vl ); 1962vfloat32m4_t v_a_abs = __riscv_vfabs_v_f32m4 (v_a ,vl ); 1963 1964vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 1965vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m4_f32m1 (v_a_abs ,tmp ,vl ); 1966float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 1967 1968float scale_a = max_abs_a / ((1 <<7 )- 1 ); 1969float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 1970scale_a_ptr [mi ]= scale_a ; 1971 1972vfloat32m4_t v_a_scale = __riscv_vfmul_vf_f32m4 (v_a ,rep_scale_a ,vl ); 1973vint16m2_t v_a_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a_scale ,vl ); 1974vint8m1_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a_quant ,vl ); 1975 1976vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 1977vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 1978int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 1979a_sum_ptr [mi ]= - a_sum ; 1980 1981__riscv_vse8_v_i8m1 (quant_a_blk + mi * blk_len ,v_a_quant_i8 ,vl ); 1982 } 1983 } 1984 }else { 1985quantize_a_nrow_i8_ref < 4 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 1986 } 1987} 1988 1989void quantize_a_row_i8_hp (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 1990constexpr size_t k_subblk_len = 32 ; 1991GGML_ASSERT (blk_len == 256 ); 1992 1993constexpr size_t subblk_count = 256 /k_subblk_len ; 1994int64_t a_blk_stride = q8_hp_blk_size (blk_len , true, true); 1995int64_t a_subblk_stride = q8_hp_blk_size (k_subblk_len , false, false); 1996size_t vlenb = __riscv_vlenb (); 1997float scale_temp [subblk_count ]= {0.0f }; 1998 1999if (vlenb == 128 ) { 2000for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 2001_Float16 * a_sum_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_subblk_stride * subblk_count ); 2002_Float16 * scale_avg_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_blk_stride - sizeof (_Float16 )); 2003float scale_avg = 0.0f ; 2004 2005for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2006const float * a_src_ptr = a_ptr + k + kk * k_subblk_len ; 2007 2008size_t vl = __riscv_vsetvl_e32m1 (k_subblk_len ); 2009vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_src_ptr ,vl ); 2010vfloat32m1_t v_a_abs = __riscv_vfabs_v_f32m1 (v_a ,vl ); 2011 2012vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2013vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_a_abs ,tmp ,vl ); 2014float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 2015 2016scale_temp [kk ]= max_abs_a / ((1 <<7 )- 1 ); 2017scale_avg += scale_temp [kk ]; 2018 } 2019 2020scale_avg /=subblk_count ; 2021const float scale_factor = scale_avg ?1.0f /scale_avg :0.0f ; 2022scale_avg_ptr [0 ]= static_cast < _Float16 > (scale_avg ); 2023 2024for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2025uint8_t * a_subblk_base = quant_a_ptr + kk * a_subblk_stride ; 2026_Float16 * scale_a_ptr = reinterpret_cast < _Float16 *> (a_subblk_base ); 2027int8_t * quant_a_blk = reinterpret_cast < int8_t *> (a_subblk_base + sizeof (_Float16 )); 2028const float * a_src_ptr = a_ptr + k + kk * k_subblk_len ; 2029 2030size_t vl = __riscv_vsetvl_e32m1 (k_subblk_len ); 2031vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_src_ptr ,vl ); 2032float rep_scale_a = scale_temp [kk ] ?1.0f /scale_temp [kk ] :0.0f ; 2033scale_a_ptr [0 ]= static_cast < _Float16 > (scale_temp [kk ]* scale_factor ); 2034 2035vfloat32m1_t v_a_scale = __riscv_vfmul_vf_f32m1 (v_a ,rep_scale_a ,vl ); 2036vint16mf2_t v_a_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a_scale ,vl ); 2037vint8mf4_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a_quant ,vl ); 2038 2039vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2040vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2041int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2042a_sum_ptr [kk ]= static_cast < _Float16 > (- a_sum )* static_cast < _Float16 > (8.0f ); 2043 2044__riscv_vse8_v_i8mf4 (quant_a_blk ,v_a_quant_i8 ,vl ); 2045 } 2046 } 2047 }else if (vlenb == 32 ) { 2048for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 2049_Float16 * a_sum_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_subblk_stride * subblk_count ); 2050_Float16 * scale_avg_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_blk_stride - sizeof (_Float16 )); 2051float scale_avg = 0.0f ; 2052 2053for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2054const float * a_src_ptr = a_ptr + k + kk * k_subblk_len ; 2055 2056size_t vl = __riscv_vsetvl_e32m4 (k_subblk_len ); 2057vfloat32m4_t v_a = __riscv_vle32_v_f32m4 (a_src_ptr ,vl ); 2058vfloat32m4_t v_a_abs = __riscv_vfabs_v_f32m4 (v_a ,vl ); 2059 2060vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2061vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m4_f32m1 (v_a_abs ,tmp ,vl ); 2062float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 2063 2064scale_temp [kk ]= max_abs_a / ((1 <<7 )- 1 ); 2065scale_avg += scale_temp [kk ]; 2066 } 2067 2068scale_avg /=subblk_count ; 2069const float scale_factor = scale_avg ?1.0f /scale_avg :0.0f ; 2070scale_avg_ptr [0 ]= static_cast < _Float16 > (scale_avg ); 2071 2072for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2073uint8_t * a_subblk_base = quant_a_ptr + kk * a_subblk_stride ; 2074_Float16 * scale_a_ptr = reinterpret_cast < _Float16 *> (a_subblk_base ); 2075int8_t * quant_a_blk = reinterpret_cast < int8_t *> (a_subblk_base + sizeof (_Float16 )); 2076const float * a_src_ptr = a_ptr + k + kk * k_subblk_len ; 2077 2078size_t vl = __riscv_vsetvl_e32m4 (k_subblk_len ); 2079vfloat32m4_t v_a = __riscv_vle32_v_f32m4 (a_src_ptr ,vl ); 2080float rep_scale_a = scale_temp [kk ] ?1.0f /scale_temp [kk ] :0.0f ; 2081scale_a_ptr [0 ]= static_cast < _Float16 > (scale_temp [kk ]* scale_factor ); 2082 2083vfloat32m4_t v_a_scale = __riscv_vfmul_vf_f32m4 (v_a ,rep_scale_a ,vl ); 2084vint16m2_t v_a_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a_scale ,vl ); 2085vint8m1_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a_quant ,vl ); 2086 2087vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2088vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2089int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2090a_sum_ptr [kk ]= static_cast < _Float16 > (- a_sum )* static_cast < _Float16 > (8.0f ); 2091 2092__riscv_vse8_v_i8m1 (quant_a_blk ,v_a_quant_i8 ,vl ); 2093 } 2094 } 2095 }else { 2096quantize_a_nrow_i8_hp_ref < 1 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 2097 } 2098} 2099 2100void quantize_a_4row_i8_hp (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 2101constexpr size_t k_subblk_len = 32 ; 2102GGML_ASSERT (blk_len == 256 ); 2103 2104constexpr size_t subblk_count = 256 /k_subblk_len ; 2105int64_t a_blk_stride = q8_hp_blk_size (blk_len , true, true); 2106int64_t a_nrow_block_stride = a_blk_stride * 4 ; 2107int64_t a_subblk_stride = q8_hp_blk_size (k_subblk_len , false, false)* 4 ; 2108size_t vlenb = __riscv_vlenb (); 2109float scale_temp [subblk_count ]= {0.0f }; 2110 2111if (vlenb == 128 ) { 2112for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 2113_Float16 * a_sum_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_subblk_stride * subblk_count ); 2114_Float16 * scale_avg_ptr = 2115reinterpret_cast < _Float16 *> (quant_a_ptr + a_nrow_block_stride - sizeof (_Float16 )* 4 ); 2116float scale_avg = 0.0f ; 2117 2118for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2119const float * a_src_ptr0 = a_ptr + 0 * count_k + k + kk * k_subblk_len ; 2120const float * a_src_ptr1 = a_ptr + 1 * count_k + k + kk * k_subblk_len ; 2121const float * a_src_ptr2 = a_ptr + 2 * count_k + k + kk * k_subblk_len ; 2122const float * a_src_ptr3 = a_ptr + 3 * count_k + k + kk * k_subblk_len ; 2123 2124size_t vl = __riscv_vsetvl_e32m1 (k_subblk_len ); 2125vfloat32m1_t v_a0 = __riscv_vle32_v_f32m1 (a_src_ptr0 ,vl ); 2126vfloat32m1_t v_a1 = __riscv_vle32_v_f32m1 (a_src_ptr1 ,vl ); 2127vfloat32m1_t v_a2 = __riscv_vle32_v_f32m1 (a_src_ptr2 ,vl ); 2128vfloat32m1_t v_a3 = __riscv_vle32_v_f32m1 (a_src_ptr3 ,vl ); 2129vfloat32m1_t v_a0_abs = __riscv_vfabs_v_f32m1 (v_a0 ,vl ); 2130vfloat32m1_t v_a1_abs = __riscv_vfabs_v_f32m1 (v_a1 ,vl ); 2131vfloat32m1_t v_a2_abs = __riscv_vfabs_v_f32m1 (v_a2 ,vl ); 2132vfloat32m1_t v_a3_abs = __riscv_vfabs_v_f32m1 (v_a3 ,vl ); 2133 2134vfloat32m1_t v_max_abs = __riscv_vfmax_vv_f32m1 (v_a0_abs ,v_a1_abs ,vl ); 2135v_max_abs = __riscv_vfmax_vv_f32m1 (v_max_abs ,v_a2_abs ,vl ); 2136v_max_abs = __riscv_vfmax_vv_f32m1 (v_max_abs ,v_a3_abs ,vl ); 2137 2138vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2139vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_max_abs ,tmp ,vl ); 2140float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 2141 2142scale_temp [kk ]= max_abs_a / ((1 <<7 )- 1 ); 2143scale_avg += scale_temp [kk ]; 2144 } 2145 2146scale_avg /=subblk_count ; 2147const float scale_factor = scale_avg ?1.0f /scale_avg :0.0f ; 2148scale_avg_ptr [0 ]= static_cast < _Float16 > (scale_avg ); 2149 2150for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2151uint8_t * a_subblk_base = quant_a_ptr + kk * a_subblk_stride ; 2152_Float16 * scale_a_ptr = reinterpret_cast < _Float16 *> (a_subblk_base ); 2153int8_t * quant_a_blk = reinterpret_cast < int8_t *> (a_subblk_base + sizeof (_Float16 )* 4 ); 2154const float * a_src_ptr0 = a_ptr + 0 * count_k + k + kk * k_subblk_len ; 2155const float * a_src_ptr1 = a_ptr + 1 * count_k + k + kk * k_subblk_len ; 2156const float * a_src_ptr2 = a_ptr + 2 * count_k + k + kk * k_subblk_len ; 2157const float * a_src_ptr3 = a_ptr + 3 * count_k + k + kk * k_subblk_len ; 2158 2159size_t vl = __riscv_vsetvl_e32m1 (k_subblk_len ); 2160vfloat32m1_t v_a0 = __riscv_vle32_v_f32m1 (a_src_ptr0 ,vl ); 2161vfloat32m1_t v_a1 = __riscv_vle32_v_f32m1 (a_src_ptr1 ,vl ); 2162vfloat32m1_t v_a2 = __riscv_vle32_v_f32m1 (a_src_ptr2 ,vl ); 2163vfloat32m1_t v_a3 = __riscv_vle32_v_f32m1 (a_src_ptr3 ,vl ); 2164 2165float rep_scale_a = scale_temp [kk ] ?1.0f /scale_temp [kk ] :0.0f ; 2166scale_a_ptr [0 ]= static_cast < _Float16 > (scale_temp [kk ]* scale_factor ); 2167 2168vfloat32m1_t v_a0_scale = __riscv_vfmul_vf_f32m1 (v_a0 ,rep_scale_a ,vl ); 2169vfloat32m1_t v_a1_scale = __riscv_vfmul_vf_f32m1 (v_a1 ,rep_scale_a ,vl ); 2170vfloat32m1_t v_a2_scale = __riscv_vfmul_vf_f32m1 (v_a2 ,rep_scale_a ,vl ); 2171vfloat32m1_t v_a3_scale = __riscv_vfmul_vf_f32m1 (v_a3 ,rep_scale_a ,vl ); 2172vint16mf2_t v_a0_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a0_scale ,vl ); 2173vint16mf2_t v_a1_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a1_scale ,vl ); 2174vint16mf2_t v_a2_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a2_scale ,vl ); 2175vint16mf2_t v_a3_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a3_scale ,vl ); 2176vint8mf4_t v_a0_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a0_quant ,vl ); 2177vint8mf4_t v_a1_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a1_quant ,vl ); 2178vint8mf4_t v_a2_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a2_quant ,vl ); 2179vint8mf4_t v_a3_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a3_quant ,vl ); 2180 2181vint16m1_t tmp_sum0 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2182vint16m1_t tmp_sum1 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2183vint16m1_t tmp_sum2 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2184vint16m1_t tmp_sum3 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2185vint16m1_t v_a0_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a0_quant_i8 ,tmp_sum0 ,vl ); 2186vint16m1_t v_a1_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a1_quant_i8 ,tmp_sum1 ,vl ); 2187vint16m1_t v_a2_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a2_quant_i8 ,tmp_sum2 ,vl ); 2188vint16m1_t v_a3_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a3_quant_i8 ,tmp_sum3 ,vl ); 2189 2190a_sum_ptr [0 * subblk_count + kk ]= 2191static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a0_sum ))* static_cast < _Float16 > (8.0f ); 2192a_sum_ptr [1 * subblk_count + kk ]= 2193static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a1_sum ))* static_cast < _Float16 > (8.0f ); 2194a_sum_ptr [2 * subblk_count + kk ]= 2195static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a2_sum ))* static_cast < _Float16 > (8.0f ); 2196a_sum_ptr [3 * subblk_count + kk ]= 2197static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a3_sum ))* static_cast < _Float16 > (8.0f ); 2198 2199__riscv_vse8_v_i8mf4 (quant_a_blk + 0 * k_subblk_len ,v_a0_quant_i8 ,vl ); 2200__riscv_vse8_v_i8mf4 (quant_a_blk + 1 * k_subblk_len ,v_a1_quant_i8 ,vl ); 2201__riscv_vse8_v_i8mf4 (quant_a_blk + 2 * k_subblk_len ,v_a2_quant_i8 ,vl ); 2202__riscv_vse8_v_i8mf4 (quant_a_blk + 3 * k_subblk_len ,v_a3_quant_i8 ,vl ); 2203 } 2204 } 2205 }else if (vlenb == 32 ) { 2206for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 2207_Float16 * a_sum_ptr = reinterpret_cast < _Float16 *> (quant_a_ptr + a_subblk_stride * subblk_count ); 2208_Float16 * scale_avg_ptr = 2209reinterpret_cast < _Float16 *> (quant_a_ptr + a_nrow_block_stride - sizeof (_Float16 )* 4 ); 2210float scale_avg = 0.0f ; 2211 2212for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2213const float * a_src_ptr0 = a_ptr + 0 * count_k + k + kk * k_subblk_len ; 2214const float * a_src_ptr1 = a_ptr + 1 * count_k + k + kk * k_subblk_len ; 2215const float * a_src_ptr2 = a_ptr + 2 * count_k + k + kk * k_subblk_len ; 2216const float * a_src_ptr3 = a_ptr + 3 * count_k + k + kk * k_subblk_len ; 2217 2218size_t vl = __riscv_vsetvl_e32m4 (k_subblk_len ); 2219vfloat32m4_t v_a0 = __riscv_vle32_v_f32m4 (a_src_ptr0 ,vl ); 2220vfloat32m4_t v_a1 = __riscv_vle32_v_f32m4 (a_src_ptr1 ,vl ); 2221vfloat32m4_t v_a2 = __riscv_vle32_v_f32m4 (a_src_ptr2 ,vl ); 2222vfloat32m4_t v_a3 = __riscv_vle32_v_f32m4 (a_src_ptr3 ,vl ); 2223 2224vfloat32m4_t v_a0_abs = __riscv_vfabs_v_f32m4 (v_a0 ,vl ); 2225vfloat32m4_t v_a1_abs = __riscv_vfabs_v_f32m4 (v_a1 ,vl ); 2226vfloat32m4_t v_a2_abs = __riscv_vfabs_v_f32m4 (v_a2 ,vl ); 2227vfloat32m4_t v_a3_abs = __riscv_vfabs_v_f32m4 (v_a3 ,vl ); 2228 2229vfloat32m4_t v_max_abs = __riscv_vfmax_vv_f32m4 (v_a0_abs ,v_a1_abs ,vl ); 2230v_max_abs = __riscv_vfmax_vv_f32m4 (v_max_abs ,v_a2_abs ,vl ); 2231v_max_abs = __riscv_vfmax_vv_f32m4 (v_max_abs ,v_a3_abs ,vl ); 2232 2233vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2234vfloat32m1_t v_a_max = __riscv_vfredmax_vs_f32m4_f32m1 (v_max_abs ,tmp ,vl ); 2235float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_a_max ); 2236 2237scale_temp [kk ]= max_abs_a / ((1 <<7 )- 1 ); 2238scale_avg += scale_temp [kk ]; 2239 } 2240 2241scale_avg /=subblk_count ; 2242const float scale_factor = scale_avg ?1.0f /scale_avg :0.0f ; 2243scale_avg_ptr [0 ]= static_cast < _Float16 > (scale_avg ); 2244 2245for (size_t kk = 0 ;kk < subblk_count ;++ kk ) { 2246uint8_t * a_subblk_base = quant_a_ptr + kk * a_subblk_stride ; 2247_Float16 * scale_a_ptr = reinterpret_cast < _Float16 *> (a_subblk_base ); 2248int8_t * quant_a_blk = reinterpret_cast < int8_t *> (a_subblk_base + sizeof (_Float16 )* 4 ); 2249const float * a_src_ptr0 = a_ptr + 0 * count_k + k + kk * k_subblk_len ; 2250const float * a_src_ptr1 = a_ptr + 1 * count_k + k + kk * k_subblk_len ; 2251const float * a_src_ptr2 = a_ptr + 2 * count_k + k + kk * k_subblk_len ; 2252const float * a_src_ptr3 = a_ptr + 3 * count_k + k + kk * k_subblk_len ; 2253 2254size_t vl = __riscv_vsetvl_e32m4 (k_subblk_len ); 2255vfloat32m4_t v_a0 = __riscv_vle32_v_f32m4 (a_src_ptr0 ,vl ); 2256vfloat32m4_t v_a1 = __riscv_vle32_v_f32m4 (a_src_ptr1 ,vl ); 2257vfloat32m4_t v_a2 = __riscv_vle32_v_f32m4 (a_src_ptr2 ,vl ); 2258vfloat32m4_t v_a3 = __riscv_vle32_v_f32m4 (a_src_ptr3 ,vl ); 2259 2260float rep_scale_a = scale_temp [kk ] ?1.0f /scale_temp [kk ] :0.0f ; 2261scale_a_ptr [0 ]= static_cast < _Float16 > (scale_temp [kk ]* scale_factor ); 2262 2263vfloat32m4_t v_a0_scale = __riscv_vfmul_vf_f32m4 (v_a0 ,rep_scale_a ,vl ); 2264vfloat32m4_t v_a1_scale = __riscv_vfmul_vf_f32m4 (v_a1 ,rep_scale_a ,vl ); 2265vfloat32m4_t v_a2_scale = __riscv_vfmul_vf_f32m4 (v_a2 ,rep_scale_a ,vl ); 2266vfloat32m4_t v_a3_scale = __riscv_vfmul_vf_f32m4 (v_a3 ,rep_scale_a ,vl ); 2267vint16m2_t v_a0_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a0_scale ,vl ); 2268vint16m2_t v_a1_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a1_scale ,vl ); 2269vint16m2_t v_a2_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a2_scale ,vl ); 2270vint16m2_t v_a3_quant = __riscv_vfncvt_x_f_w_i16m2 (v_a3_scale ,vl ); 2271vint8m1_t v_a0_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a0_quant ,vl ); 2272vint8m1_t v_a1_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a1_quant ,vl ); 2273vint8m1_t v_a2_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a2_quant ,vl ); 2274vint8m1_t v_a3_quant_i8 = __riscv_vncvt_x_x_w_i8m1 (v_a3_quant ,vl ); 2275 2276vint16m1_t tmp_sum0 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2277vint16m1_t tmp_sum1 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2278vint16m1_t tmp_sum2 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2279vint16m1_t tmp_sum3 = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2280vint16m1_t v_a0_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a0_quant_i8 ,tmp_sum0 ,vl ); 2281vint16m1_t v_a1_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a1_quant_i8 ,tmp_sum1 ,vl ); 2282vint16m1_t v_a2_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a2_quant_i8 ,tmp_sum2 ,vl ); 2283vint16m1_t v_a3_sum = __riscv_vwredsum_vs_i8m1_i16m1 (v_a3_quant_i8 ,tmp_sum3 ,vl ); 2284 2285a_sum_ptr [0 * subblk_count + kk ]= 2286static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a0_sum ))* static_cast < _Float16 > (8.0f ); 2287a_sum_ptr [1 * subblk_count + kk ]= 2288static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a1_sum ))* static_cast < _Float16 > (8.0f ); 2289a_sum_ptr [2 * subblk_count + kk ]= 2290static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a2_sum ))* static_cast < _Float16 > (8.0f ); 2291a_sum_ptr [3 * subblk_count + kk ]= 2292static_cast < _Float16 > (- __riscv_vmv_x_s_i16m1_i16 (v_a3_sum ))* static_cast < _Float16 > (8.0f ); 2293 2294__riscv_vse8_v_i8m1 (quant_a_blk + 0 * k_subblk_len ,v_a0_quant_i8 ,vl ); 2295__riscv_vse8_v_i8m1 (quant_a_blk + 1 * k_subblk_len ,v_a1_quant_i8 ,vl ); 2296__riscv_vse8_v_i8m1 (quant_a_blk + 2 * k_subblk_len ,v_a2_quant_i8 ,vl ); 2297__riscv_vse8_v_i8m1 (quant_a_blk + 3 * k_subblk_len ,v_a3_quant_i8 ,vl ); 2298 } 2299 } 2300 }else { 2301quantize_a_nrow_i8_hp_ref < 4 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 2302 } 2303} 2304 2305void quantize_a_row_i8k (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 2306GGML_ASSERT (blk_len == 256 ); 2307constexpr int64_t a_blk_stride = q8k_blk_size (256 ); 2308constexpr int64_t a_sum_size = 256 /16 ; 2309size_t vlenb = __riscv_vlenb (); 2310 2311if (vlenb == 128 ) { 2312// vlen = 1024 bits, can process 32 float32 elements with m1 2313for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 2314float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 2315int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )); 2316int8_t * quant_a_blk = 2317reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )+ sizeof (int16_t )* a_sum_size ); 2318 2319// Find max absolute value across all 256 elements 2320size_t vl = __riscv_vsetvl_e32m1 (16 ); 2321vfloat32m1_t v_max_abs = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2322 2323for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2324vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + k + bki * 16 ,vl ); 2325vfloat32m1_t v_a_abs = __riscv_vfabs_v_f32m1 (v_a ,vl ); 2326v_max_abs = __riscv_vfmax_vv_f32m1 (v_a_abs ,v_max_abs ,vl ); 2327 } 2328vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2329vfloat32m1_t v_local_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_max_abs ,tmp ,vl ); 2330float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_local_max ); 2331 2332float scale_a = max_abs_a / ((1 <<7 )- 1 ); 2333float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 2334scale_a_ptr [0 ]= scale_a ; 2335 2336// Quantize and compute sums for each 16-element group 2337for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2338vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + k + bki * 16 ,vl ); 2339vfloat32m1_t v_a_scale = __riscv_vfmul_vf_f32m1 (v_a ,rep_scale_a ,vl ); 2340vint16mf2_t v_a_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a_scale ,vl ); 2341vint8mf4_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a_quant ,vl ); 2342 2343vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2344vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2345int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2346a_sum_ptr [bki ]= - a_sum ; 2347 2348__riscv_vse8_v_i8mf4 (quant_a_blk + bki * 16 ,v_a_quant_i8 ,vl ); 2349 } 2350 } 2351 }else if (vlenb == 32 ) { 2352// vlen = 256 bits, can process 8 float32 elements with m1 2353for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_blk_stride ) { 2354float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 2355int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )); 2356int8_t * quant_a_blk = 2357reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )+ sizeof (int16_t )* a_sum_size ); 2358 2359// Find max absolute value across all 256 elements 2360size_t vl = __riscv_vsetvl_e32m2 (16 ); 2361vfloat32m2_t v_max_abs = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 2362 2363for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2364vfloat32m2_t v_a = __riscv_vle32_v_f32m2 (a_ptr + k + bki * 16 ,vl ); 2365vfloat32m2_t v_a_abs = __riscv_vfabs_v_f32m2 (v_a ,vl ); 2366v_max_abs = __riscv_vfmax_vv_f32m2 (v_a_abs ,v_max_abs ,vl ); 2367 } 2368vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2369vfloat32m1_t v_local_max = __riscv_vfredmax_vs_f32m2_f32m1 (v_max_abs ,tmp ,vl ); 2370float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_local_max ); 2371 2372float scale_a = max_abs_a / ((1 <<7 )- 1 ); 2373float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 2374scale_a_ptr [0 ]= scale_a ; 2375 2376// Quantize and compute sums for each 16-element group 2377for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2378vfloat32m2_t v_a = __riscv_vle32_v_f32m2 (a_ptr + k + bki * 16 ,vl ); 2379vfloat32m2_t v_a_scale = __riscv_vfmul_vf_f32m2 (v_a ,rep_scale_a ,vl ); 2380vint16m1_t v_a_quant = __riscv_vfncvt_x_f_w_i16m1 (v_a_scale ,vl ); 2381vint8mf2_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf2 (v_a_quant ,vl ); 2382 2383vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2384vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf2_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2385int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2386a_sum_ptr [bki ]= - a_sum ; 2387 2388__riscv_vse8_v_i8mf2 (quant_a_blk + bki * 16 ,v_a_quant_i8 ,vl ); 2389 } 2390 } 2391 }else { 2392quantize_a_nrow_i8k_ref < 1 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 2393 } 2394} 2395 2396void quantize_a_4row_i8k (size_t blk_len ,const float * a_ptr ,size_t count_k ,uint8_t * quant_a_ptr ) { 2397GGML_ASSERT (blk_len == 256 ); 2398constexpr int64_t a_blk_stride = q8k_blk_size (256 ); 2399constexpr int64_t a_nrow_block_stride = a_blk_stride * 4 ; 2400constexpr int64_t a_sum_size = 256 /16 ; 2401size_t vlenb = __riscv_vlenb (); 2402 2403if (vlenb == 128 ) { 2404// vlen = 1024 bits 2405for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 2406float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 2407int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* 4 ); 2408int8_t * quant_a_blk = 2409reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* 4 + sizeof (int16_t )* a_sum_size * 4 ); 2410 2411for (size_t mi = 0 ;mi < 4 ;mi ++ ) { 2412// Find max absolute value across all 256 elements for this row 2413size_t vl = __riscv_vsetvl_e32m1 (16 ); 2414vfloat32m1_t v_max_abs = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2415 2416for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2417vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + mi * count_k + k + bki * 16 ,vl ); 2418vfloat32m1_t v_a_abs = __riscv_vfabs_v_f32m1 (v_a ,vl ); 2419v_max_abs = __riscv_vfmax_vv_f32m1 (v_a_abs ,v_max_abs ,vl ); 2420 } 2421vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2422vfloat32m1_t v_local_max = __riscv_vfredmax_vs_f32m1_f32m1 (v_max_abs ,tmp ,vl ); 2423float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_local_max ); 2424 2425float scale_a = max_abs_a / ((1 <<7 )- 1 ); 2426float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 2427scale_a_ptr [mi ]= scale_a ; 2428 2429// Quantize and compute sums for each 16-element group 2430for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2431vfloat32m1_t v_a = __riscv_vle32_v_f32m1 (a_ptr + mi * count_k + k + bki * 16 ,vl ); 2432vfloat32m1_t v_a_scale = __riscv_vfmul_vf_f32m1 (v_a ,rep_scale_a ,vl ); 2433vint16mf2_t v_a_quant = __riscv_vfncvt_x_f_w_i16mf2 (v_a_scale ,vl ); 2434vint8mf4_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf4 (v_a_quant ,vl ); 2435 2436vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2437vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf4_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2438int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2439a_sum_ptr [mi * a_sum_size + bki ]= - a_sum ; 2440 2441__riscv_vse8_v_i8mf4 (quant_a_blk + mi * blk_len + bki * 16 ,v_a_quant_i8 ,vl ); 2442 } 2443 } 2444 } 2445 }else if (vlenb == 32 ) { 2446// vlen = 256 bits 2447for (size_t k = 0 ;k < count_k ;k += blk_len ,quant_a_ptr += a_nrow_block_stride ) { 2448float * scale_a_ptr = reinterpret_cast < float *> (quant_a_ptr ); 2449int16_t * a_sum_ptr = reinterpret_cast < int16_t *> (quant_a_ptr + sizeof (float )* 4 ); 2450int8_t * quant_a_blk = 2451reinterpret_cast < int8_t *> (quant_a_ptr + sizeof (float )* 4 + sizeof (int16_t )* a_sum_size * 4 ); 2452 2453for (size_t mi = 0 ;mi < 4 ;mi ++ ) { 2454// Find max absolute value across all 256 elements for this row 2455size_t vl = __riscv_vsetvl_e32m2 (16 ); 2456vfloat32m2_t v_max_abs = __riscv_vfmv_v_f_f32m2 (0.0f ,vl ); 2457 2458for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2459vfloat32m2_t v_a = __riscv_vle32_v_f32m2 (a_ptr + mi * count_k + k + bki * 16 ,vl ); 2460vfloat32m2_t v_a_abs = __riscv_vfabs_v_f32m2 (v_a ,vl ); 2461v_max_abs = __riscv_vfmax_vv_f32m2 (v_a_abs ,v_max_abs ,vl ); 2462 } 2463vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1 (0.0f ,vl ); 2464vfloat32m1_t v_local_max = __riscv_vfredmax_vs_f32m2_f32m1 (v_max_abs ,tmp ,vl ); 2465float max_abs_a = __riscv_vfmv_f_s_f32m1_f32 (v_local_max ); 2466 2467float scale_a = max_abs_a / ((1 <<7 )- 1 ); 2468float rep_scale_a = scale_a ?1.0f /scale_a :0.0f ; 2469scale_a_ptr [mi ]= scale_a ; 2470 2471// Quantize and compute sums for each 16-element group 2472for (size_t bki = 0 ;bki < a_sum_size ;bki ++ ) { 2473vfloat32m2_t v_a = __riscv_vle32_v_f32m2 (a_ptr + mi * count_k + k + bki * 16 ,vl ); 2474vfloat32m2_t v_a_scale = __riscv_vfmul_vf_f32m2 (v_a ,rep_scale_a ,vl ); 2475vint16m1_t v_a_quant = __riscv_vfncvt_x_f_w_i16m1 (v_a_scale ,vl ); 2476vint8mf2_t v_a_quant_i8 = __riscv_vncvt_x_x_w_i8mf2 (v_a_quant ,vl ); 2477 2478vint16m1_t tmp_sum = __riscv_vmv_v_x_i16m1 (0 ,vl ); 2479vint16m1_t v_a_sum = __riscv_vwredsum_vs_i8mf2_i16m1 (v_a_quant_i8 ,tmp_sum ,vl ); 2480int16_t a_sum = __riscv_vmv_x_s_i16m1_i16 (v_a_sum ); 2481a_sum_ptr [mi * a_sum_size + bki ]= - a_sum ; 2482 2483__riscv_vse8_v_i8mf2 (quant_a_blk + mi * blk_len + bki * 16 ,v_a_quant_i8 ,vl ); 2484 } 2485 } 2486 } 2487 }else { 2488quantize_a_nrow_i8k_ref < 4 > (blk_len ,a_ptr ,count_k ,quant_a_ptr ); 2489 } 2490} 2491 2492void forward_cpy_with_permute (ggml_compute_params * params ,ggml_tensor * op ) { 2493const ggml_tensor * src0 = op -> src [0 ]; 2494ggml_tensor * dst = op ; 2495const int ith = params -> ith ; 2496const int nth = params -> nth ; 2497 2498// [batch, m, n] -> [batch, n, m] 2499int64_t batch = src0 -> ne [2 ]* src0 -> ne [3 ]; 2500int64_t m = src0 -> ne [1 ]; 2501int64_t n = src0 -> ne [0 ]; 2502 2503int64_t batch_stride = src0 -> nb [2 ]; 2504int64_t m_src_stride = src0 -> nb [0 ]; 2505int64_t n_src_stride = src0 -> nb [1 ]; 2506int64_t n_dst_stride = n_src_stride * m ; 2507 2508permute_transpose_impl (src0 ,dst ,batch ,m ,n ,batch_stride ,m_src_stride ,n_src_stride ,n_dst_stride ,ith ,nth ); 2509} 2510 2511void forward_cont_with_permute (ggml_compute_params * params ,ggml_tensor * op ) { 2512const ggml_tensor * src0 = op -> src [0 ]; 2513ggml_tensor * dst = op ; 2514const int ith = params -> ith ; 2515const int nth = params -> nth ; 2516 2517// [batch, m, n] -> [batch, n, m] 2518int64_t batch = dst -> ne [2 ]* dst -> ne [3 ]; 2519int64_t n = dst -> ne [1 ]; 2520int64_t m = dst -> ne [0 ]; 2521 2522int64_t batch_stride = dst -> nb [2 ]; 2523int64_t m_src_stride = src0 -> nb [0 ]; 2524int64_t n_src_stride = src0 -> nb [1 ]; 2525int64_t n_dst_stride = dst -> nb [1 ]; 2526 2527permute_transpose_impl (src0 ,dst ,batch ,m ,n ,batch_stride ,m_src_stride ,n_src_stride ,n_dst_stride ,ith ,nth ); 2528} 2529 2530void forward_norm_f32 (ggml_compute_params * params ,ggml_tensor * op ) { 2531const ggml_tensor * src0 = op -> src [0 ]; 2532ggml_tensor * dst = op ; 2533GGML_ASSERT (ggml_are_same_shape (src0 ,dst )); 2534GGML_ASSERT (src0 -> nb [0 ]== sizeof (float )); 2535 2536int ith = params -> ith ; 2537int nth = params -> nth ; 2538 2539GGML_TENSOR_UNARY_OP_LOCALS 2540 2541float epsilon = * ((float * )dst -> op_params ); 2542 2543GGML_ASSERT (epsilon > 0.0f ); 2544 2545auto * input = (char * )src0 -> data ; 2546auto * output = (char * )dst -> data ; 2547 2548const auto hidden_size = ne00 ; 2549const auto task_count = ne01 * ne02 * ne03 ; 2550const auto task_per_thread = (task_count + nth - 1 ) /nth ; 2551 2552const auto task_begin = ith * task_per_thread ; 2553const auto task_end = std::min ((ith + 1 )* task_per_thread ,task_count ); 2554 2555for (auto task_idx = task_begin ;task_idx < task_end ;task_idx ++ ) { 2556int64_t i03 = task_idx / (ne02 * ne01 ); 2557int64_t i02 = (task_idx - i03 * ne02 * ne01 ) /ne01 ; 2558int64_t i01 = (task_idx - i03 * ne02 * ne01 - i02 * ne01 ); 2559 2560auto * p_input = (float * ) (input + i01 * nb01 + i02 * nb02 + i03 * nb03 ); 2561auto * p_output = (float * ) (output + i01 * nb1 + i02 * nb2 + i03 * nb3 ); 2562auto * p_temp_output = p_output ; 2563 2564size_t gvl = __riscv_vsetvlmax_e32m4 (); 2565vfloat32m4_t sum = __riscv_vfmv_v_f_f32m4 (0.f ,gvl ); 2566vfloat32m4_t sum_sq = __riscv_vfmv_v_f_f32m4 (0.f ,gvl ); 2567int64_t length = hidden_size ; 2568while (length > 0 ) { 2569gvl = __riscv_vsetvl_e32m4 (length ); 2570// load data 2571vfloat32m4_t src_data = __riscv_vle32_v_f32m4 (p_input ,gvl ); 2572 2573sum = __riscv_vfadd_vv_f32m4 (sum ,src_data ,gvl ); 2574sum_sq = __riscv_vfmacc_vv_f32m4 (sum_sq ,src_data ,src_data ,gvl ); 2575 2576__riscv_vse32_v_f32m4 (p_temp_output ,src_data ,gvl ); 2577 2578p_input += gvl ; 2579p_temp_output += gvl ; 2580length -= gvl ; 2581 } 2582 2583gvl = __riscv_vsetvlmax_e32m1 (); 2584 2585float mean = 0.f ; 2586vfloat32m1_t zero_v = __riscv_vfmv_v_f_f32m1 (0.f ,gvl ); 2587vfloat32m1_t mean_v = 2588__riscv_vfadd_vv_f32m1 (__riscv_vget_v_f32m4_f32m1 (sum ,0 ),__riscv_vget_v_f32m4_f32m1 (sum ,1 ),gvl ); 2589mean_v = __riscv_vfadd_vv_f32m1 (mean_v ,__riscv_vget_v_f32m4_f32m1 (sum ,2 ),gvl ); 2590mean_v = __riscv_vfadd_vv_f32m1 (mean_v ,__riscv_vget_v_f32m4_f32m1 (sum ,3 ),gvl ); 2591mean_v = __riscv_vfredusum_vs_f32m1_f32m1 (mean_v ,zero_v ,gvl ); 2592mean = __riscv_vfmv_f_s_f32m1_f32 (mean_v ); 2593mean /=hidden_size ; 2594 2595vfloat32m1_t mean_square_v = 2596__riscv_vfadd_vv_f32m1 (__riscv_vget_v_f32m4_f32m1 (sum_sq ,0 ),__riscv_vget_v_f32m4_f32m1 (sum_sq ,1 ),gvl ); 2597mean_square_v = __riscv_vfadd_vv_f32m1 (mean_square_v ,__riscv_vget_v_f32m4_f32m1 (sum_sq ,2 ),gvl ); 2598mean_square_v = __riscv_vfadd_vv_f32m1 (mean_square_v ,__riscv_vget_v_f32m4_f32m1 (sum_sq ,3 ),gvl ); 2599mean_square_v = __riscv_vfredusum_vs_f32m1_f32m1 (mean_square_v ,zero_v ,gvl ); 2600 2601float mean_square = __riscv_vfmv_f_s_f32m1_f32 (mean_square_v ); 2602mean_square /=hidden_size ; 2603mean_square = sqrt (mean_square - mean * mean + epsilon ); 2604 2605mean_square = 1.0f /mean_square ; 2606length = hidden_size ; 2607p_temp_output = p_output ; 2608 2609while (length > 0 ) { 2610gvl = __riscv_vsetvl_e32m4 (length ); 2611vfloat32m4_t src_data = __riscv_vle32_v_f32m4 (p_temp_output ,gvl ); 2612src_data = __riscv_vfsub_vf_f32m4 (src_data ,mean ,gvl ); 2613src_data = __riscv_vfmul_vf_f32m4 (src_data ,mean_square ,gvl ); 2614__riscv_vse32_v_f32m4 (p_output ,src_data ,gvl ); 2615p_temp_output += gvl ; 2616p_output += gvl ; 2617length -= gvl ; 2618 } 2619 } 2620} 2621 2622template < ggml_op op_type ,typename T > void forward_binary (ggml_compute_params * params ,ggml_tensor * op ) { 2623const ggml_tensor * src0 = op -> src [0 ]; 2624const ggml_tensor * src1 = op -> src [1 ]; 2625ggml_tensor * dst = op ; 2626GGML_ASSERT (ggml_can_repeat (src1 ,src0 )&& ggml_are_same_shape (src0 ,dst )); 2627 2628auto src0_rows = ggml_nrows (src0 ); 2629auto src1_rows = ggml_nrows (src1 ); 2630 2631int ith = params -> ith ; 2632int nth = params -> nth ; 2633 2634GGML_TENSOR_BINARY_OP_LOCALS 2635 2636GGML_ASSERT (nb0 == sizeof (T )); 2637GGML_ASSERT (nb00 == sizeof (T )); 2638 2639const auto [ir0 ,ir1 ]= get_thread_range (params ,src0 ); 2640 2641auto compute_func_vv = [& ](int64_t blk_len ,int64_t r ,T * src0_ptr ,T * src1_ptr ,T * dst_ptr ) { 2642int64_t idx = 0 ; 2643if constexpr (op_type == GGML_OP_ADD ) { 2644if constexpr (std::is_same_v < T ,float > ) { 2645for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2646vl = __riscv_vsetvl_e32m4 (blk_len ); 2647vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + idx + r ,vl ); 2648vfloat32m4_t rhs = __riscv_vle32_v_f32m4 (src1_ptr + idx ,vl ); 2649vfloat32m4_t res = __riscv_vfadd_vv_f32m4 (lhs ,rhs ,vl ); 2650__riscv_vse32_v_f32m4 (dst_ptr + idx + r ,res ,vl ); 2651 } 2652 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2653for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2654vl = __riscv_vsetvl_e16m4 (blk_len ); 2655vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + idx + r ),vl ); 2656vfloat16m4_t rhs = __riscv_vle16_v_f16m4 ((src1_ptr + idx ),vl ); 2657vfloat16m4_t res = __riscv_vfadd_vv_f16m4 (lhs ,rhs ,vl ); 2658__riscv_vse16_v_f16m4 ((dst_ptr + idx + r ),res ,vl ); 2659 } 2660 }else { 2661GGML_ABORT ("fatal error" ); 2662 } 2663 }else if constexpr (op_type == GGML_OP_SUB ) { 2664if constexpr (std::is_same_v < T ,float > ) { 2665for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2666vl = __riscv_vsetvl_e32m4 (blk_len ); 2667vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + idx + r ,vl ); 2668vfloat32m4_t rhs = __riscv_vle32_v_f32m4 (src1_ptr + idx ,vl ); 2669vfloat32m4_t res = __riscv_vfsub_vv_f32m4 (lhs ,rhs ,vl ); 2670__riscv_vse32_v_f32m4 (dst_ptr + idx + r ,res ,vl ); 2671 } 2672 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2673for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2674vl = __riscv_vsetvl_e16m4 (blk_len ); 2675vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + idx + r ),vl ); 2676vfloat16m4_t rhs = __riscv_vle16_v_f16m4 ((src1_ptr + idx ),vl ); 2677vfloat16m4_t res = __riscv_vfsub_vv_f16m4 (lhs ,rhs ,vl ); 2678__riscv_vse16_v_f16m4 ((dst_ptr + idx + r ),res ,vl ); 2679 } 2680 }else { 2681GGML_ABORT ("fatal error" ); 2682 } 2683 }else if constexpr (op_type == GGML_OP_MUL ) { 2684if constexpr (std::is_same_v < T ,float > ) { 2685for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2686vl = __riscv_vsetvl_e32m4 (blk_len ); 2687vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + idx + r ,vl ); 2688vfloat32m4_t rhs = __riscv_vle32_v_f32m4 (src1_ptr + idx ,vl ); 2689vfloat32m4_t res = __riscv_vfmul_vv_f32m4 (lhs ,rhs ,vl ); 2690__riscv_vse32_v_f32m4 (dst_ptr + idx + r ,res ,vl ); 2691 } 2692 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2693for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2694vl = __riscv_vsetvl_e16m4 (blk_len ); 2695vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + idx + r ),vl ); 2696vfloat16m4_t rhs = __riscv_vle16_v_f16m4 ((src1_ptr + idx ),vl ); 2697vfloat16m4_t res = __riscv_vfmul_vv_f16m4 (lhs ,rhs ,vl ); 2698__riscv_vse16_v_f16m4 ((dst_ptr + idx + r ),res ,vl ); 2699 } 2700 }else { 2701GGML_ABORT ("fatal error" ); 2702 } 2703 }else if constexpr (op_type == GGML_OP_DIV ) { 2704if constexpr (std::is_same_v < T ,float > ) { 2705for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2706vl = __riscv_vsetvl_e32m4 (blk_len ); 2707vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + idx + r ,vl ); 2708vfloat32m4_t rhs = __riscv_vle32_v_f32m4 (src1_ptr + idx ,vl ); 2709vfloat32m4_t res = __riscv_vfdiv_vv_f32m4 (lhs ,rhs ,vl ); 2710__riscv_vse32_v_f32m4 (dst_ptr + idx + r ,res ,vl ); 2711 } 2712 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2713for (size_t vl ;blk_len > 0 ;blk_len -= vl ,idx += vl ) { 2714vl = __riscv_vsetvl_e16m4 (blk_len ); 2715vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + idx + r ),vl ); 2716vfloat16m4_t rhs = __riscv_vle16_v_f16m4 ((src1_ptr + idx ),vl ); 2717vfloat16m4_t res = __riscv_vfdiv_vv_f16m4 (lhs ,rhs ,vl ); 2718__riscv_vse16_v_f16m4 ((dst_ptr + idx + r ),res ,vl ); 2719 } 2720 }else { 2721GGML_ABORT ("fatal error" ); 2722 } 2723 }else { 2724GGML_ABORT ("fatal error" ); 2725 } 2726 }; 2727 2728if (src0_rows == src1_rows && src0_rows == 1 && ne00 == ne10 ) { 2729int64_t task_per_thread = (ne00 + nth - 1 ) /nth ; 2730int64_t task_begin = ith * task_per_thread ; 2731int64_t task_end = std::min ((ith + 1 )* task_per_thread ,ne00 ); 2732 2733T * dst_ptr = ((T * )dst -> data )+ task_begin ; 2734T * src0_ptr = ((T * )src0 -> data )+ task_begin ; 2735T * src1_ptr = ((T * )src1 -> data )+ task_begin ; 2736 2737compute_func_vv (task_end - task_begin ,0 ,src0_ptr ,src1_ptr ,dst_ptr ); 2738 }else if (ne10 > 1 ) { 2739for (int64_t ir = ir0 ;ir < ir1 ;++ ir ) { 2740const int64_t i03 = ir / (ne02 * ne01 ); 2741const int64_t i02 = (ir - i03 * ne02 * ne01 ) /ne01 ; 2742const int64_t i01 = (ir - i03 * ne02 * ne01 - i02 * ne01 ); 2743 2744const int64_t i13 = i03 %ne13 ; 2745const int64_t i12 = i02 %ne12 ; 2746const int64_t i11 = i01 %ne11 ; 2747 2748T * dst_ptr = (T * ) ((char * )dst -> data + i03 * nb3 + i02 * nb2 + i01 * nb1 ); 2749T * src0_ptr = (T * ) ((char * )src0 -> data + i03 * nb03 + i02 * nb02 + i01 * nb01 ); 2750T * src1_ptr = (T * ) ((char * )src1 -> data + i13 * nb13 + i12 * nb12 + i11 * nb11 ); 2751 2752// src1 is broadcastable across src0 and dst in i1, i2, i3 2753for (int64_t r = 0 ;r < ne00 ;r += ne10 ) { 2754compute_func_vv (ne10 ,r ,src0_ptr ,src1_ptr ,dst_ptr ); 2755 } 2756 } 2757 }else { 2758for (int64_t ir = ir0 ;ir < ir1 ;++ ir ) { 2759const int64_t i03 = ir / (ne02 * ne01 ); 2760const int64_t i02 = (ir - i03 * ne02 * ne01 ) /ne01 ; 2761const int64_t i01 = (ir - i03 * ne02 * ne01 - i02 * ne01 ); 2762 2763const int64_t i13 = i03 %ne13 ; 2764const int64_t i12 = i02 %ne12 ; 2765const int64_t i11 = i01 %ne11 ; 2766 2767T * dst_ptr = (T * ) ((char * )dst -> data + i03 * nb3 + i02 * nb2 + i01 * nb1 ); 2768T * src0_ptr = (T * ) ((char * )src0 -> data + i03 * nb03 + i02 * nb02 + i01 * nb01 ); 2769T * src1_ptr = (T * ) ((char * )src1 -> data + i13 * nb13 + i12 * nb12 + i11 * nb11 ); 2770 2771T rhs_scalar = src1_ptr [0 ]; 2772int64_t blk_len = ne00 ; 2773int64_t r = 0 ; 2774 2775for (size_t vl ;blk_len > 0 ;blk_len -= vl ,r += vl ) { 2776if constexpr (op_type == GGML_OP_ADD ) { 2777if constexpr (std::is_same_v < T ,float > ) { 2778vl = __riscv_vsetvl_e32m4 (blk_len ); 2779vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + r ,vl ); 2780vfloat32m4_t res = __riscv_vfadd_vf_f32m4 (lhs ,rhs_scalar ,vl ); 2781__riscv_vse32_v_f32m4 (dst_ptr + r ,res ,vl ); 2782 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2783vl = __riscv_vsetvl_e16m4 (blk_len ); 2784vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + r ),vl ); 2785vfloat16m4_t res = __riscv_vfadd_vf_f16m4 (lhs ,rhs_scalar ,vl ); 2786__riscv_vse16_v_f16m4 ((dst_ptr + r ),res ,vl ); 2787 }else { 2788GGML_ABORT ("fatal error" ); 2789 } 2790 }else if constexpr (op_type == GGML_OP_SUB ) { 2791if constexpr (std::is_same_v < T ,float > ) { 2792vl = __riscv_vsetvl_e32m4 (blk_len ); 2793vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + r ,vl ); 2794vfloat32m4_t res = __riscv_vfsub_vf_f32m4 (lhs ,rhs_scalar ,vl ); 2795__riscv_vse32_v_f32m4 (dst_ptr + r ,res ,vl ); 2796 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2797vl = __riscv_vsetvl_e16m4 (blk_len ); 2798vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + r ),vl ); 2799vfloat16m4_t res = __riscv_vfsub_vf_f16m4 (lhs ,rhs_scalar ,vl ); 2800__riscv_vse16_v_f16m4 ((dst_ptr + r ),res ,vl ); 2801 }else { 2802GGML_ABORT ("fatal error" ); 2803 } 2804 }else if constexpr (op_type == GGML_OP_MUL ) { 2805if constexpr (std::is_same_v < T ,float > ) { 2806vl = __riscv_vsetvl_e32m4 (blk_len ); 2807vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + r ,vl ); 2808vfloat32m4_t res = __riscv_vfmul_vf_f32m4 (lhs ,rhs_scalar ,vl ); 2809__riscv_vse32_v_f32m4 (dst_ptr + r ,res ,vl ); 2810 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2811vl = __riscv_vsetvl_e16m4 (blk_len ); 2812vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + r ),vl ); 2813vfloat16m4_t res = __riscv_vfmul_vf_f16m4 (lhs ,rhs_scalar ,vl ); 2814__riscv_vse16_v_f16m4 ((dst_ptr + r ),res ,vl ); 2815 }else { 2816GGML_ABORT ("fatal error" ); 2817 } 2818 }else if constexpr (op_type == GGML_OP_DIV ) { 2819if constexpr (std::is_same_v < T ,float > ) { 2820vl = __riscv_vsetvl_e32m4 (blk_len ); 2821vfloat32m4_t lhs = __riscv_vle32_v_f32m4 (src0_ptr + r ,vl ); 2822vfloat32m4_t res = __riscv_vfdiv_vf_f32m4 (lhs ,rhs_scalar ,vl ); 2823__riscv_vse32_v_f32m4 (dst_ptr + r ,res ,vl ); 2824 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2825vl = __riscv_vsetvl_e16m4 (blk_len ); 2826vfloat16m4_t lhs = __riscv_vle16_v_f16m4 ((src0_ptr + r ),vl ); 2827vfloat16m4_t res = __riscv_vfdiv_vf_f16m4 (lhs ,rhs_scalar ,vl ); 2828__riscv_vse16_v_f16m4 ((dst_ptr + r ),res ,vl ); 2829 }else { 2830GGML_ABORT ("fatal error" ); 2831 } 2832 }else { 2833GGML_ABORT ("fatal error" ); 2834 } 2835 } 2836 } 2837 } 2838} 2839 2840template < typename T > void forward_sum_rows (const ggml_compute_params * params ,ggml_tensor * op ) { 2841const ggml_tensor * src0 = op -> src [0 ]; 2842ggml_tensor * dst = op ; 2843 2844const int ith = params -> ith ; 2845const int nth = params -> nth ; 2846 2847GGML_TENSOR_UNARY_OP_LOCALS 2848 2849GGML_ASSERT (ne0 == 1 ); 2850GGML_ASSERT (ne1 == ne01 ); 2851GGML_ASSERT (ne2 == ne02 ); 2852GGML_ASSERT (ne3 == ne03 ); 2853 2854int64_t n_task = ne01 * ne02 * ne03 ; 2855int64_t task_per_thread = (n_task + nth - 1 ) /nth ; 2856int64_t ir_start = ith * task_per_thread ; 2857int64_t ir_end = std::min (ir_start + task_per_thread ,n_task ); 2858 2859for (int64_t ir = ir_start ;ir < ir_end ;ir ++ ) { 2860const int64_t i3 = ir / (ne02 * ne01 ); 2861const int64_t i2 = (ir - i3 * ne02 * ne01 ) /ne01 ; 2862const int64_t i1 = (ir - i3 * ne02 * ne01 - i2 * ne01 ); 2863 2864T * src_row = (T * ) ((char * )src0 -> data + i1 * nb01 + i2 * nb02 + i3 * nb03 ); 2865T * dst_row = (T * ) ((char * )op -> data + i1 * nb1 + i2 * nb2 + i3 * nb3 ); 2866 2867float row_sum = 0 ; 2868 2869if constexpr (std::is_same_v < T ,float > ) { 2870size_t gvl = __riscv_vsetvlmax_e32m4 (); 2871vfloat32m4_t acc_vec = __riscv_vfmv_v_f_f32m4 (0.0f ,gvl ); 2872int64_t length = ne00 ; 2873const float * p_data = src_row ; 2874 2875while (length > 0 ) { 2876size_t vl = __riscv_vsetvl_e32m4 (length ); 2877vfloat32m4_t vec = __riscv_vle32_v_f32m4 (p_data ,vl ); 2878acc_vec = __riscv_vfadd_vv_f32m4 (acc_vec ,vec ,vl ); 2879p_data += vl ; 2880length -= vl ; 2881 } 2882 2883gvl = __riscv_vsetvlmax_e32m1 (); 2884vfloat32m1_t zero_v = __riscv_vfmv_v_f_f32m1 (0.0f ,gvl ); 2885vfloat32m1_t sum_v = __riscv_vfadd_vv_f32m1 (__riscv_vget_v_f32m4_f32m1 (acc_vec ,0 ), 2886__riscv_vget_v_f32m4_f32m1 (acc_vec ,1 ),gvl ); 2887sum_v = __riscv_vfadd_vv_f32m1 (sum_v ,__riscv_vget_v_f32m4_f32m1 (acc_vec ,2 ),gvl ); 2888sum_v = __riscv_vfadd_vv_f32m1 (sum_v ,__riscv_vget_v_f32m4_f32m1 (acc_vec ,3 ),gvl ); 2889sum_v = __riscv_vfredusum_vs_f32m1_f32m1 (sum_v ,zero_v ,gvl ); 2890row_sum = __riscv_vfmv_f_s_f32m1_f32 (sum_v ); 2891 }else if constexpr (std::is_same_v < T ,_Float16 > ) { 2892size_t gvl = __riscv_vsetvlmax_e16m2 (); 2893vfloat32m4_t acc_vec = __riscv_vfmv_v_f_f32m4 (0.0f ,gvl ); 2894int64_t length = ne00 ; 2895const _Float16 * p_data = src_row ; 2896 2897while (length > 0 ) { 2898size_t vl = __riscv_vsetvl_e16m2 (length ); 2899vfloat16m2_t vec_f16 = __riscv_vle16_v_f16m2 (p_data ,vl ); 2900vfloat32m4_t vec_f32 = __riscv_vfwcvt_f_f_v_f32m4 (vec_f16 ,vl ); 2901acc_vec = __riscv_vfadd_vv_f32m4 (acc_vec ,vec_f32 ,vl ); 2902p_data += vl ; 2903length -= vl ; 2904 } 2905 2906gvl = __riscv_vsetvlmax_e32m1 (); 2907vfloat32m1_t zero_v = __riscv_vfmv_v_f_f32m1 (0.0f ,gvl ); 2908vfloat32m1_t sum_v = __riscv_vfadd_vv_f32m1 (__riscv_vget_v_f32m4_f32m1 (acc_vec ,0 ), 2909__riscv_vget_v_f32m4_f32m1 (acc_vec ,1 ),gvl ); 2910sum_v = __riscv_vfadd_vv_f32m1 (sum_v ,__riscv_vget_v_f32m4_f32m1 (acc_vec ,2 ),gvl ); 2911sum_v = __riscv_vfadd_vv_f32m1 (sum_v ,__riscv_vget_v_f32m4_f32m1 (acc_vec ,3 ),gvl ); 2912sum_v = __riscv_vfredusum_vs_f32m1_f32m1 (sum_v ,zero_v ,gvl ); 2913row_sum = __riscv_vfmv_f_s_f32m1_f32 (sum_v ); 2914 }else { 2915GGML_ABORT ("fatal error" ); 2916 } 2917 2918dst_row [0 ]= row_sum ; 2919 } 2920} 2921 2922template < typename T > void forward_repeat_nrows (ggml_compute_params * params ,ggml_tensor * op ) { 2923const ggml_tensor * src0 = op -> src [0 ]; 2924ggml_tensor * dst = op ; 2925 2926const int ith = params -> ith ; 2927const int nth = params -> nth ; 2928 2929int64_t nrows = ggml_nrows (src0 ); 2930int64_t nrows_per_thread = (nrows + nth - 1 ) /nth ; 2931int64_t ir_start = ith * nrows_per_thread ; 2932int64_t ir_end = std::min (ir_start + nrows_per_thread ,nrows ); 2933 2934if (src0 -> ne [0 ]== 1 ) { 2935for (int64_t ir = ir_start ;ir < ir_end ;ir ++ ) { 2936T * src_row = (T * ) ((char * )src0 -> data + ir * src0 -> nb [1 ]); 2937T * dst_row = (T * ) ((char * )dst -> data + ir * dst -> nb [1 ]); 2938 2939T src_scalar = src_row [0 ]; 2940 2941int64_t length = dst -> ne [0 ]; 2942int64_t idx = 0 ; 2943size_t vl = 0 ; 2944 2945while (length > 0 ) { 2946if constexpr (std::is_same_v < T ,int32_t > ) { 2947vl = __riscv_vsetvl_e32m4 (length ); 2948vint32m4_t vec = __riscv_vmv_v_x_i32m4 (src_scalar ,vl ); 2949__riscv_vse32_v_i32m4 (dst_row + idx ,vec ,vl ); 2950 }else if constexpr (std::is_same_v < T ,int16_t > ) { 2951vl = __riscv_vsetvl_e16m4 (length ); 2952vint16m4_t vec = __riscv_vmv_v_x_i16m4 (src_scalar ,vl ); 2953__riscv_vse16_v_i16m4 ((dst_row + idx ),vec ,vl ); 2954 }else { 2955GGML_ABORT ("fatal error" ); 2956 } 2957idx += vl ; 2958length -= vl ; 2959 } 2960 } 2961 }else if (src0 -> ne [0 ]== dst -> ne [0 ]) { 2962for (int64_t ir = ir_start ;ir < ir_end ;ir ++ ) { 2963T * src_row = (T * ) ((char * )src0 -> data + ir * src0 -> nb [1 ]); 2964T * dst_row = (T * ) ((char * )dst -> data + ir * dst -> nb [1 ]); 2965 2966int64_t length = dst -> ne [0 ]; 2967int64_t idx = 0 ; 2968size_t vl = 0 ; 2969 2970while (length > 0 ) { 2971if constexpr (std::is_same_v < T ,int32_t > ) { 2972vl = __riscv_vsetvl_e32m4 (length ); 2973vint32m4_t vec = __riscv_vle32_v_i32m4 (src_row + idx ,vl ); 2974__riscv_vse32_v_i32m4 (dst_row + idx ,vec ,vl ); 2975 }else if constexpr (std::is_same_v < T ,int16_t > ) { 2976vl = __riscv_vsetvl_e16m4 (length ); 2977vint16m4_t vec = __riscv_vle16_v_i16m4 ((src_row + idx ),vl ); 2978__riscv_vse16_v_i16m4 ((dst_row + idx ),vec ,vl ); 2979 }else { 2980GGML_ABORT ("fatal error" ); 2981 } 2982idx += vl ; 2983length -= vl ; 2984 } 2985 } 2986 }else { 2987GGML_ABORT ("fatal error" ); 2988 } 2989} 2990 2991template < typename T > void forward_repeat_dim1 (ggml_compute_params * params ,ggml_tensor * op ) { 2992const ggml_tensor * src0 = op -> src [0 ]; 2993ggml_tensor * dst = op ; 2994 2995const int ith = params -> ith ; 2996const int nth = params -> nth ; 2997 2998const int64_t ne0 = dst -> ne [0 ]; 2999const int64_t ne1 = dst -> ne [1 ]; 3000const int64_t ne2 = dst -> ne [2 ]; 3001const int64_t ne3 = dst -> ne [3 ]; 3002 3003const int64_t total_batches = ne2 * ne3 ; 3004const int64_t batches_per_thread = (total_batches + nth - 1 ) /nth ; 3005const int64_t batch_start = ith * batches_per_thread ; 3006const int64_t batch_end = std::min (batch_start + batches_per_thread ,total_batches ); 3007 3008for (int64_t b = batch_start ;b < batch_end ;b ++ ) { 3009const int64_t i3 = b /ne2 ; 3010const int64_t i2 = b %ne2 ; 3011 3012T * src_base = (T * ) ((char * )src0 -> data + i2 * src0 -> nb [2 ]+ i3 * src0 -> nb [3 ]); 3013T * dst_batch = (T * ) ((char * )dst -> data + i2 * dst -> nb [2 ]+ i3 * dst -> nb [3 ]); 3014 3015for (int64_t i1 = 0 ;i1 < ne1 ;i1 ++ ) { 3016T * dst_ptr = (T * ) ((char * )dst_batch + i1 * dst -> nb [1 ]); 3017int64_t length = ne0 ; 3018int64_t idx = 0 ; 3019 3020while (length > 0 ) { 3021if constexpr (std::is_same_v < T ,int32_t > ) { 3022size_t vl = __riscv_vsetvl_e32m4 (length ); 3023vint32m4_t vec = __riscv_vle32_v_i32m4 (src_base + idx ,vl ); 3024__riscv_vse32_v_i32m4 (dst_ptr + idx ,vec ,vl ); 3025idx += vl ; 3026length -= vl ; 3027 }else if constexpr (std::is_same_v < T ,int16_t > ) { 3028size_t vl = __riscv_vsetvl_e16m4 (length ); 3029vint16m4_t vec = __riscv_vle16_v_i16m4 ((src_base + idx ),vl ); 3030__riscv_vse16_v_i16m4 ((dst_ptr + idx ),vec ,vl ); 3031idx += vl ; 3032length -= vl ; 3033 }else { 3034GGML_ABORT ("fatal error" ); 3035 } 3036 } 3037 } 3038 } 3039} 3040 3041template < typename T > void forward_get_rows (ggml_compute_params * params ,ggml_tensor * op ) { 3042const ggml_tensor * src0 = op -> src [0 ]; 3043const ggml_tensor * src1 = op -> src [1 ]; 3044ggml_tensor * dst = op ; 3045 3046GGML_TENSOR_BINARY_OP_LOCALS 3047 3048const int64_t nc = ne00 ; 3049const int64_t nr = ggml_nelements (src1 ); 3050 3051assert (ne0 == nc ); 3052assert (ne02 == ne11 ); 3053assert (nb00 == sizeof (float )); 3054assert (ggml_nrows (op )== nr ); 3055 3056const int ith = params -> ith ; 3057const int nth = params -> nth ; 3058 3059int rows_nth = nth ; 3060int cols_nth = 1 ; 3061 3062if (nr == 1 ) { 3063rows_nth = 1 ; 3064cols_nth = nth ; 3065 } 3066 3067// rows per thread 3068const int dr = (nr + rows_nth - 1 ) /rows_nth ; 3069const int dc = (nc + cols_nth - 1 ) /cols_nth ; 3070 3071int rows_ith = ith %rows_nth ; 3072int cols_ith = ith %cols_nth ; 3073 3074// row range for this thread 3075const int ir0 = dr * rows_ith ; 3076const int ir1 = MIN (ir0 + dr ,nr ); 3077 3078const int cr0 = dc * cols_ith ; 3079const int cr1 = MIN (cr0 + dc ,nc ); 3080 3081for (int64_t i = ir0 ;i < ir1 ;++ i ) { 3082const int64_t i12 = i / (ne11 * ne10 ); 3083const int64_t i11 = (i - i12 * ne11 * ne10 ) /ne10 ; 3084const int64_t i10 = (i - i12 * ne11 * ne10 - i11 * ne10 ); 3085const int64_t i01 = * (int32_t * ) ((char * )src1 -> data + i10 * nb10 + i11 * nb11 + i12 * nb12 ); 3086 3087GGML_ASSERT (i01 >=0 && i01 < ne01 ); 3088 3089memcpy1d (((char * )dst -> data + i10 * nb1 + i11 * nb2 + i12 * nb3 )+ cr0 * sizeof (T ), 3090 ((char * )src0 -> data + i01 * nb01 + i11 * nb02 + i12 * nb03 )+ cr0 * sizeof (T ), 3091 (cr1 - cr0 )* sizeof (T )); 3092 } 3093} 3094 3095template < typename T > void forward_concat (ggml_compute_params * params ,ggml_tensor * op ) { 3096const ggml_tensor * src0 = op -> src [0 ]; 3097const ggml_tensor * src1 = op -> src [1 ]; 3098ggml_tensor * dst = op ; 3099 3100GGML_ASSERT (ggml_type_size (src0 -> type )== sizeof (float )); 3101 3102GGML_TENSOR_BINARY_OP_LOCALS 3103 3104const int32_t dim = ggml_get_op_params_i32 (dst ,0 ); 3105 3106GGML_ASSERT (dim == 0 && nb0 == sizeof (float )&& nb1 == sizeof (float )* (ne00 + ne10 )); 3107 3108const int64_t nr = ggml_nrows (dst ); 3109const int64_t nc = ne0 ; 3110 3111const int ith = params -> ith ; 3112const int nth = params -> nth ; 3113 3114int rows_nth = nth ; 3115int cols_nth = 1 ; 3116 3117if (nr == 1 ) { 3118rows_nth = 1 ; 3119cols_nth = nth ; 3120 } 3121 3122const int dr = (nr + rows_nth - 1 ) /rows_nth ; 3123const int dc = (nc + cols_nth - 1 ) /cols_nth ; 3124 3125int rows_ith = ith %rows_nth ; 3126int cols_ith = ith %cols_nth ; 3127 3128// row range for this thread 3129const int ir0 = dr * rows_ith ; 3130const int ir1 = MIN (ir0 + dr ,nr ); 3131 3132const int cr0 = dc * cols_ith ; 3133const int cr1 = MIN (cr0 + dc ,nc ); 3134 3135int64_t o [4 ]= {0 ,0 ,0 ,0 }; 3136o [dim ]= src0 -> ne [dim ]; 3137const float * x ; 3138 3139for (int64_t i = ir0 ;i < ir1 ;++ i ) { 3140const int64_t i3 = i / (ne02 * ne01 ); 3141const int64_t i2 = (i - i3 * ne02 * ne01 ) /ne01 ; 3142const int64_t i1 = (i - i3 * ne02 * ne01 - i2 * ne01 ); 3143 3144for (int i0 = cr0 ;i0 < cr1 ;i0 ++ ) { 3145if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03 ) { 3146x = (const float * ) ((const char * )src0 -> data + (i0 )* nb00 + (i1 )* nb01 + (i2 )* nb02 + (i3 )* nb03 ); 3147 }else { 3148x = (const float * ) ((const char * )src1 -> data + (i0 - o [0 ])* nb10 + (i1 - o [1 ])* nb11 + 3149 (i2 - o [2 ])* nb12 + (i3 - o [3 ])* nb13 ); 3150 } 3151 3152float * y = (float * ) ((char * )dst -> data + i0 * nb0 + i1 * nb1 + i2 * nb2 + i3 * nb3 ); 3153 3154* y = * x ; 3155 } 3156 } 3157} 3158 3159template void forward_binary < GGML_OP_ADD ,float > (ggml_compute_params * params ,ggml_tensor * op ); 3160template void forward_binary < GGML_OP_SUB ,float > (ggml_compute_params * params ,ggml_tensor * op ); 3161template void forward_binary < GGML_OP_MUL ,float > (ggml_compute_params * params ,ggml_tensor * op ); 3162template void forward_binary < GGML_OP_DIV ,float > (ggml_compute_params * params ,ggml_tensor * op ); 3163template void forward_binary < GGML_OP_ADD ,_Float16 > (ggml_compute_params * params ,ggml_tensor * op ); 3164template void forward_binary < GGML_OP_SUB ,_Float16 > (ggml_compute_params * params ,ggml_tensor * op ); 3165template void forward_binary < GGML_OP_MUL ,_Float16 > (ggml_compute_params * params ,ggml_tensor * op ); 3166template void forward_binary < GGML_OP_DIV ,_Float16 > (ggml_compute_params * params ,ggml_tensor * op ); 3167template void forward_sum_rows < float > (const ggml_compute_params * params ,ggml_tensor * op ); 3168template void forward_sum_rows < _Float16 > (const ggml_compute_params * params ,ggml_tensor * op ); 3169template void forward_repeat_nrows < int32_t > (ggml_compute_params * params ,ggml_tensor * op ); 3170template void forward_repeat_nrows < int16_t > (ggml_compute_params * params ,ggml_tensor * op ); 3171template void forward_repeat_dim1 < int32_t > (ggml_compute_params * params ,ggml_tensor * op ); 3172template void forward_repeat_dim1 < int16_t > (ggml_compute_params * params ,ggml_tensor * op ); 3173template void forward_get_rows < int32_t > (ggml_compute_params * params ,ggml_tensor * op ); 3174template void forward_get_rows < int16_t > (ggml_compute_params * params ,ggml_tensor * op ); 3175template void forward_concat < int32_t > (ggml_compute_params * params ,ggml_tensor * op ); 3176template void forward_concat < int16_t > (ggml_compute_params * params ,ggml_tensor * op ); 3177 3178}// namespace spacemit_kernels::rvv