def test_add_to_structured_config(self, hydra_restore_singletons: Any) -> None: @dataclass class Config: a: int = 10 ConfigStore.instance().store(name="config", node=Config, package="nested") assert compose("config", overrides=["+nested.b=20"]) == { "nested": { "a": 10, "b": 20 } } assert compose("config", overrides=["++nested.a=30", "++nested.b=20"]) == { "nested": { "a": 30, "b": 20 } } assert compose("config", overrides=["+nested.b.c=20"]) == { "nested": { "a": 10, "b": { "c": 20 } } }
def test_top_level_config_is_list() -> None: with raises( HydraException, match= "primary config 'top_level_list/file1' must be a DictConfig, got ListConfig", ): compose("top_level_list/file1", overrides=[])
def test_initialize_ctx_with_absolute_dir(hydra_restore_singletons: Any, tmpdir: Any) -> None: with raises( HydraException, match=re.escape("config_path in initialize() must be relative")): with initialize(config_path=str(tmpdir)): compose(overrides=["+test_group=test"])
def test_force_add(self) -> None: ConfigStore.instance().store(name="config", node={"key": 0}) cfg = compose(config_name="config", overrides=["++key=1"]) assert cfg == {"key": 1} cfg = compose(config_name="config", overrides=["++key2=1"]) assert cfg == {"key": 0, "key2": 1}
def test_strict_failure_global_strict( self, config_file: str, overrides: List[str], expected: Any ) -> None: # default strict True, call is unspecified overrides.append("fooooooooo=bar") with raises(HydraException): compose(config_file, overrides)
def test_searchpath_config_errors( self, init_configs: Any, config_name: str, overrides: List[str], expected: Any, ) -> None: with expected: compose(config_name=config_name, overrides=overrides)
def test_add(self) -> None: ConfigStore.instance().store(name="config", node={"key": 0}) with raises( ConfigCompositionException, match="Could not append to config. An item is already at 'key'", ): compose(config_name="config", overrides=["+key=value"]) cfg = compose(config_name="config", overrides=["key=1"]) assert cfg == {"key": 1}
def test_missing_bad_config_dir_error(hydra_restore_singletons: Any) -> None: expected = ( "Primary config directory not found." "\nCheck that the config directory '/no_way_in_hell_1234567890' exists and readable" ) with raises(Exception, match=re.escape(expected)): with initialize_config_dir(config_dir="/no_way_in_hell_1234567890"): hydra = GlobalHydra.instance().hydra assert hydra is not None compose(config_name="test.yaml", overrides=[])
def test_missing_init_py_error(hydra_restore_singletons: Any) -> None: expected = ( "Primary config module 'hydra.test_utils.configs.missing_init_py' not found." "\nCheck that it's correct and contains an __init__.py file") with raises(Exception, match=re.escape(expected)): with initialize_config_module( config_module="hydra.test_utils.configs.missing_init_py"): hydra = GlobalHydra.instance().hydra assert hydra is not None compose(config_name="test.yaml", overrides=[])
def test_searchpath_invalid( self, init_configs: Any, ) -> None: config_name = "without_sp" override = "hydra.searchpath=['pkg://fakeconf']" with warns( expected_warning=UserWarning, match=re.escape( "provider=hydra.searchpath in command-line, path=fakeconf is not available." ), ): compose(config_name=config_name, overrides=[override])
def test_adding_to_sc_dict(hydra_restore_singletons: Any, overrides: List[str], expected: Any) -> None: @dataclass class Config: map: Dict[str, str] = field(default_factory=dict) ConfigStore.instance().store(name="config", node=Config) if isinstance(expected, dict): cfg = compose(config_name="config", overrides=overrides) assert cfg == expected else: with expected: compose(config_name="config", overrides=overrides)
def test_generated_config(self) -> None: with initialize_config_module(config_module="hydra_app.conf"): cfg = compose(config_name="config", overrides=["app.user=test_user"]) assert cfg == { "app": {"user": "******", "num1": 10, "num2": 20}, "db": {"host": "localhost", "port": 3306}, }
def get_surveys(names="Rubin", overrides: Iterable = ()): """Return specified surveys as `btk.survey.Survey` objects. NOTE: The surveys currently implemented correspond to config files inside `conf/surveys`. See the documentation for how to add your own surveys via custom config files. Args: names (str or list): A single str specifying a survey from conf/surveys or a list with multiple survey names. overrides (Iterable): List or tuple containg overrides for the survey config files. An example element of overrides could be 'surveys.Rubin.airmass=1.1', i.e. what you would pass into the CLI in order to customize the surveys used (here specified by `names`). Returns: btk.survey.Survey object or list of such objects. """ if isinstance(names, str): names = [names] if not isinstance(names, list): raise TypeError( "Argument 'names' of `get_surveys` should be a str or list.") overrides = [f"surveys={names}", *overrides] surveys = [] with initialize(config_path="../conf"): cfg = compose("config", overrides=overrides) for survey_name in cfg.surveys: survey_conf = cfg.surveys[survey_name] surveys.append(get_survey_from_cfg(survey_conf)) if len(surveys) == 1: return surveys[0] return surveys
def test_check_onnx_model_single(capsys): with capsys.disabled(): with initialize(config_path="hydraConf"): cfg = compose(config_name="yolov4") ort_session = onnxruntime.InferenceSession( "testModels/yolov4_singleBatch.onnx") # Model Instantiate model = Darknet(cfg.onnx.cfg_darknet_path) model.load_weights(cfg.onnx.model_darknet_path) model.eval() cfg.onnx.model_batch_size = 1 dummy_input_real = torch.randn( (cfg.onnx.model_batch_size, cfg.onnx.model_channels, model.height, model.width), requires_grad=True) ort_inputs = {ort_session.get_inputs( )[0].name: to_numpy(dummy_input_real)} boxes, conf = model(dummy_input_real) ort_outs = ort_session.run(None, ort_inputs) print(np.testing.assert_allclose( to_numpy(boxes), ort_outs[0], rtol=1e-03, atol=1e-05)) print(np.testing.assert_allclose( to_numpy(conf), ort_outs[1], rtol=1e-03, atol=1e-05)) assert True
def test_training(capsys): """ Execute Training for 2 epoch to check for error """ Path("testModels").mkdir(parents=True, exist_ok=True) with capsys.disabled(): with initialize(config_path="conf"): cfg = compose(config_name="semanticsegmentation") cfg.trainer.default.callbacks[ 0].dirpath = "/home/Develop/ai4prod_python/semanticSegmentation/testModels" cfg.trainer.default.callbacks[0].filename = "U2Squared" cfg.trainer.default.max_epochs = 2 # Dataset Setup dm = instantiate(cfg.dataset) dm.setup() # Model Instantiate model = instantiate(cfg.model) trainer = instantiate(cfg.trainer.default) trainer.fit(model=model, datamodule=dm) assert True
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
def test_initialize_with_module(hydra_restore_singletons: Any) -> None: with initialize_config_module( config_module="tests.test_apps.app_with_cfg_groups.conf", job_name="my_pp" ): assert compose(config_name="config") == { "optimizer": {"type": "nesterov", "lr": 0.001} }
def check_env_and_model_instantiation(config_module: str, config: str, overrides: Dict[str, str]) -> None: """Check if env instantiation works.""" with initialize_config_module(config_module): # config is relative to a module cfg = compose( config, overrides=[key + "=" + value for key, value in overrides.items()]) env_factory = EnvFactory(cfg.env, cfg.wrappers if "wrappers" in cfg else {}) env = env_factory() assert env is not None assert isinstance(env, (StructuredEnv, StructuredEnvSpacesMixin)) if 'model' in overrides and overrides['model'] == 'rllib': return if 'model' in cfg: model_composer = Factory(BaseModelComposer).instantiate( cfg.model, action_spaces_dict=env.action_spaces_dict, observation_spaces_dict=env.observation_spaces_dict, agent_counts_dict=env.agent_counts_dict) for pp in model_composer.policy.networks.values(): assert isinstance(pp, nn.Module) if model_composer.critic: for cc in model_composer.critic.networks.values(): assert isinstance(cc, nn.Module)
def test_jobname_override_initialize_ctx(hydra_restore_singletons: Any, job_name: Optional[str], expected: str) -> None: with initialize(config_path="../examples/jupyter_notebooks/cloud_app/conf", job_name=job_name): ret = compose(return_hydra_config=True) assert ret.hydra.job.name == expected
def test_jobname_override_initialize_config_dir_ctx( hydra_restore_singletons: Any, tmpdir: Any ) -> None: with initialize_config_dir( config_dir=str(tmpdir), version_base=None, job_name="test_job" ): ret = compose(return_hydra_config=True) assert ret.hydra.job.name == "test_job"
def test_hydra_main_passthrough(hydra_restore_singletons: Any) -> None: with initialize( version_base=None, config_path="test_apps/app_with_cfg_groups/conf" ): from tests.test_apps.app_with_cfg_groups.my_app import my_app # type: ignore cfg = compose(config_name="config", overrides=["optimizer.lr=1.0"]) assert my_app(cfg) == {"optimizer": {"type": "nesterov", "lr": 1.0}}
def test_with_initialize_config_module() -> None: with initialize_config_module(version_base=None, config_module="hydra_app.conf"): # config is relative to a module cfg = compose(config_name="config", overrides=["app.user=test_user"]) assert cfg == { "app": {"user": "******", "num1": 10, "num2": 20}, "db": {"host": "localhost", "port": 3306}, }
def test_compose_config( self, config_file: str, overrides: List[str], expected: Any, ) -> None: cfg = compose(config_file, overrides) assert cfg == expected
def test_initialize_config_module_ctx(hydra_restore_singletons: Any) -> None: with initialize_config_module( config_module="examples.jupyter_notebooks.cloud_app.conf"): ret = compose(return_hydra_config=True) assert ret.hydra.job.name == "app" with initialize_config_module( config_module="examples.jupyter_notebooks.cloud_app.conf", job_name="test_job"): ret = compose(return_hydra_config=True) assert ret.hydra.job.name == "test_job" with initialize_config_module( config_module="examples.jupyter_notebooks.cloud_app.conf", job_name="test_job"): ret = compose(return_hydra_config=True) assert ret.hydra.job.name == "test_job"
def test_schedulers(sch_name: str) -> None: scheduler_name = sch_name.split('.')[0] with initialize(config_path='../conf'): cfg = compose( config_name='config', overrides=[f'scheduler={scheduler_name}', 'optimizer=sgd', 'private=default'] ) optimizer = load_obj(cfg.optimizer.class_name)(torch.nn.Linear(1, 1).parameters(), **cfg.optimizer.params) load_obj(cfg.scheduler.class_name)(optimizer, **cfg.scheduler.params)
def test_initialize_config_module_ctx( self, config_file: str, overrides: List[str], expected: Any ) -> None: with initialize_config_module( config_module="examples.jupyter_notebooks.cloud_app.conf", job_name="job_name", ): ret = compose(config_file, overrides) assert ret == expected
def test_initialize_ctx( self, config_file: str, overrides: List[str], expected: Any ) -> None: with initialize( version_base=None, config_path="../examples/jupyter_notebooks/cloud_app/conf", ): ret = compose(config_file, overrides) assert ret == expected
def test_training_from_scratch(capsys): """ Execute Training for 2 epoch to check for error """ Path("testModels").mkdir(parents=True, exist_ok=True) with capsys.disabled(): with initialize(config_path="conf"): cfg = compose(config_name="classification") seed_everything(42, workers=cfg.trainer.workers) cfg.trainer.default.callbacks[ 0].dirpath = "/home/Develop/ai4prod_python/classification/testModels" cfg.trainer.default.callbacks[0].filename = MODEL_NAME cfg.trainer.default.max_epochs = 2 @dataclass class ImageClassificationInputTransform(InputTransform): # transforms added to input training data def train_input_per_sample_transform(self): return instantiate(cfg.dataset.train_transform, _convert_="all") # transform label to tensor def target_per_sample_transform(self) -> Callable: return torch.as_tensor # transforms added to input validation data def val_input_per_sample_transform(self): return instantiate(cfg.dataset.val_transform, _convert_="all") # Dataset Setup dm = ImageClassificationData.from_folders( train_folder=cfg.dataset.datasetPath + "train", train_transform=ImageClassificationInputTransform, val_folder=cfg.dataset.datasetPath + "val", val_transform=ImageClassificationInputTransform, batch_size=cfg.dataset.batch_size) # Model Instantiate model = instantiate(cfg.model.image_classifier) if cfg.model.from_scratch: cfg.model.image_classifier.pretrained = False trainer = instantiate(cfg.trainer.default) trainer.fit(model=model, datamodule=dm) assert True
def test_searchpath_in_primary_config( self, init_configs: Any, config_name: str, overrides: List[str], expected: Any, ) -> None: cfg = compose(config_name=config_name, overrides=overrides) assert cfg == expected
def test_add_config_group(self) -> None: ConfigStore.instance().store(group="group", name="a0", node={"key": 0}) ConfigStore.instance().store(group="group", name="a1", node={"key": 1}) # overriding non existing group throws with raises(ConfigCompositionException): compose(overrides=["group=a0"]) # appending a new group cfg = compose(overrides=["+group=a0"]) assert cfg == {"group": {"key": 0}} # force adding is not supported for config groups. with raises( ConfigCompositionException, match=re.escape( "force-add of config groups is not supported: '++group=a1'" ), ): compose(overrides=["++group=a1"])