haliax 1.4.dev290__tar.gz → 1.4.dev292__tar.gz
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.
- {haliax-1.4.dev290 → haliax-1.4.dev292}/PKG-INFO +1 -1
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/indexing.md +5 -3
- haliax-1.4.dev292/src/haliax/__about__.py +1 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/ops.py +14 -2
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_ops.py +16 -6
- haliax-1.4.dev290/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.coveragerc +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.flake8 +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.github/workflows/run_tests.yaml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.gitignore +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/LICENSE +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/README.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/api.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/css/material.css +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/faq.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/fp8.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/hof.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/index.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/matmul.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/nn.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/partitioning.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/rearrange.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/requirements.txt +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/docs/tutorial.md +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/mkdocs.yml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/pyproject.toml +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/__init__.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/axis.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/core.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/hof.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/embedding.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/linear.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/mlp.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/partitioning.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/random.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/types.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/util.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/core_test.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_attention.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_axis.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_conv.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_debug.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_dot.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_fp8.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_hof.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_nn.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_partitioning.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_pool.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_random.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_scan.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev290 → haliax-1.4.dev292}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: haliax
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.dev292
|
|
4
4
|
Summary: Named Tensors for Legible Deep Learning in JAX
|
|
5
5
|
Project-URL: Homepage, https://github.com/stanford-crfm/haliax
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/stanford-crfm/haliax/issues/
|
|
@@ -153,9 +153,11 @@ It's not a huge improvement, but it's a bit more convenient.
|
|
|
153
153
|
## Advanced Indexing
|
|
154
154
|
|
|
155
155
|
NumPy's [Advanced Indexing](https://numpy.org/doc/stable/user/basics.indexing.html#advanced-indexing) is supported, though we use named arrays for the indices instead of normal arrays.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
(Though, as noted above, you can use 1-D JAX arrays of integers as well.)
|
|
157
|
+
In NumPy, the indexed arrays must be broadcastable to the same shape. Advanced indexing in Haliax is similar,
|
|
158
|
+
except that it follows Haliax's broadcasting rules, meaning that shared names are broadcasted together,
|
|
159
|
+
while non-shared names are treated as separate axes and are cross-producted.
|
|
160
|
+
In particular, axes with the same name must have the same size.
|
|
159
161
|
|
|
160
162
|
```python
|
|
161
163
|
import haliax as hax
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.dev292"
|
|
@@ -5,7 +5,7 @@ import jax
|
|
|
5
5
|
import jax.numpy as jnp
|
|
6
6
|
|
|
7
7
|
from .axis import Axis, AxisSelector
|
|
8
|
-
from .core import NamedArray, NamedOrNumeric, broadcast_arrays, broadcast_arrays_and_return_axes
|
|
8
|
+
from .core import NamedArray, NamedOrNumeric, broadcast_arrays, broadcast_arrays_and_return_axes, named
|
|
9
9
|
from .jax_utils import is_scalarish
|
|
10
10
|
|
|
11
11
|
|
|
@@ -70,9 +70,21 @@ def where(
|
|
|
70
70
|
for idx in jnp.where(condition.array, size=new_axis.size, fill_value=fill_value)
|
|
71
71
|
)
|
|
72
72
|
|
|
73
|
+
# if x or y is a NamedArray, the other must be as well. wrap as needed for scalars
|
|
74
|
+
|
|
73
75
|
if is_scalarish(condition):
|
|
74
|
-
if x is None:
|
|
76
|
+
if x is None or y is None:
|
|
75
77
|
raise ValueError("Must specify x and y when condition is a scalar")
|
|
78
|
+
|
|
79
|
+
if isinstance(x, NamedArray) and not isinstance(y, NamedArray):
|
|
80
|
+
if not is_scalarish(y):
|
|
81
|
+
raise ValueError("y must be a NamedArray or scalar if x is a NamedArray")
|
|
82
|
+
y = named(y, ())
|
|
83
|
+
elif isinstance(y, NamedArray) and not isinstance(x, NamedArray):
|
|
84
|
+
if not is_scalarish(x):
|
|
85
|
+
raise ValueError("x must be a NamedArray or scalar if y is a NamedArray")
|
|
86
|
+
x = named(x, ())
|
|
87
|
+
x, y = broadcast_arrays(x, y)
|
|
76
88
|
return jax.lax.cond(condition, lambda _: x, lambda _: y, None)
|
|
77
89
|
|
|
78
90
|
condition, x, y = broadcast_arrays(condition, x, y) # type: ignore
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
1
3
|
import jax.numpy as jnp
|
|
2
4
|
import pytest
|
|
3
5
|
from jax.random import PRNGKey
|
|
@@ -105,19 +107,27 @@ def test_add_no_overlap():
|
|
|
105
107
|
# TODO: tests for other ops:
|
|
106
108
|
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
@pytest.mark.parametrize("use_jit", [False, True])
|
|
111
|
+
def test_where(use_jit):
|
|
109
112
|
Height = Axis("Height", 10)
|
|
110
113
|
Width = Axis("Width", 3)
|
|
111
114
|
Depth = Axis("Depth", 4)
|
|
112
115
|
|
|
116
|
+
hax_where: Callable = hax.where
|
|
117
|
+
if use_jit:
|
|
118
|
+
hax_where = hax.named_jit(hax_where)
|
|
119
|
+
|
|
113
120
|
named1 = hax.random.uniform(PRNGKey(0), (Height, Width, Depth))
|
|
114
121
|
named2 = hax.random.uniform(PRNGKey(1), (Height, Width, Depth))
|
|
115
122
|
|
|
116
|
-
|
|
123
|
+
hax_where(0.0, named1, 0.0)
|
|
124
|
+
|
|
125
|
+
named3 = hax_where(named1 > named2, named1, named2)
|
|
126
|
+
|
|
117
127
|
assert jnp.all(jnp.isclose(named3.array, jnp.where(named1.array > named2.array, named1.array, named2.array)))
|
|
118
128
|
|
|
119
129
|
named2_reorder = named2.rearrange((Width, Height, Depth))
|
|
120
|
-
named4 =
|
|
130
|
+
named4 = hax_where(named1 > named2_reorder, named1, named2_reorder)
|
|
121
131
|
named4 = named4.rearrange((Height, Width, Depth))
|
|
122
132
|
assert jnp.all(jnp.isclose(named4.array, jnp.where(named1.array > named2.array, named1.array, named2.array)))
|
|
123
133
|
|
|
@@ -125,7 +135,7 @@ def test_where():
|
|
|
125
135
|
named5 = hax.random.uniform(PRNGKey(1), (Height, Width))
|
|
126
136
|
named6 = hax.random.uniform(PRNGKey(2), Width)
|
|
127
137
|
|
|
128
|
-
named7 =
|
|
138
|
+
named7 = hax_where(named5 > named6, named5, named6)
|
|
129
139
|
named7 = named7.rearrange((Height, Width))
|
|
130
140
|
assert jnp.all(jnp.isclose(named7.array, jnp.where(named5.array > named6.array, named5.array, named6.array)))
|
|
131
141
|
|
|
@@ -134,12 +144,12 @@ def test_where():
|
|
|
134
144
|
named6 = hax.random.uniform(PRNGKey(2), (Width, Depth))
|
|
135
145
|
|
|
136
146
|
with pytest.raises(ValueError):
|
|
137
|
-
_ =
|
|
147
|
+
_ = hax_where(named5 > named6, named5, named6)
|
|
138
148
|
|
|
139
149
|
# now single argument mode
|
|
140
150
|
Volume = hax.Axis("Volume", Height.size * Width.size * Depth.size)
|
|
141
151
|
named7 = hax.random.uniform(PRNGKey(0), (Height, Width, Depth))
|
|
142
|
-
named8, named9, named10 =
|
|
152
|
+
named8, named9, named10 = hax_where(named7 > 0.5, fill_value=-1, new_axis=Volume)
|
|
143
153
|
assert jnp.all((named7[{"Height": named8, "Width": named9, "Depth": named10}] > 0.5).array)
|
|
144
154
|
|
|
145
155
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev290"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|