Skip to content

Commit

Permalink
Merge branch 'main' into ci/use-uv
Browse files Browse the repository at this point in the history
  • Loading branch information
jpivarski committed Nov 12, 2024
2 parents 6ff11b0 + 96d3eb0 commit ec905e2
Show file tree
Hide file tree
Showing 10 changed files with 597 additions and 33 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
numpy-version: "latest"
runs-on: ubuntu-latest
- python-version: "3.9"
numpy-version: "1.22.0"
numpy-version: "1.24.0"
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -82,4 +82,4 @@ jobs:
pytest -ra --cov --cov-report=xml --cov-report=term --durations=20
- name: Upload coverage report
uses: codecov/codecov-action@v4.3.0
uses: codecov/codecov-action@v4.5.0
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ classifiers = [
]
dynamic = ["version"]
dependencies = [
"awkward>=2.5.0",
"awkward>=2.6.7",
"numpy>=1.24.0",
]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion src/ragged/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
nonzero,
where,
)
from ._spec_set_functions import (
from ._spec_set_functions import ( # pylint: disable=R0401
unique_all,
unique_counts,
unique_inverse,
Expand Down
20 changes: 20 additions & 0 deletions src/ragged/_helper_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# BSD 3-Clause License; see https://github.com/scikit-hep/ragged/blob/main/LICENSE
from __future__ import annotations

import numpy as np


def regularise_to_float(t: np.dtype, /) -> np.dtype:
# Ensure compatibility with numpy 2.0.0
if np.__version__ >= "2.1":
# Just pass and return the input type if the numpy version is not 2.0.0
return t

if t in [np.int8, np.uint8, np.bool_, bool]:
return np.float16
elif t in [np.int16, np.uint16]:
return np.float32
elif t in [np.int32, np.uint32, np.int64, np.uint64]:
return np.float64
else:
return t
12 changes: 7 additions & 5 deletions src/ragged/_spec_array_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import numpy as np
from awkward.contents import (
Content,
EmptyArray,
ListArray,
ListOffsetArray,
NumpyArray,
Expand Down Expand Up @@ -44,7 +45,8 @@ def _shape_dtype(layout: Content) -> tuple[Shape, Dtype]:
else:
shape = (*shape, None)
node = node.content

if isinstance(node, EmptyArray):
node = node.to_NumpyArray(dtype=np.float64)
if isinstance(node, NumpyArray):
shape = shape + node.data.shape[1:]
return shape, node.data.dtype
Expand Down Expand Up @@ -244,9 +246,9 @@ def __str__(self) -> str:
if len(self._shape) == 0:
return f"{self._impl}"
elif len(self._shape) == 1:
return f"{ak._prettyprint.valuestr(self._impl, 1, 80)}"
return f"{ak.prettyprint.valuestr(self._impl, 1, 80)}"
else:
prep = ak._prettyprint.valuestr(self._impl, 20, 80 - 4)[1:-1].replace(
prep = ak.prettyprint.valuestr(self._impl, 20, 80 - 4)[1:-1].replace(
"\n ", "\n "
)
return f"[\n {prep}\n]"
Expand All @@ -259,9 +261,9 @@ def __repr__(self) -> str:
if len(self._shape) == 0:
return f"ragged.array({self._impl})"
elif len(self._shape) == 1:
return f"ragged.array({ak._prettyprint.valuestr(self._impl, 1, 80 - 14)})"
return f"ragged.array({ak.prettyprint.valuestr(self._impl, 1, 80 - 14)})"
else:
prep = ak._prettyprint.valuestr(self._impl, 20, 80 - 4)[1:-1].replace(
prep = ak.prettyprint.valuestr(self._impl, 20, 80 - 4)[1:-1].replace(
"\n ", "\n "
)
return f"ragged.array([\n {prep}\n])"
Expand Down
5 changes: 3 additions & 2 deletions src/ragged/_spec_elementwise_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import numpy as np

from ._helper_functions import regularise_to_float
from ._spec_array_object import _box, _unbox, array


Expand Down Expand Up @@ -414,7 +415,7 @@ def ceil(x: array, /) -> array:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.ceil.html
"""

return _box(type(x), np.ceil(*_unbox(x)), dtype=x.dtype)
return _box(type(x), np.ceil(*_unbox(x)), dtype=regularise_to_float(x.dtype))


def conj(x: array, /) -> array:
Expand Down Expand Up @@ -586,7 +587,7 @@ def floor(x: array, /) -> array:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.floor.html
"""

return _box(type(x), np.floor(*_unbox(x)), dtype=x.dtype)
return _box(type(x), np.floor(*_unbox(x)), dtype=regularise_to_float(x.dtype))


def floor_divide(x1: array, x2: array, /) -> array:
Expand Down
111 changes: 100 additions & 11 deletions src/ragged/_spec_set_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

from collections import namedtuple

import awkward as ak
import numpy as np

import ragged

from ._spec_array_object import array

unique_all_result = namedtuple( # pylint: disable=C0103
Expand Down Expand Up @@ -47,8 +52,39 @@ def unique_all(x: array, /) -> tuple[array, array, array, array]:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.unique_all.html
"""

x # noqa: B018, pylint: disable=W0104
raise NotImplementedError("TODO 128") # noqa: EM101
if isinstance(x, ragged.array):
if x.ndim == 0:
return unique_all_result(
values=ragged.array(np.unique(x._impl, equal_nan=False)), # pylint: disable=W0212
indices=ragged.array([0]),
inverse_indices=ragged.array([0]),
counts=ragged.array([1]),
)
else:
x_flat = ak.ravel(x._impl) # pylint: disable=W0212
if isinstance(x_flat.layout, ak.contents.EmptyArray): # pylint: disable=E1101
return unique_all_result(
values=ragged.array(np.empty(0, x.dtype)),
indices=ragged.array(np.empty(0, np.int64)),
inverse_indices=ragged.array(np.empty(0, np.int64)),
counts=ragged.array(np.empty(0, np.int64)),
)
values, indices, inverse_indices, counts = np.unique(
x_flat.layout.data, # pylint: disable=E1101
return_index=True,
return_inverse=True,
return_counts=True,
equal_nan=False,
)
return unique_all_result(
values=ragged.array(values),
indices=ragged.array(indices),
inverse_indices=ragged.array(inverse_indices),
counts=ragged.array(counts),
)
else:
msg = f"Expected ragged type but got {type(x)}" # type: ignore[unreachable]
raise TypeError(msg)


unique_counts_result = namedtuple( # pylint: disable=C0103
Expand Down Expand Up @@ -77,9 +113,30 @@ def unique_counts(x: array, /) -> tuple[array, array]:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.unique_counts.html
"""

x # noqa: B018, pylint: disable=W0104
raise NotImplementedError("TODO 129") # noqa: EM101
if isinstance(x, ragged.array):
if x.ndim == 0:
return unique_counts_result(
values=ragged.array(np.unique(x._impl, equal_nan=False)), # pylint: disable=W0212
counts=ragged.array([1]), # pylint: disable=W0212
)
else:
x_flat = ak.ravel(x._impl) # pylint: disable=W0212
if isinstance(x_flat.layout, ak.contents.EmptyArray): # pylint: disable=E1101
return unique_counts_result(
values=ragged.array(np.empty(0, x.dtype)),
counts=ragged.array(np.empty(0, np.int64)),
)
values, counts = np.unique(
x_flat.layout.data, # pylint: disable=E1101
return_counts=True,
equal_nan=False,
)
return unique_counts_result(
values=ragged.array(values), counts=ragged.array(counts)
)
else:
msg = f"Expected ragged type but got {type(x)}" # type: ignore[unreachable]
raise TypeError(msg)


unique_inverse_result = namedtuple( # pylint: disable=C0103
Expand Down Expand Up @@ -108,9 +165,32 @@ def unique_inverse(x: array, /) -> tuple[array, array]:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.unique_inverse.html
"""

x # noqa: B018, pylint: disable=W0104
raise NotImplementedError("TODO 130") # noqa: EM101
if isinstance(x, ragged.array):
if x.ndim == 0:
return unique_inverse_result(
values=ragged.array(np.unique(x._impl, equal_nan=False)), # pylint: disable=W0212
inverse_indices=ragged.array([0]),
)
else:
x_flat = ak.ravel(x._impl) # pylint: disable=W0212
if isinstance(x_flat.layout, ak.contents.EmptyArray): # pylint: disable=E1101
return unique_inverse_result(
values=ragged.array(np.empty(0, x.dtype)),
inverse_indices=ragged.array(np.empty(0, np.int64)),
)
values, inverse_indices = np.unique(
x_flat.layout.data, # pylint: disable=E1101
return_inverse=True,
equal_nan=False,
)

return unique_inverse_result(
values=ragged.array(values),
inverse_indices=ragged.array(inverse_indices),
)
else:
msg = f"Expected ragged type but got {type(x)}" # type: ignore[unreachable]
raise TypeError(msg)


def unique_values(x: array, /) -> array:
Expand All @@ -128,6 +208,15 @@ def unique_values(x: array, /) -> array:
https://data-apis.org/array-api/latest/API_specification/generated/array_api.unique_values.html
"""

x # noqa: B018, pylint: disable=W0104
raise NotImplementedError("TODO 131") # noqa: EM101
if isinstance(x, ragged.array):
if x.ndim == 0:
return ragged.array(np.unique(x._impl, equal_nan=False)) # pylint: disable=W0212

else:
x_flat = ak.ravel(x._impl) # pylint: disable=W0212
if isinstance(x_flat.layout, ak.contents.EmptyArray): # pylint: disable=E1101
return ragged.array(np.empty(0, x.dtype))
return ragged.array(np.unique(x_flat.layout.data, equal_nan=False)) # pylint: disable=E1101
else:
err = f"Expected ragged type but got {type(x)}" # type: ignore[unreachable]
raise TypeError(err)
Loading

0 comments on commit ec905e2

Please sign in to comment.