Skip to content

Add PEP723 metadata to cuda_core examples#1799

Closed
mdboom wants to merge 3 commits intoNVIDIA:mainfrom
mdboom:examples-pep723
Closed

Add PEP723 metadata to cuda_core examples#1799
mdboom wants to merge 3 commits intoNVIDIA:mainfrom
mdboom:examples-pep723

Conversation

@mdboom
Copy link
Contributor

@mdboom mdboom commented Mar 20, 2026

Partially addresses #1796.

This makes it possible for a user to download an example in isolation and run it with uv run or pipx run without creating an environment and explicitly installing the dependencies.

Unfortunately we can't do this for cuda_bindings examples as they are not standalone like this. See #1796 for details.

@mdboom mdboom requested review from Copilot and rparolin March 20, 2026 16:06
@mdboom mdboom self-assigned this Mar 20, 2026
@mdboom mdboom added cuda.core Everything related to the cuda.core module example Improvements or additions to code examples labels Mar 20, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds PEP 723 script metadata blocks to cuda_core Python examples and introduces CI validation to ensure those metadata dependencies can be resolved/run via uv run.

Changes:

  • Embedded PEP 723 dependency metadata into multiple cuda_core/examples/*.py scripts.
  • Added a CI utility script to run examples via uv run and validate PEP 723 metadata.
  • Updated the Linux wheel test workflow to install uv and run the new validation step.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
cuda_core/examples/vector_add.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/tma_tensor_map.py Adds PEP 723 dependency metadata (includes a minimum cuda_core version).
cuda_core/examples/thread_block_cluster.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/strided_memory_view_gpu.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/strided_memory_view_cpu.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/simple_multi_gpu_example.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/show_device_properties.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/saxpy.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/pytorch_example.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/memory_ops.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/jit_lto_fractal.py Adds PEP 723 dependency metadata; updates copyright year range.
cuda_core/examples/gl_interop_plasma.py Replaces manual “pip install” note with PEP 723 dependency metadata.
cuda_core/examples/cuda_graphs.py Adds PEP 723 dependency metadata; updates copyright year range.
ci/tools/run-examples-pep723 New script to execute examples with uv run and validate metadata resolution.
.github/workflows/test-wheel-linux.yml Installs uv and runs the new PEP 723 example validation in CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +23 to +39
while IFS= read -r -d '' file; do
echo "Running $file..."
OUTPUT=$(uv run "$file" 2>&1)
EXIT_CODE=$?

if [ $EXIT_CODE -ne 0 ]; then
if echo "$OUTPUT" | grep -Eq "Because only cuda-(core|bindings)"; then
echo "SKIPPED: $file (No solution found)"
else
echo "FAILED: $file"
echo "$OUTPUT"
FAILED=1
fi
else
echo "PASSED: $file"
fi
done < <(find "$TARGET_DIR" -name "*.py" -print0)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script executes every *.py example it finds, not just dependency resolution. That can hang or fail in CI for interactive/GUI/long-running examples (e.g., ones that open windows or run until user exits), which makes the metadata check flaky. Consider adding an allowlist of non-interactive examples, or enforcing a timeout per script (and treating timeouts as a separate/controlled outcome), or switching the validation approach to only validate dependency resolution without running the full example body.

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +38
if [ $EXIT_CODE -ne 0 ]; then
if echo "$OUTPUT" | grep -Eq "Because only cuda-(core|bindings)"; then
echo "SKIPPED: $file (No solution found)"
else
echo "FAILED: $file"
echo "$OUTPUT"
FAILED=1
fi
else
echo "PASSED: $file"
fi
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The skip logic depends on matching a specific uv error message substring. This is brittle across uv versions and may incorrectly fail CI if the phrasing changes. A more robust approach is to detect resolution failure via a stable signal (e.g., uv structured output if available, or matching more generic markers like No solution found plus the specific package name), and keep the skip condition tightly scoped to dependency resolution errors rather than all runtime/exception outputs.

Copilot uses AI. Check for mistakes.
# ################################################################################

# /// script
# dependencies = ["cuda_bindings", "cuda_core", "cupy"]
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using cupy as a dependency may often force a source build (or otherwise fail) on many machines/CI environments, whereas CuPy commonly recommends installing a CUDA-specific wheel package (e.g., cupy-cuda11x/cupy-cuda12x) depending on the CUDA runtime. If the goal is for uv run/pipx run to work for typical users, consider documenting/encoding a more reliably installable CuPy package choice (or otherwise clarifying the intended installation path) to avoid frequent resolution/build failures.

Suggested change
# dependencies = ["cuda_bindings", "cuda_core", "cupy"]
# dependencies = ["cuda_bindings", "cuda_core", "cupy-cuda12x"] # Use a CuPy CUDA package matching your CUDA version (e.g., cupy-cuda11x or cupy-cuda12x).

Copilot uses AI. Check for mistakes.
- name: Run cuda.core examples with PEP 723 metadata in isolation
if: ${{ env.SKIP_CUDA_BINDINGS_TEST == '0' }}
run: |
ci/tools/run-examples-pep723 cuda_core/examples/
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running the full cuda_core/examples/ directory via uv run in CI inherits the same risk as the tool: examples that are interactive, long-running, or require a display/context can hang/fail the workflow. It would be more reliable to call the tool with a curated subset of examples known to terminate quickly (or to add filtering/timeout support in the tool and use it here).

Suggested change
ci/tools/run-examples-pep723 cuda_core/examples/
timeout 600 ci/tools/run-examples-pep723 cuda_core/examples/

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

@mdboom mdboom marked this pull request as draft March 20, 2026 17:12
@copy-pr-bot
Copy link
Contributor

copy-pr-bot bot commented Mar 20, 2026

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@mdboom
Copy link
Contributor Author

mdboom commented Mar 20, 2026

I'm unsure why this is happening when running examples that use nvrtc. When we install CTK components cuda_nvrtc is on the list.

Traceback (most recent call last):
  File "/__w/cuda-python/cuda-python/cuda_core/examples/vector_add.py", line 76, in <module>
    main()
  File "/__w/cuda-python/cuda-python/cuda_core/examples/vector_add.py", line 43, in main
    prog = Program(code, code_type="c++", options=program_options)
  File "cuda/core/_program.pyx", line 76, in cuda.core._program.Program.__init__
  File "cuda/core/_program.pyx", line 562, in cuda.core._program.Program_init
  File "cuda/bindings/cynvrtc.pyx", line 20, in cuda.bindings.cynvrtc.nvrtcCreateProgram
  File "cuda/bindings/_bindings/cynvrtc.pyx", line 147, in cuda.bindings._bindings.cynvrtc._nvrtcCreateProgram
  File "cuda/bindings/_bindings/cynvrtc.pyx", line 107, in cuda.bindings._bindings.cynvrtc.cuPythonInit
  File "cuda/bindings/_bindings/cynvrtc.pyx", line 43, in cuda.bindings._bindings.cynvrtc._cuPythonInit
  File "cuda/bindings/_bindings/cynvrtc.pyx", line 44, in cuda.bindings._bindings.cynvrtc._cuPythonInit
  File "/github/home/.cache/uv/environments-v2/vector-add-0101fb477650cc1d/lib/python3.10/site-packages/cuda/pathfinder/_dynamic_libs/load_nvidia_dynamic_lib.py", line 291, in load_nvidia_dynamic_lib
    return _load_lib_no_cache(libname)
  File "/github/home/.cache/uv/environments-v2/vector-add-0101fb477650cc1d/lib/python3.10/site-packages/cuda/pathfinder/_dynamic_libs/load_nvidia_dynamic_lib.py", line 183, in _load_lib_no_cache
    ctx.raise_not_found()
  File "/github/home/.cache/uv/environments-v2/vector-add-0101fb477650cc1d/lib/python3.10/site-packages/cuda/pathfinder/_dynamic_libs/search_steps.py", line 66, in raise_not_found
    raise DynamicLibNotFoundError(f'Failure finding "{self.lib_searched_for}": {err}\n{att}')
cuda.pathfinder._dynamic_libs.load_dl_common.DynamicLibNotFoundError: Failure finding "libnvrtc.so": No such file: libnvrtc.so*, No such file: libnvrtc.so*

@mdboom
Copy link
Contributor Author

mdboom commented Mar 20, 2026

/ok to test

@mdboom mdboom closed this Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.core Everything related to the cuda.core module example Improvements or additions to code examples

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants