1515#define DLPACK_EXTERN_C
1616#endif
1717
18- /* ! \brief The current version of dlpack */
19- #define DLPACK_VERSION 80
18+ /* ! \brief The current major version of dlpack */
19+ #define DLPACK_MAJOR_VERSION 1
2020
21- /* ! \brief The current ABI version of dlpack */
22- #define DLPACK_ABI_VERSION 1
21+ /* ! \brief The current minor version of dlpack */
22+ #define DLPACK_MINOR_VERSION 1
2323
2424/* ! \brief DLPACK_DLL prefix for windows */
2525#ifdef _WIN32
3838#ifdef __cplusplus
3939extern " C" {
4040#endif
41+
42+ /* !
43+ * \brief The DLPack version.
44+ *
45+ * A change in major version indicates that we have changed the
46+ * data layout of the ABI - DLManagedTensorVersioned.
47+ *
48+ * A change in minor version indicates that we have added new
49+ * code, such as a new device type, but the ABI is kept the same.
50+ *
51+ * If an obtained DLPack tensor has a major version that disagrees
52+ * with the version number specified in this header file
53+ * (i.e. major != DLPACK_MAJOR_VERSION), the consumer must call the deleter
54+ * (and it is safe to do so). It is not safe to access any other fields
55+ * as the memory layout will have changed.
56+ *
57+ * In the case of a minor version mismatch, the tensor can be safely used as
58+ * long as the consumer knows how to interpret all fields. Minor version
59+ * updates indicate the addition of enumeration values.
60+ */
61+ typedef struct {
62+ /* ! \brief DLPack major version. */
63+ uint32_t major;
64+ /* ! \brief DLPack minor version. */
65+ uint32_t minor;
66+ } DLPackVersion;
67+
4168/* !
4269 * \brief The device type in DLDevice.
4370 */
@@ -89,6 +116,8 @@ typedef enum {
89116 kDLWebGPU = 15 ,
90117 /* ! \brief Qualcomm Hexagon DSP */
91118 kDLHexagon = 16 ,
119+ /* ! \brief Microsoft MAIA devices */
120+ kDLMAIA = 17 ,
92121} DLDeviceType;
93122
94123/* !
@@ -128,6 +157,26 @@ typedef enum {
128157 kDLComplex = 5U ,
129158 /* ! \brief boolean */
130159 kDLBool = 6U ,
160+ /* ! \brief FP8 data types */
161+ kDLFloat8_e3m4 = 7U ,
162+ kDLFloat8_e4m3 = 8U ,
163+ kDLFloat8_e4m3b11fnuz = 9U ,
164+ kDLFloat8_e4m3fn = 10U ,
165+ kDLFloat8_e4m3fnuz = 11U ,
166+ kDLFloat8_e5m2 = 12U ,
167+ kDLFloat8_e5m2fnuz = 13U ,
168+ kDLFloat8_e8m0fnu = 14U ,
169+ /* ! \brief FP6 data types
170+ * Setting bits != 6 is currently unspecified, and the producer must ensure it is set
171+ * while the consumer must stop importing if the value is unexpected.
172+ */
173+ kDLFloat6_e2m3fn = 15U ,
174+ kDLFloat6_e3m2fn = 16U ,
175+ /* ! \brief FP4 data types
176+ * Setting bits != 4 is currently unspecified, and the producer must ensure it is set
177+ * while the consumer must stop importing if the value is unexpected.
178+ */
179+ kDLFloat4_e2m1fn = 17U ,
131180} DLDataTypeCode;
132181
133182/* !
@@ -141,6 +190,12 @@ typedef enum {
141190 * - int8: type_code = 0, bits = 8, lanes = 1
142191 * - std::complex<float>: type_code = 5, bits = 64, lanes = 1
143192 * - bool: type_code = 6, bits = 8, lanes = 1 (as per common array library convention, the underlying storage size of bool is 8 bits)
193+ * - float8_e4m3: type_code = 8, bits = 8, lanes = 1 (packed in memory)
194+ * - float6_e3m2fn: type_code = 16, bits = 6, lanes = 1 (packed in memory)
195+ * - float4_e2m1fn: type_code = 17, bits = 4, lanes = 1 (packed in memory)
196+ *
197+ * When a sub-byte type is packed, DLPack requires the data to be in little bit-endian, i.e.,
198+ * for a packed data set D ((D >> (i * bits)) && bit_mask) stores the i-th element.
144199 */
145200typedef struct {
146201 /* !
@@ -186,6 +241,9 @@ typedef struct {
186241 * return size;
187242 * }
188243 * \endcode
244+ *
245+ * Note that if the tensor is of size zero, then the data pointer should be
246+ * set to `NULL`.
189247 */
190248 void * data;
191249 /* ! \brief The device of the tensor */
@@ -211,6 +269,13 @@ typedef struct {
211269 * not meant to transfer the tensor. When the borrowing framework doesn't need
212270 * the tensor, it should call the deleter to notify the host that the resource
213271 * is no longer needed.
272+ *
273+ * \note This data structure is used as Legacy DLManagedTensor
274+ * in DLPack exchange and is deprecated after DLPack v0.8
275+ * Use DLManagedTensorVersioned instead.
276+ * This data structure may get renamed or deleted in future versions.
277+ *
278+ * \sa DLManagedTensorVersioned
214279 */
215280typedef struct DLManagedTensor {
216281 /* ! \brief DLTensor which is being memory managed */
@@ -219,14 +284,83 @@ typedef struct DLManagedTensor {
219284 * which DLManagedTensor is used in the framework. It can also be NULL.
220285 */
221286 void * manager_ctx;
222- /* ! \brief Destructor signature void (*)(void*) - this should be called
223- * to destruct manager_ctx which holds the DLManagedTensor. It can be NULL
224- * if there is no way for the caller to provide a reasonable destructor.
225- * The destructors deletes the argument self as well.
287+ /* !
288+ * \brief Destructor - this should be called
289+ * to destruct the manager_ctx which backs the DLManagedTensor. It can be
290+ * NULL if there is no way for the caller to provide a reasonable destructor.
291+ * The destructor deletes the argument self as well.
226292 */
227293 void (*deleter)(struct DLManagedTensor * self);
228294} DLManagedTensor;
295+
296+ // bit masks used in in the DLManagedTensorVersioned
297+
298+ /* ! \brief bit mask to indicate that the tensor is read only. */
299+ #define DLPACK_FLAG_BITMASK_READ_ONLY (1UL << 0UL )
300+
301+ /* !
302+ * \brief bit mask to indicate that the tensor is a copy made by the producer.
303+ *
304+ * If set, the tensor is considered solely owned throughout its lifetime by the
305+ * consumer, until the producer-provided deleter is invoked.
306+ */
307+ #define DLPACK_FLAG_BITMASK_IS_COPIED (1UL << 1UL )
308+
309+ /*
310+ * \brief bit mask to indicate that whether a sub-byte type is packed or padded.
311+ *
312+ * The default for sub-byte types (ex: fp4/fp6) is assumed packed. This flag can
313+ * be set by the producer to signal that a tensor of sub-byte type is padded.
314+ */
315+ #define DLPACK_FLAG_BITMASK_IS_SUBBYTE_TYPE_PADDED (1UL << 2UL )
316+
317+ /* !
318+ * \brief A versioned and managed C Tensor object, manage memory of DLTensor.
319+ *
320+ * This data structure is intended to facilitate the borrowing of DLTensor by
321+ * another framework. It is not meant to transfer the tensor. When the borrowing
322+ * framework doesn't need the tensor, it should call the deleter to notify the
323+ * host that the resource is no longer needed.
324+ *
325+ * \note This is the current standard DLPack exchange data structure.
326+ */
327+ struct DLManagedTensorVersioned {
328+ /* !
329+ * \brief The API and ABI version of the current managed Tensor
330+ */
331+ DLPackVersion version;
332+ /* !
333+ * \brief the context of the original host framework.
334+ *
335+ * Stores DLManagedTensorVersioned is used in the
336+ * framework. It can also be NULL.
337+ */
338+ void *manager_ctx;
339+ /* !
340+ * \brief Destructor.
341+ *
342+ * This should be called to destruct manager_ctx which holds the DLManagedTensorVersioned.
343+ * It can be NULL if there is no way for the caller to provide a reasonable
344+ * destructor. The destructor deletes the argument self as well.
345+ */
346+ void (*deleter)(struct DLManagedTensorVersioned *self);
347+ /* !
348+ * \brief Additional bitmask flags information about the tensor.
349+ *
350+ * By default the flags should be set to 0.
351+ *
352+ * \note Future ABI changes should keep everything until this field
353+ * stable, to ensure that deleter can be correctly called.
354+ *
355+ * \sa DLPACK_FLAG_BITMASK_READ_ONLY
356+ * \sa DLPACK_FLAG_BITMASK_IS_COPIED
357+ */
358+ uint64_t flags;
359+ /* ! \brief DLTensor which is being memory managed */
360+ DLTensor dl_tensor;
361+ };
362+
229363#ifdef __cplusplus
230364} // DLPACK_EXTERN_C
231365#endif
232- #endif // DLPACK_DLPACK_H_
366+ #endif // DLPACK_DLPACK_H_
0 commit comments