char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
0a50d9909
char/aliceai-t5-moe
1#ifndef HVX_REDUCE_H 2#define HVX_REDUCE_H 3 4#include <math.h> 5#include <stdbool.h> 6#include <stdint.h> 7#include <assert.h> 8 9#include "hex-utils.h" 10#include "hvx-base.h" 11#include "hvx-types.h" 12 13static inline HVX_Vector hvx_vec_reduce_sum_n_i32 (HVX_Vector in ,unsigned int n ) { 14unsigned int total = n * 4 ;// total vec nbytes 15unsigned int width = 4 ;// int32 16 17HVX_Vector sum = in ,sum_t ; 18while (width < total ) { 19sum_t = Q6_V_vror_VR (sum ,width );// rotate right 20sum = Q6_Vw_vadd_VwVw (sum_t ,sum );// elementwise sum 21width = width <<1 ; 22 } 23return sum ; 24} 25 26static inline HVX_Vector hvx_vec_reduce_sum_i32 (HVX_Vector in ) { 27return hvx_vec_reduce_sum_n_i32 (in ,32 ); 28} 29 30static inline HVX_Vector hvx_vec_reduce_sum_n_qf32 (HVX_Vector in ,unsigned int n ) { 31unsigned int total = n * 4 ;// total vec nbytes 32unsigned int width = 4 ;// fp32 nbytes 33 34HVX_Vector sum = in ,sum_t ; 35while (width < total ) { 36sum_t = Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum ),width );// rotate right 37sum = Q6_Vqf32_vadd_Vqf32Vsf (sum ,sum_t );// elementwise sum 38width = width <<1 ; 39 } 40return sum ; 41} 42 43static inline HVX_Vector hvx_vec_reduce_sum_qf32 (HVX_Vector in ) { 44return hvx_vec_reduce_sum_n_qf32 (in ,32 ); 45} 46 47#if __HVX_ARCH__ > 75 48 49static inline HVX_Vector hvx_vec_reduce_sum_f32x4 (HVX_Vector_x4 in ) { 50HVX_VectorPair sum_p01 = Q6_W_vshuff_VVR (in .v [1 ],in .v [0 ],4 ); 51HVX_VectorPair sum_p23 = Q6_W_vshuff_VVR (in .v [3 ],in .v [2 ],4 ); 52HVX_Vector sum_sf01 = Q6_Vsf_vadd_VsfVsf (Q6_V_lo_W (sum_p01 ),Q6_V_hi_W (sum_p01 )); 53HVX_Vector sum_sf23 = Q6_Vsf_vadd_VsfVsf (Q6_V_lo_W (sum_p23 ),Q6_V_hi_W (sum_p23 )); 54 55HVX_VectorPair sum_p0123 = Q6_W_vshuff_VVR (sum_sf23 ,sum_sf01 ,8 ); 56HVX_Vector sum_sf = Q6_Vsf_vadd_VsfVsf (Q6_V_lo_W (sum_p0123 ),Q6_V_hi_W (sum_p0123 )); 57 58sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /2 )); 59sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /4 )); 60sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /8 )); 61return sum_sf ; 62} 63 64static inline HVX_Vector hvx_vec_reduce_sum_f32x2 (HVX_Vector in0 ,HVX_Vector in1 ) { 65HVX_VectorPair sump = Q6_W_vshuff_VVR (in1 ,in0 ,4 ); 66HVX_Vector sum_sf = Q6_Vsf_vadd_VsfVsf (Q6_V_lo_W (sump ),Q6_V_hi_W (sump )); 67 68sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /2 )); 69sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /4 )); 70sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /8 )); 71sum_sf = Q6_Vsf_vadd_VsfVsf (sum_sf ,Q6_V_vror_VR (sum_sf ,VLEN /16 )); 72return sum_sf ; 73} 74 75static inline HVX_Vector hvx_vec_reduce_sum_n_f32 (HVX_Vector in ,unsigned int n ) { 76unsigned int total = n * 4 ;// total vec nbytes 77unsigned int width = 4 ;// fp32 nbytes 78 79HVX_Vector sum = in ,sum_t ; 80while (width < total ) { 81sum_t = Q6_V_vror_VR (sum ,width );// rotate right 82sum = Q6_Vsf_vadd_VsfVsf (sum ,sum_t );// elementwise sum 83width = width <<1 ; 84 } 85return sum ; 86} 87 88#else 89 90static inline HVX_Vector hvx_vec_reduce_sum_f32x4 (HVX_Vector_x4 in ) { 91HVX_VectorPair sum_p01 = Q6_W_vshuff_VVR (in .v [1 ],in .v [0 ],4 ); 92HVX_VectorPair sum_p23 = Q6_W_vshuff_VVR (in .v [3 ],in .v [2 ],4 ); 93HVX_Vector sum_qf01 = Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (sum_p01 ),Q6_V_hi_W (sum_p01 )); 94HVX_Vector sum_qf23 = Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (sum_p23 ),Q6_V_hi_W (sum_p23 )); 95 96HVX_VectorPair sum_p0123 = Q6_W_vshuff_VVR (Q6_Vsf_equals_Vqf32 (sum_qf23 ),Q6_Vsf_equals_Vqf32 (sum_qf01 ),8 ); 97HVX_Vector sum_qf = Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (sum_p0123 ),Q6_V_hi_W (sum_p0123 )); 98 99sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /2 )); 100sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /4 )); 101sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /8 )); 102return Q6_Vsf_equals_Vqf32 (sum_qf ); 103} 104 105static inline HVX_Vector hvx_vec_reduce_sum_f32x2 (HVX_Vector in0 ,HVX_Vector in1 ) { 106HVX_VectorPair sump = Q6_W_vshuff_VVR (in1 ,in0 ,4 ); 107HVX_Vector sum_qf = Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (sump ),Q6_V_hi_W (sump )); 108 109sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /2 )); 110sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /4 )); 111sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /8 )); 112sum_qf = Q6_Vqf32_vadd_Vqf32Vsf (sum_qf ,Q6_V_vror_VR (Q6_Vsf_equals_Vqf32 (sum_qf ),VLEN /16 )); 113return Q6_Vsf_equals_Vqf32 (sum_qf ); 114} 115 116static inline HVX_Vector hvx_vec_reduce_sum_n_f32 (HVX_Vector in ,unsigned int n ) { 117unsigned int total = n * 4 ;// total vec nbytes 118unsigned int width = 4 ;// fp32 nbytes 119 120HVX_Vector sum = in ,sum_t ; 121while (width < total ) { 122sum_t = Q6_V_vror_VR (sum ,width );// rotate right 123sum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (sum ,sum_t ));// elementwise sum 124width = width <<1 ; 125 } 126return sum ; 127} 128 129#endif 130 131static inline HVX_Vector hvx_vec_reduce_sum_f32 (HVX_Vector in ) { 132return hvx_vec_reduce_sum_n_f32 (in ,32 ); 133} 134 135static inline HVX_Vector hvx_vec_reduce_max_f16 (HVX_Vector in ) { 136unsigned total = 128 ;// total vec nbytes 137unsigned width = 2 ;// fp16 nbytes 138 139HVX_Vector _max = in ,_max_t ; 140while (width < total ) { 141_max_t = Q6_V_vror_VR (_max ,width );// rotate right 142_max = Q6_Vhf_vmax_VhfVhf (_max_t ,_max );// elementwise max 143width = width <<1 ; 144 } 145 146return _max ; 147} 148 149static inline HVX_Vector hvx_vec_reduce_max2_f16 (HVX_Vector in ,HVX_Vector _max ) { 150unsigned total = 128 ;// total vec nbytes 151unsigned width = 2 ;// fp32 nbytes 152 153HVX_Vector _max_t ; 154 155_max = Q6_Vhf_vmax_VhfVhf (in ,_max ); 156while (width < total ) { 157_max_t = Q6_V_vror_VR (_max ,width );// rotate right 158_max = Q6_Vhf_vmax_VhfVhf (_max_t ,_max );// elementwise max 159width = width <<1 ; 160 } 161 162return _max ; 163} 164 165static inline HVX_Vector hvx_vec_reduce_max_f32 (HVX_Vector in ) { 166unsigned total = 128 ;// total vec nbytes 167unsigned width = 4 ;// fp32 nbytes 168 169HVX_Vector _max = in ,_max_t ; 170while (width < total ) { 171_max_t = Q6_V_vror_VR (_max ,width );// rotate right 172_max = Q6_Vsf_vmax_VsfVsf (_max_t ,_max );// elementwise max 173width = width <<1 ; 174 } 175 176return _max ; 177} 178 179static inline HVX_Vector hvx_vec_reduce_max2_f32 (HVX_Vector in ,HVX_Vector _max ) { 180unsigned total = 128 ;// total vec nbytes 181unsigned width = 4 ;// fp32 nbytes 182 183HVX_Vector _max_t ; 184 185_max = Q6_Vsf_vmax_VsfVsf (in ,_max ); 186while (width < total ) { 187_max_t = Q6_V_vror_VR (_max ,width );// rotate right 188_max = Q6_Vsf_vmax_VsfVsf (_max_t ,_max );// elementwise max 189width = width <<1 ; 190 } 191 192return _max ; 193} 194 195#define hvx_reduce_loop_body (src_type ,init_vec ,pad_vec ,vec_op ,reduce_op ,scalar_reduce ) \ 196 do { \ 197 src_type * restrict vsrc = (src_type *) src; \ 198 HVX_Vector acc = init_vec; \ 199 \ 200 const uint32_t elem_size = sizeof(float); \ 201 const uint32_t epv = 128 / elem_size; \ 202 const uint32_t nvec = num_elems / epv; \ 203 const uint32_t nloe = num_elems % epv; \ 204 \ 205 uint32_t i = 0; \ 206 _Pragma("unroll(4)") \ 207 for (; i < nvec; i++) { \ 208 acc = vec_op(acc, vsrc[i]); \ 209 } \ 210 if (nloe) { \ 211 const float * srcf = (const float *) src + i * epv; \ 212 HVX_Vector in = *(HVX_UVector *) srcf; \ 213 HVX_Vector temp = Q6_V_valign_VVR(in, pad_vec, nloe * elem_size); \ 214 acc = vec_op(acc, temp); \ 215 } \ 216 HVX_Vector v = reduce_op(acc); \ 217 return scalar_reduce(v); \ 218 } while(0) 219 220#define HVX_REDUCE_MAX_OP (acc ,val ) Q6_Vsf_vmax_VsfVsf(acc, val) 221#define HVX_REDUCE_SUM_OP (acc ,val ) Q6_Vqf32_vadd_VsfVsf(Q6_Vsf_equals_Vqf32(acc), val) 222#define HVX_SUM_SQ_OP (acc ,val ) Q6_Vqf32_vadd_Vqf32Vqf32(acc, Q6_Vqf32_vmpy_VsfVsf(val, val)) 223#define HVX_REDUCE_MAX_SCALAR (v ) hvx_vec_get_f32(v) 224#define HVX_REDUCE_SUM_SCALAR (v ) hvx_vec_get_f32(Q6_Vsf_equals_Vqf32(v)) 225 226// Max variants 227 228static inline float hvx_reduce_max_f32_a (const uint8_t * restrictsrc ,const int num_elems ) { 229HVX_Vector init_vec = hvx_vec_splat_f32 (((const float * )src )[0 ]); 230assert ((unsigned long )src %128 == 0 ); 231hvx_reduce_loop_body (HVX_Vector ,init_vec ,init_vec ,HVX_REDUCE_MAX_OP ,hvx_vec_reduce_max_f32 ,HVX_REDUCE_MAX_SCALAR ); 232} 233 234static inline float hvx_reduce_max_f32_u (const uint8_t * restrictsrc ,const int num_elems ) { 235HVX_Vector init_vec = hvx_vec_splat_f32 (((const float * )src )[0 ]); 236hvx_reduce_loop_body (HVX_UVector ,init_vec ,init_vec ,HVX_REDUCE_MAX_OP ,hvx_vec_reduce_max_f32 ,HVX_REDUCE_MAX_SCALAR ); 237} 238 239static inline float hvx_reduce_max_f32 (const uint8_t * restrictsrc ,const int num_elems ) { 240if (hex_is_aligned ((void * )src ,128 )) { 241return hvx_reduce_max_f32_a (src ,num_elems ); 242 }else { 243return hvx_reduce_max_f32_u (src ,num_elems ); 244 } 245} 246 247// Sum variants 248 249static inline float hvx_reduce_sum_f32_a (const uint8_t * restrictsrc ,const int num_elems ) { 250HVX_Vector init_vec = Q6_V_vsplat_R (0 ); 251assert ((unsigned long )src %128 == 0 ); 252hvx_reduce_loop_body (HVX_Vector ,init_vec ,init_vec ,HVX_REDUCE_SUM_OP ,hvx_vec_reduce_sum_qf32 ,HVX_REDUCE_SUM_SCALAR ); 253} 254 255static inline float hvx_reduce_sum_f32_u (const uint8_t * restrictsrc ,const int num_elems ) { 256HVX_Vector init_vec = Q6_V_vsplat_R (0 ); 257hvx_reduce_loop_body (HVX_UVector ,init_vec ,init_vec ,HVX_REDUCE_SUM_OP ,hvx_vec_reduce_sum_qf32 ,HVX_REDUCE_SUM_SCALAR ); 258} 259 260static inline float hvx_reduce_sum_f32 (const uint8_t * restrictsrc ,const int num_elems ) { 261if (hex_is_aligned ((void * )src ,128 )) { 262return hvx_reduce_sum_f32_a (src ,num_elems ); 263 }else { 264return hvx_reduce_sum_f32_u (src ,num_elems ); 265 } 266} 267 268// Sum of squares variants 269 270static inline float hvx_sum_of_squares_f32_a (const uint8_t * restrictsrc ,const int num_elems ) { 271HVX_Vector init_vec = Q6_V_vsplat_R (0 ); 272assert ((uintptr_t )src %128 == 0 ); 273hvx_reduce_loop_body (HVX_Vector ,init_vec ,init_vec ,HVX_SUM_SQ_OP ,hvx_vec_reduce_sum_qf32 ,HVX_REDUCE_SUM_SCALAR ); 274} 275 276static inline float hvx_sum_of_squares_f32_u (const uint8_t * restrictsrc ,const int num_elems ) { 277HVX_Vector init_vec = Q6_V_vsplat_R (0 ); 278hvx_reduce_loop_body (HVX_UVector ,init_vec ,init_vec ,HVX_SUM_SQ_OP ,hvx_vec_reduce_sum_qf32 ,HVX_REDUCE_SUM_SCALAR ); 279} 280 281static inline float hvx_sum_of_squares_f32 (const uint8_t * restrictsrc ,const int num_elems ) { 282if (hex_is_aligned ((void * )src ,128 )) { 283return hvx_sum_of_squares_f32_a (src ,num_elems ); 284 }else { 285return hvx_sum_of_squares_f32_u (src ,num_elems ); 286 } 287} 288 289// Signed 32-bit Integer Max variants 290 291static inline HVX_Vector hvx_vec_reduce_max_n_i32 (HVX_Vector in ,unsigned int n ) { 292unsigned int total = n * 4 ;// total vec nbytes 293unsigned int width = 4 ;// int32 nbytes 294 295HVX_Vector max_val = in ,max_t ; 296while (width < total ) { 297max_t = Q6_V_vror_VR (max_val ,width );// rotate right 298max_val = Q6_Vw_vmax_VwVw (max_t ,max_val );// elementwise signed max 299width = width <<1 ; 300 } 301return max_val ; 302} 303 304static inline HVX_Vector hvx_vec_reduce_max_i32 (HVX_Vector in ) { 305return hvx_vec_reduce_max_n_i32 (in ,32 ); 306} 307 308static inline int32_t hvx_reduce_max_i32_a (const uint8_t * restrictsrc ,const int num_elems ) { 309HVX_Vector init_vec = Q6_V_vsplat_R (((const int32_t * )src )[0 ]); 310HVX_Vector pad_vec = Q6_V_vsplat_R (0x80000000 ); 311assert ((uintptr_t )src %128 == 0 ); 312hvx_reduce_loop_body (HVX_Vector ,init_vec ,pad_vec ,Q6_Vw_vmax_VwVw ,hvx_vec_reduce_max_i32 ,hvx_vec_get_i32 ); 313} 314 315static inline int32_t hvx_reduce_max_i32_u (const uint8_t * restrictsrc ,const int num_elems ) { 316HVX_Vector init_vec = Q6_V_vsplat_R (((const int32_t * )src )[0 ]); 317HVX_Vector pad_vec = Q6_V_vsplat_R (0x80000000 ); 318hvx_reduce_loop_body (HVX_UVector ,init_vec ,pad_vec ,Q6_Vw_vmax_VwVw ,hvx_vec_reduce_max_i32 ,hvx_vec_get_i32 ); 319} 320 321static inline int32_t hvx_reduce_max_i32 (const uint8_t * restrictsrc ,const int num_elems ) { 322if (hex_is_aligned ((void * )src ,128 )) { 323return hvx_reduce_max_i32_a (src ,num_elems ); 324 }else { 325return hvx_reduce_max_i32_u (src ,num_elems ); 326 } 327} 328 329#undef hvx_reduce_loop_body 330#undef HVX_REDUCE_MAX_OP 331#undef HVX_REDUCE_SUM_OP 332#undef HVX_REDUCE_MAX_SCALAR 333#undef HVX_REDUCE_SUM_SCALAR 334#undef HVX_SUM_SQ_OP 335 336#endif /* HVX_REDUCE_H */