Improve DLPack support for non CPU devices - #233
Conversation
This improves the `from_dlpack` behaviour for round-tripping array-api-strict arrays and raises an error for arrays that are not on the CPU device.
The CPU device can not really have multiple devices, and we don't need to be able to tell devices apart. So this removes the "not spec compliant" code.
|
To illustrate my indecision, the second commit removes the special "use different device IDs for different logical devices". I think it is cleaner this way |
There was a problem hiding this comment.
This looks pretty comprehensive!
I agree with the decision to not fiddle with device IDs. I don't know if the standards mandates that CPU device ID is always 0, but even if it does not, what would <CPU, 3> mean anyway---a third node on a multinode HPC cluster? If anything, previous experience emulating these dlpack details showed that it can backfire in unexpected ways. So since fake device IDs are not strictly necessary, I agree with keeping it all minimal.
The comments below are all minor, really. One thing that stands out is the difference in naming of DLPack enum values between the DLPack spec and the Array API spec; maybe this is something to fix in the latter?
Adding a test run against torch is great actually.
Testing: my brain hurts when I try to trace through how this interacts with copy={True, False, None}. Maybe testing can be extended to cover various values of copy=?
And there are merge conflicts because of the ruff refactor (no comment).
| kDLOneAPI = 14 | ||
| kDLWebGPU = 15 | ||
| kDLHexagon = 16 | ||
| kDLMAIA = 17 |
There was a problem hiding this comment.
Nit: The spec mandates valid device type enum members without a leading kDL suffix:
https://data-apis.org/array-api/draft/API_specification/generated/array_api.array.__dlpack_device__.html#dlpack-device
I wonder why and whether we'd rather change it in the Array API spec to match the DLPack spec.
There was a problem hiding this comment.
I have no opinion on the names here, but I think this being Python we should probably match the names in https://data-apis.org/array-api/draft/API_specification/generated/array_api.array.__dlpack_device__.html#dlpack-device instead of what I did (take them from the DLPack header file). The kDLCPU feels very "C".
I also removed a few entries from the enum, those that are not mentioned on the array API spec website. We are "the strict library" after all
There was a problem hiding this comment.
I think it's worth a brief mention in the community meeting , if only to double-check the overwhelming support for dropping the C-style prefixes (and they do feel very C indeed).
There was a problem hiding this comment.
I made an entry in the hackmd
| from_dlpack(ForeignArray()) | ||
|
|
||
| # an explicit device is a request to transfer, so nothing has to be inferred | ||
| assert from_dlpack(ForeignArray(), device=CPU_DEVICE).device == CPU_DEVICE |
There was a problem hiding this comment.
Do we want to cover copy={True, False} here, too?
There was a problem hiding this comment.
Can we leave it for a new PR? I'm not yet sure I fully grok how it should work (copy=)
Co-authored-by: Evgeni Burovski <evgeny.burovskiy@gmail.com>
|
Conflicts resolved. I'd prefer to leave the |
|
I ran array-api-tests on this branch with a large number of examples, and it passed. Also checked that the SciPy tests suite passes with array-api-strict from this branch. That in itself is not very surprising, since SciPy testing of devices is rather thin, but we have a confirmation that changes here don't break it. |
|
I checked scikit-learn's tests. Of course something fails, but I suspect it might be legit bug in scikit-learn? I'll keep you posted. |
|
From my side, the PR status is ready as soon as Tim says it is. |
This improves the
from_dlpackbehaviour for round-tripping array-api-strict arrays and raises an error for arrays that are not on the CPU device.This is a follow up to #219 and #221
We use the device ID to tell the difference between the different "devices" present in array-api-strict. This seems to work/not bother libraries like torch or numpy. The device type is always CPU. In #212 we tried using different device type IDs, but that turns out not to work. I think the standard says (or suggests?) that for the CPU device the only device ID that makes sense is zero. In practice it seems every library ignores this field for CPU devices. Originally I thought we needed to use different device IDs to be able to make the following code work:
Before this PR the assert will fail.
But, now we have a
isinstance(x, Array)branch infrom_dlpack(line 257 ofarray_api_strict/_creation_functions.py). So we could do some special casing in thisifstatement. That way we don't have to report IDs that are not part of the standard. The downside is that__dlpack_device__would report the same for all the devices in array-api-strict. I can't make up my mind which option I prefer.On
mainit is possible to "transfer" a device from"device1"to the CPU by usingnp.from_dlpack(x_on_device1). This is explicitly not allowed when usingnp.asarray(). This PR adjusts the DLPack behaviour to match the__buffer__based behaviour.This also installs torch for one of the CI jobs to test DLpack'ing arrays to and from a different library.