Skip to content

Commit a2cb5b4

Browse files
committed
metal : handle zero-sized allocs (llama/9466)
1 parent 288ae51 commit a2cb5b4

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

ggml/src/ggml-metal.m

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3226,15 +3226,19 @@ GGML_CALL static ggml_backend_buffer_t ggml_backend_metal_buffer_type_alloc_buff
32263226
ctx->n_buffers = 1;
32273227

32283228
if (ctx->all_data != NULL) {
3229-
ctx->buffers[0].data = ctx->all_data;
3230-
ctx->buffers[0].size = size;
3231-
ctx->buffers[0].metal = [device newBufferWithBytesNoCopy:ctx->all_data
3232-
length:size_aligned
3233-
options:MTLResourceStorageModeShared
3234-
deallocator:nil];
3229+
ctx->buffers[0].data = ctx->all_data;
3230+
ctx->buffers[0].size = size;
3231+
ctx->buffers[0].metal = nil;
3232+
3233+
if (size_aligned > 0) {
3234+
ctx->buffers[0].metal = [device newBufferWithBytesNoCopy:ctx->all_data
3235+
length:size_aligned
3236+
options:MTLResourceStorageModeShared
3237+
deallocator:nil];
3238+
}
32353239
}
32363240

3237-
if (ctx->all_data == NULL || ctx->buffers[0].metal == nil) {
3241+
if (size_aligned > 0 && (ctx->all_data == NULL || ctx->buffers[0].metal == nil)) {
32383242
GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_aligned / 1024.0 / 1024.0);
32393243
free(ctx);
32403244
ggml_backend_metal_free_device();
@@ -3311,14 +3315,17 @@ GGML_CALL ggml_backend_buffer_t ggml_backend_metal_buffer_from_ptr(void * data,
33113315

33123316
// the buffer fits into the max buffer size allowed by the device
33133317
if (size_aligned <= device.maxBufferLength) {
3314-
ctx->buffers[ctx->n_buffers].data = data;
3315-
ctx->buffers[ctx->n_buffers].size = size;
3318+
ctx->buffers[ctx->n_buffers].data = data;
3319+
ctx->buffers[ctx->n_buffers].size = size;
3320+
ctx->buffers[ctx->n_buffers].metal = nil;
33163321

3317-
ctx->buffers[ctx->n_buffers].metal = [device newBufferWithBytesNoCopy:data length:size_aligned options:MTLResourceStorageModeShared deallocator:nil];
3322+
if (size_aligned > 0) {
3323+
ctx->buffers[ctx->n_buffers].metal = [device newBufferWithBytesNoCopy:data length:size_aligned options:MTLResourceStorageModeShared deallocator:nil];
33183324

3319-
if (ctx->buffers[ctx->n_buffers].metal == nil) {
3320-
GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_aligned / 1024.0 / 1024.0);
3321-
return false;
3325+
if (ctx->buffers[ctx->n_buffers].metal == nil) {
3326+
GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_aligned / 1024.0 / 1024.0);
3327+
return false;
3328+
}
33223329
}
33233330

33243331
ggml_backend_metal_log_allocated_size(device, size_aligned);
@@ -3334,14 +3341,17 @@ GGML_CALL ggml_backend_buffer_t ggml_backend_metal_buffer_from_ptr(void * data,
33343341
for (size_t i = 0; i < size; i += size_step) {
33353342
const size_t size_step_aligned = (i + size_view <= size) ? size_view : (size_aligned - i);
33363343

3337-
ctx->buffers[ctx->n_buffers].data = (void *) ((uint8_t *) data + i);
3338-
ctx->buffers[ctx->n_buffers].size = size_step_aligned;
3344+
ctx->buffers[ctx->n_buffers].data = (void *) ((uint8_t *) data + i);
3345+
ctx->buffers[ctx->n_buffers].size = size_step_aligned;
3346+
ctx->buffers[ctx->n_buffers].metal = nil;
33393347

3340-
ctx->buffers[ctx->n_buffers].metal = [device newBufferWithBytesNoCopy:(void *) ((uint8_t *) data + i) length:size_step_aligned options:MTLResourceStorageModeShared deallocator:nil];
3348+
if (size_step_aligned > 0) {
3349+
ctx->buffers[ctx->n_buffers].metal = [device newBufferWithBytesNoCopy:(void *) ((uint8_t *) data + i) length:size_step_aligned options:MTLResourceStorageModeShared deallocator:nil];
33413350

3342-
if (ctx->buffers[ctx->n_buffers].metal == nil) {
3343-
GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_step_aligned / 1024.0 / 1024.0);
3344-
return false;
3351+
if (ctx->buffers[ctx->n_buffers].metal == nil) {
3352+
GGML_METAL_LOG_ERROR("%s: error: failed to allocate buffer, size = %8.2f MiB\n", __func__, size_step_aligned / 1024.0 / 1024.0);
3353+
return false;
3354+
}
33453355
}
33463356

33473357
ggml_backend_metal_log_allocated_size(device, size_step_aligned);

0 commit comments

Comments
 (0)