Skip to content

Commit

Permalink
add the system class
Browse files Browse the repository at this point in the history
  • Loading branch information
ksimpson-work committed Nov 29, 2024
1 parent fd71ced commit 7d5c742
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions cuda_core/cuda/core/experimental/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
from cuda.core.experimental._launcher import LaunchConfig, launch
from cuda.core.experimental._program import Program
from cuda.core.experimental._stream import Stream, StreamOptions
from cuda.core.experimental._system import system
66 changes: 66 additions & 0 deletions cuda_core/cuda/core/experimental/_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import Tuple
from cuda import cuda, cudart
from cuda.core.experimental._device import Device
from cuda.core.experimental._utils import handle_return

class System:
""" Provide information about the cuda system.
This class is a singleton and should not be instantiated directly.
"""

_instance = None

def __new__(cls):
if cls._instance is None:
cls._instance = super(System, cls).__new__(cls)
return cls._instance

def __init__(self):
if hasattr(self, '_initialized') and self._initialized:
return
self._initialized = True

@property
def driver_version(self) -> Tuple[int, int]:
"""
Query the CUDA driver version.
Returns
-------
tuple of int
A 2-tuple of (major, minor) version numbers.
"""
version = handle_return(cuda.cuDriverGetVersion())
major = version // 1000
minor = (version % 1000) // 10
return (major, minor)

@property
def num_devices(self) -> int:
"""
Query the number of available GPUs.
Returns
-------
int
The number of available GPU devices.
"""
return handle_return(cudart.cudaGetDeviceCount())

@property
def devices(self) -> tuple:
"""
Query the available device instances.
Returns
-------
tuple of Device
A tuple containing instances of available devices.
"""
total = self.num_devices
return tuple(Device(device_id) for device_id in range(total))

system = System()
system.__doc__ = """
Singleton instance of the :obj:`~cuda.core.experimental._system.System` class.
"""
1 change: 1 addition & 0 deletions cuda_core/docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ CUDA runtime

Device
launch
system

:template: dataclass.rst

Expand Down
1 change: 1 addition & 0 deletions cuda_core/docs/source/api_private.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ CUDA runtime
_memory.Buffer
_stream.Stream
_event.Event
_system.System


CUDA compilation toolchain
Expand Down
2 changes: 2 additions & 0 deletions cuda_core/docs/source/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ maxdepth: 3
---
0.1.0 <release/0.1.0-notes>
0.2.0 <release/0.2.0-notes>
```
10 changes: 10 additions & 0 deletions cuda_core/docs/source/release/0.2.0-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# `cuda.core` Release notes

Released on <TODO>, 2024

## Hightlights
- Addition of the system singleton

## Limitations

<TODO>
37 changes: 37 additions & 0 deletions cuda_core/tests/test_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# test_System.py

try:
from cuda.bindings import driver, runtime
except ImportError:
from cuda import cuda as driver
from cuda import cudart as runtime

from cuda.core.experimental import Device, System

from cuda.core.experimental import Device
from cuda.core.experimental._utils import handle_return

def test_System_singleton():
System1 = System
System2 = System
assert System1 is System2, "System is not a singleton"

def test_driver_version():
driver_version = System.driver_version
print(driver_version)
version = handle_return(driver.cuDriverGetVersion())
expected_driver_version = (version // 1000, (version % 1000) // 10)
assert driver_version == expected_driver_version, "Driver version does not match expected value"

def test_num_devices():
num_devices = System.num_devices
expected_num_devices = handle_return(runtime.cudaGetDeviceCount())
assert num_devices == expected_num_devices, "Number of devices does not match expected value"

def test_devices():
devices = System.devices
expected_num_devices = handle_return(runtime.cudaGetDeviceCount())
expected_devices = tuple(Device(device_id) for device_id in range(expected_num_devices))
assert len(devices) == len(expected_devices), "Number of devices does not match expected value"
for device, expected_device in zip(devices, expected_devices):
assert device.device_id == expected_device.device_id, "Device ID does not match expected value"

0 comments on commit 7d5c742

Please sign in to comment.