Open alexeib opened 3 years ago
thanks @alexeib we will look into this
Also, when one of the overridden parameters is a path (containing /
), it totally messes up using override_dirname
for other directories (eg multirun subdir)
Good point!
One workaround is to use an OmegaConf custom resolver to come up with the output directory's name. For example:
# my_app.py
import hydra
from omegaconf import OmegaConf, ListConfig
def my_override_dirname(overrides: ListConfig) -> str:
"""Process the overrides passed to the app and return a single string"""
task_overrides: ListConfig = overrides.task
ret: str = "_".join(task_overrides)
ret = ret.replace("{", "")
ret = ret.replace("}", "")
ret = ret.replace("[", "")
ret = ret.replace("]", "")
ret = ret.replace(",", "_")
ret = ret.replace("/", "_")
ret = ret.replace("=", "-")
return ret
OmegaConf.register_new_resolver("my_override_dirname", my_override_dirname)
@hydra.main(config_path=".", config_name="config")
def app(cfg):
from hydra.core.hydra_config import HydraConfig
print(HydraConfig.get().runtime.output_dir)
...
app()
# config.yaml
hydra:
run:
dir: outputs/${now:%Y-%m-%d}_${my_override_dirname:${hydra.overrides}}
sweep:
dir: multirun/${now:%Y-%m-%d}
subdir: ${my_override_dirname:${hydra.overrides}}
Launching a single run:
$ python my_app.py +foo=bar
...
$ ls outputs/
2022-01-13_+foo-bar
Launching with --multirun
:
$ python my_app.py --multirun +foo=bar,baz
...
$ ls multirun/2022-01-13/
+foo-bar +foo-baz multirun.yaml
Note that instead of passing hydra.overrides
to the custom resolver, one
could just-as-well pass hydra.override_dirname
to a custom resolver for
postprocessing:
...
dir: outputs/${now:%Y-%m-%d}_${my_override_dirname_postprocessing:${hydra.override_dirname}}
Currently, when using "override_dirname" in sweep path, hydra will construct a directory name with the parameters unless excluded in the hydra.job.config.override_dirname option. Unfortunately when sweeping on parameters which are lists, dictionaries, or have commas in them, you end up with a directory name that while valid, usually breaks shell integrations and has to be quoted everywhere later. I hacked this in my local hydra install by modifying hydra/core/utils.py and adding
as the third line in run_job() function
it works for me, but obviously it is not a great solution. Any idea if there is existing support to do something like this, or if it can be added in future versions, maybe through expanding options in hydra.job.config.override_dirname?
Thanks!