Coverage for cuda / core / _stream.pyx: 87.91%

182 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-08 01:07 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

5from __future__ import annotations 

6  

7from libc.stdint cimport uintptr_t, INT32_MIN 

8from libc.stdlib cimport strtol, getenv 

9  

10from cuda.bindings cimport cydriver 

11  

12from cuda.core._event cimport Event as cyEvent 

13from cuda.core._utils.cuda_utils cimport ( 

14 check_or_create_options, 

15 HANDLE_RETURN, 

16) 

17  

18import cython 

19import warnings 

20from dataclasses import dataclass 

21from typing import Protocol 

22  

23from cuda.core._context cimport Context 

24from cuda.core._event import Event, EventOptions 

25from cuda.core._resource_handles cimport ( 

26 ContextHandle, 

27 EventHandle, 

28 StreamHandle, 

29 create_context_handle_ref, 

30 create_event_handle_noctx, 

31 create_stream_handle, 

32 create_stream_handle_with_owner, 

33 get_current_context, 

34 get_legacy_stream, 

35 get_per_thread_stream, 

36 as_intptr, 

37 as_cu, 

38 as_py, 

39) 

40  

41from cuda.core._graph import GraphBuilder 

42  

43  

44@dataclass 

45cdef class StreamOptions: 

46 """Customizable :obj:`~_stream.Stream` options. 

47  

48 Attributes 

49 ---------- 

50 nonblocking : bool, optional 

51 Stream does not synchronize with the NULL stream. (Default to True) 

52 priority : int, optional 

53 Stream priority where lower number represents a 

54 higher priority. (Default to lowest priority) 

55  

56 """ 

57  

58 nonblocking : cython.bint = True 

59 priority: int | None = None 

60  

61  

62class IsStreamT(Protocol): 

63 def __cuda_stream__(self) -> tuple[int, int]: 

64 """ 

65 For any Python object that is meant to be interpreted as a CUDA stream, the intent 

66 can be communicated by implementing this protocol that returns a 2-tuple: The protocol 

67 version number (currently ``0``) and the address of ``cudaStream_t``. Both values 

68 should be Python `int`. 

69 """ 

70 ... 

71  

72  

73cdef class Stream: 

74 """Represent a queue of GPU operations that are executed in a specific order. 

75  

76 Applications use streams to control the order of execution for 

77 GPU work. Work within a single stream are executed sequentially. 

78 Whereas work across multiple streams can be further controlled 

79 using stream priorities and :obj:`~_event.Event` managements. 

80  

81 Advanced users can utilize default streams for enforce complex 

82 implicit synchronization behaviors. 

83  

84 Directly creating a :obj:`~_stream.Stream` is not supported due to ambiguity. 

85 New streams should instead be created through a :obj:`~_device.Device` 

86 object, or created directly through using an existing handle 

87 using Stream.from_handle(). 

88 """ 

89 def __init__(self, *args, **kwargs): 

90 raise RuntimeError( 27e

91 "Stream objects cannot be instantiated directly. " 

92 "Please use Device APIs (create_stream) or other Stream APIs (from_handle)." 

93 ) 

94  

95 @staticmethod 

96 cdef Stream _from_handle(type cls, StreamHandle h_stream): 

97 """Create a Stream from an existing StreamHandle (cdef-only factory).""" 

98 cdef Stream s = cls.__new__(cls) 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

99 s._h_stream = h_stream 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

100 # _h_context is default-initialized to empty ContextHandle by C++ 

101 s._device_id = -1 # lazy init'd (invalid sentinel) 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

102 s._nonblocking = -1 # lazy init'd 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

103 s._priority = INT32_MIN # lazy init'd 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

104 return s 2Y Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cLdM MdQb@ J dd/c:cW X

105  

106 @classmethod 

107 def _legacy_default(cls): 

108 """Return the legacy default stream (supports subclassing).""" 

109 return Stream._from_handle(cls, get_legacy_stream()) 2Y Ld

110  

111 @classmethod 

112 def _per_thread_default(cls): 

113 """Return the per-thread default stream (supports subclassing).""" 

114 return Stream._from_handle(cls, get_per_thread_stream()) 2Y Md

115  

116 @classmethod 

117 def _init(cls, obj: IsStreamT | None = None, options=None, device_id: int = None, 

118 ctx: Context = None): 

119 cdef StreamHandle h_stream 

120 cdef cydriver.CUstream borrowed 

121 cdef ContextHandle h_context 

122 cdef Stream self 

123  

124 # Extract context handle if provided 

125 if ctx is not None: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cM Qb@ J dd/c:cW X

126 h_context = (<Context>ctx)._h_context 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J /c:cW X

127  

128 if obj is not None and options is not None: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cM Qb@ J dd/c:cW X

129 raise ValueError("obj and options cannot be both specified") 

130 if obj is not None: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u cd}c~cI Ub-cMb.cM Qb@ J dd/c:cW X

131 # Borrowed stream from foreign object 

132 # C++ handle prevents owner from being GC'd until handle is released 

133 # Owner is responsible for keeping the stream's context alive 

134 borrowed = _handle_from_stream_protocol(obj) 2D G H K L u cdI M J X

135 h_stream = create_stream_handle_with_owner(borrowed, obj) 2D G H K L u cdI M J

136 return Stream._from_handle(cls, h_stream) 2D G H K L u cdI M J

137  

138 cdef StreamOptions opts = check_or_create_options(StreamOptions, options, "Stream options") 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

139 nonblocking = opts.nonblocking 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

140 priority = opts.priority 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

141  

142 cdef unsigned int flags = (cydriver.CUstream_flags.CU_STREAM_NON_BLOCKING if nonblocking 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

143 else cydriver.CUstream_flags.CU_STREAM_DEFAULT) 

144 # TODO: we might want to consider memoizing high/low per CUDA context and avoid this call 

145 cdef int high, low 

146 with nogil: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

147 HANDLE_RETURN(cydriver.cuCtxGetStreamPriorityRange(&high, &low)) 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

148 cdef int prio 

149 if priority is not None: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

150 prio = priority 2MbQb

151 if not (low <= prio <= high): 2MbQb

152 raise ValueError(f"{priority=} is out of range {[low, high]}") 2Qb

153 else: 

154 prio = high 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-c.cM @ J dd/c:cW X

155  

156 # C++ creates the stream and returns owning handle with context dependency 

157 h_stream = create_stream_handle(h_context, flags, prio) 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

158 if not h_stream: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

159 raise RuntimeError("Failed to create CUDA stream") 

160 self = Stream._from_handle(cls, h_stream) 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

161 self._nonblocking = int(nonblocking) 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

162 self._priority = prio 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

163 if device_id is not None: 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

164 self._device_id = device_id 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

165 return self 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F N O P Q R S T U 1 JbKbhbibjbkblbmbnbobpbqbrbsbtbub5 6 7 8 9 ! ;c2 V 3 % ' ( ) * + , - . / 4 Xb: YbZb; D 0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb= ? PbG =c?cGb@c[c]c^c_c`c$cyb%c'c(c)c*czb+c{c|cSbTbadbd# LbH ,cK L u }c~cI Ub-cMb.cM Qb@ J dd/c:cW X

166  

167 cpdef close(self): 

168 """Destroy the stream. 

169  

170 Releases the stream handle. For owned streams, this destroys the 

171 underlying CUDA stream. For borrowed streams, this releases the 

172 reference and allows the Python owner to be GC'd. 

173 """ 

174 self._h_stream.reset() 2Z $ y Vbw Wbx dbAbBbCbDbEbFb[ ] ^ _ ` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv

175  

176 def __cuda_stream__(self) -> tuple[int, int]: 

177 """Return an instance of a __cuda_stream__ protocol.""" 

178 return (0, as_intptr(self._h_stream)) 1Du

179  

180 def __hash__(self) -> int: 

181 return hash(as_intptr(self._h_stream)) 2G =c?cGb@c[c]c^c_c`c{c|cSbTb8eKdH u ~cI UbJ

182  

183 def __eq__(self, other) -> bool: 

184 if not isinstance(other, Stream): 2PbG $cyb%c'c(c)c*c+cSbTbKdH ,cK L u I Ub-cM J :c

185 return NotImplemented 2Pb$cyb%c'c(c)c*c:c

186 return as_intptr(self._h_stream) == as_intptr((<Stream>other)._h_stream) 2PbG +cSbTbKdH ,cK L u I Ub-cM J

187  

188 def __repr__(self) -> str: 

189 Stream_ensure_ctx(self) 2E F N O P Q R S T U zb

190 return f"<Stream handle={as_intptr(self._h_stream):#x} context={as_intptr(self._h_context):#x}>" 2E F N O P Q R S T U zb

191  

192 @property 

193 def handle(self) -> cuda.bindings.driver.CUstream: 

194 """Return the underlying ``CUstream`` object. 

195  

196 .. caution:: 

197  

198 This handle is a Python object. To get the memory address of the underlying C 

199 handle, call ``int(Stream.handle)``. 

200 """ 

201 return as_py(self._h_stream) 2Z $ y Vbw Wbx 0 dbAbBbCbDbEbFb[ ] ^ _ ` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv ;cRbPbG H K L }cI M J

202  

203 @property 

204 def is_nonblocking(self) -> bool: 

205 """Return True if this is a nonblocking stream, otherwise False.""" 

206 cdef unsigned int flags 

207 if self._nonblocking == -1: 2Mb.c

208 with nogil: 

209 HANDLE_RETURN(cydriver.cuStreamGetFlags(as_cu(self._h_stream), &flags)) 

210 self._nonblocking = flags & cydriver.CUstream_flags.CU_STREAM_NON_BLOCKING 

211 return bool(self._nonblocking) 2Mb.c

212  

213 @property 

214 def priority(self) -> int: 

215 """Return the stream priority.""" 

216 cdef int prio 

217 if self._priority == INT32_MIN: 2MbQb

218 with nogil: 

219 HANDLE_RETURN(cydriver.cuStreamGetPriority(as_cu(self._h_stream), &prio)) 

220 self._priority = prio 

221 return self._priority 2MbQb

222  

223 def sync(self): 

224 """Synchronize the stream.""" 

225 with nogil: 2Z $ y w 0 db[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C 2 3 : ; D edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd= /cW

226 HANDLE_RETURN(cydriver.cuStreamSynchronize(as_cu(self._h_stream))) 2Z $ y w 0 db[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C 2 3 : ; D edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd= /cW

227  

228 def record(self, event: Event = None, options: EventOptions = None) -> Event: 

229 """Record an event onto the stream. 

230  

231 Creates an Event object (or reuses the given one) by 

232 recording on the stream. 

233  

234 Parameters 

235 ---------- 

236 event : :obj:`~_event.Event`, optional 

237 Optional event object to be reused for recording. 

238 options : :obj:`EventOptions`, optional 

239 Customizable dataclass for event creation options. 

240  

241 Returns 

242 ------- 

243 :obj:`~_event.Event` 

244 Newly created event object. 

245  

246 """ 

247 # Create an Event object (or reusing the given one) by recording 

248 # on the stream. Event flags such as disabling timing, nonblocking, 

249 # and CU_EVENT_RECORD_EXTERNAL, can be set in EventOptions. 

250 if event is None: 2w x a b c d e f g h i j k l m n o p q r s t v E F N O P Q R S T U 1 JbKb2 V 3 % ' ( ) * + , - . / 4 ? @ W

251 Stream_ensure_ctx_device(self) 2w x a b c d e f g h i j k l m n o p q r s t v E F N O P Q R S T U 1 JbKb2 V 3 % ' ( ) * + , - . / 4 ? @ W

252 event = cyEvent._init(cyEvent, self._device_id, self._h_context, options, False) 2w x a b c d e f g h i j k l m n o p q r s t v E F N O P Q R S T U 1 JbKb2 V 3 % ' ( ) * + , - . / 4 ? @ W

253 elif event.is_ipc_enabled: 11

254 raise TypeError( 11

255 "IPC-enabled events should not be re-recorded, instead create a " 

256 "new event by supplying options." 

257 ) 

258  

259 cdef cydriver.CUevent e = as_cu((<cyEvent?>(event))._h_event) 1wxabcdefghijklmnopqrstvEFNOPQRSTU12V3%'()*+,-./4?@W

260 with nogil: 1wxabcdefghijklmnopqrstvEFNOPQRSTU12V3%'()*+,-./4?@W

261 HANDLE_RETURN(cydriver.cuEventRecord(e, as_cu(self._h_stream))) 1wxabcdefghijklmnopqrstvEFNOPQRSTU12V3%'()*+,-./4?@W

262 return event 1wxabcdefghijklmnopqrstvEFNOPQRSTU12V3%'()*+,-./4?@W

263  

264 def wait(self, event_or_stream: Event | Stream): 

265 """Wait for a CUDA event or a CUDA stream. 

266  

267 Waiting for an event or a stream establishes a stream order. 

268  

269 If a :obj:`~_stream.Stream` is provided, then wait until the stream's 

270 work is completed. This is done by recording a new :obj:`~_event.Event` 

271 on the stream and then waiting on it. 

272  

273 """ 

274 cdef Stream stream 

275 cdef EventHandle h_event 

276  

277 # Handle Event directly 

278 if isinstance(event_or_stream, Event): 1wxabcdefghijklmnopqrstvWX

279 with nogil: 1wxabcdefghijklmnopqrstvW

280 # TODO: support flags other than 0? 

281 HANDLE_RETURN(cydriver.cuStreamWaitEvent( 1wxabcdefghijklmnopqrstvW

282 as_cu(self._h_stream), as_cu((<cyEvent>event_or_stream)._h_event), 0)) 

283 return 1wxabcdefghijklmnopqrstvW

284  

285 # Convert to Stream if needed 

286 if isinstance(event_or_stream, Stream): 1wxabcdefghijklmnopqrstvX

287 stream = <Stream>event_or_stream 1wxabcdefghijklmnopqrstv

288 else: 

289 try: 1X

290 stream = Stream._init(obj=event_or_stream) 1X

291 except Exception as e: 1X

292 raise ValueError( 1X

293 "only an Event, Stream, or object supporting __cuda_stream__ can be waited," 1X

294 f" got {type(event_or_stream)}" 1X

295 ) from e 1X

296  

297 # Wait on stream via temporary event 

298 with nogil: 1wxabcdefghijklmnopqrstv

299 h_event = create_event_handle_noctx(cydriver.CUevent_flags.CU_EVENT_DISABLE_TIMING) 1wxabcdefghijklmnopqrstv

300 HANDLE_RETURN(cydriver.cuEventRecord(as_cu(h_event), as_cu(stream._h_stream))) 1wxabcdefghijklmnopqrstv

301 # TODO: support flags other than 0? 

302 HANDLE_RETURN(cydriver.cuStreamWaitEvent(as_cu(self._h_stream), as_cu(h_event), 0)) 1wxabcdefghijklmnopqrstv

303  

304 @property 

305 def device(self) -> Device: 

306 """Return the :obj:`~_device.Device` singleton associated with this stream. 

307  

308 Note 

309 ---- 

310 The current context on the device may differ from this 

311 stream's context. This case occurs when a different CUDA 

312 context is set current after a stream is created. 

313  

314 """ 

315 from cuda.core._device import Device # avoid circular import 2y w x a b c d e f g h i j k l m n o p q r s t z A B C v ; Lbu

316 Stream_ensure_ctx_device(self) 2y w x a b c d e f g h i j k l m n o p q r s t z A B C v ; Lbu

317 return Device(self._device_id) 2y w x a b c d e f g h i j k l m n o p q r s t z A B C v ; Lbu

318  

319 @property 

320 def context(self) -> Context: 

321 """Return the :obj:`~_context.Context` associated with this stream.""" 

322 Stream_ensure_ctx(self) 1yabcdefghijklmnopqrstzABCv56789!#u

323 Stream_ensure_ctx_device(self) 1yabcdefghijklmnopqrstzABCv56789!#u

324 return Context._from_handle(Context, self._h_context, self._device_id) 1yabcdefghijklmnopqrstzABCv56789!#u

325  

326 @staticmethod 

327 def from_handle(handle: int) -> Stream: 

328 """Create a new :obj:`~_stream.Stream` object from a foreign stream handle. 

329  

330 Uses a cudaStream_t pointer address represented as a Python int 

331 to create a new :obj:`~_stream.Stream` object. 

332  

333 Note 

334 ---- 

335 Stream lifetime is not managed, foreign object must remain 

336 alive while this steam is active. 

337  

338 Parameters 

339 ---------- 

340 handle : int 

341 Stream handle representing the address of a foreign 

342 stream object. 

343  

344 Returns 

345 ------- 

346 :obj:`~_stream.Stream` 

347 Newly created stream object. 

348  

349 """ 

350  

351 class _stream_holder: 2G H K L cdI M J

352 def __cuda_stream__(self): 2G H K L cdI M J

353 return (0, handle) 2G H K L cdI M J

354  

355 return Stream._init(obj=_stream_holder()) 2G H K L cdI M J

356  

357 def create_graph_builder(self) -> GraphBuilder: 

358 """Create a new :obj:`~_graph.GraphBuilder` object. 

359  

360 The new graph builder will be associated with this stream. 

361  

362 Returns 

363 ------- 

364 :obj:`~_graph.GraphBuilder` 

365 Newly created graph builder object. 

366  

367 """ 

368 return GraphBuilder._init(stream=self, is_stream_owner=False) 1$0

369  

370  

371# c-only python objects, not public 

372cdef Stream C_LEGACY_DEFAULT_STREAM = Stream._legacy_default() 

373cdef Stream C_PER_THREAD_DEFAULT_STREAM = Stream._per_thread_default() 

374  

375# standard python objects, public 

376LEGACY_DEFAULT_STREAM = C_LEGACY_DEFAULT_STREAM 

377PER_THREAD_DEFAULT_STREAM = C_PER_THREAD_DEFAULT_STREAM 

378  

379  

380cpdef Stream default_stream(): 

381 """Return the default CUDA :obj:`~_stream.Stream`. 

382  

383 The type of default stream returned depends on if the environment 

384 variable CUDA_PYTHON_CUDA_PER_THREAD_DEFAULT_STREAM is set. 

385  

386 If set, returns a per-thread default stream. Otherwise returns 

387 the legacy stream. 

388  

389 """ 

390 # TODO: flip the default 

391 cdef const char* use_ptds_raw = getenv("CUDA_PYTHON_CUDA_PER_THREAD_DEFAULT_STREAM") 2Z y 0 a b c d e f g h i j k l m n o p q r s t z A B C NdOdPdQdRdSdE F TdUdVdWdXdYdZd0dhbibjbkblbmbnbob1d2d3d4dpbqbrbsbtbub5d6dV : edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd7d8d9d!dvb#dwb$d%d'd(d)d*d+d,d-d.d/d:d;d=d?d@d[d]dxb^d_d= `d{d|d}d~daebecedeGbeefegeheiejekeyblemeneoepeqereseKdteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

392  

393 cdef int use_ptds = 0 2Z y 0 a b c d e f g h i j k l m n o p q r s t z A B C NdOdPdQdRdSdE F TdUdVdWdXdYdZd0dhbibjbkblbmbnbob1d2d3d4dpbqbrbsbtbub5d6dV : edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd7d8d9d!dvb#dwb$d%d'd(d)d*d+d,d-d.d/d:d;d=d?d@d[d]dxb^d_d= `d{d|d}d~daebecedeGbeefegeheiejekeyblemeneoepeqereseKdteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

394 if use_ptds_raw != NULL: 2Z y 0 a b c d e f g h i j k l m n o p q r s t z A B C NdOdPdQdRdSdE F TdUdVdWdXdYdZd0dhbibjbkblbmbnbob1d2d3d4dpbqbrbsbtbub5d6dV : edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd7d8d9d!dvb#dwb$d%d'd(d)d*d+d,d-d.d/d:d;d=d?d@d[d]dxb^d_d= `d{d|d}d~daebecedeGbeefegeheiejekeyblemeneoepeqereseKdteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

395 use_ptds = strtol(use_ptds_raw, NULL, 10) 

396  

397 # value is non-zero, including for weird stuff like 123foo 

398 if use_ptds: 2Z y 0 a b c d e f g h i j k l m n o p q r s t z A B C NdOdPdQdRdSdE F TdUdVdWdXdYdZd0dhbibjbkblbmbnbob1d2d3d4dpbqbrbsbtbub5d6dV : edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd7d8d9d!dvb#dwb$d%d'd(d)d*d+d,d-d.d/d:d;d=d?d@d[d]dxb^d_d= `d{d|d}d~daebecedeGbeefegeheiejekeyblemeneoepeqereseKdteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

399 return C_PER_THREAD_DEFAULT_STREAM 

400 else: 

401 return C_LEGACY_DEFAULT_STREAM 2Z y 0 a b c d e f g h i j k l m n o p q r s t z A B C NdOdPdQdRdSdE F TdUdVdWdXdYdZd0dhbibjbkblbmbnbob1d2d3d4dpbqbrbsbtbub5d6dV : edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd7d8d9d!dvb#dwb$d%d'd(d)d*d+d,d-d.d/d:d;d=d?d@d[d]dxb^d_d= `d{d|d}d~daebecedeGbeefegeheiejekeyblemeneoepeqereseKdteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

402  

403  

404cdef inline int Stream_ensure_ctx(Stream self) except?-1 nogil: 

405 """Ensure the stream's context handle is populated.""" 

406 cdef cydriver.CUcontext ctx 

407 if not self._h_context: 2y a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 5 6 7 8 9 ! zb# u

408 HANDLE_RETURN(cydriver.cuStreamGetCtx(as_cu(self._h_stream), &ctx)) 2y a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 5 6 7 8 9 ! zb# u

409 with gil: 2y a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 5 6 7 8 9 ! zb# u

410 self._h_context = create_context_handle_ref(ctx) 2y a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 5 6 7 8 9 ! zb# u

411 return 0 2y a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 5 6 7 8 9 ! zb# u

412  

413  

414cdef inline int Stream_ensure_ctx_device(Stream self) except?-1: 

415 """Ensure the stream's context and device_id are populated.""" 

416 cdef cydriver.CUcontext ctx 

417 cdef cydriver.CUdevice target_dev 

418 cdef bint switch_context 

419  

420 if self._device_id < 0: 2y w x a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 1 JbKb5 6 7 8 9 ! 2 V 3 % ' ( ) * + , - . / 4 ; ? # Lbu @ W

421 with nogil: 1u

422 # Get device ID from context, switching context temporarily if needed 

423 Stream_ensure_ctx(self) 1u

424 switch_context = (get_current_context() != self._h_context) 1u

425 if switch_context: 1u

426 HANDLE_RETURN(cydriver.cuCtxPushCurrent(as_cu(self._h_context))) 1u

427 HANDLE_RETURN(cydriver.cuCtxGetDevice(&target_dev)) 1u

428 if switch_context: 1u

429 HANDLE_RETURN(cydriver.cuCtxPopCurrent(&ctx)) 1u

430 self._device_id = <int>target_dev 1u

431 return 0 2y w x a b c d e f g h i j k l m n o p q r s t z A B C v E F N O P Q R S T U 1 JbKb5 6 7 8 9 ! 2 V 3 % ' ( ) * + , - . / 4 ; ? # Lbu @ W

432  

433  

434cdef cydriver.CUstream _handle_from_stream_protocol(obj) except*: 

435 if isinstance(obj, Stream): 2D G H K L u cdI M J X

436 return <cydriver.CUstream><uintptr_t>(obj.handle) 

437  

438 try: 2D G H K L u cdI M J X

439 cuda_stream_attr = obj.__cuda_stream__ 2D G H K L u cdI M J X

440 except AttributeError: 1X

441 raise TypeError(f"{type(obj)} object does not have a '__cuda_stream__' attribute") from None 1X

442  

443 if callable(cuda_stream_attr): 2D G H K L u cdI M J

444 info = cuda_stream_attr() 2D G H K L u cdI M J

445 else: 

446 info = cuda_stream_attr 

447 warnings.simplefilter("once", DeprecationWarning) 

448 warnings.warn( 

449 "Implementing __cuda_stream__ as an attribute is deprecated; it must be implemented as a method", 

450 stacklevel=3, 

451 category=DeprecationWarning, 

452 ) 

453  

454 try: 2D G H K L u cdI M J

455 len_info = len(info) 2D G H K L u cdI M J

456 except TypeError as e: 

457 raise RuntimeError(f"obj.__cuda_stream__ must return a sequence with 2 elements, got {type(info)}") from e 

458 if len_info != 2: 2D G H K L u cdI M J

459 raise RuntimeError(f"obj.__cuda_stream__ must return a sequence with 2 elements, got {len_info} elements") 

460 if info[0] != 0: 2D G H K L u cdI M J

461 raise RuntimeError( 

462 f"The first element of the sequence returned by obj.__cuda_stream__ must be 0, got {repr(info[0])}" 

463 ) 

464 return <cydriver.CUstream><uintptr_t>(info[1]) 2D G H K L u cdI M J

465  

466# Helper for API functions that accept either Stream or GraphBuilder. Performs 

467# needed checks and returns the relevant stream. 

468cdef Stream Stream_accept(arg, bint allow_stream_protocol=False): 

469 if isinstance(arg, Stream): 2Z $ y w x 0 dbAbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv E F hbibjbkblbmbnbobpbqbrbsbtbubV 4 Xb: YbZb; D edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb=

470 return <Stream>(arg) 2$ AbBbCbDbEbFb[ Nb] ^ _ Ob` { | } ~ abbbcbE F hbibjbkblbmbnbobpbqbrbsbtbubV 4 Xb: YbZb; D edfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJd0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#cvbwbRbxb=

471 elif isinstance(arg, GraphBuilder): 2Z $ y w x 0 dbAbBbCbDbEbFb[ ] ^ _ ` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv D

472 return <Stream>(arg.stream) 2Z $ y w x 0 dbAbBbCbDbEbFb[ ] ^ _ ` { | } ~ ebfbgbabbbcba b c d e f g h i j k l m n o p q r s t z A B C HbIbv

473 elif allow_stream_protocol and hasattr(arg, "__cuda_stream__"): 1D

474 stream = Stream._init(arg) 1D

475 warnings.warn( 1D

476 "Passing foreign stream objects to this function via the " 

477 "stream protocol is deprecated. Convert the object explicitly " 

478 "using Stream(obj) instead.", 

479 stacklevel=2, 

480 category=DeprecationWarning, 1D

481 ) 

482 return <Stream>(stream) 1D

483 raise TypeError(f"Stream or GraphBuilder expected, got {type(arg).__name__}")