Skip to content
Merged
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
33 changes: 32 additions & 1 deletion cuda_bindings_12/tests/test_cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ def supportsManagedMemory():
return err == cudart.cudaError_t.cudaSuccess and isSupported


# Cap for memory pools created by tests. A pool created with maxSize 0 reserves
# virtual address space of about twice the device memory, and that reservation
# can fail on systems with a limited virtual address space.
POOL_SIZE = 2 * 1024 * 1024 # 2 MiB


def supportsCudaAPI(name):
return name in dir(cuda)

Expand Down Expand Up @@ -333,6 +339,7 @@ def test_cuda_memPool_attr():
poolProps.allocType = cuda.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_PINNED
poolProps.location.id = 0
poolProps.location.type = cuda.CUmemLocationType.CU_MEM_LOCATION_TYPE_DEVICE
poolProps.maxSize = POOL_SIZE

attr_list = [None] * 8
err, pool = cuda.cuMemPoolCreate(poolProps)
Expand Down Expand Up @@ -539,9 +546,27 @@ def test_cuda_mem_range_attr():
assert err == cuda.CUresult.CUDA_SUCCESS


@pytest.fixture
def xfail_on_graph_mempool_oom():
"""Return a check that xfails the calling test if the graph memory pool cannot be created.

The graph memory pool reserves virtual address space of about twice the
device memory, and unlike pools from cuMemPoolCreate it cannot be capped.
On systems with a limited virtual address space this reservation can fail
with CUDA_ERROR_OUT_OF_MEMORY, especially when another uncapped pool
already exists in the process.
"""

def check(err):
if err == cuda.CUresult.CUDA_ERROR_OUT_OF_MEMORY:
pytest.xfail("graph memory pool creation failed with CUDA_ERROR_OUT_OF_MEMORY")

return check


@pytest.mark.skipif(driverVersionLessThan(11040) or not supportsMemoryPool(), reason="Mempool for graphs not supported")
@pytest.mark.thread_unsafe(reason="used high memory can be higher if threaded.")
def test_cuda_graphMem_attr():
def test_cuda_graphMem_attr(xfail_on_graph_mempool_oom):
(err,) = cuda.cuInit(0)
assert err == cuda.CUresult.CUDA_SUCCESS
err, device = cuda.cuDeviceGet(0)
Expand All @@ -564,6 +589,12 @@ def test_cuda_graphMem_attr():
params.bytesize = allocSize

err, allocNode = cuda.cuGraphAddMemAllocNode(graph, None, 0, params)
if err == cuda.CUresult.CUDA_ERROR_OUT_OF_MEMORY:
(destroy_err,) = cuda.cuGraphDestroy(graph)
assert destroy_err == cuda.CUresult.CUDA_SUCCESS
(destroy_err,) = cuda.cuStreamDestroy(stream)
assert destroy_err == cuda.CUresult.CUDA_SUCCESS
xfail_on_graph_mempool_oom(err)
Comment on lines +592 to +597

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Stability & Availability · Quick win

Supported by static analysis

Script executed:

sed -n '520,625p' cuda_bindings_12/tests/test_cuda.py
rg -n 'def test_cuda_graphMem_attr|cuCtxDestroy|xfail_on_graph_mempool_oom|yield|autouse|context' cuda_bindings_12/tests/test_cuda.py cuda_bindings_12/tests/conftest.py cuda_bindings_12/tests

Repository: NVIDIA/cuda-python

Length of output: 12879


Script executed:

set -u
printf '%s\n' '--- test files and conftest files ---'
rg --files cuda_bindings_12/tests -g 'conftest.py' -g 'test_cuda.py'
printf '%s\n' '--- applicable pytest configuration and teardown hooks ---'
rg -n -F --glob 'pyproject.toml' --glob 'pytest.ini' --glob 'setup.cfg' --glob 'tox.ini' --glob 'conftest.py' --glob '*.py' \
  -e 'pytest_sessionfinish' -e 'pytest_runtest_teardown' -e 'pytest_runtest_protocol' -e 'autouse=True' -e 'cuCtxDestroy' -e 'cuda.cuCtxDestroy' \
  . || test "$?" -eq 1
printf '%s\n' '--- complete graph test through its cleanup ---'
nl -ba cuda_bindings_12/tests/test_cuda.py | sed -n '545,640p'

Repository: NVIDIA/cuda-python

Length of output: 11345


Script executed:

printf '%s\n' '--- cuda_bindings_12/tests/conftest.py ---'
nl -ba cuda_bindings_12/tests/conftest.py
printf '%s\n' '--- repository pytest configuration files ---'
for f in pyproject.toml pytest.ini setup.cfg tox.ini; do
  if [ -f "$f" ]; then
    printf '%s\n' "--- $f ---"
    nl -ba "$f" | rg -n -C 4 -e 'pytest|testpaths|addopts|python_files|plugins|conftest'
  fi
done
printf '%s\n' '--- parent and root conftest files ---'
find . -maxdepth 3 -name conftest.py -print

Repository: NVIDIA/cuda-python

Length of output: 3334


Script executed:

printf '%s\n' '--- registered pytest plugin files ---'
rg --files cuda_python_test_helpers | rg '(^|/)_pytest_plugin(\.py|/)|pytest'
printf '%s\n' '--- plugin teardown and CUDA cleanup references ---'
rg -n -C 6 -F --glob '*.py' \
  -e 'pytest_runtest_teardown' -e 'pytest_runtest_protocol' -e 'pytest_sessionfinish' \
  -e 'pytest.fixture' -e 'cuCtxDestroy' -e 'cuda.cuCtxDestroy' -e 'context' \
  cuda_python_test_helpers

Repository: NVIDIA/cuda-python

Length of output: 20168


Script executed:

nl -ba cuda_python_test_helpers/cuda_python_test_helpers/_pytest_plugin.py
printf '%s\n' '--- imports and pytest hook declarations in helper package ---'
rg -n -C 3 --glob '*.py' \
  -e '^from ' -e '^import ' -e '^def pytest_' -e '^class ' -e 'pytest_plugins' \
  cuda_python_test_helpers/cuda_python_test_helpers

Repository: NVIDIA/cuda-python

Length of output: 29198


important: Destroy ctx before xfail_on_graph_mempool_oom(err).

The OOM branch destroys graph and stream, then pytest.xfail exits before the later cuCtxDestroy(ctx) call. Add context destruction to this branch and assert success before calling the xfail helper.

assert err == cuda.CUresult.CUDA_SUCCESS
err, freeNode = cuda.cuGraphAddMemFreeNode(graph, [allocNode], 1, params.dptr)
assert err == cuda.CUresult.CUDA_SUCCESS
Expand Down
7 changes: 7 additions & 0 deletions cuda_bindings_12/tests/test_cudart.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def supportsMemoryPool():
return isSuccess(err) and isSupported


# Cap for memory pools created by tests. A pool created with maxSize 0 reserves
# virtual address space of about twice the device memory, and that reservation
# can fail on systems with a limited virtual address space.
POOL_SIZE = 2 * 1024 * 1024 # 2 MiB


def supportsSparseTexturesDeviceFilter():
err, isSupported = cudart.cudaDeviceGetAttribute(cudart.cudaDeviceAttr.cudaDevAttrSparseCudaArraySupported, 0)
return isSuccess(err) and isSupported
Expand Down Expand Up @@ -425,6 +431,7 @@ def test_cudart_MemPool_attr():
poolProps.allocType = cudart.cudaMemAllocationType.cudaMemAllocationTypePinned
poolProps.location.id = 0
poolProps.location.type = cudart.cudaMemLocationType.cudaMemLocationTypeDevice
poolProps.maxSize = POOL_SIZE

attr_list = [None] * 8
err, pool = cudart.cudaMemPoolCreate(poolProps)
Expand Down
1 change: 1 addition & 0 deletions cuda_bindings_13/tests/test_cuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ def test_ffi_coverage_new_mempool_attributes():
pool_props.alloc_type = driver.MemAllocationType.PINNED
pool_props.location.id = 0
pool_props.location.type = driver.MemLocationType.DEVICE
pool_props.max_size = POOL_SIZE
pool = driver.mem_pool_create(pool_props)
try:
for attr in [
Expand Down
Loading