Esempio n. 1
0
def launch_jobs(temp_dir: str) -> None:
    runs = []
    with open(os.path.join(temp_dir, JOB_SPEC_PICKLE), "rb") as f:
        job_spec = pickle.load(f)  # nosec
        singleton_state = job_spec["singleton_state"]
        sweep_configs = job_spec["sweep_configs"]
        task_function = job_spec["task_function"]

        instance_id = _get_instance_id()

        sweep_dir = None

        for sweep_config in sweep_configs:
            with open_dict(sweep_config):
                sweep_config.hydra.job.id = (
                    f"{instance_id}_{sweep_config.hydra.job.num}"
                )
            setup_globals()
            Singleton.set_state(singleton_state)
            HydraConfig.instance().set_config(sweep_config)
            ray_init_cfg = sweep_config.hydra.launcher.ray_init_cfg
            ray_remote_cfg = sweep_config.hydra.launcher.ray_remote_cfg

            if not sweep_dir:
                sweep_dir = Path(str(HydraConfig.get().sweep.dir))
                sweep_dir.mkdir(parents=True, exist_ok=True)

            start_ray(ray_init_cfg)
            ray_obj = launch_job_on_ray(
                ray_remote_cfg, sweep_config, task_function, singleton_state
            )
            runs.append(ray_obj)

    result = [ray.get(run) for run in runs]
    _dump_job_return(result, temp_dir)
Esempio n. 2
0
def execute_job(
    idx: int,
    overrides: Sequence[str],
    config_loader: ConfigLoader,
    config: DictConfig,
    task_function: TaskFunction,
    singleton_state: Dict[Any, Any],
) -> JobReturn:
    """Calls `run_job` in parallel
    """
    setup_globals()
    Singleton.set_state(singleton_state)

    sweep_config = config_loader.load_sweep_config(config, list(overrides))
    with open_dict(sweep_config):
        sweep_config.hydra.job.id = "{}_{}".format(sweep_config.hydra.job.name,
                                                   idx)
        sweep_config.hydra.job.num = idx
    HydraConfig.instance().set_config(sweep_config)

    ret = run_job(
        config=sweep_config,
        task_function=task_function,
        job_dir_key="hydra.sweep.dir",
        job_subdir_key="hydra.sweep.subdir",
    )

    return ret
Esempio n. 3
0
def run_maze_job(hydra_overrides: Dict[str, str], config_module: str, config_name: str) -> DictConfig:
    """Runs rollout with the given config overrides using maze_run.

    :param hydra_overrides: Config overrides for hydra.
    :param config_module: The config module.
    :param config_name: The name of the default config.
    """
    with initialize_config_module(config_module=config_module):
        # Config is relative to a module
        # For the HydraConfig init below, we need the hydra key there as well (=> return_hydra_config=True)
        cfg = compose(config_name=config_name,
                      overrides=[key + "=" + str(val) for key, val in hydra_overrides.items()],
                      return_hydra_config=True)

        # Init the HydraConfig: This is when Hydra actually creates the output dir and changes into it
        # (otherwise we only have the config object, but not the full run environment)
        HydraConfig.instance().set_config(cfg)

        # For the rollout itself, the Hydra config should not be there anymore
        with open_dict(cfg):
            del cfg["hydra"]

        # Run the rollout
        maze_run(cfg)

    return cfg
Esempio n. 4
0
def dispatch_job(
    idx: int,
    overrides: Sequence[str],
    config_loader: ConfigLoader,
    config: DictConfig,
    task_function: TaskFunction,
    singleton_state: Dict[Any, Any],
) -> JobReturn:
    """Calls `run_job` in parallel

    Note that Joblib's default backend runs isolated Python processes, see
    https://joblib.readthedocs.io/en/latest/parallel.html#shared-memory-semantics
    """
    setup_globals()
    Singleton.set_state(singleton_state)

    log.info("\t#{} : {}".format(idx, " ".join(filter_overrides(overrides))))
    sweep_config = config_loader.load_sweep_config(config, list(overrides))
    with open_dict(sweep_config):
        sweep_config.hydra.job.id = "{}_{}".format(sweep_config.hydra.job.name,
                                                   idx)
        sweep_config.hydra.job.num = idx
    HydraConfig.instance().set_config(sweep_config)

    ret = run_job(
        config=sweep_config,
        task_function=task_function,
        job_dir_key="hydra.sweep.dir",
        job_subdir_key="hydra.sweep.subdir",
    )

    return ret
Esempio n. 5
0
    def launch(
        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int
    ) -> Sequence[JobReturn]:
        setup_globals()
        assert self.config is not None
        assert self.task_function is not None
        assert self.config_loader is not None

        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
        sweep_dir = self.config.hydra.sweep.dir
        Path(str(sweep_dir)).mkdir(parents=True, exist_ok=True)
        log.info(f"Launching {len(job_overrides)} jobs locally")
        runs: List[JobReturn] = []
        for idx, overrides in enumerate(job_overrides):
            idx = initial_job_idx + idx
            lst = " ".join(filter_overrides(overrides))
            log.info(f"\t#{idx} : {lst}")
            sweep_config = self.config_loader.load_sweep_config(
                self.config, list(overrides)
            )
            with open_dict(sweep_config):
                sweep_config.hydra.job.id = idx
                sweep_config.hydra.job.num = idx
            HydraConfig.instance().set_config(sweep_config)
            ret = run_job(
                config=sweep_config,
                task_function=self.task_function,
                job_dir_key="hydra.sweep.dir",
                job_subdir_key="hydra.sweep.subdir",
            )
            runs.append(ret)
            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
        return runs
Esempio n. 6
0
    def multirun(
        self,
        config_name: Optional[str],
        task_function: TaskFunction,
        overrides: List[str],
        with_log_configuration: bool = True,
    ) -> Any:
        # Initial config is loaded without strict (individual job configs may have strict).
        cfg = self.compose_config(
            config_name=config_name,
            overrides=overrides,
            strict=False,
            with_log_configuration=with_log_configuration,
            run_mode=RunMode.MULTIRUN,
        )
        HydraConfig.instance().set_config(cfg)

        sweeper = Plugins.instance().instantiate_sweeper(
            config=cfg,
            config_loader=self.config_loader,
            task_function=task_function)
        task_overrides = OmegaConf.to_container(cfg.hydra.overrides.task,
                                                resolve=False)
        assert isinstance(task_overrides, list)
        return sweeper.sweep(arguments=task_overrides)
Esempio n. 7
0
    def launch(
        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int
    ) -> Sequence[JobReturn]:
        setup_globals()
        assert self.hydra_context is not None
        assert self.config is not None
        assert self.task_function is not None

        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
        sweep_dir = self.config.hydra.sweep.dir
        Path(str(sweep_dir)).mkdir(parents=True, exist_ok=True)
        log.info("Launching {} jobs on slurm".format(len(job_overrides)))
        runs: List[JobReturn] = []
        for idx, overrides in enumerate(job_overrides):
            idx = initial_job_idx + idx
            lst = " ".join(filter_overrides(overrides))
            log.info(f"\t#{idx} : {lst}")
            sweep_config = self.hydra_context.config_loader.load_sweep_config(
                self.config, list(overrides)
            )

            with open_dict(sweep_config):
                sweep_config.hydra.job.id = idx
                sweep_config.hydra.job.num = idx
            HydraConfig.instance().set_config(sweep_config)
            log.info("\tJob name : {}".format(slurm_utils.resolve_name(sweep_config.slurm.job_name)))

            slurm_utils.write_slurm(sweep_config)
            slurm_utils.write_sh(sweep_config, " ".join(filter_overrides(overrides)))
            slurm_utils.launch_job(sweep_config)

            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
            if sweep_config.wait:
                time.sleep(1)
        return runs
Esempio n. 8
0
    def _print_search_path(self, config_name: Optional[str],
                           overrides: List[str]) -> None:
        assert log is not None
        log.debug("")
        self._log_header(header="Config search path", filler="*")

        box: List[List[str]] = [["Provider", "Search path"]]

        cfg = self.compose_config(
            config_name=config_name,
            overrides=overrides,
            run_mode=RunMode.RUN,
            with_log_configuration=False,
        )
        HydraConfig.instance().set_config(cfg)
        cfg = self.get_sanitized_cfg(cfg, cfg_type="hydra")

        sources = cfg.hydra.runtime.config_sources

        for sp in sources:
            box.append([sp.provider, f"{sp.schema}://{sp.path}"])

        provider_pad, search_path_pad = get_column_widths(box)
        header = "| {} | {} |".format("Provider".ljust(provider_pad),
                                      "Search path".ljust(search_path_pad))
        self._log_header(header=header, filler="-")

        for source in sources:
            log.debug("| {} | {} |".format(
                source.provider.ljust(provider_pad),
                f"{source.schema}://{source.path}".ljust(search_path_pad),
            ))
        self._log_footer(header=header, filler="-")
Esempio n. 9
0
    def launch(self, job_overrides: Sequence[Sequence[str]],
               initial_job_idx: int) -> Sequence[JobReturn]:
        """
        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.
        :param initial_job_idx: Initial job idx in batch.
        :return: an array of return values from run_job with indexes corresponding to the input list indexes.
        """
        setup_globals()
        assert self.config is not None
        assert self.config_loader is not None
        assert self.task_function is not None

        configure_log(self.config.hydra.hydra_logging,
                      self.config.hydra.verbose)
        sweep_dir = Path(str(self.config.hydra.sweep.dir))
        sweep_dir.mkdir(parents=True, exist_ok=True)
        log.info(
            f"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally"
        )
        log.info(f"Sweep output dir : {sweep_dir}")
        runs = []

        for idx, overrides in enumerate(job_overrides):
            idx = initial_job_idx + idx
            lst = " ".join(filter_overrides(overrides))
            log.info(f"\t#{idx} : {lst}")
            sweep_config = self.config_loader.load_sweep_config(
                self.config, list(overrides))
            with open_dict(sweep_config):
                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)
                # In that case, it will not be available here because we are still in the main process.
                # but instead should be populated remotely before calling the task_function.
                sweep_config.hydra.job.id = f"job_id_for_{idx}"
                sweep_config.hydra.job.num = idx
            HydraConfig.instance().set_config(sweep_config)

            # If your launcher is executing code in a different process, it is important to restore
            # the singleton state in the new process.
            # To do this, you will likely need to serialize the singleton state along with the other
            # parameters passed to the child process.

            # happening on this process (executing launcher)
            state = Singleton.get_state()

            # happening on the spawned process (executing task_function in run_job)
            Singleton.set_state(state)

            ret = run_job(
                config=sweep_config,
                task_function=self.task_function,
                job_dir_key="hydra.sweep.dir",
                job_subdir_key="hydra.sweep.subdir",
            )
            runs.append(ret)
            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.
            # This is needed for launchers that calls run_job in the same process and not spawn a new one.
            configure_log(self.config.hydra.hydra_logging,
                          self.config.hydra.verbose)
        return runs
Esempio n. 10
0
def setup_multirun():
    from hydra.core.hydra_config import HydraConfig
    if 'num' in HydraConfig.get().job:
        job_num = HydraConfig.get().job.num % torch.cuda.device_count()
        gpu = job_num % torch.cuda.device_count()
        torch.cuda.set_device(gpu)
        print(f'Job number {job_num:2d}')
        print(f'Setting active GPU to {gpu}')
Esempio n. 11
0
def run_job(
    config: DictConfig,
    task_function: TaskFunction,
    job_dir_key: str,
    job_subdir_key: Optional[str],
    configure_logging: bool = True,
) -> "JobReturn":
    old_cwd = os.getcwd()
    working_dir = str(OmegaConf.select(config, job_dir_key))
    orig_hydra_cfg = HydraConfig.instance().cfg
    if job_subdir_key is not None:
        # evaluate job_subdir_key lazily.
        # this is running on the client side in sweep and contains things such as job:id which
        # are only available there.
        subdir = str(OmegaConf.select(config, job_subdir_key))
        working_dir = os.path.join(working_dir, subdir)
    try:
        ret = JobReturn()
        ret.working_dir = working_dir
        task_cfg = copy.deepcopy(config)
        hydra_cfg = OmegaConf.masked_copy(task_cfg, "hydra")
        # maintain parent to preserve interpolation links from hydra_cfg to job_cfg
        hydra_cfg._set_parent(task_cfg)
        with read_write(task_cfg):
            with open_dict(task_cfg):
                del task_cfg["hydra"]
        HydraConfig.instance().cfg = hydra_cfg  # type: ignore

        ret.cfg = task_cfg
        ret.hydra_cfg = hydra_cfg
        overrides = OmegaConf.to_container(config.hydra.overrides.task)
        assert isinstance(overrides, list)
        ret.overrides = overrides
        # handle output directories here
        Path(str(working_dir)).mkdir(parents=True, exist_ok=True)
        os.chdir(working_dir)

        if configure_logging:
            configure_log(config.hydra.job_logging, config.hydra.verbose)

        if config.hydra.output_subdir is not None:
            hydra_output = Path(config.hydra.output_subdir)
            _save_config(task_cfg, "config.yaml", hydra_output)
            _save_config(hydra_cfg, "hydra.yaml", hydra_output)
            _save_config(config.hydra.overrides.task, "overrides.yaml",
                         hydra_output)

        with env_override(hydra_cfg.hydra.job.env_set):
            ret.return_value = task_function(task_cfg)
        ret.task_name = JobRuntime.instance().get("name")

        _flush_loggers()

        return ret
    finally:
        HydraConfig.instance().cfg = orig_hydra_cfg
        os.chdir(old_cwd)
Esempio n. 12
0
def get_original_cwd() -> str:
    """
    :return: the original working directory the Hydra application was launched from
    """
    if not HydraConfig.initialized():
        raise ValueError(
            "get_original_cwd() must only be used after HydraConfig is initialized"
        )
    ret = HydraConfig.get().runtime.cwd
    assert ret is not None and isinstance(ret, str)
    return ret
Esempio n. 13
0
def test_foo(restore_singletons: Any) -> Any:
    utils.setup_globals()

    config_loader = ConfigLoaderImpl(
        config_search_path=create_config_search_path(
            "pkg://hydra.test_utils.configs"))
    cfg = config_loader.load_configuration(
        config_name="accessing_hydra_config", overrides=[])
    HydraConfig.instance().set_config(cfg)
    with open_dict(cfg):
        del cfg["hydra"]
    assert cfg.job_name == "UNKNOWN_NAME"
    assert cfg.config_name == "accessing_hydra_config"
Esempio n. 14
0
def _run_job(
    sweep_config: DictConfig,
    task_function: TaskFunction,
    singleton_state: Dict[Any, Any],
) -> JobReturn:
    setup_globals()
    Singleton.set_state(singleton_state)
    HydraConfig.instance().set_config(sweep_config)
    return run_job(
        config=sweep_config,
        task_function=task_function,
        job_dir_key="hydra.sweep.dir",
        job_subdir_key="hydra.sweep.subdir",
    )
Esempio n. 15
0
    def launch(self, job_overrides: Sequence[Sequence[str]],
               initial_job_idx: int) -> Sequence[JobReturn]:
        """
        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.
        :param initial_job_idx: Initial job idx in batch.
        :return: an array of return values from run_job with indexes corresponding to the input list indexes.
        """
        setup_globals()
        assert self.config is not None
        assert self.config_loader is not None
        assert self.task_function is not None

        configure_log(self.config.hydra.hydra_logging,
                      self.config.hydra.verbose)
        sweep_dir = Path(str(self.config.hydra.sweep.dir))
        sweep_dir.mkdir(parents=True, exist_ok=True)
        log.info(
            "Example Launcher(foo={}, bar={}) is launching {} jobs locally".
            format(self.foo, self.bar, len(job_overrides)))
        log.info("Sweep output dir : {}".format(sweep_dir))
        runs = []

        for idx, overrides in enumerate(job_overrides):
            idx = initial_job_idx + idx
            log.info("\t#{} : {}".format(idx, " ".join(
                filter_overrides(overrides))))
            sweep_config = self.config_loader.load_sweep_config(
                self.config, list(overrides))
            with open_dict(sweep_config):
                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)
                # In that case, it will not be available here because we are still in the main process.
                # but instead should be populated remotely before calling the task_function.
                sweep_config.hydra.job.id = "job_id_for_{}".format(idx)
                sweep_config.hydra.job.num = idx
            HydraConfig.instance().set_config(sweep_config)

            ret = run_job(
                config=sweep_config,
                task_function=self.task_function,
                job_dir_key="hydra.sweep.dir",
                job_subdir_key="hydra.sweep.subdir",
            )
            runs.append(ret)
            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.
            # This is needed for launchers that calls run_job in the same process and not spawn a new one.
            configure_log(self.config.hydra.hydra_logging,
                          self.config.hydra.verbose)
        return runs
def hydra_instance() -> Union[Hydra, GlobalHydra]:
    "Provide Hydra/GlobalHydra instance for compose"
    if HydraConfig.initialized():
        yield GlobalHydra.instance()
    hydra_init = initialize(config_path="../peddet/conf")
    yield hydra_init
    GlobalHydra.instance().clear()
Esempio n. 17
0
def get_class_dist(labels_file="78-classes_train.json",
                   str2id_file="78-classes_labels.json"):
    labels_dir = "./datasets/20bn-sth-sth-v2/labels/"
    if HydraConfig.initialized():
        labels_dir = os.path.join(hydra.utils.get_original_cwd(), labels_dir)
        data_info_path = os.path.join(labels_dir, labels_file)
    else:
        labels_dir = os.path.join(os.getcwd(), labels_dir)
        data_info_path = os.path.abspath(os.path.join(labels_dir, labels_file))
    data_info_frame = pd.read_json(data_info_path)
    ids_frame = pd.read_json(os.path.join(labels_dir, str2id_file),\
                             typ='series')
    data_info_frame["template"] = data_info_frame["template"].str.replace(
        "[", "")
    data_info_frame["template"] = data_info_frame["template"].str.replace(
        "]", "")
    #classes present in labels_file (78)
    classes = ids_frame[data_info_frame["template"]]
    unique, counts = np.unique(classes, return_counts=True)
    old2new = map_orig2new()
    #str: new id
    classes = ids_frame[unique].replace(old2new)
    #returns
    unique_str = ids_frame[unique]
    unique_new_ids = [old2new[i] for i in unique]
    #new_ids: count
    new_ids_counts = dict(zip(unique_new_ids, counts))
    #str_count:
    str_counts = dict(zip(unique_str, counts))
    #new_ids in order of the dataframe
    class_labels = list(classes[data_info_frame["template"]])
    return new_ids_counts, str_counts, class_labels
Esempio n. 18
0
def _get_job_id() -> int:
    try:
        return HydraConfig.get().job.id
    except MissingMandatoryValue:
        # The numeric job ID is missing if not in a multirun context. In that
        # case, there can only be a single run.
        return 0
Esempio n. 19
0
def test_configuration_set_via_cmd_and_default_config(
    sweep_runner: TSweepRunner, ) -> None:
    sweep = sweep_runner(
        calling_file="tests/test_ax_sweeper_plugin.py",
        calling_module=None,
        task_function=quadratic,
        config_path="config",
        config_name="config.yaml",
        overrides=[
            "hydra/launcher=basic",
            "hydra.sweeper.params.ax_config.max_trials=2",
            "hydra.sweeper.params.ax_config.early_stop.max_epochs_without_improvement=2",
            "quadratic=basic",
            "quadratic.x=-5:-2",
            "quadratic.y=-1:1",
        ],
    )
    with sweep:
        ax_config = HydraConfig.get().sweeper.params.ax_config
        assert ax_config.max_trials == 2
        assert ax_config.early_stop.max_epochs_without_improvement == 2
        assert ax_config.experiment.minimize is True
        assert sweep.returns is None
        returns = OmegaConf.load(f"{sweep.temp_dir}/optimization_results.yaml")
        assert isinstance(returns, DictConfig)
        best_parameters = returns["ax"]
        assert "quadratic_x" in best_parameters
        assert "quadratic_y" in best_parameters
Esempio n. 20
0
def setup_globals() -> None:
    # please add documentation when you add a new resolver
    OmegaConf.register_new_resolver(
        "now",
        lambda pattern: datetime.now().strftime(pattern),
        use_cache=True,
        replace=True,
    )
    OmegaConf.register_new_resolver(
        "hydra",
        lambda path: OmegaConf.select(cast(DictConfig, HydraConfig.get()), path
                                      ),
        replace=True,
    )

    vi = sys.version_info
    version_dict = {
        "major": f"{vi[0]}",
        "minor": f"{vi[0]}.{vi[1]}",
        "micro": f"{vi[0]}.{vi[1]}.{vi[2]}",
    }
    OmegaConf.register_new_resolver(
        "python_version",
        lambda level="minor": version_dict.get(level),
        replace=True)
Esempio n. 21
0
def test_configuration_set_via_cmd_and_default_config(
        sweep_runner: TSweepRunner,  # noqa: F811
) -> None:
    sweep = sweep_runner(
        calling_file=os.path.dirname(os.path.abspath(__file__)),
        calling_module=None,
        task_function=quadratic,
        config_path="tests/config",
        config_name="default_quadratic.yaml",
        overrides=[
            "hydra/sweeper=ax",
            "hydra/launcher=basic",
            "hydra.sweeper.params.ax_config.client.random_seed=1",
            "hydra.sweeper.params.ax_config.max_trials=2",
            "hydra.sweeper.params.ax_config.early_stop.max_epochs_without_improvement=2",
            "quadratic.x=-5:-2",
            "quadratic.y=-1:1",
        ],
    )
    with sweep:
        ax_config = HydraConfig.instance().hydra.sweeper.params.ax_config
        assert ax_config.max_trials == 2
        assert ax_config.early_stop.max_epochs_without_improvement == 2
        assert ax_config.experiment.minimize is True
        assert sweep.returns is None
        returns = OmegaConf.load(f"{sweep.temp_dir}/optimization_results.yaml")
        assert isinstance(returns, DictConfig)
        best_parameters = returns["ax"]
        assert "quadratic.x" in best_parameters
        assert "quadratic.y" in best_parameters
Esempio n. 22
0
def error_checks(trainer: 'pytorch_lightning.Trainer',
                 cfg: Optional[Union[DictConfig, Dict]] = None):
    """
    Checks that the passed trainer is compliant with NeMo and exp_manager's passed configuration. Checks that:
        - Throws error when hydra has changed the working directory. This causes issues with lightning's DDP
        - Throws error when trainer has loggers defined but create_tensorboard_logger or create_WandB_logger is True
        - Prints error messages when 1) run on multi-node and not Slurm, and 2) run on multi-gpu without DDP
    """
    if HydraConfig.initialized() and get_original_cwd() != os.getcwd():
        raise ValueError(
            "Hydra changed the working directory. This interferes with ExpManger's functionality. Please pass "
            "hydra.run.dir=. to your python script.")
    if trainer.logger is not None and (cfg.create_tensorboard_logger
                                       or cfg.create_wandb_logger):
        raise LoggerMisconfigurationError(
            "The pytorch lightning trainer that was passed to exp_manager contained a logger, and either "
            f"create_tensorboard_logger: {cfg.create_tensorboard_logger} or create_wandb_logger: "
            f"{cfg.create_wandb_logger} was set to True. These can only be used if trainer does not already have a"
            " logger.")
    if trainer.num_nodes > 1 and not check_slurm(trainer):
        logging.error(
            "You are running multi-node training without SLURM handling the processes."
            " Please note that this is not tested in NeMo and could result in errors."
        )
    if trainer.num_gpus > 1 and not isinstance(
            trainer.accelerator.training_type_plugin, DDPPlugin):
        logging.error(
            "You are running multi-gpu without ddp.Please note that this is not tested in NeMo and could result in "
            "errors.")
Esempio n. 23
0
 def run(
     self,
     config_name: Optional[str],
     task_function: TaskFunction,
     overrides: List[str],
 ) -> JobReturn:
     cfg = self.compose_config(config_name=config_name,
                               overrides=overrides,
                               with_log_configuration=True)
     HydraConfig.instance().set_config(cfg)
     return run_job(
         config=cfg,
         task_function=task_function,
         job_dir_key="hydra.run.dir",
         job_subdir_key=None,
     )
Esempio n. 24
0
def launch(
    launcher: RayAWSLauncher,
    job_overrides: Sequence[Sequence[str]],
    initial_job_idx: int,
) -> Sequence[JobReturn]:
    setup_globals()
    assert launcher.config is not None
    assert launcher.config_loader is not None
    assert launcher.task_function is not None

    setup_commands = launcher.env_setup.commands
    with read_write(setup_commands):
        setup_commands.extend([
            f"pip install {package}=={version}"
            for package, version in launcher.env_setup.pip_packages.items()
        ])
        setup_commands.extend(launcher.ray_cfg.cluster.setup_commands)

    with read_write(launcher.ray_cfg.cluster):
        launcher.ray_cfg.cluster.setup_commands = setup_commands

    configure_log(launcher.config.hydra.hydra_logging,
                  launcher.config.hydra.verbose)

    log.info(f"Ray Launcher is launching {len(job_overrides)} jobs, ")

    with tempfile.TemporaryDirectory() as local_tmp_dir:
        sweep_configs = []
        for idx, overrides in enumerate(job_overrides):
            idx = initial_job_idx + idx
            ostr = " ".join(filter_overrides(overrides))
            log.info(f"\t#{idx} : {ostr}")
            sweep_config = launcher.config_loader.load_sweep_config(
                launcher.config, list(overrides))
            with open_dict(sweep_config):
                # job.id will be set on the EC2 instance before running the job.
                sweep_config.hydra.job.num = idx

            sweep_configs.append(sweep_config)

        _pickle_jobs(
            tmp_dir=local_tmp_dir,
            sweep_configs=sweep_configs,  # type: ignore
            task_function=launcher.task_function,
            singleton_state=Singleton.get_state(),
        )

        with tempfile.NamedTemporaryFile(suffix=".yaml", delete=False) as f:
            with open(f.name, "w") as file:
                OmegaConf.save(config=launcher.ray_cfg.cluster,
                               f=file.name,
                               resolve=True)
            launcher.ray_yaml_path = f.name
            log.info(
                f"Saving RayClusterConf in a temp yaml file: {launcher.ray_yaml_path}."
            )

            return launch_jobs(launcher, local_tmp_dir,
                               Path(HydraConfig.get().sweep.dir))
Esempio n. 25
0
    def __enter__(self):
        # do nothing if hydra is not initialized
        if not HydraConfig.initialized() or not self.input_dir:
            return

        self.hydra_out_dir = os.getcwd()
        original_dir = os.path.join(hydra.utils.get_original_cwd(), self.input_dir)
        print(f"Switching load directory to {original_dir}")
        os.chdir(original_dir)
Esempio n. 26
0
def test_to_absolute_path(orig_cwd: str, path: str, expected: str) -> None:
    # normalize paths to current OS
    orig_cwd = str(Path(orig_cwd))
    path = str(Path(path))
    expected = str(Path(expected))
    cfg = OmegaConf.create({"hydra": {"runtime": {"cwd": orig_cwd}}})
    assert isinstance(cfg, DictConfig)
    HydraConfig().set_config(cfg)
    assert utils.to_absolute_path(path) == expected
Esempio n. 27
0
    def app_help(self, config_name: Optional[str], args_parser: ArgumentParser,
                 args: Any) -> None:
        cfg = self.compose_config(
            config_name=config_name,
            overrides=args.overrides,
            run_mode=RunMode.RUN,
            with_log_configuration=True,
        )
        HydraConfig.instance().set_config(cfg)
        help_cfg = cfg.hydra.help
        clean_cfg = copy.deepcopy(cfg)

        clean_cfg = self.get_sanitized_cfg(clean_cfg, "job")
        help_text = self.get_help(help_cfg,
                                  clean_cfg,
                                  args_parser,
                                  resolve=args.resolve)
        print(help_text)
Esempio n. 28
0
    def _print_config_info(self, config_name: Optional[str],
                           overrides: List[str]) -> None:
        assert log is not None
        self._print_search_path(config_name=config_name, overrides=overrides)
        self._print_defaults_tree(config_name=config_name, overrides=overrides)
        self._print_defaults_list(config_name=config_name, overrides=overrides)

        cfg = run_and_report(lambda: self.compose_config(
            config_name=config_name,
            overrides=overrides,
            run_mode=RunMode.RUN,
            with_log_configuration=False,
        ))
        HydraConfig.instance().set_config(cfg)
        self._log_header(header="Config", filler="*")
        with flag_override(cfg, ["struct", "readonly"], [False, False]):
            del cfg["hydra"]
        log.info(OmegaConf.to_yaml(cfg))
Esempio n. 29
0
def execute_job(
    idx: int,
    overrides: Sequence[str],
    config_loader: ConfigLoader,
    config: DictConfig,
    task_function: TaskFunction,
    singleton_state: Dict[Any, Any],
    cmd_prefix: str,
    tsp_prefix: str,
) -> JobReturn:
    """Calls `run_job` in parallel
    """
    setup_globals()
    Singleton.set_state(singleton_state)

    lst = " ".join(overrides)

    sweep_config = config_loader.load_sweep_config(config, list(overrides))
    with open_dict(sweep_config):
        sweep_config.hydra.job.id = "{}_{}".format(sweep_config.hydra.job.name,
                                                   idx)
        sweep_config.hydra.job.num = idx
    HydraConfig.instance().set_config(sweep_config)

    def tsp_task_function(task_cfg):
        working_dir = os.getcwd()
        cmd = f"{cmd_prefix} {lst}"
        log.info(f"\t#{idx} : {lst}")
        cmd = f"cd {hydra.utils.get_original_cwd()} && {cmd} hydra.run.dir={working_dir}"
        job_id = int(subprocess.check_output(cmd, shell=True).rstrip())
        log.info(
            f"Submitted {idx} to TaskSpooler. View logs: {tsp_prefix} -t {job_id}"
        )
        return job_id

    ret = run_job(
        config=sweep_config,
        task_function=tsp_task_function,
        job_dir_key="hydra.sweep.dir",
        job_subdir_key="hydra.sweep.subdir",
    )
    ret.id = ret.return_value

    return ret
Esempio n. 30
0
 def multirun(
     self,
     config_name: Optional[str],
     task_function: TaskFunction,
     overrides: List[str],
 ) -> Any:
     # Initial config is loaded without strict (individual job configs may have strict).
     cfg = self.compose_config(
         config_name=config_name,
         overrides=overrides,
         strict=False,
         with_log_configuration=True,
     )
     HydraConfig.instance().set_config(cfg)
     sweeper = Plugins.instance().instantiate_sweeper(
         config=cfg, config_loader=self.config_loader, task_function=task_function
     )
     task_overrides = cfg.hydra.overrides.task
     return sweeper.sweep(arguments=task_overrides)