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
« 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
5from __future__ import annotations
7from libc.limits cimport ULLONG_MAX
8from libc.stdint cimport uintptr_t
9from libc.string cimport memset
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
26from cuda.core._utils.cuda_utils cimport (
27 HANDLE_RETURN,
28)
31cdef class _MemPoolAttributes:
32 """Provides access to memory pool attributes."""
34 def __init__(self, *args, **kwargs):
35 raise RuntimeError("_MemPoolAttributes cannot be instantiated directly. Please use MemoryResource APIs.")
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
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 )
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
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
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
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
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
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
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
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
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
111cdef class _MemPool(MemoryResource):
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
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 | ; ) * + , -
126 def allocate(self, size_t size, *, stream: Stream | GraphBuilder) -> Buffer:
127 """Allocate a buffer of the requested size.
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.
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
149 def deallocate(self, ptr: "DevicePointerType", size_t size, *, stream: Stream | GraphBuilder):
150 """Deallocate a buffer previously allocated by this resource.
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)
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
173 @property
174 def handle(self) -> object:
175 """Handle to the underlying memory pool."""
176 return as_py(self._h_pool)
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
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
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
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
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.
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
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
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 )
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
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
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.
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 ` {
276cdef int MP_raise_release_threshold(_MemPool self) except? -1:
277 """Raise the pool's release threshold to ULLONG_MAX if currently zero.
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 ¤t_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
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).")
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
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)
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
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 | ; ) * + , -