44
55from __future__ import annotations
66
7- cimport cython
87from libc.stdint cimport uintptr_t, int64_t, uint64_t
98
109from cuda.bindings cimport cydriver
@@ -19,7 +18,6 @@ from typing import TypeVar, Union
1918
2019from cuda.core.experimental._dlpack import DLDeviceType, make_py_capsule
2120from cuda.core.experimental._utils.cuda_utils import driver
22- from cuda.core.experimental._device import Device
2321
2422__all__ = [' Buffer' , ' MemoryResource' ]
2523
@@ -49,8 +47,6 @@ cdef class Buffer:
4947 self ._ipc_data = None
5048 self ._ptr_obj = None
5149 self ._alloc_stream = None
52- self ._owner = None
53- self ._mem_attrs_inited = False
5450
5551 def __init__ (self , *args , **kwargs ):
5652 raise RuntimeError (" Buffer objects cannot be instantiated directly. "
@@ -59,19 +55,15 @@ cdef class Buffer:
5955 @classmethod
6056 def _init (
6157 cls , ptr: DevicePointerT , size_t size , mr: MemoryResource | None = None ,
62- stream: Stream | None = None , ipc_descriptor: IPCBufferDescriptor | None = None ,
63- owner : object | None = None
58+ stream: Stream | None = None , ipc_descriptor: IPCBufferDescriptor | None = None
6459 ):
6560 cdef Buffer self = Buffer.__new__ (cls )
6661 self ._ptr = < uintptr_t> (int (ptr))
6762 self ._ptr_obj = ptr
6863 self ._size = size
69- if mr is not None and owner is not None :
70- raise ValueError (" owner and memory resource cannot be both specified together" )
7164 self ._memory_resource = mr
7265 self ._ipc_data = IPCDataForBuffer(ipc_descriptor, True ) if ipc_descriptor is not None else None
7366 self ._alloc_stream = < Stream> (stream) if stream is not None else None
74- self ._owner = owner
7567 return self
7668
7769 def __dealloc__ (self ):
@@ -83,8 +75,7 @@ cdef class Buffer:
8375
8476 @staticmethod
8577 def from_handle (
86- ptr: DevicePointerT , size_t size , mr: MemoryResource | None = None ,
87- owner: object | None = None ,
78+ ptr: DevicePointerT , size_t size , mr: MemoryResource | None = None
8879 ) -> Buffer:
8980 """Create a new :class:`Buffer` object from a pointer.
9081
@@ -96,13 +87,9 @@ cdef class Buffer:
9687 Memory size of the buffer
9788 mr : :obj:`~_memory.MemoryResource`, optional
9889 Memory resource associated with the buffer
99- owner : object , optional
100- An object holding external allocation that the ``ptr`` points to.
101- The reference is kept as long as the buffer is alive.
102- The ``owner`` and ``mr`` cannot be specified together.
10390 """
10491 # TODO: It is better to take a stream for latter deallocation
105- return Buffer._init(ptr , size , mr = mr, owner = owner )
92+ return Buffer._init(ptr , size , mr = mr)
10693
10794 @classmethod
10895 def from_ipc_descriptor(
@@ -310,9 +297,7 @@ cdef class Buffer:
310297 """Return the device ordinal of this buffer."""
311298 if self._memory_resource is not None:
312299 return self._memory_resource.device_id
313- else:
314- Buffer_init_mem_attrs(self )
315- return self._mem_attrs.device_id
300+ raise NotImplementedError("WIP: Currently this property only supports buffers with associated MemoryResource")
316301
317302 @property
318303 def handle(self ) -> DevicePointerT:
@@ -336,18 +321,14 @@ cdef class Buffer:
336321 """Return True if this buffer can be accessed by the GPU , otherwise False."""
337322 if self._memory_resource is not None:
338323 return self._memory_resource.is_device_accessible
339- else:
340- Buffer_init_mem_attrs(self )
341- return self._mem_attrs.is_device_accessible
324+ raise NotImplementedError("WIP: Currently this property only supports buffers with associated MemoryResource")
342325
343326 @property
344327 def is_host_accessible(self ) -> bool:
345328 """Return True if this buffer can be accessed by the CPU , otherwise False."""
346329 if self._memory_resource is not None:
347330 return self._memory_resource.is_host_accessible
348- else:
349- Buffer_init_mem_attrs(self )
350- return self._mem_attrs.is_host_accessible
331+ raise NotImplementedError("WIP: Currently this property only supports buffers with associated MemoryResource")
351332
352333 @property
353334 def is_mapped(self ) -> bool:
@@ -365,92 +346,20 @@ cdef class Buffer:
365346 """Return the memory size of this buffer."""
366347 return self._size
367348
368- @property
369- def owner(self ) -> object:
370- """Return the object holding external allocation."""
371- return self._owner
372-
373349
374350# Buffer Implementation
375351# ---------------------
376352cdef inline void Buffer_close(Buffer self , stream ):
377353 cdef Stream s
378- if self ._ptr:
379- if self ._memory_resource is not None :
380- s = Stream_accept(stream) if stream is not None else self ._alloc_stream
381- self ._memory_resource.deallocate(self ._ptr, self ._size, s)
354+ if self ._ptr and self ._memory_resource is not None :
355+ s = Stream_accept(stream) if stream is not None else self ._alloc_stream
356+ self ._memory_resource.deallocate(self ._ptr, self ._size, s)
382357 self ._ptr = 0
383358 self ._memory_resource = None
384- self ._owner = None
385359 self ._ptr_obj = None
386360 self ._alloc_stream = None
387361
388362
389- cdef Buffer_init_mem_attrs(Buffer self ):
390- if not self ._mem_attrs_inited:
391- query_memory_attrs(self ._mem_attrs, self ._ptr)
392- self ._mem_attrs_inited = True
393-
394-
395- cdef int query_memory_attrs(_MemAttrs & out, uintptr_t ptr) except - 1 nogil:
396- cdef unsigned int memory_type = 0
397- cdef int is_managed = 0
398- cdef int device_id = 0
399- _query_memory_attrs(memory_type, is_managed, device_id, < cydriver.CUdeviceptr> ptr)
400-
401- if memory_type == 0 :
402- # unregistered host pointer
403- out.is_host_accessible = True
404- out.is_device_accessible = False
405- out.device_id = - 1
406- # for managed memory, the memory type can be CU_MEMORYTYPE_DEVICE,
407- # so we need to check it first not to falsely claim it is not
408- # host accessible.
409- elif (
410- is_managed
411- or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST
412- ):
413- # For pinned memory allocated with cudaMallocHost or paged-locked
414- # with cudaHostRegister, the memory_type is
415- # cydriver.CUmemorytype.CU_MEMORYTYPE_HOST.
416- # TODO(ktokarski): In some cases, the registered memory requires
417- # using different ptr for device and host, we could check
418- # cuMemHostGetDevicePointer and
419- # CU_DEVICE_ATTRIBUTE_CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM
420- # to double check the device accessibility.
421- out.is_host_accessible = True
422- out.is_device_accessible = True
423- out.device_id = device_id
424- elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE:
425- out.is_host_accessible = False
426- out.is_device_accessible = True
427- out.device_id = device_id
428- else :
429- raise ValueError (f" Unsupported memory type: {memory_type}" )
430- return 0
431-
432-
433- cdef inline int _query_memory_attrs(unsigned int & memory_type, int & is_managed, int & device_id, cydriver.CUdeviceptr ptr) except - 1 nogil:
434- cdef cydriver.CUpointer_attribute attrs[3 ]
435- cdef uintptr_t vals[3 ]
436- attrs[0 ] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE
437- attrs[1 ] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED
438- attrs[2 ] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL
439- vals[0 ] = < uintptr_t>< void * > & memory_type
440- vals[1 ] = < uintptr_t>< void * > & is_managed
441- vals[2 ] = < uintptr_t>< void * > & device_id
442-
443- cdef cydriver.CUresult ret
444- ret = cydriver.cuPointerGetAttributes(3 , attrs, < void ** > vals, ptr)
445- if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED:
446- with cython.gil:
447- # Device class handles the cuInit call internally
448- Device()
449- ret = cydriver.cuPointerGetAttributes(3 , attrs, < void ** > vals, ptr)
450- HANDLE_RETURN(ret)
451- return 0
452-
453-
454363cdef class MemoryResource:
455364 """ Abstract base class for memory resources that manage allocation and
456365 deallocation of buffers.
0 commit comments