From 30276e61f2a461e6d33f1f25dc58cf20e30752cf Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Wed, 30 Dec 2020 23:04:33 +0100 Subject: [PATCH 01/12] Update data interchange section with Python API and semantics --- spec/_static/images/DLPack_diagram.png | Bin 0 -> 31727 bytes spec/design_topics/data_interchange.md | 69 +++++++++++++++++++++---- 2 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 spec/_static/images/DLPack_diagram.png diff --git a/spec/_static/images/DLPack_diagram.png b/spec/_static/images/DLPack_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..a8459853204978f52288c4f3f74ccd1f5e30e2fb GIT binary patch literal 31727 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 N>l(u=e!Cg Date: Wed, 30 Dec 2020 23:08:06 +0100 Subject: [PATCH 02/12] temporary commit to enable MyST feature duplicate change with that in the complex64/128 PR --- spec/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/conf.py b/spec/conf.py index 98dd78c5c..308ba52d2 100644 --- a/spec/conf.py +++ b/spec/conf.py @@ -50,6 +50,7 @@ # MyST options myst_heading_anchors = 3 +myst_enable_extensions = ["colon_fence"] # -- Options for HTML output ------------------------------------------------- From 4e2c49df554b4dbfc525788989e260d81a496ea2 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 2 Jan 2021 16:48:19 +0100 Subject: [PATCH 03/12] Add DLPack synchronization semantics; add from_dlpack/__dlpack__ to API --- spec/API_specification/array_object.md | 17 +++++++++++++++ spec/API_specification/creation_functions.md | 21 ++++++++++++++++++ spec/design_topics/data_interchange.md | 23 ++++++++++---------- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index cd6400745..7e18fa24a 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -366,6 +366,23 @@ Evaluates `x1_i & x2_i` for each element `x1_i` of an array instance `x1` with t Element-wise results must equal the results returned by the equivalent element-wise function [`bitwise_and(x1, x2)`](elementwise_functions.md#logical_andx1-x2-). ``` +(method-__dlpack__)= +### \_\_dlpack\_\_(/, *, stream=None) + +Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dlpack`. + +#### Parameters + +- **stream**: _Optional\[int\]_ + + - If given, the CUDA or ROCm stream number the consumer will use. Default is `None`, which means the legacy default stream. + +#### Returns + +- **capsule**: _<PyCapsule>_ + + - A DLPack capsule for the array. See {ref}`data-interchange` for details. + (method-__eq__)= ### \_\_eq\_\_(x1, x2, /) diff --git a/spec/API_specification/creation_functions.md b/spec/API_specification/creation_functions.md index 741cff989..baf48fde9 100644 --- a/spec/API_specification/creation_functions.md +++ b/spec/API_specification/creation_functions.md @@ -116,6 +116,27 @@ Returns a two-dimensional array with ones on the `k`th diagonal and zeros elsewh - an array where all elements are equal to zero, except for the `k`th diagonal, whose values are equal to one. +(function-from_dlpack)= +### from_dlpack(x, /) + +Returns a new array containing the data from another (array) object with a `__dlpack__` method. + +#### Parameters + +- **x**: _object_ + + - input (array) object. + +#### Returns + +- **out**: _<array>_ + + - an array containing the data in `x`. + + ```{note} + The returned array may be either a copy or a view. See {ref}`data-interchange` for details. + ``` + (function-full)= ### full(shape, fill_value, /, *, dtype=None) diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index 0b0a36a59..b1370f5da 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -63,10 +63,11 @@ containing the data the object holds). The array API will offer the following syntax for data interchange: -1. A `__dlpack__()` method on the array object. -2. A `from_dlpack(x)` function, which accept (array) objects with a - `__dlpack__` method and use that method to construct a new array +1. A `from_dlpack(x)` function, which accepts (array) objects with a + `__dlpack__` method and uses that method to construct a new array containing the data from `x`. +2. A `__dlpack__(self, stream=None)` method on the array object, which + will be called from within `from_dlpack`. ## Semantics @@ -87,8 +88,14 @@ If an array that is accessed via the interchange protocol lives on a device that the requesting library does not support, it is recommended to raise a `TypeError`. +Stream handling through the `stream` keyword applies to CUDA and ROCm. The +producer must pass the stream it will use to the consumer, the consumer must +synchronize only when necessary. In the common case of the default stream +being used, synchronization will be unnecessary so asynchronous execution is +enabled. -### Implementation + +## Implementation _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._ @@ -114,11 +121,3 @@ It is recommended that implementers of this array API document whether the `.device` attribute of the array returned from `from_dlpack` is guaranteed to be a certain order or not. ::: - -## Out of scope for data interchange - -- Stream handling, e.g. for CUDA streams. TBD: if DLPack gains - synchronization semantics support (see - [dlpack/issues/57](https://github.com/dmlc/dlpack/issues/57)), details on - semantics can be added here. It may be necessary for correctness to at - least have a way to check which stream is in use. \ No newline at end of file From 0b701c47239a9cbf79c54a1ca4422c07e20d8f5c Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Tue, 12 Jan 2021 17:21:18 +0100 Subject: [PATCH 04/12] Update stream numbering for `__dlpack__` This matches `__cuda_array_interface__`. --- spec/API_specification/array_object.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 7e18fa24a..8687cb3cb 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -375,7 +375,13 @@ Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dl - **stream**: _Optional\[int\]_ - - If given, the CUDA or ROCm stream number the consumer will use. Default is `None`, which means the legacy default stream. + - If given, the CUDA or ROCm stream number the consumer will use. Options are: + - `None`: no synchronization (default), + - `1`: the legacy default stream, + - `2`: the per-thread default stream, + - `> 2`: stream number represented as a Python integer. + + Note that `0` is disallowed (it's ambiguous, it could mean either `None`, `1` or `2`). #### Returns From a4549afe396e696553126524e9e5e9e122662e4c Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Tue, 16 Feb 2021 17:23:47 +0100 Subject: [PATCH 05/12] Add __dlpack__ device and update description of stream=None --- spec/API_specification/array_object.md | 22 +++++++++++++++++++++- spec/design_topics/data_interchange.md | 6 ++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 8687cb3cb..4c9d9e89e 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -376,19 +376,39 @@ Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dl - **stream**: _Optional\[int\]_ - If given, the CUDA or ROCm stream number the consumer will use. Options are: - - `None`: no synchronization (default), + - `None`: producer must assume the legacy default stream (default), - `1`: the legacy default stream, - `2`: the per-thread default stream, - `> 2`: stream number represented as a Python integer. Note that `0` is disallowed (it's ambiguous, it could mean either `None`, `1` or `2`). + ```{note} + It is recommended that implementers explicitly handle streams. If + they use the legacy default stream, specifying `1` is preferred. + `None` is a safe default for developers who do not want to think + about stream handling at all, potentially at the cost of more + synchronization than necessary. + ``` + #### Returns - **capsule**: _<PyCapsule>_ - A DLPack capsule for the array. See {ref}`data-interchange` for details. +(method-__dlpack_device__)= +### \_\_dlpack\_device\_\_() + +Returns device type and device ID in DLPack format. Meant for use within {ref}`function-from_dlpack`. + +#### Returns + +- **device**: _Tuple\[int, int\]_ + + - A tuple `(device_type, device_id)` in DLPack format. + + (method-__eq__)= ### \_\_eq\_\_(x1, x2, /) diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index b1370f5da..fd19699aa 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -66,8 +66,10 @@ The array API will offer the following syntax for data interchange: 1. A `from_dlpack(x)` function, which accepts (array) objects with a `__dlpack__` method and uses that method to construct a new array containing the data from `x`. -2. A `__dlpack__(self, stream=None)` method on the array object, which - will be called from within `from_dlpack`. +2. `__dlpack__(self, stream=None)` and `__dlpack_device__` methods on the + array object, which will be called from within `from_dlpack`, to query + what device the array is on (may be needed to pass in the correct + stream, e.g. in the case of multiple GPUs) and to access the data. ## Semantics From a719b18ef272835669bd8049313e20c8df6c9c24 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Wed, 17 Feb 2021 20:28:31 +0100 Subject: [PATCH 06/12] Add more device-specific notes for CUDA/ROCm stream handling --- spec/API_specification/array_object.md | 23 +++++++++++++++++------ spec/design_topics/data_interchange.md | 11 ++++++----- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 4c9d9e89e..89f190ce7 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -375,20 +375,31 @@ Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dl - **stream**: _Optional\[int\]_ - - If given, the CUDA or ROCm stream number the consumer will use. Options are: + - If given, the stream number the consumer will use on the device the array is present on, as a Python integer. Device-specific notes: + + :::{admonition} CUDA - `None`: producer must assume the legacy default stream (default), - `1`: the legacy default stream, - `2`: the per-thread default stream, - `> 2`: stream number represented as a Python integer. Note that `0` is disallowed (it's ambiguous, it could mean either `None`, `1` or `2`). + ::: + + :::{admonition} ROCm + - `None`: producer must assume the legacy default stream (default), + - `0`: the default stream, + - `> 2`: stream number represented as a Python integer. + + Using `1` and `2` is not supported. + ::: - ```{note} + ```{tip} It is recommended that implementers explicitly handle streams. If - they use the legacy default stream, specifying `1` is preferred. - `None` is a safe default for developers who do not want to think - about stream handling at all, potentially at the cost of more - synchronization than necessary. + they use the legacy default stream, specifying `1` (CUDA) or `0` + (ROCm) is preferred. `None` is a safe default for developers who do + not want to think about stream handling at all, potentially at the + cost of more synchronization than necessary. ``` #### Returns diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index fd19699aa..35004eafd 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -90,11 +90,12 @@ If an array that is accessed via the interchange protocol lives on a device that the requesting library does not support, it is recommended to raise a `TypeError`. -Stream handling through the `stream` keyword applies to CUDA and ROCm. The -producer must pass the stream it will use to the consumer, the consumer must -synchronize only when necessary. In the common case of the default stream -being used, synchronization will be unnecessary so asynchronous execution is -enabled. +Stream handling through the `stream` keyword applies to CUDA and ROCm (perhaps +to other devices that have a stream concept as well, however those haven't been +considered in detail). The producer must pass the stream it will use to the +consumer, the consumer must synchronize only when necessary. In the common case +of the default stream being used, synchronization will be unnecessary so +asynchronous execution is enabled. ## Implementation From 693b15ab6f34c3dba2f66a45969da73cd49141e0 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Wed, 17 Feb 2021 22:00:50 +0100 Subject: [PATCH 07/12] Fix issue where producer/consumer were reversed --- spec/design_topics/data_interchange.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index 35004eafd..bc0c3ee65 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -92,10 +92,10 @@ raise a `TypeError`. Stream handling through the `stream` keyword applies to CUDA and ROCm (perhaps to other devices that have a stream concept as well, however those haven't been -considered in detail). The producer must pass the stream it will use to the -consumer, the consumer must synchronize only when necessary. In the common case -of the default stream being used, synchronization will be unnecessary so -asynchronous execution is enabled. +considered in detail). The consumer must pass the stream it will use to the +producer; the producer must synchronize or wait on the stream when necessary. +In the common case of the default stream being used, synchronization will be +unnecessary so asynchronous execution is enabled. ## Implementation From 897ca2eae442e969a7910ee4dd852f1de1fc9c7f Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Wed, 17 Feb 2021 23:48:23 +0100 Subject: [PATCH 08/12] Improve the description of the stream keyword for `__dlpack__` --- spec/API_specification/array_object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 89f190ce7..932eb6db3 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -375,7 +375,7 @@ Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dl - **stream**: _Optional\[int\]_ - - If given, the stream number the consumer will use on the device the array is present on, as a Python integer. Device-specific notes: + - An optional pointer to a stream, as a Python integer, provided by the consumer that the producer will use to make the array safe to operate on. Device-specific notes: :::{admonition} CUDA - `None`: producer must assume the legacy default stream (default), From d3b9a793e8c2fd68097ecef24aab72f193d2505e Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 20 Feb 2021 17:51:05 +0100 Subject: [PATCH 09/12] Update __dlpack_device__ to use IntEnum for device type --- spec/API_specification/array_object.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 932eb6db3..76e65fe3e 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -415,10 +415,20 @@ Returns device type and device ID in DLPack format. Meant for use within {ref}`f #### Returns -- **device**: _Tuple\[int, int\]_ +- **device**: _Tuple\[enum.IntEnum, int\]_ - - A tuple `(device_type, device_id)` in DLPack format. + - A tuple `(device_type, device_id)` in DLPack format. Valid device type enum members are: + ``` + CPU = 1 + CUDA = 2 + CPU_PINNED = 3 + OPENCL = 4 + VULKAN = 7 + METAL = 8 + VPI = 9 + ROCM = 10 + ``` (method-__eq__)= ### \_\_eq\_\_(x1, x2, /) From 75261ccc0338c66aceb9fe8a50cde1bb66b89991 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 20 Feb 2021 17:58:22 +0100 Subject: [PATCH 10/12] Add -1 as a sentinel value for DLPack stream handling --- spec/API_specification/array_object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/API_specification/array_object.md b/spec/API_specification/array_object.md index 76e65fe3e..2fd52ac9e 100644 --- a/spec/API_specification/array_object.md +++ b/spec/API_specification/array_object.md @@ -375,7 +375,7 @@ Exports the array as a DLPack capsule, for consumption by {ref}`function-from_dl - **stream**: _Optional\[int\]_ - - An optional pointer to a stream, as a Python integer, provided by the consumer that the producer will use to make the array safe to operate on. Device-specific notes: + - An optional pointer to a stream, as a Python integer, provided by the consumer that the producer will use to make the array safe to operate on. The pointer is a positive integer. `-1` is a special value that may be used by the consumer to signal "producer must not do any synchronization". Device-specific notes: :::{admonition} CUDA - `None`: producer must assume the legacy default stream (default), From 5cde9aa58240205eb5b8cf8b5cf7395ba7a54320 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 20 Feb 2021 18:00:34 +0100 Subject: [PATCH 11/12] Add supported DLPack version range. --- spec/design_topics/data_interchange.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index bc0c3ee65..4162ce4d4 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -114,7 +114,8 @@ visible to users of the Python API. The consumer must set the PyCapsule name to `"used_dltensor"`, and call the `deleter` of the `DLPackManagedTensor` when it no longer needs the data. -For further details on DLPack design and how to implement support for it, +DLPack version used must be `0.2 <= DLPACK_VERSION < 1.0`. For further +details on DLPack design and how to implement support for it, refer to [github.com/dmlc/dlpack](https://github.com/dmlc/dlpack). :::{warning} From 603ad2e044c9eaa255470006285a81635f886ecc Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 21 Feb 2021 16:04:57 +0100 Subject: [PATCH 12/12] Add details on strides null and size 0 arrays. Also fix a couple of small textual things. --- spec/design_topics/data_interchange.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/design_topics/data_interchange.md b/spec/design_topics/data_interchange.md index 4162ce4d4..0cfa0c784 100644 --- a/spec/design_topics/data_interchange.md +++ b/spec/design_topics/data_interchange.md @@ -114,6 +114,10 @@ visible to users of the Python API. The consumer must set the PyCapsule name to `"used_dltensor"`, and call the `deleter` of the `DLPackManagedTensor` when it no longer needs the data. +When the `strides` field in the `DLTensor` struct is `NULL`, it indicates a +row-major compact array. If the array is of size zero, the data pointer in +`DLTensor` should be set to either `NULL` or `0`. + DLPack version used must be `0.2 <= DLPACK_VERSION < 1.0`. For further details on DLPack design and how to implement support for it, refer to [github.com/dmlc/dlpack](https://github.com/dmlc/dlpack). @@ -121,7 +125,7 @@ refer to [github.com/dmlc/dlpack](https://github.com/dmlc/dlpack). :::{warning} 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. -It is recommended that implementers of this array API document whether the -`.device` attribute of the array returned from `from_dlpack` is guaranteed to -be a certain order or not. +It is recommended that implementers of this array API consider and document +whether the `.device` attribute of the array returned from `from_dlpack` is +guaranteed to be in a certain order or not. :::