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

118 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-19 01:12 +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  

7cimport cython 

8from libc.limits cimport ULLONG_MAX 

9from libc.stdint cimport uintptr_t 

10from libc.string cimport memset 

11  

12from cuda.bindings cimport cydriver 

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

14from cuda.core._memory cimport _ipc 

15from cuda.core._stream cimport Stream_accept, Stream 

16from cuda.core._resource_handles cimport ( 

17 MemoryPoolHandle, 

18 DevicePtrHandle, 

19 create_mempool_handle, 

20 deviceptr_alloc_from_pool, 

21 get_last_error, 

22 as_cu, 

23 as_py, 

24) 

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

26  

27from cuda.core._utils.cuda_utils cimport ( 

28 HANDLE_RETURN, 

29) 

30  

31import uuid 

32from typing import TYPE_CHECKING 

33  

34if TYPE_CHECKING: 

35 from cuda.core.graph import GraphBuilder 

36 from cuda.core.typing import DevicePointerType 

37  

38  

39cdef class _MemPoolAttributes: 

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

41 cdef: 

42 MemoryPoolHandle _h_pool 

43  

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

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

46  

47 @staticmethod 

48 cdef _MemPoolAttributes _init(MemoryPoolHandle h_pool): 

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

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

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

52  

53 def __repr__(self) -> str: 

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

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

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

57 ) 

58  

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

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

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

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

63  

64 @property 

65 def reuse_follow_event_dependencies(self) -> bool: 

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

67 cdef int value 

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

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

70  

71 @property 

72 def reuse_allow_opportunistic(self) -> bool: 

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

74 cdef int value 

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

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

77  

78 @property 

79 def reuse_allow_internal_dependencies(self) -> bool: 

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

81 cdef int value 

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

83 return bool(value) 19YE%2bac

84  

85 @property 

86 def release_threshold(self) -> int: 

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

88 cdef cydriver.cuuint64_t value 

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

90 return int(value) 18XD$1bac

91  

92 @property 

93 def reserved_mem_current(self) -> int: 

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

95 cdef cydriver.cuuint64_t value 

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

97 return int(value) 1jfRNdolhTPbac

98  

99 @property 

100 def reserved_mem_high(self) -> int: 

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

102 cdef cydriver.cuuint64_t value 

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

104 return int(value) 1RNoTPbac

105  

106 @property 

107 def used_mem_current(self) -> int: 

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

109 cdef cydriver.cuuint64_t value 

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

111 return int(value) 1kgSOepmiUQbac

112  

113 @property 

114 def used_mem_high(self) -> int: 

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

116 cdef cydriver.cuuint64_t value 

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

118 return int(value) 1SOpUQInJbac

119  

120  

121cdef class _MemPool(MemoryResource): 

122  

123 def __cinit__(self) -> None: 

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

125 self._mempool_owned = False 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvb;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~d0c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t wbxbybzbAbBbCb] ^ me5 newdaeL beZcce. / : deK DbM _ 8 X j f R N 9 Y ! Z # 0 k g S O D eed feo geE heF ieG jee kep le$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 Eb` { 7 C H | ; ) ^eFbGbHb* + , - IbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

126 self._ipc_data = None 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvb;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~d0c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t wbxbybzbAbBbCb] ^ me5 newdaeL beZcce. / : deK DbM _ 8 X j f R N 9 Y ! Z # 0 k g S O D eed feo geE heF ieG jee kep le$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 Eb` { 7 C H | ; ) ^eFbGbHb* + , - IbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

127 self._attributes = None 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvb;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~d0c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t wbxbybzbAbBbCb] ^ me5 newdaeL beZcce. / : deK DbM _ 8 X j f R N 9 Y ! Z # 0 k g S O D eed feo geE heF ieG jee kep le$ 1 l h T P % 2 ' 3 ( 4 m i U Q I n J b a c 6 Eb` { 7 C H | ; ) ^eFbGbHb* + , - IbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

128  

129 def close(self) -> None: 

130 """ 

131 Close the memory resource and destroy the associated memory pool 

132 if owned. 

133 """ 

134 _MP_close(self) 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -

135  

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

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

138  

139 Parameters 

140 ---------- 

141 size : int 

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

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

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

145 asynchronously. Must be passed explicitly; pass 

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

147  

148 Returns 

149 ------- 

150 Buffer 

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

152 resource was created for. 

153 """ 

154 if self.is_mapped: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 Db_ j f k g l h m i b c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

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

156 cdef Stream s = Stream_accept(stream) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 Db_ j f k g l h m i b c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

157 return _MP_allocate(self, size, s) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 Db_ j f k g l h m i b c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

158  

159 def deallocate( 

160 self, 

161 ptr: DevicePointerType, 

162 size_t size, 

163 *, 

164 stream: Stream | GraphBuilder 

165 ) -> None: 

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

167  

168 Parameters 

169 ---------- 

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

171 The pointer or handle to the buffer to deallocate. 

172 size : int 

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

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

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

176 asynchronously. Must be passed explicitly; pass 

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

178 """ 

179 cdef Stream s = Stream_accept(stream) 

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

181  

182 @property 

183 @cython.critical_section 

184 def attributes(self) -> _MemPoolAttributes: 

185 """Memory pool attributes.""" 

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

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

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

189  

190 @property 

191 def handle(self) -> object: 

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

193 return as_py(self._h_pool) 

194  

195 @property 

196 def is_handle_owned(self) -> bool: 

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

198 return self._mempool_owned 

199  

200 @property 

201 def is_ipc_enabled(self) -> bool: 

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

203 return self._ipc_data is not None 2_e0c`e1cq 2cr 3czd4cAd5cBd6cCd7cu 8cv 9c{e!c|e#cDd$cEd%cFd'cGd(c}e)c~e*caf+cHd,cId-cbf.ccf/cJd:cKd;cdf=cef?cLd@cMd[cff]cgf^cNd_cOd`chf{cif|cPd}cQd~cjfadkfbdRdcdSdddlfedTdfdUdgdVdhdWdidXdjdYdkdZdld0dmd1dnd2dodw x 3dpd4dqd5drd6dsdxdtdydudy 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

204  

205 @property 

206 def is_mapped(self) -> bool: 

207 """ 

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

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

210 """ 

211 return self._ipc_data is not None and self._ipc_data._is_mapped 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

212  

213 @property 

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

215 """ 

216 A universally unique identifier for this memory resource. Meaningful 

217 only for IPC-enabled memory resources. 

218 """ 

219 return getattr(self._ipc_data, 'uuid', None) 2q r xdyds t

220  

221  

222cdef int MP_init_create_pool( 

223 _MemPool self, 

224 cydriver.CUmemLocationType loc_type, 

225 int loc_id, 

226 cydriver.CUmemAllocationType alloc_type, 

227 bint ipc_enabled, 

228 size_t max_size, 

229) except? -1: 

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

231 parameters. 

232  

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

234 """ 

235 cdef cydriver.CUmemPoolProps properties 

236 memset(&properties, 0, sizeof(cydriver.CUmemPoolProps)) 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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  

238 properties.allocType = alloc_type 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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

239 properties.handleTypes = ( 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 _ipc.IPC_HANDLE_TYPE if ipc_enabled 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 else cydriver.CUmemAllocationHandleType.CU_MEM_HANDLE_TYPE_NONE 25 wdL . / : 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 | )

242 ) 

243 properties.location.id = loc_id 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 properties.location.type = loc_type 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 properties.maxSize = max_size 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 self._mempool_owned = True 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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

248 self._h_pool = create_mempool_handle(properties) 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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

249 if not self._h_pool: 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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

250 HANDLE_RETURN(get_last_error()) 

251 raise RuntimeError( 

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

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

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

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

256 ) 

257  

258 if ipc_enabled: 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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 alloc_handle = _ipc.MP_export_mempool(self) 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t X f N Y Z 0 g O 1 h P 2 3 4 i Q C ; ) * + , - V W

260 self._ipc_data = _ipc.IPCDataForMR(alloc_handle, False) 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t X f N Y Z 0 g O 1 h P 2 3 4 i Q C ; ) * + , - V W

261  

262 return 0 20c1cq 2cr 3c4c5c6c7cu 8cv 9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodw x pdqdrdsdtdudy z A B s t 5 wdL . / : 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

263  

264  

265cdef int MP_init_current_pool( 

266 _MemPool self, 

267 cydriver.CUmemLocationType loc_type, 

268 int loc_id, 

269 cydriver.CUmemAllocationType alloc_type, 

270) except? -1: 

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

272 location and allocation type. 

273  

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

275 Requires CUDA 13+. 

276 """ 

277 IF CUDA_CORE_BUILD_MAJOR >= 13: 

278 cdef cydriver.CUmemLocation loc 

279 cdef cydriver.CUmemoryPool pool 

280 loc.id = loc_id 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

281 loc.type = loc_type 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

282 with nogil: 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

283 HANDLE_RETURN(cydriver.cuMemGetMemPool(&pool, &loc, alloc_type)) 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

284 self._h_pool = create_mempool_handle_ref(pool) 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

285 self._mempool_owned = False 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

286 ELSE: 

287 raise RuntimeError( 

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

289 ) 

290 return 0 2;d=d?d@dVcWc[dXc]dYc^d_d`d{d|d}d~daeL beZcce. / : deK M _ D eed feo geE heF ieG jee kep len a ` {

291  

292  

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

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

295  

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

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

298 ULLONG_MAX avoids repeated OS round-trips. 

299 """ 

300 cdef cydriver.cuuint64_t current_threshold 

301 cdef cydriver.cuuint64_t max_threshold = ULLONG_MAX 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

302 with nogil: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

303 HANDLE_RETURN( 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

304 cydriver.cuMemPoolGetAttribute( 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

305 as_cu(self._h_pool), 

306 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

307 &current_threshold 

308 ) 

309 ) 

310 if current_threshold == 0: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

311 HANDLE_RETURN(cydriver.cuMemPoolSetAttribute( 1[

312 as_cu(self._h_pool), 

313 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

314 &max_threshold 

315 )) 

316 return 0 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvbwbxbybzbAbBbCb] ^ meneDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUc

317  

318  

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

320# A result of CU_STREAM_CAPTURE_STATUS_INVALIDATED is considered an error. 

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

322 cdef cydriver.CUstreamCaptureStatus capturing 

323 HANDLE_RETURN(cydriver.cuStreamIsCapturing(s, &capturing)) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

324 if capturing != cydriver.CUstreamCaptureStatus.CU_STREAM_CAPTURE_STATUS_NONE: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

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

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

327  

328  

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

330 cdef cydriver.CUstream s = as_cu(stream._h_stream) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

331 cdef DevicePtrHandle h_ptr 

332 with nogil: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

333 check_not_capturing(s) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

334 h_ptr = deviceptr_alloc_from_pool(size, self._h_pool, stream._h_stream) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

335 if not h_ptr: 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

336 HANDLE_RETURN(get_last_error()) 

337 raise RuntimeError( 

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

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

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

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

342 ) 

343 return Buffer_from_deviceptr_handle(h_ptr, size, self, None, cls) 2} ~ abbbcbdbebfbgbhbibjbkblbmbnbob= ? @ pbqbrb[ sbtbubvboepeqeVcWcXcYcreseteuevewexeq r zdAdBdCdu v DdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2dw x 3d4d5d6dxdydy z A B s t wbxbybzbAbBbCb] ^ 5 L ZcK DbM _ j f k g d e l h m i b a c 6 Eb` { 7 C H FbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{bV W |b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcuc7dvcwc8dxcyczcAcBcCc9d!d#dDc$dEc%dFcGcHc'dIcJcKcLcMcNc(dOcPc)d*dQc+d,dRc-d.dScTcUc/d:d

344  

345  

346cdef inline void _MP_deallocate( 

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

348) noexcept nogil: 

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

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

351 cdef cydriver.CUresult r 

352 with nogil: 

353 r = cydriver.cuMemFreeAsync(devptr, s) 

354 if r != cydriver.CUDA_ERROR_INVALID_CONTEXT: 

355 HANDLE_RETURN(r) 

356  

357  

358cdef inline _MP_close(_MemPool self): 

359 if not self._h_pool: 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -

360 return 

361  

362 # Reset members in declaration order. 

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

364 self._h_pool.reset() 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -

365 self._mempool_owned = False 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -

366 self._ipc_data = None 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -

367 self._attributes = None 2yezeq Aer BeCeDeEeFeu Gev HeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:ew x ;e=e?e@e[e]ey z A B s t I n J C H | ; ) * + , -