Improvements to device support #70
Copy link
Copy link
Open
Labels
Description
#59 added support for basic devices. Some improvements that could be made:
- Factor out the device checking logic (into a decorator?)
- Add devices that don't support certain dtypes (non-support for float64/complex128 being the most common)
- Allow the user to manually create custom "devices" with certain properties (probably via the flags API).
- Better testing for device support. This ideally should go in array-api-tests, but currently it doesn't test devices at all, so it would be useful to have some basic tests here.
Reactions are currently unavailable
Activity
ogrisel commentedon Oct 21, 2024
I tried to run the scikit-learn tests with
array-api-stricton the non-default device and I got some failures that do not happen with PyTorch and non-default device. So I suspect there is something fishy happening with the new devices inarray-api-strictbut I have not investigated the root cause yet.scikit-learn/scikit-learn#30090
betatim commentedon Oct 21, 2024
I'll take a look/investigate that failure further.
lucyleeow commentedon Mar 28, 2025
Commenting here because it partially relates OP but directly related to @ogrisel 's comment #70 (comment)
Looking at: https://data-apis.org/array-api/latest/design_topics/device_support.html#device-support , the spec is very light in this area. It only specifies support for local control over data allocation target device, and syntax for device assignment. I agree that it makes sense that strict does not allow mixing of devices, but there are 2 different options here:
Current behaviour seems a bit conflicting (?), this works:
this fails:
due to this check (in
__array__):array-api-strict/array_api_strict/_array_object.py
Lines 166 to 167 in a8f567a
this seems to be the only place where such a check is happening. And it's probably the cause of the behaviour noticed by @ogrisel where some tests on non-default devices are failing on strict but not with Torch and non-default device.
(I think we should agree on a behaviour and make it consistent)
@ev-br
(ref: noticed while working on #134 )
ev-br commentedon Mar 28, 2025
First and foremost, working on device support is very welcome @lucyleeow !
Two quick notes:
Neither dunder array nor nested asarrays are standard-compliant.
asarrayis not strict enough #118 tracks the latter inarray-api-compatand I just sent a PR to potentially clarify the spec, docs: clarify that behavior when provided a nested sequence toasarrayis unspecified array-api#917My gut feeling is that allowing multiple dummy devices in array-api-strict is more useful than only allowing a single CPU_DEVICE. If only to simplify testing device support in array-api-tests (the last bullet in the OP).
lucascolley commentedon Mar 28, 2025
Agreed, having different devices is useful for testing.
is more idiomatically written as
which should not fail
betatim commentedon Mar 31, 2025
The idea behind the "multi device support" in array-api-strict is to help projects test the behaviour of using more than one device, without needing actual special hardware (like a CUDA GPU).
The decision I made was to allow arrays on the default device (CPU_DEVICE) to be converted back to Numpy arrays. The reasoning being that it was already possible (don't introduce breaking changes) and that there are libraries that allow this (so it would be useful to test this). The "non default devices" don't allow conversion to Numpy arrays because there are libraries that don't allow you to do that and there was no existing behaviour so we could do what we wanted.
I think the error you get when you write
asarray([asarray([1,2], device=Device('device1')), asarray([1,2], device=Device('device1'))])is a bit weird/hard to figure out. At least I was puzzled by it. Maybe we can improve that to help users and point them to what Lucas suggested as the way to write this? Though I was also not sure what the intended outcome ofasarray([asarray([1,2], device=Device('device1')), asarray([1,2], device=Device('device1'))])is, an array on the default device or ondevice1?lucyleeow commentedon Mar 31, 2025
Thanks for the background @betatim, I think your decisions all sound reasonable.
I'm afraid the context is very boring, while working on #134, I wanted to amend
test_indexing_arraysto also test device support. That test unfortunately has:array-api-strict/array_api_strict/tests/test_array_object.py
Line 112 in a8f567a
which I think we now agree should have been written
xp.stack([a[idx[i]] for i in range(idx.shape[0])])I agree that the error is confusing. Indeed, this was also the error returned by bug #134 , though that one is an actual bug to be fixed.
I am now interested in what test failed with
array-api-strictbut passed with PyTorch? @ogriselogrisel commentedon Apr 22, 2026
Another thing that could be useful: make it possible to configure an
array_api_strictdevice object that can perform computation onxp.float32data but would raise an exception when attempting to call functions that need to allocate a device array withxp.float64dtype.This is the case for torch with the "mps" device on macOS. However, it's not easy to replicate for people who do not have access to recent Apple hardware. For reference here are the errors one gets with torch via array API compat on MPS:
Ideally, this limitation should be documented in
__array_namespace__info__.EDIT: I just realized that this need was already expressed in the description of the issue:
ev-br commentedon Apr 24, 2026
So the requests seem to converge on essentially #64. Here's a WIP/POC enhancement, #206
ISTM it'd be most helpful to split the discussion into two streams:
ogrisel commentedon Apr 30, 2026
Another related issue:
__setitem__#207ev-br commentedon Jul 9, 2026
array-api-strict==2.6 (released today, 09 Jul 2026) ships with gh-207 (no implicit device tranfers in
__setitem__) and gh-206 (a newDevice("no_float64")device).ev-br commentedon Jul 27, 2026
array-api-strict==2.6.1 adds a
Device("no_x64")to mimic the default JAX behaviour: only support single precision floats and integers of <=32 bit width.