Esempio n. 1
0
def check_config(executable, conda_env, configs):
    """Check if the given configs are consistent with the Sacred experiment in the given executable.

    Parameters
    ----------
    executable: str
        The Python file containing the experiment.
    conda_env: str
        The experiment's Anaconda environment.
    configs: list of dicts
        Contains the parameter configurations.

    Returns
    -------
    None

    """
    import sacred

    exp_module = import_exe(executable, conda_env)

    # Extract experiment from module
    exps = [v for k, v in exp_module.__dict__.items() if type(v) == sacred.Experiment]
    if len(exps) == 0:
        raise ExecutableError(f"Found no Sacred experiment. Something is wrong in '{executable}'.")
    elif len(exps) > 1:
        raise ExecutableError(f"Found more than 1 Sacred experiment in '{executable}'. "
                              f"Can't check parameter configs. Disable via --no-sanity-check.")
    exp = exps[0]

    empty_run = sacred.initialize.create_run(exp, exp.default_command, config_updates=None, named_configs=())

    captured_args = {
            sacred.utils.join_paths(cf.prefix, n)
            for cf in exp.captured_functions
            for n in cf.signature.arguments
    }

    for config in configs:
        config_added = {k: v for k, v in config.items() if k not in empty_run.config.keys()}
        config_flattened = {k for k, _ in sacred.utils.iterate_flattened(config_added)}

        # Check for unused arguments
        for conf in sorted(config_flattened):
            if not (set(sacred.utils.iter_prefixes(conf)) & captured_args):
                raise sacred.utils.ConfigAddedError(conf, config=config_added)

        # Check for missing arguments
        options = empty_run.config.copy()
        options.update(config)
        options.update({k: None for k in sacred.utils.ConfigAddedError.SPECIAL_ARGS})
        empty_run.main_function.signature.construct_arguments((), {}, options, False)
Esempio n. 2
0
def set_executable_and_working_dir(config_path, seml_dict):
    """
    Determine the working directory of the project and chdir into the working directory.
    Parameters
    ----------
    config_path: Path to the config file
    seml_dict: SEML config dictionary

    Returns
    -------
    None
    """
    config_dir = str(Path(config_path).expanduser().resolve().parent)

    working_dir = config_dir
    os.chdir(working_dir)
    if "executable" not in seml_dict:
        raise ConfigError(
            "Please specify an executable path for the experiment.")
    executable = seml_dict['executable']
    executable_relative_to_config = os.path.exists(executable)
    executable_relative_to_project_root = False
    if 'project_root_dir' in seml_dict:
        working_dir = str(
            Path(seml_dict['project_root_dir']).expanduser().resolve())
        seml_dict['use_uploaded_sources'] = True
        os.chdir(working_dir)  # use project root as base dir from now on
        executable_relative_to_project_root = os.path.exists(executable)
        del seml_dict[
            'project_root_dir']  # from now on we use only the working dir
    else:
        seml_dict['use_uploaded_sources'] = False
        logging.warning(
            "'project_root_dir' not defined in seml config. Source files will not be saved in MongoDB."
        )
    seml_dict['working_dir'] = working_dir
    if not (executable_relative_to_config
            or executable_relative_to_project_root):
        raise ExecutableError(f"Could not find the executable.")
    executable = str(Path(executable).expanduser().resolve())
    seml_dict['executable'] = (str(Path(executable).relative_to(working_dir))
                               if executable_relative_to_project_root else str(
                                   Path(executable).relative_to(config_dir)))
Esempio n. 3
0
def upload_sources(seml_config, collection, batch_id):
    root_dir = str(Path(seml_config['working_dir']).expanduser().resolve())

    sources = get_imported_sources(seml_config['executable'],
                                   root_dir=root_dir,
                                   conda_env=seml_config['conda_environment'])
    executable_abs = str(
        Path(seml_config['executable']).expanduser().resolve())

    if executable_abs not in sources:
        raise ExecutableError(
            f"Executable {executable_abs} was not found in the sources to upload."
        )

    uploaded_files = []
    for s in sources:
        file_id = upload_file(s, collection, batch_id, 'source_file')
        source_path = Path(s)
        uploaded_files.append(
            (str(source_path.relative_to(root_dir)), file_id))
    return uploaded_files