Kernels
danieldk HF Staff commited on
Commit
37a6646
·
verified ·
1 Parent(s): 1ec3eb7

Build uploaded using `kernels`.

Browse files
Files changed (37) hide show
  1. .gitattributes +6 -0
  2. build/torch210-cxx11-cu126-x86_64-linux/_ops.py +3 -3
  3. build/torch210-cxx11-cu126-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  4. build/torch210-cxx11-cu126-x86_64-linux/core.py +28 -18
  5. build/torch210-cxx11-cu126-x86_64-linux/sm80_compile.py +149 -0
  6. build/torch210-cxx11-cu126-x86_64-linux/sm89_compile.py +146 -0
  7. build/torch210-cxx11-cu126-x86_64-linux/sm90_compile.py +94 -0
  8. build/torch210-cxx11-cu128-x86_64-linux/_ops.py +3 -3
  9. build/torch210-cxx11-cu128-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  10. build/torch210-cxx11-cu128-x86_64-linux/core.py +28 -18
  11. build/torch210-cxx11-cu128-x86_64-linux/sm80_compile.py +149 -0
  12. build/torch210-cxx11-cu128-x86_64-linux/sm89_compile.py +146 -0
  13. build/torch210-cxx11-cu128-x86_64-linux/sm90_compile.py +94 -0
  14. build/torch210-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  15. build/torch210-cxx11-cu130-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  16. build/torch210-cxx11-cu130-x86_64-linux/core.py +28 -18
  17. build/torch210-cxx11-cu130-x86_64-linux/sm80_compile.py +149 -0
  18. build/torch210-cxx11-cu130-x86_64-linux/sm89_compile.py +146 -0
  19. build/torch210-cxx11-cu130-x86_64-linux/sm90_compile.py +94 -0
  20. build/torch29-cxx11-cu126-x86_64-linux/_ops.py +3 -3
  21. build/torch29-cxx11-cu126-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  22. build/torch29-cxx11-cu126-x86_64-linux/core.py +28 -18
  23. build/torch29-cxx11-cu126-x86_64-linux/sm80_compile.py +149 -0
  24. build/torch29-cxx11-cu126-x86_64-linux/sm89_compile.py +146 -0
  25. build/torch29-cxx11-cu126-x86_64-linux/sm90_compile.py +94 -0
  26. build/torch29-cxx11-cu128-x86_64-linux/_ops.py +3 -3
  27. build/torch29-cxx11-cu128-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  28. build/torch29-cxx11-cu128-x86_64-linux/core.py +28 -18
  29. build/torch29-cxx11-cu128-x86_64-linux/sm80_compile.py +149 -0
  30. build/torch29-cxx11-cu128-x86_64-linux/sm89_compile.py +146 -0
  31. build/torch29-cxx11-cu128-x86_64-linux/sm90_compile.py +94 -0
  32. build/torch29-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  33. build/torch29-cxx11-cu130-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} +1 -1
  34. build/torch29-cxx11-cu130-x86_64-linux/core.py +28 -18
  35. build/torch29-cxx11-cu130-x86_64-linux/sm80_compile.py +149 -0
  36. build/torch29-cxx11-cu130-x86_64-linux/sm89_compile.py +146 -0
  37. build/torch29-cxx11-cu130-x86_64-linux/sm90_compile.py +94 -0
.gitattributes CHANGED
@@ -42,3 +42,9 @@ build/torch28-cxx11-cu129-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lf
42
  build/torch29-cxx11-cu126-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
43
  build/torch29-cxx11-cu128-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
44
  build/torch29-cxx11-cu130-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
42
  build/torch29-cxx11-cu126-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
43
  build/torch29-cxx11-cu128-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
44
  build/torch29-cxx11-cu130-x86_64-linux/_sage_attention_fd27ff6.abi3.so filter=lfs diff=lfs merge=lfs -text
45
+ build/torch210-cxx11-cu126-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
46
+ build/torch210-cxx11-cu128-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
47
+ build/torch210-cxx11-cu130-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
48
+ build/torch29-cxx11-cu126-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
49
+ build/torch29-cxx11-cu128-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
50
+ build/torch29-cxx11-cu130-x86_64-linux/_sage_attention_6e51d70.abi3.so filter=lfs diff=lfs merge=lfs -text
build/torch210-cxx11-cu126-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch210-cxx11-cu126-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d53a88f707f1e0d577a47804705a016689f87f4ea6774ee43c505e518a1f6381
3
  size 26060392
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8b4b01fb9797a2b69820d313342d84dcfc94f0bf333aec597283953b8bd9eb7f
3
  size 26060392
build/torch210-cxx11-cu126-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch210-cxx11-cu126-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch210-cxx11-cu126-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch210-cxx11-cu126-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )
build/torch210-cxx11-cu128-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch210-cxx11-cu128-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:197bf16fca0554701c5620459b775bad35addd285c1278087320215b975ccadf
3
  size 26573256
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:86cee1d97e0e6fcd5aaf9480aaa092d96d7e8780214e2768ae1a68448df2dbf3
3
  size 26573256
build/torch210-cxx11-cu128-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch210-cxx11-cu128-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch210-cxx11-cu128-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch210-cxx11-cu128-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )
build/torch210-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch210-cxx11-cu130-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:351b02c6234e73d9efbee0132ab44a20e57c2453226ef9e8a86d0232d22bebc6
3
  size 27244536
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:52f21795a824fc986e20cc3bda1ccfb7327343868888692d117ee8b81376dda9
3
  size 27244536
build/torch210-cxx11-cu130-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch210-cxx11-cu130-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch210-cxx11-cu130-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch210-cxx11-cu130-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )
build/torch29-cxx11-cu126-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch29-cxx11-cu126-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:7504326736656248338fe6d96345810d2eb0e8abd7136e4da90db197779214e4
3
  size 26050976
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b3aaf3cffb71067f4816ba5da358cd3a0d3b19b9cb2ba1ec0eedf1bf9b4051e3
3
  size 26050976
build/torch29-cxx11-cu126-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch29-cxx11-cu126-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch29-cxx11-cu126-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch29-cxx11-cu126-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )
build/torch29-cxx11-cu128-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch29-cxx11-cu128-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:44e7fea6089e29f0611740963becd2a2c73fa54c04626df244add57c58c25282
3
  size 26559000
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c58f1609620670fd73e4b5e111a3efc2e1f17197afe9705a45d00e6aac8e02b5
3
  size 26559000
build/torch29-cxx11-cu128-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch29-cxx11-cu128-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch29-cxx11-cu128-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch29-cxx11-cu128-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )
build/torch29-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _sage_attention_fd27ff6
3
- ops = torch.ops._sage_attention_fd27ff6
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_sage_attention_fd27ff6::{op_name}"
 
1
  import torch
2
+ from . import _sage_attention_6e51d70
3
+ ops = torch.ops._sage_attention_6e51d70
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_sage_attention_6e51d70::{op_name}"
build/torch29-cxx11-cu130-x86_64-linux/{_sage_attention_fd27ff6.abi3.so → _sage_attention_6e51d70.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0a991d9feee4186bf22ca8da3dd27acfcc1852b282c46052ad16f29f842f7ec1
3
  size 27230776
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bce203e59afbf482ef8d9669badd97ca0600d5fefc8c66cfc6158a9c319b3f78
3
  size 27230776
build/torch29-cxx11-cu130-x86_64-linux/core.py CHANGED
@@ -25,6 +25,24 @@ from .quant import sub_mean
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  from typing import Any, List, Literal, Optional, Tuple, Union
29
  import warnings
30
 
@@ -116,7 +134,6 @@ def sageattn(
116
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
117
  - All tensors must be on the same cuda device.
118
  """
119
- print("########tensor_layout", tensor_layout)
120
  arch = get_cuda_arch_versions()[q.device.index]
121
  if arch == "sm80":
122
  return sageattn_qk_int8_pv_fp16_cuda(
@@ -166,8 +183,6 @@ def sageattn(
166
  else:
167
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
168
 
169
-
170
- @torch.compiler.disable
171
  def sageattn_qk_int8_pv_fp16_cuda(
172
  q: torch.Tensor,
173
  k: torch.Tensor,
@@ -363,7 +378,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
363
 
364
  if pv_accum_dtype == "fp32":
365
  v = v.to(torch.float16)
366
- lse = ops.qk_int8_sv_f16_accum_f32_attn(
367
  q_int8,
368
  k_int8,
369
  v,
@@ -379,7 +394,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
379
  elif pv_accum_dtype == "fp16":
380
  if smooth_v:
381
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
382
- lse = ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
383
  q_int8,
384
  k_int8,
385
  smoothed_v,
@@ -395,7 +410,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
395
  )
396
  else:
397
  v = v.to(torch.float16)
398
- lse = ops.qk_int8_sv_f16_accum_f16_attn(
399
  q_int8,
400
  k_int8,
401
  v,
@@ -410,7 +425,7 @@ def sageattn_qk_int8_pv_fp16_cuda(
410
  )
411
  elif pv_accum_dtype == "fp16+fp32":
412
  v = v.to(torch.float16)
413
- lse = ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
414
  q_int8,
415
  k_int8,
416
  v,
@@ -438,8 +453,6 @@ def sageattn_qk_int8_pv_fp16_cuda(
438
  else:
439
  return o
440
 
441
-
442
- @torch.compiler.disable
443
  def sageattn_qk_int8_pv_fp8_cuda(
444
  q: torch.Tensor,
445
  k: torch.Tensor,
@@ -635,10 +648,9 @@ def sageattn_qk_int8_pv_fp8_cuda(
635
  v_fp8, v_scale, vm = per_channel_fp8(
636
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
637
  )
638
- print("before kernel call")
639
  if pv_accum_dtype == "fp32":
640
  if smooth_v:
641
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
642
  q_int8,
643
  k_int8,
644
  v_fp8,
@@ -655,7 +667,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
655
  )
656
  torch.cuda.synchronize()
657
  else:
658
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
659
  q_int8,
660
  k_int8,
661
  v_fp8,
@@ -671,7 +683,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
671
  )
672
  torch.cuda.synchronize()
673
  elif pv_accum_dtype == "fp32+fp32":
674
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
675
  q_int8,
676
  k_int8,
677
  v_fp8,
@@ -687,7 +699,7 @@ def sageattn_qk_int8_pv_fp8_cuda(
687
  )
688
  torch.cuda.synchronize()
689
  elif pv_accum_dtype == "fp32+fp16":
690
- lse = ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
691
  q_int8,
692
  k_int8,
693
  v_fp8,
@@ -703,7 +715,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
703
  )
704
  torch.cuda.synchronize()
705
  o = o[..., :head_dim_og]
706
- print("after kernel call")
707
  if return_lse:
708
  return (
709
  o,
@@ -715,7 +726,6 @@ def sageattn_qk_int8_pv_fp8_cuda(
715
  return o
716
 
717
 
718
- @torch.compiler.disable
719
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
720
  q: torch.Tensor,
721
  k: torch.Tensor,
@@ -926,7 +936,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
926
 
927
  if pv_accum_dtype == "fp32":
928
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
929
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
930
  q_int8,
931
  k_int8,
932
  v_fp8,
@@ -941,7 +951,7 @@ def sageattn_qk_int8_pv_fp8_cuda_sm90(
941
  _return_lse,
942
  )
943
  elif pv_accum_dtype == "fp32+fp32":
944
- lse = ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
945
  q_int8,
946
  k_int8,
947
  v_fp8,
 
25
  from .quant import per_channel_fp8
26
  from .quant_per_thread import per_thread_int8 as per_thread_int8_triton
27
 
28
+ try:
29
+ from . import sm80_compile
30
+ SM80_ENABLED = True
31
+ except:
32
+ SM80_ENABLED = False
33
+
34
+ try:
35
+ from . import sm89_compile
36
+ SM89_ENABLED = True
37
+ except:
38
+ SM89_ENABLED = False
39
+
40
+ try:
41
+ from . import sm90_compile
42
+ SM90_ENABLED = True
43
+ except:
44
+ SM90_ENABLED = False
45
+
46
  from typing import Any, List, Literal, Optional, Tuple, Union
47
  import warnings
48
 
 
134
  - The tensors `q`, `k`, and `v` must have the dtype ``torch.float16`` or ``torch.bfloat16``
135
  - All tensors must be on the same cuda device.
136
  """
 
137
  arch = get_cuda_arch_versions()[q.device.index]
138
  if arch == "sm80":
139
  return sageattn_qk_int8_pv_fp16_cuda(
 
183
  else:
184
  raise ValueError(f"Unsupported CUDA architecture: {arch}")
185
 
 
 
186
  def sageattn_qk_int8_pv_fp16_cuda(
187
  q: torch.Tensor,
188
  k: torch.Tensor,
 
378
 
379
  if pv_accum_dtype == "fp32":
380
  v = v.to(torch.float16)
381
+ lse = sm80_compile.qk_int8_sv_f16_accum_f32_attn(
382
  q_int8,
383
  k_int8,
384
  v,
 
394
  elif pv_accum_dtype == "fp16":
395
  if smooth_v:
396
  smoothed_v, vm = sub_mean(v, tensor_layout=tensor_layout)
397
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
398
  q_int8,
399
  k_int8,
400
  smoothed_v,
 
410
  )
411
  else:
412
  v = v.to(torch.float16)
413
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn(
414
  q_int8,
415
  k_int8,
416
  v,
 
425
  )
426
  elif pv_accum_dtype == "fp16+fp32":
427
  v = v.to(torch.float16)
428
+ lse = sm80_compile.qk_int8_sv_f16_accum_f16_attn_inst_buf(
429
  q_int8,
430
  k_int8,
431
  v,
 
453
  else:
454
  return o
455
 
 
 
456
  def sageattn_qk_int8_pv_fp8_cuda(
457
  q: torch.Tensor,
458
  k: torch.Tensor,
 
648
  v_fp8, v_scale, vm = per_channel_fp8(
649
  v, tensor_layout=tensor_layout, scale_max=quant_v_scale_max, smooth_v=smooth_v
650
  )
 
651
  if pv_accum_dtype == "fp32":
652
  if smooth_v:
653
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
654
  q_int8,
655
  k_int8,
656
  v_fp8,
 
667
  )
668
  torch.cuda.synchronize()
669
  else:
670
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
671
  q_int8,
672
  k_int8,
673
  v_fp8,
 
683
  )
684
  torch.cuda.synchronize()
685
  elif pv_accum_dtype == "fp32+fp32":
686
+ lse = sm89_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
687
  q_int8,
688
  k_int8,
689
  v_fp8,
 
699
  )
700
  torch.cuda.synchronize()
701
  elif pv_accum_dtype == "fp32+fp16":
702
+ lse = sm89_compile.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
703
  q_int8,
704
  k_int8,
705
  v_fp8,
 
715
  )
716
  torch.cuda.synchronize()
717
  o = o[..., :head_dim_og]
 
718
  if return_lse:
719
  return (
720
  o,
 
726
  return o
727
 
728
 
 
729
  def sageattn_qk_int8_pv_fp8_cuda_sm90(
730
  q: torch.Tensor,
731
  k: torch.Tensor,
 
936
 
937
  if pv_accum_dtype == "fp32":
938
  raise NotImplementedError("Please use pv_accum_dtype='fp32+fp32' for sm90.")
939
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
940
  q_int8,
941
  k_int8,
942
  v_fp8,
 
951
  _return_lse,
952
  )
953
  elif pv_accum_dtype == "fp32+fp32":
954
+ lse = sm90_compile.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
955
  q_int8,
956
  k_int8,
957
  v_fp8,
build/torch29-cxx11-cu130-x86_64-linux/sm80_compile.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f16_accum_f16_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ """
20
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
21
+ """
22
+ return ops.qk_int8_sv_f16_accum_f16_attn(
23
+ query, key, value, output, query_scale, key_scale, tensor_layout,
24
+ is_causal, qk_quant_gran, sm_scale, return_lse
25
+ )
26
+
27
+
28
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"), mutates_args=("output",), device_types="cuda")
29
+ def qk_int8_sv_f16_accum_f32_attn(
30
+ query: torch.Tensor,
31
+ key: torch.Tensor,
32
+ value: torch.Tensor,
33
+ output: torch.Tensor,
34
+ query_scale: torch.Tensor,
35
+ key_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ """
43
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP32 accumulation.
44
+ """
45
+ return ops.qk_int8_sv_f16_accum_f32_attn(
46
+ query, key, value, output, query_scale, key_scale, tensor_layout,
47
+ is_causal, qk_quant_gran, sm_scale, return_lse
48
+ )
49
+
50
+
51
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
52
+ def qk_int8_sv_f16_accum_f16_attn_inst_buf(
53
+ query: torch.Tensor,
54
+ key: torch.Tensor,
55
+ value: torch.Tensor,
56
+ output: torch.Tensor,
57
+ query_scale: torch.Tensor,
58
+ key_scale: torch.Tensor,
59
+ tensor_layout: int,
60
+ is_causal: int,
61
+ qk_quant_gran: int,
62
+ sm_scale: float,
63
+ return_lse: int,
64
+ ) -> torch.Tensor:
65
+ """
66
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
67
+ """
68
+ return ops.qk_int8_sv_f16_accum_f16_attn_inst_buf(
69
+ query, key, value, output, query_scale, key_scale, tensor_layout,
70
+ is_causal, qk_quant_gran, sm_scale, return_lse
71
+ )
72
+
73
+
74
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
75
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
76
+ query: torch.Tensor,
77
+ key: torch.Tensor,
78
+ value: torch.Tensor,
79
+ output: torch.Tensor,
80
+ query_scale: torch.Tensor,
81
+ key_scale: torch.Tensor,
82
+ value_mean: torch.Tensor,
83
+ tensor_layout: int,
84
+ is_causal: int,
85
+ qk_quant_gran: int,
86
+ sm_scale: float,
87
+ return_lse: int,
88
+ ) -> torch.Tensor:
89
+ """
90
+ Custom CUDA kernel for SageAttention with INT8 quantization for Q and K, FP16 PV with FP16 accumulation.
91
+ """
92
+ return ops.qk_int8_sv_f16_accum_f16_fuse_v_mean_attn(
93
+ query, key, value, output, query_scale, key_scale, value_mean,
94
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
95
+ )
96
+
97
+
98
+ def sm80_qk_fake_impl(
99
+ query: torch.Tensor,
100
+ key: torch.Tensor,
101
+ value: torch.Tensor,
102
+ output: torch.Tensor,
103
+ query_scale: torch.Tensor,
104
+ key_scale: torch.Tensor,
105
+ tensor_layout: int,
106
+ is_causal: int,
107
+ qk_quant_gran: int,
108
+ sm_scale: float,
109
+ return_lse: int,
110
+ ) -> torch.Tensor:
111
+ batch_size = query.size(0)
112
+
113
+ if tensor_layout == 0:
114
+ num_qo_heads = query.size(2)
115
+ qo_len = query.size(1)
116
+ else:
117
+ num_qo_heads = query.size(1)
118
+ qo_len = query.size(2)
119
+
120
+ if return_lse:
121
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
122
+ else:
123
+ lse = torch.empty((0))
124
+ return lse
125
+
126
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn"))(sm80_qk_fake_impl)
127
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f32_attn"))(sm80_qk_fake_impl)
128
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_attn_inst_buf"))(sm80_qk_fake_impl)
129
+
130
+
131
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f16_accum_f16_fuse_v_mean_attn"))
132
+ def qk_int8_sv_f16_accum_f16_fuse_v_mean_attn_fake_impl(
133
+ query: torch.Tensor,
134
+ key: torch.Tensor,
135
+ value: torch.Tensor,
136
+ output: torch.Tensor,
137
+ query_scale: torch.Tensor,
138
+ key_scale: torch.Tensor,
139
+ value_mean: torch.Tensor,
140
+ tensor_layout: int,
141
+ is_causal: int,
142
+ qk_quant_gran: int,
143
+ sm_scale: float,
144
+ return_lse: int,
145
+ ) -> torch.Tensor:
146
+ return sm80_qk_fake_impl(
147
+ query, key, value, output, query_scale, key_scale, tensor_layout,
148
+ is_causal, qk_quant_gran, sm_scale, return_lse
149
+ )
build/torch29-cxx11-cu130-x86_64-linux/sm89_compile.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ value_scale: torch.Tensor,
14
+ tensor_layout: int,
15
+ is_causal: int,
16
+ qk_quant_gran: int,
17
+ sm_scale: float,
18
+ return_lse: int,
19
+ ) -> torch.Tensor:
20
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn(
21
+ query, key, value, output, query_scale, key_scale, value_scale,
22
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
23
+ )
24
+
25
+
26
+
27
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
28
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
29
+ query: torch.Tensor,
30
+ key: torch.Tensor,
31
+ value: torch.Tensor,
32
+ output: torch.Tensor,
33
+ query_scale: torch.Tensor,
34
+ key_scale: torch.Tensor,
35
+ value_scale: torch.Tensor,
36
+ tensor_layout: int,
37
+ is_causal: int,
38
+ qk_quant_gran: int,
39
+ sm_scale: float,
40
+ return_lse: int,
41
+ ) -> torch.Tensor:
42
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf(
43
+ query, key, value, output, query_scale, key_scale, value_scale,
44
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
45
+ )
46
+
47
+
48
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
49
+ def qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
50
+ query: torch.Tensor,
51
+ key: torch.Tensor,
52
+ value: torch.Tensor,
53
+ output: torch.Tensor,
54
+ query_scale: torch.Tensor,
55
+ key_scale: torch.Tensor,
56
+ value_scale: torch.Tensor,
57
+ tensor_layout: int,
58
+ is_causal: int,
59
+ qk_quant_gran: int,
60
+ sm_scale: float,
61
+ return_lse: int,
62
+ ) -> torch.Tensor:
63
+ return ops.qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf(
64
+ query, key, value, output, query_scale, key_scale, value_scale,
65
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
66
+ )
67
+
68
+
69
+ def sm89_qk_with_key_value(
70
+ query: torch.Tensor,
71
+ key: torch.Tensor,
72
+ value: torch.Tensor,
73
+ output: torch.Tensor,
74
+ query_scale: torch.Tensor,
75
+ key_scale: torch.Tensor,
76
+ value_scale: torch.Tensor,
77
+ tensor_layout: int,
78
+ is_causal: int,
79
+ qk_quant_gran: int,
80
+ sm_scale: float,
81
+ return_lse: int,
82
+ ) -> torch.Tensor:
83
+ batch_size = query.size(0)
84
+
85
+ if tensor_layout == 0:
86
+ num_qo_heads = query.size(2)
87
+ qo_len = query.size(1)
88
+ else:
89
+ num_qo_heads = query.size(1)
90
+ qo_len = query.size(2)
91
+
92
+ if return_lse:
93
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
94
+ else:
95
+ lse = torch.empty((0))
96
+ return lse
97
+
98
+
99
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
100
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f16_fuse_v_scale_attn_inst_buf"))(sm89_qk_with_key_value)
101
+ torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn"))(sm89_qk_with_key_value)
102
+
103
+
104
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"), mutates_args=("output",), device_types="cuda")
105
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
106
+ query: torch.Tensor,
107
+ key: torch.Tensor,
108
+ value: torch.Tensor,
109
+ output: torch.Tensor,
110
+ query_scale: torch.Tensor,
111
+ key_scale: torch.Tensor,
112
+ value_scale: torch.Tensor,
113
+ value_mean: torch.Tensor,
114
+ tensor_layout: int,
115
+ is_causal: int,
116
+ qk_quant_gran: int,
117
+ sm_scale: float,
118
+ return_lse: int,
119
+ ) -> torch.Tensor:
120
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn(
121
+ query, key, value, output, query_scale, key_scale, value_scale,
122
+ value_mean, tensor_layout, is_causal, qk_quant_gran, sm_scale,
123
+ return_lse
124
+ )
125
+
126
+
127
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_fuse_v_mean_attn"))
128
+ def sm89_qk_with_key_value_mean(
129
+ query: torch.Tensor,
130
+ key: torch.Tensor,
131
+ value: torch.Tensor,
132
+ output: torch.Tensor,
133
+ query_scale: torch.Tensor,
134
+ key_scale: torch.Tensor,
135
+ value_scale: torch.Tensor,
136
+ value_mean: torch.Tensor,
137
+ tensor_layout: int,
138
+ is_causal: int,
139
+ qk_quant_gran: int,
140
+ sm_scale: float,
141
+ return_lse: int,
142
+ ) -> torch.Tensor:
143
+ return sm89_qk_with_key_value(
144
+ query, key, value, output, query_scale, key_scale, value_scale,
145
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
146
+ )
build/torch29-cxx11-cu130-x86_64-linux/sm90_compile.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ._ops import ops
2
+ import torch
3
+ from ._ops import add_op_namespace_prefix
4
+
5
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"), mutates_args=("output",), device_types="cuda")
6
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf(
7
+ query: torch.Tensor,
8
+ key: torch.Tensor,
9
+ value: torch.Tensor,
10
+ output: torch.Tensor,
11
+ query_scale: torch.Tensor,
12
+ key_scale: torch.Tensor,
13
+ tensor_layout: int,
14
+ is_causal: int,
15
+ qk_quant_gran: int,
16
+ sm_scale: float,
17
+ return_lse: int,
18
+ ) -> torch.Tensor:
19
+ return ops.qk_int8_sv_f8_accum_f32_attn_inst_buf(
20
+ query, key, value, output, query_scale, key_scale, tensor_layout,
21
+ is_causal, qk_quant_gran, sm_scale, return_lse
22
+ )
23
+
24
+
25
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_attn_inst_buf"))
26
+ def qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
27
+ query: torch.Tensor,
28
+ key: torch.Tensor,
29
+ value: torch.Tensor,
30
+ output: torch.Tensor,
31
+ query_scale: torch.Tensor,
32
+ key_scale: torch.Tensor,
33
+ tensor_layout: int,
34
+ is_causal: int,
35
+ qk_quant_gran: int,
36
+ sm_scale: float,
37
+ return_lse: int,
38
+ ) -> torch.Tensor:
39
+ batch_size = query.size(0)
40
+
41
+ if tensor_layout == 0:
42
+ num_qo_heads = query.size(2)
43
+ qo_len = query.size(1)
44
+ else:
45
+ num_qo_heads = query.size(1)
46
+ qo_len = query.size(2)
47
+
48
+ if return_lse:
49
+ lse = torch.empty((batch_size, num_qo_heads, qo_len), dtype=torch.float32, device=query.device)
50
+ else:
51
+ lse = torch.empty((0))
52
+ return lse
53
+
54
+
55
+ @torch.library.custom_op(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"), mutates_args=("output",), device_types="cuda")
56
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
57
+ query: torch.Tensor,
58
+ key: torch.Tensor,
59
+ value: torch.Tensor,
60
+ output: torch.Tensor,
61
+ query_scale: torch.Tensor,
62
+ key_scale: torch.Tensor,
63
+ value_scale: torch.Tensor,
64
+ tensor_layout: int,
65
+ is_causal: int,
66
+ qk_quant_gran: int,
67
+ sm_scale: float,
68
+ return_lse: int,
69
+ ) -> torch.Tensor:
70
+ return ops.qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90(
71
+ query, key, value, output, query_scale, key_scale, value_scale,
72
+ tensor_layout, is_causal, qk_quant_gran, sm_scale, return_lse
73
+ )
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90"))
77
+ def qk_int8_sv_f8_accum_f32_fuse_v_scale_attn_inst_buf_sm90_fake_impl(
78
+ query: torch.Tensor,
79
+ key: torch.Tensor,
80
+ value: torch.Tensor,
81
+ output: torch.Tensor,
82
+ query_scale: torch.Tensor,
83
+ key_scale: torch.Tensor,
84
+ value_scale: torch.Tensor,
85
+ tensor_layout: int,
86
+ is_causal: int,
87
+ qk_quant_gran: int,
88
+ sm_scale: float,
89
+ return_lse: int,
90
+ ) -> torch.Tensor:
91
+ return qk_int8_sv_f8_accum_f32_attn_inst_buf_fake_impl(
92
+ query, key, value, output, query_scale, key_scale, tensor_layout,
93
+ is_causal, qk_quant_gran, sm_scale, return_lse
94
+ )