array-api-strict 2.1.3__py3-none-any.whl → 2.2__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 +8 -4
- array_api_strict/_elementwise_functions.py +25 -0
- array_api_strict/_flags.py +8 -3
- array_api_strict/_indexing_functions.py +12 -0
- array_api_strict/_info.py +121 -114
- array_api_strict/_typing.py +4 -3
- array_api_strict/_utility_functions.py +30 -0
- array_api_strict/_version.py +3 -3
- array_api_strict/tests/test_array_object.py +5 -1
- array_api_strict/tests/test_elementwise_functions.py +8 -2
- array_api_strict/tests/test_flags.py +53 -7
- {array_api_strict-2.1.3.dist-info → array_api_strict-2.2.dist-info}/METADATA +1 -1
- {array_api_strict-2.1.3.dist-info → array_api_strict-2.2.dist-info}/RECORD +16 -16
- {array_api_strict-2.1.3.dist-info → array_api_strict-2.2.dist-info}/WHEEL +1 -1
- {array_api_strict-2.1.3.dist-info → array_api_strict-2.2.dist-info}/LICENSE +0 -0
- {array_api_strict-2.1.3.dist-info → array_api_strict-2.2.dist-info}/top_level.txt +0 -0
array_api_strict/__init__.py
CHANGED
|
@@ -172,10 +172,12 @@ from ._elementwise_functions import (
|
|
|
172
172
|
minimum,
|
|
173
173
|
multiply,
|
|
174
174
|
negative,
|
|
175
|
+
nextafter,
|
|
175
176
|
not_equal,
|
|
176
177
|
positive,
|
|
177
178
|
pow,
|
|
178
179
|
real,
|
|
180
|
+
reciprocal,
|
|
179
181
|
remainder,
|
|
180
182
|
round,
|
|
181
183
|
sign,
|
|
@@ -240,10 +242,12 @@ __all__ += [
|
|
|
240
242
|
"minimum",
|
|
241
243
|
"multiply",
|
|
242
244
|
"negative",
|
|
245
|
+
"nextafter",
|
|
243
246
|
"not_equal",
|
|
244
247
|
"positive",
|
|
245
248
|
"pow",
|
|
246
249
|
"real",
|
|
250
|
+
"reciprocal",
|
|
247
251
|
"remainder",
|
|
248
252
|
"round",
|
|
249
253
|
"sign",
|
|
@@ -258,9 +262,9 @@ __all__ += [
|
|
|
258
262
|
"trunc",
|
|
259
263
|
]
|
|
260
264
|
|
|
261
|
-
from ._indexing_functions import take
|
|
265
|
+
from ._indexing_functions import take, take_along_axis
|
|
262
266
|
|
|
263
|
-
__all__ += ["take"]
|
|
267
|
+
__all__ += ["take", "take_along_axis"]
|
|
264
268
|
|
|
265
269
|
from ._info import __array_namespace_info__
|
|
266
270
|
|
|
@@ -305,9 +309,9 @@ from ._statistical_functions import cumulative_sum, max, mean, min, prod, std, s
|
|
|
305
309
|
|
|
306
310
|
__all__ += ["cumulative_sum", "max", "mean", "min", "prod", "std", "sum", "var"]
|
|
307
311
|
|
|
308
|
-
from ._utility_functions import all, any
|
|
312
|
+
from ._utility_functions import all, any, diff
|
|
309
313
|
|
|
310
|
-
__all__ += ["all", "any"]
|
|
314
|
+
__all__ += ["all", "any", "diff"]
|
|
311
315
|
|
|
312
316
|
from ._array_object import Device
|
|
313
317
|
__all__ += ["Device"]
|
|
@@ -805,6 +805,20 @@ def negative(x: Array, /) -> Array:
|
|
|
805
805
|
return Array._new(np.negative(x._array), device=x.device)
|
|
806
806
|
|
|
807
807
|
|
|
808
|
+
@requires_api_version('2024.12')
|
|
809
|
+
def nextafter(x1: Array, x2: Array, /) -> Array:
|
|
810
|
+
"""
|
|
811
|
+
Array API compatible wrapper for :py:func:`np.nextafter <numpy.nextafter>`.
|
|
812
|
+
|
|
813
|
+
See its docstring for more information.
|
|
814
|
+
"""
|
|
815
|
+
if x1.device != x2.device:
|
|
816
|
+
raise ValueError(f"Arrays from two different devices ({x1.device} and {x2.device}) can not be combined.")
|
|
817
|
+
if x1.dtype not in _real_floating_dtypes or x2.dtype not in _real_floating_dtypes:
|
|
818
|
+
raise TypeError("Only real floating-point dtypes are allowed in nextafter")
|
|
819
|
+
x1, x2 = Array._normalize_two_args(x1, x2)
|
|
820
|
+
return Array._new(np.nextafter(x1._array, x2._array), device=x1.device)
|
|
821
|
+
|
|
808
822
|
def not_equal(x1: Array, x2: Array, /) -> Array:
|
|
809
823
|
"""
|
|
810
824
|
Array API compatible wrapper for :py:func:`np.not_equal <numpy.not_equal>`.
|
|
@@ -858,6 +872,17 @@ def real(x: Array, /) -> Array:
|
|
|
858
872
|
return Array._new(np.real(x._array), device=x.device)
|
|
859
873
|
|
|
860
874
|
|
|
875
|
+
@requires_api_version('2024.12')
|
|
876
|
+
def reciprocal(x: Array, /) -> Array:
|
|
877
|
+
"""
|
|
878
|
+
Array API compatible wrapper for :py:func:`np.reciprocal <numpy.reciprocal>`.
|
|
879
|
+
|
|
880
|
+
See its docstring for more information.
|
|
881
|
+
"""
|
|
882
|
+
if x.dtype not in _floating_dtypes:
|
|
883
|
+
raise TypeError("Only floating-point dtypes are allowed in reciprocal")
|
|
884
|
+
return Array._new(np.reciprocal(x._array), device=x.device)
|
|
885
|
+
|
|
861
886
|
def remainder(x1: Array, x2: Array, /) -> Array:
|
|
862
887
|
"""
|
|
863
888
|
Array API compatible wrapper for :py:func:`np.remainder <numpy.remainder>`.
|
array_api_strict/_flags.py
CHANGED
|
@@ -24,6 +24,8 @@ supported_versions = (
|
|
|
24
24
|
"2023.12",
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
+
draft_version = "2024.12"
|
|
28
|
+
|
|
27
29
|
API_VERSION = default_version = "2023.12"
|
|
28
30
|
|
|
29
31
|
BOOLEAN_INDEXING = True
|
|
@@ -70,8 +72,8 @@ def set_array_api_strict_flags(
|
|
|
70
72
|
----------
|
|
71
73
|
api_version : str, optional
|
|
72
74
|
The version of the standard to use. Supported versions are:
|
|
73
|
-
``{supported_versions}
|
|
74
|
-
``{default_version!r}``.
|
|
75
|
+
``{supported_versions}``, plus the draft version ``{draft_version}``.
|
|
76
|
+
The default version number is ``{default_version!r}``.
|
|
75
77
|
|
|
76
78
|
Note that 2021.12 is supported, but currently gives the same thing as
|
|
77
79
|
2022.12 (except that the fft extension will be disabled).
|
|
@@ -134,10 +136,12 @@ def set_array_api_strict_flags(
|
|
|
134
136
|
global API_VERSION, BOOLEAN_INDEXING, DATA_DEPENDENT_SHAPES, ENABLED_EXTENSIONS
|
|
135
137
|
|
|
136
138
|
if api_version is not None:
|
|
137
|
-
if api_version not in supported_versions:
|
|
139
|
+
if api_version not in [*supported_versions, draft_version]:
|
|
138
140
|
raise ValueError(f"Unsupported standard version {api_version!r}")
|
|
139
141
|
if api_version == "2021.12":
|
|
140
142
|
warnings.warn("The 2021.12 version of the array API specification was requested but the returned namespace is actually version 2022.12", stacklevel=2)
|
|
143
|
+
if api_version == draft_version:
|
|
144
|
+
warnings.warn(f"The {draft_version} version of the array API specification is in draft status. Not all features are implemented in array_api_strict, some functions may not be fully tested, and behaviors are subject to change before the final standard release.")
|
|
141
145
|
API_VERSION = api_version
|
|
142
146
|
array_api_strict.__array_api_version__ = API_VERSION
|
|
143
147
|
|
|
@@ -169,6 +173,7 @@ set_array_api_strict_flags.__doc__ = set_array_api_strict_flags.__doc__.format(
|
|
|
169
173
|
supported_versions=supported_versions,
|
|
170
174
|
default_version=default_version,
|
|
171
175
|
default_extensions=default_extensions,
|
|
176
|
+
draft_version=draft_version,
|
|
172
177
|
)
|
|
173
178
|
|
|
174
179
|
def get_array_api_strict_flags():
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from ._array_object import Array
|
|
4
4
|
from ._dtypes import _integer_dtypes
|
|
5
|
+
from ._flags import requires_api_version
|
|
5
6
|
|
|
6
7
|
from typing import TYPE_CHECKING
|
|
7
8
|
|
|
@@ -25,3 +26,14 @@ def take(x: Array, indices: Array, /, *, axis: Optional[int] = None) -> Array:
|
|
|
25
26
|
if x.device != indices.device:
|
|
26
27
|
raise ValueError(f"Arrays from two different devices ({x.device} and {indices.device}) can not be combined.")
|
|
27
28
|
return Array._new(np.take(x._array, indices._array, axis=axis), device=x.device)
|
|
29
|
+
|
|
30
|
+
@requires_api_version('2024.12')
|
|
31
|
+
def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1) -> Array:
|
|
32
|
+
"""
|
|
33
|
+
Array API compatible wrapper for :py:func:`np.take_along_axis <numpy.take_along_axis>`.
|
|
34
|
+
|
|
35
|
+
See its docstring for more information.
|
|
36
|
+
"""
|
|
37
|
+
if x.device != indices.device:
|
|
38
|
+
raise ValueError(f"Arrays from two different devices ({x.device} and {indices.device}) can not be combined.")
|
|
39
|
+
return Array._new(np.take_along_axis(x._array, indices._array, axis), device=x.device)
|
array_api_strict/_info.py
CHANGED
|
@@ -2,131 +2,138 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
5
7
|
if TYPE_CHECKING:
|
|
6
8
|
from typing import Optional, Union, Tuple, List
|
|
7
|
-
from ._typing import device, DefaultDataTypes, DataTypes, Capabilities
|
|
9
|
+
from ._typing import device, DefaultDataTypes, DataTypes, Capabilities
|
|
8
10
|
|
|
9
11
|
from ._array_object import ALL_DEVICES, CPU_DEVICE
|
|
10
12
|
from ._flags import get_array_api_strict_flags, requires_api_version
|
|
11
13
|
from ._dtypes import bool, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128
|
|
12
14
|
|
|
13
15
|
@requires_api_version('2023.12')
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
class __array_namespace_info__:
|
|
17
|
+
@requires_api_version('2023.12')
|
|
18
|
+
def capabilities(self) -> Capabilities:
|
|
19
|
+
flags = get_array_api_strict_flags()
|
|
20
|
+
res = {"boolean indexing": flags['boolean_indexing'],
|
|
21
|
+
"data-dependent shapes": flags['data_dependent_shapes'],
|
|
22
|
+
}
|
|
23
|
+
if flags['api_version'] >= '2024.12':
|
|
24
|
+
# maxdims is 32 for NumPy 1.x and 64 for NumPy 2.0. Eventually we will
|
|
25
|
+
# drop support for NumPy 1 but for now, just compute the number
|
|
26
|
+
# directly
|
|
27
|
+
for i in range(1, 100):
|
|
28
|
+
try:
|
|
29
|
+
np.zeros((1,)*i)
|
|
30
|
+
except ValueError:
|
|
31
|
+
maxdims = i - 1
|
|
32
|
+
break
|
|
33
|
+
else:
|
|
34
|
+
raise RuntimeError("Could not get max dimensions (this is a bug in array-api-strict)")
|
|
35
|
+
res['max dimensions'] = maxdims
|
|
36
|
+
return res
|
|
28
37
|
|
|
29
|
-
@requires_api_version('2023.12')
|
|
30
|
-
def
|
|
31
|
-
|
|
32
|
-
device: Optional[device] = None,
|
|
33
|
-
) -> DefaultDataTypes:
|
|
34
|
-
return {
|
|
35
|
-
"real floating": float64,
|
|
36
|
-
"complex floating": complex128,
|
|
37
|
-
"integral": int64,
|
|
38
|
-
"indexing": int64,
|
|
39
|
-
}
|
|
38
|
+
@requires_api_version('2023.12')
|
|
39
|
+
def default_device(self) -> device:
|
|
40
|
+
return CPU_DEVICE
|
|
40
41
|
|
|
41
|
-
@requires_api_version('2023.12')
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
) ->
|
|
47
|
-
if kind is None:
|
|
48
|
-
return {
|
|
49
|
-
"bool": bool,
|
|
50
|
-
"int8": int8,
|
|
51
|
-
"int16": int16,
|
|
52
|
-
"int32": int32,
|
|
53
|
-
"int64": int64,
|
|
54
|
-
"uint8": uint8,
|
|
55
|
-
"uint16": uint16,
|
|
56
|
-
"uint32": uint32,
|
|
57
|
-
"uint64": uint64,
|
|
58
|
-
"float32": float32,
|
|
59
|
-
"float64": float64,
|
|
60
|
-
"complex64": complex64,
|
|
61
|
-
"complex128": complex128,
|
|
62
|
-
}
|
|
63
|
-
if kind == "bool":
|
|
64
|
-
return {"bool": bool}
|
|
65
|
-
if kind == "signed integer":
|
|
66
|
-
return {
|
|
67
|
-
"int8": int8,
|
|
68
|
-
"int16": int16,
|
|
69
|
-
"int32": int32,
|
|
70
|
-
"int64": int64,
|
|
71
|
-
}
|
|
72
|
-
if kind == "unsigned integer":
|
|
73
|
-
return {
|
|
74
|
-
"uint8": uint8,
|
|
75
|
-
"uint16": uint16,
|
|
76
|
-
"uint32": uint32,
|
|
77
|
-
"uint64": uint64,
|
|
78
|
-
}
|
|
79
|
-
if kind == "integral":
|
|
42
|
+
@requires_api_version('2023.12')
|
|
43
|
+
def default_dtypes(
|
|
44
|
+
self,
|
|
45
|
+
*,
|
|
46
|
+
device: Optional[device] = None,
|
|
47
|
+
) -> DefaultDataTypes:
|
|
80
48
|
return {
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"uint8": uint8,
|
|
86
|
-
"uint16": uint16,
|
|
87
|
-
"uint32": uint32,
|
|
88
|
-
"uint64": uint64,
|
|
49
|
+
"real floating": float64,
|
|
50
|
+
"complex floating": complex128,
|
|
51
|
+
"integral": int64,
|
|
52
|
+
"indexing": int64,
|
|
89
53
|
}
|
|
90
|
-
if kind == "real floating":
|
|
91
|
-
return {
|
|
92
|
-
"float32": float32,
|
|
93
|
-
"float64": float64,
|
|
94
|
-
}
|
|
95
|
-
if kind == "complex floating":
|
|
96
|
-
return {
|
|
97
|
-
"complex64": complex64,
|
|
98
|
-
"complex128": complex128,
|
|
99
|
-
}
|
|
100
|
-
if kind == "numeric":
|
|
101
|
-
return {
|
|
102
|
-
"int8": int8,
|
|
103
|
-
"int16": int16,
|
|
104
|
-
"int32": int32,
|
|
105
|
-
"int64": int64,
|
|
106
|
-
"uint8": uint8,
|
|
107
|
-
"uint16": uint16,
|
|
108
|
-
"uint32": uint32,
|
|
109
|
-
"uint64": uint64,
|
|
110
|
-
"float32": float32,
|
|
111
|
-
"float64": float64,
|
|
112
|
-
"complex64": complex64,
|
|
113
|
-
"complex128": complex128,
|
|
114
|
-
}
|
|
115
|
-
if isinstance(kind, tuple):
|
|
116
|
-
res = {}
|
|
117
|
-
for k in kind:
|
|
118
|
-
res.update(dtypes(kind=k))
|
|
119
|
-
return res
|
|
120
|
-
raise ValueError(f"unsupported kind: {kind!r}")
|
|
121
54
|
|
|
122
|
-
@requires_api_version('2023.12')
|
|
123
|
-
def
|
|
124
|
-
|
|
55
|
+
@requires_api_version('2023.12')
|
|
56
|
+
def dtypes(
|
|
57
|
+
self,
|
|
58
|
+
*,
|
|
59
|
+
device: Optional[device] = None,
|
|
60
|
+
kind: Optional[Union[str, Tuple[str, ...]]] = None,
|
|
61
|
+
) -> DataTypes:
|
|
62
|
+
if kind is None:
|
|
63
|
+
return {
|
|
64
|
+
"bool": bool,
|
|
65
|
+
"int8": int8,
|
|
66
|
+
"int16": int16,
|
|
67
|
+
"int32": int32,
|
|
68
|
+
"int64": int64,
|
|
69
|
+
"uint8": uint8,
|
|
70
|
+
"uint16": uint16,
|
|
71
|
+
"uint32": uint32,
|
|
72
|
+
"uint64": uint64,
|
|
73
|
+
"float32": float32,
|
|
74
|
+
"float64": float64,
|
|
75
|
+
"complex64": complex64,
|
|
76
|
+
"complex128": complex128,
|
|
77
|
+
}
|
|
78
|
+
if kind == "bool":
|
|
79
|
+
return {"bool": bool}
|
|
80
|
+
if kind == "signed integer":
|
|
81
|
+
return {
|
|
82
|
+
"int8": int8,
|
|
83
|
+
"int16": int16,
|
|
84
|
+
"int32": int32,
|
|
85
|
+
"int64": int64,
|
|
86
|
+
}
|
|
87
|
+
if kind == "unsigned integer":
|
|
88
|
+
return {
|
|
89
|
+
"uint8": uint8,
|
|
90
|
+
"uint16": uint16,
|
|
91
|
+
"uint32": uint32,
|
|
92
|
+
"uint64": uint64,
|
|
93
|
+
}
|
|
94
|
+
if kind == "integral":
|
|
95
|
+
return {
|
|
96
|
+
"int8": int8,
|
|
97
|
+
"int16": int16,
|
|
98
|
+
"int32": int32,
|
|
99
|
+
"int64": int64,
|
|
100
|
+
"uint8": uint8,
|
|
101
|
+
"uint16": uint16,
|
|
102
|
+
"uint32": uint32,
|
|
103
|
+
"uint64": uint64,
|
|
104
|
+
}
|
|
105
|
+
if kind == "real floating":
|
|
106
|
+
return {
|
|
107
|
+
"float32": float32,
|
|
108
|
+
"float64": float64,
|
|
109
|
+
}
|
|
110
|
+
if kind == "complex floating":
|
|
111
|
+
return {
|
|
112
|
+
"complex64": complex64,
|
|
113
|
+
"complex128": complex128,
|
|
114
|
+
}
|
|
115
|
+
if kind == "numeric":
|
|
116
|
+
return {
|
|
117
|
+
"int8": int8,
|
|
118
|
+
"int16": int16,
|
|
119
|
+
"int32": int32,
|
|
120
|
+
"int64": int64,
|
|
121
|
+
"uint8": uint8,
|
|
122
|
+
"uint16": uint16,
|
|
123
|
+
"uint32": uint32,
|
|
124
|
+
"uint64": uint64,
|
|
125
|
+
"float32": float32,
|
|
126
|
+
"float64": float64,
|
|
127
|
+
"complex64": complex64,
|
|
128
|
+
"complex128": complex128,
|
|
129
|
+
}
|
|
130
|
+
if isinstance(kind, tuple):
|
|
131
|
+
res = {}
|
|
132
|
+
for k in kind:
|
|
133
|
+
res.update(self.dtypes(kind=k))
|
|
134
|
+
return res
|
|
135
|
+
raise ValueError(f"unsupported kind: {kind!r}")
|
|
125
136
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"default_dtypes",
|
|
130
|
-
"devices",
|
|
131
|
-
"dtypes",
|
|
132
|
-
]
|
|
137
|
+
@requires_api_version('2023.12')
|
|
138
|
+
def devices(self) -> List[device]:
|
|
139
|
+
return list(ALL_DEVICES)
|
array_api_strict/_typing.py
CHANGED
|
@@ -21,7 +21,6 @@ import sys
|
|
|
21
21
|
|
|
22
22
|
from typing import (
|
|
23
23
|
Any,
|
|
24
|
-
ModuleType,
|
|
25
24
|
TypedDict,
|
|
26
25
|
TypeVar,
|
|
27
26
|
Protocol,
|
|
@@ -29,6 +28,7 @@ from typing import (
|
|
|
29
28
|
|
|
30
29
|
from ._array_object import Array, _device
|
|
31
30
|
from ._dtypes import _DType
|
|
31
|
+
from ._info import __array_namespace_info__
|
|
32
32
|
|
|
33
33
|
_T_co = TypeVar("_T_co", covariant=True)
|
|
34
34
|
|
|
@@ -41,7 +41,7 @@ Device = _device
|
|
|
41
41
|
|
|
42
42
|
Dtype = _DType
|
|
43
43
|
|
|
44
|
-
Info =
|
|
44
|
+
Info = __array_namespace_info__
|
|
45
45
|
|
|
46
46
|
if sys.version_info >= (3, 12):
|
|
47
47
|
from collections.abc import Buffer as SupportsBufferProtocol
|
|
@@ -54,7 +54,8 @@ class SupportsDLPack(Protocol):
|
|
|
54
54
|
def __dlpack__(self, /, *, stream: None = ...) -> PyCapsule: ...
|
|
55
55
|
|
|
56
56
|
Capabilities = TypedDict(
|
|
57
|
-
"Capabilities", {"boolean indexing": bool, "data-dependent shapes": bool
|
|
57
|
+
"Capabilities", {"boolean indexing": bool, "data-dependent shapes": bool,
|
|
58
|
+
"max dimensions": int}
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
DefaultDataTypes = TypedDict(
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from ._array_object import Array
|
|
4
|
+
from ._flags import requires_api_version
|
|
5
|
+
from ._dtypes import _numeric_dtypes
|
|
4
6
|
|
|
5
7
|
from typing import TYPE_CHECKING
|
|
6
8
|
if TYPE_CHECKING:
|
|
@@ -37,3 +39,31 @@ def any(
|
|
|
37
39
|
See its docstring for more information.
|
|
38
40
|
"""
|
|
39
41
|
return Array._new(np.asarray(np.any(x._array, axis=axis, keepdims=keepdims)), device=x.device)
|
|
42
|
+
|
|
43
|
+
@requires_api_version('2024.12')
|
|
44
|
+
def diff(
|
|
45
|
+
x: Array,
|
|
46
|
+
/,
|
|
47
|
+
*,
|
|
48
|
+
axis: int = -1,
|
|
49
|
+
n: int = 1,
|
|
50
|
+
prepend: Optional[Array] = None,
|
|
51
|
+
append: Optional[Array] = None,
|
|
52
|
+
) -> Array:
|
|
53
|
+
if x.dtype not in _numeric_dtypes:
|
|
54
|
+
raise TypeError("Only numeric dtypes are allowed in diff")
|
|
55
|
+
|
|
56
|
+
# TODO: The type promotion behavior for prepend and append is not
|
|
57
|
+
# currently specified.
|
|
58
|
+
|
|
59
|
+
# NumPy does not support prepend=None or append=None
|
|
60
|
+
kwargs = dict(axis=axis, n=n)
|
|
61
|
+
if prepend is not None:
|
|
62
|
+
if prepend.device != x.device:
|
|
63
|
+
raise ValueError(f"Arrays from two different devices ({prepend.device} and {x.device}) can not be combined.")
|
|
64
|
+
kwargs['prepend'] = prepend._array
|
|
65
|
+
if append is not None:
|
|
66
|
+
if append.device != x.device:
|
|
67
|
+
raise ValueError(f"Arrays from two different devices ({append.device} and {x.device}) can not be combined.")
|
|
68
|
+
kwargs['append'] = append._array
|
|
69
|
+
return Array._new(np.diff(x._array, **kwargs), device=x.device)
|
array_api_strict/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-11-
|
|
11
|
+
"date": "2024-11-11T15:30:59-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.
|
|
14
|
+
"full-revisionid": "fe4f34ad30ba59c1c981037dd181f6b4daf23b22",
|
|
15
|
+
"version": "2.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -453,8 +453,12 @@ def test_array_namespace():
|
|
|
453
453
|
assert a.__array_namespace__(api_version="2021.12") is array_api_strict
|
|
454
454
|
assert array_api_strict.__array_api_version__ == "2021.12"
|
|
455
455
|
|
|
456
|
+
with pytest.warns(UserWarning):
|
|
457
|
+
assert a.__array_namespace__(api_version="2024.12") is array_api_strict
|
|
458
|
+
assert array_api_strict.__array_api_version__ == "2024.12"
|
|
459
|
+
|
|
456
460
|
pytest.raises(ValueError, lambda: a.__array_namespace__(api_version="2021.11"))
|
|
457
|
-
pytest.raises(ValueError, lambda: a.__array_namespace__(api_version="
|
|
461
|
+
pytest.raises(ValueError, lambda: a.__array_namespace__(api_version="2025.12"))
|
|
458
462
|
|
|
459
463
|
def test_iter():
|
|
460
464
|
pytest.raises(TypeError, lambda: iter(asarray(3)))
|
|
@@ -2,6 +2,8 @@ from inspect import signature, getmodule
|
|
|
2
2
|
|
|
3
3
|
from numpy.testing import assert_raises
|
|
4
4
|
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
5
7
|
from .. import asarray, _elementwise_functions
|
|
6
8
|
from .._elementwise_functions import bitwise_left_shift, bitwise_right_shift
|
|
7
9
|
from .._dtypes import (
|
|
@@ -79,10 +81,12 @@ elementwise_function_input_types = {
|
|
|
79
81
|
"minimum": "real numeric",
|
|
80
82
|
"multiply": "numeric",
|
|
81
83
|
"negative": "numeric",
|
|
84
|
+
"nextafter": "real floating-point",
|
|
82
85
|
"not_equal": "all",
|
|
83
86
|
"positive": "numeric",
|
|
84
87
|
"pow": "numeric",
|
|
85
88
|
"real": "complex floating-point",
|
|
89
|
+
"reciprocal": "floating-point",
|
|
86
90
|
"remainder": "real numeric",
|
|
87
91
|
"round": "numeric",
|
|
88
92
|
"sign": "numeric",
|
|
@@ -126,7 +130,8 @@ def test_function_device_persists():
|
|
|
126
130
|
yield asarray(1., dtype=d)
|
|
127
131
|
|
|
128
132
|
# Use the latest version of the standard so all functions are included
|
|
129
|
-
|
|
133
|
+
with pytest.warns(UserWarning):
|
|
134
|
+
set_array_api_strict_flags(api_version="2024.12")
|
|
130
135
|
|
|
131
136
|
for func_name, types in elementwise_function_input_types.items():
|
|
132
137
|
dtypes = _dtype_categories[types]
|
|
@@ -162,7 +167,8 @@ def test_function_types():
|
|
|
162
167
|
yield asarray(1.0, dtype=d)
|
|
163
168
|
|
|
164
169
|
# Use the latest version of the standard so all functions are included
|
|
165
|
-
|
|
170
|
+
with pytest.warns(UserWarning):
|
|
171
|
+
set_array_api_strict_flags(api_version="2024.12")
|
|
166
172
|
|
|
167
173
|
for x in _array_vals():
|
|
168
174
|
for func_name, types in elementwise_function_input_types.items():
|
|
@@ -3,8 +3,6 @@ import subprocess
|
|
|
3
3
|
|
|
4
4
|
from .._flags import (set_array_api_strict_flags, get_array_api_strict_flags,
|
|
5
5
|
reset_array_api_strict_flags)
|
|
6
|
-
from .._info import (capabilities, default_device, default_dtypes, devices,
|
|
7
|
-
dtypes)
|
|
8
6
|
from .._fft import (fft, ifft, fftn, ifftn, rfft, irfft, rfftn, irfftn, hfft,
|
|
9
7
|
ihfft, fftfreq, rfftfreq, fftshift, ifftshift)
|
|
10
8
|
from .._linalg import (cholesky, cross, det, diagonal, eigh, eigvalsh, inv,
|
|
@@ -99,6 +97,21 @@ def test_flags_api_version_2023_12():
|
|
|
99
97
|
'enabled_extensions': ('linalg', 'fft'),
|
|
100
98
|
}
|
|
101
99
|
|
|
100
|
+
def test_flags_api_version_2024_12():
|
|
101
|
+
# Make sure setting the version to 2024.12 issues a warning.
|
|
102
|
+
with pytest.warns(UserWarning) as record:
|
|
103
|
+
set_array_api_strict_flags(api_version='2024.12')
|
|
104
|
+
assert len(record) == 1
|
|
105
|
+
assert '2024.12' in str(record[0].message)
|
|
106
|
+
assert 'draft' in str(record[0].message)
|
|
107
|
+
flags = get_array_api_strict_flags()
|
|
108
|
+
assert flags == {
|
|
109
|
+
'api_version': '2024.12',
|
|
110
|
+
'boolean_indexing': True,
|
|
111
|
+
'data_dependent_shapes': True,
|
|
112
|
+
'enabled_extensions': ('linalg', 'fft'),
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
def test_setting_flags_invalid():
|
|
103
116
|
# Test setting flags with invalid values
|
|
104
117
|
pytest.raises(ValueError, lambda:
|
|
@@ -245,14 +258,17 @@ def test_fft(func_name):
|
|
|
245
258
|
set_array_api_strict_flags(enabled_extensions=('fft',))
|
|
246
259
|
func()
|
|
247
260
|
|
|
261
|
+
# Test functionality even if the info object is already created
|
|
262
|
+
_info = xp.__array_namespace_info__()
|
|
263
|
+
|
|
248
264
|
api_version_2023_12_examples = {
|
|
249
265
|
'__array_namespace_info__': lambda: xp.__array_namespace_info__(),
|
|
250
266
|
# Test these functions directly to ensure they are properly decorated
|
|
251
|
-
'capabilities': capabilities,
|
|
252
|
-
'default_device': default_device,
|
|
253
|
-
'default_dtypes': default_dtypes,
|
|
254
|
-
'devices': devices,
|
|
255
|
-
'dtypes': dtypes,
|
|
267
|
+
'capabilities': _info.capabilities,
|
|
268
|
+
'default_device': _info.default_device,
|
|
269
|
+
'default_dtypes': _info.default_dtypes,
|
|
270
|
+
'devices': _info.devices,
|
|
271
|
+
'dtypes': _info.dtypes,
|
|
256
272
|
'clip': lambda: xp.clip(xp.asarray([1, 2, 3]), 1, 2),
|
|
257
273
|
'copysign': lambda: xp.copysign(xp.asarray([1., 2., 3.]), xp.asarray([-1., -1., -1.])),
|
|
258
274
|
'cumulative_sum': lambda: xp.cumulative_sum(xp.asarray([1, 2, 3])),
|
|
@@ -285,6 +301,36 @@ def test_api_version_2023_12(func_name):
|
|
|
285
301
|
set_array_api_strict_flags(api_version='2022.12')
|
|
286
302
|
pytest.raises(RuntimeError, func)
|
|
287
303
|
|
|
304
|
+
api_version_2024_12_examples = {
|
|
305
|
+
'diff': lambda: xp.diff(xp.asarray([0, 1, 2])),
|
|
306
|
+
'nextafter': lambda: xp.nextafter(xp.asarray(0.), xp.asarray(1.)),
|
|
307
|
+
'reciprocal': lambda: xp.reciprocal(xp.asarray([2.])),
|
|
308
|
+
'take_along_axis': lambda: xp.take_along_axis(xp.zeros((2, 3)),
|
|
309
|
+
xp.zeros((1, 4), dtype=xp.int64)),
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@pytest.mark.parametrize('func_name', api_version_2024_12_examples.keys())
|
|
313
|
+
def test_api_version_2024_12(func_name):
|
|
314
|
+
func = api_version_2024_12_examples[func_name]
|
|
315
|
+
|
|
316
|
+
# By default, these functions should error
|
|
317
|
+
pytest.raises(RuntimeError, func)
|
|
318
|
+
|
|
319
|
+
# In 2022.12 and 2023.12, these functions should error
|
|
320
|
+
set_array_api_strict_flags(api_version='2022.12')
|
|
321
|
+
pytest.raises(RuntimeError, func)
|
|
322
|
+
set_array_api_strict_flags(api_version='2023.12')
|
|
323
|
+
pytest.raises(RuntimeError, func)
|
|
324
|
+
|
|
325
|
+
# They should not error in 2024.12
|
|
326
|
+
with pytest.warns(UserWarning):
|
|
327
|
+
set_array_api_strict_flags(api_version='2024.12')
|
|
328
|
+
func()
|
|
329
|
+
|
|
330
|
+
# Test the behavior gets updated properly
|
|
331
|
+
set_array_api_strict_flags(api_version='2023.12')
|
|
332
|
+
pytest.raises(RuntimeError, func)
|
|
333
|
+
|
|
288
334
|
def test_disabled_extensions():
|
|
289
335
|
# Test that xp.extension errors when an extension is disabled, and that
|
|
290
336
|
# xp.__all__ is updated properly.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
array_api_strict/__init__.py,sha256=
|
|
1
|
+
array_api_strict/__init__.py,sha256=Nm_8GFfA0bpkVMw3urULYSadngGPaW6C2VuEpM-ziyI,6904
|
|
2
2
|
array_api_strict/_array_object.py,sha256=Q69HJ8qdQqqugWIRf4RsifZUEypbhNV_y5EVSygmbrQ,52571
|
|
3
3
|
array_api_strict/_constants.py,sha256=AYayN2jf1Dp5rXZ7WPBdUhtPBo_JMCi-pD9oW5zmFkI,87
|
|
4
4
|
array_api_strict/_creation_functions.py,sha256=A9TTvPSznF9NsxT0Pd_G9yU6IZAfW1tpBkFMYoJyguw,12985
|
|
5
5
|
array_api_strict/_data_type_functions.py,sha256=sKxKRQiwoXPwQJPbiN5BhF9rbc3ZtXfjRuglB7VsIgo,7016
|
|
6
6
|
array_api_strict/_dtypes.py,sha256=QDGo9rqiS_o3quv7QRFM0j6DkvOjRauQ1Ymikwlu8Ns,6213
|
|
7
|
-
array_api_strict/_elementwise_functions.py,sha256=
|
|
7
|
+
array_api_strict/_elementwise_functions.py,sha256=epo92ppRP4XDcDhS431J599NA1pT4DK08wIdV9vVO8s,39713
|
|
8
8
|
array_api_strict/_fft.py,sha256=xH1o4j_amq3e1yGVChV6vms7oAfCzpzB18I-IzjNSXw,9702
|
|
9
|
-
array_api_strict/_flags.py,sha256=
|
|
10
|
-
array_api_strict/_indexing_functions.py,sha256=
|
|
11
|
-
array_api_strict/_info.py,sha256=
|
|
9
|
+
array_api_strict/_flags.py,sha256=lUb-SowhHvA9MLBm0ICO5L7M7FgclWPF8v8z5N--Q_o,13558
|
|
10
|
+
array_api_strict/_indexing_functions.py,sha256=3AqC8Mgi9BakrStlZoIV34d0Au5dMk6qT07TxpvvCGk,1520
|
|
11
|
+
array_api_strict/_info.py,sha256=QvW1PV7dO2oGPWAerG3wJn61QAqjqxx4iHkWPUturI4,4455
|
|
12
12
|
array_api_strict/_linalg.py,sha256=sfmd5fuq2nHy_9kD2QQ23_JbbVZo7LHFgb10qjrr7nw,19846
|
|
13
13
|
array_api_strict/_linear_algebra_functions.py,sha256=12XPBU27X3WZdaq9Ob2eUmL_PxMzDNF76pY4iESlPyo,3872
|
|
14
14
|
array_api_strict/_manipulation_functions.py,sha256=Pa1gVRlaSC39-Zd6n4Q8c9P0anZYdyCh95Wyx3az3lc,6681
|
|
@@ -16,17 +16,17 @@ array_api_strict/_searching_functions.py,sha256=32IiLLpa91N-jtzaxj4Nw9nQgF2ROkcN
|
|
|
16
16
|
array_api_strict/_set_functions.py,sha256=PZVsxkRQi5Zi104dI2fHZBFqpluOAW0IJzzdJSyajiI,3295
|
|
17
17
|
array_api_strict/_sorting_functions.py,sha256=GG7g2NYCFn2G2fFS6ZdfYOWpuuSIrdZdJWEuL72_-LI,2065
|
|
18
18
|
array_api_strict/_statistical_functions.py,sha256=dMJ-x8TQW5MD2rFYCmRH6QthA2KDKXjhkj4hcbd3LSU,5148
|
|
19
|
-
array_api_strict/_typing.py,sha256=
|
|
20
|
-
array_api_strict/_utility_functions.py,sha256=
|
|
21
|
-
array_api_strict/_version.py,sha256=
|
|
19
|
+
array_api_strict/_typing.py,sha256=oaHM01VhgC5JIHxXMouEEajNs0OXtwOasnIznK7z9fk,1889
|
|
20
|
+
array_api_strict/_utility_functions.py,sha256=Mu07FogReaAFToPMHE_j90YBEDEvxD5jPcMK3zeUiG0,2007
|
|
21
|
+
array_api_strict/_version.py,sha256=20M94v12DlLnRLp4vkFO-TkQKxHY21bls4ZgOvbf7jE,495
|
|
22
22
|
array_api_strict/tests/__init__.py,sha256=t_2GZ3lKcsu4ec4GMKPUDYaeMUJyDquBlQAcPgj7kFE,282
|
|
23
23
|
array_api_strict/tests/conftest.py,sha256=-wIDryl2MdRLdSonU1G1xWssNq2TFKiWuHquNasXYA8,468
|
|
24
|
-
array_api_strict/tests/test_array_object.py,sha256=
|
|
24
|
+
array_api_strict/tests/test_array_object.py,sha256=IzfVo63eiPoFFwb4woNT15e4gJFfYVyD7zK-wddRMBY,21865
|
|
25
25
|
array_api_strict/tests/test_creation_functions.py,sha256=ve0MeqZPrG2dmCG3hTVhap1YgIW-lAaSZIJ_ZoOV9cQ,8323
|
|
26
26
|
array_api_strict/tests/test_data_type_functions.py,sha256=pLAtm96gpAduNVqq-914JvjAollzhBp4YojVfNScBzs,2138
|
|
27
27
|
array_api_strict/tests/test_device_support.py,sha256=zpfhHxeRREoXfp0qZTlilm2ZceBc71uCKea1GMVe-ZU,855
|
|
28
|
-
array_api_strict/tests/test_elementwise_functions.py,sha256=
|
|
29
|
-
array_api_strict/tests/test_flags.py,sha256=
|
|
28
|
+
array_api_strict/tests/test_elementwise_functions.py,sha256=ManUmYZF3oT-UXH4lqWJna3zDHdxVBeuvIdFlFPABQ4,7114
|
|
29
|
+
array_api_strict/tests/test_flags.py,sha256=YadbyJEu7DmMo3TKl3nROf7R4xDIrQfm8acifHA3CYc,18598
|
|
30
30
|
array_api_strict/tests/test_indexing_functions.py,sha256=C23FnuowVDC1OBuDH06pvsd61qM2dTpTwzw6UgC4BoY,1281
|
|
31
31
|
array_api_strict/tests/test_linalg.py,sha256=CJ4JnCkWyysMUAih3PI-ZZeOH-X39H0p-RKBoEwk6Jw,5675
|
|
32
32
|
array_api_strict/tests/test_manipulation_functions.py,sha256=CzcudVxUKhQ4Ec94Vda4C6HaAqrOQPQfQxT4uTM2fsM,1064
|
|
@@ -34,8 +34,8 @@ array_api_strict/tests/test_set_functions.py,sha256=ikzab1j3SXxGf0OqwHrOAM13HwQe
|
|
|
34
34
|
array_api_strict/tests/test_sorting_functions.py,sha256=1xvQBKts5KTKYc-puMITX9iR_KTbzzVB8fY-SObad_Y,899
|
|
35
35
|
array_api_strict/tests/test_statistical_functions.py,sha256=JwS4DhASt5T0YUNtbFK2nSXgDrVVZx1tVpe7LU2aPK4,1365
|
|
36
36
|
array_api_strict/tests/test_validation.py,sha256=JdsK4z1M0U5YoJrfWSzOpEhmlehvZHF5SG0I0k6oDy8,672
|
|
37
|
-
array_api_strict-2.
|
|
38
|
-
array_api_strict-2.
|
|
39
|
-
array_api_strict-2.
|
|
40
|
-
array_api_strict-2.
|
|
41
|
-
array_api_strict-2.
|
|
37
|
+
array_api_strict-2.2.dist-info/LICENSE,sha256=djDm4UfHAJmycwFUNyUmrTdRkrFF9Ac8uqIlbxH7j5Y,1585
|
|
38
|
+
array_api_strict-2.2.dist-info/METADATA,sha256=uCWtV4ZiiCzUkNRWapj10LpJxUCPHy8fzddfOiFt2cM,1593
|
|
39
|
+
array_api_strict-2.2.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
|
|
40
|
+
array_api_strict-2.2.dist-info/top_level.txt,sha256=M4cE8VLgRHp_d9TPkbk7_I4JriELFdEJz-NKJJqAkAE,17
|
|
41
|
+
array_api_strict-2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|