@@ -55,17 +55,19 @@ cdef class Buffer:
5555 size_t _size
5656 object _mr
5757 object _ptr_obj
58+ object _alloc_stream
5859
5960 def __init__ (self , *args , **kwargs ):
6061 raise RuntimeError (" Buffer objects cannot be instantiated directly. Please use MemoryResource APIs." )
6162
6263 @classmethod
63- def _init (cls , ptr: DevicePointerT , size_t size , mr: MemoryResource | None = None ):
64+ def _init (cls , ptr: DevicePointerT , size_t size , mr: MemoryResource | None = None , stream: Stream | None = None ):
6465 cdef Buffer self = Buffer.__new__ (cls )
6566 self ._ptr = < uintptr_t> (int (ptr))
6667 self ._ptr_obj = ptr
6768 self ._size = size
6869 self ._mr = mr
70+ self ._alloc_stream = stream
6971 return self
7072
7173 def __del__ (self ):
@@ -81,13 +83,16 @@ cdef class Buffer:
8183 ----------
8284 stream : Stream, optional
8385 The stream object to use for asynchronous deallocation. If None,
84- the behavior depends on the underlying memory resource .
86+ the allocation stream is used .
8587 """
8688 if self ._ptr and self ._mr is not None :
89+ if stream is None :
90+ stream = self ._alloc_stream
8791 self ._mr.deallocate(self ._ptr, self ._size, stream)
8892 self ._ptr = 0
8993 self ._mr = None
9094 self ._ptr_obj = None
95+ self ._alloc_stream = None
9196
9297 @property
9398 def handle (self ) -> DevicePointerT:
@@ -745,9 +750,9 @@ class DeviceMemoryResource(MemoryResource):
745750 stream = default_stream()
746751 err , ptr = driver.cuMemAllocFromPoolAsync(size, self ._mempool_handle, stream.handle)
747752 raise_if_driver_error(err )
748- return Buffer._init(ptr , size , self )
753+ return Buffer._init(ptr , size , self , stream )
749754
750- def deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream = None ):
755+ def deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream ):
751756 """ Deallocate a buffer previously allocated by this resource.
752757
753758 Parameters
@@ -756,12 +761,11 @@ class DeviceMemoryResource(MemoryResource):
756761 The pointer or handle to the buffer to deallocate.
757762 size : int
758763 The size of the buffer to deallocate, in bytes.
759- stream : Stream, optional
764+ stream : Stream
760765 The stream on which to perform the deallocation asynchronously.
761- If None, an internal stream is used.
766+ When the buffer destructor is invoked by the gc instead of explicitly destroyed
767+ via the :meth:`Buffer.close` method, the allocation stream is used.
762768 """
763- if stream is None :
764- stream = default_stream()
765769 err, = driver.cuMemFreeAsync(ptr, stream.handle)
766770 raise_if_driver_error(err)
767771
@@ -832,11 +836,13 @@ class LegacyPinnedMemoryResource(MemoryResource):
832836 Buffer
833837 The allocated buffer object , which is accessible on both host and device.
834838 """
839+ if stream is None:
840+ stream = default_stream()
835841 err , ptr = driver.cuMemAllocHost(size)
836842 raise_if_driver_error(err )
837- return Buffer._init(ptr , size , self )
843+ return Buffer._init(ptr , size , self , stream )
838844
839- def deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream = None ):
845+ def deallocate(self , ptr: DevicePointerT , size_t size , stream: Stream ):
840846 """ Deallocate a buffer previously allocated by this resource.
841847
842848 Parameters
@@ -847,10 +853,8 @@ class LegacyPinnedMemoryResource(MemoryResource):
847853 The size of the buffer to deallocate, in bytes.
848854 stream : Stream, optional
849855 The stream on which to perform the deallocation asynchronously.
850- If None, no synchronization would happen.
851856 """
852- if stream:
853- stream.sync()
857+ stream.sync()
854858 err, = driver.cuMemFreeHost(ptr)
855859 raise_if_driver_error(err)
856860
@@ -877,14 +881,14 @@ class _SynchronousMemoryResource(MemoryResource):
877881 self ._handle = None
878882 self ._dev_id = getattr (device_id, ' device_id' , device_id)
879883
880- def allocate (self , size , stream = None ) -> Buffer:
884+ def allocate (self , size , stream: Stream = None ) -> Buffer:
885+ if stream is None:
886+ stream = default_stream()
881887 err , ptr = driver.cuMemAlloc(size)
882888 raise_if_driver_error(err )
883- return Buffer._init(ptr , size , self )
889+ return Buffer._init(ptr , size , self , stream )
884890
885- def deallocate(self , ptr , size , stream = None ):
886- if stream is None :
887- stream = default_stream()
891+ def deallocate(self , ptr , size , stream: Stream ):
888892 stream.sync()
889893 err, = driver.cuMemFree(ptr)
890894 raise_if_driver_error(err)
0 commit comments