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

117 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-13 01:38 +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  

30import uuid 

31from typing import TYPE_CHECKING 

32  

33if TYPE_CHECKING: 

34 from cuda.core.graph import GraphBuilder 

35 from cuda.core.typing import DevicePointerType 

36  

37  

38cdef class _MemPoolAttributes: 

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

40  

41 def __init__(self, *args, **kwargs) -> None: 

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

43  

44 @staticmethod 

45 cdef _MemPoolAttributes _init(MemoryPoolHandle h_pool): 

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

47 self._h_pool = h_pool 2tc8 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

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

49  

50 def __repr__(self) -> str: 

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

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

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

54 ) 

55  

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

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

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

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

60  

61 @property 

62 def reuse_follow_event_dependencies(self) -> bool: 

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

64 cdef int value 

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

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

67  

68 @property 

69 def reuse_allow_opportunistic(self) -> bool: 

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

71 cdef int value 

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

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

74  

75 @property 

76 def reuse_allow_internal_dependencies(self) -> bool: 

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

78 cdef int value 

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

80 return bool(value) 19YE%2bac

81  

82 @property 

83 def release_threshold(self) -> int: 

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

85 cdef cydriver.cuuint64_t value 

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

87 return int(value) 18XD$1bac

88  

89 @property 

90 def reserved_mem_current(self) -> int: 

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

92 cdef cydriver.cuuint64_t value 

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

94 return int(value) 1jfRNdolhTPbac

95  

96 @property 

97 def reserved_mem_high(self) -> int: 

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

99 cdef cydriver.cuuint64_t value 

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

101 return int(value) 1RNoTPbac

102  

103 @property 

104 def used_mem_current(self) -> int: 

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

106 cdef cydriver.cuuint64_t value 

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

108 return int(value) 1kgSOepmiUQbac

109  

110 @property 

111 def used_mem_high(self) -> int: 

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

113 cdef cydriver.cuuint64_t value 

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

115 return int(value) 2tcS O p U Q I n J b a c

116  

117  

118cdef class _MemPool(MemoryResource): 

119  

120 def __cinit__(self) -> None: 

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

122 self._mempool_owned = False 2} ~ = ? @ abbbcbdbebfbgbhbIdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUducvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t ibjbkblbmbnbob[ ] 7d5 8d/cVdL WdscXd. / : YdK pbM ^ 8 X j f R N 9 Y ! Z # 0 k g S O D Zdd 0do 1dE 2dF 3dG 4de 5dp 6d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 qb_ ` 7 C H { ; ) Kerb* + , - sbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

123 self._ipc_data = None 2} ~ = ? @ abbbcbdbebfbgbhbIdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUducvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t ibjbkblbmbnbob[ ] 7d5 8d/cVdL WdscXd. / : YdK pbM ^ 8 X j f R N 9 Y ! Z # 0 k g S O D Zdd 0do 1dE 2dF 3dG 4de 5dp 6d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 qb_ ` 7 C H { ; ) Kerb* + , - sbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

124 self._attributes = None 2} ~ = ? @ abbbcbdbebfbgbhbIdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUducvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t ibjbkblbmbnbob[ ] 7d5 8d/cVdL WdscXd. / : YdK pbM ^ 8 X j f R N 9 Y ! Z # 0 k g S O D Zdd 0do 1dE 2dF 3dG 4de 5dp 6d$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 qb_ ` 7 C H { ; ) Kerb* + , - sbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

125  

126 def close(self) -> None: 

127 """ 

128 Close the memory resource and destroy the associated memory pool 

129 if owned. 

130 """ 

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

132  

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

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

135  

136 Parameters 

137 ---------- 

138 size : int 

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

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

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

142 asynchronously. Must be passed explicitly; pass 

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

144  

145 Returns 

146 ------- 

147 Buffer 

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

149 resource was created for. 

150 """ 

151 if self.is_mapped: 2} ~ = ? @ abbbcbdbebfbgbhbq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 pb^ j f k g l h m i b c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

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

153 cdef Stream s = Stream_accept(stream) 2} ~ = ? @ abbbcbdbebfbgbhbq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 pb^ j f k g l h m i b c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

154 return _MP_allocate(self, size, s) 2} ~ = ? @ abbbcbdbebfbgbhbq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 pb^ j f k g l h m i b c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

155  

156 def deallocate( 

157 self, 

158 ptr: DevicePointerType, 

159 size_t size, 

160 *, 

161 stream: Stream | GraphBuilder 

162 ) -> None: 

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

164  

165 Parameters 

166 ---------- 

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

168 The pointer or handle to the buffer to deallocate. 

169 size : int 

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

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

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

173 asynchronously. Must be passed explicitly; pass 

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

175 """ 

176 cdef Stream s = Stream_accept(stream) 

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

178  

179 @property 

180 def attributes(self) -> _MemPoolAttributes: 

181 """Memory pool attributes.""" 

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

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

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

185  

186 @property 

187 def handle(self) -> object: 

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

189 return as_py(self._h_pool) 

190  

191 @property 

192 def is_handle_owned(self) -> bool: 

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

194 return self._mempool_owned 

195  

196 @property 

197 def is_ipc_enabled(self) -> bool: 

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

199 return self._ipc_data is not None 2LeucMevcq wcr xc=cyc?czcu Acv Bc@cCc[cDc]cEc^cFcNeGcOeHcPeIc_cJc`cKcQeLcReMc{cNc|cOcSePcTeQc}cRc~cScUeTcVeUcadVcbdWcWeXcXeYccdZcdd0cYe1cZe2ced3cfd4c0e5cgd6chd7cid8cjd9ckd!cld#cmd$cnd%cod'cpd(cw x qd)crd*csd+ctd,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

200  

201 @property 

202 def is_mapped(self) -> bool: 

203 """ 

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

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

206 """ 

207 return self._ipc_data is not None and self._ipc_data._is_mapped 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

208  

209 @property 

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

211 """ 

212 A universally unique identifier for this memory resource. Meaningful 

213 only for IPC-enabled memory resources. 

214 """ 

215 return getattr(self._ipc_data, 'uuid', None) 2q r :c;cs t

216  

217  

218cdef int MP_init_create_pool( 

219 _MemPool self, 

220 cydriver.CUmemLocationType loc_type, 

221 int loc_id, 

222 cydriver.CUmemAllocationType alloc_type, 

223 bint ipc_enabled, 

224 size_t max_size, 

225) except? -1: 

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

227 parameters. 

228  

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

230 """ 

231 cdef cydriver.CUmemPoolProps properties 

232 memset(&properties, 0, sizeof(cydriver.CUmemPoolProps)) 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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  

234 properties.allocType = alloc_type 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

235 properties.handleTypes = ( 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

236 _ipc.IPC_HANDLE_TYPE if ipc_enabled 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

237 else cydriver.CUmemAllocationHandleType.CU_MEM_HANDLE_TYPE_NONE 25 /cL . / : K M 8 j R 9 ! # k S D d o E F G e p $ l T % ' ( m U I n J b a c 6 7 H { )

238 ) 

239 properties.location.id = loc_id 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

240 properties.location.type = loc_type 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

241 properties.maxSize = max_size 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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  

243 self._mempool_owned = True 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

244 self._h_pool = create_mempool_handle(properties) 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

245 if not self._h_pool: 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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 HANDLE_RETURN(get_last_error()) 

247 raise RuntimeError( 

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

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

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

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

252 ) 

253  

254 if ipc_enabled: 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

255 alloc_handle = _ipc.MP_export_mempool(self) 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(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

256 self._ipc_data = _ipc.IPCDataForMR(alloc_handle, False) 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(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

257  

258 return 0 2ucvcq wcr xcyczcu Acv BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(cw x )c*c+c,c-c.cy z A B s t 5 /cL . / : 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

259  

260  

261cdef int MP_init_current_pool( 

262 _MemPool self, 

263 cydriver.CUmemLocationType loc_type, 

264 int loc_id, 

265 cydriver.CUmemAllocationType alloc_type, 

266) except? -1: 

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

268 location and allocation type. 

269  

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

271 Requires CUDA 13+. 

272 """ 

273 IF CUDA_CORE_BUILD_MAJOR >= 13: 

274 cdef cydriver.CUmemLocation loc 

275 cdef cydriver.CUmemoryPool pool 

276 loc.id = loc_id 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

277 loc.type = loc_type 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

278 with nogil: 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

279 HANDLE_RETURN(cydriver.cuMemGetMemPool(&pool, &loc, alloc_type)) 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

280 self._h_pool = create_mempool_handle_ref(pool) 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

281 self._mempool_owned = False 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

282 ELSE: 

283 raise RuntimeError( 

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

285 ) 

286 return 0 2IdJdKdLdocpcMdqcNdrcOdPdQdRdSdTdUdVdL WdscXd. / : YdK M ^ D Zdd 0do 1dE 2dF 3dG 4de 5dp 6dn a _ `

287  

288  

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

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

291  

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

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

294 ULLONG_MAX avoids repeated OS round-trips. 

295 """ 

296 cdef cydriver.cuuint64_t current_threshold 

297 cdef cydriver.cuuint64_t max_threshold = ULLONG_MAX 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

298 with nogil: 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

299 HANDLE_RETURN( 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

300 cydriver.cuMemPoolGetAttribute( 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

301 as_cu(self._h_pool), 

302 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

303 &current_threshold 

304 ) 

305 ) 

306 if current_threshold == 0: 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

307 HANDLE_RETURN(cydriver.cuMemPoolSetAttribute( 1|

308 as_cu(self._h_pool), 

309 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

310 &max_threshold 

311 )) 

312 return 0 2} ~ = ? @ abbbcbdbebfbgbhbibjbkblbmbnbob[ ] 7d8dpbqbrbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcnc

313  

314  

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

316# A result of CU_STREAM_CAPTURE_STATUS_INVALIDATED is considered an error. 

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

318 cdef cydriver.CUstreamCaptureStatus capturing 

319 HANDLE_RETURN(cydriver.cuStreamIsCapturing(s, &capturing)) 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

320 if capturing != cydriver.CUstreamCaptureStatus.CU_STREAM_CAPTURE_STATUS_NONE: 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

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

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

323  

324  

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

326 cdef cydriver.CUstream s = as_cu(stream._h_stream) 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

327 cdef DevicePtrHandle h_ptr 

328 with nogil: 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

329 check_not_capturing(s) 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

330 h_ptr = deviceptr_alloc_from_pool(size, self._h_pool, stream._h_stream) 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

331 if not h_ptr: 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

332 HANDLE_RETURN(get_last_error()) 

333 raise RuntimeError( 

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

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

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

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

338 ) 

339 return Buffer_from_deviceptr_handle(h_ptr, size, self, None, cls) 2} ~ = ? @ abbbcbdbebfbgbhb9d!d#docpcqcrc$d%d'd(d)d*d+dq r =c?cu v @c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdw x qdrdsdtd:c;cy z A B s t ibjbkblbmbnbob[ ] 5 L scK pbM ^ j f k g d e l h m i b a c 6 qb_ ` 7 C H rbsbtbubvbwbxbybzbAb| BbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)bV W *b+b,b-b.b/b:b;b=b?budvd@b[b]b^b_bwd`b{b|bxd}byd~bzdacbcAdccBddcCdecDdfcEdFdgchcicjckcGdlcHdmcnc

340  

341  

342cdef inline void _MP_deallocate( 

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

344) noexcept nogil: 

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

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

347 cdef cydriver.CUresult r 

348 with nogil: 

349 r = cydriver.cuMemFreeAsync(devptr, s) 

350 if r != cydriver.CUDA_ERROR_INVALID_CONTEXT: 

351 HANDLE_RETURN(r) 

352  

353  

354cdef inline _MP_close(_MemPool self): 

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

356 return 

357  

358 # Reset members in declaration order. 

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

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

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

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

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