diff --git a/predtuner/approxapp.py b/predtuner/approxapp.py index 61d203b41ceaf9e39200e7112bc16851cb758fdc..5cd82a19e770f6c34208fac1bda6d738c5f6ed4c 100644 --- a/predtuner/approxapp.py +++ b/predtuner/approxapp.py @@ -89,6 +89,13 @@ class ApproxApp(abc.ABC): knobs.append(baseline_knob) return baseline_knob + def add_baseline_to_knobs(self, approxes: KnobsT): + approxes = approxes.copy() + for op_name in self.ops: + if op_name not in approxes: + approxes[op_name] = self.baseline_knob.name + return approxes + class BaselineKnob(ApproxKnob): def __init__(self, name: str = "__baseline__"): diff --git a/predtuner/modeledapp.py b/predtuner/modeledapp.py index 6c5fe7008b41c9ea7859ada00646405512700c9d..06efc8cc69e7898b667f775bb68bb1a5be60a269 100644 --- a/predtuner/modeledapp.py +++ b/predtuner/modeledapp.py @@ -144,12 +144,16 @@ class LinearPerfModel(IPerfModel): """Weighted linear performance predictor based on cost of each operator.""" def __init__( - self, op_costs: Dict[str, float], knob_speedups: Dict[str, float] + self, + app: ModeledApp, + op_costs: Dict[str, float], + knob_speedups: Dict[str, float], ) -> None: import numpy as np import pandas as pd super().__init__() + self.app = app knob_cost_factor_v = 1 / np.array(list(knob_speedups.values())) layer_cost_v = np.array(list(op_costs.values())) costs = np.outer(layer_cost_v, knob_cost_factor_v) @@ -163,6 +167,7 @@ class LinearPerfModel(IPerfModel): def measure_perf(self, with_approxes: KnobsT) -> float: """We implement this using a weighted linear performance model.""" + with_approxes = self.app.add_baseline_to_knobs(with_approxes) return float( sum(self.cost_df.loc[layer, knob] for layer, knob in with_approxes.items()) ) @@ -204,6 +209,7 @@ class QoSModelP1(IQoSModel): def measure_qos(self, with_approxes: KnobsT) -> float: """Implementation of model.""" assert self.baseline_tensor is not None + with_approxes = self.app.add_baseline_to_knobs(with_approxes) delta_tensors = np.array( [self.delta_tensors[op][knob] for op, knob in with_approxes.items()] ) @@ -274,6 +280,7 @@ class QoSModelP2(IQoSModel): def measure_qos(self, with_approxes: KnobsT) -> float: assert self.baseline_qos is not None and self.qos_df is not None + with_approxes = self.app.add_baseline_to_knobs(with_approxes) delta_qoses = ( np.array([self.qos_df.loc[kv] for kv in with_approxes.items()]) - self.baseline_qos diff --git a/predtuner/torchapp.py b/predtuner/torchapp.py index c93bd8adc9e1163fde6603e1734d9764bcbc7964..0e6fc287be85cc0b73766ce91c1034a6e07186d1 100644 --- a/predtuner/torchapp.py +++ b/predtuner/torchapp.py @@ -1,6 +1,6 @@ import abc from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union +from typing import Any, Callable, List, Optional, Set, Tuple, Union import numpy as np import torch @@ -152,7 +152,7 @@ class TorchApp(ModeledApp, abc.ABC): p1_storage = self.model_storage / "p1.pkl" if self.model_storage else None p2_storage = self.model_storage / "p2.json" if self.model_storage else None return [ - LinearPerfModel(self._op_costs, self._knob_speedups), + LinearPerfModel(self, self._op_costs, self._knob_speedups), QoSModelP1( self, self._get_raw_output_valset, batched_valset_qos, p1_storage ),