Skip to content

fix(bindings): guard unpopulated NVML field query results - #3148

Open
rwgk wants to merge 10 commits into
NVIDIA:mainfrom
rwgk:work_around_orin_nvml_field_values_bug
Open

rwgk wants to merge 10 commits into
NVIDIA:mainfrom
rwgk:work_around_orin_nvml_field_values_bug

Conversation

@rwgk

@rwgk rwgk commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Description

Protect nvml.device_get_field_values callers when native NVML returns aggregate success without populating an output entry. Initialize each entry's status to ERROR_UNKNOWN before every query, including queries that reuse a caller-provided buffer. Preserve native-written results and statuses, partial-batch results, and existing aggregate-error exceptions.

Default the scope to zero for plain integer field IDs while preserving explicit scopes. Regenerate the NVML binding from the cybind template.

Update the existing hardware NVLink test to exercise both caller-provided buffers and integer field-ID lists, including empty requests. Accept the defined fallback only for the known Orin case.

Validation

Jetson Orin hardware retest at 19089f0db52909b7b78684c9a6611db72c4162b0 on 2026-10-21 UTC: Linux aarch64, CUDA 13.4 / nvcc 13.4.59, driver 630.03, CPython 3.12.3. Posted run summary.

The build from cuda_bindings_13 completed successfully (exit status 0).

Suite Result
cuda-pathfinder 1,618 passed, 2 skipped
cuda-bindings, each of default and per-thread default stream modes 634 passed, 80 skipped, 17 warnings, 2 subtests passed
cuda-bindings Cython 9 passed
cuda-core 3,751 passed, 535 skipped, 3 xfailed, 5 warnings, 9 subtests passed; 2 failed and 1 teardown error
cuda-core Cython 1 passed

test_nvlink_get_link_count passed with both caller-provided buffers and integer field-ID lists in both stream modes.

The full QA command exited with status 1 because of these cuda-core results:

  • TestFileDescriptorLimit::test_export_near_the_limit: OSError: [Errno 9] Bad file descriptor.
  • test_dmr_check_capture_state[global]: CUDA_ERROR_STREAM_CAPTURE_INVALIDATED.
  • TestManyChunkBuffer::test_main teardown: BaselineMemoryResourceReleasedWarning for release of three pre-existing virtual-address reservations.

The failing traces contain no NVML frames; this run alone does not establish whether the failures are pre-existing.

Additional local validation on NVIDIA A10G / driver 620.43 / CUDA 13.4 / CPython 3.12.3: successful rebuild from the renamed source root; 6 remaining NVLink/core tests and 2 subtests passed. Cybind template/output tests: 35 passed. Repository-wide pre-commit checks passed.

References:

  • nvbug 6952048
  • cybind MR 591

Seed the field status with an invalid sentinel so a successful native no-op
cannot accidentally pass on recycled memory. Xfail when Orin leaves the
sentinel unchanged, preserving normal checks on fixed drivers and other
devices.

Label the workaround explicitly in the source comment and xfail reason.
@copy-pr-bot

copy-pr-bot Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the cuda.bindings Everything related to the cuda.bindings module label Oct 18, 2026
@rwgk rwgk added the bug Something isn't working label Oct 18, 2026
@rwgk rwgk self-assigned this Oct 18, 2026
@rwgk rwgk added this to the cuda.bindings next milestone Oct 18, 2026
@rwgk
rwgk marked this pull request as ready for review October 19, 2026 03:45
@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: df0633c4-a54b-42f4-9a94-4556a6c18824
📥 Commits

Reviewing files that changed from the base of the PR and between 35dbf78 and 3a1fcac.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 1c67ac7f-1a92-4d77-9847-d74c21f31d97
📥 Commits

Reviewing files that changed from the base of the PR and between fbf8f40 and 35dbf78.

📒 Files selected for processing: 3
  • cuda_bindings_13/cuda/bindings/nvml.pyx
  • cuda_bindings_13/tests/nvml/test_field_values.py
  • cuda_bindings_13/tests/nvml/test_nvlink.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes

    • Improved NVML field-value handling by reporting unpopulated entries as unknown and assigning the correct default scope for integer field IDs.
    • Preserved native return statuses and scope information when retrieving field values.
    • Avoided unnecessary native queries when no field values are requested.
  • Tests

    • Added coverage for field-value initialization, error propagation, scope handling, and empty requests.
    • Expanded NVLink link-count testing across supported input formats and platform-specific outcomes.

device_get_field_values initializes requested entries to NVML_ERROR_UNKNOWN, and integer field IDs receive scope ID zero. New tests exercise native results, errors, and empty requests. The NVLink test covers buffer and field-ID inputs.

Changes: NVML Field Value Handling

Layer / File(s) Summary
Field-value initialization and scope handling
cuda_bindings_13/cuda/bindings/nvml.pyx
Integer field-ID inputs now use scope ID zero. Requested entries start with NVML_ERROR_UNKNOWN before the native query. The documentation describes the status of entries NVML leaves unpopulated.
Field-value behavior tests
cuda_bindings_13/tests/nvml/test_field_values.py
A compiled NVML shim and subprocess tests cover unpopulated entries, native results and metadata, permission errors, and empty requests.
NVLink query input coverage
cuda_bindings_13/tests/nvml/test_nvlink.py
The test exercises buffer and field-ID inputs with scope ID zero and accepts the specified statuses, including ERROR_UNKNOWN for Orin (nvgpu).

Suggested reviewers: mdboom

Priority: ⬇️ Low

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 35dbf

The Orin test no longer skips checks for later devices. No actionable merge-blocking issue remains after normal checks.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 85c60964-6f71-40be-90e0-cf913a2bf0c1
📥 Commits

Reviewing files that changed from the base of the PR and between 576ef68 and 412659b.

📒 Files selected for processing: 1
  • cuda_bindings/tests/nvml/test_nvlink.py

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread cuda_bindings/tests/nvml/test_nvlink.py Outdated
fields[0].nvml_return = -1
value = nvml.device_get_field_values(device, fields)[0]
if value.nvml_return == -1 and "Orin" in nvml.device_get_name(device):
pytest.xfail(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

set -eu
printf '%s\n' '--- reviewed head test ---'
git show 412659b856b8c1d7086bdef9351f66e3b4cecabd:cuda_bindings/tests/nvml/test_nvlink.py | nl -ba | sed -n '1,90p'
printf '%s\n' '--- base test ---'
git show 576ef68874f2fcbbb00f7f2302960c3b20597164:cuda_bindings/tests/nvml/test_nvlink.py | nl -ba | sed -n '1,90p'
printf '%s\n' '--- diff ---'
git diff --unified=30 576ef68874f2fcbbb00f7f2302960c3b20597164 412659b856b8c1d7086bdef9351f66e3b4cecabd -- cuda_bindings/tests/nvml/test_nvlink.py

Repository: NVIDIA/cuda-python

Length of output: 5440


important: Defer the Orin xfail only after bypassing its sentinel assertion.

When the Orin sentinel remains, moving pytest.xfail() after the loop still reaches the first return-code assertion, which rejects -1 before the alternate query and later devices run. Record the Orin condition, skip only that assertion, keep the alternate query active, and call pytest.xfail() after the loop.

Suggested fix
 def test_nvlink_get_link_count(all_devices):
     """
     Checks that the link count of the device is same.
     """
+    orin_nvml_bug = False
     for device in all_devices:
...
         value = nvml.device_get_field_values(device, fields)[0]
         if value.nvml_return == -1 and "Orin" in nvml.device_get_name(device):
-            pytest.xfail(
-                "Orin NVML nvbug 6952048: nvmlDeviceGetFieldValues returns success without populating the result"
-            )
-        assert value.nvml_return == nvml.Return.SUCCESS or value.nvml_return == nvml.Return.ERROR_NOT_SUPPORTED, (
-            f"Unexpected return {value.nvml_return} for link count field query"
-        )
+            orin_nvml_bug = True
+        else:
+            assert value.nvml_return == nvml.Return.SUCCESS or value.nvml_return == nvml.Return.ERROR_NOT_SUPPORTED, (
+                f"Unexpected return {value.nvml_return} for link count field query"
+            )
...
         assert value.nvml_return == nvml.Return.SUCCESS or value.nvml_return == nvml.Return.ERROR_NOT_SUPPORTED, (
             f"Unexpected return {value.nvml_return} for link count field query"
         )
+
+    if orin_nvml_bug:
+        pytest.xfail(
+            "Orin NVML nvbug 6952048: nvmlDeviceGetFieldValues returns success without populating the result"
+        )

@github-actions

Copy link
Copy Markdown
Contributor

@rwgk
rwgk requested a review from mdboom October 19, 2026 05:12

@mdboom mdboom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think we should just workaround this in a test. Seems like a bug that we should protect our users from. That is, we should set an error code inside of the device_get_field_values function and populate the error back out.

@rwgk
rwgk marked this pull request as draft October 19, 2026 23:57
@rwgk rwgk changed the title test(bindings): work around Orin NVML field-values bug fix(bindings): guard unpopulated NVML field query results Oct 20, 2026
@rwgk

rwgk commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test fbf8f40

@rwgk
rwgk marked this pull request as ready for review October 20, 2026 02:08
@rwgk

rwgk commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@mdboom is this the direction you had in mind?

@rwgk

rwgk commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Orin @ fbf8f40:

jetson:~/wrk/forked/work_around_orin_nvml_field_values_bug $ grep_pytest_summary `nlog`
/home/rgrossekunst/wrk/logs/work_around_orin_nvml_field_values_bug_qa_bindings_linux_2026-10-20+005518+0000_tests_log.txt
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_pathfinder
======================= 1618 passed, 2 skipped in 13.75s =======================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings
== 641 passed, 80 skipped, 17 warnings, 2 subtests passed in 71.23s (0:01:11) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings
== 641 passed, 80 skipped, 17 warnings, 2 subtests passed in 69.32s (0:01:09) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings
============================== 9 passed in 1.00s ===============================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
= 3747 passed, 535 skipped, 3 xfailed, 3 warnings, 9 subtests passed in 134.38s (0:02:14) =
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
============================== 1 passed in 0.40s ===============================

@mdboom mdboom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This LGTM, but let's merge the generator side first then this.

I wouldn't include the test_field_values.py file at all. It's mostly just testing that a mock works and isn't really testing anything in practice about upstream NVML. I worry it will just fail at some unrelated moment in the future. The changes to the existing test in test_nvlink.py looks much better and I think covers what we need to.

rwgk added 2 commits October 20, 2026 15:47
Generated from cybind commit adf423398b177ab19e017b33173178ceee36157f. Use the FieldValue array property to initialize per-query errors, incorporating the review suggestion from cybind MR 591.
…→work_around_orin_nvml_field_values_bug

# Conflicts:
#	cuda_bindings_13/tests/nvml/test_field_values.py
@rwgk
rwgk marked this pull request as draft October 21, 2026 00:14
@rwgk

rwgk commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Orin @ 19089f0:

jetson:~/wrk/forked/work_around_orin_nvml_field_values_bug $ grep_pytest_summary `nlog`
/home/rgrossekunst/wrk/logs/work_around_orin_nvml_field_values_bug_qa_bindings_linux_2026-10-21+003925+0000_tests_log.txt
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_pathfinder
======================= 1618 passed, 2 skipped in 13.80s =======================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 68.78s (0:01:08) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 67.59s (0:01:07) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
============================== 9 passed in 0.99s ===============================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
= 2 failed, 3751 passed, 535 skipped, 3 xfailed, 5 warnings, 1 error, 9 subtests passed in 139.27s (0:02:19) =
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
============================== 1 passed in 0.38s ===============================

@rwgk

rwgk commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Attempting to deflake:

Orin @ 19089f0 attempt 2:

/home/rgrossekunst/wrk/logs/work_around_orin_nvml_field_values_bug_qa_bindings_linux_2026-10-21+005219+0000_tests_log.txt
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_pathfinder
======================= 1618 passed, 2 skipped in 13.18s =======================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 65.74s (0:01:05) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 66.54s (0:01:06) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
============================== 9 passed in 1.00s ===============================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
= 1 failed, 3752 passed, 535 skipped, 3 xfailed, 3 warnings, 1 error, 9 subtests passed in 116.76s (0:01:56) =
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
============================== 1 passed in 0.39s ===============================

@rwgk

rwgk commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Attempting to deflake:

Orin @ 19089f0 attempt 3:

/home/rgrossekunst/wrk/logs/work_around_orin_nvml_field_values_bug_qa_bindings_linux_2026-10-21+005858+0000_tests_log.txt
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_pathfinder
======================= 1618 passed, 2 skipped in 13.32s =======================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 67.09s (0:01:07) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
== 634 passed, 80 skipped, 17 warnings, 2 subtests passed in 67.32s (0:01:07) ==
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_bindings_13
============================== 9 passed in 1.22s ===============================
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
= 1 failed, 3751 passed, 536 skipped, 3 xfailed, 5 warnings, 1 error, 9 subtests passed in 120.23s (0:02:00) =
rootdir: /home/rgrossekunst/wrk/forked/work_around_orin_nvml_field_values_bug/cuda_core
============================== 1 passed in 0.40s ===============================

@rwgk

rwgk commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Both reruns reproduce the same IPC export failure, and each also has one teardown error. The teardown error is very likely fallout from the export failure.

Run Failed test Teardown error
Attempt 2 test_export_near_the_limit Process-argument lifetime test
Attempt 3 test_export_near_the_limit TestManyChunkBuffer::test_main

The original graph-capture failure passes in both reruns. Both NVLink input forms also continue to pass in both stream modes.

The primary failure has a revealing exception chain:

  1. The test deliberately lowers the file-descriptor limit.
  2. The CUDA export status check accepts success, but the resulting descriptor is -24, matching Linux -EMFILE—“too many open files.”
  3. Handle construction rejects it with ValueError.
  4. Rollback calls os.close(-24), raising EBADF and masking that first exception. Export and rollback code

This strongly suggests a native CUDA export error-reporting defect under descriptor exhaustion, alongside a cuda-core cleanup bug. A small native reproducer should confirm the exact CUDA return/output pair.

The teardown errors have a consistent explanation. The unexpected exception bypasses the FD-limit test’s buffer-closing loop, leaving three virtual-memory reservations alive. That cleanup sits after the finally block. Test cleanup

In all three runs, the first later test that explicitly invokes garbage collection releases exactly those three older reservations. The fixture then reports a baseline-resource release during teardown. Changing the random seed changes which test receives the error. Traceback retention is the likely mechanism, although the logs do not identify the retaining references directly.

I would investigate this separately from PR 3148: the IPC code is unchanged by that PR. The useful next steps are an isolated Orin reproduction of the FD-limit test, a native export probe, and cleanup fixes that preserve the original exception and close buffers on every exit. Further whole-suite reruns are unlikely to resolve this repeatable failure.

@rwgk
rwgk marked this pull request as ready for review October 21, 2026 03:53
@rwgk

rwgk commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

@mdboom Both MR 591 and this PR are merge-ready.

Unfortunately there is a new, unrelated failure on Orin. I'll work on that separately.

@rwgk
rwgk enabled auto-merge (squash) October 21, 2026 06:30

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working cuda.bindings Everything related to the cuda.bindings module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants