def __init__(self, cost_oracle: typing.Mapping[str, float], tae: typing.Type[SerialRunner] = ExecuteTARunOld, **kwargs: typing.Any) -> None: ''' Constructor Arguments --------- cost_oracle: typing.Mapping[str,float] cost of oracle per instance ''' super().__init__(**kwargs) self.cost_oracle = cost_oracle if tae is ExecuteTARunAClib: self.runner = ExecuteTARunAClib(**kwargs) # type: SerialRunner elif tae is ExecuteTARunOld: self.runner = ExecuteTARunOld(**kwargs) elif tae is ExecuteTAFuncDict: self.runner = ExecuteTAFuncDict(**kwargs) elif tae is ExecuteTAFuncArray: self.runner = ExecuteTAFuncArray(**kwargs) else: raise Exception('TAE not supported')
def test_run_execute_func_for_fmin(self, mock): mock.return_value = {'x1': 2, 'x2': 1} c = Configuration(configuration_space=self.cs, values={}) target = lambda x: x[0]**2 + x[1] taf = ExecuteTAFuncArray(target, stats=self.stats) rval = taf._call_ta(target, c) self.assertEqual(rval, 5)
def test_epils(self): taf = ExecuteTAFuncArray(ta=self.branin) epils = EPILS(self.scenario, tae_runner=taf) inc = epils.optimize() # not enough runs available to change the inc self.assertEqual(inc["x"], 2.5) self.assertEqual(inc["y"], 7.5)
def test_inject_stats_and_runhistory_object_to_TAE(self): ta = ExecuteTAFuncArray(lambda x: x**2) self.assertIsNone(ta.stats) self.assertIsNone(ta.runhistory) ROAR(tae_runner=ta, scenario=self.scenario) self.assertIsInstance(ta.stats, Stats) self.assertIsInstance(ta.runhistory, RunHistory)
class ExecuteTARunHydra(ExecuteTARun): """Returns min(cost, cost_portfolio) """ def __init__(self, cost_oracle: typing.Mapping[str, float], tae: typing.Type[ExecuteTARun] = ExecuteTARunOld, **kwargs): ''' Constructor Arguments --------- cost_oracle: typing.Mapping[str,float] cost of oracle per instance ''' super().__init__(**kwargs) self.cost_oracle = cost_oracle if tae is ExecuteTARunAClib: self.runner = ExecuteTARunAClib(**kwargs) elif tae is ExecuteTARunOld: self.runner = ExecuteTARunOld(**kwargs) elif tae is ExecuteTAFuncDict: self.runner = ExecuteTAFuncDict(**kwargs) elif tae is ExecuteTAFuncArray: self.runner = ExecuteTAFuncArray(**kwargs) else: raise Exception('TAE not supported') def run(self, **kwargs): """ see ~smac.tae.execute_ta_run.ExecuteTARunOld for docstring """ status, cost, runtime, additional_info = self.runner.run(**kwargs) inst = kwargs["instance"] try: oracle_perf = self.cost_oracle[inst] except KeyError: oracle_perf = None if oracle_perf is not None: if self.run_obj == "runtime": self.logger.debug("Portfolio perf: %f vs %f = %f", oracle_perf, runtime, min(oracle_perf, runtime)) runtime = min(oracle_perf, runtime) cost = runtime else: self.logger.debug("Portfolio perf: %f vs %f = %f", oracle_perf, cost, min(oracle_perf, cost)) cost = min(oracle_perf, cost) if oracle_perf < kwargs['cutoff'] and status is StatusType.TIMEOUT: status = StatusType.SUCCESS else: self.logger.error( "Oracle performance missing --- should not happen") return status, cost, runtime, additional_info
def fmin_smac(func: callable, x0: list, bounds: list, maxfun: int = -1, maxtime: int = -1, rng: np.random.RandomState = None): """ Minimize a function func using the SMAC algorithm. This function is a convenience wrapper for the SMAC class. Parameters ---------- func : callable f(x) Function to minimize. x0 : list Initial guess/default configuration. bounds : list ``(min, max)`` pairs for each element in ``x``, defining the bound on that parameters. maxtime : int, optional Maximum runtime in seconds. maxfun : int, optional Maximum number of function evaluations. rng : np.random.RandomState, optional Random number generator used by SMAC. Returns ------- x : list Estimated position of the minimum. f : float Value of `func` at the minimum. s : :class:`smac.facade.smac_facade.SMAC` SMAC objects which enables the user to get e.g., the trajectory and runhistory. """ # create configuration space cs = ConfigurationSpace() for idx, (lower_bound, upper_bound) in enumerate(bounds): parameter = UniformFloatHyperparameter(name="x%d" % (idx + 1), lower=lower_bound, upper=upper_bound, default_value=x0[idx]) cs.add_hyperparameter(parameter) # Create target algorithm runner ta = ExecuteTAFuncArray(ta=func) # create scenario scenario_dict = { "run_obj": "quality", "cs": cs, "deterministic": "true", "initial_incumbent": "DEFAULT" } if maxfun > 0: scenario_dict["runcount_limit"] = maxfun if maxtime > 0: scenario_dict["wallclock_limit"] = maxtime scenario = Scenario(scenario_dict) smac = SMAC(scenario=scenario, tae_runner=ta, rng=rng) smac.logger = logging.getLogger(smac.__module__ + "." + smac.__class__.__name__) incumbent = smac.optimize() config_id = smac.solver.runhistory.config_ids[incumbent] run_key = RunKey(config_id, None, 0) incumbent_performance = smac.solver.runhistory.data[run_key] incumbent = np.array( [incumbent['x%d' % (idx + 1)] for idx in range(len(bounds))], dtype=np.float) return incumbent, incumbent_performance.cost, \ smac
class ExecuteTARunHydra(SerialRunner): """Returns min(cost, cost_portfolio) """ def __init__(self, cost_oracle: typing.Mapping[str, float], tae: typing.Type[SerialRunner] = ExecuteTARunOld, **kwargs: typing.Any) -> None: ''' Constructor Arguments --------- cost_oracle: typing.Mapping[str,float] cost of oracle per instance ''' super().__init__(**kwargs) self.cost_oracle = cost_oracle if tae is ExecuteTARunAClib: self.runner = ExecuteTARunAClib(**kwargs) # type: SerialRunner elif tae is ExecuteTARunOld: self.runner = ExecuteTARunOld(**kwargs) elif tae is ExecuteTAFuncDict: self.runner = ExecuteTAFuncDict(**kwargs) elif tae is ExecuteTAFuncArray: self.runner = ExecuteTAFuncArray(**kwargs) else: raise Exception('TAE not supported') def run( self, config: Configuration, instance: str, cutoff: typing.Optional[float] = None, seed: int = 12345, budget: typing.Optional[float] = None, instance_specific: str = "0" ) -> typing.Tuple[StatusType, float, float, typing.Dict]: """ see ~smac.tae.execute_ta_run.ExecuteTARunOld for docstring """ if cutoff is None: raise ValueError('Cutoff of type None is not supported') status, cost, runtime, additional_info = self.runner.run( config=config, instance=instance, cutoff=cutoff, seed=seed, budget=budget, instance_specific=instance_specific, ) if instance in self.cost_oracle: oracle_perf = self.cost_oracle[instance] if self.run_obj == "runtime": self.logger.debug("Portfolio perf: %f vs %f = %f", oracle_perf, runtime, min(oracle_perf, runtime)) runtime = min(oracle_perf, runtime) cost = runtime else: self.logger.debug("Portfolio perf: %f vs %f = %f", oracle_perf, cost, min(oracle_perf, cost)) cost = min(oracle_perf, cost) if oracle_perf < cutoff and status is StatusType.TIMEOUT: status = StatusType.SUCCESS else: self.logger.error( "Oracle performance missing --- should not happen") return status, cost, runtime, additional_info
def fmin_smac(func: typing.Callable, x0: typing.List[float], bounds: typing.List[typing.List[float]], maxfun: int=-1, rng: np.random.RandomState=None, scenario_args: typing.Mapping[str, typing.Any]=None, **kwargs): """ Minimize a function func using the BORF facade (i.e., a modified version of SMAC). This function is a convenience wrapper for the BORF class. Parameters ---------- func : typing.Callable Function to minimize. x0 : typing.List[float] Initial guess/default configuration. bounds : typing.List[typing.List[float]] ``(min, max)`` pairs for each element in ``x``, defining the bound on that parameters. maxfun : int, optional Maximum number of function evaluations. rng : np.random.RandomState, optional Random number generator used by SMAC. scenario_args: typing.Mapping[str,typing.Any] Arguments passed to the scenario See smac.scenario.scenario.Scenario **kwargs: Arguments passed to the optimizer class See ~smac.facade.smac_facade.SMAC Returns ------- x : list Estimated position of the minimum. f : float Value of `func` at the minimum. s : :class:`smac.facade.smac_facade.SMAC` SMAC objects which enables the user to get e.g., the trajectory and runhistory. """ # create configuration space cs = ConfigurationSpace() # Adjust zero padding tmplt = 'x{0:0' + str(len(str(len(bounds)))) + 'd}' for idx, (lower_bound, upper_bound) in enumerate(bounds): parameter = UniformFloatHyperparameter(name=tmplt.format(idx + 1), lower=lower_bound, upper=upper_bound, default_value=x0[idx]) cs.add_hyperparameter(parameter) # Create target algorithm runner ta = ExecuteTAFuncArray(ta=func) # create scenario scenario_dict = { "run_obj": "quality", "cs": cs, "deterministic": "true", "initial_incumbent": "DEFAULT", } if scenario_args is not None: scenario_dict.update(scenario_args) if maxfun > 0: scenario_dict["runcount_limit"] = maxfun scenario = Scenario(scenario_dict) smac = BORF(scenario=scenario, tae_runner=ta, rng=rng, **kwargs) smac.logger = logging.getLogger(smac.__module__ + "." + smac.__class__.__name__) incumbent = smac.optimize() config_id = smac.solver.runhistory.config_ids[incumbent] run_key = RunKey(config_id, None, 0) incumbent_performance = smac.solver.runhistory.data[run_key] incumbent = np.array([incumbent[tmplt.format(idx + 1)] for idx in range(len(bounds))], dtype=np.float) return incumbent, incumbent_performance.cost, smac