-
Notifications
You must be signed in to change notification settings - Fork 294
Four graph-API bugs, each with the regression test it needed #546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
YangXu1990uiuc
wants to merge
4
commits into
NVIDIA:develop
Choose a base branch
from
YangXu1990uiuc:yanxu/graph-api-bugfixes
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
4944ff7
Fix cudnn.Graph(workspace_alloc=False): its guard was never name-mangled
YangXu1990uiuc 6424a7e
Reach cudnn.experimental the way the comment above it already prescribes
YangXu1990uiuc 07d5450
Point the diagnostics at what actually failed
YangXu1990uiuc 00841a0
Let an environment probe decline instead of aborting the plan walk
YangXu1990uiuc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """An engine that cannot serve a graph must say so with a decline type. | ||
|
|
||
| ``build_plans()`` walks the ranked plan list and skips an entry that raises one | ||
| of ``engines.base.decline_types()``, moving on to the next plan and ultimately | ||
| to the cuDNN backend. Anything else propagates and aborts the walk, so a graph | ||
| the backend could have served fails outright. | ||
|
|
||
| "This machine has no CUDA device" and "the driver did not report the property I | ||
| need to size a pipeline" are declines: the engine cannot serve the graph, but | ||
| another entry in the list can. They were raising RuntimeError, which is not a | ||
| decline type and is not caught by the engines' own ``build_plan`` handlers | ||
| either, so a probe failure took down the whole walk instead of falling back. | ||
| """ | ||
|
|
||
| import pytest | ||
|
|
||
| import cudnn | ||
| from cudnn.engines.base import decline_types | ||
|
|
||
|
|
||
| @pytest.mark.L0 | ||
| def test_device_probes_decline_when_no_driver(monkeypatch): | ||
| from cudnn.frost import device | ||
|
|
||
| monkeypatch.setattr(device, "_driver", lambda: None) | ||
|
|
||
| with pytest.raises(decline_types()): | ||
| device.current_device() | ||
| with pytest.raises(decline_types()): | ||
| device._device_handle(0) | ||
| with pytest.raises(decline_types()): | ||
| with device.device_context(0): | ||
| pass | ||
|
|
||
|
|
||
| @pytest.mark.L0 | ||
| @pytest.mark.parametrize("probe", ["_sm_smem_budget_bytes_of", "_l2_swizzle_budget_bytes_of"]) | ||
| def test_tile_config_probes_decline_when_unavailable(monkeypatch, probe): | ||
| from cudnn.frost import device as frost_device | ||
| from cudnn.gemm.frost import tile_config | ||
|
|
||
| fn = getattr(tile_config, probe) | ||
| # Both probes are @lru_cache'd, so an earlier test that already queried this | ||
| # device would serve a cached answer and never reach the raise. | ||
| fn.cache_clear() | ||
| monkeypatch.setattr(frost_device, "is_available", lambda: False) | ||
| try: | ||
| with pytest.raises(decline_types()): | ||
| fn(0) | ||
| finally: | ||
| fn.cache_clear() | ||
|
|
||
|
|
||
| @pytest.mark.L0 | ||
| def test_decline_types_are_what_build_plans_skips(): | ||
| """The tuple is the contract; keep it and the walk in agreement.""" | ||
| assert NotImplementedError in decline_types() | ||
| assert cudnn.cudnnGraphNotSupportedError in decline_types() | ||
| assert ImportError in decline_types() | ||
| # RuntimeError must NOT be a decline: it is how an engine reports a bug, | ||
| # and swallowing it would hide real failures behind a silent fallback. | ||
| assert RuntimeError not in decline_types() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Tests for the fluent ``cudnn.Graph`` wrapper (python/cudnn/wrapper.py).""" | ||
|
|
||
| import pytest | ||
| import torch | ||
|
|
||
| import cudnn | ||
|
|
||
|
|
||
| def _matmul_graph(**kwargs): | ||
| """A 64x64 half matmul through the fluent wrapper.""" | ||
| with cudnn.Graph( | ||
| handle="auto", | ||
| io_data_type=cudnn.data_type.HALF, | ||
| compute_data_type=cudnn.data_type.FLOAT, | ||
| inputs=["X", "W"], | ||
| outputs=["Y"], | ||
| **kwargs, | ||
| ) as graph: | ||
| X = graph.tensor(name="X", dim=[1, 64, 64], stride=[64 * 64, 64, 1]) | ||
| W = graph.tensor(name="W", dim=[1, 64, 64], stride=[64 * 64, 64, 1]) | ||
| Y = graph.matmul(name="mm", A=X, B=W) | ||
| Y.set_output(True).set_name("Y") | ||
| return graph | ||
|
|
||
|
|
||
| @pytest.mark.L0 | ||
| def test_workspace_alloc_default_allocates(): | ||
| """The default path allocates a workspace the caller never has to think about.""" | ||
| graph = _matmul_graph() | ||
| assert torch.is_tensor(graph._Graph__workspace) | ||
|
|
||
|
|
||
| @pytest.mark.L0 | ||
| def test_workspace_alloc_false_is_honored(): | ||
| """``workspace_alloc=False`` means the CALLER owns the workspace. | ||
|
|
||
| Regression: the sentinel is written as ``self.__workspace`` (mangled to | ||
| ``_Graph__workspace``) but was read back with ``hasattr(self, "__workspace")`` | ||
| — a plain string, which is NOT name-mangled. That probe was therefore always | ||
| False, the sentinel was overwritten with a fresh allocation on every | ||
| ``__exit__``, and the "Need to specify workspace" guard below was unreachable. | ||
| """ | ||
| graph = _matmul_graph(workspace_alloc=False) | ||
| assert graph._Graph__workspace is False | ||
|
|
||
| x = torch.randn(1, 64, 64, dtype=torch.half, device="cuda") | ||
| w = torch.randn(1, 64, 64, dtype=torch.half, device="cuda") | ||
|
|
||
| with pytest.raises(RuntimeError, match="Need to specify workspace"): | ||
| graph(x, w) | ||
|
|
||
| workspace = torch.empty(max(graph.get_workspace_size(), 1), dtype=torch.uint8, device="cuda") | ||
| out = graph(x, w, workspace=workspace) | ||
| torch.testing.assert_close(out.float(), (x @ w).float(), atol=1e-2, rtol=1e-2) | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 50378
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 38965
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 50377
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 50377
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 15908
🏁 Script executed:
Repository: NVIDIA/cudnn-frontend
Length of output: 43090
Skip fluent graph tests on cuDNN versions below 9.12.0.
cudnn.GraphraisesRuntimeErrorwhencudnn.backend_version() < 91200. Add apytest.mark.skipiffor this condition. The shared CUDA assertion does not provide a skip.🤖 Prompt for AI Agents
Source: Coding guidelines