haliax 1.4.dev409__tar.gz → 1.4.dev411__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 (128) hide show
  1. {haliax-1.4.dev409 → haliax-1.4.dev411}/.agents/projects/api_parity.md +1 -1
  2. haliax-1.4.dev411/.pre-commit-config.yaml +43 -0
  3. haliax-1.4.dev411/AUTHORS.md +5 -0
  4. haliax-1.4.dev411/CONTRIBUTORS.md +15 -0
  5. {haliax-1.4.dev409 → haliax-1.4.dev411}/PKG-INFO +2 -1
  6. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/api.md +1 -0
  7. haliax-1.4.dev411/etc/license_header.txt +3 -0
  8. haliax-1.4.dev411/src/haliax/__about__.py +6 -0
  9. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/__init__.py +11 -3
  10. haliax-1.4.dev411/src/haliax/_src/__init__.py +3 -0
  11. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/compile_utils.py +5 -0
  12. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/dot.py +7 -4
  13. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/einsum.py +5 -0
  14. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/fp8.py +5 -1
  15. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/parsing.py +5 -0
  16. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/rearrange.py +5 -0
  17. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/scan.py +11 -14
  18. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/state_dict.py +9 -7
  19. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/_src/util.py +5 -1
  20. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/axis.py +24 -38
  21. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/core.py +25 -41
  22. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/debug.py +5 -1
  23. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/field.py +5 -0
  24. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/haxtyping.py +49 -23
  25. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/hof.py +10 -3
  26. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/jax_utils.py +7 -5
  27. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/__init__.py +5 -0
  28. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/activations.py +5 -1
  29. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/attention.py +6 -2
  30. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/conv.py +5 -1
  31. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/dropout.py +5 -0
  32. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/embedding.py +5 -0
  33. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/linear.py +5 -0
  34. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/loss.py +9 -8
  35. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/mlp.py +5 -1
  36. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/normalization.py +6 -1
  37. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/pool.py +5 -1
  38. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/nn/scan.py +69 -62
  39. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/ops.py +36 -14
  40. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/partitioning.py +13 -12
  41. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/quantization.py +6 -3
  42. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/random.py +5 -0
  43. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/specialized_fns.py +5 -0
  44. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/state_dict.py +5 -1
  45. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/tree_util.py +5 -0
  46. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/types.py +6 -3
  47. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/util.py +5 -1
  48. {haliax-1.4.dev409 → haliax-1.4.dev411}/src/haliax/wrap.py +7 -4
  49. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/core_test.py +6 -3
  50. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_attention.py +5 -0
  51. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_axis.py +5 -0
  52. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_conv.py +5 -0
  53. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_debug.py +5 -0
  54. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_dot.py +5 -0
  55. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_dtype_typing.py +5 -0
  56. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_einsum.py +5 -0
  57. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_field.py +5 -0
  58. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_fp8.py +5 -0
  59. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_hof.py +5 -0
  60. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_int8.py +5 -0
  61. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_moe_linear.py +5 -0
  62. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_namedarray_typing.py +6 -1
  63. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_nn.py +5 -0
  64. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_ops.py +28 -0
  65. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_parsing.py +5 -0
  66. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_partitioning.py +9 -3
  67. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_pool.py +5 -1
  68. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_random.py +5 -1
  69. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_rearrange.py +5 -1
  70. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_scan.py +6 -0
  71. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_scatter_gather.py +5 -1
  72. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_specialized_fns.py +5 -0
  73. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_state_dict.py +5 -0
  74. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_tree_util.py +5 -0
  75. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_utils.py +5 -1
  76. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_visualize_sharding.py +5 -0
  77. haliax-1.4.dev409/.pre-commit-config.yaml +0 -39
  78. haliax-1.4.dev409/src/haliax/__about__.py +0 -1
  79. haliax-1.4.dev409/src/haliax/_src/__init__.py +0 -0
  80. {haliax-1.4.dev409 → haliax-1.4.dev411}/.coveragerc +0 -0
  81. {haliax-1.4.dev409 → haliax-1.4.dev411}/.flake8 +0 -0
  82. {haliax-1.4.dev409 → haliax-1.4.dev411}/.github/workflows/publish_dev.yaml +0 -0
  83. {haliax-1.4.dev409 → haliax-1.4.dev411}/.github/workflows/run_pre_commit.yaml +0 -0
  84. {haliax-1.4.dev409 → haliax-1.4.dev411}/.github/workflows/run_quick_levanter_tests.yaml +0 -0
  85. {haliax-1.4.dev409 → haliax-1.4.dev411}/.github/workflows/run_tests.yaml +0 -0
  86. {haliax-1.4.dev409 → haliax-1.4.dev411}/.gitignore +0 -0
  87. {haliax-1.4.dev409 → haliax-1.4.dev411}/.playbooks/add-types.md +0 -0
  88. {haliax-1.4.dev409 → haliax-1.4.dev411}/.playbooks/wrap-non-named.md +0 -0
  89. {haliax-1.4.dev409 → haliax-1.4.dev411}/.readthedocs.yaml +0 -0
  90. {haliax-1.4.dev409 → haliax-1.4.dev411}/AGENTS.md +0 -0
  91. {haliax-1.4.dev409 → haliax-1.4.dev411}/CONTRIBUTING.md +0 -0
  92. {haliax-1.4.dev409 → haliax-1.4.dev411}/LICENSE +0 -0
  93. {haliax-1.4.dev409 → haliax-1.4.dev411}/README.md +0 -0
  94. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/broadcasting.md +0 -0
  95. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/cheatsheet.md +0 -0
  96. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/css/material.css +0 -0
  97. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/css/mkdocstrings.css +0 -0
  98. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/faq.md +0 -0
  99. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/data_parallel_mesh.png +0 -0
  100. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/data_parallel_mesh_replicated.png +0 -0
  101. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_1d.png +0 -0
  102. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_1d_zero.png +0 -0
  103. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d.png +0 -0
  104. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
  105. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
  106. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
  107. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
  108. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/figures/device_mesh_2d_zero.png +0 -0
  109. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/fp8.md +0 -0
  110. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/index.md +0 -0
  111. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/indexing.md +0 -0
  112. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/matmul.md +0 -0
  113. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/nn.md +0 -0
  114. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/partitioning.md +0 -0
  115. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/primer.md +0 -0
  116. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/rearrange.ipynb +0 -0
  117. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/rearrange.md +0 -0
  118. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/requirements.txt +0 -0
  119. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/scan.md +0 -0
  120. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/state-dict.md +0 -0
  121. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/tutorial.md +0 -0
  122. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/typing.md +0 -0
  123. {haliax-1.4.dev409 → haliax-1.4.dev411}/docs/vmap.md +0 -0
  124. {haliax-1.4.dev409 → haliax-1.4.dev411}/mkdocs.yml +0 -0
  125. {haliax-1.4.dev409 → haliax-1.4.dev411}/pyproject.toml +0 -0
  126. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_bitwise_ops.py +0 -0
  127. {haliax-1.4.dev409 → haliax-1.4.dev411}/tests/test_nan_reductions.py +0 -0
  128. {haliax-1.4.dev409 → haliax-1.4.dev411}/uv.lock +0 -0
@@ -107,7 +107,7 @@ APIs that don't translate well to named tensors are intentionally omitted here.
107
107
  - [x] `nanstd`
108
108
  - [x] `nansum`
109
109
  - [x] `nanvar`
110
- - [ ] `nonzero`
110
+ - [x] `nonzero`
111
111
  - [ ] `ogrid`
112
112
  - [x] `packbits`
113
113
  - [ ] `partition`
@@ -0,0 +1,43 @@
1
+ # See https://pre-commit.com
2
+ exclude: ".git|.venv|tests/snapshots/.*/.*"
3
+
4
+ repos:
5
+ - repo: https://github.com/astral-sh/ruff-pre-commit
6
+ rev: v0.11.10
7
+ hooks:
8
+ - id: ruff
9
+ args: [ --fix, --exit-non-zero-on-fix ]
10
+
11
+ - repo: https://github.com/Lucas-C/pre-commit-hooks
12
+ rev: v1.5.5
13
+ hooks:
14
+ - id: insert-license
15
+ files: \.py$
16
+ args:
17
+ - --license-filepath
18
+ - etc/license_header.txt
19
+ - --use-current-year
20
+
21
+ - repo: https://github.com/psf/black
22
+ rev: 25.1.0
23
+ hooks:
24
+ - id: black
25
+
26
+ - repo: https://github.com/pre-commit/pre-commit-hooks
27
+ rev: v5.0.0
28
+ hooks:
29
+ - id: check-added-large-files
30
+ - id: check-ast
31
+ - id: check-case-conflict
32
+ - id: check-merge-conflict
33
+ - id: check-toml
34
+ - id: check-yaml
35
+ args: [ --unsafe ]
36
+ - id: end-of-file-fixer
37
+ - id: trailing-whitespace
38
+
39
+ - repo: https://github.com/pre-commit/mirrors-mypy
40
+ rev: v1.16.1
41
+ hooks:
42
+ - id: mypy
43
+ args: [--ignore-missing-imports, --check-untyped-defs]
@@ -0,0 +1,5 @@
1
+ # The Levanter Authors
2
+
3
+ The Levanter Authors currently include:
4
+
5
+ - The Board of Trustees of the Leland Stanford Junior University
@@ -0,0 +1,15 @@
1
+ # Contributors
2
+
3
+ The following individuals have contributed to Haliax:
4
+
5
+ - David Hall <dlwh@stanford.edu>
6
+ - David Hall <dlwh@cs.stanford.edu>
7
+ - Jason Wang <blahblahj.wsy@gmail.com>
8
+ - Ivan Zhou <ivan.zhouyq@gmail.com>
9
+ - rohan-mehta-1024 <69774557+rohan-mehta-1024@users.noreply.github.com>
10
+ - Gary Miguel <garymm@garymm.org>
11
+ - Jennifer Zhou <jennifer@jezh.me>
12
+ - Joseph Camacho <camacho.joseph@gmail.com>
13
+ - Omead Pooladzandi <opooladz@ucla.edu>
14
+ - Patrick Kidger <33688385+patrick-kidger@users.noreply.github.com>
15
+ - Russell Power <russell.power@gmail.com>
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haliax
3
- Version: 1.4.dev409
3
+ Version: 1.4.dev411
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/
7
7
  Project-URL: Documentation, https://haliax.readthedocs.io/en/latest/
8
8
  Author-email: David Hall <dlwh@cs.stanford.edu>
9
+ License-File: AUTHORS.md
9
10
  License-File: LICENSE
10
11
  Classifier: Development Status :: 4 - Beta
11
12
  Classifier: Intended Audience :: Science/Research
@@ -283,6 +283,7 @@ These are all more or less directly from JAX's NumPy API.
283
283
  ::: haliax.pad
284
284
  ::: haliax.searchsorted
285
285
  ::: haliax.top_k
286
+ ::: haliax.nonzero
286
287
  ::: haliax.trace
287
288
  ::: haliax.tril
288
289
  ::: haliax.triu
@@ -0,0 +1,3 @@
1
+ Copyright 2025 The Levanter Authors
2
+
3
+ SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,6 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ __version__ = "1.4.dev411"
@@ -1,10 +1,14 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import typing as t
2
7
  from typing import Optional, Sequence
3
8
 
4
9
  import jax
5
10
  import jax.numpy as jnp
6
11
 
7
-
8
12
  try:
9
13
  from jax.typing import DTypeLike
10
14
  except ImportError:
@@ -44,7 +48,9 @@ from .axis import (
44
48
  )
45
49
  from .core import (
46
50
  NamedArray,
47
- NamedArrayAxes, NamedArrayAxesSpec, NamedOrNumeric,
51
+ NamedArrayAxes,
52
+ NamedArrayAxesSpec,
53
+ NamedOrNumeric,
48
54
  are_shape_checks_enabled,
49
55
  broadcast_arrays,
50
56
  broadcast_axis,
@@ -78,6 +84,7 @@ from .ops import (
78
84
  trace,
79
85
  tril,
80
86
  triu,
87
+ nonzero,
81
88
  unique,
82
89
  unique_values,
83
90
  unique_counts,
@@ -102,7 +109,6 @@ from .wrap import (
102
109
  wrap_reduction_call,
103
110
  )
104
111
 
105
-
106
112
  T = t.TypeVar("T")
107
113
  A = t.TypeVar("A", Scalar, NamedArray, jnp.ndarray)
108
114
 
@@ -801,6 +807,7 @@ def argsort(a: NamedArray, axis: AxisSelector) -> NamedArray:
801
807
 
802
808
  # elemwise binary ops
803
809
 
810
+
804
811
  # Note that all the heavy lifting is done by the `wrap_elemwise_binary` decorator
805
812
  @wrap_elemwise_binary
806
813
  def add(x1: NamedOrNumeric, x2: NamedOrNumeric, /) -> NamedOrNumeric:
@@ -1193,6 +1200,7 @@ __all__ = [
1193
1200
  "map",
1194
1201
  "vmap",
1195
1202
  "trace",
1203
+ "nonzero",
1196
1204
  "where",
1197
1205
  "unique",
1198
1206
  "unique_values",
@@ -0,0 +1,3 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  # This whole file is copied from Equinox.
2
7
  # (c) 2023, Google LLC. and/or Patrick Kidger. Apache 2.0 licensed.
3
8
  # Patrick doesn't like that I depend on Equinox internals, so I copied this stuff
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import functools as ft
2
7
  import typing
3
8
  import warnings
@@ -30,8 +35,7 @@ def dot(
30
35
  preferred_element_type: Optional[DTypeLike] = None,
31
36
  out_axes: Optional[PartialAxisSpec] = ...,
32
37
  dot_general=jax.lax.dot_general,
33
- ) -> NamedArray:
34
- ...
38
+ ) -> NamedArray: ...
35
39
 
36
40
 
37
41
  @typing.overload
@@ -42,8 +46,7 @@ def dot(
42
46
  preferred_element_type: Optional[DTypeLike] = None,
43
47
  out_axes: Optional[PartialAxisSpec] = ...,
44
48
  dot_general=jax.lax.dot_general,
45
- ) -> NamedArray:
46
- ...
49
+ ) -> NamedArray: ...
47
50
 
48
51
 
49
52
  def dot(
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import functools
2
7
  from types import EllipsisType
3
8
  from typing import Optional, Tuple
@@ -1,9 +1,13 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  from functools import partial
2
7
 
3
8
  from jax import custom_jvp, custom_vjp, lax
4
9
  from jax import numpy as jnp
5
10
 
6
-
7
11
  # All of this is copy paste from flax/linen/fp8_ops.py
8
12
  # (Until we get to the module)
9
13
 
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import dataclasses
2
7
  from types import EllipsisType
3
8
  from typing import Mapping, NoReturn, Optional, Sequence
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  # Support for einops-style rearrangement strings, but supporting named axes and unordered matching
2
7
  import dataclasses
3
8
  import typing
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import dataclasses
2
7
  import functools as ft
3
8
  import inspect
@@ -16,7 +21,6 @@ from haliax.core import NamedArray
16
21
  from haliax.jax_utils import is_jax_array_like, multilevel_scan, tree_checkpoint_name
17
22
  from haliax.util import is_jax_or_hax_array_like, is_named_array
18
23
 
19
-
20
24
  BoolAxisSpec = Union[bool, Callable[[Any], bool]]
21
25
  Carry = TypeVar("Carry")
22
26
  X = TypeVar("X", contravariant=True)
@@ -31,8 +35,7 @@ def is_named_or_shaped_array_like(x):
31
35
  class ScanFn(Protocol[Carry, Args, Y]):
32
36
  """ """
33
37
 
34
- def __call__(self, carry: Carry, *args: Args.args, **kwargs: Args.kwargs) -> tuple[Carry, Y]:
35
- ...
38
+ def __call__(self, carry: Carry, *args: Args.args, **kwargs: Args.kwargs) -> tuple[Carry, Y]: ...
36
39
 
37
40
 
38
41
  @dataclasses.dataclass(frozen=True)
@@ -262,8 +265,7 @@ def scan(
262
265
  reverse: bool = False,
263
266
  unroll: int = 1,
264
267
  is_scanned: BoolAxisSpec = is_named_or_shaped_array_like,
265
- ) -> Callable[[Carry, PyTree[X]], tuple[Carry, PyTree[Y]]]:
266
- ...
268
+ ) -> Callable[[Carry, PyTree[X]], tuple[Carry, PyTree[Y]]]: ...
267
269
 
268
270
 
269
271
  @overload
@@ -275,8 +277,7 @@ def scan(
275
277
  reverse: bool = False,
276
278
  unroll: int = 1,
277
279
  is_scanned: BoolAxisSpec = is_named_or_shaped_array_like,
278
- ) -> Callable:
279
- ...
280
+ ) -> Callable: ...
280
281
 
281
282
 
282
283
  def scan(
@@ -444,8 +445,7 @@ def fold(
444
445
  reverse: bool = False,
445
446
  unroll: int = 1,
446
447
  is_scanned: BoolAxisSpec = is_named_or_shaped_array_like,
447
- ) -> Callable[[Carry, PyTree[X]], Carry]:
448
- ...
448
+ ) -> Callable[[Carry, PyTree[X]], Carry]: ...
449
449
 
450
450
 
451
451
  @overload
@@ -457,8 +457,7 @@ def fold(
457
457
  reverse: bool = False,
458
458
  unroll: int = 1,
459
459
  is_scanned: BoolAxisSpec = is_named_or_shaped_array_like,
460
- ) -> Callable:
461
- ...
460
+ ) -> Callable: ...
462
461
 
463
462
 
464
463
  def fold(
@@ -549,9 +548,7 @@ def _zero_if_array_else_none(x: Any) -> ResolvedUnnamedAxisSpec:
549
548
  return 0 if is_jax_array_like(x) else None
550
549
 
551
550
 
552
- def _format_tree_path(
553
- path: tuple[jtu.KeyEntry, ...], arg_pos_names: dict[int, str] | None = None
554
- ) -> str:
551
+ def _format_tree_path(path: tuple[jtu.KeyEntry, ...], arg_pos_names: dict[int, str] | None = None) -> str:
555
552
  parts: list[str] = []
556
553
  i = 0
557
554
  if len(path) >= 2 and isinstance(path[0], jtu.SequenceKey):
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  # Module to support torch-style "state dict" serialization via safetensors
2
7
  import dataclasses
3
8
  import typing
@@ -19,7 +24,6 @@ from haliax.core import NamedArray, named
19
24
  from haliax.jax_utils import is_jax_array_like, is_scalarish
20
25
  from haliax.tree_util import scan_aware_tree_map
21
26
 
22
-
23
27
  try:
24
28
  import safetensors
25
29
  except ImportError:
@@ -92,6 +96,7 @@ def _flatten_to_unflatten(t, state_dict, prefix):
92
96
  """
93
97
  Flatten the torch compatible state_dict before loading into t, and then recover the unflattened layers.
94
98
  """
99
+
95
100
  # typically, `t` is a bunch of ShapeDtypeStructs, which can't be transposed etc. so we instead have to zeros()
96
101
  # into real arrays (that aren't actually real b/c this is inside a jit)
97
102
  def _dt_struct_to_array(struct):
@@ -107,18 +112,15 @@ def _flatten_to_unflatten(t, state_dict, prefix):
107
112
 
108
113
 
109
114
  @typing.overload
110
- def with_prefix(prefix: str | None, leaf: str) -> str:
111
- ...
115
+ def with_prefix(prefix: str | None, leaf: str) -> str: ...
112
116
 
113
117
 
114
118
  @typing.overload
115
- def with_prefix(prefix: str, leaf: None) -> str:
116
- ...
119
+ def with_prefix(prefix: str, leaf: None) -> str: ...
117
120
 
118
121
 
119
122
  @typing.overload
120
- def with_prefix(prefix: Optional[str], leaf: Optional[str]) -> Optional[str]:
121
- ...
123
+ def with_prefix(prefix: Optional[str], leaf: Optional[str]) -> Optional[str]: ...
122
124
 
123
125
 
124
126
  def with_prefix(prefix: Optional[str], leaf: Optional[str]) -> Optional[str]:
@@ -1,5 +1,9 @@
1
- from typing import Callable, MutableMapping, Sequence, TypeAlias, TypeVar
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
2
5
 
6
+ from typing import Callable, MutableMapping, Sequence, TypeAlias, TypeVar
3
7
 
4
8
  T = TypeVar("T")
5
9
  U = TypeVar("U")
@@ -1,3 +1,8 @@
1
+ # Copyright 2025 The Levanter Authors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
1
6
  import typing
2
7
  from dataclasses import dataclass
3
8
  from math import prod
@@ -88,8 +93,7 @@ def selects_axis(selector: AxisSelection, selected: AxisSelection) -> bool:
88
93
  return True
89
94
 
90
95
 
91
- class _Sentinel:
92
- ...
96
+ class _Sentinel: ...
93
97
 
94
98
 
95
99
  def is_axis_compatible(ax1: AxisSelector, ax2: AxisSelector):
@@ -140,23 +144,19 @@ def axis_spec_to_shape_dict(axis_spec: AxisSelection) -> dict[str, Optional[int]
140
144
 
141
145
 
142
146
  @typing.overload
143
- def axis_spec_to_tuple(axis_spec: ShapeDict) -> tuple[Axis, ...]:
144
- ...
147
+ def axis_spec_to_tuple(axis_spec: ShapeDict) -> tuple[Axis, ...]: ...
145
148
 
146
149
 
147
150
  @typing.overload
148
- def axis_spec_to_tuple(axis_spec: AxisSpec) -> tuple[Axis, ...]:
149
- ...
151
+ def axis_spec_to_tuple(axis_spec: AxisSpec) -> tuple[Axis, ...]: ...
150
152
 
151
153
 
152
154
  @typing.overload
153
- def axis_spec_to_tuple(axis_spec: PartialShapeDict) -> tuple[AxisSelector, ...]:
154
- ...
155
+ def axis_spec_to_tuple(axis_spec: PartialShapeDict) -> tuple[AxisSelector, ...]: ...
155
156
 
156
157
 
157
158
  @typing.overload
158
- def axis_spec_to_tuple(axis_spec: AxisSelection) -> tuple[AxisSelector, ...]:
159
- ...
159
+ def axis_spec_to_tuple(axis_spec: AxisSelection) -> tuple[AxisSelector, ...]: ...
160
160
 
161
161
 
162
162
  def axis_spec_to_tuple(axis_spec: AxisSelection) -> tuple[AxisSelector, ...]:
@@ -230,23 +230,19 @@ def concat_axes(a1, a2):
230
230
 
231
231
 
232
232
  @typing.overload
233
- def union_axes(a1: ShapeDict, a2: AxisSpec) -> ShapeDict:
234
- ...
233
+ def union_axes(a1: ShapeDict, a2: AxisSpec) -> ShapeDict: ...
235
234
 
236
235
 
237
236
  @typing.overload
238
- def union_axes(a1: AxisSpec, a2: ShapeDict) -> ShapeDict:
239
- ...
237
+ def union_axes(a1: AxisSpec, a2: ShapeDict) -> ShapeDict: ...
240
238
 
241
239
 
242
240
  @typing.overload
243
- def union_axes(a1: AxisSpec, a2: AxisSpec) -> AxisSpec:
244
- ...
241
+ def union_axes(a1: AxisSpec, a2: AxisSpec) -> AxisSpec: ...
245
242
 
246
243
 
247
244
  @typing.overload
248
- def union_axes(a1: AxisSelection, a2: AxisSelection) -> AxisSelection:
249
- ...
245
+ def union_axes(a1: AxisSelection, a2: AxisSelection) -> AxisSelection: ...
250
246
 
251
247
 
252
248
  def union_axes(a1: AxisSelection, a2: AxisSelection) -> AxisSelection:
@@ -372,23 +368,19 @@ def without_axes(axis_spec: AxisSelection, to_remove: AxisSelection, allow_misma
372
368
 
373
369
 
374
370
  @typing.overload
375
- def unsize_axes(axis_spec: PartialShapeDict, to_unsize: AxisSelection) -> PartialShapeDict:
376
- ...
371
+ def unsize_axes(axis_spec: PartialShapeDict, to_unsize: AxisSelection) -> PartialShapeDict: ...
377
372
 
378
373
 
379
374
  @typing.overload
380
- def unsize_axes(axis_spec: AxisSelection, to_unsize: AxisSelection) -> AxisSelection:
381
- ...
375
+ def unsize_axes(axis_spec: AxisSelection, to_unsize: AxisSelection) -> AxisSelection: ...
382
376
 
383
377
 
384
378
  @typing.overload
385
- def unsize_axes(axis_spec: PartialShapeDict) -> PartialShapeDict:
386
- ...
379
+ def unsize_axes(axis_spec: PartialShapeDict) -> PartialShapeDict: ...
387
380
 
388
381
 
389
382
  @typing.overload
390
- def unsize_axes(axis_spec: AxisSelection) -> AxisSelection:
391
- ...
383
+ def unsize_axes(axis_spec: AxisSelection) -> AxisSelection: ...
392
384
 
393
385
 
394
386
  def unsize_axes(axis_spec: AxisSelection, to_unsize: Optional[AxisSelection] = None) -> AxisSelection:
@@ -424,13 +416,11 @@ def unsize_axes(axis_spec: AxisSelection, to_unsize: Optional[AxisSelection] = N
424
416
 
425
417
 
426
418
  @overload
427
- def replace_axis(axis_spec: AxisSpec, old: AxisSelector, new: AxisSpec) -> AxisSpec:
428
- ...
419
+ def replace_axis(axis_spec: AxisSpec, old: AxisSelector, new: AxisSpec) -> AxisSpec: ...
429
420
 
430
421
 
431
422
  @overload
432
- def replace_axis(axis_spec: AxisSelection, old: AxisSelector, new: AxisSelection) -> AxisSelection:
433
- ...
423
+ def replace_axis(axis_spec: AxisSelection, old: AxisSelector, new: AxisSelection) -> AxisSelection: ...
434
424
 
435
425
 
436
426
  def replace_axis(axis_spec: AxisSelection, old: AxisSelector, new: AxisSelection) -> AxisSelection:
@@ -466,13 +456,11 @@ def replace_axis(axis_spec: AxisSelection, old: AxisSelector, new: AxisSelection
466
456
 
467
457
 
468
458
  @overload
469
- def intersect_axes(ax1: ShapeDict, ax2: AxisSelection) -> ShapeDict:
470
- ...
459
+ def intersect_axes(ax1: ShapeDict, ax2: AxisSelection) -> ShapeDict: ...
471
460
 
472
461
 
473
462
  @overload
474
- def intersect_axes(ax1: tuple[AxisSelector, ...], ax2: AxisSpec) -> tuple[Axis, ...]:
475
- ...
463
+ def intersect_axes(ax1: tuple[AxisSelector, ...], ax2: AxisSpec) -> tuple[Axis, ...]: ...
476
464
 
477
465
 
478
466
  @overload
@@ -550,13 +538,11 @@ def axis_size(ax: AxisSpec) -> int:
550
538
 
551
539
 
552
540
  @typing.overload
553
- def resolve_axis(axis_spec: AxisSpec, axis_selection: AxisSelector) -> Axis:
554
- ...
541
+ def resolve_axis(axis_spec: AxisSpec, axis_selection: AxisSelector) -> Axis: ...
555
542
 
556
543
 
557
544
  @typing.overload
558
- def resolve_axis(axis_spec: AxisSpec, axis_selection: AxisSelection) -> AxisSpec:
559
- ...
545
+ def resolve_axis(axis_spec: AxisSpec, axis_selection: AxisSelection) -> AxisSpec: ...
560
546
 
561
547
 
562
548
  def resolve_axis(axis_spec: AxisSpec, axis_selection: AxisSelection) -> AxisSpec: