char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
eafe15a5e
char/aliceai-t5-moe
1#ifndef HTP_OPNODE_H 2#define HTP_OPNODE_H 3 4#define GGML_COMMON_IMPL_CPP 5#include "ggml-backend-impl.h" 6#include "ggml-common.h" 7 8#include <algorithm> 9#include <string> 10#include <vector> 11#include <memory> 12#include <stdio.h> 13#include "htp-ops.h" 14#include "htp/matmul-ops.h" 15#include "htp/flash-attn-ops.h" 16#include "htp/unary-ops.h" 17#include "htp/allreduce-ops.h" 18 19struct htp_opnode { 20ggml_tensor * node { nullptr }; 21htp_op_code opcode {HTP_OP_INVALID }; 22int32_t kernel_params [HTP_OP_MAX_KERN_PARAMS ] {0 }; 23 24std ::vector < ggml_tensor *> fused ; 25std ::vector < std ::shared_ptr < ggml_tensor >>dummy ; 26 27std ::vector < const ggml_tensor *> inputs ; 28std ::vector < const ggml_tensor *> outputs ; 29std ::string name ; 30 31int n_active_src (const ggml_tensor * t )const { 32if (!t )return 0 ; 33for (int i = GGML_MAX_SRC - 1 ;i >=0 ;i -- ) { 34if (t -> src [i ]) { 35return i + 1 ; 36 } 37 } 38return 0 ; 39 } 40 41void init (ggml_tensor * node ) { 42this -> node = node ; 43if (this -> node ) { 44this -> name = ggml_op_desc (this -> node ); 45 46// Build inputs (preserving optional nullptrs) 47int n_inputs = n_active_src (this -> node ); 48this -> inputs .resize (n_inputs ,nullptr ); 49for (int i = 0 ;i < n_inputs ;i ++ ) { 50this -> inputs [i ]= this -> node -> src [i ]; 51 } 52 53// Build outputs 54this -> outputs .push_back (this -> dst ()); 55 } 56 } 57 58htp_opnode (htp_op_code opcode = HTP_OP_INVALID ,ggml_tensor * node = nullptr ) :opcode (opcode ) { 59init (node ); 60 } 61 62ggml_op op ()const {return node -> op ; } 63const ggml_tensor * src0 ()const {return node -> src [0 ]; } 64const ggml_tensor * src1 ()const {return node -> src [1 ]; } 65const ggml_tensor * dst ()const {return outputs .empty () ?node :outputs .back (); } 66 67ggml_tensor * add_dummy (const ggml_tensor & t ) { 68dummy .push_back (std ::make_shared < ggml_tensor > (t )); 69return dummy .back ().get (); 70 } 71 72void add_fused (ggml_tensor * t ,bool extra_dst = false) { 73fused .push_back (t ); 74 75name += "+" ; 76name += ggml_op_desc (t ); 77 78if (extra_dst ) { 79outputs .push_back (t ); 80 }else { 81outputs .clear (); 82outputs .push_back (t ); 83 } 84 85// Remove the newly fused intermediate output tensor t from inputs (if it was there) 86inputs .erase (std ::remove (inputs .begin (),inputs .end (),t ),inputs .end ()); 87 88// Append new inputs from t, preserving middle nullptrs 89int n_inputs = n_active_src (t ); 90for (int i = 0 ;i < n_inputs ;i ++ ) { 91const auto* src = t -> src [ i ]; 92if (! src ) { 93inputs . push_back ( nullptr ); 94} else if ( src != node && 95std :: find ( fused . begin (), fused . end (), src ) == fused . end () && 96std :: find ( inputs . begin (), inputs . end (), src ) == inputs . end ()) { 97inputs . push_back ( src ); 98} 99} 100} 101 102const std:: vector < const ggml_tensor *> & get_inputs () const { 103return inputs ; 104} 105 106const std:: vector < const ggml_tensor *> & get_outputs () const { 107return outputs ; 108} 109 110std ::string op_name () const { 111return name ; 112} 113 114bool is_empty () const { 115return ggml_op_is_empty ( node -> op ); 116} 117 118bool stackable () const { 119switch ( this -> op ()) { 120case GGML_OP_MUL_MAT : 121case GGML_OP_MUL_MAT_ID : 122return ggml_is_quantized ( this -> src0 () -> type ); 123default : 124return false; 125} 126} 127 128bool same_input ( const htp_opnode & n ) const { 129return n . src1 () == this -> src1 (); 130} 131}; 132 133struct htp_opformat { 134char strides [ 64 * GGML_MAX_SRC ]; 135char dims [ 64 * GGML_MAX_SRC ]; 136char types [ 16 * GGML_MAX_SRC ]; 137char buffs [ 64 * GGML_MAX_SRC ]; 138char names [ 64 * GGML_MAX_SRC ]; 139char kparams [ 128 ]; 140 141int format_tensor_dims (char * str , size_t max_size , const struct ggml_tensor * t ) { 142if (!t) { 143return snprintf (str, max_size, "NONE"); 144} 145if (t -> ne [ 2 ] == 1 && t -> ne [ 3 ] == 1 ) { 146return snprintf ( str , max_size , "%d:%d" , (int) t -> ne [ 0 ], (int) t -> ne [ 1 ]); 147} else { 148return snprintf ( str , max_size , "%d:%d:%d:%d" , (int) t -> ne [ 0 ], (int) t -> ne [ 1 ], (int) t -> ne [ 2 ], (int) t -> ne [ 3 ]); 149} 150} 151 152void format_op_dims (char * str , size_t max_size , const htp_opnode & node ) { 153char * p = str ; 154char * p_end = str + max_size ; 155auto inputs = node. get_inputs (); 156 157if (!inputs. empty ()) { 158p += std:: min (( size_t ) format_tensor_dims (p, p_end - p, inputs[ 0 ]), ( size_t )(p_end - p)); 159 160for ( size_t i = 1 ; i < inputs. size (); i ++ ) { 161if (p < p_end) { 162p += std:: min (( size_t ) snprintf (p, p_end - p, " x " ), ( size_t )(p_end - p)); 163} 164if (p < p_end) { 165p += std:: min (( size_t ) format_tensor_dims (p, p_end - p, inputs[i]), ( size_t )(p_end - p)); 166} 167} 168 169if (p < p_end) { 170p += std:: min (( size_t ) snprintf (p, p_end - p, " -> " ), ( size_t )(p_end - p)); 171} 172} 173 174char self[ 64 ]; 175format_tensor_dims (self, sizeof (self), node. dst ()); 176if (p < p_end) { 177p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , self), ( size_t )(p_end - p)); 178} 179} 180 181int format_tensor_strides ( char * str, size_t max_size, const struct ggml_tensor * t) { 182if (!t) { 183return snprintf (str, max_size, "NONE" ); 184} 185const char * c = ggml_is_contiguous (t) ? "" : "!" ; 186 187if (t -> ne [ 2 ] == 1 && t -> ne [ 3 ] == 1 ) { 188return snprintf (str, max_size, "%zu:%zu%s" , ( size_t ) t -> nb [ 0 ], ( size_t ) t -> nb [ 1 ], c); 189} else { 190return snprintf (str, max_size, "%zu:%zu:%zu:%zu%s" , ( size_t ) t -> nb [ 0 ], ( size_t ) t -> nb [ 1 ], ( size_t ) t -> nb [ 2 ], ( size_t ) t -> nb [ 3 ], c); 191} 192} 193 194void format_op_strides ( char * str, size_t max_size, const htp_opnode & node) { 195char * p = str; 196char * p_end = str + max_size; 197auto inputs = node. get_inputs (); 198 199if (!inputs. empty ()) { 200p += std:: min (( size_t ) format_tensor_strides (p, p_end - p, inputs[ 0 ]), ( size_t )(p_end - p)); 201 202for ( size_t i = 1 ; i < inputs. size (); i ++ ) { 203if (p < p_end) { 204p += std:: min (( size_t ) snprintf (p, p_end - p, " x " ), ( size_t )(p_end - p)); 205} 206if (p < p_end) { 207p += std:: min (( size_t ) format_tensor_strides (p, p_end - p, inputs[i]), ( size_t )(p_end - p)); 208} 209} 210 211if (p < p_end) { 212p += std:: min (( size_t ) snprintf (p, p_end - p, " -> " ), ( size_t )(p_end - p)); 213} 214} 215 216char self[ 64 ]; 217format_tensor_strides (self, sizeof (self), node. dst ()); 218if (p < p_end) { 219p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , self), ( size_t )(p_end - p)); 220} 221} 222 223void format_op_types ( char * str, size_t max_size, const htp_opnode & node) { 224char * p = str; 225char * p_end = str + max_size; 226auto inputs = node. get_inputs (); 227 228if (!inputs. empty ()) { 229if (p < p_end) { 230p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , inputs[ 0 ] ? ggml_type_name (inputs[ 0 ] -> type ) : "NONE" ), ( size_t )(p_end - p)); 231} 232 233for ( size_t i = 1 ; i < inputs. size (); i ++ ) { 234if (p < p_end) { 235p += std:: min (( size_t ) snprintf (p, p_end - p, " x " ), ( size_t )(p_end - p)); 236} 237if (p < p_end) { 238p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , inputs[i] ? ggml_type_name (inputs[i] -> type ) : "NONE" ), ( size_t )(p_end - p)); 239} 240} 241 242if (p < p_end) { 243p += std:: min (( size_t ) snprintf (p, p_end - p, " -> " ), ( size_t )(p_end - p)); 244} 245} 246 247if (p < p_end) { 248p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , ggml_type_name (node. dst () -> type )), ( size_t )(p_end - p)); 249} 250} 251 252const char * tensor_buff_name ( const struct ggml_tensor * t) { 253if (t && t -> buffer ) { 254return ggml_backend_buffer_name (t -> buffer ); 255} 256return "NONE" ; 257} 258 259void format_op_buffs ( char * str, size_t max_size, const htp_opnode & node) { 260char * p = str; 261char * p_end = str + max_size; 262auto inputs = node. get_inputs (); 263 264if (!inputs. empty ()) { 265if (p < p_end) { 266p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , tensor_buff_name (inputs[ 0 ])), ( size_t )(p_end - p)); 267} 268 269for ( size_t i = 1 ; i < inputs. size (); i ++ ) { 270if (p < p_end) { 271p += std:: min (( size_t ) snprintf (p, p_end - p, " x " ), ( size_t )(p_end - p)); 272} 273if (p < p_end) { 274p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , tensor_buff_name (inputs[i])), ( size_t )(p_end - p)); 275} 276} 277 278if (p < p_end) { 279p += std:: min (( size_t ) snprintf (p, p_end - p, " -> " ), ( size_t )(p_end - p)); 280} 281} 282 283if (p < p_end) { 284p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , tensor_buff_name (node. dst ())), ( size_t )(p_end - p)); 285} 286} 287 288void format_op_names ( char * str, size_t max_size, const htp_opnode & node) { 289char * p = str; 290char * p_end = str + max_size; 291auto inputs = node. get_inputs (); 292 293if (!inputs. empty ()) { 294if (p < p_end) { 295p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , inputs[ 0 ] ? inputs[ 0 ] -> name : "NONE" ), ( size_t )(p_end - p)); 296} 297 298for ( size_t i = 1 ; i < inputs. size (); i ++ ) { 299if (p < p_end) { 300p += std:: min (( size_t ) snprintf (p, p_end - p, " x " ), ( size_t )(p_end - p)); 301} 302if (p < p_end) { 303p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , inputs[i] ? inputs[i] -> name : "NONE" ), ( size_t )(p_end - p)); 304} 305} 306 307if (p < p_end) { 308p += std:: min (( size_t ) snprintf (p, p_end - p, " -> " ), ( size_t )(p_end - p)); 309} 310} 311 312if (p < p_end) { 313p += std:: min (( size_t ) snprintf (p, p_end - p, "%s" , node. dst () -> name ), ( size_t )(p_end - p)); 314} 315} 316void format_kernel_params ( char * str, size_t max_size, const htp_opnode & node) { 317if (node. opcode == HTP_OP_MUL_MAT || node. opcode == HTP_OP_MUL_MAT_ID || 318node. opcode == HTP_OP_MUL_MAT_NX || node. opcode == HTP_OP_MUL_MAT_ID_NX || 319node. opcode == HTP_OP_MUL_MAT_ADD ) { 320const auto * kparams = ( const struct htp_mm_kernel_params * ) node . kernel_params ; 321const char * path = "unknown" ; 322int32_t type = kparams -> kernel_type ; 323if ( type == HTP_MM_KERNEL_HMX_2D || type == HTP_MM_KERNEL_HMX_F16_BATCHED ) { 324path = "hmx-tiled" ; 325} else if ( type == HTP_MM_KERNEL_HVX_F16_F16_VTCM || type == HTP_MM_KERNEL_HVX_F32_F32_VTCM || 326type == HTP_MM_KERNEL_HVX_QUANT_ROW || type == HTP_MM_KERNEL_HVX_QUANT_BLOCK ) { 327path = "hvx-tiled" ; 328} else if ( type == HTP_MM_KERNEL_HVX_F16_F16_DDR || type == HTP_MM_KERNEL_HVX_F16_F32_DDR || 329type == HTP_MM_KERNEL_HVX_F32_F32_DDR || type == HTP_MM_KERNEL_HVX_F32_F16_DDR || 330type == HTP_MM_KERNEL_HVX_QUANT_ROW_FLAT ) { 331path = "hvx-flat" ; 332} 333snprintf ( str , max_size , "%s vtcm %d" , path , (int) kparams -> vtcm_size ); 334} else if ( node . opcode == HTP_OP_FLASH_ATTN_EXT ) { 335const auto * kparams = ( const struct htp_fa_kernel_params * ) node . kernel_params ; 336const char * path = "unknown" ; 337int32_t type = kparams -> kernel_type ; 338if ( type == HTP_FA_KERNEL_HMX ) { 339path = kparams -> u . hmx . pipeline ? "hmx-pipe" : "hmx-seq" ; 340} else if ( type == HTP_FA_KERNEL_HVX ) { 341path = "hvx" ; 342} 343snprintf ( str , max_size , "%s vtcm %d" , path , (int) kparams -> vtcm_size ); 344} else if ( htp_op_is_unary ( node . opcode )) { 345const auto * kparams = ( const struct htp_unary_kernel_params * ) node . kernel_params ; 346snprintf ( str , max_size , "%s vtcm %d" , kparams -> col_tile ? "wide-row" : "row-block" , (int) kparams -> vtcm_size ); 347} else if ( node . opcode == HTP_OP_MDEV_GROUP && node . node ) { 348snprintf ( str , max_size , "idx %d count %d" , (int) node . node -> op_params [ 0 ], (int) node . dst () -> ne [ 1 ]); 349} else if (( node . opcode == HTP_OP_FENCE || node . opcode == HTP_OP_CPY_FENCE ) && node . node ) { 350snprintf ( str , max_size , "seq 0x%x" , (uint32_t) node . node -> op_params [ 0 ]); 351} else if ( node . opcode == HTP_OP_ALLREDUCE && node . node ) { 352snprintf ( str , max_size , "seq 0x%x -> 0x%x" , (uint32_t) node . node -> op_params [ 0 ], (uint32_t) node . node -> op_params [ 1 ]); 353} else { 354snprintf ( str , max_size , "----" ); 355} 356} 357 358void format ( const htp_opnode & node ) { 359format_op_dims ( dims , sizeof ( dims ), node ); 360format_op_strides ( strides , sizeof ( strides ), node ); 361format_op_types ( types , sizeof ( types ), node ); 362format_op_buffs ( buffs , sizeof ( buffs ), node ); 363format_op_names ( names , sizeof ( names ), node ); 364format_kernel_params ( kparams , sizeof ( kparams ), node ); 365} 366 367htp_opformat () { 368strides [ 0 ] = '\0' ; 369dims [ 0 ] = '\0' ; 370types [ 0 ] = '\0' ; 371buffs [ 0 ] = '\0' ; 372names [ 0 ] = '\0' ; 373kparams [ 0 ] = '\0' ; 374} 375htp_opformat ( const htp_opnode & node ) { format ( node ); } 376}; 377 378#endif // HTP_OPNODE_H