MCPcopy Create free account
hub / github.com/RightNow-AI/autokernel / flash_attention_kernel

Function flash_attention_kernel

kernels/flash_attention.py:23–127  ·  view source on GitHub ↗

Flash attention with online softmax. One program per (batch, head, query-block).

(
    Q_ptr, K_ptr, V_ptr, O_ptr,
    stride_qz, stride_qh, stride_qm, stride_qk,
    stride_kz, stride_kh, stride_kn, stride_kk,
    stride_vz, stride_vh, stride_vn, stride_vk,
    stride_oz, stride_oh, stride_om, stride_ok,
    Z, H, M_size, N_size,
    D: tl.constexpr,
    sm_scale,
    IS_CAUSAL: tl.constexpr,
    BLOCK_M: tl.constexpr,
    BLOCK_N: tl.constexpr,
)

Source from the content-addressed store, hash-verified

21
22@triton.jit
23def flash_attention_kernel(
24 Q_ptr, K_ptr, V_ptr, O_ptr,
25 stride_qz, stride_qh, stride_qm, stride_qk,
26 stride_kz, stride_kh, stride_kn, stride_kk,
27 stride_vz, stride_vh, stride_vn, stride_vk,
28 stride_oz, stride_oh, stride_om, stride_ok,
29 Z, H, M_size, N_size,
30 D: tl.constexpr,
31 sm_scale,
32 IS_CAUSAL: tl.constexpr,
33 BLOCK_M: tl.constexpr,
34 BLOCK_N: tl.constexpr,
35):
36 """Flash attention with online softmax. One program per (batch, head, query-block)."""
37 pid_z = tl.program_id(2) # batch
38 pid_h = tl.program_id(1) # head
39 pid_m = tl.program_id(0) # query block
40
41 # Offsets into the batch and head
42 qkv_offset_z = pid_z * stride_qz
43 qkv_offset_h = pid_h * stride_qh
44
45 k_offset_z = pid_z * stride_kz
46 k_offset_h = pid_h * stride_kh
47
48 v_offset_z = pid_z * stride_vz
49 v_offset_h = pid_h * stride_vh
50
51 o_offset_z = pid_z * stride_oz
52 o_offset_h = pid_h * stride_oh
53
54 # Query block offsets
55 offs_m = pid_m * BLOCK_M + tl.arange(0, BLOCK_M)
56 offs_d = tl.arange(0, D)
57
58 # Load Q block [BLOCK_M, D]
59 q_ptrs = Q_ptr + qkv_offset_z + qkv_offset_h + offs_m[:, None] * stride_qm + offs_d[None, :] * stride_qk
60 q_mask = offs_m[:, None] < M_size
61 q = tl.load(q_ptrs, mask=q_mask, other=0.0)
62
63 # Initialize running max and sum for online softmax
64 m_i = tl.full((BLOCK_M,), float("-inf"), dtype=tl.float32)
65 l_i = tl.zeros((BLOCK_M,), dtype=tl.float32)
66 acc = tl.zeros((BLOCK_M, D), dtype=tl.float32)
67
68 # Determine the range of KV blocks to iterate over
69 if IS_CAUSAL:
70 kv_end = tl.minimum(N_size, (pid_m + 1) * BLOCK_M)
71 else:
72 kv_end = N_size
73
74 # Iterate over KV blocks
75 for start_n in range(0, kv_end, BLOCK_N):
76 offs_n = start_n + tl.arange(0, BLOCK_N)
77
78 # Load K block [BLOCK_N, D]
79 k_ptrs = K_ptr + k_offset_z + k_offset_h + offs_n[:, None] * stride_kn + offs_d[None, :] * stride_kk
80 k_mask = offs_n[:, None] < N_size

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected