haliax 1.4.dev353__tar.gz → 1.4.dev355__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.dev353 → haliax-1.4.dev355}/PKG-INFO +1 -1
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/indexing.md +39 -0
- haliax-1.4.dev355/src/haliax/__about__.py +1 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/hof.py +15 -4
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_hof.py +19 -0
- haliax-1.4.dev353/src/haliax/__about__.py +0 -1
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.coveragerc +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.flake8 +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.github/workflows/publish_dev.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.github/workflows/run_pre_commit.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.github/workflows/run_tests.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.gitignore +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.pre-commit-config.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/.readthedocs.yaml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/CONTRIBUTING.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/LICENSE +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/README.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/api.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/broadcasting.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/cheatsheet.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/css/material.css +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/css/mkdocstrings.css +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/faq.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/data_parallel_mesh.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/data_parallel_mesh_replicated.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_1d.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_1d_zero.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/figures/device_mesh_2d_zero.png +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/fp8.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/index.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/matmul.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/nn.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/partitioning.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/rearrange.ipynb +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/rearrange.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/requirements.txt +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/scan.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/state-dict.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/tutorial.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/docs/vmap.md +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/mkdocs.yml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/pyproject.toml +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/__init__.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/__init__.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/compile_utils.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/dot.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/einsum.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/fp8.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/parsing.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/rearrange.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/scan.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/state_dict.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/_src/util.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/axis.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/core.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/debug.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/jax_utils.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/__init__.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/activations.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/attention.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/conv.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/dropout.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/embedding.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/linear.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/loss.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/mlp.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/normalization.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/pool.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/nn/scan.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/ops.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/partitioning.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/quantization.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/random.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/specialized_fns.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/state_dict.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/tree_util.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/types.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/util.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/src/haliax/wrap.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/core_test.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_attention.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_axis.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_conv.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_debug.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_dot.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_einsum.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_fp8.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_int8.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_nn.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_ops.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_parsing.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_partitioning.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_pool.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_random.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_rearrange.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_scan.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_scatter_gather.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_specialized_fns.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_state_dict.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_tree_util.py +0 -0
- {haliax-1.4.dev353 → haliax-1.4.dev355}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: haliax
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.dev355
|
|
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/
|
|
@@ -287,3 +287,42 @@ operation more effectively.)
|
|
|
287
287
|
|
|
288
288
|
It's worth emphasizing that these functions are typically compiled to scatter-add and friends (as appropriate).
|
|
289
289
|
This is the preferred way to do scatter/gather operations in JAX, as well as in Haliax.
|
|
290
|
+
|
|
291
|
+
## Scatter/Gather
|
|
292
|
+
|
|
293
|
+
Haliax supports scatter/gather semantics in its indexing operations. When an axis
|
|
294
|
+
is indexed by another NamedArray (or a 1-D JAX array), the values of that axis
|
|
295
|
+
are gathered according to the index array and the axes of the indexer are
|
|
296
|
+
inserted into the result.
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
import haliax as hax
|
|
300
|
+
import jax.numpy as jnp
|
|
301
|
+
|
|
302
|
+
B, S, V = Axis("batch", 4), Axis("seq", 3), Axis("vocab", 7)
|
|
303
|
+
x = hax.arange((B, S, V))
|
|
304
|
+
idx = hax.arange((B, S), dtype=jnp.int32) % V.size
|
|
305
|
+
|
|
306
|
+
out = x["vocab", idx]
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Here `out` has axes `(B, S)` and its values match `jax.numpy.take_along_axis`
|
|
310
|
+
on the underlying ndarray.
|
|
311
|
+
|
|
312
|
+
For scatter-style updates where each batch writes to a different position, use
|
|
313
|
+
[`updated_slice`][haliax.updated_slice]:
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
Batch = hax.Axis("batch", 2)
|
|
317
|
+
Seq = hax.Axis("seq", 5)
|
|
318
|
+
New = hax.Axis("seq", 2)
|
|
319
|
+
|
|
320
|
+
cache = hax.zeros((Batch, Seq), dtype=int)
|
|
321
|
+
lengths = hax.named([1, 3], axis=Batch)
|
|
322
|
+
kv = hax.named([[1, 2], [3, 4]], axis=(Batch, New))
|
|
323
|
+
|
|
324
|
+
result = updated_slice(cache, {"seq": lengths}, kv)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
This inserts `[1, 2]` starting at position `1` in batch `0` and `[3, 4]` starting
|
|
328
|
+
at position `3` in batch `1`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.dev355"
|
|
@@ -19,16 +19,16 @@ from ._src.scan import (
|
|
|
19
19
|
map,
|
|
20
20
|
scan,
|
|
21
21
|
)
|
|
22
|
-
from .axis import Axis, AxisSelector, selects_axis
|
|
22
|
+
from .axis import Axis, AxisSelection, AxisSelector, selects_axis
|
|
23
23
|
from .core import NamedArray
|
|
24
24
|
from .jax_utils import Static, broadcast_prefix, is_jax_array_like
|
|
25
25
|
from .partitioning import physical_axis_name
|
|
26
|
-
from .util import is_named_array
|
|
26
|
+
from .util import ensure_tuple, is_named_array
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def vmap(
|
|
30
30
|
fn,
|
|
31
|
-
axis:
|
|
31
|
+
axis: AxisSelection,
|
|
32
32
|
*,
|
|
33
33
|
default: PyTree[UnnamedAxisSpec] = _zero_if_array_else_none,
|
|
34
34
|
args: PyTree[UnnamedAxisSpec] = (),
|
|
@@ -43,7 +43,9 @@ def vmap(
|
|
|
43
43
|
|
|
44
44
|
Args:
|
|
45
45
|
fn (Callable): function to vmap over
|
|
46
|
-
axis (Axis): axis to vmap over
|
|
46
|
+
axis (Axis or Sequence[Axis]): axis or axes to vmap over. If a sequence is
|
|
47
|
+
provided, the function will be vmapped over each axis in turn,
|
|
48
|
+
from innermost to outermost.
|
|
47
49
|
default: how to handle (unnamed) arrays by default. Should be either an integer or None, or a callable that takes a PyTree leaf
|
|
48
50
|
and returns an integer or None, or a PyTree prefix of the same. If an integer, the array will be mapped over that axis. If None, the array will not be mapped over.
|
|
49
51
|
args: optional per-argument overrides for how to handle arrays. Should be a PyTree prefix of the same type as default.
|
|
@@ -53,6 +55,15 @@ def vmap(
|
|
|
53
55
|
if kwargs is None:
|
|
54
56
|
kwargs = {}
|
|
55
57
|
|
|
58
|
+
axes = ensure_tuple(axis) # type: ignore
|
|
59
|
+
if len(axes) > 1:
|
|
60
|
+
mapped = fn
|
|
61
|
+
for ax in reversed(axes):
|
|
62
|
+
mapped = vmap(mapped, ax, default=default, args=args, kwargs=kwargs)
|
|
63
|
+
return mapped
|
|
64
|
+
else:
|
|
65
|
+
axis = axes[0]
|
|
66
|
+
|
|
56
67
|
signature = inspect.signature(fn)
|
|
57
68
|
|
|
58
69
|
# this mirrors equinox's filter_vmap, but it's not really documented there so:
|
|
@@ -321,3 +321,22 @@ def test_vmap_error_for_incorrectly_specified_args():
|
|
|
321
321
|
Width = Axis("Width", 3)
|
|
322
322
|
|
|
323
323
|
hax.vmap(lambda a: Module(a), Batch)(Width)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def test_vmap_multiple_axes():
|
|
327
|
+
Batch1 = Axis("Batch1", 4)
|
|
328
|
+
Batch2 = Axis("Batch2", 3)
|
|
329
|
+
Width = Axis("Width", 2)
|
|
330
|
+
Depth = Axis("Depth", 5)
|
|
331
|
+
|
|
332
|
+
named = hax.random.uniform(PRNGKey(0), (Batch1, Batch2, Width, Depth))
|
|
333
|
+
|
|
334
|
+
def vmap_fun(x):
|
|
335
|
+
return x.sum(Width)
|
|
336
|
+
|
|
337
|
+
selected = hax.vmap(vmap_fun, (Batch1, Batch2))(named)
|
|
338
|
+
|
|
339
|
+
expected = jnp.sum(named.array, axis=2)
|
|
340
|
+
|
|
341
|
+
assert jnp.allclose(selected.array, expected)
|
|
342
|
+
assert selected.axes == (Batch1, Batch2, Depth)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.dev353"
|
|
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
|
|
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
|