haliax 1.4.dev296__tar.gz → 1.4.dev298__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 (98) hide show
  1. {haliax-1.4.dev296 → haliax-1.4.dev298}/.github/workflows/run_tests.yaml +1 -7
  2. {haliax-1.4.dev296 → haliax-1.4.dev298}/PKG-INFO +2 -1
  3. {haliax-1.4.dev296 → haliax-1.4.dev298}/pyproject.toml +2 -0
  4. haliax-1.4.dev298/src/haliax/__about__.py +1 -0
  5. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/__init__.py +2 -0
  6. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/axis.py +13 -0
  7. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/core.py +6 -2
  8. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/embedding.py +9 -2
  9. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/linear.py +12 -2
  10. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/mlp.py +21 -4
  11. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_fp8.py +11 -7
  12. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_hof.py +32 -0
  13. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_partitioning.py +11 -16
  14. haliax-1.4.dev296/src/haliax/__about__.py +0 -1
  15. {haliax-1.4.dev296 → haliax-1.4.dev298}/.coveragerc +0 -0
  16. {haliax-1.4.dev296 → haliax-1.4.dev298}/.flake8 +0 -0
  17. {haliax-1.4.dev296 → haliax-1.4.dev298}/.github/workflows/publish_dev.yaml +0 -0
  18. {haliax-1.4.dev296 → haliax-1.4.dev298}/.github/workflows/run_pre_commit.yaml +0 -0
  19. {haliax-1.4.dev296 → haliax-1.4.dev298}/.gitignore +0 -0
  20. {haliax-1.4.dev296 → haliax-1.4.dev298}/.pre-commit-config.yaml +0 -0
  21. {haliax-1.4.dev296 → haliax-1.4.dev298}/.readthedocs.yaml +0 -0
  22. {haliax-1.4.dev296 → haliax-1.4.dev298}/CONTRIBUTING.md +0 -0
  23. {haliax-1.4.dev296 → haliax-1.4.dev298}/LICENSE +0 -0
  24. {haliax-1.4.dev296 → haliax-1.4.dev298}/README.md +0 -0
  25. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/api.md +0 -0
  26. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/broadcasting.md +0 -0
  27. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/cheatsheet.md +0 -0
  28. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/css/material.css +0 -0
  29. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/css/mkdocstrings.css +0 -0
  30. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/faq.md +0 -0
  31. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/data_parallel_mesh.png +0 -0
  32. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/data_parallel_mesh_replicated.png +0 -0
  33. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_1d.png +0 -0
  34. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_1d_zero.png +0 -0
  35. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d.png +0 -0
  36. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_batch_partitioned.png +0 -0
  37. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_data_replicated.png +0 -0
  38. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_data_replicated_mlp_partitioned.png +0 -0
  39. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_intermediate_fully_partitioned.png +0 -0
  40. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/figures/device_mesh_2d_zero.png +0 -0
  41. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/fp8.md +0 -0
  42. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/hof.md +0 -0
  43. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/index.md +0 -0
  44. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/indexing.md +0 -0
  45. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/matmul.md +0 -0
  46. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/nn.md +0 -0
  47. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/partitioning.md +0 -0
  48. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/rearrange.ipynb +0 -0
  49. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/rearrange.md +0 -0
  50. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/requirements.txt +0 -0
  51. {haliax-1.4.dev296 → haliax-1.4.dev298}/docs/tutorial.md +0 -0
  52. {haliax-1.4.dev296 → haliax-1.4.dev298}/mkdocs.yml +0 -0
  53. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/__init__.py +0 -0
  54. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/compile_utils.py +0 -0
  55. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/dot.py +0 -0
  56. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/einsum.py +0 -0
  57. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/fp8.py +0 -0
  58. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/parsing.py +0 -0
  59. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/rearrange.py +0 -0
  60. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/_src/util.py +0 -0
  61. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/debug.py +0 -0
  62. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/hof.py +0 -0
  63. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/jax_utils.py +0 -0
  64. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/__init__.py +0 -0
  65. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/activations.py +0 -0
  66. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/attention.py +0 -0
  67. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/conv.py +0 -0
  68. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/dropout.py +0 -0
  69. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/loss.py +0 -0
  70. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/normalization.py +0 -0
  71. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/pool.py +0 -0
  72. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/nn/scan.py +0 -0
  73. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/ops.py +0 -0
  74. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/partitioning.py +0 -0
  75. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/quantization.py +0 -0
  76. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/random.py +0 -0
  77. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/specialized_fns.py +0 -0
  78. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/tree_util.py +0 -0
  79. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/types.py +0 -0
  80. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/util.py +0 -0
  81. {haliax-1.4.dev296 → haliax-1.4.dev298}/src/haliax/wrap.py +0 -0
  82. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/core_test.py +0 -0
  83. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_attention.py +0 -0
  84. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_axis.py +0 -0
  85. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_conv.py +0 -0
  86. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_debug.py +0 -0
  87. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_dot.py +0 -0
  88. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_einsum.py +0 -0
  89. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_nn.py +0 -0
  90. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_ops.py +0 -0
  91. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_parsing.py +0 -0
  92. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_pool.py +0 -0
  93. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_random.py +0 -0
  94. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_rearrange.py +0 -0
  95. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_scan.py +0 -0
  96. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_specialized_fns.py +0 -0
  97. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_tree_util.py +0 -0
  98. {haliax-1.4.dev296 → haliax-1.4.dev298}/tests/test_utils.py +0 -0
@@ -21,13 +21,7 @@ jobs:
21
21
  python -m pip install --upgrade pip
22
22
  pip install flake8 pytest
23
23
  pip install --upgrade "jax[cpu]==0.4.25" "jaxlib[cpu]==0.4.25"
24
- pip install .
25
- # - name: Lint with flake8
26
- # run: |
27
- # # stop the build if there are Python syntax errors or undefined names
28
- # flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
29
- # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
30
- # flake8 . --count --exit-zero --max-complexity=50 --max-line-length=127 --statistics
24
+ pip install .[dev]
31
25
  - name: Test with pytest
32
26
  run: |
33
27
  XLA_FLAGS=--xla_force_host_platform_device_count=8 PYTHONPATH=tests:src:. pytest tests
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: haliax
3
- Version: 1.4.dev296
3
+ Version: 1.4.dev298
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/
@@ -17,6 +17,7 @@ Requires-Dist: equinox>=0.10.6
17
17
  Requires-Dist: jaxtyping>=0.2.20
18
18
  Requires-Dist: jmp>=0.0.4
19
19
  Provides-Extra: dev
20
+ Requires-Dist: chex>=0.1.86; extra == 'dev'
20
21
  Requires-Dist: mkdocs-include-markdown-plugin; extra == 'dev'
21
22
  Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'dev'
22
23
  Requires-Dist: mkdocs-macros-plugin>=0.7.0; extra == 'dev'
@@ -36,8 +36,10 @@ dev=["pytest >= 7.4.0", "mypy >= 0.910", "mkdocs >= 1.4.3", "mkdocs-material >=
36
36
  "pymdown-extensions",
37
37
  "pygments",
38
38
  "pymdown-extensions",
39
+ "chex>=0.1.86"
39
40
  ]
40
41
 
42
+
41
43
  [tool.hatch.version]
42
44
  path = "src/haliax/__about__.py"
43
45
 
@@ -0,0 +1 @@
1
+ __version__ = "1.4.dev298"
@@ -26,6 +26,7 @@ from .axis import (
26
26
  AxisSelector,
27
27
  AxisSpec,
28
28
  axis_name,
29
+ axis_size,
29
30
  concat_axes,
30
31
  dblock,
31
32
  ds,
@@ -55,6 +56,7 @@ from .core import (
55
56
  unflatten_axis,
56
57
  updated_slice,
57
58
  )
59
+ from .jax_utils import filter_checkpoint
58
60
  from .hof import fold, map, scan, vmap
59
61
  from .ops import clip, isclose, pad_left, trace, tril, triu, where
60
62
  from .partitioning import auto_sharded, axis_mapping, fsdp, named_jit, shard, shard_with_axis_mapping
@@ -1,5 +1,6 @@
1
1
  import typing
2
2
  from dataclasses import dataclass
3
+ from math import prod
3
4
  from types import EllipsisType
4
5
  from typing import Dict, List, Mapping, Optional, Sequence, Tuple, Union, overload
5
6
 
@@ -354,6 +355,17 @@ def axis_name(ax: AxisSelection) -> Union[str, Tuple[str, ...]]:
354
355
  return tuple(_ax_name(x) for x in ax)
355
356
 
356
357
 
358
+ def axis_size(ax: AxisSpec) -> int:
359
+ """
360
+ Returns the size of the axis or the product of the sizes of the axes in the axis spec
361
+ """
362
+
363
+ if isinstance(ax, Axis):
364
+ return ax.size
365
+ else:
366
+ return prod(axis.size for axis in ensure_tuple(ax)) # type: ignore
367
+
368
+
357
369
  class dslice(eqx.Module):
358
370
  """
359
371
  Dynamic slice, comprising a (start, length) pair. Also aliased as ds.
@@ -524,6 +536,7 @@ __all__ = [
524
536
  "PartialShapeDict",
525
537
  "ShapeDict",
526
538
  "axis_name",
539
+ "axis_size",
527
540
  "concat_axes",
528
541
  "union_axes",
529
542
  "axis_spec_to_shape_dict",
@@ -441,7 +441,11 @@ class NamedArray:
441
441
 
442
442
  @typing.overload
443
443
  def dot(
444
- self, *args, axis: Optional[AxisSelection], precision: PrecisionLike = None, dot_general=jax.lax.dot_general
444
+ self,
445
+ *args: "NamedArray",
446
+ axis: Optional[AxisSelection],
447
+ precision: PrecisionLike = None,
448
+ dot_general=jax.lax.dot_general,
445
449
  ) -> "NamedArray":
446
450
  ...
447
451
 
@@ -1143,7 +1147,7 @@ def flatten_axes(array: NamedArray, old_axes: AxisSelection, new_axis: AxisSelec
1143
1147
  """
1144
1148
  old_axes = ensure_tuple(old_axes)
1145
1149
  old_axes = array.resolve_axis(old_axes)
1146
- total_axis_size = prod(array.axis_size(ax) for ax in old_axes)
1150
+ total_axis_size = haliax.axis_size(old_axes)
1147
1151
 
1148
1152
  if isinstance(new_axis, Axis):
1149
1153
  if new_axis.size != total_axis_size:
@@ -1,4 +1,6 @@
1
1
  import dataclasses
2
+ import math
3
+ import warnings
2
4
  from typing import Optional
3
5
 
4
6
  import equinox as eqx
@@ -21,9 +23,14 @@ class Embedding(eqx.Module):
21
23
  Embed: AxisSpec = eqx.static_field()
22
24
 
23
25
  @staticmethod
24
- def init(Vocab: Axis, Embed: AxisSpec, initializer_range: float = 0.02, *, key):
26
+ def init(Vocab: Axis, Embed: AxisSpec, *, init_scale: float = 1, key, initializer_range: Optional[float] = None):
27
+ if initializer_range is not None:
28
+ warnings.warn("initializer_range is deprecated. Use init_std instead.", DeprecationWarning)
29
+ init_scale = initializer_range
30
+
25
31
  all_axes = (Vocab,) + ensure_tuple(Embed)
26
- weight = hax.random.normal(key, all_axes) * initializer_range
32
+ output_size = hax.axis_size(Embed)
33
+ weight = hax.random.truncated_normal(key, all_axes, -3, 3) * (init_scale / math.sqrt(output_size))
27
34
  return Embedding(weight=weight, Vocab=Vocab, Embed=Embed)
28
35
 
29
36
  def __call__(self, input_ids, *, key: Optional[PRNGKeyArray] = None):
@@ -1,3 +1,4 @@
1
+ import math
1
2
  from typing import Callable, Optional
2
3
 
3
4
  import equinox as eqx
@@ -25,7 +26,14 @@ class Linear(eqx.Module):
25
26
 
26
27
  @staticmethod
27
28
  def init(
28
- In: AxisSpec, Out: AxisSpec, *, key, use_bias=True, out_first: bool = False, dot_general=None
29
+ In: AxisSpec,
30
+ Out: AxisSpec,
31
+ *,
32
+ key,
33
+ use_bias=True,
34
+ out_first: bool = False,
35
+ dot_general=None,
36
+ init_scale: float = 1.0,
29
37
  ) -> "Linear":
30
38
  """
31
39
 
@@ -36,9 +44,11 @@ class Linear(eqx.Module):
36
44
  use_bias: bool: Whether to use a bias term
37
45
  out_first: bool: Whether to put output axes first in the weight matrix. out_first is how PyTorch does it.
38
46
  dot_general: Callable: The dot_general function to use. Defaults to jax.lax.dot_general. For fp8 or int8
47
+ init_scale: float: The scale to use for initialization. We scale init by 1/sqrt(Input.size)*init_scale
39
48
  """
40
49
  joint_spec = hax.concat_axis_specs(Out, In) if out_first else hax.concat_axis_specs(In, Out)
41
- weight = hax.random.normal(key, joint_spec) * 0.02
50
+ input_size = hax.axis_size(In)
51
+ weight = hax.random.truncated_normal(key, joint_spec, -3, 3) * (init_scale / math.sqrt(input_size))
42
52
  bias = hax.zeros(Out) if use_bias else None
43
53
 
44
54
  if dot_general is None:
@@ -48,6 +48,7 @@ class MLP(eqx.Module):
48
48
  use_final_bias: bool = True,
49
49
  key: PRNGKeyArray,
50
50
  dot_general: Optional[DotGeneralOp] = None,
51
+ init_scale: float = 1.0,
51
52
  ):
52
53
  Width = _get_width(width)
53
54
  Width2 = Width.alias(Width.name + "2")
@@ -58,18 +59,34 @@ class MLP(eqx.Module):
58
59
 
59
60
  if depth == 0:
60
61
  # special case: no hidden layers
61
- layers.append(Linear.init(Input, Output, use_bias=use_final_bias, key=keys[0], dot_general=dot_general))
62
+ layers.append(
63
+ Linear.init(
64
+ Input, Output, use_bias=use_final_bias, key=keys[0], dot_general=dot_general, init_scale=init_scale
65
+ )
66
+ )
62
67
  else:
63
68
  # first hidden layer
64
- layers.append(Linear.init(Input, Width, use_bias=use_bias, key=keys[0], dot_general=dot_general))
69
+ layers.append(
70
+ Linear.init(
71
+ Input, Width, use_bias=use_bias, key=keys[0], dot_general=dot_general, init_scale=init_scale
72
+ )
73
+ )
65
74
  # middle hidden layers
66
75
  cur = Width
67
76
  next = Width2
68
77
  for i in range(1, depth):
69
- layers.append(Linear.init(cur, next, use_bias=use_bias, key=keys[i], dot_general=dot_general))
78
+ layers.append(
79
+ Linear.init(
80
+ cur, next, use_bias=use_bias, key=keys[i], dot_general=dot_general, init_scale=init_scale
81
+ )
82
+ )
70
83
  cur, next = next, cur
71
84
  # final hidden layer
72
- layers.append(Linear.init(cur, Output, use_bias=use_final_bias, key=keys[-1], dot_general=dot_general))
85
+ layers.append(
86
+ Linear.init(
87
+ cur, Output, use_bias=use_final_bias, key=keys[-1], dot_general=dot_general, init_scale=init_scale
88
+ )
89
+ )
73
90
 
74
91
  return MLP(
75
92
  layers=tuple(layers),
@@ -1,8 +1,10 @@
1
+ import chex
1
2
  import equinox as eqx
2
3
  import jax.numpy as jnp
3
4
  import jax.random as jrandom
4
5
  import jax.tree_util
5
6
  import numpy as np
7
+ from chex import assert_trees_all_close
6
8
 
7
9
  import haliax as hax
8
10
  from haliax._src.fp8 import compute_scale
@@ -19,18 +21,20 @@ from haliax.quantization import (
19
21
  def test_fp8_is_reasonable():
20
22
  In = hax.Axis("In", 8)
21
23
  Out = hax.Axis("Out", 8)
22
- linear = Linear.init(In, Out, key=jrandom.PRNGKey(0))
24
+ linear = Linear.init(In, Out, key=jrandom.PRNGKey(0), init_scale=0.1)
23
25
 
24
- fp8_linear = Linear.init(In, Out, key=jrandom.PRNGKey(0), dot_general=hax.quantization.Fp8DotGeneralOp.init())
26
+ fp8_linear = Linear.init(
27
+ In, Out, key=jrandom.PRNGKey(0), dot_general=hax.quantization.Fp8DotGeneralOp.init(), init_scale=0.1
28
+ )
25
29
 
26
- input = hax.random.normal(jrandom.PRNGKey(0), In) * 10
30
+ input = hax.random.normal(jrandom.PRNGKey(3), In)
27
31
  output = linear(input)
28
32
  fp8_output = fp8_linear(input)
29
33
 
30
34
  assert output.shape == fp8_output.shape
31
35
  assert output.dtype == fp8_output.dtype
32
36
 
33
- assert jnp.allclose(output.array, fp8_output.array, atol=1e-1, rtol=1e-1)
37
+ assert_trees_all_close(output.array, fp8_output.array, atol=1e-2, rtol=5e-2)
34
38
 
35
39
 
36
40
  # https://github.com/google/flax/blob/6f2b08e024c2fd2f8cec42a6c82408cb35412319/tests/linen/linen_test.py#L1222
@@ -130,9 +134,9 @@ def test_fp_loop():
130
134
  def test_layer_splicing():
131
135
  key, init_key, random_key = jrandom.split(jrandom.PRNGKey(seed=123), 3)
132
136
  Input = hax.Axis("Input", 16)
133
- Hidden = hax.Axis("Hidden", 16)
137
+ Hidden = hax.Axis("Hidden", 64)
134
138
  Output = hax.Axis("Output", 32)
135
- mlp = hax.nn.MLP.init(Input, Output, Hidden, 3, key=init_key)
139
+ mlp = hax.nn.MLP.init(Input, Output, Hidden, 3, key=init_key, init_scale=0.1)
136
140
 
137
141
  mlp_q = fp8_linear_layers(mlp, Fp8Config())
138
142
  for layer in mlp_q.layers:
@@ -141,7 +145,7 @@ def test_layer_splicing():
141
145
  input = hax.random.normal(jrandom.PRNGKey(0), Input) * 10 # 10 so we don't underflow
142
146
  output = mlp(input)
143
147
  output_q = mlp_q(input)
144
- assert jnp.allclose(output.array, output_q.array, atol=1e-3, rtol=1e-3)
148
+ chex.assert_trees_all_close(output.array, output_q.array, atol=1e-3, rtol=1e-3)
145
149
  assert not jnp.allclose(output_q.array, 0) # don't want them to all underflow
146
150
 
147
151
  mlp_q = fp8_linear_layers(mlp, Fp8Config(targets="layers.0"))
@@ -87,6 +87,38 @@ def test_scan_doesnt_scan_scalars():
87
87
  assert jnp.all(jnp.equal(selected.array, named1.array * 4.0))
88
88
 
89
89
 
90
+ def test_scan_doesnt_scan_init():
91
+ Height = Axis("Height", 10)
92
+ named1 = hax.random.uniform(PRNGKey(0), (Height,))
93
+
94
+ init = jnp.arange(Height.size, dtype=jnp.float32)
95
+
96
+ def scan_fun(acc, z, x):
97
+ out = acc + z * x, x * z
98
+ return out
99
+
100
+ total, selected = hax.scan(scan_fun, Height)(init, 4.0, named1)
101
+
102
+ assert jnp.all(jnp.isclose(total, init + jnp.sum(named1.array * 4.0)))
103
+
104
+ # double check with named array init
105
+ total, selected = hax.scan(scan_fun, Height)(hax.named(init, "Height"), 4.0, named1)
106
+
107
+ assert jnp.all(jnp.isclose(total.array, init + jnp.sum(named1.array * 4.0)))
108
+
109
+ # now do fold
110
+ def fold_fun(acc, z, x):
111
+ return acc + z * x
112
+
113
+ total = hax.fold(fold_fun, Height)(init, 4.0, named1)
114
+
115
+ assert jnp.all(jnp.isclose(total, init + jnp.sum(named1.array * 4.0)))
116
+
117
+ total = hax.fold(fold_fun, Height)(hax.named(init, "Height"), 4.0, named1)
118
+
119
+ assert jnp.all(jnp.isclose(total.array, init + jnp.sum(named1.array * 4.0)))
120
+
121
+
90
122
  def test_reduce():
91
123
  Height = Axis("Height", 10)
92
124
  Width = Axis("Width", 3)
@@ -108,26 +108,21 @@ def test_pjit_class_init_with_args():
108
108
  def test_infer_resource_partition_gda_bug():
109
109
  devices = jax.devices()
110
110
  with Mesh(np.array(devices).reshape(-1, 1), (ResourceAxis.DATA, ResourceAxis.MODEL)):
111
- jax.config.update("jax_parallel_functions_output_gda", True)
112
- try:
113
111
 
114
- def foo():
115
- return hax.zeros((Dim1, Dim2, Dim3))
112
+ def foo():
113
+ return hax.zeros((Dim1, Dim2, Dim3))
116
114
 
117
- pjit_foo = named_jit(foo, resource_map)
118
- r = pjit_foo()
119
- assert r.axes == (Dim1, Dim2, Dim3)
115
+ pjit_foo = named_jit(foo, resource_map)
116
+ r = pjit_foo()
117
+ assert r.axes == (Dim1, Dim2, Dim3)
120
118
 
121
- def bar(x):
122
- return x
123
-
124
- # this won't work with GDAs
125
- pjit_bar = named_jit(bar, resource_map)
126
- r = pjit_bar(r)
127
- assert r.axes == (Dim1, Dim2, Dim3)
119
+ def bar(x):
120
+ return x
128
121
 
129
- finally:
130
- jax.config.update("jax_parallel_functions_output_gda", False)
122
+ # this won't work with GDAs
123
+ pjit_bar = named_jit(bar, resource_map)
124
+ r = pjit_bar(r)
125
+ assert r.axes == (Dim1, Dim2, Dim3)
131
126
 
132
127
 
133
128
  @skip_if_not_enough_devices(4)
@@ -1 +0,0 @@
1
- __version__ = "1.4.dev296"
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