def test_shiwa_selection(name: str, param: tp.Any, budget: int, num_workers: int, expected: str, caplog: tp.Any) -> None: with caplog.at_level(logging.DEBUG, logger="nevergrad.optimization.optimizerlib"): optlib.registry[name](param, budget=budget, num_workers=num_workers).optim # type: ignore pattern = rf".*{name} selected (?P<name>\w+?) optimizer\." match = re.match(pattern, caplog.text.splitlines()[-1]) assert match is not None, f"Did not detect selection in logs: {caplog.text}" assert match.group("name") == expected
def noisy_inverse_threshold_discretization( indexes: tp.List[int], arity: int = 2, gen: tp.Any = None ) -> np.ndarray: indexes_arr = np.array(indexes, copy=True) pdf_bin_size = 1 / arity # We take a random point in the bin. return scipy.stats.norm.ppf(indexes_arr * pdf_bin_size + gen.rand() * pdf_bin_size) # type: ignore
def __init__(self, *args: tp.Any, **kwargs: tp.Any) -> None: super().__init__() if any( isinstance(x, Parameter) for x in args + tuple(kwargs.values())): raise errors.NevergradTypeError( "Operation with Parameter instances are not supported")
def test_ngopt_selection(name: str, param: tp.Any, budget: int, num_workers: int, expected: str, caplog: tp.Any) -> None: with caplog.at_level(logging.DEBUG, logger="nevergrad.optimization.optimizerlib"): # pylint: disable=expression-not-assigned opt = optlib.registry[name](param, budget=budget, num_workers=num_workers) # pylint: disable=pointless-statement opt.optim # type: ignore pattern = rf".*{name} selected (?P<name>\w+?) optimizer\." match = re.match(pattern, caplog.text.splitlines()[-1]) assert match is not None, f"Did not detect selection in logs: {caplog.text}" choice = match.group("name") if expected != "#CONTINUOUS": assert choice == expected else: print( f"Continuous param={param} budget={budget} workers={num_workers} --> {choice}" ) if num_workers >= budget and budget > 600: assert choice == "MetaTuneRecentering" if num_workers > 1: assert choice not in ["SQP", "Cobyla"] assert choice == opt._info()["sub-optim"]
def stopping_criterion(self, optimizer: tp.Any) -> bool: """Checks whether a solution was found This is used as stopping criterio callback """ if optimizer.num_tell < 1: return False best = optimizer.pareto_front()[0] return not np.any(best.losses > 0)
def __init__(self, **parameters: tp.Any) -> None: super().__init__() self._content: tp.Dict[tp.Any, Parameter] = {k: as_parameter(p) for k, p in parameters.items()} self._sizes: tp.Optional[tp.Dict[str, int]] = None self._sanity_check(list(self._content.values())) self._ignore_in_repr: tp.Dict[ str, str ] = {} # hacky undocumented way to bypass boring representations
def apply(self, method: str, *args: tp.Any, **kwargs: tp.Any) -> tp.Dict[tp.Any, tp.Any]: """Calls the named method with the provided input parameters (or their subobjects if from the base class!) on the subobjects. """ outputs: tp.Dict[tp.Any, tp.Any] = {} for key, subobj in self.items(): subargs = [self._get_subobject(arg, key) for arg in args] subkwargs = {k: self._get_subobject(kwarg, key) for k, kwarg in kwargs.items()} outputs[key] = getattr(subobj, method)(*subargs, **subkwargs) return outputs
def _convert_to_string(data: tp.Any, extension: str) -> str: """Converts the data into a string to be injected in a file""" if isinstance(data, np.ndarray): string = repr(data.tolist()) else: string = repr(data) if extension in [".h", ".hpp", ".cpp", ".c"] and isinstance( data, np.ndarray): # TODO: custom extensions are handled as python string = string.replace("[", "{").replace("]", "}") return string
def __init__(self, **parameters: tp.Any) -> None: super().__init__() self._subobjects = utils.Subobjects(self, base=core.Parameter, attribute="_content") self._content: tp.Dict[tp.Any, core.Parameter] = { k: core.as_parameter(p) for k, p in parameters.items() } self._sizes: tp.Optional[tp.Dict[str, int]] = None self._sanity_check(list(self._content.values())) self._ignore_in_repr: tp.Dict[ str, str ] = {} # hacky undocumented way to bypass boring representations
def _get_nash(optimizer: tp.Any) -> tp.List[tp.Tuple[tp.Tuple[float, ...], int]]: """Returns an empirical distribution. limited using a threshold equal to max_num_trials^(1/4). """ if not optimizer.archive: return [(optimizer.current_bests["pessimistic"].x, 1)] max_num_trial = max(p.count for p in optimizer.archive.values()) sum_num_trial = sum(p.count for p in optimizer.archive.values()) threshold = np.power(max_num_trial, 0.5) if threshold <= np.power(sum_num_trial, 0.25): return [(optimizer.provide_recommendation(), 1)] # make deterministic at the price of sort complexity return sorted( ((np.frombuffer(k), p.count) for k, p in optimizer.archive.bytesdict.items() if p.count >= threshold), key=operator.itemgetter(1), )
def __call__(self, *args: tp.Any, **kwargs: tp.Any) -> str: """Call the cammand line with addidional arguments The keyword arguments will be sent as --{key}={val} The logs are bufferized. They will be printed if the job fails, or sent as output of the function Errors are provided with the internal stderr """ # TODO make the following command more robust (probably fails in multiple cases) full_command = (self.command + [str(x) for x in args] + ["--{}={}".format(x, y) for x, y in kwargs.items()]) if self.verbose: print(f"The following command is sent: {full_command}") outlines: tp.List[str] = [] with subprocess.Popen( full_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, cwd=self.cwd, env=self.env, ) as process: try: assert process.stdout is not None for line in iter(process.stdout.readline, b""): if not line: break outlines.append(line.decode().strip()) if self.verbose: print(outlines[-1], flush=True) except Exception: # pylint: disable=broad-except process.kill() process.wait() raise FailedJobError("Job got killed for an unknown reason.") stderr = process.communicate()[1] # we already got stdout stdout = "\n".join(outlines) retcode = process.poll() if stderr and (retcode or self.verbose): print(stderr.decode(), file=sys.stderr) if retcode: subprocess_error = subprocess.CalledProcessError(retcode, process.args, output=stdout, stderr=stderr) raise FailedJobError(stderr.decode()) from subprocess_error return stdout
def test_cma_logs(capsys: tp.Any) -> None: opt = registry["CMA"](2, budget=300, num_workers=4) [opt.ask() for _ in range(4)] # pylint: disable=expression-not-assigned captured = capsys.readouterr() assert captured.out == "" assert captured.err == ""