#version 450 #extension GL_EXT_control_flow_attributes : require layout(constant_id = 0) const uint S_V = 128; layout(constant_id = 1) const uint KDA = 0; layout(local_size_x_id = 0, local_size_y = 1, local_size_z = 1) in; layout(push_constant) uniform Parameters { uint H; uint n_tokens; uint n_seqs; uint s_off; uint sq1, sq2, sq3; uint sv1, sv2, sv3; uint sb1, sb2, sb3; uint neq1, rq3; float scale; }; layout(binding = 0) readonly buffer QBuf { FLOAT_TYPE data_q[]; }; layout(binding = 1) readonly buffer KBuf { FLOAT_TYPE data_k[]; }; layout(binding = 2) readonly buffer VBuf { FLOAT_TYPE data_v[]; }; layout(binding = 3) readonly buffer GBuf { FLOAT_TYPE data_g[]; }; layout(binding = 4) readonly buffer BetaBuf { FLOAT_TYPE data_beta[]; }; layout(binding = 5) readonly buffer StateBuf { FLOAT_TYPE data_state[]; }; layout(binding = 6) buffer DstBuf { FLOAT_TYPE data_dst[]; }; shared FLOAT_TYPE s_k[S_V]; shared FLOAT_TYPE s_q[S_V]; shared FLOAT_TYPE s_g[S_V]; // KDA only: cached exp(g[i]) void main() { const uint head_id = gl_WorkGroupID.x; const uint seq_id = gl_WorkGroupID.y; const uint col = gl_LocalInvocationID.x; const uint iq1 = head_id % neq1; const uint iq3 = seq_id / rq3; const uint state_size = S_V * S_V; const uint state_base = (seq_id * H + head_id) * state_size; FLOAT_TYPE state[S_V]; [[unroll]] for (uint i = 0; i < S_V; i++) { state[i] = FLOAT_TYPE(data_state[state_base + col * S_V + i]); } uint attn_off = (seq_id * n_tokens * H + head_id) * S_V; for (uint t = 0; t < n_tokens; t++) { const uint q_off = iq3 * sq3 + t * sq2 + iq1 * sq1; const uint k_off = q_off; const uint v_off = seq_id * sv3 + t * sv2 + head_id * sv1; s_q[col] = FLOAT_TYPE(data_q[q_off + col]); s_k[col] = FLOAT_TYPE(data_k[k_off + col]); const uint gb_off = seq_id * sb3 + t * sb2 + head_id * sb1; if (KDA != 0) { const uint g_base = gb_off * S_V; s_g[col] = exp(FLOAT_TYPE(data_g[g_base + col])); } barrier(); const FLOAT_TYPE v_val = FLOAT_TYPE(data_v[v_off + col]); const FLOAT_TYPE beta_val = FLOAT_TYPE(data_beta[gb_off]); if (KDA == 0) { const FLOAT_TYPE g_val = exp(FLOAT_TYPE(data_g[gb_off])); FLOAT_TYPE kv_col = 0.0; [[unroll]] for (uint i = 0; i < S_V; i += 4) { kv_col += dot( vec4(state[i], state[i+1], state[i+2], state[i+3]), vec4(s_k[i], s_k[i+1], s_k[i+2], s_k[i+3]) ); } FLOAT_TYPE delta_col = (v_val - g_val * kv_col) * beta_val; FLOAT_TYPE attn_col = 0.0; [[unroll]] for (uint i = 0; i < S_V; i += 4) { vec4 sv = vec4(state[i], state[i+1], state[i+2], state[i+3]); vec4 kv = vec4(s_k[i], s_k[i+1], s_k[i+2], s_k[i+3]); sv = g_val * sv + kv * delta_col; state[i] = sv.x; state[i+1] = sv.y; state[i+2] = sv.z; state[i+3] = sv.w; attn_col += dot(sv, vec4(s_q[i], s_q[i+1], s_q[i+2], s_q[i+3])); } data_dst[attn_off + col] = attn_col * scale; } else { FLOAT_TYPE kv_col = 0.0; [[unroll]] for (uint i = 0; i < S_V; i += 4) { vec4 gv = vec4(s_g[i], s_g[i+1], s_g[i+2], s_g[i+3]); vec4 sv = vec4(state[i], state[i+1], state[i+2], state[i+3]); vec4 kv = vec4(s_k[i], s_k[i+1], s_k[i+2], s_k[i+3]); kv_col += dot(gv * sv, kv); } FLOAT_TYPE delta_col = (v_val - kv_col) * beta_val; FLOAT_TYPE attn_col = 0.0; [[unroll]] for (uint i = 0; i < S_V; i += 4) { vec4 gv = vec4(s_g[i], s_g[i+1], s_g[i+2], s_g[i+3]); vec4 sv = vec4(state[i], state[i+1], state[i+2], state[i+3]); vec4 kv = vec4(s_k[i], s_k[i+1], s_k[i+2], s_k[i+3]); sv = gv * sv + kv * delta_col; state[i] = sv.x; state[i+1] = sv.y; state[i+2] = sv.z; state[i+3] = sv.w; attn_col += dot(sv, vec4(s_q[i], s_q[i+1], s_q[i+2], s_q[i+3])); } data_dst[attn_off + col] = attn_col * scale; } attn_off += S_V * H; barrier(); } [[unroll]] for (uint i = 0; i < S_V; i++) { data_dst[s_off + state_base + col * S_V + i] = state[i]; } }