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-but-set-variable" 2 3#include <HAP_farf.h> 4#include <string.h> 5 6#include "hex-common.h" 7#include "hex-profile.h" 8 9#define GGML_COMMON_DECL_C 10#include "ggml-common.h" 11#include "htp-ctx.h" 12#include "htp-ops.h" 13#include "htp-tensor.h" 14#include "hvx-types.h" 15#include "hvx-utils.h" 16 17struct htp_solve_tri_context { 18struct htp_ops_context * octx ; 19uint32_t jobs_per_thread ; 20uint32_t total_jobs ; 21uint32_t job_start ; 22uint32_t k_chunks ; 23uint32_t col_block ; 24}; 25 26static inline void solve_tri_row_scalar (const float * A_row , 27const float * B_row , 28float * X , 29uint32_t row , 30uint32_t k , 31uint32_t col0 , 32uint32_t coln , 33float inv_diag ) { 34for (uint32_t col = col0 ;col < col0 + coln ;++ col ) { 35float sum = 0.0f ; 36for (uint32_t t = 0 ;t < row ;++ t ) { 37sum += A_row [t ]* X [t * k + col ]; 38 } 39X [row * k + col ]= (B_row [col ]- sum )* inv_diag ; 40 } 41} 42 43static inline HVX_Vector hvx_load_partial_f32 (const float * src ,uint32_t n ) { 44HVX_Vector v = * ((const HVX_UVector * )src ); 45HVX_VectorPred mask = Q6_Q_vsetq2_R (n * sizeof (float )); 46return Q6_V_vmux_QVV (mask ,v ,Q6_V_vzero ()); 47} 48 49static inline void solve_tri_row_hvx (const float * A_row , 50const float * B_row , 51float * X , 52uint32_t row , 53uint32_t k , 54uint32_t col0 , 55uint32_t coln , 56float inv_diag ) { 57const bool full = (coln == VLEN_FP32 ); 58 59HVX_Vector sum_v = Q6_V_vzero (); 60for (uint32_t t = 0 ;t < row ;++ t ) { 61const float a = A_row [t ]; 62const float * x_row_col = X + t * k + col0 ; 63 64HVX_Vector x_v = full ?* ((const HVX_UVector * )x_row_col ) :hvx_load_partial_f32 (x_row_col ,coln ); 65HVX_Vector a_v = hvx_vec_splat_f32 (a ); 66sum_v = hvx_vec_add_f32_f32 (sum_v ,hvx_vec_mul_f32_f32 (x_v ,a_v )); 67 } 68 69const float * b_row_col = B_row + col0 ; 70float * x_out_col = X + row * k + col0 ; 71 72HVX_Vector b_v = full ?* ((const HVX_UVector * )b_row_col ) :hvx_load_partial_f32 (b_row_col ,coln ); 73HVX_Vector inv_diag_v = hvx_vec_splat_f32 (inv_diag ); 74 75HVX_Vector out_v = hvx_vec_mul_f32_f32 (hvx_vec_sub_f32_f32 (b_v ,sum_v ),inv_diag_v ); 76hvx_vec_store_u ((void * )x_out_col ,coln * sizeof (float ),out_v ); 77} 78 79// Batch-level thread: each job is one full batch. 80static void solve_tri_batch_thread_f32 (unsigned int nth ,unsigned int ith ,void * data ) { 81struct htp_solve_tri_context * sctx = (struct htp_solve_tri_context * )data ; 82struct htp_ops_context * octx = sctx -> octx ; 83 84const struct htp_tensor * src0 = octx -> src [0 ];// A 85const struct htp_tensor * src1 = octx -> src [1 ];// B 86const struct htp_tensor * dst = octx -> dst ;// X 87 88const uint32_t n = src0 -> ne [0 ]; 89const uint32_t k = src1 -> ne [0 ]; 90 91const uint32_t ne02 = src0 -> ne [2 ]; 92 93const uint32_t col_block = VLEN_FP32 ; 94const uint32_t k_full = (k /col_block )* col_block ; 95 96const uint32_t start_batch = sctx -> job_start + sctx -> jobs_per_thread * ith ; 97const uint32_t end_batch = MIN (start_batch + sctx -> jobs_per_thread ,sctx -> job_start + sctx -> total_jobs ); 98 99struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 100htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )start_batch ); 101 102for (uint32_t batch = start_batch ;batch < end_batch ;++ batch ) { 103const uint32_t i03 = batch /ne02 ; 104const uint32_t i02 = batch - i03 * ne02 ; 105 106const float * A_batch = 107 (const float * ) ((const uint8_t * ) (uintptr_t )src0 -> data + i02 * src0 -> nb [2 ]+ i03 * src0 -> nb [3 ]); 108const float * B_batch = 109 (const float * ) ((const uint8_t * ) (uintptr_t )src1 -> data + i02 * src1 -> nb [2 ]+ i03 * src1 -> nb [3 ]); 110float * X_batch = (float * ) ((uint8_t * ) (uintptr_t )dst -> data + i02 * dst -> nb [2 ]+ i03 * dst -> nb [3 ]); 111 112for (uint32_t row = 0 ;row < n ;++ row ) { 113const float diag = A_batch [row * n + row ]; 114const float inv_diag = 1.0f /diag ; 115const float * A_row = A_batch + row * n ; 116const float * B_row = B_batch + row * k ; 117 118uint32_t col0 = 0 ; 119for (;col0 < k_full ;col0 += col_block ) { 120solve_tri_row_hvx (A_row ,B_row ,X_batch ,row ,k ,col0 ,col_block ,inv_diag ); 121 } 122 123if (col0 < k ) { 124const uint32_t coln = k - col0 ; 125if (coln >=8 ) { 126solve_tri_row_hvx (A_row ,B_row ,X_batch ,row ,k ,col0 ,coln ,inv_diag ); 127 }else { 128solve_tri_row_scalar (A_row ,B_row ,X_batch ,row ,k ,col0 ,coln ,inv_diag ); 129 } 130 } 131 } 132 } 133 134htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )end_batch ); 135 136FARF (HIGH ,"solve-tri-batch %d/%d: A=(%ux%u) B=(%ux%u) batch %u:%u\n" , 137ith ,nth ,n ,n ,k ,n ,start_batch ,end_batch ); 138} 139 140// Chunk-level thread: each job is one (batch, col_chunk) pair. 141static void solve_tri_chunk_thread_f32 (unsigned int nth ,unsigned int ith ,void * data ) { 142struct htp_solve_tri_context * sctx = (struct htp_solve_tri_context * )data ; 143struct htp_ops_context * octx = sctx -> octx ; 144 145const struct htp_tensor * src0 = octx -> src [0 ];// A 146const struct htp_tensor * src1 = octx -> src [1 ];// B 147const struct htp_tensor * dst = octx -> dst ;// X 148 149const uint32_t n = src0 -> ne [0 ]; 150const uint32_t k = src1 -> ne [0 ]; 151 152const uint32_t ne02 = src0 -> ne [2 ]; 153 154const uint32_t start_job = sctx -> job_start + sctx -> jobs_per_thread * ith ; 155const uint32_t end_job = MIN (start_job + sctx -> jobs_per_thread ,sctx -> job_start + sctx -> total_jobs ); 156 157struct htp_thread_trace * tr = & octx -> ctx -> trace [ith ]; 158htp_trace_event_start (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )start_job ); 159 160for (uint32_t job = start_job ;job < end_job ;++ job ) { 161const uint32_t batch = job /sctx -> k_chunks ; 162const uint32_t chunk = job - batch * sctx -> k_chunks ; 163 164const uint32_t i03 = batch /ne02 ; 165const uint32_t i02 = batch - i03 * ne02 ; 166 167const float * A_batch = 168 (const float * ) ((const uint8_t * ) (uintptr_t )src0 -> data + i02 * src0 -> nb [2 ]+ i03 * src0 -> nb [3 ]); 169const float * B_batch = 170 (const float * ) ((const uint8_t * ) (uintptr_t )src1 -> data + i02 * src1 -> nb [2 ]+ i03 * src1 -> nb [3 ]); 171float * X_batch = (float * ) ((uint8_t * ) (uintptr_t )dst -> data + i02 * dst -> nb [2 ]+ i03 * dst -> nb [3 ]); 172 173const uint32_t col0 = chunk * sctx -> col_block ; 174const uint32_t coln = MIN (sctx -> col_block ,k - col0 ); 175 176for (uint32_t row = 0 ;row < n ;++ row ) { 177const float diag = A_batch [row * n + row ]; 178const float inv_diag = 1.0f /diag ; 179 180const float * A_row = A_batch + row * n ; 181const float * B_row = B_batch + row * k ; 182 183if (coln >=8 ) { 184solve_tri_row_hvx (A_row ,B_row ,X_batch ,row ,k ,col0 ,coln ,inv_diag ); 185 }else { 186solve_tri_row_scalar (A_row ,B_row ,X_batch ,row ,k ,col0 ,coln ,inv_diag ); 187 } 188 } 189 } 190 191htp_trace_event_stop (tr ,HTP_TRACE_EVT_HVX_COMP , (uint16_t )end_job ); 192 193FARF (HIGH ,"solve-tri-chunk %d/%d: A=(%ux%u) B=(%ux%u) jobs %u:%u\n" , 194ith ,nth ,n ,n ,k ,n ,start_job ,end_job ); 195} 196 197int op_solve_tri (struct htp_ops_context * octx ) { 198const struct htp_tensor * src0 = octx -> src [0 ];// A 199const struct htp_tensor * src1 = octx -> src [1 ];// B 200const struct htp_tensor * dst = octx -> dst ;// X 201 202if (src0 -> type != HTP_TYPE_F32 || src1 -> type != HTP_TYPE_F32 || dst -> type != HTP_TYPE_F32 ) { 203return HTP_STATUS_NO_SUPPORT ; 204 } 205 206// left=true, lower=true, uni=false only 207if (src0 -> ne [0 ]!= src0 -> ne [1 ]) { 208return HTP_STATUS_INVAL_PARAMS ; 209 } 210if (src0 -> ne [1 ]!= src1 -> ne [1 ]) { 211return HTP_STATUS_INVAL_PARAMS ; 212 } 213if (src0 -> ne [2 ]!= src1 -> ne [2 ]|| src0 -> ne [3 ]!= src1 -> ne [3 ]) { 214return HTP_STATUS_INVAL_PARAMS ; 215 } 216if (dst -> ne [0 ]!= src1 -> ne [0 ]|| dst -> ne [1 ]!= src1 -> ne [1 ]|| dst -> ne [2 ]!= src1 -> ne [2 ]|| 217dst -> ne [3 ]!= src1 -> ne [3 ]) { 218return HTP_STATUS_INVAL_PARAMS ; 219 } 220 221if (octx -> flags & HTP_OPFLAGS_SKIP_COMPUTE ) { 222return HTP_STATUS_OK ; 223 } 224 225const uint32_t k = src1 -> ne [0 ]; 226 227const uint32_t col_block = VLEN_FP32 ; 228const uint32_t k_chunks = (k + col_block - 1 ) /col_block ; 229const uint32_t total_batches = src0 -> ne [2 ]* src0 -> ne [3 ]; 230const bool batched = total_batches >= (uint32_t )octx -> n_threads ; 231 232FARF (HIGH ,"solve-tri: (%ux%ux%ux%u) x (%ux%ux%ux%u) -> (%ux%ux%ux%u) : batched %d\n" , 233src0 -> ne [0 ],src0 -> ne [1 ],src0 -> ne [2 ],src0 -> ne [3 ], 234src1 -> ne [0 ],src1 -> ne [1 ],src1 -> ne [2 ],src1 -> ne [3 ], 235dst -> ne [0 ],dst -> ne [1 ],dst -> ne [2 ],dst -> ne [3 ],batched ); 236 237if (batched ) { 238uint32_t job_start = 0 ; 239uint32_t njobs = total_batches ; 240 241if (octx -> ctx -> mdev .count > 1 ) { 242const uint32_t batch_size = dst -> nb [2 ]; 243const uint32_t batches_per_chunk = (batch_size > 0 ) ? (HEX_L2_LINE_SIZE /hex_gcd_u32 (batch_size ,HEX_L2_LINE_SIZE )) :1 ; 244const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (total_batches ,htp_tensor_mdev_data_aligned (dst ) ?batches_per_chunk :0 ,octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 245job_start = range .start ; 246njobs = range .count ; 247 } 248 249if (njobs == 0 ) { 250return HTP_STATUS_OK ; 251 } 252 253// Batch-level parallelism 254const uint32_t n_threads = octx -> n_threads ; 255 256struct htp_solve_tri_context sctx = { 257 .octx = octx , 258 .jobs_per_thread = fastdiv (njobs + n_threads - 1 ,& octx -> n_threads_div ), 259 .total_jobs = njobs , 260 .job_start = job_start , 261 .k_chunks = k_chunks , 262 .col_block = col_block , 263 }; 264 265work_queue_run (octx -> ctx -> work_queue ,solve_tri_batch_thread_f32 ,& sctx ,n_threads ); 266 }else { 267// Chunk-level parallelism 268const uint32_t total_jobs = total_batches * k_chunks ; 269 270uint32_t job_start = 0 ; 271uint32_t njobs = total_jobs ; 272 273if (octx -> ctx -> mdev .count > 1 ) { 274const bool can_split = htp_tensor_mdev_data_aligned (dst )&& ((dst -> nb [1 ]& (HTP_TENSOR_MDEV_LINE_SIZE - 1 ))== 0 ); 275const struct htp_tensor_mdev_range range = htp_tensor_mdev_partition (total_jobs ,can_split ?1 :0 ,octx -> ctx -> mdev .idx ,octx -> ctx -> mdev .count ,& octx -> ctx -> mdev .count_div ); 276job_start = range .start ; 277njobs = range .count ; 278 } 279 280if (njobs == 0 ) { 281return HTP_STATUS_OK ; 282 } 283 284const uint32_t n_threads = octx -> n_threads ; 285 286struct htp_solve_tri_context sctx = { 287 .octx = octx , 288 .jobs_per_thread = fastdiv (njobs + n_threads - 1 ,& octx -> n_threads_div ), 289 .total_jobs = njobs , 290 .job_start = job_start , 291 .k_chunks = k_chunks , 292 .col_block = col_block , 293 }; 294 295work_queue_run (octx -> ctx -> work_queue ,solve_tri_chunk_thread_f32 ,& sctx ,n_threads ); 296 } 297 298return HTP_STATUS_OK ; 299}