Skip to content

Commit 14ff25e

Browse files
Omar AtieOmar Atie
authored andcommitted
Merge upstream/main into feat/launch-config-sync-policy-2628
Sync PR #2637 with latest main (preserve branch history, no force-push).
2 parents 1e48c4e + 0b5d816 commit 14ff25e

7 files changed

Lines changed: 107 additions & 27 deletions

File tree

.github/workflows/pr-metadata-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ on:
1717
- reopened
1818
- ready_for_review
1919

20+
permissions:
21+
pull-requests: read
22+
2023
jobs:
2124
check-metadata:
2225
name: PR has assignee, labels, and milestone

cuda_bindings/tests/nvml/test_pynvml.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# A set of tests ported from https://github.com/gpuopenanalytics/pynvml/blob/11.5.3/pynvml/tests/test_nvml.py
55

66
import os
7-
import time
87

98
import pytest
109

@@ -150,23 +149,6 @@ def test_device_get_power_usage(ngpus, handles, subtests):
150149
assert power_mwatts >= 0.0
151150

152151

153-
def test_device_get_total_energy_consumption(ngpus, handles, subtests):
154-
for i in range(ngpus):
155-
with subtests.test(device_index=i):
156-
with unsupported_before(handles[i], None):
157-
energy_mjoules1 = nvml.device_get_total_energy_consumption(handles[i])
158-
159-
for _ in range(10): # idle for 150 ms
160-
time.sleep(0.015) # and check for increase every 15 ms
161-
with unsupported_before(handles[i], None):
162-
energy_mjoules2 = nvml.device_get_total_energy_consumption(handles[i])
163-
assert energy_mjoules2 >= energy_mjoules1
164-
if energy_mjoules2 > energy_mjoules1:
165-
break
166-
else:
167-
raise AssertionError("energy did not increase across 150 ms interval")
168-
169-
170152
# [Skipping] pynvml.nvmlDeviceGetGpuOperationMode
171153
# [Skipping] pynvml.nvmlDeviceGetCurrentGpuOperationMode
172154
# [Skipping] pynvml.nvmlDeviceGetPendingGpuOperationMode

cuda_core/cuda/core/_program.pyi

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ class ProgramOptions:
313313
Load NVIDIA's `libdevice <https://docs.nvidia.com/cuda/libdevice-users-guide/>`_
314314
math builtins library. Only supported for the NVVM backend.
315315
Default: False
316+
numba_debug : bool, optional
317+
Emit the debug information layout expected by Numba. Recognized only by
318+
newer toolkits; compilers that do not support it reject the option with
319+
an error.
320+
Default: False
316321
"""
317322
name: str | None = 'default_program'
318323
arch: str | None = None
@@ -424,6 +429,17 @@ _nvvm_import_attempted = False
424429
def _can_load_generated_ptx() -> bool:
425430
"""Check if the driver can load PTX generated by the current NVRTC version."""
426431

432+
def _assert_single_dashed_nvvm_options(options: list[str]) -> None:
433+
"""Guard against emitting a double-dashed option to libNVVM.
434+
435+
libNVVM's parser accepts only single-dashed options and rejects the
436+
double-dashed spelling of every option with NVVM_ERROR_INVALID_OPTION
437+
(see #2570). Every option on this path is generated from typed fields, so
438+
a double dash can only mean a bug in ``cuda.core`` rather than bad user
439+
input. Fail here, naming the option, instead of leaving the user with
440+
libNVVM's opaque error.
441+
"""
442+
427443
def _program_compile_uncached(program, target_type, name_expressions, logs):
428444
"""Run ``Program_compile`` without the cache wrapper.
429445

cuda_core/cuda/core/_program.pyx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,11 @@ class ProgramOptions:
466466
Load NVIDIA's `libdevice <https://docs.nvidia.com/cuda/libdevice-users-guide/>`_
467467
math builtins library. Only supported for the NVVM backend.
468468
Default: False
469+
numba_debug : bool, optional
470+
Emit the debug information layout expected by Numba. Recognized only by
471+
newer toolkits; compilers that do not support it reject the option with
472+
an error.
473+
Default: False
469474
"""
470475

471476
name: str | None = "default_program"
@@ -1220,6 +1225,24 @@ cdef inline list _prepare_nvrtc_options_impl(object opts):
12201225
return [o.encode() for o in options]
12211226

12221227

1228+
cpdef void _assert_single_dashed_nvvm_options(options: list[str]) except *:
1229+
"""Guard against emitting a double-dashed option to libNVVM.
1230+
1231+
libNVVM's parser accepts only single-dashed options and rejects the
1232+
double-dashed spelling of every option with NVVM_ERROR_INVALID_OPTION
1233+
(see #2570). Every option on this path is generated from typed fields, so
1234+
a double dash can only mean a bug in ``cuda.core`` rather than bad user
1235+
input. Fail here, naming the option, instead of leaving the user with
1236+
libNVVM's opaque error.
1237+
"""
1238+
for option in options:
1239+
if option.startswith("--"):
1240+
raise RuntimeError(
1241+
f"Internal error: NVVM option {option!r} is double-dashed. libNVVM accepts "
1242+
f"only single-dashed options; emit {option[1:]!r} instead."
1243+
)
1244+
1245+
12231246
cdef inline object _prepare_nvvm_options_impl(object opts, bint as_bytes):
12241247
"""Build NVVM-specific compiler options."""
12251248
options = []
@@ -1232,8 +1255,10 @@ cdef inline object _prepare_nvvm_options_impl(object opts, bint as_bytes):
12321255
options.append(f"-arch={arch}")
12331256
if opts.debug is not None and opts.debug:
12341257
options.append("-g")
1258+
# libNVVM only accepts single-dashed options; the double-dashed spelling
1259+
# accepted by NVRTC is rejected with NVVM_ERROR_INVALID_OPTION.
12351260
if opts.numba_debug:
1236-
options.append("--numba-debug")
1261+
options.append("-numba-debug")
12371262
if opts.device_code_optimize is False:
12381263
options.append("-opt=0")
12391264
elif opts.device_code_optimize is True:
@@ -1313,6 +1338,8 @@ cdef inline object _prepare_nvvm_options_impl(object opts, bint as_bytes):
13131338
if unsupported:
13141339
raise CUDAError(f"The following options are not supported by NVVM backend: {', '.join(unsupported)}")
13151340

1341+
_assert_single_dashed_nvvm_options(options)
1342+
13161343
if as_bytes:
13171344
return [o.encode() for o in options]
13181345
else:

cuda_core/docs/source/release/1.2.0-notes.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ Fixes and enhancements
120120
``coscheduled_sm_count`` explicitly when an aligned result is required.
121121
(`#2389 <https://github.com/NVIDIA/cuda-python/pull/2389>`__)
122122

123+
- ``ProgramOptions(numba_debug=True)`` now works on the NVVM backend. The
124+
option was emitted to libNVVM as ``--numba-debug``, but libNVVM accepts only
125+
single-dashed options, so every such compile failed with
126+
``NVVM_ERROR_INVALID_OPTION``. It is now emitted as ``-numba-debug``, matching
127+
what numba-cuda passes on the NVVM path. The NVRTC backend accepts both
128+
spellings and was unaffected. The option itself is only recognized by newer
129+
toolkits; libNVVM from CUDA 12.x does not support it under either spelling and
130+
still reports ``NVVM_ERROR_INVALID_OPTION``.
131+
(closes `#2570 <https://github.com/NVIDIA/cuda-python/issues/2570>`__)
132+
123133
Deprecation Notices
124134
-------------------
125135

cuda_core/tests/system/test_system_device.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,10 @@ def test_clock(subtests):
590590
with unsupported_before(device, None):
591591
pstate = device.performance_state
592592

593-
min_, max_ = clock.get_min_max_clock_of_pstate_mhz(pstate)
593+
# Individual queries may be unsupported for a clock domain even
594+
# on newer devices.
595+
with unsupported_before(device, None):
596+
min_, max_ = clock.get_min_max_clock_of_pstate_mhz(pstate)
594597
assert isinstance(min_, int)
595598
assert min_ >= 0
596599
assert isinstance(max_, int)
@@ -601,7 +604,7 @@ def test_clock(subtests):
601604
assert isinstance(max_mhz, int)
602605
assert max_mhz >= 0
603606

604-
with unsupported_before(device, DeviceArch.KEPLER):
607+
with unsupported_before(device, None):
605608
current_mhz = clock.get_current_mhz()
606609
assert isinstance(current_mhz, int)
607610
assert current_mhz >= 0

cuda_core/tests/test_program.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,16 @@ def _check_nvvm_arch(arch: str) -> bool:
9393

9494

9595
def _check_nvvm_supports_numba_debug() -> bool:
96-
"""Check if the installed libNVVM recognizes --numba-debug (CTK 13.2+)."""
96+
"""Check if the installed libNVVM recognizes -numba-debug.
97+
98+
libNVVM only accepts single-dashed options, so the double-dashed spelling
99+
used by NVRTC is rejected by every libNVVM version.
100+
"""
97101
if not _has_check_nvvm_compiler_options():
98102
return False
99103
from cuda.bindings.utils import check_nvvm_compiler_options
100104

101-
return check_nvvm_compiler_options(["--numba-debug"])
105+
return check_nvvm_compiler_options(["-numba-debug"])
102106

103107

104108
@pytest.fixture(scope="session")
@@ -762,18 +766,53 @@ def test_program_options_as_bytes_nvvm_unsupported_option():
762766

763767
@nvvm_available
764768
def test_nvvm_program_options_as_bytes_numba_debug():
765-
"""numba_debug must be plumbed through to libNVVM as --numba-debug
766-
(see #1287)."""
769+
"""numba_debug must be plumbed through to libNVVM as -numba-debug
770+
(see #1287, #2570). libNVVM rejects the double-dashed spelling."""
767771
options = ProgramOptions(arch="sm_80", debug=True, numba_debug=True)
768772
nvvm_bytes = options.as_bytes("nvvm")
769-
assert b"--numba-debug" in nvvm_bytes
773+
assert b"-numba-debug" in nvvm_bytes
774+
assert b"--numba-debug" not in nvvm_bytes
770775
assert b"-g" in nvvm_bytes
771776

772777

778+
@pytest.mark.agent_authored(model="claude-opus-5[1m]")
779+
def test_nvvm_options_reject_double_dash():
780+
"""The guard must name a double-dashed option rather than let libNVVM
781+
reject it with an opaque error (see #2570)."""
782+
from cuda.core._program import _assert_single_dashed_nvvm_options
783+
784+
_assert_single_dashed_nvvm_options(["-arch=compute_80", "-g", "-numba-debug"])
785+
786+
with pytest.raises(RuntimeError, match=r"--numba-debug.*double-dashed"):
787+
_assert_single_dashed_nvvm_options(["-arch=compute_80", "--numba-debug"])
788+
789+
790+
@nvvm_available
791+
@pytest.mark.agent_authored(model="claude-opus-5[1m]")
792+
def test_nvvm_program_options_as_bytes_all_single_dashed():
793+
"""Every option cuda.core emits to libNVVM must be single-dashed, because
794+
libNVVM rejects the double-dashed spelling of all of them (see #2570).
795+
This covers every NVVM-supported field of ProgramOptions."""
796+
options = ProgramOptions(
797+
arch="sm_80",
798+
debug=True,
799+
numba_debug=True,
800+
device_code_optimize=True,
801+
ftz=True,
802+
prec_sqrt=True,
803+
prec_div=True,
804+
fma=True,
805+
)
806+
nvvm_bytes = options.as_bytes("nvvm")
807+
assert nvvm_bytes, "expected at least one emitted option"
808+
offenders = [o for o in nvvm_bytes if o.startswith(b"--")]
809+
assert not offenders, f"double-dashed options are rejected by libNVVM: {offenders}"
810+
811+
773812
@nvvm_available
774813
@pytest.mark.skipif(
775814
not _check_nvvm_supports_numba_debug(),
776-
reason="installed libNVVM does not recognize --numba-debug (needs CTK 13.2+)",
815+
reason="installed libNVVM does not recognize -numba-debug",
777816
)
778817
def test_nvvm_program_numba_debug(init_cuda, nvvm_ir):
779818
options = ProgramOptions(arch="sm_80", debug=True, numba_debug=True)

0 commit comments

Comments
 (0)