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
39 changes: 39 additions & 0 deletions cuda_bindings/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

import os
import pathlib
import sys

CUDA_PATH = os.environ.get("CUDA_PATH")
CUDA_INCLUDE_PATH = None
CCCL_INCLUDE_PATHS = None
if CUDA_PATH is not None:
path = os.path.join(CUDA_PATH, "include")
if os.path.isdir(path):
CUDA_INCLUDE_PATH = path
CCCL_INCLUDE_PATHS = (path,)
path = os.path.join(path, "cccl")
if os.path.isdir(path):
CCCL_INCLUDE_PATHS = (path,) + CCCL_INCLUDE_PATHS


try:
import cuda_python_test_helpers
except ImportError:
# Import shared platform helpers for tests across repos
test_helpers_path = str(pathlib.Path(__file__).resolve().parents[2] / "cuda_python_test_helpers")
try:
sys.path.insert(0, test_helpers_path)
import cuda_python_test_helpers
Comment on lines +25 to +28
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: If the import on line 28 fails, the path remains in sys.path since the finally block's removal is conditional. Consider moving the import outside the try-finally and only wrapping the sys.path manipulation, or ensure the path is always removed regardless of import success.

finally:
# Clean up sys.path modification
if test_helpers_path in sys.path:
sys.path.remove(test_helpers_path)
Comment on lines +26 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: The sys.path cleanup in the finally block runs before the import statement (line 28) completes, which means cuda_python_test_helpers may not be accessible after the try-finally block exits. The finally block executes immediately after the try block, removing the path before the module can be used at line 35-36. Move the cleanup to after all usage of the imported module (after line 36).



IS_WSL = cuda_python_test_helpers.IS_WSL
supports_ipc_mempool = cuda_python_test_helpers.supports_ipc_mempool


del cuda_python_test_helpers
3 changes: 3 additions & 0 deletions cuda_bindings/tests/test_graphics_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

import pytest
from cuda.bindings import runtime as cudart
from helpers import IS_WSL


@pytest.mark.skipif(IS_WSL, reason="Graphics interop not supported on this platform")
def test_graphics_api_smoketest():
Comment on lines +9 to 10
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: This skipif decorator now prevents the test from running on WSL, which contradicts the PR description. The description says "Adding cudaErrorOperatingSystem to the error tuple" but the actual change removed that error from the assertion and skips WSL entirely instead. Was the intention to skip the test on WSL (as implemented) or to allow it to run while accepting cudaErrorOperatingSystem as a valid error (as the PR title suggests)?

# Due to lazy importing in pyglet, pytest.importorskip doesn't work
try:
Expand All @@ -26,6 +28,7 @@ def test_graphics_api_smoketest():
assert error_name in ("cudaErrorInvalidValue", "cudaErrorUnknown")
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: The PR description says "Adding cudaErrorOperatingSystem" but line 28 shows it was removed from the acceptable errors. The original code had "cudaErrorOperatingSystem" in this tuple and the change removed it.



@pytest.mark.skipif(IS_WSL, reason="Graphics interop not supported on this platform")
def test_cuda_register_image_invalid():
"""Exercise cudaGraphicsGLRegisterImage with dummy handle only using CUDA runtime API."""
fake_gl_texture_id = 1
Expand Down
10 changes: 8 additions & 2 deletions cuda_core/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@
import cuda_python_test_helpers
except ImportError:
# Import shared platform helpers for tests across repos
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "cuda_python_test_helpers"))
import cuda_python_test_helpers
test_helpers_path = str(pathlib.Path(__file__).resolve().parents[2] / "cuda_python_test_helpers")
try:
sys.path.insert(0, test_helpers_path)
import cuda_python_test_helpers
finally:
# Clean up sys.path modification
if test_helpers_path in sys.path:
sys.path.remove(test_helpers_path)
Comment on lines +30 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

What are you trying to achieve here by removing this from sys.path after adding it?

The import system will keep cuda_python_test_helpers in sys.modules, so any subsequent imports of it will just pull from that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My understanding was its preventing polluting global state because the import path changes is alive for the duration of the lifetime of the interpreter process.

Comment on lines +26 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: The finally block removes test_helpers_path from sys.path immediately after import on line 28. This breaks the import cuda_python_test_helpers statement since Python needs the path to remain in sys.path during the import process. The cleanup should happen after all uses of the imported module (after line 36), not inside the try/finally that wraps the import.



IS_WSL = cuda_python_test_helpers.IS_WSL
Expand Down
5 changes: 3 additions & 2 deletions cuda_python_test_helpers/cuda_python_test_helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from contextlib import suppress
from typing import Union

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


def _detect_wsl() -> bool:
data = ""
Expand Down Expand Up @@ -39,6 +37,9 @@ def supports_ipc_mempool(device_id: Union[int, object]) -> bool:
except Exception:
from cuda import cuda as driver # type: ignore

# Lazy import handle_return to avoid hard dependency on cuda.core
from cuda.core.experimental._utils.cuda_utils import handle_return

# Initialize CUDA
handle_return(driver.cuInit(0))

Expand Down