From f1924e054ab76dc7b2401775b818932714cb00ba Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 17 Jul 2024 10:16:19 +0100 Subject: [PATCH 1/2] Fix 'minimal register usage' optimization objective --- slothy/core/core.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/slothy/core/core.py b/slothy/core/core.py index cddf4fdd..113319e9 100644 --- a/slothy/core/core.py +++ b/slothy/core/core.py @@ -1231,7 +1231,6 @@ def __init__(self, config): self._kernel_input_output = None self._pre_core_post_dict = None self._codesize_with_bubbles = None - self._register_used = None self._optimization_wall_time = None self._optimization_user_time = None @@ -2201,7 +2200,7 @@ def _allow_renaming(_): if self.config.constraints.minimize_register_usage is not None: ty = self.config.constraints.minimize_register_usage regs = self.arch.RegisterType.list_registers(ty) - self._register_used = { reg : self._NewBoolVar(f"reg_used[{reg}]") for reg in regs } + self._model._register_used = { reg : self._NewBoolVar(f"reg_used[{reg}]") for reg in regs } # Create variables for register renaming @@ -2506,9 +2505,9 @@ def _add_constraints_register_renaming(self): for reg in self.arch.RegisterType.list_registers(ty): arr = self._model.register_usage_vars.get(reg,[]) if len(arr) > 0: - self._model.AddMaxEquality(self._register_used[reg], arr) + self._AddMaxEquality(self._model._register_used[reg], arr) else: - self._Add(self._register_used[reg] is False) + self._Add(self._model._register_used[reg] == False) # Ensure that outputs are unambiguous for t in self._get_nodes(allnodes=True): @@ -3064,8 +3063,6 @@ def _add_objective(self, force_objective=False): name = None printer = None - # We only support objectives of the form: Maximize/Minimize the sum of a set of variables. - # If the number of stalls is variable, its minimization is our objective if force_objective is False and self.config.variable_size: name = "minimize cycles" @@ -3090,8 +3087,8 @@ def _add_objective(self, force_objective=False): maxlist = [ t.program_start_var for t in self._get_nodes() ] name = "move stalls to top" elif self.config.constraints.minimize_register_usage is not None: - # Minimize the number of registers used - minlist = list(self._register_used.values()) + minlist = list(self._model._register_used.values()) + name = "minimize number of registers used" elif self.config.constraints.minimize_use_of_extra_registers is not None: ty = self.config.constraints.minimize_use_of_extra_registers minlist = [] @@ -3169,6 +3166,8 @@ def _AddHint(self,var,val): # pylint:disable=invalid-name return self._model.cp_model.AddHint(var,val) def _AddNoOverlap(self,interval_list): # pylint:disable=invalid-name return self._model.cp_model.AddNoOverlap(interval_list) + def _AddMaxEquality(self,varlist,var): # pylint:disable=invalid-name + return self._model.cp_model.AddMaxEquality(varlist, var) def _export_model(self): if self.config.log_model is None: From ae8087e2fabd2a6bba2988a7cba2fe53b91bcd2b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 17 Jul 2024 10:16:41 +0100 Subject: [PATCH 2/2] Fix binary search routine for `functional_only` runs --- slothy/core/heuristics.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/slothy/core/heuristics.py b/slothy/core/heuristics.py index 79f2ad4a..63acdf7e 100644 --- a/slothy/core/heuristics.py +++ b/slothy/core/heuristics.py @@ -128,10 +128,14 @@ def optimize_binsearch(source, logger, conf, **kwargs): The Result object for the succceeding optimization with the smallest number of stalls. """ + flexible = not conf.constraints.functional_only + if conf.variable_size: - return Heuristics.optimize_binsearch_internal(source, logger, conf, **kwargs) + return Heuristics.optimize_binsearch_internal(source, logger, conf, + flexible=flexible, **kwargs) - return Heuristics.optimize_binsearch_external(source, logger, conf, **kwargs) + return Heuristics.optimize_binsearch_external(source, logger, conf, + flexible=flexible, **kwargs) @staticmethod def _log_reoptimization_failure(log): @@ -201,7 +205,7 @@ def optimize_binsearch_external(source, logger, conf, flexible=True, **kwargs): return core.result @staticmethod - def optimize_binsearch_internal(source, logger, conf, **kwargs): + def optimize_binsearch_internal(source, logger, conf, flexible=True, **kwargs): """Internally optimize for minimum number of stalls, and potentially a secondary objective. This finds the minimum number of stalls for which a one-shot SLOTHY optimization succeeds. @@ -213,11 +217,21 @@ def optimize_binsearch_internal(source, logger, conf, **kwargs): logger: The logger to be used. conf: The configuration to apply. This is fixed for all one-shot SLOTHY runs invoked by this call, except for variation of stall count. + flexible: Indicates whether the number of stalls should be minimized + through a binary search, or whether a single one-shot SLOTHY optimization + for a fixed number of stalls (encoded in the configuration) should be + conducted. Returns: A Result object representing the final optimization result. """ + if not flexible: + core = SlothyBase(conf.arch, conf.target, logger=logger,config=conf) + if not core.optimize(source): + raise SlothyException("Optimization failed") + return core.result + logger.info("Perform internal binary search for minimal number of stalls...") start_attempt = conf.constraints.stalls_first_attempt