Hydra utils
Utility functions related to working with Hydra.
patched_safe_name #
Patches a bug in Hydra-zen where the target of inner classes is incorrect: https://github.com/mit-ll-responsible-ai/hydra-zen/issues/705
interpolate_config_attribute #
Use this in a config to to get an attribute from another config after it is instantiated.
Multiple attributes can be specified, which will lead to trying each of them in order until the attribute is found. If none are found, then an error will be raised.
For example, if we only know the number of classes in the datamodule after it is instantiated, we can set this in the network config so it is created with the right number of output dims.
This is equivalent to:
import hydra_zen import torchvision.models resnet50_config = hydra_zen.builds( ... torchvision.models.resnet50, ... num_classes=interpolate_config_attribute("datamodule.num_classes"), ... populate_full_signature=True, ... ) print(hydra_zen.to_yaml(resnet50_config)) # doctest: +NORMALIZE_WHITESPACE target: torchvision.models.resnet.resnet50 weights: null progress: true num_classes: ${instance_attr:datamodule.num_classes}
interpolated_field #
interpolated_field(
interpolation: str,
default: T | Literal[MISSING] = MISSING,
default_factory: (
Callable[[], T] | Literal[MISSING]
) = MISSING,
instance_attr: bool = False,
) -> T
Field with a default value computed with a OmegaConf-style interpolation when appropriate.
When the dataclass is created by Hydra / OmegaConf, the interpolation is used. Otherwise, behaves as usual (either using default or calling the default_factory).
Parameters#
interpolation: The string interpolation to use to get the default value.
default: The default value to use when not in a hydra/OmegaConf context.
default_factory: The default value to use when not in a hydra/OmegaConf context.
instance_attr: Whether to use the instance_attr
custom resolver to run the interpolation with respect to instantiated objects instead of their configs.
Passing interpolation='${instance_attr:some_config.some_attr}'
has the same effect.
This last parameter is important, since in order to retrieve the instance attribute, we need to instantiate the objects, which could be expensive. These instantiated objects are reused at least, but still, be mindful when using this parameter.
add_attributes #
add_attributes(fn: partial[T]) -> Partial[T]
Adds a getattr to the partial that returns the value in v.keywords
.
get_attr #
Recursive version of getattr
when the attribute is like 'a.b.c'.
register_instance_attr_resolver #
Registers the instance_attr
custom resolver with OmegaConf.
resolve_dictconfig #
resolve_dictconfig(dict_config: DictConfig) -> Config
Resolve all interpolations in the DictConfig
.
Returns a Config
object, which is a simple dataclass used to give
nicer type hints for the contents of an experiment config.
instance_attr #
instance_attr(
*attributes: str,
_instantiated_objects_cache: (
MutableMapping[str, Any] | None
) = None
)
Allows interpolations of the instantiated objects attributes (rather than configs).
This is very hacky
This is quite hacky and very dependent on the code of Hydra / OmegaConf not changing too much in the future. For this reason, consider pinning the versions of these libraries in your project if you intend do use this feature.
This works during a call to hydra.utils.instantiate
, by looking at the stack trace to find
the instantiated objects, which are in a variable in that function.
If there is a ${instance_attr:datamodule.num_classes}
interpolation in a config, this will:
- instantiate the
datamodule
config -
store it at the key
'datamodule'
in the instantiated objects cache dict (if passed).(This is useful since it makes it possible for us to later reuse this instantiated datamodule instead of re-instantiating it.)
-
Retrieve the value of the attribute (
getattr(datamodule, 'num_classes')
) and return it.
being_called_in_hydra_context #
being_called_in_hydra_context() -> bool
Returns True
if this function is being called indirectly by Hydra/OmegaConf.
Can be used in a field default factory to change the default value based on whether the config
is being instantiated by Hydra vs in code. For example, you could have a default value for a
field a
of a dataclass Foo
that is 'a=123when called in code, for example when doing
Foo()in a python file, but then when called by Hydra, the default value could be
a=${some_interpolation}`, so that Hydra/OmegaConf resolve that interpolation.
make_config_and_store #
make_config_and_store(
target: Callable[..., Target],
*,
store: ZenStore,
**overrides
)
Creates a config dataclass for the given target and stores it in the config store.
This uses hydra_zen.builds
to create the config dataclass and stores it at the name config_name
, or target.__name__
.