Repository navigation
test(helpers): keep the EGL device probe from importing pyglet.gl - #3027
Conversation
select_headless_egl_device_for_cuda runs before the graphics tests set pyglet.options["headless_device"]. Importing pyglet.gl there creates pyglet's shadow window, which in headless mode opens the EGL display on device 0 and caches it, so the later headless_device assignment has no effect and the GL context lands on EGL device 0 again (NVIDIA#2864). Match MissingFunctionException by module and name instead, as is_gl_context_unavailable already does, and add a subprocess test that asserts the probe leaves pyglet.gl unimported. Follow-up to NVIDIA#3020. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
CI does not install cuda_python_test_helpers; the parent imports it only through the conftest sys.path fallback, which the -c child does not inherit, so test_egl_device_probe_does_not_import_pyglet_gl failed in every Linux row with ModuleNotFoundError. The child now gets a PYTHONPATH that names the parent directory of the package the parent imported, and a failure reports the child's stderr. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
📝 SummarySummary by CodeRabbit
WalkthroughThe EGL device probe no longer imports ChangesHeadless EGL probe
Suggested reviewers: Priority: ⬇️ Low Change: Bug fix Merge Risk: 🔵 Low · up to The EGL regression test can stall on a system where device probing hangs. Add a subprocess timeout before merging, or accept this bounded test-run risk.
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: NVIDIA/cuda-python/.coderabbit.yaml
- Review profile: CHILL
- Plan: Enterprise
- Run ID:
cfa2f253-9dee-4a61-9ef2-0aa48edc8019
📒 Files selected for processing (2)
cuda_core/tests/test_graphics.pycuda_python_test_helpers/cuda_python_test_helpers/graphics.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.
| proc = subprocess.run( # noqa: S603 - trusted argv: this interpreter | ||
| [sys.executable, "-c", code], capture_output=True, text=True, env=env | ||
| ) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
suggestion: Bound the EGL probe subprocess. If EGL initialization or the probe blocks, subprocess.run waits indefinitely and stalls the test run. Set a timeout and report subprocess.TimeoutExpired as a test failure. Based on learnings: flag process-spawning calls without a timeout because a hung child can block indefinitely.
🧰 Tools
🪛 ast-grep (0.45.3)
[error] 104-106: Command coming from incoming request
Context: subprocess.run( # noqa: S603 - trusted argv: this interpreter
[sys.executable, "-c", code], capture_output=True, text=True, env=env
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
Source: Learnings
Summary
Follow-up to #3020. The narrowed catch imports
pyglet.gl.lib.MissingFunctionExceptioninsideselect_headless_egl_device_for_cuda, which runs before_configure_pyglet_headless()setspyglet.options["headless_device"]. Importingpyglet.glcreates pyglet's shadow window (pyglet/gl/__init__.pyimportspyglet.windowat the bottom). In headless modeHeadlessDisplay.__init__readsheadless_deviceat that moment, andpyglet.display.get_display()returns the cached display afterwards, so the laterheadless_deviceassignment has no effect. The headless tests run in the shadow window's context, so on the multi-GPU systems #2865 fixed, the GL context lands on EGL device 0 again andcuGraphicsGLRegister*fails with the originalCUDA_ERROR_INVALID_DEVICE. Before #3020 the probe imported onlypyglet.libs.egl, which does not importpyglet.gl.CI cannot detect this: no runner has an EGL device order that differs from the CUDA device order.
Changes
cuda_python_test_helpers/graphics.py: drop thepyglet.gl.libimport from the probe and matchMissingFunctionExceptionby module and name through a small helper, the same patternis_gl_context_unavailableuses. Everything else still propagates. The module docstring now states the rule.cuda_core/tests/test_graphics.py: addtest_egl_device_probe_does_not_import_pyglet_gl, which runs the probe in a subprocess withheadlessset and assertspyglet.glis not insys.modules.Verification
Reproducible without a GPU on any Linux host with a libEGL (shown here with Mesa):
With the default
headless_device, the import leaves aShadowWindowand a cachedHeadlessDisplaybehind; the fixed probe leavespyglet.glunimported. The multi-GPU case itself was not re-run on hardware with a divergent device order.Related Work
🤖 Generated with Claude Code