From 61b5de2b6bc1b64e3f55c33393fd26f1202c65f6 Mon Sep 17 00:00:00 2001 From: Monishver Chandrasekaran Date: Tue, 13 Jan 2026 22:56:39 -0500 Subject: [PATCH 1/3] feat: Make legacy_default and per_thread_default public - Fixes #1445 Signed-off-by: Monishver Chandrasekaran --- cuda_core/cuda/core/_stream.pyx | 56 +++++++++++++++++++++++++++++---- cuda_core/tests/test_stream.py | 20 +++++++++--- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/cuda_core/cuda/core/_stream.pyx b/cuda_core/cuda/core/_stream.pyx index d1747abe2d..83a09c3f7c 100644 --- a/cuda_core/cuda/core/_stream.pyx +++ b/cuda_core/cuda/core/_stream.pyx @@ -107,13 +107,57 @@ cdef class Stream: return s @classmethod - def _legacy_default(cls): - """Return the legacy default stream (supports subclassing).""" + def legacy_default(cls): + """Return the legacy default stream. + + The legacy default stream is an implicit stream which synchronizes + with all other streams in the same CUDA context except for non-blocking + streams. When any operation is launched on the legacy default stream, + it waits for all previously launched operations in blocking streams to + complete, and all subsequent operations in blocking streams wait for + the legacy default stream operation to complete. + + Returns + ------- + Stream + The legacy default stream instance for the current context. + + See Also + -------- + per_thread_default : Per-thread default stream alternative. + + Examples + -------- + >>> stream = Stream.legacy_default() + >>> stream.sync() # Synchronize all operations + """ return Stream._from_handle(cls, get_legacy_stream()) @classmethod - def _per_thread_default(cls): - """Return the per-thread default stream (supports subclassing).""" + def per_thread_default(cls): + """Return the per-thread default stream. + + The per-thread default stream is local to both the calling thread and + the CUDA context. Unlike the legacy default stream, it does not + synchronize with other streams and behaves like an explicitly created + non-blocking stream. This allows for better concurrency in multi-threaded + applications. + + Returns + ------- + Stream + The per-thread default stream instance for the current thread + and context. + + See Also + -------- + legacy_default : Legacy default stream alternative. + + Examples + -------- + >>> stream = Stream.per_thread_default() + >>> stream.sync() # Synchronize only this thread's operations + """ return Stream._from_handle(cls, get_per_thread_stream()) @classmethod @@ -378,8 +422,8 @@ cdef class Stream: # c-only python objects, not public -cdef Stream C_LEGACY_DEFAULT_STREAM = Stream._legacy_default() -cdef Stream C_PER_THREAD_DEFAULT_STREAM = Stream._per_thread_default() +cdef Stream C_LEGACY_DEFAULT_STREAM = Stream.legacy_default() +cdef Stream C_PER_THREAD_DEFAULT_STREAM = Stream.per_thread_default() # standard python objects, public LEGACY_DEFAULT_STREAM = C_LEGACY_DEFAULT_STREAM diff --git a/cuda_core/tests/test_stream.py b/cuda_core/tests/test_stream.py index 925daa7cd5..f9c62fa967 100644 --- a/cuda_core/tests/test_stream.py +++ b/cuda_core/tests/test_stream.py @@ -116,18 +116,28 @@ class MyStream(Stream): def test_stream_legacy_default_subclassing(): class MyStream(Stream): pass - - stream = MyStream._legacy_default() + stream = MyStream.legacy_default() assert isinstance(stream, MyStream) - def test_stream_per_thread_default_subclassing(): class MyStream(Stream): pass - - stream = MyStream._per_thread_default() + stream = MyStream.per_thread_default() assert isinstance(stream, MyStream) +def test_stream_legacy_default_public_api(): + """Test public legacy_default() method.""" + stream = Stream.legacy_default() + assert isinstance(stream, Stream) + # Verify it's the same as LEGACY_DEFAULT_STREAM + assert stream == LEGACY_DEFAULT_STREAM + +def test_stream_per_thread_default_public_api(): + """Test public per_thread_default() method.""" + stream = Stream.per_thread_default() + assert isinstance(stream, Stream) + # Verify it's the same as PER_THREAD_DEFAULT_STREAM + assert stream == PER_THREAD_DEFAULT_STREAM # ============================================================================ # Stream Equality Tests From 8c9a466843d3352810aad1981966d5ad73796920 Mon Sep 17 00:00:00 2001 From: Monishver Chandrasekaran Date: Wed, 14 Jan 2026 09:50:04 -0500 Subject: [PATCH 2/3] feat: Make legacy_default and per_thread_default public - Fixes #1445 Signed-off-by: Monishver Chandrasekaran --- cuda_core/cuda/core/_stream.pyx | 44 ++++++++++++++------------------- cuda_core/tests/test_stream.py | 6 +++++ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/cuda_core/cuda/core/_stream.pyx b/cuda_core/cuda/core/_stream.pyx index 83a09c3f7c..05cbcce76a 100644 --- a/cuda_core/cuda/core/_stream.pyx +++ b/cuda_core/cuda/core/_stream.pyx @@ -109,54 +109,46 @@ cdef class Stream: @classmethod def legacy_default(cls): """Return the legacy default stream. - - The legacy default stream is an implicit stream which synchronizes - with all other streams in the same CUDA context except for non-blocking - streams. When any operation is launched on the legacy default stream, - it waits for all previously launched operations in blocking streams to - complete, and all subsequent operations in blocking streams wait for + + The legacy default stream is an implicit stream which synchronizes + with all other streams in the same CUDA context except for non-blocking + streams. When any operation is launched on the legacy default stream, + it waits for all previously launched operations in blocking streams to + complete, and all subsequent operations in blocking streams wait for the legacy default stream operation to complete. - + Returns ------- Stream The legacy default stream instance for the current context. - + See Also -------- per_thread_default : Per-thread default stream alternative. - - Examples - -------- - >>> stream = Stream.legacy_default() - >>> stream.sync() # Synchronize all operations + """ return Stream._from_handle(cls, get_legacy_stream()) @classmethod def per_thread_default(cls): """Return the per-thread default stream. - - The per-thread default stream is local to both the calling thread and - the CUDA context. Unlike the legacy default stream, it does not - synchronize with other streams and behaves like an explicitly created - non-blocking stream. This allows for better concurrency in multi-threaded + + The per-thread default stream is local to both the calling thread and + the CUDA context. Unlike the legacy default stream, it does not + synchronize with other streams and behaves like an explicitly created + non-blocking stream. This allows for better concurrency in multi-threaded applications. - + Returns ------- Stream - The per-thread default stream instance for the current thread + The per-thread default stream instance for the current thread and context. - + See Also -------- legacy_default : Legacy default stream alternative. - - Examples - -------- - >>> stream = Stream.per_thread_default() - >>> stream.sync() # Synchronize only this thread's operations + """ return Stream._from_handle(cls, get_per_thread_stream()) diff --git a/cuda_core/tests/test_stream.py b/cuda_core/tests/test_stream.py index f9c62fa967..70beb5b40f 100644 --- a/cuda_core/tests/test_stream.py +++ b/cuda_core/tests/test_stream.py @@ -116,15 +116,19 @@ class MyStream(Stream): def test_stream_legacy_default_subclassing(): class MyStream(Stream): pass + stream = MyStream.legacy_default() assert isinstance(stream, MyStream) + def test_stream_per_thread_default_subclassing(): class MyStream(Stream): pass + stream = MyStream.per_thread_default() assert isinstance(stream, MyStream) + def test_stream_legacy_default_public_api(): """Test public legacy_default() method.""" stream = Stream.legacy_default() @@ -132,6 +136,7 @@ def test_stream_legacy_default_public_api(): # Verify it's the same as LEGACY_DEFAULT_STREAM assert stream == LEGACY_DEFAULT_STREAM + def test_stream_per_thread_default_public_api(): """Test public per_thread_default() method.""" stream = Stream.per_thread_default() @@ -139,6 +144,7 @@ def test_stream_per_thread_default_public_api(): # Verify it's the same as PER_THREAD_DEFAULT_STREAM assert stream == PER_THREAD_DEFAULT_STREAM + # ============================================================================ # Stream Equality Tests # ============================================================================ From 4b8a53ce4731d53282101c4deada2ac1009eb66c Mon Sep 17 00:00:00 2001 From: Monishver Chandrasekaran Date: Wed, 14 Jan 2026 11:16:17 -0500 Subject: [PATCH 3/3] added init_cuda for test_stream methods --- cuda_core/tests/test_stream.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cuda_core/tests/test_stream.py b/cuda_core/tests/test_stream.py index 70beb5b40f..a40910dbf4 100644 --- a/cuda_core/tests/test_stream.py +++ b/cuda_core/tests/test_stream.py @@ -129,7 +129,7 @@ class MyStream(Stream): assert isinstance(stream, MyStream) -def test_stream_legacy_default_public_api(): +def test_stream_legacy_default_public_api(init_cuda): """Test public legacy_default() method.""" stream = Stream.legacy_default() assert isinstance(stream, Stream) @@ -137,7 +137,7 @@ def test_stream_legacy_default_public_api(): assert stream == LEGACY_DEFAULT_STREAM -def test_stream_per_thread_default_public_api(): +def test_stream_per_thread_default_public_api(init_cuda): """Test public per_thread_default() method.""" stream = Stream.per_thread_default() assert isinstance(stream, Stream)