|
| 1 | +# Differences from the Array API Specification |
| 2 | + |
| 3 | +There are some known differences between this library and the array API |
| 4 | +specification: |
| 5 | + |
| 6 | +## NumPy and CuPy |
| 7 | + |
| 8 | +- The array methods `__array_namespace__`, `device` (for NumPy), `to_device`, |
| 9 | + and `mT` are not defined. This reuses `np.ndarray` and `cp.ndarray` and we |
| 10 | + don't want to monkeypatch or wrap it. The helper functions `device()` and |
| 11 | + `to_device()` are provided to work around these missing methods (see above). |
| 12 | + `x.mT` can be replaced with `xp.linalg.matrix_transpose(x)`. |
| 13 | + `array_namespace(x)` should be used instead of `x.__array_namespace__`. |
| 14 | + |
| 15 | +- Value-based casting for scalars will be in effect unless explicitly disabled |
| 16 | + with the environment variable `NPY_PROMOTION_STATE=weak` or |
| 17 | + `np._set_promotion_state('weak')` (requires NumPy 1.24 or newer, see [NEP |
| 18 | + 50](https://numpy.org/neps/nep-0050-scalar-promotion.html) and |
| 19 | + https://github.com/numpy/numpy/issues/22341) |
| 20 | + |
| 21 | +- `asarray()` does not support `copy=False`. |
| 22 | + |
| 23 | +- Functions which are not wrapped may not have the same type annotations |
| 24 | + as the spec. |
| 25 | + |
| 26 | +- Functions which are not wrapped may not use positional-only arguments. |
| 27 | + |
| 28 | +The minimum supported NumPy version is 1.21. However, this older version of |
| 29 | +NumPy has a few issues: |
| 30 | + |
| 31 | +- `unique_*` will not compare nans as unequal. |
| 32 | +- `finfo()` has no `smallest_normal`. |
| 33 | +- No `from_dlpack` or `__dlpack__`. |
| 34 | +- `argmax()` and `argmin()` do not have `keepdims`. |
| 35 | +- `qr()` doesn't support matrix stacks. |
| 36 | +- `asarray()` doesn't support `copy=True` (as noted above, `copy=False` is not |
| 37 | + supported even in the latest NumPy). |
| 38 | +- Type promotion behavior will be value based for 0-D arrays (and there is no |
| 39 | + `NPY_PROMOTION_STATE=weak` to disable this). |
| 40 | + |
| 41 | +If any of these are an issue, it is recommended to bump your minimum NumPy |
| 42 | +version. |
| 43 | + |
| 44 | +## PyTorch |
| 45 | + |
| 46 | +- Like NumPy/CuPy, we do not wrap the `torch.Tensor` object. It is missing the |
| 47 | + `__array_namespace__` and `to_device` methods, so the corresponding helper |
| 48 | + functions `array_namespace()` and `to_device()` in this library should be |
| 49 | + used instead (see above). |
| 50 | + |
| 51 | +- The `x.size` attribute on `torch.Tensor` is a function that behaves |
| 52 | + differently from |
| 53 | + [`x.size`](https://data-apis.org/array-api/draft/API_specification/generated/array_api.array.size.html) |
| 54 | + in the spec. Use the `size(x)` helper function as a portable workaround (see |
| 55 | + above). |
| 56 | + |
| 57 | +- PyTorch does not have unsigned integer types other than `uint8`, and no |
| 58 | + attempt is made to implement them here. |
| 59 | + |
| 60 | +- PyTorch has type promotion semantics that differ from the array API |
| 61 | + specification for 0-D tensor objects. The array functions in this wrapper |
| 62 | + library do work around this, but the operators on the Tensor object do not, |
| 63 | + as no operators or methods on the Tensor object are modified. If this is a |
| 64 | + concern, use the functional form instead of the operator form, e.g., `add(x, |
| 65 | + y)` instead of `x + y`. |
| 66 | + |
| 67 | +- [`unique_all()`](https://data-apis.org/array-api/latest/API_specification/generated/array_api.unique_all.html#array_api.unique_all) |
| 68 | + is not implemented, due to the fact that `torch.unique` does not support |
| 69 | + returning the `indices` array. The other |
| 70 | + [`unique_*`](https://data-apis.org/array-api/latest/API_specification/set_functions.html) |
| 71 | + functions are implemented. |
| 72 | + |
| 73 | +- Slices do not support negative steps. |
| 74 | + |
| 75 | +- [`std()`](https://data-apis.org/array-api/latest/API_specification/generated/array_api.std.html#array_api.std) |
| 76 | + and |
| 77 | + [`var()`](https://data-apis.org/array-api/latest/API_specification/generated/array_api.var.html#array_api.var) |
| 78 | + do not support floating-point `correction`. |
| 79 | + |
| 80 | +- The `stream` argument of the `to_device()` helper (see above) is not |
| 81 | + supported. |
| 82 | + |
| 83 | +- As with NumPy, type annotations and positional-only arguments may not |
| 84 | + exactly match the spec for functions that are not wrapped at all. |
| 85 | + |
| 86 | +The minimum supported PyTorch version is 1.13. |
| 87 | + |
| 88 | +## JAX |
| 89 | + |
| 90 | +Unlike the other libraries supported here, JAX array API support is contained |
| 91 | +entirely in the JAX library. The JAX array API support is tracked at |
| 92 | +https://github.com/google/jax/issues/18353. |
| 93 | + |
| 94 | +## Dask |
| 95 | + |
| 96 | +If you're using dask with numpy, many of the same limitations that apply to numpy |
| 97 | +will also apply to dask. Besides those differences, other limitations include missing |
| 98 | +sort functionality (no `sort` or `argsort`), and limited support for the optional `linalg` |
| 99 | +and `fft` extensions. |
| 100 | + |
| 101 | +In particular, the `fft` namespace is not compliant with the array API spec. Any functions |
| 102 | +that you find under the `fft` namespace are the original, unwrapped functions under [`dask.array.fft`](https://docs.dask.org/en/latest/array-api.html#fast-fourier-transforms), which may or may not be Array API compliant. Use at your own risk! |
| 103 | + |
| 104 | +For `linalg`, several methods are missing, for example: |
| 105 | +- `cross` |
| 106 | +- `det` |
| 107 | +- `eigh` |
| 108 | +- `eigvalsh` |
| 109 | +- `matrix_power` |
| 110 | +- `pinv` |
| 111 | +- `slogdet` |
| 112 | +- `matrix_norm` |
| 113 | +- `matrix_rank` |
| 114 | +Other methods may only be partially implemented or return incorrect results at times. |
| 115 | + |
| 116 | +The minimum supported Dask version is 2023.12.0. |
0 commit comments