char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
13e673863
char/aliceai-t5-moe
1#ifndef HVX_BASE_H 2#define HVX_BASE_H 3 4#include <stdbool.h> 5#include <stdint.h> 6#include <math.h> 7#include <assert.h> 8 9#include "hex-utils.h" 10#include "hvx-types.h" 11 12#define hvx_vmem (A ) *((HVX_Vector *)(A)) 13#define hvx_vmemu (A ) *((HVX_UVector *)(A)) 14 15static inline void hvx_vec_store_u (void * restrictdst ,uint32_t n ,HVX_Vector v ) { 16// Rotate as needed. 17v = Q6_V_vlalign_VVR (v ,v , (size_t )dst ); 18 19uint32_t left_off = (size_t )dst & 127 ; 20uint32_t right_off = left_off + n ; 21 22HVX_VectorPred ql_not = Q6_Q_vsetq_R ((size_t )dst ); 23HVX_VectorPred qr = Q6_Q_vsetq2_R (right_off ); 24 25if (right_off > 128 ) { 26Q6_vmem_QRIV (qr , (HVX_Vector * )dst + 1 ,v ); 27// all 1's 28qr = Q6_Q_vcmp_eq_VbVb (v ,v ); 29 } 30 31ql_not = Q6_Q_or_QQn (ql_not ,qr ); 32Q6_vmem_QnRIV (ql_not , (HVX_Vector * )dst ,v ); 33} 34 35static inline void hvx_vec_store_a (void * restrictdst ,uint32_t n ,HVX_Vector v ) { 36assert ((unsigned long )dst %128 == 0 ); 37HVX_VectorPred m = Q6_Q_or_QQn (Q6_Q_vsetq_R ((unsigned long )dst ),Q6_Q_vsetq2_R (n )); 38Q6_vmem_QnRIV (m , (HVX_Vector * )dst ,v ); 39} 40 41static inline HVX_Vector hvx_vec_splat_f32 (float v ) { 42union {float f ;uint32_t i ; }u = { .f = v }; 43return Q6_V_vsplat_R (u .i ); 44} 45 46static inline HVX_Vector hvx_vec_splat_f16 (_Float16 v ) { 47union {__fp16 f ;uint16_t i ; }u = { .f = v }; 48return Q6_Vh_vsplat_R (u .i ); 49} 50 51static inline HVX_Vector hvx_vec_repl4 (HVX_Vector v ) { 52// vdelta control to replicate first 4 bytes across all elements 53static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 540x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 550x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 560x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 570x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 580x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 590x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 600x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 610x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 62 }; 63 64HVX_Vector ctrl = * (HVX_Vector * )repl ; 65return Q6_V_vdelta_VV (v ,ctrl ); 66} 67 68static inline float hvx_vec_get_f32 (HVX_Vector v ) { 69float __attribute__((aligned (128 )))x ; 70hvx_vec_store_a (& x ,4 ,v ); 71return x ; 72} 73 74static inline int32_t hvx_vec_get_i32 (HVX_Vector v ) { 75int32_t __attribute__((aligned (128 )))x ; 76hvx_vec_store_a (& x ,4 ,v ); 77return x ; 78} 79 80static inline _Float16 hvx_vec_get_f16 (HVX_Vector v ) { 81_Float16 __attribute__((aligned (128 )))x ; 82hvx_vec_store_a (& x ,2 ,v ); 83return x ; 84} 85 86static inline HVX_Vector hvx_vec_abs_f16 (HVX_Vector v ) { 87// abs by clearing the fp16 sign bit 88HVX_Vector mask = Q6_Vh_vsplat_R (0x7fff ); 89return Q6_V_vand_VV (v ,mask ); 90} 91 92static inline HVX_Vector hvx_vec_neg_f16 (HVX_Vector v ) { 93// neg by setting the fp16 sign bit 94HVX_Vector mask = Q6_Vh_vsplat_R (0x8000 ); 95return Q6_V_vxor_VV (v ,mask ); 96} 97 98static inline HVX_Vector hvx_vec_abs_f32 (HVX_Vector v ) { 99// abs by clearing the fp32 sign bit 100HVX_Vector mask = Q6_V_vsplat_R (0x7fffffff ); 101return Q6_V_vand_VV (v ,mask ); 102} 103 104static inline HVX_Vector hvx_vec_neg_f32 (HVX_Vector v ) { 105#if __HVX_ARCH__ > 75 106return Q6_Vsf_vfneg_Vsf (v ); 107#else 108// neg by setting the fp32 sign bit 109HVX_Vector mask = Q6_V_vsplat_R (0x80000000 ); 110return Q6_V_vxor_VV (v ,mask ); 111#endif // __HVX_ARCH__ > 75 112} 113 114static inline HVX_VectorPred hvx_vec_is_nan_f16 (HVX_Vector v ) { 115const HVX_Vector vnan_exp = Q6_Vh_vsplat_R (0x7C00 ); 116const HVX_Vector vnan_frac = Q6_Vh_vsplat_R (0x7FFF ); 117 118// get pred of which are NaN, i.e., exponent bits all 1s and fraction bits non 0s 119HVX_VectorPred p_exp = Q6_Q_vcmp_eq_VhVh (Q6_V_vand_VV (v ,vnan_exp ),vnan_exp ); 120HVX_VectorPred p_frac = Q6_Q_not_Q (Q6_Q_vcmp_eq_VhVh (Q6_V_vand_VV (v ,vnan_frac ),vnan_exp )); 121return Q6_Q_and_QQ (p_exp ,p_frac ); 122} 123 124static inline HVX_Vector hvx_vec_f32_to_f16_shuff (HVX_Vector v0 ,HVX_Vector v1 ) { 125#if __HVX_ARCH__ >=81 126HVX_Vector q0 = Q6_Vqf32_equals_Vsf (v0 ); 127HVX_Vector q1 = Q6_Vqf32_equals_Vsf (v1 ); 128#else 129const HVX_Vector zero = Q6_V_vzero (); 130HVX_Vector q0 = Q6_Vqf32_vadd_VsfVsf (v0 ,zero ); 131HVX_Vector q1 = Q6_Vqf32_vadd_VsfVsf (v1 ,zero ); 132#endif 133return Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (q1 ,q0 )); 134} 135 136static inline HVX_Vector hvx_vec_f32_to_f16 (HVX_Vector v0 ,HVX_Vector v1 ) { 137return Q6_Vh_vdeal_Vh (hvx_vec_f32_to_f16_shuff (v0 ,v1 )); 138} 139 140#if __HVX_ARCH__ >=79 141static inline HVX_VectorPair hvx_vec_f16_to_f32_shuff (HVX_Vector v ) { 142const HVX_Vector one = hvx_vec_splat_f16 (1.0 ); 143HVX_VectorPair p = Q6_Wsf_vmpy_VhfVhf (v ,one ); 144return Q6_W_vcombine_VV (Q6_V_hi_W (p ),Q6_V_lo_W (p )); 145} 146static inline HVX_VectorPair hvx_vec_f16_to_f32 (HVX_Vector v ) { 147const HVX_Vector one = hvx_vec_splat_f16 (1.0 ); 148HVX_VectorPair p = Q6_Wsf_vmpy_VhfVhf (Q6_Vh_vshuff_Vh (v ),one ); 149return Q6_W_vcombine_VV (Q6_V_hi_W (p ),Q6_V_lo_W (p )); 150} 151#else 152static inline HVX_VectorPair hvx_vec_f16_to_f32_shuff (HVX_Vector v ) { 153const HVX_Vector one = hvx_vec_splat_f16 (1.0 ); 154HVX_VectorPair p = Q6_Wqf32_vmpy_VhfVhf (v ,one ); 155return Q6_W_vcombine_VV (Q6_Vsf_equals_Vqf32 (Q6_V_hi_W (p )),Q6_Vsf_equals_Vqf32 (Q6_V_lo_W (p ))); 156} 157static inline HVX_VectorPair hvx_vec_f16_to_f32 (HVX_Vector v ) { 158const HVX_Vector one = hvx_vec_splat_f16 (1.0 ); 159HVX_VectorPair p = Q6_Wqf32_vmpy_VhfVhf (Q6_Vh_vshuff_Vh (v ),one ); 160return Q6_W_vcombine_VV (Q6_Vsf_equals_Vqf32 (Q6_V_hi_W (p )),Q6_Vsf_equals_Vqf32 (Q6_V_lo_W (p ))); 161} 162#endif 163 164static inline HVX_Vector hvx_vec_i16_from_hf_rnd_sat (HVX_Vector vin ) { 165// This looks complicated. 166// Ideally should just be Q6_Vh_equals_Vhf(vin) 167// but that instruction does not do proper rounding. 168 169// convert to qf32, multiplying by 1.0 in the process. 170HVX_VectorPair v32 = Q6_Wqf32_vmpy_VhfVhf (vin ,Q6_Vh_vsplat_R (0x3C00 )); 171 172// 'in-range' values are +/32752. 173// add 192K to it, convert to sf 174HVX_Vector v192K = Q6_V_vsplat_R (0x48400000 ); 175HVX_Vector vsf_0 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_Vqf32Vsf (Q6_V_lo_W (v32 ),v192K )); 176HVX_Vector vsf_1 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_Vqf32Vsf (Q6_V_hi_W (v32 ),v192K )); 177 178// for in-range cases, result is {163858... 229360} so the exponent is always 144. 179// if we extract bits 21..0 as a signed quantity, and round 6 bits off, that will be the answer. 180// Start by <<10 to get the final 'sign' bit in bit 15... 181vsf_0 = Q6_Vw_vasl_VwR (vsf_0 ,10 ); 182vsf_1 = Q6_Vw_vasl_VwR (vsf_1 ,10 ); 183 184// now round down to 16 185return Q6_Vh_vround_VwVw_sat (vsf_1 ,vsf_0 ); 186} 187 188#if __HVX_ARCH__ < 79 189 190static inline HVX_VectorPair hvx_vec_mpyacc_f32_f16 (HVX_VectorPair acc ,HVX_Vector x ,HVX_Vector y ) 191{ 192HVX_VectorPair m = Q6_Wqf32_vmpy_VhfVhf (x ,y ); 193HVX_Vector a0 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_Vqf32Vsf (Q6_V_lo_W (m ),Q6_V_lo_W (acc ))); 194HVX_Vector a1 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_Vqf32Vsf (Q6_V_hi_W (m ),Q6_V_hi_W (acc ))); 195return Q6_W_vcombine_VV (a1 ,a0 ); 196} 197 198#else 199 200static inline HVX_VectorPair hvx_vec_mpyacc_f32_f16 (HVX_VectorPair acc ,HVX_Vector x ,HVX_Vector y ) 201{ 202return Q6_Wsf_vmpyacc_WsfVhfVhf (acc ,x ,y ); 203} 204 205#endif 206 207#if __HVX_ARCH__ < 79 208 209static inline HVX_Vector hvx_vec_add_f16_f16 (HVX_Vector a ,HVX_Vector b ) 210{ 211const HVX_Vector negone = Q6_Vh_vsplat_R (0xBC00 );// -1.0 in IEEE FP16 212const HVX_Vector one = Q6_Vh_vsplat_R (0x3C00 );// 1.0 in IEEE FP16 213HVX_VectorPair a_p = Q6_Wqf32_vmpy_VhfVhf (a ,one ); 214HVX_VectorPair b_p = Q6_Wqf32_vmpy_VhfVhf (b ,negone ); 215HVX_Vector a0 = Q6_Vqf32_vsub_Vqf32Vqf32 (Q6_V_lo_W (a_p ),Q6_V_lo_W (b_p )); 216HVX_Vector a1 = Q6_Vqf32_vsub_Vqf32Vqf32 (Q6_V_hi_W (a_p ),Q6_V_hi_W (b_p )); 217return Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (a1 ,a0 )); 218} 219 220static inline HVX_Vector hvx_vec_sub_f16_f16 (HVX_Vector a ,HVX_Vector b ) 221{ 222const HVX_Vector negone = Q6_Vh_vsplat_R (0xBC00 );// -1.0 in IEEE FP16 223const HVX_Vector one = Q6_Vh_vsplat_R (0x3C00 );// 1.0 in IEEE FP16 224HVX_VectorPair a_p = Q6_Wqf32_vmpy_VhfVhf (a ,one ); 225HVX_VectorPair b_p = Q6_Wqf32_vmpy_VhfVhf (b ,negone ); 226HVX_Vector a0 = Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_lo_W (a_p ),Q6_V_lo_W (b_p )); 227HVX_Vector a1 = Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_hi_W (a_p ),Q6_V_hi_W (b_p )); 228return Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (a1 ,a0 )); 229} 230 231static inline HVX_Vector hvx_vec_mul_f16_f16 (HVX_Vector a ,HVX_Vector b ) 232{ 233return Q6_Vhf_equals_Wqf32 (Q6_Wqf32_vmpy_VhfVhf (a ,b )); 234} 235 236static inline HVX_Vector hvx_vec_add_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 237return Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (a ,b )); 238} 239 240static inline HVX_Vector hvx_vec_sub_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 241return Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vsub_VsfVsf (a ,b )); 242} 243 244static inline HVX_Vector hvx_vec_mul_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 245return Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vmpy_VsfVsf (a ,b )); 246} 247 248#else 249 250static inline HVX_Vector hvx_vec_add_f16_f16 (HVX_Vector a ,HVX_Vector b ) 251{ 252return Q6_Vhf_vadd_VhfVhf (a ,b ); 253} 254 255static inline HVX_Vector hvx_vec_sub_f16_f16 (HVX_Vector a ,HVX_Vector b ) 256{ 257return Q6_Vhf_vsub_VhfVhf (a ,b ); 258} 259 260static inline HVX_Vector hvx_vec_mul_f16_f16 (HVX_Vector a ,HVX_Vector b ) 261{ 262return Q6_Vhf_vmpy_VhfVhf (a ,b ); 263} 264 265static inline HVX_Vector hvx_vec_add_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 266return Q6_Vsf_vadd_VsfVsf (a ,b ); 267} 268 269static inline HVX_Vector hvx_vec_sub_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 270return Q6_Vsf_vsub_VsfVsf (a ,b ); 271} 272 273static inline HVX_Vector hvx_vec_mul_f32_f32 (HVX_Vector a ,HVX_Vector b ) { 274return Q6_Vsf_vmpy_VsfVsf (a ,b ); 275} 276 277#endif // __HVX_ARCH__ < 79 278 279static inline HVX_Vector hvx_vec_load_act_tile (const uint8_t * y_q ,uint32_t kt ,HVX_Vector * v_act_all ) { 280if (kt %4 == 0 ) { 281* v_act_all = hvx_vmem (y_q + kt * 32 ); 282return * v_act_all ; 283 }else if (kt %4 == 1 ) { 284return Q6_V_vror_VR (* v_act_all ,32 ); 285 }else if (kt %4 == 2 ) { 286return Q6_V_vror_VR (* v_act_all ,64 ); 287 }else { 288return Q6_V_vror_VR (* v_act_all ,96 ); 289 } 290} 291 292#endif /* HVX_BASE_H */