flash-attention Agent Skills & AI Rules

GitHub

Fast and memory-efficient exact attention

25,191 stars Python Python 8 files ยท ~9,025 tokens
RAW Rules
2 Discovered Rules โ€ข ~3,510 Estimated Tokens
Quick:
Loading skill content...

Claude Agent Guidelines & System Prompt

CLAUDE.md claude-rule ~2,490 tokens
Raw
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

FlashAttention-4 (FA4) โ€” fast, memory-efficient exact attention kernels written in Python using CuTeDSL (NVIDIA CUTLASS DSL). Kernels are compiled to PTX/CUBIN at runtime. Targets Hopper (SM90) and Blackwell (SM100/SM110) GPUs. Package name: `flash-attn-4`.

The repository also contains older generations (FA2 in top-level `csrc/`, FA3 in `hopper/`) but active development is on FA4 in `flash_attn/cute/`.

## Agent Scratch Space

Use `agent_space/` for project-local scratch work such as lab notes, profiling outputs, temporary repro scripts, and experiment artifacts. Treat it as disposable workspace rather than product code.

## Build & Install

```bash
pip install flash-attn-4
# or dev install:
pip install -e "flash_attn/cute[dev]"
```

Dependencies: `nvidia-cutlass-dsl>=4.6.2`, `torch`, `einops`, `apache-tvm-ffi`, `quack-kernels>=0.5.3`.

## Running Tests

```bash
pytest tests/cute/test_flash_attn.py
pytest tests/cute/test_flash_attn.py -k "test_flash_attn_output" -x  # single test
pytest tests/cute/test_flash_attn_mla.py  # MLA (qv): dense / sparse / paged, 1CTA (FLASH_ATTENTION_MLA_1CTA=1) and 2CTA
pytest tests/cute/test_flash_attn_varlen.py
pytest tests/cute/test_mask_mod.py
pytest tests/cute/test_score_mod.py
pytest tests/cute/test_block_sparsity.py
```

### Fast two-pass testing

Compilation dominates test time. The fast workflow separates compilation (parallel, no GPU work) from execution (uses cached binaries). The compilation pass still opens a CUDA context per xdist worker (a few hundred MB each), so set `CUDA_VISIBLE_DEVICES` for both passes:

```bash
# Pass 1: compile all kernels in parallel using FakeTensorMode (no GPU memory allocation)
FLASH_ATTENTION_FAKE_TENSOR=1 FLASH_ATTENTION_CUTE_DSL_CACHE_ENABLED=1 pytest -n 64 -x tests/cute/test_flash_attn.py

# Pass 2: run tests using cached compiled kernels
FLASH_ATTENTION_FAKE_TENSOR=0 FLASH_ATTENTION_CUTE_DSL_CACHE_ENABLED=1 pytest -x tests/cute/test_flash_attn.py
```

- `FLASH_ATTENTION_FAKE_TENSOR=1` โ€” uses PyTorch FakeTensorMode to compile kernels without allocating GPU memory or running them.
- `FLASH_ATTENTION_CUTE_DSL_CACHE_ENABLED=1` โ€” enables persistent disk cache at `/tmp/${USER}/flash_attention_cute_dsl_cache/`.
- `-n 256` โ€” pytest-xdist parallel workers (only useful in the compilation pass).
- `tools/two_pass_tests.sh -k EXPR -g 0,1 [-f FILES]` runs both passes, both limited to the `-g` GPUs. The execution pass runs with
  `FLASH_ATTENTION_TEST_EXPECT_CACHED=1`, which fails any test that still compiles a kernel.
  `FLASH_ATTENTION_TEST_COUNT_COMPILES=1` only reports the compiles.
- Tests must support the compilation pass: decorate with
  `@maybe_fake_tensor_mode(USE_FAKE_TENSOR)`, issue every kernel variant (every env /
  monkeypatch knob) before the first data-dependent check, then `if is_fake_mode(): return`.
- `FLASH_ATTENTION_TEST_RECORD_KEYS=path` records every compile-cache lookup, for diffing the
  kernel set of a selection across changes.
- **Most test files do not support the compilation pass yet.** Only `test_flash_attn_mla.py`
  is fully converted; `test_flash_attn.py` mostly is, and `test_flash_attn_fast.py` and
  `test_flash_attn_combine.py` partly. The mask_mod, score_mod, block-sparsity, varlen, hd256
  scheduler and race-condition files are not converted at all. Their tests run with real tensors in pass 1 and
  can compile again in pass 2, so `FLASH_ATTENTION_TEST_EXPECT_CACHED=1` (and
  `tools/two_pass_tests.sh`) reports them as failures even when the results are correct. Run
  those files in a single pass, or check that a failure is "kernel(s) compiled during the
  execution pass" before treating it as a regression.

Tests are parametrized over dtype (fp16/bf16), head dimension (64, 96, 128), sequence length, causal/non-causal, and MHA/GQA/MQA.

If you get OOM errors running tests or benchmarks, use `nvidia-smi` to find a free GPU and select it with `CUDA_VISIBLE_DEVICES=<id>`.

## Linting

Pre-commit uses ruff on `flash_attn/cute/` files. Large kernel files (`flash_bwd.py`, `flash_fwd.py`, `flash_fwd_sm100.py`, `interface.py`) are excluded from auto-formatting.

```bash
ruff check flash_attn/cute/ --fix
ruff format flash_attn/cute/
```

## Code Architecture

### Public API (`flash_attn/cute/interface.py`)

Two entry points exported from `flash_attn/cute/__init__.py`:
- `flash_attn_func(q, k, v, ...)` โ€” standard attention
- `flash_attn_varlen_func(q, k, v, cu_seqlens_q, cu_seqlens_k, ...)` โ€” variable-length

Key parameters: `causal`, `window_size_left/right`, `softmax_scale`, `softcap`, `score_mod`, `mask_mod`, `block_sparse_tensors`, `num_splits`, `pack_gqa`, `m_block_size`, `n_block_size`, `num_threads`.

Tensor layout: `(batch, seqlen, num_heads, head_dim)`, last dim contiguous, 16-byte aligned.

### Forward Kernels

- `flash_fwd.py` โ€” `FlashAttentionForwardSm90`: Hopper forward. No SplitKV or paged KV.
- `flash_fwd_sm100.py` โ€” `FlashAttentionForwardSm100`: Blackwell forward. Full features including SplitKV, paged KV cache, persistent kernels, 2CTA instructions.
- `flash_fwd_combine.py` โ€” `FlashAttentionForwardCombine`: merges SplitKV partial results.

### Backward Kernels

- `flash_bwd.py` โ€” `FlashAttentionBackwardSm80`: Ampere backward (base).
- `flash_bwd_sm90.py` โ€” `FlashAttentionBackwardSm90`: Hopper backward.
- `flash_bwd_sm100.py` โ€” `FlashAttentionBackwardSm100`: Blackwell backward with 2CTA and block sparse support.
- `flash_bwd_preprocess.py` / `flash_bwd_postprocess.py` โ€” auxiliary backward kernels.

### Core Abstractions

- `softmax.py` โ€” Online softmax with row_max/row_sum tracking, score modifier support.
- `mask.py` โ€” `AttentionMask`: causal, local/sliding window, block sparse, mask_mod application.
- `block_info.py` โ€” `BlockInfo`: tile dimensions, n/m block range computation for causal/local masking.
- `seqlen_info.py` โ€” `SeqlenInfoQK`: sequence length and offset tracking for varlen.
- `pipeline.py` โ€” `PipelineStateSimple`: circular buffer index/phase management for pipelined loads.
- `tile_scheduler.py` โ€” Tile scheduling strategies (single tile, varlen-aware, persistent).
- `copy_utils.py` โ€” Type-converting copies, shared-to-register loads, TMA copy atoms.
- `named_barrier.py` โ€” Named barrier enums for warp synchronization.

### Architecture-Specific Helpers

- `hopper_helpers.py` โ€” SM90 warp-group GEMM, shared memory layout creation, fence/commit/wait.
- `blackwell_helpers.py` โ€” SM100 UMMA-based GEMM, PTX-optimized paths, 2CTA support.
- `mma_sm100_desc.py` โ€” Hardware MMA descriptor enums (formats, saturation, scaling).

### Other Components

- `pack_gqa.py` โ€” Packs multiple Q heads per KV head for efficient GQA.
- `paged_kv.py` โ€” `PagedKVManager`: paged KV cache with TMA support.
- `fast_math.py` โ€” exp2 polynomial coefficients, softcap score_mod creation.
- `utils.py` โ€” Hash functions for compile cache keys, warp reductions, predicates.
- `cache_utils.py` โ€” JIT compilation cache management.
- `cute_dsl_utils.py` โ€” Patched `cute.compile` that optionally dumps SASS.

### Compilation & Caching

Kernels are JIT-compiled. Cache key includes dtype, head_dim, causal, mask/score_mod hashes, architecture, block sizes. Caching levels: in-memory LRU + optional disk cache via `get_jit_cache()`.

Env vars: `CUTE_CUBIN_PATH` (dump CUBIN/SASS), `CUTE_DSL_KEEP_PTX=1` (inspect PTX), `CUTE_DSL_PTXAS_PATH` (custom ptxas).

## Key Patterns

- Compile-time constants use `cutlass.Constexpr[type]` for kernel specialization.
- Score/mask modifiers are user-defined `@cute.jit` callables injected into the kernel at compile time.
- Forward execution: load Q tile โ†’ loop over K/V blocks (pipelined) โ†’ online softmax accumulation โ†’ store O and LSE.
- 2CTA instructions (SM100, hdim=128): both CTAs in a cluster coordinate via shared mbarriers; tx_count must be multiplied by `cta_group_size`.

## Debugging GPU Kernels

**Before proposing a root cause for any hang, deadlock, illegal-address trap, Xid fault, sanitizer report, or numerical mismatch that is not visible in the CuteDSL source, read `AI/DEBUG_METHODOLOGY.md` and follow its protocol** (falsifiable-prediction discipline, evidence tiers, fix-validation hygiene, hypothesis ledger in `agent_space/`).

Tactical docs in `AI/`:
- `DEBUG_2CTA.md` โ€” kernel hang/deadlock debugging (printf bisection, pipeline barrier analysis, 2CTA pitfalls).
- `RACECHECK_TMA_HAZARD.md` โ€” `compute-sanitizer` false positives with `cp.async.bulk` (repro scripts: `racecheck_repro_1d_*.py`).
- `CLC_TRACE_DEBUG.md` โ€” visualization of CLC scheduling (`parse_clc_log.py`).
- `SASS_MMA_ANALYSIS.md` โ€” dumping SASS and analyzing HGMMA instruction mix.
- `SM90_BLOCK_SIZE_TUNING.md` โ€” choosing tile sizes/MMA configs on Hopper (`sm90_config_search.py`).
- `SM90_R2P_MASKING_SASS.md` โ€” SASS-level analysis of R2P predicate masking in SM90 forward.
- `VARLEN_PREPROCESS_TILE_BUG.md` โ€” post-mortem: varlen preprocess tile-size mismatch and padded-offset layout.

Key tools:
- `cute.printf` with thread guards (`tidx % 32 == 0`, `elect_one()`) for targeted output
- `compute-sanitizer --tool=racecheck` (beware false positives with raw TMA)
- `CUTE_DSL_KEEP_PTX=1` and `CUTE_DSL_LINEINFO=1` for PTX inspection and sanitizer source mapping