Skip to content

Commit e181da8

Browse files
Changes Implementation section of data-interchange to close #337 (#338)
* Changes Implementation section of data-interchange to close #337 * Clarify expectations of consumer/producer with respect to lifetime management of DLManagedTensor passed via Python capsule
1 parent f4fb0f2 commit e181da8

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

spec/design_topics/data_interchange.md

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,24 +126,38 @@ unnecessary so asynchronous execution is enabled.
126126

127127
### Implementation
128128

129-
_Note that while this API standard largely tries to avoid discussing implementation details, some discussion and requirements are needed here because data interchange requires coordination between implementers on, e.g., memory management._
129+
_Note that while this API standard largely tries to avoid discussing
130+
implementation details, some discussion and requirements are needed
131+
here because data interchange requires coordination between
132+
implementers on, e.g., memory management._
130133

131134
![Diagram of DLPack structs](/_static/images/DLPack_diagram.png)
132135

133-
_DLPack diagram. Dark blue are the structs it defines, light blue struct members, gray text enum values of supported devices and data types._
136+
_DLPack diagram. Dark blue are the structs it defines, light blue
137+
struct members, gray text enum values of supported devices and data
138+
types._
134139

135140
The `__dlpack__` method will produce a `PyCapsule` containing a
136-
`DLPackManagedTensor`, which will be consumed immediately within
141+
`DLManagedTensor`, which will be consumed immediately within
137142
`from_dlpack` - therefore it is consumed exactly once, and it will not be
138143
visible to users of the Python API.
139144

140-
The producer must set the PyCapsule name to ``"dltensor"`` so that it can
141-
be inspected by name.
142-
The consumer must set the PyCapsule name to `"used_dltensor"`, and call the
143-
`deleter` of the `DLPackManagedTensor` when it no longer needs the data.
145+
The producer must set the `PyCapsule` name to ``"dltensor"`` so that
146+
it can be inspected by name, and set `PyCapsule_Destructor` that calls
147+
the `deleter` of the `DLManagedTensor` when the `"dltensor"`-named
148+
capsule is no longer needed.
144149

145-
Note: the capsule names ``"dltensor"`` and `"used_dltensor"` must be statically
146-
allocated.
150+
The consumer must transer ownership of the `DLManangedTensor` from the
151+
capsule to its own object. It does so by renaming the capsule to
152+
`"used_dltensor"` to ensure that `PyCapsule_Destructor` will not get
153+
called (ensured if `PyCapsule_Destructor` calls `deleter` only for
154+
capsules whose name is `"dltensor"`), but the `deleter` of the
155+
`DLManagedTensor` will be called by the destructor of the consumer
156+
library object created to own the `DLManagerTensor` obtained from the
157+
capsule.
158+
159+
Note: the capsule names ``"dltensor"`` and `"used_dltensor"` must be
160+
statically allocated.
147161

148162
When the `strides` field in the `DLTensor` struct is `NULL`, it indicates a
149163
row-major compact array. If the array is of size zero, the data pointer in
@@ -153,8 +167,13 @@ DLPack version used must be `0.2 <= DLPACK_VERSION < 1.0`. For further
153167
details on DLPack design and how to implement support for it,
154168
refer to [github.com/dmlc/dlpack](https://github.com/dmlc/dlpack).
155169

156-
:::{warning}
157-
DLPack contains a `device_id`, which will be the device ID (an integer, `0, 1, ...`) which the producer library uses. In practice this will likely be the same numbering as that of the consumer, however that is not guaranteed. Depending on the hardware type, it may be possible for the consumer library implementation to look up the actual device from the pointer to the data - this is possible for example for CUDA device pointers.
170+
:::{warning} DLPack contains a `device_id`, which will be the device
171+
ID (an integer, `0, 1, ...`) which the producer library uses. In
172+
practice this will likely be the same numbering as that of the
173+
consumer, however that is not guaranteed. Depending on the hardware
174+
type, it may be possible for the consumer library implementation to
175+
look up the actual device from the pointer to the data - this is
176+
possible for example for CUDA device pointers.
158177

159178
It is recommended that implementers of this array API consider and document
160179
whether the `.device` attribute of the array returned from `from_dlpack` is

0 commit comments

Comments
 (0)