Skip to content

Commit 7d5c742

Browse files
committed
add the system class
1 parent fd71ced commit 7d5c742

File tree

7 files changed

+118
-0
lines changed

7 files changed

+118
-0
lines changed

cuda_core/cuda/core/experimental/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
from cuda.core.experimental._launcher import LaunchConfig, launch
88
from cuda.core.experimental._program import Program
99
from cuda.core.experimental._stream import Stream, StreamOptions
10+
from cuda.core.experimental._system import system
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from typing import Tuple
2+
from cuda import cuda, cudart
3+
from cuda.core.experimental._device import Device
4+
from cuda.core.experimental._utils import handle_return
5+
6+
class System:
7+
""" Provide information about the cuda system.
8+
This class is a singleton and should not be instantiated directly.
9+
"""
10+
11+
_instance = None
12+
13+
def __new__(cls):
14+
if cls._instance is None:
15+
cls._instance = super(System, cls).__new__(cls)
16+
return cls._instance
17+
18+
def __init__(self):
19+
if hasattr(self, '_initialized') and self._initialized:
20+
return
21+
self._initialized = True
22+
23+
@property
24+
def driver_version(self) -> Tuple[int, int]:
25+
"""
26+
Query the CUDA driver version.
27+
28+
Returns
29+
-------
30+
tuple of int
31+
A 2-tuple of (major, minor) version numbers.
32+
"""
33+
version = handle_return(cuda.cuDriverGetVersion())
34+
major = version // 1000
35+
minor = (version % 1000) // 10
36+
return (major, minor)
37+
38+
@property
39+
def num_devices(self) -> int:
40+
"""
41+
Query the number of available GPUs.
42+
43+
Returns
44+
-------
45+
int
46+
The number of available GPU devices.
47+
"""
48+
return handle_return(cudart.cudaGetDeviceCount())
49+
50+
@property
51+
def devices(self) -> tuple:
52+
"""
53+
Query the available device instances.
54+
55+
Returns
56+
-------
57+
tuple of Device
58+
A tuple containing instances of available devices.
59+
"""
60+
total = self.num_devices
61+
return tuple(Device(device_id) for device_id in range(total))
62+
63+
system = System()
64+
system.__doc__ = """
65+
Singleton instance of the :obj:`~cuda.core.experimental._system.System` class.
66+
"""

cuda_core/docs/source/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CUDA runtime
1616

1717
Device
1818
launch
19+
system
1920

2021
:template: dataclass.rst
2122

cuda_core/docs/source/api_private.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CUDA runtime
1616
_memory.Buffer
1717
_stream.Stream
1818
_event.Event
19+
_system.System
1920

2021

2122
CUDA compilation toolchain

cuda_core/docs/source/release.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ maxdepth: 3
66
---
77
88
0.1.0 <release/0.1.0-notes>
9+
0.2.0 <release/0.2.0-notes>
10+
911
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# `cuda.core` Release notes
2+
3+
Released on <TODO>, 2024
4+
5+
## Hightlights
6+
- Addition of the system singleton
7+
8+
## Limitations
9+
10+
<TODO>

cuda_core/tests/test_system.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# test_System.py
2+
3+
try:
4+
from cuda.bindings import driver, runtime
5+
except ImportError:
6+
from cuda import cuda as driver
7+
from cuda import cudart as runtime
8+
9+
from cuda.core.experimental import Device, System
10+
11+
from cuda.core.experimental import Device
12+
from cuda.core.experimental._utils import handle_return
13+
14+
def test_System_singleton():
15+
System1 = System
16+
System2 = System
17+
assert System1 is System2, "System is not a singleton"
18+
19+
def test_driver_version():
20+
driver_version = System.driver_version
21+
print(driver_version)
22+
version = handle_return(driver.cuDriverGetVersion())
23+
expected_driver_version = (version // 1000, (version % 1000) // 10)
24+
assert driver_version == expected_driver_version, "Driver version does not match expected value"
25+
26+
def test_num_devices():
27+
num_devices = System.num_devices
28+
expected_num_devices = handle_return(runtime.cudaGetDeviceCount())
29+
assert num_devices == expected_num_devices, "Number of devices does not match expected value"
30+
31+
def test_devices():
32+
devices = System.devices
33+
expected_num_devices = handle_return(runtime.cudaGetDeviceCount())
34+
expected_devices = tuple(Device(device_id) for device_id in range(expected_num_devices))
35+
assert len(devices) == len(expected_devices), "Number of devices does not match expected value"
36+
for device, expected_device in zip(devices, expected_devices):
37+
assert device.device_id == expected_device.device_id, "Device ID does not match expected value"

0 commit comments

Comments
 (0)