Coverage for cuda / core / _memory / _memory_pool.pyx: 83.19%

113 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-22 01:37 +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.limits cimport ULLONG_MAX 

8from libc.stdint cimport uintptr_t 

9from libc.string cimport memset 

10  

11from cuda.bindings cimport cydriver 

12from cuda.core._memory._buffer cimport Buffer, Buffer_from_deviceptr_handle, MemoryResource 

13from cuda.core._memory cimport _ipc 

14from cuda.core._stream cimport Stream_accept, Stream 

15from cuda.core._resource_handles cimport ( 

16 MemoryPoolHandle, 

17 DevicePtrHandle, 

18 create_mempool_handle, 

19 deviceptr_alloc_from_pool, 

20 get_last_error, 

21 as_cu, 

22 as_py, 

23) 

24from cuda.core._resource_handles cimport create_mempool_handle_ref # no-cython-lint 

25  

26from cuda.core._utils.cuda_utils cimport ( 

27 HANDLE_RETURN, 

28) 

29  

30  

31cdef class _MemPoolAttributes: 

32 """Provides access to memory pool attributes.""" 

33  

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

35 raise RuntimeError("_MemPoolAttributes cannot be instantiated directly. Please use MemoryResource APIs.") 

36  

37 @staticmethod 

38 cdef _MemPoolAttributes _init(MemoryPoolHandle h_pool): 

39 cdef _MemPoolAttributes self = _MemPoolAttributes.__new__(_MemPoolAttributes) 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

40 self._h_pool = h_pool 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

41 return self 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

42  

43 def __repr__(self): 

44 return f"{self.__class__.__name__}(%s)" % ", ".join( 1bac

45 f"{attr}={getattr(self, attr)}" for attr in dir(self) 1bac

46 if not attr.startswith("_") 1bac

47 ) 

48  

49 cdef int _getattribute(self, cydriver.CUmemPool_attribute attr_enum, void* value) except?-1: 

50 with nogil: 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

51 HANDLE_RETURN(cydriver.cuMemPoolGetAttribute(as_cu(self._h_pool), attr_enum, value)) 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

52 return 0 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

53  

54 @property 

55 def reuse_follow_event_dependencies(self): 

56 """Allow memory to be reused when there are event dependencies between streams.""" 

57 cdef int value 

58 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_REUSE_FOLLOW_EVENT_DEPENDENCIES, &value) 1#0G(4bac

59 return bool(value) 1#0G(4bac

60  

61 @property 

62 def reuse_allow_opportunistic(self): 

63 """Allow reuse of completed frees without dependencies.""" 

64 cdef int value 

65 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_REUSE_ALLOW_OPPORTUNISTIC, &value) 1!ZF'3bac

66 return bool(value) 1!ZF'3bac

67  

68 @property 

69 def reuse_allow_internal_dependencies(self): 

70 """Allow insertion of new stream dependencies for memory reuse.""" 

71 cdef int value 

72 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_REUSE_ALLOW_INTERNAL_DEPENDENCIES, &value) 19YE%2bac

73 return bool(value) 19YE%2bac

74  

75 @property 

76 def release_threshold(self): 

77 """Amount of reserved memory to hold before OS release.""" 

78 cdef cydriver.cuuint64_t value 

79 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, &value) 18XD$1bac

80 return int(value) 18XD$1bac

81  

82 @property 

83 def reserved_mem_current(self): 

84 """Current amount of backing memory allocated.""" 

85 cdef cydriver.cuuint64_t value 

86 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RESERVED_MEM_CURRENT, &value) 1jfRNdolhTPbac

87 return int(value) 1jfRNdolhTPbac

88  

89 @property 

90 def reserved_mem_high(self): 

91 """High watermark of backing memory allocated.""" 

92 cdef cydriver.cuuint64_t value 

93 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RESERVED_MEM_HIGH, &value) 1RNoTPbac

94 return int(value) 1RNoTPbac

95  

96 @property 

97 def used_mem_current(self): 

98 """Current amount of memory in use.""" 

99 cdef cydriver.cuuint64_t value 

100 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_USED_MEM_CURRENT, &value) 1kgSOepmiUQbac

101 return int(value) 1kgSOepmiUQbac

102  

103 @property 

104 def used_mem_high(self): 

105 """High watermark of memory in use.""" 

106 cdef cydriver.cuuint64_t value 

107 self._getattribute(cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_USED_MEM_HIGH, &value) 1SOpUQInJbac

108 return int(value) 1SOpUQInJbac

109  

110  

111cdef class _MemPool(MemoryResource): 

112  

113 def __cinit__(self): 

114 # Note: subclasses use MP_init_create_pool or MP_init_current_pool to initialize. 

115 self._mempool_owned = False 2*c} ~ = ? @ abbbcbdbebfbgbhbHdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdpcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t ibjbkblbmb[ nb] ^ 5 UdL VdocWd. / : XdK obM _ 8 X j f R N 9 Y ! Z # 0 k g S O D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 pb` { 7 C H | ; ) Heqb* + , - rbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjc

116 self._ipc_data = None 2} ~ = ? @ abbbcbdbebfbgbhbHdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdpcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t ibjbkblbmb[ nb] ^ 5 UdL VdocWd. / : XdK obM _ 8 X j f R N 9 Y ! Z # 0 k g S O D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 pb` { 7 C H | ; ) Heqb* + , - rbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjc

117 self._attributes = None 2} ~ = ? @ abbbcbdbebfbgbhbHdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdpcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t ibjbkblbmb[ nb] ^ 5 UdL VdocWd. / : XdK obM _ 8 X j f R N 9 Y ! Z # 0 k g S O D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 pb` { 7 C H | ; ) Heqb* + , - rbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjc

118  

119 def close(self): 

120 """ 

121 Close the memory resource and destroy the associated memory pool 

122 if owned. 

123 """ 

124 _MP_close(self) 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -

125  

126 def allocate(self, size_t size, *, stream: Stream | GraphBuilder) -> Buffer: 

127 """Allocate a buffer of the requested size. 

128  

129 Parameters 

130 ---------- 

131 size : int 

132 The size of the buffer to allocate, in bytes. 

133 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

134 Keyword-only. The stream on which to perform the allocation 

135 asynchronously. Must be passed explicitly; pass 

136 ``device.default_stream`` to use the default stream. 

137  

138 Returns 

139 ------- 

140 Buffer 

141 The allocated buffer object, which is accessible on the device that this memory 

142 resource was created for. 

143 """ 

144 if self.is_mapped: 2} ~ = ? @ abbbcbdbebfbgbhbq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 ob_ j f k g l h m i b c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

145 raise TypeError("Cannot allocate from a mapped IPC-enabled memory resource") 

146 cdef Stream s = Stream_accept(stream) 2} ~ = ? @ abbbcbdbebfbgbhbq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 ob_ j f k g l h m i b c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

147 return _MP_allocate(self, size, s) 2} ~ = ? @ abbbcbdbebfbgbhbq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 ob_ j f k g l h m i b c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

148  

149 def deallocate(self, ptr: "DevicePointerType", size_t size, *, stream: Stream | GraphBuilder): 

150 """Deallocate a buffer previously allocated by this resource. 

151  

152 Parameters 

153 ---------- 

154 ptr : :obj:`~_memory.DevicePointerType` 

155 The pointer or handle to the buffer to deallocate. 

156 size : int 

157 The size of the buffer to deallocate, in bytes. 

158 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

159 Keyword-only. The stream on which to perform the deallocation 

160 asynchronously. Must be passed explicitly; pass 

161 ``device.default_stream`` to use the default stream. 

162 """ 

163 cdef Stream s = Stream_accept(stream) 

164 _MP_deallocate(self, <uintptr_t>ptr, size, s) 

165  

166 @property 

167 def attributes(self) -> _MemPoolAttributes: 

168 """Memory pool attributes.""" 

169 if self._attributes is None: 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

170 self._attributes = _MemPoolAttributes._init(self._h_pool) 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

171 return self._attributes 18XjfRN9Y!Z#0kgSODdoEFGep$1lhTP%2'3(4miUQInJbac

172  

173 @property 

174 def handle(self) -> object: 

175 """Handle to the underlying memory pool.""" 

176 return as_py(self._h_pool) 

177  

178 @property 

179 def is_handle_owned(self) -> bool: 

180 """Whether the memory resource handle is owned. If False, ``close`` has no effect.""" 

181 return self._mempool_owned 

182  

183 @property 

184 def is_ipc_enabled(self) -> bool: 

185 """Whether this memory resource has IPC enabled.""" 

186 return self._ipc_data is not None 2IepcJeqcq rcr sc-ctc.cucu vcv wc/cxc:cyc;czc=cAcKeBcLeCcMeDc?cEc@cFcNeGcOeHc[cIc]cJcPeKcQeLc^cMc_cNcReOcSePc`cQc{cRcTeScUeTc|cUc}cVcVeWcWeXc~cYcadZcXe0cbd1ccd2cdd3ced4cfd5cgd6chd7cid8cjd9ckd!cw x ld#cmd$cnd%cod'c+c(c,c)cy z A B s t ] ^ 5 K 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q 6 7 C H * + , - V W

187  

188 @property 

189 def is_mapped(self) -> bool: 

190 """ 

191 Whether this is a mapping of an IPC-enabled memory resource from 

192 another process. If True, allocation is not permitted. 

193 """ 

194 return self._ipc_data is not None and self._ipc_data._is_mapped 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

195  

196 @property 

197 def uuid(self) -> uuid.UUID | None: 

198 """ 

199 A universally unique identifier for this memory resource. Meaningful 

200 only for IPC-enabled memory resources. 

201 """ 

202 return getattr(self._ipc_data, 'uuid', None) 2q r +c,cs t

203  

204  

205cdef int MP_init_create_pool( 

206 _MemPool self, 

207 cydriver.CUmemLocationType loc_type, 

208 int loc_id, 

209 cydriver.CUmemAllocationType alloc_type, 

210 bint ipc_enabled, 

211 size_t max_size, 

212) except? -1: 

213 """Initialize a _MemPool by creating a new memory pool with the given 

214 parameters. 

215  

216 Sets ``_h_pool`` (owning), ``_mempool_owned``, and ``_ipc_data``. 

217 """ 

218 cdef cydriver.CUmemPoolProps properties 

219 memset(&properties, 0, sizeof(cydriver.CUmemPoolProps)) 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

220  

221 properties.allocType = alloc_type 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

222 properties.handleTypes = ( 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

223 _ipc.IPC_HANDLE_TYPE if ipc_enabled 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

224 else cydriver.CUmemAllocationHandleType.CU_MEM_HANDLE_TYPE_NONE 15L./:KM8jR9!#kSDdoEFGep$lT%'(mUInJbac67H|)

225 ) 

226 properties.location.id = loc_id 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

227 properties.location.type = loc_type 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

228 properties.maxSize = max_size 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

229  

230 self._mempool_owned = True 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

231 self._h_pool = create_mempool_handle(properties) 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

232 if not self._h_pool: 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

233 HANDLE_RETURN(get_last_error()) 

234 raise RuntimeError( 

235 f"Failed to initialize {self.__class__.__name__}: " 

236 "cuda-core returned an empty memory pool handle without recording a CUDA error. " 

237 "This is an internal cuda-core error; please report it with your CUDA driver, " 

238 "CUDA Toolkit, and cuda-python versions." 

239 ) 

240  

241 if ipc_enabled: 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

242 alloc_handle = _ipc.MP_export_mempool(self) 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t X f N Y Z 0 g O 1 h P 2 3 4 i Q C ; ) * + , - V W

243 self._ipc_data = _ipc.IPCDataForMR(alloc_handle, False) 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t X f N Y Z 0 g O 1 h P 2 3 4 i Q C ; ) * + , - V W

244  

245 return 0 2pcqcq rcr sctcucu vcv wcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!cw x #c$c%c'c(c)cy z A B s t 5 L . / : K M 8 X j f R N 9 Y ! Z # 0 k g S O D d o E F G e p $ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 7 C H | ; ) * + , - V W

246  

247  

248cdef int MP_init_current_pool( 

249 _MemPool self, 

250 cydriver.CUmemLocationType loc_type, 

251 int loc_id, 

252 cydriver.CUmemAllocationType alloc_type, 

253) except? -1: 

254 """Initialize a _MemPool by getting the driver's current pool for a 

255 location and allocation type. 

256  

257 Sets ``_h_pool`` (non-owning) via ``cuMemGetMemPool``. 

258 Requires CUDA 13+. 

259 """ 

260 IF CUDA_CORE_BUILD_MAJOR >= 13: 

261 cdef cydriver.CUmemLocation loc 

262 cdef cydriver.CUmemoryPool pool 

263 loc.id = loc_id 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

264 loc.type = loc_type 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

265 with nogil: 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

266 HANDLE_RETURN(cydriver.cuMemGetMemPool(&pool, &loc, alloc_type)) 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

267 self._h_pool = create_mempool_handle_ref(pool) 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

268 self._mempool_owned = False 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

269 ELSE: 

270 raise RuntimeError( 

271 "Getting the current memory pool requires CUDA 13.0 or later" 

272 ) 

273 return 0 2HdIdJdKdkclcLdmcMdncNdOdPdQdRdSdTdUdL VdocWd. / : XdK M _ D Ydd Zdo 0dE 1dF 2dG 3de 4dp 5dn a ` {

274  

275  

276cdef int MP_raise_release_threshold(_MemPool self) except? -1: 

277 """Raise the pool's release threshold to ULLONG_MAX if currently zero. 

278  

279 By default the release threshold is 0, meaning memory is returned to 

280 the OS as soon as there are no active suballocations. Setting it to 

281 ULLONG_MAX avoids repeated OS round-trips. 

282 """ 

283 cdef cydriver.cuuint64_t current_threshold 

284 cdef cydriver.cuuint64_t max_threshold = ULLONG_MAX 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

285 with nogil: 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

286 HANDLE_RETURN( 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

287 cydriver.cuMemPoolGetAttribute( 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

288 as_cu(self._h_pool), 

289 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

290 &current_threshold 

291 ) 

292 ) 

293 if current_threshold == 0: 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

294 HANDLE_RETURN(cydriver.cuMemPoolSetAttribute( 1[

295 as_cu(self._h_pool), 

296 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

297 &max_threshold 

298 )) 

299 return 0 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmb[ nb] ^ obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjc

300  

301  

302# Raise an exception if the given stream is capturing. 

303# A result of CU_STREAM_CAPTURE_STATUS_INVALIDATED is considered an error. 

304cdef inline int check_not_capturing(cydriver.CUstream s) except?-1 nogil: 

305 cdef cydriver.CUstreamCaptureStatus capturing 

306 HANDLE_RETURN(cydriver.cuStreamIsCapturing(s, &capturing)) 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

307 if capturing != cydriver.CUstreamCaptureStatus.CU_STREAM_CAPTURE_STATUS_NONE: 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

308 raise RuntimeError("_MemPool cannot perform memory operations on " 1=?@

309 "a capturing stream (consider using GraphMemoryResource).") 

310  

311  

312cdef Buffer _MP_allocate(_MemPool self, size_t size, Stream stream, type cls = Buffer): 

313 cdef cydriver.CUstream s = as_cu(stream._h_stream) 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

314 cdef DevicePtrHandle h_ptr 

315 with nogil: 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

316 check_not_capturing(s) 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

317 h_ptr = deviceptr_alloc_from_pool(size, self._h_pool, stream._h_stream) 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

318 if not h_ptr: 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

319 HANDLE_RETURN(get_last_error()) 

320 raise RuntimeError( 

321 f"Failed to allocate {size} bytes from {self.__class__.__name__}: " 

322 "cuda-core returned an empty allocation handle without recording a CUDA error. " 

323 "This is an internal cuda-core error; please report it with your CUDA driver, " 

324 "CUDA Toolkit, and cuda-python versions." 

325 ) 

326 return Buffer_from_deviceptr_handle(h_ptr, size, self, None, cls) 2} ~ = ? @ abbbcbdbebfbgbhb6d7d8dkclcmcnc9d!d#d$d%d'd(dq r -c.cu v /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdw x ldmdndod+c,cy z A B s t ibjbkblbmb[ nb] ^ 5 L ocK obM _ j f k g d e l h m i b a c 6 pb` { 7 C H qbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?bpdqdrd@b[b]bsdtdudvdwdxd^b_b`b{b|bydzdAd}b~bacbcccdcecBdCdDdfcgcEdFdhcGdicjc

327  

328  

329cdef inline void _MP_deallocate( 

330 _MemPool self, uintptr_t ptr, size_t size, Stream stream 

331) noexcept nogil: 

332 cdef cydriver.CUstream s = as_cu(stream._h_stream) 

333 cdef cydriver.CUdeviceptr devptr = <cydriver.CUdeviceptr>ptr 

334 cdef cydriver.CUresult r 

335 with nogil: 

336 r = cydriver.cuMemFreeAsync(devptr, s) 

337 if r != cydriver.CUDA_ERROR_INVALID_CONTEXT: 

338 HANDLE_RETURN(r) 

339  

340  

341cdef inline _MP_close(_MemPool self): 

342 if not self._h_pool: 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -

343 return 

344  

345 # Reset members in declaration order. 

346 # The RAII deleter calls cuMemPoolDestroy if this is an owning handle. 

347 self._h_pool.reset() 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -

348 self._mempool_owned = False 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -

349 self._ipc_data = None 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -

350 self._attributes = None 2)d*dq +dr ,d-d.du /dv :d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAew x BeCeDeEeFeGey z A B s t I n J C H | ; ) * + , -