char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
13e673863
char/aliceai-t5-moe
1// Dynamic quantizers that produce flat (non-tiled) activations 2 3static inline void quantize_block_f32_q8_0_flat ( 4float * restrictx , 5uint8_t * restricty_quants , 6__fp16 * restricty_scales , 7uint32_t block_idx 8) { 9HVX_Vector * vx = (HVX_Vector * )x ; 10HVX_Vector zero = Q6_V_vzero (); 11 12HVX_Vector vmax0_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [0 ])); 13HVX_Vector vmax1_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [1 ])); 14HVX_Vector vmax2_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [2 ])); 15HVX_Vector vmax3_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [3 ])); 16 17HVX_Vector vx0_qf = Q6_Vqf32_vsub_VsfVsf (vx [0 ],zero ); 18HVX_Vector vx1_qf = Q6_Vqf32_vsub_VsfVsf (vx [1 ],zero ); 19HVX_Vector vx2_qf = Q6_Vqf32_vsub_VsfVsf (vx [2 ],zero ); 20HVX_Vector vx3_qf = Q6_Vqf32_vsub_VsfVsf (vx [3 ],zero ); 21 22HVX_Vector vmax0_qf = Q6_Vqf32_vsub_VsfVsf (vmax0_sf ,zero ); 23HVX_Vector vmax1_qf = Q6_Vqf32_vsub_VsfVsf (vmax1_sf ,zero ); 24HVX_Vector vmax2_qf = Q6_Vqf32_vsub_VsfVsf (vmax2_sf ,zero ); 25HVX_Vector vmax3_qf = Q6_Vqf32_vsub_VsfVsf (vmax3_sf ,zero ); 26 27HVX_Vector vmax01_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vmax1_qf ,vmax0_qf ))); 28HVX_Vector vmax23_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vmax3_qf ,vmax2_qf ))); 29 30HVX_Vector vx01_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vx1_qf ,vx0_qf ))); 31HVX_Vector vx23_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vx3_qf ,vx2_qf ))); 32 33HVX_Vector vd01_qf16 = Q6_Vqf16_vmpy_VhfVhf (vmax01_hf ,Q6_Vh_vsplat_R (0x2008 ));// 1.0 / 127.0 34HVX_Vector vd23_qf16 = Q6_Vqf16_vmpy_VhfVhf (vmax23_hf ,Q6_Vh_vsplat_R (0x2008 ));// 1.0 / 127.0 35HVX_Vector vd01_hf = Q6_Vhf_equals_Vqf16 (vd01_qf16 ); 36HVX_Vector vd23_hf = Q6_Vhf_equals_Vqf16 (vd23_qf16 ); 37 38HVX_Vector vd01_inv_hf = hvx_vec_inverse_f16 (vd01_hf ); 39HVX_Vector vd23_inv_hf = hvx_vec_inverse_f16 (vd23_hf ); 40vx01_hf = Q6_Vhf_equals_Vqf16 (Q6_Vqf16_vmpy_VhfVhf (vx01_hf ,vd01_inv_hf )); 41vx23_hf = Q6_Vhf_equals_Vqf16 (Q6_Vqf16_vmpy_VhfVhf (vx23_hf ,vd23_inv_hf )); 42 43HVX_Vector vx01_i16 = hvx_vec_i16_from_hf_rnd_sat (vx01_hf ); 44HVX_Vector vx23_i16 = hvx_vec_i16_from_hf_rnd_sat (vx23_hf ); 45HVX_Vector vx_i8 = Q6_Vb_vpack_VhVh_sat (vx23_i16 ,vx01_i16 ); 46 47* (HVX_Vector * ) (y_quants + block_idx * 128 )= vx_i8 ; 48 49HVX_VectorPair vp1 = Q6_W_vshuff_VVR (vd23_hf ,vd01_hf ,-2 ); 50HVX_VectorPair vp2 = Q6_W_vshuff_VVR (Q6_V_hi_W (vp1 ),Q6_V_lo_W (vp1 ),-2 ); 51HVX_Vector v_scales = Q6_V_lo_W (vp2 ); 52hvx_vec_store_u (y_scales + block_idx * 4 ,8 ,v_scales ); 53} 54 55static inline void quantize_block_f32_q8_1_flat ( 56float * restrictx , 57uint8_t * restricty_quants , 58__fp16 * restricty_scales , 59uint32_t block_idx 60) { 61HVX_Vector * vx = (HVX_Vector * )x ; 62HVX_Vector zero = Q6_V_vzero (); 63 64HVX_Vector vmax0_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [0 ])); 65HVX_Vector vmax1_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [1 ])); 66HVX_Vector vmax2_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [2 ])); 67HVX_Vector vmax3_sf = hvx_vec_reduce_max_f32 (hvx_vec_abs_f32 (vx [3 ])); 68 69HVX_Vector vx0_qf = Q6_Vqf32_vsub_VsfVsf (vx [0 ],zero ); 70HVX_Vector vx1_qf = Q6_Vqf32_vsub_VsfVsf (vx [1 ],zero ); 71HVX_Vector vx2_qf = Q6_Vqf32_vsub_VsfVsf (vx [2 ],zero ); 72HVX_Vector vx3_qf = Q6_Vqf32_vsub_VsfVsf (vx [3 ],zero ); 73 74HVX_Vector vmax0_qf = Q6_Vqf32_vsub_VsfVsf (vmax0_sf ,zero ); 75HVX_Vector vmax1_qf = Q6_Vqf32_vsub_VsfVsf (vmax1_sf ,zero ); 76HVX_Vector vmax2_qf = Q6_Vqf32_vsub_VsfVsf (vmax2_sf ,zero ); 77HVX_Vector vmax3_qf = Q6_Vqf32_vsub_VsfVsf (vmax3_sf ,zero ); 78 79HVX_Vector vmax01_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vmax1_qf ,vmax0_qf ))); 80HVX_Vector vmax23_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vmax3_qf ,vmax2_qf ))); 81 82HVX_Vector vx01_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vx1_qf ,vx0_qf ))); 83HVX_Vector vx23_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (vx3_qf ,vx2_qf ))); 84 85HVX_Vector vd01_qf16 = Q6_Vqf16_vmpy_VhfVhf (vmax01_hf ,Q6_Vh_vsplat_R (0x2008 ));// 1.0 / 127.0 86HVX_Vector vd23_qf16 = Q6_Vqf16_vmpy_VhfVhf (vmax23_hf ,Q6_Vh_vsplat_R (0x2008 ));// 1.0 / 127.0 87HVX_Vector vd01_hf = Q6_Vhf_equals_Vqf16 (vd01_qf16 ); 88HVX_Vector vd23_hf = Q6_Vhf_equals_Vqf16 (vd23_qf16 ); 89 90HVX_Vector vd01_inv_hf = hvx_vec_inverse_f16 (vd01_hf ); 91HVX_Vector vd23_inv_hf = hvx_vec_inverse_f16 (vd23_hf ); 92vx01_hf = Q6_Vhf_equals_Vqf16 (Q6_Vqf16_vmpy_VhfVhf (vx01_hf ,vd01_inv_hf )); 93vx23_hf = Q6_Vhf_equals_Vqf16 (Q6_Vqf16_vmpy_VhfVhf (vx23_hf ,vd23_inv_hf )); 94 95HVX_Vector vx01_i16 = hvx_vec_i16_from_hf_rnd_sat (vx01_hf ); 96HVX_Vector vx23_i16 = hvx_vec_i16_from_hf_rnd_sat (vx23_hf ); 97HVX_Vector vx_i8 = Q6_Vb_vpack_VhVh_sat (vx23_i16 ,vx01_i16 ); 98 99const HVX_Vector ones = Q6_Vb_vsplat_R (1 ); 100HVX_Vector v_sums = Q6_Vw_vrmpy_VbVb (vx_i8 ,ones ); 101v_sums = Q6_Vw_vadd_VwVw (v_sums ,Q6_V_vror_VR (v_sums ,4 )); 102v_sums = Q6_Vw_vadd_VwVw (v_sums ,Q6_V_vror_VR (v_sums ,8 )); 103v_sums = Q6_Vw_vadd_VwVw (v_sums ,Q6_V_vror_VR (v_sums ,16 )); 104 105* (HVX_Vector * ) (y_quants + block_idx * 128 )= vx_i8 ; 106 107HVX_VectorPair vp1 = Q6_W_vshuff_VVR (vd23_hf ,vd01_hf ,-2 ); 108HVX_VectorPair vp2 = Q6_W_vshuff_VVR (Q6_V_hi_W (vp1 ),Q6_V_lo_W (vp1 ),-2 ); 109HVX_Vector v_scales = Q6_V_lo_W (vp2 ); 110 111HVX_VectorPair v_deal1 = Q6_W_vdeal_VVR (v_sums ,v_sums ,-4 ); 112HVX_Vector v_even1 = Q6_V_lo_W (v_deal1 ); 113HVX_VectorPair v_deal2 = Q6_W_vdeal_VVR (v_even1 ,v_even1 ,-4 ); 114HVX_Vector v_even2 = Q6_V_lo_W (v_deal2 ); 115HVX_VectorPair v_deal3 = Q6_W_vdeal_VVR (v_even2 ,v_even2 ,-4 ); 116HVX_Vector v_sums_shuffled = Q6_V_lo_W (v_deal3 ); 117 118HVX_Vector v_sums_sf = Q6_Vsf_equals_Vw (v_sums_shuffled ); 119HVX_Vector v_sums_hf = hvx_vec_f32_to_f16 (v_sums_sf ,Q6_V_vzero ()); 120 121HVX_Vector v_prod = hvx_vec_mul_f16_f16 (v_scales ,v_sums_hf ); 122 123HVX_VectorPair vp_scales = Q6_W_vshuff_VVR (v_prod ,v_scales ,-2 ); 124HVX_Vector v_final = Q6_V_lo_W (vp_scales ); 125 126hvx_vec_store_u (y_scales + block_idx * 8 ,16 ,v_final ); 127} 128 129static inline void quantize_row_f32_q8_0_flat (float * restrictx ,uint8_t * restricty ,uint32_t k ) { 130assert (k %32 == 0 ); 131const uint32_t quants_size = hex_round_up (k ,128 ); 132uint8_t * restricty_quants = y ; 133__fp16 * restricty_scales = (__fp16 * ) (y + quants_size ); 134 135const uint32_t nb = (k + 127 ) /128 ; 136for (uint32_t i = 0 ;i < nb ;i ++ ) { 137quantize_block_f32_q8_0_flat (x + i * 128 ,y_quants ,y_scales ,i ); 138 } 139} 140 141static inline void quantize_row_f32_q8_1_flat (float * restrictx ,uint8_t * restricty ,uint32_t k ) { 142assert (k %32 == 0 ); 143const uint32_t quants_size = hex_round_up (k ,128 ); 144uint8_t * restricty_quants = y ; 145__fp16 * restricty_scales = (__fp16 * ) (y + quants_size ); 146 147const uint32_t nb = (k + 127 ) /128 ; 148for (uint32_t i = 0 ;i < nb ;i ++ ) { 149quantize_block_f32_q8_1_flat (x + i * 128 ,y_quants ,y_scales ,i ); 150 } 151} 152 153static inline void quantize_f32_q8_0_flat_kernel ( 154const uint8_t * restrictsrc_data , 155uint8_t * restrictdst_data , 156uint8_t * restricttmp_data , 157uint32_t ne0 , 158uint32_t nrows , 159size_t src_row_size , 160size_t dst_row_size 161) { 162const size_t src_row_size_padded = hex_round_up (src_row_size ,QK_Q8_0_TILED * sizeof (float )); 163hvx_splat_f32_a (tmp_data ,0.0f ,src_row_size_padded /sizeof (float )); 164 165for (uint32_t i = 0 ;i < nrows ;++ i ) { 166hex_l2fetch (src_data ,src_row_size ,src_row_size ,2 ); 167hvx_copy_f32_aa (tmp_data ,src_data ,ne0 ); 168 169quantize_row_f32_q8_0_flat ((float * )tmp_data ,dst_data ,ne0 ); 170dst_data += dst_row_size ; 171src_data += src_row_size ; 172 } 173} 174 175static inline void quantize_f32_q8_1_flat_kernel ( 176const uint8_t * restrictsrc_data , 177uint8_t * restrictdst_data , 178uint8_t * restricttmp_data , 179uint32_t ne0 , 180uint32_t nrows , 181size_t src_row_size , 182size_t dst_row_size 183) { 184const size_t src_row_size_padded = hex_round_up (src_row_size ,QK_Q8_0_TILED * sizeof (float )); 185hvx_splat_f32_a (tmp_data ,0.0f ,src_row_size_padded /sizeof (float )); 186 187for (uint32_t i = 0 ;i < nrows ;++ i ) { 188hex_l2fetch (src_data ,src_row_size ,src_row_size ,2 ); 189hvx_copy_f32_aa (tmp_data ,src_data ,ne0 ); 190 191quantize_row_f32_q8_1_flat ((float * )tmp_data ,dst_data ,ne0 ); 192dst_data += dst_row_size ; 193src_data += src_row_size ; 194 } 195} 196 197static inline void quantize_f32_f32_flat_kernel ( 198const uint8_t * restrictsrc_data , 199uint8_t * restrictdst_data , 200uint8_t * restricttmp_data , 201uint32_t ne0 , 202uint32_t nrows , 203size_t src_stride , 204size_t dst_stride 205) { 206 (void )tmp_data ; 207const size_t src_row_size = ne0 * sizeof (float ); 208for (uint32_t i = 0 ;i < nrows ;++ i ) { 209hex_l2fetch (src_data ,src_row_size ,src_stride ,2 ); 210hvx_copy_f32_au (dst_data ,src_data ,ne0 ); 211 212dst_data += dst_stride ; 213src_data += src_stride ; 214 } 215} 216 217static inline void quantize_f32_f16_flat_kernel ( 218const uint8_t * restrictsrc_data , 219uint8_t * restrictdst_data , 220uint8_t * restricttmp_data , 221uint32_t ne0 , 222uint32_t nrows , 223size_t src_stride , 224size_t dst_stride 225) { 226 (void )tmp_data ; 227const size_t src_row_size = ne0 * sizeof (float ); 228for (uint32_t i = 0 ;i < nrows ;++ i ) { 229hex_l2fetch (src_data ,src_row_size ,src_stride ,2 ); 230hvx_copy_f16_f32_au (dst_data ,src_data ,ne0 ); 231 232dst_data += dst_stride ; 233src_data += src_stride ; 234 } 235} 236 237static inline void quantize_f16_f16_flat_kernel ( 238const uint8_t * restrictsrc_data , 239uint8_t * restrictdst_data , 240uint8_t * restricttmp_data , 241uint32_t ne0 , 242uint32_t nrows , 243size_t src_stride , 244size_t dst_stride 245) { 246 (void )tmp_data ; 247const size_t src_row_size = ne0 * sizeof (float ); 248for (uint32_t i = 0 ;i < nrows ;++ i ) { 249hex_l2fetch (src_data ,src_row_size ,src_stride ,2 ); 250hvx_copy_f16_au (dst_data ,src_data ,ne0 ); 251 252dst_data += dst_stride ; 253src_data += src_stride ; 254 } 255} 256 257// Dot kernels that consume flat (non-tiled) activations 258 259static void flat_vec_dot_q4_0_32x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ,uint32_t valid_rows ,const float * restrictsz ) { 260const uint8_t * restricttile_ptr = vx ; 261const uint8_t * restricty_q = vy ; 262 263HVX_Vector v_sum_float = Q6_V_vzero (); 264HVX_Vector i8 = Q6_Vb_vsplat_R (8 ); 265 266static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 2670x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2680x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2690x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2700x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2710x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2720x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2730x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 2740x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 275 }; 276HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 277 278const uint32_t quants_size = hex_round_up (n ,128 ); 279const __fp16 * restricty_scales = (const __fp16 * ) (y_q + quants_size ); 280 281uint32_t n_k_tiles = n /32 ; 282for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 283const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 284 285uint32_t block_idx = kt /4 ; 286uint32_t sub_idx = kt %4 ; 287 288HVX_Vector vx_i8 = * (const HVX_Vector * ) (y_q + block_idx * 128 ); 289HVX_Vector v_act_raw = Q6_V_vror_VR (vx_i8 ,sub_idx * 32 ); 290 291HVX_Vector v_act_rep [8 ]; 292v_act_rep [0 ]= Q6_V_vdelta_VV (v_act_raw ,v_repl_ctrl ); 293v_act_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,4 ),v_repl_ctrl ); 294v_act_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,8 ),v_repl_ctrl ); 295v_act_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,12 ),v_repl_ctrl ); 296v_act_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,16 ),v_repl_ctrl ); 297v_act_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,20 ),v_repl_ctrl ); 298v_act_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,24 ),v_repl_ctrl ); 299v_act_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,28 ),v_repl_ctrl ); 300 301HVX_Vector v_sum = accum_4bit_32x1 (vptr ,v_act_rep ,i8 ); 302HVX_Vector v_sum_sf = Q6_Vsf_equals_Vw (v_sum ); 303 304HVX_Vector v_scale_w = vptr [4 ]; 305 306__fp16 scale_a_val = y_scales [kt ]; 307HVX_Vector v_scale_a = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a_val )); 308 309HVX_Vector v_scale_comb = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a ); 310HVX_Vector v_sum_scaled = hvx_vec_mul_f32_f32 (v_sum_sf ,v_scale_comb ); 311 312v_sum_float = hvx_vec_add_f32_f32 (v_sum_float ,v_sum_scaled ); 313 } 314 315if (sz ) { 316hvx_vec_store_u (s ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float ,hvx_vmemu (sz ))); 317 }else { 318hvx_vec_store_u (s ,valid_rows * sizeof (float ),v_sum_float ); 319 } 320} 321 322static void flat_vec_dot_q4_0_32x2 (const uint32_t n ,float * restricts0 ,float * restricts1 ,const void * restrictvx ,const void * restrictvy0 ,const void * restrictvy1 ,uint32_t valid_rows ,const float * restrictsz0 ,const float * restrictsz1 ) { 323const uint8_t * restricttile_ptr = vx ; 324const uint8_t * restricty0_q = vy0 ; 325const uint8_t * restricty1_q = vy1 ; 326 327HVX_Vector v_sum_float_c0 = Q6_V_vzero (); 328HVX_Vector v_sum_float_c1 = Q6_V_vzero (); 329HVX_Vector i8 = Q6_Vb_vsplat_R (8 ); 330 331static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 3320x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3330x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3340x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3350x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3360x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3370x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3380x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 3390x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 340 }; 341HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 342 343const uint32_t quants_size = hex_round_up (n ,128 ); 344const __fp16 * restricty0_scales = (const __fp16 * ) (y0_q + quants_size ); 345const __fp16 * restricty1_scales = (const __fp16 * ) (y1_q + quants_size ); 346 347uint32_t n_k_tiles = n /32 ; 348for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 349const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 350 351uint32_t block_idx = kt /4 ; 352uint32_t sub_idx = kt %4 ; 353 354HVX_Vector vx0_i8 = * (const HVX_Vector * ) (y0_q + block_idx * 128 ); 355HVX_Vector vx1_i8 = * (const HVX_Vector * ) (y1_q + block_idx * 128 ); 356 357HVX_Vector v_act0_raw = Q6_V_vror_VR (vx0_i8 ,sub_idx * 32 ); 358HVX_Vector v_act1_raw = Q6_V_vror_VR (vx1_i8 ,sub_idx * 32 ); 359 360HVX_Vector v_act0_rep [8 ]; 361v_act0_rep [0 ]= Q6_V_vdelta_VV (v_act0_raw ,v_repl_ctrl ); 362v_act0_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,4 ),v_repl_ctrl ); 363v_act0_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,8 ),v_repl_ctrl ); 364v_act0_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,12 ),v_repl_ctrl ); 365v_act0_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,16 ),v_repl_ctrl ); 366v_act0_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,20 ),v_repl_ctrl ); 367v_act0_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,24 ),v_repl_ctrl ); 368v_act0_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,28 ),v_repl_ctrl ); 369 370HVX_Vector v_act1_rep [8 ]; 371v_act1_rep [0 ]= Q6_V_vdelta_VV (v_act1_raw ,v_repl_ctrl ); 372v_act1_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,4 ),v_repl_ctrl ); 373v_act1_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,8 ),v_repl_ctrl ); 374v_act1_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,12 ),v_repl_ctrl ); 375v_act1_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,16 ),v_repl_ctrl ); 376v_act1_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,20 ),v_repl_ctrl ); 377v_act1_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,24 ),v_repl_ctrl ); 378v_act1_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,28 ),v_repl_ctrl ); 379 380HVX_VectorPair v_sums = accum_4bit_32x2 (vptr ,v_act0_rep ,v_act1_rep ,i8 ); 381HVX_Vector v_sum_c0 = Q6_V_lo_W (v_sums ); 382HVX_Vector v_sum_c1 = Q6_V_hi_W (v_sums ); 383 384HVX_Vector v_sum_sf_c0 = Q6_Vsf_equals_Vw (v_sum_c0 ); 385HVX_Vector v_sum_sf_c1 = Q6_Vsf_equals_Vw (v_sum_c1 ); 386 387HVX_Vector v_scale_w = vptr [4 ]; 388 389__fp16 scale_a0_val = y0_scales [kt ]; 390__fp16 scale_a1_val = y1_scales [kt ]; 391HVX_Vector v_scale_a0 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a0_val )); 392HVX_Vector v_scale_a1 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a1_val )); 393 394HVX_Vector v_scale_comb_c0 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a0 ); 395HVX_Vector v_scale_comb_c1 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a1 ); 396 397HVX_Vector v_sum_scaled_c0 = hvx_vec_mul_f32_f32 (v_sum_sf_c0 ,v_scale_comb_c0 ); 398HVX_Vector v_sum_scaled_c1 = hvx_vec_mul_f32_f32 (v_sum_sf_c1 ,v_scale_comb_c1 ); 399 400v_sum_float_c0 = hvx_vec_add_f32_f32 (v_sum_float_c0 ,v_sum_scaled_c0 ); 401v_sum_float_c1 = hvx_vec_add_f32_f32 (v_sum_float_c1 ,v_sum_scaled_c1 ); 402 } 403 404if (sz0 ) { 405hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c0 ,hvx_vmemu (sz0 ))); 406 }else { 407hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),v_sum_float_c0 ); 408 } 409if (sz1 ) { 410hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c1 ,hvx_vmemu (sz1 ))); 411 }else { 412hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),v_sum_float_c1 ); 413 } 414} 415 416static void flat_vec_dot_q4_1_32x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ,uint32_t valid_rows ,const float * restrictsz ) { 417const uint8_t * restricttile_ptr = vx ; 418const uint8_t * restricty_q = vy ; 419 420HVX_Vector v_sum_float = Q6_V_vzero (); 421 422static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 4230x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4240x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4250x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4260x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4270x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4280x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4290x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4300x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 431 }; 432HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 433 434const uint32_t quants_size = hex_round_up (n ,128 ); 435const __fp16 * restricty_scales = (const __fp16 * ) (y_q + quants_size ); 436 437uint32_t n_k_tiles = n /32 ; 438for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 439const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 440 441uint32_t block_idx = kt /4 ; 442uint32_t sub_idx = kt %4 ; 443 444HVX_Vector vx_i8 = * (const HVX_Vector * ) (y_q + block_idx * 128 ); 445HVX_Vector v_act_raw = Q6_V_vror_VR (vx_i8 ,sub_idx * 32 ); 446 447HVX_Vector v_act_rep [8 ]; 448v_act_rep [0 ]= Q6_V_vdelta_VV (v_act_raw ,v_repl_ctrl ); 449v_act_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,4 ),v_repl_ctrl ); 450v_act_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,8 ),v_repl_ctrl ); 451v_act_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,12 ),v_repl_ctrl ); 452v_act_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,16 ),v_repl_ctrl ); 453v_act_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,20 ),v_repl_ctrl ); 454v_act_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,24 ),v_repl_ctrl ); 455v_act_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,28 ),v_repl_ctrl ); 456 457HVX_Vector v_sum = accum_4bit_32x1 (vptr ,v_act_rep ,Q6_V_vzero ()); 458HVX_Vector v_sum_sf = Q6_Vsf_equals_Vw (v_sum ); 459 460HVX_Vector v_scale_offset = vptr [4 ]; 461HVX_VectorPair p_deal = Q6_W_vdeal_VVR (v_scale_offset ,v_scale_offset ,-2 ); 462HVX_Vector v_scale = Q6_V_lo_W (p_deal ); 463HVX_Vector v_offset = Q6_V_hi_W (p_deal ); 464 465__fp16 scale_a_val = y_scales [kt * 2 + 0 ]; 466__fp16 sum_a_val = y_scales [kt * 2 + 1 ]; 467HVX_Vector v_scale_a = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a_val )); 468HVX_Vector v_sum_a = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& sum_a_val )); 469 470HVX_Vector v_scale_comb = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale ,v_scale_a ); 471HVX_Vector v_offset_comb = hvx_vec_mul_f16_f16_to_f32_lower32 (v_offset ,v_sum_a ); 472 473HVX_Vector v_scaled_dot = hvx_vec_mul_f32_f32 (v_sum_sf ,v_scale_comb ); 474HVX_Vector v_sum_scaled = hvx_vec_add_f32_f32 (v_scaled_dot ,v_offset_comb ); 475 476v_sum_float = hvx_vec_add_f32_f32 (v_sum_float ,v_sum_scaled ); 477 } 478 479if (sz ) { 480hvx_vec_store_u (s ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float ,hvx_vmemu (sz ))); 481 }else { 482hvx_vec_store_u (s ,valid_rows * sizeof (float ),v_sum_float ); 483 } 484} 485 486static void flat_vec_dot_q4_1_32x2 (const uint32_t n ,float * restricts0 ,float * restricts1 ,const void * restrictvx ,const void * restrictvy0 ,const void * restrictvy1 ,uint32_t valid_rows ,const float * restrictsz0 ,const float * restrictsz1 ) { 487const uint8_t * restricttile_ptr = vx ; 488const uint8_t * restricty0_q = vy0 ; 489const uint8_t * restricty1_q = vy1 ; 490 491HVX_Vector v_sum_float_c0 = Q6_V_vzero (); 492HVX_Vector v_sum_float_c1 = Q6_V_vzero (); 493 494static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 4950x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4960x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4970x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4980x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 4990x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 5000x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 5010x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 5020x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 503 }; 504HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 505 506const uint32_t quants_size = hex_round_up (n ,128 ); 507const __fp16 * restricty0_scales = (const __fp16 * ) (y0_q + quants_size ); 508const __fp16 * restricty1_scales = (const __fp16 * ) (y1_q + quants_size ); 509 510uint32_t n_k_tiles = n /32 ; 511for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 512const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 513 514uint32_t block_idx = kt /4 ; 515uint32_t sub_idx = kt %4 ; 516 517HVX_Vector vx0_i8 = * (const HVX_Vector * ) (y0_q + block_idx * 128 ); 518HVX_Vector vx1_i8 = * (const HVX_Vector * ) (y1_q + block_idx * 128 ); 519 520HVX_Vector v_act0_raw = Q6_V_vror_VR (vx0_i8 ,sub_idx * 32 ); 521HVX_Vector v_act1_raw = Q6_V_vror_VR (vx1_i8 ,sub_idx * 32 ); 522 523HVX_Vector v_act0_rep [8 ]; 524v_act0_rep [0 ]= Q6_V_vdelta_VV (v_act0_raw ,v_repl_ctrl ); 525v_act0_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,4 ),v_repl_ctrl ); 526v_act0_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,8 ),v_repl_ctrl ); 527v_act0_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,12 ),v_repl_ctrl ); 528v_act0_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,16 ),v_repl_ctrl ); 529v_act0_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,20 ),v_repl_ctrl ); 530v_act0_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,24 ),v_repl_ctrl ); 531v_act0_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,28 ),v_repl_ctrl ); 532 533HVX_Vector v_act1_rep [8 ]; 534v_act1_rep [0 ]= Q6_V_vdelta_VV (v_act1_raw ,v_repl_ctrl ); 535v_act1_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,4 ),v_repl_ctrl ); 536v_act1_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,8 ),v_repl_ctrl ); 537v_act1_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,12 ),v_repl_ctrl ); 538v_act1_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,16 ),v_repl_ctrl ); 539v_act1_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,20 ),v_repl_ctrl ); 540v_act1_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,24 ),v_repl_ctrl ); 541v_act1_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,28 ),v_repl_ctrl ); 542 543HVX_VectorPair v_sums = accum_4bit_32x2 (vptr ,v_act0_rep ,v_act1_rep ,Q6_V_vzero ()); 544HVX_Vector v_sum_c0 = Q6_V_lo_W (v_sums ); 545HVX_Vector v_sum_c1 = Q6_V_hi_W (v_sums ); 546 547HVX_Vector v_sum_sf_c0 = Q6_Vsf_equals_Vw (v_sum_c0 ); 548HVX_Vector v_sum_sf_c1 = Q6_Vsf_equals_Vw (v_sum_c1 ); 549 550HVX_Vector v_scale_offset = vptr [4 ]; 551HVX_VectorPair p_deal = Q6_W_vdeal_VVR (v_scale_offset ,v_scale_offset ,-2 ); 552HVX_Vector v_scale = Q6_V_lo_W (p_deal ); 553HVX_Vector v_offset = Q6_V_hi_W (p_deal ); 554 555__fp16 scale_a0_val = y0_scales [kt * 2 + 0 ]; 556__fp16 sum_a0_val = y0_scales [kt * 2 + 1 ]; 557__fp16 scale_a1_val = y1_scales [kt * 2 + 0 ]; 558__fp16 sum_a1_val = y1_scales [kt * 2 + 1 ]; 559 560HVX_Vector v_scale_a0 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a0_val )); 561HVX_Vector v_sum_a0 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& sum_a0_val )); 562HVX_Vector v_scale_a1 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a1_val )); 563HVX_Vector v_sum_a1 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& sum_a1_val )); 564 565HVX_Vector v_scale_comb_c0 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale ,v_scale_a0 ); 566HVX_Vector v_offset_comb_c0 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_offset ,v_sum_a0 ); 567HVX_Vector v_scale_comb_c1 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale ,v_scale_a1 ); 568HVX_Vector v_offset_comb_c1 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_offset ,v_sum_a1 ); 569 570HVX_Vector v_scaled_dot_c0 = hvx_vec_mul_f32_f32 (v_sum_sf_c0 ,v_scale_comb_c0 ); 571HVX_Vector v_sum_scaled_c0 = hvx_vec_add_f32_f32 (v_scaled_dot_c0 ,v_offset_comb_c0 ); 572 573HVX_Vector v_scaled_dot_c1 = hvx_vec_mul_f32_f32 (v_sum_sf_c1 ,v_scale_comb_c1 ); 574HVX_Vector v_sum_scaled_c1 = hvx_vec_add_f32_f32 (v_scaled_dot_c1 ,v_offset_comb_c1 ); 575 576v_sum_float_c0 = hvx_vec_add_f32_f32 (v_sum_float_c0 ,v_sum_scaled_c0 ); 577v_sum_float_c1 = hvx_vec_add_f32_f32 (v_sum_float_c1 ,v_sum_scaled_c1 ); 578 } 579 580if (sz0 ) { 581hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c0 ,hvx_vmemu (sz0 ))); 582 }else { 583hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),v_sum_float_c0 ); 584 } 585if (sz1 ) { 586hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c1 ,hvx_vmemu (sz1 ))); 587 }else { 588hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),v_sum_float_c1 ); 589 } 590} 591 592static void flat_vec_dot_q8_0_32x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ,uint32_t valid_rows ,const float * restrictsz ) { 593const uint8_t * restricttile_ptr = vx ; 594const uint8_t * restricty_q = vy ; 595 596HVX_Vector v_sum_float = Q6_V_vzero (); 597 598static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 5990x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6000x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6010x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6020x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6030x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6040x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6050x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6060x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 607 }; 608HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 609 610const uint32_t quants_size = hex_round_up (n ,128 ); 611const __fp16 * restricty_scales = (const __fp16 * ) (y_q + quants_size ); 612 613uint32_t n_k_tiles = n /32 ; 614for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 615const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 1152 ); 616 617uint32_t block_idx = kt /4 ; 618uint32_t sub_idx = kt %4 ; 619 620HVX_Vector vx_i8 = * (const HVX_Vector * ) (y_q + block_idx * 128 ); 621HVX_Vector v_act_raw = Q6_V_vror_VR (vx_i8 ,sub_idx * 32 ); 622 623HVX_Vector v_act_rep [8 ]; 624v_act_rep [0 ]= Q6_V_vdelta_VV (v_act_raw ,v_repl_ctrl ); 625v_act_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,4 ),v_repl_ctrl ); 626v_act_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,8 ),v_repl_ctrl ); 627v_act_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,12 ),v_repl_ctrl ); 628v_act_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,16 ),v_repl_ctrl ); 629v_act_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,20 ),v_repl_ctrl ); 630v_act_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,24 ),v_repl_ctrl ); 631v_act_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,28 ),v_repl_ctrl ); 632 633HVX_Vector v_sum = accum_q8_0_32x1 (vptr ,v_act_rep ); 634HVX_Vector v_sum_sf = Q6_Vsf_equals_Vw (v_sum ); 635 636HVX_Vector v_scale_w = vptr [8 ]; 637 638__fp16 scale_a_val = y_scales [kt ]; 639HVX_Vector v_scale_a = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a_val )); 640 641HVX_Vector v_scale_comb = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a ); 642HVX_Vector v_sum_scaled = hvx_vec_mul_f32_f32 (v_sum_sf ,v_scale_comb ); 643 644v_sum_float = hvx_vec_add_f32_f32 (v_sum_float ,v_sum_scaled ); 645 } 646 647if (sz ) { 648hvx_vec_store_u (s ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float ,hvx_vmemu (sz ))); 649 }else { 650hvx_vec_store_u (s ,valid_rows * sizeof (float ),v_sum_float ); 651 } 652} 653 654static void flat_vec_dot_q8_0_32x2 (const uint32_t n ,float * restricts0 ,float * restricts1 ,const void * restrictvx ,const void * restrictvy0 ,const void * restrictvy1 ,uint32_t valid_rows ,const float * restrictsz0 ,const float * restrictsz1 ) { 655const uint8_t * restricttile_ptr = vx ; 656const uint8_t * restricty0_q = vy0 ; 657const uint8_t * restricty1_q = vy1 ; 658 659HVX_Vector v_sum_float_c0 = Q6_V_vzero (); 660HVX_Vector v_sum_float_c1 = Q6_V_vzero (); 661 662static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 6630x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6640x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6650x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6660x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6670x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6680x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6690x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 6700x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 671 }; 672HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 673 674const uint32_t quants_size = hex_round_up (n ,128 ); 675const __fp16 * restricty0_scales = (const __fp16 * ) (y0_q + quants_size ); 676const __fp16 * restricty1_scales = (const __fp16 * ) (y1_q + quants_size ); 677 678uint32_t n_k_tiles = n /32 ; 679for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 680const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 1152 ); 681 682uint32_t block_idx = kt /4 ; 683uint32_t sub_idx = kt %4 ; 684 685HVX_Vector vx0_i8 = * (const HVX_Vector * ) (y0_q + block_idx * 128 ); 686HVX_Vector vx1_i8 = * (const HVX_Vector * ) (y1_q + block_idx * 128 ); 687 688HVX_Vector v_act0_raw = Q6_V_vror_VR (vx0_i8 ,sub_idx * 32 ); 689HVX_Vector v_act1_raw = Q6_V_vror_VR (vx1_i8 ,sub_idx * 32 ); 690 691HVX_Vector v_act0_rep [8 ]; 692v_act0_rep [0 ]= Q6_V_vdelta_VV (v_act0_raw ,v_repl_ctrl ); 693v_act0_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,4 ),v_repl_ctrl ); 694v_act0_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,8 ),v_repl_ctrl ); 695v_act0_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,12 ),v_repl_ctrl ); 696v_act0_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,16 ),v_repl_ctrl ); 697v_act0_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,20 ),v_repl_ctrl ); 698v_act0_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,24 ),v_repl_ctrl ); 699v_act0_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,28 ),v_repl_ctrl ); 700 701HVX_Vector v_act1_rep [8 ]; 702v_act1_rep [0 ]= Q6_V_vdelta_VV (v_act1_raw ,v_repl_ctrl ); 703v_act1_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,4 ),v_repl_ctrl ); 704v_act1_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,8 ),v_repl_ctrl ); 705v_act1_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,12 ),v_repl_ctrl ); 706v_act1_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,16 ),v_repl_ctrl ); 707v_act1_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,20 ),v_repl_ctrl ); 708v_act1_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,24 ),v_repl_ctrl ); 709v_act1_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,28 ),v_repl_ctrl ); 710 711HVX_VectorPair v_sums = accum_q8_0_32x2 (vptr ,v_act0_rep ,v_act1_rep ); 712HVX_Vector v_sum_c0 = Q6_V_lo_W (v_sums ); 713HVX_Vector v_sum_c1 = Q6_V_hi_W (v_sums ); 714 715HVX_Vector v_sum_sf_c0 = Q6_Vsf_equals_Vw (v_sum_c0 ); 716HVX_Vector v_sum_sf_c1 = Q6_Vsf_equals_Vw (v_sum_c1 ); 717 718HVX_Vector v_scale_w = vptr [8 ]; 719 720__fp16 scale_a0_val = y0_scales [kt ]; 721__fp16 scale_a1_val = y1_scales [kt ]; 722HVX_Vector v_scale_a0 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a0_val )); 723HVX_Vector v_scale_a1 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a1_val )); 724 725HVX_Vector v_scale_comb_c0 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a0 ); 726HVX_Vector v_scale_comb_c1 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a1 ); 727 728HVX_Vector v_sum_scaled_c0 = hvx_vec_mul_f32_f32 (v_sum_sf_c0 ,v_scale_comb_c0 ); 729HVX_Vector v_sum_scaled_c1 = hvx_vec_mul_f32_f32 (v_sum_sf_c1 ,v_scale_comb_c1 ); 730 731v_sum_float_c0 = hvx_vec_add_f32_f32 (v_sum_float_c0 ,v_sum_scaled_c0 ); 732v_sum_float_c1 = hvx_vec_add_f32_f32 (v_sum_float_c1 ,v_sum_scaled_c1 ); 733 } 734 735if (sz0 ) { 736hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c0 ,hvx_vmemu (sz0 ))); 737 }else { 738hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),v_sum_float_c0 ); 739 } 740if (sz1 ) { 741hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c1 ,hvx_vmemu (sz1 ))); 742 }else { 743hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),v_sum_float_c1 ); 744 } 745} 746 747static void flat_vec_dot_iq4nl_32x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ,uint32_t valid_rows ,const float * restrictsz ) { 748const uint8_t * restricttile_ptr = vx ; 749const uint8_t * restricty_q = vy ; 750 751HVX_Vector v_sum_float = Q6_V_vzero (); 752HVX_Vector mask_h4 = Q6_Vb_vsplat_R (0x0F ); 753HVX_Vector lut = * (const HVX_Vector * )kvalues_iq4nl_lut ; 754 755static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 7560x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7570x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7580x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7590x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7600x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7610x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7620x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 7630x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 764 }; 765HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 766 767const uint32_t quants_size = hex_round_up (n ,128 ); 768const __fp16 * restricty_scales = (const __fp16 * ) (y_q + quants_size ); 769 770uint32_t n_k_tiles = n /32 ; 771for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 772const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 773 774uint32_t block_idx = kt /4 ; 775uint32_t sub_idx = kt %4 ; 776 777HVX_Vector vx = * (const HVX_Vector * ) (y_q + block_idx * 128 ); 778HVX_Vector v_act_raw = Q6_V_vror_VR (vx ,sub_idx * 32 ); 779 780HVX_Vector v_act_rep [8 ]; 781v_act_rep [0 ]= Q6_V_vdelta_VV (v_act_raw ,v_repl_ctrl ); 782v_act_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,4 ),v_repl_ctrl ); 783v_act_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,8 ),v_repl_ctrl ); 784v_act_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,12 ),v_repl_ctrl ); 785v_act_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,16 ),v_repl_ctrl ); 786v_act_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,20 ),v_repl_ctrl ); 787v_act_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,24 ),v_repl_ctrl ); 788v_act_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,28 ),v_repl_ctrl ); 789 790HVX_Vector v_sum = accum_4bit_32x1_lut (vptr ,v_act_rep ,mask_h4 ,lut ); 791HVX_Vector v_sum_sf = Q6_Vsf_equals_Vw (v_sum ); 792 793HVX_Vector v_scale_w = vptr [4 ]; 794 795__fp16 scale_a_val = y_scales [kt ]; 796HVX_Vector v_scale_a = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a_val )); 797 798HVX_Vector v_scale_comb = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a ); 799HVX_Vector v_sum_scaled = hvx_vec_mul_f32_f32 (v_sum_sf ,v_scale_comb ); 800 801v_sum_float = hvx_vec_add_f32_f32 (v_sum_float ,v_sum_scaled ); 802 } 803 804if (sz ) { 805hvx_vec_store_u (s ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float ,hvx_vmemu (sz ))); 806 }else { 807hvx_vec_store_u (s ,valid_rows * sizeof (float ),v_sum_float ); 808 } 809} 810 811static void flat_vec_dot_iq4nl_32x2 (const uint32_t n ,float * restricts0 ,float * restricts1 ,const void * restrictvx ,const void * restrictvy0 ,const void * restrictvy1 ,uint32_t valid_rows ,const float * restrictsz0 ,const float * restrictsz1 ) { 812const uint8_t * restricttile_ptr = vx ; 813const uint8_t * restricty0_q = vy0 ; 814const uint8_t * restricty1_q = vy1 ; 815 816HVX_Vector v_sum_float_c0 = Q6_V_vzero (); 817HVX_Vector v_sum_float_c1 = Q6_V_vzero (); 818HVX_Vector mask_h4 = Q6_Vb_vsplat_R (0x0F ); 819HVX_Vector lut = * (const HVX_Vector * )kvalues_iq4nl_lut ; 820 821static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 8220x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8230x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8240x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8250x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8260x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8270x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8280x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 8290x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 830 }; 831HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 832 833const uint32_t quants_size = hex_round_up (n ,128 ); 834const __fp16 * restricty0_scales = (const __fp16 * ) (y0_q + quants_size ); 835const __fp16 * restricty1_scales = (const __fp16 * ) (y1_q + quants_size ); 836 837uint32_t n_k_tiles = n /32 ; 838for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 839const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 840 841uint32_t block_idx = kt /4 ; 842uint32_t sub_idx = kt %4 ; 843 844HVX_Vector vx0 = * (const HVX_Vector * ) (y0_q + block_idx * 128 ); 845HVX_Vector vx1 = * (const HVX_Vector * ) (y1_q + block_idx * 128 ); 846 847HVX_Vector v_act0_raw = Q6_V_vror_VR (vx0 ,sub_idx * 32 ); 848HVX_Vector v_act1_raw = Q6_V_vror_VR (vx1 ,sub_idx * 32 ); 849 850HVX_Vector v_act0_rep [8 ]; 851v_act0_rep [0 ]= Q6_V_vdelta_VV (v_act0_raw ,v_repl_ctrl ); 852v_act0_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,4 ),v_repl_ctrl ); 853v_act0_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,8 ),v_repl_ctrl ); 854v_act0_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,12 ),v_repl_ctrl ); 855v_act0_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,16 ),v_repl_ctrl ); 856v_act0_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,20 ),v_repl_ctrl ); 857v_act0_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,24 ),v_repl_ctrl ); 858v_act0_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,28 ),v_repl_ctrl ); 859 860HVX_Vector v_act1_rep [8 ]; 861v_act1_rep [0 ]= Q6_V_vdelta_VV (v_act1_raw ,v_repl_ctrl ); 862v_act1_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,4 ),v_repl_ctrl ); 863v_act1_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,8 ),v_repl_ctrl ); 864v_act1_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,12 ),v_repl_ctrl ); 865v_act1_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,16 ),v_repl_ctrl ); 866v_act1_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,20 ),v_repl_ctrl ); 867v_act1_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,24 ),v_repl_ctrl ); 868v_act1_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,28 ),v_repl_ctrl ); 869 870HVX_VectorPair v_sums = accum_4bit_32x2_lut (vptr ,v_act0_rep ,v_act1_rep ,mask_h4 ,lut ); 871HVX_Vector v_sum_c0 = Q6_V_lo_W (v_sums ); 872HVX_Vector v_sum_c1 = Q6_V_hi_W (v_sums ); 873 874HVX_Vector v_sum_sf_c0 = Q6_Vsf_equals_Vw (v_sum_c0 ); 875HVX_Vector v_sum_sf_c1 = Q6_Vsf_equals_Vw (v_sum_c1 ); 876 877HVX_Vector v_scale_w = vptr [4 ]; 878 879__fp16 scale_a0_val = y0_scales [kt ]; 880__fp16 scale_a1_val = y1_scales [kt ]; 881HVX_Vector v_scale_a0 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a0_val )); 882HVX_Vector v_scale_a1 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a1_val )); 883 884HVX_Vector v_scale_comb_c0 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a0 ); 885HVX_Vector v_scale_comb_c1 = hvx_vec_mul_f16_f16_to_f32_lower32 (v_scale_w ,v_scale_a1 ); 886 887HVX_Vector v_sum_scaled_c0 = hvx_vec_mul_f32_f32 (v_sum_sf_c0 ,v_scale_comb_c0 ); 888HVX_Vector v_sum_scaled_c1 = hvx_vec_mul_f32_f32 (v_sum_sf_c1 ,v_scale_comb_c1 ); 889 890v_sum_float_c0 = hvx_vec_add_f32_f32 (v_sum_float_c0 ,v_sum_scaled_c0 ); 891v_sum_float_c1 = hvx_vec_add_f32_f32 (v_sum_float_c1 ,v_sum_scaled_c1 ); 892 } 893 894if (sz0 ) { 895hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c0 ,hvx_vmemu (sz0 ))); 896 }else { 897hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),v_sum_float_c0 ); 898 } 899if (sz1 ) { 900hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c1 ,hvx_vmemu (sz1 ))); 901 }else { 902hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),v_sum_float_c1 ); 903 } 904} 905 906static void flat_vec_dot_mxfp4_32x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ,uint32_t valid_rows ,const float * restrictsz ) { 907const uint8_t * restricttile_ptr = vx ; 908const uint8_t * restricty_q = vy ; 909 910HVX_Vector v_sum_float = Q6_V_vzero (); 911HVX_Vector mask_h4 = Q6_Vb_vsplat_R (0x0F ); 912HVX_Vector lut = * (const HVX_Vector * )kvalues_mxfp4_lut ; 913HVX_Vector expand = * (const HVX_Vector * )expand_x32_e8m0 ; 914HVX_Vector e8m0_mask = Q6_V_vsplat_R (0x000000ff ); 915 916static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 9170x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9180x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9190x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9200x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9210x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9220x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9230x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9240x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 925 }; 926HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 927 928const uint32_t quants_size = hex_round_up (n ,128 ); 929const __fp16 * restricty_scales = (const __fp16 * ) (y_q + quants_size ); 930 931uint32_t n_k_tiles = n /32 ; 932for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 933const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 934 935uint32_t block_idx = kt /4 ; 936uint32_t sub_idx = kt %4 ; 937 938HVX_Vector vx = * (const HVX_Vector * ) (y_q + block_idx * 128 ); 939HVX_Vector v_act_raw = Q6_V_vror_VR (vx ,sub_idx * 32 ); 940 941HVX_Vector v_act_rep [8 ]; 942v_act_rep [0 ]= Q6_V_vdelta_VV (v_act_raw ,v_repl_ctrl ); 943v_act_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,4 ),v_repl_ctrl ); 944v_act_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,8 ),v_repl_ctrl ); 945v_act_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,12 ),v_repl_ctrl ); 946v_act_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,16 ),v_repl_ctrl ); 947v_act_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,20 ),v_repl_ctrl ); 948v_act_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,24 ),v_repl_ctrl ); 949v_act_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act_raw ,28 ),v_repl_ctrl ); 950 951HVX_Vector v_sum = accum_4bit_32x1_lut (vptr ,v_act_rep ,mask_h4 ,lut ); 952HVX_Vector v_sum_sf = Q6_Vsf_equals_Vw (v_sum ); 953 954HVX_Vector v_scale_w = hvx_vmem (tile_ptr + kt * 640 + 512 ); 955HVX_Vector r0_d = Q6_V_vdelta_VV (v_scale_w ,expand ); 956r0_d = Q6_V_vand_VV (r0_d ,e8m0_mask ); 957HVX_Vector v_scale_w_f32 = Q6_Vw_vasl_VwR (r0_d ,23 ); 958 959__fp16 scale_a_val = y_scales [kt ]; 960HVX_Vector v_scale_a_f16 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a_val )); 961HVX_VectorPair p_scale_a_f32 = hvx_vec_f16_to_f32 (v_scale_a_f16 ); 962HVX_Vector v_scale_a = Q6_V_lo_W (p_scale_a_f32 ); 963 964HVX_Vector v_scale_comb = hvx_vec_mul_f32_f32 (v_scale_w_f32 ,v_scale_a ); 965HVX_Vector v_sum_scaled = hvx_vec_mul_f32_f32 (v_sum_sf ,v_scale_comb ); 966 967v_sum_float = hvx_vec_add_f32_f32 (v_sum_float ,v_sum_scaled ); 968 } 969 970v_sum_float = hvx_vec_mul_f32_f32 (v_sum_float ,hvx_vec_splat_f32 (0.5f )); 971 972if (sz ) { 973hvx_vec_store_u (s ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float ,hvx_vmemu (sz ))); 974 }else { 975hvx_vec_store_u (s ,valid_rows * sizeof (float ),v_sum_float ); 976 } 977} 978 979static void flat_vec_dot_mxfp4_32x2 (const uint32_t n ,float * restricts0 ,float * restricts1 ,const void * restrictvx ,const void * restrictvy0 ,const void * restrictvy1 ,uint32_t valid_rows ,const float * restrictsz0 ,const float * restrictsz1 ) { 980const uint8_t * restricttile_ptr = vx ; 981const uint8_t * restricty0_q = vy0 ; 982const uint8_t * restricty1_q = vy1 ; 983 984HVX_Vector v_sum_float_c0 = Q6_V_vzero (); 985HVX_Vector v_sum_float_c1 = Q6_V_vzero (); 986HVX_Vector mask_h4 = Q6_Vb_vsplat_R (0x0F ); 987HVX_Vector lut = * (const HVX_Vector * )kvalues_mxfp4_lut ; 988HVX_Vector expand = * (const HVX_Vector * )expand_x32_e8m0 ; 989HVX_Vector e8m0_mask = Q6_V_vsplat_R (0x000000ff ); 990 991static const uint8_t __attribute__((aligned (128 )))repl [128 ]= { 9920x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9930x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9940x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9950x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9960x40 ,0x40 ,0x40 ,0x40 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9970x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9980x20 ,0x20 ,0x20 ,0x20 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 9990x10 ,0x10 ,0x10 ,0x10 ,0x04 ,0x04 ,0x04 ,0x04 ,0x08 ,0x08 ,0x08 ,0x08 ,0x04 ,0x04 ,0x04 ,0x04 , 1000 }; 1001HVX_Vector v_repl_ctrl = * (const HVX_Vector * )repl ; 1002 1003const uint32_t quants_size = hex_round_up (n ,128 ); 1004const __fp16 * restricty0_scales = (const __fp16 * ) (y0_q + quants_size ); 1005const __fp16 * restricty1_scales = (const __fp16 * ) (y1_q + quants_size ); 1006 1007uint32_t n_k_tiles = n /32 ; 1008for (uint32_t kt = 0 ;kt < n_k_tiles ;kt ++ ) { 1009const HVX_Vector * restrictvptr = (const HVX_Vector * ) (tile_ptr + kt * 640 ); 1010 1011uint32_t block_idx = kt /4 ; 1012uint32_t sub_idx = kt %4 ; 1013 1014HVX_Vector vx0 = * (const HVX_Vector * ) (y0_q + block_idx * 128 ); 1015HVX_Vector vx1 = * (const HVX_Vector * ) (y1_q + block_idx * 128 ); 1016 1017HVX_Vector v_act0_raw = Q6_V_vror_VR (vx0 ,sub_idx * 32 ); 1018HVX_Vector v_act1_raw = Q6_V_vror_VR (vx1 ,sub_idx * 32 ); 1019 1020HVX_Vector v_act0_rep [8 ]; 1021v_act0_rep [0 ]= Q6_V_vdelta_VV (v_act0_raw ,v_repl_ctrl ); 1022v_act0_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,4 ),v_repl_ctrl ); 1023v_act0_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,8 ),v_repl_ctrl ); 1024v_act0_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,12 ),v_repl_ctrl ); 1025v_act0_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,16 ),v_repl_ctrl ); 1026v_act0_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,20 ),v_repl_ctrl ); 1027v_act0_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,24 ),v_repl_ctrl ); 1028v_act0_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act0_raw ,28 ),v_repl_ctrl ); 1029 1030HVX_Vector v_act1_rep [8 ]; 1031v_act1_rep [0 ]= Q6_V_vdelta_VV (v_act1_raw ,v_repl_ctrl ); 1032v_act1_rep [1 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,4 ),v_repl_ctrl ); 1033v_act1_rep [2 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,8 ),v_repl_ctrl ); 1034v_act1_rep [3 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,12 ),v_repl_ctrl ); 1035v_act1_rep [4 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,16 ),v_repl_ctrl ); 1036v_act1_rep [5 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,20 ),v_repl_ctrl ); 1037v_act1_rep [6 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,24 ),v_repl_ctrl ); 1038v_act1_rep [7 ]= Q6_V_vdelta_VV (Q6_V_vror_VR (v_act1_raw ,28 ),v_repl_ctrl ); 1039 1040HVX_VectorPair v_sums = accum_4bit_32x2_lut (vptr ,v_act0_rep ,v_act1_rep ,mask_h4 ,lut ); 1041HVX_Vector v_sum_c0 = Q6_V_lo_W (v_sums ); 1042HVX_Vector v_sum_c1 = Q6_V_hi_W (v_sums ); 1043 1044HVX_Vector v_sum_sf_c0 = Q6_Vsf_equals_Vw (v_sum_c0 ); 1045HVX_Vector v_sum_sf_c1 = Q6_Vsf_equals_Vw (v_sum_c1 ); 1046 1047HVX_Vector v_scale_w = hvx_vmem (tile_ptr + kt * 640 + 512 ); 1048HVX_Vector r0_d = Q6_V_vdelta_VV (v_scale_w ,expand ); 1049r0_d = Q6_V_vand_VV (r0_d ,e8m0_mask ); 1050HVX_Vector v_scale_w_f32 = Q6_Vw_vasl_VwR (r0_d ,23 ); 1051 1052__fp16 scale_a0_val = y0_scales [kt ]; 1053__fp16 scale_a1_val = y1_scales [kt ]; 1054HVX_Vector v_scale_a0_f16 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a0_val )); 1055HVX_Vector v_scale_a1_f16 = hvx_vec_repl_f16 (Q6_Vh_vsplat_R (* (const int16_t * )& scale_a1_val )); 1056HVX_VectorPair p_scale_a0_f32 = hvx_vec_f16_to_f32 (v_scale_a0_f16 ); 1057HVX_VectorPair p_scale_a1_f32 = hvx_vec_f16_to_f32 (v_scale_a1_f16 ); 1058HVX_Vector v_scale_a0 = Q6_V_lo_W (p_scale_a0_f32 ); 1059HVX_Vector v_scale_a1 = Q6_V_lo_W (p_scale_a1_f32 ); 1060 1061HVX_Vector v_scale_comb_c0 = hvx_vec_mul_f32_f32 (v_scale_w_f32 ,v_scale_a0 ); 1062HVX_Vector v_scale_comb_c1 = hvx_vec_mul_f32_f32 (v_scale_w_f32 ,v_scale_a1 ); 1063 1064HVX_Vector v_sum_scaled_c0 = hvx_vec_mul_f32_f32 (v_sum_sf_c0 ,v_scale_comb_c0 ); 1065HVX_Vector v_sum_scaled_c1 = hvx_vec_mul_f32_f32 (v_sum_sf_c1 ,v_scale_comb_c1 ); 1066 1067v_sum_float_c0 = hvx_vec_add_f32_f32 (v_sum_float_c0 ,v_sum_scaled_c0 ); 1068v_sum_float_c1 = hvx_vec_add_f32_f32 (v_sum_float_c1 ,v_sum_scaled_c1 ); 1069 } 1070 1071v_sum_float_c0 = hvx_vec_mul_f32_f32 (v_sum_float_c0 ,hvx_vec_splat_f32 (0.5f )); 1072v_sum_float_c1 = hvx_vec_mul_f32_f32 (v_sum_float_c1 ,hvx_vec_splat_f32 (0.5f )); 1073 1074if (sz0 ) { 1075hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c0 ,hvx_vmemu (sz0 ))); 1076 }else { 1077hvx_vec_store_u (s0 ,valid_rows * sizeof (float ),v_sum_float_c0 ); 1078 } 1079if (sz1 ) { 1080hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),hvx_vec_add_f32_f32 (v_sum_float_c1 ,hvx_vmemu (sz1 ))); 1081 }else { 1082hvx_vec_store_u (s1 ,valid_rows * sizeof (float ),v_sum_float_c1 ); 1083 } 1084} 1085 1086#if __HVX_ARCH__ < 79 1087#define HVX_OP_ADD_F32 (a ,b ) Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(a, b)) 1088#define HVX_OP_MUL_F32 (a ,b ) Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(a, b)) 1089#else 1090#define HVX_OP_ADD_F32 (a ,b ) Q6_Vsf_vadd_VsfVsf(a, b) 1091#define HVX_OP_MUL_F32 (a ,b ) Q6_Vsf_vmpy_VsfVsf(a, b) 1092#endif 1093 1094static inline void vec_dot_f32_f32_aa_1x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ) { 1095const HVX_Vector * restrictx = (const HVX_Vector * )vx ; 1096const HVX_Vector * restricty = (const HVX_Vector * )vy ; 1097 1098uint32_t nvec = n /VLEN_FP32 ;// num full fp32 hvx vectors 1099uint32_t nloe = n %VLEN_FP32 ;// leftover elements 1100 1101HVX_Vector rsum = Q6_V_vzero (); 1102 1103uint32_t i = 0 ; 1104 1105#pragma unroll(4) 1106for (i = 0 ;i < nvec ;i ++ ) { 1107HVX_Vector prod = HVX_OP_MUL_F32 (x [i ],y [i ]); 1108rsum = HVX_OP_ADD_F32 (rsum ,prod ); 1109 } 1110 1111if (nloe ) { 1112HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 4 ); 1113HVX_Vector x_sf = Q6_V_vand_QV (bmask ,x [i ]); 1114HVX_Vector y_sf = Q6_V_vand_QV (bmask ,y [i ]); 1115HVX_Vector prod = HVX_OP_MUL_F32 (x_sf ,y_sf ); 1116rsum = HVX_OP_ADD_F32 (rsum ,prod ); 1117 } 1118 1119* s = hvx_vec_get_f32 (hvx_vec_reduce_sum_f32 (rsum )); 1120} 1121 1122static inline void vec_dot_f32_f32_aa_2x1 (const uint32_t n ,float * restricts0 , 1123const void * restrictvx0 ,const void * restrictvx1 , 1124const void * restrictvy0 ) { 1125const HVX_Vector * restrictx0 = (const HVX_Vector * )vx0 ; 1126const HVX_Vector * restrictx1 = (const HVX_Vector * )vx1 ; 1127const HVX_Vector * restricty = (const HVX_Vector * )vy0 ; 1128 1129uint32_t nvec = n /VLEN_FP32 ; 1130uint32_t nloe = n %VLEN_FP32 ; 1131 1132HVX_Vector rsum0 = Q6_V_vzero (); 1133HVX_Vector rsum1 = Q6_V_vzero (); 1134 1135uint32_t i = 0 ; 1136 1137#pragma unroll(2) 1138for (i = 0 ;i < nvec ;i ++ ) { 1139HVX_Vector y_sf = y [i ]; 1140HVX_Vector prod0 = HVX_OP_MUL_F32 (x0 [i ],y_sf ); 1141HVX_Vector prod1 = HVX_OP_MUL_F32 (x1 [i ],y_sf ); 1142rsum0 = HVX_OP_ADD_F32 (rsum0 ,prod0 ); 1143rsum1 = HVX_OP_ADD_F32 (rsum1 ,prod1 ); 1144 } 1145 1146if (nloe ) { 1147HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 4 ); 1148HVX_Vector y_sf = Q6_V_vand_QV (bmask ,y [i ]); 1149HVX_Vector x0_sf = Q6_V_vand_QV (bmask ,x0 [i ]); 1150HVX_Vector x1_sf = Q6_V_vand_QV (bmask ,x1 [i ]); 1151HVX_Vector prod0 = HVX_OP_MUL_F32 (x0_sf ,y_sf ); 1152HVX_Vector prod1 = HVX_OP_MUL_F32 (x1_sf ,y_sf ); 1153rsum0 = HVX_OP_ADD_F32 (rsum0 ,prod0 ); 1154rsum1 = HVX_OP_ADD_F32 (rsum1 ,prod1 ); 1155 } 1156 1157HVX_Vector rsum = hvx_vec_reduce_sum_f32x2 (rsum0 ,rsum1 ); 1158hvx_vec_store_u (s0 ,8 ,rsum ); 1159} 1160 1161static inline void vec_dot_f32_f32_aa_2x2 (const uint32_t n ,float * restricts0 ,float * restricts1 , 1162const void * restrictvx0 ,const void * restrictvx1 , 1163const void * restrictvy0 ,const void * restrictvy1 ) { 1164const HVX_Vector * restrictx0 = (const HVX_Vector * )vx0 ; 1165const HVX_Vector * restrictx1 = (const HVX_Vector * )vx1 ; 1166const HVX_Vector * restricty0 = (const HVX_Vector * )vy0 ; 1167const HVX_Vector * restricty1 = (const HVX_Vector * )vy1 ; 1168 1169uint32_t nvec = n /VLEN_FP32 ; 1170uint32_t nloe = n %VLEN_FP32 ; 1171 1172HVX_Vector r0_c0_sum = Q6_V_vzero (); 1173HVX_Vector r0_c1_sum = Q6_V_vzero (); 1174HVX_Vector r1_c0_sum = Q6_V_vzero (); 1175HVX_Vector r1_c1_sum = Q6_V_vzero (); 1176 1177uint32_t i = 0 ; 1178 1179#pragma unroll(2) 1180for (i = 0 ;i < nvec ;i ++ ) { 1181HVX_Vector r0_sf = x0 [i ]; 1182HVX_Vector r1_sf = x1 [i ]; 1183HVX_Vector c0_sf = y0 [i ]; 1184HVX_Vector c1_sf = y1 [i ]; 1185 1186r0_c0_sum = HVX_OP_ADD_F32 (r0_c0_sum ,HVX_OP_MUL_F32 (r0_sf ,c0_sf )); 1187r0_c1_sum = HVX_OP_ADD_F32 (r0_c1_sum ,HVX_OP_MUL_F32 (r0_sf ,c1_sf )); 1188r1_c0_sum = HVX_OP_ADD_F32 (r1_c0_sum ,HVX_OP_MUL_F32 (r1_sf ,c0_sf )); 1189r1_c1_sum = HVX_OP_ADD_F32 (r1_c1_sum ,HVX_OP_MUL_F32 (r1_sf ,c1_sf )); 1190 } 1191 1192if (nloe ) { 1193HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 4 ); 1194 1195HVX_Vector r0_sf = Q6_V_vand_QV (bmask ,x0 [i ]); 1196HVX_Vector r1_sf = Q6_V_vand_QV (bmask ,x1 [i ]); 1197HVX_Vector c0_sf = Q6_V_vand_QV (bmask ,y0 [i ]); 1198HVX_Vector c1_sf = Q6_V_vand_QV (bmask ,y1 [i ]); 1199 1200r0_c0_sum = HVX_OP_ADD_F32 (r0_c0_sum ,HVX_OP_MUL_F32 (r0_sf ,c0_sf )); 1201r0_c1_sum = HVX_OP_ADD_F32 (r0_c1_sum ,HVX_OP_MUL_F32 (r0_sf ,c1_sf )); 1202r1_c0_sum = HVX_OP_ADD_F32 (r1_c0_sum ,HVX_OP_MUL_F32 (r1_sf ,c0_sf )); 1203r1_c1_sum = HVX_OP_ADD_F32 (r1_c1_sum ,HVX_OP_MUL_F32 (r1_sf ,c1_sf )); 1204 } 1205 1206// Reduce and store results 1207HVX_Vector r0_r1_c0_sum = hvx_vec_reduce_sum_f32x2 (r0_c0_sum ,r1_c0_sum ); 1208HVX_Vector r0_r1_c1_sum = hvx_vec_reduce_sum_f32x2 (r0_c1_sum ,r1_c1_sum ); 1209 1210hvx_vec_store_u (s0 ,8 ,r0_r1_c0_sum ); 1211hvx_vec_store_u (s1 ,8 ,r0_r1_c1_sum ); 1212} 1213 1214static inline void vec_dot_f32_f32_uu_1x1 (const uint32_t n ,float * restricts ,const void * restrictx ,const void * restricty ) { 1215const HVX_UVector * restrictvx = (const HVX_UVector * restrict)x ; 1216const HVX_UVector * restrictvy = (const HVX_UVector * restrict)y ; 1217 1218uint32_t nvec = n /VLEN_FP32 ;// num full fp32 hvx vectors 1219uint32_t nloe = n %VLEN_FP32 ;// leftover elements 1220 1221HVX_Vector rsum = Q6_V_vzero (); 1222 1223uint32_t i = 0 ; 1224 1225#pragma unroll(2) 1226for (i = 0 ;i < nvec ;i ++ ) { 1227HVX_Vector x_sf = vx [i ]; 1228HVX_Vector y_sf = vy [i ]; 1229 1230rsum = HVX_OP_ADD_F32 (rsum ,HVX_OP_MUL_F32 (x_sf ,y_sf )); 1231 } 1232 1233if (nloe ) { 1234HVX_Vector x_sf = vx [i ]; 1235HVX_Vector y_sf = vy [i ]; 1236 1237HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 4 ); 1238x_sf = Q6_V_vand_QV (bmask ,x_sf ); 1239y_sf = Q6_V_vand_QV (bmask ,y_sf ); 1240 1241rsum = HVX_OP_ADD_F32 (rsum ,HVX_OP_MUL_F32 (x_sf ,y_sf )); 1242 } 1243 1244rsum = hvx_vec_reduce_sum_f32 (rsum ); 1245hvx_vec_store_u (& s [0 ],4 ,rsum ); 1246} 1247 1248#undef HVX_OP_ADD_F32 1249#undef HVX_OP_MUL_F32 1250 1251static inline void vec_dot_f16_f16_aa_1x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ) { 1252const HVX_Vector * restrictx = (const HVX_Vector * )vx ; 1253const HVX_Vector * restricty = (const HVX_Vector * )vy ; 1254 1255uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 1256uint32_t nloe = n %VLEN_FP16 ;// leftover elements 1257 1258HVX_VectorPair rsum_p = Q6_W_vzero (); 1259 1260uint32_t i = 0 ; 1261 1262#pragma unroll(4) 1263for (i = 0 ;i < nvec ;i ++ ) { 1264rsum_p = hvx_vec_mpyacc_f32_f16 (rsum_p ,x [i ],y [i ]); 1265 } 1266 1267if (nloe ) { 1268HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 1269HVX_Vector x_hf = Q6_V_vand_QV (bmask ,x [i ]); 1270HVX_Vector y_hf = Q6_V_vand_QV (bmask ,y [i ]); 1271rsum_p = hvx_vec_mpyacc_f32_f16 (rsum_p ,x_hf ,y_hf ); 1272 } 1273 1274HVX_Vector rsum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (rsum_p ),Q6_V_hi_W (rsum_p ))); 1275hvx_vec_store_u (s ,4 ,hvx_vec_reduce_sum_f32 (rsum )); 1276} 1277 1278static inline void vec_dot_f16_f16_aa_2x1 (const uint32_t n ,float * restricts0 , 1279const void * restrictvx0 ,const void * restrictvx1 , 1280const void * restrictvy0 ) { 1281const HVX_Vector * restrictx0 = (const HVX_Vector * )vx0 ; 1282const HVX_Vector * restrictx1 = (const HVX_Vector * )vx1 ; 1283const HVX_Vector * restricty = (const HVX_Vector * )vy0 ; 1284 1285uint32_t nvec = n /VLEN_FP16 ; 1286uint32_t nloe = n %VLEN_FP16 ; 1287 1288HVX_VectorPair rsum0_p = Q6_W_vzero (); 1289HVX_VectorPair rsum1_p = Q6_W_vzero (); 1290 1291uint32_t i = 0 ; 1292 1293#pragma unroll(2) 1294for (i = 0 ;i < nvec ;i ++ ) { 1295HVX_Vector y_hf = y [i ]; 1296rsum0_p = hvx_vec_mpyacc_f32_f16 (rsum0_p ,x0 [i ],y_hf ); 1297rsum1_p = hvx_vec_mpyacc_f32_f16 (rsum1_p ,x1 [i ],y_hf ); 1298 } 1299 1300if (nloe ) { 1301HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 1302HVX_Vector y_hf = Q6_V_vand_QV (bmask ,y [i ]); 1303HVX_Vector x0_hf = Q6_V_vand_QV (bmask ,x0 [i ]); 1304HVX_Vector x1_hf = Q6_V_vand_QV (bmask ,x1 [i ]); 1305rsum0_p = hvx_vec_mpyacc_f32_f16 (rsum0_p ,x0_hf ,y_hf ); 1306rsum1_p = hvx_vec_mpyacc_f32_f16 (rsum1_p ,x1_hf ,y_hf ); 1307 } 1308 1309HVX_Vector rsum0 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (rsum0_p ),Q6_V_hi_W (rsum0_p ))); 1310HVX_Vector rsum1 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (rsum1_p ),Q6_V_hi_W (rsum1_p ))); 1311HVX_Vector rsum = hvx_vec_reduce_sum_f32x2 (rsum0 ,rsum1 ); 1312hvx_vec_store_u (s0 ,8 ,rsum ); 1313} 1314 1315static inline void vec_dot_f16_f16_aa_2x2 (const uint32_t n ,float * restricts0 ,float * restricts1 , 1316const void * restrictvx0 ,const void * restrictvx1 , 1317const void * restrictvy0 ,const void * restrictvy1 ) { 1318const HVX_Vector * restrictx0 = (const HVX_Vector * )vx0 ; 1319const HVX_Vector * restrictx1 = (const HVX_Vector * )vx1 ; 1320const HVX_Vector * restricty0 = (const HVX_Vector * )vy0 ; 1321const HVX_Vector * restricty1 = (const HVX_Vector * )vy1 ; 1322 1323uint32_t nvec = n /VLEN_FP16 ; 1324uint32_t nloe = n %VLEN_FP16 ; 1325 1326// Row sums (sf) - 4 accumulators for 2x2 tile 1327HVX_VectorPair r0_c0_sum_p = Q6_W_vzero (); 1328HVX_VectorPair r0_c1_sum_p = Q6_W_vzero (); 1329HVX_VectorPair r1_c0_sum_p = Q6_W_vzero (); 1330HVX_VectorPair r1_c1_sum_p = Q6_W_vzero (); 1331 1332uint32_t i = 0 ; 1333 1334#pragma unroll(2) 1335for (i = 0 ;i < nvec ;i ++ ) { 1336HVX_Vector r0_hf = x0 [i ]; 1337HVX_Vector r1_hf = x1 [i ]; 1338HVX_Vector c0_hf = y0 [i ]; 1339HVX_Vector c1_hf = y1 [i ]; 1340 1341// Compute 4 dot products: r0xc0, r0xc1, r1xc0, r1xc1 1342r0_c0_sum_p = hvx_vec_mpyacc_f32_f16 (r0_c0_sum_p ,r0_hf ,c0_hf ); 1343r0_c1_sum_p = hvx_vec_mpyacc_f32_f16 (r0_c1_sum_p ,r0_hf ,c1_hf ); 1344r1_c0_sum_p = hvx_vec_mpyacc_f32_f16 (r1_c0_sum_p ,r1_hf ,c0_hf ); 1345r1_c1_sum_p = hvx_vec_mpyacc_f32_f16 (r1_c1_sum_p ,r1_hf ,c1_hf ); 1346 } 1347 1348if (nloe ) { 1349HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 1350 1351HVX_Vector r0_hf = Q6_V_vand_QV (bmask ,x0 [i ]); 1352HVX_Vector r1_hf = Q6_V_vand_QV (bmask ,x1 [i ]); 1353HVX_Vector c0_hf = Q6_V_vand_QV (bmask ,y0 [i ]); 1354HVX_Vector c1_hf = Q6_V_vand_QV (bmask ,y1 [i ]); 1355 1356r0_c0_sum_p = hvx_vec_mpyacc_f32_f16 (r0_c0_sum_p ,r0_hf ,c0_hf ); 1357r0_c1_sum_p = hvx_vec_mpyacc_f32_f16 (r0_c1_sum_p ,r0_hf ,c1_hf ); 1358r1_c0_sum_p = hvx_vec_mpyacc_f32_f16 (r1_c0_sum_p ,r1_hf ,c0_hf ); 1359r1_c1_sum_p = hvx_vec_mpyacc_f32_f16 (r1_c1_sum_p ,r1_hf ,c1_hf ); 1360 } 1361 1362HVX_Vector r0_c0_sum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (r0_c0_sum_p ),Q6_V_hi_W (r0_c0_sum_p ))); 1363HVX_Vector r0_c1_sum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (r0_c1_sum_p ),Q6_V_hi_W (r0_c1_sum_p ))); 1364HVX_Vector r1_c0_sum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (r1_c0_sum_p ),Q6_V_hi_W (r1_c0_sum_p ))); 1365HVX_Vector r1_c1_sum = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (Q6_V_lo_W (r1_c1_sum_p ),Q6_V_hi_W (r1_c1_sum_p ))); 1366 1367// Reduce and store results 1368HVX_Vector r0_r1_c0_sum = hvx_vec_reduce_sum_f32x2 (r0_c0_sum ,r1_c0_sum ); 1369HVX_Vector r0_r1_c1_sum = hvx_vec_reduce_sum_f32x2 (r0_c1_sum ,r1_c1_sum ); 1370 1371hvx_vec_store_u (& s0 [0 ],8 ,r0_r1_c0_sum );// row0,col0 row1,col0 1372hvx_vec_store_u (& s1 [0 ],8 ,r0_r1_c1_sum );// row0,col1 row1,col1 1373} 1374 1375static inline void vec_dot_f16_f16_uu_1x1 (const uint32_t n ,float * restricts ,const void * restrictvx ,const void * restrictvy ) { 1376const HVX_UVector * restrictx = (const HVX_UVector * )vx ; 1377const HVX_UVector * restricty = (const HVX_UVector * )vy ; 1378 1379uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 1380uint32_t nloe = n %VLEN_FP16 ;// leftover elements 1381 1382HVX_Vector rsum = Q6_V_vzero (); 1383 1384uint32_t i = 0 ; 1385 1386#pragma unroll(4) 1387for (i = 0 ;i < nvec ;i ++ ) { 1388HVX_VectorPair xy_qf = Q6_Wqf32_vmpy_VhfVhf (x [i ],y [i ]); 1389rsum = Q6_Vqf32_vadd_Vqf32Vqf32 (rsum ,Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_lo_W (xy_qf ),Q6_V_hi_W (xy_qf ))); 1390 } 1391 1392if (nloe ) { 1393HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 1394HVX_Vector x_hf = Q6_V_vand_QV (bmask ,x [i ]); 1395HVX_Vector y_hf = Q6_V_vand_QV (bmask ,y [i ]); 1396 1397HVX_VectorPair xy_qf = Q6_Wqf32_vmpy_VhfVhf (x_hf ,y_hf ); 1398rsum = Q6_Vqf32_vadd_Vqf32Vqf32 (rsum ,Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_lo_W (xy_qf ),Q6_V_hi_W (xy_qf ))); 1399 } 1400 1401rsum = hvx_vec_reduce_sum_f32 (Q6_Vsf_equals_Vqf32 (rsum )); 1402hvx_vec_store_u (& s [0 ],4 ,rsum ); 1403} 1404 1405static inline void vec_dot_f16_f32_uu_1x1 (const uint32_t n ,float * restricts ,const void * restrictx ,const void * restricty ) { 1406const HVX_UVector * restrictvx = (const HVX_UVector * restrict)x ; 1407const HVX_UVector * restrictvy = (const HVX_UVector * restrict)y ; 1408 1409uint32_t nvec = n /VLEN_FP16 ;// num full fp16 hvx vectors 1410uint32_t nloe = n %VLEN_FP16 ;// leftover elements 1411 1412const HVX_Vector zero = Q6_V_vzero (); 1413 1414HVX_Vector rsum = Q6_V_vzero (); 1415 1416uint32_t i = 0 ; 1417 1418#pragma unroll(2) 1419for (i = 0 ;i < nvec ;i ++ ) { 1420// Load y (fp32) and convert into fp16 1421HVX_Vector y0_qf = Q6_Vqf32_vsub_VsfVsf (vy [i * 2 + 0 ],zero );// 32 elements 1422HVX_Vector y1_qf = Q6_Vqf32_vsub_VsfVsf (vy [i * 2 + 1 ],zero );// 32 elements 1423HVX_Vector y_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (y1_qf ,y0_qf ))); 1424 1425// Load x (fp16) 1426HVX_Vector x_hf = vx [i ]; 1427 1428HVX_VectorPair xy_qf = Q6_Wqf32_vmpy_VhfVhf (x_hf ,y_hf ); 1429 1430rsum = Q6_Vqf32_vadd_Vqf32Vqf32 (rsum ,Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_lo_W (xy_qf ),Q6_V_hi_W (xy_qf ))); 1431 } 1432 1433if (nloe ) { 1434// Load y (fp32) and convert into fp16 1435HVX_Vector y0_qf = Q6_Vqf32_vsub_VsfVsf (vy [i * 2 + 0 ],zero );// 32 elements 1436HVX_Vector y1_qf = Q6_Vqf32_vsub_VsfVsf (vy [i * 2 + 1 ],zero );// 32 elements 1437HVX_Vector y_hf = Q6_Vh_vdeal_Vh (Q6_Vhf_equals_Wqf32 (Q6_W_vcombine_VV (y1_qf ,y0_qf ))); 1438 1439// Load x (fp16) 1440HVX_Vector x_hf = vx [i ]; 1441 1442// Zero-out unused elements 1443// Note that we need to clear both x and y because they may contain NANs 1444HVX_VectorPred bmask = Q6_Q_vsetq_R (nloe * 2 ); 1445x_hf = Q6_V_vand_QV (bmask ,x_hf ); 1446y_hf = Q6_V_vand_QV (bmask ,y_hf ); 1447 1448HVX_VectorPair xy_qf = Q6_Wqf32_vmpy_VhfVhf (x_hf ,y_hf ); 1449 1450rsum = Q6_Vqf32_vadd_Vqf32Vqf32 (rsum ,Q6_Vqf32_vadd_Vqf32Vqf32 (Q6_V_lo_W (xy_qf ),Q6_V_hi_W (xy_qf ))); 1451 } 1452 1453// Convert into fp32 and reduce 1454rsum = hvx_vec_reduce_sum_f32 (Q6_Vsf_equals_Vqf32 (rsum )); 1455hvx_vec_store_u (& s [0 ],4 ,rsum ); 1456} 1457 1458static inline void hvx_tensor_add_f32_grid ( 1459const struct htp_tensor * restrictdst , 1460const struct htp_tensor * restrictsrc2 , 1461uint32_t start_row , 1462uint32_t end_row , 1463uint32_t start_col , 1464uint32_t end_col , 1465const struct fastdiv_values * div_ne11_12 , 1466const struct fastdiv_values * div_ne11 1467) { 1468if (start_row >=end_row || start_col >=end_col )return ; 1469const uint32_t nb1 = dst -> nb [1 ];// row stride in bytes 1470 1471const uint32_t ne11 = dst -> ne [1 ]; 1472const uint32_t ne12 = dst -> ne [2 ]; 1473const uint32_t ne11_12 = ne11 * ne12 ; 1474 1475const bool is_broadcast1 = (src2 -> ne [1 ]== 1 ); 1476const bool is_broadcast2 = (src2 -> ne [2 ]== 1 ); 1477const bool is_broadcast3 = (src2 -> ne [3 ]== 1 ); 1478 1479for (uint32_t r = start_row ;r < end_row ;r ++ ) { 1480float * dst_row = (float * ) ((uint8_t * )dst -> data + r * nb1 ); 1481 1482uint32_t i13 = fastdiv (r ,div_ne11_12 ); 1483uint32_t i12 = fastdiv (r - i13 * ne11_12 ,div_ne11 ); 1484uint32_t i11 = r - i13 * ne11_12 - i12 * ne11 ; 1485 1486uint32_t i23 = is_broadcast3 ?0 :i13 ; 1487uint32_t i22 = is_broadcast2 ?0 :i12 ; 1488uint32_t i21 = is_broadcast1 ?0 :i11 ; 1489 1490const float * src2_row = (const float * ) ((const uint8_t * )src2 -> data + 1491i21 * src2 -> nb [1 ]+ i22 * src2 -> nb [2 ]+ i23 * src2 -> nb [3 ]); 1492 1493float * dst_ptr = & dst_row [start_col ]; 1494const float * src2_ptr = & src2_row [start_col ]; 1495int remaining = end_col - start_col ; 1496while (remaining >=32 ) { 1497HVX_Vector v_out = hvx_vmemu (dst_ptr ); 1498HVX_Vector v_z = hvx_vmemu (src2_ptr ); 1499hvx_vmemu (dst_ptr )= hvx_vec_add_f32_f32 (v_out ,v_z ); 1500dst_ptr += 32 ; 1501src2_ptr += 32 ; 1502remaining -= 32 ; 1503 } 1504if (remaining > 0 ) { 1505HVX_Vector v_out = hvx_vmemu (dst_ptr ); 1506HVX_Vector v_z = hvx_vmemu (src2_ptr ); 1507hvx_vec_store_u (dst_ptr ,remaining * sizeof (float ),hvx_vec_add_f32_f32 (v_out ,v_z )); 1508 } 1509 } 1510} 1511