Skip to content

Commit 106da2f

Browse files
danielfrglijinf2
andauthored
Migrate samples (#2959)
* Migrating cuda-python samples from cuda-samples * Examples format * Consolidate test suite into cuda.core one * Drop duplicated samples and add missing content to /samples * Migrate existing cuda.core examples to /sampels * Migrate existing cuda.bindings examples to /samples * Add missing deps for samples * Cleanup * Split into cuda_bindings and cuda_core samples * Review * Fix sample runner error and waiver handling * Address code rabbit review * Fix pytest collection of cuda.core sample tests without a package. Relative imports fail when example_tests has no __init__.py; import run_samples as a top-level module instead. * fix(samples): resolve two CI failures in systemInfo and vectorAdd - systemInfo: guard get_process_name() call behind CUDA_BINDINGS_NVML_IS_COMPATIBLE to avoid NameError when NVML bindings are incompatible with the driver. - vectorAdd: replace cp.random.rand() with NumPy-generated data transferred via cp.asarray() to avoid a dependency on libcurand which is not present in the cuda-13x wheel environment. * fix(samples): waive fftSignalAnalysis when libcufft is unavailable CuPy's FFT backend requires libcufft (so.11 or so.12), which is not bundled in the cuda-13x wheel environment used in CI. Probe cupy.cuda.cufft at startup and exit with the runner waiver code (CUDA_PYTHON_SAMPLE_WAIVER_EXIT_CODE=77) so the test is reported as SKIPPED rather than FAILED. * fix(samples): declare nvidia-cufft-cu12 as explicit dependency for fftSignalAnalysis CuPy's FFT backend requires libcufft (shipped by nvidia-cufft-cu12 on PyPI). Adding it to the PEP 723 inline script block and requirements.txt lets the sample runner automatically waive the test when cuFFT is not installed, rather than crashing with an ImportError at runtime. * fix(samples): declare nvidia-cublas-cu12 as explicit dependency for numpyVsCupy cp.dot() requires libcublasLt (shipped by nvidia-cublas-cu12 on PyPI). Adding it to the PEP 723 inline script block and requirements.txt lets the sample runner automatically waive the test when cuBLAS is not installed. * fix(samples): replace cp.random.randint() with numpy in parallelHistogram cp.random requires libcurand which is not installed in the cuda-13x wheel CI environment. The random data is only used as histogram input, so generating it on CPU via numpy and uploading with cp.asarray() is equivalent and removes the curand dependency. * fix(samples): waive blurImageUnifiedMemory when ManagedMemoryResource is unsupported ManagedMemoryResource with preferred_location requires concurrent managed memory access support, which is not available on all devices (e.g. RTX 4090 in the CI environment). Catch CUDA_ERROR_NOT_SUPPORTED at runtime and exit with the runner waiver code so the test is reported as SKIPPED rather than FAILED. This mirrors the existing Windows waiver already in the sample. * fix(samples): waive blurImageUnifiedMemory when concurrent managed access is unavailable Per CUDA docs (cuMemPoolCreate): managed memory pools require all devices to have non-zero concurrentManagedAccess; otherwise CUDA_ERROR_NOT_SUPPORTED is returned. This attribute is 0 on Windows, WSL, and some Linux VM environments. Check device.properties.concurrent_managed_access before attempting to create the ManagedMemoryResource and exit with the runner waiver code when it is False, mirroring the existing Windows waiver already in the sample. * fix(samples): waive blurImageUnifiedMemory when concurrent managed access is unavailable Managed memory pools (cuMemPoolCreate) require all devices to have non-zero concurrentManagedAccess; otherwise CUDA_ERROR_NOT_SUPPORTED is returned. This attribute is 0 on Windows, WSL, and some Linux VM environments. Move the concurrent_managed_access check to just after device info is printed and simplify the message, keeping it alongside the existing Windows waiver. * fix(samples): waive ipcMemoryPool on WSL where CUDA IPC is unsupported NVIDIA WSL User Guide states that only legacy CUDA IPC APIs are supported from driver R510; the newer IPC memory pool API (cuMemPoolCreate with POSIX FD handles) is not supported on WSL2. Detect WSL by checking for 'microsoft' in /proc/sys/kernel/osrelease and return False from check_ipc_support() so the sample exits cleanly with a waiver instead of crashing with CUDA_ERROR_INVALID_VALUE. * fix(samples): waive launchConfigTuning and memoryResources when concurrent managed access is unavailable Both samples use ManagedMemoryResource which requires concurrent managed memory access (concurrentManagedAccess != 0). On WSL and Windows this attribute is 0, causing CUDA_ERROR_NOT_SUPPORTED at pool creation. Add concurrent_managed_access check after device init, consistent with the existing Windows waiver and the fix applied to blurImageUnifiedMemory. * samples/cuda_core: fix systemInfo NotFoundError when process has no CUDA context nvmlSystemGetProcessName returns NVML_ERROR_NOT_FOUND when the process has not yet established a CUDA context (i.e. no cudaMalloc or equivalent has been called). This is expected NVML behavior per the API docs. Guard the get_process_name() call with a try/except NotFoundError so the sample gracefully prints N/A instead of crashing. * address pre-commit check * samples/cuda_core: skip glInteropMipmapLod if OpenGL unavailable Catch OSError (FileNotFoundError is a subclass) when pyglet tries to load opengl32.dll on headless Windows CI runners (TCC/MCDM mode or missing display driver). Exit with EXIT_WAIVED so the test is skipped rather than failing. See: #2767 * samples/cuda_core: skip all glInterop samples if OpenGL unavailable Catch OSError (FileNotFoundError is a subclass) when pyglet tries to load opengl32.dll on headless Windows CI runners (TCC/MCDM mode or missing display driver). Exit with EXIT_WAIVED so the test is skipped rather than failing. Applies the same fix to glInteropFluid, glInteropPlasma, and glInteropFluidNumbaCudaMlir (same root cause as glInteropMipmapLod). See: #2767 * samples/cuda_core: remove duplicate EXIT_WAIVED in glInteropMipmapLod The file already defined EXIT_WAIVED at module level; the extra definition added near the imports created a duplicate that caused test_core_sample_waivers_use_negotiated_exit_code to fail (expects exactly one assignment). * samples/cuda_core: waive copyImageArraytoGPU if memory pools unsupported PinnedMemoryResource internally calls cuMemPoolCreate; on Windows with WDDM T4 (memory_pools_supported=False) this raises CUDA_ERROR_NOT_SUPPORTED. Check device.properties.memory_pools_supported early and exit with EXIT_WAIVED so the test is skipped rather than failing. * samples/cuda_core: waive streamingCopyComputeOverlap if memory pools unsupported PinnedMemoryResource internally calls cuMemGetMemPool; on Windows with TCC mode T4 (memory_pools_supported=False) this raises CUDA_ERROR_NOT_SUPPORTED. Check device.properties.memory_pools_supported early and exit with EXIT_WAIVED so the test is skipped rather than failing. * samples/cuda_core: also catch AttributeError in glInterop OpenGL waiver On Python 3.13, ctypes.windll.opengl32 wraps the underlying FileNotFoundError as AttributeError: opengl32 rather than propagating the OSError directly. Extend the except clause to (OSError, AttributeError) so the waiver fires on both Python 3.12 and 3.13 Windows CI runners. * tests/memory_ipc: clear stale buffer before flaky rerun in ChildErrorHarness When pytest-rerunfailures retries test_main on the same instance, self.buffer from the previous run may still be set while its backing DeviceMemoryResource has already been closed by the finally block. process.start() (spawn mode) pickles self.child_main which requires serializing self.__dict__, hitting the closed MR and raising: RuntimeError: DeviceMemoryResource has been closed when serializing dict item 'buffer' Fix by popping 'buffer' from self.__dict__ at the start of each test_main run so a stale closed-MR buffer never reaches the pickler. * samples/cuda_core: declare nvidia-cuda-cccl-cu12 dependency for tmaTensorMap The kernel uses <cuda/barrier> from libcudacxx (CCCL). On Windows CI with pip-installed CUDA, cuda.pathfinder cannot locate the cccl include directory because nvidia-cuda-cccl-cu12 is not installed, causing NVRTC to fail with 'cannot open source file cuda/barrier'. Add nvidia-cuda-cccl-cu12 to the PEP 723 inline dependencies and requirements.txt so the sample runner installs (or waives) it, matching the same pattern used for nvidia-cufft-cu12 in fftSignalAnalysis. * TST: mark test_set_stats_level as thread_unsafe cuFile stats level is process-global state (a C library global variable inside libcufile). Running test_set_stats_level concurrently with test_stats_start_stop (which also calls set_stats_level(1)) can cause a race condition where get_stats_level() returns the value set by the other test, failing the assertion. All other cuFile stats tests (test_stats_start_stop, test_get_stats_l1/l2/l3) were already marked thread_unsafe; this commit fixes the oversight for test_set_stats_level. * samples/cuda_core: waive greenContext on CUDA 13.1+ (issue #2765) SMResource.split(dry_run=True) fails with cuDevSmResourceSplit when result=NULL and smCount is non-zero. This causes the auto SM-split probe in greenContext to fail on CUDA 13.1+. Waive the sample on affected drivers until the cuda.core bug is fixed. * docs/cuda_core: fix broken links in 0.3.1 release notes cuda_graphs.py and memory_ops.py were migrated from cuda_core/examples/ to samples/cuda_core/ in this PR. Update the 0.3.1 release notes to use the :sample-file: role pointing to the new locations so lychee link checks pass. * fix format * samples/cuda_core: migrate persistent program cache * address pre-commit * fix(samples): restore CuPy RNG in vectorAdd and parallelHistogram Revert the cp.asarray(np.random...) CPU-generate-then-transfer workaround back to cp.random.rand()/cp.random.randint() in both samples, per review feedback that the CPU fallback deviated from the original CuPy-based content and taught users an unnecessary host-to-device transfer. cp.random dlopens libcurand at runtime, which the cuda_core CI test environment does not currently install. Rather than widening the shared test-cu12/test-cu13 dependency groups, declare nvidia-curand explicitly in each sample's PEP 723 script header and requirements.txt so the shared sample runner's dependency gate (missing_dependencies) waives the sample cleanly when curand is unavailable instead of the process crashing on dlopen. * add curand as dependency to cuda core run-tests * fix(samples): use CUDA 13-native cufft/cublas instead of -cu12 packages Replace nvidia-cufft-cu12/nvidia-cublas-cu12 with nvidia-cufft/nvidia-cublas in fftSignalAnalysis and numpyVsCupy, per review feedback not to mix CUDA 12 and CUDA 13 packages. Follow-up on switching to cupy-cuda13x[ctk] tracked in #2961. * chore: refresh pixi lock files Run pixi update + pixi lock --check on pixi.toml, cuda_bindings, cuda_core, cuda_pathfinder manifests to address lockfile freshness check in CI. Refs #2959 * chore: refresh benchmarks/cuda_core pixi lock * chore: apply pre-commit ruff format to sample READMEs --------- Co-authored-by: Jinfeng <[email protected]>
1 parent a7ec832 commit 106da2f

251 files changed

Lines changed: 31366 additions & 7374 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/labeler.yml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77

88
cuda.bindings:
99
- changed-files:
10-
- any-glob-to-any-file: 'cuda_bindings/**'
10+
- any-glob-to-any-file:
11+
- 'cuda_bindings/**'
12+
- 'samples/cuda_bindings/**'
1113

1214
cuda.core:
1315
- changed-files:
14-
- any-glob-to-any-file: 'cuda_core/**'
16+
- any-glob-to-any-file:
17+
- 'cuda_core/**'
18+
- 'samples/cuda_core/**'
1519

1620
cuda.pathfinder:
1721
- changed-files:

‎.spdx-ignore‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ LICENSE*
66
.gitattributes
77
.gitignore
88
requirements*.txt
9-
cuda_bindings/examples/*
9+
10+
# Samples are synced to NVIDIA/cuda-samples on release and carry either the
11+
# upstream verbose BSD-style copyright header or an SPDX identifier.
12+
samples/**/*.py
1013

1114
# Vendored
1215
cuda_core/cuda/core/_include/dlpack.h

‎benchmarks/cuda_core/pixi.lock‎

Lines changed: 67 additions & 62 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ci/tools/run-tests‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ elif [[ "${test_module}" == "core" || "${test_module}" == nightly-* ]]; then
129129
# Constrain cuda-toolkit to the requested CTK version to avoid
130130
# pip pulling in a newer nvidia-cuda-runtime that conflicts with it.
131131
pip install "${CORE_WHL[@]}" --group "test-cu${TEST_CUDA_MAJOR}" "${TEST_FT_GROUP[@]}" "cuda-toolkit==${TEST_CUDA_MAJOR_MINOR}.*"
132+
# Optional deps needed by some cuda.core samples exercised in this suite.
133+
# CuPy already comes from the
134+
# test-cuXX group; install the rest best-effort so those samples run
135+
# instead of being waived. Samples with heavier/unavailable deps stay waived.
136+
echo "Installing optional sample deps (nvtx, pillow)"
137+
pip install nvtx pillow || echo "Warning: optional sample deps install failed; affected samples will be waived"
138+
# curand: some samples (vectorAdd, parallelHistogram) call cp.random,
139+
# which dlopens libcurand at runtime.
140+
echo "Installing optional sample deps (curand)"
141+
pip install "cuda-toolkit[curand]==${TEST_CUDA_MAJOR_MINOR}.*" || echo "Warning: curand install failed; affected samples will be waived"
132142
echo "Installed packages before core tests:"
133143
pip list
134144
echo "Running core tests"

‎cuda_bindings/AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ subpackage in the `cuda-python` monorepo.
4343
- **Cython tests**:
4444
- build: `tests/cython/build_tests.sh` (or platform equivalent)
4545
- run: `pytest tests/cython/`
46-
- **Examples**: example coverage is pytest-based under `examples/`.
46+
- **Samples**: sample coverage is pytest-based under `../samples/cuda_bindings/`.
4747
- **Benchmarks**: run with `pytest --benchmark-only benchmarks/` when needed.
4848

4949
The `legacy_tests` subdirectory tests the old pre-v2 APIs of `driver`, `runtime`

‎cuda_bindings/DESCRIPTION.rst‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ cuda-bindings: Low-level CUDA interfaces
1313

1414
* `Repository <https://github.com/NVIDIA/cuda-python/tree/main/cuda_bindings>`_
1515
* `Documentation <https://nvidia.github.io/cuda-python/cuda-bindings/>`_
16-
* `Examples <https://github.com/NVIDIA/cuda-python/tree/main/cuda_bindings/examples>`_
16+
* `Examples <https://github.com/NVIDIA/cuda-python/tree/main/samples/cuda_bindings>`_
1717
* `Issue tracker <https://github.com/NVIDIA/cuda-python/issues/>`_
1818

1919
For the installation instruction, please refer to the `Installation <https://nvidia.github.io/cuda-python/cuda-bindings/latest/install.html>`_ page.

‎cuda_bindings/cuda/bindings/_example_helpers/__init__.py‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

‎cuda_bindings/cuda/bindings/_example_helpers/common.py‎

Lines changed: 0 additions & 90 deletions
This file was deleted.

‎cuda_bindings/cuda/bindings/_example_helpers/helper_cuda.py‎

Lines changed: 0 additions & 48 deletions
This file was deleted.

‎cuda_bindings/cuda/bindings/_example_helpers/helper_string.py‎

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)