brainstate.transform.vmap2

Contents

brainstate.transform.vmap2#

brainstate.transform.vmap2(fn=<brainstate.typing.Missing object>, *, in_axes=0, out_axes=0, axis_name=None, axis_size=None, spmd_axis_name=None, state_in_axes=None, state_out_axes=None, unexpected_out_state_mapping='auto')#

Vectorize a callable while preserving BrainState state semantics.

This mirrors jax.vmap() but routes execution through StatefulMapping so reads and writes to State instances (including random states) are tracked across the mapped axis. The returned object can be used directly or as a decorator when fn is omitted.

Parameters:
Returns:

A StatefulMapping if fn is supplied, otherwise a decorator.

Return type:

StatefulMapping | Callable[[TypeVar(F, bound= Callable)], StatefulMapping]

Raises:
  • ValueError – If axis sizes are inconsistent or cannot be inferred.

  • BatchAxisError – If a state write violates state_out_axes under the 'raise' policy.

See also

brainstate.transform.StatefulMapping

Underlying state-aware mapping helper.

brainstate.transform.pmap2

Multi-device parallel variant.

brainstate.transform.vmap

Declaration-based vectorisation (now a shim).

Notes

Keyword arguments passed when calling the wrapped function are mapped over axis 0, matching jax.vmap() (they are not broadcast). To keep a keyword argument broadcast as a compile-time constant, construct a StatefulMapping directly and list it in static_argnames.

Examples

>>> import brainstate
>>> import jax.numpy as jnp
>>> from brainstate.util.filter import OfType
>>>
>>> counter = brainstate.ShortTermState(jnp.zeros(3))
>>>
>>> @brainstate.transform.vmap2(
...     in_axes=0,
...     out_axes=0,
...     state_in_axes={0: OfType(brainstate.ShortTermState)},
...     state_out_axes={0: OfType(brainstate.ShortTermState)},
... )
... def accumulate(x):
...     counter.value = counter.value + x
...     return counter.value
>>>
>>> accumulate(jnp.asarray([1., 2., 3.]))
Array([1., 2., 3.], dtype=float32)
>>> counter.value
Array([1., 2., 3.], dtype=float32)