@@ -39,9 +39,6 @@ if TYPE_CHECKING:
3939 from ._device import Device
4040 import uuid
4141
42- # TODO: define a memory property mixin class and make Buffer and
43- # MemoryResource both inherit from it
44-
4542
4643PyCapsule = TypeVar(" PyCapsule" )
4744""" Represent the capsule type."""
@@ -50,7 +47,56 @@ DevicePointerT = Union[driver.CUdeviceptr, int, None]
5047""" A type union of :obj:`~driver.CUdeviceptr`, `int` and `None` for hinting :attr:`Buffer.handle`."""
5148
5249
53- cdef class Buffer:
50+ cdef class _cyBuffer:
51+ """
52+ Internal only. Responsible for offering fast C method access.
53+ """
54+ cdef:
55+ intptr_t _ptr
56+ size_t _size
57+ _cyMemoryResource _mr
58+ object _ptr_obj
59+
60+
61+ cdef class _cyMemoryResource:
62+ """
63+ Internal only. Responsible for offering fast C method access.
64+ """
65+ cdef Buffer _allocate(self , size_t size, cyStream stream):
66+ raise NotImplementedError
67+
68+ cdef void _deallocate(self , intptr_t ptr, size_t size, cyStream stream) noexcept:
69+ raise NotImplementedError
70+
71+
72+ class MemoryResourceAttributes (abc.ABC ):
73+
74+ @property
75+ @abc.abstractmethod
76+ def is_device_accessible (self ) -> bool:
77+ """bool: True if buffers allocated by this resource can be accessed on the device."""
78+ ...
79+
80+ @property
81+ @abc.abstractmethod
82+ def is_host_accessible(self ) -> bool:
83+ """bool: True if buffers allocated by this resource can be accessed on the host."""
84+ ...
85+
86+ @property
87+ @abc.abstractmethod
88+ def device_id(self ) -> int:
89+ """int: The device ordinal for which this memory resource is responsible.
90+
91+ Raises
92+ ------
93+ RuntimeError
94+ If the resource is not bound to a specific device.
95+ """
96+ ...
97+
98+
99+ cdef class Buffer(_cyBuffer , MemoryResourceAttributes ):
54100 """ Represent a handle to allocated memory.
55101
56102 This generic object provides a unified representation for how
@@ -59,12 +105,7 @@ cdef class Buffer:
59105
60106 Support for data interchange mechanisms are provided by DLPack.
61107 """
62-
63- cdef:
64- intptr_t _ptr
65- size_t _size
66- object _mr
67- object _ptr_obj
108+ cdef dict __dict__ # required if inheriting from both Cython/Python classes
68109
69110 def __init__ (self , *args , **kwargs ):
70111 raise RuntimeError (" Buffer objects cannot be instantiated directly. Please use MemoryResource APIs." )
@@ -96,17 +137,12 @@ cdef class Buffer:
96137 The stream object to use for asynchronous deallocation. If None,
97138 the behavior depends on the underlying memory resource.
98139 """
99- cdef _cyMemoryResource cy_mr
100140 if self ._ptr and self ._mr is not None :
101- if isinstance (self ._mr, _cyMemoryResource):
102- # FIXME
103- if stream is None :
104- stream = Stream.__new__ (Stream)
105- (< cyStream> (stream))._handle = < cydriver.CUstream> (0 )
106- cy_mr = < _cyMemoryResource> (self ._mr)
107- cy_mr._deallocate(self ._ptr, self ._size, < cyStream> stream)
108- else :
109- self ._mr.deallocate(self ._ptr, self ._size, stream)
141+ # To be fixed in NVIDIA/cuda-python#1032
142+ if stream is None :
143+ stream = Stream.__new__ (Stream)
144+ (< cyStream> (stream))._handle = < cydriver.CUstream> (0 )
145+ self ._mr._deallocate(self ._ptr, self ._size, < cyStream> stream)
110146 self ._ptr = 0
111147 self ._mr = None
112148 self ._ptr_obj = None
@@ -303,18 +339,7 @@ cdef class Buffer:
303339 return Buffer._init(ptr , size , mr = mr)
304340
305341
306- cdef class _cyMemoryResource:
307- """
308- Internal only. Responsible for offering fast C method access.
309- """
310- cdef Buffer _allocate(self , size_t size , cyStream stream ):
311- raise NotImplementedError
312-
313- cdef int _deallocate(self , intptr_t ptr, size_t size, cyStream stream) except ?- 1 :
314- raise NotImplementedError
315-
316-
317- class MemoryResource (abc.ABC ):
342+ cdef class MemoryResource(_cyMemoryResource , MemoryResourceAttributes , abc.ABC ):
318343 """ Abstract base class for memory resources that manage allocation and deallocation of buffers.
319344
320345 Subclasses must implement methods for allocating and deallocation, as well as properties
@@ -323,14 +348,10 @@ class MemoryResource(abc.ABC):
323348 hold a reference to self, the buffer properties are retrieved simply by looking up the underlying
324349 memory resource's respective property.)
325350 """
351+ cdef dict __dict__ # required if inheriting from both Cython/Python classes
326352
327- @abc.abstractmethod
328- def __init__ (self , *args , **kwargs ):
329- """ Initialize the memory resource.
330-
331- Subclasses may use additional arguments to configure the resource.
332- """
333- ...
353+ cdef void _deallocate(self , intptr_t ptr, size_t size, cyStream stream) noexcept:
354+ self .deallocate(ptr, size, stream)
334355
335356 @abc.abstractmethod
336357 def allocate (self , size_t size , stream: Stream = None ) -> Buffer:
@@ -370,30 +391,6 @@ class MemoryResource(abc.ABC):
370391 """
371392 ...
372393
373- @property
374- @abc.abstractmethod
375- def is_device_accessible (self ) -> bool:
376- """bool: True if buffers allocated by this resource can be accessed on the device."""
377- ...
378-
379- @property
380- @abc.abstractmethod
381- def is_host_accessible(self ) -> bool:
382- """bool: True if buffers allocated by this resource can be accessed on the host."""
383- ...
384-
385- @property
386- @abc.abstractmethod
387- def device_id(self ) -> int:
388- """int: The device ordinal for which this memory resource is responsible.
389-
390- Raises
391- ------
392- RuntimeError
393- If the resource is not bound to a specific device.
394- """
395- ...
396-
397394
398395# IPC is currently only supported on Linux. On other platforms, the IPC handle
399396# type is set equal to the no-IPC handle type.
@@ -570,7 +567,7 @@ class DeviceMemoryResourceAttributes:
570567_ipc_registry = {}
571568
572569
573- cdef class DeviceMemoryResource(_cyMemoryResource, MemoryResource):
570+ cdef class DeviceMemoryResource(MemoryResource):
574571 """
575572 Create a device memory resource managing a stream-ordered memory pool.
576573
@@ -657,7 +654,7 @@ cdef class DeviceMemoryResource(_cyMemoryResource, MemoryResource):
657654 bint _is_mapped
658655 object _uuid
659656 IPCAllocationHandle _alloc_handle
660- dict __dict__ # TODO: check if we still need this
657+ dict __dict__ # required if inheriting from both Cython/Python classes
661658 object __weakref__
662659
663660 def __cinit__ (self ):
@@ -917,14 +914,13 @@ cdef class DeviceMemoryResource(_cyMemoryResource, MemoryResource):
917914 stream = default_stream()
918915 return self._allocate(size , <cyStream>stream )
919916
920- cdef int _deallocate(self , intptr_t ptr , size_t size , cyStream stream ) except?-1 :
917+ cdef void _deallocate(self , intptr_t ptr , size_t size , cyStream stream ) noexcept :
921918 cdef cydriver.CUstream s = stream._handle
922919 cdef cydriver.CUdeviceptr devptr = < cydriver.CUdeviceptr> ptr
923920 with nogil:
924921 HANDLE_RETURN(cydriver.cuMemFreeAsync(devptr , s ))
925- return 0
926922
927- def deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream = None ):
923+ cpdef deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream = None ):
928924 """ Deallocate a buffer previously allocated by this resource.
929925
930926 Parameters
0 commit comments