Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:56

0001 /*!
0002  *  Copyright (c) 2017 by Contributors
0003  * \file dlpack.h
0004  * \brief The common header of DLPack.
0005  */
0006 #ifndef DLPACK_DLPACK_H_
0007 #define DLPACK_DLPACK_H_
0008 
0009 /**
0010  * \brief Compatibility with C++
0011  */
0012 #ifdef __cplusplus
0013 #define DLPACK_EXTERN_C extern "C"
0014 #else
0015 #define DLPACK_EXTERN_C
0016 #endif
0017 
0018 /*! \brief The current major version of dlpack */
0019 #define DLPACK_MAJOR_VERSION 1
0020 
0021 /*! \brief The current minor version of dlpack */
0022 #define DLPACK_MINOR_VERSION 0
0023 
0024 /*! \brief DLPACK_DLL prefix for windows */
0025 #ifdef _WIN32
0026 #ifdef DLPACK_EXPORTS
0027 #define DLPACK_DLL __declspec(dllexport)
0028 #else
0029 #define DLPACK_DLL __declspec(dllimport)
0030 #endif
0031 #else
0032 #define DLPACK_DLL
0033 #endif
0034 
0035 #include <stdint.h>
0036 #include <stddef.h>
0037 
0038 #ifdef __cplusplus
0039 extern "C" {
0040 #endif
0041 
0042 /*!
0043  * \brief The DLPack version.
0044  *
0045  * A change in major version indicates that we have changed the
0046  * data layout of the ABI - DLManagedTensorVersioned.
0047  *
0048  * A change in minor version indicates that we have added new
0049  * code, such as a new device type, but the ABI is kept the same.
0050  *
0051  * If an obtained DLPack tensor has a major version that disagrees
0052  * with the version number specified in this header file
0053  * (i.e. major != DLPACK_MAJOR_VERSION), the consumer must call the deleter
0054  * (and it is safe to do so). It is not safe to access any other fields
0055  * as the memory layout will have changed.
0056  *
0057  * In the case of a minor version mismatch, the tensor can be safely used as
0058  * long as the consumer knows how to interpret all fields. Minor version
0059  * updates indicate the addition of enumeration values.
0060  */
0061 typedef struct {
0062   /*! \brief DLPack major version. */
0063   uint32_t major;
0064   /*! \brief DLPack minor version. */
0065   uint32_t minor;
0066 } DLPackVersion;
0067 
0068 /*!
0069  * \brief The device type in DLDevice.
0070  */
0071 #ifdef __cplusplus
0072 typedef enum : int32_t {
0073 #else
0074 typedef enum {
0075 #endif
0076   /*! \brief CPU device */
0077   kDLCPU = 1,
0078   /*! \brief CUDA GPU device */
0079   kDLCUDA = 2,
0080   /*!
0081    * \brief Pinned CUDA CPU memory by cudaMallocHost
0082    */
0083   kDLCUDAHost = 3,
0084   /*! \brief OpenCL devices. */
0085   kDLOpenCL = 4,
0086   /*! \brief Vulkan buffer for next generation graphics. */
0087   kDLVulkan = 7,
0088   /*! \brief Metal for Apple GPU. */
0089   kDLMetal = 8,
0090   /*! \brief Verilog simulator buffer */
0091   kDLVPI = 9,
0092   /*! \brief ROCm GPUs for AMD GPUs */
0093   kDLROCM = 10,
0094   /*!
0095    * \brief Pinned ROCm CPU memory allocated by hipMallocHost
0096    */
0097   kDLROCMHost = 11,
0098   /*!
0099    * \brief Reserved extension device type,
0100    * used for quickly test extension device
0101    * The semantics can differ depending on the implementation.
0102    */
0103   kDLExtDev = 12,
0104   /*!
0105    * \brief CUDA managed/unified memory allocated by cudaMallocManaged
0106    */
0107   kDLCUDAManaged = 13,
0108   /*!
0109    * \brief Unified shared memory allocated on a oneAPI non-partititioned
0110    * device. Call to oneAPI runtime is required to determine the device
0111    * type, the USM allocation type and the sycl context it is bound to.
0112    *
0113    */
0114   kDLOneAPI = 14,
0115   /*! \brief GPU support for next generation WebGPU standard. */
0116   kDLWebGPU = 15,
0117   /*! \brief Qualcomm Hexagon DSP */
0118   kDLHexagon = 16,
0119   /*! \brief Microsoft MAIA devices */
0120   kDLMAIA = 17,
0121 } DLDeviceType;
0122 
0123 /*!
0124  * \brief A Device for Tensor and operator.
0125  */
0126 typedef struct {
0127   /*! \brief The device type used in the device. */
0128   DLDeviceType device_type;
0129   /*!
0130    * \brief The device index.
0131    * For vanilla CPU memory, pinned memory, or managed memory, this is set to 0.
0132    */
0133   int32_t device_id;
0134 } DLDevice;
0135 
0136 /*!
0137  * \brief The type code options DLDataType.
0138  */
0139 typedef enum {
0140   /*! \brief signed integer */
0141   kDLInt = 0U,
0142   /*! \brief unsigned integer */
0143   kDLUInt = 1U,
0144   /*! \brief IEEE floating point */
0145   kDLFloat = 2U,
0146   /*!
0147    * \brief Opaque handle type, reserved for testing purposes.
0148    * Frameworks need to agree on the handle data type for the exchange to be well-defined.
0149    */
0150   kDLOpaqueHandle = 3U,
0151   /*! \brief bfloat16 */
0152   kDLBfloat = 4U,
0153   /*!
0154    * \brief complex number
0155    * (C/C++/Python layout: compact struct per complex number)
0156    */
0157   kDLComplex = 5U,
0158   /*! \brief boolean */
0159   kDLBool = 6U,
0160 } DLDataTypeCode;
0161 
0162 /*!
0163  * \brief The data type the tensor can hold. The data type is assumed to follow the
0164  * native endian-ness. An explicit error message should be raised when attempting to
0165  * export an array with non-native endianness
0166  *
0167  *  Examples
0168  *   - float: type_code = 2, bits = 32, lanes = 1
0169  *   - float4(vectorized 4 float): type_code = 2, bits = 32, lanes = 4
0170  *   - int8: type_code = 0, bits = 8, lanes = 1
0171  *   - std::complex<float>: type_code = 5, bits = 64, lanes = 1
0172  *   - bool: type_code = 6, bits = 8, lanes = 1 (as per common array library convention, the underlying storage size of bool is 8 bits)
0173  */
0174 typedef struct {
0175   /*!
0176    * \brief Type code of base types.
0177    * We keep it uint8_t instead of DLDataTypeCode for minimal memory
0178    * footprint, but the value should be one of DLDataTypeCode enum values.
0179    * */
0180   uint8_t code;
0181   /*!
0182    * \brief Number of bits, common choices are 8, 16, 32.
0183    */
0184   uint8_t bits;
0185   /*! \brief Number of lanes in the type, used for vector types. */
0186   uint16_t lanes;
0187 } DLDataType;
0188 
0189 /*!
0190  * \brief Plain C Tensor object, does not manage memory.
0191  */
0192 typedef struct {
0193   /*!
0194    * \brief The data pointer points to the allocated data. This will be CUDA
0195    * device pointer or cl_mem handle in OpenCL. It may be opaque on some device
0196    * types. This pointer is always aligned to 256 bytes as in CUDA. The
0197    * `byte_offset` field should be used to point to the beginning of the data.
0198    *
0199    * Note that as of Nov 2021, multiply libraries (CuPy, PyTorch, TensorFlow,
0200    * TVM, perhaps others) do not adhere to this 256 byte aligment requirement
0201    * on CPU/CUDA/ROCm, and always use `byte_offset=0`.  This must be fixed
0202    * (after which this note will be updated); at the moment it is recommended
0203    * to not rely on the data pointer being correctly aligned.
0204    *
0205    * For given DLTensor, the size of memory required to store the contents of
0206    * data is calculated as follows:
0207    *
0208    * \code{.c}
0209    * static inline size_t GetDataSize(const DLTensor* t) {
0210    *   size_t size = 1;
0211    *   for (tvm_index_t i = 0; i < t->ndim; ++i) {
0212    *     size *= t->shape[i];
0213    *   }
0214    *   size *= (t->dtype.bits * t->dtype.lanes + 7) / 8;
0215    *   return size;
0216    * }
0217    * \endcode
0218    *
0219    * Note that if the tensor is of size zero, then the data pointer should be
0220    * set to `NULL`.
0221    */
0222   void* data;
0223   /*! \brief The device of the tensor */
0224   DLDevice device;
0225   /*! \brief Number of dimensions */
0226   int32_t ndim;
0227   /*! \brief The data type of the pointer*/
0228   DLDataType dtype;
0229   /*! \brief The shape of the tensor */
0230   int64_t* shape;
0231   /*!
0232    * \brief strides of the tensor (in number of elements, not bytes)
0233    *  can be NULL, indicating tensor is compact and row-majored.
0234    */
0235   int64_t* strides;
0236   /*! \brief The offset in bytes to the beginning pointer to data */
0237   uint64_t byte_offset;
0238 } DLTensor;
0239 
0240 /*!
0241  * \brief C Tensor object, manage memory of DLTensor. This data structure is
0242  *  intended to facilitate the borrowing of DLTensor by another framework. It is
0243  *  not meant to transfer the tensor. When the borrowing framework doesn't need
0244  *  the tensor, it should call the deleter to notify the host that the resource
0245  *  is no longer needed.
0246  *
0247  * \note This data structure is used as Legacy DLManagedTensor
0248  *       in DLPack exchange and is deprecated after DLPack v0.8
0249  *       Use DLManagedTensorVersioned instead.
0250  *       This data structure may get renamed or deleted in future versions.
0251  *
0252  * \sa DLManagedTensorVersioned
0253  */
0254 typedef struct DLManagedTensor {
0255   /*! \brief DLTensor which is being memory managed */
0256   DLTensor dl_tensor;
0257   /*! \brief the context of the original host framework of DLManagedTensor in
0258    *   which DLManagedTensor is used in the framework. It can also be NULL.
0259    */
0260   void * manager_ctx;
0261   /*!
0262    * \brief Destructor - this should be called
0263    * to destruct the manager_ctx  which backs the DLManagedTensor. It can be
0264    * NULL if there is no way for the caller to provide a reasonable destructor.
0265    * The destructor deletes the argument self as well.
0266    */
0267   void (*deleter)(struct DLManagedTensor * self);
0268 } DLManagedTensor;
0269 
0270 // bit masks used in in the DLManagedTensorVersioned
0271 
0272 /*! \brief bit mask to indicate that the tensor is read only. */
0273 #define DLPACK_FLAG_BITMASK_READ_ONLY (1UL << 0UL)
0274 
0275 /*!
0276  * \brief bit mask to indicate that the tensor is a copy made by the producer.
0277  *
0278  * If set, the tensor is considered solely owned throughout its lifetime by the
0279  * consumer, until the producer-provided deleter is invoked.
0280  */
0281 #define DLPACK_FLAG_BITMASK_IS_COPIED (1UL << 1UL)
0282 
0283 /*!
0284  * \brief A versioned and managed C Tensor object, manage memory of DLTensor.
0285  *
0286  * This data structure is intended to facilitate the borrowing of DLTensor by
0287  * another framework. It is not meant to transfer the tensor. When the borrowing
0288  * framework doesn't need the tensor, it should call the deleter to notify the
0289  * host that the resource is no longer needed.
0290  *
0291  * \note This is the current standard DLPack exchange data structure.
0292  */
0293 struct DLManagedTensorVersioned {
0294   /*!
0295    * \brief The API and ABI version of the current managed Tensor
0296    */
0297   DLPackVersion version;
0298   /*!
0299    * \brief the context of the original host framework.
0300    *
0301    * Stores DLManagedTensorVersioned is used in the
0302    * framework. It can also be NULL.
0303    */
0304   void *manager_ctx;
0305   /*!
0306    * \brief Destructor.
0307    *
0308    * This should be called to destruct manager_ctx which holds the DLManagedTensorVersioned.
0309    * It can be NULL if there is no way for the caller to provide a reasonable
0310    * destructor. The destructor deletes the argument self as well.
0311    */
0312   void (*deleter)(struct DLManagedTensorVersioned *self);
0313   /*!
0314    * \brief Additional bitmask flags information about the tensor.
0315    *
0316    * By default the flags should be set to 0.
0317    *
0318    * \note Future ABI changes should keep everything until this field
0319    *       stable, to ensure that deleter can be correctly called.
0320    *
0321    * \sa DLPACK_FLAG_BITMASK_READ_ONLY
0322    * \sa DLPACK_FLAG_BITMASK_IS_COPIED
0323    */
0324   uint64_t flags;
0325   /*! \brief DLTensor which is being memory managed */
0326   DLTensor dl_tensor;
0327 };
0328 
0329 #ifdef __cplusplus
0330 }  // DLPACK_EXTERN_C
0331 #endif
0332 #endif  // DLPACK_DLPACK_H_