array-api-strict 2.0__py3-none-any.whl → 2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- array_api_strict/__init__.py +3 -0
- array_api_strict/_array_object.py +129 -53
- array_api_strict/_creation_functions.py +37 -21
- array_api_strict/_data_type_functions.py +5 -3
- array_api_strict/_dtypes.py +1 -1
- array_api_strict/_elementwise_functions.py +133 -67
- array_api_strict/_fft.py +17 -17
- array_api_strict/_flags.py +19 -10
- array_api_strict/_indexing_functions.py +3 -1
- array_api_strict/_info.py +2 -2
- array_api_strict/_linalg.py +31 -20
- array_api_strict/_linear_algebra_functions.py +13 -4
- array_api_strict/_manipulation_functions.py +28 -13
- array_api_strict/_searching_functions.py +13 -5
- array_api_strict/_set_functions.py +8 -7
- array_api_strict/_sorting_functions.py +2 -2
- array_api_strict/_statistical_functions.py +8 -8
- array_api_strict/_typing.py +2 -2
- array_api_strict/_utility_functions.py +2 -2
- array_api_strict/_version.py +3 -3
- array_api_strict/tests/test_array_object.py +24 -8
- array_api_strict/tests/test_device_support.py +38 -0
- array_api_strict/tests/test_elementwise_functions.py +73 -7
- array_api_strict/tests/test_flags.py +57 -48
- array_api_strict/tests/test_indexing_functions.py +20 -0
- array_api_strict/tests/test_linalg.py +14 -13
- array_api_strict/tests/test_sorting_functions.py +14 -0
- array_api_strict/tests/test_statistical_functions.py +15 -5
- {array_api_strict-2.0.dist-info → array_api_strict-2.1.dist-info}/METADATA +1 -5
- array_api_strict-2.1.dist-info/RECORD +41 -0
- {array_api_strict-2.0.dist-info → array_api_strict-2.1.dist-info}/WHEEL +1 -1
- array_api_strict-2.0.dist-info/RECORD +0 -40
- {array_api_strict-2.0.dist-info → array_api_strict-2.1.dist-info}/LICENSE +0 -0
- {array_api_strict-2.0.dist-info → array_api_strict-2.1.dist-info}/top_level.txt +0 -0
|
@@ -32,9 +32,12 @@ def _supports_buffer_protocol(obj):
|
|
|
32
32
|
def _check_device(device):
|
|
33
33
|
# _array_object imports in this file are inside the functions to avoid
|
|
34
34
|
# circular imports
|
|
35
|
-
from ._array_object import
|
|
35
|
+
from ._array_object import Device, ALL_DEVICES
|
|
36
36
|
|
|
37
|
-
if device not
|
|
37
|
+
if device is not None and not isinstance(device, Device):
|
|
38
|
+
raise ValueError(f"Unsupported device {device!r}")
|
|
39
|
+
|
|
40
|
+
if device is not None and device not in ALL_DEVICES:
|
|
38
41
|
raise ValueError(f"Unsupported device {device!r}")
|
|
39
42
|
|
|
40
43
|
def asarray(
|
|
@@ -76,10 +79,10 @@ def asarray(
|
|
|
76
79
|
new_array = np.array(obj._array, copy=copy, dtype=_np_dtype)
|
|
77
80
|
if new_array is not obj._array:
|
|
78
81
|
raise ValueError("Unable to avoid copy while creating an array from given array.")
|
|
79
|
-
return Array._new(new_array)
|
|
82
|
+
return Array._new(new_array, device=device)
|
|
80
83
|
elif _supports_buffer_protocol(obj):
|
|
81
84
|
# Buffer protocol will always support no-copy
|
|
82
|
-
return Array._new(np.array(obj, copy=copy, dtype=_np_dtype))
|
|
85
|
+
return Array._new(np.array(obj, copy=copy, dtype=_np_dtype), device=device)
|
|
83
86
|
else:
|
|
84
87
|
# No-copy is unsupported for Python built-in types.
|
|
85
88
|
raise ValueError("Unable to avoid copy while creating an array from given object.")
|
|
@@ -89,13 +92,13 @@ def asarray(
|
|
|
89
92
|
copy = False
|
|
90
93
|
|
|
91
94
|
if isinstance(obj, Array):
|
|
92
|
-
return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype))
|
|
95
|
+
return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype), device=device)
|
|
93
96
|
if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)):
|
|
94
97
|
# Give a better error message in this case. NumPy would convert this
|
|
95
98
|
# to an object array. TODO: This won't handle large integers in lists.
|
|
96
99
|
raise OverflowError("Integer out of bounds for array dtypes")
|
|
97
100
|
res = np.array(obj, dtype=_np_dtype, copy=copy)
|
|
98
|
-
return Array._new(res)
|
|
101
|
+
return Array._new(res, device=device)
|
|
99
102
|
|
|
100
103
|
|
|
101
104
|
def arange(
|
|
@@ -119,7 +122,7 @@ def arange(
|
|
|
119
122
|
|
|
120
123
|
if dtype is not None:
|
|
121
124
|
dtype = dtype._np_dtype
|
|
122
|
-
return Array._new(np.arange(start, stop=stop, step=step, dtype=dtype))
|
|
125
|
+
return Array._new(np.arange(start, stop=stop, step=step, dtype=dtype), device=device)
|
|
123
126
|
|
|
124
127
|
|
|
125
128
|
def empty(
|
|
@@ -140,7 +143,7 @@ def empty(
|
|
|
140
143
|
|
|
141
144
|
if dtype is not None:
|
|
142
145
|
dtype = dtype._np_dtype
|
|
143
|
-
return Array._new(np.empty(shape, dtype=dtype))
|
|
146
|
+
return Array._new(np.empty(shape, dtype=dtype), device=device)
|
|
144
147
|
|
|
145
148
|
|
|
146
149
|
def empty_like(
|
|
@@ -158,7 +161,7 @@ def empty_like(
|
|
|
158
161
|
|
|
159
162
|
if dtype is not None:
|
|
160
163
|
dtype = dtype._np_dtype
|
|
161
|
-
return Array._new(np.empty_like(x._array, dtype=dtype))
|
|
164
|
+
return Array._new(np.empty_like(x._array, dtype=dtype), device=device)
|
|
162
165
|
|
|
163
166
|
|
|
164
167
|
def eye(
|
|
@@ -182,7 +185,7 @@ def eye(
|
|
|
182
185
|
|
|
183
186
|
if dtype is not None:
|
|
184
187
|
dtype = dtype._np_dtype
|
|
185
|
-
return Array._new(np.eye(n_rows, M=n_cols, k=k, dtype=dtype))
|
|
188
|
+
return Array._new(np.eye(n_rows, M=n_cols, k=k, dtype=dtype), device=device)
|
|
186
189
|
|
|
187
190
|
|
|
188
191
|
_default = object()
|
|
@@ -208,7 +211,7 @@ def from_dlpack(
|
|
|
208
211
|
if copy not in [_default, None]:
|
|
209
212
|
raise NotImplementedError("The copy argument to from_dlpack is not yet implemented")
|
|
210
213
|
|
|
211
|
-
return Array._new(np.from_dlpack(x))
|
|
214
|
+
return Array._new(np.from_dlpack(x), device=device)
|
|
212
215
|
|
|
213
216
|
|
|
214
217
|
def full(
|
|
@@ -237,7 +240,7 @@ def full(
|
|
|
237
240
|
# This will happen if the fill value is not something that NumPy
|
|
238
241
|
# coerces to one of the acceptable dtypes.
|
|
239
242
|
raise TypeError("Invalid input to full")
|
|
240
|
-
return Array._new(res)
|
|
243
|
+
return Array._new(res, device=device)
|
|
241
244
|
|
|
242
245
|
|
|
243
246
|
def full_like(
|
|
@@ -265,7 +268,7 @@ def full_like(
|
|
|
265
268
|
# This will happen if the fill value is not something that NumPy
|
|
266
269
|
# coerces to one of the acceptable dtypes.
|
|
267
270
|
raise TypeError("Invalid input to full_like")
|
|
268
|
-
return Array._new(res)
|
|
271
|
+
return Array._new(res, device=device)
|
|
269
272
|
|
|
270
273
|
|
|
271
274
|
def linspace(
|
|
@@ -290,7 +293,7 @@ def linspace(
|
|
|
290
293
|
|
|
291
294
|
if dtype is not None:
|
|
292
295
|
dtype = dtype._np_dtype
|
|
293
|
-
return Array._new(np.linspace(start, stop, num, dtype=dtype, endpoint=endpoint))
|
|
296
|
+
return Array._new(np.linspace(start, stop, num, dtype=dtype, endpoint=endpoint), device=device)
|
|
294
297
|
|
|
295
298
|
|
|
296
299
|
def meshgrid(*arrays: Array, indexing: str = "xy") -> List[Array]:
|
|
@@ -307,8 +310,17 @@ def meshgrid(*arrays: Array, indexing: str = "xy") -> List[Array]:
|
|
|
307
310
|
if len({a.dtype for a in arrays}) > 1:
|
|
308
311
|
raise ValueError("meshgrid inputs must all have the same dtype")
|
|
309
312
|
|
|
313
|
+
if len({a.device for a in arrays}) > 1:
|
|
314
|
+
raise ValueError("meshgrid inputs must all be on the same device")
|
|
315
|
+
|
|
316
|
+
# arrays is allowed to be empty
|
|
317
|
+
if arrays:
|
|
318
|
+
device = arrays[0].device
|
|
319
|
+
else:
|
|
320
|
+
device = None
|
|
321
|
+
|
|
310
322
|
return [
|
|
311
|
-
Array._new(array)
|
|
323
|
+
Array._new(array, device=device)
|
|
312
324
|
for array in np.meshgrid(*[a._array for a in arrays], indexing=indexing)
|
|
313
325
|
]
|
|
314
326
|
|
|
@@ -331,7 +343,7 @@ def ones(
|
|
|
331
343
|
|
|
332
344
|
if dtype is not None:
|
|
333
345
|
dtype = dtype._np_dtype
|
|
334
|
-
return Array._new(np.ones(shape, dtype=dtype))
|
|
346
|
+
return Array._new(np.ones(shape, dtype=dtype), device=device)
|
|
335
347
|
|
|
336
348
|
|
|
337
349
|
def ones_like(
|
|
@@ -346,10 +358,12 @@ def ones_like(
|
|
|
346
358
|
|
|
347
359
|
_check_valid_dtype(dtype)
|
|
348
360
|
_check_device(device)
|
|
361
|
+
if device is None:
|
|
362
|
+
device = x.device
|
|
349
363
|
|
|
350
364
|
if dtype is not None:
|
|
351
365
|
dtype = dtype._np_dtype
|
|
352
|
-
return Array._new(np.ones_like(x._array, dtype=dtype))
|
|
366
|
+
return Array._new(np.ones_like(x._array, dtype=dtype), device=device)
|
|
353
367
|
|
|
354
368
|
|
|
355
369
|
def tril(x: Array, /, *, k: int = 0) -> Array:
|
|
@@ -363,7 +377,7 @@ def tril(x: Array, /, *, k: int = 0) -> Array:
|
|
|
363
377
|
if x.ndim < 2:
|
|
364
378
|
# Note: Unlike np.tril, x must be at least 2-D
|
|
365
379
|
raise ValueError("x must be at least 2-dimensional for tril")
|
|
366
|
-
return Array._new(np.tril(x._array, k=k))
|
|
380
|
+
return Array._new(np.tril(x._array, k=k), device=x.device)
|
|
367
381
|
|
|
368
382
|
|
|
369
383
|
def triu(x: Array, /, *, k: int = 0) -> Array:
|
|
@@ -377,7 +391,7 @@ def triu(x: Array, /, *, k: int = 0) -> Array:
|
|
|
377
391
|
if x.ndim < 2:
|
|
378
392
|
# Note: Unlike np.triu, x must be at least 2-D
|
|
379
393
|
raise ValueError("x must be at least 2-dimensional for triu")
|
|
380
|
-
return Array._new(np.triu(x._array, k=k))
|
|
394
|
+
return Array._new(np.triu(x._array, k=k), device=x.device)
|
|
381
395
|
|
|
382
396
|
|
|
383
397
|
def zeros(
|
|
@@ -398,7 +412,7 @@ def zeros(
|
|
|
398
412
|
|
|
399
413
|
if dtype is not None:
|
|
400
414
|
dtype = dtype._np_dtype
|
|
401
|
-
return Array._new(np.zeros(shape, dtype=dtype))
|
|
415
|
+
return Array._new(np.zeros(shape, dtype=dtype), device=device)
|
|
402
416
|
|
|
403
417
|
|
|
404
418
|
def zeros_like(
|
|
@@ -413,7 +427,9 @@ def zeros_like(
|
|
|
413
427
|
|
|
414
428
|
_check_valid_dtype(dtype)
|
|
415
429
|
_check_device(device)
|
|
430
|
+
if device is None:
|
|
431
|
+
device = x.device
|
|
416
432
|
|
|
417
433
|
if dtype is not None:
|
|
418
434
|
dtype = dtype._np_dtype
|
|
419
|
-
return Array._new(np.zeros_like(x._array, dtype=dtype))
|
|
435
|
+
return Array._new(np.zeros_like(x._array, dtype=dtype), device=device)
|
|
@@ -37,10 +37,12 @@ def astype(
|
|
|
37
37
|
_check_device(device)
|
|
38
38
|
else:
|
|
39
39
|
raise TypeError("The device argument to astype requires at least version 2023.12 of the array API")
|
|
40
|
+
else:
|
|
41
|
+
device = x.device
|
|
40
42
|
|
|
41
43
|
if not copy and dtype == x.dtype:
|
|
42
44
|
return x
|
|
43
|
-
return Array._new(x._array.astype(dtype=dtype._np_dtype, copy=copy))
|
|
45
|
+
return Array._new(x._array.astype(dtype=dtype._np_dtype, copy=copy), device=device)
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
def broadcast_arrays(*arrays: Array) -> List[Array]:
|
|
@@ -52,7 +54,7 @@ def broadcast_arrays(*arrays: Array) -> List[Array]:
|
|
|
52
54
|
from ._array_object import Array
|
|
53
55
|
|
|
54
56
|
return [
|
|
55
|
-
Array._new(array) for array in np.broadcast_arrays(*[a._array for a in arrays])
|
|
57
|
+
Array._new(array, device=arrays[0].device) for array in np.broadcast_arrays(*[a._array for a in arrays])
|
|
56
58
|
]
|
|
57
59
|
|
|
58
60
|
|
|
@@ -64,7 +66,7 @@ def broadcast_to(x: Array, /, shape: Tuple[int, ...]) -> Array:
|
|
|
64
66
|
"""
|
|
65
67
|
from ._array_object import Array
|
|
66
68
|
|
|
67
|
-
return Array._new(np.broadcast_to(x._array, shape))
|
|
69
|
+
return Array._new(np.broadcast_to(x._array, shape), device=x.device)
|
|
68
70
|
|
|
69
71
|
|
|
70
72
|
def can_cast(from_: Union[Dtype, Array], to: Dtype, /) -> bool:
|
array_api_strict/_dtypes.py
CHANGED
|
@@ -121,7 +121,7 @@ _dtype_categories = {
|
|
|
121
121
|
"integer": _integer_dtypes,
|
|
122
122
|
"integer or boolean": _integer_or_boolean_dtypes,
|
|
123
123
|
"boolean": _boolean_dtypes,
|
|
124
|
-
"real floating-point":
|
|
124
|
+
"real floating-point": _real_floating_dtypes,
|
|
125
125
|
"complex floating-point": _complex_floating_dtypes,
|
|
126
126
|
"floating-point": _floating_dtypes,
|
|
127
127
|
}
|