char-fork/llama.cpp

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

lhezopencl: support non-contig rows in norm (#24965)fdb2c11c7

char/aliceai-t5-moe
5.7 KiB164 linesraw
1#pragma OPENCL EXTENSION cl_khr_fp16 : enable
2
3#ifdef cl_intel_required_subgroup_size
4#pragma OPENCL EXTENSION cl_intel_required_subgroup_size : enable
5#define INTEL_GPU 1
6#define REQD_SUBGROUP_SIZE_16 __attribute__((intel_reqd_sub_group_size(16)))
7#define REQD_SUBGROUP_SIZE_32 __attribute__((intel_reqd_sub_group_size(32)))
8#elif defined(cl_qcom_reqd_sub_group_size)
9#pragma OPENCL EXTENSION cl_qcom_reqd_sub_group_size : enable
10#define ADRENO_GPU 1
11#define REQD_SUBGROUP_SIZE_64  __attribute__((qcom_reqd_sub_group_size("half")))
12#define REQD_SUBGROUP_SIZE_128 __attribute__((qcom_reqd_sub_group_size("full")))
13#endif
14
15//------------------------------------------------------------------------------
16// norm
17//------------------------------------------------------------------------------
18kernel void kernel_norm(
19        global void * src0,
20        ulong offset0,
21        global float * dst,
22        ulong offsetd,
23        int ne00,
24        int ne01,
25        int ne02,
26        int ne03,
27        ulong nb00,
28        ulong nb01,
29        ulong nb02,
30        ulong nb03,
31        float eps,
32        local float * sum
33) {
34    src0 = (global void*)((global char*)src0 + offset0);
35    dst = (global void*)((global char*)dst + offsetd);
36
37    int i03 = get_group_id(2);
38    int i02 = get_group_id(1);
39    int i01 = get_group_id(0);
40
41    global float * x = (global float *) ((global char *) src0 + i03*nb03 + i02*nb02 + i01*nb01);
42
43    // MEAN
44    // parallel sum
45    sum[get_local_id(0)] = 0.0f;
46    for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
47        // this kernel handles float, nb00/4 translates byte offset to element offset
48        sum[get_local_id(0)] += x[i00*nb00/4];
49    }
50    // reduce
51    barrier(CLK_LOCAL_MEM_FENCE);
52    for (uint i = get_local_size(0)/2; i > 0; i /= 2) {
53        if (get_local_id(0) < i) {
54            sum[get_local_id(0)] += sum[get_local_id(0) + i];
55        }
56        barrier(CLK_LOCAL_MEM_FENCE);
57    }
58    float mean  = sum[0] / ne00;
59
60    // recenter and VARIANCE
61    barrier(CLK_LOCAL_MEM_FENCE);
62    global float * y = dst + i03*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00;
63    sum[get_local_id(0)] = 0.0f;
64    for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
65        // this kernel handles float, nb00/4 translates byte offset to element offset
66        y[i00] = x[i00*nb00/4] - mean;
67        sum[get_local_id(0)] += y[i00] * y[i00];
68    }
69
70    // reduce
71    barrier(CLK_LOCAL_MEM_FENCE);
72    for (uint i = get_local_size(0)/2; i > 0; i /= 2) {
73        if (get_local_id(0) < i) {
74            sum[get_local_id(0)] += sum[get_local_id(0) + i];
75        }
76        barrier(CLK_LOCAL_MEM_FENCE);
77    }
78    float variance = sum[0] / ne00;
79
80    float scale = 1.0f/sqrt(variance + eps);
81    for (int i00 = get_local_id(0); i00 < ne00; i00 += get_local_size(0)) {
82        y[i00] = y[i00] * scale;
83    }
84}
85
86//------------------------------------------------------------------------------
87// norm_mul_add
88//------------------------------------------------------------------------------
89#ifdef INTEL_GPU
90REQD_SUBGROUP_SIZE_32
91#elif defined (ADRENO_GPU)
92REQD_SUBGROUP_SIZE_64
93#endif
94kernel void kernel_norm_mul_add(
95        global char * src0_ptr, ulong src0_offset,
96        global char * src1_ptr, ulong src1_offset,
97        global char * src2_ptr, ulong src2_offset,
98        global char * dst_ptr,  ulong dst_offset,
99        int ne00, int ne01, int ne02, int ne03,
100        ulong nb01, ulong nb02, ulong nb03,
101        int ne10, int ne11, int ne12, int ne13,
102        ulong nb11, ulong nb12, ulong nb13,
103        int ne20, int ne21, int ne22, int ne23,
104        ulong nb21, ulong nb22, ulong nb23,
105        ulong nbd1, ulong nbd2, ulong nbd3,
106        float eps,
107        local float2 * sums
108) {
109    const int i03 = get_group_id(2);
110    const int i02 = get_group_id(1);
111    const int i01 = get_group_id(0);
112
113    global float4 * x = (global float4 *)(src0_ptr + src0_offset + i01*nb01 + i02*nb02 + i03*nb03);
114    global float4 * w = (global float4 *)(src1_ptr + src1_offset + (i01%ne11)*nb11 + (i02%ne12)*nb12 + (i03%ne13)*nb13);
115    global float4 * b = (global float4 *)(src2_ptr + src2_offset + (i01%ne21)*nb21 + (i02%ne22)*nb22 + (i03%ne23)*nb23);
116    global float4 * y = (global float4 *)(dst_ptr  + dst_offset  + i01*nbd1 + i02*nbd2 + i03*nbd3);
117
118    float p_sum = 0.0f;
119    float p_sum_sq = 0.0f;
120
121    const int n_chunks = ne00 / 4;
122    for (int i00 = get_local_id(0); i00 < n_chunks; i00 += get_local_size(0)) {
123        float4 val = x[i00];
124        p_sum += val.x + val.y + val.z + val.w;
125        p_sum_sq += dot(val, val);
126    }
127
128    p_sum = sub_group_reduce_add(p_sum);
129    p_sum_sq = sub_group_reduce_add(p_sum_sq);
130
131    if (get_sub_group_local_id() == 0) {
132        sums[get_sub_group_id()] = (float2)(p_sum, p_sum_sq);
133    }
134    barrier(CLK_LOCAL_MEM_FENCE);
135
136    if (get_local_id(0) == 0) {
137        float sum = 0.0f;
138        float sum_sq = 0.0f;
139        for (uint i = 0; i < get_num_sub_groups(); ++i) {
140            float2 s = sums[i];
141            sum += s.x;
142            sum_sq += s.y;
143        }
144
145        const float inv_ne00 = 1.0f / (float)ne00;
146        const float mean = sum * inv_ne00;
147        const float variance = mad(-mean, mean, sum_sq * inv_ne00);
148
149        sums[0] = (float2)(mean, rsqrt(variance + eps));
150    }
151    barrier(CLK_LOCAL_MEM_FENCE);
152
153    const float2 mean_scale = sums[0];
154    const float mean = mean_scale.x;
155    const float scale = mean_scale.y;
156    const float neg_mean_scale = -mean * scale;
157
158    for (int i00 = get_local_id(0); i00 < n_chunks; i00 += get_local_size(0)) {
159        const int w_idx = ne10 > 1 ? i00 : 0;
160        const int b_idx = ne20 > 1 ? i00 : 0;
161        const float4 norm_x = mad(x[i00], (float4)scale, (float4)neg_mean_scale);
162        y[i00] = mad(norm_x, w[w_idx], b[b_idx]);
163    }
164}