haliax 1.4.dev356__tar.gz → 1.4.dev359__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.
Files changed (107) hide show
  1. {haliax-1.4.dev356 → haliax-1.4.dev359}/PKG-INFO +1 -1
  2. haliax-1.4.dev359/src/haliax/__about__.py +1 -0
  3. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/__init__.py +3 -3
  4. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/core.py +40 -18
  5. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/hof.py +4 -2
  6. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/attention.py +1 -1
  7. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/normalization.py +1 -1
  8. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/ops.py +3 -3
  9. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/random.py +3 -3
  10. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/specialized_fns.py +1 -1
  11. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/wrap.py +2 -2
  12. haliax-1.4.dev356/src/haliax/__about__.py +0 -1
  13. {haliax-1.4.dev356 → haliax-1.4.dev359}/.coveragerc +0 -0
  14. {haliax-1.4.dev356 → haliax-1.4.dev359}/.flake8 +0 -0
  15. {haliax-1.4.dev356 → haliax-1.4.dev359}/.github/workflows/publish_dev.yaml +0 -0
  16. {haliax-1.4.dev356 → haliax-1.4.dev359}/.github/workflows/run_pre_commit.yaml +0 -0
  17. {haliax-1.4.dev356 → haliax-1.4.dev359}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
  18. {haliax-1.4.dev356 → haliax-1.4.dev359}/.github/workflows/run_tests.yaml +0 -0
  19. {haliax-1.4.dev356 → haliax-1.4.dev359}/.gitignore +0 -0
  20. {haliax-1.4.dev356 → haliax-1.4.dev359}/.pre-commit-config.yaml +0 -0
  21. {haliax-1.4.dev356 → haliax-1.4.dev359}/.readthedocs.yaml +0 -0
  22. {haliax-1.4.dev356 → haliax-1.4.dev359}/CONTRIBUTING.md +0 -0
  23. {haliax-1.4.dev356 → haliax-1.4.dev359}/LICENSE +0 -0
  24. {haliax-1.4.dev356 → haliax-1.4.dev359}/README.md +0 -0
  25. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/api.md +0 -0
  26. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/broadcasting.md +0 -0
  27. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/cheatsheet.md +0 -0
  28. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/css/material.css +0 -0
  29. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/css/mkdocstrings.css +0 -0
  30. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/faq.md +0 -0
  31. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/data_parallel_mesh.png +0 -0
  32. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/data_parallel_mesh_replicated.png +0 -0
  33. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_1d.png +0 -0
  34. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_1d_zero.png +0 -0
  35. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d.png +0 -0
  36. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
  37. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
  38. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
  39. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
  40. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/figures/device_mesh_2d_zero.png +0 -0
  41. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/fp8.md +0 -0
  42. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/index.md +0 -0
  43. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/indexing.md +0 -0
  44. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/matmul.md +0 -0
  45. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/nn.md +0 -0
  46. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/partitioning.md +0 -0
  47. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/rearrange.ipynb +0 -0
  48. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/rearrange.md +0 -0
  49. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/requirements.txt +0 -0
  50. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/scan.md +0 -0
  51. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/state-dict.md +0 -0
  52. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/tutorial.md +0 -0
  53. {haliax-1.4.dev356 → haliax-1.4.dev359}/docs/vmap.md +0 -0
  54. {haliax-1.4.dev356 → haliax-1.4.dev359}/mkdocs.yml +0 -0
  55. {haliax-1.4.dev356 → haliax-1.4.dev359}/pyproject.toml +0 -0
  56. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/__init__.py +0 -0
  57. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/compile_utils.py +0 -0
  58. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/dot.py +0 -0
  59. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/einsum.py +0 -0
  60. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/fp8.py +0 -0
  61. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/parsing.py +0 -0
  62. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/rearrange.py +0 -0
  63. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/scan.py +0 -0
  64. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/state_dict.py +0 -0
  65. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/_src/util.py +0 -0
  66. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/axis.py +0 -0
  67. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/debug.py +0 -0
  68. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/jax_utils.py +0 -0
  69. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/__init__.py +0 -0
  70. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/activations.py +0 -0
  71. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/conv.py +0 -0
  72. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/dropout.py +0 -0
  73. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/embedding.py +0 -0
  74. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/linear.py +0 -0
  75. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/loss.py +0 -0
  76. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/mlp.py +0 -0
  77. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/pool.py +0 -0
  78. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/nn/scan.py +0 -0
  79. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/partitioning.py +0 -0
  80. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/quantization.py +0 -0
  81. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/state_dict.py +0 -0
  82. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/tree_util.py +0 -0
  83. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/types.py +0 -0
  84. {haliax-1.4.dev356 → haliax-1.4.dev359}/src/haliax/util.py +0 -0
  85. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/core_test.py +0 -0
  86. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_attention.py +0 -0
  87. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_axis.py +0 -0
  88. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_conv.py +0 -0
  89. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_debug.py +0 -0
  90. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_dot.py +0 -0
  91. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_einsum.py +0 -0
  92. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_fp8.py +0 -0
  93. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_hof.py +0 -0
  94. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_int8.py +0 -0
  95. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_nn.py +0 -0
  96. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_ops.py +0 -0
  97. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_parsing.py +0 -0
  98. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_partitioning.py +0 -0
  99. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_pool.py +0 -0
  100. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_random.py +0 -0
  101. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_rearrange.py +0 -0
  102. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_scan.py +0 -0
  103. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_scatter_gather.py +0 -0
  104. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_specialized_fns.py +0 -0
  105. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_state_dict.py +0 -0
  106. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_tree_util.py +0 -0
  107. {haliax-1.4.dev356 → haliax-1.4.dev359}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haliax
3
- Version: 1.4.dev356
3
+ Version: 1.4.dev359
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/
@@ -0,0 +1 @@
1
+ __version__ = "1.4.dev359"
@@ -212,7 +212,7 @@ def repeat(
212
212
  a: NamedArray, repeats: int | jnp.ndarray, axis: AxisSelector, total_repeat_length: Optional[int] = None
213
213
  ) -> NamedArray:
214
214
  """Version of [jax.numpy.repeat][] that returns a NamedArray"""
215
- index = a._lookup_indices(axis)
215
+ index = a.axis_indices(axis)
216
216
  if index is None:
217
217
  raise ValueError(f"Axis {axis} not found in array {a}")
218
218
 
@@ -235,7 +235,7 @@ def tile(a: NamedArray, reps: dict[AxisSelector, int]) -> NamedArray:
235
235
  new_dims = []
236
236
  dim_reps = [1] * len(a.axes)
237
237
  for ax, i in reps.items():
238
- index = a._lookup_indices(ax)
238
+ index = a.axis_indices(ax)
239
239
  if index is None:
240
240
  new_dims.append(Axis(axis_name(ax), i))
241
241
  else:
@@ -265,7 +265,7 @@ def concatenate(axis: AxisSelector, arrays: Sequence[NamedArray]) -> NamedArray:
265
265
  if len(arrays) == 0:
266
266
  return zeros(axis)
267
267
 
268
- axis_index = arrays[0]._lookup_indices(aname)
268
+ axis_index = arrays[0].axis_indices(aname)
269
269
  if axis_index is None:
270
270
  raise ValueError(f"Axis {aname} not found in 0th array {arrays[0]}")
271
271
 
@@ -1,6 +1,7 @@
1
1
  import contextlib
2
2
  import functools as ft
3
3
  import typing
4
+ import warnings
4
5
  from dataclasses import dataclass
5
6
  from math import prod
6
7
  from types import EllipsisType
@@ -142,7 +143,7 @@ class NamedArray:
142
143
 
143
144
  def has_axis(self, axis: AxisSelection) -> bool:
144
145
  """Returns true if the given axis is present in this NamedArray."""
145
- return self._lookup_indices(axis) is not None
146
+ return self.axis_indices(axis) is not None
146
147
 
147
148
  @overload
148
149
  def axis_size(self, axis: AxisSelector) -> int: # type: ignore
@@ -156,7 +157,7 @@ class NamedArray:
156
157
  """
157
158
  Returns the size of the given axis, or a tuple of sizes if given multiple axes.
158
159
  """
159
- indices = self._lookup_indices(axis)
160
+ indices = self.axis_indices(axis)
160
161
  if isinstance(indices, int):
161
162
  return self.axes[indices].size
162
163
  elif indices is None:
@@ -184,7 +185,7 @@ class NamedArray:
184
185
 
185
186
  Raises a ValueError if any of the axes are not found.
186
187
  """
187
- indices = self._lookup_indices(axes)
188
+ indices = self.axis_indices(axes)
188
189
  if isinstance(indices, int):
189
190
  return self.axes[indices]
190
191
  elif indices is None:
@@ -235,6 +236,27 @@ class NamedArray:
235
236
  For a single axis, returns an int corresponding to the index of the axis.
236
237
  For multiple axes, returns a tuple of ints corresponding to the indices of the axes.
237
238
 
239
+ If the axis is not present, returns None for that position
240
+ """
241
+ warnings.warn(
242
+ "_lookup_indices() is deprecated, use axis_indices() instead",
243
+ DeprecationWarning,
244
+ )
245
+ return self.axis_indices(axis)
246
+
247
+ @overload
248
+ def axis_indices(self, axis: AxisSelector) -> Optional[int]: # type: ignore
249
+ ...
250
+
251
+ @overload
252
+ def axis_indices(self, axis: Sequence[AxisSelector]) -> Tuple[Optional[int], ...]:
253
+ ...
254
+
255
+ def axis_indices(self, axis: AxisSelection) -> Union[Optional[int], Tuple[Optional[int], ...]]:
256
+ """
257
+ For a single axis, returns an int corresponding to the index of the axis.
258
+ For multiple axes, returns a tuple of ints corresponding to the indices of the axes.
259
+
238
260
  If the axis is not present, returns None for that position
239
261
  """
240
262
  if isinstance(axis, Axis):
@@ -262,7 +284,7 @@ class NamedArray:
262
284
  except ValueError:
263
285
  return None
264
286
  else:
265
- return tuple(self._lookup_indices(a) for a in axis)
287
+ return tuple(self.axis_indices(a) for a in axis)
266
288
 
267
289
  # Axis rearrangement
268
290
  @typing.overload
@@ -675,7 +697,7 @@ def take(array: NamedArray, axis: AxisSelector, index: Union[int, NamedArray]) -
675
697
 
676
698
  if index is a NamedArray, then those axes are added to the output array
677
699
  """
678
- axis_index = array._lookup_indices(axis)
700
+ axis_index = array.axis_indices(axis)
679
701
  if axis_index is None:
680
702
  raise ValueError(f"axis {axis} not found in {array}")
681
703
 
@@ -696,14 +718,14 @@ def take(array: NamedArray, axis: AxisSelector, index: Union[int, NamedArray]) -
696
718
 
697
719
  if intersecting_axes:
698
720
  # if the eliminated axis is also in the index, we rename it to a dummy axis that we can broadcast over it
699
- need_to_use_dummy_axis = index._lookup_indices(axis.name) is not None
721
+ need_to_use_dummy_axis = index.axis_indices(axis.name) is not None
700
722
  if need_to_use_dummy_axis:
701
723
  index = index.rename({axis.name: "__DUMMY_" + axis.name})
702
724
  array = haliax.broadcast_to(array, index.axes, ensure_order=False, enforce_no_extra_axes=False)
703
725
  new_axes = eliminate_axes(array.axes, axis)
704
726
  index = haliax.broadcast_to(index, new_axes, ensure_order=True, enforce_no_extra_axes=True)
705
727
 
706
- axis_index = array._lookup_indices(axis) # if it moved
728
+ axis_index = array.axis_indices(axis) # if it moved
707
729
  index_array = jnp.expand_dims(index.array, axis=axis_index)
708
730
  new_array = jnp.take_along_axis(array.array, index_array, axis=axis_index)
709
731
  new_array = jnp.squeeze(new_array, axis=axis_index)
@@ -792,7 +814,7 @@ def _slice_old(
792
814
  Note:
793
815
  This method is basically a wrapper around jax.lax.dynamic_slice_in_dim.
794
816
  """
795
- axis_index = array._lookup_indices(axis)
817
+ axis_index = array.axis_indices(axis)
796
818
  if axis_index is None:
797
819
  raise ValueError(f"axis {axis} not found in {array}")
798
820
 
@@ -824,7 +846,7 @@ def _slice_new(
824
846
  new_lengths = [axis.size for axis in array.axes]
825
847
 
826
848
  for axis, s in start.items():
827
- axis_index = array._lookup_indices(axis_name(axis))
849
+ axis_index = array.axis_indices(axis_name(axis))
828
850
  if axis_index is None:
829
851
  raise ValueError(f"axis {axis} not found in {array}")
830
852
 
@@ -883,14 +905,14 @@ def updated_slice(
883
905
  f = updated_slice
884
906
  for axis_name in map_axes:
885
907
  # make sure that axis_name is in `array`. otherwise it doesn't make sense to vmap over it
886
- if array._lookup_indices(axis_name) is None:
908
+ if array.axis_indices(axis_name) is None:
887
909
  raise ValueError(f"axis {axis_name} not found in original array's axes: {array.shape}")
888
910
  f = haliax.vmap(f, axis=axis_name)
889
911
  return f(array, start, update)
890
912
 
891
913
  array_slice_indices = [0] * len(array.axes)
892
914
  for axis, s in start.items():
893
- axis_index = array._lookup_indices(haliax.axis_name(axis))
915
+ axis_index = array.axis_indices(haliax.axis_name(axis))
894
916
  if axis_index is None:
895
917
  raise ValueError(f"axis {axis} not found in {array}")
896
918
  if isinstance(s, NamedArray): # this can happen in the vmap case
@@ -900,7 +922,7 @@ def updated_slice(
900
922
 
901
923
  array_slice_indices[axis_index] = s
902
924
  total_length = array.axes[axis_index].size
903
- update_axis = update._lookup_indices(haliax.axis_name(axis))
925
+ update_axis = update.axis_indices(haliax.axis_name(axis))
904
926
 
905
927
  # if s is a tracer we can't check the size
906
928
  if update_axis is None:
@@ -923,7 +945,7 @@ def updated_slice(
923
945
  )
924
946
  broadcasted_axes = []
925
947
  for ax in array.axes:
926
- upd_ax = update._lookup_indices(ax.name)
948
+ upd_ax = update.axis_indices(ax.name)
927
949
  broadcasted_axes.append(ax if upd_ax is None else update.axes[upd_ax])
928
950
  update = haliax.broadcast_to(update, broadcasted_axes, enforce_no_extra_axes=True)
929
951
  upd_arr = update.array
@@ -967,7 +989,7 @@ def _compute_new_axes_and_slices_for_index(
967
989
  index_axis_names = set()
968
990
 
969
991
  for axis, slice_ in slices.items():
970
- axis_index = array._lookup_indices(axis)
992
+ axis_index = array.axis_indices(axis)
971
993
  if axis_index is None:
972
994
  raise ValueError(f"axis {axis} not found in {array}")
973
995
  if isinstance(slice_, py_slice) or isinstance(slice_, dslice) or is_pallas_dslice(slice_):
@@ -1111,7 +1133,7 @@ def split(a: NamedArray, axis: AxisSelector, new_axes: Sequence[Axis]) -> Sequen
1111
1133
  new_axes (Sequence[Axis]): the axes to split into. Must have the same total length as the axis being split.
1112
1134
  """
1113
1135
  # check the lengths of the new axes
1114
- index = a._lookup_indices(axis)
1136
+ index = a.axis_indices(axis)
1115
1137
  if index is None:
1116
1138
  raise ValueError(f"Axis {axis} not found in {a.axes}")
1117
1139
 
@@ -1136,7 +1158,7 @@ def unbind(array: NamedArray, axis: AxisSelector) -> List[NamedArray]:
1136
1158
  Unbind an array along an axis, returning a list of NamedArrays, one for each position on that axis.
1137
1159
  Analogous to torch.unbind or np.rollaxis
1138
1160
  """
1139
- axis_index = array._lookup_indices(axis)
1161
+ axis_index = array.axis_indices(axis)
1140
1162
  if axis_index is None:
1141
1163
  raise ValueError(f"axis {axis} not found in {array}")
1142
1164
  new_axes = array.axes[:axis_index] + array.axes[axis_index + 1 :]
@@ -1153,7 +1175,7 @@ def roll(array: NamedArray, shift: Union[int, Tuple[int, ...]], axis: AxisSelect
1153
1175
  """
1154
1176
  Roll an array along an axis or axes. Analogous to np.roll
1155
1177
  """
1156
- axis_indices = array._lookup_indices(axis)
1178
+ axis_indices = array.axis_indices(axis)
1157
1179
  if axis_indices is None:
1158
1180
  raise ValueError(f"axis {axis} not found in {array}")
1159
1181
  return NamedArray(jnp.roll(array.array, shift, axis_indices), array.axes)
@@ -1331,7 +1353,7 @@ def unflatten_axis(array: NamedArray, axis: AxisSelector, new_axes: AxisSpec) ->
1331
1353
  """
1332
1354
  Split an axis into a sequence of axes. The old axis must have the same size as the product of the new axes.
1333
1355
  """
1334
- old_index = array._lookup_indices(axis)
1356
+ old_index = array.axis_indices(axis)
1335
1357
  if old_index is None:
1336
1358
  raise ValueError(f"Axis {axis} not found in {array}")
1337
1359
 
@@ -61,8 +61,10 @@ def vmap(
61
61
  for ax in reversed(axes):
62
62
  mapped = vmap(mapped, ax, default=default, args=args, kwargs=kwargs)
63
63
  return mapped
64
- else:
64
+ elif len(axes) == 1: # type: ignore
65
65
  axis = axes[0]
66
+ else:
67
+ return fn
66
68
 
67
69
  signature = inspect.signature(fn)
68
70
 
@@ -83,7 +85,7 @@ def vmap(
83
85
 
84
86
  def _index_of_batch_axis(array, default):
85
87
  if isinstance(array, NamedArray):
86
- return array._lookup_indices(axis)
88
+ return array.axis_indices(axis)
87
89
  elif callable(default):
88
90
  return default(array)
89
91
  else:
@@ -111,7 +111,7 @@ def dot_product_attention(
111
111
  KPos = ensure_tuple(key.resolve_axis(KPos))
112
112
  # any axis in KPos that's in query is a problem
113
113
  for axis in KPos:
114
- if axis in query.axes:
114
+ if query.has_axis(axis):
115
115
  raise ValueError(
116
116
  f"Axis {axis} in KPos is also in query. Attended-to axes must be distinct from query axis"
117
117
  )
@@ -163,7 +163,7 @@ def standardize(
163
163
  """Analogous to [jax.nn.standardize][], but with support for NamedArrays."""
164
164
  x, mean, variance, where = haliax.broadcast_arrays(x, mean, variance, where) # type: ignore
165
165
  raw_x, mean, variance, where = unwrap_namedarrays(x, mean, variance, where)
166
- axis_indices = x._lookup_indices(axis)
166
+ axis_indices = x.axis_indices(axis)
167
167
 
168
168
  plain = jnn.standardize(raw_x, axis_indices, mean=mean, variance=variance, epsilon=epsilon, where=where)
169
169
  return NamedArray(plain, x.axes)
@@ -11,8 +11,8 @@ from .jax_utils import is_scalarish
11
11
 
12
12
  def trace(array: NamedArray, axis1: AxisSelector, axis2: AxisSelector, offset=0, dtype=None) -> NamedArray:
13
13
  """Compute the trace of an array along two named axes."""
14
- a1_index = array._lookup_indices(axis1)
15
- a2_index = array._lookup_indices(axis2)
14
+ a1_index = array.axis_indices(axis1)
15
+ a2_index = array.axis_indices(axis2)
16
16
 
17
17
  if a1_index is None:
18
18
  raise ValueError(f"Axis {axis1} not found in array. Available axes: {array.axes}")
@@ -139,7 +139,7 @@ def pad_left(array: NamedArray, axis: Axis, new_axis: Axis, value=0) -> NamedArr
139
139
  if amount_to_pad_to < 0:
140
140
  raise ValueError(f"Cannot pad {axis} to {new_axis}")
141
141
 
142
- idx = array._lookup_indices(axis)
142
+ idx = array.axis_indices(axis)
143
143
 
144
144
  padding = [(0, 0)] * array.ndim
145
145
  if idx is None:
@@ -218,7 +218,7 @@ def choice(
218
218
  :return: Array with shape `shape` + (`a.axes` - `axis`)
219
219
  """
220
220
 
221
- index = a._lookup_indices(axis)
221
+ index = a.axis_indices(axis)
222
222
  assert index is not None, f"axis {axis} not in a"
223
223
 
224
224
  shape = ensure_tuple(shape)
@@ -261,7 +261,7 @@ def categorical(key, logits: NamedArray, axis: AxisSelector, shape: Optional[Axi
261
261
 
262
262
  logits = logits.broadcast_axis(shape)
263
263
 
264
- index = logits._lookup_indices(axis)
264
+ index = logits.axis_indices(axis)
265
265
  assert index is not None, f"axis {axis} not in logits"
266
266
 
267
267
  jax_shape = to_jax_shape(shape)
@@ -280,7 +280,7 @@ def gumbel(key, shape: AxisSpec, dtype=float):
280
280
 
281
281
  @named_call
282
282
  def permutation(key, x: NamedArray, axis: AxisSelector, independent: bool = False):
283
- axis_index = x._lookup_indices(axis)
283
+ axis_index = x.axis_indices(axis)
284
284
  jax_array = jrandom.permutation(key, x.array, axis_index, independent=independent)
285
285
  return haliax.auto_sharded(NamedArray(jax_array, x.axes))
286
286
 
@@ -22,7 +22,7 @@ def top_k(
22
22
  NamedArray: array with the top k elements along the given axis
23
23
  NamedArray: array with the top k elements' indices along the given axis
24
24
  """
25
- pos = arr._lookup_indices(axis)
25
+ pos = arr.axis_indices(axis)
26
26
  if pos is None:
27
27
  raise ValueError(f"Axis {axis} not found in {arr}")
28
28
  new_array = jnp.moveaxis(arr.array, pos, -1) # move axis to the last position
@@ -52,7 +52,7 @@ def wrap_reduction_call(
52
52
  axis = ensure_tuple(axis)
53
53
  if single_axis_only and len(axis) > 1:
54
54
  raise ValueError(f"{fn.__name__} only supports a single axis")
55
- indices = a._lookup_indices(axis)
55
+ indices = a.axis_indices(axis)
56
56
  if indices is None or any(x is None for x in indices):
57
57
  raise ValueError(f"axis {axis} is not in {a.axes}")
58
58
  new_axes = [ax for ax in a.axes if not selects_axis(axis, ax)]
@@ -74,7 +74,7 @@ def wrap_axiswise_call(fn, a, axis: Optional[AxisSelection], *, single_axis_only
74
74
  if axis is None:
75
75
  return fn(a.array, axis=None, **kwargs)
76
76
  else:
77
- indices = ensure_tuple(a._lookup_indices(axis))
77
+ indices = ensure_tuple(a.axis_indices(axis))
78
78
  if any(x is None for x in indices):
79
79
  raise ValueError(f"axis {axis} is not in {a.axes}")
80
80
  if len(indices) == 1:
@@ -1 +0,0 @@
1
- __version__ = "1.4.dev356"
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