char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
eafe15a5e
char/aliceai-t5-moe
1#pragma clang diagnostic ignored "-Wunused-variable" 2#pragma clang diagnostic ignored "-Wunused-function" 3#pragma clang diagnostic ignored "-Wunused-but-set-variable" 4 5#include <HAP_farf.h> 6 7#include <math.h> 8#include <string.h> 9 10#include "hex-dma.h" 11#include "hvx-utils.h" 12 13#define GGML_COMMON_DECL_C 14#include "ggml-common.h" 15#include "htp-ctx.h" 16#include "htp-ops.h" 17#include "hex-common.h" 18#include "htp-tensor.h" 19#include "htp-vtcm.h" 20 21#define htp_act_preamble \ 22 const struct htp_tensor * src0 = actx->octx->src[0]; \ 23 const struct htp_tensor * src1 = actx->octx->src[1]; \ 24 const struct htp_tensor * dst = actx->octx->dst; \ 25 \ 26 const uint32_t ne00 = src0->ne[0]; \ 27 const uint32_t ne01 = src0->ne[1]; \ 28 const uint32_t ne02 = src0->ne[2]; \ 29 const uint32_t ne03 = src0->ne[3]; \ 30 \ 31 const uint32_t nb00 = src0->nb[0]; \ 32 const uint32_t nb01 = src0->nb[1]; \ 33 const uint32_t nb02 = src0->nb[2]; \ 34 const uint32_t nb03 = src0->nb[3]; \ 35 \ 36 const uint32_t ne10 = src1 ? src1->ne[0] : 0; \ 37 const uint32_t ne11 = src1 ? src1->ne[1] : 0; \ 38 const uint32_t ne12 = src1 ? src1->ne[2] : 0; \ 39 const uint32_t ne13 = src1 ? src1->ne[3] : 0; \ 40 \ 41 const uint32_t nb10 = src1 ? src1->nb[0] : 0; \ 42 const uint32_t nb11 = src1 ? src1->nb[1] : 0; \ 43 const uint32_t nb12 = src1 ? src1->nb[2] : 0; \ 44 const uint32_t nb13 = src1 ? src1->nb[3] : 0; \ 45 \ 46 const uint32_t ne0 = dst->ne[0]; \ 47 const uint32_t ne1 = dst->ne[1]; \ 48 const uint32_t ne2 = dst->ne[2]; \ 49 const uint32_t ne3 = dst->ne[3]; \ 50 \ 51 const uint32_t nb0 = dst->nb[0]; \ 52 const uint32_t nb1 = dst->nb[1]; \ 53 const uint32_t nb2 = dst->nb[2]; \ 54 const uint32_t nb3 = dst->nb[3]; 55 56struct htp_act_context { 57struct htp_ops_context * octx ; 58 59// Precomputed values 60const uint8_t * data_src0 ; 61const uint8_t * data_src1 ; 62uint8_t * data_dst ; 63 64size_t src0_row_size ; 65size_t src1_row_size ; 66size_t dst_row_size ; 67 68size_t src0_row_stride ; 69size_t src1_row_stride ; 70 71size_t src0_row_size_aligned ; 72size_t src1_row_size_aligned ; 73size_t dst_row_size_aligned ; 74 75size_t src0_spad_half_size ; 76size_t src1_spad_half_size ; 77size_t dst_spad_half_size ; 78 79uint32_t block ; 80uint32_t src0_nrows ; 81uint32_t src0_nrows_per_thread ; 82uint32_t row_start ; 83int nc ; 84 85uint8_t * vtcm_src0 ; 86uint8_t * vtcm_src1 ; 87uint8_t * vtcm_dst ; 88 89size_t vtcm_src0_size_per_thread ; 90size_t vtcm_src1_size_per_thread ; 91size_t vtcm_dst_size_per_thread ; 92}; 93 94struct htp_act_vtcm_layout { 95size_t total_bytes ; 96size_t off_src0 ; 97size_t off_src1 ; 98size_t off_dst ; 99 100size_t src0_bytes_per_thread ; 101size_t src1_bytes_per_thread ; 102size_t dst_bytes_per_thread ; 103 104uint32_t vtcm_row_per_thread ; 105}; 106 107static inline void htp_act_vtcm_layout_build (struct htp_act_vtcm_layout * L , 108size_t src0_row_size_aligned , 109size_t src1_row_size_aligned , 110size_t dst_row_size_aligned , 111uint32_t n_threads , 112size_t vtcm_size ) { 113const size_t spad_size_per_row = src0_row_size_aligned + src1_row_size_aligned + dst_row_size_aligned ; 114const uint32_t vtcm_row_per_thread = (uint32_t ) (vtcm_size / (n_threads * spad_size_per_row )); 115 116L -> vtcm_row_per_thread = vtcm_row_per_thread ; 117 118L -> src0_bytes_per_thread = src0_row_size_aligned * vtcm_row_per_thread ; 119L -> src1_bytes_per_thread = src1_row_size_aligned * vtcm_row_per_thread ; 120L -> dst_bytes_per_thread = dst_row_size_aligned * vtcm_row_per_thread ; 121 122L -> off_src0 = 0 ; 123L -> off_src1 = L -> off_src0 + L -> src0_bytes_per_thread * n_threads ; 124L -> off_dst = L -> off_src1 + L -> src1_bytes_per_thread * n_threads ; 125 126L -> total_bytes = L -> off_dst + L -> dst_bytes_per_thread * n_threads ; 127} 128 129#define htp_glu_op_preamble \ 130 const size_t src0_row_size_aligned = actx->src0_row_size_aligned; \ 131 const size_t src1_row_size_aligned = actx->src1_row_size_aligned; \ 132 const size_t dst_row_size_aligned = actx->dst_row_size_aligned; \ 133 const int nc = actx->nc; 134 135// swiglu(x) = x1 * sigmoid(x0) 136static void swiglu_f32 (const float * restrictsrc0 , 137const float * restrictsrc1 , 138float * restrictdst , 139const uint32_t num_rows , 140const struct htp_act_context * actx ) { 141htp_glu_op_preamble ; 142 143for (uint32_t ib = 0 ;ib < num_rows ;ib ++ ) { 144const uint8_t * restrictsrc0_ptr = (const uint8_t * )src0 + (ib * src0_row_size_aligned ); 145const uint8_t * restrictsrc1_ptr = (const uint8_t * )src1 + (ib * src1_row_size_aligned ); 146uint8_t * restrictdst_ptr = (uint8_t * )dst + (ib * dst_row_size_aligned ); 147 148hvx_sigmoid_f32_aa (dst_ptr ,src0_ptr ,nc ); 149hvx_mul_mul_f32_aa (dst_ptr ,src0_ptr ,dst_ptr ,src1_ptr ,nc ); 150 } 151} 152 153// out = x * sigmoid(alpha * x) * (clamp(y, -limit, limit) + 1.f) 154static void swiglu_oai_f32 (const float * restrictsrc0 , 155const float * restrictsrc1 , 156float * restrictdst , 157const uint32_t num_rows , 158const struct htp_act_context * actx ) { 159htp_glu_op_preamble ; 160const float alpha = ((const float * ) (actx -> octx -> op_params ))[2 ]; 161const float limit = ((const float * ) (actx -> octx -> op_params ))[3 ]; 162 163for (uint32_t ib = 0 ;ib < num_rows ;ib ++ ) { 164const uint8_t * restrictsrc0_ptr = (const uint8_t * )src0 + (ib * src0_row_size_aligned ); 165const uint8_t * restrictsrc1_ptr = (const uint8_t * )src1 + (ib * src1_row_size_aligned ); 166uint8_t * restrictdst_ptr = (uint8_t * )dst + (ib * dst_row_size_aligned ); 167 168// x (src0_ptr) = std::min(src0_p[k], limit); 169hvx_min_scalar_f32 ((uint8_t * )src0_ptr ,src0_ptr ,limit ,nc ); 170// y1 (src1_ptr) = std::clamp(src1_p[k], -limit, limit); 171hvx_clamp_scalar_f32 ((uint8_t * )src1_ptr ,src1_ptr ,- limit ,limit ,nc ); 172// y (src1_ptr) = y1 + 1.f 173hvx_add_scalar_f32 ((uint8_t * )src1_ptr ,src1_ptr ,1.0 ,nc ); 174// x1 (dst_ptr) = alpha * x 175hvx_mul_scalar_f32 (dst_ptr ,src0_ptr ,alpha ,nc ); 176// x2 (dst_ptr) = sigmoid(x1) = 1/(1+exp(-x1)) 177hvx_sigmoid_f32_aa (dst_ptr ,dst_ptr ,nc ); 178// out = x * sigmoid(alpha * x) * (y + 1.f) 179hvx_mul_mul_f32_aa (dst_ptr ,src0_ptr ,dst_ptr ,src1_ptr ,nc ); 180 } 181} 182 183static void swiglu_clamp_f32 (const float * restrictsrc0 , 184const float * restrictsrc1 , 185float * restrictdst , 186const uint32_t num_rows , 187const struct htp_act_context * actx ) { 188htp_glu_op_preamble ; 189const float limit = ((const float * ) (actx -> octx -> op_params ))[3 ]; 190 191for (uint32_t ib = 0 ;ib < num_rows ;ib ++ ) { 192const uint8_t * restrictsrc0_ptr = (const uint8_t * )src0 + (ib * src0_row_size_aligned ); 193const uint8_t * restrictsrc1_ptr = (const uint8_t * )src1 + (ib * src1_row_size_aligned ); 194uint8_t * restrictdst_ptr = (uint8_t * )dst + (ib * dst_row_size_aligned ); 195 196hvx_min_scalar_f32 ((uint8_t * )src0_ptr ,src0_ptr ,limit ,nc ); 197hvx_clamp_scalar_f32 ((uint8_t * )src1_ptr ,src1_ptr ,- limit ,limit ,nc ); 198hvx_sigmoid_f32_aa (dst_ptr ,src0_ptr ,nc ); 199hvx_mul_mul_f32_aa (dst_ptr ,src0_ptr ,dst_ptr ,src1_ptr ,nc ); 200 } 201} 202 203static const float GELU_COEF_A = 0.044715f ; 204static const float SQRT_2_OVER_PI = 0.79788456080286535587989211986876f ; 205 206static inline HVX_Vector hvx_vec_fast_sigmoid_f32_2it (HVX_Vector v ) { 207v = Q6_Vqf32_vmpy_VsfVsf (v ,Q6_V_vsplat_R (FAST_SIGMOID_LOG2F )); 208v = Q6_Vqf32_vmpy_VsfVsf (Q6_Vsf_equals_Vqf32 (v ),Q6_V_vsplat_R (FAST_SIGMOID_C3 )); 209 210HVX_Vector in_int = hvx_vec_truncate_f32 (Q6_Vsf_equals_Vqf32 (v )); 211HVX_Vector x = Q6_Vqf32_vsub_Vqf32Vsf (v ,Q6_Vsf_equals_Vw (in_int )); 212HVX_Vector xx = Q6_Vqf32_vmpy_Vqf32Vqf32 (x ,x ); 213 214HVX_Vector v1 = Q6_Vqf32_vmpy_VsfVsf (Q6_Vsf_equals_Vqf32 (xx ),Q6_V_vsplat_R (FAST_SIGMOID_C2 )); 215v1 = Q6_Vqf32_vadd_Vqf32Vsf (v1 ,Q6_V_vsplat_R (FAST_SIGMOID_LOG2F )); 216 217HVX_Vector v2 = Q6_Vqf32_vmpy_VsfVsf (Q6_Vsf_equals_Vqf32 (x ),Q6_V_vsplat_R (FAST_SIGMOID_C1 )); 218v2 = Q6_Vqf32_vmpy_Vqf32Vqf32 (v2 ,xx ); 219v2 = Q6_Vqf32_vadd_Vqf32Vqf32 (v2 ,x ); 220 221HVX_Vector v3 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_Vqf32Vqf32 (v2 ,v1 )); 222v3 = Q6_Vw_vaslacc_VwVwR (v3 ,in_int ,24 ); 223 224HVX_Vector v4 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vsub_Vqf32Vqf32 (v2 ,v1 )); 225HVX_Vector v5 = Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vsub_VsfVsf (v3 ,v4 )); 226 227// Newton-Raphson with 2 iterations 228HVX_Vector two_sf = hvx_vec_splat_f32 (2.0f ); 229HVX_Vector i_sf = Q6_Vw_vsub_VwVw (Q6_V_vsplat_R (0x7EEEEBB3 ),v5 ); 230HVX_Vector r_qf = Q6_Vqf32_vmpy_VsfVsf ( 231i_sf ,Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vsub_VsfVsf (two_sf ,Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vmpy_VsfVsf (i_sf ,v5 ))))); 232r_qf = Q6_Vqf32_vmpy_Vqf32Vqf32 ( 233r_qf ,Q6_Vqf32_vsub_VsfVsf (two_sf ,Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vmpy_VsfVsf (Q6_Vsf_equals_Vqf32 (r_qf ),v5 )))); 234HVX_Vector res = Q6_Vsf_equals_Vqf32 (r_qf ); 235 236res = Q6_Vqf32_vmpy_VsfVsf (v3 ,res ); 237 238return Q6_Vsf_equals_Vqf32 (res ); 239} 240 241static inline HVX_Vector hvx_vec_fast_sigmoid_f32_guard_2it (HVX_Vector v , 242HVX_Vector one , 243HVX_Vector max_exp , 244HVX_Vector min_exp ) { 245const HVX_VectorPred pred_max = Q6_Q_vcmp_gt_VsfVsf (max_exp ,v ); 246const HVX_VectorPred pred_min = Q6_Q_vcmp_gt_VsfVsf (v ,min_exp ); 247 248HVX_Vector out = hvx_vec_fast_sigmoid_f32_2it (v ); 249out = Q6_V_vmux_QVV (pred_max ,out ,one ); 250return Q6_V_vmux_QVV (pred_min ,out ,Q6_V_vzero ()); 251} 252 253static inline void hvx_geglu_f32_aa (uint8_t * restrictdst ,const uint8_t * restrictsrc0 ,const uint8_t * restrictsrc1 ,uint32_t n ) { 254assert ((unsigned long )dst %128 == 0 ); 255assert ((unsigned long )src0 %128 == 0 ); 256assert ((unsigned long )src1 %128 == 0 ); 257 258HVX_Vector * restrictvdst = (HVX_Vector * )dst ; 259const HVX_Vector * restrictvsrc0 = (const HVX_Vector * )src0 ; 260const HVX_Vector * restrictvsrc1 = (const HVX_Vector * )src1 ; 261 262const uint32_t epv = 128 /sizeof (float ); 263const uint32_t nvec = n /epv ; 264const uint32_t nloe = n %epv ; 265 266const float GELU_COEF_A_TIMES_SQRT = GELU_COEF_A * SQRT_2_OVER_PI ; 267 268const HVX_Vector v_coef_a_times_sqrt = hvx_vec_splat_f32 (GELU_COEF_A_TIMES_SQRT ); 269const HVX_Vector v_sqrt_2_pi = hvx_vec_splat_f32 (SQRT_2_OVER_PI ); 270const HVX_Vector v_one = hvx_vec_splat_f32 (1.0f ); 271const HVX_Vector v_max_exp = hvx_vec_splat_f32 (87.0f ); 272const HVX_Vector v_min_exp = hvx_vec_splat_f32 (-87.0f ); 273 274uint32_t i = 0 ; 275 276_Pragma ("unroll(4)" ) 277for (;i < nvec ;i ++ ) { 278HVX_Vector x = vsrc0 [i ]; 279HVX_Vector g = vsrc1 [i ]; 280 281HVX_Vector x2 = hvx_vec_mul_f32_f32 (x ,x ); 282HVX_Vector coef = hvx_vec_mul_f32_f32 (x2 ,v_coef_a_times_sqrt ); 283coef = hvx_vec_add_f32_f32 (coef ,v_sqrt_2_pi ); 284HVX_Vector inner = hvx_vec_mul_f32_f32 (x ,coef ); 285 286// y2 = 2 * inner = inner + inner 287HVX_Vector y2 = hvx_vec_add_f32_f32 (inner ,inner ); 288 289// Fast sigmoid approximation (2 iterations) 290HVX_Vector sig2y = hvx_vec_fast_sigmoid_f32_guard_2it (y2 ,v_one ,v_max_exp ,v_min_exp ); 291 292HVX_Vector gelu_x = hvx_vec_mul_f32_f32 (x ,sig2y ); 293vdst [i ]= hvx_vec_mul_f32_f32 (gelu_x ,g ); 294 } 295 296if (nloe ) { 297HVX_Vector x = vsrc0 [i ]; 298HVX_Vector g = vsrc1 [i ]; 299 300HVX_Vector x2 = hvx_vec_mul_f32_f32 (x ,x ); 301HVX_Vector coef = hvx_vec_mul_f32_f32 (x2 ,v_coef_a_times_sqrt ); 302coef = hvx_vec_add_f32_f32 (coef ,v_sqrt_2_pi ); 303HVX_Vector inner = hvx_vec_mul_f32_f32 (x ,coef ); 304 305HVX_Vector y2 = hvx_vec_add_f32_f32 (inner ,inner ); 306 307HVX_Vector sig2y = hvx_vec_fast_sigmoid_f32_guard_2it (y2 ,v_one ,v_max_exp ,v_min_exp ); 308 309HVX_Vector gelu_x = hvx_vec_mul_f32_f32 (x ,sig2y ); 310HVX_Vector res = hvx_vec_mul_f32_f32 (gelu_x ,g ); 311hvx_vec_store_a ((void * )& vdst [i ],nloe * sizeof (float ),res ); 312 } 313} 314 315// geglu(x, g) = gelu(x) * g 316static void geglu_f32 (const float * restrictsrc0 , 317const float * restrictsrc1 , 318float * restrictdst , 319const uint32_t num_rows , 320const struct htp_act_context * actx ) { 321htp_glu_op_preamble ; 322 323for (uint32_t ib = 0 ;ib < num_rows ;ib ++ ) { 324const uint8_t * restrictsrc0_ptr = (const uint8_t * )src0 + (ib * src0_row_size_aligned ); 325const uint8_t * restrictsrc1_ptr = (const uint8_t * )src1 + (ib * src1_row_size_aligned ); 326uint8_t * restrictdst_ptr = (uint8_t * )dst + (ib * dst_row_size_aligned ); 327 328hvx_geglu_f32_aa (dst_ptr ,src0_ptr ,src1_ptr ,nc ); 329 } 330} 331 332#define DEFINE_GLU_PER_THREAD (NAME ,OP_STR ,CORE_EXPR ) \ 333 static void glu_##NAME##_f32_per_thread(unsigned int nth, unsigned int ith, void * data) { \ 334 struct htp_act_context * actx = (struct htp_act_context *) data; \ 335 htp_act_preamble; \ 336 \ 337 struct htp_thread_trace * tr = actx->octx->ctx ? &actx->octx->ctx->trace[ith] : NULL; \ 338 \ 339 size_t src0_row_size = actx->src0_row_size; \ 340 size_t src1_row_size = actx->src1_row_size; \ 341 size_t dst_row_size = actx->dst_row_size; \ 342 \ 343 size_t src0_row_stride = actx->src0_row_stride; \ 344 size_t src1_row_stride = actx->src1_row_stride; \ 345 \ 346 const uint32_t src0_nrows = actx->src0_nrows; \ 347 const uint32_t src0_nrows_per_thread = actx->src0_nrows_per_thread; \ 348 \ 349 const uint32_t src0_start_row = actx->row_start + src0_nrows_per_thread * ith; \ 350 const uint32_t src0_end_row = MIN(src0_start_row + src0_nrows_per_thread, actx->row_start + src0_nrows); \ 351 \ 352/* no work for this thread */ \ 353if (src0_start_row >=src0_end_row ) { \ 354return ; \ 355 } \ 356 \ 357const uint8_t * restrictdata_src0 = actx -> data_src0 ; \ 358const uint8_t * restrictdata_src1 = actx -> data_src1 ; \ 359uint8_t * restrictdata_dst = actx -> data_dst ; \ 360 \ 361const size_t src0_row_size_aligned = actx -> src0_row_size_aligned ; \ 362const size_t src1_row_size_aligned = actx -> src1_row_size_aligned ; \ 363const size_t dst_row_size_aligned = actx -> dst_row_size_aligned ; \ 364 \ 365uint8_t * restrictsrc0_spad_data = actx -> vtcm_src0 + (ith * actx -> vtcm_src0_size_per_thread ); \ 366uint8_t * restrictsrc1_spad_data = actx -> vtcm_src1 + (ith * actx -> vtcm_src1_size_per_thread ); \ 367uint8_t * restrictdst_spad_data = actx -> vtcm_dst + (ith * actx -> vtcm_dst_size_per_thread ); \ 368 \ 369size_t src0_spad_half_size = actx -> src0_spad_half_size ; \ 370size_t src1_spad_half_size = actx -> src1_spad_half_size ; \ 371size_t dst_spad_half_size = actx -> dst_spad_half_size ; \ 372 \ 373const int BLOCK = actx -> block ; \ 374if (BLOCK == 0 ) { \ 375FARF (ERROR , \ 376OP_STR \ 377" : current VTCM reservation %zu is too small for even 1 row per thread, needed at least %zu\n" , \ 378actx -> vtcm_src0_size_per_thread ,src0_row_size_aligned ); \ 379return ; \ 380 } \ 381 \ 382dma_queue * dma_queue = actx -> octx -> ctx -> dma [ith ]; \ 383 \ 384/* See discussion: https://github.com/ggml-org/llama.cpp/pull/18151#issuecomment-3678235379 */ \ 385for (uint32_t ir = src0_start_row ,spad_idx = 0 ;ir < src0_end_row && spad_idx < 2 ;ir += BLOCK ,spad_idx ++ ) { \ 386const uint32_t block_size = MIN (BLOCK ,src0_end_row - ir ); \ 387 \ 388/* Dummy DMA transation for sequencing (interleaving dst,src,dst,...) */ \ 389dma_queue_push_vtcm_to_ddr (dma_queue , \ 390dma_make_ptr (data_dst ,dst_spad_data + (spad_idx * dst_spad_half_size )), \ 391dst_row_size ,dst_row_size_aligned ,0 ); \ 392 \ 393dma_queue_push ( \ 394dma_queue , \ 395dma_make_ptr (src0_spad_data + (spad_idx * src0_spad_half_size ),data_src0 + (ir * src0_row_stride )), \ 396src0_row_size_aligned ,src0_row_stride ,src0_row_size ,block_size ); \ 397dma_queue_push ( \ 398dma_queue , \ 399dma_make_ptr (src1_spad_data + (spad_idx * src1_spad_half_size ),data_src1 + (ir * src1_row_stride )), \ 400src1_row_size_aligned ,src1_row_stride ,src1_row_size ,block_size ); \ 401 } \ 402 \ 403for (uint32_t ir = src0_start_row ;ir < src0_end_row ;ir += BLOCK ) { \ 404const uint32_t block_size = MIN (BLOCK ,src0_end_row - ir ); \ 405 \ 406float * dst_spad = (float * )dma_queue_pop (dma_queue ).src ; \ 407float * src0_spad = (float * )dma_queue_pop (dma_queue ).dst ; \ 408float * src1_spad = (float * )dma_queue_pop (dma_queue ).dst ; \ 409 \ 410htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP ,ir ); \ 411CORE_EXPR ; \ 412htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP ,ir ); \ 413 \ 414dma_queue_push_vtcm_to_ddr (dma_queue ,dma_make_ptr (data_dst + (ir * dst_row_size ),dst_spad ), \ 415dst_row_size ,dst_row_size_aligned ,block_size ); \ 416 \ 417/* prefetch N+2 loop iteration if any */ \ 418const uint32_t pref_block = (ir + BLOCK * 2 ); \ 419if (pref_block < src0_end_row ) { \ 420const uint32_t pref_block_size = MIN (BLOCK ,src0_end_row - pref_block ); \ 421dma_queue_push (dma_queue ,dma_make_ptr (src0_spad ,data_src0 + (pref_block * src0_row_stride )), \ 422src0_row_size_aligned ,src0_row_stride ,src0_row_size ,pref_block_size ); \ 423dma_queue_push (dma_queue ,dma_make_ptr (src1_spad ,data_src1 + (pref_block * src1_row_stride )), \ 424src1_row_size_aligned ,src1_row_stride ,src1_row_size ,pref_block_size ); \ 425 } \ 426 } \ 427 \ 428dma_queue_flush (dma_queue ); \ 429 \ 430 } 431 432DEFINE_GLU_PER_THREAD (swiglu ,"swiglu-f32" ,swiglu_f32 (src0_spad ,src1_spad ,dst_spad ,block_size ,actx )) 433DEFINE_GLU_PER_THREAD (swiglu_oai ,"swiglu-oai-f32" ,swiglu_oai_f32 (src0_spad ,src1_spad ,dst_spad ,block_size ,actx )) 434DEFINE_GLU_PER_THREAD (swiglu_clamp ,"swiglu-clamp-f32" ,swiglu_clamp_f32 (src0_spad ,src1_spad ,dst_spad ,block_size ,actx )) 435DEFINE_GLU_PER_THREAD (geglu ,"geglu-f32" ,geglu_f32 (src0_spad ,src1_spad ,dst_spad ,block_size ,actx )) 436 437static int execute_op_activations_f32 (struct htp_ops_context * octx ) { 438const struct htp_tensor * src0 = octx -> src [0 ]; 439const struct htp_tensor * src1 = octx -> src [1 ]; 440const struct htp_tensor * dst = octx -> dst ; 441 442if ((dst -> ne [0 ]* SIZEOF_FP32 )!= dst -> nb [1 ]) { 443FARF (ERROR ,"Non-contiguous dst is not supported at this time \n" ); 444return HTP_STATUS_NO_SUPPORT ; 445 } 446 447worker_callback_t act_op_func ; 448const char * op_type = NULL ; 449 450switch (octx -> op ) { 451case HTP_OP_GLU_SWIGLU : 452act_op_func = (worker_callback_t )glu_swiglu_f32_per_thread ; 453op_type = "swiglu-f32" ; 454break ; 455 456case HTP_OP_GLU_SWIGLU_OAI : 457act_op_func = (worker_callback_t )glu_swiglu_oai_f32_per_thread ; 458op_type = "swiglu-oai-f32" ; 459break ; 460 461case HTP_OP_GLU_SWIGLU_CLAMP : 462act_op_func = (worker_callback_t )glu_swiglu_clamp_f32_per_thread ; 463op_type = "swiglu-clamp-f32" ; 464break ; 465 466case HTP_OP_GLU_GEGLU : 467act_op_func = (worker_callback_t )glu_geglu_f32_per_thread ; 468op_type = "geglu-f32" ; 469break ; 470default : 471FARF (ERROR ,"Unsupported activations Op %u\n" ,octx -> op ); 472return HTP_STATUS_NO_SUPPORT ; 473 } 474 475const uint32_t src0_nrows = src0 -> ne [1 ]* src0 -> ne [2 ]* src0 -> ne [3 ]; 476const size_t dst_row_size = dst -> ne [0 ]* SIZEOF_FP32 ; 477 478uint32_t row_start = 0 ; 479uint32_t nrows = src0_nrows ; 480 481if (octx -> ctx -> mdev .count > 1 ) { 482uint32_t rows_per_chunk = 0 ; 483htp_tensor_mdev_rows_per_chunk (dst ,sizeof (float ), (uint32_t )dst_row_size ,& rows_per_chunk ); 484const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (src0_nrows ,rows_per_chunk ,octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 485row_start = range .start ; 486nrows = range .count ; 487 } 488 489if (nrows == 0 ) { 490return HTP_STATUS_OK ; 491 } 492 493const uint32_t n_threads = octx -> n_threads ; 494 495// row_size = bytes of useful data per row (what the kernel touches / what DMA copies). 496// row_stride = bytes between successive rows in DDR (may exceed row_size for non-contig src). 497const size_t nc_bytes = dst_row_size ; 498const size_t src0_row_size = nc_bytes ; 499const size_t src1_row_size = nc_bytes ; 500const size_t src0_row_stride = src0 -> nb [1 ]; 501const size_t src1_row_stride = src1 ?src1 -> nb [1 ] :src0 -> nb [1 ]; 502 503const size_t src0_row_size_aligned = hex_round_up (src0_row_size ,VLEN ); 504const size_t src1_row_size_aligned = hex_round_up (src1_row_size ,VLEN ); 505const size_t dst_row_size_aligned = hex_round_up (dst_row_size ,VLEN ); 506 507struct htp_act_vtcm_layout L ; 508htp_act_vtcm_layout_build (& L ,src0_row_size_aligned ,src1_row_size_aligned ,dst_row_size_aligned ,n_threads , 509octx -> ctx -> vtcm_size ); 510 511// Make sure the reserved vtcm size is sufficient 512if (L .vtcm_row_per_thread == 0 ) { 513FARF (ERROR ,"act-%s : current VTCM reservation %zu is too small for even 1 row per thread, needed at least %zu\n" ,op_type ,octx -> ctx -> vtcm_size , 514 (src0_row_size_aligned + src1_row_size_aligned + dst_row_size_aligned )* n_threads ); 515return HTP_STATUS_VTCM_TOO_SMALL ; 516 } 517 518if (src1 ) { 519FARF (HIGH ,"%s: %ux%ux%ux%u x %ux%ux%ux%u -> %ux%ux%ux%u : src0-vtcm-size %zu src1-vtcm-size %zu dst-vtcm-size %zu\n" , 520op_type ,src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ],src1 -> ne [0 ],src1 -> ne [1 ],src1 -> ne [2 ], 521src1 -> ne [3 ],dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ],L .src0_bytes_per_thread * n_threads , 522L .src1_bytes_per_thread * n_threads ,L .dst_bytes_per_thread * n_threads ); 523 }else { 524FARF (HIGH ,"%s: %ux%ux%ux%u -> %ux%ux%ux%u : src0-vtcm-size %zu src1-vtcm-size %zu dst-vtcm-size %zu\n" ,op_type , 525src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ],dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 526L .src0_bytes_per_thread * n_threads ,L .src1_bytes_per_thread * n_threads ,L .dst_bytes_per_thread * n_threads ); 527 } 528 529if ((octx -> flags & HTP_OPFLAGS_SKIP_COMPUTE )) { 530return HTP_STATUS_OK ; 531 } 532 533// Prepare context 534struct htp_act_context actx ; 535actx .octx = octx ; 536 537actx .src0_nrows_per_thread = fastdiv (nrows + n_threads - 1 ,& octx -> n_threads_div ); 538 539actx .src0_row_size = src0_row_size ; 540actx .src1_row_size = src1_row_size ; 541actx .dst_row_size = dst_row_size ; 542 543actx .src0_row_size_aligned = src0_row_size_aligned ; 544actx .src1_row_size_aligned = src1_row_size_aligned ; 545actx .dst_row_size_aligned = dst_row_size_aligned ; 546 547actx .src0_row_stride = src0_row_stride ; 548actx .src1_row_stride = src1_row_stride ; 549 550uint8_t * const base = (uint8_t * )octx -> ctx -> vtcm_base ; 551actx .vtcm_src0 = VTCM_LAYOUT_PTR (uint8_t ,base ,L .off_src0 ); 552actx .vtcm_src1 = VTCM_LAYOUT_PTR (uint8_t ,base ,L .off_src1 ); 553actx .vtcm_dst = VTCM_LAYOUT_PTR (uint8_t ,base ,L .off_dst ); 554 555actx .vtcm_src0_size_per_thread = L .src0_bytes_per_thread ; 556actx .vtcm_src1_size_per_thread = L .src1_bytes_per_thread ; 557actx .vtcm_dst_size_per_thread = L .dst_bytes_per_thread ; 558 559actx .src0_spad_half_size = L .src0_bytes_per_thread /2 ; 560actx .src1_spad_half_size = L .src1_bytes_per_thread /2 ; 561actx .dst_spad_half_size = L .dst_bytes_per_thread /2 ; 562 563actx .block = actx .src0_spad_half_size /actx .src0_row_size_aligned ; 564actx .src0_nrows = nrows ; 565actx .row_start = row_start ; 566 567actx .nc = dst -> ne [0 ]; 568 569// Pointers and GLU logic 570const uint8_t * data_src0 = (const uint8_t * )src0 -> data ; 571const uint8_t * data_src1 = src1 ? (const uint8_t * )src1 -> data :NULL ; 572 573if (!src1 && (octx -> op == HTP_OP_GLU_SWIGLU || octx -> op == HTP_OP_GLU_SWIGLU_OAI || octx -> op == HTP_OP_GLU_SWIGLU_CLAMP || octx -> op == HTP_OP_GLU_GEGLU )) { 574const int32_t swapped = octx -> op_params [1 ]; 575data_src1 = data_src0 ; 576actx .src1_row_size = actx .src0_row_size ; 577 578size_t nc_in_bytes = actx .nc * SIZEOF_FP32 ; 579if (swapped ) { 580data_src0 += nc_in_bytes ; 581 }else { 582data_src1 += nc_in_bytes ; 583 } 584 } 585 586actx .data_src0 = data_src0 ; 587actx .data_src1 = data_src1 ; 588actx .data_dst = (uint8_t * )dst -> data ; 589 590work_queue_run (octx -> ctx -> work_queue ,act_op_func ,& actx ,n_threads ); 591return HTP_STATUS_OK ; 592} 593 594int op_activations (struct htp_ops_context * octx ) { 595switch (octx -> src [0 ]-> type ) { 596case HTP_TYPE_F32 : 597return execute_op_activations_f32 (octx ); 598 599default : 600return HTP_STATUS_NO_SUPPORT ; 601 } 602}