MCPcopy Create free account
hub / github.com/Tiiny-AI/PowerInfer / ggml_tallocr_free_tensor

Function ggml_tallocr_free_tensor

ggml-alloc.c:156–225  ·  view source on GitHub ↗

this is a very naive implementation, but for our case the number of free blocks should be very small

Source from the content-addressed store, hash-verified

154
155// this is a very naive implementation, but for our case the number of free blocks should be very small
156static void ggml_tallocr_free_tensor(ggml_tallocr_t alloc, struct ggml_tensor * tensor) {
157 if (ggml_tallocr_is_own(alloc, tensor) == false) {
158 // the tensor was not allocated in this buffer
159 // this can happen because the graph allocator will try to free weights and other tensors from different buffers
160 // the easiest way to deal with this is just to ignore it
161 // AT_PRINTF("ignoring %s (their buffer: %p, our buffer: %p)\n", tensor->name, (void *)tensor->buffer, (void *)alloc->buffer);
162 return;
163 }
164
165 void * ptr = tensor->data;
166
167 size_t size = ggml_backend_buffer_get_alloc_size(alloc->buffer, tensor);
168 size = aligned_offset(NULL, size, alloc->alignment);
169 AT_PRINTF("%s: freeing %s at %p (%zu bytes) - n_free_blocks = %d\n", __func__, tensor->name, ptr, size, alloc->n_free_blocks);
170
171 if (!alloc->measure) {
172 ggml_backend_buffer_free_tensor(alloc->buffer, tensor);
173 }
174
175#ifdef GGML_ALLOCATOR_DEBUG
176 remove_allocated_tensor(alloc, tensor);
177#endif
178
179 // see if we can merge with an existing block
180 for (int i = 0; i < alloc->n_free_blocks; i++) {
181 struct free_block * block = &alloc->free_blocks[i];
182 // check if ptr is at the end of the block
183 if ((char*)block->addr + block->size == ptr) {
184 block->size += size;
185 // check if we can merge with the next block
186 if (i < alloc->n_free_blocks - 1 && (char*)block->addr + block->size == alloc->free_blocks[i+1].addr) {
187 block->size += alloc->free_blocks[i+1].size;
188 alloc->n_free_blocks--;
189 for (int j = i+1; j < alloc->n_free_blocks; j++) {
190 alloc->free_blocks[j] = alloc->free_blocks[j+1];
191 }
192 }
193 return;
194 }
195 // check if ptr is at the beginning of the block
196 if ((char*)ptr + size == block->addr) {
197 block->addr = ptr;
198 block->size += size;
199 // check if we can merge with the previous block
200 if (i > 0 && (char*)alloc->free_blocks[i-1].addr + alloc->free_blocks[i-1].size == block->addr) {
201 alloc->free_blocks[i-1].size += block->size;
202 alloc->n_free_blocks--;
203 for (int j = i; j < alloc->n_free_blocks; j++) {
204 alloc->free_blocks[j] = alloc->free_blocks[j+1];
205 }
206 }
207 return;
208 }
209 }
210 // otherwise, add a new block
211 GGML_ASSERT(alloc->n_free_blocks < MAX_FREE_BLOCKS && "out of free blocks");
212 // insert the new block in the correct position to keep the array sorted by address (to make merging blocks faster)
213 int insert_pos = 0;

Callers 1

free_nodeFunction · 0.85

Calls 5

ggml_tallocr_is_ownFunction · 0.85
aligned_offsetFunction · 0.70
remove_allocated_tensorFunction · 0.70

Tested by

no test coverage detected