diff --git a/sacred/experiment.py b/sacred/experiment.py index ef68ec81..897faaf6 100755 --- a/sacred/experiment.py +++ b/sacred/experiment.py @@ -56,6 +56,7 @@ def __init__( interactive: bool = False, base_dir: Optional[PathType] = None, additional_host_info: List[HostInfoGetter] = None, + nest_ingredients: bool = False, ): """ Create a new experiment with the given name and optional ingredients. @@ -117,6 +118,7 @@ def __init__( self.observers = [] self.current_run = None self.captured_out_filter = None + self.nest_ingredients = nest_ingredients """Filter function to be applied to captured output of a run""" self.option_hooks = [] diff --git a/sacred/initialize.py b/sacred/initialize.py index 1172ed91..55422a9e 100755 --- a/sacred/initialize.py +++ b/sacred/initialize.py @@ -470,6 +470,8 @@ def create_run( pre_runs, post_runs, experiment.captured_out_filter, + sorted_ingredients, + experiment.nest_ingredients, ) if hasattr(main_function, "unobserved"): diff --git a/sacred/run.py b/sacred/run.py index 7a9fa578..cc6aef87 100755 --- a/sacred/run.py +++ b/sacred/run.py @@ -11,6 +11,7 @@ from sacred.randomness import set_global_seed from sacred.utils import SacredInterrupt, join_paths, IntervalTimer from sacred.stdout_capturing import get_stdcapturer +from sacred.observers import FileStorageObserver class Run: @@ -29,6 +30,8 @@ def __init__( pre_run_hooks, post_run_hooks, captured_out_filter=None, + sorted_ingredients=None, + nest_ingredients=False, ): self._id = None @@ -112,6 +115,10 @@ def __init__( self.capture_mode = None """Determines the way the stdout/stderr are captured""" + self.sorted_ingredients = sorted_ingredients + + self.nest_ingredients = nest_ingredients + self._heartbeat = None self._failed_observers = [] self._output_file = None @@ -334,8 +341,19 @@ def _emit_started(self): ) if self._id is None: self._id = _id + if ( + observer.__class__.__name__ == "FileStorageObserver" + and self.nest_ingredients + ): + for ingredient in self.sorted_ingredients: + ingredient_observer_dir = os.path.join( + observer.dir, ingredient.path + ) + new_observer = FileStorageObserver.create(ingredient_observer_dir) + ingredient.observers.append(new_observer) # do not catch any exceptions on startup: # the experiment SHOULD fail if any of the observers fails + if self._id is None: self.run_logger.info("Started") else: