char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Danielevulkan: optimize operations in the IM2COL shader (#22685)acd604fb2

char/aliceai-t5-moe
3.7 KiB138 linesraw
1#version 450
2
3#extension GL_EXT_shader_16bit_storage : require
4#extension GL_EXT_control_flow_attributes : require
5
6#include "types.glsl"
7
8layout (push_constant) uniform parameter
9{
10    BDA_STORAGE_T dst_addr;
11    uint batch_offset; uint offset_delta;
12    uint IC;
13    uint IW; uint IH;
14    uint OW; uint OH;
15    uint KW; uint KH;
16    uint OH_batch;
17    uint CHW;
18    int s0; int s1;
19    int p0; int p1;
20    int d0; int d1;
21    uint batch_IC;
22} p;
23
24layout(constant_id = 0) const uint BLOCK_SIZE = 32;
25
26const uint NUM_ITER = 512 / BLOCK_SIZE;
27
28layout(local_size_x_id = 0, local_size_y = 1, local_size_z = 1) in;
29
30layout (binding = 0) readonly buffer X {A_TYPE data_a[];};
31layout (binding = 1) writeonly buffer D {D_TYPE data_d[];};
32
33#if BDA
34layout (buffer_reference) buffer D_ptr {D_TYPE d;};
35#endif
36
37void im2col(const uint ow, const uint z_idx) {
38    const uint oh = z_idx % p.OH;
39    const uint batch_idx = z_idx / p.OH;
40
41    const uint gidx = gl_LocalInvocationID.x;
42    const uint src_batch = batch_idx * p.batch_offset;
43    const BDA_OFFSET_T dst_row = ((BDA_OFFSET_T(batch_idx) * p.OH + oh) * p.OW + ow) * p.CHW;
44
45    const uint KHKW = p.KH * p.KW;
46
47    // Precompute base input coordinates
48    const int base_iw = int(ow * p.s0) - p.p0;
49    const int base_ih = int(oh * p.s1) - p.p1;
50
51    // Precompute step deltas
52    const uint delta_ic  = BLOCK_SIZE / KHKW;
53    const uint delta_rem = BLOCK_SIZE % KHKW;
54
55    const uint delta_ky  = delta_rem / p.KW;
56    const uint delta_kx  = delta_rem % p.KW;
57
58    const uint delta_ic_offset = delta_ic * p.offset_delta;
59
60    // If using BDA mode, precompute the base pointer  and step size
61#if BDA
62    const BDA_STORAGE_T base_dst_addr = p.dst_addr + D_SIZE * dst_row;
63    const uint bda_step = D_SIZE * BLOCK_SIZE;
64#endif
65
66    uint wg_x = gl_WorkGroupID.x;
67    do {
68        const uint wg_offset = wg_x * 512;
69
70        uint chw_idx = wg_offset + gidx;
71
72        uint ic  = chw_idx / KHKW;
73        uint rem = chw_idx % KHKW;
74
75        uint ky  = rem / p.KW;
76        uint kx  = rem % p.KW;
77
78        uint ic_offset = src_batch + ic * p.offset_delta;
79
80        // Initialize running pointer/index for the destination buffer
81#if BDA
82        BDA_STORAGE_T current_dst_addr = base_dst_addr + D_SIZE * chw_idx;
83#else
84        uint current_dst_idx = dst_row + chw_idx;
85#endif
86
87        [[unroll]] for (uint i = 0; i < NUM_ITER; ++i) {
88            if (chw_idx >= p.CHW) {
89                return;
90            }
91
92            const int iiw = base_iw + int(kx * p.d0);
93            const int iih = base_ih + int(ky * p.d1);
94
95            A_TYPE val = A_TYPE(0);
96            if (uint(iih) < p.IH && uint(iiw) < p.IW) {
97                val = data_a[ic_offset + uint(iih) * p.IW + uint(iiw)];
98            }
99
100#if BDA
101            D_ptr(current_dst_addr).d = D_TYPE(val);
102            current_dst_addr += bda_step;
103#else
104            data_d[current_dst_idx] = D_TYPE(val);
105            current_dst_idx += BLOCK_SIZE;
106#endif
107
108            chw_idx   += BLOCK_SIZE;
109            ic_offset += delta_ic_offset;
110            kx        += delta_kx;
111            ky        += delta_ky;
112
113            // Handle X axis wrap
114            uint kx_wrap = uint(kx >= p.KW);
115            kx          -= kx_wrap * p.KW;
116            ky          += kx_wrap;
117
118            // Handle Y axis wrap
119            uint ky_wrap = uint(ky >= p.KH);
120            ky          -= ky_wrap * p.KH;
121            ic_offset   += ky_wrap * p.offset_delta;
122        }
123
124        wg_x += gl_NumWorkGroups.x;
125    } while (wg_x * 512 < p.CHW);
126}
127
128void main() {
129    uint ow = gl_GlobalInvocationID.y;
130    while (ow < p.OW) {
131        uint z = gl_GlobalInvocationID.z;
132        while (z < p.OH_batch) {
133            im2col(ow, z);
134            z += gl_NumWorkGroups.z;
135        }
136        ow += gl_NumWorkGroups.y;
137    }
138}