Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cuda_core/cuda/core/_device.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,10 @@ class DeviceProperties:
"""bool: Device supports HOST_NUMA location with the virtual memory management APIs like cuMemCreate, cuMemMap and related APIs."""
@property
def host_numa_memory_pools_supported(self) -> bool:
"""bool: Device supports HOST_NUMA location with the cuMemAllocAsync and cuMemPool family of APIs."""
"""bool: Device supports HOST_NUMA location with the cuMemAllocAsync and cuMemPool family of APIs.

The value is inferred for drivers before CUDA 12.9.
"""
@property
def host_numa_multinode_ipc_supported(self) -> bool:
"""bool: Device supports HOST_NUMA location IPC between nodes in a multi-node system."""
Expand Down
18 changes: 14 additions & 4 deletions cuda_core/cuda/core/_device.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ from cuda.core._rt cimport (
get_last_error,
as_cu,
)
from cuda.core._utils.version cimport cy_driver_version

from cuda.core._stream import IsStreamType, Stream, StreamOptions
from cuda.core._utils.clear_error_support import assert_type
Expand Down Expand Up @@ -910,10 +911,19 @@ cdef class DeviceProperties:

@property
def host_numa_memory_pools_supported(self) -> bool:
"""bool: Device supports HOST_NUMA location with the cuMemAllocAsync and cuMemPool family of APIs."""
return bool(
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_MEMORY_POOLS_SUPPORTED)
)
"""bool: Device supports HOST_NUMA location with the cuMemAllocAsync and cuMemPool family of APIs.

The value is inferred for drivers before CUDA 12.9.
"""
cdef tuple drv_ver = cy_driver_version()
if drv_ver >= (12, 9, 0):
return bool(
self._get_cached_attribute(
driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_MEMORY_POOLS_SUPPORTED
)
)
# The attribute arrived in CUDA 12.9, HOST_NUMA pools in CUDA 12.6 (#2795).
return drv_ver >= (12, 6, 0) and self.memory_pools_supported and not self.integrated

# Start of CUDA 13 device attributes

Expand Down
50 changes: 50 additions & 0 deletions cuda_core/tests/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import contextlib
import subprocess
import sys
import textwrap
from concurrent.futures import ThreadPoolExecutor

import pytest
Expand Down Expand Up @@ -471,6 +472,55 @@ def test_device_properties_complete():
assert tab_props == live_props # Ensure exact match.


@pytest.mark.agent_authored(model="gpt-6")
@pytest.mark.parametrize("driver_version", [12050, 12060, 12080])
def test_host_numa_memory_pools_supported_on_pre_12_9_driver(driver_version):
script = textwrap.dedent(
"""
import sys

from cuda.bindings import driver

simulated_driver_version = int(sys.argv[1])
driver.cuDriverGetVersion = lambda: (driver.CUresult.CUDA_SUCCESS, simulated_driver_version)
(status,) = driver.cuInit(0)
if int(status) == int(driver.CUresult.CUDA_ERROR_NO_DEVICE):
print("No CUDA device is available")
raise SystemExit(77)
assert int(status) == int(driver.CUresult.CUDA_SUCCESS), status
status, device_count = driver.cuDeviceGetCount()
if int(status) == int(driver.CUresult.CUDA_ERROR_NO_DEVICE) or (
int(status) == int(driver.CUresult.CUDA_SUCCESS) and device_count == 0
):
print("No CUDA device is available")
raise SystemExit(77)
assert int(status) == int(driver.CUresult.CUDA_SUCCESS), status
status, device = driver.cuDeviceGet(0)
assert int(status) == int(driver.CUresult.CUDA_SUCCESS), status
Comment thread
coderabbitai[bot] marked this conversation as resolved.

from cuda.core._device import DeviceProperties

properties = DeviceProperties._init(device)
expected = (
False
if simulated_driver_version < 12060
else properties.memory_pools_supported and not properties.integrated
)
assert properties.host_numa_memory_pools_supported is expected
"""
)
result = subprocess.run( # noqa: S603 - executes a repository-owned test script
[sys.executable, "-c", script, str(driver_version)],
capture_output=True,
check=False,
text=True,
timeout=60,
)
if result.returncode == 77:
pytest.skip(result.stdout + result.stderr)
assert result.returncode == 0, result.stdout + result.stderr


# ============================================================================
# Device Equality Tests
# ============================================================================
Expand Down
Loading