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
« 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
5from __future__ import annotations
7cimport cython
8from libc.limits cimport ULLONG_MAX
9from libc.stdint cimport uintptr_t
10from libc.string cimport memset
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
27from cuda.core._utils.cuda_utils cimport (
28 HANDLE_RETURN,
29)
31import uuid
32from typing import TYPE_CHECKING
34if TYPE_CHECKING:
35 from cuda.core.graph import GraphBuilder
36 from cuda.core.typing import DevicePointerType
39cdef class _MemPoolAttributes:
40 """Provides access to memory pool attributes."""
41 cdef:
42 MemoryPoolHandle _h_pool
44 def __init__(self, *args, **kwargs) -> None:
45 raise RuntimeError("_MemPoolAttributes cannot be instantiated directly. Please use MemoryResource APIs.")
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
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 )
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
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
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
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
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
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
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
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
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
121cdef class _MemPool(MemoryResource):
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
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 | ; ) * + , -
136 def allocate(self, size_t size, *, stream: Stream | GraphBuilder) -> Buffer:
137 """Allocate a buffer of the requested size.
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.
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
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.
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)
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
190 @property
191 def handle(self) -> object:
192 """Handle to the underlying memory pool."""
193 return as_py(self._h_pool)
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
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
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
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
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.
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
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
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 )
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
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
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.
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 ` {
293cdef int MP_raise_release_threshold(_MemPool self) except? -1:
294 """Raise the pool's release threshold to ULLONG_MAX if currently zero.
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 ¤t_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
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).")
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
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)
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
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 | ; ) * + , -