@@ -26,49 +26,54 @@ cdef void pycapsule_deleter(object capsule) noexcept:
2626
2727
2828cdef void deleter(DLManagedTensor* tensor) noexcept with gil:
29- stdlib.free(tensor.dl_tensor.shape)
30- if tensor.manager_ctx:
31- cpython.Py_DECREF(< object > tensor.manager_ctx)
32- tensor.manager_ctx = NULL
33- stdlib.free(tensor)
29+ if tensor:
30+ if tensor.dl_tensor.shape:
31+ stdlib.free(tensor.dl_tensor.shape)
32+ if tensor.manager_ctx:
33+ cpython.Py_DECREF(< object > tensor.manager_ctx)
34+ tensor.manager_ctx = NULL
35+ stdlib.free(tensor)
3436
3537
3638cdef void versioned_deleter(DLManagedTensorVersioned* tensor) noexcept with gil:
37- stdlib.free(tensor.dl_tensor.shape)
38- if tensor.manager_ctx:
39- cpython.Py_DECREF(< object > tensor.manager_ctx)
40- tensor.manager_ctx = NULL
41- stdlib.free(tensor)
42-
43-
44- cpdef object make_py_capsule(object buf, bint versioned):
45- cdef DLManagedTensor* dlm_tensor
46- cdef DLManagedTensorVersioned* dlm_tensor_ver
47- cdef DLTensor* dl_tensor
48- cdef void * tensor_ptr
49- cdef const char * capsule_name
50-
51- if versioned:
39+ if tensor:
40+ if tensor.dl_tensor.shape:
41+ stdlib.free(tensor.dl_tensor.shape)
42+ if tensor.manager_ctx:
43+ cpython.Py_DECREF(< object > tensor.manager_ctx)
44+ tensor.manager_ctx = NULL
45+ stdlib.free(tensor)
46+
47+
48+ cdef inline DLManagedTensorVersioned* allocate_dlm_tensor_versioned() except ? NULL :
49+ cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL
50+ try :
5251 dlm_tensor_ver = < DLManagedTensorVersioned* > (
5352 stdlib.malloc(sizeof(DLManagedTensorVersioned)))
54- dlm_tensor_ver.version.major = DLPACK_MAJOR_VERSION
55- dlm_tensor_ver.version.minor = DLPACK_MINOR_VERSION
56- dlm_tensor_ver.manager_ctx = < void * > buf
57- dlm_tensor_ver.deleter = versioned_deleter
58- dlm_tensor_ver.flags = 0
59- dl_tensor = & dlm_tensor_ver.dl_tensor
60- tensor_ptr = dlm_tensor_ver
61- capsule_name = DLPACK_VERSIONED_TENSOR_UNUSED_NAME
62- else :
53+ dlm_tensor_ver.dl_tensor.shape = NULL
54+ dlm_tensor_ver.manager_ctx = NULL
55+ return dlm_tensor_ver
56+ except :
57+ if dlm_tensor_ver:
58+ stdlib.free(dlm_tensor_ver)
59+ raise
60+
61+
62+ cdef inline DLManagedTensor* allocate_dlm_tensor() except ? NULL :
63+ cdef DLManagedTensor* dlm_tensor = NULL
64+ try :
6365 dlm_tensor = < DLManagedTensor* > (
6466 stdlib.malloc(sizeof(DLManagedTensor)))
65- dl_tensor = & dlm_tensor.dl_tensor
66- dlm_tensor.manager_ctx = < void * > buf
67- dlm_tensor.deleter = deleter
68- tensor_ptr = dlm_tensor
69- capsule_name = DLPACK_TENSOR_UNUSED_NAME
67+ dlm_tensor.dl_tensor.shape = NULL
68+ dlm_tensor.manager_ctx = NULL
69+ return dlm_tensor
70+ except :
71+ if dlm_tensor:
72+ stdlib.free(dlm_tensor)
73+ raise
7074
71- dl_tensor.data = < void * >< intptr_t> (int (buf.handle))
75+
76+ cdef inline int setup_dl_tensor_layout(DLTensor* dl_tensor, object buf) except - 1 :
7277 dl_tensor.ndim = 1
7378 cdef int64_t* shape_strides = \
7479 < int64_t* > stdlib.malloc(sizeof(int64_t) * 2 )
@@ -77,7 +82,10 @@ cpdef object make_py_capsule(object buf, bint versioned):
7782 dl_tensor.shape = shape_strides
7883 dl_tensor.strides = NULL
7984 dl_tensor.byte_offset = 0
85+ return 0
86+
8087
88+ cdef inline int setup_dl_tensor_device(DLTensor* dl_tensor, object buf) except - 1 :
8189 cdef DLDevice* device = & dl_tensor.device
8290 # buf should be a Buffer instance
8391 if buf.is_device_accessible and not buf.is_host_accessible:
@@ -91,14 +99,59 @@ cpdef object make_py_capsule(object buf, bint versioned):
9199 device.device_id = 0
92100 else : # not buf.is_device_accessible and not buf.is_host_accessible
93101 raise BufferError(" invalid buffer" )
102+ return 0
94103
104+
105+ cdef inline int setup_dl_tensor_dtype(DLTensor* dl_tensor) except - 1 nogil:
95106 cdef DLDataType* dtype = & dl_tensor.dtype
96107 dtype.code = < uint8_t> kDLInt
97108 dtype.lanes = < uint16_t> 1
98109 dtype.bits = < uint8_t> 8
110+ return 0
111+
99112
100- cpython.Py_INCREF(buf)
101- return cpython.PyCapsule_New(tensor_ptr, capsule_name, pycapsule_deleter)
113+ cpdef object make_py_capsule(object buf, bint versioned):
114+ cdef DLManagedTensor* dlm_tensor = NULL
115+ cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL
116+ cdef DLTensor* dl_tensor
117+ cdef void * tensor_ptr
118+ cdef const char * capsule_name
119+ cdef object ret = None
120+
121+ try :
122+ if versioned:
123+ dlm_tensor_ver = allocate_dlm_tensor_versioned()
124+ # Transfer the reference to manager_ctx
125+ cpython.Py_INCREF(buf)
126+ dlm_tensor_ver.manager_ctx = < void * > buf
127+ dlm_tensor_ver.deleter = versioned_deleter
128+ dlm_tensor_ver.version.major = DLPACK_MAJOR_VERSION
129+ dlm_tensor_ver.version.minor = DLPACK_MINOR_VERSION
130+ dlm_tensor_ver.flags = 0
131+ dl_tensor = & dlm_tensor_ver.dl_tensor
132+ tensor_ptr = dlm_tensor_ver
133+ capsule_name = DLPACK_VERSIONED_TENSOR_UNUSED_NAME
134+ else :
135+ dlm_tensor = allocate_dlm_tensor()
136+ # Transfer the reference to manager_ctx
137+ cpython.Py_INCREF(buf)
138+ dlm_tensor.manager_ctx = < void * > buf
139+ dlm_tensor.deleter = deleter
140+ dl_tensor = & dlm_tensor.dl_tensor
141+ tensor_ptr = dlm_tensor
142+ capsule_name = DLPACK_TENSOR_UNUSED_NAME
143+
144+ dl_tensor.data = < void * >< intptr_t> (int (buf.handle))
145+ setup_dl_tensor_layout(dl_tensor, buf)
146+ setup_dl_tensor_device(dl_tensor, buf)
147+ setup_dl_tensor_dtype(dl_tensor)
148+ ret = cpython.PyCapsule_New(tensor_ptr, capsule_name, pycapsule_deleter)
149+ except :
150+ if ret is None :
151+ deleter(dlm_tensor)
152+ versioned_deleter(dlm_tensor_ver)
153+ raise
154+ return ret
102155
103156
104157class DLDeviceType (IntEnum ):
0 commit comments