Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build-wheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ jobs:
run: |
pip install ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}/*.whl --group ./cuda_bindings/pyproject.toml:test
pushd ${{ env.CUDA_BINDINGS_CYTHON_TESTS_DIR }}
bash build_tests.sh
python test_cython.py
popd

- name: Upload cuda.bindings Cython tests
Expand All @@ -364,7 +364,7 @@ jobs:
run: |
pip install ${{ env.CUDA_CORE_ARTIFACTS_DIR }}/"cu${BUILD_CUDA_MAJOR}"/*.whl --group ./cuda_core/pyproject.toml:test
pushd ${{ env.CUDA_CORE_CYTHON_TESTS_DIR }}
bash build_tests.sh
python test_cython.py
popd

- name: Upload cuda.core Cython tests
Expand Down
3 changes: 0 additions & 3 deletions cuda_bindings/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ subpackage in the `cuda-python` monorepo.
## Testing expectations

- **Primary tests**: `pytest tests/`
- **Cython tests**:
- build: `tests/cython/build_tests.sh` (or platform equivalent)
- run: `pytest tests/cython/`
- **Examples**: example coverage is pytest-based under `examples/`.
- **Benchmarks**: run with `pytest --benchmark-only benchmarks/` when needed.
- **Orchestrated run**: from repo root, `scripts/run_tests.sh bindings`.
Expand Down
11 changes: 0 additions & 11 deletions cuda_bindings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,6 @@ To run these tests:
* `python -m pytest tests/` against editable installations
* `pytest tests/` against installed packages

### Cython Unit Tests

Cython tests are located in `tests/cython` and need to be built. These builds have the same CUDA Toolkit header requirements as [Installing from Source](https://nvidia.github.io/cuda-python/cuda-bindings/latest/install.html#requirements) where the major.minor version must match `cuda.bindings`. To build them:

1. Setup environment variable `CUDA_PATH` (or `CUDA_HOME`) with the path to the CUDA Toolkit installation. Note: If both are set, `CUDA_PATH` takes precedence.
2. Run `build_tests` script located in `test/cython` appropriate to your platform. This will both cythonize the tests and build them.

To run these tests:
* `python -m pytest tests/cython/` against editable installations
* `pytest tests/cython/` against installed packages

### Samples

Various [CUDA Samples](https://github.com/NVIDIA/cuda-samples/tree/master) that were rewritten using CUDA Python are located in `examples`.
Expand Down
7 changes: 0 additions & 7 deletions cuda_bindings/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,13 @@ libnvfatbin = "*"
[package.target.linux.run-dependencies]
libcufile = "*"

[target.linux.tasks.build-cython-tests]
cmd = ["$PIXI_PROJECT_ROOT/tests/cython/build_tests.sh"]

[target.win-64.tasks.build-cython-tests]
cmd = ["$PIXI_PROJECT_ROOT/tests/cython/build_tests.bat"]

[target.linux.tasks.test]
cmd = [
"pytest",
"$PIXI_PROJECT_ROOT",
"--override-ini",
"norecursedirs=examples", # include cython tests (ignore by default config)
]
depends-on = [{ task = "build-cython-tests" }]

[target.linux.tasks.build-docs]
cmd = [
Expand Down
10 changes: 0 additions & 10 deletions cuda_bindings/tests/cython/build_tests.bat

This file was deleted.

18 changes: 0 additions & 18 deletions cuda_bindings/tests/cython/build_tests.sh

This file was deleted.

127 changes: 103 additions & 24 deletions cuda_bindings/tests/cython/test_cython.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,115 @@
# SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE

import functools
import importlib
import sys
import os
from pathlib import Path

import pytest
from Cython.Build import cythonize
from setuptools import Extension
from setuptools.dist import Distribution

def py_func(func):
"""
Wraps func in a plain Python function.
"""
TESTS_DIR = Path(__file__).resolve().parent
CYTHON_TEST_MODULES = ["test_ccuda", "test_ccudart", "test_interoperability_cython"]

@functools.wraps(func)
def wrapped(*args, **kwargs):
return func(*args, **kwargs)

return wrapped
def _get_cuda_include_dir():
cuda_home = os.environ.get("CUDA_PATH") or os.environ.get("CUDA_HOME")
if cuda_home:
return Path(cuda_home) / "include"
return None


def build_cython_test_modules():
include_dirs = []
cuda_include_dir = _get_cuda_include_dir()
if cuda_include_dir:
include_dirs.append(str(cuda_include_dir))

extensions = [
Extension(
name=module_name,
sources=[str(TESTS_DIR / f"{module_name}.pyx")],
include_dirs=include_dirs,
)
for module_name in CYTHON_TEST_MODULES
]

cython_test_modules = ["test_ccuda", "test_ccudart", "test_interoperability_cython"]
ext_modules = cythonize(
extensions,
compiler_directives={"language_level": "3", "freethreading_compatible": True},
nthreads=1,
)

distribution = Distribution(
{
"name": "cuda-bindings-cython-tests",
"ext_modules": ext_modules,
}
)
build_ext = distribution.get_command_obj("build_ext")
build_ext.inplace = True
build_ext.build_temp = str(TESTS_DIR / "build" / "temp")

for mod in cython_test_modules:
# Ensure in-place extension outputs are written into tests/cython.
cwd = os.getcwd()
os.chdir(TESTS_DIR)
try:
# For each callable in `mod` with name `test_*`,
# wrap the callable in a plain Python function
# and set the result as an attribute of this module.
mod = importlib.import_module(mod)
for name in dir(mod):
item = getattr(mod, name)
if callable(item) and name.startswith("test_"):
item = py_func(item)
setattr(sys.modules[__name__], name, item)
except ImportError:
raise
distribution.run_command("build_ext")
finally:
os.chdir(cwd)


def _import_cython_test_modules():
imported_modules = {}
build_attempted = False

for module_name in CYTHON_TEST_MODULES:
try:
imported_modules[module_name] = importlib.import_module(module_name)
except ImportError:
if not build_attempted:
build_cython_test_modules()
importlib.invalidate_caches()
build_attempted = True

imported_modules[module_name] = importlib.import_module(module_name)

return imported_modules


@pytest.fixture(scope="session")
def cython_test_modules():
return _import_cython_test_modules()


def _make_wrapped_test(module_name, test_name):
def wrapped(cython_test_modules):
test_func = getattr(cython_test_modules[module_name], test_name)
return test_func()

wrapped.__name__ = test_name
wrapped.__module__ = __name__
return wrapped


registered_tests = set()
for module_name, module in _import_cython_test_modules().items():
for test_name in dir(module):
item = getattr(module, test_name)
if not callable(item) or not test_name.startswith("test_"):
continue

if test_name in registered_tests:
raise RuntimeError(f"duplicate cython test name discovered: {test_name}")
registered_tests.add(test_name)
globals()[test_name] = _make_wrapped_test(module_name, test_name)


def main():
build_cython_test_modules()


if __name__ == "__main__":
main()
3 changes: 0 additions & 3 deletions cuda_core/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ This file describes `cuda_core`, the high-level Pythonic CUDA subpackage in the
## Testing expectations

- **Primary tests**: `pytest tests/`
- **Cython tests**:
- build: `tests/cython/build_tests.sh` (or platform equivalent)
- run: `pytest tests/cython/`
- **Examples**: validate affected examples in `examples/` when changing user
workflows or public APIs.
- **Orchestrated run**: from repo root, `scripts/run_tests.sh core`.
Expand Down
11 changes: 0 additions & 11 deletions cuda_core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,3 @@ Alternatively, from the repository root you can use a simple script:
* `./scripts/run_tests.sh core` to run only `cuda_core` tests
* `./scripts/run_tests.sh` to run all package tests (pathfinder → bindings → core)
* `./scripts/run_tests.sh smoke` to run meta-level smoke tests under `tests/integration`

### Cython Unit Tests

Cython tests are located in `tests/cython` and need to be built. These builds have the same CUDA Toolkit header requirements as [those of cuda.bindings](https://nvidia.github.io/cuda-python/cuda-bindings/latest/install.html#requirements) where the major.minor version must match `cuda.bindings`. To build them:

1. Set up environment variable `CUDA_PATH` (or `CUDA_HOME`) with the path to the CUDA Toolkit installation. Note: If both are set, `CUDA_PATH` takes precedence.
2. Run `build_tests` script located in `tests/cython` appropriate to your platform. This will both cythonize the tests and build them.

To run these tests:
* `python -m pytest tests/cython/` with editable installations
* `pytest tests/cython/` with installed packages
4 changes: 2 additions & 2 deletions cuda_core/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ cuda-bindings = "*"
cuda-pathfinder = "*"

[target.linux.tasks.build-cython-tests]
cmd = ["$PIXI_PROJECT_ROOT/tests/cython/build_tests.sh"]
cmd = ["python", "$PIXI_PROJECT_ROOT/tests/cython/test_cython.py"]

[target.linux.tasks.docs-build]
cmd = ["$PIXI_PROJECT_ROOT/docs/build_docs.sh"]
Expand All @@ -203,7 +203,7 @@ env = { SPHINXOPTS = "-v -j 1 -d build/.doctrees" }
default-environment = "docs"

[target.win-64.tasks.build-cython-tests]
cmd = ["$PIXI_PROJECT_ROOT/tests/cython/build_tests.bat"]
cmd = ["python", "$PIXI_PROJECT_ROOT/tests/cython/test_cython.py"]

[target.linux.tasks.test]
cmd = [
Expand Down
18 changes: 0 additions & 18 deletions cuda_core/tests/cython/build_tests.sh

This file was deleted.

Loading
Loading