1
1
# array-api-strict
2
2
3
3
` array_api_strict ` is a strict, minimal implementation of the [ Python array
4
- API] ( https://data-apis.org/array-api/latest/ )
4
+ API] ( https://data-apis.org/array-api/latest/ ) .
5
5
6
6
The purpose of array-api-strict is to provide an implementation of the array
7
7
API for consuming libraries to test against so they can be completely sure
@@ -11,191 +11,12 @@ It is *not* intended to be used by end-users. End-users of the array API
11
11
should just use their favorite array library (NumPy, CuPy, PyTorch, etc.) as
12
12
usual. It is also not intended to be used as a dependency by consuming
13
13
libraries. Consuming library code should use the
14
- [ array-api-compat] ( https://github.com/ data-apis/array-api-compat ) package to
14
+ [ array-api-compat] ( https://data-apis.org /array-api-compat/ ) package to
15
15
support the array API. Rather, it is intended to be used in the test suites of
16
16
consuming libraries to test their array API usage.
17
17
18
18
array-api-strict currently supports the 2022.12 version of the standard.
19
19
2023.12 support is planned and is tracked by [ this
20
20
issue] ( https://github.com/data-apis/array-api-strict/issues/25 ) .
21
21
22
- ## Install
23
-
24
- ` array-api-strict ` is available on both
25
- [ PyPI] ( https://pypi.org/project/array-api-strict/ )
26
-
27
- ```
28
- python -m pip install array-api-strict
29
- ```
30
-
31
- and [ Conda-forge] ( https://anaconda.org/conda-forge/array-api-strict )
32
-
33
- ```
34
- conda install --channel conda-forge array-api-strict
35
- ```
36
-
37
- array-api-strict supports NumPy 1.26 and (the upcoming) NumPy 2.0.
38
-
39
- ## Rationale
40
-
41
- The array API has many functions and behaviors that are required to be
42
- implemented by conforming libraries, but it does not, in most cases, disallow
43
- implementing additional functions, keyword arguments, and behaviors that
44
- aren't explicitly required by the standard.
45
-
46
- However, this poses a problem for consumers of the array API, as they may
47
- accidentally use a function or rely on a behavior which just happens to be
48
- implemented in every array library they test against (e.g., NumPy and
49
- PyTorch), but isn't required by the standard and may not be included in other
50
- libraries.
51
-
52
- array-api-strict solves this problem by providing a strict, minimal
53
- implementation of the array API standard. Only those functions and behaviors
54
- that are explicitly * required* by the standard are implemented. For example,
55
- most NumPy functions accept Python scalars as inputs:
56
-
57
- ``` py
58
- >> > import numpy as np
59
- >> > np.sin(0.0 )
60
- 0.0
61
- ```
62
-
63
- However, the standard only specifies function inputs on ` Array ` objects. And
64
- indeed, some libraries, such as PyTorch, do not allow this:
65
-
66
- ``` py
67
- >> > import torch
68
- >> > torch.sin(0.0 )
69
- Traceback (most recent call last):
70
- File " <stdin>" , line 1 , in < module>
71
- TypeError : sin(): argument ' input' (position 1 ) must be Tensor, not float
72
- ```
73
-
74
- In array-api-strict, this is also an error:
75
-
76
- ``` py
77
- >> > import array_api_strict as xp
78
- >> > xp.sin(0.0 )
79
- Traceback (most recent call last):
80
- ...
81
- AttributeError : ' float' object has no attribute ' dtype'
82
- ```
83
-
84
- Here is an (incomplete) list of the sorts of ways that array-api-strict is
85
- strict/minimal:
86
-
87
- - Only those functions and methods that are [ defined in the
88
- standard] ( https://data-apis.org/array-api/latest/API_specification/index.html )
89
- are included.
90
-
91
- - In those functions, only the keyword-arguments that are defined by the
92
- standard are included. All signatures in array-api-strict use
93
- [ positional-only
94
- arguments] ( https://data-apis.org/array-api/latest/API_specification/function_and_method_signatures.html#function-and-method-signatures ) .
95
- As noted above, only ` array_api_strict ` array objects are accepted by
96
- functions, except in the places where the standard allows Python scalars
97
- (i.e., functions do not automatically call ` asarray ` on their inputs).
98
-
99
- - Only those [ dtypes that are defined in the
100
- standard] ( https://data-apis.org/array-api/latest/API_specification/data_types.html )
101
- are included.
102
-
103
- - All functions and methods reject inputs if the standard does not * require*
104
- the input dtype(s) to be supported. This is one of the most restrictive
105
- aspects of the library. For example, in NumPy, most transcendental functions
106
- like ` sin ` will accept integer array inputs, but the [ standard only requires
107
- them to accept floating-point
108
- inputs] ( https://data-apis.org/array-api/latest/API_specification/generated/array_api.sin.html#array_api.sin ) ,
109
- so in array-api-strict, ` sin(integer_array) ` will raise an exception.
110
-
111
- - The
112
- [ indexing] ( https://data-apis.org/array-api/latest/API_specification/indexing.html )
113
- semantics required by the standard are limited compared to those implemented
114
- by NumPy (e.g., out-of-bounds slices are not supported, integer array
115
- indexing is not supported, only a single boolean array index is supported).
116
-
117
- - There are no distinct "scalar" objects as in NumPy. There are only 0-D
118
- arrays.
119
-
120
- - Dtype objects are just empty objects that only implement [ equality
121
- comparison] ( https://data-apis.org/array-api/latest/API_specification/generated/array_api.data_types.__eq__.html ) .
122
- The way to access dtype objects in the standard is by name, like
123
- ` xp.float32 ` .
124
-
125
- - The array object type itself is private and should not be accessed.
126
- Subclassing or otherwise trying to directly initialize this object is not
127
- supported. Arrays should be created with one of the [ array creation
128
- functions] ( https://data-apis.org/array-api/latest/API_specification/creation_functions.html )
129
- such as ` asarray ` .
130
-
131
- ## Caveats
132
-
133
- array-api-strict is a thin pure Python wrapper around NumPy. NumPy 2.0 fully
134
- supports the array API but NumPy 1.26 does not, so many behaviors are wrapped
135
- in NumPy 1.26 to provide array API compatible behavior. Although it is based
136
- on NumPy, mixing NumPy arrays with array-api-strict arrays is not supported.
137
- This should generally raise an error, as it indicates a potential portability
138
- issue, but this hasn't necessarily been tested thoroughly.
139
-
140
- 1 . array-api-strict is validated against the [ array API test
141
- suite] ( https://github.com/data-apis/array-api-tests ) . However, there may be
142
- a few minor instances where NumPy deviates from the standard in a way that
143
- is inconvenient to workaround in array-api-strict, since it aims to remain
144
- pure Python. You can see the full list of tests that are known to fail in
145
- the [ xfails
146
- file] ( https://github.com/data-apis/array-api-strict/blob/main/array-api-tests-xfails.txt ) .
147
-
148
- The most notable of these is that in NumPy 1.26, the ` copy=False ` flag is
149
- not implemented for ` asarray ` and therefore ` array_api_strict ` raises
150
- ` NotImplementedError ` in that case.
151
-
152
- 2 . Since NumPy is a CPU-only library, the [ device
153
- support] ( https://data-apis.org/array-api/latest/design_topics/device_support.html )
154
- in array-api-strict is superficial only. ` x.device ` is always a (private)
155
- ` CPU_DEVICE ` object, and ` device ` keywords to creation functions only
156
- accept either this object or ` None ` . A future version of array-api-strict
157
- [ may add support for a CuPy
158
- backend] ( https://github.com/data-apis/array-api-strict/issues/5 ) so that
159
- more significant device support can be tested.
160
-
161
- 3 . Although only array types are expected in array-api-strict functions,
162
- currently most functions do not do extensive type checking on their inputs,
163
- so a sufficiently duck-typed object may pass through silently (or at best,
164
- you may get ` AttributeError ` instead of ` TypeError ` ). However, all type
165
- signatures have type annotations (based on those from the standard), so
166
- this deviation may be tested with type checking. This [ behavior may improve
167
- in the future] ( https://github.com/data-apis/array-api-strict/issues/6 ) .
168
-
169
- 4 . There are some behaviors in the standard that are not required to be
170
- implemented by libraries that cannot support [ data dependent
171
- shapes] ( https://data-apis.org/array-api/latest/design_topics/data_dependent_output_shapes.html ) .
172
- This includes [ the ` unique_* `
173
- functions] ( https://data-apis.org/array-api/latest/API_specification/set_functions.html ) ,
174
- [ boolean array
175
- indexing] ( https://data-apis.org/array-api/latest/API_specification/indexing.html#boolean-array-indexing ) ,
176
- and the
177
- [ ` nonzero ` ] ( https://data-apis.org/array-api/latest/API_specification/generated/array_api.nonzero.html )
178
- function. array-api-strict currently implements all of these. In the
179
- future, [ there may be a way to disable them] ( https://github.com/data-apis/array-api-strict/issues/7 ) .
180
-
181
- 5 . array-api-strict currently only supports the latest version of the array
182
- API standard. [ This may change in the future depending on
183
- need] ( https://github.com/data-apis/array-api-strict/issues/8 ) .
184
-
185
- ## Usage
186
-
187
- TODO: Add a sample CI script here.
188
-
189
- ## Relationship to ` numpy.array_api `
190
-
191
- Previously this implementation was available as ` numpy.array_api ` , but it was
192
- moved to a separate package for NumPy 2.0.
193
-
194
- Note that the history of this repo prior to commit
195
- fbefd42e4d11e9be20e0a4785f2619fc1aef1e7c was generated automatically
196
- from the numpy git history, using the following
197
- [ git-filter-repo] ( https://github.com/newren/git-filter-repo ) command:
198
-
199
- ```
200
- git_filter_repo.py --path numpy/array_api/ --path-rename numpy/array_api:array_api_strict --replace-text <(echo -e "numpy.array_api==>array_api_strict\nfrom ..core==>from numpy.core\nfrom .._core==>from numpy._core\nfrom ..linalg==>from numpy.linalg\nfrom numpy import array_api==>import array_api_strict") --commit-callback 'commit.message = commit.message.rstrip() + b"\n\nOriginal NumPy Commit: " + commit.original_id'
201
- ```
22
+ See the documentation for more details https://data-apis.org/array-api-strict/
0 commit comments