A pure functional call to `method_fn`.
| 1150 | Returns: |
| 1151 | The method output. |
| 1152 | |
| 1153 | Raises: |
| 1154 | ValueError: If invoking from outside of an InvocationContext, or a context with invalid |
| 1155 | module path. |
| 1156 | """ |
| 1157 | return self.forward(*args, **kwargs) |
| 1158 | |
| 1159 | |
| 1160 | @functools.partial(flax_struct.dataclass, frozen=False) |
| 1161 | class _Functional: # pytype: disable=invalid-annotation |
| 1162 | """A pure functional call to `method_fn`.""" |
| 1163 | |
| 1164 | # The function to call. |
| 1165 | method_fn: Callable = flax_struct.field(pytree_node=False) |
| 1166 | # The context to call method_fn in. |
| 1167 | # This will be copied to prevent method_fn from mutating the original. |
| 1168 | context: InvocationContext = flax_struct.field( |
| 1169 | pytree_node=True |
| 1170 | ) # pytype: disable=invalid-annotation |
| 1171 | # Whether to require that context.parent is current_context(). |
| 1172 | require_parent: bool = flax_struct.field(pytree_node=False) |
| 1173 | # Whether to copy the argument pytrees to prevent method_fn from mutating the original. |
| 1174 | copy_args_tree: bool = flax_struct.field(pytree_node=False, default=True) |
| 1175 | |
| 1176 | def __call__(self, *args, **kwargs) -> tuple[Any, OutputCollection]: |
| 1177 | """Invokes method_fn in a pure functional fashion. |
| 1178 | |
| 1179 | The invocation will not depend on external inputs or have any side effects. The results only |
| 1180 | depend on the given inputs. All outputs are reflected in the return value. |
| 1181 | |
| 1182 | Args: |
| 1183 | *args: Positional arguments to method_fn. |
| 1184 | **kwargs: Keyword arguments to method_fn. |
| 1185 | |
| 1186 | Returns: |
| 1187 | (method_outputs, output_collection), where |
| 1188 | - method_outputs are the return value of the method. |
| 1189 | - output_collection is an OutputCollection containing summaries and state updates. |
| 1190 | |
| 1191 | Raises: |
| 1192 | ValueError: If there are circular references in args, kwargs, or context. |
| 1193 | """ |
| 1194 | call = getattr(self.method_fn, "__qualname__", None) or getattr(self.method_fn, "__name__") |
| 1195 | logging.vlog(1, "functional: %s.%s (*%s, **%s)", call, self.method_fn, args, kwargs) |
| 1196 | |
| 1197 | # Some badly behaved tests call F() with an InvocationContext.state that contains |
| 1198 | # circular references. |
| 1199 | # This results in a cryptic error that doesn't make the root cause obvious. |
| 1200 | # So we raise a clearer error explicitly. |
| 1201 | raise_for_cycles(dict(context=self.context, args=args, kwargs=kwargs)) |
| 1202 | context = self.context |
| 1203 | if self.copy_args_tree: |
no outgoing calls
no test coverage detected