Skip to content

Commit 5f7326b

Browse files
vulkan: improve im2col performance
1 parent 19d3c82 commit 5f7326b

File tree

1 file changed

+15
-33
lines changed

1 file changed

+15
-33
lines changed

ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,51 +37,33 @@ void main() {
3737
const uint gidx = gl_GlobalInvocationID.x;
3838

3939
const uint oh = gl_GlobalInvocationID.y;
40-
const uint batch = gl_GlobalInvocationID.z / p.IC;
41-
const uint ic = gl_GlobalInvocationID.z % p.IC;
40+
const uint batch_ic = gl_GlobalInvocationID.z;
4241

43-
A_TYPE values[NUM_ITER];
44-
uint offset_dst[NUM_ITER];
45-
[[unroll]] for (uint idx = 0; idx < NUM_ITER; ++idx) {
46-
values[idx] = A_TYPE(0);
47-
}
42+
const uint batch = batch_ic / p.IC;
43+
const uint ic = batch_ic % p.IC;
44+
45+
const uint ksize = p.OW * ((p.KH > 1) ? p.KW : 1);
46+
const uint src_base = ic * p.offset_delta + batch * p.batch_offset;
47+
const uint dst_base = ((batch * p.OH + oh) * p.OW) * p.CHW + ic * p.KW * p.KH;
4848

4949
[[unroll]] for (uint idx = 0; idx < NUM_ITER; ++idx) {
5050

5151
const uint i = gidx * NUM_ITER + idx;
52+
if (i >= p.pelements) continue;
5253

53-
const uint ksize = p.OW * (p.KH > 1 ? p.KW : 1);
5454
const uint kx = i / ksize;
55-
const uint kd = kx * ksize;
56-
const uint ky = (i - kd) / p.OW;
55+
const uint ky = (i % ksize) / p.OW;
5756
const uint ix = i % p.OW;
5857

59-
const uint iiw = ix * p.s0 + kx * p.d0 - p.p0;
60-
const uint iih = oh * p.s1 + ky * p.d1 - p.p1;
61-
62-
offset_dst[idx] =
63-
((batch * p.OH + oh) * p.OW + ix) * p.CHW +
64-
(ic * (p.KW * p.KH) + ky * p.KW + kx);
65-
66-
if (i >= p.pelements) {
67-
continue;
68-
}
58+
const int iiw = int(ix * uint(p.s0)) + int(kx * uint(p.d0)) - p.p0;
59+
const int iih = int(oh * uint(p.s1)) + int(ky * uint(p.d1)) - p.p1;
6960

70-
if (iih < p.IH && iiw < p.IW) {
71-
const uint offset_src = ic * p.offset_delta + batch * p.batch_offset;
72-
values[idx] = data_a[offset_src + iih * p.IW + iiw];
73-
}
74-
}
75-
76-
[[unroll]] for (uint idx = 0; idx < NUM_ITER; ++idx) {
77-
78-
const uint i = gidx * NUM_ITER + idx;
61+
const uint dst_offset = dst_base + ix * p.CHW + ky * p.KW + kx;
7962

80-
if (i >= p.pelements) {
81-
continue;
82-
}
63+
const bool valid = iih >= 0 && iih < int(p.IH) && iiw >= 0 && iiw < int(p.IW);
64+
const uint src_offset = src_base + uint(iih) * p.IW + uint(iiw);
8365

84-
data_d[offset_dst[idx]] = D_TYPE(values[idx]);
66+
data_d[dst_offset] = D_TYPE(valid ? data_a[src_offset] : 0.0);
8567
}
8668

8769
}

0 commit comments

Comments
 (0)