mirror of
				https://github.com/ggml-org/llama.cpp.git
				synced 2025-11-03 09:22:01 +00:00 
			
		
		
		
	metal : use vm_allocate instead of posix_memalign on macOS (#7078)
				
					
				
			* fix: use `malloc` instead of `posix_memalign` in `ggml-metal.m` to make it not crash Electron proccesses * fix: typo * fix: use `vm_allocate` instead of `posix_memalign` * fix: don't call `newBufferWithBytesNoCopy` with `NULL` when `ggml_metal_host_malloc` returns `NULL` * fix: use `vm_allocate` only on macOS
This commit is contained in:
		
							
								
								
									
										17
									
								
								ggml-metal.m
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								ggml-metal.m
									
									
									
									
									
								
							@@ -265,11 +265,20 @@ static void ggml_metal_log(enum ggml_log_level level, const char * format, ...){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void * ggml_metal_host_malloc(size_t n) {
 | 
					static void * ggml_metal_host_malloc(size_t n) {
 | 
				
			||||||
    void * data = NULL;
 | 
					    void * data = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if TARGET_OS_OSX
 | 
				
			||||||
 | 
					    kern_return_t err = vm_allocate((vm_map_t) mach_task_self(), (void *) &data, n, VM_FLAGS_ANYWHERE);
 | 
				
			||||||
 | 
					    if (err != KERN_SUCCESS) {
 | 
				
			||||||
 | 
					        GGML_METAL_LOG_ERROR("%s: error: vm_allocate failed\n", __func__);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    const int result = posix_memalign((void **) &data, sysconf(_SC_PAGESIZE), n);
 | 
					    const int result = posix_memalign((void **) &data, sysconf(_SC_PAGESIZE), n);
 | 
				
			||||||
    if (result != 0) {
 | 
					    if (result != 0) {
 | 
				
			||||||
        GGML_METAL_LOG_ERROR("%s: error: posix_memalign failed\n", __func__);
 | 
					        GGML_METAL_LOG_ERROR("%s: error: posix_memalign failed\n", __func__);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return data;
 | 
					    return data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2840,7 +2849,11 @@ GGML_CALL static void ggml_backend_metal_buffer_free_buffer(ggml_backend_buffer_
 | 
				
			|||||||
    ggml_backend_metal_free_device();
 | 
					    ggml_backend_metal_free_device();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ctx->owned) {
 | 
					    if (ctx->owned) {
 | 
				
			||||||
 | 
					#if TARGET_OS_OSX
 | 
				
			||||||
 | 
					        vm_deallocate((vm_map_t)mach_task_self(), (vm_address_t)ctx->all_data, ctx->all_size);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
        free(ctx->all_data);
 | 
					        free(ctx->all_data);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    free(ctx);
 | 
					    free(ctx);
 | 
				
			||||||
@@ -2944,14 +2957,16 @@ GGML_CALL static ggml_backend_buffer_t ggml_backend_metal_buffer_type_alloc_buff
 | 
				
			|||||||
    ctx->owned = true;
 | 
					    ctx->owned = true;
 | 
				
			||||||
    ctx->n_buffers = 1;
 | 
					    ctx->n_buffers = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ctx->all_data != NULL) {
 | 
				
			||||||
        ctx->buffers[0].data = ctx->all_data;
 | 
					        ctx->buffers[0].data = ctx->all_data;
 | 
				
			||||||
        ctx->buffers[0].size = size;
 | 
					        ctx->buffers[0].size = size;
 | 
				
			||||||
        ctx->buffers[0].metal = [device newBufferWithBytesNoCopy:ctx->all_data
 | 
					        ctx->buffers[0].metal = [device newBufferWithBytesNoCopy:ctx->all_data
 | 
				
			||||||
                        length:size_aligned
 | 
					                        length:size_aligned
 | 
				
			||||||
                        options:MTLResourceStorageModeShared
 | 
					                        options:MTLResourceStorageModeShared
 | 
				
			||||||
                        deallocator:nil];
 | 
					                        deallocator:nil];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ctx->buffers[0].metal == nil) {
 | 
					    if (ctx->all_data == NULL || ctx->buffers[0].metal == nil) {
 | 
				
			||||||
        GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_aligned / 1024.0 / 1024.0);
 | 
					        GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_aligned / 1024.0 / 1024.0);
 | 
				
			||||||
        free(ctx);
 | 
					        free(ctx);
 | 
				
			||||||
        ggml_backend_metal_free_device();
 | 
					        ggml_backend_metal_free_device();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user