Skip to content

Commit 2d6ecf3

Browse files
authored
feat: prefer torch stable abi for cuda fa2 (#997)
* feat: prefer torch stable abi for cuda fa2 * fix: avoid all aten ops Signed-off-by: David Holtz <david.richard.holtz@gmail.com> * fix: bump flake to latest builder * fix: update build toml formatting * fix: throw if generator passed --------- Signed-off-by: David Holtz <david.richard.holtz@gmail.com>
1 parent 0c5fb33 commit 2d6ecf3

11 files changed

Lines changed: 851 additions & 665 deletions

flash-attn2/build.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[general]
22
name = "flash-attn2"
3-
version = 2
3+
version = 3
44
license = "BSD-3-Clause"
5+
edition = 5
56
backends = [
67
"cpu",
78
"cuda",
@@ -14,9 +15,14 @@ repo-id = "kernels-community/flash-attn2"
1415
[torch]
1516
src = [
1617
"torch-ext/torch_binding.cpp",
18+
"torch-ext/torch_binding_stable.cpp",
1719
"torch-ext/torch_binding.h",
1820
]
1921

22+
[torch.stable-abi]
23+
cuda = "2.10"
24+
rocm = "2.10"
25+
2026
[kernel.flash_attn_xpu]
2127
backend = "xpu"
2228
depends = [
@@ -181,6 +187,7 @@ depends = [
181187
src = [
182188
"flash_attn/flash_api.cpp",
183189
"flash_attn/src/philox_unpack.cuh",
190+
"flash_attn/src/cuda_check.h",
184191
"flash_attn/src/namespace_config.h",
185192
"flash_attn/src/hardware_info.h",
186193
"flash_attn/src/flash.h",

flash-attn2/flash_attn/flash_api.cpp

Lines changed: 595 additions & 642 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Self-contained CUDA error-check macros.
2+
//
3+
// Replaces c10's <c10/cuda/CUDAException.h> (C10_CUDA_CHECK /
4+
// C10_CUDA_KERNEL_LAUNCH_CHECK), which hard-errors in stable-ABI builds under
5+
// TORCH_STABLE_ONLY / TORCH_TARGET_VERSION. These are used from .cu translation
6+
// units compiled by nvcc, where the CUDA runtime is available.
7+
8+
#pragma once
9+
10+
#include <cstdio>
11+
#include <cstdlib>
12+
13+
#include <cuda_runtime.h>
14+
15+
#define C10_CUDA_CHECK(EXPR) \
16+
do { \
17+
const cudaError_t __err = (EXPR); \
18+
if (__err != cudaSuccess) { \
19+
fprintf(stderr, "CUDA error %s:%d: %s\n", __FILE__, __LINE__, \
20+
cudaGetErrorString(__err)); \
21+
abort(); \
22+
} \
23+
} while (0)
24+
25+
#define C10_CUDA_KERNEL_LAUNCH_CHECK() C10_CUDA_CHECK(cudaGetLastError())

flash-attn2/flash_attn/src/flash.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <cuda.h>
1010
#include <vector>
1111

12-
#include <ATen/cuda/CUDAGeneratorImpl.h> // For at::Generator and at::PhiloxCudaState
12+
#include "philox_unpack.cuh" // For FLASH_NAMESPACE::PhiloxCudaState
1313

1414
namespace FLASH_NAMESPACE {
1515
constexpr int TOTAL_DIM = 0;
@@ -119,7 +119,7 @@ struct Flash_fwd_params : public Qkv_params {
119119
float softcap;
120120

121121
// Random state.
122-
at::PhiloxCudaState philox_args;
122+
PhiloxCudaState philox_args;
123123

124124
// Pointer to the RNG seed (idx 0) and offset (idx 1).
125125
uint64_t * rng_state;

flash-attn2/flash_attn/src/flash_bwd_launch_template.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#pragma once
66

77
#include "namespace_config.h"
8-
#include <c10/cuda/CUDAException.h> // For C10_CUDA_CHECK and C10_CUDA_KERNEL_LAUNCH_CHECK
8+
#include "cuda_check.h" // For C10_CUDA_CHECK and C10_CUDA_KERNEL_LAUNCH_CHECK
99

1010
#include "static_switch.h"
1111
#include "hardware_info.h"

flash-attn2/flash_attn/src/flash_fwd_kernel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ inline __device__ void compute_attn_1rowblock(const Params &params, const int bi
6666
constexpr int kHeadDim = Kernel_traits::kHeadDim;
6767
constexpr int kNWarps = Kernel_traits::kNWarps;
6868

69-
auto seed_offset = at::cuda::philox::unpack(params.philox_args);
69+
auto seed_offset = FLASH_NAMESPACE::philox_compat::unpack(params.philox_args);
7070
FLASH_NAMESPACE::Dropout dropout(std::get<0>(seed_offset), std::get<1>(seed_offset), params.p_dropout_in_uint8_t,
7171
bidb, bidh, tidx, params.h);
7272

flash-attn2/flash_attn/src/flash_fwd_launch_template.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#pragma once
66
#include "namespace_config.h"
7-
#include <c10/cuda/CUDAException.h> // For C10_CUDA_CHECK and C10_CUDA_KERNEL_LAUNCH_CHECK
7+
#include "cuda_check.h" // For C10_CUDA_CHECK and C10_CUDA_KERNEL_LAUNCH_CHECK
88

99
#include "static_switch.h"
1010
#include "hardware_info.h"
Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,65 @@
1-
// This is purely so that it works with torch 2.1. For torch 2.2+ we can include ATen/cuda/PhiloxUtils.cuh
1+
// Self-contained Philox RNG state + unpack helper.
2+
//
3+
// This replaces ATen's `at::PhiloxCudaState` and `at::cuda::philox::unpack`
4+
// (formerly pulled in via <ATen/cuda/CUDAGeneratorImpl.h> and
5+
// <ATen/cuda/detail/UnpackRaw.cuh>). Those ATen headers cannot be included in
6+
// stable-ABI builds, where they hard-error under TORCH_STABLE_ONLY. The layout
7+
// and semantics here mirror ATen's so the kernels are unchanged.
28

39
#pragma once
4-
#include <ATen/cuda/detail/UnpackRaw.cuh>
10+
11+
#include <cstdint>
12+
#include <tuple>
13+
14+
#include "namespace_config.h"
15+
16+
namespace FLASH_NAMESPACE {
17+
18+
struct PhiloxCudaState {
19+
PhiloxCudaState() = default;
20+
21+
// Non-captured (eager) state: literal seed and offset values.
22+
PhiloxCudaState(uint64_t seed, uint64_t offset) {
23+
seed_.val = seed;
24+
offset_.val = offset;
25+
}
26+
27+
// Captured (CUDA graph) state: pointers resolved at kernel launch time.
28+
PhiloxCudaState(int64_t *seed, int64_t *offset_extragraph,
29+
uint32_t offset_intragraph) {
30+
seed_.ptr = seed;
31+
offset_.ptr = offset_extragraph;
32+
offset_intragraph_ = offset_intragraph;
33+
captured_ = true;
34+
}
35+
36+
union Payload {
37+
uint64_t val;
38+
int64_t *ptr;
39+
};
40+
41+
Payload seed_{};
42+
Payload offset_{};
43+
uint32_t offset_intragraph_ = 0;
44+
bool captured_ = false;
45+
};
46+
47+
// Namespace deliberately not named `philox`: FLASH_NAMESPACE already declares a
48+
// `philox(...)` function in philox.cuh, which would collide.
49+
namespace philox_compat {
50+
51+
__host__ __device__ __forceinline__ std::tuple<uint64_t, uint64_t>
52+
unpack(PhiloxCudaState arg) {
53+
if (arg.captured_) {
54+
// offset_intragraph_ counts thread-local subsequence usage within a graph.
55+
return std::make_tuple(
56+
static_cast<uint64_t>(*arg.seed_.ptr),
57+
static_cast<uint64_t>(*arg.offset_.ptr) + arg.offset_intragraph_);
58+
} else {
59+
return std::make_tuple(arg.seed_.val, arg.offset_.val);
60+
}
61+
}
62+
63+
} // namespace philox_compat
64+
65+
} // namespace FLASH_NAMESPACE

flash-attn2/torch-ext/torch_binding.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
// CUDA registers via the Torch stable ABI in torch_binding_stable.cpp /
2+
// flash_attn/flash_api.cpp; the ATen headers below are only available (and
3+
// only needed) for the CPU and XPU backends.
4+
#if !defined(CUDA_KERNEL)
15
#include <torch/library.h>
26

37
#include "registration.h"
48
#include "torch_binding.h"
9+
#endif
510

611
// TODO: Add all of the functions listed
712
// PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
@@ -13,6 +18,10 @@
1318
// m.def("fwd_kvcache", &FLASH_NAMESPACE::mha_fwd_kvcache, "Forward pass, with KV-cache");
1419
//
1520

21+
// CUDA registers via the Torch stable ABI in flash_attn/flash_api.cpp;
22+
// this original ATen registration is only for the CPU and XPU backends.
23+
#if !defined(CUDA_KERNEL)
24+
1625
TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
1726
ops.def("fwd("
1827
"Tensor! q, "
@@ -28,9 +37,7 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
2837
"float softcap, "
2938
"bool return_softmax, "
3039
"Generator? gen_) -> Tensor[]");
31-
#if defined(CUDA_KERNEL)
32-
ops.impl("fwd", torch::kCUDA, &mha_fwd);
33-
#elif defined(XPU_KERNEL)
40+
#if defined(XPU_KERNEL)
3441
ops.impl("fwd", torch::kXPU, &mha_fwd);
3542
#endif
3643

@@ -56,9 +63,7 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
5663
"float softcap, "
5764
"bool return_softmax, "
5865
"Generator? gen_) -> Tensor[]");
59-
#if defined(CUDA_KERNEL)
60-
ops.impl("varlen_fwd", torch::kCUDA, &mha_varlen_fwd);
61-
#elif defined(XPU_KERNEL)
66+
#if defined(XPU_KERNEL)
6267
ops.impl("varlen_fwd", torch::kXPU, &mha_varlen_fwd);
6368
#elif defined(CPU_KERNEL)
6469
ops.impl("varlen_fwd", torch::kCPU, &mha_varlen_fwd);
@@ -85,9 +90,7 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
8590
"bool deterministic, "
8691
"Generator? gen_, "
8792
"Tensor? rng_state) -> Tensor[]");
88-
#if defined(CUDA_KERNEL)
89-
ops.impl("bwd", torch::kCUDA, &mha_bwd);
90-
#elif defined(XPU_KERNEL)
93+
#if defined(XPU_KERNEL)
9194
ops.impl("bwd", torch::kXPU, &mha_bwd);
9295
#endif
9396

@@ -115,9 +118,7 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
115118
"bool deterministic, "
116119
"Generator? gen_, "
117120
"Tensor? rng_state) -> Tensor[]");
118-
#if defined(CUDA_KERNEL)
119-
ops.impl("varlen_bwd", torch::kCUDA, &mha_varlen_bwd);
120-
#elif defined(XPU_KERNEL)
121+
#if defined(XPU_KERNEL)
121122
ops.impl("varlen_bwd", torch::kXPU, &mha_varlen_bwd);
122123
#endif
123124

@@ -142,11 +143,11 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
142143
"float softcap, "
143144
"bool is_rotary_interleaved, "
144145
"int num_splits) -> Tensor[]");
145-
#if defined(CUDA_KERNEL)
146-
ops.impl("fwd_kvcache", torch::kCUDA, &mha_fwd_kvcache);
147-
#elif defined(XPU_KERNEL)
146+
#if defined(XPU_KERNEL)
148147
ops.impl("fwd_kvcache", torch::kXPU, &mha_fwd_kvcache);
149148
#endif
150149
}
151150

152151
REGISTER_EXTENSION(TORCH_EXTENSION_NAME)
152+
153+
#endif // !defined(CUDA_KERNEL)

flash-attn2/torch-ext/torch_binding.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <vector>
4+
35
#include <torch/torch.h>
46

57
// std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor>

0 commit comments

Comments
 (0)