char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
c9ca51c1f
char/aliceai-t5-moe
1#version 450 2 3#extension GL_EXT_control_flow_attributes : enable 4 5#ifdef USE_SUBGROUPS 6#extension GL_KHR_shader_subgroup_basic : enable 7#extension GL_KHR_shader_subgroup_arithmetic : enable 8#endif 9 10#include "types.glsl" 11#include "utils.glsl" 12 13layout (push_constant) uniform parameter 14{ 15 uint32_t ne00; 16 uint32_t ne01; 17 uint32_t nb00; 18 uint32_t nb01; 19 uint32_t a_offset; 20 uint32_t n_experts; 21 uint32_t hoist_row_ids; 22 uint32_t ne00mp; 23 uint32_t ne00L; 24} p; 25 26#define BLOCK_SIZE 256 27 28layout(local_size_x = BLOCK_SIZE, local_size_y = 1, local_size_z = 1) in; 29 30layout (binding = 0) readonly buffer A {uint data_a[];}; 31layout (binding = 1) writeonly buffer D {uint data_d[];}; 32 33shared uint vals[BLOCK_SIZE]; 34shared uint offsets[BLOCK_SIZE]; 35shared uint cursors[BLOCK_SIZE]; 36 37// data_d layout when p.hoist_row_ids is set: 38// [0, n_experts) per-expert row count 39// [n_experts, 2*n_experts) per-expert start offset into the row id region 40// [2*n_experts] total row count 41// [2*n_experts + 1, ) row ids grouped by expert, packed as (i01 << 16) | (i00 & 0xffff) 42// Otherwise only data_d[expert_id] is written, holding that expert's row count. 43void main() { 44 const uint expert_id = gl_WorkGroupID.x; 45 const uint num_elements = p.ne00 * p.ne01; 46 const uint tid = gl_LocalInvocationID.x; 47 48 if (p.hoist_row_ids != 0) { 49 if (tid < p.n_experts) { 50 vals[tid] = 0; 51 } 52 barrier(); 53 54 for (uint idx = tid; idx < num_elements; idx += BLOCK_SIZE) { 55 const uint i01 = fastdiv(idx, p.ne00mp, p.ne00L); 56 const uint i00 = idx - i01 * p.ne00; 57 const uint expert = data_a[p.a_offset + i01 * p.nb01 + i00 * p.nb00]; 58 if (expert < p.n_experts) { 59 atomicAdd(vals[expert], 1); 60 } 61 } 62 barrier(); 63 64#ifdef USE_SUBGROUPS 65 if (gl_SubgroupID == 0) { 66 // pad the trip count so the subgroup ops stay in uniform control flow 67 const uint n_experts_padded = (p.n_experts + gl_SubgroupSize - 1) & ~(gl_SubgroupSize - 1); 68 uint base = 0; 69 for (uint expert = gl_SubgroupInvocationID; expert < n_experts_padded; expert += gl_SubgroupSize) { 70 const bool in_range = expert < p.n_experts; 71 const uint count = in_range ? vals[expert] : 0; 72 const uint offset = base + subgroupExclusiveAdd(count); 73 if (in_range) { 74 data_d[expert] = count; 75 data_d[p.n_experts + expert] = offset; 76 offsets[expert] = offset; 77 cursors[expert] = 0; 78 } 79 base += subgroupAdd(count); 80 } 81 if (subgroupElect()) { 82 data_d[2 * p.n_experts] = base; 83 } 84 } 85#else 86 if (tid == 0) { 87 uint offset = 0; 88 for (uint expert = 0; expert < p.n_experts; ++expert) { 89 const uint count = vals[expert]; 90 data_d[expert] = count; 91 data_d[p.n_experts + expert] = offset; 92 offsets[expert] = offset; 93 cursors[expert] = 0; 94 offset += count; 95 } 96 data_d[2 * p.n_experts] = offset; 97 } 98#endif 99 barrier(); 100 101 for (uint idx = tid; idx < num_elements; idx += BLOCK_SIZE) { 102 const uint i01 = fastdiv(idx, p.ne00mp, p.ne00L); 103 const uint i00 = idx - i01 * p.ne00; 104 const uint expert = data_a[p.a_offset + i01 * p.nb01 + i00 * p.nb00]; 105 if (expert < p.n_experts) { 106 const uint row = atomicAdd(cursors[expert], 1); 107 const uint packed_row_id = (i01 << 16) | (i00 & 0xffffu); 108 data_d[2 * p.n_experts + 1 + offsets[expert] + row] = packed_row_id; 109 } 110 } 111 return; 112 } 113 114 uint count = 0; 115 for (uint idx = tid; idx < num_elements; idx += BLOCK_SIZE) { 116 const uint i01 = fastdiv(idx, p.ne00mp, p.ne00L); 117 const uint i00 = idx - i01 * p.ne00; 118 const uint a = data_a[p.a_offset + i01 * p.nb01 + i00 * p.nb00]; 119 120 count += uint(a == expert_id); 121 } 122 123 vals[tid] = count; 124 barrier(); 125 [[unroll]] for (uint s = BLOCK_SIZE / 2; s > 0; s >>= 1) { 126 if (tid < s) { 127 vals[tid] += vals[tid + s]; 128 } 129 barrier(); 130 } 131 132 if (tid == 0) { 133 data_d[expert_id] = vals[0]; 134 } 135}