char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
153d324bc
char/aliceai-t5-moe
1#include "ggml.h" 2#include "ggml-impl.h" 3#include "ggml-blas.h" 4#include "ggml-backend-impl.h" 5 6#include <future> 7#include <vector> 8#include <cstring> 9 10#if defined(GGML_BLAS_USE_ACCELERATE ) 11# include <Accelerate/Accelerate.h> 12#elif defined(GGML_BLAS_USE_MKL ) 13# include <mkl.h> 14#elif defined(GGML_BLAS_USE_BLIS ) 15# include <blis.h> 16#elif defined(GGML_BLAS_USE_NVPL ) 17# include <nvpl_blas.h> 18#else 19# include <cblas.h> 20#endif 21 22struct ggml_backend_blas_context { 23int n_threads = GGML_DEFAULT_N_THREADS ; 24 std::unique_ptr < char []> work_data ; 25size_t work_size = 0 ; 26#ifndef GGML_USE_OPENMP 27 std::vector < std::future < void >> tasks ; 28#endif 29}; 30 31static void ggml_backend_blas_mul_mat (ggml_backend_blas_context * ctx ,struct ggml_tensor * dst ) { 32const struct ggml_tensor * src0 = dst -> src [0 ]; 33const struct ggml_tensor * src1 = dst -> src [1 ]; 34 35GGML_TENSOR_BINARY_OP_LOCALS 36 37const enum ggml_type type = src0 -> type ; 38 39GGML_ASSERT (ne0 == ne01 ); 40GGML_ASSERT (ne1 == ne11 ); 41GGML_ASSERT (ne2 == ne12 ); 42GGML_ASSERT (ne3 == ne13 ); 43 44// we don't support permuted src0 or src1 45GGML_ASSERT (nb00 == ggml_type_size (type )); 46GGML_ASSERT (nb10 == ggml_type_size (src1 -> type )); 47 48// dst cannot be transposed or permuted 49GGML_ASSERT (nb0 == sizeof (float )); 50GGML_ASSERT (nb0 <=nb1 ); 51GGML_ASSERT (nb1 <=nb2 ); 52GGML_ASSERT (nb2 <=nb3 ); 53 54// broadcast factors 55const int64_t r2 = ne12 /ne02 ; 56const int64_t r3 = ne13 /ne03 ; 57 58const int64_t ne_plane = ne01 * ne00 ; 59const size_t desired_wsize = type == GGML_TYPE_F32 ?0 :ne03 * ne02 * ne_plane * sizeof (float ); 60 61if (ctx -> work_size < desired_wsize ) { 62ctx -> work_data .reset (new char [desired_wsize ]); 63ctx -> work_size = desired_wsize ; 64 } 65void * wdata = ctx -> work_data .get (); 66 67// convert src0 to float 68if (type != GGML_TYPE_F32 ) { 69const auto * type_traits = ggml_get_type_traits (type ); 70ggml_to_float_t const to_float = type_traits -> to_float ; 71 72for (int64_t i03 = 0 ;i03 < ne03 ;i03 ++ ) { 73for (int64_t i02 = 0 ;i02 < ne02 ;i02 ++ ) { 74const void * x = (char * )src0 -> data + i02 * nb02 + i03 * nb03 ; 75float * const wplane = (float * )wdata + i02 * ne_plane + i03 * ne02 * ne_plane ; 76 77const int min_cols_per_thread = 4096 ; 78const int min_rows_per_thread = std::max ((int )(min_cols_per_thread /ne00 ),1 ); 79const int n_threads = std::max (std::min (ctx -> n_threads , (int )(ne01 /min_rows_per_thread )),1 ); 80 81#ifdef GGML_USE_OPENMP 82#pragma omp parallel for num_threads(n_threads) 83for (int64_t i01 = 0 ;i01 < ne01 ;i01 ++ ) { 84to_float ((const char * )x + i01 * nb01 ,wplane + i01 * ne00 ,ne00 ); 85 } 86#else 87for (int i = 1 ;i < n_threads ;i ++ ) { 88const int64_t start = i * ne01 /n_threads ; 89const int64_t end = (i + 1 )* ne01 /n_threads ; 90if (start < end ) { 91ctx -> tasks .push_back (std::async (std::launch::async , [= ]() { 92for (int64_t i01 = start ;i01 < end ;i01 ++ ) { 93to_float ((const char * )x + i01 * nb01 ,wplane + i01 * ne00 ,ne00 ); 94 } 95 })); 96 } 97 } 98 { 99// reuse the current thread for the first task 100const int64_t start = 0 ; 101const int64_t end = ne01 /n_threads ; 102for (int64_t i01 = start ;i01 < end ;i01 ++ ) { 103to_float ((const char * )x + i01 * nb01 ,wplane + i01 * ne00 ,ne00 ); 104 } 105 } 106#endif 107 } 108 } 109 110#ifndef GGML_USE_OPENMP 111// wait for all tasks to finish 112for (auto & task :ctx -> tasks ) { 113task .get (); 114 } 115ctx -> tasks .clear (); 116#endif 117 } 118 119#if defined(GGML_BLAS_USE_OPENBLAS ) 120openblas_set_num_threads (ctx -> n_threads ); 121#elif defined(GGML_BLAS_USE_BLIS ) 122bli_thread_set_num_threads (ctx -> n_threads ); 123#elif defined(GGML_BLAS_USE_NVPL ) 124nvpl_blas_set_num_threads (ctx -> n_threads ); 125#elif defined(GGML_BLAS_USE_MKL ) 126mkl_set_num_threads (ctx -> n_threads ); 127#endif 128 129for (int64_t i13 = 0 ;i13 < ne13 ;i13 ++ ) { 130for (int64_t i12 = 0 ;i12 < ne12 ;i12 ++ ) { 131const int64_t i03 = i13 /r3 ; 132const int64_t i02 = i12 /r2 ; 133 134const float * x = (float * ) ((char * )src0 -> data + i02 * nb02 + i03 * nb03 ); 135const float * y = (float * ) ((char * )src1 -> data + i12 * nb12 + i13 * nb13 ); 136float * d = (float * ) ((char * )dst -> data + i12 * nb2 + i13 * nb3 ); 137 138if (type != GGML_TYPE_F32 ) { 139x = (float * )wdata + i02 * ne_plane + i03 * ne02 * ne_plane ; 140 } 141 142cblas_sgemm (CblasRowMajor ,CblasNoTrans ,CblasTrans , 143ne1 ,ne01 ,ne10 , 1441.0f ,y ,ne10 , 145x ,ne00 , 1460.0f ,d ,ne01 ); 147 } 148 } 149} 150 151static void ggml_backend_blas_out_prod (ggml_backend_blas_context * ctx ,struct ggml_tensor * dst ) { 152const struct ggml_tensor * src0 = dst -> src [0 ]; 153const struct ggml_tensor * src1 = dst -> src [1 ]; 154 155GGML_TENSOR_BINARY_OP_LOCALS 156 157GGML_ASSERT (ne0 == ne00 ); 158GGML_ASSERT (ne1 == ne10 ); 159GGML_ASSERT (ne2 == ne02 ); 160GGML_ASSERT (ne02 == ne12 ); 161GGML_ASSERT (ne3 == ne13 ); 162GGML_ASSERT (ne03 == ne13 ); 163 164// we don't support permuted src0 or src1 165GGML_ASSERT (nb00 == sizeof (float )); 166 167// dst cannot be transposed or permuted 168GGML_ASSERT (nb0 == sizeof (float )); 169// GGML_ASSERT(nb0 <= nb1); 170// GGML_ASSERT(nb1 <= nb2); 171// GGML_ASSERT(nb2 <= nb3); 172 173// Arguments to ggml_compute_forward_out_prod (expressed as major,minor) 174// src0: (k,n) 175// src1: (k,m) 176// dst: (m,n) 177// 178// Arguments to sgemm (see https://github.com/Reference-LAPACK/lapack/blob/master/BLAS/SRC/sgemm.f) 179// Also expressed as (major,minor) 180// a: (m,k): so src1 transposed 181// b: (k,n): so src0 182// c: (m,n) 183// 184// However, if ggml_is_transposed(src1) is true, then 185// src1->data already contains a transposed version, so sgemm mustn't 186// transpose it further. 187 188int n = src0 -> ne [0 ]; 189int k = src0 -> ne [1 ]; 190int m = src1 -> ne [0 ]; 191 192CBLAS_TRANSPOSE transposeA ; 193int lda ; 194 195if (!ggml_is_transposed (src1 )) { 196transposeA = CblasTrans ; 197lda = m ; 198 }else { 199transposeA = CblasNoTrans ; 200lda = k ; 201 } 202 203float * a = (float * ) ((char * )src1 -> data ); 204float * b = (float * ) ((char * )src0 -> data ); 205float * c = (float * ) ((char * )dst -> data ); 206 207cblas_sgemm (CblasRowMajor ,transposeA ,CblasNoTrans ,m ,n ,k ,1.0 ,a ,lda ,b ,n ,0.0 ,c ,n ); 208 209GGML_UNUSED (ctx ); 210} 211 212// backend interface 213 214static const char * ggml_backend_blas_get_name (ggml_backend_t backend ) { 215return "BLAS" ; 216 217GGML_UNUSED (backend ); 218} 219 220static void ggml_backend_blas_free (ggml_backend_t backend ) { 221ggml_backend_blas_context * ctx = (ggml_backend_blas_context * )backend -> context ; 222delete ctx ; 223delete backend ; 224} 225 226static enum ggml_status ggml_backend_blas_graph_compute (ggml_backend_t backend ,struct ggml_cgraph * cgraph ) { 227ggml_backend_blas_context * ctx = (ggml_backend_blas_context * )backend -> context ; 228 229for (int i = 0 ;i < cgraph -> n_nodes ;i ++ ) { 230struct ggml_tensor * node = cgraph -> nodes [i ]; 231 232if ((node -> flags & GGML_TENSOR_FLAG_COMPUTE )== 0 ) { 233continue ; 234 } 235 236switch (node -> op ) { 237case GGML_OP_MUL_MAT : 238ggml_backend_blas_mul_mat (ctx ,node ); 239break ; 240 241case GGML_OP_OUT_PROD : 242ggml_backend_blas_out_prod (ctx ,node ); 243break ; 244 245case GGML_OP_NONE : 246case GGML_OP_RESHAPE : 247case GGML_OP_VIEW : 248case GGML_OP_PERMUTE : 249case GGML_OP_TRANSPOSE : 250break ; 251 252default : 253GGML_ABORT ("%s: unsupported op %s\n" ,__func__ ,ggml_op_desc (node )); 254 } 255 } 256 257return GGML_STATUS_SUCCESS ; 258 259GGML_UNUSED (backend ); 260} 261 262static struct ggml_backend_i blas_backend_i = { 263/* .get_name = */ ggml_backend_blas_get_name , 264/* .free = */ ggml_backend_blas_free , 265/* .set_tensor_async = */ NULL , 266/* .get_tensor_async = */ NULL , 267/* .set_tensor_2d_async = */ NULL , 268/* .get_tensor_2d_async = */ NULL , 269/* .cpy_tensor_async = */ NULL , 270/* .synchronize = */ NULL , 271/* .graph_plan_create = */ NULL , 272/* .graph_plan_free = */ NULL , 273/* .graph_plan_update = */ NULL , 274/* .graph_plan_compute = */ NULL , 275/* .graph_compute = */ ggml_backend_blas_graph_compute , 276/* .event_record = */ NULL , 277/* .event_wait = */ NULL , 278/* .graph_optimize = */ NULL , 279}; 280 281static ggml_guid_t ggml_backend_blas_guid (void ) { 282static ggml_guid guid = {0x12 ,0xa8 ,0xae ,0xf4 ,0xc0 ,0x1e ,0x61 ,0x97 ,0x8f ,0xeb ,0x33 ,0x04 ,0xa1 ,0x33 ,0x51 ,0x2d }; 283return & guid ; 284} 285 286ggml_backend_t ggml_backend_blas_init (void ) { 287ggml_backend_blas_context * ctx = new ggml_backend_blas_context ; 288 289ggml_backend_t backend = new ggml_backend { 290/* .guid = */ ggml_backend_blas_guid (), 291/* .iface = */ blas_backend_i , 292/* .device = */ ggml_backend_reg_dev_get (ggml_backend_blas_reg (),0 ), 293/* .context = */ ctx , 294 }; 295 296#if defined(GGML_BLAS_USE_OPENBLAS )&& defined(GGML_USE_OPENMP ) 297if (openblas_get_parallel ()!= OPENBLAS_OPENMP ) { 298GGML_LOG_DEBUG ("%s: warning: ggml is using OpenMP, but OpenBLAS was compiled without OpenMP support\n" ,__func__ ); 299 } 300#endif 301 302#if defined(BLIS_ENABLE_CBLAS )&& defined(GGML_USE_OPENMP )&& !defined(BLIS_ENABLE_OPENMP ) 303GGML_LOG_DEBUG ("%s: warning: ggml is using OpenMP, but BLIS was compiled without OpenMP support\n" ,__func__ ); 304#endif 305 306return backend ; 307} 308 309bool ggml_backend_is_blas (ggml_backend_t backend ) { 310return backend != NULL && ggml_guid_matches (backend -> guid ,ggml_backend_blas_guid ()); 311} 312 313void ggml_backend_blas_set_n_threads (ggml_backend_t backend_blas ,int n_threads ) { 314GGML_ASSERT (ggml_backend_is_blas (backend_blas )); 315 316ggml_backend_blas_context * ctx = (ggml_backend_blas_context * )backend_blas -> context ; 317ctx -> n_threads = n_threads ; 318} 319 320// device interface 321 322static const char * ggml_backend_blas_device_get_name (ggml_backend_dev_t dev ) { 323return "BLAS" ; 324 325GGML_UNUSED (dev ); 326} 327 328static const char * ggml_backend_blas_device_get_description (ggml_backend_dev_t dev ) { 329#if defined(GGML_BLAS_USE_ACCELERATE ) 330return "Accelerate" ; 331#elif defined(GGML_BLAS_USE_MKL ) 332return "MKL" ; 333#elif defined(GGML_BLAS_USE_BLIS ) 334return "BLIS" ; 335#elif defined(GGML_BLAS_USE_NVPL ) 336return "NVPL" ; 337#elif defined(GGML_BLAS_USE_OPENBLAS ) 338return "OpenBLAS" ; 339#else 340return "BLAS" ; 341#endif 342 343GGML_UNUSED (dev ); 344} 345 346static void ggml_backend_blas_device_get_memory (ggml_backend_dev_t dev ,size_t * free ,size_t * total ) { 347// no memory to report 348* free = 0 ; 349* total = 0 ; 350 351GGML_UNUSED (dev ); 352} 353 354static enum ggml_backend_dev_type ggml_backend_blas_device_get_type (ggml_backend_dev_t dev ) { 355return GGML_BACKEND_DEVICE_TYPE_ACCEL ; 356 357GGML_UNUSED (dev ); 358} 359 360static void ggml_backend_blas_device_get_props (ggml_backend_dev_t dev ,struct ggml_backend_dev_props * props ) { 361props -> name = ggml_backend_blas_device_get_name (dev ); 362props -> description = ggml_backend_blas_device_get_description (dev ); 363props -> type = ggml_backend_blas_device_get_type (dev ); 364ggml_backend_blas_device_get_memory (dev ,& props -> memory_free ,& props -> memory_total ); 365props -> caps = { 366/* .async = */ false, 367/* .host_buffer = */ false, 368/* .buffer_from_host_ptr = */ true, 369/* .events = */ false, 370/* .mmap_support = */ true, 371 }; 372} 373 374static ggml_backend_t ggml_backend_blas_device_init_backend (ggml_backend_dev_t dev ,const char * params ) { 375return ggml_backend_blas_init (); 376 377GGML_UNUSED (dev ); 378GGML_UNUSED (params ); 379} 380 381static ggml_backend_buffer_type_t ggml_backend_blas_device_get_buffer_type (ggml_backend_dev_t dev ) { 382return ggml_backend_cpu_buffer_type (); 383 384GGML_UNUSED (dev ); 385} 386 387static ggml_backend_buffer_t ggml_backend_blas_device_buffer_from_host_ptr (ggml_backend_dev_t dev ,void * ptr ,size_t size ,size_t max_tensor_size ) { 388return ggml_backend_cpu_buffer_from_ptr (ptr ,size ); 389 390GGML_UNUSED (dev ); 391GGML_UNUSED (max_tensor_size ); 392} 393 394static bool ggml_backend_blas_device_supports_op (ggml_backend_dev_t dev ,const struct ggml_tensor * op ) { 395const struct ggml_tensor * src0 = op -> src [0 ]; 396const struct ggml_tensor * src1 = op -> src [1 ]; 397 398switch (op -> op ) { 399case GGML_OP_NONE : 400case GGML_OP_RESHAPE : 401case GGML_OP_VIEW : 402case GGML_OP_PERMUTE : 403case GGML_OP_TRANSPOSE : 404return true; 405 406case GGML_OP_MUL_MAT : 407 { 408// BLAS usually is only faster for large matrices 409const struct ggml_tensor * src0 = op -> src [0 ]; 410const struct ggml_tensor * src1 = op -> src [1 ]; 411 412const int64_t ne10 = src1 -> ne [0 ]; 413 414const int64_t ne0 = op -> ne [0 ]; 415const int64_t ne1 = op -> ne [1 ]; 416 417// TODO: find the optimal value 418const int64_t min_batch = 32 ; 419 420// default back to CPU fast path 421// see: https://github.com/ggml-org/llama.cpp/issues/25565 422if (ggml_get_op_params_i32 (op ,1 )== GGML_HINT_SRC0_IS_HADAMARD ) { 423return false; 424 } 425 426return ggml_is_contiguous (src0 )&& 427ggml_is_contiguous (src1 )&& 428src1 -> type == GGML_TYPE_F32 && 429 (ne0 >=min_batch && ne1 >=min_batch && ne10 >=min_batch )&& 430 (src0 -> type == GGML_TYPE_F32 || ggml_get_type_traits (src0 -> type )-> to_float != NULL ); 431 } 432 433case GGML_OP_OUT_PROD : 434return op -> src [0 ]-> type == GGML_TYPE_F32 && 435op -> src [1 ]-> type == GGML_TYPE_F32 && 436ggml_is_matrix (src0 )&& 437ggml_is_matrix (src1 )&& 438ggml_is_contiguous (src0 )&& 439 (ggml_is_contiguous (src1 )|| ggml_is_transposed (src1 ))&& 440 (src0 -> type == GGML_TYPE_F32 || ggml_get_type_traits (src0 -> type )-> to_float != NULL ); 441 442default : 443return false; 444 445 } 446 447GGML_UNUSED (dev ); 448} 449 450static bool ggml_backend_blas_device_supports_buft (ggml_backend_dev_t dev ,ggml_backend_buffer_type_t buft ) { 451return ggml_backend_buft_is_host (buft ); 452 453GGML_UNUSED (dev ); 454} 455 456static const struct ggml_backend_device_i ggml_backend_blas_device_i = { 457/* .get_name = */ ggml_backend_blas_device_get_name , 458/* .get_description = */ ggml_backend_blas_device_get_description , 459/* .get_memory = */ ggml_backend_blas_device_get_memory , 460/* .get_type = */ ggml_backend_blas_device_get_type , 461/* .get_props = */ ggml_backend_blas_device_get_props , 462/* .init_backend = */ ggml_backend_blas_device_init_backend , 463/* .get_buffer_type = */ ggml_backend_blas_device_get_buffer_type , 464/* .get_host_buffer_type = */ NULL , 465/* .buffer_from_host_ptr = */ ggml_backend_blas_device_buffer_from_host_ptr , 466/* .supports_op = */ ggml_backend_blas_device_supports_op , 467/* .supports_buft = */ ggml_backend_blas_device_supports_buft , 468/* .offload_op = */ NULL , 469/* .event_new = */ NULL , 470/* .event_free = */ NULL , 471/* .event_synchronize = */ NULL , 472}; 473 474// backend reg interface 475 476static const char * ggml_backend_blas_reg_get_name (ggml_backend_reg_t reg ) { 477return "BLAS" ; 478 479GGML_UNUSED (reg ); 480} 481 482static size_t ggml_backend_blas_reg_get_device_count (ggml_backend_reg_t reg ) { 483return 1 ; 484 485GGML_UNUSED (reg ); 486} 487 488static ggml_backend_dev_t ggml_backend_blas_reg_get_device (ggml_backend_reg_t reg ,size_t index ) { 489GGML_ASSERT (index == 0 ); 490 491static ggml_backend_device ggml_backend_blas_device = { 492/* .iface = */ ggml_backend_blas_device_i , 493/* .reg = */ reg , 494/* .context = */ nullptr , 495 }; 496 497return & ggml_backend_blas_device ; 498 499GGML_UNUSED (reg ); 500GGML_UNUSED (index ); 501} 502 503static void * ggml_backend_blas_get_proc_address (ggml_backend_reg_t reg ,const char * name ) { 504if (std::strcmp (name ,"ggml_backend_set_n_threads" )== 0 ) { 505return (void * )ggml_backend_blas_set_n_threads ; 506 } 507return NULL ; 508 509GGML_UNUSED (reg ); 510GGML_UNUSED (name ); 511} 512 513static const struct ggml_backend_reg_i ggml_backend_blas_reg_i = { 514/* .get_name = */ ggml_backend_blas_reg_get_name , 515/* .get_device_count = */ ggml_backend_blas_reg_get_device_count , 516/* .get_device = */ ggml_backend_blas_reg_get_device , 517/* .get_proc_address = */ ggml_backend_blas_get_proc_address , 518}; 519 520ggml_backend_reg_t ggml_backend_blas_reg (void ) { 521static struct ggml_backend_reg ggml_backend_blas_reg = { 522/* .api_version = */ GGML_BACKEND_API_VERSION , 523/* .iface = */ ggml_backend_blas_reg_i , 524/* .context = */ NULL , 525 }; 526 527return & ggml_backend_blas_reg ; 528} 529 530GGML_BACKEND_DL_IMPL (ggml_backend_blas_reg )