You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There, each function, constant, and object is described with details
105
106
on parameters, return values, and special cases.
106
107
107
-
### Testing against Array API
108
+
### Testing against array API
108
109
109
110
There are two main ways to test your API for compliance: either using
110
111
`array-api-tests` suite or testing your API manually against the
111
112
`array-api-strict` reference implementation.
112
113
113
-
#### Array API Test suite (Recommended)
114
+
#### array-api-tests suite (Recommended)
114
115
115
116
{ref}`array-api-tests` is a test suite which verifies that your API
116
117
adheres to the standard. For each function or method, it confirms
@@ -126,10 +127,10 @@ cover only the minimal workflow:
126
127
variable to your package import name.
127
128
3. Inside the `array-api-tests` directory run the command for running pytest: `pytest`. There are
128
129
multiple useful options delivered by the test suite. A few worth mentioning:
129
-
-`--max-examples=1000` - maximal number of test cases to generate when using
130
+
-`--max-examples=1000` - maximum number of test cases to generate when using
130
131
hypothesis. This allows you to balance between execution time of the test
131
132
suite and thoroughness of the testing. It's advised to use as many examples
132
-
as the time buget can fit. Each test case is a random combination of
133
+
as the time budget can fit. Each test case is a random combination of
133
134
possible inputs: the more cases, the higher chance of finding an
134
135
unsupported edge case.
135
136
- With the `--xfails-file` option, you can describe which tests are expected
@@ -144,13 +145,15 @@ cover only the minimal workflow:
144
145
option is to skip these for the time being.
145
146
146
147
We strongly advise you to embed this setup in your CI as well. This will allow
147
-
you to continuously monitor Array API coverage, and make sure new changes don't break existing
148
-
APIs. As a reference, see [NumPy's Array API Tests CI setup](https://github.com/numpy/numpy/blob/581d10f43b539a189a2d37856e5130464de9e5f6/.github/workflows/linux.yml#L296).
148
+
you to continuously monitor array API standard coverage, and make sure new
149
+
changes don't break existing APIs. As a reference, see
150
+
[NumPy's array-api-tests CI setup](https://github.com/numpy/numpy/blob/581d10f43b539a189a2d37856e5130464de9e5f6/.github/workflows/linux.yml#L296)
151
+
and [a Pixi workspace setup](https://github.com/mdhaber/mparray/blob/0ef47e008fef92c605f73907436d4c6617419161/pixi.toml#L119-L179).
149
152
150
153
151
-
#### Array API Strict
154
+
#### array-api-strict
152
155
153
-
A simpler, and more manual, way of testing Array API coverage is to
156
+
A simpler, and more manual, way of testing array API standard coverage is to
154
157
run your API calls along with the {ref}`array-api-strict` Python implementation.
155
158
156
159
This way, you can ensure that the outputs coming from your API match the minimal
@@ -163,10 +166,9 @@ cases.
163
166
164
167
## Array Consumers
165
168
166
-
For array consumers, the main premise is to keep in mind that your **array
167
-
manipulation operations should not lock in for a particular array producing
168
-
library**. For instance, if you use NumPy for arrays, then your code could
169
-
contain:
169
+
For array consumers, the main premise is that your **array manipulation operations
170
+
should not be specific to one particular array producing library**. For instance,
171
+
if your code is specific to NumPy, it might contain:
170
172
171
173
```python
172
174
import numpy as np
@@ -178,12 +180,12 @@ return np.dot(c, b)
178
180
```
179
181
180
182
The first step should be as simple as assigning the `np` namespace to a dedicated
181
-
namespace variable. The convention used in the ecosystem is to name it `xp`. Then,
182
-
it is vital to ensure that each method and function call is something that the Array API
183
-
supports. For example, `dot` is present in the NumPy's API, but the standard
184
-
doesn't support it. For the sake of simplicity, let's assume both `c` and `b`
185
-
are `ndim=2`; therefore, we select `tensordot` instead, as both NumPy and the
186
-
standard define it:
183
+
namespace variable. The convention used in the ecosystem is to name it `xp`.
184
+
Then, it is vital to ensure that each method and function call is something that
185
+
the array API standard supports. For example, `dot` is present in the NumPy
186
+
API, but the standard doesn't support it. For the sake of simplicity, let's
187
+
assume both `c` and `b`are `ndim=2`; therefore, we select `tensordot` instead,
188
+
as both NumPy and the standard define it:
187
189
188
190
```python
189
191
import numpy as np
@@ -196,18 +198,19 @@ c = xp.mean(a, axis=0)
196
198
return xp.tensordot(c, b, axes=1)
197
199
```
198
200
199
-
At this point, replacing one backend with another one should only require providing a different
200
-
namespace, such as `xp = torch` (e.g., via an environment variable). This can be useful
201
-
if you're writing a script or in your custom software. The other alternatives are:
201
+
At this point, replacing one backend with another one should only require
202
+
providing a different namespace, such as `xp = torch` (e.g., via an environment
203
+
variable). This can be useful if you're writing a script or in your custom
204
+
software. The other alternatives are:
202
205
203
-
- If you are building a library where the backend is determined by input arrays,
204
-
and your function accepts array arguments, then a recommended way is to ask
205
-
your input arrays for a namespace to use: `xp = arr.__array_namespace__()`.
206
-
If the given library doesn't have it, then [`array_api_compat.array_namespace()`](https://data-apis.org/array-api-compat/helper-functions.html#array_api_compat.array_namespace)
207
-
should be used instead:
206
+
- If you are building a library where the backend is determined by input
207
+
arrays, and your function accepts array arguments, then a recommended way to
208
+
fetch the namespace is to use[`array_api_compat.array_namespace()`](https://data-apis.org/array-api-compat/helper-functions.html#array_api_compat.array_namespace).
209
+
In case you don't want to introduce a new package dependency, you can rely
210
+
on a plain `xp = arr.__array_namespace__()`:
208
211
```python
209
212
deffunc(array1, scalar1, scalar2):
210
-
xp =array1.__array_namespace__() # or array_namespace(array1)
213
+
xp =array_namespace(array1) # or array1.__array_namespace__()
211
214
return xp.arange(scalar1, scalar2) @ array1
212
215
```
213
216
- For a function that accepts scalars and returns arrays, use namespace `xp` as
@@ -227,7 +230,7 @@ offers a set of useful utility functions, such as:
0 commit comments