Skip to content

Commit 22eb5ff

Browse files
committed
Merge branch 'main' into add-missing-device-attributes
2 parents a4a3b9e + 598874c commit 22eb5ff

File tree

20 files changed

+200
-115
lines changed

20 files changed

+200
-115
lines changed

.bandit

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

.github/workflows/bandit.yml

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,27 @@ jobs:
1919
permissions:
2020
security-events: write
2121
steps:
22-
- name: Perform Bandit Analysis
23-
# KEEP IN SYNC WITH bandit rev in .pre-commit-config.yaml
24-
# Current runner uses Python 3.8, so the action installs bandit==1.7.10
25-
# via `pip install bandit[sarif]`. If runner Python moves to >=3.9,
26-
# the action will resolve to 1.8.x and you'll need to bump pre-commit.
27-
# (Bandit >=1.8.0 dropped Python 3.8 via Requires-Python metadata.)
28-
uses: PyCQA/bandit-action@8a1b30610f61f3f792fe7556e888c9d7dffa52de # v1.0.0
22+
- name: Checkout
23+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
24+
25+
- name: Install uv
26+
uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
27+
28+
- name: Get ignore codes
29+
id: ignore-codes
30+
# This are computed so that we can run only the `S` (bandit)
31+
# checks. Passing --select to ruff overrides any config files
32+
# (ruff.toml, pyproject.toml, etc), so to avoid having keep everything
33+
# in sync we grab them from the TOML programmatically
34+
run: |
35+
set -euxo pipefail
36+
37+
echo "codes=$(uvx toml2json ./ruff.toml | jq -r '.lint.ignore | map(select(test("^S\\d+"))) | join(",")')" >> "$GITHUB_OUTPUT"
38+
- name: Perform Bandit Analysis using Ruff
39+
uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # v3.5.1
40+
with:
41+
args: "check --select S --ignore ${{ steps.ignore-codes.outputs.codes }} --output-format sarif --output-file results.sarif"
42+
- name: Upload SARIF file
43+
uses: github/codeql-action/upload-sarif@v3
44+
with:
45+
sarif_file: results.sarif

.github/workflows/ci.yml

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,38 @@ jobs:
3232
cuda_build_ver=$(jq -r .cuda.build.version ci/versions.json)
3333
echo "cuda_build_ver=$cuda_build_ver" >> $GITHUB_OUTPUT
3434
35+
should-skip:
36+
runs-on: ubuntu-latest
37+
outputs:
38+
skip: ${{ steps.get-should-skip.outputs.skip }}
39+
steps:
40+
- name: Checkout repository
41+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
42+
- name: Compute whether to skip builds and tests
43+
id: get-should-skip
44+
env:
45+
GH_TOKEN: ${{ github.token }}
46+
run: |
47+
set -euxo pipefail
48+
if ${{ startsWith(github.ref_name, 'pull-request/') }}; then
49+
skip="$(gh pr view "$(grep -Po '(\d+)$' <<< '${{ github.ref_name }}')" --json title --jq '.title | contains("[no-ci]")')"
50+
else
51+
skip=false
52+
fi
53+
echo "skip=${skip}" >> "$GITHUB_OUTPUT"
54+
3555
# WARNING: make sure all of the build jobs are in sync
3656
build-linux-64:
3757
needs:
3858
- ci-vars
59+
- should-skip
3960
strategy:
4061
fail-fast: false
4162
matrix:
4263
host-platform:
4364
- linux-64
4465
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
45-
if: ${{ github.repository_owner == 'nvidia' }}
66+
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
4667
secrets: inherit
4768
uses: ./.github/workflows/build-wheel.yml
4869
with:
@@ -53,13 +74,14 @@ jobs:
5374
build-linux-aarch64:
5475
needs:
5576
- ci-vars
77+
- should-skip
5678
strategy:
5779
fail-fast: false
5880
matrix:
5981
host-platform:
6082
- linux-aarch64
6183
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
62-
if: ${{ github.repository_owner == 'nvidia' }}
84+
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
6385
secrets: inherit
6486
uses: ./.github/workflows/build-wheel.yml
6587
with:
@@ -70,13 +92,14 @@ jobs:
7092
build-windows:
7193
needs:
7294
- ci-vars
95+
- should-skip
7396
strategy:
7497
fail-fast: false
7598
matrix:
7699
host-platform:
77100
- win-64
78101
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
79-
if: ${{ github.repository_owner == 'nvidia' }}
102+
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
80103
secrets: inherit
81104
uses: ./.github/workflows/build-wheel.yml
82105
with:
@@ -163,15 +186,12 @@ jobs:
163186

164187
checks:
165188
name: Check job status
166-
permissions:
167-
checks: read
189+
runs-on: ubuntu-latest
168190
needs:
169-
- build-linux-64
170191
- test-linux-64
171-
- build-linux-aarch64
172192
- test-linux-aarch64
173-
- build-windows
174193
- test-windows
175194
- doc
176-
secrets: inherit
177-
uses: ./.github/workflows/status-check.yml
195+
steps:
196+
- name: Exit
197+
run: exit 0

.github/workflows/status-check.yml

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

.pre-commit-config.yaml

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ci:
1515
# pre-commit autoupdate --freeze
1616
repos:
1717
- repo: https://github.com/astral-sh/ruff-pre-commit
18-
rev: 0b19ef1fd6ad680ed7752d6daba883ce1265a6de # frozen: v0.12.2
18+
rev: f298305809c552671cc47e0fec0ba43e96c146a2 # frozen: v0.13.2
1919
hooks:
2020
- id: ruff
2121
args: [--fix, --show-fixes]
@@ -40,7 +40,7 @@ repos:
4040

4141
# Standard hooks
4242
- repo: https://github.com/pre-commit/pre-commit-hooks
43-
rev: "v5.0.0"
43+
rev: "3e8a8703264a2f4a69428a0aa4dcb512790b2c8c" # frozen: v6.0.0
4444
hooks:
4545
- id: check-added-large-files
4646
- id: check-case-conflict
@@ -58,22 +58,14 @@ repos:
5858

5959
# Checking for common mistakes
6060
- repo: https://github.com/pre-commit/pygrep-hooks
61-
rev: "v1.10.0"
61+
rev: "3a6eb0fadf60b3cccfd80bad9dbb6fae7e47b316" # frozen: v1.10.0
6262
hooks:
6363
- id: rst-backticks
6464
- id: rst-directive-colons
6565
- id: rst-inline-touching-normal
6666

67-
- repo: https://github.com/PyCQA/bandit
68-
rev: "36fd65054fc8864b4037d0918904f9331512feb5" # frozen: 1.7.10 KEEP IN SYNC WITH .github/workflows/bandit.yml
69-
hooks:
70-
- id: bandit
71-
args:
72-
- --ini
73-
- .bandit
74-
7567
- repo: https://github.com/pre-commit/mirrors-mypy
76-
rev: 0f86793af5ef5f6dc63c8d04a3cabfa3ea8f9c6a # frozen: v1.16.1
68+
rev: 9f70dc58c23dfcca1b97af99eaeee3140a807c7e # frozen: v1.18.2
7769
hooks:
7870
- id: mypy
7971
name: mypy-pathfinder

cuda_bindings/tests/test_cuda.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ def test_get_error_name_and_string():
653653
@pytest.mark.skipif(not callableBinary("nvidia-smi"), reason="Binary existance needed")
654654
def test_device_get_name():
655655
# TODO: Refactor this test once we have nvml bindings to avoid the use of subprocess
656-
import subprocess # nosec B404
656+
import subprocess
657657

658658
(err,) = cuda.cuInit(0)
659659
assert err == cuda.CUresult.CUDA_SUCCESS
@@ -663,8 +663,10 @@ def test_device_get_name():
663663
assert err == cuda.CUresult.CUDA_SUCCESS
664664

665665
p = subprocess.check_output(
666-
["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"], shell=False, stderr=subprocess.PIPE
667-
) # nosec B603, B607
666+
["nvidia-smi", "--query-gpu=name", "--format=csv,noheader"], # noqa: S607
667+
shell=False,
668+
stderr=subprocess.PIPE,
669+
)
668670

669671
delimiter = b"\r\n" if platform.system() == "Windows" else b"\n"
670672
expect = p.split(delimiter)

cuda_bindings/tests/test_nvvm.py

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,12 @@
44

55
import binascii
66
import re
7-
import textwrap
87
from contextlib import contextmanager
98

109
import pytest
1110
from cuda.bindings import nvvm
1211

13-
MINIMAL_NVVMIR_FIXTURE_PARAMS = ["txt", "bitcode_static"]
14-
try:
15-
import llvmlite.binding as llvmlite_binding # Optional test dependency.
16-
except ImportError:
17-
llvmlite_binding = None
18-
else:
19-
MINIMAL_NVVMIR_FIXTURE_PARAMS.append("bitcode_dynamic")
20-
21-
MINIMAL_NVVMIR_TXT = b"""\
12+
MINIMAL_NVVMIR_TXT_TEMPLATE = b"""\
2213
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64"
2314
2415
target triple = "nvptx64-nvidia-cuda"
@@ -130,43 +121,24 @@
130121
"6e673e0000000000",
131122
}
132123

133-
MINIMAL_NVVMIR_CACHE = {}
134-
135124

136-
@pytest.fixture(params=MINIMAL_NVVMIR_FIXTURE_PARAMS)
125+
@pytest.fixture(params=("txt", "bitcode_static"))
137126
def minimal_nvvmir(request):
138-
for pass_counter in range(2):
139-
nvvmir = MINIMAL_NVVMIR_CACHE.get(request.param, -1)
140-
if nvvmir != -1:
141-
if nvvmir is None:
142-
pytest.skip(f"UNAVAILABLE: {request.param}")
143-
return nvvmir
144-
if pass_counter:
145-
raise AssertionError("This code path is meant to be unreachable.")
146-
# Build cache entries, then try again (above).
147-
major, minor, debug_major, debug_minor = nvvm.ir_version()
148-
txt = MINIMAL_NVVMIR_TXT % (major, debug_major)
149-
if llvmlite_binding is None:
150-
bitcode_dynamic = None
151-
else:
152-
bitcode_dynamic = llvmlite_binding.parse_assembly(txt.decode()).as_bitcode()
153-
bitcode_static = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major))
154-
if bitcode_static is not None:
155-
bitcode_static = binascii.unhexlify(bitcode_static)
156-
MINIMAL_NVVMIR_CACHE["txt"] = txt
157-
MINIMAL_NVVMIR_CACHE["bitcode_dynamic"] = bitcode_dynamic
158-
MINIMAL_NVVMIR_CACHE["bitcode_static"] = bitcode_static
159-
if bitcode_static is None:
160-
if bitcode_dynamic is None:
161-
raise RuntimeError("Please `pip install llvmlite` to generate `bitcode_static` (see PR #443)")
162-
bitcode_hex = binascii.hexlify(bitcode_dynamic).decode("ascii")
163-
print("\n\nMINIMAL_NVVMIR_BITCODE_STATIC = { # PLEASE ADD TO test_nvvm.py")
164-
print(f" ({major}, {debug_major}): # (major, debug_major)")
165-
lines = textwrap.wrap(bitcode_hex, width=80)
166-
for line in lines[:-1]:
167-
print(f' "{line}"')
168-
print(f' "{lines[-1]}",')
169-
print("}\n", flush=True)
127+
major, minor, debug_major, debug_minor = nvvm.ir_version()
128+
129+
if request.param == "txt":
130+
return MINIMAL_NVVMIR_TXT_TEMPLATE % (major, debug_major)
131+
132+
bitcode_static_binascii = MINIMAL_NVVMIR_BITCODE_STATIC.get((major, debug_major))
133+
if bitcode_static_binascii:
134+
return binascii.unhexlify(bitcode_static_binascii)
135+
raise RuntimeError(
136+
"Static bitcode for NVVM IR version "
137+
f"{major}.{debug_major} is not available in this test.\n"
138+
"Maintainers: Please run the helper script to generate it and add the "
139+
"output to the MINIMAL_NVVMIR_BITCODE_STATIC dict:\n"
140+
" ../../toolshed/build_static_bitcode_input.py"
141+
)
170142

171143

172144
@pytest.fixture(params=[nvvm.compile_program, nvvm.verify_program])

cuda_bindings/tests/test_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import platform
55
import random
6-
import subprocess # nosec B404
6+
import subprocess
77
import sys
88
from pathlib import Path
99

@@ -72,7 +72,7 @@ def test_ptx_utils(kernel, actual_ptx_ver, min_cuda_ver):
7272
),
7373
)
7474
def test_get_handle(target):
75-
ptr = random.randint(1, 1024)
75+
ptr = random.randint(1, 1024) # noqa: S311
7676
obj = target(ptr)
7777
handle = get_cuda_native_handle(obj)
7878
assert handle == ptr
@@ -105,6 +105,6 @@ def test_get_handle_error(target):
105105
],
106106
)
107107
def test_cyclical_imports(module):
108-
subprocess.check_call( # nosec B603
108+
subprocess.check_call( # noqa: S603
109109
[sys.executable, Path(__file__).parent / "utils" / "check_cyclical_import.py", f"cuda.bindings.{module}"],
110110
)

cuda_core/cuda/core/experimental/_memoryview.pyx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,23 @@ cdef class StridedMemoryView:
105105
else:
106106
pass
107107

108+
def __dealloc__(self):
109+
if self.dl_tensor == NULL:
110+
return
111+
112+
if cpython.PyCapsule_IsValid(
113+
self.metadata, DLPACK_VERSIONED_TENSOR_USED_NAME):
114+
data = cpython.PyCapsule_GetPointer(
115+
self.metadata, DLPACK_VERSIONED_TENSOR_USED_NAME)
116+
dlm_tensor_ver = <DLManagedTensorVersioned*>data
117+
dlm_tensor_ver.deleter(dlm_tensor_ver)
118+
elif cpython.PyCapsule_IsValid(
119+
self.metadata, DLPACK_TENSOR_USED_NAME):
120+
data = cpython.PyCapsule_GetPointer(
121+
self.metadata, DLPACK_TENSOR_USED_NAME)
122+
dlm_tensor = <DLManagedTensor*>data
123+
dlm_tensor.deleter(dlm_tensor)
124+
108125
@property
109126
def shape(self) -> tuple[int]:
110127
if self._shape is None and self.exporting_obj is not None:

cuda_core/docs/source/release/0.X.Y-notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ Fixes and enhancements
4848
- Make :class:`Buffer` creation more performant.
4949
- Enabled :class:`MemoryResource` subclasses to accept :class:`Device` objects, in addition to previously supported device ordinals.
5050
- Fixed a bug in :class:`Stream` and other classes where object cleanup would error during interpreter shutdown.
51+
- :class:`StridedMemoryView` of an underlying array using the DLPack protocol will no longer leak memory.

0 commit comments

Comments
 (0)