|
27 | 27 | PinnedMemoryResourceOptions, |
28 | 28 | _device, |
29 | 29 | ) |
30 | | -from cuda.core._utils.cuda_utils import handle_return |
| 30 | +from cuda.core._utils.cuda_utils import CUDAError, handle_return |
| 31 | + |
| 32 | +try: |
| 33 | + from cuda.bindings._test_helpers.mempool import xfail_if_mempool_oom |
| 34 | +except ModuleNotFoundError: |
| 35 | + # Older cuda.bindings artifacts (for example 12.9.x backports) do not ship |
| 36 | + # this helper yet. In that case, keep the primary failure visible instead of |
| 37 | + # xfail-ing the known Windows MCDM mempool setup issue. |
| 38 | + def xfail_if_mempool_oom(err_or_exc, api_name=None, device=0): |
| 39 | + return |
| 40 | + |
31 | 41 |
|
32 | 42 | # Import shared test helpers for tests across subprojects. |
33 | 43 | # PLEASE KEEP IN SYNC with copies in other conftest.py in this repo. |
@@ -61,21 +71,56 @@ def skip_if_managed_memory_unsupported(device): |
61 | 71 | pytest.skip("ManagedMemoryResource requires CUDA 13.0 or later") |
62 | 72 | try: |
63 | 73 | ManagedMemoryResource() |
| 74 | + except CUDAError as e: |
| 75 | + xfail_if_mempool_oom(e, device) |
| 76 | + raise |
64 | 77 | except RuntimeError as e: |
65 | 78 | if "requires CUDA 13.0" in str(e): |
66 | 79 | pytest.skip("ManagedMemoryResource requires CUDA 13.0 or later") |
67 | 80 | raise |
68 | 81 |
|
69 | 82 |
|
70 | | -def create_managed_memory_resource_or_skip(*args, **kwargs): |
| 83 | +def create_managed_memory_resource_or_skip(*args, xfail_device=None, **kwargs): |
| 84 | + # Keep the established "skip" helper name for call-site readability, even though |
| 85 | + # Windows MCDM mempool OOM setup failures are xfailed instead of skipped. |
71 | 86 | try: |
72 | 87 | return ManagedMemoryResource(*args, **kwargs) |
| 88 | + except CUDAError as e: |
| 89 | + xfail_if_mempool_oom(e, _device_id_from_resource_options(xfail_device, args, kwargs)) |
| 90 | + raise |
73 | 91 | except RuntimeError as e: |
74 | 92 | if "requires CUDA 13.0" in str(e): |
75 | 93 | pytest.skip("ManagedMemoryResource requires CUDA 13.0 or later") |
76 | 94 | raise |
77 | 95 |
|
78 | 96 |
|
| 97 | +def create_pinned_memory_resource_or_xfail(*args, xfail_device=None, **kwargs): |
| 98 | + try: |
| 99 | + return PinnedMemoryResource(*args, **kwargs) |
| 100 | + except CUDAError as e: |
| 101 | + xfail_if_mempool_oom(e, xfail_device) |
| 102 | + raise |
| 103 | + |
| 104 | + |
| 105 | +def _device_id_from_resource_options(device, args, kwargs): |
| 106 | + if device is not None: |
| 107 | + return device |
| 108 | + options = kwargs.get("options") |
| 109 | + if options is None and args: |
| 110 | + options = args[0] |
| 111 | + if options is None: |
| 112 | + return 0 |
| 113 | + if isinstance(options, dict): |
| 114 | + preferred_location = options.get("preferred_location") |
| 115 | + preferred_location_type = options.get("preferred_location_type") |
| 116 | + else: |
| 117 | + preferred_location = getattr(options, "preferred_location", None) |
| 118 | + preferred_location_type = getattr(options, "preferred_location_type", None) |
| 119 | + if preferred_location_type in (None, "device") and isinstance(preferred_location, int) and preferred_location >= 0: |
| 120 | + return preferred_location |
| 121 | + return 0 |
| 122 | + |
| 123 | + |
79 | 124 | @pytest.fixture(scope="session", autouse=True) |
80 | 125 | def session_setup(): |
81 | 126 | # Always init CUDA. |
|
0 commit comments