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

117 statements  

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

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) 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

50 self._h_pool = h_pool 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

51 return self 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

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: 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

61 HANDLE_RETURN(cydriver.cuMemPoolGetAttribute(as_cu(self._h_pool), attr_enum, value)) 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

62 return 0 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

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#0H(4bac

69 return bool(value) 1#0H(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!ZG'3bac

76 return bool(value) 1!ZG'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) 19YF%2bac

83 return bool(value) 19YF%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) 18XE$1bac

90 return int(value) 18XE$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) 1jfRLdslhTNbac

97 return int(value) 1jfRLdslhTNbac

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) 1RLsTNbac

104 return int(value) 1RLsTNbac

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) 1kgSMetmiUObac

111 return int(value) 1kgSMetmiUObac

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) 1SMtUOInJbac

118 return int(value) 1SMtUOInJbac

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` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvb?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebe5c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r wbxbybzbAb= Bb? @ ce5 deCdeeP feAdge[ ] ^ heK CbQ Db8 X j f R L 9 Y ! Z # 0 k g S M E ied jes keF leG meH nee oet pe$ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 EbFbGb7 C D _ . ) `eHbIbJb* + , - KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

126 self._ipc_data = None 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvb?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebe5c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r wbxbybzbAb= Bb? @ ce5 deCdeeP feAdge[ ] ^ heK CbQ Db8 X j f R L 9 Y ! Z # 0 k g S M E ied jes keF leG meH nee oet pe$ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 EbFbGb7 C D _ . ) `eHbIbJb* + , - KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

127 self._attributes = None 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvb?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebe5c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r wbxbybzbAb= Bb? @ ce5 deCdeeP feAdge[ ] ^ heK CbQ Db8 X j f R L 9 Y ! Z # 0 k g S M E ied jes keF leG meH nee oet pe$ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 EbFbGb7 C D _ . ) `eHbIbJb* + , - KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

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) 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -

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` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 CbDbj f k g l h m i b c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

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

156 cdef Stream s = Stream_accept(stream) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 CbDbj f k g l h m i b c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

157 return _MP_allocate(self, size, s) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 CbDbj f k g l h m i b c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

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: 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

187 self._attributes = _MemPoolAttributes._init(self._h_pool) 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

188 return self._attributes 18XjfRL9Y!Z#0kgSMEdsFGHet$1lhTN%2'3(4miUOInJbac

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{e5c|e6co 7cp 8cFd9cGd!cHd#cId$cu %cv 'c}e(c~e)cJd*cKd+cLd,cMd-caf.cbf/ccf:cNd;cOd=cdf?cef@cPd[cQd]cff^cgf_cRd`cSd{chf|cif}cTd~cUdadjfbdkfcdVdddWdedlffdmfgdXdhdYdidnfjdZdkd0dld1dmd2dnd3dod4dpd5dqd6drd7dsd8dtdw x 9dud!dvd#dwd$dxdDdydEdzdy z A B q r ? @ 5 K 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O 6 7 C D * + , - 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` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

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) 2o p DdEdq r

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)) 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

237  

238 properties.allocType = alloc_type 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

239 properties.handleTypes = ( 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

240 _ipc.IPC_HANDLE_TYPE if ipc_enabled 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

241 else cydriver.CUmemAllocationHandleType.CU_MEM_HANDLE_TYPE_NONE 25 CdP [ ] ^ K Q 8 j R 9 ! # k S E d s F G H e t $ l T % ' ( m U I n J b a c 6 7 D _ )

242 ) 

243 properties.location.id = loc_id 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

244 properties.location.type = loc_type 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

245 properties.maxSize = max_size 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

246  

247 self._mempool_owned = True 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

248 self._h_pool = create_mempool_handle(properties) 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

249 if not self._h_pool: 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - 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: 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - V W

259 alloc_handle = _ipc.MP_export_mempool(self) 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r X f L Y Z 0 g M 1 h N 2 3 4 i O C . ) * + , - V W

260 self._ipc_data = _ipc.IPCDataForMR(alloc_handle, False) 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r X f L Y Z 0 g M 1 h N 2 3 4 i O C . ) * + , - V W

261  

262 return 0 25c6co 7cp 8c9c!c#c$cu %cv 'c(c)c*c+c,c-c.c/c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdw x udvdwdxdydzdy z A B q r 5 CdP [ ] ^ K Q 8 X j f R L 9 Y ! Z # 0 k g S M E d s F G H e t $ 1 l h T N % 2 ' 3 ( 4 m i U O I n J b a c 6 7 C D _ . ) * + , - 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.CUmemoryPool pool 

279 cdef cydriver.CUmemLocation loc = cydriver.CUmemLocation( 

280 type=loc_type, id=loc_id) 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

281 with nogil: 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

282 HANDLE_RETURN(cydriver.cuMemGetMemPool(&pool, &loc, alloc_type)) 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

283 self._h_pool = create_mempool_handle_ref(pool) 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

284 self._mempool_owned = False 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

285 ELSE: 

286 raise RuntimeError( 

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

288 ) 

289 return 0 2?d@d[d]d1c2c^d3c_d4c`d{d|d}d~daebeeeP feAdge[ ] ^ heK Q DbE ied jes keF leG meH nee oet pen a FbGb

290  

291  

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

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

294  

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

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

297 ULLONG_MAX avoids repeated OS round-trips. 

298 """ 

299 cdef cydriver.cuuint64_t current_threshold 

300 cdef cydriver.cuuint64_t max_threshold = ULLONG_MAX 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

301 with nogil: 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

302 HANDLE_RETURN( 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

303 cydriver.cuMemPoolGetAttribute( 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

304 as_cu(self._h_pool), 

305 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

306 &current_threshold 

307 ) 

308 ) 

309 if current_threshold == 0: 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

310 HANDLE_RETURN(cydriver.cuMemPoolSetAttribute( 1=

311 as_cu(self._h_pool), 

312 cydriver.CUmemPool_attribute.CU_MEMPOOL_ATTR_RELEASE_THRESHOLD, 

313 &max_threshold 

314 )) 

315 return 0 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbwbxbybzbAb= Bb? @ cedeCbEbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c

316  

317  

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

319# A result of CU_STREAM_CAPTURE_STATUS_INVALIDATED is considered an error. 

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

321 cdef cydriver.CUstreamCaptureStatus capturing 

322 HANDLE_RETURN(cydriver.cuStreamIsCapturing(s, &capturing)) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

323 if capturing != cydriver.CUstreamCaptureStatus.CU_STREAM_CAPTURE_STATUS_NONE: 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

324 raise RuntimeError("_MemPool cannot perform memory operations on " 1/:;

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

326  

327  

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

329 cdef cydriver.CUstream s = as_cu(stream._h_stream) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

330 cdef DevicePtrHandle h_ptr 

331 with nogil: 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

332 check_not_capturing(s) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

333 h_ptr = deviceptr_alloc_from_pool(size, self._h_pool, stream._h_stream) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

334 if not h_ptr: 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

335 HANDLE_RETURN(get_last_error()) 

336 raise RuntimeError( 

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

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

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

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

341 ) 

342 return Buffer_from_deviceptr_handle(h_ptr, size, self, None, cls) 2` { | } ~ abbbcbdbebfbgbhbibjbkblbmbnb/ : ; obpbqbrbsbtbubvbqerese1c2c3c4cteuevewexeyezeo p FdGdHdIdu v JdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8dw x 9d!d#d$dDdEdy z A B q r wbxbybzbAb= Bb? @ 5 P AdK CbQ Dbj f k g d e l h m i b a c 6 EbFbGb7 C D HbIbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!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}bV W ~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwc%dxc'dyc(dzcAcBcCc)dDcEc*dFc+dGcHcIcJcKcLc,d-dMc.dNcOc/dPc:dQcRcScTcUcVc;dWcXc=dYcZc0c

343  

344  

345cdef inline void _MP_deallocate( 

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

347) noexcept nogil: 

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

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

350 cdef cydriver.CUresult r 

351 with nogil: 

352 r = cydriver.cuMemFreeAsync(devptr, s) 

353 if r != cydriver.CUDA_ERROR_INVALID_CONTEXT: 

354 HANDLE_RETURN(r) 

355  

356  

357cdef inline _MP_close(_MemPool self): 

358 if not self._h_pool: 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -

359 return 

360  

361 # Reset members in declaration order. 

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

363 self._h_pool.reset() 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -

364 self._mempool_owned = False 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -

365 self._ipc_data = None 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -

366 self._attributes = None 2AeBeo Cep DeEeFeGeHeu Iev JeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e:e;e=ew x ?e@e[e]e^e_ey z A B q r I n J C D _ . ) * + , -