char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
81ff7abe5
char/aliceai-t5-moe
1#ifndef HMX_FA_KERNELS_H 2#define HMX_FA_KERNELS_H 3 4#include <stdint.h> 5#include <stddef.h> 6#include <stdbool.h> 7#include "hvx-utils.h" 8#include "hmx-utils.h" 9#include "hex-fastdiv.h" 10 11// HMX-specific parameters, offsets and inner kernels for Flash Attention 12 13// Scatter offsets for diagonal tile: entry[2i] = i*136, entry[2i+1] = i*136+6 14// 136 = 4 * 32 + 8 = byte offset to diagonal in a 32x32 fp16 interleaved tile 15static const int16_t d_tile_scatter_offsets [64 ] __attribute__((aligned (128 )))= { 160 * 136 ,0 * 136 + 6 , 171 * 136 ,1 * 136 + 6 , 182 * 136 ,2 * 136 + 6 , 193 * 136 ,3 * 136 + 6 , 204 * 136 ,4 * 136 + 6 , 215 * 136 ,5 * 136 + 6 , 226 * 136 ,6 * 136 + 6 , 237 * 136 ,7 * 136 + 6 , 248 * 136 ,8 * 136 + 6 , 259 * 136 ,9 * 136 + 6 , 2610 * 136 ,10 * 136 + 6 , 2711 * 136 ,11 * 136 + 6 , 2812 * 136 ,12 * 136 + 6 , 2913 * 136 ,13 * 136 + 6 , 3014 * 136 ,14 * 136 + 6 , 3115 * 136 ,15 * 136 + 6 , 320 ,0 , 330 ,0 , 340 ,0 , 350 ,0 , 360 ,0 , 370 ,0 , 380 ,0 , 390 ,0 , 400 ,0 , 410 ,0 , 420 ,0 , 430 ,0 , 440 ,0 , 450 ,0 , 460 ,0 , 470 ,0 , 48}; 49// Inner HMX tile computation kernels 50 51static void hmx_fa_qk_dot_tile ( 52const __fp16 * row_tiles , 53const __fp16 * col_tiles , 54__fp16 * out_tile , 55size_t n_dot_tiles 56) { 57if (n_dot_tiles == 2 ) { 58 asmvolatile ( 59HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 60HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 61 : 62 :"r" (2047 ), 63"r" (row_tiles + 0 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 0 * HMX_FP16_TILE_N_ELMS ), 64"r" (row_tiles + 1 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 1 * HMX_FP16_TILE_N_ELMS ) 65 ); 66 }else if (n_dot_tiles == 4 ) { 67 asmvolatile ( 68HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 69HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 70HMX_LOAD_MPY_F16 ("%5" ,"%6" ,"%0" ) 71HMX_LOAD_MPY_F16 ("%7" ,"%8" ,"%0" ) 72 : 73 :"r" (2047 ), 74"r" (row_tiles + 0 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 0 * HMX_FP16_TILE_N_ELMS ), 75"r" (row_tiles + 1 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 1 * HMX_FP16_TILE_N_ELMS ), 76"r" (row_tiles + 2 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 2 * HMX_FP16_TILE_N_ELMS ), 77"r" (row_tiles + 3 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 3 * HMX_FP16_TILE_N_ELMS ) 78 ); 79 }else if (n_dot_tiles == 8 ) { 80 asmvolatile ( 81HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 82HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 83HMX_LOAD_MPY_F16 ("%5" ,"%6" ,"%0" ) 84HMX_LOAD_MPY_F16 ("%7" ,"%8" ,"%0" ) 85HMX_LOAD_MPY_F16 ("%9" ,"%10" ,"%0" ) 86HMX_LOAD_MPY_F16 ("%11" ,"%12" ,"%0" ) 87HMX_LOAD_MPY_F16 ("%13" ,"%14" ,"%0" ) 88HMX_LOAD_MPY_F16 ("%15" ,"%16" ,"%0" ) 89 : 90 :"r" (2047 ), 91"r" (row_tiles + 0 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 0 * HMX_FP16_TILE_N_ELMS ), 92"r" (row_tiles + 1 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 1 * HMX_FP16_TILE_N_ELMS ), 93"r" (row_tiles + 2 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 2 * HMX_FP16_TILE_N_ELMS ), 94"r" (row_tiles + 3 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 3 * HMX_FP16_TILE_N_ELMS ), 95"r" (row_tiles + 4 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 4 * HMX_FP16_TILE_N_ELMS ), 96"r" (row_tiles + 5 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 5 * HMX_FP16_TILE_N_ELMS ), 97"r" (row_tiles + 6 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 6 * HMX_FP16_TILE_N_ELMS ), 98"r" (row_tiles + 7 * HMX_FP16_TILE_N_ELMS ),"r" (col_tiles + 7 * HMX_FP16_TILE_N_ELMS ) 99 ); 100 }else { 101for (size_t k = 0 ;k < n_dot_tiles ;++ k ) { 102 asmvolatile ( 103HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 104 : 105 :"r" (2047 ),"r" (row_tiles ),"r" (col_tiles ) 106 ); 107row_tiles += HMX_FP16_TILE_N_ELMS ; 108col_tiles += HMX_FP16_TILE_N_ELMS ; 109 } 110 } 111 asmvolatile ( 112HMX_STORE_AFTER_F16 ("%0" ,"%1" ) 113 : 114 :"r" (out_tile ),"r" (0 ) 115 :"memory" 116 ); 117} 118 119static void hmx_fa_o_update_tile ( 120const __fp16 * d_diag , 121const __fp16 * o_rc , 122const __fp16 * p_tile_in , 123const __fp16 * v_tile_in , 124__fp16 * o_tile_out , 125size_t n_col_tiles 126) { 127 asmvolatile ( 128HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 129 : 130 :"r" (2047 ),"r" (d_diag ),"r" (o_rc ) 131 ); 132if (n_col_tiles == 2 ) { 133 asmvolatile ( 134HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 135HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 136 : 137 :"r" (2047 ), 138"r" (p_tile_in + 0 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 0 * HMX_FP16_TILE_N_ELMS ), 139"r" (p_tile_in + 1 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 1 * HMX_FP16_TILE_N_ELMS ) 140 ); 141 }else if (n_col_tiles == 4 ) { 142 asmvolatile ( 143HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 144HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 145HMX_LOAD_MPY_F16 ("%5" ,"%6" ,"%0" ) 146HMX_LOAD_MPY_F16 ("%7" ,"%8" ,"%0" ) 147 : 148 :"r" (2047 ), 149"r" (p_tile_in + 0 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 0 * HMX_FP16_TILE_N_ELMS ), 150"r" (p_tile_in + 1 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 1 * HMX_FP16_TILE_N_ELMS ), 151"r" (p_tile_in + 2 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 2 * HMX_FP16_TILE_N_ELMS ), 152"r" (p_tile_in + 3 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 3 * HMX_FP16_TILE_N_ELMS ) 153 ); 154 }else if (n_col_tiles == 8 ) { 155 asmvolatile ( 156HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 157HMX_LOAD_MPY_F16 ("%3" ,"%4" ,"%0" ) 158HMX_LOAD_MPY_F16 ("%5" ,"%6" ,"%0" ) 159HMX_LOAD_MPY_F16 ("%7" ,"%8" ,"%0" ) 160HMX_LOAD_MPY_F16 ("%9" ,"%10" ,"%0" ) 161HMX_LOAD_MPY_F16 ("%11" ,"%12" ,"%0" ) 162HMX_LOAD_MPY_F16 ("%13" ,"%14" ,"%0" ) 163HMX_LOAD_MPY_F16 ("%15" ,"%16" ,"%0" ) 164 : 165 :"r" (2047 ), 166"r" (p_tile_in + 0 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 0 * HMX_FP16_TILE_N_ELMS ), 167"r" (p_tile_in + 1 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 1 * HMX_FP16_TILE_N_ELMS ), 168"r" (p_tile_in + 2 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 2 * HMX_FP16_TILE_N_ELMS ), 169"r" (p_tile_in + 3 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 3 * HMX_FP16_TILE_N_ELMS ), 170"r" (p_tile_in + 4 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 4 * HMX_FP16_TILE_N_ELMS ), 171"r" (p_tile_in + 5 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 5 * HMX_FP16_TILE_N_ELMS ), 172"r" (p_tile_in + 6 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 6 * HMX_FP16_TILE_N_ELMS ), 173"r" (p_tile_in + 7 * HMX_FP16_TILE_N_ELMS ),"r" (v_tile_in + 7 * HMX_FP16_TILE_N_ELMS ) 174 ); 175 }else { 176for (size_t k = 0 ;k < n_col_tiles ;++ k ) { 177 asmvolatile ( 178HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 179 : 180 :"r" (2047 ),"r" (p_tile_in ),"r" (v_tile_in ) 181 ); 182p_tile_in += HMX_FP16_TILE_N_ELMS ; 183v_tile_in += HMX_FP16_TILE_N_ELMS ; 184 } 185 } 186 asmvolatile ( 187HMX_STORE_AFTER_F16 ("%0" ,"%1" ) 188 : 189 :"r" (o_tile_out ),"r" (0 ) 190 :"memory" 191 ); 192} 193 194static inline void hmx_fa_o_norm_tile ( 195const __fp16 * d_diag , 196const __fp16 * o_rc , 197__fp16 * o_out 198) { 199 asmvolatile ( 200HMX_LOAD_MPY_F16 ("%1" ,"%2" ,"%0" ) 201 : 202 :"r" (2047 ),"r" (d_diag ),"r" (o_rc ) 203 ); 204 asmvolatile ( 205HMX_STORE_AFTER_F16 ("%0" ,"%1" ) 206 : 207 :"r" (o_out ),"r" (0 ) 208 :"memory" 209 ); 210} 211 212static inline void hmx_fa_q_prep_fp32_d2 ( 213__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 214size_t start ,size_t end ,size_t g_rows_end , 215size_t DK ,size_t G ,size_t n_rows_q , 216const struct fastdiv_values * div_G ,bool q_transposed 217) { 218for (size_t r = start ;r < end ;r += 2 ) { 219size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 220size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 221__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 222 223if (r >=g_rows_end ) { 224 ((HVX_Vector * ) (out_base + 0 * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= Q6_V_vzero (); 225 ((HVX_Vector * ) (out_base + 1 * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= Q6_V_vzero (); 226continue ; 227 } 228 229const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 230const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 231const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 232const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 233 234const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 235const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 236 237const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (float )); 238const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 239 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (float )) 240 :NULL ; 241 242 { 243HVX_Vector v0 = pv_in0 [0 ]; 244HVX_Vector v1 = pv_in1 ?pv_in1 [0 ] :Q6_V_vzero (); 245HVX_Vector v_hf = hvx_vec_f32_to_f16_shuff (v0 ,v1 ); 246 ((HVX_Vector * ) (out_base + 0 * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= v_hf ; 247 } 248 { 249HVX_Vector v0 = pv_in0 [1 ]; 250HVX_Vector v1 = pv_in1 ?pv_in1 [1 ] :Q6_V_vzero (); 251HVX_Vector v_hf = hvx_vec_f32_to_f16_shuff (v0 ,v1 ); 252 ((HVX_Vector * ) (out_base + 1 * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= v_hf ; 253 } 254 } 255} 256 257static inline void hmx_fa_q_prep_fp32_d4 ( 258__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 259size_t start ,size_t end ,size_t g_rows_end , 260size_t DK ,size_t G ,size_t n_rows_q , 261const struct fastdiv_values * div_G ,bool q_transposed 262) { 263for (size_t r = start ;r < end ;r += 2 ) { 264size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 265size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 266__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 267 268if (r >=g_rows_end ) { 269for (uint32_t d = 0 ;d < 4 ;++ d ) { 270 ((HVX_Vector * ) (out_base + d * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= Q6_V_vzero (); 271 } 272continue ; 273 } 274 275const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 276const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 277const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 278const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 279 280const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 281const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 282 283const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (float )); 284const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 285 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (float )) 286 :NULL ; 287 288for (uint32_t d = 0 ;d < 4 ;++ d ) { 289HVX_Vector v0 = pv_in0 [d ]; 290HVX_Vector v1 = pv_in1 ?pv_in1 [d ] :Q6_V_vzero (); 291HVX_Vector v_hf = hvx_vec_f32_to_f16_shuff (v0 ,v1 ); 292 ((HVX_Vector * ) (out_base + d * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= v_hf ; 293 } 294 } 295} 296 297static inline void hmx_fa_q_prep_fp32 ( 298__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 299size_t start ,size_t end ,size_t g_rows_end , 300size_t DK ,size_t G ,size_t n_rows_q , 301const struct fastdiv_values * div_G ,uint32_t d_limit ,bool q_transposed 302) { 303for (size_t r = start ;r < end ;r += 2 ) { 304size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 305size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 306__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 307 308if (r >=g_rows_end ) { 309for (uint32_t d = 0 ;d < d_limit ;++ d ) { 310 ((HVX_Vector * ) (out_base + d * HMX_FP16_TILE_N_ELMS ))[r1 /2 ]= Q6_V_vzero (); 311 } 312continue ; 313 } 314 315const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 316const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 317const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 318const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 319 320const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 321const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 322 323const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (float )); 324const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 325 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (float )) 326 :NULL ; 327 328for (uint32_t d = 0 ;d < d_limit ;++ d ) { 329HVX_Vector v0 = pv_in0 [d ]; 330HVX_Vector v1 = pv_in1 ?pv_in1 [d ] :Q6_V_vzero (); 331HVX_Vector v_hf = hvx_vec_f32_to_f16_shuff (v0 ,v1 ); 332 333HVX_Vector * out_tile = (HVX_Vector * ) (out_base + d * HMX_FP16_TILE_N_ELMS ); 334out_tile [r1 /2 ]= v_hf ; 335 } 336 } 337} 338 339static inline void hmx_fa_q_prep_fp16_d1 ( 340__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 341size_t start ,size_t end ,size_t g_rows_end , 342size_t DK ,size_t G ,size_t n_rows_q , 343const struct fastdiv_values * div_G ,bool q_transposed 344) { 345for (size_t r = start ;r < end ;r += 2 ) { 346size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 347size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 348__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 349 350if (r >=g_rows_end ) { 351__fp16 * out_dtile = out_base + 0 * HMX_FP16_TILE_N_ELMS * 2 ; 352HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 353HVX_Vector * pv_out1 = pv_out0 + 16 ; 354* pv_out0 = Q6_V_vzero (); 355* pv_out1 = Q6_V_vzero (); 356continue ; 357 } 358 359const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 360const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 361const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 362const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 363 364const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 365const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 366 367const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (__fp16 )); 368const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 369 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (__fp16 )) 370 :NULL ; 371 372HVX_Vector v0 = pv_in0 [0 ]; 373HVX_Vector v1 = pv_in1 ?pv_in1 [0 ] :Q6_V_vzero (); 374HVX_VectorPair vp = Q6_W_vshuff_VVR (v1 ,v0 ,-2 ); 375 376__fp16 * out_dtile = out_base + 0 * HMX_FP16_TILE_N_ELMS * 2 ; 377HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 378HVX_Vector * pv_out1 = pv_out0 + 16 ; 379 380* pv_out0 = Q6_V_lo_W (vp ); 381* pv_out1 = Q6_V_hi_W (vp ); 382 } 383} 384 385static inline void hmx_fa_q_prep_fp16_d2 ( 386__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 387size_t start ,size_t end ,size_t g_rows_end , 388size_t DK ,size_t G ,size_t n_rows_q , 389const struct fastdiv_values * div_G ,bool q_transposed 390) { 391for (size_t r = start ;r < end ;r += 2 ) { 392size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 393size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 394__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 395 396if (r >=g_rows_end ) { 397for (uint32_t d = 0 ;d < 2 ;++ d ) { 398__fp16 * out_dtile = out_base + d * HMX_FP16_TILE_N_ELMS * 2 ; 399HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 400HVX_Vector * pv_out1 = pv_out0 + 16 ; 401* pv_out0 = Q6_V_vzero (); 402* pv_out1 = Q6_V_vzero (); 403 } 404continue ; 405 } 406 407const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 408const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 409const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 410const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 411 412const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 413const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 414 415const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (__fp16 )); 416const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 417 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (__fp16 )) 418 :NULL ; 419 420 { 421HVX_Vector v0 = pv_in0 [0 ]; 422HVX_Vector v1 = pv_in1 ?pv_in1 [0 ] :Q6_V_vzero (); 423HVX_VectorPair vp = Q6_W_vshuff_VVR (v1 ,v0 ,-2 ); 424 425__fp16 * out_dtile = out_base + 0 * HMX_FP16_TILE_N_ELMS * 2 ; 426HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 427HVX_Vector * pv_out1 = pv_out0 + 16 ; 428 429* pv_out0 = Q6_V_lo_W (vp ); 430* pv_out1 = Q6_V_hi_W (vp ); 431 } 432 { 433HVX_Vector v0 = pv_in0 [1 ]; 434HVX_Vector v1 = pv_in1 ?pv_in1 [1 ] :Q6_V_vzero (); 435HVX_VectorPair vp = Q6_W_vshuff_VVR (v1 ,v0 ,-2 ); 436 437__fp16 * out_dtile = out_base + 1 * HMX_FP16_TILE_N_ELMS * 2 ; 438HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 439HVX_Vector * pv_out1 = pv_out0 + 16 ; 440 441* pv_out0 = Q6_V_lo_W (vp ); 442* pv_out1 = Q6_V_hi_W (vp ); 443 } 444 } 445} 446 447static inline void hmx_fa_q_prep_fp16 ( 448__fp16 * vtcm_q_tiles ,const uint8_t * temp_q_vtcm , 449size_t start ,size_t end ,size_t g_rows_end , 450size_t DK ,size_t G ,size_t n_rows_q , 451const struct fastdiv_values * div_G ,uint32_t d_limit ,bool q_transposed 452) { 453for (size_t r = start ;r < end ;r += 2 ) { 454size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 455size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 456__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 457 458if (r >=g_rows_end ) { 459for (uint32_t d = 0 ;d < d_limit ;++ d ) { 460__fp16 * out_dtile = out_base + d * HMX_FP16_TILE_N_ELMS * 2 ; 461HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 462HVX_Vector * pv_out1 = pv_out0 + 16 ; 463* pv_out0 = Q6_V_vzero (); 464* pv_out1 = Q6_V_vzero (); 465 } 466continue ; 467 } 468 469const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 470const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 471const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 472const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 473 474const size_t offset0 = q_transposed ? (h_idx0 * n_rows_q + q_idx0 ) : (q_idx0 * G + h_idx0 ); 475const size_t offset1 = q_transposed ? (h_idx1 * n_rows_q + q_idx1 ) : (q_idx1 * G + h_idx1 ); 476 477const HVX_Vector * pv_in0 = (const HVX_Vector * ) (temp_q_vtcm + offset0 * DK * sizeof (__fp16 )); 478const HVX_Vector * pv_in1 = (r + 1 < g_rows_end ) 479 ? (const HVX_Vector * ) (temp_q_vtcm + offset1 * DK * sizeof (__fp16 )) 480 :NULL ; 481 482for (uint32_t d = 0 ;d < d_limit ;++ d ) { 483HVX_Vector v0 = pv_in0 [d ]; 484HVX_Vector v1 = pv_in1 ?pv_in1 [d ] :Q6_V_vzero (); 485HVX_VectorPair vp = Q6_W_vshuff_VVR (v1 ,v0 ,-2 ); 486 487__fp16 * out_dtile = out_base + d * HMX_FP16_TILE_N_ELMS * 2 ; 488HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 489HVX_Vector * pv_out1 = pv_out0 + 16 ; 490 491* pv_out0 = Q6_V_lo_W (vp ); 492* pv_out1 = Q6_V_hi_W (vp ); 493 } 494 } 495} 496 497 498static inline void hmx_fa_q_prep_fallback ( 499__fp16 * vtcm_q_tiles ,uintptr_t q_data , 500size_t q_nb1 ,size_t q_nb2 ,size_t q_nb3 , 501uint32_t q_start ,uint32_t kv_head ,uint32_t ib3 , 502size_t start ,size_t end ,size_t n_rows_g , 503size_t G ,size_t DK ,bool is_q_fp32 , 504const struct fastdiv_values * div_G 505) { 506for (size_t r = start ;r < end ;r += 2 ) { 507const size_t q_idx0 = fastdiv (r + 0 ,div_G ); 508const size_t h_idx0 = fastmodulo (r + 0 ,G ,div_G ); 509const size_t q_idx1 = fastdiv (r + 1 ,div_G ); 510const size_t h_idx1 = fastmodulo (r + 1 ,G ,div_G ); 511 512const uint8_t * q_ptr0 = (r + 0 < n_rows_g ) ? ((const uint8_t * )q_data + (q_start + q_idx0 )* q_nb1 + 513 (kv_head * G + h_idx0 )* q_nb2 + ib3 * q_nb3 ) : 514NULL ; 515const uint8_t * q_ptr1 = (r + 1 < n_rows_g ) ? ((const uint8_t * )q_data + (q_start + q_idx1 )* q_nb1 + 516 (kv_head * G + h_idx1 )* q_nb2 + ib3 * q_nb3 ) : 517NULL ; 518 519size_t r0 = r /HMX_FP16_TILE_N_ROWS ; 520size_t r1 = r %HMX_FP16_TILE_N_ROWS ; 521__fp16 * out_base = vtcm_q_tiles + r0 * HMX_FP16_TILE_N_ROWS * DK ; 522 523if (is_q_fp32 ) { 524const HVX_UVector * pv_in0 = q_ptr0 ? (const HVX_UVector * )q_ptr0 :NULL ; 525const HVX_UVector * pv_in1 = q_ptr1 ? (const HVX_UVector * )q_ptr1 :NULL ; 526 527for (uint32_t d = 0 ;d < DK /32 ;++ d ) { 528HVX_Vector v0 = pv_in0 ?pv_in0 [d ] :Q6_V_vzero (); 529HVX_Vector v1 = pv_in1 ?pv_in1 [d ] :Q6_V_vzero (); 530HVX_Vector v_hf = hvx_vec_f32_to_f16_shuff (v0 ,v1 ); 531 532HVX_Vector * out_tile = (HVX_Vector * ) (out_base + d * HMX_FP16_TILE_N_ELMS ); 533out_tile [r1 /2 ]= v_hf ; 534 } 535 }else { 536const HVX_UVector * pv_in0 = q_ptr0 ? (const HVX_UVector * )q_ptr0 :NULL ; 537const HVX_UVector * pv_in1 = q_ptr1 ? (const HVX_UVector * )q_ptr1 :NULL ; 538 539for (uint32_t d = 0 ;d < DK /64 ;++ d ) { 540HVX_Vector v0 = pv_in0 ?pv_in0 [d ] :Q6_V_vzero (); 541HVX_Vector v1 = pv_in1 ?pv_in1 [d ] :Q6_V_vzero (); 542HVX_VectorPair vp = Q6_W_vshuff_VVR (v1 ,v0 ,-2 ); 543 544__fp16 * out_dtile = out_base + d * HMX_FP16_TILE_N_ELMS * 2 ; 545HVX_Vector * pv_out0 = ((HVX_Vector * )out_dtile )+ r1 /2 ; 546HVX_Vector * pv_out1 = pv_out0 + 16 ; 547 548* pv_out0 = Q6_V_lo_W (vp ); 549* pv_out1 = Q6_V_hi_W (vp ); 550 } 551 } 552 } 553} 554 555#endif /* HMX_FA_KERNELS_H */