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#define GGML_COMMON_DECL_C 9#include "ggml-common.h" 10#include "hex-common.h" 11#include "hex-profile.h" 12#include "htp-ctx.h" 13#include "htp-ops.h" 14#include "htp-tensor.h" 15#include "hvx-types.h" 16#include "hvx-utils.h" 17#include "hex-dma.h" 18 19#define htp_cumsum_tensors_preamble \ 20 const struct htp_tensor * restrict src0 = octx->src[0]; \ 21 const struct htp_tensor * restrict dst = octx->dst; \ 22 \ 23 const uint32_t ne00 = src0->ne[0]; \ 24 const uint32_t ne01 = src0->ne[1]; \ 25 const uint32_t ne02 = src0->ne[2]; \ 26 const uint32_t ne03 = src0->ne[3]; \ 27 \ 28 const uint32_t ne0 = dst->ne[0]; \ 29 const uint32_t ne1 = dst->ne[1]; \ 30 const uint32_t ne2 = dst->ne[2]; \ 31 const uint32_t ne3 = dst->ne[3]; \ 32 \ 33 const uint32_t nb00 = src0->nb[0]; \ 34 const uint32_t nb01 = src0->nb[1]; \ 35 const uint32_t nb02 = src0->nb[2]; \ 36 const uint32_t nb03 = src0->nb[3]; \ 37 \ 38 const uint32_t nb0 = dst->nb[0]; \ 39 const uint32_t nb1 = dst->nb[1]; \ 40 const uint32_t nb2 = dst->nb[2]; \ 41 const uint32_t nb3 = dst->nb[3]; 42 43struct htp_cumsum_context { 44struct htp_ops_context * octx ; 45size_t src_row_size ; 46size_t dst_row_size ; 47size_t src_row_size_aligned ; 48size_t dst_row_size_aligned ; 49uint32_t rows_per_thread ; 50uint32_t total_rows ; 51uint32_t row_start ; 52}; 53 54#define htp_cumsum_preamble \ 55 struct htp_cumsum_context * cctx = (struct htp_cumsum_context *) data; \ 56 struct htp_ops_context * octx = cctx->octx; \ 57 htp_cumsum_tensors_preamble; \ 58 dma_queue * dma_queue = octx->ctx->dma[ith]; 59 60// --------------------------------------------------------------------------- 61// HVX prefix scan helpers 62// --------------------------------------------------------------------------- 63 64#if __HVX_ARCH__ > 75 65static inline HVX_Vector hvx_cumsum_vadd (HVX_Vector a ,HVX_Vector b ) { 66return Q6_Vsf_vadd_VsfVsf (a ,b ); 67} 68#else 69static inline HVX_Vector hvx_cumsum_vadd (HVX_Vector a ,HVX_Vector b ) { 70return Q6_Vsf_equals_Vqf32 (Q6_Vqf32_vadd_VsfVsf (a ,b )); 71} 72#endif // __HVX_ARCH__ > 75 73 74static inline HVX_Vector hvx_prefix_scan_f32 (HVX_Vector v ,HVX_Vector carry_in ) { 75const HVX_Vector zero = Q6_V_vsplat_R (0 ); 76 77v = hvx_cumsum_vadd (v ,Q6_V_vlalign_VVR (v ,zero ,4 )); 78v = hvx_cumsum_vadd (v ,Q6_V_vlalign_VVR (v ,zero ,8 )); 79v = hvx_cumsum_vadd (v ,Q6_V_vlalign_VVR (v ,zero ,16 )); 80v = hvx_cumsum_vadd (v ,Q6_V_vlalign_VVR (v ,zero ,32 )); 81v = hvx_cumsum_vadd (v ,Q6_V_vlalign_VVR (v ,zero ,64 )); 82v = hvx_cumsum_vadd (v ,carry_in ); 83 84return v ; 85} 86 87static inline HVX_Vector hvx_splat_last_f32 (HVX_Vector v ) { 88return hvx_vec_repl4 (Q6_V_vror_VR (v ,124 )); 89} 90 91static inline void hvx_cumsum_row_f32 (const float * restrictsrc ,float * restrictdst ,uint32_t n ) { 92const uint32_t nvec = n /VLEN_FP32 ; 93const uint32_t nloe = n %VLEN_FP32 ; 94 95HVX_Vector carry = Q6_V_vsplat_R (0 ); 96 97for (uint32_t i = 0 ;i < nvec ;i ++ ) { 98HVX_Vector v = * ((const HVX_UVector * ) (src + i * VLEN_FP32 )); 99v = hvx_prefix_scan_f32 (v ,carry ); 100hvx_vec_store_u (dst + i * VLEN_FP32 ,VLEN ,v ); 101carry = hvx_splat_last_f32 (v ); 102 } 103 104if (nloe ) { 105float acc = hvx_vec_get_f32 (carry ); 106const float * src_tail = src + nvec * VLEN_FP32 ; 107float * dst_tail = dst + nvec * VLEN_FP32 ; 108for (uint32_t i = 0 ;i < nloe ;i ++ ) { 109acc += src_tail [i ]; 110dst_tail [i ]= acc ; 111 } 112 } 113} 114 115// --------------------------------------------------------------------------- 116// Per thread worker: Double-buffered DMA 117// --------------------------------------------------------------------------- 118 119static void cumsum_thread_f32_dma (unsigned int nth ,unsigned int ith ,void * data ) { 120htp_cumsum_preamble ; 121 122const uint32_t ir0 = cctx -> row_start + cctx -> rows_per_thread * ith ; 123const uint32_t ir1 = MIN (ir0 + cctx -> rows_per_thread ,cctx -> row_start + cctx -> total_rows ); 124 125if (ir0 >=ir1 ) { 126return ; 127 } 128 129const size_t src_row_size = cctx -> src_row_size ; 130const size_t dst_row_size = cctx -> dst_row_size ; 131const size_t src_row_size_aligned = cctx -> src_row_size_aligned ; 132const size_t dst_row_size_aligned = cctx -> dst_row_size_aligned ; 133 134const uint8_t * src_data = (const uint8_t * )src0 -> data ; 135uint8_t * dst_data = (uint8_t * )dst -> data ; 136 137uint8_t * src_spad = octx -> src0_spad .data + (ith * src_row_size_aligned * 2 ); 138uint8_t * dst_spad = octx -> dst_spad .data + (ith * dst_row_size_aligned * 2 ); 139 140for (uint32_t ir = ir0 ,spad_idx = 0 ;ir < ir1 && spad_idx < 2 ;ir ++ ,spad_idx ++ ) { 141// Dummy dst writeback to establish queue ordering 142dma_queue_push_vtcm_to_ddr (dma_queue , 143dma_make_ptr (dst_data ,dst_spad + (spad_idx * dst_row_size_aligned )), 144dst_row_size ,dst_row_size_aligned ,0 ); 145 146dma_queue_push_ddr_to_vtcm (dma_queue , 147dma_make_ptr (src_spad + (spad_idx * src_row_size_aligned ), 148src_data + (ir * src_row_size )), 149src_row_size_aligned ,src_row_size ,1 ); 150 } 151 152struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 153 154for (uint32_t ir = ir0 ;ir < ir1 ;ir ++ ) { 155float * dst_spad_row = (float * )dma_queue_pop (dma_queue ).src ; 156float * src_spad_row = (float * )dma_queue_pop (dma_queue ).dst ; 157 158htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 159hvx_cumsum_row_f32 (src_spad_row ,dst_spad_row ,ne00 ); 160htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir ); 161 162dma_queue_push_vtcm_to_ddr (dma_queue , 163dma_make_ptr (dst_data + (ir * dst_row_size ), (uint8_t * )dst_spad_row ), 164dst_row_size ,dst_row_size_aligned ,1 ); 165 166const uint32_t next_row = ir + 2 ; 167if (next_row < ir1 ) { 168dma_queue_push_ddr_to_vtcm (dma_queue , 169dma_make_ptr ((uint8_t * )src_spad_row ,src_data + (next_row * src_row_size )), 170src_row_size_aligned ,src_row_size ,1 ); 171 } 172 } 173 174dma_queue_flush (dma_queue ); 175 176FARF (HIGH ,"cumsum-f32-dma %d/%d: %ux%ux%ux%u (%u:%u) -> %ux%ux%ux%u\n" , 177ith ,nth ,src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ],ir0 ,ir1 , 178dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ]); 179} 180 181// --------------------------------------------------------------------------- 182// Per thread worker: Direct HVX (no DMA) 183// --------------------------------------------------------------------------- 184 185static void cumsum_thread_f32 (unsigned int nth ,unsigned int ith ,void * data ) { 186htp_cumsum_preamble ; 187 188const uint8_t * src_data = (const uint8_t * )src0 -> data ; 189uint8_t * dst_data = (uint8_t * )dst -> data ; 190 191const uint32_t ir0 = cctx -> row_start + cctx -> rows_per_thread * ith ; 192const uint32_t ir1 = MIN (ir0 + cctx -> rows_per_thread ,cctx -> row_start + cctx -> total_rows ); 193 194struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 195htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir0 ); 196 197for (uint32_t ir = ir0 ;ir < ir1 ;ir ++ ) { 198const float * restrictsrc_row = (const float * ) (src_data + ir * cctx -> src_row_size ); 199float * restrictdst_row = (float * ) (dst_data + ir * cctx -> dst_row_size ); 200hvx_cumsum_row_f32 (src_row ,dst_row ,ne00 ); 201 } 202 203htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )ir0 ); 204 205FARF (HIGH ,"cumsum-f32 %d/%d: %ux%ux%ux%u (%u:%u) -> %ux%ux%ux%u\n" , 206ith ,nth ,src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ],ir0 ,ir1 , 207dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ]); 208} 209 210int op_cumsum_f32 (struct htp_ops_context * octx ) { 211const struct htp_tensor * src0 = octx -> src [0 ]; 212const struct htp_tensor * dst = octx -> dst ; 213 214if (octx -> flags & HTP_OPFLAGS_SKIP_COMPUTE ) { 215return HTP_STATUS_OK ; 216 } 217 218const uint32_t total_rows = src0 -> ne [1 ]* src0 -> ne [2 ]* src0 -> ne [3 ]; 219const size_t dst_data_row_size = dst -> ne [0 ]* sizeof (float ); 220 221uint32_t row_start = 0 ; 222uint32_t nrows = total_rows ; 223 224if (octx -> ctx -> mdev .count > 1 ) { 225uint32_t rows_per_chunk = 0 ; 226htp_tensor_mdev_rows_per_chunk (dst ,sizeof (float ), (uint32_t )dst_data_row_size ,& rows_per_chunk ); 227const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (total_rows ,rows_per_chunk ,octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 228row_start = range .start ; 229nrows = range .count ; 230 } 231 232if (nrows == 0 ) { 233return HTP_STATUS_OK ; 234 } 235 236const uint32_t n_threads = octx -> n_threads ; 237 238const size_t src_row_size = src0 -> nb [1 ]; 239const size_t dst_row_size = dst -> nb [1 ]; 240const size_t src_row_size_aligned = hex_round_up (src_row_size ,VLEN ); 241const size_t dst_row_size_aligned = hex_round_up (dst_row_size ,VLEN ); 242 243// 2 ping-pong buffers per thread for src and dst 244const size_t spad_per_thread = 2 * (src_row_size_aligned + dst_row_size_aligned ); 245 246octx -> src0_spad .size_per_thread = src_row_size_aligned * 2 ; 247octx -> dst_spad .size_per_thread = dst_row_size_aligned * 2 ; 248 249octx -> src0_spad .size = n_threads * octx -> src0_spad .size_per_thread ; 250octx -> dst_spad .size = n_threads * octx -> dst_spad .size_per_thread ; 251 252octx -> src0_spad .data = octx -> ctx -> vtcm_base ;octx -> src0_spad .src = NULL ; 253octx -> dst_spad .data = octx -> src0_spad .data + octx -> src0_spad .size ;octx -> dst_spad .src = NULL ; 254 255struct htp_cumsum_context cctx = { 256 .octx = octx , 257 .src_row_size = src_row_size , 258 .dst_row_size = dst_row_size , 259 .src_row_size_aligned = src_row_size_aligned , 260 .dst_row_size_aligned = dst_row_size_aligned , 261 .rows_per_thread = fastdiv (nrows + n_threads - 1 ,& octx -> n_threads_div ), 262 .total_rows = nrows , 263 .row_start = row_start , 264 }; 265 266if (octx -> ctx -> vtcm_size < spad_per_thread * n_threads ) { 267work_queue_run (octx -> ctx -> work_queue ,cumsum_thread_f32 ,& cctx ,n_threads ); 268 }else { 269work_queue_run (octx -> ctx -> work_queue ,cumsum_thread_f32_dma ,& cctx ,n_threads ); 270 } 271 272return HTP_STATUS_OK ; 273} 274 275int op_cumsum (struct htp_ops_context * octx ) { 276const struct htp_tensor * dst = octx -> dst ; 277 278switch (dst -> type ) { 279case HTP_TYPE_F32 : 280return op_cumsum_f32 (octx ); 281default : 282return HTP_STATUS_NO_SUPPORT ; 283 } 284}