char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
0a50d9909
char/aliceai-t5-moe
1#ifndef HVX_FA_KERNELS_H 2#define HVX_FA_KERNELS_H 3 4#include <assert.h> 5#include <math.h> 6#include "hvx-utils.h" 7 8// Little inner kernels for HVX 9 10#if __HVX_ARCH__ < 79 11#define HVX_OP_ADD_F32 (a ,b ) Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(a, b)) 12#define HVX_OP_SUB_F32 (a ,b ) Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_VsfVsf(a, b)) 13#define HVX_OP_MUL_F32 (a ,b ) Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(a, b)) 14#else 15#define HVX_OP_ADD_F32 (a ,b ) Q6_Vsf_vadd_VsfVsf(a, b) 16#define HVX_OP_SUB_F32 (a ,b ) Q6_Vsf_vsub_VsfVsf(a, b) 17#define HVX_OP_MUL_F32 (a ,b ) Q6_Vsf_vmpy_VsfVsf(a, b) 18#endif 19 20// This is a bit of a hack because the compiler is struggling to properly inline 21// the default hvx_vec_f32_to_f16 with output into the local array. 22static __attribute__((unused )) __attribute__((noinline ))void hvx_vec_f32_to_f16_a (void * ptr ,HVX_Vector v0 ,HVX_Vector v1 ) 23{ 24* (HVX_Vector * )ptr = hvx_vec_f32_to_f16 (v0 ,v1 ); 25} 26 27// Dot product of two F16 vectors, accumulating to float 28static inline void hvx_dot_f16_f16_aa (float * restrictr ,const void * restrictx ,const void * restricty ,unsigned int n ,float s ) { 29const HVX_Vector * restrictvx = (const HVX_Vector * restrict)x ;// fp16 30const HVX_Vector * restrictvy = (const HVX_Vector * restrict)y ;// fp16 31 32uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 33uint32_t nloe = n %VLEN_FP16 ;// leftover elements 34 35HVX_VectorPair rsum_p = Q6_W_vcombine_VV (Q6_V_vsplat_R (0 ),Q6_V_vsplat_R (0 )); 36 37uint32_t i = 0 ; 38 39#pragma unroll(4) 40for (i = 0 ;i < nvec ;i ++ ) { 41rsum_p = hvx_vec_mpyacc_f32_f16 (rsum_p ,vx [i ],vy [i ]); 42 } 43 44if (nloe ) { 45HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 46HVX_Vector y_hf = Q6_V_vand_QV (bmask ,vy [i ]); 47HVX_Vector x_hf = Q6_V_vand_QV (bmask ,vx [i ]); 48 49rsum_p = hvx_vec_mpyacc_f32_f16 (rsum_p ,x_hf ,y_hf ); 50 } 51 52HVX_Vector rsum = HVX_OP_ADD_F32 (Q6_V_lo_W (rsum_p ),Q6_V_hi_W (rsum_p )); 53rsum = HVX_OP_MUL_F32 (hvx_vec_splat_f32 (s ),hvx_vec_reduce_sum_f32 (rsum )); 54hvx_vec_store_u (r ,4 ,rsum ); 55} 56 57static inline HVX_Vector hvx_dot_f16_f16_aa_rx4 (const void * restricty , 58const uint8_t * restrictx , 59const size_t stride_x , 60const size_t nvec , 61const size_t nloe ) { 62const HVX_Vector * restrictvx0 = (const HVX_Vector * restrict)x ;// fp16 63const HVX_Vector * restrictvx1 = (const HVX_Vector * restrict) (x + stride_x );// fp16 64const HVX_Vector * restrictvx2 = (const HVX_Vector * restrict) (x + stride_x * 2 );// fp16 65const HVX_Vector * restrictvx3 = (const HVX_Vector * restrict) (x + stride_x * 3 );// fp16 66const HVX_Vector * restrictvy = (const HVX_Vector * restrict)y ;// fp16 67 68HVX_VectorPair rsum0_p = Q6_W_vcombine_VV (Q6_V_vsplat_R (0 ),Q6_V_vsplat_R (0 )); 69HVX_VectorPair rsum1_p = Q6_W_vcombine_VV (Q6_V_vsplat_R (0 ),Q6_V_vsplat_R (0 )); 70HVX_VectorPair rsum2_p = Q6_W_vcombine_VV (Q6_V_vsplat_R (0 ),Q6_V_vsplat_R (0 )); 71HVX_VectorPair rsum3_p = Q6_W_vcombine_VV (Q6_V_vsplat_R (0 ),Q6_V_vsplat_R (0 )); 72 73uint32_t i = 0 ; 74 75for (i = 0 ;i < nvec ;i ++ ) { 76HVX_Vector y_hf = vy [i ]; 77HVX_Vector x0_hf = vx0 [i ]; 78HVX_Vector x1_hf = vx1 [i ]; 79HVX_Vector x2_hf = vx2 [i ]; 80HVX_Vector x3_hf = vx3 [i ]; 81 82rsum0_p = hvx_vec_mpyacc_f32_f16 (rsum0_p ,x0_hf ,y_hf ); 83rsum1_p = hvx_vec_mpyacc_f32_f16 (rsum1_p ,x1_hf ,y_hf ); 84rsum2_p = hvx_vec_mpyacc_f32_f16 (rsum2_p ,x2_hf ,y_hf ); 85rsum3_p = hvx_vec_mpyacc_f32_f16 (rsum3_p ,x3_hf ,y_hf ); 86 } 87 88if (nloe ) { 89// Load x (fp16) and zero-out unused elements 90HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 91HVX_Vector y_hf = Q6_V_vand_QV (bmask ,vy [i ]); 92HVX_Vector x0_hf = Q6_V_vand_QV (bmask ,vx0 [i ]); 93HVX_Vector x1_hf = Q6_V_vand_QV (bmask ,vx1 [i ]); 94HVX_Vector x2_hf = Q6_V_vand_QV (bmask ,vx2 [i ]); 95HVX_Vector x3_hf = Q6_V_vand_QV (bmask ,vx3 [i ]); 96 97rsum0_p = hvx_vec_mpyacc_f32_f16 (rsum0_p ,x0_hf ,y_hf ); 98rsum1_p = hvx_vec_mpyacc_f32_f16 (rsum1_p ,x1_hf ,y_hf ); 99rsum2_p = hvx_vec_mpyacc_f32_f16 (rsum2_p ,x2_hf ,y_hf ); 100rsum3_p = hvx_vec_mpyacc_f32_f16 (rsum3_p ,x3_hf ,y_hf ); 101 } 102 103HVX_Vector rsum0 = HVX_OP_ADD_F32 (Q6_V_lo_W (rsum0_p ),Q6_V_hi_W (rsum0_p )); 104HVX_Vector rsum1 = HVX_OP_ADD_F32 (Q6_V_lo_W (rsum1_p ),Q6_V_hi_W (rsum1_p )); 105HVX_Vector rsum2 = HVX_OP_ADD_F32 (Q6_V_lo_W (rsum2_p ),Q6_V_hi_W (rsum2_p )); 106HVX_Vector rsum3 = HVX_OP_ADD_F32 (Q6_V_lo_W (rsum3_p ),Q6_V_hi_W (rsum3_p )); 107 108HVX_Vector_x4 rsum0123 = { .v = {rsum0 ,rsum1 ,rsum2 ,rsum3 } }; 109return hvx_vec_reduce_sum_f32x4 (rsum0123 ); 110} 111 112static inline HVX_Vector hvx_dot_f16_f16_aa_rx32 (const void * restricty , 113const uint8_t * restrictx , 114const size_t stride_x , 115const size_t n , 116float s ) { 117 118const size_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 119const size_t nloe = n %VLEN_FP16 ;// leftover elements 120 121HVX_Vector sums = Q6_V_vzero (); 122const size_t stride_x_4 = stride_x * 4 ; 123for (uint32_t j = 0 ;j < VLEN_FP32 ;j += 4 ) { 124HVX_Vector sums_x4 = hvx_dot_f16_f16_aa_rx4 (y ,x ,stride_x ,nvec ,nloe ); 125HVX_VectorPred pred = Q6_Q_vsetq_R (j * SIZEOF_FP32 ); 126sums = Q6_V_vmux_QVV (pred ,sums ,sums_x4 ); 127x += stride_x_4 ; 128 } 129 130return HVX_OP_MUL_F32 (hvx_vec_splat_f32 (s ),sums ); 131} 132 133// MAD: y (F32) += x (F16) * s (F16) 134static inline void hvx_mad_f32_f16_aa (float * restricty ,const void * restrictx ,const __fp16 * restricts ,uint32_t n ) { 135const HVX_Vector * restrictvx0 = (const HVX_Vector * )x ; 136 137HVX_VectorPair * restrictvy_p = (HVX_VectorPair * )y ; 138HVX_Vector * restrictvy = (HVX_Vector * )y ; 139 140uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 141uint32_t nloe = n %VLEN_FP16 ;// leftover elements 142 143HVX_Vector S0 = hvx_vec_splat_f16 (* s ); 144 145uint32_t i = 0 ; 146 147#pragma unroll(2) 148for (i = 0 ;i < nvec ;++ i ) { 149vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 150 } 151 152if (nloe ) { 153HVX_VectorPair xy_p = vy_p [i ]; 154xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 155 156HVX_Vector xy = Q6_V_lo_W (xy_p ); 157i = 2 * i ;// index for vy 158 159if (nloe >=VLEN_FP32 ) { 160vy [i ]= xy ; 161nloe -= VLEN_FP32 ;++ i ;xy = Q6_V_hi_W (xy_p ); 162 } 163 164if (nloe ) { 165hvx_vec_store_a (& vy [i ],nloe * 4 ,xy ); 166 } 167 } 168} 169 170// MAD: y (F32) += x0 (F16) * s0 (F16) + x1 (F16) * s1 (F16) 171static inline void hvx_mad_f32_f16_aa_rx2 (float * restricty ,const void * restrictx0 ,const void * restrictx1 , 172const __fp16 * restricts0 ,const __fp16 * restricts1 ,uint32_t n ) { 173const HVX_Vector * restrictvx0 = (const HVX_Vector * )x0 ; 174const HVX_Vector * restrictvx1 = (const HVX_Vector * )x1 ; 175 176HVX_VectorPair * restrictvy_p = (HVX_VectorPair * )y ; 177HVX_Vector * restrictvy = (HVX_Vector * )y ; 178 179uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 180uint32_t nloe = n %VLEN_FP16 ;// leftover elements 181 182HVX_Vector S0 = hvx_vec_splat_f16 (* s0 ); 183HVX_Vector S1 = hvx_vec_splat_f16 (* s1 ); 184 185uint32_t i = 0 ; 186 187#pragma unroll(2) 188for (i = 0 ;i < nvec ;++ i ) { 189vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 190vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx1 [i ]),S1 ); 191 } 192 193if (nloe ) { 194HVX_VectorPair xy_p = vy_p [i ]; 195xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 196xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx1 [i ]),S1 ); 197 198HVX_Vector xy = Q6_V_lo_W (xy_p ); 199i = 2 * i ;// index for vy 200 201if (nloe >=VLEN_FP32 ) { 202vy [i ]= xy ; 203nloe -= VLEN_FP32 ;++ i ;xy = Q6_V_hi_W (xy_p ); 204 } 205 206if (nloe ) { 207hvx_vec_store_a (& vy [i ],nloe * 4 ,xy ); 208 } 209 } 210} 211static inline void hvx_mad_f32_f16_aa_vec (float * restricty ,const void * restrictx ,HVX_Vector S0 ,uint32_t n ) { 212const HVX_Vector * restrictvx0 = (const HVX_Vector * )x ; 213 214HVX_VectorPair * restrictvy_p = (HVX_VectorPair * )y ; 215HVX_Vector * restrictvy = (HVX_Vector * )y ; 216 217uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 218uint32_t nloe = n %VLEN_FP16 ;// leftover elements 219 220uint32_t i = 0 ; 221 222#pragma unroll(2) 223for (i = 0 ;i < nvec ;++ i ) { 224vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 225 } 226 227if (nloe ) { 228HVX_VectorPair xy_p = vy_p [i ]; 229xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 230 231HVX_Vector xy = Q6_V_lo_W (xy_p ); 232i = 2 * i ;// index for vy 233 234if (nloe >=VLEN_FP32 ) { 235vy [i ]= xy ; 236nloe -= VLEN_FP32 ;++ i ;xy = Q6_V_hi_W (xy_p ); 237 } 238 239if (nloe ) { 240hvx_vec_store_a (& vy [i ],nloe * 4 ,xy ); 241 } 242 } 243} 244 245static inline void hvx_mad_f32_f16_aa_rx2_vec (float * restricty ,const void * restrictx0 ,const void * restrictx1 , 246HVX_Vector S0 ,HVX_Vector S1 ,uint32_t n ) { 247const HVX_Vector * restrictvx0 = (const HVX_Vector * )x0 ; 248const HVX_Vector * restrictvx1 = (const HVX_Vector * )x1 ; 249 250HVX_VectorPair * restrictvy_p = (HVX_VectorPair * )y ; 251HVX_Vector * restrictvy = (HVX_Vector * )y ; 252 253uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 254uint32_t nloe = n %VLEN_FP16 ;// leftover elements 255 256uint32_t i = 0 ; 257 258#pragma unroll(2) 259for (i = 0 ;i < nvec ;++ i ) { 260vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 261vy_p [i ]= hvx_vec_mpyacc_f32_f16 (vy_p [i ],Q6_Vh_vshuff_Vh (vx1 [i ]),S1 ); 262 } 263 264if (nloe ) { 265HVX_VectorPair xy_p = vy_p [i ]; 266xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx0 [i ]),S0 ); 267xy_p = hvx_vec_mpyacc_f32_f16 (xy_p ,Q6_Vh_vshuff_Vh (vx1 [i ]),S1 ); 268 269HVX_Vector xy = Q6_V_lo_W (xy_p ); 270i = 2 * i ;// index for vy 271 272if (nloe >=VLEN_FP32 ) { 273vy [i ]= xy ; 274nloe -= VLEN_FP32 ;++ i ;xy = Q6_V_hi_W (xy_p ); 275 } 276 277if (nloe ) { 278hvx_vec_store_a (& vy [i ],nloe * 4 ,xy ); 279 } 280 } 281} 282 283static inline void hvx_scale_vec_f32_aa (uint8_t * restrictdst ,const uint8_t * restrictsrc ,const uint32_t n ,HVX_Vector vs ) { 284assert ((size_t )dst %128 == 0 ); 285assert ((size_t )src %128 == 0 ); 286 287const HVX_Vector * restrictvsrc = (const HVX_Vector * restrict)src ; 288HVX_Vector * restrictvdst = (HVX_Vector * restrict)dst ; 289 290const uint32_t nvec = n /VLEN_FP32 ; 291const uint32_t nloe = n %VLEN_FP32 ; 292 293uint32_t i = 0 ; 294#pragma unroll(4) 295for (;i < nvec ;++ i ) { 296vdst [i ]= HVX_OP_MUL_F32 (vsrc [i ],vs ); 297 } 298if (nloe ) { 299hvx_vec_store_a (& vdst [i ],nloe * sizeof (float ),HVX_OP_MUL_F32 (vsrc [i ],vs )); 300 } 301} 302 303#endif /* HVX_FA_KERNELS_H */