Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,434 changes: 2,951 additions & 1,483 deletions pixi.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exclude-newer = "7d"

[exclude-newer]
pixi-build-python = "5d" # for compatibility with pixi-build-api-version 7
mparray = "0d"
Comment thread
lucascolley marked this conversation as resolved.

### array-api-extra package definition ###

Expand Down Expand Up @@ -372,6 +373,7 @@ numpy = "=1.24.1"
pytorch = ">=2.12.0"
dask-core = ">=2026.7.1" # No distributed, tornado, etc.
sparse = ">=0.19.2"
mparray = ">=0.2.2"

[feature.backends.target.unix.dependencies]
jax = ">=0.10.2" # waiting for conda-forge/jaxlib-feedstock#326
Expand Down
1 change: 1 addition & 0 deletions src/array_api_extra/_lib/_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Backend(Enum): # numpydoc ignore=PR02
ARRAY_API_STRICTEST = "array_api_strict:strictest"
NUMPY = "numpy"
NUMPY_READONLY = "numpy:readonly"
MPARRAY = "mparray"
CUPY = "cupy"
TORCH = "torch"
TORCH_GPU = "torch:gpu"
Expand Down
6 changes: 6 additions & 0 deletions src/array_api_extra/_lib/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"eager_shape",
"in1d",
"is_jax_jit_enabled",
"is_mparray_namespace",
"is_python_scalar",
"jax_autojit",
"meta_namespace",
Expand Down Expand Up @@ -616,3 +617,8 @@ def is_jax_jit_enabled(xp: ArrayNamespace) -> bool: # numpydoc ignore=PR01,RT01
return bool(x)
except jax.errors.TracerBoolConversionError:
return True


def is_mparray_namespace(xp: ArrayNamespace) -> bool: # numpydoc ignore=PR01,RT01
"""Return True if the argument is the MPArray namespace."""
return xp.__name__ == "mparray"
1 change: 1 addition & 0 deletions src/array_api_extra/_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def nunique(x: Array, /, *, xp: ArrayNamespace | None = None) -> Array:
if (
_compat.is_numpy_namespace(xp)
or _compat.is_cupy_namespace(xp)
or _helpers.is_mparray_namespace(xp)
or (
_compat.is_torch_namespace(xp)
and _helpers.capabilities(xp, x)["data-dependent shapes"]
Expand Down
3 changes: 3 additions & 0 deletions src/array_api_extra/testing/_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,9 @@ def _as_numpy_array( # numpydoc ignore=PR01,RT01
cpu = typing.cast(Device, jax.devices("cpu")[0])
array = _compat.to_device(array, cpu)

if _helpers.is_mparray_namespace(xp):
return np.asarray(array._data, dtype=array.dtype) # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue]

if hasattr(array, "__dlpack__"):
try:
return np.from_dlpack(array)
Expand Down
3 changes: 2 additions & 1 deletion tests/main/test_at.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ def test_incompatible_dtype(
with pytest.warns(FutureWarning, match="cannot safely cast"):
z = at_op(x, idx, op, 1.1, copy=copy)

elif library.like(Backend.DASK):
# MPArray mutation is currently a little too flexible; see mdhaber/mparray#21
elif library.like(Backend.DASK) or (library == Backend.MPARRAY):
z = at_op(x, idx, op, 1.1, copy=copy)
Comment thread
lucascolley marked this conversation as resolved.

elif library.like(Backend.ARRAY_API_STRICT):
Expand Down
1 change: 1 addition & 0 deletions tests/main/test_elementwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ def test_basic(self, xp: ArrayNamespace):
atol=1e-11,
)

@pytest.mark.skip_xp_backend(Backend.MPARRAY, reason="negative zero not supported")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a fundamental limitation of mpmath, it seems. I don't think fixing it is high priority.

def test_real(self, xp: ArrayNamespace):
x = xp.asarray([0.0, -0.0, 1.0, -1.0])
expected = xp.asarray([0.0, xp.pi, 0.0, xp.pi], dtype=x.dtype)
Expand Down
1 change: 1 addition & 0 deletions tests/main/test_lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
Backend.TORCH_GPU, reason="device->host copy"
),
pytest.mark.skip_xp_backend(Backend.SPARSE, reason="densification"),
pytest.mark.skip_xp_backend(Backend.MPARRAY, reason="precision loss"),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how as_numpy=True should work. I think np.asarray(my_mparray) currently wraps my_mparray as the only element of an object array. Instead, it could:

  • Extract the underlying object array, but I don't think that's what this is supposed to do.
  • Converted the underlying object array to a numerical NumPy array, but it risks precision loss.
  • Raise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's open an issue on the mparray side for this one, given that it isn't entirely clear which way to go yet. That would be sufficient to move forward here

],
),
],
Expand Down
1 change: 1 addition & 0 deletions tests/main/test_searching.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def xp_searchsorted(

@pytest.mark.skip_xp_backend(Backend.DASK, reason="no take_along_axis")
@pytest.mark.skip_xp_backend(Backend.SPARSE, reason="no searchsorted")
@pytest.mark.skip_xp_backend(Backend.MPARRAY, reason="see mdhaber/mparray#20")
class TestSearchsorted:
def test_input_validation(self, xp: ArrayNamespace):
message = "`side` must be either 'left' or 'right'."
Expand Down
1 change: 1 addition & 0 deletions tests/main/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ def test_lazy_xp_function_deprecated_static_argnames():


@pytest.mark.skip_xp_backend(Backend.TORCH_GPU, reason="device->host copy")
@pytest.mark.skip_xp_backend(Backend.MPARRAY, reason="mparray lacks __array_ufunc__")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want compiled ufuncs to work on these if they don't preserve the precision; it's probably better to fail. (However, mparray.special will provide a lot of special functions, and scipy.special will be able to delegate to them.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that seems fine to me

@pytest.mark.filterwarnings("ignore:__array_wrap__:DeprecationWarning") # PyTorch
def test_lazy_xp_function_cython_ufuncs(xp: ArrayNamespace, library: Backend):
pytest.importorskip("scipy")
Expand Down