Skip to content

Commit 13268c5

Browse files
authored
metal : slight speed-up for add and mul kernels (#2917)
1 parent 4dcd47d commit 13268c5

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

ggml-metal.m

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,12 @@ void ggml_metal_graph_compute(
680680
} break;
681681
case GGML_OP_ADD:
682682
{
683+
GGML_ASSERT(ggml_is_contiguous(src0));
684+
685+
// utilize float4
686+
GGML_ASSERT(ne00 % 4 == 0);
687+
const int64_t nb = ne00/4;
688+
683689
if (ggml_nelements(src1) == ne10) {
684690
// src1 is a row
685691
[encoder setComputePipelineState:ctx->pipeline_add_row];
@@ -689,14 +695,20 @@ void ggml_metal_graph_compute(
689695
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
690696
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
691697
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
692-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
698+
[encoder setBytes:&nb length:sizeof(nb) atIndex:3];
693699

694-
const int64_t n = ggml_nelements(dst);
700+
const int64_t n = ggml_nelements(dst)/4;
695701

696702
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
697703
} break;
698704
case GGML_OP_MUL:
699705
{
706+
GGML_ASSERT(ggml_is_contiguous(src0));
707+
708+
// utilize float4
709+
GGML_ASSERT(ne00 % 4 == 0);
710+
const int64_t nb = ne00/4;
711+
700712
if (ggml_nelements(src1) == ne10) {
701713
// src1 is a row
702714
[encoder setComputePipelineState:ctx->pipeline_mul_row];
@@ -706,9 +718,9 @@ void ggml_metal_graph_compute(
706718
[encoder setBuffer:id_src0 offset:offs_src0 atIndex:0];
707719
[encoder setBuffer:id_src1 offset:offs_src1 atIndex:1];
708720
[encoder setBuffer:id_dst offset:offs_dst atIndex:2];
709-
[encoder setBytes:&ne00 length:sizeof(ne00) atIndex:3];
721+
[encoder setBytes:&nb length:sizeof(nb) atIndex:3];
710722

711-
const int64_t n = ggml_nelements(dst);
723+
const int64_t n = ggml_nelements(dst)/4;
712724

713725
[encoder dispatchThreadgroups:MTLSizeMake(n, 1, 1) threadsPerThreadgroup:MTLSizeMake(1, 1, 1)];
714726
} break;

ggml-metal.metal

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,41 @@ typedef struct {
2525
} block_q8_0;
2626

2727
kernel void kernel_add(
28-
device const float * src0,
29-
device const float * src1,
30-
device float * dst,
28+
device const float4 * src0,
29+
device const float4 * src1,
30+
device float4 * dst,
3131
uint tpig[[thread_position_in_grid]]) {
3232
dst[tpig] = src0[tpig] + src1[tpig];
3333
}
3434

3535
// assumption: src1 is a row
3636
// broadcast src1 into src0
3737
kernel void kernel_add_row(
38-
device const float * src0,
39-
device const float * src1,
40-
device float * dst,
41-
constant int64_t & ne00,
38+
device const float4 * src0,
39+
device const float4 * src1,
40+
device float4 * dst,
41+
constant int64_t & nb,
4242
uint tpig[[thread_position_in_grid]]) {
43-
dst[tpig] = src0[tpig] + src1[tpig % ne00];
43+
dst[tpig] = src0[tpig] + src1[tpig % nb];
4444
}
4545

4646
kernel void kernel_mul(
47-
device const float * src0,
48-
device const float * src1,
49-
device float * dst,
47+
device const float4 * src0,
48+
device const float4 * src1,
49+
device float4 * dst,
5050
uint tpig[[thread_position_in_grid]]) {
5151
dst[tpig] = src0[tpig] * src1[tpig];
5252
}
5353

5454
// assumption: src1 is a row
5555
// broadcast src1 into src0
5656
kernel void kernel_mul_row(
57-
device const float * src0,
58-
device const float * src1,
59-
device float * dst,
60-
constant int64_t & ne00,
57+
device const float4 * src0,
58+
device const float4 * src1,
59+
device float4 * dst,
60+
constant int64_t & nb,
6161
uint tpig[[thread_position_in_grid]]) {
62-
dst[tpig] = src0[tpig] * src1[tpig % ne00];
62+
dst[tpig] = src0[tpig] * src1[tpig % nb];
6363
}
6464

6565
kernel void kernel_scale(

0 commit comments

Comments
 (0)