Some initial dlpack testing in array-api-tests: data-apis/array-api-tests#433
- How to tell if a device is dlpack-compatible
Apparently, the only way (?) is to try-catch an error
https://data-apis.org/array-api/draft/API_specification/generated/array_api.from_dlpack.html :
Raises: BufferError – The dlpack and dlpack_device methods on the input array may raise BufferError when the data cannot be exported as DLPack (e.g., incompatible dtype, strides, or device).
A papercut, pytorch emits a ValueError, however:
>>> d = torch.device(type="meta")
>>> torch.empty(2, device=d).__dlpack_device__()
...
ValueError: Unknown device type meta for Dlpack
And device= has no effect in CuPy (see below).
kDLCPUenumerator: relation to the python side enumeration not clear.
The ... standard only mandates that a compliant library should offer a way for dlpack to return a capsule referencing an array whose underlying memory is accessible to the Python interpreter (represented by the kDLCPU enumerator in DLPack).
Is kDLCPU in C the same as CPU in python?
Suggestion: the spec could clarify the relation between python and C enumerations.
- Not clear if
copy=Falsecross-device transfer will succeed or not:
Check for matching __dlpack_device__?
Then what about CPU_PINNED vs CPU? CUDA_MANADED vs CUDA?
Is __dlpack_device__ even the right abstraction --- what is ONE_API, for example
Only checked numpy, cupy, pytorch and jax. Papercuts:
-
numpy : scalars do not support
dlpack -
torch: ValueError instead of BufferError in
__dlpack_device__ -
cupy : as of 14.0.1,
copy=Truefails for CUDA -> CUDA cupy/cupy#9842 -
jax:
copy=Trueis broken on CUDA
data-apis/array-api-tests#433 (comment), jax-ml/jax#33790
CuPy creation functions do not have a device= argument [1, 2].
Instead, https://docs.cupy.dev/en/stable/user_guide/basic.html recommends context managers:
>>> with cupy.cuda.Device(1):
... x = cupy.arange(3)
>>> x.device
<CUDa Device 1>
This is problematic, needs some work in CuPy [2], and has been previously discussed [3] in April 2025. The crux of the matter is
with cp.cuda.Device(1):
y = cp.asarray(1, device=cp.cuda.Device(0)) # y should be on Device(0)
z = y + 1 # device of z?
[1] data-apis/array-api-compat#337 [2] data-apis/array-api-compat#293 (comment) [3] https://hackmd.io/zn5bvdZTQIeJmb3RW1B-8g#Meeting-minutes-17-April-2025