mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 17:24:57 +02:00
metal : fix more leaks due to missing autoreleasepools
This commit is contained in:
@@ -69,6 +69,10 @@ struct ggml_metal {
|
||||
// extra command buffers for things like getting, setting and copying tensors
|
||||
NSMutableArray * cmd_bufs_ext;
|
||||
|
||||
// buffers to release after async Metal operations complete
|
||||
// if Metal released them, it would do so on a Metal-internal thread without an autorelease pool, which could cause leaks
|
||||
NSMutableArray * bufs_release_later;
|
||||
|
||||
// the last command buffer queued into the Metal queue with operations relevant to the current Metal backend
|
||||
id<MTLCommandBuffer> cmd_buf_last;
|
||||
|
||||
@@ -178,7 +182,8 @@ ggml_metal_t ggml_metal_init(ggml_metal_device_t dev) {
|
||||
res->cmd_bufs[i].obj = nil;
|
||||
}
|
||||
|
||||
res->cmd_bufs_ext = [[NSMutableArray alloc] init];
|
||||
res->cmd_bufs_ext = [[NSMutableArray alloc] init];
|
||||
res->bufs_release_later = [[NSMutableArray alloc] init];
|
||||
|
||||
res->cmd_buf_last = nil;
|
||||
|
||||
@@ -206,6 +211,11 @@ void ggml_metal_free(ggml_metal_t ctx) {
|
||||
[ctx->cmd_bufs_ext removeAllObjects];
|
||||
[ctx->cmd_bufs_ext release];
|
||||
|
||||
@autoreleasepool {
|
||||
[ctx->bufs_release_later removeAllObjects];
|
||||
[ctx->bufs_release_later release];
|
||||
}
|
||||
|
||||
if (ctx->pipelines_ext) {
|
||||
ggml_metal_pipelines_free(ctx->pipelines_ext);
|
||||
ctx->pipelines_ext = nil;
|
||||
@@ -294,6 +304,10 @@ void ggml_metal_synchronize(ggml_metal_t ctx) {
|
||||
|
||||
[ctx->cmd_bufs_ext removeAllObjects];
|
||||
}
|
||||
|
||||
@autoreleasepool {
|
||||
[ctx->bufs_release_later removeAllObjects];
|
||||
}
|
||||
}
|
||||
|
||||
static struct ggml_metal_buffer_id ggml_metal_get_buffer_id(const struct ggml_tensor * t) {
|
||||
@@ -337,6 +351,8 @@ void ggml_metal_set_tensor_async(ggml_metal_t ctx, struct ggml_tensor * tensor,
|
||||
|
||||
[encoder endEncoding];
|
||||
[cmd_buf commit];
|
||||
|
||||
[ctx->bufs_release_later addObject:buf_src];
|
||||
[buf_src release];
|
||||
|
||||
// do not wait here for completion
|
||||
@@ -381,6 +397,8 @@ void ggml_metal_get_tensor_async(ggml_metal_t ctx, const struct ggml_tensor * te
|
||||
|
||||
[encoder endEncoding];
|
||||
[cmd_buf commit];
|
||||
|
||||
[ctx->bufs_release_later addObject:buf_dst];
|
||||
[buf_dst release];
|
||||
|
||||
// do not wait here for completion
|
||||
|
||||
@@ -1279,19 +1279,21 @@ ggml_metal_device_t ggml_metal_device_init(int device, int n_devices) {
|
||||
void ggml_metal_device_free(ggml_metal_device_t dev) {
|
||||
assert(dev != NULL);
|
||||
|
||||
ggml_metal_rsets_free(dev->rsets);
|
||||
@autoreleasepool {
|
||||
ggml_metal_rsets_free(dev->rsets);
|
||||
|
||||
ggml_metal_library_free(dev->library);
|
||||
dev->library = NULL;
|
||||
ggml_metal_library_free(dev->library);
|
||||
dev->library = NULL;
|
||||
|
||||
if (dev->mtl_queue) {
|
||||
[dev->mtl_queue release];
|
||||
dev->mtl_queue = nil;
|
||||
}
|
||||
if (dev->mtl_queue) {
|
||||
[dev->mtl_queue release];
|
||||
dev->mtl_queue = nil;
|
||||
}
|
||||
|
||||
if (dev->mtl_device) {
|
||||
[dev->mtl_device release];
|
||||
dev->mtl_device = nil;
|
||||
if (dev->mtl_device) {
|
||||
[dev->mtl_device release];
|
||||
dev->mtl_device = nil;
|
||||
}
|
||||
}
|
||||
|
||||
free(dev);
|
||||
@@ -2118,14 +2120,16 @@ ggml_metal_buffer_t ggml_metal_buffer_map(ggml_metal_device_t dev, void * ptr, s
|
||||
}
|
||||
|
||||
void ggml_metal_buffer_free(ggml_metal_buffer_t buf) {
|
||||
ggml_metal_device_rsets_rm(buf->dev, buf->rset);
|
||||
@autoreleasepool {
|
||||
ggml_metal_device_rsets_rm(buf->dev, buf->rset);
|
||||
|
||||
for (int i = 0; i < buf->n_buffers; i++) {
|
||||
[buf->buffers[i].metal release];
|
||||
for (int i = 0; i < buf->n_buffers; i++) {
|
||||
[buf->buffers[i].metal release];
|
||||
}
|
||||
|
||||
ggml_metal_buffer_rset_free(buf);
|
||||
}
|
||||
|
||||
ggml_metal_buffer_rset_free(buf);
|
||||
|
||||
if (buf->is_shared && buf->owned) {
|
||||
#if TARGET_OS_OSX
|
||||
vm_deallocate((vm_map_t)mach_task_self(), (vm_address_t)buf->all_data, buf->all_size);
|
||||
|
||||
Reference in New Issue
Block a user