char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
6036c635e
char/aliceai-t5-moe
1#include "ggml-alloc.h" 2#include "ggml-backend-impl.h" 3#include "ggml.h" 4#include "ggml-impl.h" 5 6#include <assert.h> 7#include <limits.h> 8#include <stdarg.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <string.h> 12 13#define MAX (a ,b ) ((a) > (b) ? (a) : (b)) 14#define MAX_FREE_BLOCKS 256 15 16//#define GGML_ALLOCATOR_DEBUG 17 18//#define AT_PRINTF(...) GGML_LOG_DEBUG(__VA_ARGS__) 19#define AT_PRINTF (...) 20 21// ops that return true for this function must not use restrict pointers for their backend implementations 22bool ggml_op_can_inplace (enum ggml_op op ) { 23switch (op ) { 24case GGML_OP_FILL : 25case GGML_OP_SCALE : 26case GGML_OP_DIAG_MASK_ZERO : 27case GGML_OP_DIAG_MASK_INF : 28case GGML_OP_ADD : 29case GGML_OP_ADD_ID : 30case GGML_OP_ADD1 : 31case GGML_OP_SUB : 32case GGML_OP_MUL : 33case GGML_OP_DIV : 34case GGML_OP_SQR : 35case GGML_OP_SQRT : 36case GGML_OP_LOG : 37case GGML_OP_UNARY : 38case GGML_OP_ROPE : 39case GGML_OP_ROPE_BACK : 40case GGML_OP_SILU_BACK : 41case GGML_OP_RMS_NORM : 42case GGML_OP_RMS_NORM_BACK : 43case GGML_OP_CLAMP : 44case GGML_OP_SOFT_MAX : 45case GGML_OP_SOFT_MAX_BACK : 46return true; 47 48default : 49return false; 50 } 51} 52 53static size_t aligned_offset (const void * buffer ,size_t offset ,size_t alignment ) { 54assert (alignment && !(alignment & (alignment - 1 )));// power of 2 55size_t align = (alignment - (((uintptr_t )buffer + offset ) %alignment )) %alignment ; 56return offset + align ; 57} 58 59// tallocr 60 61struct ggml_tallocr ggml_tallocr_new (ggml_backend_buffer_t buffer ) { 62void * base = ggml_backend_buffer_get_base (buffer ); 63size_t align = ggml_backend_buffer_get_alignment (buffer ); 64 65assert (align && !(align & (align - 1 )));// power of 2 66 67struct ggml_tallocr talloc = (struct ggml_tallocr ) { 68/*.buffer = */ buffer , 69/*.base = */ base , 70/*.alignment = */ align , 71/*.offset = */ aligned_offset (base ,0 ,align ), 72 }; 73return talloc ; 74} 75 76enum ggml_status ggml_tallocr_alloc (struct ggml_tallocr * talloc ,struct ggml_tensor * tensor ) { 77size_t size = ggml_backend_buffer_get_alloc_size (talloc -> buffer ,tensor ); 78size = GGML_PAD (size ,talloc -> alignment ); 79 80if (talloc -> offset + size > ggml_backend_buffer_get_size (talloc -> buffer )) { 81GGML_LOG_ERROR ("%s: not enough space in the buffer to allocate %s (needed %zu, available %zu)\n" , 82__func__ ,tensor -> name ,size ,ggml_backend_buffer_get_size (talloc -> buffer )- talloc -> offset ); 83GGML_ABORT ("not enough space in the buffer" ); 84 } 85 86void * addr = (char * )ggml_backend_buffer_get_base (talloc -> buffer )+ talloc -> offset ; 87talloc -> offset += size ; 88 89assert (((uintptr_t )addr %talloc -> alignment )== 0 ); 90 91return ggml_backend_tensor_alloc (talloc -> buffer ,tensor ,addr ); 92} 93 94// dynamic tensor allocator 95 96#define GGML_VBUFFER_MAX_CHUNKS 16 97 98// relative memory address within an allocation that can be split into multiple buffers (chunks) 99struct buffer_address { 100int chunk ;// index of a backend buffer 101size_t offset ;// local memory offset within the buffer 102}; 103 104static const struct buffer_address GGML_BUFFER_ADDRESS_INVALID = {-1 ,SIZE_MAX }; 105 106static bool ggml_buffer_address_less (struct buffer_address a ,struct buffer_address b ) { 107return a .chunk != b .chunk ?a .chunk < b .chunk :a .offset < b .offset ; 108} 109 110struct free_block { 111size_t offset ; 112size_t size ; 113}; 114 115struct tallocr_chunk { 116struct free_block free_blocks [MAX_FREE_BLOCKS ]; 117int n_free_blocks ; 118size_t max_size ; 119}; 120 121struct ggml_dyn_tallocr { 122size_t alignment ; 123size_t max_chunk_size ; 124struct tallocr_chunk * chunks [GGML_VBUFFER_MAX_CHUNKS ]; 125int n_chunks ; 126 127#ifdef GGML_ALLOCATOR_DEBUG 128struct { 129const struct ggml_tensor * tensor ; 130struct buffer_address addr ; 131 }allocated_tensors [1024 ]; 132#endif 133}; 134 135static void ggml_dyn_tallocr_insert_block (struct tallocr_chunk * chunk ,size_t offset ,size_t size ) { 136GGML_ASSERT (chunk -> n_free_blocks < MAX_FREE_BLOCKS && "out of free blocks" ); 137// insert the new block in the correct position to keep the array sorted by address (to make merging blocks faster) 138int insert_pos = 0 ; 139while (insert_pos < chunk -> n_free_blocks && chunk -> free_blocks [insert_pos ].offset < offset ) { 140insert_pos ++ ; 141 } 142// shift all blocks from insert_pos onward to make room for the new block 143for (int i = chunk -> n_free_blocks ;i > insert_pos ;i -- ) { 144chunk -> free_blocks [i ]= chunk -> free_blocks [i - 1 ]; 145 } 146// insert the new block 147chunk -> free_blocks [insert_pos ].offset = offset ; 148chunk -> free_blocks [insert_pos ].size = size ; 149chunk -> n_free_blocks ++ ; 150} 151 152static void ggml_dyn_tallocr_remove_block (struct tallocr_chunk * chunk ,int idx ) { 153// shift all elements after idx by 1 to the left, overwriting the element at idx 154for (int i = idx ;i < chunk -> n_free_blocks - 1 ;i ++ ) { 155chunk -> free_blocks [i ]= chunk -> free_blocks [i + 1 ]; 156 } 157chunk -> n_free_blocks -- ; 158} 159 160static int ggml_dyn_tallocr_new_chunk (struct ggml_dyn_tallocr * alloc ,size_t min_size ) { 161if (alloc -> n_chunks >=GGML_VBUFFER_MAX_CHUNKS ) { 162return -1 ; 163 } 164struct tallocr_chunk * chunk = calloc (1 ,sizeof (struct tallocr_chunk )); 165chunk -> n_free_blocks = 1 ; 166chunk -> free_blocks [0 ].offset = 0 ; 167// available space in a chunk is limited to max_chunk_size, but can be higher if: 168// 1. a single tensor exceeds the maximum, and cannot fit any other way 169// 2. we are running out of chunks 170// backends will either manage to allocate the larger size, or report an error. 171chunk -> free_blocks [0 ].size = MAX (min_size ,alloc -> max_chunk_size ); 172if (alloc -> n_chunks == GGML_VBUFFER_MAX_CHUNKS - 1 ) { 173chunk -> free_blocks [0 ].size = SIZE_MAX /2 ; 174 } 175alloc -> chunks [alloc -> n_chunks ]= chunk ; 176alloc -> n_chunks ++ ; 177return alloc -> n_chunks - 1 ; 178} 179 180#ifdef GGML_ALLOCATOR_DEBUG 181static void add_allocated_tensor (struct ggml_dyn_tallocr * alloc ,struct buffer_address addr ,const struct ggml_tensor * tensor ) { 182for (int i = 0 ;i < 1024 ;i ++ ) { 183if (alloc -> allocated_tensors [i ].tensor == NULL ) { 184alloc -> allocated_tensors [i ].tensor = tensor ; 185alloc -> allocated_tensors [i ].addr = addr ; 186return ; 187 } 188 } 189GGML_ABORT ("out of allocated_tensors" ); 190} 191static void remove_allocated_tensor (struct ggml_dyn_tallocr * alloc ,struct buffer_address addr ,const struct ggml_tensor * tensor ) { 192for (int i = 0 ;i < 1024 ;i ++ ) { 193if (alloc -> allocated_tensors [i ].addr .chunk == addr .chunk && alloc -> allocated_tensors [i ].addr .offset == addr .offset ) { 194alloc -> allocated_tensors [i ].tensor = NULL ; 195return ; 196 } 197 } 198GGML_ABORT ("tried to free tensor %s not found\n" ,tensor -> name ); 199} 200#endif 201 202static struct buffer_address ggml_dyn_tallocr_alloc (struct ggml_dyn_tallocr * alloc ,size_t size ,const struct ggml_tensor * tensor ) { 203size = aligned_offset (NULL ,size ,alloc -> alignment ); 204 205AT_PRINTF ("%s: allocating %s (%zu bytes) - " ,__func__ ,tensor -> name ,size ); 206 207int best_fit_chunk = -1 ; 208int best_fit_block = -1 ; 209size_t max_avail = 0 ; 210 211// find the best fitting free block besides the last block, within any chunk 212for (int c = 0 ;c < alloc -> n_chunks ;++ c ) { 213struct tallocr_chunk * chunk = alloc -> chunks [c ]; 214size_t best_fit_size = SIZE_MAX ; 215for (int i = 0 ;i < chunk -> n_free_blocks - 1 ;i ++ ) { 216struct free_block * block = & chunk -> free_blocks [i ]; 217max_avail = MAX (max_avail ,block -> size ); 218if (block -> size >=size && block -> size <=best_fit_size ) { 219best_fit_chunk = c ; 220best_fit_block = i ; 221best_fit_size = block -> size ; 222 } 223 } 224 } 225 226if (best_fit_block == -1 ) { 227// no suitable block found, try the last block (this may grow a chunks size) 228int64_t best_reuse = INT64_MIN ; 229for (int c = 0 ;c < alloc -> n_chunks ;++ c ) { 230struct tallocr_chunk * chunk = alloc -> chunks [c ]; 231if (chunk -> n_free_blocks > 0 ) { 232struct free_block * block = & chunk -> free_blocks [chunk -> n_free_blocks - 1 ]; 233max_avail = MAX (max_avail ,block -> size ); 234int64_t reuse_factor = chunk -> max_size - block -> offset - size ; 235// reuse_factor < 0 : amount of extra memory that needs to be allocated 236// reuse_factor = 0 : allocated free space exactly matches tensor size 237// reuse_factor > 0 : superfluous memory that will remain unused 238bool better_reuse = best_reuse < 0 && reuse_factor > best_reuse ; 239bool better_fit = reuse_factor >=0 && reuse_factor < best_reuse ; 240if (block -> size >=size && (better_reuse || better_fit )) { 241best_fit_chunk = c ; 242best_fit_block = chunk -> n_free_blocks - 1 ; 243best_reuse = reuse_factor ; 244 } 245 } 246 } 247 } 248 249if (best_fit_block == -1 ) { 250// none of the existing chunks have enough space left 251best_fit_chunk = ggml_dyn_tallocr_new_chunk (alloc ,size ); 252best_fit_block = 0 ; 253 } 254if (best_fit_chunk == -1 ) { 255// since the last chunk always has virtually endless memory, this should never happen 256GGML_LOG_ERROR ("%s: not enough space in the buffer to allocate %zu bytes, largest block available %zu bytes\n" , 257__func__ ,size ,max_avail ); 258GGML_ABORT ("graph allocation: failed to reserve memory" ); 259 } 260 261struct tallocr_chunk * chunk = alloc -> chunks [best_fit_chunk ]; 262struct free_block * block = & chunk -> free_blocks [best_fit_block ]; 263struct buffer_address addr = {.chunk = best_fit_chunk , .offset = block -> offset }; 264block -> offset += size ; 265block -> size -= size ; 266if (block -> size == 0 ) { 267// remove block if empty 268ggml_dyn_tallocr_remove_block (chunk ,best_fit_block ); 269 } 270 271AT_PRINTF ("block %d, offset %zu, chunk %d\n" ,best_fit_block ,addr .offset ,addr .chunk ); 272 273#ifdef GGML_ALLOCATOR_DEBUG 274add_allocated_tensor (alloc ,addr ,tensor ); 275size_t cur_max = addr .offset + size ; 276if (cur_max > chunk -> max_size ) { 277// sort allocated_tensors by chunk/offset 278for (int i = 0 ;i < 1024 ;i ++ ) { 279for (int j = i + 1 ;j < 1024 ;j ++ ) { 280if (ggml_buffer_address_less (alloc -> allocated_tensors [j ].addr ,alloc -> allocated_tensors [i ].addr )) { 281const struct ggml_tensor * tmp_tensor = alloc -> allocated_tensors [i ].tensor ; 282struct buffer_address tmp_addr = alloc -> allocated_tensors [i ].addr ; 283alloc -> allocated_tensors [i ].tensor = alloc -> allocated_tensors [j ].tensor ; 284alloc -> allocated_tensors [i ].addr = alloc -> allocated_tensors [j ].addr ; 285alloc -> allocated_tensors [j ].tensor = tmp_tensor ; 286alloc -> allocated_tensors [j ].addr = tmp_addr ; 287 } 288 } 289 } 290GGML_LOG_DEBUG ("max_size[%d] = %.2f MB: tensors: " ,addr .chunk ,cur_max /1024.0 /1024.0 ); 291for (int i = 0 ;i < 1024 ;i ++ ) { 292if (alloc -> allocated_tensors [i ].tensor ) { 293GGML_LOG_DEBUG ("%s [%d: %zx-%zx] (%.2f MB) " ,alloc -> allocated_tensors [i ].tensor -> name , 294alloc -> allocated_tensors [i ].addr .chunk , 295alloc -> allocated_tensors [i ].addr .offset , 296alloc -> allocated_tensors [i ].addr .offset + ggml_nbytes (alloc -> allocated_tensors [i ].tensor ), 297ggml_nbytes (alloc -> allocated_tensors [i ].tensor ) /1024.0 /1024.0 ); 298 } 299 } 300GGML_LOG_DEBUG ("\n" ); 301 } 302#endif 303 304chunk -> max_size = MAX (chunk -> max_size ,addr .offset + size ); 305 306return addr ; 307 308GGML_UNUSED (tensor ); 309} 310 311// this is a very naive implementation, but for our case the number of free blocks should be very small 312static void ggml_dyn_tallocr_free_bytes (struct ggml_dyn_tallocr * alloc ,struct buffer_address addr ,size_t size ) { 313size = aligned_offset (NULL ,size ,alloc -> alignment ); 314 315struct tallocr_chunk * chunk = alloc -> chunks [addr .chunk ]; 316 317// see if we can merge with an existing block 318for (int i = 0 ;i < chunk -> n_free_blocks ;i ++ ) { 319struct free_block * block = & chunk -> free_blocks [i ]; 320// check if ptr is at the end of the block 321if (block -> offset + block -> size == addr .offset ) { 322block -> size += size ; 323// check if we can merge with the next block 324if (i < chunk -> n_free_blocks - 1 ) { 325struct free_block * next = & chunk -> free_blocks [i + 1 ]; 326if (block -> offset + block -> size == next -> offset ) { 327block -> size += next -> size ; 328ggml_dyn_tallocr_remove_block (chunk ,i + 1 ); 329 } 330 } 331return ; 332 } 333// check if ptr is at the beginning of the block 334if (addr .offset + size == block -> offset ) { 335block -> offset = addr .offset ; 336block -> size += size ; 337// check if we can merge with the previous block 338if (i > 0 ) { 339struct free_block * prev = & chunk -> free_blocks [i - 1 ]; 340if (prev -> offset + prev -> size == block -> offset ) { 341prev -> size += block -> size ; 342ggml_dyn_tallocr_remove_block (chunk ,i ); 343 } 344 } 345return ; 346 } 347 } 348// otherwise, add a new block 349ggml_dyn_tallocr_insert_block (chunk ,addr .offset ,size ); 350} 351 352static void ggml_dyn_tallocr_reset (struct ggml_dyn_tallocr * alloc ) { 353for (int i = 0 ;i < GGML_VBUFFER_MAX_CHUNKS ;i ++ ) { 354free (alloc -> chunks [i ]); 355alloc -> chunks [i ]= NULL ; 356 } 357alloc -> n_chunks = 0 ; 358 359#ifdef GGML_ALLOCATOR_DEBUG 360for (int i = 0 ;i < 1024 ;i ++ ) { 361alloc -> allocated_tensors [i ].tensor = NULL ; 362 } 363#endif 364} 365 366static struct ggml_dyn_tallocr * ggml_dyn_tallocr_new (size_t alignment ,size_t max_buffer_size ) { 367struct ggml_dyn_tallocr * alloc = (struct ggml_dyn_tallocr * )malloc (sizeof (struct ggml_dyn_tallocr )); 368 369* alloc = (struct ggml_dyn_tallocr ) { 370/*.alignment = */ alignment , 371/*.max_chunk_size = */ MIN (max_buffer_size ,SIZE_MAX /2 ),// clamp to avoid overflows 372/*.chunks = */ {NULL }, 373/*.n_chunks = */ 0 , 374#ifdef GGML_ALLOCATOR_DEBUG 375/*.allocated_tensors = */ {{0 }}, 376#endif 377 }; 378 379ggml_dyn_tallocr_reset (alloc ); 380 381return alloc ; 382} 383 384static void ggml_dyn_tallocr_free (struct ggml_dyn_tallocr * alloc ) { 385for (int i = 0 ;i < alloc -> n_chunks ;++ i ) { 386free (alloc -> chunks [i ]); 387 } 388free (alloc ); 389} 390 391static size_t ggml_dyn_tallocr_max_size (struct ggml_dyn_tallocr * alloc ,int chunk ) { 392return chunk < alloc -> n_chunks ?alloc -> chunks [chunk ]-> max_size :0 ; 393} 394 395 396// virtual buffer with contiguous memory range, split into multiple backend buffers (chunks) 397 398struct vbuffer { 399ggml_backend_buffer_t chunks [GGML_VBUFFER_MAX_CHUNKS ]; 400}; 401 402static void ggml_vbuffer_free (struct vbuffer * buf ) { 403if (buf == NULL ) { 404return ; 405 } 406for (int i = 0 ;i < GGML_VBUFFER_MAX_CHUNKS ;++ i ) { 407ggml_backend_buffer_free (buf -> chunks [i ]); 408 } 409free (buf ); 410} 411 412static size_t ggml_vbuffer_chunk_size (struct vbuffer * buf ,int chunk ) { 413return buf -> chunks [chunk ] ?ggml_backend_buffer_get_size (buf -> chunks [chunk ]) :0 ; 414} 415 416static size_t ggml_vbuffer_size (struct vbuffer * buf ) { 417size_t size = 0 ; 418for (int i = 0 ;i < GGML_VBUFFER_MAX_CHUNKS && buf -> chunks [i ];++ i ) { 419size += ggml_backend_buffer_get_size (buf -> chunks [i ]); 420 } 421return size ; 422} 423 424static struct vbuffer * ggml_vbuffer_alloc (ggml_backend_buffer_type_t buft ,const struct ggml_dyn_tallocr * talloc ,enum ggml_backend_buffer_usage usage ) { 425struct vbuffer * buf = (struct vbuffer * )calloc (1 ,sizeof (struct vbuffer )); 426if (buf == NULL ) { 427return NULL ; 428 } 429 430for (int n = 0 ;n < talloc -> n_chunks ;n ++ ) { 431size_t chunk_size = talloc -> chunks [n ]-> max_size ; 432buf -> chunks [n ]= ggml_backend_buft_alloc_buffer (buft ,chunk_size ); 433if (buf -> chunks [n ]== NULL ) { 434ggml_vbuffer_free (buf ); 435return NULL ; 436 } 437ggml_backend_buffer_set_usage (buf -> chunks [n ],usage ); 438 } 439return buf ; 440} 441 442static void ggml_vbuffer_tensor_alloc (struct vbuffer * buf ,struct ggml_tensor * tensor ,struct buffer_address buf_addr ) { 443void * base = ggml_backend_buffer_get_base (buf -> chunks [buf_addr .chunk ]); 444void * addr = (char * )base + buf_addr .offset ; 445ggml_backend_tensor_alloc (buf -> chunks [buf_addr .chunk ],tensor ,addr ); 446} 447 448static void ggml_vbuffer_reset (struct vbuffer * buf ) { 449for (int i = 0 ;i < GGML_VBUFFER_MAX_CHUNKS && buf -> chunks [i ];++ i ) { 450ggml_backend_buffer_reset (buf -> chunks [i ]); 451 } 452} 453 454 455///////////////////////////////////// 456 457// graph allocator 458 459struct hash_node { 460int n_children ; 461int n_views ; 462int buffer_id ; 463struct buffer_address addr ; 464bool allocated ; 465}; 466 467struct tensor_alloc { 468int buffer_id ; 469struct buffer_address addr ; 470size_t size_max ;// 0 = pre-allocated, unused, or view 471}; 472 473struct leaf_alloc { 474struct tensor_alloc leaf ; 475}; 476 477struct node_alloc { 478struct tensor_alloc dst ; 479struct tensor_alloc src [GGML_MAX_SRC ]; 480}; 481 482struct ggml_gallocr { 483ggml_backend_buffer_type_t * bufts ;// [n_buffers] 484struct vbuffer ** buffers ;// [n_buffers] 485struct ggml_dyn_tallocr ** buf_tallocs ;// [n_buffers] 486int n_buffers ; 487 488struct ggml_hash_set hash_set ; 489struct hash_node * hash_values ;// [hash_set.size] 490 491struct node_alloc * node_allocs ;// [n_nodes] 492int n_nodes ; 493 494struct leaf_alloc * leaf_allocs ;// [n_leafs] 495int n_leafs ; 496}; 497 498ggml_gallocr_t ggml_gallocr_new_n (ggml_backend_buffer_type_t * bufts ,int n_bufs ) { 499ggml_gallocr_t galloc = (ggml_gallocr_t )calloc (1 ,sizeof (struct ggml_gallocr )); 500GGML_ASSERT (galloc != NULL ); 501 502galloc -> bufts = calloc (n_bufs ,sizeof (ggml_backend_buffer_type_t )); 503GGML_ASSERT (galloc -> bufts != NULL ); 504 505galloc -> buffers = calloc (n_bufs ,sizeof (struct vbuffer * )); 506GGML_ASSERT (galloc -> buffers != NULL ); 507 508galloc -> buf_tallocs = calloc (n_bufs ,sizeof (struct ggml_dyn_tallocr * )); 509GGML_ASSERT (galloc -> buf_tallocs != NULL ); 510 511for (int i = 0 ;i < n_bufs ;i ++ ) { 512galloc -> bufts [i ]= bufts [i ]; 513galloc -> buffers [i ]= NULL ; 514 515// check if the same buffer type is used multiple times and reuse the same allocator 516for (int j = 0 ;j < i ;j ++ ) { 517if (bufts [i ]== bufts [j ]) { 518galloc -> buf_tallocs [i ]= galloc -> buf_tallocs [j ]; 519break ; 520 } 521 } 522 523if (galloc -> buf_tallocs [i ]== NULL ) { 524size_t alignment = ggml_backend_buft_get_alignment (bufts [i ]); 525size_t max_size = ggml_backend_buft_get_max_size (bufts [i ]); 526galloc -> buf_tallocs [i ]= ggml_dyn_tallocr_new (alignment ,max_size ); 527 } 528 } 529galloc -> n_buffers = n_bufs ; 530 531return galloc ; 532} 533 534ggml_gallocr_t ggml_gallocr_new (ggml_backend_buffer_type_t buft ) { 535return ggml_gallocr_new_n (& buft ,1 ); 536} 537 538void ggml_gallocr_free (ggml_gallocr_t galloc ) { 539if (galloc == NULL ) { 540return ; 541 } 542 543for (int i = 0 ;i < galloc -> n_buffers ;i ++ ) { 544if (galloc -> buffers != NULL ) { 545// skip if already freed 546bool freed = false; 547for (int j = 0 ;j < i ;j ++ ) { 548if (galloc -> buffers [j ]== galloc -> buffers [i ]) { 549freed = true; 550break ; 551 } 552 } 553if (!freed ) { 554ggml_vbuffer_free (galloc -> buffers [i ]); 555 } 556 } 557if (galloc -> buf_tallocs != NULL ) { 558// skip if already freed 559bool freed = false; 560for (int j = 0 ;j < i ;j ++ ) { 561if (galloc -> buf_tallocs [j ]== galloc -> buf_tallocs [i ]) { 562freed = true; 563break ; 564 } 565 } 566if (!freed ) { 567ggml_dyn_tallocr_free (galloc -> buf_tallocs [i ]); 568 } 569 } 570 } 571 572ggml_hash_set_free (& galloc -> hash_set ); 573free (galloc -> hash_values ); 574free (galloc -> bufts ); 575free (galloc -> buffers ); 576free (galloc -> buf_tallocs ); 577free (galloc -> node_allocs ); 578free (galloc -> leaf_allocs ); 579free (galloc ); 580} 581 582typedef struct ggml_gallocr * ggml_gallocr_t ; 583 584static struct hash_node * ggml_gallocr_hash_get (ggml_gallocr_t galloc ,struct ggml_tensor * t ) { 585size_t i = ggml_hash_find_or_insert (& galloc -> hash_set ,t ); 586return & galloc -> hash_values [i ]; 587} 588 589static bool ggml_gallocr_is_own (ggml_gallocr_t galloc ,struct ggml_tensor * t ) { 590return ggml_gallocr_hash_get (galloc ,t )-> allocated ; 591} 592 593static bool ggml_gallocr_is_allocated (ggml_gallocr_t galloc ,struct ggml_tensor * t ) { 594return t -> data != NULL // tensor data already set externally 595|| t -> buffer // tensor on external buffer (but not yet allocated) 596|| ggml_gallocr_is_own (galloc ,t );// tensor will be allocated by galloc 597} 598 599// free the extra space at the end if the new tensor is smaller 600static void ggml_gallocr_free_extra_space (ggml_gallocr_t galloc ,struct ggml_tensor * node ,struct ggml_tensor * parent ) { 601struct hash_node * hn = ggml_gallocr_hash_get (galloc ,node ); 602struct hash_node * p_hn = ggml_gallocr_hash_get (galloc ,parent ); 603 604size_t parent_size = ggml_backend_buft_get_alloc_size (galloc -> bufts [p_hn -> buffer_id ],parent ); 605size_t node_size = ggml_backend_buft_get_alloc_size (galloc -> bufts [hn -> buffer_id ],node ); 606 607GGML_ASSERT (parent_size >=node_size ); 608 609// note: we want after the freeing the chunks to continue to be aligned 610struct ggml_dyn_tallocr * p_alloc = galloc -> buf_tallocs [p_hn -> buffer_id ]; 611parent_size = aligned_offset (NULL ,parent_size ,p_alloc -> alignment ); 612node_size = aligned_offset (NULL ,node_size ,p_alloc -> alignment ); 613 614if (parent_size > node_size ) { 615struct buffer_address p_addr = p_hn -> addr ; 616p_addr .offset += node_size ; 617size_t extra_size = parent_size - node_size ; 618AT_PRINTF ("freeing extra %zu bytes from parent %s for %s\n" ,extra_size ,parent -> name ,node -> name ); 619ggml_dyn_tallocr_free_bytes (p_alloc ,p_addr ,extra_size ); 620 } 621} 622 623static void ggml_gallocr_allocate_node (ggml_gallocr_t galloc ,struct ggml_tensor * node ,int buffer_id ) { 624GGML_ASSERT (buffer_id >=0 ); 625struct hash_node * hn = ggml_gallocr_hash_get (galloc ,node ); 626 627if (!ggml_gallocr_is_allocated (galloc ,node )&& !ggml_impl_is_view (node )) { 628hn -> allocated = true; 629assert (hn -> addr .offset == 0 ); 630 631// try to reuse a parent's buffer (inplace) 632if (ggml_op_can_inplace (node -> op )) { 633for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 634struct ggml_tensor * parent = node -> src [i ]; 635if (parent == NULL ) { 636continue ; 637 } 638 639// if the node's data is external, then we cannot re-use it 640if (!ggml_gallocr_is_own (galloc ,parent )) { 641AT_PRINTF ("not reusing parent %s for %s as %p is external\n" ,parent -> name ,node -> name ,parent -> data ); 642continue ; 643 } 644 645// outputs cannot be reused 646if (parent -> flags & GGML_TENSOR_FLAG_OUTPUT || (parent -> view_src != NULL && parent -> view_src -> flags & GGML_TENSOR_FLAG_OUTPUT )) { 647AT_PRINTF ("not reusing parent %s for %s as it is an output\n" ,parent -> name ,node -> name ); 648continue ; 649 } 650 651if (!ggml_are_same_layout (node ,parent )) { 652AT_PRINTF ("not reusing parent %s for %s as layouts are different\n" ,parent -> name ,node -> name ); 653continue ; 654 } 655 656struct hash_node * p_hn = ggml_gallocr_hash_get (galloc ,parent ); 657if (p_hn -> n_children == 1 && p_hn -> n_views == 0 ) { 658if (ggml_impl_is_view (parent )) { 659struct ggml_tensor * view_src = parent -> view_src ; 660struct hash_node * view_src_hn = ggml_gallocr_hash_get (galloc ,view_src ); 661if (view_src_hn -> n_views == 1 && view_src_hn -> n_children == 0 && view_src -> data == parent -> data ) { 662AT_PRINTF ("reusing view parent %s (%s) for %s\n" ,parent -> name ,view_src -> name ,node -> name ); 663assert (view_src_hn -> addr .chunk == p_hn -> addr .chunk && view_src_hn -> addr .offset == p_hn -> addr .offset ); 664hn -> buffer_id = p_hn -> buffer_id ; 665hn -> addr = p_hn -> addr ; 666p_hn -> allocated = false;// avoid freeing the parent 667view_src_hn -> allocated = false; 668ggml_gallocr_free_extra_space (galloc ,node ,view_src ); 669return ; 670 } 671 }else { 672AT_PRINTF ("reusing parent %s for %s\n" ,parent -> name ,node -> name ); 673hn -> buffer_id = p_hn -> buffer_id ; 674hn -> addr = p_hn -> addr ; 675p_hn -> allocated = false;// avoid freeing the parent 676ggml_gallocr_free_extra_space (galloc ,node ,parent ); 677return ; 678 } 679 } 680 } 681 } 682// allocate tensor from the buffer 683struct ggml_dyn_tallocr * alloc = galloc -> buf_tallocs [buffer_id ]; 684ggml_backend_buffer_type_t buft = galloc -> bufts [buffer_id ]; 685size_t size = ggml_backend_buft_get_alloc_size (buft ,node ); 686hn -> buffer_id = buffer_id ; 687hn -> addr = ggml_dyn_tallocr_alloc (alloc ,size ,node ); 688 } 689} 690 691static void ggml_gallocr_free_node (ggml_gallocr_t galloc ,struct ggml_tensor * node ) { 692// graph outputs are never freed 693if (node -> flags & GGML_TENSOR_FLAG_OUTPUT ) { 694AT_PRINTF ("not freeing output %s\n" ,node -> name ); 695return ; 696 } 697 698struct hash_node * hn = ggml_gallocr_hash_get (galloc ,node ); 699int buffer_id = hn -> buffer_id ; 700struct ggml_dyn_tallocr * alloc = galloc -> buf_tallocs [buffer_id ]; 701ggml_backend_buffer_type_t buft = galloc -> bufts [buffer_id ]; 702size_t size = ggml_backend_buft_get_alloc_size (buft ,node ); 703 704AT_PRINTF ("%s: freeing %s at {chunk=%d, offset=%zu} (%zu bytes) - n_free_blocks = %d\n" , 705__func__ ,node -> name ,hn -> addr .chunk ,hn -> addr .offset ,size ,alloc -> chunks [hn -> addr .chunk ]-> n_free_blocks ); 706#ifdef GGML_ALLOCATOR_DEBUG 707remove_allocated_tensor (alloc ,hn -> addr ,node ); 708#endif 709 710ggml_dyn_tallocr_free_bytes (alloc ,hn -> addr ,size ); 711hn -> allocated = false; 712} 713 714static int get_node_buffer_id (const int * node_buffer_ids ,int i ) { 715return node_buffer_ids ?node_buffer_ids [i ] :0 ; 716} 717 718static void ggml_gallocr_alloc_graph_impl (ggml_gallocr_t galloc ,struct ggml_cgraph * graph ,const int * node_buffer_ids ,const int * leaf_buffer_ids ) { 719// clear hash tables 720ggml_hash_set_reset (& galloc -> hash_set ); 721memset (galloc -> hash_values ,0 ,sizeof (struct hash_node )* galloc -> hash_set .size ); 722 723// allocate leafs 724// these may be tensors that the application is not using in the graph, but may still want to allocate for other purposes 725for (int i = 0 ;i < graph -> n_leafs ;i ++ ) { 726struct ggml_tensor * leaf = graph -> leafs [i ]; 727ggml_gallocr_allocate_node (galloc ,leaf ,get_node_buffer_id (leaf_buffer_ids ,i )); 728 } 729 730// count number of children and views 731// allocate other graph inputs and leafs first to avoid overwriting them 732for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 733struct ggml_tensor * node = graph -> nodes [i ]; 734 735// TODO: better way to add external dependencies 736// GGML_OP_NONE does not appear normally in the graph nodes, but is used by ggml-backend to add dependencies to 737// control when some tensors are allocated and freed. in this case, the dependencies are in `src`, but the node 738// itself is never used and should not be considered a dependency 739if (ggml_impl_is_view (node )&& node -> op != GGML_OP_NONE ) { 740struct ggml_tensor * view_src = node -> view_src ; 741ggml_gallocr_hash_get (galloc ,view_src )-> n_views += 1 ; 742 } 743 744if (node -> flags & GGML_TENSOR_FLAG_INPUT ) { 745ggml_gallocr_allocate_node (galloc ,graph -> nodes [i ],get_node_buffer_id (node_buffer_ids ,i )); 746 } 747 748for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 749struct ggml_tensor * src = node -> src [j ]; 750if (src == NULL ) { 751continue ; 752 } 753 754ggml_gallocr_hash_get (galloc ,src )-> n_children += 1 ; 755 756// allocate explicit inputs 757if (src -> flags & GGML_TENSOR_FLAG_INPUT ) { 758ggml_gallocr_allocate_node (galloc ,src ,get_node_buffer_id (node_buffer_ids ,i )); 759 } 760 } 761 } 762 763// allocate tensors 764for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 765struct ggml_tensor * node = graph -> nodes [i ]; 766int buffer_id = get_node_buffer_id (node_buffer_ids ,i ); 767 768// allocate parents (only leafs need to be allocated at this point) 769for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 770struct ggml_tensor * parent = node -> src [j ]; 771if (parent == NULL ) { 772continue ; 773 } 774ggml_gallocr_allocate_node (galloc ,parent ,buffer_id ); 775 } 776 777// allocate node 778ggml_gallocr_allocate_node (galloc ,node ,buffer_id ); 779 780AT_PRINTF ("exec: %s (%s) <= " ,ggml_op_desc (node ),node -> name ); 781for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 782struct ggml_tensor * parent = node -> src [j ]; 783if (parent == NULL ) { 784continue ; 785 } 786AT_PRINTF ("%s" ,parent -> name ); 787if (j < GGML_MAX_SRC - 1 && node -> src [j + 1 ]!= NULL ) { 788AT_PRINTF (", " ); 789 } 790 } 791AT_PRINTF ("\n" ); 792 793// update parents 794for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 795struct ggml_tensor * parent = node -> src [j ]; 796if (parent == NULL ) { 797continue ; 798 } 799struct hash_node * p_hn = ggml_gallocr_hash_get (galloc ,parent ); 800p_hn -> n_children -= 1 ; 801 802AT_PRINTF ("parent %s: %d children, %d views, allocated: %d\n" , 803parent -> name ,p_hn -> n_children ,p_hn -> n_views ,p_hn -> allocated ); 804 805if (p_hn -> n_children == 0 && p_hn -> n_views == 0 ) { 806if (ggml_impl_is_view (parent )) { 807struct ggml_tensor * view_src = parent -> view_src ; 808struct hash_node * view_src_hn = ggml_gallocr_hash_get (galloc ,view_src ); 809view_src_hn -> n_views -= 1 ; 810AT_PRINTF ("view_src %s: %d children, %d views\n" , 811view_src -> name ,view_src_hn -> n_children ,view_src_hn -> n_views ); 812if (view_src_hn -> n_views == 0 && view_src_hn -> n_children == 0 && view_src_hn -> allocated ) { 813ggml_gallocr_free_node (galloc ,view_src ); 814 } 815 } 816else if (p_hn -> allocated ) { 817ggml_gallocr_free_node (galloc ,parent ); 818 } 819 } 820AT_PRINTF ("\n" ); 821 } 822 } 823} 824 825static bool ggml_gallocr_reserve_n_impl ( 826ggml_gallocr_t galloc ,struct ggml_cgraph * graph ,const int * node_buffer_ids ,const int * leaf_buffer_ids ,bool no_alloc ) { 827size_t min_hash_size = graph -> n_nodes + graph -> n_leafs ; 828// add 25% margin to avoid hash collisions 829min_hash_size += min_hash_size /4 ; 830 831// initialize hash table 832if (galloc -> hash_set .size < min_hash_size ) { 833ggml_hash_set_free (& galloc -> hash_set ); 834galloc -> hash_set = ggml_hash_set_new (min_hash_size ); 835GGML_ASSERT (galloc -> hash_set .keys != NULL ); 836 837free (galloc -> hash_values ); 838galloc -> hash_values = malloc (sizeof (struct hash_node )* galloc -> hash_set .size ); 839GGML_ASSERT (galloc -> hash_values != NULL ); 840 } 841 842// reset allocators 843for (int i = 0 ;i < galloc -> n_buffers ;i ++ ) { 844ggml_dyn_tallocr_reset (galloc -> buf_tallocs [i ]); 845 } 846 847// allocate in hash table 848ggml_gallocr_alloc_graph_impl (galloc ,graph ,node_buffer_ids ,leaf_buffer_ids ); 849 850// set the node_allocs from the hash table 851if (galloc -> n_nodes < graph -> n_nodes ) { 852free (galloc -> node_allocs ); 853galloc -> node_allocs = calloc (graph -> n_nodes ,sizeof (struct node_alloc )); 854GGML_ASSERT (galloc -> node_allocs != NULL ); 855 } 856galloc -> n_nodes = graph -> n_nodes ; 857for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 858struct ggml_tensor * node = graph -> nodes [i ]; 859struct node_alloc * node_alloc = & galloc -> node_allocs [i ]; 860if (node -> view_src || node -> data ) { 861node_alloc -> dst .buffer_id = -1 ; 862node_alloc -> dst .addr = GGML_BUFFER_ADDRESS_INVALID ; 863node_alloc -> dst .size_max = 0 ; 864 }else { 865struct hash_node * hn = ggml_gallocr_hash_get (galloc ,node ); 866node_alloc -> dst .buffer_id = hn -> buffer_id ; 867node_alloc -> dst .addr = hn -> addr ; 868node_alloc -> dst .size_max = ggml_backend_buft_get_alloc_size (galloc -> bufts [hn -> buffer_id ],node ); 869 } 870for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 871struct ggml_tensor * src = node -> src [j ]; 872if (!src || src -> view_src || src -> data ) { 873node_alloc -> src [j ].buffer_id = -1 ; 874node_alloc -> src [j ].addr = GGML_BUFFER_ADDRESS_INVALID ; 875node_alloc -> src [j ].size_max = 0 ; 876 }else { 877struct hash_node * hn = ggml_gallocr_hash_get (galloc ,src ); 878node_alloc -> src [j ].buffer_id = hn -> buffer_id ; 879node_alloc -> src [j ].addr = hn -> addr ; 880node_alloc -> src [j ].size_max = ggml_backend_buft_get_alloc_size (galloc -> bufts [hn -> buffer_id ],src ); 881 } 882 } 883 } 884if (galloc -> n_leafs < graph -> n_leafs ) { 885free (galloc -> leaf_allocs ); 886galloc -> leaf_allocs = calloc (graph -> n_leafs ,sizeof (galloc -> leaf_allocs [0 ])); 887GGML_ASSERT (galloc -> leaf_allocs != NULL ); 888 } 889galloc -> n_leafs = graph -> n_leafs ; 890for (int i = 0 ;i < graph -> n_leafs ;i ++ ) { 891struct ggml_tensor * leaf = graph -> leafs [i ]; 892struct hash_node * hn = ggml_gallocr_hash_get (galloc ,leaf ); 893if (leaf -> view_src || leaf -> data ) { 894galloc -> leaf_allocs [i ].leaf .buffer_id = -1 ; 895galloc -> leaf_allocs [i ].leaf .addr = GGML_BUFFER_ADDRESS_INVALID ; 896galloc -> leaf_allocs [i ].leaf .size_max = 0 ; 897 }else { 898galloc -> leaf_allocs [i ].leaf .buffer_id = hn -> buffer_id ; 899galloc -> leaf_allocs [i ].leaf .addr = hn -> addr ; 900galloc -> leaf_allocs [i ].leaf .size_max = ggml_backend_buft_get_alloc_size (galloc -> bufts [hn -> buffer_id ],leaf ); 901 } 902 } 903 904// reallocate buffers if needed 905for (int i = 0 ;i < galloc -> n_buffers ;i ++ ) { 906// if the buffer type is used multiple times, we reuse the same buffer 907for (int j = 0 ;j < i ;j ++ ) { 908if (galloc -> buf_tallocs [j ]== galloc -> buf_tallocs [i ]) { 909galloc -> buffers [i ]= galloc -> buffers [j ]; 910break ; 911 } 912 } 913 914// even if there are no tensors allocated in this buffer, we still need to allocate it to initialize views 915bool realloc = galloc -> buffers [i ]== NULL ; 916size_t new_size = 0 ; 917for (int c = 0 ;c < galloc -> buf_tallocs [i ]-> n_chunks ;c ++ ) { 918size_t cur_chunk_size = galloc -> buffers [i ] ?ggml_vbuffer_chunk_size (galloc -> buffers [i ],c ) :0 ; 919size_t new_chunk_size = ggml_dyn_tallocr_max_size (galloc -> buf_tallocs [i ],c ); 920new_size += new_chunk_size ; 921if (new_chunk_size > cur_chunk_size ) { 922realloc = true; 923 } 924 } 925if (realloc ) { 926#ifndef NDEBUG 927 { 928size_t cur_size = galloc -> buffers [i ] ?ggml_vbuffer_size (galloc -> buffers [i ]) :0 ; 929if (cur_size > 0 ) { 930GGML_LOG_DEBUG ("%s: reallocating %s buffer from size %.02f MiB to %.02f MiB\n" , 931__func__ ,ggml_backend_buft_name (galloc -> bufts [i ]),cur_size /1024.0 /1024.0 ,new_size /1024.0 /1024.0 ); 932 } 933 } 934#endif 935ggml_vbuffer_free (galloc -> buffers [i ]); 936if (no_alloc ) { 937galloc -> buffers [i ]= NULL ; 938 }else { 939galloc -> buffers [i ]= ggml_vbuffer_alloc (galloc -> bufts [i ],galloc -> buf_tallocs [i ],GGML_BACKEND_BUFFER_USAGE_COMPUTE ); 940if (galloc -> buffers [i ]== NULL ) { 941GGML_LOG_ERROR ("%s: failed to allocate %s buffer of size %zu\n" ,__func__ ,ggml_backend_buft_name (galloc -> bufts [i ]),new_size ); 942return false; 943 } 944 } 945 } 946 } 947 948return true; 949} 950 951void ggml_gallocr_reserve_n_size ( 952ggml_gallocr_t galloc ,struct ggml_cgraph * graph ,const int * node_buffer_ids ,const int * leaf_buffer_ids ,size_t * sizes ) { 953GGML_ASSERT (ggml_gallocr_reserve_n_impl (galloc ,graph ,node_buffer_ids ,leaf_buffer_ids ,/*no_alloc =*/ true)); 954for (int i = 0 ;i < galloc -> n_buffers ;i ++ ) { 955sizes [i ]= 0 ; 956for (int c = 0 ;c < galloc -> buf_tallocs [i ]-> n_chunks ;c ++ ) { 957sizes [i ]+= galloc -> buf_tallocs [i ]-> chunks [c ]-> max_size ; 958 } 959 } 960} 961 962bool ggml_gallocr_reserve_n (ggml_gallocr_t galloc ,struct ggml_cgraph * graph ,const int * node_buffer_ids ,const int * leaf_buffer_ids ) { 963return ggml_gallocr_reserve_n_impl (galloc ,graph ,node_buffer_ids ,leaf_buffer_ids ,/*no_alloc =*/ false); 964} 965 966bool ggml_gallocr_reserve (ggml_gallocr_t galloc ,struct ggml_cgraph * graph ) { 967return ggml_gallocr_reserve_n (galloc ,graph ,NULL ,NULL ); 968} 969 970static void ggml_gallocr_init_tensor (ggml_gallocr_t galloc ,struct ggml_tensor * tensor ,struct tensor_alloc * tensor_alloc ) { 971int buffer_id = tensor_alloc -> buffer_id ; 972assert (tensor -> data || tensor -> view_src || ggml_backend_buft_get_alloc_size (galloc -> bufts [buffer_id ],tensor ) <=tensor_alloc -> size_max ); 973 974if (tensor -> view_src != NULL ) { 975if (tensor -> buffer == NULL ) { 976assert (tensor_alloc -> addr .offset == SIZE_MAX ); 977if (tensor -> view_src -> buffer == NULL ) { 978// this tensor was allocated without ggml-backend 979return ; 980 } 981ggml_backend_view_init (tensor ); 982 } 983 }else { 984if (tensor -> data == NULL ) { 985assert (tensor_alloc -> addr .offset != SIZE_MAX ); 986assert (ggml_backend_buft_get_alloc_size (galloc -> bufts [buffer_id ],tensor ) <=tensor_alloc -> size_max ); 987ggml_vbuffer_tensor_alloc (galloc -> buffers [buffer_id ],tensor ,tensor_alloc -> addr ); 988 }else { 989if (tensor -> buffer == NULL ) { 990// this tensor was allocated without ggml-backend 991return ; 992 } 993 } 994 } 995} 996 997static bool ggml_gallocr_node_needs_realloc (ggml_gallocr_t galloc ,struct ggml_tensor * node ,struct tensor_alloc * talloc ) { 998size_t node_size = 0 ; 999if (!node -> data && !node -> view_src ) { 1000// If we previously had data but don't now then reallocate 1001if (talloc -> buffer_id < 0 ) { 1002return false; 1003 } 1004node_size = ggml_backend_buft_get_alloc_size (galloc -> bufts [talloc -> buffer_id ],node ); 1005 } 1006return talloc -> size_max >=node_size ; 1007} 1008 1009static bool ggml_gallocr_needs_realloc (ggml_gallocr_t galloc ,struct ggml_cgraph * graph ) { 1010if (galloc -> n_nodes != graph -> n_nodes ) { 1011#ifndef NDEBUG 1012GGML_LOG_DEBUG ("%s: graph has different number of nodes\n" ,__func__ ); 1013#endif 1014return true; 1015 } 1016 1017if (galloc -> n_leafs != graph -> n_leafs ) { 1018#ifndef NDEBUG 1019GGML_LOG_DEBUG ("%s: graph has different number of leafs\n" ,__func__ ); 1020#endif 1021return true; 1022 } 1023 1024for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1025struct ggml_tensor * node = graph -> nodes [i ]; 1026struct node_alloc * node_alloc = & galloc -> node_allocs [i ]; 1027 1028if (!ggml_gallocr_node_needs_realloc (galloc ,node ,& node_alloc -> dst )) { 1029#ifndef NDEBUG 1030GGML_LOG_DEBUG ("%s: node %s is not valid\n" ,__func__ ,node -> name ); 1031#endif 1032return true; 1033 } 1034 1035for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1036struct ggml_tensor * src = node -> src [j ]; 1037if (src == NULL ) { 1038continue ; 1039 } 1040if (!ggml_gallocr_node_needs_realloc (galloc ,src ,& node_alloc -> src [j ])) { 1041#ifndef NDEBUG 1042GGML_LOG_DEBUG ("%s: src %d (%s) of node %s is not valid\n" ,__func__ ,j ,src -> name ,node -> name ); 1043#endif 1044return true; 1045 } 1046 } 1047 } 1048 1049return false; 1050} 1051 1052bool ggml_gallocr_alloc_graph (ggml_gallocr_t galloc ,struct ggml_cgraph * graph ) { 1053if (ggml_gallocr_needs_realloc (galloc ,graph )) { 1054if (galloc -> n_buffers == 1 ) { 1055#ifndef NDEBUG 1056GGML_LOG_DEBUG ("%s: reallocating buffers automatically\n" ,__func__ ); 1057#endif 1058if (!ggml_gallocr_reserve (galloc ,graph )) { 1059return false; 1060 } 1061 }else { 1062#ifndef NDEBUG 1063GGML_LOG_DEBUG ("%s: cannot reallocate multi buffer graph automatically, call reserve\n" ,__func__ ); 1064#endif 1065return false; 1066 } 1067 } 1068 1069// reset buffers 1070for (int i = 0 ;i < galloc -> n_buffers ;i ++ ) { 1071if (galloc -> buffers [i ]!= NULL ) { 1072ggml_vbuffer_reset (galloc -> buffers [i ]); 1073 } 1074 } 1075 1076// allocate the graph tensors from the previous assignments 1077// leafs 1078for (int i = 0 ;i < graph -> n_leafs ;i ++ ) { 1079struct ggml_tensor * leaf = graph -> leafs [i ]; 1080struct leaf_alloc * leaf_alloc = & galloc -> leaf_allocs [i ]; 1081ggml_gallocr_init_tensor (galloc ,leaf ,& leaf_alloc -> leaf ); 1082 } 1083// nodes 1084for (int i = 0 ;i < graph -> n_nodes ;i ++ ) { 1085struct ggml_tensor * node = graph -> nodes [i ]; 1086struct node_alloc * node_alloc = & galloc -> node_allocs [i ]; 1087for (int j = 0 ;j < GGML_MAX_SRC ;j ++ ) { 1088struct ggml_tensor * src = node -> src [j ]; 1089if (src == NULL ) { 1090continue ; 1091 } 1092ggml_gallocr_init_tensor (galloc ,src ,& node_alloc -> src [j ]); 1093 } 1094ggml_gallocr_init_tensor (galloc ,node ,& node_alloc -> dst ); 1095 } 1096 1097return true; 1098} 1099 1100size_t ggml_gallocr_get_buffer_size (ggml_gallocr_t galloc ,int buffer_id ) { 1101GGML_ASSERT (buffer_id >=0 && buffer_id < galloc -> n_buffers ); 1102 1103if (galloc -> buffers [buffer_id ]== NULL ) { 1104return 0 ; 1105 } 1106 1107for (int i = 0 ;i < buffer_id ;i ++ ) { 1108if (galloc -> buffers [i ]== galloc -> buffers [buffer_id ]) { 1109// this buffer is the same as a previous one due to the same buffer type being used multiple times 1110// only return the buffer size the first time it appears to avoid double counting 1111return 0 ; 1112 } 1113 } 1114 1115return ggml_vbuffer_size (galloc -> buffers [buffer_id ]); 1116} 1117 1118// utils 1119 1120static void free_buffers (ggml_backend_buffer_t ** buffers ,const size_t * n_buffers ) { 1121for (size_t i = 0 ;i < * n_buffers ;i ++ ) { 1122ggml_backend_buffer_free ((* buffers )[i ]); 1123 } 1124free (* buffers ); 1125} 1126 1127static bool alloc_tensor_range (struct ggml_context * ctx , 1128struct ggml_tensor * first ,struct ggml_tensor * last , 1129ggml_backend_buffer_type_t buft ,size_t size , 1130ggml_backend_buffer_t ** buffers ,size_t * n_buffers ) { 1131 1132ggml_backend_buffer_t buffer = ggml_backend_buft_alloc_buffer (buft ,size ); 1133if (buffer == NULL ) { 1134GGML_LOG_ERROR ("%s: failed to allocate %s buffer of size %zu\n" ,__func__ ,ggml_backend_buft_name (buft ),size ); 1135free_buffers (buffers ,n_buffers ); 1136return false; 1137 } 1138 1139* buffers = realloc (* buffers ,sizeof (ggml_backend_buffer_t )* (* n_buffers + 1 )); 1140 (* buffers )[(* n_buffers )++ ]= buffer ; 1141 1142struct ggml_tallocr tallocr = ggml_tallocr_new (buffer ); 1143 1144for (struct ggml_tensor * t = first ;t != last ;t = ggml_get_next_tensor (ctx ,t )) { 1145enum ggml_status status = GGML_STATUS_SUCCESS ; 1146if (t -> data == NULL ) { 1147if (t -> view_src == NULL ) { 1148status = ggml_tallocr_alloc (& tallocr ,t ); 1149 }else if (t -> buffer == NULL ) { 1150status = ggml_backend_view_init (t ); 1151 } 1152 }else { 1153if (t -> view_src != NULL && t -> buffer == NULL ) { 1154// view of a pre-allocated tensor 1155status = ggml_backend_view_init (t ); 1156 } 1157 } 1158if (status != GGML_STATUS_SUCCESS ) { 1159GGML_LOG_ERROR ("%s: failed to initialize tensor %s\n" ,__func__ ,t -> name ); 1160free_buffers (buffers ,n_buffers ); 1161return false; 1162 } 1163 } 1164 1165return true; 1166} 1167 1168static ggml_backend_buffer_t ggml_backend_alloc_ctx_tensors_from_buft_impl ( 1169struct ggml_context * ctx ,ggml_backend_buffer_type_t buft ,size_t * nbytes_total ,bool no_alloc ) { 1170GGML_ASSERT (ggml_get_no_alloc (ctx )== true); 1171 1172size_t alignment = ggml_backend_buft_get_alignment (buft ); 1173size_t max_size = ggml_backend_buft_get_max_size (buft ); 1174 1175ggml_backend_buffer_t * buffers = NULL ; 1176size_t n_buffers = 0 ; 1177* nbytes_total = 0 ; 1178 1179size_t cur_buf_size = 0 ; 1180struct ggml_tensor * first = ggml_get_first_tensor (ctx ); 1181for (struct ggml_tensor * t = first ;t != NULL ;t = ggml_get_next_tensor (ctx ,t )) { 1182size_t this_size = 0 ; 1183if (t -> data == NULL && t -> view_src == NULL ) { 1184this_size = GGML_PAD (ggml_backend_buft_get_alloc_size (buft ,t ),alignment ); 1185 } 1186 1187if (cur_buf_size > 0 && (cur_buf_size + this_size )> max_size ) { 1188// allocate tensors in the current buffer 1189if (!no_alloc && !alloc_tensor_range (ctx ,first ,t ,buft ,cur_buf_size ,& buffers ,& n_buffers )) { 1190return NULL ; 1191 } 1192first = t ; 1193* nbytes_total += cur_buf_size ; 1194cur_buf_size = this_size ; 1195 }else { 1196cur_buf_size += this_size ; 1197 } 1198 } 1199 1200// allocate remaining tensors 1201if (cur_buf_size > 0 ) { 1202* nbytes_total += cur_buf_size ; 1203if (!no_alloc && !alloc_tensor_range (ctx ,first ,NULL ,buft ,cur_buf_size ,& buffers ,& n_buffers )) { 1204return NULL ; 1205 } 1206 } 1207 1208if (no_alloc ) { 1209return NULL ; 1210 } 1211 1212if (n_buffers == 0 ) { 1213#ifndef NDEBUG 1214GGML_LOG_DEBUG ("%s: all tensors in the context are already allocated\n" ,__func__ ); 1215#endif 1216GGML_ASSERT (!buffers ); 1217return NULL ; 1218 } 1219 1220ggml_backend_buffer_t buffer ; 1221if (n_buffers == 1 ) { 1222buffer = buffers [0 ]; 1223 }else { 1224buffer = ggml_backend_multi_buffer_alloc_buffer (buffers ,n_buffers ); 1225 } 1226if (buffers ) { 1227free (buffers );// can be NULL if context is empty or no_alloc 1228 } 1229return buffer ; 1230} 1231 1232size_t ggml_backend_alloc_ctx_tensors_from_buft_size (struct ggml_context * ctx ,ggml_backend_buffer_type_t buft ) { 1233size_t nbytes_total = 0 ; 1234ggml_backend_buffer_t buf = ggml_backend_alloc_ctx_tensors_from_buft_impl (ctx ,buft ,& nbytes_total ,/*no_alloc=*/ true); 1235GGML_ASSERT (!buf ); 1236return nbytes_total ; 1237} 1238 1239ggml_backend_buffer_t ggml_backend_alloc_ctx_tensors_from_buft (struct ggml_context * ctx ,ggml_backend_buffer_type_t buft ) { 1240size_t nbytes_total = 0 ; 1241if (ggml_backend_buft_is_meta (buft )) { 1242return ggml_backend_meta_alloc_ctx_tensors_from_buft (ctx ,buft ); 1243 } 1244return ggml_backend_alloc_ctx_tensors_from_buft_impl (ctx ,buft ,& nbytes_total ,/*no_alloc =*/ false); 1245} 1246 1247ggml_backend_buffer_t ggml_backend_alloc_ctx_tensors (struct ggml_context * ctx ,ggml_backend_t backend ) { 1248return ggml_backend_alloc_ctx_tensors_from_buft (ctx ,ggml_backend_get_default_buffer_type (backend )); 1249}