char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
43f3dda62
char/aliceai-t5-moe
1// Note: porting this file to C++ is a work in progress 2 3#ifdef _WIN32 4#define WIN32_LEAN_AND_MEAN 5#ifndef NOMINMAX 6# define NOMINMAX 7#endif 8#include <windows.h> 9#endif 10 11#include "ggml-backend.h" 12#include "ggml-backend-impl.h" 13#include "ggml-alloc.h" 14#include "ggml-impl.h" 15 16#include <assert.h> 17#include <limits.h> 18#include <stdarg.h> 19#include <stdio.h> 20#include <stdlib.h> 21#include <string.h> 22#include <algorithm> 23#include <unordered_map> 24#include <vector> 25 26#ifdef __APPLE__ 27#include <sys/types.h> 28#include <sys/sysctl.h> 29#endif 30 31 32// backend buffer type 33 34const char * ggml_backend_buft_name (ggml_backend_buffer_type_t buft ) { 35GGML_ASSERT (buft ); 36return buft -> iface .get_name (buft ); 37} 38 39ggml_backend_buffer_t ggml_backend_buft_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ) { 40GGML_ASSERT (buft ); 41if (size == 0 ) { 42// return a dummy buffer for zero-sized allocations 43return ggml_backend_buffer_init (buft , {},NULL ,0 ); 44 } 45return buft -> iface .alloc_buffer (buft ,size ); 46} 47 48size_t ggml_backend_buft_get_alignment (ggml_backend_buffer_type_t buft ) { 49GGML_ASSERT (buft ); 50return buft -> iface .get_alignment (buft ); 51} 52 53size_t ggml_backend_buft_get_max_size (ggml_backend_buffer_type_t buft ) { 54GGML_ASSERT (buft ); 55// get_max_size is optional, defaults to SIZE_MAX 56if (buft -> iface .get_max_size ) { 57return buft -> iface .get_max_size (buft ); 58 } 59return SIZE_MAX ; 60} 61 62size_t ggml_backend_buft_get_alloc_size (ggml_backend_buffer_type_t buft ,const struct ggml_tensor * tensor ) { 63GGML_ASSERT (buft ); 64// get_alloc_size is optional, defaults to ggml_nbytes 65if (buft -> iface .get_alloc_size ) { 66size_t size = buft -> iface .get_alloc_size (buft ,tensor ); 67assert (size >=ggml_nbytes (tensor )); 68 69// [TAG_ALLOC_SIZE_EXPAND] 70// if you hit this assert, update ggml_backend_op_alloc_size_may_expand() accordingly 71GGML_ASSERT (size <=ggml_nbytes (tensor )|| 72ggml_op_is_empty (tensor -> op )|| 73ggml_is_quantized (tensor -> type )|| // [TAG_ALLOC_SIZE_EXPAND] 74ggml_op_alloc_size_may_expand (tensor -> op )); 75 76return size ; 77 } 78return ggml_nbytes (tensor ); 79} 80 81bool ggml_backend_buft_is_host (ggml_backend_buffer_type_t buft ) { 82GGML_ASSERT (buft ); 83if (buft -> iface .is_host ) { 84return buft -> iface .is_host (buft ); 85 } 86return false; 87} 88 89ggml_backend_dev_t ggml_backend_buft_get_device (ggml_backend_buffer_type_t buft ) { 90GGML_ASSERT (buft ); 91return buft -> device ; 92} 93 94// backend buffer 95 96ggml_backend_buffer_t ggml_backend_buffer_init ( 97ggml_backend_buffer_type_t buft , 98struct ggml_backend_buffer_i iface , 99void * context , 100size_t size ) { 101ggml_backend_buffer_t buffer = new ggml_backend_buffer { 102/* .interface = */ iface , 103/* .buft = */ buft , 104/* .context = */ context , 105/* .size = */ size , 106/* .usage = */ GGML_BACKEND_BUFFER_USAGE_ANY 107 }; 108 109return buffer ; 110} 111 112const char * ggml_backend_buffer_name (ggml_backend_buffer_t buffer ) { 113return ggml_backend_buft_name (ggml_backend_buffer_get_type (buffer )); 114} 115 116void ggml_backend_buffer_free (ggml_backend_buffer_t buffer ) { 117if (buffer == NULL ) { 118return ; 119 } 120 121if (buffer -> iface .free_buffer != NULL ) { 122buffer -> iface .free_buffer (buffer ); 123 } 124delete buffer ; 125} 126 127size_t ggml_backend_buffer_get_size (ggml_backend_buffer_t buffer ) { 128GGML_ASSERT (buffer ); 129return buffer -> size ; 130} 131 132void * ggml_backend_buffer_get_base (ggml_backend_buffer_t buffer ) { 133GGML_ASSERT (buffer ); 134// get_base is optional if the buffer is zero-sized 135if (!ggml_backend_buffer_is_meta (buffer )&& buffer -> size == 0 ) { 136return NULL ; 137 } 138 139// FIXME JG: a multi_buffer has a non-zero size, according to the above comment get_base is not optional, 140// I don't know whether the above comment is correct 141if (!buffer -> iface .get_base ) { 142return NULL ; 143 } 144 145void * base = buffer -> iface .get_base (buffer ); 146 147GGML_ASSERT (base != NULL && "backend buffer base cannot be NULL" ); 148 149return base ; 150} 151 152enum ggml_status ggml_backend_buffer_init_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ) { 153GGML_ASSERT (buffer ); 154// init_tensor is optional 155if (buffer -> iface .init_tensor ) { 156return buffer -> iface .init_tensor (buffer ,tensor ); 157 } 158return GGML_STATUS_SUCCESS ; 159} 160 161void ggml_backend_buffer_clear (ggml_backend_buffer_t buffer ,uint8_t value ) { 162GGML_ASSERT (buffer ); 163// clear is optional if the buffer is zero-sized 164if (buffer -> size == 0 ) { 165return ; 166 } 167 168buffer -> iface .clear (buffer ,value ); 169} 170 171size_t ggml_backend_buffer_get_alignment (ggml_backend_buffer_t buffer ) { 172return ggml_backend_buft_get_alignment (ggml_backend_buffer_get_type (buffer )); 173} 174 175size_t ggml_backend_buffer_get_max_size (ggml_backend_buffer_t buffer ) { 176return ggml_backend_buft_get_max_size (ggml_backend_buffer_get_type (buffer )); 177} 178 179size_t ggml_backend_buffer_get_alloc_size (ggml_backend_buffer_t buffer ,const struct ggml_tensor * tensor ) { 180return ggml_backend_buft_get_alloc_size (ggml_backend_buffer_get_type (buffer ),tensor ); 181} 182 183bool ggml_backend_buffer_is_host (ggml_backend_buffer_t buffer ) { 184return ggml_backend_buft_is_host (ggml_backend_buffer_get_type (buffer )); 185} 186 187void ggml_backend_buffer_set_usage (ggml_backend_buffer_t buffer ,enum ggml_backend_buffer_usage usage ) { 188GGML_ASSERT (buffer ); 189buffer -> usage = usage ; 190 191// FIXME: add a generic callback to the buffer interface 192if (ggml_backend_buffer_is_multi_buffer (buffer )) { 193ggml_backend_multi_buffer_set_usage (buffer ,usage ); 194 }else if (ggml_backend_buffer_is_meta (buffer )) { 195ggml_backend_meta_buffer_set_usage (buffer ,usage ); 196 } 197} 198 199enum ggml_backend_buffer_usage ggml_backend_buffer_get_usage (ggml_backend_buffer_t buffer ) { 200GGML_ASSERT (buffer ); 201return buffer -> usage ; 202} 203 204ggml_backend_buffer_type_t ggml_backend_buffer_get_type (ggml_backend_buffer_t buffer ) { 205GGML_ASSERT (buffer ); 206return buffer -> buft ; 207} 208 209void ggml_backend_buffer_reset (ggml_backend_buffer_t buffer ) { 210GGML_ASSERT (buffer ); 211if (buffer -> iface .reset ) { 212buffer -> iface .reset (buffer ); 213 } 214} 215 216bool ggml_backend_buffer_copy_tensor (const struct ggml_tensor * src ,struct ggml_tensor * dst ) { 217ggml_backend_buffer_t dst_buf = dst -> view_src ?dst -> view_src -> buffer :dst -> buffer ; 218if (dst_buf -> iface .cpy_tensor ) { 219return dst_buf -> iface .cpy_tensor (dst_buf ,src ,dst ); 220 } 221return false; 222} 223 224// backend 225 226ggml_guid_t ggml_backend_guid (ggml_backend_t backend ) { 227if (backend == NULL ) { 228return NULL ; 229 } 230return backend -> guid ; 231} 232 233const char * ggml_backend_name (ggml_backend_t backend ) { 234if (backend == NULL ) { 235return "NULL" ; 236 } 237return backend -> iface .get_name (backend ); 238} 239 240void ggml_backend_free (ggml_backend_t backend ) { 241if (backend == NULL ) { 242return ; 243 } 244 245backend -> iface .free (backend ); 246} 247 248ggml_backend_buffer_type_t ggml_backend_get_default_buffer_type (ggml_backend_t backend ) { 249GGML_ASSERT (backend ); 250return ggml_backend_dev_buffer_type (backend -> device ); 251} 252 253ggml_backend_buffer_t ggml_backend_alloc_buffer (ggml_backend_t backend ,size_t size ) { 254return ggml_backend_buft_alloc_buffer (ggml_backend_get_default_buffer_type (backend ),size ); 255} 256 257size_t ggml_backend_get_alignment (ggml_backend_t backend ) { 258return ggml_backend_buft_get_alignment (ggml_backend_get_default_buffer_type (backend )); 259} 260 261size_t ggml_backend_get_max_size (ggml_backend_t backend ) { 262return ggml_backend_buft_get_max_size (ggml_backend_get_default_buffer_type (backend )); 263} 264 265void ggml_backend_tensor_set_async (ggml_backend_t backend ,struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ) { 266GGML_ASSERT (backend ); 267GGML_ASSERT (tensor ); 268GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 269GGML_ASSERT (offset + size <=ggml_nbytes (tensor )&& "tensor write out of bounds" ); 270 271if (backend -> iface .set_tensor_async == NULL ) { 272ggml_backend_synchronize (backend ); 273ggml_backend_tensor_set (tensor ,data ,offset ,size ); 274 }else { 275backend -> iface .set_tensor_async (backend ,tensor ,data ,offset ,size ); 276 } 277} 278 279void ggml_backend_tensor_get_async (ggml_backend_t backend ,const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ) { 280GGML_ASSERT (backend ); 281GGML_ASSERT (tensor ); 282GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 283GGML_ASSERT (offset + size <=ggml_nbytes (tensor )&& "tensor read out of bounds" ); 284 285if (backend -> iface .get_tensor_async == NULL ) { 286ggml_backend_synchronize (backend ); 287ggml_backend_tensor_get (tensor ,data ,offset ,size ); 288 }else { 289backend -> iface .get_tensor_async (backend ,tensor ,data ,offset ,size ); 290 } 291} 292 293void ggml_backend_tensor_set_2d_async (ggml_backend_t backend ,struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size , 294size_t n_copies ,size_t stride_tensor ,size_t stride_data ) { 295GGML_ASSERT (backend ); 296GGML_ASSERT (tensor ); 297GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 298 299if (n_copies <=1 || backend -> iface .set_tensor_2d_async == NULL ) { 300for (size_t i = 0 ;i < n_copies ;i ++ ) { 301ggml_backend_tensor_set_async (backend ,tensor , (const char * )data + i * stride_data ,offset + i * stride_tensor ,size ); 302 } 303return ; 304 } 305if (size == 0 ) { 306return ; 307 } 308 309GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 310GGML_ASSERT (offset + (n_copies - 1 )* stride_tensor + size <=ggml_nbytes (tensor )&& "tensor write out of bounds" ); 311backend -> iface .set_tensor_2d_async (backend ,tensor ,data ,offset ,size ,n_copies ,stride_tensor ,stride_data ); 312} 313 314void ggml_backend_tensor_get_2d_async (ggml_backend_t backend ,const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size , 315size_t n_copies ,size_t stride_tensor ,size_t stride_data ) { 316GGML_ASSERT (backend ); 317GGML_ASSERT (tensor ); 318GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 319 320if (n_copies <=1 || backend -> iface .get_tensor_2d_async == NULL ) { 321for (size_t i = 0 ;i < n_copies ;i ++ ) { 322ggml_backend_tensor_get_async (backend ,tensor , (char * )data + i * stride_data ,offset + i * stride_tensor ,size ); 323 } 324return ; 325 } 326if (size == 0 ) { 327return ; 328 } 329 330GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 331GGML_ASSERT (offset + (n_copies - 1 )* stride_tensor + size <=ggml_nbytes (tensor )&& "tensor read out of bounds" ); 332backend -> iface .get_tensor_2d_async (backend ,tensor ,data ,offset ,size ,n_copies ,stride_tensor ,stride_data ); 333} 334 335void ggml_backend_tensor_set (struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ) { 336GGML_ASSERT (tensor ); 337ggml_backend_buffer_t buf = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 338GGML_ASSERT (buf != NULL && "tensor buffer not set" ); 339 340if (size == 0 ) { 341return ; 342 } 343 344GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 345GGML_ASSERT (offset + size <=ggml_nbytes (tensor )&& "tensor write out of bounds" ); 346 347buf -> iface .set_tensor (buf ,tensor ,data ,offset ,size ); 348} 349 350void ggml_backend_tensor_get (const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ) { 351GGML_ASSERT (tensor ); 352ggml_backend_buffer_t buf = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 353GGML_ASSERT (buf != NULL && "tensor buffer not set" ); 354 355if (size == 0 ) { 356return ; 357 } 358 359GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 360GGML_ASSERT (offset + size <=ggml_nbytes (tensor )&& "tensor read out of bounds" ); 361 362buf -> iface .get_tensor (buf ,tensor ,data ,offset ,size ); 363} 364 365void ggml_backend_tensor_set_2d (struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size , 366size_t n_copies ,size_t stride_tensor ,size_t stride_data ) { 367GGML_ASSERT (tensor ); 368ggml_backend_buffer_t buf = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 369GGML_ASSERT (buf != NULL && "tensor buffer not set" ); 370 371if (n_copies <=1 || buf -> iface .set_tensor_2d == NULL ) { 372for (size_t i = 0 ;i < n_copies ;i ++ ) { 373ggml_backend_tensor_set (tensor , (const char * )data + i * stride_data ,offset + i * stride_tensor ,size ); 374 } 375return ; 376 } 377if (size == 0 ) { 378return ; 379 } 380 381GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 382GGML_ASSERT (offset + (n_copies - 1 )* stride_tensor + size <=ggml_nbytes (tensor )&& "tensor write out of bounds" ); 383 384buf -> iface .set_tensor_2d (buf ,tensor ,data ,offset ,size ,n_copies ,stride_tensor ,stride_data ); 385} 386 387void ggml_backend_tensor_get_2d (const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size , 388size_t n_copies ,size_t stride_tensor ,size_t stride_data ) { 389GGML_ASSERT (tensor ); 390ggml_backend_buffer_t buf = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 391GGML_ASSERT (buf != NULL && "tensor buffer not set" ); 392 393if (n_copies <=1 || buf -> iface .get_tensor_2d == NULL ) { 394for (size_t i = 0 ;i < n_copies ;i ++ ) { 395ggml_backend_tensor_get (tensor , (char * )data + i * stride_data ,offset + i * stride_tensor ,size ); 396 } 397return ; 398 } 399if (size == 0 ) { 400return ; 401 } 402 403GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 404GGML_ASSERT (offset + (n_copies - 1 )* stride_tensor + size <=ggml_nbytes (tensor )&& "tensor read out of bounds" ); 405 406buf -> iface .get_tensor_2d (buf ,tensor ,data ,offset ,size ,n_copies ,stride_tensor ,stride_data ); 407} 408 409void ggml_backend_tensor_memset (struct ggml_tensor * tensor ,uint8_t value ,size_t offset ,size_t size ) { 410GGML_ASSERT (tensor ); 411ggml_backend_buffer_t buf = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 412 413if (size == 0 ) { 414return ; 415 } 416 417GGML_ASSERT (buf != NULL && "tensor buffer not set" ); 418GGML_ASSERT (tensor -> data != NULL && "tensor not allocated" ); 419GGML_ASSERT (offset + size <=ggml_nbytes (tensor )&& "tensor write out of bounds" ); 420GGML_ASSERT (buf -> iface .memset_tensor != NULL && "memset not implemented by backend buffer" ); 421 422buf -> iface .memset_tensor (buf ,tensor ,value ,offset ,size ); 423} 424 425void ggml_backend_synchronize (ggml_backend_t backend ) { 426GGML_ASSERT (backend ); 427if (backend -> iface .synchronize == NULL ) { 428return ; 429 } 430 431backend -> iface .synchronize (backend ); 432} 433 434ggml_backend_graph_plan_t ggml_backend_graph_plan_create (ggml_backend_t backend ,struct ggml_cgraph * cgraph ) { 435GGML_ASSERT (backend ); 436GGML_ASSERT (backend -> iface .graph_plan_create != NULL ); 437 438return backend -> iface .graph_plan_create (backend ,cgraph ); 439} 440 441void ggml_backend_graph_plan_free (ggml_backend_t backend ,ggml_backend_graph_plan_t plan ) { 442GGML_ASSERT (backend ); 443GGML_ASSERT (backend -> iface .graph_plan_free != NULL ); 444 445backend -> iface .graph_plan_free (backend ,plan ); 446} 447 448enum ggml_status ggml_backend_graph_plan_compute (ggml_backend_t backend ,ggml_backend_graph_plan_t plan ) { 449GGML_ASSERT (backend ); 450GGML_ASSERT (backend -> iface .graph_plan_compute != NULL ); 451 452return backend -> iface .graph_plan_compute (backend ,plan ); 453} 454 455enum ggml_status ggml_backend_graph_compute (ggml_backend_t backend ,struct ggml_cgraph * cgraph ) { 456enum ggml_status err = ggml_backend_graph_compute_async (backend ,cgraph ); 457ggml_backend_synchronize (backend ); 458return err ; 459} 460 461enum ggml_status ggml_backend_graph_compute_async (ggml_backend_t backend ,struct ggml_cgraph * cgraph ) { 462GGML_ASSERT (backend ); 463return backend -> iface .graph_compute (backend ,cgraph ); 464} 465 466bool ggml_backend_supports_op (ggml_backend_t backend ,const struct ggml_tensor * op ) { 467GGML_ASSERT (backend ); 468return ggml_backend_dev_supports_op (backend -> device ,op ); 469} 470 471bool ggml_backend_supports_buft (ggml_backend_t backend ,ggml_backend_buffer_type_t buft ) { 472GGML_ASSERT (backend ); 473return ggml_backend_dev_supports_buft (backend -> device ,buft ); 474} 475 476bool ggml_backend_offload_op (ggml_backend_t backend ,const struct ggml_tensor * op ) { 477GGML_ASSERT (backend ); 478return ggml_backend_dev_offload_op (backend -> device ,op ); 479} 480 481ggml_backend_dev_t ggml_backend_get_device (ggml_backend_t backend ) { 482GGML_ASSERT (backend ); 483return backend -> device ; 484} 485 486// backend copy 487 488void ggml_backend_tensor_copy (const struct ggml_tensor * src ,struct ggml_tensor * dst ) { 489GGML_ASSERT (ggml_are_same_layout (src ,dst )&& "cannot copy tensors with different layouts" ); 490 491if (src == dst ) { 492return ; 493 } 494 495if (ggml_backend_buffer_is_host (src -> buffer )) { 496ggml_backend_tensor_set (dst ,src -> data ,0 ,ggml_nbytes (src )); 497 }else if (ggml_backend_buffer_is_host (dst -> buffer )) { 498ggml_backend_tensor_get (src ,dst -> data ,0 ,ggml_nbytes (src )); 499 }else if (!ggml_backend_buffer_copy_tensor (src ,dst )) { 500#ifndef NDEBUG 501GGML_LOG_DEBUG ("%s: warning: slow copy from %s to %s\n" ,__func__ ,ggml_backend_buffer_name (src -> buffer ),ggml_backend_buffer_name (dst -> buffer )); 502#endif // NDEBUG 503size_t nbytes = ggml_nbytes (src ); 504void * data = malloc (nbytes ); 505ggml_backend_tensor_get (src ,data ,0 ,nbytes ); 506ggml_backend_tensor_set (dst ,data ,0 ,nbytes ); 507free (data ); 508 } 509} 510 511void ggml_backend_tensor_copy_async (ggml_backend_t backend_src ,ggml_backend_t backend_dst ,const struct ggml_tensor * src ,struct ggml_tensor * dst ) { 512GGML_ASSERT (ggml_are_same_layout (src ,dst )&& "cannot copy tensors with different layouts" ); 513 514if (src == dst ) { 515return ; 516 } 517 518GGML_ASSERT (backend_dst ); 519if (backend_dst -> iface .cpy_tensor_async != NULL ) { 520if (backend_dst -> iface .cpy_tensor_async (backend_src ,backend_dst ,src ,dst )) { 521return ; 522 } 523 } 524 525// an async copy would normally happen after all the queued operations on both backends are completed 526// to simulate the same behavior, we need to synchronize both backends first, and do a blocking copy 527ggml_backend_synchronize (backend_src ); 528ggml_backend_synchronize (backend_dst ); 529ggml_backend_tensor_copy (src ,dst ); 530} 531 532// events 533 534ggml_backend_event_t ggml_backend_event_new (ggml_backend_dev_t device ) { 535// null device is allowed for the transition period to the device interface 536if (device == NULL || device -> iface .event_new == NULL ) { 537return NULL ; 538 } 539return device -> iface .event_new (device ); 540} 541 542void ggml_backend_event_free (ggml_backend_event_t event ) { 543if (event == NULL ) { 544return ; 545 } 546event -> device -> iface .event_free (event -> device ,event ); 547} 548 549void ggml_backend_event_record (ggml_backend_event_t event ,ggml_backend_t backend ) { 550GGML_ASSERT (backend ); 551GGML_ASSERT (backend -> iface .event_record != NULL ); 552 553backend -> iface .event_record (backend ,event ); 554} 555 556void ggml_backend_event_synchronize (ggml_backend_event_t event ) { 557GGML_ASSERT (event ); 558GGML_ASSERT (event -> device -> iface .event_synchronize ); 559 560event -> device -> iface .event_synchronize (event -> device ,event ); 561} 562 563void ggml_backend_event_wait (ggml_backend_t backend ,ggml_backend_event_t event ) { 564GGML_ASSERT (backend ); 565GGML_ASSERT (backend -> iface .event_wait != NULL ); 566 567backend -> iface .event_wait (backend ,event ); 568} 569 570static void ggml_backend_graph_optimize (ggml_backend_t backend ,struct ggml_cgraph * cgraph ,struct ggml_backend_graph_optimize_params * params ) { 571GGML_ASSERT (backend ); 572if (backend -> iface .graph_optimize != NULL ) { 573backend -> iface .graph_optimize (backend ,cgraph ,params ); 574 } 575} 576 577// Backend device 578 579const char * ggml_backend_dev_name (ggml_backend_dev_t device ) { 580GGML_ASSERT (device ); 581return device -> iface .get_name (device ); 582} 583 584const char * ggml_backend_dev_description (ggml_backend_dev_t device ) { 585GGML_ASSERT (device ); 586return device -> iface .get_description (device ); 587} 588 589void ggml_backend_dev_memory (ggml_backend_dev_t device ,size_t * free ,size_t * total ) { 590GGML_ASSERT (device ); 591device -> iface .get_memory (device ,free ,total ); 592} 593 594enum ggml_backend_dev_type ggml_backend_dev_type (ggml_backend_dev_t device ) { 595GGML_ASSERT (device ); 596return device -> iface .get_type (device ); 597} 598 599void ggml_backend_dev_get_props (ggml_backend_dev_t device ,struct ggml_backend_dev_props * props ) { 600GGML_ASSERT (device ); 601memset (props ,0 ,sizeof (* props )); 602device -> iface .get_props (device ,props ); 603} 604 605ggml_backend_reg_t ggml_backend_dev_backend_reg (ggml_backend_dev_t device ) { 606GGML_ASSERT (device ); 607return device -> reg ; 608} 609 610ggml_backend_t ggml_backend_dev_init (ggml_backend_dev_t device ,const char * params ) { 611GGML_ASSERT (device ); 612return device -> iface .init_backend (device ,params ); 613} 614 615ggml_backend_buffer_type_t ggml_backend_dev_buffer_type (ggml_backend_dev_t device ) { 616GGML_ASSERT (device ); 617return device -> iface .get_buffer_type (device ); 618} 619 620ggml_backend_buffer_type_t ggml_backend_dev_host_buffer_type (ggml_backend_dev_t device ) { 621GGML_ASSERT (device ); 622if (device -> iface .get_host_buffer_type == NULL ) { 623return NULL ; 624 } 625 626return device -> iface .get_host_buffer_type (device ); 627} 628 629ggml_backend_buffer_t ggml_backend_dev_buffer_from_host_ptr (ggml_backend_dev_t device ,void * ptr ,size_t size ,size_t max_tensor_size ) { 630GGML_ASSERT (device ); 631return device -> iface .buffer_from_host_ptr (device ,ptr ,size ,max_tensor_size ); 632} 633 634bool ggml_backend_dev_supports_op (ggml_backend_dev_t device ,const struct ggml_tensor * op ) { 635GGML_ASSERT (device ); 636return device -> iface .supports_op (device ,op ); 637} 638 639bool ggml_backend_dev_supports_buft (ggml_backend_dev_t device ,ggml_backend_buffer_type_t buft ) { 640GGML_ASSERT (device ); 641return device -> iface .supports_buft (device ,buft ); 642} 643 644bool ggml_backend_dev_offload_op (ggml_backend_dev_t device ,const struct ggml_tensor * op ) { 645GGML_ASSERT (device ); 646if (device -> iface .offload_op != NULL ) { 647return device -> iface .offload_op (device ,op ); 648 } 649 650return false; 651} 652 653// Backend (reg) 654 655const char * ggml_backend_reg_name (ggml_backend_reg_t reg ) { 656GGML_ASSERT (reg ); 657return reg -> iface .get_name (reg ); 658} 659 660size_t ggml_backend_reg_dev_count (ggml_backend_reg_t reg ) { 661GGML_ASSERT (reg ); 662return reg -> iface .get_device_count (reg ); 663} 664 665ggml_backend_dev_t ggml_backend_reg_dev_get (ggml_backend_reg_t reg ,size_t index ) { 666GGML_ASSERT (reg ); 667return reg -> iface .get_device (reg ,index ); 668} 669 670void * ggml_backend_reg_get_proc_address (ggml_backend_reg_t reg ,const char * name ) { 671GGML_ASSERT (reg ); 672if (!reg -> iface .get_proc_address ) { 673return NULL ; 674 } 675return reg -> iface .get_proc_address (reg ,name ); 676} 677 678// multi-buffer buffer 679 680struct ggml_backend_multi_buffer_context { 681ggml_backend_buffer_t * buffers ; 682size_t n_buffers ; 683}; 684 685static void ggml_backend_multi_buffer_free_buffer (ggml_backend_buffer_t buffer ) { 686GGML_ASSERT (buffer ); 687ggml_backend_multi_buffer_context * ctx = (ggml_backend_multi_buffer_context * )buffer -> context ; 688for (size_t i = 0 ;i < ctx -> n_buffers ;i ++ ) { 689ggml_backend_buffer_free (ctx -> buffers [i ]); 690 } 691 692free (ctx -> buffers ); 693free (ctx ); 694} 695 696static void ggml_backend_multi_buffer_clear (ggml_backend_buffer_t buffer ,uint8_t value ) { 697GGML_ASSERT (buffer ); 698ggml_backend_multi_buffer_context * ctx = (ggml_backend_multi_buffer_context * )buffer -> context ; 699for (size_t i = 0 ;i < ctx -> n_buffers ;i ++ ) { 700ggml_backend_buffer_clear (ctx -> buffers [i ],value ); 701 } 702} 703 704static const struct ggml_backend_buffer_i ggml_backend_multi_buffer_i = { 705/* .free_buffer = */ ggml_backend_multi_buffer_free_buffer , 706/* .get_base = */ NULL , 707/* .init_tensor = */ NULL , 708/* .memset_tensor = */ NULL , 709/* .set_tensor = */ NULL , 710/* .get_tensor = */ NULL , 711/* .set_tensor_2d = */ NULL , 712/* .get_tensor_2d = */ NULL , 713/* .cpy_tensor = */ NULL , 714/* .clear = */ ggml_backend_multi_buffer_clear , 715/* .reset = */ NULL , 716}; 717 718ggml_backend_buffer_t ggml_backend_multi_buffer_alloc_buffer (ggml_backend_buffer_t * buffers ,size_t n_buffers ) { 719ggml_backend_multi_buffer_context * ctx = (ggml_backend_multi_buffer_context * )malloc (sizeof (struct ggml_backend_multi_buffer_context )); 720ctx -> n_buffers = n_buffers ; 721ctx -> buffers = (ggml_backend_buffer_t * )malloc (n_buffers * sizeof (ggml_backend_buffer_t )); 722 723GGML_ASSERT (ctx -> buffers != NULL ); 724 725size_t total_size = 0 ; 726for (size_t i = 0 ;i < n_buffers ;i ++ ) { 727ctx -> buffers [i ]= buffers [i ]; 728total_size += ggml_backend_buffer_get_size (buffers [i ]); 729 } 730 731return ggml_backend_buffer_init (buffers [0 ]-> buft ,ggml_backend_multi_buffer_i ,ctx ,total_size ); 732} 733 734bool ggml_backend_buffer_is_multi_buffer (ggml_backend_buffer_t buffer ) { 735GGML_ASSERT (buffer ); 736return buffer -> iface .free_buffer == ggml_backend_multi_buffer_free_buffer ; 737} 738 739void ggml_backend_multi_buffer_set_usage (ggml_backend_buffer_t buffer ,enum ggml_backend_buffer_usage usage ) { 740GGML_ASSERT (buffer ); 741GGML_ASSERT (ggml_backend_buffer_is_multi_buffer (buffer )); 742ggml_backend_multi_buffer_context * ctx = (ggml_backend_multi_buffer_context * )buffer -> context ; 743for (size_t i = 0 ;i < ctx -> n_buffers ;i ++ ) { 744ggml_backend_buffer_set_usage (ctx -> buffers [i ],usage ); 745 } 746} 747 748// creates a copy of the tensor with the same memory layout 749static struct ggml_tensor * ggml_dup_tensor_layout (struct ggml_context * ctx ,const struct ggml_tensor * tensor ) { 750struct ggml_tensor * dup = ggml_dup_tensor (ctx ,tensor ); 751for (int i = 0 ;i < GGML_MAX_DIMS ;i ++ ) { 752dup -> nb [i ]= tensor -> nb [i ]; 753 } 754return dup ; 755} 756 757static bool ggml_is_view_op (enum ggml_op op ) { 758return op == GGML_OP_VIEW || op == GGML_OP_RESHAPE || op == GGML_OP_PERMUTE || op == GGML_OP_TRANSPOSE ; 759} 760 761// scheduler 762 763#ifndef GGML_SCHED_MAX_BACKENDS 764#define GGML_SCHED_MAX_BACKENDS 16 765#endif 766 767#ifndef GGML_SCHED_MAX_SPLIT_INPUTS 768#define GGML_SCHED_MAX_SPLIT_INPUTS 30 769#endif 770 771#ifndef GGML_SCHED_MAX_COPIES 772#define GGML_SCHED_MAX_COPIES 4 773#endif 774 775struct ggml_backend_sched_split { 776int backend_id ; 777int i_start ; 778int i_end ; 779struct ggml_tensor ** inputs ; 780int n_inputs ; 781int inputs_capacity ; 782// graph view of this split 783struct ggml_cgraph graph ; 784}; 785 786struct ggml_backend_sched { 787bool is_reset ;// true if the scheduler has been reset since the last graph split 788bool is_alloc ; 789 790int n_backends ; 791 792ggml_backend_t backends [GGML_SCHED_MAX_BACKENDS ]; 793ggml_backend_buffer_type_t bufts [GGML_SCHED_MAX_BACKENDS ]; 794ggml_gallocr_t galloc ; 795 796// hash map of the nodes in the graph 797struct ggml_hash_set hash_set ; 798int * hv_tensor_backend_ids ;// [hash_set.size] 799struct ggml_tensor ** hv_tensor_copies ;// [hash_set.size][n_backends][n_copies] 800 801int * node_backend_ids ;// [graph_size] 802int * leaf_backend_ids ;// [graph_size] 803 804int * prev_node_backend_ids ;// [graph_size] 805int * prev_leaf_backend_ids ;// [graph_size] 806 807// copy of the graph with modified inputs 808struct ggml_cgraph graph ; 809 810// graph splits 811struct ggml_backend_sched_split * splits ; 812int n_splits ; 813int splits_capacity ; 814 815// pipeline parallelism support 816int n_copies ; 817int cur_copy ; 818int next_copy ; 819ggml_backend_event_t events [GGML_SCHED_MAX_BACKENDS ][GGML_SCHED_MAX_COPIES ]; 820struct ggml_tensor ** graph_inputs ; 821int n_graph_inputs ; 822int graph_inputs_capacity ; 823 824struct ggml_context * ctx ; 825 826ggml_backend_sched_eval_callback callback_eval ; 827void * callback_eval_user_data ; 828 829char * context_buffer ; 830size_t context_buffer_size ; 831 832bool op_offload ; 833 834int debug ; 835 836// used for debugging graph reallocations [GGML_SCHED_DEBUG_REALLOC] 837// ref: https://github.com/ggml-org/llama.cpp/pull/17617 838int debug_realloc ; 839int debug_graph_size ; 840int debug_prev_graph_size ; 841}; 842 843#define hash_id (tensor ) ggml_hash_find_or_insert(&sched->hash_set, tensor) 844#define tensor_backend_id (tensor ) sched->hv_tensor_backend_ids[hash_id(tensor)] 845#define tensor_id_copy (id ,backend_id ,copy_id ) sched->hv_tensor_copies[(id) * sched->n_backends * sched->n_copies + (backend_id) * sched->n_copies + (copy_id)] 846#define tensor_copy (tensor ,backend_id ,copy_id ) tensor_id_copy(hash_id(tensor), backend_id, copy_id) 847 848static void ggml_backend_sched_split_inputs_grow (struct ggml_backend_sched_split * split ) { 849int new_cap = GGML_SCHED_MAX_SPLIT_INPUTS ; 850if (split -> inputs_capacity > 0 ) { 851new_cap = 2 * split -> inputs_capacity ; 852GGML_LOG_DEBUG ("%s: increasing split inputs capacity from %d to %d\n" ,__func__ ,split -> inputs_capacity ,new_cap ); 853 } 854auto * pnew = (struct ggml_tensor ** )realloc ((void * )split -> inputs ,new_cap * sizeof (struct ggml_tensor * )); 855if (pnew == NULL ) { 856GGML_LOG_ERROR ("%s: failed to allocate %zu bytes\n" ,__func__ ,new_cap * sizeof (struct ggml_tensor * )); 857GGML_ABORT ("failed to grow split inputs container" ); 858 } 859split -> inputs = pnew ; 860split -> inputs_capacity = new_cap ; 861} 862 863static void ggml_backend_sched_graph_inputs_grow (ggml_backend_sched_t sched ) { 864int new_cap = GGML_SCHED_MAX_SPLIT_INPUTS ; 865if (sched -> graph_inputs_capacity > 0 ) { 866new_cap = 2 * sched -> graph_inputs_capacity ; 867GGML_LOG_DEBUG ("%s: increasing graph inputs capacity from %d to %d\n" ,__func__ ,sched -> graph_inputs_capacity ,new_cap ); 868 } 869auto * pnew = (struct ggml_tensor ** )realloc ((void * )sched -> graph_inputs ,new_cap * sizeof (struct ggml_tensor * )); 870if (pnew == NULL ) { 871GGML_LOG_ERROR ("%s: failed to allocate %zu bytes\n" ,__func__ ,new_cap * sizeof (struct ggml_tensor * )); 872GGML_ABORT ("failed to grow graph inputs container" ); 873 } 874sched -> graph_inputs = pnew ; 875sched -> graph_inputs_capacity = new_cap ; 876} 877 878// returns the priority of the backend, lower id is higher priority 879static int ggml_backend_sched_backend_id (ggml_backend_sched_t sched ,ggml_backend_t backend ) { 880for (int i = 0 ;i < sched -> n_backends ;i ++ ) { 881if (sched -> backends [i ]== backend ) { 882return i ; 883 } 884 } 885return -1 ; 886} 887 888static int ggml_backend_sched_backend_from_buffer (ggml_backend_sched_t sched ,const struct ggml_tensor * tensor ,const struct ggml_tensor * op ) { 889ggml_backend_buffer_t buffer = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 890if (buffer == NULL ) { 891return -1 ; 892 } 893 894// find highest prio backend that supports the buffer type and the op 895for (int i = 0 ;i < sched -> n_backends ;i ++ ) { 896if (ggml_backend_supports_buft (sched -> backends [i ],buffer -> buft )&& 897ggml_backend_supports_op (sched -> backends [i ],op )) { 898return i ; 899 } 900 } 901 902#ifndef NDEBUG 903GGML_LOG_DEBUG ("%s: warning: no backend supports op %s with a weight with buffer type %s used in tensor %s, the weight will need to be copied\n" , 904__func__ ,ggml_op_desc (tensor ),ggml_backend_buffer_name (buffer ),tensor -> name ); 905#endif 906 907return -1 ; 908} 909 910#if 0 911#define GGML_SCHED_MAX_SPLITS_DEBUG 4096 912static char causes [GGML_DEFAULT_GRAPH_SIZE * 16 + GGML_SCHED_MAX_SPLITS_DEBUG * GGML_SCHED_MAX_SPLIT_INPUTS ][128 ];// debug only 913#define SET_CAUSE (node , ...) sprintf(causes[hash_id(node)], __VA_ARGS__) 914#define GET_CAUSE (node ) causes[hash_id(node)] 915#else 916#define SET_CAUSE (node , ...) 917#define GET_CAUSE (node ) "" 918#endif 919 920// returns the backend that should be used for the node based on the current locations 921static int ggml_backend_sched_backend_id_from_cur (ggml_backend_sched_t sched ,struct ggml_tensor * tensor ) { 922// assign pre-allocated nodes to their backend 923int cur_backend_id = ggml_backend_sched_backend_from_buffer (sched ,tensor ,tensor ); 924if (cur_backend_id != -1 ) { 925SET_CAUSE (tensor ,"1.dst" ); 926return cur_backend_id ; 927 } 928 929// view_src 930if (tensor -> view_src != NULL ) { 931cur_backend_id = ggml_backend_sched_backend_from_buffer (sched ,tensor -> view_src ,tensor ); 932if (cur_backend_id != -1 ) { 933SET_CAUSE (tensor ,"1.vsrc" ); 934return cur_backend_id ; 935 } 936 } 937 938if (tensor -> buffer || (tensor -> view_src && tensor -> view_src -> buffer )) { 939// since the tensor is pre-allocated, it cannot be moved to another backend 940ggml_backend_buffer_t buffer = tensor -> view_src ?tensor -> view_src -> buffer :tensor -> buffer ; 941GGML_ABORT ("pre-allocated tensor (%s) in a buffer (%s) that cannot run the operation (%s)" ,tensor -> name ,ggml_backend_buffer_name (buffer ),ggml_op_name (tensor -> op )); 942 } 943 944// graph input 945if (tensor -> flags & GGML_TENSOR_FLAG_INPUT ) { 946cur_backend_id = sched -> n_backends - 1 ;// last backend (assumed CPU) 947SET_CAUSE (tensor ,"1.inp" ); 948return cur_backend_id ; 949 } 950 951// operations with weights are preferably run on the same backend as the weights 952// TODO: there are exceptions (see below) - not an ideal solution 953bool allow = true; 954 955// skip ROPE since the rope freqs tensor is too small to choose a backend based on it 956allow = allow && tensor -> op != GGML_OP_ROPE ; 957 958// skip FLASH_ATTN_EXT since the sinks tensor is too small to choose a based based on it 959allow = allow && tensor -> op != GGML_OP_FLASH_ATTN_EXT ; 960 961if (allow ) { 962for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 963const struct ggml_tensor * src = tensor -> src [i ]; 964if (src == NULL ) { 965continue ; 966 } 967if (src -> buffer != NULL && src -> buffer -> usage == GGML_BACKEND_BUFFER_USAGE_WEIGHTS ) { 968int src_backend_id = ggml_backend_sched_backend_from_buffer (sched ,src ,tensor ); 969// check if a backend with higher prio wants to offload the op 970if (sched -> op_offload && src_backend_id == sched -> n_backends - 1 && ggml_backend_buffer_is_host (src -> buffer )) { 971for (int b = 0 ;b < src_backend_id ;b ++ ) { 972if (ggml_backend_supports_op (sched -> backends [b ],tensor )&& ggml_backend_offload_op (sched -> backends [b ],tensor )) { 973SET_CAUSE (tensor ,"1.off" ); 974return b ; 975 } 976 } 977 } 978SET_CAUSE (tensor ,"1.wgt%d" ,i ); 979return src_backend_id ; 980 } 981 } 982 } 983 984return -1 ; 985} 986 987static char * fmt_size (size_t size ) { 988static char buffer [128 ]; 989if (size >=1024 * 1024 ) { 990snprintf (buffer ,sizeof (buffer ),"%zuM" ,size /1024 /1024 ); 991 }else { 992snprintf (buffer ,sizeof (buffer ),"%zuK" ,size /1024 ); 993 } 994return buffer ; 995} 996 997static void ggml_backend_sched_print_assignments (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ) { 998int cur_split = 0 ; 999for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1000if (cur_split < sched -> n_splits && i == sched -> splits [cur_split ].i_start ) { 1001ggml_backend_t split_backend = sched -> backends [sched -> splits [cur_split ].backend_id ]; 1002GGML_LOG_DEBUG ("\n## SPLIT #%d: %s # %d inputs" ,cur_split ,ggml_backend_name (split_backend ), 1003sched -> splits [cur_split ].n_inputs ); 1004for (int j = 0 ;j < sched -> splits [cur_split ].n_inputs ;j ++ ) { 1005if (j == 0 ) { 1006GGML_LOG_DEBUG (": " ); 1007 } 1008GGML_LOG_DEBUG ("[%s (%5.5s)] " ,sched -> splits [cur_split ].inputs [j ]-> name , 1009fmt_size (ggml_nbytes (sched -> splits [cur_split ].inputs [j ]))); 1010 } 1011GGML_LOG_DEBUG ("\n" ); 1012cur_split ++ ; 1013 } 1014struct ggml_tensor * node = graph -> nodes [i ]; 1015if (ggml_is_view_op (node -> op )) { 1016continue ; 1017 } 1018if (sched -> debug > 1 ) { 1019ggml_backend_t tensor_backend = ggml_backend_sched_get_tensor_backend (sched ,node ); 1020GGML_LOG_DEBUG ("node #%3d (%10.10s): %20.20s (%5.5s) [%5.5s %8.8s] use=%d,c=%d:" ,i ,ggml_op_desc (node ),node -> name , 1021fmt_size (ggml_nbytes (node )),tensor_backend ?ggml_backend_name (tensor_backend ) :"NULL" ,GET_CAUSE (node ), 1022graph -> use_counts [ggml_hash_find (& graph -> visited_hash_set ,node )],node -> flags & GGML_TENSOR_FLAG_COMPUTE ?1 :0 ); 1023for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1024struct ggml_tensor * src = node -> src [j ]; 1025if (src == NULL ) { 1026continue ; 1027 } 1028ggml_backend_t src_backend = ggml_backend_sched_get_tensor_backend (sched ,src ); 1029GGML_LOG_DEBUG (" %20.20s (%5.5s) [%5.5s %8.8s]" ,src -> name , 1030fmt_size (ggml_nbytes (src )),src_backend ?ggml_backend_name (src_backend ) :"NULL" ,GET_CAUSE (src )); 1031 } 1032GGML_LOG_DEBUG ("\n" ); 1033 } 1034 } 1035} 1036 1037static bool ggml_backend_sched_buffer_supported (ggml_backend_sched_t sched ,struct ggml_tensor * t ,int backend_id ) { 1038ggml_backend_buffer_t buf = t -> view_src ?t -> view_src -> buffer :t -> buffer ; 1039ggml_backend_buffer_type_t buft = NULL ; 1040 1041if (buf ) { 1042// the tensor is already allocated 1043buft = buf -> buft ; 1044 }else { 1045// see if the tensor already has a backend assigned, and use the buffer type of that backend 1046int tensor_backend_id = tensor_backend_id (t ); 1047if (tensor_backend_id == -1 && t -> view_src ) { 1048tensor_backend_id = tensor_backend_id (t -> view_src ); 1049 } 1050if (tensor_backend_id != -1 ) { 1051buft = sched -> bufts [tensor_backend_id ]; 1052 } 1053 } 1054 1055return buft != NULL && ggml_backend_supports_buft (sched -> backends [backend_id ],buft ); 1056} 1057 1058static void ggml_backend_sched_set_if_supported (ggml_backend_sched_t sched ,struct ggml_tensor * node ,int cur_backend_id ,int * node_backend_id ) { 1059if (ggml_backend_supports_op (sched -> backends [cur_backend_id ],node )) { 1060* node_backend_id = cur_backend_id ; 1061SET_CAUSE (node ,"2.sup" ); 1062 } 1063} 1064 1065// assigns backends to ops and splits the graph into subgraphs that can be computed on the same backend 1066void ggml_backend_sched_split_graph (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ) { 1067// reset splits 1068sched -> n_splits = 0 ; 1069sched -> n_graph_inputs = 0 ; 1070sched -> is_reset = false; 1071 1072struct ggml_init_params params = { 1073/* .mem_size = */ sched -> context_buffer_size , 1074/* .mem_buffer = */ sched -> context_buffer , 1075/* .no_alloc = */ true 1076 }; 1077 1078ggml_free (sched -> ctx ); 1079 1080sched -> ctx = ggml_init (params ); 1081if (sched -> ctx == NULL ) { 1082GGML_ABORT ("%s: failed to initialize context\n" ,__func__ ); 1083 } 1084 1085graph -> uid = ggml_graph_next_uid (); 1086 1087// pass 1: assign backends to ops with pre-allocated inputs 1088for (int i = 0 ;i < graph -> n_leafs ;i ++ ) { 1089struct ggml_tensor * leaf = graph -> leafs [i ]; 1090int * leaf_backend_id = & tensor_backend_id (leaf ); 1091// do not overwrite user assignments 1092if (* leaf_backend_id == -1 ) { 1093* leaf_backend_id = ggml_backend_sched_backend_id_from_cur (sched ,leaf ); 1094 } 1095 } 1096 1097for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1098struct ggml_tensor * node = graph -> nodes [i ]; 1099int * node_backend_id = & tensor_backend_id (node ); 1100// do not overwrite user assignments 1101if (* node_backend_id == -1 ) { 1102* node_backend_id = ggml_backend_sched_backend_id_from_cur (sched ,node ); 1103 1104#if 0 1105// src 1106if (node -> op == GGML_OP_NONE ) { 1107continue ; 1108 } 1109 1110for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1111struct ggml_tensor * src = node -> src [j ]; 1112if (src == NULL ) { 1113continue ; 1114 } 1115int * src_backend_id = & tensor_backend_id (src ); 1116if (* src_backend_id == -1 ) { 1117* src_backend_id = ggml_backend_sched_backend_id_from_cur (sched ,src ); 1118 } 1119 } 1120#endif 1121 } 1122 } 1123 1124// pass 2: expand current backend assignments 1125// assign the same backend to adjacent nodes 1126// expand gpu backends (i.e. non last prio) up and down, ignoring cpu (the lowest priority backend) 1127// thus, cpu will never be used unless weights are on cpu, or there are no gpu ops between cpu ops 1128// ops unsupported by the backend being expanded will be left unassigned so that they can be assigned later when the locations of its inputs are known 1129// expand gpu down 1130 { 1131int cur_backend_id = -1 ; 1132for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1133struct ggml_tensor * node = graph -> nodes [i ]; 1134if (ggml_is_view_op (node -> op )) { 1135continue ; 1136 } 1137int * node_backend_id = & tensor_backend_id (node ); 1138if (* node_backend_id != -1 ) { 1139if (* node_backend_id == sched -> n_backends - 1 ) { 1140// skip cpu (lowest prio backend) 1141cur_backend_id = -1 ; 1142 }else { 1143cur_backend_id = * node_backend_id ; 1144 } 1145 }else if (cur_backend_id != -1 ) { 1146ggml_backend_sched_set_if_supported (sched ,node ,cur_backend_id ,node_backend_id ); 1147 } 1148 } 1149 } 1150// expand gpu up 1151 { 1152int cur_backend_id = -1 ; 1153for (int i = graph -> n_nodes - 1 ;i >=0 ;i -- ) { 1154struct ggml_tensor * node = graph -> nodes [i ]; 1155if (ggml_is_view_op (node -> op )) { 1156continue ; 1157 } 1158int * node_backend_id = & tensor_backend_id (node ); 1159if (* node_backend_id != -1 ) { 1160if (* node_backend_id == sched -> n_backends - 1 ) { 1161// skip cpu (lowest prio backend) 1162cur_backend_id = -1 ; 1163 }else { 1164cur_backend_id = * node_backend_id ; 1165 } 1166 }else if (cur_backend_id != -1 ) { 1167ggml_backend_sched_set_if_supported (sched ,node ,cur_backend_id ,node_backend_id ); 1168 } 1169 } 1170 } 1171// expand rest down 1172 { 1173int cur_backend_id = -1 ; 1174for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1175struct ggml_tensor * node = graph -> nodes [i ]; 1176if (ggml_is_view_op (node -> op )) { 1177continue ; 1178 } 1179int * node_backend_id = & tensor_backend_id (node ); 1180if (* node_backend_id != -1 ) { 1181cur_backend_id = * node_backend_id ; 1182 }else if (cur_backend_id != -1 ) { 1183ggml_backend_sched_set_if_supported (sched ,node ,cur_backend_id ,node_backend_id ); 1184 } 1185 } 1186 } 1187// expand rest up 1188 { 1189int cur_backend_id = -1 ; 1190for (int i = graph -> n_nodes - 1 ;i >=0 ;i -- ) { 1191struct ggml_tensor * node = graph -> nodes [i ]; 1192if (ggml_is_view_op (node -> op )) { 1193continue ; 1194 } 1195int * node_backend_id = & tensor_backend_id (node ); 1196if (* node_backend_id != -1 ) { 1197cur_backend_id = * node_backend_id ; 1198 }else if (cur_backend_id != -1 ) { 1199ggml_backend_sched_set_if_supported (sched ,node ,cur_backend_id ,node_backend_id ); 1200 } 1201 } 1202 } 1203 1204// pass 3: upgrade nodes to higher prio backends with compatible buffer types 1205// if the tensor is already in the same buffer type (*) as another higher priority backend, we should move it there 1206// however, we also need to verify that the sources are in compatible buffer types 1207// (*) the actual requirement is more relaxed, the buffer type of the backend should be supported by all the users of this tensor further down the graph 1208// however, this is slow to verify, so we have a more strict requirement that the buffer type is the same 1209// this is not uncommon since multiple backends can use host memory, with the same buffer type (eg. BLAS and CPU) 1210// additionally, set remaining unassigned nodes to the backend with the most supported inputs 1211// only nodes that could not be assigned during expansion due to the backend not supporting the op should be unassigned at this point 1212for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1213struct ggml_tensor * node = graph -> nodes [i ]; 1214if (ggml_is_view_op (node -> op )) { 1215continue ; 1216 } 1217int * node_backend_id = & tensor_backend_id (node ); 1218if (* node_backend_id == -1 ) { 1219// unassigned node: find the backend with the most supported inputs 1220int n_supported_best = -1 ; 1221for (int b = 0 ;b < sched -> n_backends ;b ++ ) { 1222if (ggml_backend_supports_op (sched -> backends [b ],node )) { 1223int n_supported = 0 ; 1224for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1225struct ggml_tensor * src = node -> src [j ]; 1226if (src == NULL ) { 1227continue ; 1228 } 1229if ((tensor_backend_id (src )!= -1 || tensor_backend_id (src -> view_src )!= -1 )&& ggml_backend_sched_buffer_supported (sched ,src ,b )) { 1230n_supported ++ ; 1231 } 1232 } 1233if (n_supported > n_supported_best ) { 1234n_supported_best = n_supported ; 1235* node_backend_id = b ; 1236SET_CAUSE (node ,"3.best" ); 1237 } 1238 } 1239 } 1240 }else { 1241// assigned node: upgrade to higher prio backend if possible 1242for (int b = 0 ;b < * node_backend_id ;b ++ ) { 1243if (sched -> bufts [b ]== sched -> bufts [* node_backend_id ]&& ggml_backend_supports_op (sched -> backends [b ],node )) { 1244bool supported = true; 1245for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1246struct ggml_tensor * src = node -> src [j ]; 1247if (src == NULL ) { 1248continue ; 1249 } 1250if (!ggml_backend_sched_buffer_supported (sched ,src ,b )) { 1251supported = false; 1252break ; 1253 } 1254 } 1255if (supported ) { 1256* node_backend_id = b ; 1257SET_CAUSE (node ,"3.upg" ); 1258break ; 1259 } 1260 } 1261 } 1262 } 1263 } 1264 1265// pass 4: assign backends to remaining src from dst and view_src 1266for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1267struct ggml_tensor * node = graph -> nodes [i ]; 1268int * cur_backend_id = & tensor_backend_id (node ); 1269if (node -> view_src != NULL && * cur_backend_id == -1 ) { 1270* cur_backend_id = tensor_backend_id (node -> view_src ); 1271SET_CAUSE (node ,"4.vsrc" ); 1272 } 1273for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1274struct ggml_tensor * src = node -> src [j ]; 1275if (src == NULL ) { 1276continue ; 1277 } 1278int * src_backend_id = & tensor_backend_id (src ); 1279if (* src_backend_id == -1 ) { 1280if (src -> view_src != NULL ) { 1281// views are always on the same backend as the source 1282* src_backend_id = tensor_backend_id (src -> view_src ); 1283SET_CAUSE (src ,"4.vsrc" ); 1284 }else { 1285* src_backend_id = * cur_backend_id ; 1286SET_CAUSE (src ,"4.cur" ); 1287 } 1288 } 1289 } 1290// if the node is still unassigned, assign it to the first backend that supports it 1291for (int b = 0 ;b < sched -> n_backends && * cur_backend_id == -1 ;b ++ ) { 1292ggml_backend_sched_set_if_supported (sched ,node ,b ,cur_backend_id ); 1293 } 1294GGML_ASSERT (* cur_backend_id != -1 ); 1295 } 1296 1297// pass 5: split graph, find tensors that need to be copied 1298 { 1299int i_split = 0 ; 1300struct ggml_backend_sched_split * split = & sched -> splits [0 ]; 1301// find the backend of the first split, skipping view ops 1302int i = 0 ; 1303for (;i < graph -> n_nodes ;i ++ ) { 1304struct ggml_tensor * node = graph -> nodes [i ]; 1305if (!ggml_is_view_op (node -> op )) { 1306split -> backend_id = tensor_backend_id (node ); 1307break ; 1308 } 1309 } 1310split -> i_start = 0 ; 1311split -> n_inputs = 0 ; 1312int cur_backend_id = split -> backend_id ; 1313for (;i < graph -> n_nodes ;i ++ ) { 1314struct ggml_tensor * node = graph -> nodes [i ]; 1315 1316if (ggml_is_view_op (node -> op )) { 1317continue ; 1318 } 1319 1320const int node_backend_id = tensor_backend_id (node ); 1321 1322GGML_ASSERT (node_backend_id != -1 );// all nodes should be assigned by now, this can happen if there is no CPU fallback 1323 1324// check if we should start a new split based on the sources of the current node 1325bool need_new_split = false; 1326if (node_backend_id == cur_backend_id && split -> n_inputs > 0 ) { 1327for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1328struct ggml_tensor * src = node -> src [j ]; 1329if (src == NULL ) { 1330continue ; 1331 } 1332// check if a weight is on a different and incompatible backend 1333// by starting a new split, the memory of the previously offloaded weights can be reused 1334if (src -> buffer != NULL && src -> buffer -> usage == GGML_BACKEND_BUFFER_USAGE_WEIGHTS ) { 1335int src_backend_id = tensor_backend_id (src ); 1336if (src_backend_id != cur_backend_id && !ggml_backend_sched_buffer_supported (sched ,src ,cur_backend_id )) { 1337need_new_split = true; 1338break ; 1339 } 1340 } 1341 } 1342 } 1343 1344if (node_backend_id != cur_backend_id || need_new_split ) { 1345split -> i_end = i ; 1346i_split ++ ; 1347if (i_split >=sched -> splits_capacity ) { 1348int old_cap = sched -> splits_capacity ; 1349sched -> splits_capacity *=2 ; 1350sched -> splits = (ggml_backend_sched_split * ) 1351realloc (sched -> splits ,sched -> splits_capacity * sizeof (struct ggml_backend_sched_split )); 1352GGML_ASSERT (sched -> splits != NULL ); 1353for (int k = old_cap ;k < sched -> splits_capacity ;k ++ ) { 1354memset (& sched -> splits [k ],0 ,sizeof (struct ggml_backend_sched_split )); 1355 } 1356 } 1357split = & sched -> splits [i_split ]; 1358split -> backend_id = node_backend_id ; 1359split -> i_start = i ; 1360split -> n_inputs = 0 ; 1361cur_backend_id = node_backend_id ; 1362 } 1363 1364// find inputs that are not on the same backend 1365for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1366struct ggml_tensor * src = node -> src [j ]; 1367if (src == NULL ) { 1368continue ; 1369 } 1370 1371size_t src_id = hash_id (src ); 1372const int src_backend_id = sched -> hv_tensor_backend_ids [src_id ]; 1373GGML_ASSERT (src_backend_id != -1 );// all inputs should be assigned by now 1374 1375if (src -> flags & GGML_TENSOR_FLAG_INPUT && sched -> n_copies > 1 ) { 1376if (tensor_id_copy (src_id ,src_backend_id ,0 )== NULL ) { 1377ggml_backend_t backend = sched -> backends [src_backend_id ]; 1378for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1379struct ggml_tensor * tensor_copy ; 1380if (c == sched -> cur_copy ) { 1381tensor_copy = src ;// use the original tensor as the current copy 1382 }else { 1383tensor_copy = ggml_dup_tensor_layout (sched -> ctx ,src ); 1384ggml_format_name (tensor_copy ,"%s#%s#%d" ,ggml_backend_name (backend ),src -> name ,c ); 1385 } 1386ggml_set_input (tensor_copy ); 1387ggml_set_output (tensor_copy );// prevent ggml-alloc from overwriting the tensor 1388tensor_id_copy (src_id ,src_backend_id ,c )= tensor_copy ; 1389SET_CAUSE (tensor_copy ,"4.cpy" ); 1390 } 1391int n_graph_inputs = sched -> n_graph_inputs ++ ; 1392if (n_graph_inputs >=sched -> graph_inputs_capacity ) { 1393ggml_backend_sched_graph_inputs_grow (sched ); 1394 } 1395sched -> graph_inputs [n_graph_inputs ]= src ; 1396 } 1397 } 1398 1399if (src_backend_id != cur_backend_id && !ggml_backend_sched_buffer_supported (sched ,src ,cur_backend_id )) { 1400// create a copy of the input in the split's backend 1401if (tensor_id_copy (src_id ,cur_backend_id ,0 )== NULL ) { 1402ggml_backend_t backend = sched -> backends [cur_backend_id ]; 1403for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1404struct ggml_tensor * tensor_copy = ggml_dup_tensor_layout (sched -> ctx ,src ); 1405ggml_format_name (tensor_copy ,"%s#%s#%d" ,ggml_backend_name (backend ),src -> name ,c ); 1406if (sched -> n_copies > 1 ) { 1407ggml_set_input (tensor_copy ); 1408ggml_set_output (tensor_copy );// prevent ggml-alloc from overwriting the tensor 1409 } 1410tensor_id_copy (src_id ,cur_backend_id ,c )= tensor_copy ; 1411SET_CAUSE (tensor_copy ,"4.cpy" ); 1412 } 1413int n_inputs = split -> n_inputs ++ ; 1414if (n_inputs >=split -> inputs_capacity ) { 1415ggml_backend_sched_split_inputs_grow (split ); 1416 } 1417split -> inputs [n_inputs ]= src ; 1418 } 1419node -> src [j ]= tensor_id_copy (src_id ,cur_backend_id ,sched -> cur_copy ); 1420 } 1421 } 1422 } 1423split -> i_end = graph -> n_nodes ; 1424sched -> n_splits = i_split + 1 ; 1425 } 1426 1427if (sched -> debug ) { 1428ggml_backend_sched_print_assignments (sched ,graph ); 1429 } 1430 1431// swap node_backend_ids and leaf _backend_ids with prevs 1432 { 1433int * tmp = sched -> node_backend_ids ; 1434sched -> node_backend_ids = sched -> prev_node_backend_ids ; 1435sched -> prev_node_backend_ids = tmp ; 1436 1437tmp = sched -> leaf_backend_ids ; 1438sched -> leaf_backend_ids = sched -> prev_leaf_backend_ids ; 1439sched -> prev_leaf_backend_ids = tmp ; 1440 } 1441 1442// optimize the split graphs and collect the allocation dependencies added by the backends 1443// this needs to happen before we make graph_copy, so they are in sync 1444// TODO: this may create many small allocations in the scheduler, restructure to use a flat array 1445 std::unordered_map < ggml_tensor * , std::vector < ggml_tensor *>> alloc_deps ; 1446 1447struct ggml_backend_graph_optimize_params opt_params = { 1448/* .add_alloc_dep = */ [](void * user_data ,ggml_tensor * tensor ,ggml_tensor * until ) { 1449auto & deps = * (std::unordered_map < ggml_tensor * , std::vector < ggml_tensor *>> * )user_data ; 1450 std::vector < ggml_tensor *> & keep = deps [until ]; 1451if (std::find (keep .begin (),keep .end (),tensor )== keep .end ()) { 1452keep .push_back (tensor ); 1453 } 1454 }, 1455/* .user_data = */ & alloc_deps , 1456 }; 1457 1458for (int i = 0 ;i < sched -> n_splits ;i ++ ) { 1459struct ggml_backend_sched_split * split = & sched -> splits [i ]; 1460split -> graph = ggml_graph_view (graph ,split -> i_start ,split -> i_end ); 1461 1462ggml_backend_graph_optimize (sched -> backends [split -> backend_id ],& split -> graph ,& opt_params ); 1463 } 1464 1465// each dep is added to graph_copy as a GGML_OP_NONE node with the kept tensors as srcs 1466int n_dep_nodes = 0 ; 1467for (const auto & it :alloc_deps ) { 1468n_dep_nodes += (it .second .size ()+ GGML_MAX_SRC - 1 ) /GGML_MAX_SRC ; 1469 } 1470 1471int total_inputs = sched -> n_graph_inputs ; 1472for (int i = 0 ;i < sched -> n_splits ;i ++ ) { 1473total_inputs += sched -> splits [i ].n_inputs ; 1474 } 1475int graph_size = std::max (graph -> n_nodes ,graph -> n_leafs )+ total_inputs * 2 * sched -> n_copies + n_dep_nodes ; 1476 1477// remember the actual graph_size for performing reallocation checks later [GGML_SCHED_DEBUG_REALLOC] 1478sched -> debug_prev_graph_size = sched -> debug_graph_size ; 1479sched -> debug_graph_size = graph_size ; 1480 1481if (sched -> graph .size < graph_size ) { 1482sched -> graph .size = graph_size ; 1483sched -> graph .nodes = (ggml_tensor ** )realloc (sched -> graph .nodes ,graph_size * sizeof (struct ggml_tensor * )); 1484sched -> graph .leafs = (ggml_tensor ** )realloc (sched -> graph .leafs ,graph_size * sizeof (struct ggml_tensor * )); 1485GGML_ASSERT (sched -> graph .nodes != NULL ); 1486GGML_ASSERT (sched -> graph .leafs != NULL ); 1487 } 1488sched -> graph .n_nodes = 0 ; 1489sched -> graph .n_leafs = 0 ; 1490 1491struct ggml_cgraph * graph_copy = & sched -> graph ; 1492 1493int n_dep_nodes_added = 0 ; 1494 1495for (int i = 0 ;i < sched -> n_splits ;i ++ ) { 1496struct ggml_backend_sched_split * split = & sched -> splits [i ]; 1497 1498// add inputs to the graph copy so that they are allocated by ggml-alloc at the start of the split 1499for (int j = 0 ;j < split -> n_inputs ;j ++ ) { 1500assert (graph_copy -> size > (graph_copy -> n_nodes + 1 )); 1501 1502struct ggml_tensor * input = split -> inputs [j ]; 1503const size_t input_id = hash_id (input ); 1504struct ggml_tensor * input_cpy = tensor_id_copy (input_id ,split -> backend_id ,sched -> cur_copy ); 1505 1506// add a dependency to the input source so that it is not freed before the copy is done 1507struct ggml_tensor * input_dep = ggml_view_tensor (sched -> ctx ,input ); 1508input_dep -> src [0 ]= input ; 1509sched -> node_backend_ids [graph_copy -> n_nodes ]= sched -> hv_tensor_backend_ids [input_id ]; 1510graph_copy -> nodes [graph_copy -> n_nodes ++ ]= input_dep ; 1511 1512// add a dependency to the input copy so that it is allocated at the start of the split 1513sched -> node_backend_ids [graph_copy -> n_nodes ]= split -> backend_id ; 1514graph_copy -> nodes [graph_copy -> n_nodes ++ ]= input_cpy ; 1515 } 1516 1517for (int j = split -> i_start ;j < split -> i_end ;j ++ ) { 1518assert (graph_copy -> size > graph_copy -> n_nodes ); 1519sched -> node_backend_ids [graph_copy -> n_nodes ]= tensor_backend_id (graph -> nodes [j ]); 1520graph_copy -> nodes [graph_copy -> n_nodes ++ ]= graph -> nodes [j ]; 1521 1522if (alloc_deps .empty ()) { 1523continue ; 1524 } 1525 1526// add a dependency node so that the kept tensors are not freed before this node is computed 1527auto it = alloc_deps .find (graph -> nodes [j ]); 1528if (it != alloc_deps .end ()) { 1529const std::vector < ggml_tensor *> & keep = it -> second ; 1530for (size_t k = 0 ;k < keep .size ();k += GGML_MAX_SRC ) { 1531struct ggml_tensor * dep = ggml_view_tensor (sched -> ctx ,keep [k ]); 1532for (size_t s = 0 ;s < GGML_MAX_SRC && k + s < keep .size ();s ++ ) { 1533dep -> src [s ]= keep [k + s ]; 1534 } 1535assert (graph_copy -> size > graph_copy -> n_nodes ); 1536sched -> node_backend_ids [graph_copy -> n_nodes ]= split -> backend_id ; 1537graph_copy -> nodes [graph_copy -> n_nodes ++ ]= dep ; 1538n_dep_nodes_added ++ ; 1539 } 1540 } 1541 } 1542 } 1543 1544// a mismatch means a backend added a dep with an `until` tensor that is not a node of the optimized graph 1545GGML_ASSERT (n_dep_nodes_added == n_dep_nodes ); 1546 1547if (sched -> n_copies > 1 ) { 1548// add input copies as leafs so that they are allocated first 1549for (int i = 0 ;i < sched -> n_graph_inputs ;i ++ ) { 1550struct ggml_tensor * input = sched -> graph_inputs [i ]; 1551size_t id = hash_id (input ); 1552int backend_id = tensor_backend_id (input ); 1553for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1554struct ggml_tensor * input_cpy = tensor_id_copy (id ,backend_id ,c ); 1555sched -> leaf_backend_ids [graph_copy -> n_leafs ]= backend_id ; 1556assert (graph_copy -> size > graph_copy -> n_leafs ); 1557graph_copy -> leafs [graph_copy -> n_leafs ++ ]= input_cpy ; 1558 } 1559 } 1560 1561for (int i = 0 ;i < sched -> n_splits ;i ++ ) { 1562struct ggml_backend_sched_split * split = & sched -> splits [i ]; 1563int backend_id = split -> backend_id ; 1564for (int j = 0 ;j < split -> n_inputs ;j ++ ) { 1565struct ggml_tensor * input = split -> inputs [j ]; 1566size_t id = hash_id (input ); 1567for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1568struct ggml_tensor * input_cpy = tensor_id_copy (id ,backend_id ,c ); 1569sched -> leaf_backend_ids [graph_copy -> n_leafs ]= backend_id ; 1570assert (graph_copy -> size > graph_copy -> n_leafs ); 1571graph_copy -> leafs [graph_copy -> n_leafs ++ ]= input_cpy ; 1572 } 1573 } 1574 } 1575 } 1576 1577// add leafs from the original graph 1578for (int i = 0 ;i < graph -> n_leafs ;i ++ ) { 1579struct ggml_tensor * leaf = graph -> leafs [i ]; 1580sched -> leaf_backend_ids [graph_copy -> n_leafs ]= tensor_backend_id (leaf ); 1581assert (graph_copy -> size > graph_copy -> n_leafs ); 1582graph_copy -> leafs [graph_copy -> n_leafs ++ ]= leaf ; 1583 } 1584 1585// set ids for all splits 1586for (int i = 0 ;i < sched -> n_splits ;++ i ) { 1587sched -> splits [i ].graph .uid = ggml_graph_next_uid (); 1588 } 1589} 1590 1591static bool ggml_backend_sched_alloc_splits (ggml_backend_sched_t sched ) { 1592bool backend_ids_changed = false; 1593for (int i = 0 ;i < sched -> graph .n_nodes ;i ++ ) { 1594if (sched -> node_backend_ids [i ]!= sched -> prev_node_backend_ids [i ]&& 1595sched -> bufts [sched -> node_backend_ids [i ]]!= sched -> bufts [sched -> prev_node_backend_ids [i ]]) { 1596backend_ids_changed = true; 1597break ; 1598 } 1599 } 1600if (!backend_ids_changed ) { 1601for (int i = 0 ;i < sched -> graph .n_leafs ;i ++ ) { 1602if (sched -> leaf_backend_ids [i ]!= sched -> prev_leaf_backend_ids [i ]&& 1603sched -> bufts [sched -> leaf_backend_ids [i ]]!= sched -> bufts [sched -> prev_leaf_backend_ids [i ]]) { 1604backend_ids_changed = true; 1605break ; 1606 } 1607 } 1608 } 1609 1610// allocate graph 1611if (backend_ids_changed || !ggml_gallocr_alloc_graph (sched -> galloc ,& sched -> graph )) { 1612#ifndef NDEBUG 1613GGML_LOG_DEBUG ("%s: failed to allocate graph, reserving (backend_ids_changed = %d)\n" ,__func__ ,backend_ids_changed ); 1614#endif 1615 1616if (sched -> debug_realloc > 0 ) { 1617// we are interested only in situations where the graph was reallocated even though its size remained the same [GGML_SCHED_DEBUG_REALLOC] 1618// example: https://github.com/ggml-org/llama.cpp/pull/17143 1619const bool unexpected = !backend_ids_changed && sched -> debug_prev_graph_size == sched -> debug_graph_size ; 1620 1621if (unexpected || sched -> debug_realloc > 1 ) { 1622GGML_ABORT ("%s: unexpected graph reallocation (graph size = %d, nodes = %d, leafs = %d), debug_realloc = %d\n" ,__func__ , 1623sched -> debug_graph_size ,sched -> graph .n_nodes ,sched -> graph .n_leafs ,sched -> debug_realloc ); 1624 } 1625 } 1626 1627// the re-allocation may cause the split inputs to be moved to a different address 1628// synchronize without ggml_backend_sched_synchronize to avoid changing cur_copy 1629for (int i = 0 ;i < sched -> n_backends ;i ++ ) { 1630ggml_backend_synchronize (sched -> backends [i ]); 1631 } 1632 1633ggml_gallocr_reserve_n (sched -> galloc ,& sched -> graph ,sched -> node_backend_ids ,sched -> leaf_backend_ids ); 1634if (!ggml_gallocr_alloc_graph (sched -> galloc ,& sched -> graph )) { 1635GGML_LOG_ERROR ("%s: failed to allocate graph\n" ,__func__ ); 1636return false; 1637 } 1638 } 1639 1640return true; 1641} 1642 1643static enum ggml_status ggml_backend_sched_compute_splits (ggml_backend_sched_t sched ) { 1644GGML_ASSERT (sched ); 1645struct ggml_backend_sched_split * splits = sched -> splits ; 1646 1647ggml_tensor * prev_ids_tensor = nullptr ; 1648 std::vector < int32_t > ids ; 1649 std::vector < ggml_bitset_t > used_ids ; 1650 1651int prev_backend_id = -1 ; 1652 1653for (int split_id = 0 ;split_id < sched -> n_splits ;split_id ++ ) { 1654struct ggml_backend_sched_split * split = & splits [split_id ]; 1655int split_backend_id = split -> backend_id ; 1656ggml_backend_t split_backend = sched -> backends [split_backend_id ]; 1657 1658// ensure the previous split's async work has completed before we start 1659// this split, the allocator may have reused buffer regions across splits 1660if (split -> n_inputs == 0 && prev_backend_id >=0 && prev_backend_id != split_backend_id ) { 1661if (sched -> events [prev_backend_id ][sched -> cur_copy ]!= NULL ) { 1662ggml_backend_event_synchronize (sched -> events [prev_backend_id ][sched -> cur_copy ]); 1663 }else { 1664ggml_backend_synchronize (sched -> backends [prev_backend_id ]); 1665 } 1666 } 1667 1668// copy the input tensors to the split backend 1669for (int input_id = 0 ;input_id < split -> n_inputs ;input_id ++ ) { 1670ggml_backend_t input_backend = ggml_backend_sched_get_tensor_backend (sched ,split -> inputs [input_id ]); 1671struct ggml_tensor * input = split -> inputs [input_id ]; 1672struct ggml_tensor * input_cpy = tensor_copy (input ,split_backend_id ,sched -> cur_copy ); 1673 1674if (input -> flags & GGML_TENSOR_FLAG_INPUT ) { 1675// inputs from the user must be copied immediately to prevent the user overwriting the data before the copy is done 1676if (sched -> events [split_backend_id ][sched -> cur_copy ]!= NULL ) { 1677ggml_backend_event_synchronize (sched -> events [split_backend_id ][sched -> cur_copy ]); 1678 }else { 1679ggml_backend_synchronize (split_backend ); 1680 } 1681ggml_backend_tensor_copy (input ,input_cpy ); 1682 }else { 1683// wait for the split backend to finish using the input before overwriting it 1684if (sched -> events [split_backend_id ][sched -> cur_copy ]!= NULL ) { 1685ggml_backend_event_wait (split_backend ,sched -> events [split_backend_id ][sched -> cur_copy ]); 1686 }else { 1687ggml_backend_synchronize (split_backend ); 1688 } 1689 1690// when offloading MoE weights, we can reduce the amount of data copied by copying only the experts that are used 1691ggml_tensor * node = split -> graph .nodes [0 ]; 1692if (split -> graph .n_nodes > 0 && 1693ggml_backend_buffer_get_usage (input -> buffer )== GGML_BACKEND_BUFFER_USAGE_WEIGHTS && 1694ggml_backend_buffer_is_host (input -> buffer )&& ( 1695 (node -> src [0 ]== input_cpy && node -> op == GGML_OP_MUL_MAT_ID ) 1696//|| (node->src[1] == input_cpy && node->op == GGML_OP_ADD_ID) /* GGML_OP_ADD_ID weights are small and not worth splitting */ 1697 )) { 1698 1699const int64_t n_expert = node -> op == GGML_OP_MUL_MAT_ID ?input -> ne [2 ] :input -> ne [1 ]; 1700const size_t expert_size = node -> op == GGML_OP_MUL_MAT_ID ?input -> nb [2 ] :input -> nb [1 ]; 1701 1702ggml_backend_synchronize (input_backend ); 1703 1704// get the ids 1705ggml_tensor * ids_tensor = node -> src [2 ]; 1706ggml_backend_t ids_backend = split_backend ; 1707 1708if (ggml_nelements (ids_tensor )== 0 ) { 1709continue ; 1710 } 1711 1712// if the ids tensor is also an input of the split, it may not have been copied yet to the split backend 1713// in that case, we use the original ids tensor 1714for (int i = input_id + 1 ;i < split -> n_inputs ;i ++ ) { 1715if (ids_tensor == tensor_copy (split -> inputs [i ],split_backend_id ,sched -> cur_copy )) { 1716ids_tensor = split -> inputs [i ]; 1717ids_backend = ggml_backend_sched_get_tensor_backend (sched ,split -> inputs [i ]); 1718break ; 1719 } 1720 } 1721 1722if (ids_tensor != prev_ids_tensor ) { 1723ids .resize (ggml_nbytes (ids_tensor ) /sizeof (int32_t )); 1724ggml_backend_tensor_get_async (ids_backend ,ids_tensor ,ids .data (),0 ,ggml_nbytes (ids_tensor )); 1725ggml_backend_synchronize (ids_backend ); 1726 1727// find the used experts 1728used_ids .clear (); 1729used_ids .resize (ggml_bitset_size (n_expert )); 1730for (int64_t i1 = 0 ;i1 < ids_tensor -> ne [1 ];i1 ++ ) { 1731for (int64_t i0 = 0 ;i0 < ids_tensor -> ne [0 ];i0 ++ ) { 1732int32_t id = ids [i1 * ids_tensor -> nb [1 ]/sizeof (int32_t )+ i0 * ids_tensor -> nb [0 ]/sizeof (int32_t )]; 1733GGML_ASSERT (id >=0 && id < n_expert ); 1734ggml_bitset_set (used_ids .data (),id ); 1735 } 1736 } 1737 1738prev_ids_tensor = ids_tensor ; 1739 } 1740 1741// group consecutive experts and copy them together 1742auto copy_experts = [& ](int32_t first_id ,int32_t last_id ) { 1743const size_t expert_offset = first_id * expert_size ; 1744const size_t expert_size_copy = (last_id - first_id + 1 )* expert_size ; 1745const size_t padding = std::min < size_t > (expert_size ,512 ); 1746const size_t padding_end = last_id < n_expert - 1 ?padding :0 ; 1747 1748ggml_backend_tensor_set_async (split_backend , 1749input_cpy , 1750 (const uint8_t * )input -> data + expert_offset ,expert_offset , 1751// copy a bit extra at the to ensure there are no NaNs in the padding of the last expert 1752// this is necessary for MMQ in the CUDA backend 1753expert_size_copy + padding_end ); 1754 }; 1755 1756int id = 0 ; 1757while (!ggml_bitset_get (used_ids .data (),id )) { 1758id ++ ; 1759 } 1760int32_t first_id = id ; 1761int32_t last_id = first_id ; 1762 1763for (++ id ;id < n_expert ;++ id ) { 1764if (!ggml_bitset_get (used_ids .data (),id )) { 1765continue ; 1766 } 1767 1768if (id == last_id + 1 ) { 1769last_id = id ; 1770continue ; 1771 } 1772 1773copy_experts (first_id ,last_id ); 1774 1775first_id = id ; 1776last_id = id ; 1777 } 1778copy_experts (first_id ,last_id ); 1779 }else { 1780// try async copy, but if not possible, we can still use a sync copy without synchronizing the dst backend, since we handle the synchronization here with multiple copies and events 1781// TODO: add public function to facilitate this, since applications do not have direct access to the backend interface 1782if (!split_backend -> iface .cpy_tensor_async || !split_backend -> iface .cpy_tensor_async (input_backend ,split_backend ,input ,input_cpy )) { 1783ggml_backend_synchronize (input_backend ); 1784if (sched -> events [split_backend_id ][sched -> cur_copy ]!= NULL ) { 1785ggml_backend_event_synchronize (sched -> events [split_backend_id ][sched -> cur_copy ]); 1786 }else { 1787ggml_backend_synchronize (split_backend ); 1788 } 1789ggml_backend_tensor_copy (input ,input_cpy ); 1790 } 1791 } 1792 } 1793 } 1794 1795if (!sched -> callback_eval ) { 1796enum ggml_status ec = ggml_backend_graph_compute_async (split_backend ,& split -> graph ); 1797if (ec != GGML_STATUS_SUCCESS ) { 1798return ec ; 1799 } 1800 }else { 1801// similar to ggml_backend_compare_graph_backend 1802for (int j0 = 0 ;j0 < split -> graph .n_nodes ;j0 ++ ) { 1803struct ggml_tensor * t = split -> graph .nodes [j0 ]; 1804 1805// check if the user needs data from this node 1806bool need = sched -> callback_eval (t , true,sched -> callback_eval_user_data ); 1807 1808int j1 = j0 ; 1809 1810// determine the range [j0, j1] of nodes that can be computed together 1811while (!need && j1 < split -> graph .n_nodes - 1 ) { 1812t = split -> graph .nodes [++ j1 ]; 1813need = sched -> callback_eval (t , true,sched -> callback_eval_user_data ); 1814 } 1815 1816struct ggml_cgraph gv = ggml_graph_view (& split -> graph ,j0 ,j1 + 1 ); 1817 1818enum ggml_status ec = ggml_backend_graph_compute_async (split_backend ,& gv ); 1819if (ec != GGML_STATUS_SUCCESS ) { 1820return ec ; 1821 } 1822 1823// TODO: pass backend to the callback, then the user can decide if they want to synchronize 1824ggml_backend_synchronize (split_backend ); 1825 1826if (need && !sched -> callback_eval (t , false,sched -> callback_eval_user_data )) { 1827break ; 1828 } 1829 1830j0 = j1 ; 1831 } 1832 } 1833 1834// record the event of this split 1835if (sched -> events [split_backend_id ][sched -> cur_copy ]!= NULL ) { 1836ggml_backend_event_record (sched -> events [split_backend_id ][sched -> cur_copy ],split_backend ); 1837 } 1838 1839prev_backend_id = split_backend_id ; 1840 } 1841 1842return GGML_STATUS_SUCCESS ; 1843} 1844 1845ggml_backend_sched_t ggml_backend_sched_new ( 1846ggml_backend_t * backends , 1847ggml_backend_buffer_type_t * bufts , 1848int n_backends , 1849size_t graph_size , 1850bool parallel , 1851bool op_offload ) { 1852GGML_ASSERT (n_backends > 0 ); 1853GGML_ASSERT (n_backends <=GGML_SCHED_MAX_BACKENDS ); 1854GGML_ASSERT (ggml_backend_dev_type (ggml_backend_get_device (backends [n_backends - 1 ]))== GGML_BACKEND_DEVICE_TYPE_CPU ); 1855 1856struct ggml_backend_sched * sched = (ggml_backend_sched * )calloc (1 ,sizeof (struct ggml_backend_sched )); 1857 1858const char * GGML_SCHED_DEBUG = getenv ("GGML_SCHED_DEBUG" ); 1859sched -> debug = GGML_SCHED_DEBUG ?atoi (GGML_SCHED_DEBUG ) :0 ; 1860 1861sched -> debug_realloc = 0 ; 1862#ifdef GGML_SCHED_NO_REALLOC 1863sched -> debug_realloc = 1 ; 1864#endif 1865const char * GGML_SCHED_DEBUG_REALLOC = getenv ("GGML_SCHED_DEBUG_REALLOC" ); 1866sched -> debug_realloc = GGML_SCHED_DEBUG_REALLOC ?atoi (GGML_SCHED_DEBUG_REALLOC ) :sched -> debug_realloc ; 1867 1868sched -> n_backends = n_backends ; 1869sched -> n_copies = parallel ?GGML_SCHED_MAX_COPIES :1 ; 1870 1871// initialize hash table 1872// FIXME: needs to be size*2 to account for leafs (do it in graph_split instead) 1873sched -> hash_set = ggml_hash_set_new (graph_size ); 1874sched -> hv_tensor_backend_ids = (int * )malloc (sched -> hash_set .size * sizeof (sched -> hv_tensor_backend_ids [0 ])); 1875sched -> hv_tensor_copies = (ggml_tensor ** )malloc (sched -> hash_set .size * sched -> n_backends * sched -> n_copies * sizeof (struct ggml_tensor * )); 1876 1877const size_t ggml_sched_max_splits = graph_size ;// at most there is one split for each node in the graph 1878const size_t nodes_size = graph_size + ggml_sched_max_splits * GGML_SCHED_MAX_SPLIT_INPUTS * 2 ; 1879sched -> node_backend_ids = (int * )calloc (nodes_size ,sizeof (sched -> node_backend_ids [0 ])); 1880sched -> leaf_backend_ids = (int * )calloc (nodes_size ,sizeof (sched -> leaf_backend_ids [0 ])); 1881sched -> prev_node_backend_ids = (int * )calloc (nodes_size ,sizeof (sched -> prev_node_backend_ids [0 ])); 1882sched -> prev_leaf_backend_ids = (int * )calloc (nodes_size ,sizeof (sched -> prev_leaf_backend_ids [0 ])); 1883 1884sched -> debug_graph_size = 0 ; 1885sched -> debug_prev_graph_size = 0 ; 1886 1887sched -> context_buffer_size = ggml_sched_max_splits * GGML_SCHED_MAX_SPLIT_INPUTS * 2 * sizeof (struct ggml_tensor )+ ggml_graph_overhead_custom (graph_size , false); 1888sched -> context_buffer = (char * )malloc (sched -> context_buffer_size ); 1889 1890const int initial_splits_capacity = 16 ; 1891sched -> splits = (ggml_backend_sched_split * )calloc (initial_splits_capacity ,sizeof (sched -> splits [0 ])); 1892sched -> splits_capacity = initial_splits_capacity ; 1893 1894sched -> graph_inputs_capacity = GGML_SCHED_MAX_SPLIT_INPUTS ; 1895sched -> graph_inputs = (struct ggml_tensor ** )calloc (sched -> graph_inputs_capacity ,sizeof (struct ggml_tensor * )); 1896 1897for (int b = 0 ;b < n_backends ;b ++ ) { 1898sched -> backends [b ]= backends [b ]; 1899sched -> bufts [b ]= bufts ?bufts [b ] :ggml_backend_get_default_buffer_type (backends [b ]); 1900GGML_ASSERT (ggml_backend_supports_buft (backends [b ],sched -> bufts [b ])); 1901 1902if (sched -> n_copies > 1 ) { 1903for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1904sched -> events [b ][c ]= ggml_backend_event_new (backends [b ]-> device ); 1905 } 1906 } 1907 } 1908 1909sched -> galloc = ggml_gallocr_new_n (sched -> bufts ,n_backends ); 1910sched -> op_offload = op_offload ; 1911 1912ggml_backend_sched_reset (sched ); 1913 1914return sched ; 1915} 1916 1917void ggml_backend_sched_free (ggml_backend_sched_t sched ) { 1918if (sched == NULL ) { 1919return ; 1920 } 1921for (int b = 0 ;b < sched -> n_backends ;b ++ ) { 1922for (int c = 0 ;c < sched -> n_copies ;c ++ ) { 1923ggml_backend_event_free (sched -> events [b ][c ]); 1924 } 1925 } 1926ggml_gallocr_free (sched -> galloc ); 1927ggml_free (sched -> ctx ); 1928ggml_hash_set_free (& sched -> hash_set ); 1929for (int i = 0 ;i < sched -> splits_capacity ;i ++ ) { 1930free (sched -> splits [i ].inputs ); 1931 } 1932free (sched -> splits ); 1933free (sched -> graph_inputs ); 1934free (sched -> hv_tensor_backend_ids ); 1935free (sched -> hv_tensor_copies ); 1936free (sched -> node_backend_ids ); 1937free (sched -> leaf_backend_ids ); 1938free (sched -> prev_node_backend_ids ); 1939free (sched -> prev_leaf_backend_ids ); 1940free (sched -> context_buffer ); 1941free (sched -> graph .nodes ); 1942free (sched -> graph .leafs ); 1943free (sched ); 1944} 1945 1946void ggml_backend_sched_reset (ggml_backend_sched_t sched ) { 1947GGML_ASSERT (sched ); 1948// reset state for the next run 1949if (!sched -> is_reset ) { 1950ggml_hash_set_reset (& sched -> hash_set ); 1951memset (sched -> hv_tensor_backend_ids ,-1 ,sched -> hash_set .size * sizeof (sched -> hv_tensor_backend_ids [0 ])); 1952memset (sched -> hv_tensor_copies ,0 ,sched -> hash_set .size * sched -> n_backends * sched -> n_copies * sizeof (struct ggml_tensor * )); 1953sched -> is_reset = true; 1954 } 1955sched -> is_alloc = false; 1956} 1957 1958void ggml_backend_sched_reserve_size (ggml_backend_sched_t sched ,struct ggml_cgraph * measure_graph ,size_t * sizes ) { 1959GGML_ASSERT (sched ); 1960GGML_ASSERT ((int )sched -> hash_set .size >=measure_graph -> n_nodes + measure_graph -> n_leafs ); 1961GGML_ASSERT (sizes ); 1962 1963ggml_backend_sched_reset (sched ); 1964 1965ggml_backend_sched_synchronize (sched ); 1966 1967ggml_backend_sched_split_graph (sched ,measure_graph ); 1968 1969ggml_gallocr_reserve_n_size (sched -> galloc ,& sched -> graph ,sched -> node_backend_ids ,sched -> leaf_backend_ids ,sizes ); 1970} 1971 1972bool ggml_backend_sched_reserve (ggml_backend_sched_t sched ,struct ggml_cgraph * measure_graph ) { 1973GGML_ASSERT (sched ); 1974GGML_ASSERT ((int )sched -> hash_set .size >=measure_graph -> n_nodes + measure_graph -> n_leafs ); 1975 1976ggml_backend_sched_synchronize (sched ); 1977 1978ggml_backend_sched_split_graph (sched ,measure_graph ); 1979 1980if (!ggml_gallocr_reserve_n (sched -> galloc ,& sched -> graph ,sched -> node_backend_ids ,sched -> leaf_backend_ids )) { 1981return false; 1982 } 1983 1984ggml_backend_sched_reset (sched ); 1985 1986return true; 1987} 1988 1989bool ggml_backend_sched_alloc_graph (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ) { 1990GGML_ASSERT (sched ); 1991GGML_ASSERT ((int )sched -> hash_set .size >=graph -> n_nodes + graph -> n_leafs ); 1992GGML_ASSERT (!sched -> is_alloc ); 1993 1994sched -> cur_copy = sched -> next_copy ; 1995sched -> next_copy = (sched -> next_copy + 1 ) %sched -> n_copies ; 1996 1997ggml_backend_sched_split_graph (sched ,graph ); 1998 1999if (!ggml_backend_sched_alloc_splits (sched )) { 2000return false; 2001 } 2002 2003sched -> is_alloc = true; 2004 2005return true; 2006} 2007 2008enum ggml_status ggml_backend_sched_graph_compute (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ) { 2009enum ggml_status err = ggml_backend_sched_graph_compute_async (sched ,graph ); 2010ggml_backend_sched_synchronize (sched ); 2011return err ; 2012} 2013 2014enum ggml_status ggml_backend_sched_graph_compute_async (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ) { 2015GGML_ASSERT (sched ); 2016if (!sched -> is_reset && !sched -> is_alloc ) { 2017ggml_backend_sched_reset (sched ); 2018 } 2019 2020if (!sched -> is_alloc ) { 2021if (!ggml_backend_sched_alloc_graph (sched ,graph )) { 2022return GGML_STATUS_ALLOC_FAILED ; 2023 } 2024 } 2025 2026return ggml_backend_sched_compute_splits (sched ); 2027} 2028 2029void ggml_backend_sched_synchronize (ggml_backend_sched_t sched ) { 2030GGML_ASSERT (sched ); 2031for (int i = 0 ;i < sched -> n_backends ;i ++ ) { 2032ggml_backend_synchronize (sched -> backends [i ]); 2033 } 2034if (!sched -> is_alloc ) { 2035// if the graph is not already allocated, always use copy 0 after a synchronization 2036// this ensures that during generation the same copy is used every time, 2037// which avoids changes in the graph that could cause CUDA or other graphs to be disabled 2038sched -> next_copy = 0 ; 2039 } 2040} 2041 2042void ggml_backend_sched_set_eval_callback (ggml_backend_sched_t sched ,ggml_backend_sched_eval_callback callback ,void * user_data ) { 2043GGML_ASSERT (sched ); 2044sched -> callback_eval = callback ; 2045sched -> callback_eval_user_data = user_data ; 2046} 2047 2048int ggml_backend_sched_get_n_splits (ggml_backend_sched_t sched ) { 2049GGML_ASSERT (sched ); 2050return sched -> n_splits ; 2051} 2052 2053int ggml_backend_sched_get_n_copies (ggml_backend_sched_t sched ) { 2054GGML_ASSERT (sched ); 2055return sched -> n_copies ; 2056} 2057 2058int ggml_backend_sched_get_n_backends (ggml_backend_sched_t sched ) { 2059GGML_ASSERT (sched ); 2060return sched -> n_backends ; 2061} 2062 2063ggml_backend_t ggml_backend_sched_get_backend (ggml_backend_sched_t sched ,int i ) { 2064GGML_ASSERT (sched ); 2065GGML_ASSERT (i >=0 && i < sched -> n_backends ); 2066return sched -> backends [i ]; 2067} 2068 2069ggml_backend_buffer_type_t ggml_backend_sched_get_buffer_type (ggml_backend_sched_t sched ,ggml_backend_t backend ) { 2070GGML_ASSERT (sched ); 2071int backend_index = ggml_backend_sched_backend_id (sched ,backend ); 2072GGML_ASSERT (backend_index >=0 && backend_index < sched -> n_backends ); 2073 2074return sched -> bufts [backend_index ]; 2075} 2076 2077size_t ggml_backend_sched_get_buffer_size (ggml_backend_sched_t sched ,ggml_backend_t backend ) { 2078GGML_ASSERT (sched ); 2079int backend_index = ggml_backend_sched_backend_id (sched ,backend ); 2080GGML_ASSERT (backend_index >=0 && backend_index < sched -> n_backends ); 2081 2082return ggml_gallocr_get_buffer_size (sched -> galloc ,backend_index ); 2083} 2084 2085void ggml_backend_sched_set_tensor_backend (ggml_backend_sched_t sched ,struct ggml_tensor * node ,ggml_backend_t backend ) { 2086GGML_ASSERT (sched ); 2087int backend_index = ggml_backend_sched_backend_id (sched ,backend ); 2088GGML_ASSERT (backend_index >=0 && backend_index < sched -> n_backends ); 2089tensor_backend_id (node )= backend_index ; 2090SET_CAUSE (node ,"usr" ); 2091sched -> is_reset = false; 2092} 2093 2094ggml_backend_t ggml_backend_sched_get_tensor_backend (ggml_backend_sched_t sched ,struct ggml_tensor * node ) { 2095GGML_ASSERT (sched ); 2096int backend_index = tensor_backend_id (node ); 2097if (backend_index == -1 ) { 2098return NULL ; 2099 } 2100return sched -> backends [backend_index ]; 2101} 2102 2103// utils 2104 2105bool ggml_op_alloc_size_may_expand (enum ggml_op op ) { 2106switch (op ) { 2107case GGML_OP_FLASH_ATTN_EXT : 2108case GGML_OP_MUL_MAT : 2109case GGML_OP_MUL_MAT_ID : 2110case GGML_OP_CUMSUM : 2111case GGML_OP_ARGSORT : 2112case GGML_OP_TOP_K : 2113return true; 2114default : 2115return false; 2116 } 2117} 2118 2119enum ggml_status ggml_backend_view_init (struct ggml_tensor * tensor ) { 2120GGML_ASSERT (tensor ); 2121GGML_ASSERT (tensor -> buffer == NULL ); 2122GGML_ASSERT (tensor -> view_src != NULL ); 2123GGML_ASSERT (tensor -> view_src -> buffer != NULL ); 2124GGML_ASSERT (tensor -> view_src -> data != NULL ); 2125 2126tensor -> buffer = tensor -> view_src -> buffer ; 2127tensor -> data = (char * )tensor -> view_src -> data + tensor -> view_offs ; 2128return ggml_backend_buffer_init_tensor (tensor -> buffer ,tensor ); 2129} 2130 2131enum ggml_status ggml_backend_tensor_alloc (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ,void * addr ) { 2132GGML_ASSERT (tensor ); 2133GGML_ASSERT (tensor -> buffer == NULL ); 2134GGML_ASSERT (tensor -> data == NULL ); 2135GGML_ASSERT (tensor -> view_src == NULL ); 2136GGML_ASSERT (addr >=ggml_backend_buffer_get_base (buffer )); 2137GGML_ASSERT (ggml_backend_buffer_is_meta (buffer )|| 2138 (char * )addr + ggml_backend_buffer_get_alloc_size (buffer ,tensor ) <= 2139 (char * )ggml_backend_buffer_get_base (buffer )+ ggml_backend_buffer_get_size (buffer )); 2140 2141tensor -> buffer = buffer ; 2142tensor -> data = addr ; 2143return ggml_backend_buffer_init_tensor (buffer ,tensor ); 2144} 2145 2146static struct ggml_tensor * graph_copy_dup_tensor (struct ggml_hash_set hash_set ,struct ggml_tensor ** node_copies , 2147struct ggml_context * ctx_allocated ,struct ggml_context * ctx_unallocated ,struct ggml_tensor * src ) { 2148 2149GGML_ASSERT (src != NULL ); 2150GGML_ASSERT (src -> data && "graph must be allocated" ); 2151 2152size_t id = ggml_hash_insert (& hash_set ,src ); 2153if (id == GGML_HASHSET_ALREADY_EXISTS ) { 2154return node_copies [ggml_hash_find (& hash_set ,src )]; 2155 } 2156 2157struct ggml_tensor * dst = ggml_dup_tensor_layout (src -> data && !src -> view_src ?ctx_allocated :ctx_unallocated ,src ); 2158if (src -> view_src != NULL ) { 2159dst -> view_src = graph_copy_dup_tensor (hash_set ,node_copies ,ctx_allocated ,ctx_unallocated ,src -> view_src ); 2160dst -> view_offs = src -> view_offs ; 2161 } 2162dst -> op = src -> op ; 2163dst -> flags = src -> flags ; 2164memcpy (dst -> op_params ,src -> op_params ,sizeof (dst -> op_params )); 2165ggml_set_name (dst ,src -> name ); 2166 2167// copy src 2168for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 2169struct ggml_tensor * s = src -> src [i ]; 2170if (s == NULL ) { 2171continue ; 2172 } 2173dst -> src [i ]= graph_copy_dup_tensor (hash_set ,node_copies ,ctx_allocated ,ctx_unallocated ,s ); 2174 } 2175 2176node_copies [id ]= dst ; 2177return dst ; 2178} 2179 2180static void graph_copy_init_tensor (struct ggml_hash_set * hash_set ,struct ggml_tensor ** node_copies ,bool * node_init ,struct ggml_tensor * src ) { 2181size_t id = ggml_hash_find (hash_set ,src ); 2182if (node_init [id ]) { 2183return ; 2184 } 2185node_init [id ]= true; 2186 2187struct ggml_tensor * dst = node_copies [id ]; 2188if (dst -> view_src != NULL ) { 2189graph_copy_init_tensor (hash_set ,node_copies ,node_init ,src -> view_src ); 2190enum ggml_status status = ggml_backend_view_init (dst ); 2191GGML_ASSERT (status == GGML_STATUS_SUCCESS ); 2192 } 2193else { 2194ggml_backend_tensor_copy (src ,dst ); 2195 } 2196 2197// init src 2198for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 2199struct ggml_tensor * s = src -> src [i ]; 2200if (s == NULL ) { 2201continue ; 2202 } 2203graph_copy_init_tensor (hash_set ,node_copies ,node_init ,s ); 2204 } 2205} 2206 2207struct ggml_backend_graph_copy ggml_backend_graph_copy (ggml_backend_t backend ,struct ggml_cgraph * graph ) { 2208GGML_ASSERT (graph ); 2209struct ggml_hash_set hash_set = ggml_hash_set_new (graph -> visited_hash_set .size ); 2210struct ggml_tensor ** node_copies = (ggml_tensor ** )calloc (hash_set .size ,sizeof (node_copies [0 ]));// NOLINT 2211bool * node_init = (bool * )calloc (hash_set .size ,sizeof (node_init [0 ])); 2212 2213struct ggml_init_params params = { 2214/* .mem_size = */ ggml_tensor_overhead ()* hash_set .size + ggml_graph_overhead_custom (graph -> size , false), 2215/* .mem_buffer = */ NULL , 2216/* .no_alloc = */ true 2217 }; 2218 2219struct ggml_context * ctx_allocated = ggml_init (params ); 2220struct ggml_context * ctx_unallocated = ggml_init (params ); 2221 2222if (ctx_allocated == NULL || ctx_unallocated == NULL ) { 2223GGML_LOG_ERROR ("%s: failed to allocate context for graph copy\n" ,__func__ ); 2224ggml_hash_set_free (& hash_set ); 2225free (node_copies ); 2226free (node_init ); 2227ggml_free (ctx_allocated ); 2228ggml_free (ctx_unallocated ); 2229return { 2230/* .buffer = */ NULL , 2231/* .ctx_allocated = */ NULL , 2232/* .ctx_unallocated = */ NULL , 2233/* .graph = */ NULL , 2234 }; 2235 } 2236 2237// dup nodes 2238for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 2239struct ggml_tensor * node = graph -> nodes [i ]; 2240graph_copy_dup_tensor (hash_set ,node_copies ,ctx_allocated ,ctx_unallocated ,node ); 2241 } 2242 2243// allocate nodes 2244ggml_backend_buffer_t buffer = ggml_backend_alloc_ctx_tensors (ctx_allocated ,backend ); 2245if (buffer == NULL ) { 2246GGML_LOG_ERROR ("%s: failed to allocate buffer for graph copy\n" ,__func__ ); 2247ggml_hash_set_free (& hash_set ); 2248free (node_copies ); 2249free (node_init ); 2250ggml_free (ctx_allocated ); 2251ggml_free (ctx_unallocated ); 2252return { 2253/* .buffer = */ NULL , 2254/* .ctx_allocated = */ NULL , 2255/* .ctx_unallocated = */ NULL , 2256/* .graph = */ NULL , 2257 }; 2258 } 2259 2260//printf("copy buffer size: %zu MB\n", ggml_backend_buffer_get_size(buffer) / 1024 / 1024); 2261 2262// copy data and init views 2263for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 2264struct ggml_tensor * node = graph -> nodes [i ]; 2265graph_copy_init_tensor (& hash_set ,node_copies ,node_init ,node ); 2266 } 2267 2268// build graph copy 2269struct ggml_cgraph * graph_copy = ggml_new_graph_custom (ctx_allocated ,graph -> size , false); 2270for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 2271struct ggml_tensor * node = graph -> nodes [i ]; 2272struct ggml_tensor * node_copy = node_copies [ggml_hash_find (& hash_set ,node )]; 2273graph_copy -> nodes [i ]= node_copy ; 2274 } 2275graph_copy -> n_nodes = graph -> n_nodes ; 2276 2277ggml_hash_set_free (& hash_set ); 2278free (node_copies ); 2279free (node_init ); 2280 2281return { 2282/* .buffer = */ buffer , 2283/* .ctx_allocated = */ ctx_allocated , 2284/* .ctx_unallocated = */ ctx_unallocated , 2285/* .graph = */ graph_copy , 2286 }; 2287} 2288 2289void ggml_backend_graph_copy_free (struct ggml_backend_graph_copy copy ) { 2290ggml_backend_buffer_free (copy .buffer ); 2291ggml_free (copy .ctx_allocated ); 2292ggml_free (copy .ctx_unallocated ); 2293} 2294 2295bool ggml_backend_compare_graph_backend (ggml_backend_t backend1 ,ggml_backend_t backend2 ,struct ggml_cgraph * graph ,ggml_backend_eval_callback callback ,void * user_data ,struct ggml_tensor const * const * test_nodes ,size_t num_test_nodes ) { 2296struct ggml_backend_graph_copy copy = ggml_backend_graph_copy (backend2 ,graph ); 2297if (copy .buffer == NULL ) { 2298return false; 2299 } 2300 2301struct ggml_cgraph * g1 = graph ; 2302struct ggml_cgraph * g2 = copy .graph ; 2303 2304assert (g1 -> n_nodes == g2 -> n_nodes ); 2305 2306if (num_test_nodes != 0 ) { 2307GGML_ASSERT (test_nodes ); 2308// Compute the whole graph and only test the output for specific tensors 2309ggml_backend_graph_compute (backend1 ,g1 ); 2310ggml_backend_graph_compute (backend2 ,g2 ); 2311 2312bool verified = false; 2313for (int i = 0 ;i < g1 -> n_nodes ;i ++ ) { 2314for (size_t j = 0 ;j < num_test_nodes ;++ j ) { 2315if (g1 -> nodes [i ]== test_nodes [j ]) { 2316callback (i ,g1 -> nodes [i ],g2 -> nodes [i ],user_data ); 2317verified = true; 2318 } 2319 } 2320 } 2321GGML_ASSERT (verified ); 2322 }else { 2323for (int i = 0 ;i < g1 -> n_nodes ;i ++ ) { 2324struct ggml_tensor * t1 = g1 -> nodes [i ]; 2325struct ggml_tensor * t2 = g2 -> nodes [i ]; 2326 2327assert (t1 -> op == t2 -> op && ggml_are_same_layout (t1 ,t2 )); 2328 2329struct ggml_cgraph g1v = ggml_graph_view (g1 ,i ,i + 1 ); 2330struct ggml_cgraph g2v = ggml_graph_view (g2 ,i ,i + 1 ); 2331 2332ggml_backend_graph_compute (backend1 ,& g1v ); 2333ggml_backend_graph_compute (backend2 ,& g2v ); 2334 2335if (ggml_is_view_op (t1 -> op )) { 2336continue ; 2337 } 2338 2339// compare results, calculate rms etc 2340if (!callback (i ,t1 ,t2 ,user_data )) { 2341break ; 2342 } 2343 } 2344 } 2345ggml_backend_graph_copy_free (copy ); 2346 2347return true; 2348} 2349 2350// CPU backend - buffer 2351 2352static void * ggml_backend_cpu_buffer_get_base (ggml_backend_buffer_t buffer ) { 2353GGML_ASSERT (buffer ); 2354uintptr_t data = (uintptr_t )buffer -> context ; 2355 2356// align the buffer 2357if (data %TENSOR_ALIGNMENT != 0 ) { 2358data = GGML_PAD (data ,TENSOR_ALIGNMENT ); 2359 } 2360 2361return (void * )data ; 2362} 2363 2364static void ggml_backend_cpu_buffer_free_buffer (ggml_backend_buffer_t buffer ) { 2365GGML_ASSERT (buffer ); 2366ggml_aligned_free (buffer -> context ,buffer -> size ); 2367} 2368 2369static void ggml_backend_cpu_buffer_memset_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ,uint8_t value ,size_t offset ,size_t size ) { 2370GGML_ASSERT (tensor ); 2371memset ((char * )tensor -> data + offset ,value ,size ); 2372 2373GGML_UNUSED (buffer ); 2374} 2375 2376static void ggml_backend_cpu_buffer_set_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ) { 2377GGML_ASSERT (tensor ); 2378memcpy ((char * )tensor -> data + offset ,data ,size ); 2379 2380GGML_UNUSED (buffer ); 2381} 2382 2383static void ggml_backend_cpu_buffer_get_tensor (ggml_backend_buffer_t buffer ,const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ) { 2384GGML_ASSERT (tensor ); 2385memcpy (data , (const char * )tensor -> data + offset ,size ); 2386 2387GGML_UNUSED (buffer ); 2388} 2389 2390static bool ggml_backend_cpu_buffer_cpy_tensor (ggml_backend_buffer_t buffer ,const struct ggml_tensor * src ,struct ggml_tensor * dst ) { 2391GGML_ASSERT (src ); 2392if (ggml_backend_buffer_is_host (src -> buffer )) { 2393memcpy (dst -> data ,src -> data ,ggml_nbytes (src )); 2394return true; 2395 } 2396return false; 2397 2398GGML_UNUSED (buffer ); 2399} 2400 2401static void ggml_backend_cpu_buffer_clear (ggml_backend_buffer_t buffer ,uint8_t value ) { 2402GGML_ASSERT (buffer ); 2403memset (buffer -> context ,value ,buffer -> size ); 2404} 2405 2406static const struct ggml_backend_buffer_i ggml_backend_cpu_buffer_i = { 2407/* .free_buffer = */ ggml_backend_cpu_buffer_free_buffer , 2408/* .get_base = */ ggml_backend_cpu_buffer_get_base , 2409/* .init_tensor = */ NULL ,// no initialization required 2410/* .memset_tensor = */ ggml_backend_cpu_buffer_memset_tensor , 2411/* .set_tensor = */ ggml_backend_cpu_buffer_set_tensor , 2412/* .get_tensor = */ ggml_backend_cpu_buffer_get_tensor , 2413/* .set_tensor_2d = */ NULL , 2414/* .get_tensor_2d = */ NULL , 2415/* .cpy_tensor = */ ggml_backend_cpu_buffer_cpy_tensor , 2416/* .clear = */ ggml_backend_cpu_buffer_clear , 2417/* .reset = */ NULL , 2418}; 2419 2420static const struct ggml_backend_buffer_i ggml_backend_cpu_buffer_from_ptr_i = { 2421/* .free_buffer = */ NULL ,// ptr is not owned by the buffer, so it does not need to be freed 2422/* .get_base = */ ggml_backend_cpu_buffer_get_base , 2423/* .init_tensor = */ NULL ,// no initialization required 2424/* .memset_tensor = */ ggml_backend_cpu_buffer_memset_tensor , 2425/* .set_tensor = */ ggml_backend_cpu_buffer_set_tensor , 2426/* .get_tensor = */ ggml_backend_cpu_buffer_get_tensor , 2427/* .set_tensor_2d = */ NULL , 2428/* .get_tensor_2d = */ NULL , 2429/* .cpy_tensor = */ ggml_backend_cpu_buffer_cpy_tensor , 2430/* .clear = */ ggml_backend_cpu_buffer_clear , 2431/* .reset = */ NULL , 2432}; 2433 2434// CPU backend buffer type 2435 2436// this buffer type is defined here to make it available to all backends 2437 2438static const char * ggml_backend_cpu_buffer_type_get_name (ggml_backend_buffer_type_t buft ) { 2439return "CPU" ; 2440 2441GGML_UNUSED (buft ); 2442} 2443 2444static ggml_backend_buffer_t ggml_backend_cpu_buffer_type_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ) { 2445void * data = ggml_aligned_malloc (size ); 2446 2447if (data == NULL ) { 2448GGML_LOG_ERROR ("%s: failed to allocate buffer of size %zu\n" ,__func__ ,size ); 2449return NULL ; 2450 } 2451 2452return ggml_backend_buffer_init (buft ,ggml_backend_cpu_buffer_i ,data ,size ); 2453} 2454 2455static size_t ggml_backend_cpu_buffer_type_get_alignment (ggml_backend_buffer_type_t buft ) { 2456return TENSOR_ALIGNMENT ; 2457 2458GGML_UNUSED (buft ); 2459} 2460 2461static bool ggml_backend_cpu_buffer_type_is_host (ggml_backend_buffer_type_t buft ) { 2462return true; 2463 2464GGML_UNUSED (buft ); 2465} 2466 2467ggml_backend_buffer_type_t ggml_backend_cpu_buffer_type (void ) { 2468static struct ggml_backend_buffer_type ggml_backend_cpu_buffer_type = { 2469/* .iface = */ { 2470/* .get_name = */ ggml_backend_cpu_buffer_type_get_name , 2471/* .alloc_buffer = */ ggml_backend_cpu_buffer_type_alloc_buffer , 2472/* .get_alignment = */ ggml_backend_cpu_buffer_type_get_alignment , 2473/* .get_max_size = */ NULL ,// defaults to SIZE_MAX 2474/* .get_alloc_size = */ NULL ,// defaults to ggml_nbytes 2475/* .is_host = */ ggml_backend_cpu_buffer_type_is_host , 2476 }, 2477/* .device = */ NULL ,// FIXME ggml_backend_reg_dev_get(ggml_backend_cpu_reg(), 0), 2478/* .context = */ NULL , 2479 }; 2480 2481return & ggml_backend_cpu_buffer_type ; 2482} 2483 2484static const char * ggml_backend_cpu_buffer_from_ptr_type_get_name (ggml_backend_buffer_type_t buft ) { 2485return "CPU_Mapped" ; 2486 2487GGML_UNUSED (buft ); 2488} 2489 2490static ggml_backend_buffer_type_t ggml_backend_cpu_buffer_from_ptr_type (void ) { 2491static struct ggml_backend_buffer_type ggml_backend_cpu_buffer_type = { 2492/* .iface = */ { 2493/* .get_name = */ ggml_backend_cpu_buffer_from_ptr_type_get_name , 2494/* .alloc_buffer = */ ggml_backend_cpu_buffer_type_alloc_buffer , 2495/* .get_alignment = */ ggml_backend_cpu_buffer_type_get_alignment , 2496/* .get_max_size = */ NULL ,// defaults to SIZE_MAX 2497/* .get_alloc_size = */ NULL ,// defaults to ggml_nbytes 2498/* .is_host = */ ggml_backend_cpu_buffer_type_is_host , 2499 }, 2500/* .device = */ NULL ,// FIXME ggml_backend_reg_dev_get(ggml_backend_cpu_reg(), 0), 2501/* .context = */ NULL , 2502 }; 2503 2504return & ggml_backend_cpu_buffer_type ; 2505} 2506 2507ggml_backend_buffer_t ggml_backend_cpu_buffer_from_ptr (void * ptr ,size_t size ) { 2508GGML_ASSERT ((uintptr_t )ptr %TENSOR_ALIGNMENT == 0 && "buffer pointer must be aligned" ); 2509return ggml_backend_buffer_init (ggml_backend_cpu_buffer_from_ptr_type (),ggml_backend_cpu_buffer_from_ptr_i ,ptr ,size ); 2510}