-
Notifications
You must be signed in to change notification settings - Fork 190
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
[FEA]: Introduce Python module with CCCL headers #3201
Changes from 76 commits
daab580
ef9d5f4
bc116dc
2913ae0
7dbb82b
0703901
fc0e543
2e64345
82467cd
f13a96b
9ed6036
c9a4d96
df943c0
40c8389
e3c7867
acbd477
06f575f
e747768
499b191
62ce2d3
65c5a15
bffece6
585447c
55c4311
1f3a029
61637d6
4a0cca1
7dd3d16
efab5be
9fde3d1
bda5d51
4e9720d
c1aea17
d18d699
9be94c6
c2a9f24
c89d620
1b3599b
796b741
9a63830
477fe3b
246ddf7
e1fd264
87b46ca
9597dad
eddc6cc
bcf0de8
c763301
71fd243
79057cf
ccaf8a5
46a8329
a07222b
2d3c2ed
b65f510
47893d9
324ac4f
3026c81
b0d422a
e904846
c1f571d
792e4ba
695cc9b
ea33a21
d439f79
9a7b498
5d33bb0
be34834
b2b2b5b
9f83b0d
4807a79
d97a68a
ec206fd
1f4d210
f94bbb1
b48f866
917147f
ebdbb22
12dbf29
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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cuda/cccl/include | ||
*egg-info |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Note | ||
|
||
This package is currently FOR INTERNAL USE ONLY and not meant to be used/installed explicitly. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
from cuda.cccl._version import __version__ | ||
|
||
shwina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
__all__ = ["__version__"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
# This file is generated by ci/update_version.sh | ||
# Do not edit this file manually. | ||
__version__ = "2.8.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
import os | ||
import shutil | ||
from dataclasses import dataclass | ||
from functools import lru_cache | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
|
||
def _get_cuda_path() -> Optional[Path]: | ||
cuda_path = os.environ.get("CUDA_PATH") | ||
if cuda_path: | ||
cuda_path = Path(cuda_path) | ||
if cuda_path.exists(): | ||
return cuda_path | ||
|
||
nvcc_path = shutil.which("nvcc") | ||
if nvcc_path: | ||
return Path(nvcc_path).parent.parent | ||
|
||
default_path = Path("/usr/local/cuda") | ||
if default_path.exists(): | ||
return default_path | ||
|
||
return None | ||
|
||
|
||
@dataclass | ||
class IncludePaths: | ||
cuda: Optional[Path] | ||
libcudacxx: Optional[Path] | ||
cub: Optional[Path] | ||
thrust: Optional[Path] | ||
|
||
def as_tuple(self): | ||
# Note: higher-level ... lower-level order: | ||
return (self.thrust, self.cub, self.libcudacxx, self.cuda) | ||
|
||
|
||
@lru_cache() | ||
def get_include_paths() -> IncludePaths: | ||
# TODO: once docs env supports Python >= 3.9, we | ||
# can move this to a module-level import. | ||
from importlib.resources import as_file, files | ||
|
||
cuda_incl = None | ||
cuda_path = _get_cuda_path() | ||
if cuda_path is not None: | ||
cuda_incl = cuda_path / "include" | ||
|
||
with as_file(files("cuda.cccl.include")) as f: | ||
cccl_incl = Path(f) | ||
assert cccl_incl.exists() | ||
|
||
return IncludePaths( | ||
cuda=cuda_incl, | ||
libcudacxx=cccl_incl / "libcudacxx", | ||
cub=cccl_incl, | ||
thrust=cccl_incl, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
[build-system] | ||
requires = ["setuptools>=61.0.0"] | ||
build-backend = "setuptools.build_meta" | ||
|
||
[project] | ||
name = "cuda-cccl" | ||
description = "Experimental Package with CCCL headers to support JIT compilation" | ||
authors = [{ name = "NVIDIA Corporation" }] | ||
classifiers = [ | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Environment :: GPU :: NVIDIA CUDA", | ||
"License :: OSI Approved :: Apache Software License", | ||
] | ||
requires-python = ">=3.9" | ||
dynamic = ["version", "readme"] | ||
|
||
[project.urls] | ||
Homepage = "https://github.com/NVIDIA/cccl" | ||
|
||
[tool.setuptools.dynamic] | ||
version = { attr = "cuda.cccl._version.__version__" } | ||
readme = { file = ["README.md"], content-type = "text/markdown" } | ||
|
||
[tool.setuptools.package-data] | ||
cuda = ["cccl/include/**/*"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
import shutil | ||
from pathlib import Path | ||
|
||
from setuptools import setup | ||
from setuptools.command.build_py import build_py | ||
|
||
PROJECT_PATH = Path(__file__).resolve().parent | ||
CCCL_PATH = PROJECT_PATH.parents[1] | ||
|
||
|
||
class CustomBuildPy(build_py): | ||
"""Copy CCCL headers BEFORE super().run() | ||
|
||
Note that the CCCL headers cannot be referenced directly: | ||
setuptools (and pyproject.toml) does not support relative paths that | ||
reference files outside the package directory (like ../../). | ||
This is a restriction designed to avoid inadvertently packaging files | ||
that are outside the source tree. | ||
""" | ||
|
||
def run(self): | ||
cccl_headers = [ | ||
("cub", "cub"), | ||
("libcudacxx", "include"), | ||
("thrust", "thrust"), | ||
] | ||
|
||
inc_path = PROJECT_PATH / "cuda" / "cccl" / "include" | ||
inc_path.mkdir(parents=True, exist_ok=True) | ||
|
||
for proj_dir, header_dir in cccl_headers: | ||
src_path = CCCL_PATH / proj_dir / header_dir | ||
dst_path = inc_path / proj_dir | ||
if dst_path.exists(): | ||
shutil.rmtree(dst_path) | ||
shutil.copytree(src_path, dst_path) | ||
|
||
init_py_path = inc_path / "__init__.py" | ||
init_py_path.write_text("# Intentionally empty.\n") | ||
|
||
super().run() | ||
|
||
|
||
setup( | ||
license_files=["../../LICENSE"], | ||
cmdclass={"build_py": CustomBuildPy}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
cuda/_include | ||
env | ||
*egg-info |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,9 +3,6 @@ | |
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
import functools | ||
import importlib.resources as pkg_resources | ||
import os | ||
import shutil | ||
|
||
from cuda.bindings import nvrtc | ||
from cuda.cooperative.experimental._caching import disk_cache | ||
|
@@ -20,22 +17,6 @@ def CHECK_NVRTC(err, prog): | |
raise RuntimeError(f"NVRTC error: {log.decode('ascii')}") | ||
|
||
|
||
def get_cuda_path(): | ||
cuda_path = os.environ.get("CUDA_PATH", "") | ||
if os.path.exists(cuda_path): | ||
return cuda_path | ||
|
||
nvcc_path = shutil.which("nvcc") | ||
if nvcc_path is not None: | ||
return os.path.dirname(os.path.dirname(nvcc_path)) | ||
|
||
default_path = "/usr/local/cuda" | ||
if os.path.exists(default_path): | ||
return default_path | ||
|
||
return None | ||
|
||
|
||
# cpp is the C++ source code | ||
# cc = 800 for Ampere, 900 Hopper, etc | ||
# rdc is true or false | ||
|
@@ -47,24 +28,15 @@ def compile_impl(cpp, cc, rdc, code, nvrtc_path, nvrtc_version): | |
check_in("rdc", rdc, [True, False]) | ||
check_in("code", code, ["lto", "ptx"]) | ||
|
||
with pkg_resources.path("cuda", "_include") as include_path: | ||
# Using `.parent` for compatibility with pip install --editable: | ||
include_path = pkg_resources.files("cuda.cooperative").parent.joinpath( | ||
"_include" | ||
) | ||
cub_path = include_path | ||
thrust_path = include_path | ||
libcudacxx_path = os.path.join(include_path, "libcudacxx") | ||
cuda_include_path = os.path.join(get_cuda_path(), "include") | ||
|
||
opts = [ | ||
b"--std=c++17", | ||
bytes(f"--include-path={cub_path}", encoding="ascii"), | ||
bytes(f"--include-path={thrust_path}", encoding="ascii"), | ||
bytes(f"--include-path={libcudacxx_path}", encoding="ascii"), | ||
bytes(f"--include-path={cuda_include_path}", encoding="ascii"), | ||
bytes(f"--gpu-architecture=compute_{cc}", encoding="ascii"), | ||
] | ||
opts = [b"--std=c++17"] | ||
|
||
# TODO: move this to a module-level import (after docs env modernization). | ||
from cuda.cccl.include_paths import get_include_paths | ||
|
||
for path in get_include_paths().as_tuple(): | ||
if path: | ||
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 check should be moved to 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 it's better to keep the
... it's safer. The Possibly, in the future some of the paths will be I expect the runtime overhead (the price we pay for the flexibility) to be unmeasurable, especially because this function is cached, but even without caching. However, I changed it to |
||
opts += [f"--include-path={path}".encode("ascii")] | ||
opts += [f"--gpu-architecture=compute_{cc}".encode("ascii")] | ||
if rdc: | ||
opts += [b"--relocatable-device-code=true"] | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,41 @@ | ||
# Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
[build-system] | ||
requires = ["packaging", "setuptools>=61.0.0", "wheel"] | ||
requires = ["setuptools>=61.0.0"] | ||
build-backend = "setuptools.build_meta" | ||
|
||
[project] | ||
name = "cuda-cooperative" | ||
description = "Experimental Core Library for CUDA Python" | ||
authors = [{ name = "NVIDIA Corporation" }] | ||
classifiers = [ | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Environment :: GPU :: NVIDIA CUDA", | ||
"License :: OSI Approved :: Apache Software License", | ||
] | ||
requires-python = ">=3.9" | ||
dependencies = [ | ||
"cuda-cccl", | ||
"numpy", | ||
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 don't have a good way to declare version constraint for cuda-cccl statically, I suspect we will need to move |
||
"numba>=0.60.0", | ||
"pynvjitlink-cu12>=0.2.4", | ||
"cuda-python", | ||
"jinja2", | ||
leofang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
] | ||
dynamic = ["version", "readme"] | ||
|
||
leofang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[project.optional-dependencies] | ||
test = ["pytest", "pytest-xdist"] | ||
|
||
[project.urls] | ||
Homepage = "https://developer.nvidia.com/" | ||
|
||
[tool.setuptools.dynamic] | ||
version = { attr = "cuda.cooperative._version.__version__" } | ||
readme = { file = ["README.md"], content-type = "text/markdown" } | ||
|
||
[tool.ruff] | ||
extend = "../../pyproject.toml" | ||
|
||
|
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.
Q: Is it possible that we consolidate
.gitignore
files at the root directory and not have independent ones per sub dir...?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 created #3212 to look into this later.