Skip to content

Commit dc56154

Browse files
committed
No implicit init, and fix docs build
1 parent a323200 commit dc56154

File tree

10 files changed

+48
-28
lines changed

10 files changed

+48
-28
lines changed

.github/workflows/build-docs.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,6 @@ jobs:
202202
- name: Build all docs
203203
if: ${{ inputs.component == 'all' }}
204204
run: |
205-
pushd cuda_core/docs/
206-
python -c "import cuda.core"
207-
popd
208-
209205
pushd cuda_python/docs/
210206
if [[ "${{ inputs.is-release }}" == "false" ]]; then
211207
./build_all_docs.sh latest-only

cuda_core/cuda/core/system/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@
2222
from .device import Device, DeviceArchitecture
2323
from .exceptions import *
2424

25-
initialize()
26-
2725
__all__.extend(
2826
[
27+
"initialize",
2928
"Device",
3029
"DeviceArchitecture",
3130
"UninitializedError",

cuda_core/cuda/core/system/_nvml_context.pyx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ _lock = threading.Lock()
2929

3030

3131
def initialize() -> None:
32-
"""Idempotent (per-process) initialization of NVUtil's NVML
32+
"""Idempotent (per-process) initialization of Nvidia Management Library (NVML).
3333

3434
Notes
3535
-----
@@ -89,5 +89,7 @@ def validate() -> None:
8989
"""
9090
if _NVML_STATE == _NVMLState.DISABLED_LIBRARY_NOT_FOUND:
9191
raise exceptions.LibraryNotFoundError("The underlying NVML library was not found")
92+
elif not is_initialized():
93+
raise exceptions.UninitializedError("NVML library is not initialized")
9294
elif nvml.device_get_count_v2() == 0:
9395
raise exceptions.GpuNotFoundError("No GPUs available")

cuda_core/cuda/core/system/device.pyx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ from typing import Iterable
1010

1111
from cuda.bindings import _nvml as nvml
1212

13+
from ._nvml_context import validate
1314
from .utils import unpack_bitmask
1415

1516

@@ -189,6 +190,8 @@ cdef class Device:
189190
cdef intptr_t _handle
190191

191192
def __init__(self, index: int | None = None, uuid: bytes | str | None = None):
193+
validate()
194+
192195
if index is not None and uuid is not None:
193196
raise ValueError("Handle requires only one of either device `index` or `uuid`.")
194197
if index is None and uuid is None:

cuda_core/cuda/core/system/system.pyx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ HAS_WORKING_NVML = _BINDINGS_VERSION >= (13, 1, 2) or (_BINDINGS_VERSION[0] == 1
1515

1616
if HAS_WORKING_NVML:
1717
from cuda.bindings import _nvml as nvml
18+
from ._nvml_context import validate
1819
else:
1920
from cuda.core._utils.cuda_utils import driver, handle_return, runtime
2021

@@ -36,6 +37,7 @@ def get_driver_version_full() -> tuple[int, int, int]:
3637
"""
3738
cdef int v
3839
if HAS_WORKING_NVML:
40+
validate()
3941
v = nvml.system_get_cuda_driver_version()
4042
else:
4143
v = handle_return(driver.cuDriverGetVersion())
@@ -48,6 +50,7 @@ def get_gpu_driver_version() -> tuple[int, ...]:
4850
"""
4951
if not HAS_WORKING_NVML:
5052
raise RuntimeError("NVML library is not available")
53+
validate()
5154
return tuple(int(v) for v in nvml.system_get_driver_version().split("."))
5255

5356

@@ -65,6 +68,7 @@ def get_num_devices() -> int:
6568
Return the number of devices in the system.
6669
"""
6770
if HAS_WORKING_NVML:
71+
validate()
6872
return nvml.device_get_count_v2()
6973
else:
7074
return handle_return(runtime.cudaGetDeviceCount())
@@ -84,6 +88,7 @@ def get_process_name(pid: int) -> str:
8488
name: str
8589
The process name.
8690
"""
91+
validate()
8792
return nvml.system_get_process_name(pid)
8893

8994

cuda_core/docs/build_docs.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ if [[ -z "${SPHINX_CUDA_CORE_VER}" ]]; then
2222
fi
2323

2424
# build the docs (in parallel)
25-
SPHINXOPTS="-T -j 4 -d build/.doctrees" make html
25+
SPHINXOPTS="-j 4 -d build/.doctrees" make html
2626

2727
# for debugging/developing (conf.py), please comment out the above line and
2828
# use the line below instead, as we must build in serial to avoid getting

cuda_core/docs/source/api.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,21 @@ CUDA compilation toolchain
6464
LinkerOptions
6565

6666

67-
CUDA system information
68-
-----------------------
67+
CUDA system information and Nvidia Management Library (NVML)
68+
------------------------------------------------------------
6969

70-
.. automethod:: cuda.core._system.System.get_driver_version
71-
.. automethod:: cuda.core._system.System.get_num_devices
70+
.. autosummary::
71+
:toctree: generated/
72+
73+
system.initialize
74+
system.Device
75+
system.DeviceArchitecture
76+
system.get_driver_version
77+
system.get_driver_version_full
78+
system.get_gpu_driver_version
79+
system.get_num_devices
80+
system.get_nvml_version
81+
system.get_process_name
7282

7383

7484
.. module:: cuda.core.utils

cuda_core/tests/system/conftest.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,11 @@
99
skip_if_nvml_unsupported = pytest.mark.skipif(
1010
not system.HAS_WORKING_NVML, reason="NVML support requires cuda.bindings version 12.9.6+ or 13.1.2+"
1111
)
12+
13+
14+
@pytest.fixture(autouse=True, scope="session")
15+
def initialize_nvml():
16+
if system.HAS_WORKING_NVML:
17+
from cuda.core.system._nvml_context import initialize
18+
19+
initialize()

cuda_core/tests/system/test_nvml_context.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,20 @@ def _run_process(target):
2525
assert not p.exitcode
2626

2727

28-
def _test_initialized():
28+
def _test_uninitialized():
2929
from cuda.core.system import _nvml_context
3030

31-
assert _nvml_context._NVML_STATE == INITIALIZED
31+
assert _nvml_context._NVML_STATE == UNINITIALIZED
3232

3333

34-
def test_initialized():
35-
_run_process(_test_initialized)
34+
def test_uninitialized():
35+
_run_process(_test_uninitialized)
3636

3737

3838
def _test_is_initialized():
3939
from cuda.core.system import _nvml_context
4040

41+
_nvml_context.initialize()
4142
assert _nvml_context._NVML_STATE == INITIALIZED
4243
assert _nvml_context.is_initialized() is True
4344

@@ -46,20 +47,11 @@ def test_is_initialized():
4647
_run_process(_test_is_initialized)
4748

4849

49-
def _test_uninitialized():
50-
from cuda.core.system import _nvml_context
51-
52-
_nvml_context._NVML_STATE = UNINITIALIZED
53-
assert _nvml_context.is_initialized() is False
54-
55-
56-
def test_uninitialized():
57-
_run_process(_test_uninitialized)
58-
59-
6050
def _test_wrong_owner():
6151
from cuda.core.system import _nvml_context
6252

53+
_nvml_context.initialize()
54+
6355
_nvml_context._NVML_OWNER_PID = 0
6456
assert _nvml_context.is_initialized() is False
6557

@@ -81,6 +73,8 @@ def test_wsl():
8173
def _test_validate():
8274
from cuda.core.system import _nvml_context
8375

76+
_nvml_context.initialize()
77+
8478
assert _nvml_context.validate() is None
8579

8680

cuda_core/tests/system/test_system_device.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
if system.HAS_WORKING_NVML:
2020
from cuda.bindings import _nvml as nvml
2121

22-
if system.get_num_devices() == 0:
22+
23+
@pytest.fixture(autouse=True, scope="module")
24+
def check_gpu_available(initialize_nvml):
25+
if not system.HAS_WORKING_NVML or system.get_num_devices() == 0:
2326
pytest.skip("No GPUs available to run device tests", allow_module_level=True)
2427

2528

0 commit comments

Comments
 (0)