FanAxes describes axis indices corresponding to input, output, and batch axes. Note: axes not listed in {in,out,batch}_axis are assumed to be the “receptive field” (convolution kernel spatial axes). Used for https://jax.readthedocs.io/en/latest/_autosummary/jax.nn.initializers.vari
| 22 | |
| 23 | |
| 24 | class FanAxes(NamedTuple): |
| 25 | """FanAxes describes axis indices corresponding to input, output, and batch axes. |
| 26 | |
| 27 | Note: axes not listed in {in,out,batch}_axis are assumed to be the “receptive field” |
| 28 | (convolution kernel spatial axes). |
| 29 | |
| 30 | Used for |
| 31 | https://jax.readthedocs.io/en/latest/_autosummary/jax.nn.initializers.variance_scaling.html. |
| 32 | """ |
| 33 | |
| 34 | class AxisType(Enum): |
| 35 | IN_AXIS = "in_axis" |
| 36 | OUT_AXIS = "out_axis" |
| 37 | BATCH_AXIS = "batch_axis" |
| 38 | NONE = None |
| 39 | |
| 40 | # Input axis or sequence of axes of the fan "input" dimension. |
| 41 | in_axis: Union[tuple[int, ...], int] |
| 42 | # Output axis or sequence of axes of the fan "output" dimension. |
| 43 | out_axis: Union[tuple[int, ...], int] |
| 44 | # Batch axis or sequence of axes that should be ignored when computing fan. |
| 45 | batch_axis: Union[tuple[int, ...], int] = () |
| 46 | |
| 47 | def canonicalize(self) -> "FanAxes": |
| 48 | """Returns a FanAxes equivalent to this one where all fields are tuples.""" |
| 49 | |
| 50 | def canonicalize(maybe_tuple: Union[None, int, Sequence[Union[int]]]) -> tuple[int, ...]: |
| 51 | if maybe_tuple is None: |
| 52 | return tuple() |
| 53 | if isinstance(maybe_tuple, int): |
| 54 | return (maybe_tuple,) |
| 55 | if isinstance(maybe_tuple, tuple): |
| 56 | return tuple(sorted(maybe_tuple)) |
| 57 | raise TypeError(f"Invalid type {type(maybe_tuple)} for data {maybe_tuple}.") |
| 58 | |
| 59 | axes = {} |
| 60 | for typ in self._fields: |
| 61 | axes[typ] = canonicalize(getattr(self, typ)) |
| 62 | return FanAxes(**axes) |
| 63 | |
| 64 | def __eq__(self, other): |
| 65 | if not isinstance(other, FanAxes): |
| 66 | return False |
| 67 | return self.canonicalize()._asdict() == other.canonicalize()._asdict() |
| 68 | |
| 69 | # We can't insert into other locations besides the start and end |
| 70 | # because FanAxes doesn't know the number of dimensions of the parameter shape. |
| 71 | def _insert_axis(self, axis: int, *, axis_type: "FanAxes.AxisType") -> "FanAxes": |
| 72 | """Returns a copy of this where a new axis of the given type has been inserted |
| 73 | at the given index, moving the other axes accordingly. |
| 74 | |
| 75 | Only 0 and -1 are supported for locations. |
| 76 | |
| 77 | Args: |
| 78 | axis: The index of the new axis. |
| 79 | axis_type: The type of axis to insert. |
| 80 | |
| 81 | Returns: |
no outgoing calls