| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| import ctypes |
| from libc.stdint cimport int32_t, int64_t, uint64_t, uint32_t, uint8_t, int16_t |
| from libc.string cimport memcpy |
| from libcpp.vector cimport vector |
| from cpython.bytes cimport PyBytes_AsStringAndSize, PyBytes_FromStringAndSize, PyBytes_AsString |
| from cpython cimport Py_INCREF, Py_DECREF, Py_REFCNT |
| from cpython cimport PyErr_CheckSignals, PyGILState_Ensure, PyGILState_Release, PyObject |
| from cpython cimport pycapsule, PyCapsule_Destructor |
| from cpython cimport PyErr_SetNone |
| |
| cdef extern from "dlpack/dlpack.h": |
| int DLPACK_MAJOR_VERSION |
| int DLPACK_MINOR_VERSION |
| |
| cdef enum: |
| kDLCPU = 1, |
| kDLCUDA = 2, |
| kDLCUDAHost = 3, |
| kDLOpenCL = 4, |
| kDLVulkan = 7, |
| kDLMetal = 8, |
| kDLVPI = 9, |
| kDLROCM = 10, |
| kDLROCMHost = 11, |
| kDLExtDev = 12, |
| kDLCUDAManaged = 13, |
| kDLOneAPI = 14, |
| kDLWebGPU = 15, |
| kDLHexagon = 16, |
| kDLMAIA = 17 |
| kDLTrn = 18 |
| |
| ctypedef struct DLDataType: |
| uint8_t code |
| uint8_t bits |
| int16_t lanes |
| |
| ctypedef struct DLDevice: |
| int device_type |
| int device_id |
| |
| ctypedef struct DLTensor: |
| void* data |
| DLDevice device |
| int ndim |
| DLDataType dtype |
| int64_t* shape |
| int64_t* strides |
| uint64_t byte_offset |
| |
| ctypedef struct DLPackVersion: |
| uint32_t major |
| uint32_t minor |
| |
| ctypedef struct DLManagedTensor: |
| DLTensor dl_tensor |
| void* manager_ctx |
| void (*deleter)(DLManagedTensor* self) |
| |
| ctypedef struct DLManagedTensorVersioned: |
| DLPackVersion version |
| DLTensor dl_tensor |
| void* manager_ctx |
| void (*deleter)(DLManagedTensorVersioned* self) |
| uint64_t flags |
| |
| # DLPack Exchange API function pointer types |
| ctypedef int (*DLPackManagedTensorAllocator)( |
| DLTensor* prototype, |
| DLManagedTensorVersioned** out, |
| void* error_ctx, |
| void (*SetError)(void* error_ctx, const char* kind, const char* message) |
| ) noexcept |
| |
| ctypedef int (*DLPackManagedTensorFromPyObjectNoSync)( |
| void* py_object, |
| DLManagedTensorVersioned** out |
| ) except -1 |
| |
| ctypedef int (*DLPackManagedTensorToPyObjectNoSync)( |
| DLManagedTensorVersioned* tensor, |
| void** out_py_object |
| ) except -1 |
| |
| ctypedef int (*DLPackCurrentWorkStream)( |
| int device_type, |
| int32_t device_id, |
| void** out_current_stream |
| ) except -1 |
| |
| ctypedef int (*DLPackDLTensorFromPyObjectNoSync)( |
| void* py_object, |
| DLTensor* out |
| ) except -1 |
| |
| ctypedef struct DLPackExchangeAPIHeader: |
| DLPackVersion version |
| DLPackExchangeAPIHeader* prev_api |
| |
| ctypedef struct DLPackExchangeAPI: |
| DLPackExchangeAPIHeader header |
| DLPackManagedTensorAllocator managed_tensor_allocator |
| DLPackManagedTensorFromPyObjectNoSync managed_tensor_from_py_object_no_sync |
| DLPackManagedTensorToPyObjectNoSync managed_tensor_to_py_object_no_sync |
| DLPackDLTensorFromPyObjectNoSync dltensor_from_py_object_no_sync |
| DLPackCurrentWorkStream current_work_stream |
| |
| |
| # Cython binding for TVM FFI C API |
| cdef extern from "tvm/ffi/c_api.h": |
| cdef enum TVMFFITypeIndex: |
| kTVMFFIAny = -1 |
| kTVMFFINone = 0 |
| kTVMFFIInt = 1 |
| kTVMFFIBool = 2 |
| kTVMFFIFloat = 3 |
| kTVMFFIOpaquePtr = 4 |
| kTVMFFIDataType = 5 |
| kTVMFFIDevice = 6 |
| kTVMFFIDLTensorPtr = 7 |
| kTVMFFIRawStr = 8 |
| kTVMFFIByteArrayPtr = 9 |
| kTVMFFIObjectRValueRef = 10 |
| kTVMFFISmallStr = 11 |
| kTVMFFISmallBytes = 12 |
| kTVMFFIStaticObjectBegin = 64 |
| kTVMFFIObject = 64 |
| kTVMFFIStr = 65 |
| kTVMFFIBytes = 66 |
| kTVMFFIError = 67 |
| kTVMFFIFunction = 68 |
| kTVMFFIShape = 69 |
| kTVMFFITensor = 70 |
| kTVMFFIArray = 71 |
| kTVMFFIMap = 72 |
| kTVMFFIModule = 73 |
| kTVMFFIOpaquePyObject = 74 |
| kTVMFFIList = 75 |
| kTVMFFIDict = 76 |
| kTVMFFIStaticObjectEnd |
| |
| ctypedef void* TVMFFIObjectHandle |
| |
| ctypedef struct TVMFFIObject: |
| uint64_t combined_ref_count |
| int32_t type_index |
| uint32_t __padding |
| void (*deleter)(void* self, int flags) |
| |
| ctypedef struct TVMFFIAny: |
| int32_t type_index |
| int32_t zero_padding |
| int64_t v_int64 |
| double v_float64 |
| void* v_ptr |
| TVMFFIObject* v_obj |
| const char* v_c_str |
| DLDataType v_dtype |
| DLDevice v_device |
| |
| ctypedef struct TVMFFIByteArray: |
| const char* data |
| size_t size |
| |
| ctypedef struct TVMFFIOpaqueObjectCell: |
| void* handle |
| |
| ctypedef struct TVMFFIShapeCell: |
| const int64_t* data |
| size_t size |
| |
| ctypedef enum TVMFFIBacktraceUpdateMode: |
| kTVMFFIBacktraceUpdateModeReplace = 0 |
| kTVMFFIBacktraceUpdateModeAppend = 1 |
| |
| ctypedef struct TVMFFIErrorCell: |
| TVMFFIByteArray kind |
| TVMFFIByteArray message |
| TVMFFIByteArray backtrace |
| void (*update_backtrace)( |
| TVMFFIObjectHandle self, const TVMFFIByteArray* backtrace, int32_t update_mode |
| ) |
| TVMFFIObjectHandle cause_chain |
| TVMFFIObjectHandle extra_context |
| |
| ctypedef int (*TVMFFISafeCallType)( |
| void* handle, const TVMFFIAny* args, int32_t num_args, |
| TVMFFIAny* result) noexcept |
| |
| cdef enum TVMFFIFieldFlagBitMask: |
| kTVMFFIFieldFlagBitMaskWritable = 1 << 0 |
| kTVMFFIFieldFlagBitMaskHasDefault = 1 << 1 |
| kTVMFFIFieldFlagBitMaskIsStaticMethod = 1 << 2 |
| kTVMFFIFieldFlagBitMaskSEqHashIgnore = 1 << 3 |
| kTVMFFIFieldFlagBitMaskSEqHashDefRecursive = 1 << 4 |
| kTVMFFIFieldFlagBitMaskDefaultFromFactory = 1 << 5 |
| kTVMFFIFieldFlagBitMaskReprOff = 1 << 6 |
| kTVMFFIFieldFlagBitMaskCompareOff = 1 << 7 |
| kTVMFFIFieldFlagBitMaskHashOff = 1 << 8 |
| kTVMFFIFieldFlagBitMaskInitOff = 1 << 9 |
| kTVMFFIFieldFlagBitMaskKwOnly = 1 << 10 |
| kTVMFFIFieldFlagBitSetterIsFunctionObj = 1 << 11 |
| kTVMFFIFieldFlagBitMaskSEqHashDefNonRecursive = 1 << 12 |
| |
| ctypedef int (*TVMFFIFieldGetter)(void* field, TVMFFIAny* result) noexcept |
| ctypedef int (*TVMFFIFieldSetter)(void* field, const TVMFFIAny* value) noexcept |
| ctypedef int (*TVMFFIObjectCreator)(TVMFFIObjectHandle* result) noexcept |
| |
| ctypedef struct TVMFFIFieldInfo: |
| TVMFFIByteArray name |
| TVMFFIByteArray doc |
| TVMFFIByteArray metadata |
| int64_t flags |
| int64_t size |
| int64_t alignment |
| int64_t offset |
| TVMFFIFieldGetter getter |
| void* setter |
| TVMFFIAny default_value_or_factory |
| int32_t field_static_type_index |
| |
| ctypedef struct TVMFFIMethodInfo: |
| TVMFFIByteArray name |
| TVMFFIByteArray doc |
| TVMFFIByteArray metadata |
| int64_t flags |
| TVMFFIAny method |
| |
| cdef enum TVMFFISEqHashKind: |
| kTVMFFISEqHashKindUnsupported = 0 |
| kTVMFFISEqHashKindTreeNode = 1 |
| kTVMFFISEqHashKindFreeVar = 2 |
| kTVMFFISEqHashKindDAGNode = 3 |
| kTVMFFISEqHashKindConstTreeNode = 4 |
| kTVMFFISEqHashKindUniqueInstance = 5 |
| |
| cdef enum TVMFFIDefRegionKind: |
| kTVMFFIDefRegionKindNone = 0 |
| kTVMFFIDefRegionKindRecursive = 1 |
| kTVMFFIDefRegionKindNonRecursive = 2 |
| |
| ctypedef struct TVMFFITypeMetadata: |
| TVMFFIByteArray doc |
| TVMFFIObjectCreator creator |
| int32_t total_size |
| TVMFFISEqHashKind structural_eq_hash_kind |
| |
| ctypedef struct TVMFFITypeInfo: |
| int32_t type_index |
| int32_t type_depth |
| TVMFFIByteArray type_key |
| const TVMFFITypeInfo** type_ancestors |
| uint64_t type_key_hash |
| int32_t num_fields |
| int32_t num_methods |
| const TVMFFIFieldInfo* fields |
| const TVMFFIMethodInfo* methods |
| const TVMFFITypeMetadata* metadata |
| |
| ctypedef struct TVMFFITypeAttrColumn: |
| const TVMFFIAny* data |
| int32_t size |
| int32_t begin_index |
| |
| int TVMFFIObjectDecRef(TVMFFIObjectHandle obj) nogil |
| int TVMFFIObjectIncRef(TVMFFIObjectHandle obj) nogil |
| int TVMFFIObjectCreateOpaque(void* handle, int32_t type_index, |
| void (*deleter)(void*), TVMFFIObjectHandle* out) nogil |
| int TVMFFIObjectGetTypeIndex(TVMFFIObjectHandle obj) nogil |
| int TVMFFIFunctionCall(TVMFFIObjectHandle func, TVMFFIAny* args, int32_t num_args, |
| TVMFFIAny* result) nogil |
| int TVMFFIFunctionCreate(void* self, TVMFFISafeCallType safe_call, |
| void (*deleter)(void*), TVMFFIObjectHandle* out) nogil |
| int TVMFFIAnyViewToOwnedAny(const TVMFFIAny* any_view, TVMFFIAny* out) nogil |
| int TVMFFIFunctionSetGlobal(TVMFFIByteArray* name, TVMFFIObjectHandle f, int override) nogil |
| int TVMFFIFunctionGetGlobal(TVMFFIByteArray* name, TVMFFIObjectHandle* out) nogil |
| void TVMFFIErrorMoveFromRaised(TVMFFIObjectHandle* result) nogil |
| void TVMFFIErrorSetRaised(TVMFFIObjectHandle error) nogil |
| int TVMFFIErrorCreate(TVMFFIByteArray* kind, TVMFFIByteArray* message, |
| TVMFFIByteArray* backtrace, TVMFFIObjectHandle* out) nogil |
| |
| int TVMFFITypeKeyToIndex(TVMFFIByteArray* type_key, int32_t* out_tindex) nogil |
| int TVMFFIStringFromByteArray(TVMFFIByteArray* input_, TVMFFIAny* out) nogil |
| int TVMFFIBytesFromByteArray(TVMFFIByteArray* input_, TVMFFIAny* out) nogil |
| int TVMFFIDataTypeFromString(TVMFFIByteArray* str, DLDataType* out) nogil |
| int TVMFFIDataTypeToString(const DLDataType* dtype, TVMFFIAny* out) nogil |
| const TVMFFIByteArray* TVMFFIBacktrace(const char* filename, int lineno, |
| const char* func, int cross_ffi_boundary) nogil |
| int TVMFFITensorFromDLPack(DLManagedTensor* src, int32_t require_alignment, |
| int32_t require_contiguous, TVMFFIObjectHandle* out) nogil |
| int TVMFFITensorFromDLPackVersioned(DLManagedTensorVersioned* src, |
| int32_t require_alignment, |
| int32_t require_contiguous, |
| TVMFFIObjectHandle* out) nogil |
| int TVMFFITensorToDLPack(TVMFFIObjectHandle src, DLManagedTensor** out) nogil |
| int TVMFFITensorToDLPackVersioned(TVMFFIObjectHandle src, |
| DLManagedTensorVersioned** out) nogil |
| const TVMFFITypeInfo* TVMFFIGetTypeInfo(int32_t type_index) nogil |
| TVMFFIByteArray TVMFFISmallBytesGetContentByteArray(const TVMFFIAny* value) nogil |
| TVMFFIByteArray* TVMFFIBytesGetByteArrayPtr(TVMFFIObjectHandle obj) nogil |
| TVMFFIErrorCell* TVMFFIErrorGetCellPtr(TVMFFIObjectHandle obj) nogil |
| TVMFFIOpaqueObjectCell* TVMFFIOpaqueObjectGetCellPtr(TVMFFIObjectHandle obj) nogil |
| TVMFFIShapeCell* TVMFFIShapeGetCellPtr(TVMFFIObjectHandle obj) nogil |
| DLTensor* TVMFFITensorGetDLTensorPtr(TVMFFIObjectHandle obj) nogil |
| DLDevice TVMFFIDLDeviceFromIntPair(int32_t device_type, int32_t device_id) nogil |
| const TVMFFITypeAttrColumn* TVMFFIGetTypeAttrColumn(const TVMFFIByteArray* attr_name) nogil |
| |
| int32_t TVMFFITypeGetOrAllocIndex( |
| const TVMFFIByteArray* type_key, |
| int32_t static_type_index, |
| int32_t type_depth, |
| int32_t num_child_slots, |
| int32_t child_slots_can_overflow, |
| int32_t parent_type_index |
| ) nogil |
| int TVMFFITypeRegisterField(int32_t type_index, const TVMFFIFieldInfo* info) nogil |
| int TVMFFITypeRegisterMethod(int32_t type_index, const TVMFFIMethodInfo* info) nogil |
| int TVMFFITypeRegisterMetadata(int32_t type_index, const TVMFFITypeMetadata* metadata) nogil |
| int TVMFFITypeRegisterAttr(int32_t type_index, const TVMFFIByteArray* attr_name, |
| const TVMFFIAny* attr_value) nogil |
| void TVMFFIErrorSetRaisedFromCStr(const char* kind, const char* message) nogil |
| |
| cdef extern from "tvm/ffi/extra/c_env_api.h": |
| ctypedef void* TVMFFIStreamHandle |
| |
| int TVMFFIEnvRegisterCAPI(const char* name, void* ptr) nogil |
| void* TVMFFIEnvGetStream(int32_t device_type, int32_t device_id) nogil |
| int TVMFFIEnvSetStream(int32_t device_type, int32_t device_id, TVMFFIStreamHandle stream, |
| TVMFFIStreamHandle* opt_out_original_stream) nogil |
| |
| |
| def _env_set_current_stream(int device_type, int device_id, uint64_t stream): |
| cdef TVMFFIStreamHandle prev_stream = NULL |
| CHECK_CALL(TVMFFIEnvSetStream( |
| device_type, |
| device_id, |
| <void*>stream, |
| &prev_stream)) |
| return <uint64_t>prev_stream |
| |
| |
| def _env_get_current_stream(int device_type, int device_id): |
| cdef void* current_stream |
| current_stream = TVMFFIEnvGetStream(device_type, device_id) |
| return <uint64_t>current_stream |
| |
| |
| # PyObject-tying state machine (binds one Python wrapper to one C++ chandle). The C++ impl lives in |
| # tvm_ffi_python_object.h; see its top-of-file banner for the design. |
| cdef extern from "tvm_ffi_python_object.h": |
| int TVMFFIPyRegisterDefaultAllocator() noexcept |
| void TVMFFIPyMarkPythonFinalizing() noexcept |
| |
| void TVMFFIPyCompareAndRebindPyObject(void* chandle, PyObject* expect, PyObject* new_object) noexcept |
| void TVMFFIPyTpDealloc(void** ptr_to_chandle, PyObject* wrapper) noexcept |
| void TVMFFIPyInstallTypeSlots(PyObject* type_obj) noexcept |
| object TVMFFIPyMakeRetObject(void* chandle, PyObject* cls_type) |
| |
| |
| cdef extern from "tvm_ffi_python_helpers.h": |
| # no need to expose fields of the call context setter data structure |
| ctypedef struct TVMFFIPyCallContext: |
| int device_type |
| int device_id |
| TVMFFIStreamHandle stream |
| const DLPackExchangeAPI* dlpack_c_exchange_api |
| |
| ctypedef struct TVMFFIPyArgSetter: |
| int (*func)(TVMFFIPyArgSetter* handle, TVMFFIPyCallContext* ctx, PyObject* py_arg, TVMFFIAny* out) except -1 |
| const DLPackExchangeAPI* dlpack_c_exchange_api |
| |
| # The main call function |
| int TVMFFIPyFuncCall( |
| void* chandle, |
| PyObject* py_arg_tuple, |
| TVMFFIAny* result, |
| int* c_api_ret_code, |
| int release_gil, |
| const DLPackExchangeAPI** out_ctx_dlpack_api |
| ) except -1 |
| |
| int TVMFFIPyConstructorCall( |
| void* chandle, |
| PyObject* py_arg_tuple, |
| TVMFFIAny* result, |
| int* c_api_ret_code, |
| TVMFFIPyCallContext* parent_ctx |
| ) except -1 |
| |
| int TVMFFIPyCallFieldSetter( |
| void* field_setter, |
| int64_t field_flags, |
| void* field_ptr, |
| PyObject* py_arg, |
| int* c_api_ret_code |
| ) except -1 |
| |
| int TVMFFIPyPyObjectToFFIAny( |
| PyObject* py_arg, |
| TVMFFIAny* out, |
| int* c_api_ret_code |
| ) except -1 |
| |
| int TVMFFIPySetArgumentGenericDispatcher( |
| TVMFFIPyCallContext* ctx, |
| PyObject* py_arg, |
| TVMFFIAny* out |
| ) except -1 |
| |
| size_t TVMFFIPyGetArgDispatchMapSize() noexcept |
| |
| void TVMFFIPyPushTempFFIObject(TVMFFIPyCallContext* ctx, TVMFFIObjectHandle arg) noexcept |
| void TVMFFIPyPushTempPyObject(TVMFFIPyCallContext* ctx, PyObject* arg) noexcept |
| void TVMFFIPyPushExtraTempPyObject(TVMFFIPyCallContext* ctx, PyObject* arg) |
| # the predefined setters for common POD types |
| int TVMFFIPyArgSetterFloat_(TVMFFIPyArgSetter*, TVMFFIPyCallContext*, PyObject* arg, TVMFFIAny* out) except -1 |
| int TVMFFIPyArgSetterInt_(TVMFFIPyArgSetter*, TVMFFIPyCallContext*, PyObject* arg, TVMFFIAny* out) except -1 |
| int TVMFFIPyArgSetterBool_(TVMFFIPyArgSetter*, TVMFFIPyCallContext*, PyObject* arg, TVMFFIAny* out) except -1 |
| int TVMFFIPyArgSetterNone_(TVMFFIPyArgSetter*, TVMFFIPyCallContext*, PyObject* arg, TVMFFIAny* out) except -1 |
| |
| # Callback arg setter types — view-based AnyView -> PyObject conversion |
| # used by the C++ -> Python callback path (PyCallback). |
| ctypedef int (*TVMFFIPyCallbackArgSetterCallback)(TVMFFIPyCallbackArgSetter* handle, |
| const DLPackExchangeAPI* api, |
| const TVMFFIAny* arg, |
| PyObject** out) except -1 |
| |
| ctypedef struct TVMFFIPyCallbackArgSetter: |
| TVMFFIPyCallbackArgSetterCallback func |
| |
| # Built-in C callback arg setters for POD types. |
| int TVMFFIPyCallbackArgSetterNone_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny*, PyObject** out) except -1 |
| int TVMFFIPyCallbackArgSetterBool_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny* arg, PyObject** out) except -1 |
| int TVMFFIPyCallbackArgSetterInt_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny* arg, PyObject** out) except -1 |
| int TVMFFIPyCallbackArgSetterFloat_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny* arg, PyObject** out) except -1 |
| int TVMFFIPyCallbackArgSetterSmallStr_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny* arg, PyObject** out) except -1 |
| int TVMFFIPyCallbackArgSetterSmallBytes_(TVMFFIPyCallbackArgSetter*, const DLPackExchangeAPI*, |
| const TVMFFIAny* arg, PyObject** out) except -1 |
| |
| int TVMFFIPyCallback(void* context, const TVMFFIAny* packed_args, |
| int32_t num_args, TVMFFIAny* result) noexcept |
| |
| # Closure + convert helper for the PyCallback path. Returns the raw FFI rc; |
| # callers use CHECK_CALL to translate the TLS FFI error into a Python exception. |
| int TVMFFIPyConvertPyCallback(PyObject* callable, |
| const DLPackExchangeAPI* dlpack_api, |
| TVMFFIObjectHandle* out_handle) noexcept |
| |
| # MLIRPackedSafeCall |
| void* TVMFFIPyMLIRPackedSafeCallCreate(void (*mlir_packed_safe_call)(void**) noexcept, PyObject* keep_alive_object) |
| int TVMFFIPyMLIRPackedSafeCallInvoke(void* self, const TVMFFIAny* args, int32_t num_args, TVMFFIAny* rv) |
| void TVMFFIPyMLIRPackedSafeCallDeleter(void* self) |
| # deleter for python objects |
| void TVMFFIPyObjectDeleter(void* py_obj) noexcept nogil |
| # dummy target for testing |
| int TVMFFITestingDummyTarget() nogil |
| |
| |
| cdef class ByteArrayArg: |
| __slots__ = () |
| cdef TVMFFIByteArray cdata |
| cdef object py_data |
| |
| def __cinit__(self, py_data): |
| if isinstance(py_data, bytearray): |
| py_data = bytes(py_data) |
| cdef char* data |
| cdef Py_ssize_t size |
| self.py_data = py_data |
| PyBytes_AsStringAndSize(py_data, &data, &size) |
| self.cdata.data = data |
| self.cdata.size = size |
| |
| cdef inline TVMFFIByteArray* cptr(self): |
| return &self.cdata |
| |
| |
| cdef inline py_str(const char* x): |
| """Convert a c_char_p to a python string |
| |
| Parameters |
| ---------- |
| x : c_char_p |
| A char pointer that can be passed to C API |
| """ |
| return x.decode("utf-8") |
| |
| |
| cdef inline str bytearray_to_str(const TVMFFIByteArray* x): |
| return PyBytes_FromStringAndSize(x.data, x.size).decode("utf-8") |
| |
| |
| cdef inline bytes bytearray_to_bytes(const TVMFFIByteArray* x): |
| return PyBytes_FromStringAndSize(x.data, x.size) |
| |
| |
| cdef inline c_str(pystr): |
| """Create ctypes char * from a python string |
| |
| Parameters |
| ---------- |
| string : string type |
| python string |
| |
| Returns |
| ------- |
| str : c_char_p |
| A char pointer that can be passed to C API |
| """ |
| return pystr.encode("utf-8") |
| |
| |
| cdef inline object ctypes_handle(void* chandle): |
| """Cast C handle to ctypes handle.""" |
| return ctypes.cast(<unsigned long long>chandle, ctypes.c_void_p) |
| |
| |
| cdef inline void* c_handle(object handle): |
| """Cast C types handle to c handle.""" |
| cdef unsigned long long v_ptr |
| cdef object value = handle.value |
| v_ptr = 0 if value is None else value |
| return <void*>(v_ptr) |
| |
| |
| cdef _init_env_api(): |
| # Initialize env api for signal handling |
| # Also registers the gil state release and ensure as PyErr_CheckSignals |
| # function is called with gil released and we need to regrab the gil |
| CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyErr_CheckSignals"), <void*>PyErr_CheckSignals)) |
| CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyGILState_Ensure"), <void*>PyGILState_Ensure)) |
| CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyGILState_Release"), <void*>PyGILState_Release)) |
| |
| |
| _init_env_api() |
| |
| # ensure testing is linked and we can run testcases |
| TVMFFITestingDummyTarget() |