Skip to content

cuda.core: Fix graphics tests - #2701

Merged
juenglin merged 7 commits into
NVIDIA:mainfrom
juenglin:graphics-tests
Aug 27, 2026
Merged

cuda.core: Fix graphics tests#2701
juenglin merged 7 commits into
NVIDIA:mainfrom
juenglin:graphics-tests

Conversation

@juenglin

@juenglin juenglin commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description

The GL context helpers in cuda_core/tests/test_graphics.py and cuda_bindings/tests/test_graphics_apis.py wrapped yield in except Exception and called pytest.skip(), so CUDA errors, assertion failures, and TypeErrors raised in the test body were recorded as "could not create GL context" skips rather than failures. The cuda_core graphics tests also never requested init_cuda, so whether from_gl_buffer / from_gl_image succeeded depended on leftover thread state from the previous test (pytest-randomly seed).

This PR:

  • Splits each helper into a plain setup function (_configure_pyglet_headless, _open_gl_window, _setup_gl_buffer, _setup_gl_texture) and a thin context manager that wraps only the setup call in try/except so test-body exceptions propagate as failures.
  • Adds init_cuda to every cuda_core graphics test that touches CUDA, and uses init_cuda.create_stream() instead of a local _create_stream() helper.
  • Converts the cuda_core test classes to plain test functions (they carried no shared state or fixtures).
  • Fixes two StridedMemoryView.from_buffer call sites that passed dtype=np.float32 (a scalar type class) instead of np.dtype(np.float32).
  • Marks test_close_while_mapped_passes_stream_override as xfail(strict=True) because Buffer is an immutable Cython type and neither patch.object nor __class__ assignment can intercept Buffer.close.

Checklist

  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@copy-pr-bot

copy-pr-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Aug 25, 2026
@juenglin juenglin added bug Something isn't working P0 High priority - Must do! test Improvements or additions to tests labels Aug 25, 2026
@juenglin juenglin added this to the cuda.core 1.2.0 milestone Aug 25, 2026
@juenglin juenglin self-assigned this Aug 25, 2026
Stop treating graphics test-body failures as GL-unavailable skips, and bind a CUDA context in those tests so missing thread state cannot hide real errors.
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test baf3e23

@github-actions

This comment has been minimized.


with patch.object(Buffer, "close", new=tracking_close):
resource.close(stream=close_stream)
@pytest.mark.xfail(

@juenglin juenglin Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I couldn't get this test to work. Should I remove it?

============================================================= short test summary info =============================================================
FAILED cuda_core/tests/test_graphics.py::test_close_while_mapped_passes_stream_override - TypeError: cannot set 'close' attribute of immutable type 'cuda.core._memory._buffer.Buffer'
========================================================== 1 failed, 29 passed in 0.63s ===========================================================

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.

Yes, I agree with removing it. The stream behavior of Buffer.close() is already covered elsewhere.

@juenglin
juenglin marked this pull request as ready for review August 26, 2026 14:51
@github-actions github-actions Bot added the cuda.bindings Everything related to the cuda.bindings module label Aug 26, 2026
@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 8fbb9cf

@juenglin

Copy link
Copy Markdown
Contributor Author

pre-commit.ci run

@juenglin

Copy link
Copy Markdown
Contributor Author

/ok to test 5dc9814

@Andy-Jost Andy-Jost 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.

Looks good. The structure is improved and the main problem is addressed. Found a few minor issues to optionally clean up.

Comment thread cuda_core/pixi.lock

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.

Were the changes to this file intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I updated the lock file after adding the missing pyglet test dependency.

Comment on lines +76 to +85
def _setup_gl_buffer(pyglet, nbytes):
"""Open a GL context and allocate a buffer. Returns (win, buf_id)."""
win = _open_gl_window(pyglet)
from pyglet.gl import gl as _gl

buf_id = _gl.GLuint(0)
_gl.glGenBuffers(1, ctypes.byref(buf_id))
_gl.glBindBuffer(_gl.GL_ARRAY_BUFFER, buf_id.value)
_gl.glBufferData(_gl.GL_ARRAY_BUFFER, nbytes, None, _gl.GL_DYNAMIC_DRAW)
return win, buf_id

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.

Optional: if setup fails after creating win or buf_id, those resources may leak. Low severity.

Comment on lines +88 to +100
def _setup_gl_texture(pyglet, width, height):
"""Open a GL context and allocate a 2-D RGBA8 texture. Returns (win, tex_id, target)."""
win = _open_gl_window(pyglet)
from pyglet.gl import gl as _gl

tex_id = _gl.GLuint(0)
_gl.glGenTextures(1, ctypes.byref(tex_id))
target = _gl.GL_TEXTURE_2D
_gl.glBindTexture(target, tex_id.value)
_gl.glTexParameteri(target, _gl.GL_TEXTURE_MIN_FILTER, _gl.GL_NEAREST)
_gl.glTexParameteri(target, _gl.GL_TEXTURE_MAG_FILTER, _gl.GL_NEAREST)
_gl.glTexImage2D(target, 0, _gl.GL_RGBA8, width, height, 0, _gl.GL_RGBA, _gl.GL_UNSIGNED_BYTE, None)
return win, tex_id, target

@Andy-Jost Andy-Jost Aug 27, 2026

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.

Optional: similarly, a failure after creating win or tex_id may leave those resources uncleaned. Low severity.


with patch.object(Buffer, "close", new=tracking_close):
resource.close(stream=close_stream)
@pytest.mark.xfail(

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.

Yes, I agree with removing it. The stream behavior of Buffer.close() is already covered elsewhere.

Comment on lines +24 to +50
def _setup_gl_texture(pyglet):
"""Open a GL context and allocate a 2-D RGBA8 texture. Returns (win, tex_id, target)."""
if not pyglet.options.get("headless"):
# Hidden window path (WGL on Windows, GLX/WLS on Linux)
from pyglet import gl

config = gl.Config(double_buffer=False)
win = pyglet.window.Window(visible=False, config=config)
win.switch_to()
else:
# Headless EGL path; pyglet will arrange a pbuffer-like headless context
from pyglet.gl import headless # noqa: F401

win = None

# Make a tiny texture so we have a real GL object to register
from pyglet.gl import gl as _gl

tex_id = _gl.GLuint(0)
_gl.glGenTextures(1, ctypes.byref(tex_id))
target = _gl.GL_TEXTURE_2D
_gl.glBindTexture(target, tex_id.value)
_gl.glTexParameteri(target, _gl.GL_TEXTURE_MIN_FILTER, _gl.GL_NEAREST)
_gl.glTexParameteri(target, _gl.GL_TEXTURE_MAG_FILTER, _gl.GL_NEAREST)
width, height = 16, 16
_gl.glTexImage2D(target, 0, _gl.GL_RGBA8, width, height, 0, _gl.GL_RGBA, _gl.GL_UNSIGNED_BYTE, None)
return win, tex_id, target

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.

Optional: same potential leak issue here

@juenglin

Copy link
Copy Markdown
Contributor Author

Thanks. I have a few more things for a follow-on PR and will address your comments there.

@juenglin
juenglin merged commit 190527c into NVIDIA:main Aug 27, 2026
111 checks passed
@github-actions

Copy link
Copy Markdown
Doc Preview CI
Preview removed because the pull request was closed or merged.

juenglin added a commit to juenglin/cuda-python that referenced this pull request Aug 27, 2026
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 cuda.core Everything related to the cuda.core module P0 High priority - Must do! test Improvements or additions to tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants