char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
f027c4f1b
char/aliceai-t5-moe
1#ifndef HVX_LOG_H 2#define HVX_LOG_H 3 4#include "hvx-base.h" 5 6// Approximates ln(x) element-wise for float vectors. 7// x must contain positive float elements. 8// Uses Abramowitz & Stegun polynomial approximation 4.1.44 for ln(1+y) over [0, 1]. 9static inline HVX_Vector hvx_vec_log_f32 (HVX_Vector x ) { 10// x = m * 2^e, where m in [1, 2) 11HVX_Vector biased_e = Q6_Vuw_vlsr_VuwR (x ,23 ); 12HVX_Vector e_int = Q6_Vw_vsub_VwVw (biased_e ,Q6_V_vsplat_R (127 )); 13HVX_Vector e_float = Q6_Vsf_equals_Vw (e_int ); 14 15// Extract mantissa and set exponent to 127 (which represents float value in [1.0, 2.0)) 16HVX_Vector mant_mask = Q6_V_vsplat_R (0x007FFFFF ); 17HVX_Vector exp_127 = Q6_V_vsplat_R (0x3F800000 ); 18HVX_Vector m = Q6_V_vor_VV (Q6_V_vand_VV (x ,mant_mask ),exp_127 ); 19 20// y = m - 1.0f, y in [0, 1) 21HVX_Vector y = hvx_vec_sub_f32_f32 (m ,hvx_vec_splat_f32 (1.0f )); 22 23// Abramowitz & Stegun 4.1.44 polynomial approximation of ln(1+y) 24HVX_Vector c ; 25HVX_Vector res ; 26 27c = hvx_vec_splat_f32 (-0.0064535442f ); 28res = hvx_vec_mul_f32_f32 (y ,c ); 29 30c = hvx_vec_splat_f32 (0.0360884937f ); 31res = hvx_vec_add_f32_f32 (res ,c ); 32res = hvx_vec_mul_f32_f32 (y ,res ); 33 34c = hvx_vec_splat_f32 (-0.0953293897f ); 35res = hvx_vec_add_f32_f32 (res ,c ); 36res = hvx_vec_mul_f32_f32 (y ,res ); 37 38c = hvx_vec_splat_f32 (0.1676540711f ); 39res = hvx_vec_add_f32_f32 (res ,c ); 40res = hvx_vec_mul_f32_f32 (y ,res ); 41 42c = hvx_vec_splat_f32 (-0.2407338084f ); 43res = hvx_vec_add_f32_f32 (res ,c ); 44res = hvx_vec_mul_f32_f32 (y ,res ); 45 46c = hvx_vec_splat_f32 (0.3317990258f ); 47res = hvx_vec_add_f32_f32 (res ,c ); 48res = hvx_vec_mul_f32_f32 (y ,res ); 49 50c = hvx_vec_splat_f32 (-0.4998741238f ); 51res = hvx_vec_add_f32_f32 (res ,c ); 52res = hvx_vec_mul_f32_f32 (y ,res ); 53 54c = hvx_vec_splat_f32 (0.9999964239f ); 55res = hvx_vec_add_f32_f32 (res ,c ); 56res = hvx_vec_mul_f32_f32 (y ,res ); 57 58// ln(x) = e * ln(2) + ln(1+y) 59HVX_Vector ln2 = hvx_vec_splat_f32 (0.69314718056f ); 60HVX_Vector term_e = hvx_vec_mul_f32_f32 (e_float ,ln2 ); 61 62return hvx_vec_add_f32_f32 (term_e ,res ); 63} 64 65static inline void hvx_log_f32_aa (uint8_t * restrictdst ,const uint8_t * restrictsrc ,uint32_t n ) { 66assert ((unsigned long )dst %128 == 0 ); 67assert ((unsigned long )src %128 == 0 ); 68 69HVX_Vector * restrictvdst = (HVX_Vector * )dst ; 70HVX_Vector * restrictvsrc = (HVX_Vector * )src ; 71 72const uint32_t elem_size = sizeof (float ); 73const uint32_t epv = 128 /elem_size ; 74const uint32_t nvec = n /epv ; 75const uint32_t nloe = n %epv ; 76 77uint32_t i = 0 ; 78 79_Pragma ("unroll(4)" ) 80for (;i < nvec ;i ++ ) { 81vdst [i ]= hvx_vec_log_f32 (vsrc [i ]); 82 } 83if (nloe ) { 84HVX_Vector v = hvx_vec_log_f32 (vsrc [i ]); 85hvx_vec_store_a ((void * )& vdst [i ],nloe * elem_size ,v ); 86 } 87} 88 89// Compute log(x) for f16 by promoting to f32, applying hvx_vec_log_f32, and narrowing back. 90static inline void hvx_log_f16_aa (uint8_t * restrictdst ,const uint8_t * restrictsrc ,uint32_t n ) { 91assert ((unsigned long )dst %128 == 0 ); 92assert ((unsigned long )src %128 == 0 ); 93 94HVX_Vector * restrictvdst = (HVX_Vector * )dst ; 95HVX_Vector * restrictvsrc = (HVX_Vector * )src ; 96 97const uint32_t nvec = n /VLEN_FP16 ; 98const uint32_t nloe = n %VLEN_FP16 ; 99 100uint32_t i = 0 ; 101 102_Pragma ("unroll(4)" ) 103for (;i < nvec ;i ++ ) { 104HVX_VectorPair p = hvx_vec_f16_to_f32 (vsrc [i ]); 105HVX_Vector r0 = hvx_vec_log_f32 (Q6_V_lo_W (p )); 106HVX_Vector r1 = hvx_vec_log_f32 (Q6_V_hi_W (p )); 107vdst [i ]= hvx_vec_f32_to_f16 (r0 ,r1 ); 108 } 109if (nloe ) { 110HVX_VectorPair p = hvx_vec_f16_to_f32 (vsrc [i ]); 111HVX_Vector r0 = hvx_vec_log_f32 (Q6_V_lo_W (p )); 112HVX_Vector r1 = hvx_vec_log_f32 (Q6_V_hi_W (p )); 113HVX_Vector v = hvx_vec_f32_to_f16 (r0 ,r1 ); 114hvx_vec_store_a ((void * )& vdst [i ],nloe * SIZEOF_FP16 ,v ); 115 } 116} 117 118#endif /* HVX_LOG_H */