braintrace 0.2.5__tar.gz → 0.2.6__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.
- {braintrace-0.2.5 → braintrace-0.2.6}/PKG-INFO +1 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/vjp_graph_executor.py +2 -2
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compatible_imports.py +133 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compatible_imports_test.py +74 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/graph.py +2 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hid_param_op.py +4 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hid_param_op_test.py +29 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hidden_group.py +14 -2
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hidden_group_test.py +43 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/scan_descent.py +2 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/scan_descent_test.py +14 -4
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/tests/compiler_oracle_test.py +5 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_version.py +1 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace.egg-info/PKG-INFO +1 -1
- {braintrace-0.2.5 → braintrace-0.2.6}/LICENSE +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/README.md +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/__init___test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/_common.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/_common_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/axes.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/axes_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/base.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/base_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/d_rtrl.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/d_rtrl_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/dni.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/dni_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/e_prop.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/e_prop_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/graph_executor.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/graph_executor_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/io_dim_vjp.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/io_dim_vjp_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/ostl.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/ostl_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/param_dim_vjp.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/param_dim_vjp_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/pp_prop.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/pp_prop_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/random_projection_vjp.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/random_projection_vjp_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/sequence.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/sequence_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/snap_n.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/snap_n_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/approx_correctness_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/axis_acceptance_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/axis_discrimination_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/axis_golden_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/conv_vmap_correctness_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/cross_check_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/diagnostic_exploration_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/exact_correctness_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/public_api_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/scan_descent_support_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/scan_fusion_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/snn_model_correctness_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/transform_correctness_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/while_support_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/three_factor.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/three_factor_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/uoro.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/uoro_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/vjp_base.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/vjp_base_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/vjp_graph_executor_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compile.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compile_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/base.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/base_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/canonicalize.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/canonicalize_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/diagnostics.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/diagnostics_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/graph_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hidden_pertubation.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/hidden_pertubation_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/jaxpr_graph.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/jaxpr_graph_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/module_info.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/module_info_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/position_graph.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/position_graph_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/report.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/report_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/tests/cell_relation_guardrail_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/tests/compiler_property_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_grad_exponential.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_grad_exponential_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_input_data.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_input_data_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_legacy/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_legacy/_ops.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_legacy/_ops_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_legacy/_params.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_legacy/_params_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_misc.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_misc_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/_primitive.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/_primitive_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/_registries.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/_registries_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/conv.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/conv_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/dense.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/dense_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/einsum.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/einsum_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/elemwise.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/elemwise_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/embedding.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/embedding_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/grouped.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/grouped_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/lora.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/lora_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/op_rule_oracle.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/op_rule_oracle_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/sparse.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_op/sparse_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_state_management.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_state_management_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/compiler_models.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/models.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/oracle.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/oracle_models.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/oracle_models_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/oracle_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/scenario_catalog.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_testing/scenario_catalog_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_typing.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_typing_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_version_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/__init__.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/__init___test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_conv.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_conv_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_embedding.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_embedding_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_linear.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_linear_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_readout.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_readout_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_rnn.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/nn/_rnn_test.py +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace/py.typed +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace.egg-info/SOURCES.txt +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace.egg-info/dependency_links.txt +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace.egg-info/requires.txt +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/braintrace.egg-info/top_level.txt +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/pyproject.toml +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/setup.cfg +0 -0
- {braintrace-0.2.5 → braintrace-0.2.6}/setup.py +0 -0
|
@@ -49,7 +49,7 @@ from brainstate._compatible_import import get_aval
|
|
|
49
49
|
from jax.interpreters import partial_eval as pe
|
|
50
50
|
from jax.tree_util import register_pytree_node_class
|
|
51
51
|
|
|
52
|
-
from braintrace._compatible_imports import Var, wrap_init
|
|
52
|
+
from braintrace._compatible_imports import Var, jaxpr_constvars, wrap_init
|
|
53
53
|
from braintrace._compiler import (
|
|
54
54
|
ControlFlowPolicy,
|
|
55
55
|
DEFAULT_MAX_JACOBIAN_ELEMENTS,
|
|
@@ -341,7 +341,7 @@ class ETraceVjpGraphExecutor(ETraceGraphExecutor):
|
|
|
341
341
|
y_stack = intermediate_values[m[relation.y_var]]
|
|
342
342
|
cvars = list(dict.fromkeys(
|
|
343
343
|
v for j in relation.y_to_hidden_group_jaxprs
|
|
344
|
-
for v in j
|
|
344
|
+
for v in jaxpr_constvars(j, 1)))
|
|
345
345
|
c_stacks = tuple(intermediate_values[m[v]] for v in cvars)
|
|
346
346
|
|
|
347
347
|
def _one_substep(
|
|
@@ -32,9 +32,12 @@ __all__ = [
|
|
|
32
32
|
'scan_num_consts_carry',
|
|
33
33
|
'scan_params_add_ys',
|
|
34
34
|
'wrap_init',
|
|
35
|
+
'jaxpr_all_invars',
|
|
36
|
+
'split_jaxpr_invars',
|
|
37
|
+
'jaxpr_constvars',
|
|
35
38
|
]
|
|
36
39
|
|
|
37
|
-
from typing import Any, Dict, Tuple
|
|
40
|
+
from typing import Any, Dict, List, Tuple
|
|
38
41
|
|
|
39
42
|
from brainstate._compatible_import import Primitive, Var, JaxprEqn, Jaxpr, ClosedJaxpr, Literal, wrap_init
|
|
40
43
|
|
|
@@ -146,3 +149,132 @@ def scan_params_add_ys(params: Dict, n_extra: int) -> Dict:
|
|
|
146
149
|
carry_ft, ys_ft = params['ft_out'].unpack()
|
|
147
150
|
new_ft_out = _ft.pack((carry_ft, _ft.pack((ys_ft, _ft.nones(n_extra)))))
|
|
148
151
|
return {**params, 'ft_out': new_ft_out}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def jaxpr_all_invars(jaxpr: Jaxpr) -> List[Var]:
|
|
155
|
+
"""Return every positional input of *jaxpr*, constvars first.
|
|
156
|
+
|
|
157
|
+
This is the argument order :func:`jax.core.eval_jaxpr` expects: it writes
|
|
158
|
+
``[*consts, *args]`` against exactly this list.
|
|
159
|
+
|
|
160
|
+
JAX 0.11 merged ``ClosedJaxpr`` into ``Jaxpr`` and now derives the
|
|
161
|
+
``constvars`` / ``invars`` boundary from how many const *values* are
|
|
162
|
+
attached, rather than storing it with the symbols. An open jaxpr built with
|
|
163
|
+
symbolic constvars and no attached values therefore reports
|
|
164
|
+
``constvars == []`` and ``invars == [*constvars, *invars]``. Their
|
|
165
|
+
concatenation is stable across every supported JAX version, which is why
|
|
166
|
+
every split in this module is derived from it.
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
jaxpr : Jaxpr
|
|
171
|
+
The jaxpr to inspect.
|
|
172
|
+
|
|
173
|
+
Returns
|
|
174
|
+
-------
|
|
175
|
+
list of Var
|
|
176
|
+
The concatenation ``[*jaxpr.constvars, *jaxpr.invars]``.
|
|
177
|
+
|
|
178
|
+
Examples
|
|
179
|
+
--------
|
|
180
|
+
.. code-block:: python
|
|
181
|
+
|
|
182
|
+
>>> import jax
|
|
183
|
+
>>> import jax.numpy as jnp
|
|
184
|
+
>>> from braintrace._compatible_imports import jaxpr_all_invars
|
|
185
|
+
>>> jaxpr = jax.make_jaxpr(lambda x, y: x * y)(jnp.ones(3), jnp.ones(3))
|
|
186
|
+
>>> len(jaxpr_all_invars(jaxpr.jaxpr))
|
|
187
|
+
2
|
|
188
|
+
"""
|
|
189
|
+
return [*jaxpr.constvars, *jaxpr.invars]
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def split_jaxpr_invars(jaxpr: Jaxpr, num_invars: int) -> Tuple[List[Var], List[Var]]:
|
|
193
|
+
"""Split *jaxpr*'s positional inputs into ``(constvars, invars)``.
|
|
194
|
+
|
|
195
|
+
The compiler builds transition jaxprs whose ``invars`` are the
|
|
196
|
+
differentiated inputs and whose ``constvars`` are surrounding intermediates
|
|
197
|
+
bound at execution time. Since JAX 0.11 that boundary cannot be read back
|
|
198
|
+
off the jaxpr (see :func:`jaxpr_all_invars`), so it is recovered from the
|
|
199
|
+
invar count, which every caller already knows -- the invars are what it is
|
|
200
|
+
about to feed in.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
jaxpr : Jaxpr
|
|
205
|
+
The jaxpr to split.
|
|
206
|
+
num_invars : int
|
|
207
|
+
The number of trailing positional inputs that are ``invars``. The
|
|
208
|
+
leading remainder are the ``constvars``.
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
-------
|
|
212
|
+
tuple of (list of Var, list of Var)
|
|
213
|
+
``(constvars, invars)``.
|
|
214
|
+
|
|
215
|
+
Raises
|
|
216
|
+
------
|
|
217
|
+
ValueError
|
|
218
|
+
If *num_invars* is negative or exceeds the number of positional inputs.
|
|
219
|
+
|
|
220
|
+
Examples
|
|
221
|
+
--------
|
|
222
|
+
.. code-block:: python
|
|
223
|
+
|
|
224
|
+
>>> import jax
|
|
225
|
+
>>> import jax.numpy as jnp
|
|
226
|
+
>>> from braintrace._compatible_imports import split_jaxpr_invars
|
|
227
|
+
>>> jaxpr = jax.make_jaxpr(lambda x, y: x * y)(jnp.ones(3), jnp.ones(3))
|
|
228
|
+
>>> constvars, invars = split_jaxpr_invars(jaxpr.jaxpr, 1)
|
|
229
|
+
>>> len(constvars), len(invars)
|
|
230
|
+
(1, 1)
|
|
231
|
+
"""
|
|
232
|
+
all_invars = jaxpr_all_invars(jaxpr)
|
|
233
|
+
if not 0 <= num_invars <= len(all_invars):
|
|
234
|
+
raise ValueError(
|
|
235
|
+
f'Cannot split a jaxpr with {len(all_invars)} positional inputs at '
|
|
236
|
+
f'num_invars={num_invars}. This means the caller and the jaxpr '
|
|
237
|
+
f'disagree about the transition signature; evaluating it would '
|
|
238
|
+
f'misalign the eval_jaxpr argument list.'
|
|
239
|
+
)
|
|
240
|
+
boundary = len(all_invars) - num_invars
|
|
241
|
+
return all_invars[:boundary], all_invars[boundary:]
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def jaxpr_constvars(jaxpr: Jaxpr, num_invars: int) -> List[Var]:
|
|
245
|
+
"""Return only the ``constvars`` of *jaxpr*, given its invar count.
|
|
246
|
+
|
|
247
|
+
Thin wrapper over :func:`split_jaxpr_invars` for the common case where the
|
|
248
|
+
caller needs the const values to pass to :func:`jax.core.eval_jaxpr` and
|
|
249
|
+
already holds the invars.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
jaxpr : Jaxpr
|
|
254
|
+
The jaxpr to inspect.
|
|
255
|
+
num_invars : int
|
|
256
|
+
The number of trailing positional inputs that are ``invars``.
|
|
257
|
+
|
|
258
|
+
Returns
|
|
259
|
+
-------
|
|
260
|
+
list of Var
|
|
261
|
+
The leading ``constvars``.
|
|
262
|
+
|
|
263
|
+
Raises
|
|
264
|
+
------
|
|
265
|
+
ValueError
|
|
266
|
+
If *num_invars* is negative or exceeds the number of positional inputs.
|
|
267
|
+
|
|
268
|
+
Examples
|
|
269
|
+
--------
|
|
270
|
+
.. code-block:: python
|
|
271
|
+
|
|
272
|
+
>>> import jax
|
|
273
|
+
>>> import jax.numpy as jnp
|
|
274
|
+
>>> from braintrace._compatible_imports import jaxpr_constvars
|
|
275
|
+
>>> jaxpr = jax.make_jaxpr(lambda x, y: x * y)(jnp.ones(3), jnp.ones(3))
|
|
276
|
+
>>> len(jaxpr_constvars(jaxpr.jaxpr, 1))
|
|
277
|
+
1
|
|
278
|
+
"""
|
|
279
|
+
constvars, _ = split_jaxpr_invars(jaxpr, num_invars)
|
|
280
|
+
return constvars
|
|
@@ -15,12 +15,16 @@
|
|
|
15
15
|
|
|
16
16
|
import types
|
|
17
17
|
|
|
18
|
+
import jax
|
|
18
19
|
import jax.numpy as jnp
|
|
20
|
+
import pytest
|
|
19
21
|
from jax import jit, make_jaxpr, lax
|
|
20
22
|
|
|
21
23
|
from braintrace._compatible_imports import (
|
|
24
|
+
Jaxpr,
|
|
22
25
|
is_jit_primitive, is_scan_primitive, is_while_primitive,
|
|
23
26
|
is_cond_primitive, scan_num_consts_carry, scan_params_add_ys,
|
|
27
|
+
jaxpr_all_invars, split_jaxpr_invars, jaxpr_constvars,
|
|
24
28
|
)
|
|
25
29
|
|
|
26
30
|
|
|
@@ -81,6 +85,76 @@ class TestScanAddYs:
|
|
|
81
85
|
assert len(new_ys) == len(old_ys) + 2 # ys grew by 2
|
|
82
86
|
|
|
83
87
|
|
|
88
|
+
def _open_jaxpr_with_split(num_constvars: int):
|
|
89
|
+
"""An open jaxpr built the way the compiler builds transition jaxprs.
|
|
90
|
+
|
|
91
|
+
Symbolic ``constvars`` with no attached const *values* -- the shape JAX
|
|
92
|
+
0.11 no longer records a boundary for. Returns ``(jaxpr, constvars,
|
|
93
|
+
invars)`` so a test can compare against the intended split rather than
|
|
94
|
+
whatever the object reports.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def f(a, b, h):
|
|
98
|
+
return a * h + b
|
|
99
|
+
|
|
100
|
+
traced = make_jaxpr(f)(jnp.ones(3), jnp.ones(3), jnp.ones(3)).jaxpr
|
|
101
|
+
all_in = jaxpr_all_invars(traced)
|
|
102
|
+
constvars, invars = all_in[:num_constvars], all_in[num_constvars:]
|
|
103
|
+
jaxpr = Jaxpr(
|
|
104
|
+
constvars=constvars,
|
|
105
|
+
invars=invars,
|
|
106
|
+
outvars=traced.outvars,
|
|
107
|
+
eqns=traced.eqns,
|
|
108
|
+
debug_info=traced.debug_info,
|
|
109
|
+
)
|
|
110
|
+
return jaxpr, constvars, invars
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class TestJaxprInvarSplit:
|
|
114
|
+
"""The const/invar split of a value-less open jaxpr survives JAX 0.11.
|
|
115
|
+
|
|
116
|
+
JAX 0.11 merged ``ClosedJaxpr`` into ``Jaxpr`` and derives
|
|
117
|
+
``constvars``/``invars`` from how many const *values* are attached, so an
|
|
118
|
+
open jaxpr built with symbolic constvars reports ``constvars == []``. These
|
|
119
|
+
helpers recover the boundary from the known invar count instead.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
def test_all_invars_is_the_eval_jaxpr_argument_order(self):
|
|
123
|
+
jaxpr, constvars, invars = _open_jaxpr_with_split(2)
|
|
124
|
+
assert jaxpr_all_invars(jaxpr) == [*constvars, *invars]
|
|
125
|
+
|
|
126
|
+
def test_split_recovers_the_intended_boundary(self):
|
|
127
|
+
jaxpr, constvars, invars = _open_jaxpr_with_split(2)
|
|
128
|
+
assert split_jaxpr_invars(jaxpr, len(invars)) == (constvars, invars)
|
|
129
|
+
assert jaxpr_constvars(jaxpr, len(invars)) == constvars
|
|
130
|
+
|
|
131
|
+
def test_the_recovered_consts_actually_evaluate(self):
|
|
132
|
+
# The regression that broke the whole suite on jaxlib 0.11.1: reading
|
|
133
|
+
# ``jaxpr.constvars`` back handed eval_jaxpr too few values.
|
|
134
|
+
jaxpr, _, invars = _open_jaxpr_with_split(2)
|
|
135
|
+
consts = [jnp.full((3,), 2.0), jnp.full((3,), 5.0)]
|
|
136
|
+
out = jax.core.eval_jaxpr(jaxpr, consts, jnp.full((3,), 3.0))
|
|
137
|
+
assert jnp.allclose(out[0], 2.0 * 3.0 + 5.0)
|
|
138
|
+
|
|
139
|
+
def test_zero_constvars_edge(self):
|
|
140
|
+
jaxpr, constvars, invars = _open_jaxpr_with_split(0)
|
|
141
|
+
assert constvars == []
|
|
142
|
+
assert jaxpr_constvars(jaxpr, len(invars)) == []
|
|
143
|
+
|
|
144
|
+
def test_all_constvars_edge(self):
|
|
145
|
+
jaxpr, constvars, invars = _open_jaxpr_with_split(3)
|
|
146
|
+
assert invars == []
|
|
147
|
+
assert jaxpr_constvars(jaxpr, 0) == constvars
|
|
148
|
+
|
|
149
|
+
@pytest.mark.parametrize('num_invars', [-1, 4])
|
|
150
|
+
def test_out_of_range_num_invars_raises(self, num_invars):
|
|
151
|
+
# A miscounted call must fail at the compiler boundary, not silently
|
|
152
|
+
# produce a misaligned eval_jaxpr argument list.
|
|
153
|
+
jaxpr, _, _ = _open_jaxpr_with_split(1)
|
|
154
|
+
with pytest.raises(ValueError, match='positional inputs'):
|
|
155
|
+
split_jaxpr_invars(jaxpr, num_invars)
|
|
156
|
+
|
|
157
|
+
|
|
84
158
|
class TestPrimitive:
|
|
85
159
|
def test_jit(self):
|
|
86
160
|
@jit
|
|
@@ -22,6 +22,7 @@ import brainstate
|
|
|
22
22
|
import jax
|
|
23
23
|
import numpy as np
|
|
24
24
|
|
|
25
|
+
from braintrace._compatible_imports import jaxpr_all_invars
|
|
25
26
|
from braintrace._misc import NotSupportedError
|
|
26
27
|
from braintrace._typing import (
|
|
27
28
|
ETraceVals,
|
|
@@ -571,7 +572,7 @@ def compile_etrace_graph(
|
|
|
571
572
|
if relation.control_flow_context is not None:
|
|
572
573
|
continue
|
|
573
574
|
for hpo_jaxpr in relation.y_to_hidden_group_jaxprs:
|
|
574
|
-
for v in hpo_jaxpr
|
|
575
|
+
for v in jaxpr_all_invars(hpo_jaxpr):
|
|
575
576
|
out_wy2hid_jaxvars_dict[v] = None
|
|
576
577
|
out_wy2hid_jaxvars = list(out_wy2hid_jaxvars_dict)
|
|
577
578
|
|
|
@@ -63,6 +63,7 @@ from braintrace._compatible_imports import (
|
|
|
63
63
|
is_scan_primitive,
|
|
64
64
|
is_while_primitive,
|
|
65
65
|
is_cond_primitive,
|
|
66
|
+
jaxpr_constvars,
|
|
66
67
|
)
|
|
67
68
|
from braintrace._op import (
|
|
68
69
|
get_trainable_invars,
|
|
@@ -248,7 +249,9 @@ class HiddenParamOpRelation(NamedTuple):
|
|
|
248
249
|
"""
|
|
249
250
|
vals_of_hidden_groups = []
|
|
250
251
|
for jaxpr, group in zip(self.y_to_hidden_group_jaxprs, self.hidden_groups):
|
|
251
|
-
|
|
252
|
+
# ``y`` is the jaxpr's only invar (see ``_build_transition_jaxpr``);
|
|
253
|
+
# everything ahead of it is a constvar bound from the forward pass.
|
|
254
|
+
consts = [const_vals[var] for var in jaxpr_constvars(jaxpr, 1)]
|
|
252
255
|
# ``list[Array]`` before concatenation, a single ``Array`` after.
|
|
253
256
|
hidden_vals: Any = jax.core.eval_jaxpr(jaxpr, consts, y_val)
|
|
254
257
|
if concat_hidden_vals:
|
|
@@ -195,3 +195,32 @@ class TestTrainableInvarsPopulatedForDense:
|
|
|
195
195
|
assert r.trainable_leaf_indices['weight'] == 0
|
|
196
196
|
assert r.trainable_processing_chains['weight'] == ()
|
|
197
197
|
assert r.trainable_param_states['weight'] is not None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class TestYToHiddenJaxprConstvarSplit:
|
|
201
|
+
"""The ``y -> hidden group`` jaxprs keep a recoverable const/invar split.
|
|
202
|
+
|
|
203
|
+
Since JAX 0.11 an open jaxpr with symbolic-only constvars reports
|
|
204
|
+
``constvars == []``, so the split is recovered from the invar count instead:
|
|
205
|
+
these jaxprs take exactly one invar, the relation's ``y_var``. The
|
|
206
|
+
executable counterpart of this assertion lives in
|
|
207
|
+
``_testing/scenario_catalog_test.py::test_gru_y_to_hidden_groups_executes``.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
def test_y_is_the_sole_invar_and_the_rest_are_constvars(self):
|
|
211
|
+
import jax.numpy as jnp
|
|
212
|
+
from braintrace._compatible_imports import jaxpr_all_invars, split_jaxpr_invars
|
|
213
|
+
|
|
214
|
+
gru = braintrace.nn.GRUCell(3, 4)
|
|
215
|
+
brainstate.nn.init_all_states(gru)
|
|
216
|
+
relations = find_hidden_param_op_relations_from_module(gru, jnp.zeros(3))
|
|
217
|
+
|
|
218
|
+
assert len(relations) > 0
|
|
219
|
+
checked = 0
|
|
220
|
+
for r in relations:
|
|
221
|
+
for jaxpr in r.y_to_hidden_group_jaxprs:
|
|
222
|
+
constvars, invars = split_jaxpr_invars(jaxpr, 1)
|
|
223
|
+
assert invars == [r.y_var]
|
|
224
|
+
assert constvars == jaxpr_all_invars(jaxpr)[:-1]
|
|
225
|
+
checked += 1
|
|
226
|
+
assert checked > 0
|
|
@@ -63,6 +63,7 @@ from braintrace._compatible_imports import (
|
|
|
63
63
|
is_scan_primitive,
|
|
64
64
|
is_while_primitive,
|
|
65
65
|
is_cond_primitive,
|
|
66
|
+
jaxpr_constvars,
|
|
66
67
|
scan_num_consts_carry,
|
|
67
68
|
)
|
|
68
69
|
from braintrace._op import is_etp_primitive, is_etp_enable_gradient_primitive
|
|
@@ -1621,6 +1622,11 @@ class JaxprEvalForHiddenGroup(JaxprEvaluation):
|
|
|
1621
1622
|
pattern = build_snap_pattern(
|
|
1622
1623
|
group.transition_jaxpr, group.varshape, self.sparse_n,
|
|
1623
1624
|
num_state=group.num_state,
|
|
1625
|
+
# Seed the adjacency walk from the hidden invars explicitly. Since
|
|
1626
|
+
# JAX 0.11 the jaxpr's own ``invars`` also lists the constvars, so
|
|
1627
|
+
# the implicit default would widen the seed set and inflate the
|
|
1628
|
+
# derived pattern (usually all the way to conservative).
|
|
1629
|
+
hidden_invars=group.hidden_invars,
|
|
1624
1630
|
max_jacobian_elements=self.snap_max_jacobian_elements,
|
|
1625
1631
|
)
|
|
1626
1632
|
if pattern.conservative:
|
|
@@ -1764,7 +1770,10 @@ class JaxprEvalForHiddenGroup(JaxprEvaluation):
|
|
|
1764
1770
|
for outvar in hidden_outvars
|
|
1765
1771
|
],
|
|
1766
1772
|
transition_jaxpr=jaxpr,
|
|
1767
|
-
|
|
1773
|
+
# ``write_jaxpr_of_hidden_group_transition`` gives the jaxpr one
|
|
1774
|
+
# invar per hidden state; the leading remainder are the
|
|
1775
|
+
# constvars bound from the forward pass.
|
|
1776
|
+
transition_jaxpr_constvars=jaxpr_constvars(jaxpr, len(hidden_invars)),
|
|
1768
1777
|
is_diagonal_recurrence=not self.include_recurrent_mixing,
|
|
1769
1778
|
)
|
|
1770
1779
|
group = self._attach_snap_pattern(group)
|
|
@@ -1832,7 +1841,10 @@ class JaxprEvalForHiddenGroup(JaxprEvaluation):
|
|
|
1832
1841
|
hidden_paths=[self.outvar_to_hidden_path[outvar]],
|
|
1833
1842
|
hidden_states=[self.path_to_state[self.outvar_to_hidden_path[outvar]]],
|
|
1834
1843
|
transition_jaxpr=zero_jaxpr,
|
|
1835
|
-
|
|
1844
|
+
# Mirrors ``zero_jaxpr``'s ``constvars=[outvar], invars=[invar]``
|
|
1845
|
+
# above -- read literally, not back off the jaxpr, which since
|
|
1846
|
+
# JAX 0.11 no longer records the boundary for a value-less split.
|
|
1847
|
+
transition_jaxpr_constvars=[outvar],
|
|
1836
1848
|
# A zero-recurrence transition (``D^t = 0``) is trivially diagonal;
|
|
1837
1849
|
# keep the flag mode-derived for uniformity (this fallback only
|
|
1838
1850
|
# fires in the default mode in practice).
|
|
@@ -1975,3 +1975,46 @@ class TestSplitHiddenWidthGuard:
|
|
|
1975
1975
|
assert len(parts) == 2
|
|
1976
1976
|
np.testing.assert_array_equal(np.asarray(parts[0]), np.ones((2, 3)))
|
|
1977
1977
|
np.testing.assert_array_equal(np.asarray(parts[1]), np.full((2, 3), 2.0))
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
from braintrace._compatible_imports import jaxpr_all_invars
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
class TestTransitionJaxprConstvarSplit:
|
|
1984
|
+
"""A compiled group's const/invar split stays intact on every JAX version.
|
|
1985
|
+
|
|
1986
|
+
JAX 0.11 merged ``ClosedJaxpr`` into ``Jaxpr`` and stopped recording the
|
|
1987
|
+
boundary for an open jaxpr with symbolic-only constvars, which is exactly
|
|
1988
|
+
what the compiler builds here. ``transition_jaxpr_constvars`` must therefore
|
|
1989
|
+
be carried explicitly rather than read back off the jaxpr.
|
|
1990
|
+
"""
|
|
1991
|
+
|
|
1992
|
+
def _gru_group(self):
|
|
1993
|
+
gru = braintrace.nn.GRUCell(3, 4)
|
|
1994
|
+
brainstate.nn.init_all_states(gru)
|
|
1995
|
+
groups, _ = find_hidden_groups_from_module(gru, brainstate.random.randn(3))
|
|
1996
|
+
assert len(groups) == 1
|
|
1997
|
+
return groups[0]
|
|
1998
|
+
|
|
1999
|
+
def test_constvars_are_the_leading_positional_inputs(self):
|
|
2000
|
+
group = self._gru_group()
|
|
2001
|
+
all_in = jaxpr_all_invars(group.transition_jaxpr)
|
|
2002
|
+
n_const = len(all_in) - len(group.hidden_invars)
|
|
2003
|
+
# A non-trivial split: reading ``.constvars`` back would give [] on 0.11.
|
|
2004
|
+
assert n_const > 0
|
|
2005
|
+
assert group.transition_jaxpr_constvars == all_in[:n_const]
|
|
2006
|
+
assert list(group.hidden_invars) == all_in[n_const:]
|
|
2007
|
+
|
|
2008
|
+
def test_the_transition_evaluates_with_those_constvars(self):
|
|
2009
|
+
# The arity failure that broke the suite on jaxlib 0.11.1 surfaces here.
|
|
2010
|
+
group = self._gru_group()
|
|
2011
|
+
input_vals = [
|
|
2012
|
+
jnp.zeros(v.aval.shape, v.aval.dtype)
|
|
2013
|
+
for v in group.transition_jaxpr_constvars
|
|
2014
|
+
]
|
|
2015
|
+
hidden_vals = [
|
|
2016
|
+
jnp.zeros(v.aval.shape, v.aval.dtype)
|
|
2017
|
+
for v in group.hidden_invars
|
|
2018
|
+
]
|
|
2019
|
+
out = group.transition(hidden_vals, input_vals)
|
|
2020
|
+
assert len(out) == len(group.hidden_outvars)
|
|
@@ -64,6 +64,7 @@ from braintrace._compatible_imports import (
|
|
|
64
64
|
is_cond_primitive,
|
|
65
65
|
is_scan_primitive,
|
|
66
66
|
is_while_primitive,
|
|
67
|
+
jaxpr_all_invars,
|
|
67
68
|
new_var,
|
|
68
69
|
scan_num_consts_carry,
|
|
69
70
|
scan_params_add_ys,
|
|
@@ -443,7 +444,7 @@ def analyze_and_rewrite_scan(eqn: JaxprEqn, minfo: 'ModuleInfo') -> Optional[Sca
|
|
|
443
444
|
if r.x_var is not None:
|
|
444
445
|
hoist_seen[r.x_var] = None
|
|
445
446
|
for j in r.y_to_hidden_group_jaxprs:
|
|
446
|
-
for v in
|
|
447
|
+
for v in jaxpr_all_invars(j):
|
|
447
448
|
hoist_seen[v] = None
|
|
448
449
|
for g in body_groups:
|
|
449
450
|
for v in list(g.hidden_invars) + list(g.transition_jaxpr_constvars):
|
|
@@ -13,7 +13,12 @@ import pytest
|
|
|
13
13
|
|
|
14
14
|
import braintrace
|
|
15
15
|
from braintrace import ControlFlowPolicy
|
|
16
|
-
from braintrace._compatible_imports import
|
|
16
|
+
from braintrace._compatible_imports import (
|
|
17
|
+
is_scan_primitive,
|
|
18
|
+
jaxpr_constvars,
|
|
19
|
+
scan_num_consts_carry,
|
|
20
|
+
split_jaxpr_invars,
|
|
21
|
+
)
|
|
17
22
|
from braintrace._compiler.module_info import extract_module_info
|
|
18
23
|
from braintrace._compiler.scan_descent import (
|
|
19
24
|
_descent_blockers,
|
|
@@ -219,8 +224,13 @@ class TestAnalyzeAndRewriteScan:
|
|
|
219
224
|
# outer-facing hidden vars are the scan carry vars, known to minfo
|
|
220
225
|
assert g.hidden_outvars[0] in minfo.outvar_to_hidden_path
|
|
221
226
|
assert g.hidden_invars[0] in minfo.invar_to_hidden_path
|
|
222
|
-
# body-scoped transition: one substep, invars == descent.body_hidden_invars
|
|
223
|
-
|
|
227
|
+
# body-scoped transition: one substep, invars == descent.body_hidden_invars.
|
|
228
|
+
# Split by invar count rather than reading ``.invars`` -- since JAX 0.11
|
|
229
|
+
# that also lists the constvars for a value-less open jaxpr.
|
|
230
|
+
_, transition_invars = split_jaxpr_invars(
|
|
231
|
+
g.transition_jaxpr, len(g.descent.body_hidden_invars)
|
|
232
|
+
)
|
|
233
|
+
assert list(transition_invars) == list(g.descent.body_hidden_invars)
|
|
224
234
|
|
|
225
235
|
assert len(bundle.relations) == 1
|
|
226
236
|
r = bundle.relations[0]
|
|
@@ -231,7 +241,7 @@ class TestAnalyzeAndRewriteScan:
|
|
|
231
241
|
m = bundle.info.stacked_var_map
|
|
232
242
|
assert r.x_var in m and r.y_var in m
|
|
233
243
|
for j in r.y_to_hidden_group_jaxprs:
|
|
234
|
-
assert all(v in m for v in j
|
|
244
|
+
assert all(v in m for v in jaxpr_constvars(j, 1))
|
|
235
245
|
assert all(v in m for v in g.descent.body_hidden_invars)
|
|
236
246
|
assert all(v in m for v in g.transition_jaxpr_constvars)
|
|
237
247
|
# stacked avals carry the substep axis
|
|
@@ -47,6 +47,7 @@ import jax.numpy as jnp
|
|
|
47
47
|
import numpy as np
|
|
48
48
|
|
|
49
49
|
from braintrace import compile_etrace_graph
|
|
50
|
+
from braintrace._compatible_imports import jaxpr_constvars
|
|
50
51
|
from braintrace._testing.scenario_catalog import (
|
|
51
52
|
ElemwiseOnlyRNN,
|
|
52
53
|
PartialPathRNN,
|
|
@@ -67,8 +68,11 @@ def _transition_callable(rel, group, const_vals):
|
|
|
67
68
|
The returned callable takes ``y_val`` and returns the *concatenated*
|
|
68
69
|
hidden state value for the matching group.
|
|
69
70
|
"""
|
|
70
|
-
consts = [const_vals[v] for v in rel.y_to_hidden_group_jaxprs[0].constvars]
|
|
71
71
|
jaxpr = rel.y_to_hidden_group_jaxprs[0]
|
|
72
|
+
# ``y`` is the jaxpr's sole invar; everything ahead of it is a constvar.
|
|
73
|
+
# Read via the helper, not ``jaxpr.constvars`` -- since JAX 0.11 an open
|
|
74
|
+
# jaxpr with symbolic-only constvars reports that as empty.
|
|
75
|
+
consts = [const_vals[v] for v in jaxpr_constvars(jaxpr, 1)]
|
|
72
76
|
|
|
73
77
|
def f(y_val):
|
|
74
78
|
out = jax.core.eval_jaxpr(jaxpr, consts, y_val)
|
|
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
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/approx_correctness_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/axis_discrimination_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/conv_vmap_correctness_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/diagnostic_exploration_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/scan_descent_support_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/snn_model_correctness_test.py
RENAMED
|
File without changes
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_algorithm/tests/transform_correctness_test.py
RENAMED
|
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
|
{braintrace-0.2.5 → braintrace-0.2.6}/braintrace/_compiler/tests/cell_relation_guardrail_test.py
RENAMED
|
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
|