char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
eafe15a5e
char/aliceai-t5-moe
1#include <math.h> 2#include <stdint.h> 3#include <string.h> 4 5#include "hvx-utils.h" 6#include "hex-fastdiv.h" 7#include "hex-common.h" 8#include "hex-profile.h" 9 10#define GGML_COMMON_DECL_C 11#include "ggml-common.h" 12#include "htp-ctx.h" 13#include "htp-tensor.h" 14 15#ifndef MIN 16#define MIN (a ,b ) ((a) < (b) ? (a) : (b)) 17#endif 18 19#define HTP_GDN_MAX_SV 128 20 21 22struct htp_gdn_context { 23struct htp_ops_context * octx ; 24uint32_t rows_per_thread ; 25size_t state_bytes ; 26uint8_t * vtcm_base ; 27size_t vtcm_per_thread ; 28uint32_t row_start ; 29uint32_t nrows ; 30}; 31 32static inline HVX_Vector gdn_mul_dot_f32 (float * restrictdst ,const float * restrictmul ,const float * restrictdot ,uint32_t n ) { 33HVX_Vector acc = Q6_V_vzero (); 34 35const uint32_t epv = 128 /sizeof (float ); 36const uint32_t nvec = n /epv ; 37const uint32_t nloe = n %epv ; 38for (uint32_t i = 0 ;i < nvec ;++ i ) { 39HVX_Vector vd = hvx_vmemu (dst + i * epv ); 40HVX_Vector vm = hvx_vmem (mul + i * epv ); 41HVX_Vector vdot = hvx_vmem (dot + i * epv ); 42HVX_Vector out = hvx_vec_mul_f32_f32 (vd ,vm ); 43hvx_vmemu (dst + i * epv )= out ; 44acc = hvx_vec_add_f32_f32 (acc ,hvx_vec_mul_f32_f32 (out ,vdot )); 45 } 46 47if (nloe ) { 48const uint32_t off = nvec * epv ; 49HVX_Vector vd = hvx_vmemu (dst + off ); 50HVX_Vector vm = hvx_vmem (mul + off ); 51HVX_Vector vdot = hvx_vmem (dot + off ); 52HVX_Vector out = hvx_vec_mul_f32_f32 (vd ,vm ); 53hvx_vec_store_u (dst + off ,nloe * sizeof (float ),out ); 54HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 55HVX_Vector prod = hvx_vec_mul_f32_f32 (out ,vdot ); 56acc = hvx_vec_add_f32_f32 (acc ,Q6_V_vmux_QVV (mask ,prod ,Q6_V_vzero ())); 57 } 58 59return hvx_vec_reduce_sum_f32 (acc ); 60} 61 62static inline HVX_Vector gdn_mul_scalar_dot_f32 (float * restrictdst ,float mul ,const float * restrictdot ,uint32_t n ) { 63HVX_Vector acc = Q6_V_vzero (); 64const HVX_Vector vmul = hvx_vec_splat_f32 (mul ); 65 66const uint32_t epv = 128 /sizeof (float ); 67const uint32_t nvec = n /epv ; 68const uint32_t nloe = n %epv ; 69for (uint32_t i = 0 ;i < nvec ;++ i ) { 70HVX_Vector vd = hvx_vmemu (dst + i * epv ); 71HVX_Vector vdot = hvx_vmem (dot + i * epv ); 72HVX_Vector out = hvx_vec_mul_f32_f32 (vd ,vmul ); 73hvx_vmemu (dst + i * epv )= out ; 74acc = hvx_vec_add_f32_f32 (acc ,hvx_vec_mul_f32_f32 (out ,vdot )); 75 } 76 77if (nloe ) { 78const uint32_t off = nvec * epv ; 79HVX_Vector vd = hvx_vmemu (dst + off ); 80HVX_Vector vdot = hvx_vmem (dot + off ); 81HVX_Vector out = hvx_vec_mul_f32_f32 (vd ,vmul ); 82hvx_vec_store_u (dst + off ,nloe * sizeof (float ),out ); 83HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 84HVX_Vector prod = hvx_vec_mul_f32_f32 (out ,vdot ); 85acc = hvx_vec_add_f32_f32 (acc ,Q6_V_vmux_QVV (mask ,prod ,Q6_V_vzero ())); 86 } 87 88return hvx_vec_reduce_sum_f32 (acc ); 89} 90 91static inline HVX_Vector gdn_add_scaled_dot_f32 (float * restrictdst ,const float * restrictsrc , 92HVX_Vector vscale ,const float * restrictdot ,uint32_t n ) { 93HVX_Vector acc = Q6_V_vzero (); 94 95const uint32_t epv = 128 /sizeof (float ); 96const uint32_t nvec = n /epv ; 97const uint32_t nloe = n %epv ; 98for (uint32_t i = 0 ;i < nvec ;++ i ) { 99HVX_Vector vd = hvx_vmemu (dst + i * epv ); 100HVX_Vector vs = hvx_vmem (src + i * epv ); 101HVX_Vector vdot = hvx_vmem (dot + i * epv ); 102HVX_Vector out = hvx_vec_add_f32_f32 (vd ,hvx_vec_mul_f32_f32 (vs ,vscale )); 103hvx_vmemu (dst + i * epv )= out ; 104acc = hvx_vec_add_f32_f32 (acc ,hvx_vec_mul_f32_f32 (out ,vdot )); 105 } 106 107if (nloe ) { 108const uint32_t off = nvec * epv ; 109HVX_Vector vd = hvx_vmemu (dst + off ); 110HVX_Vector vs = hvx_vmem (src + off ); 111HVX_Vector vdot = hvx_vmem (dot + off ); 112HVX_Vector out = hvx_vec_add_f32_f32 (vd ,hvx_vec_mul_f32_f32 (vs ,vscale )); 113hvx_vec_store_u (dst + off ,nloe * sizeof (float ),out ); 114HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 115HVX_Vector prod = hvx_vec_mul_f32_f32 (out ,vdot ); 116acc = hvx_vec_add_f32_f32 (acc ,Q6_V_vmux_QVV (mask ,prod ,Q6_V_vzero ())); 117 } 118 119return hvx_vec_reduce_sum_f32 (acc ); 120} 121 122static inline void gdn_mul_dot4_f32 (float * restrictdst0 ,float * restrictdst1 , 123float * restrictdst2 ,float * restrictdst3 ,const float * restrictmul , 124const float * restrictdot ,uint32_t n ,float * restrictsums ) { 125HVX_Vector acc0 = Q6_V_vzero (); 126HVX_Vector acc1 = Q6_V_vzero (); 127HVX_Vector acc2 = Q6_V_vzero (); 128HVX_Vector acc3 = Q6_V_vzero (); 129 130const uint32_t epv = 128 /sizeof (float ); 131const uint32_t nvec = n /epv ; 132const uint32_t nloe = n %epv ; 133for (uint32_t i = 0 ;i < nvec ;++ i ) { 134HVX_Vector vm = hvx_vmem (mul + i * epv ); 135HVX_Vector vdot = hvx_vmem (dot + i * epv ); 136 137HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + i * epv ),vm ); 138HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + i * epv ),vm ); 139HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + i * epv ),vm ); 140HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + i * epv ),vm ); 141 142hvx_vmemu (dst0 + i * epv )= out0 ; 143hvx_vmemu (dst1 + i * epv )= out1 ; 144hvx_vmemu (dst2 + i * epv )= out2 ; 145hvx_vmemu (dst3 + i * epv )= out3 ; 146 147acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 148acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 149acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 150acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 151 } 152 153if (nloe ) { 154const uint32_t off = nvec * epv ; 155HVX_Vector vm = hvx_vmem (mul + off ); 156HVX_Vector vdot = hvx_vmem (dot + off ); 157HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 158HVX_Vector zero = Q6_V_vzero (); 159 160HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + off ),vm ); 161HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + off ),vm ); 162HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + off ),vm ); 163HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + off ),vm ); 164 165hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 166hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 167hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 168hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 169 170acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 171acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 172acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 173acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 174 } 175 176HVX_Vector_x4 acc = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 177hvx_vec_store_u (sums ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (acc )); 178} 179 180static inline void gdn_mul_scalar_dot4_f32 (float * restrictdst0 ,float * restrictdst1 , 181float * restrictdst2 ,float * restrictdst3 ,float mul , 182const float * restrictdot ,uint32_t n ,float * restrictsums ) { 183HVX_Vector acc0 = Q6_V_vzero (); 184HVX_Vector acc1 = Q6_V_vzero (); 185HVX_Vector acc2 = Q6_V_vzero (); 186HVX_Vector acc3 = Q6_V_vzero (); 187const HVX_Vector vmul = hvx_vec_splat_f32 (mul ); 188 189const uint32_t epv = 128 /sizeof (float ); 190const uint32_t nvec = n /epv ; 191const uint32_t nloe = n %epv ; 192for (uint32_t i = 0 ;i < nvec ;++ i ) { 193HVX_Vector vdot = hvx_vmem (dot + i * epv ); 194 195HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + i * epv ),vmul ); 196HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + i * epv ),vmul ); 197HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + i * epv ),vmul ); 198HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + i * epv ),vmul ); 199 200hvx_vmemu (dst0 + i * epv )= out0 ; 201hvx_vmemu (dst1 + i * epv )= out1 ; 202hvx_vmemu (dst2 + i * epv )= out2 ; 203hvx_vmemu (dst3 + i * epv )= out3 ; 204 205acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 206acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 207acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 208acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 209 } 210 211if (nloe ) { 212const uint32_t off = nvec * epv ; 213HVX_Vector vdot = hvx_vmem (dot + off ); 214HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 215HVX_Vector zero = Q6_V_vzero (); 216 217HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + off ),vmul ); 218HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + off ),vmul ); 219HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + off ),vmul ); 220HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + off ),vmul ); 221 222hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 223hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 224hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 225hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 226 227acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 228acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 229acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 230acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 231 } 232 233HVX_Vector_x4 acc = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 234hvx_vec_store_u (sums ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (acc )); 235} 236 237static inline void gdn_add_scaled_dot4_f32 (float * restrictdst0 ,float * restrictdst1 , 238float * restrictdst2 ,float * restrictdst3 ,const float * restrictsrc , 239const float * restrictscale ,const float * restrictdot ,uint32_t n , 240float * restrictsums ) { 241HVX_Vector acc0 = Q6_V_vzero (); 242HVX_Vector acc1 = Q6_V_vzero (); 243HVX_Vector acc2 = Q6_V_vzero (); 244HVX_Vector acc3 = Q6_V_vzero (); 245const HVX_Vector scale0 = hvx_vec_splat_f32 (scale [0 ]); 246const HVX_Vector scale1 = hvx_vec_splat_f32 (scale [1 ]); 247const HVX_Vector scale2 = hvx_vec_splat_f32 (scale [2 ]); 248const HVX_Vector scale3 = hvx_vec_splat_f32 (scale [3 ]); 249 250const uint32_t epv = 128 /sizeof (float ); 251const uint32_t nvec = n /epv ; 252const uint32_t nloe = n %epv ; 253for (uint32_t i = 0 ;i < nvec ;++ i ) { 254HVX_Vector vs = hvx_vmem (src + i * epv ); 255HVX_Vector vdot = hvx_vmem (dot + i * epv ); 256 257HVX_Vector out0 = hvx_vec_add_f32_f32 (hvx_vmemu (dst0 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale0 )); 258HVX_Vector out1 = hvx_vec_add_f32_f32 (hvx_vmemu (dst1 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale1 )); 259HVX_Vector out2 = hvx_vec_add_f32_f32 (hvx_vmemu (dst2 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale2 )); 260HVX_Vector out3 = hvx_vec_add_f32_f32 (hvx_vmemu (dst3 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale3 )); 261 262hvx_vmemu (dst0 + i * epv )= out0 ; 263hvx_vmemu (dst1 + i * epv )= out1 ; 264hvx_vmemu (dst2 + i * epv )= out2 ; 265hvx_vmemu (dst3 + i * epv )= out3 ; 266 267acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 268acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 269acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 270acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 271 } 272 273if (nloe ) { 274const uint32_t off = nvec * epv ; 275HVX_Vector vs = hvx_vmem (src + off ); 276HVX_Vector vdot = hvx_vmem (dot + off ); 277HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 278HVX_Vector zero = Q6_V_vzero (); 279 280HVX_Vector out0 = hvx_vec_add_f32_f32 (hvx_vmemu (dst0 + off ),hvx_vec_mul_f32_f32 (vs ,scale0 )); 281HVX_Vector out1 = hvx_vec_add_f32_f32 (hvx_vmemu (dst1 + off ),hvx_vec_mul_f32_f32 (vs ,scale1 )); 282HVX_Vector out2 = hvx_vec_add_f32_f32 (hvx_vmemu (dst2 + off ),hvx_vec_mul_f32_f32 (vs ,scale2 )); 283HVX_Vector out3 = hvx_vec_add_f32_f32 (hvx_vmemu (dst3 + off ),hvx_vec_mul_f32_f32 (vs ,scale3 )); 284 285hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 286hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 287hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 288hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 289 290acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 291acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 292acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 293acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 294 } 295 296HVX_Vector_x4 acc = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 297hvx_vec_store_u (sums ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (acc )); 298} 299 300static inline void gdn_mul_dot8_f32 (float * restrictdst0 ,float * restrictdst1 , 301float * restrictdst2 ,float * restrictdst3 ,float * restrictdst4 , 302float * restrictdst5 ,float * restrictdst6 ,float * restrictdst7 , 303const float * restrictmul ,const float * restrictdot ,uint32_t n , 304float * restrictsums ) { 305HVX_Vector acc0 = Q6_V_vzero (); 306HVX_Vector acc1 = Q6_V_vzero (); 307HVX_Vector acc2 = Q6_V_vzero (); 308HVX_Vector acc3 = Q6_V_vzero (); 309HVX_Vector acc4 = Q6_V_vzero (); 310HVX_Vector acc5 = Q6_V_vzero (); 311HVX_Vector acc6 = Q6_V_vzero (); 312HVX_Vector acc7 = Q6_V_vzero (); 313 314const uint32_t epv = 128 /sizeof (float ); 315const uint32_t nvec = n /epv ; 316const uint32_t nloe = n %epv ; 317for (uint32_t i = 0 ;i < nvec ;++ i ) { 318HVX_Vector vm = hvx_vmem (mul + i * epv ); 319HVX_Vector vdot = hvx_vmem (dot + i * epv ); 320 321HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + i * epv ),vm ); 322HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + i * epv ),vm ); 323HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + i * epv ),vm ); 324HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + i * epv ),vm ); 325HVX_Vector out4 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst4 + i * epv ),vm ); 326HVX_Vector out5 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst5 + i * epv ),vm ); 327HVX_Vector out6 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst6 + i * epv ),vm ); 328HVX_Vector out7 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst7 + i * epv ),vm ); 329 330hvx_vmemu (dst0 + i * epv )= out0 ; 331hvx_vmemu (dst1 + i * epv )= out1 ; 332hvx_vmemu (dst2 + i * epv )= out2 ; 333hvx_vmemu (dst3 + i * epv )= out3 ; 334hvx_vmemu (dst4 + i * epv )= out4 ; 335hvx_vmemu (dst5 + i * epv )= out5 ; 336hvx_vmemu (dst6 + i * epv )= out6 ; 337hvx_vmemu (dst7 + i * epv )= out7 ; 338 339acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 340acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 341acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 342acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 343acc4 = hvx_vec_add_f32_f32 (acc4 ,hvx_vec_mul_f32_f32 (out4 ,vdot )); 344acc5 = hvx_vec_add_f32_f32 (acc5 ,hvx_vec_mul_f32_f32 (out5 ,vdot )); 345acc6 = hvx_vec_add_f32_f32 (acc6 ,hvx_vec_mul_f32_f32 (out6 ,vdot )); 346acc7 = hvx_vec_add_f32_f32 (acc7 ,hvx_vec_mul_f32_f32 (out7 ,vdot )); 347 } 348 349if (nloe ) { 350const uint32_t off = nvec * epv ; 351HVX_Vector vm = hvx_vmem (mul + off ); 352HVX_Vector vdot = hvx_vmem (dot + off ); 353HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 354HVX_Vector zero = Q6_V_vzero (); 355 356HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + off ),vm ); 357HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + off ),vm ); 358HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + off ),vm ); 359HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + off ),vm ); 360HVX_Vector out4 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst4 + off ),vm ); 361HVX_Vector out5 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst5 + off ),vm ); 362HVX_Vector out6 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst6 + off ),vm ); 363HVX_Vector out7 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst7 + off ),vm ); 364 365hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 366hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 367hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 368hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 369hvx_vec_store_u (dst4 + off ,nloe * sizeof (float ),out4 ); 370hvx_vec_store_u (dst5 + off ,nloe * sizeof (float ),out5 ); 371hvx_vec_store_u (dst6 + off ,nloe * sizeof (float ),out6 ); 372hvx_vec_store_u (dst7 + off ,nloe * sizeof (float ),out7 ); 373 374acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 375acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 376acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 377acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 378acc4 = hvx_vec_add_f32_f32 (acc4 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out4 ,vdot ),zero )); 379acc5 = hvx_vec_add_f32_f32 (acc5 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out5 ,vdot ),zero )); 380acc6 = hvx_vec_add_f32_f32 (acc6 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out6 ,vdot ),zero )); 381acc7 = hvx_vec_add_f32_f32 (acc7 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out7 ,vdot ),zero )); 382 } 383 384HVX_Vector_x4 accA = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 385HVX_Vector_x4 accB = { .v = {acc4 ,acc5 ,acc6 ,acc7 } }; 386hvx_vec_store_u (sums + 0 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accA )); 387hvx_vec_store_u (sums + 4 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accB )); 388} 389 390static inline void gdn_mul_scalar_dot8_f32 (float * restrictdst0 ,float * restrictdst1 , 391float * restrictdst2 ,float * restrictdst3 ,float * restrictdst4 , 392float * restrictdst5 ,float * restrictdst6 ,float * restrictdst7 , 393float mul ,const float * restrictdot ,uint32_t n ,float * restrictsums ) { 394HVX_Vector acc0 = Q6_V_vzero (); 395HVX_Vector acc1 = Q6_V_vzero (); 396HVX_Vector acc2 = Q6_V_vzero (); 397HVX_Vector acc3 = Q6_V_vzero (); 398HVX_Vector acc4 = Q6_V_vzero (); 399HVX_Vector acc5 = Q6_V_vzero (); 400HVX_Vector acc6 = Q6_V_vzero (); 401HVX_Vector acc7 = Q6_V_vzero (); 402const HVX_Vector vmul = hvx_vec_splat_f32 (mul ); 403 404const uint32_t epv = 128 /sizeof (float ); 405const uint32_t nvec = n /epv ; 406const uint32_t nloe = n %epv ; 407for (uint32_t i = 0 ;i < nvec ;++ i ) { 408HVX_Vector vdot = hvx_vmem (dot + i * epv ); 409 410HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + i * epv ),vmul ); 411HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + i * epv ),vmul ); 412HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + i * epv ),vmul ); 413HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + i * epv ),vmul ); 414HVX_Vector out4 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst4 + i * epv ),vmul ); 415HVX_Vector out5 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst5 + i * epv ),vmul ); 416HVX_Vector out6 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst6 + i * epv ),vmul ); 417HVX_Vector out7 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst7 + i * epv ),vmul ); 418 419hvx_vmemu (dst0 + i * epv )= out0 ; 420hvx_vmemu (dst1 + i * epv )= out1 ; 421hvx_vmemu (dst2 + i * epv )= out2 ; 422hvx_vmemu (dst3 + i * epv )= out3 ; 423hvx_vmemu (dst4 + i * epv )= out4 ; 424hvx_vmemu (dst5 + i * epv )= out5 ; 425hvx_vmemu (dst6 + i * epv )= out6 ; 426hvx_vmemu (dst7 + i * epv )= out7 ; 427 428acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 429acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 430acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 431acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 432acc4 = hvx_vec_add_f32_f32 (acc4 ,hvx_vec_mul_f32_f32 (out4 ,vdot )); 433acc5 = hvx_vec_add_f32_f32 (acc5 ,hvx_vec_mul_f32_f32 (out5 ,vdot )); 434acc6 = hvx_vec_add_f32_f32 (acc6 ,hvx_vec_mul_f32_f32 (out6 ,vdot )); 435acc7 = hvx_vec_add_f32_f32 (acc7 ,hvx_vec_mul_f32_f32 (out7 ,vdot )); 436 } 437 438if (nloe ) { 439const uint32_t off = nvec * epv ; 440HVX_Vector vdot = hvx_vmem (dot + off ); 441HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 442HVX_Vector zero = Q6_V_vzero (); 443 444HVX_Vector out0 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst0 + off ),vmul ); 445HVX_Vector out1 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst1 + off ),vmul ); 446HVX_Vector out2 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst2 + off ),vmul ); 447HVX_Vector out3 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst3 + off ),vmul ); 448HVX_Vector out4 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst4 + off ),vmul ); 449HVX_Vector out5 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst5 + off ),vmul ); 450HVX_Vector out6 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst6 + off ),vmul ); 451HVX_Vector out7 = hvx_vec_mul_f32_f32 (hvx_vmemu (dst7 + off ),vmul ); 452 453hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 454hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 455hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 456hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 457hvx_vec_store_u (dst4 + off ,nloe * sizeof (float ),out4 ); 458hvx_vec_store_u (dst5 + off ,nloe * sizeof (float ),out5 ); 459hvx_vec_store_u (dst6 + off ,nloe * sizeof (float ),out6 ); 460hvx_vec_store_u (dst7 + off ,nloe * sizeof (float ),out7 ); 461 462acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 463acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 464acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 465acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 466acc4 = hvx_vec_add_f32_f32 (acc4 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out4 ,vdot ),zero )); 467acc5 = hvx_vec_add_f32_f32 (acc5 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out5 ,vdot ),zero )); 468acc6 = hvx_vec_add_f32_f32 (acc6 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out6 ,vdot ),zero )); 469acc7 = hvx_vec_add_f32_f32 (acc7 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out7 ,vdot ),zero )); 470 } 471 472HVX_Vector_x4 accA = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 473HVX_Vector_x4 accB = { .v = {acc4 ,acc5 ,acc6 ,acc7 } }; 474hvx_vec_store_u (sums + 0 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accA )); 475hvx_vec_store_u (sums + 4 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accB )); 476} 477 478static inline void gdn_add_scaled_dot8_f32 (float * restrictdst0 ,float * restrictdst1 , 479float * restrictdst2 ,float * restrictdst3 ,float * restrictdst4 , 480float * restrictdst5 ,float * restrictdst6 ,float * restrictdst7 , 481const float * restrictsrc ,const float * restrictscale , 482const float * restrictdot ,uint32_t n ,float * restrictsums ) { 483HVX_Vector acc0 = Q6_V_vzero (); 484HVX_Vector acc1 = Q6_V_vzero (); 485HVX_Vector acc2 = Q6_V_vzero (); 486HVX_Vector acc3 = Q6_V_vzero (); 487HVX_Vector acc4 = Q6_V_vzero (); 488HVX_Vector acc5 = Q6_V_vzero (); 489HVX_Vector acc6 = Q6_V_vzero (); 490HVX_Vector acc7 = Q6_V_vzero (); 491const HVX_Vector scale0 = hvx_vec_splat_f32 (scale [0 ]); 492const HVX_Vector scale1 = hvx_vec_splat_f32 (scale [1 ]); 493const HVX_Vector scale2 = hvx_vec_splat_f32 (scale [2 ]); 494const HVX_Vector scale3 = hvx_vec_splat_f32 (scale [3 ]); 495const HVX_Vector scale4 = hvx_vec_splat_f32 (scale [4 ]); 496const HVX_Vector scale5 = hvx_vec_splat_f32 (scale [5 ]); 497const HVX_Vector scale6 = hvx_vec_splat_f32 (scale [6 ]); 498const HVX_Vector scale7 = hvx_vec_splat_f32 (scale [7 ]); 499 500const uint32_t epv = 128 /sizeof (float ); 501const uint32_t nvec = n /epv ; 502const uint32_t nloe = n %epv ; 503for (uint32_t i = 0 ;i < nvec ;++ i ) { 504HVX_Vector vs = hvx_vmem (src + i * epv ); 505HVX_Vector vdot = hvx_vmem (dot + i * epv ); 506 507HVX_Vector out0 = hvx_vec_add_f32_f32 (hvx_vmemu (dst0 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale0 )); 508HVX_Vector out1 = hvx_vec_add_f32_f32 (hvx_vmemu (dst1 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale1 )); 509HVX_Vector out2 = hvx_vec_add_f32_f32 (hvx_vmemu (dst2 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale2 )); 510HVX_Vector out3 = hvx_vec_add_f32_f32 (hvx_vmemu (dst3 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale3 )); 511HVX_Vector out4 = hvx_vec_add_f32_f32 (hvx_vmemu (dst4 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale4 )); 512HVX_Vector out5 = hvx_vec_add_f32_f32 (hvx_vmemu (dst5 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale5 )); 513HVX_Vector out6 = hvx_vec_add_f32_f32 (hvx_vmemu (dst6 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale6 )); 514HVX_Vector out7 = hvx_vec_add_f32_f32 (hvx_vmemu (dst7 + i * epv ),hvx_vec_mul_f32_f32 (vs ,scale7 )); 515 516hvx_vmemu (dst0 + i * epv )= out0 ; 517hvx_vmemu (dst1 + i * epv )= out1 ; 518hvx_vmemu (dst2 + i * epv )= out2 ; 519hvx_vmemu (dst3 + i * epv )= out3 ; 520hvx_vmemu (dst4 + i * epv )= out4 ; 521hvx_vmemu (dst5 + i * epv )= out5 ; 522hvx_vmemu (dst6 + i * epv )= out6 ; 523hvx_vmemu (dst7 + i * epv )= out7 ; 524 525acc0 = hvx_vec_add_f32_f32 (acc0 ,hvx_vec_mul_f32_f32 (out0 ,vdot )); 526acc1 = hvx_vec_add_f32_f32 (acc1 ,hvx_vec_mul_f32_f32 (out1 ,vdot )); 527acc2 = hvx_vec_add_f32_f32 (acc2 ,hvx_vec_mul_f32_f32 (out2 ,vdot )); 528acc3 = hvx_vec_add_f32_f32 (acc3 ,hvx_vec_mul_f32_f32 (out3 ,vdot )); 529acc4 = hvx_vec_add_f32_f32 (acc4 ,hvx_vec_mul_f32_f32 (out4 ,vdot )); 530acc5 = hvx_vec_add_f32_f32 (acc5 ,hvx_vec_mul_f32_f32 (out5 ,vdot )); 531acc6 = hvx_vec_add_f32_f32 (acc6 ,hvx_vec_mul_f32_f32 (out6 ,vdot )); 532acc7 = hvx_vec_add_f32_f32 (acc7 ,hvx_vec_mul_f32_f32 (out7 ,vdot )); 533 } 534 535if (nloe ) { 536const uint32_t off = nvec * epv ; 537HVX_Vector vs = hvx_vmem (src + off ); 538HVX_Vector vdot = hvx_vmem (dot + off ); 539HVX_VectorPred mask = Q6_Q_vsetq2_R (nloe * sizeof (float )); 540HVX_Vector zero = Q6_V_vzero (); 541 542HVX_Vector out0 = hvx_vec_add_f32_f32 (hvx_vmemu (dst0 + off ),hvx_vec_mul_f32_f32 (vs ,scale0 )); 543HVX_Vector out1 = hvx_vec_add_f32_f32 (hvx_vmemu (dst1 + off ),hvx_vec_mul_f32_f32 (vs ,scale1 )); 544HVX_Vector out2 = hvx_vec_add_f32_f32 (hvx_vmemu (dst2 + off ),hvx_vec_mul_f32_f32 (vs ,scale2 )); 545HVX_Vector out3 = hvx_vec_add_f32_f32 (hvx_vmemu (dst3 + off ),hvx_vec_mul_f32_f32 (vs ,scale3 )); 546HVX_Vector out4 = hvx_vec_add_f32_f32 (hvx_vmemu (dst4 + off ),hvx_vec_mul_f32_f32 (vs ,scale4 )); 547HVX_Vector out5 = hvx_vec_add_f32_f32 (hvx_vmemu (dst5 + off ),hvx_vec_mul_f32_f32 (vs ,scale5 )); 548HVX_Vector out6 = hvx_vec_add_f32_f32 (hvx_vmemu (dst6 + off ),hvx_vec_mul_f32_f32 (vs ,scale6 )); 549HVX_Vector out7 = hvx_vec_add_f32_f32 (hvx_vmemu (dst7 + off ),hvx_vec_mul_f32_f32 (vs ,scale7 )); 550 551hvx_vec_store_u (dst0 + off ,nloe * sizeof (float ),out0 ); 552hvx_vec_store_u (dst1 + off ,nloe * sizeof (float ),out1 ); 553hvx_vec_store_u (dst2 + off ,nloe * sizeof (float ),out2 ); 554hvx_vec_store_u (dst3 + off ,nloe * sizeof (float ),out3 ); 555hvx_vec_store_u (dst4 + off ,nloe * sizeof (float ),out4 ); 556hvx_vec_store_u (dst5 + off ,nloe * sizeof (float ),out5 ); 557hvx_vec_store_u (dst6 + off ,nloe * sizeof (float ),out6 ); 558hvx_vec_store_u (dst7 + off ,nloe * sizeof (float ),out7 ); 559 560acc0 = hvx_vec_add_f32_f32 (acc0 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out0 ,vdot ),zero )); 561acc1 = hvx_vec_add_f32_f32 (acc1 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out1 ,vdot ),zero )); 562acc2 = hvx_vec_add_f32_f32 (acc2 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out2 ,vdot ),zero )); 563acc3 = hvx_vec_add_f32_f32 (acc3 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out3 ,vdot ),zero )); 564acc4 = hvx_vec_add_f32_f32 (acc4 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out4 ,vdot ),zero )); 565acc5 = hvx_vec_add_f32_f32 (acc5 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out5 ,vdot ),zero )); 566acc6 = hvx_vec_add_f32_f32 (acc6 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out6 ,vdot ),zero )); 567acc7 = hvx_vec_add_f32_f32 (acc7 ,Q6_V_vmux_QVV (mask ,hvx_vec_mul_f32_f32 (out7 ,vdot ),zero )); 568 } 569 570HVX_Vector_x4 accA = { .v = {acc0 ,acc1 ,acc2 ,acc3 } }; 571HVX_Vector_x4 accB = { .v = {acc4 ,acc5 ,acc6 ,acc7 } }; 572hvx_vec_store_u (sums + 0 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accA )); 573hvx_vec_store_u (sums + 4 ,4 * sizeof (float ),hvx_vec_reduce_sum_f32x4 (accB )); 574} 575 576static void gated_delta_net_f32_pp_thread (unsigned int nth ,unsigned int ith ,void * data ) { 577struct htp_gdn_context * gctx = (struct htp_gdn_context * )data ; 578struct htp_ops_context * octx = gctx -> octx ; 579 580const struct htp_tensor * q = octx -> src [0 ]; 581const struct htp_tensor * k = octx -> src [1 ]; 582const struct htp_tensor * v = octx -> src [2 ]; 583const struct htp_tensor * g = octx -> src [3 ]; 584const struct htp_tensor * beta = octx -> src [4 ]; 585const struct htp_tensor * state = octx -> src [5 ]; 586const struct htp_tensor * dst = octx -> dst ; 587 588const uint32_t S_v = v -> ne [0 ]; 589const uint32_t H = v -> ne [1 ]; 590const uint32_t n_tokens = v -> ne [2 ]; 591const uint32_t n_seqs = v -> ne [3 ]; 592const uint32_t K = octx -> op_params [0 ]; 593 594const uint32_t row_end = gctx -> row_start + gctx -> nrows ; 595 596if (ith >=gctx -> nrows ) { 597return ; 598 } 599 600const uint32_t rq3 = n_seqs /q -> ne [3 ]; 601const uint32_t rk3 = n_seqs /k -> ne [3 ]; 602const float scale = 1.0f /sqrtf ((float )S_v ); 603 604float * dst_base = (float * ) (uintptr_t )dst -> data ; 605float * state_out_base = dst_base + (uint64_t )S_v * H * n_tokens * n_seqs ; 606const float * state_in_base = (const float * ) (uintptr_t )state -> data ; 607 608const bool kda = (g -> ne [0 ]== S_v ); 609float local_gate [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 610float local_q [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 611float local_k [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 612float local_sums [32 ] __attribute__((aligned (128 ))); 613 614dma_queue * dma = octx -> ctx -> dma [ith ]; 615size_t state_aligned = (size_t )S_v * S_v * sizeof (float ); 616state_aligned = (state_aligned + 127 )& ~(size_t )127 ; 617float * s_work [2 ]; 618s_work [0 ]= (float * ) (gctx -> vtcm_base + gctx -> vtcm_per_thread * ith ); 619s_work [1 ]= s_work [0 ]+ state_aligned /sizeof (float ); 620 621struct fastdiv_values fd_H = init_fastdiv_values (H ); 622struct fastdiv_values fd_q1 = init_fastdiv_values (q -> ne [1 ]); 623struct fastdiv_values fd_k1 = init_fastdiv_values (k -> ne [1 ]); 624struct fastdiv_values fd_rq3 = init_fastdiv_values (rq3 ); 625struct fastdiv_values fd_rk3 = init_fastdiv_values (rk3 ); 626 627const uint64_t state_seq_stride = state -> nb [3 ] /sizeof (float ); 628const uint64_t state_size_per_snap = (uint64_t )S_v * S_v * H * n_seqs ; 629 630uint32_t ir_prefetch = gctx -> row_start + ith ; 631int spad_idx = 0 ; 632 633// Prefetch preamble (up to 2 steps) 634for (int k = 0 ;k < 2 && ir_prefetch < row_end ;k ++ ) { 635const uint32_t piv1 = fastmodulo (ir_prefetch ,H ,& fd_H ); 636const uint32_t piv3 = fastdiv (ir_prefetch ,& fd_H ); 637const float * ps_in = state_in_base + (uint64_t )piv3 * state_seq_stride + (uint64_t )piv1 * S_v * S_v ; 638// final state lands in snapshot slot 0 (most-recent-first ordering) 639float * ps_out = state_out_base + ((uint64_t )piv3 * H + piv1 )* S_v * S_v ; 640 641// Push dummy write-back 642dma_queue_push (dma ,dma_make_ptr (ps_out ,s_work [spad_idx ]), 643S_v * sizeof (float ),S_v * sizeof (float ), 644S_v * sizeof (float ),0 ); 645 646// Push fetch 647dma_queue_push (dma ,dma_make_ptr (s_work [spad_idx ],ps_in ), 648S_v * sizeof (float ),S_v * sizeof (float ), 649S_v * sizeof (float ),S_v ); 650 651ir_prefetch += nth ; 652spad_idx ^=1 ; 653 } 654 655struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 656htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t ) (gctx -> row_start + ith )); 657 658int curr_spad_idx = 0 ; 659for (uint32_t ir = gctx -> row_start + ith ;ir < row_end ;ir += nth ) { 660dma_queue_pop (dma ); 661dma_queue_pop (dma ); 662 663float * s_work_curr = s_work [curr_spad_idx ]; 664 665const uint32_t iv1 = fastmodulo (ir ,H ,& fd_H ); 666const uint32_t iv3 = fastdiv (ir ,& fd_H ); 667 668const uint32_t iq1 = fastmodulo (iv1 ,q -> ne [1 ],& fd_q1 ); 669const uint32_t ik1 = fastmodulo (iv1 ,k -> ne [1 ],& fd_k1 ); 670const uint32_t iq3 = fastdiv (iv3 ,& fd_rq3 ); 671const uint32_t ik3 = fastdiv (iv3 ,& fd_rk3 ); 672 673// final state lands in snapshot slot 0 (most-recent-first ordering) 674float * s_out = state_out_base + ((uint64_t )iv3 * H + iv1 )* S_v * S_v ; 675 676float * attn_data = dst_base + ((uint64_t )iv3 * n_tokens * H + iv1 )* S_v ; 677 678for (uint32_t t = 0 ;t < n_tokens ;++ t ) { 679const float * q_t = (const float * ) ((const uint8_t * ) (uintptr_t )q -> data + 680 (uint64_t )iq3 * q -> nb [3 ]+ (uint64_t )t * q -> nb [2 ]+ (uint64_t )iq1 * q -> nb [1 ]); 681const float * k_t = (const float * ) ((const uint8_t * ) (uintptr_t )k -> data + 682 (uint64_t )ik3 * k -> nb [3 ]+ (uint64_t )t * k -> nb [2 ]+ (uint64_t )ik1 * k -> nb [1 ]); 683const float * v_t = (const float * ) ((const uint8_t * ) (uintptr_t )v -> data + 684 (uint64_t )iv3 * v -> nb [3 ]+ (uint64_t )t * v -> nb [2 ]+ (uint64_t )iv1 * v -> nb [1 ]); 685const float * g_t = (const float * ) ((const uint8_t * ) (uintptr_t )g -> data + 686 (uint64_t )iv3 * g -> nb [3 ]+ (uint64_t )t * g -> nb [2 ]+ (uint64_t )iv1 * g -> nb [1 ]); 687const float beta_val = * (const float * ) ((const uint8_t * ) (uintptr_t )beta -> data + 688 (uint64_t )iv3 * beta -> nb [3 ]+ (uint64_t )t * beta -> nb [2 ]+ (uint64_t )iv1 * beta -> nb [1 ]); 689 690hvx_copy_f32_au ((uint8_t * )local_q , (const uint8_t * )q_t ,S_v ); 691hvx_copy_f32_au ((uint8_t * )local_k , (const uint8_t * )k_t ,S_v ); 692 693if (kda ) { 694hvx_exp_f32 ((uint8_t * )local_gate , (const uint8_t * )g_t ,S_v , false); 695 696uint32_t j = 0 ; 697for (;j + 8 <=S_v ;j += 8 ) { 698float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 699float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 700float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 701float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 702float * row4 = s_work_curr + (uint64_t ) (j + 4 )* S_v ; 703float * row5 = s_work_curr + (uint64_t ) (j + 5 )* S_v ; 704float * row6 = s_work_curr + (uint64_t ) (j + 6 )* S_v ; 705float * row7 = s_work_curr + (uint64_t ) (j + 7 )* S_v ; 706gdn_mul_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 707local_gate ,local_k ,S_v ,local_sums ); 708 709float local_delta_b [32 ] __attribute__((aligned (128 ))); 710HVX_Vector vv_t = hvx_vmemu (v_t + j ); 711HVX_Vector v_local_sums = hvx_vmem (local_sums ); 712HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 713hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 714 715gdn_add_scaled_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 716local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 717 718HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 719hvx_vec_store_u (attn_data + j ,8 * sizeof (float ),res_attn ); 720 } 721for (;j + 4 <=S_v ;j += 4 ) { 722float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 723float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 724float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 725float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 726gdn_mul_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_gate ,local_k ,S_v ,local_sums ); 727 728float local_delta_b [32 ] __attribute__((aligned (128 ))); 729HVX_Vector vv_t = hvx_vmemu (v_t + j ); 730HVX_Vector v_local_sums = hvx_vmem (local_sums ); 731HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 732hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 733 734gdn_add_scaled_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 735 736HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 737hvx_vec_store_u (attn_data + j ,4 * sizeof (float ),res_attn ); 738 } 739HVX_Vector vscale_splat = hvx_vec_splat_f32 (scale ); 740for (;j < S_v ;++ j ) { 741float * row = s_work_curr + (uint64_t )j * S_v ; 742HVX_Vector vsum = gdn_mul_dot_f32 (row ,local_gate ,local_k ,S_v ); 743HVX_Vector vv_t = hvx_vec_splat_f32 (v_t [j ]); 744HVX_Vector vdj = hvx_vec_mul_f32_f32 (hvx_vec_sub_f32_f32 (vv_t ,vsum ),hvx_vec_splat_f32 (beta_val )); 745HVX_Vector vres = gdn_add_scaled_dot_f32 (row ,local_k ,vdj ,local_q ,S_v ); 746attn_data [j ]= hvx_vec_get_f32 (hvx_vec_mul_f32_f32 (vres ,vscale_splat )); 747 } 748 }else { 749const float gate = expf (g_t [0 ]); 750uint32_t j = 0 ; 751for (;j + 8 <=S_v ;j += 8 ) { 752float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 753float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 754float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 755float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 756float * row4 = s_work_curr + (uint64_t ) (j + 4 )* S_v ; 757float * row5 = s_work_curr + (uint64_t ) (j + 5 )* S_v ; 758float * row6 = s_work_curr + (uint64_t ) (j + 6 )* S_v ; 759float * row7 = s_work_curr + (uint64_t ) (j + 7 )* S_v ; 760gdn_mul_scalar_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 761gate ,local_k ,S_v ,local_sums ); 762 763float local_delta_b [32 ] __attribute__((aligned (128 ))); 764HVX_Vector vv_t = hvx_vmemu (v_t + j ); 765HVX_Vector v_local_sums = hvx_vmem (local_sums ); 766HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 767hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 768 769gdn_add_scaled_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 770local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 771 772HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 773hvx_vec_store_u (attn_data + j ,8 * sizeof (float ),res_attn ); 774 } 775for (;j + 4 <=S_v ;j += 4 ) { 776float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 777float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 778float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 779float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 780gdn_mul_scalar_dot4_f32 (row0 ,row1 ,row2 ,row3 ,gate ,local_k ,S_v ,local_sums ); 781 782float local_delta_b [32 ] __attribute__((aligned (128 ))); 783HVX_Vector vv_t = hvx_vmemu (v_t + j ); 784HVX_Vector v_local_sums = hvx_vmem (local_sums ); 785HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 786hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 787 788gdn_add_scaled_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 789 790HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 791hvx_vec_store_u (attn_data + j ,4 * sizeof (float ),res_attn ); 792 } 793HVX_Vector vscale_splat = hvx_vec_splat_f32 (scale ); 794for (;j < S_v ;++ j ) { 795float * row = s_work_curr + (uint64_t )j * S_v ; 796HVX_Vector vsum = gdn_mul_scalar_dot_f32 (row ,gate ,local_k ,S_v ); 797HVX_Vector vv_t = hvx_vec_splat_f32 (v_t [j ]); 798HVX_Vector vdj = hvx_vec_mul_f32_f32 (hvx_vec_sub_f32_f32 (vv_t ,vsum ),hvx_vec_splat_f32 (beta_val )); 799HVX_Vector vres = gdn_add_scaled_dot_f32 (row ,local_k ,vdj ,local_q ,S_v ); 800attn_data [j ]= hvx_vec_get_f32 (hvx_vec_mul_f32_f32 (vres ,vscale_splat )); 801 } 802 } 803 804if (K > 1 ) { 805// snapshot slot mapping: slot 0 = most recent state, slot s = s tokens back. 806const int64_t target_slot = (int64_t )n_tokens - 1 - (int64_t )t ; 807if (target_slot >=0 && target_slot < (int64_t )K ) { 808float * curr_state_o = state_out_base + (uint64_t )target_slot * state_size_per_snap + ((uint64_t )iv3 * H + iv1 )* S_v * S_v ; 809if (curr_state_o != s_out ) { 810hvx_copy_f32_uu ((uint8_t * )curr_state_o , (const uint8_t * )s_work_curr ,S_v * S_v ); 811 } 812 } 813 } 814 815attn_data += (uint64_t )S_v * H ; 816 } 817 818// Push real write-back 819dma_queue_push (dma ,dma_make_ptr (s_out ,s_work_curr ), 820S_v * sizeof (float ),S_v * sizeof (float ), 821S_v * sizeof (float ),S_v ); 822 823// Prefetch next block (if any) 824if (ir_prefetch < row_end ) { 825const uint32_t piv1 = fastmodulo (ir_prefetch ,H ,& fd_H ); 826const uint32_t piv3 = fastdiv (ir_prefetch ,& fd_H ); 827const float * ps_in = state_in_base + (uint64_t )piv3 * state_seq_stride + (uint64_t )piv1 * S_v * S_v ; 828 829dma_queue_push (dma ,dma_make_ptr (s_work [spad_idx ],ps_in ), 830S_v * sizeof (float ),S_v * sizeof (float ), 831S_v * sizeof (float ),S_v ); 832 833ir_prefetch += nth ; 834spad_idx ^=1 ; 835 } 836 837curr_spad_idx ^=1 ; 838 } 839dma_queue_flush (dma ); 840htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )row_end ); 841} 842 843 844static void gated_delta_net_f32_tg_thread (unsigned int nth ,unsigned int ith ,void * data ) { 845struct htp_gdn_context * gctx = (struct htp_gdn_context * )data ; 846struct htp_ops_context * octx = gctx -> octx ; 847 848const struct htp_tensor * q = octx -> src [0 ]; 849const struct htp_tensor * k = octx -> src [1 ]; 850const struct htp_tensor * v = octx -> src [2 ]; 851const struct htp_tensor * g = octx -> src [3 ]; 852const struct htp_tensor * beta = octx -> src [4 ]; 853const struct htp_tensor * state = octx -> src [5 ]; 854const struct htp_tensor * dst = octx -> dst ; 855 856const uint32_t S_v = v -> ne [0 ]; 857const uint32_t H = v -> ne [1 ]; 858const uint32_t n_seqs = v -> ne [3 ]; 859 860const uint32_t row_end = gctx -> row_start + gctx -> nrows ; 861 862if (ith >=gctx -> nrows ) { 863return ; 864 } 865 866const uint32_t rq3 = n_seqs /q -> ne [3 ]; 867const uint32_t rk3 = n_seqs /k -> ne [3 ]; 868const float scale = 1.0f /sqrtf ((float )S_v ); 869 870float * dst_base = (float * ) (uintptr_t )dst -> data ; 871float * state_out_base = dst_base + (uint64_t )S_v * H * n_seqs ; 872const float * state_in_base = (const float * ) (uintptr_t )state -> data ; 873 874const bool kda = (g -> ne [0 ]== S_v ); 875float local_gate [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 876float local_q [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 877float local_k [HTP_GDN_MAX_SV ] __attribute__((aligned (128 ))); 878float local_sums [32 ] __attribute__((aligned (128 ))); 879 880dma_queue * dma = octx -> ctx -> dma [ith ]; 881size_t state_aligned = (size_t )S_v * S_v * sizeof (float ); 882state_aligned = (state_aligned + 127 )& ~(size_t )127 ; 883float * s_work [2 ]; 884s_work [0 ]= (float * ) (gctx -> vtcm_base + gctx -> vtcm_per_thread * ith ); 885s_work [1 ]= s_work [0 ]+ state_aligned /sizeof (float ); 886 887struct fastdiv_values fd_H = init_fastdiv_values (H ); 888struct fastdiv_values fd_q1 = init_fastdiv_values (q -> ne [1 ]); 889struct fastdiv_values fd_k1 = init_fastdiv_values (k -> ne [1 ]); 890struct fastdiv_values fd_rq3 = init_fastdiv_values (rq3 ); 891struct fastdiv_values fd_rk3 = init_fastdiv_values (rk3 ); 892 893const uint64_t state_seq_stride = state -> nb [3 ] /sizeof (float ); 894 895uint32_t ir_prefetch = gctx -> row_start + ith ; 896int spad_idx = 0 ; 897 898// Prefetch preamble (up to 2 steps) 899for (int k = 0 ;k < 2 && ir_prefetch < row_end ;k ++ ) { 900const uint32_t piv1 = fastmodulo (ir_prefetch ,H ,& fd_H ); 901const uint32_t piv3 = fastdiv (ir_prefetch ,& fd_H ); 902const float * ps_in = state_in_base + (uint64_t )piv3 * state_seq_stride + (uint64_t )piv1 * S_v * S_v ; 903// final state lands in snapshot slot 0 (most-recent-first ordering) 904float * ps_out = state_out_base + ((uint64_t )piv3 * H + piv1 )* S_v * S_v ; 905 906// Push dummy write-back 907dma_queue_push (dma ,dma_make_ptr (ps_out ,s_work [spad_idx ]), 908S_v * sizeof (float ),S_v * sizeof (float ), 909S_v * sizeof (float ),0 ); 910 911// Push fetch 912dma_queue_push (dma ,dma_make_ptr (s_work [spad_idx ],ps_in ), 913S_v * sizeof (float ),S_v * sizeof (float ), 914S_v * sizeof (float ),S_v ); 915 916ir_prefetch += nth ; 917spad_idx ^=1 ; 918 } 919 920struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 921htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t ) (gctx -> row_start + ith )); 922 923int curr_spad_idx = 0 ; 924for (uint32_t ir = gctx -> row_start + ith ;ir < row_end ;ir += nth ) { 925dma_queue_pop (dma ); 926dma_queue_pop (dma ); 927 928float * s_work_curr = s_work [curr_spad_idx ]; 929 930const uint32_t iv1 = fastmodulo (ir ,H ,& fd_H ); 931const uint32_t iv3 = fastdiv (ir ,& fd_H ); 932 933const uint32_t iq1 = fastmodulo (iv1 ,q -> ne [1 ],& fd_q1 ); 934const uint32_t ik1 = fastmodulo (iv1 ,k -> ne [1 ],& fd_k1 ); 935const uint32_t iq3 = fastdiv (iv3 ,& fd_rq3 ); 936const uint32_t ik3 = fastdiv (iv3 ,& fd_rk3 ); 937 938// final state lands in snapshot slot 0 (most-recent-first ordering) 939float * s_out = state_out_base + ((uint64_t )iv3 * H + iv1 )* S_v * S_v ; 940 941float * attn_data = dst_base + ((uint64_t )iv3 * H + iv1 )* S_v ; 942 943const float * q_t = (const float * ) ((const uint8_t * ) (uintptr_t )q -> data + 944 (uint64_t )iq3 * q -> nb [3 ]+ (uint64_t )iq1 * q -> nb [1 ]); 945const float * k_t = (const float * ) ((const uint8_t * ) (uintptr_t )k -> data + 946 (uint64_t )ik3 * k -> nb [3 ]+ (uint64_t )ik1 * k -> nb [1 ]); 947const float * v_t = (const float * ) ((const uint8_t * ) (uintptr_t )v -> data + 948 (uint64_t )iv3 * v -> nb [3 ]+ (uint64_t )iv1 * v -> nb [1 ]); 949const float * g_t = (const float * ) ((const uint8_t * ) (uintptr_t )g -> data + 950 (uint64_t )iv3 * g -> nb [3 ]+ (uint64_t )iv1 * g -> nb [1 ]); 951const float beta_val = * (const float * ) ((const uint8_t * ) (uintptr_t )beta -> data + 952 (uint64_t )iv3 * beta -> nb [3 ]+ (uint64_t )iv1 * beta -> nb [1 ]); 953 954hvx_copy_f32_au ((uint8_t * )local_q , (const uint8_t * )q_t ,S_v ); 955hvx_copy_f32_au ((uint8_t * )local_k , (const uint8_t * )k_t ,S_v ); 956 957if (kda ) { 958hvx_exp_f32 ((uint8_t * )local_gate , (const uint8_t * )g_t ,S_v , false); 959 960uint32_t j = 0 ; 961for (;j + 8 <=S_v ;j += 8 ) { 962float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 963float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 964float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 965float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 966float * row4 = s_work_curr + (uint64_t ) (j + 4 )* S_v ; 967float * row5 = s_work_curr + (uint64_t ) (j + 5 )* S_v ; 968float * row6 = s_work_curr + (uint64_t ) (j + 6 )* S_v ; 969float * row7 = s_work_curr + (uint64_t ) (j + 7 )* S_v ; 970gdn_mul_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 971local_gate ,local_k ,S_v ,local_sums ); 972 973float local_delta_b [32 ] __attribute__((aligned (128 ))); 974HVX_Vector vv_t = hvx_vmemu (v_t + j ); 975HVX_Vector v_local_sums = hvx_vmem (local_sums ); 976HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 977hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 978 979gdn_add_scaled_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 980local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 981 982HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 983hvx_vec_store_u (attn_data + j ,8 * sizeof (float ),res_attn ); 984 } 985for (;j + 4 <=S_v ;j += 4 ) { 986float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 987float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 988float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 989float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 990gdn_mul_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_gate ,local_k ,S_v ,local_sums ); 991 992float local_delta_b [32 ] __attribute__((aligned (128 ))); 993HVX_Vector vv_t = hvx_vmemu (v_t + j ); 994HVX_Vector v_local_sums = hvx_vmem (local_sums ); 995HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 996hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 997 998gdn_add_scaled_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 999 1000HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 1001hvx_vec_store_u (attn_data + j ,4 * sizeof (float ),res_attn ); 1002 } 1003HVX_Vector vscale_splat = hvx_vec_splat_f32 (scale ); 1004for (;j < S_v ;++ j ) { 1005float * row = s_work_curr + (uint64_t )j * S_v ; 1006HVX_Vector vsum = gdn_mul_dot_f32 (row ,local_gate ,local_k ,S_v ); 1007HVX_Vector vv_t = hvx_vec_splat_f32 (v_t [j ]); 1008HVX_Vector vdj = hvx_vec_mul_f32_f32 (hvx_vec_sub_f32_f32 (vv_t ,vsum ),hvx_vec_splat_f32 (beta_val )); 1009HVX_Vector vres = gdn_add_scaled_dot_f32 (row ,local_k ,vdj ,local_q ,S_v ); 1010attn_data [j ]= hvx_vec_get_f32 (hvx_vec_mul_f32_f32 (vres ,vscale_splat )); 1011 } 1012 }else { 1013const float gate = expf (g_t [0 ]); 1014uint32_t j = 0 ; 1015for (;j + 8 <=S_v ;j += 8 ) { 1016float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 1017float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 1018float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 1019float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 1020float * row4 = s_work_curr + (uint64_t ) (j + 4 )* S_v ; 1021float * row5 = s_work_curr + (uint64_t ) (j + 5 )* S_v ; 1022float * row6 = s_work_curr + (uint64_t ) (j + 6 )* S_v ; 1023float * row7 = s_work_curr + (uint64_t ) (j + 7 )* S_v ; 1024gdn_mul_scalar_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 1025gate ,local_k ,S_v ,local_sums ); 1026 1027float local_delta_b [32 ] __attribute__((aligned (128 ))); 1028HVX_Vector vv_t = hvx_vmemu (v_t + j ); 1029HVX_Vector v_local_sums = hvx_vmem (local_sums ); 1030HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 1031hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 1032 1033gdn_add_scaled_dot8_f32 (row0 ,row1 ,row2 ,row3 ,row4 ,row5 ,row6 ,row7 , 1034local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 1035 1036HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 1037hvx_vec_store_u (attn_data + j ,8 * sizeof (float ),res_attn ); 1038 } 1039for (;j + 4 <=S_v ;j += 4 ) { 1040float * row0 = s_work_curr + (uint64_t ) (j + 0 )* S_v ; 1041float * row1 = s_work_curr + (uint64_t ) (j + 1 )* S_v ; 1042float * row2 = s_work_curr + (uint64_t ) (j + 2 )* S_v ; 1043float * row3 = s_work_curr + (uint64_t ) (j + 3 )* S_v ; 1044gdn_mul_scalar_dot4_f32 (row0 ,row1 ,row2 ,row3 ,gate ,local_k ,S_v ,local_sums ); 1045 1046float local_delta_b [32 ] __attribute__((aligned (128 ))); 1047HVX_Vector vv_t = hvx_vmemu (v_t + j ); 1048HVX_Vector v_local_sums = hvx_vmem (local_sums ); 1049HVX_Vector diff = hvx_vec_sub_f32_f32 (vv_t ,v_local_sums ); 1050hvx_vmem (local_delta_b )= hvx_vec_mul_f32_f32 (diff ,hvx_vec_splat_f32 (beta_val )); 1051 1052gdn_add_scaled_dot4_f32 (row0 ,row1 ,row2 ,row3 ,local_k ,local_delta_b ,local_q ,S_v ,local_sums ); 1053 1054HVX_Vector res_attn = hvx_vec_mul_f32_f32 (hvx_vmem (local_sums ),hvx_vec_splat_f32 (scale )); 1055hvx_vec_store_u (attn_data + j ,4 * sizeof (float ),res_attn ); 1056 } 1057HVX_Vector vscale_splat = hvx_vec_splat_f32 (scale ); 1058for (;j < S_v ;++ j ) { 1059float * row = s_work_curr + (uint64_t )j * S_v ; 1060HVX_Vector vsum = gdn_mul_scalar_dot_f32 (row ,gate ,local_k ,S_v ); 1061HVX_Vector vv_t = hvx_vec_splat_f32 (v_t [j ]); 1062HVX_Vector vdj = hvx_vec_mul_f32_f32 (hvx_vec_sub_f32_f32 (vv_t ,vsum ),hvx_vec_splat_f32 (beta_val )); 1063HVX_Vector vres = gdn_add_scaled_dot_f32 (row ,local_k ,vdj ,local_q ,S_v ); 1064attn_data [j ]= hvx_vec_get_f32 (hvx_vec_mul_f32_f32 (vres ,vscale_splat )); 1065 } 1066 } 1067 1068// Push real write-back 1069dma_queue_push (dma ,dma_make_ptr (s_out ,s_work_curr ), 1070S_v * sizeof (float ),S_v * sizeof (float ), 1071S_v * sizeof (float ),S_v ); 1072 1073// Prefetch next block (if any) 1074if (ir_prefetch < row_end ) { 1075const uint32_t piv1 = fastmodulo (ir_prefetch ,H ,& fd_H ); 1076const uint32_t piv3 = fastdiv (ir_prefetch ,& fd_H ); 1077const float * ps_in = state_in_base + (uint64_t )piv3 * state_seq_stride + (uint64_t )piv1 * S_v * S_v ; 1078 1079dma_queue_push (dma ,dma_make_ptr (s_work [spad_idx ],ps_in ), 1080S_v * sizeof (float ),S_v * sizeof (float ), 1081S_v * sizeof (float ),S_v ); 1082 1083ir_prefetch += nth ; 1084spad_idx ^=1 ; 1085 } 1086 1087curr_spad_idx ^=1 ; 1088 } 1089dma_queue_flush (dma ); 1090htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )row_end ); 1091} 1092 1093 1094int op_gated_delta_net (struct htp_ops_context * octx ) { 1095const struct htp_tensor * q = octx -> src [0 ]; 1096const struct htp_tensor * k = octx -> src [1 ]; 1097const struct htp_tensor * v = octx -> src [2 ]; 1098const struct htp_tensor * g = octx -> src [3 ]; 1099const struct htp_tensor * beta = octx -> src [4 ]; 1100const struct htp_tensor * state = octx -> src [5 ]; 1101const struct htp_tensor * dst = octx -> dst ; 1102 1103if (q -> type != HTP_TYPE_F32 || k -> type != HTP_TYPE_F32 || v -> type != HTP_TYPE_F32 || 1104g -> type != HTP_TYPE_F32 || beta -> type != HTP_TYPE_F32 || state -> type != HTP_TYPE_F32 || 1105dst -> type != HTP_TYPE_F32 ) { 1106return HTP_STATUS_NO_SUPPORT ; 1107 } 1108 1109const uint32_t S_v = v -> ne [0 ]; 1110const uint32_t H = v -> ne [1 ]; 1111const uint32_t n_tokens = v -> ne [2 ]; 1112const uint32_t n_seqs = v -> ne [3 ]; 1113const uint32_t K = octx -> op_params [0 ]; 1114 1115if (S_v == 0 || S_v > HTP_GDN_MAX_SV || H == 0 || n_tokens == 0 || n_seqs == 0 ) { 1116return HTP_STATUS_NO_SUPPORT ; 1117 } 1118if ((g -> ne [0 ]!= 1 && g -> ne [0 ]!= S_v )|| beta -> ne [0 ]!= 1 ) { 1119return HTP_STATUS_NO_SUPPORT ; 1120 } 1121if (q -> ne [0 ]!= S_v || k -> ne [0 ]!= S_v || q -> ne [1 ]== 0 || k -> ne [1 ]== 0 || 1122q -> ne [2 ]!= n_tokens || k -> ne [2 ]!= n_tokens || q -> ne [3 ]== 0 || k -> ne [3 ]== 0 || 1123 (n_seqs %q -> ne [3 ])!= 0 || (n_seqs %k -> ne [3 ])!= 0 ) { 1124return HTP_STATUS_NO_SUPPORT ; 1125 } 1126// state holds s0 only: [S_v, S_v, H, n_seqs] 1127if (state -> ne [0 ]!= S_v || state -> ne [1 ]!= S_v || state -> ne [2 ]!= H || state -> ne [3 ]!= n_seqs ) { 1128return HTP_STATUS_NO_SUPPORT ; 1129 } 1130if (dst -> ne [0 ]!= S_v * H || dst -> ne [1 ]!= n_tokens * n_seqs + S_v * n_seqs * K ) { 1131return HTP_STATUS_NO_SUPPORT ; 1132 } 1133 1134if (octx -> flags & HTP_OPFLAGS_SKIP_COMPUTE ) { 1135return HTP_STATUS_OK ; 1136 } 1137 1138const uint32_t total_rows = H * n_seqs ; 1139 1140uint32_t row_start = 0 ; 1141uint32_t nrows = total_rows ; 1142 1143if (octx -> ctx -> mdev .count > 1 ) { 1144const uint32_t head_bytes = S_v * sizeof (float ); 1145const uint32_t rows_per_chunk = (head_bytes > 0 ) ? (HEX_L2_LINE_SIZE /hex_gcd_u32 (head_bytes ,HEX_L2_LINE_SIZE )) :1 ; 1146const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (total_rows ,htp_tensor_mdev_data_aligned (dst ) ?rows_per_chunk :0 , 1147octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 1148row_start = range .start ; 1149nrows = range .count ; 1150 } 1151 1152if (nrows == 0 ) { 1153return HTP_STATUS_OK ; 1154 } 1155 1156const uint32_t n_threads = octx -> n_threads ; 1157 1158struct htp_gdn_context gctx ; 1159gctx .octx = octx ; 1160gctx .row_start = row_start ; 1161gctx .nrows = nrows ; 1162gctx .rows_per_thread = fastdiv (nrows + n_threads - 1 ,& octx -> n_threads_div ); 1163gctx .state_bytes = (size_t )S_v * S_v * sizeof (float ); 1164 1165size_t state_aligned = (size_t )S_v * S_v * sizeof (float ); 1166state_aligned = (state_aligned + 127 )& ~(size_t )127 ; 1167 1168assert (octx -> ctx -> vtcm_size >=2 * state_aligned * n_threads ); 1169 1170gctx .vtcm_base = octx -> ctx -> vtcm_base ; 1171gctx .vtcm_per_thread = 2 * state_aligned ; 1172 1173FARF (HIGH ,"gated-delta-net-f32: q(%ux%ux%ux%u) k(%ux%ux%ux%u) v(%ux%ux%ux%u) state(%ux%ux%ux%u) -> (%ux%ux%ux%u) : " 1174"vtcm-size %zu n_threads %u\n" , 1175q -> ne [0 ],q -> ne [1 ],q -> ne [2 ],q -> ne [3 ], 1176k -> ne [0 ],k -> ne [1 ],k -> ne [2 ],k -> ne [3 ], 1177v -> ne [0 ],v -> ne [1 ],v -> ne [2 ],v -> ne [3 ], 1178state -> ne [0 ],state -> ne [1 ],state -> ne [2 ],state -> ne [3 ], 1179dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 1180gctx .vtcm_per_thread * octx -> n_threads ,octx -> n_threads ); 1181 1182if (n_tokens == 1 ) { 1183work_queue_run (octx -> ctx -> work_queue ,gated_delta_net_f32_tg_thread ,& gctx ,n_threads ); 1184 }else { 1185work_queue_run (octx -> ctx -> work_queue ,gated_delta_net_f32_pp_thread ,& gctx ,n_threads ); 1186 } 1187 1188return HTP_STATUS_OK ; 1189}