From def1ad89584e22619f02d76150c7829bb7e4461b Mon Sep 17 00:00:00 2001 From: Yifan Zhao <yifanz16@illinois.edu> Date: Sun, 14 Mar 2021 23:57:31 -0500 Subject: [PATCH] Handle relative speedup better --- predtuner/approxapp.py | 17 +++++++++++++---- test/integrated_tuning.py | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/predtuner/approxapp.py b/predtuner/approxapp.py index 0775ec8..552229d 100644 --- a/predtuner/approxapp.py +++ b/predtuner/approxapp.py @@ -113,6 +113,10 @@ class Config: self.knobs = dict(sorted(knobs.items())) self.test_qos: Optional[float] = test_qos + @property + def qos_speedup(self): + return self.qos, 1 / self.cost + T = TypeVar("T", bound=Config) @@ -213,7 +217,7 @@ class ApproxTuner(Generic[T]): @staticmethod def take_best_configs(configs: List[T], n: Optional[int] = None) -> List[T]: - points = np.array([[c.cost, c.qos] for c in configs]) + points = np.array([c.qos_speedup for c in configs]) taken_idx = is_pareto_efficient(points, take_n=n) return [configs[i] for i in taken_idx] @@ -237,12 +241,11 @@ class ApproxTuner(Generic[T]): f"No tuning session has been run; call self.tune() first." ) - _, cost = self.app.measure_qos_cost({}, False) fig, ax = plt.subplots() confs = self.kept_configs if not confs: return fig - qos_speedup = [(c.qos, cost / c.cost) for c in confs] + qos_speedup = [c.qos_speedup for c in confs] qoses, speedups = zip(*sorted(qos_speedup, key=lambda p: p[0])) ax.plot(qoses, speedups) ax.scatter(qoses, speedups) @@ -315,6 +318,8 @@ class TunerInterface(MeasurementInterface): self.keep_thres = keep_thres self.pbar = tqdm(total=test_limit, leave=False) self.app_kwargs = app_kwargs + _, self.baseline_cost = app.measure_qos_cost({}, False, **self.app_kwargs) + msg_logger.debug(f"Baseline cost = {self.baseline_cost}") # tune_thres can come in as np.float64 and opentuner doesn't like that objective = ThresholdAccuracyMinimizeTime(float(tuner_thres)) @@ -343,6 +348,9 @@ class TunerInterface(MeasurementInterface): cfg = desired_result.configuration.data qos, cost = self.app.measure_qos_cost(cfg, False, **self.app_kwargs) + # We only want to measure cost in relative. + # This `cost` is inverse of speedup because opentuner needs a lower-better value. + cost /= self.baseline_cost # Print a debug message for each config in tuning and keep threshold self.print_debug_config(qos, cost) self.pbar.update(self.progress_getter() - self.pbar.n) @@ -362,5 +370,6 @@ class TunerInterface(MeasurementInterface): else: kind = "tuning and keep" msg_logger.debug( - f"Found config within {kind} threshold: QoS = {qos}, cost = {cost}" + f"Found config within {kind} threshold: QoS = {qos}, " + f"cost = {cost} ({1 / cost} speedup)" ) diff --git a/test/integrated_tuning.py b/test/integrated_tuning.py index 0ea3541..fe7f9e1 100644 --- a/test/integrated_tuning.py +++ b/test/integrated_tuning.py @@ -36,3 +36,5 @@ baseline, _ = app.measure_qos_cost({}, False) tuner = app.get_tuner() tuner.tune(100, 2.1, 3.0, True, 50, cost_model="cost_linear", qos_model="qos_p1") tuner.dump_configs("tuner_results/test/configs.json") +fig = tuner.plot_configs() +fig.savefig("tuner_results/test/configs.png", dpi=300) -- GitLab