colosseum.experiment.utils

  1import os
  2from glob import glob
  3from typing import Dict, List, Optional, Type, Union
  4
  5import gin
  6import yaml
  7from tqdm import tqdm
  8
  9from colosseum import config
 10from colosseum.agent.agents.base import BaseAgent
 11from colosseum.agent.utils import sample_n_agent_hyperparameters
 12from colosseum.experiment import ExperimentConfig
 13from colosseum.experiment.folder_structuring import (
 14    get_mdp_agent_gin_configs,
 15    get_experiment_config,
 16)
 17from colosseum.mdp import BaseMDP
 18from colosseum.utils import ensure_folder
 19from colosseum.utils.miscellanea import get_colosseum_agent_classes
 20from colosseum.utils.miscellanea import get_colosseum_mdp_classes
 21
 22
 23def apply_gin_config(gin_config_files_paths: List[str]):
 24    """
 25    binds the gin files configuration to the corresponding objects.
 26    """
 27
 28    import gin
 29
 30    gin.clear_config()
 31
 32    get_colosseum_mdp_classes()
 33    get_colosseum_agent_classes()
 34
 35    for config_file in gin_config_files_paths:
 36        gin.parse_config_file(config_file)
 37
 38
 39def check_same_experiment(folder_1: str, folder_2: str, exclude_config: bool = False):
 40    """
 41    checks whether all the files from folder_1 perfectly match the configuration files in folder_2.
 42    """
 43
 44    # Check same experiment configuration
 45    if not exclude_config:
 46        with open(ensure_folder(folder_1) + "experiment_config.yml", "r") as f:
 47            config_1 = yaml.load(f, yaml.Loader)
 48        with open(ensure_folder(folder_2) + "experiment_config.yml", "r") as f:
 49            config_2 = yaml.load(f, yaml.Loader)
 50        if config_1 != config_2:
 51            return False
 52
 53    # Check same MDP configs
 54    mdp_configs_1 = set(os.listdir(ensure_folder(folder_1) + "mdp_configs"))
 55    mdp_configs_2 = set(os.listdir(ensure_folder(folder_2) + "mdp_configs"))
 56    if mdp_configs_1 != mdp_configs_2:
 57        return False
 58    for mdp_config in mdp_configs_1:
 59        with open(ensure_folder(folder_1) + "mdp_configs" + os.sep + mdp_config) as f:
 60            mdp_config_1 = f.read()
 61        with open(ensure_folder(folder_2) + "mdp_configs" + os.sep + mdp_config) as f:
 62            mdp_config_2 = f.read()
 63        if mdp_config_1 != mdp_config_2:
 64            return False
 65
 66    # Check same agent configs
 67    if "agents_configs" in os.listdir(ensure_folder(folder_1)):
 68        agent_configs_1 = set(os.listdir(ensure_folder(folder_1) + "agents_configs"))
 69        agent_configs_2 = set(os.listdir(ensure_folder(folder_2) + "agents_configs"))
 70        if agent_configs_1 != agent_configs_2:
 71            return False
 72        for agent_config in agent_configs_1:
 73            with open(
 74                ensure_folder(folder_1) + "agents_configs" + os.sep + agent_config
 75            ) as f:
 76                agent_config_1 = f.read()
 77            with open(
 78                ensure_folder(folder_2) + "agents_configs" + os.sep + agent_config
 79            ) as f:
 80                agent_config_2 = f.read()
 81            if agent_config_1 != agent_config_2:
 82                return False
 83
 84    return True
 85
 86
 87def check_experiments_to_run_folders_formatting(
 88    experiment_configs: Optional[Dict[str, ExperimentConfig]] = None
 89):
 90    """
 91    checks whether there are problems in the structure of the experiments folders.
 92    """
 93    experiment_folders = glob(config.get_experiments_folder() + "**")
 94    assert (
 95        len(experiment_folders) > 0
 96    ), f"No experiment folder found in {config.get_experiment_to_run_folder()}."
 97
 98    for experiment_folder in experiment_folders:
 99        check_experiment_folder(experiment_folder, experiment_configs)
100
101
102def check_experiment_folder(
103    experiment_folder: str,
104    experiment_config: Union[str, ExperimentConfig] = None,
105):
106    """
107    checks the integrity of the experiment folder.
108    """
109
110    assert os.path.isdir(
111        experiment_folder
112    ), f"The file {experiment_folder} is not a directory, please remove it."
113
114    assert "agents_configs" in os.listdir(
115        experiment_folder
116    ), f"The experiment folder {experiment_folder} is missing the agents_configs folder."
117    assert "mdp_configs" in os.listdir(
118        experiment_folder
119    ), f"The experiment folder {experiment_folder} is missing the mdp_configs folder."
120    b_config_file = "experiment_config.yml" in os.listdir(experiment_folder)
121
122    experiment_name = experiment_folder[experiment_folder.rfind(os.sep) + 1 :]
123    assert (
124        experiment_config is not None or b_config_file
125    ), "The experiment configuration should be either provided as a .yml file or as an ExperimentConfig object."
126    if b_config_file:
127        config_file = ensure_folder(experiment_folder) + "experiment_config.yml"
128        with open(config_file, "r") as f:
129            experiment_config = yaml.load(f, yaml.Loader)
130        assert (
131            "n_seeds" in experiment_config.keys()
132        ), f"n_seeds missing from {config_file}."
133        assert (
134            "n_steps" in experiment_config.keys()
135        ), f"n_steps missing from {config_file}."
136        assert (
137            "max_interaction_time_s" in experiment_config.keys()
138        ), f"max_interaction_time_s missing from {config_file}."
139        assert (
140            "log_performance_indicators_every" in experiment_config.keys()
141        ), f"log_performance_indicators_every missing from {config_file}."
142    else:
143        assert (
144            type(experiment_config) == ExperimentConfig
145        ), "The experiment configuration should be given as an ExperimentConfig object."
146
147    from colosseum.experiment.folder_structuring import remove_corrupted_log_files
148
149    remove_corrupted_log_files(experiment_folder, ExperimentConfig(**experiment_config))
150
151
152def instantiate_gin_files(
153    dest_folder: str,
154    agent_classes: List[Type["BaseAgent"]],
155    mdp_classes: List[Type["BaseMDP"]],
156    n_samples_agents: int,
157    n_samples_mdps: int,
158    seed: int,
159) -> List[str]:
160    """
161    produces and instantiates gin files from samples of the given MDP and Agent classes in the destination folder.
162    Returns
163    -------
164    List[str]
165        The file paths of the gin files
166    """
167    os.makedirs(dest_folder, exist_ok=True)
168
169    # Store gin files for MDPs
170    gin_files = []
171    for mdp_class in mdp_classes:
172        fp = (
173            ensure_folder(dest_folder)
174            + "mdp_configs"
175            + os.sep
176            + mdp_class.__name__
177            + ".gin"
178        )
179        gin_files.append(fp)
180        with open(fp, "w") as f:
181            f.write(
182                "\n\n".join(
183                    mdp_class.produce_gin_file_from_mdp_parameters(
184                        mdp_hyperparameters, mdp_class.__name__, i
185                    )
186                    for i, mdp_hyperparameters in enumerate(
187                        mdp_class.sample_parameters(n_samples_mdps, seed)
188                    )
189                )
190            )
191
192    # Store gin file for agents
193    for agent_class in agent_classes:
194        fp = (
195            ensure_folder(dest_folder)
196            + "agents_configs"
197            + os.sep
198            + agent_class.__name__
199            + ".gin"
200        )
201        gin_files.append(fp)
202        with open(fp, "w") as f:
203            f.write(
204                "\n\n".join(
205                    agent_class.produce_gin_file_from_parameters(
206                        agent_hyperparameter, i
207                    )
208                    for i, agent_hyperparameter in enumerate(
209                        sample_n_agent_hyperparameters(
210                            n_samples_agents, agent_class, seed
211                        )
212                    )
213                )
214            )
215
216    return gin_files
217
218
219def instantiate_mdps_from_experiment_folder(
220    experiment_folder: str, exclude_horizon_from_parameters=False
221) -> List["BaseMDP"]:
222    """
223    Returns
224    -------
225    List["BaseMDP"]
226        The MDP instances corresponding to the experiment folder in input.
227    """
228    (
229        mdp_classes_scopes,
230        agent_classes_scopes,
231        gin_config_files_paths,
232    ) = get_mdp_agent_gin_configs(experiment_folder)
233    exp_config = get_experiment_config(experiment_folder, None)
234
235    loop = mdp_classes_scopes.items()
236    if config.VERBOSE_LEVEL != 0:
237        loop = tqdm(loop, desc=os.path.basename(experiment_folder))
238
239    mdps = []
240    for mdp_class, mdp_scopes in loop:
241        for mdp_scope in mdp_scopes:
242            apply_gin_config(gin_config_files_paths)
243            with gin.config_scope(mdp_scope):
244                for seed in range(exp_config.n_seeds):
245                    mdps.append(
246                        mdp_class(
247                            seed=seed,
248                            exclude_horizon_from_parameters=exclude_horizon_from_parameters,
249                        )
250                    )
251
252    return mdps
def apply_gin_config(gin_config_files_paths: List[str]):
24def apply_gin_config(gin_config_files_paths: List[str]):
25    """
26    binds the gin files configuration to the corresponding objects.
27    """
28
29    import gin
30
31    gin.clear_config()
32
33    get_colosseum_mdp_classes()
34    get_colosseum_agent_classes()
35
36    for config_file in gin_config_files_paths:
37        gin.parse_config_file(config_file)

binds the gin files configuration to the corresponding objects.

def check_same_experiment(folder_1: str, folder_2: str, exclude_config: bool = False):
40def check_same_experiment(folder_1: str, folder_2: str, exclude_config: bool = False):
41    """
42    checks whether all the files from folder_1 perfectly match the configuration files in folder_2.
43    """
44
45    # Check same experiment configuration
46    if not exclude_config:
47        with open(ensure_folder(folder_1) + "experiment_config.yml", "r") as f:
48            config_1 = yaml.load(f, yaml.Loader)
49        with open(ensure_folder(folder_2) + "experiment_config.yml", "r") as f:
50            config_2 = yaml.load(f, yaml.Loader)
51        if config_1 != config_2:
52            return False
53
54    # Check same MDP configs
55    mdp_configs_1 = set(os.listdir(ensure_folder(folder_1) + "mdp_configs"))
56    mdp_configs_2 = set(os.listdir(ensure_folder(folder_2) + "mdp_configs"))
57    if mdp_configs_1 != mdp_configs_2:
58        return False
59    for mdp_config in mdp_configs_1:
60        with open(ensure_folder(folder_1) + "mdp_configs" + os.sep + mdp_config) as f:
61            mdp_config_1 = f.read()
62        with open(ensure_folder(folder_2) + "mdp_configs" + os.sep + mdp_config) as f:
63            mdp_config_2 = f.read()
64        if mdp_config_1 != mdp_config_2:
65            return False
66
67    # Check same agent configs
68    if "agents_configs" in os.listdir(ensure_folder(folder_1)):
69        agent_configs_1 = set(os.listdir(ensure_folder(folder_1) + "agents_configs"))
70        agent_configs_2 = set(os.listdir(ensure_folder(folder_2) + "agents_configs"))
71        if agent_configs_1 != agent_configs_2:
72            return False
73        for agent_config in agent_configs_1:
74            with open(
75                ensure_folder(folder_1) + "agents_configs" + os.sep + agent_config
76            ) as f:
77                agent_config_1 = f.read()
78            with open(
79                ensure_folder(folder_2) + "agents_configs" + os.sep + agent_config
80            ) as f:
81                agent_config_2 = f.read()
82            if agent_config_1 != agent_config_2:
83                return False
84
85    return True

checks whether all the files from folder_1 perfectly match the configuration files in folder_2.

def check_experiments_to_run_folders_formatting( experiment_configs: Optional[Dict[str, colosseum.experiment.config.ExperimentConfig]] = None):
 88def check_experiments_to_run_folders_formatting(
 89    experiment_configs: Optional[Dict[str, ExperimentConfig]] = None
 90):
 91    """
 92    checks whether there are problems in the structure of the experiments folders.
 93    """
 94    experiment_folders = glob(config.get_experiments_folder() + "**")
 95    assert (
 96        len(experiment_folders) > 0
 97    ), f"No experiment folder found in {config.get_experiment_to_run_folder()}."
 98
 99    for experiment_folder in experiment_folders:
100        check_experiment_folder(experiment_folder, experiment_configs)

checks whether there are problems in the structure of the experiments folders.

def check_experiment_folder( experiment_folder: str, experiment_config: Union[str, colosseum.experiment.config.ExperimentConfig] = None):
103def check_experiment_folder(
104    experiment_folder: str,
105    experiment_config: Union[str, ExperimentConfig] = None,
106):
107    """
108    checks the integrity of the experiment folder.
109    """
110
111    assert os.path.isdir(
112        experiment_folder
113    ), f"The file {experiment_folder} is not a directory, please remove it."
114
115    assert "agents_configs" in os.listdir(
116        experiment_folder
117    ), f"The experiment folder {experiment_folder} is missing the agents_configs folder."
118    assert "mdp_configs" in os.listdir(
119        experiment_folder
120    ), f"The experiment folder {experiment_folder} is missing the mdp_configs folder."
121    b_config_file = "experiment_config.yml" in os.listdir(experiment_folder)
122
123    experiment_name = experiment_folder[experiment_folder.rfind(os.sep) + 1 :]
124    assert (
125        experiment_config is not None or b_config_file
126    ), "The experiment configuration should be either provided as a .yml file or as an ExperimentConfig object."
127    if b_config_file:
128        config_file = ensure_folder(experiment_folder) + "experiment_config.yml"
129        with open(config_file, "r") as f:
130            experiment_config = yaml.load(f, yaml.Loader)
131        assert (
132            "n_seeds" in experiment_config.keys()
133        ), f"n_seeds missing from {config_file}."
134        assert (
135            "n_steps" in experiment_config.keys()
136        ), f"n_steps missing from {config_file}."
137        assert (
138            "max_interaction_time_s" in experiment_config.keys()
139        ), f"max_interaction_time_s missing from {config_file}."
140        assert (
141            "log_performance_indicators_every" in experiment_config.keys()
142        ), f"log_performance_indicators_every missing from {config_file}."
143    else:
144        assert (
145            type(experiment_config) == ExperimentConfig
146        ), "The experiment configuration should be given as an ExperimentConfig object."
147
148    from colosseum.experiment.folder_structuring import remove_corrupted_log_files
149
150    remove_corrupted_log_files(experiment_folder, ExperimentConfig(**experiment_config))

checks the integrity of the experiment folder.

def instantiate_gin_files( dest_folder: str, agent_classes: List[Type[colosseum.agent.agents.base.BaseAgent]], mdp_classes: List[Type[colosseum.mdp.base.BaseMDP]], n_samples_agents: int, n_samples_mdps: int, seed: int) -> List[str]:
153def instantiate_gin_files(
154    dest_folder: str,
155    agent_classes: List[Type["BaseAgent"]],
156    mdp_classes: List[Type["BaseMDP"]],
157    n_samples_agents: int,
158    n_samples_mdps: int,
159    seed: int,
160) -> List[str]:
161    """
162    produces and instantiates gin files from samples of the given MDP and Agent classes in the destination folder.
163    Returns
164    -------
165    List[str]
166        The file paths of the gin files
167    """
168    os.makedirs(dest_folder, exist_ok=True)
169
170    # Store gin files for MDPs
171    gin_files = []
172    for mdp_class in mdp_classes:
173        fp = (
174            ensure_folder(dest_folder)
175            + "mdp_configs"
176            + os.sep
177            + mdp_class.__name__
178            + ".gin"
179        )
180        gin_files.append(fp)
181        with open(fp, "w") as f:
182            f.write(
183                "\n\n".join(
184                    mdp_class.produce_gin_file_from_mdp_parameters(
185                        mdp_hyperparameters, mdp_class.__name__, i
186                    )
187                    for i, mdp_hyperparameters in enumerate(
188                        mdp_class.sample_parameters(n_samples_mdps, seed)
189                    )
190                )
191            )
192
193    # Store gin file for agents
194    for agent_class in agent_classes:
195        fp = (
196            ensure_folder(dest_folder)
197            + "agents_configs"
198            + os.sep
199            + agent_class.__name__
200            + ".gin"
201        )
202        gin_files.append(fp)
203        with open(fp, "w") as f:
204            f.write(
205                "\n\n".join(
206                    agent_class.produce_gin_file_from_parameters(
207                        agent_hyperparameter, i
208                    )
209                    for i, agent_hyperparameter in enumerate(
210                        sample_n_agent_hyperparameters(
211                            n_samples_agents, agent_class, seed
212                        )
213                    )
214                )
215            )
216
217    return gin_files

produces and instantiates gin files from samples of the given MDP and Agent classes in the destination folder.

Returns
  • List[str]: The file paths of the gin files
def instantiate_mdps_from_experiment_folder( experiment_folder: str, exclude_horizon_from_parameters=False) -> List[colosseum.mdp.base.BaseMDP]:
220def instantiate_mdps_from_experiment_folder(
221    experiment_folder: str, exclude_horizon_from_parameters=False
222) -> List["BaseMDP"]:
223    """
224    Returns
225    -------
226    List["BaseMDP"]
227        The MDP instances corresponding to the experiment folder in input.
228    """
229    (
230        mdp_classes_scopes,
231        agent_classes_scopes,
232        gin_config_files_paths,
233    ) = get_mdp_agent_gin_configs(experiment_folder)
234    exp_config = get_experiment_config(experiment_folder, None)
235
236    loop = mdp_classes_scopes.items()
237    if config.VERBOSE_LEVEL != 0:
238        loop = tqdm(loop, desc=os.path.basename(experiment_folder))
239
240    mdps = []
241    for mdp_class, mdp_scopes in loop:
242        for mdp_scope in mdp_scopes:
243            apply_gin_config(gin_config_files_paths)
244            with gin.config_scope(mdp_scope):
245                for seed in range(exp_config.n_seeds):
246                    mdps.append(
247                        mdp_class(
248                            seed=seed,
249                            exclude_horizon_from_parameters=exclude_horizon_from_parameters,
250                        )
251                    )
252
253    return mdps
Returns
  • List["BaseMDP"]: The MDP instances corresponding to the experiment folder in input.