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
« 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
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) 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
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: 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
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
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
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
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
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
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
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
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
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` { | } ~ 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
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 _ . ) * + , -
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` { | } ~ 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
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: 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
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{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
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
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
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)) 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
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
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 )
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
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
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.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
292cdef int MP_raise_release_threshold(_MemPool self) except? -1:
293 """Raise the pool's release threshold to ULLONG_MAX if currently zero.
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 ¤t_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
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).")
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
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)
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
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 _ . ) * + , -