char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
f401bb139
char/aliceai-t5-moe
1enable f16; 2 3#ifdef MASK_F32 4#define MaskType f32 5#endif 6#ifdef MASK_F16 7#define MaskType f16 8#endif 9 10struct Params { 11 offset_src0: u32, 12 offset_src1: u32, 13 offset_sinks: u32, 14 offset_dst: u32, 15 16 // Strides (in elements) 17 stride_src01: u32, 18 stride_src02: u32, 19 stride_src03: u32, 20 21 stride_src11: u32, 22 stride_src12: u32, 23 stride_src13: u32, 24 25 stride_dst1: u32, 26 stride_dst2: u32, 27 stride_dst3: u32, 28 29 // shape of src0/dst 30 ne0: u32, 31 ne1: u32, 32 ne2: u32, 33 34 // shape of src1 35 ne12: u32, 36 ne13: u32, 37 38 scale: f32, 39 max_bias: f32, 40 n_head_log2: f32, 41 m0: f32, 42 m1: f32, 43}; 44 45#define SRC_BINDING 0 46@group(0) @binding(SRC_BINDING) 47var<storage, read_write> src: array<f32>; 48 49#ifdef HAS_MASK 50#define MASK_BINDING SRC_BINDING + 1 51@group(0) @binding(MASK_BINDING) 52var<storage, read_write> mask: array<MaskType>; 53#else 54#define MASK_BINDING SRC_BINDING 55#endif 56 57#ifdef HAS_SINK 58#define SINKS_BINDING MASK_BINDING + 1 59@group(0) @binding(SINKS_BINDING) 60var<storage, read_write> sinks: array<f32>; 61#else 62#define SINKS_BINDING MASK_BINDING 63#endif 64 65#define DST_BINDING SINKS_BINDING + 1 66@group(0) @binding(DST_BINDING) 67var<storage, read_write> dst: array<f32>; 68 69#ifdef INPLACE 70#define PARAMS_BINDING DST_BINDING 71#else 72#define PARAMS_BINDING (DST_BINDING + 1) 73#endif 74 75@group(0) @binding(PARAMS_BINDING) 76var<uniform> params: Params; 77 78#ifdef INPLACE 79fn inter_value(i: u32) -> f32 { 80 return src[i]; 81} 82fn update(i: u32, val: f32) { 83 src[i] = val; 84} 85 86#else 87fn inter_value(i: u32) -> f32 { 88 return dst[i]; 89} 90fn update(i: u32, val: f32) { 91 dst[i] = val; 92} 93#endif 94 95#ifdef HAS_MASK 96fn mask_val(i: u32) -> f32 { 97 return f32(mask[i]); 98} 99 100#else 101fn mask_val(i: u32) -> f32 { 102 return 0.0; 103} 104#endif 105 106#ifdef HAS_SINK 107fn lower_max_bound(i2: u32) -> f32 { 108 return sinks[params.offset_sinks + i2]; 109} 110fn add_sinks(val: f32, i2: u32, max_val: f32) -> f32 { 111 return val + exp(sinks[params.offset_sinks + i2] - max_val); 112} 113#else 114fn lower_max_bound(i2: u32) -> f32 { 115 return -1e30; 116} 117fn add_sinks(val: f32, i2: u32, max_val: f32) -> f32 { 118 return val; 119} 120#endif 121 122const CACHE_SIZE: u32 = 16; 123var<workgroup> scratch: array<f32, WG_SIZE>; 124 125@compute @workgroup_size(WG_SIZE) 126fn main(@builtin(workgroup_id) wid: vec3<u32>, 127 @builtin(local_invocation_id) lid: vec3<u32>) { 128 129 var i = wid.x; 130 let i3 = i / (params.ne2 * params.ne1); 131 i = i % (params.ne2 * params.ne1); 132 let i2 = i / params.ne1; 133 let i1 = i % params.ne1; 134 let i_src0_row = params.offset_src0 + i3 * params.stride_src03 + i2 * params.stride_src02 + i1 * params.stride_src01; 135 let i_src1_row = params.offset_src1 + (i3 % params.ne13) * params.stride_src13 + (i2 % params.ne12) * params.stride_src12 + i1 * params.stride_src11; 136 let i_dst_row = params.offset_dst + i3 * params.stride_dst3 + i2 * params.stride_dst2 + i1 * params.stride_dst1; 137 let elems = (params.ne0 + WG_SIZE - 1) / WG_SIZE; 138 139 let head = f32(i2); 140 let slope = select(1, select(pow(params.m1, 2 * (head - params.n_head_log2) + 1), pow(params.m0, head + 1), head < params.n_head_log2), params.max_bias > 0); 141 142 var cache: array<f32, CACHE_SIZE>; 143 144 var max_val = lower_max_bound(i2); 145 var col = lid.x; 146 for (var j: u32 = 0; j < elems; j++) { 147 if (col >= params.ne0) { 148 break; 149 } 150 let val = src[i_src0_row + col] * params.scale + slope * mask_val(i_src1_row + col); 151 max_val = max(max_val, val); 152 if (col < CACHE_SIZE) { 153 cache[col] = val; 154 } 155 col += WG_SIZE; 156 } 157 158 scratch[lid.x] = max_val; 159 workgroupBarrier(); 160 var offset: u32 = WG_SIZE / 2; 161 while (offset > 0) { 162 if (lid.x < offset) { 163 scratch[lid.x] = max(scratch[lid.x], scratch[lid.x + offset]); 164 } 165 offset = offset / 2; 166 workgroupBarrier(); 167 } 168 let row_max = scratch[0]; 169 workgroupBarrier(); 170 171 var sum = 0.0f; 172 col = lid.x; 173 for (var j: u32 = 0; j < elems; j++) { 174 if (col >= params.ne0) { 175 break; 176 } 177 let val = select(src[i_src0_row + col] * params.scale + slope * mask_val(i_src1_row + col), 178 cache[col], col < CACHE_SIZE); 179 let ex = exp(val - row_max); 180 sum += ex; 181 if (col < CACHE_SIZE) { 182 cache[col] = ex; 183 } else { 184 update(i_dst_row + col, ex); 185 } 186 col += WG_SIZE; 187 } 188 189 scratch[lid.x] = sum; 190 workgroupBarrier(); 191 offset = WG_SIZE / 2; 192 while (offset > 0) { 193 if (lid.x < offset) { 194 scratch[lid.x] += scratch[lid.x + offset]; 195 } 196 offset = offset / 2; 197 workgroupBarrier(); 198 } 199 let row_sum = add_sinks(scratch[0], i2, row_max); 200 201 let sum_recip = 1.0 / row_sum; 202 col = lid.x; 203 for (var j: u32 = 0; j < elems; j++) { 204 if (col >= params.ne0) { 205 break; 206 } 207 update(i_dst_row + col, select(inter_value(i_dst_row + col), cache[col], col < CACHE_SIZE) * sum_recip); 208 col += WG_SIZE; 209 } 210}