@@ -19,102 +19,37 @@ const NEG_INF: f32 = -1.0e30;
1919
2020override wg_size : u32 = 64 ;
2121
22- const TM : u32 = 4u ;
23- const TN : u32 = 4u ;
24-
25- fn load_q_vec4 (s : u32 , h : u32 , d4 : u32 ) -> vec4 <f32 > {
26- var r = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
27- if (s >= params . S ) {
28- return r ;
29- }
30- let base = s * params . Hq * params . D + h * params . D ;
31- if (d4 + 0u < params . D ) { r . x = t_q [base + d4 + 0u ]; }
32- if (d4 + 1u < params . D ) { r . y = t_q [base + d4 + 1u ]; }
33- if (d4 + 2u < params . D ) { r . z = t_q [base + d4 + 2u ]; }
34- if (d4 + 3u < params . D ) { r . w = t_q [base + d4 + 3u ]; }
35- return r ;
36- }
37-
38- fn load_k_vec4 (c : u32 , kvh : u32 , d4 : u32 ) -> vec4 <f32 > {
39- var r = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
40- if (c >= params . context_len ) {
41- return r ;
42- }
43- let base = c * params . Hkv * params . D + kvh * params . D ;
44- if (d4 + 0u < params . D ) { r . x = t_k_cache [base + d4 + 0u ]; }
45- if (d4 + 1u < params . D ) { r . y = t_k_cache [base + d4 + 1u ]; }
46- if (d4 + 2u < params . D ) { r . z = t_k_cache [base + d4 + 2u ]; }
47- if (d4 + 3u < params . D ) { r . w = t_k_cache [base + d4 + 3u ]; }
48- return r ;
49- }
50-
51- fn store_qk (s : u32 , c : u32 , h : u32 , raw : f32 ) {
52- if (s >= params . S || c >= params . context_len ) {
53- return ;
54- }
55- var val = raw * params . scale ;
56- // Causal mask: position c may not attend beyond s + input_pos.
57- if (c > s + params . input_pos ) {
58- val = NEG_INF ;
59- }
60- let idx = h * params . S * params . context_len + s * params . context_len + c ;
61- t_attn_weights [idx ] = val ;
62- }
63-
6422@compute @workgroup_size (wg_size , 1 , 1 )
6523fn main (@builtin (global_invocation_id ) gid : vec3 <u32 >) {
66- let nrt = (params . S + TM - 1u ) / TM ;
67- let nct = (params . context_len + TN - 1u ) / TN ;
68- let tiles = nrt * nct ;
69- let total = tiles * params . Hq ;
70- if (gid . x >= total ) {
24+ let total = params . Hq * params . S * params . context_len ;
25+ let idx = gid . x ;
26+ if (idx >= total ) {
7127 return ;
7228 }
29+ let c = idx % params . context_len ;
30+ let s = (idx / params . context_len ) % params . S ;
31+ let h = idx / (params . context_len * params . S );
7332
74- let h = gid . x / tiles ;
75- let rem = gid . x % tiles ;
76- let row_tile = rem / nct ;
77- let col_tile = rem % nct ;
7833 let kvh = h / params . g ;
79- let s0 = row_tile * TM ;
80- let c0 = col_tile * TN ;
8134
82- var acc : array <vec4 <f32 >, 4 >;
83- acc [0 ] = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
84- acc [1 ] = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
85- acc [2 ] = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
86- acc [3 ] = vec4 <f32 >(0 .0 , 0 .0 , 0 .0 , 0 .0 );
35+ let q_base = s * params . Hq * params . D + h * params . D ;
36+ let k_base = c * params . Hkv * params . D + kvh * params . D ;
8737
88- var d4 : u32 = 0u ;
38+ var acc : f32 = 0 .0 ;
39+ var d : u32 = 0u ;
8940 loop {
90- if (d4 >= params . D ) {
41+ if (d >= params . D ) {
9142 break ;
9243 }
93- let q0 = load_q_vec4 (s0 + 0u , h , d4 );
94- let q1 = load_q_vec4 (s0 + 1u , h , d4 );
95- let q2 = load_q_vec4 (s0 + 2u , h , d4 );
96- let q3 = load_q_vec4 (s0 + 3u , h , d4 );
97- let k0 = load_k_vec4 (c0 + 0u , kvh , d4 );
98- let k1 = load_k_vec4 (c0 + 1u , kvh , d4 );
99- let k2 = load_k_vec4 (c0 + 2u , kvh , d4 );
100- let k3 = load_k_vec4 (c0 + 3u , kvh , d4 );
101- acc [0 ] += vec4 <f32 >(dot (q0 , k0 ), dot (q0 , k1 ), dot (q0 , k2 ), dot (q0 , k3 ));
102- acc [1 ] += vec4 <f32 >(dot (q1 , k0 ), dot (q1 , k1 ), dot (q1 , k2 ), dot (q1 , k3 ));
103- acc [2 ] += vec4 <f32 >(dot (q2 , k0 ), dot (q2 , k1 ), dot (q2 , k2 ), dot (q2 , k3 ));
104- acc [3 ] += vec4 <f32 >(dot (q3 , k0 ), dot (q3 , k1 ), dot (q3 , k2 ), dot (q3 , k3 ));
105- d4 = d4 + 4u ;
44+ acc = acc + t_q [q_base + d ] * t_k_cache [k_base + d ];
45+ d = d + 1u ;
10646 }
47+ acc = acc * params . scale ;
10748
108- var m : u32 = 0u ;
109- loop {
110- if (m >= TM ) {
111- break ;
112- }
113- let av = acc [m ];
114- store_qk (s0 + m , c0 + 0u , h , av . x );
115- store_qk (s0 + m , c0 + 1u , h , av . y );
116- store_qk (s0 + m , c0 + 2u , h , av . z );
117- store_qk (s0 + m , c0 + 3u , h , av . w );
118- m = m + 1u ;
49+ // Causal mask: position c may not attend beyond s + input_pos.
50+ if (c > s + params . input_pos ) {
51+ acc = NEG_INF ;
11952 }
53+
54+ t_attn_weights [idx ] = acc ;
12055}
0 commit comments