Skip to content

Commit ed73944

Browse files
committed
Incorporate suggestions to use a global table
for all function pointers
1 parent 2175043 commit ed73944

File tree

1 file changed

+63
-11
lines changed

1 file changed

+63
-11
lines changed

include/dlpack/dlpack.h

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,11 @@ typedef struct DLManagedTensorVersioned {
363363
//--------------------------------------------------------------------
364364
// DLPack C functions for speed exchange
365365
//--------------------------------------------------------------------
366-
/*
366+
/*!
367367
* \brief A generic C-style allocator that exposes allocation of a Tensor/Array.
368368
*
369-
* Array/Tensor libraries can store this field as an int in the type of the Tensor/Array.
370-
*
371-
* mypackage.Tensor.__c_dlpack_tensor_allocator__ = MyPackageDLPackTensorAllocator
372-
*
373369
* This information can then be used to set allocators of a callee to run allocations.
370+
* This function can be exposed by the framework through the DLPackExchangeAPI.
374371
*
375372
* This particular function does not assume a Python environment; as a result,
376373
* the error handling mechanism is different from Python-related functions.
@@ -383,6 +380,8 @@ typedef struct DLManagedTensorVersioned {
383380
* \return 0 on success, -1 on failure.
384381
* The callee should call SetError(error_ctx, kind, message) to set the error kind and message.
385382
* \note Error propagation via SetError.
383+
*
384+
* \sa DLPackExchangeAPI
386385
*/
387386
typedef int (*DLPackTensorAllocator)( //
388387
DLTensor* prototype, DLManagedTensorVersioned** out, void* error_ctx, //
@@ -398,9 +397,7 @@ typedef int (*DLPackTensorAllocator)( //
398397
* It also provides an option to query the current context stream of the device provided
399398
* by the tensor.
400399
*
401-
* Array/Tensor libraries can store this field as an int in the type of the Tensor/Array.
402-
*
403-
* mypackage.Tensor.__c_dlpack_from_pyobject__ = MyPackageDLPackFromPyObject
400+
* This function is exposed by the framework through the DLPackExchangeAPI.
404401
*
405402
* This information can then be picked up by importers and libraries to run the speed conversion.
406403
* This function should not throw any exceptions; if it fails, it should return -1 and
@@ -414,6 +411,8 @@ typedef int (*DLPackTensorAllocator)( //
414411
* \return 0 on success, -1 on failure. PyError should be set if -1 is returned.
415412
* \note We use void* to avoid dependency on Python.h, so this specific type is
416413
* not dependent on Python.h and can be copied to dlpack.h.
414+
*
415+
* \sa DLPackExchangeAPI
417416
*/
418417
typedef int (*DLPackFromPyObject)( //
419418
void* py_object, //
@@ -427,18 +426,71 @@ typedef int (*DLPackFromPyObject)( //
427426
* This function is a C-style function pointer to quickly convert a DLManagedTensorVersioned
428427
* to a PyObject* without going through the Python Interpreter.
429428
*
430-
* Array/Tensor libraries can store this field as an int in the type of the Tensor/Array.
431-
*
432-
* mypackage.Tensor.__c_dlpack_to_pyobject__ = MyPackageDLPackToPyObject
429+
* This function is exposed by the framework through the DLPackExchangeAPI.
433430
*
434431
* \param tensor The DLManagedTensorVersioned to convert.
435432
* \param out_py_object The output Python object.
436433
* \return 0 on success, -1 on failure. PyError should be set if -1 is returned.
437434
* \note We use void* to avoid dependency on Python.h, so this specific type is
438435
* not dependent on Python.h and can be copied to dlpack.h.
436+
*
437+
* \sa DLPackExchangeAPI
439438
*/
440439
typedef int (*DLPackToPyObject)(DLManagedTensorVersioned* tensor, void** out_py_object);
441440

441+
/*!
442+
* \brief Framework-specific function pointers table for DLPack exchange.
443+
*
444+
* Array/Tensor librarie should statically create and initialize this structure
445+
* then return a pointer to DLPackExchangeAPI as an int value in Tensor/Array.
446+
* The DLPackExchangeAPI* should stay alive throughout the lifetime of process.
447+
*
448+
* One simple way to do so is to create a static instance of DLPackExchangeAPI
449+
* within the framework and return a pointer to it, the following code
450+
* shows an example to do so in c++. It should also be reasonably easy
451+
* to do so in other languages.
452+
*
453+
* \code{.cpp}
454+
* struct MyDLPackExchangeAPI : public DLPackExchangeAPI {
455+
* MyDLPackExchangeAPI() {
456+
* version.major = DLPACK_MAJOR_VERSION;
457+
* version.minor = DLPACK_MINOR_VERSION;
458+
* tensor_allocator = MyDLPackTensorAllocator;
459+
* dlpack_from_py_object = MyDLPackFromPyObject;
460+
* dlpack_to_py_object = MyDLPackToPyObject
461+
* }
462+
*
463+
* const DLPackExchangeAPI* Global() {
464+
* static MyDLPackExchangeAPI inst;
465+
* return &inst;
466+
* }
467+
* };
468+
* \endcode
469+
*
470+
* mypackage.Tensor.__c_dlpack_exchange_api__ = MyPackageDLPackExchangeAPI
471+
*/
472+
struct DLPackExchangeAPI {
473+
/*!
474+
* \brief The current DLPack version.
475+
*/
476+
DLPackVersion version;
477+
/*!
478+
* \brief Framework-specific function pointer for DLPackTensorAllocator
479+
* \sa DLPackTensorAllocator
480+
*/
481+
DLPackTensorAllocator tensor_allocator;
482+
/*!
483+
* \brief Framework-specific function pointer for DLPackFromPyObject
484+
* \sa DLPackFromPyObject
485+
*/
486+
DLPackFromPyObject dlpack_from_py_object;
487+
/*!
488+
* \brief Framework-specific function pointer for DLPackToPyObject
489+
* \sa DLPackToPyObject
490+
*/
491+
DLPackToPyObject dlpack_to_py_object;
492+
};
493+
442494
#ifdef __cplusplus
443495
} // DLPACK_EXTERN_C
444496
#endif

0 commit comments

Comments
 (0)