abstract loop body into Runner class
This commit is contained in:
parent
3c7b41b562
commit
953f522360
2 changed files with 86 additions and 50 deletions
|
@ -153,6 +153,73 @@ for problem_list in GO_BENCHMARKS.values():
|
|||
), "please use Infinity instead; it's basically equivalent"
|
||||
|
||||
|
||||
class Runner:
|
||||
def __init__(self, multiple=2, run_anyway=3, always_run_anyway=True, quiet=False):
|
||||
self.multiple = multiple
|
||||
self.run_anyway = run_anyway
|
||||
self.always_run_anyway = always_run_anyway
|
||||
self.quiet = quiet
|
||||
self._wrapped = None
|
||||
|
||||
def run(
|
||||
self, optimizer, objective, size, budget, frugal_percent=1.0, greedy_percent=2.0
|
||||
):
|
||||
note = (lambda s: None) if self.quiet else m36
|
||||
warn = m33
|
||||
|
||||
opt_name = optimizer.__name__
|
||||
obj_name = objective.__name__
|
||||
obj_realname = getattr(objective, "__realname__", obj_name)
|
||||
|
||||
wrapped_kwargs = dict(
|
||||
objective=objective,
|
||||
optimizer=optimizer,
|
||||
budget=budget,
|
||||
size=size,
|
||||
frugal_percent=frugal_percent,
|
||||
greedy_percent=greedy_percent,
|
||||
)
|
||||
if self._wrapped is None:
|
||||
wrapped = COWrap(**wrapped_kwargs)
|
||||
else:
|
||||
# this can be 10+ times faster.
|
||||
wrapped = self._wrapped.attempt_reuse(**wrapped_kwargs)
|
||||
self._wrapped = wrapped
|
||||
|
||||
results = []
|
||||
|
||||
run = 1
|
||||
while (cache := wrapped.cached(run)) is not None:
|
||||
run += 1
|
||||
fopt, xopt, history = cache
|
||||
results.append((fopt, opt_name, history))
|
||||
|
||||
once = False
|
||||
while (
|
||||
run <= self.multiple
|
||||
or (self.always_run_anyway or not once)
|
||||
and self.run_anyway
|
||||
and run <= self.run_anyway
|
||||
):
|
||||
# assert run == wrapped._run, (run, wrapped._run)
|
||||
if run != (_run := wrapped._run):
|
||||
warn(f"Note: updating local run count from {run} to {_run}.")
|
||||
run = _run
|
||||
continue # check conditions again
|
||||
|
||||
note(
|
||||
f"Using {opt_name} to optimize {obj_realname} ({obj_name}) [{run}] ..."
|
||||
)
|
||||
_ = optimizer(wrapped, size=size, budget=budget)
|
||||
fopt, xopt = wrapped.finish()
|
||||
result = (fopt, opt_name, wrapped.history)
|
||||
results.append(result)
|
||||
once = True
|
||||
run += 1
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def main(argv, display=True):
|
||||
from .utilities import fib
|
||||
from .utilities import prune_results, perform_another_experimental_scoring_method
|
||||
|
@ -199,7 +266,7 @@ def main(argv, display=True):
|
|||
if type(score) is float:
|
||||
assert type(price) is float, "type mismatch"
|
||||
# unweight = 10 # len(optimizers) # sum(place_scores)
|
||||
unweight = multiple * np.sqrt(len(optimizers))
|
||||
unweight = runner.multiple * np.sqrt(len(optimizers))
|
||||
stats = f"(score:{score * unweight:4.0f}, price:{price * unweight:4.0f})"
|
||||
else:
|
||||
stats = f"(score:{score:4}, price:{price:4})"
|
||||
|
@ -253,9 +320,7 @@ def main(argv, display=True):
|
|||
old_summary = True
|
||||
note = (lambda s: None) if quieter else m36
|
||||
|
||||
multiple = 2
|
||||
run_anyway = 3
|
||||
always_run_anyway = True
|
||||
runner = Runner()
|
||||
|
||||
percents = dict(frugal_percent=1.0, greedy_percent=2.0)
|
||||
|
||||
|
@ -270,7 +335,11 @@ def main(argv, display=True):
|
|||
size = abs(size)
|
||||
objectives = GO_BENCHMARKS[size] # * multiple
|
||||
optimizers = list(which) # copy
|
||||
ms = f" ({multiple}+{run_anyway-multiple} times)" if multiple != 1 else ""
|
||||
ms = (
|
||||
f" ({runner.multiple}+{runner.run_anyway - runner.multiple} times)"
|
||||
if runner.multiple != 1
|
||||
else ""
|
||||
)
|
||||
n_obj = len(objectives)
|
||||
n_opt = len(optimizers)
|
||||
print(f"Optimizing {n_obj} objectives{ms} with {n_opt} optimizers...")
|
||||
|
@ -281,54 +350,12 @@ def main(argv, display=True):
|
|||
|
||||
results = {}
|
||||
for optimizer in prog(pseudo_shuffled(optimizers), pref="m"):
|
||||
opt_name = optimizer.__name__
|
||||
wrapped = None
|
||||
for objective in prog(pseudo_shuffled(objectives), pref="s"):
|
||||
obj_name = objective.__name__
|
||||
obj_realname = getattr(objective, "__realname__", obj_name)
|
||||
|
||||
if wrapped is None:
|
||||
wrapped = COWrap(
|
||||
objective,
|
||||
optimizer=optimizer,
|
||||
budget=budget,
|
||||
size=size,
|
||||
**percents,
|
||||
)
|
||||
else:
|
||||
wrapped.objective = objective # 10+ times faster
|
||||
|
||||
run = 1
|
||||
while (cache := wrapped.cached(run)) is not None:
|
||||
run += 1
|
||||
fopt, xopt, history = cache
|
||||
results.setdefault(obj_name, []).append((fopt, opt_name, history))
|
||||
|
||||
once = False
|
||||
while (
|
||||
run <= multiple
|
||||
or (always_run_anyway or not once)
|
||||
and run_anyway
|
||||
and run <= run_anyway
|
||||
):
|
||||
# assert run == wrapped._run, (run, wrapped._run)
|
||||
if run != (_run := wrapped._run):
|
||||
m33(f"Note: updating local run count from {run} to {_run}.")
|
||||
run = _run
|
||||
continue # check conditions again
|
||||
|
||||
note(
|
||||
f"Using {opt_name} to optimize {obj_realname} ({obj_name}) [{run}] ..."
|
||||
)
|
||||
_ = optimizer(wrapped, size=size, budget=budget)
|
||||
fopt, xopt = wrapped.finish()
|
||||
result = (fopt, opt_name, wrapped.history)
|
||||
results.setdefault(obj_name, []).append(result)
|
||||
once = True
|
||||
run += 1
|
||||
new_results = runner.run(optimizer, objective, size, budget)
|
||||
results.setdefault(objective.__name__, []).extend(new_results)
|
||||
|
||||
all_results = results
|
||||
results = prune_results(results, multiple, _check=old_summary)
|
||||
results = prune_results(results, runner.multiple, _check=old_summary)
|
||||
|
||||
scores, prices = {}, {}
|
||||
all_opt_names = set()
|
||||
|
|
|
@ -162,6 +162,15 @@ class COWrap:
|
|||
self._cached_summaries = None
|
||||
self.reset_objective()
|
||||
|
||||
# this should always have the same arguments as __init__.
|
||||
def attempt_reuse(self, objective, *, optimizer, size, budget, **kwargs):
|
||||
if self.optimizer != optimizer or self.size != size or self.budget != budget:
|
||||
return type(self)(
|
||||
objective, optimizer=optimizer, size=size, budget=budget, **kwargs
|
||||
)
|
||||
self.objective = objective
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
"<COWrap on "
|
||||
|
|
Loading…
Reference in a new issue