-
Notifications
You must be signed in to change notification settings - Fork 578
Make to_sparse_semi_structured_cutlass_sm9x ABI stable #3727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 28 commits
7282131
6904b15
91d707e
19300fa
864de15
f75c166
c8bb8e5
1c86c1b
92f81f6
22ea328
950e5bc
56b67ff
b9aeb0e
840860d
9c8cf49
a6cd36d
e5e8cff
232e364
e47b77d
0c155e6
e7441f9
9fa4849
cfb35fe
b6d8f09
3a88f76
4422455
4e90861
80ac545
0dd28f8
60850d2
ef5f9ee
4611c8e
68faa64
66e8ab8
a5c3ff1
82a9537
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| import json | ||
| import os | ||
| import pickle | ||
| import re | ||
| import subprocess | ||
| import sys | ||
| import time | ||
|
|
@@ -149,6 +150,38 @@ def use_debug_mode(): | |
| ) | ||
|
|
||
|
|
||
| # Check if torch version is at least 2.10.0 (for stable ABI support) | ||
| # util copied from torchao/utils.py | ||
| def _parse_version(version_string): | ||
| """ | ||
| Parse version string representing pre-release with -1 | ||
|
|
||
| Examples: "2.5.0.dev20240708+cu121" -> [2, 5, -1], "2.5.0" -> [2, 5, 0] | ||
| """ | ||
| # Check for pre-release indicators | ||
| is_prerelease = bool(re.search(r"(git|dev)", version_string)) | ||
| match = re.match(r"(\d+)\.(\d+)\.(\d+)", version_string) | ||
| if match: | ||
| major, minor, patch = map(int, match.groups()) | ||
| if is_prerelease: | ||
| patch = -1 | ||
| return [major, minor, patch] | ||
| else: | ||
| raise ValueError(f"Invalid version string format: {version_string}") | ||
|
|
||
|
|
||
| def _is_fbcode(): | ||
| return not hasattr(torch.version, "git_version") | ||
|
|
||
|
|
||
| def _torch_version_at_least(min_version): | ||
| if _is_fbcode(): | ||
| return True | ||
|
|
||
| # Parser for local identifiers | ||
| return _parse_version(torch.__version__) >= _parse_version(min_version) | ||
|
|
||
|
|
||
| def detect_hipify_v2(): | ||
| try: | ||
| from torch.utils.hipify import __version__ | ||
|
|
@@ -321,12 +354,14 @@ def get_cutlass_build_flags(): | |
| """ | ||
| # Try nvcc then torch version | ||
| cuda_version = get_cuda_version_from_nvcc() or torch.version.cuda | ||
| print("cuda version:", cuda_version) | ||
|
|
||
| try: | ||
| if not cuda_version: | ||
| raise ValueError("No CUDA version found") | ||
|
|
||
| major, minor = map(int, cuda_version.split(".")[:2]) | ||
| print("major, minor", major, minor) | ||
| build_sm90a = major > 12 or (major == 12 and minor >= 6) | ||
| build_sm100a = major > 12 or (major == 12 and minor >= 8) | ||
|
|
||
|
|
@@ -443,6 +478,7 @@ def get_extensions(): | |
| print("If you'd like to compile ROCm extensions locally please install ROCm") | ||
|
|
||
| use_cuda = torch.version.cuda and CUDA_HOME is not None | ||
| print("use cuda:", use_cuda) | ||
|
jerryzh168 marked this conversation as resolved.
Outdated
|
||
| use_rocm = torch.version.hip and ROCM_HOME is not None | ||
| extension = CUDAExtension if (use_cuda or use_rocm) else CppExtension | ||
|
|
||
|
|
@@ -621,6 +657,7 @@ def get_extensions(): | |
|
|
||
| use_cutlass = False | ||
| cutlass_90a_sources = None | ||
| cutlass_90a_stable_sources = None | ||
| build_for_sm90a = False | ||
| build_for_sm100a = False | ||
| if use_cuda and not IS_WINDOWS: | ||
|
|
@@ -632,6 +669,7 @@ def get_extensions(): | |
| ) | ||
| cutlass_extensions_include_dir = os.path.join(cwd, extensions_cuda_dir) | ||
| if use_cutlass: | ||
| print("use_cutlass, adding extra compile args") | ||
| extra_compile_args["nvcc"].extend( | ||
| [ | ||
| "-DTORCHAO_USE_CUTLASS", | ||
|
|
@@ -659,11 +697,6 @@ def get_extensions(): | |
| "rowwise_scaled_linear_sparse_cutlass", | ||
| "rowwise_scaled_linear_sparse_cutlass_f8f8.cu", | ||
| ), | ||
| os.path.join( | ||
| extensions_cuda_dir, | ||
| "to_sparse_semi_structured_cutlass_sm9x", | ||
| "to_sparse_semi_structured_cutlass_sm9x_f8.cu", | ||
| ), | ||
|
jerryzh168 marked this conversation as resolved.
|
||
| os.path.join(extensions_cuda_dir, "activation24", "sparsify24.cu"), | ||
| os.path.join(extensions_cuda_dir, "activation24", "sparse_gemm.cu"), | ||
| ] | ||
|
|
@@ -675,8 +708,19 @@ def get_extensions(): | |
| "rowwise_scaled_linear_sparse_cutlass_" + dtypes + ".cu", | ||
| ) | ||
| ) | ||
|
|
||
| # Define sm90a sources that use stable ABI (requires torch >= 2.10.0) | ||
| cutlass_90a_stable_sources = [ | ||
| os.path.join( | ||
| extensions_cuda_dir, | ||
| "to_sparse_semi_structured_cutlass_sm9x", | ||
| "to_sparse_semi_structured_cutlass_sm9x_f8.cu", | ||
| ), | ||
| ] | ||
|
|
||
| # Always remove sm90a sources from main sources | ||
| sources = [s for s in sources if s not in cutlass_90a_sources] | ||
| sources = [s for s in sources if s not in cutlass_90a_stable_sources] | ||
|
|
||
| else: | ||
| # Remove CUTLASS-based kernels from the sources list. An | ||
|
|
@@ -758,6 +802,60 @@ def get_extensions(): | |
| ) | ||
| ) | ||
|
|
||
| # Build stable ABI sm90a sources separately with stable ABI flags | ||
| # only after torch 2.10 so ABI related API are available | ||
|
|
||
| print(f"nvcc version: {get_cuda_version_from_nvcc()}") | ||
| print(f"torch.version.cuda: {torch.version.cuda}") | ||
| print(f"build_for_sm90a: {build_for_sm90a}") | ||
| print("cutlass_90a_stable_sources:", cutlass_90a_stable_sources) | ||
| print("torch_version_at_least_2_10:", _torch_version_at_least("2.10.0")) | ||
| if ( | ||
| _torch_version_at_least("2.10.0") | ||
| and cutlass_90a_stable_sources is not None | ||
| and len(cutlass_90a_stable_sources) > 0 | ||
| and build_for_sm90a | ||
| ): | ||
| print("building cutlass 90a stable ABI extension") | ||
| cutlass_90a_stable_extra_compile_args = copy.deepcopy(extra_compile_args) | ||
| # Only use sm90a architecture for these sources, ignoring other flags | ||
| cutlass_90a_stable_extra_compile_args["nvcc"].extend( | ||
| [ | ||
| "-gencode=arch=compute_90a,code=sm_90a", | ||
| "-DUSE_CUDA", | ||
| # define TORCH_TARGET_VERSION with min version 2.10 to expose only the | ||
| # stable API subset from torch | ||
| "-DTORCH_TARGET_VERSION=0x020a000000000000", | ||
| ] | ||
| ) | ||
| print( | ||
| "cutlass_90a_stable_extra_compile_args nvcc:", | ||
| cutlass_90a_stable_extra_compile_args["nvcc"], | ||
| ) | ||
| # Add -DUSE_CUDA flag for ABI stable headers that need it | ||
| cutlass_90a_stable_extra_compile_args["cxx"].extend( | ||
| [ | ||
| "-DUSE_CUDA", | ||
| # define TORCH_TARGET_VERSION with min version 2.10 to expose only the | ||
| # stable API subset from torch | ||
| "-DTORCH_TARGET_VERSION=0x020a000000000000", | ||
| ] | ||
| ) | ||
|
|
||
| print( | ||
| "cutlass_90a_stable_extra_compile_args cxx:", | ||
| cutlass_90a_stable_extra_compile_args["cxx"], | ||
| ) | ||
| ext_modules.append( | ||
| extension( | ||
| "torchao._C_cutlass_90a_stable", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you maintain an unstable version for torch 2.10 minus? It might be wise to enable users to build these kernels on an older torch still?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is just a temporary thing to keep this PR and #3725 separate. After both PRs are landed there will be a single
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah and we'll drop support for 2.10 minus afterwards |
||
| cutlass_90a_stable_sources, | ||
| py_limited_api=True, | ||
| extra_compile_args=cutlass_90a_stable_extra_compile_args, | ||
| extra_link_args=extra_link_args, | ||
| ) | ||
| ) | ||
|
|
||
| # Build CMakeLists from /torchao/csrc/cpu - additional options become available : TORCHAO_BUILD_CPU_AARCH64, TORCHAO_BUILD_KLEIDIAI, TORCHAO_BUILD_MPS_OPS, TORCHAO_PARALLEL_BACKEND | ||
| if build_macos_arm_auto or os.getenv("BUILD_TORCHAO_EXPERIMENTAL") == "1": | ||
| build_options = BuildOptions() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not import the util
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the code that is installing torchao, so it is assuming torchao is not installed yet, you mean just import the file? is that too confusing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to keep setup.py as simple as possible. Importing torchao/utils.py might have side effects outside the scope of this file