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#include <HAP_perf.h> 7 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 "hex-common.h" 16#include "hex-profile.h" 17#include "htp-ctx.h" 18#include "htp-ops.h" 19#include "htp-tensor.h" 20 21/* Circular wrap: maps any integer x into [0, n) */ 22static inline uint32_t wrap_around (int32_t x ,uint32_t n ) { 23return (uint32_t )(((x % (int32_t )n )+ (int32_t )n ) % (int32_t )n ); 24} 25 26/* Decompose a flat dst row index into (i1, i2, i3) */ 27static inline void pad_decompose_row (uint32_t ir ,uint32_t ne1 ,uint32_t ne2 , 28uint32_t * i1 ,uint32_t * i2 ,uint32_t * i3 ) { 29* i1 = ir %ne1 ; 30* i2 = (ir /ne1 ) %ne2 ; 31* i3 = ir / (ne1 * ne2 ); 32} 33 34/* Return non-zero if row (i1,i2,i3) falls in the non-padded interior */ 35static inline int pad_is_interior (uint32_t i1 ,uint32_t i2 ,uint32_t i3 , 36int32_t lp1 ,int32_t rp1 ,uint32_t ne1 , 37int32_t lp2 ,int32_t rp2 ,uint32_t ne2 , 38int32_t lp3 ,int32_t rp3 ,uint32_t ne3 ) { 39return ((int32_t )i1 >=lp1 && (int32_t )i1 < (int32_t )ne1 - rp1 )&& 40 ((int32_t )i2 >=lp2 && (int32_t )i2 < (int32_t )ne2 - rp2 )&& 41 ((int32_t )i3 >=lp3 && (int32_t )i3 < (int32_t )ne3 - rp3 ); 42} 43 44/* Compute the DDR src row pointer for a zero-pad interior row */ 45static inline const uint8_t * pad_src_row_ptr (const struct htp_tensor * src , 46uint32_t i1 ,uint32_t i2 ,uint32_t i3 , 47int32_t lp1 ,int32_t lp2 ,int32_t lp3 ) { 48return (const uint8_t * )src -> data 49+ (i1 - (uint32_t )lp1 )* src -> nb [1 ] 50+ (i2 - (uint32_t )lp2 )* src -> nb [2 ] 51+ (i3 - (uint32_t )lp3 )* src -> nb [3 ]; 52} 53 54/* Compute the DDR src row pointer for a circular row (wrap-around indexing) */ 55static inline const uint8_t * pad_circ_src_row_ptr (const struct htp_tensor * src , 56uint32_t i1 ,uint32_t i2 ,uint32_t i3 , 57int32_t lp1 ,int32_t lp2 ,int32_t lp3 ) { 58return (const uint8_t * )src -> data 59+ wrap_around ((int32_t )i1 - lp1 ,src -> ne [1 ])* src -> nb [1 ] 60+ wrap_around ((int32_t )i2 - lp2 ,src -> ne [2 ])* src -> nb [2 ] 61+ wrap_around ((int32_t )i3 - lp3 ,src -> ne [3 ])* src -> nb [3 ]; 62} 63 64struct htp_pad_context { 65struct htp_ops_context * octx ; 66 67int32_t lp0 ,rp0 ; 68int32_t lp1 ,rp1 ; 69int32_t lp2 ,rp2 ; 70int32_t lp3 ,rp3 ; 71 72uint32_t nrows_per_thread ; 73uint32_t total_dst_rows ; 74uint32_t row_start ; 75 76size_t type_size ; 77 78// Row sizes for DMA kernel (populated when VTCM is available) 79size_t src_row_size ; 80size_t src_row_size_aligned ; 81size_t dst_row_size ; 82size_t dst_row_size_aligned ; 83}; 84 85#define htp_pad_preamble \ 86 const struct htp_tensor * src = octx->src[0]; \ 87 const struct htp_tensor * dst = octx->dst; \ 88 \ 89 const uint32_t ne00 = src->ne[0]; \ 90 const uint32_t nb00 = src->nb[0]; \ 91 \ 92 const uint32_t ne0 = dst->ne[0]; \ 93 const uint32_t ne1 = dst->ne[1]; \ 94 const uint32_t ne2 = dst->ne[2]; \ 95 const uint32_t ne3 = dst->ne[3]; \ 96 \ 97 const uint32_t nb1 = dst->nb[1]; \ 98 const uint32_t nb2 = dst->nb[2]; \ 99 const uint32_t nb3 = dst->nb[3]; \ 100 \ 101 const int32_t lp0 = pctx->lp0, rp0 = pctx->rp0; \ 102 const int32_t lp1 = pctx->lp1, rp1 = pctx->rp1; \ 103 const int32_t lp2 = pctx->lp2, rp2 = pctx->rp2; \ 104 const int32_t lp3 = pctx->lp3, rp3 = pctx->rp3; \ 105 \ 106 const size_t type_size = pctx->type_size; \ 107 \ 108 const uint32_t row_start = pctx->row_start + pctx->nrows_per_thread * ith; \ 109 const uint32_t row_end = MIN(row_start + pctx->nrows_per_thread, pctx->row_start + pctx->total_dst_rows); 110 111 112#define htp_pad_dma_preamble \ 113 const size_t src_row_size = pctx->src_row_size; \ 114 const size_t src_row_size_aligned = pctx->src_row_size_aligned; \ 115 const size_t dst_row_size = pctx->dst_row_size; \ 116 const size_t dst_row_size_aligned = pctx->dst_row_size_aligned; \ 117 \ 118 uint8_t * src_spad_base = octx->src0_spad.data + ith * octx->src0_spad.size_per_thread; \ 119 uint8_t * dst_spad_base = octx->dst_spad.data + ith * octx->dst_spad.size_per_thread; \ 120 \ 121 dma_queue * dma = octx->ctx->dma[ith]; 122 123// --------------------------------------------------------------------------- 124// HVX vectorized PAD kernel 125// --------------------------------------------------------------------------- 126 127static void pad_job_per_thread_hvx (unsigned int nth ,unsigned int ith ,void * data ) { 128const struct htp_pad_context * pctx = (const struct htp_pad_context * )data ; 129struct htp_ops_context * octx = pctx -> octx ; 130htp_pad_preamble ; 131 132struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 133htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP ,row_start ); 134 135for (uint32_t dst_row = row_start ;dst_row < row_end ;dst_row ++ ) { 136uint32_t i1 ,i2 ,i3 ; 137pad_decompose_row (dst_row ,ne1 ,ne2 ,& i1 ,& i2 ,& i3 ); 138 139uint8_t * dst_ptr = (uint8_t * )dst -> data + i1 * nb1 + i2 * nb2 + i3 * nb3 ; 140 141const int interior = pad_is_interior (i1 ,i2 ,i3 , 142lp1 ,rp1 ,ne1 , 143lp2 ,rp2 ,ne2 , 144lp3 ,rp3 ,ne3 ); 145 146if (!interior ) { 147hvx_splat_f32_u (dst_ptr ,0.0f ,ne0 ); 148 }else { 149const uint8_t * src_ptr = pad_src_row_ptr (src ,i1 ,i2 ,i3 ,lp1 ,lp2 ,lp3 ); 150 151if (lp0 > 0 ) { 152hvx_splat_f32_u (dst_ptr ,0.0f , (uint32_t )lp0 ); 153 } 154 155uint8_t * dst_row_start = dst_ptr + (size_t )lp0 * type_size ; 156if (nb00 == type_size ) { 157hvx_copy_f32_uu (dst_row_start ,src_ptr ,ne00 ); 158 }else { 159for (uint32_t i = 0 ;i < ne00 ;i ++ ) { 160memcpy (dst_row_start + i * type_size , 161src_ptr + (size_t )i * nb00 , 162type_size ); 163 } 164 } 165 166if (rp0 > 0 ) { 167hvx_splat_f32_u (dst_ptr + ((size_t )lp0 + ne00 )* type_size ,0.0f , (uint32_t )rp0 ); 168 } 169 } 170 } 171 172htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP ,row_start ); 173 174FARF (HIGH ,"pad-hvx %d/%d: (%ux%ux%ux%u) -> (%ux%ux%ux%u) rows %u:%u\n" , 175ith ,nth , 176src -> ne [0 ],src -> ne [1 ],src -> ne [2 ],src -> ne [3 ], 177dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 178row_start ,row_end ); 179} 180 181// --------------------------------------------------------------------------- 182// HVX + DMA PAD kernel - aligned, double-buffered 183// --------------------------------------------------------------------------- 184 185static void pad_job_per_thread_hvx_dma (unsigned int nth ,unsigned int ith ,void * data ) { 186const struct htp_pad_context * pctx = (const struct htp_pad_context * )data ; 187struct htp_ops_context * octx = pctx -> octx ; 188htp_pad_preamble ; 189htp_pad_dma_preamble ; 190 191// ----------------------------------------------------------------------- 192// Priming phase: push 2 pairs of (dummy_dst_DMA, src_DMA) to seed the 193// double-buffer pipeline before the main loop begins. 194// ----------------------------------------------------------------------- 195for (uint32_t ir = row_start ,spad_idx = 0 ;ir < row_end && spad_idx < 2 ;ir ++ ,spad_idx ++ ) { 196uint8_t * src_spad_cur = src_spad_base + spad_idx * src_row_size_aligned ; 197uint8_t * dst_spad_cur = dst_spad_base + spad_idx * dst_row_size_aligned ; 198 199dma_queue_push_vtcm_to_ddr (dma , 200dma_make_ptr ((uint8_t * )dst -> data ,dst_spad_cur ), 201dst_row_size ,dst_row_size_aligned ,0 ); 202 203uint32_t i1 ,i2 ,i3 ; 204pad_decompose_row (ir ,ne1 ,ne2 ,& i1 ,& i2 ,& i3 ); 205const int interior = pad_is_interior (i1 ,i2 ,i3 , 206lp1 ,rp1 ,ne1 , 207lp2 ,rp2 ,ne2 , 208lp3 ,rp3 ,ne3 ); 209 210const uint8_t * src_ptr = interior 211 ?pad_src_row_ptr (src ,i1 ,i2 ,i3 ,lp1 ,lp2 ,lp3 ) :NULL ; 212 213// Interior row: real DMA (1 row) from DDR to VTCM. 214// Border row: null DMA (nrows=0) 215dma_queue_push_ddr_to_vtcm (dma , 216dma_make_ptr (src_spad_cur , 217src_ptr ?src_ptr : (const uint8_t * )src_spad_cur ), 218src_row_size_aligned ,src_row_size ,src_ptr ?1 :0 ); 219 } 220 221// ----------------------------------------------------------------------- 222// Main loop: pop completed DMAs, compute in VTCM with aligned HVX ops, 223// push dst DMA and prefetch src for the next+1 row. 224// ----------------------------------------------------------------------- 225struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 226 227for (uint32_t ir = row_start ;ir < row_end ;ir ++ ) { 228uint8_t * dst_spad_cur = (uint8_t * )dma_queue_pop (dma ).src ; 229uint8_t * src_spad_cur = (uint8_t * )dma_queue_pop (dma ).dst ; 230 231uint32_t i1 ,i2 ,i3 ; 232pad_decompose_row (ir ,ne1 ,ne2 ,& i1 ,& i2 ,& i3 ); 233 234uint8_t * dst_ptr = (uint8_t * )dst -> data + i1 * nb1 + i2 * nb2 + i3 * nb3 ; 235 236const int interior = pad_is_interior (i1 ,i2 ,i3 , 237lp1 ,rp1 ,ne1 , 238lp2 ,rp2 ,ne2 , 239lp3 ,rp3 ,ne3 ); 240 241htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 242if (!interior ) { 243hvx_splat_f32_a (dst_spad_cur ,0.0f ,ne0 ); 244 }else { 245hvx_splat_f32_a (dst_spad_cur ,0.0f ,ne0 ); 246 247uint8_t * dst_interior = dst_spad_cur + (size_t )lp0 * type_size ; 248 249if ((uintptr_t )dst_interior %VLEN == 0 ) { 250hvx_copy_f32_aa (dst_interior ,src_spad_cur ,ne00 ); 251 }else { 252hvx_copy_f32_ua (dst_interior ,src_spad_cur ,ne00 ); 253 } 254 } 255htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 256 257dma_queue_push_vtcm_to_ddr (dma , 258dma_make_ptr (dst_ptr ,dst_spad_cur ), 259dst_row_size ,dst_row_size_aligned ,1 ); 260 261const uint32_t next_row = ir + 2 ; 262if (next_row < row_end ) { 263uint32_t ni1 ,ni2 ,ni3 ; 264pad_decompose_row (next_row ,ne1 ,ne2 ,& ni1 ,& ni2 ,& ni3 ); 265const int next_interior = pad_is_interior (ni1 ,ni2 ,ni3 , 266lp1 ,rp1 ,ne1 , 267lp2 ,rp2 ,ne2 , 268lp3 ,rp3 ,ne3 ); 269const uint8_t * next_src_ptr = next_interior 270 ?pad_src_row_ptr (src ,ni1 ,ni2 ,ni3 ,lp1 ,lp2 ,lp3 ) :NULL ; 271 272dma_queue_push_ddr_to_vtcm (dma , 273dma_make_ptr (src_spad_cur , 274next_src_ptr ?next_src_ptr : (const uint8_t * )src_spad_cur ), 275src_row_size_aligned ,src_row_size ,next_src_ptr ?1 :0 ); 276 } 277 } 278 279dma_queue_flush (dma ); 280 281FARF (HIGH ,"pad-hvx-dma %d/%d: (%ux%ux%ux%u) -> (%ux%ux%ux%u) rows %u:%u\n" , 282ith ,nth , 283src -> ne [0 ],src -> ne [1 ],src -> ne [2 ],src -> ne [3 ], 284dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 285row_start ,row_end ); 286} 287 288// --------------------------------------------------------------------------- 289// HVX circular PAD kernel 290// --------------------------------------------------------------------------- 291 292static void pad_job_per_thread_hvx_circular (unsigned int nth ,unsigned int ith ,void * data ) { 293const struct htp_pad_context * pctx = (const struct htp_pad_context * )data ; 294struct htp_ops_context * octx = pctx -> octx ; 295htp_pad_preamble ; 296 297struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 298htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP ,row_start ); 299 300for (uint32_t dst_row = row_start ;dst_row < row_end ;dst_row ++ ) { 301uint32_t i1 ,i2 ,i3 ; 302pad_decompose_row (dst_row ,ne1 ,ne2 ,& i1 ,& i2 ,& i3 ); 303 304uint8_t * dst_ptr = (uint8_t * )dst -> data + i1 * nb1 + i2 * nb2 + i3 * nb3 ; 305const uint8_t * src_row = pad_circ_src_row_ptr (src ,i1 ,i2 ,i3 ,lp1 ,lp2 ,lp3 ); 306 307if (nb00 == type_size ) { 308 309if (lp0 > 0 ) { 310if ((uint32_t )lp0 < 32 ) { 311memcpy (dst_ptr , 312src_row + (size_t )(ne00 - (uint32_t )lp0 )* type_size , 313 (size_t )lp0 * type_size ); 314 }else { 315hvx_copy_f32_uu (dst_ptr , 316src_row + (size_t )(ne00 - (uint32_t )lp0 )* type_size , 317 (uint32_t )lp0 ); 318 } 319 } 320hvx_copy_f32_uu (dst_ptr + (size_t )lp0 * type_size ,src_row ,ne00 ); 321if (rp0 > 0 ) { 322if ((uint32_t )rp0 < 32 ) { 323memcpy (dst_ptr + ((size_t )lp0 + ne00 )* type_size , 324src_row , 325 (size_t )rp0 * type_size ); 326 }else { 327hvx_copy_f32_uu (dst_ptr + ((size_t )lp0 + ne00 )* type_size , 328src_row , 329 (uint32_t )rp0 ); 330 } 331 } 332 }else { 333for (uint32_t i = 0 ;i < (uint32_t )lp0 ;i ++ ) { 334* (float * )(dst_ptr + i * type_size )= 335* (const float * )(src_row + (size_t )(ne00 - (uint32_t )lp0 + i )* nb00 ); 336 } 337for (uint32_t i = 0 ;i < ne00 ;i ++ ) { 338* (float * )(dst_ptr + ((size_t )lp0 + i )* type_size )= 339* (const float * )(src_row + (size_t )i * nb00 ); 340 } 341for (uint32_t i = 0 ;i < (uint32_t )rp0 ;i ++ ) { 342* (float * )(dst_ptr + ((size_t )lp0 + ne00 + i )* type_size )= 343* (const float * )(src_row + (size_t )i * nb00 ); 344 } 345 } 346 } 347 348htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP ,row_start ); 349 350FARF (HIGH ,"pad-hvx-circ %d/%d: (%ux%ux%ux%u) -> (%ux%ux%ux%u) rows %u:%u\n" , 351ith ,nth , 352src -> ne [0 ],src -> ne [1 ],src -> ne [2 ],src -> ne [3 ], 353dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 354row_start ,row_end ); 355} 356 357// --------------------------------------------------------------------------- 358// HVX + DMA circular PAD kernel - aligned, double-buffered 359// --------------------------------------------------------------------------- 360 361static void pad_job_per_thread_hvx_circular_dma (unsigned int nth ,unsigned int ith ,void * data ) { 362const struct htp_pad_context * pctx = (const struct htp_pad_context * )data ; 363struct htp_ops_context * octx = pctx -> octx ; 364htp_pad_preamble ; 365htp_pad_dma_preamble ; 366 367// ----------------------------------------------------------------------- 368// Priming phase: push 2 pairs of (dummy_dst_DMA, src_DMA) to seed the 369// double-buffer pipeline. Every row is a real src DMA (no null DMAs). 370// ----------------------------------------------------------------------- 371for (uint32_t ir = row_start ,spad_idx = 0 ;ir < row_end && spad_idx < 2 ;ir ++ ,spad_idx ++ ) { 372uint8_t * src_spad_cur = src_spad_base + spad_idx * src_row_size_aligned ; 373uint8_t * dst_spad_cur = dst_spad_base + spad_idx * dst_row_size_aligned ; 374 375dma_queue_push_vtcm_to_ddr (dma , 376dma_make_ptr ((uint8_t * )dst -> data ,dst_spad_cur ), 377dst_row_size ,dst_row_size_aligned ,0 ); 378 379uint32_t pi1 ,pi2 ,pi3 ; 380pad_decompose_row (ir ,ne1 ,ne2 ,& pi1 ,& pi2 ,& pi3 ); 381dma_queue_push_ddr_to_vtcm (dma , 382dma_make_ptr (src_spad_cur ,pad_circ_src_row_ptr (src ,pi1 ,pi2 ,pi3 ,lp1 ,lp2 ,lp3 )), 383src_row_size_aligned ,src_row_size ,1 ); 384 } 385 386// ----------------------------------------------------------------------- 387// Main loop: pop completed DMAs, assemble circular row in VTCM with 388// aligned HVX ops, push dst DMA and prefetch src for the next+1 row. 389// ----------------------------------------------------------------------- 390struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 391 392for (uint32_t ir = row_start ;ir < row_end ;ir ++ ) { 393uint8_t * dst_spad_cur = (uint8_t * )dma_queue_pop (dma ).src ; 394uint8_t * src_spad_cur = (uint8_t * )dma_queue_pop (dma ).dst ; 395 396uint32_t i1 ,i2 ,i3 ; 397pad_decompose_row (ir ,ne1 ,ne2 ,& i1 ,& i2 ,& i3 ); 398uint8_t * dst_ptr = (uint8_t * )dst -> data + i1 * nb1 + i2 * nb2 + i3 * nb3 ; 399 400htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 401if (lp0 > 0 ) { 402uint8_t * dst_left = dst_spad_cur ; 403const uint8_t * src_left = src_spad_cur + (size_t )(ne00 - (uint32_t )lp0 )* type_size ; 404if ((uint32_t )lp0 < 32 ) { 405memcpy (dst_left ,src_left , (size_t )lp0 * type_size ); 406 }else { 407hvx_copy_f32_uu (dst_left ,src_left , (uint32_t )lp0 ); 408 } 409 } 410 411 { 412uint8_t * dst_mid = dst_spad_cur + (size_t )lp0 * type_size ; 413if ((uintptr_t )dst_mid %VLEN == 0 ) { 414hvx_copy_f32_aa (dst_mid ,src_spad_cur ,ne00 ); 415 }else { 416hvx_copy_f32_ua (dst_mid ,src_spad_cur ,ne00 ); 417 } 418 } 419 420if (rp0 > 0 ) { 421uint8_t * dst_right = dst_spad_cur + ((size_t )lp0 + ne00 )* type_size ; 422if ((uint32_t )rp0 < 32 ) { 423memcpy (dst_right ,src_spad_cur , (size_t )rp0 * type_size ); 424 }else { 425if ((uintptr_t )dst_right %VLEN == 0 ) { 426hvx_copy_f32_aa (dst_right ,src_spad_cur , (uint32_t )rp0 ); 427 }else { 428hvx_copy_f32_ua (dst_right ,src_spad_cur , (uint32_t )rp0 ); 429 } 430 } 431 } 432htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 433 434dma_queue_push_vtcm_to_ddr (dma , 435dma_make_ptr (dst_ptr ,dst_spad_cur ), 436dst_row_size ,dst_row_size_aligned ,1 ); 437 438const uint32_t next_row = ir + 2 ; 439if (next_row < row_end ) { 440uint32_t nri1 ,nri2 ,nri3 ; 441pad_decompose_row (next_row ,ne1 ,ne2 ,& nri1 ,& nri2 ,& nri3 ); 442dma_queue_push_ddr_to_vtcm (dma , 443dma_make_ptr (src_spad_cur , 444pad_circ_src_row_ptr (src ,nri1 ,nri2 ,nri3 ,lp1 ,lp2 ,lp3 )), 445src_row_size_aligned ,src_row_size ,1 ); 446 } 447 } 448 449dma_queue_flush (dma ); 450 451FARF (HIGH ,"pad-hvx-circ-dma %d/%d: (%ux%ux%ux%u) -> (%ux%ux%ux%u) rows %u:%u\n" , 452ith ,nth , 453src -> ne [0 ],src -> ne [1 ],src -> ne [2 ],src -> ne [3 ], 454dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 455row_start ,row_end ); 456} 457 458int op_pad (struct htp_ops_context * octx ) { 459const struct htp_tensor * src0 = octx -> src [0 ]; 460const struct htp_tensor * dst = octx -> dst ; 461 462// Only F32 supported 463size_t type_size ; 464switch (src0 -> type ) { 465case HTP_TYPE_F32 :type_size = 4 ;break ; 466default : 467FARF (ERROR ,"pad-hvx: unsupported type %u\n" ,src0 -> type ); 468return HTP_STATUS_NO_SUPPORT ; 469 } 470 471if (octx -> flags & HTP_OPFLAGS_SKIP_COMPUTE ) { 472return HTP_STATUS_OK ; 473 } 474 475const int32_t lp0 = octx -> op_params [0 ]; 476const int32_t rp0 = octx -> op_params [1 ]; 477const int32_t lp1 = octx -> op_params [2 ]; 478const int32_t rp1 = octx -> op_params [3 ]; 479const int32_t lp2 = octx -> op_params [4 ]; 480const int32_t rp2 = octx -> op_params [5 ]; 481const int32_t lp3 = octx -> op_params [6 ]; 482const int32_t rp3 = octx -> op_params [7 ]; 483const int32_t circular = octx -> op_params [8 ]; 484 485const uint32_t ne0 = dst -> ne [0 ]; 486const uint32_t ne00 = src0 -> ne [0 ]; 487 488const uint32_t total_dst_rows = dst -> ne [1 ]* dst -> ne [2 ]* dst -> ne [3 ]; 489const size_t dst_row_size = (size_t )ne0 * type_size ; 490 491uint32_t row_start = 0 ; 492uint32_t nrows = total_dst_rows ; 493 494if (octx -> ctx -> mdev .count > 1 ) { 495uint32_t rows_per_chunk = 0 ; 496htp_tensor_mdev_rows_per_chunk (dst ,type_size , (uint32_t )dst_row_size ,& rows_per_chunk ); 497const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (total_dst_rows ,rows_per_chunk ,octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 498row_start = range .start ; 499nrows = range .count ; 500 } 501 502if (nrows == 0 ) { 503return HTP_STATUS_OK ; 504 } 505 506const uint32_t n_threads = octx -> n_threads ; 507 508const size_t src_row_size = (size_t )ne00 * type_size ; 509const size_t src_row_size_aligned = hex_round_up (src_row_size ,VLEN ); 510const size_t dst_row_size_aligned = hex_round_up (dst_row_size ,VLEN ); 511 512// Total VTCM needed: 2 buffers (ping+pong) for src and dst, per thread 513const size_t vtcm_needed = (size_t )n_threads * 2 * (src_row_size_aligned + dst_row_size_aligned ); 514 515const int use_dma = (src0 -> nb [0 ]== (uint32_t )type_size )&& (ne00 >=512 )&& 516 (octx -> ctx -> vtcm_size >=vtcm_needed ); 517 518if (use_dma ) { 519octx -> src0_spad .size_per_thread = 2 * src_row_size_aligned ; 520octx -> dst_spad .size_per_thread = 2 * dst_row_size_aligned ; 521octx -> src0_spad .size = n_threads * octx -> src0_spad .size_per_thread ; 522octx -> dst_spad .size = n_threads * octx -> dst_spad .size_per_thread ; 523octx -> src0_spad .data = octx -> ctx -> vtcm_base ; 524octx -> dst_spad .data = octx -> src0_spad .data + octx -> src0_spad .size ; 525octx -> src0_spad .src = NULL ; 526octx -> dst_spad .src = NULL ; 527 } 528 529struct htp_pad_context pctx = { 530 .octx = octx , 531 .lp0 = lp0 , .rp0 = rp0 , 532 .lp1 = lp1 , .rp1 = rp1 , 533 .lp2 = lp2 , .rp2 = rp2 , 534 .lp3 = lp3 , .rp3 = rp3 , 535 .nrows_per_thread = fastdiv (nrows + n_threads - 1 ,& octx -> n_threads_div ), 536 .total_dst_rows = nrows , 537 .row_start = row_start , 538 .type_size = type_size , 539 .src_row_size = src_row_size , 540 .src_row_size_aligned = src_row_size_aligned , 541 .dst_row_size = dst_row_size , 542 .dst_row_size_aligned = dst_row_size_aligned , 543 }; 544 545FARF (HIGH ,"pad-hvx%s%s: (%ux%ux%ux%u) -> (%ux%ux%ux%u) pads=(%d,%d,%d,%d,%d,%d,%d,%d)\n" , 546circular ?"-circ" :"" , 547use_dma ?"-dma" :"" , 548src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ], 549dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ], 550lp0 ,rp0 ,lp1 ,rp1 ,lp2 ,rp2 ,lp3 ,rp3 ); 551 552if (circular && use_dma ) {work_queue_run (octx -> ctx -> work_queue ,pad_job_per_thread_hvx_circular_dma ,& pctx ,n_threads ); } 553else if (circular ) {work_queue_run (octx -> ctx -> work_queue ,pad_job_per_thread_hvx_circular ,& pctx ,n_threads ); } 554else if (use_dma ) {work_queue_run (octx -> ctx -> work_queue ,pad_job_per_thread_hvx_dma ,& pctx ,n_threads ); } 555else {work_queue_run (octx -> ctx -> work_queue ,pad_job_per_thread_hvx ,& pctx ,n_threads ); } 556 557return HTP_STATUS_OK ; 558}