def __init__(self, *args, **kwds): if self.__class__ is _ScenarioTreeManagerSolverWorker: raise NotImplementedError( "%s is an abstract class for subclassing" % self.__class__) super(_ScenarioTreeManagerSolverWorker, self).__init__(*args, **kwds) assert self.manager is not None # solver related objects self._scenario_solvers = {} self._bundle_solvers = {} self._preprocessor = None self._solver_manager = None # there are situations in which it is valuable to snapshot / # store the solutions associated with the scenario # instances. for example, when one wants to use a warm-start # from a particular iteration solve, following a modification # and re-solve of the problem instances in a user-defined # callback. the following nested dictionary is intended to # serve that purpose. The nesting is dependent on whether # bundling and or phpyro is in use self._cached_solutions = {} self._cached_scenariotree_solutions = {} # # initialize the preprocessor # self._preprocessor = None if not self.get_option("disable_advanced_preprocessing"): self._preprocessor = ScenarioTreePreprocessor( self._options, options_prefix=self._options_prefix) assert self._manager.preprocessor is None self._manager.preprocessor = self._preprocessor # # initialize the solver manager # self._solver_manager = SolverManagerFactory( self.get_option("solver_manager"), host=self.get_option('solver_manager_pyro_host'), port=self.get_option('solver_manager_pyro_port')) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None solver = self._scenario_solvers[scenario.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if self._preprocessor is not None: self._preprocessor.add_scenario(scenario, scenario._instance, solver) for bundle in self.manager.scenario_tree._scenario_bundles: solver = self._bundle_solvers[bundle.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) bundle_instance = \ self.manager._bundle_binding_instance_map[bundle.name] if self._preprocessor is not None: self._preprocessor.add_bundle(bundle, bundle_instance, solver)
def _declare_options(cls, options=None): if options is None: options = PySPConfigBlock() # options for controlling the solver manager # (not the scenario tree manager) safe_declare_common_option(options, "solver_manager_pyro_host") safe_declare_common_option(options, "solver_manager_pyro_port") safe_declare_common_option(options, "solver_manager_pyro_shutdown") ScenarioTreePreprocessor._declare_options(options) return options
class _ScenarioTreeManagerSolverWorker(ScenarioTreeManagerSolver, PySPConfiguredObject): @classmethod def _declare_options(cls, options=None): if options is None: options = PySPConfigBlock() # options for controlling the solver manager # (not the scenario tree manager) safe_declare_common_option(options, "solver_manager_pyro_host") safe_declare_common_option(options, "solver_manager_pyro_port") safe_declare_common_option(options, "solver_manager_pyro_shutdown") ScenarioTreePreprocessor._declare_options(options) return options @property def preprocessor(self): return self._preprocessor def __init__(self, *args, **kwds): if self.__class__ is _ScenarioTreeManagerSolverWorker: raise NotImplementedError( "%s is an abstract class for subclassing" % self.__class__) super(_ScenarioTreeManagerSolverWorker, self).__init__(*args, **kwds) # TODO: Does this import need to be delayed because # it is in a plugins subdirectory? from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver assert self.manager is not None # solver related objects self._scenario_solvers = {} self._bundle_solvers = {} self._preprocessor = None self._solver_manager = None # there are situations in which it is valuable to snapshot / # store the solutions associated with the scenario # instances. for example, when one wants to use a warm-start # from a particular iteration solve, following a modification # and re-solve of the problem instances in a user-defined # callback. the following nested dictionary is intended to # serve that purpose. The nesting is dependent on whether # bundling and or phpyro is in use self._cached_solutions = {} self._cached_scenariotree_solutions = {} # # initialize the preprocessor # self._preprocessor = None if not self.get_option("disable_advanced_preprocessing"): self._preprocessor = ScenarioTreePreprocessor(self._options, options_prefix=self._options_prefix) assert self._manager.preprocessor is None self._manager.preprocessor = self._preprocessor # # initialize the solver manager # self._solver_manager = SolverManagerFactory( self.get_option("solver_manager"), host=self.get_option('solver_manager_pyro_host'), port=self.get_option('solver_manager_pyro_port')) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None solver = self._scenario_solvers[scenario.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") if self._preprocessor is not None: self._preprocessor.add_scenario(scenario, scenario._instance, solver) for bundle in self.manager.scenario_tree._scenario_bundles: solver = self._bundle_solvers[bundle.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") bundle_instance = \ self.manager._bundle_binding_instance_map[bundle.name] if self._preprocessor is not None: self._preprocessor.add_bundle(bundle, bundle_instance, solver) # # Override some methods for ScenarioTreeManager that # were implemented by _ScenarioTreeManagerWorker: # def _close_impl(self): if (self._manager is not None) and \ (self._manager.preprocessor is not None): assert self.preprocessor is self._manager.preprocessor for bundle in self.manager.scenario_tree._scenario_bundles: self._preprocessor.remove_bundle(bundle) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None self._preprocessor.remove_scenario(scenario) self._manager.preprocessor = None self._preprocessor = None else: assert self._preprocessor is None if self._solver_manager is not None: self._solver_manager.deactivate() self._solver_manager = None if self.get_option("solver_manager_pyro_shutdown"): print("Shutting down Pyro components for solver manager.") shutdown_pyro_components( host=self.get_option("solver_manager_pyro_host"), port=self.get_option("solver_manager_pyro_port"), num_retries=0, caller_name=self.__class__.__name__) for solver in self._scenario_solvers.values(): solver.deactivate() self._scenario_solvers = {} for solver in self._bundle_solvers.values(): solver.deactivate() self._bundle_solvers = {} self._preprocessor = None self._objective_sense = None # # Abstract methods for ScenarioTreeManagerSolver: # def _queue_object_solves(self, object_type, objects, ephemeral_solver_options, disable_warmstart): if self.get_option("verbose"): print("Queuing %s solves" % (object_type[:-1])) assert object_type in ('bundles', 'scenarios') solver_dict = None instance_dict = None modify_kwds_func = None if object_type == 'bundles': if objects is None: objects = self.manager.scenario_tree._scenario_bundle_map solver_dict = self._bundle_solvers instance_dict = self.manager._bundle_binding_instance_map for bundle_name in objects: for scenario_name in self.manager.scenario_tree.\ get_bundle(bundle_name).\ scenario_names: self.manager.scenario_tree.get_scenario(scenario_name).\ _instance_objective.deactivate() if self.preprocessor is not None: self.preprocessor.preprocess_bundles(bundles=objects) modify_kwds_func = self.preprocessor.modify_bundle_solver_keywords else: if objects is None: objects = self.manager.scenario_tree._scenario_map solver_dict = self._scenario_solvers instance_dict = self.manager._instances if self.manager.scenario_tree.contains_bundles(): for scenario_name in objects: self.manager.scenario_tree.get_scenario(scenario_name).\ _instance_objective.activate() if self.preprocessor is not None: self.preprocessor.preprocess_scenarios(scenarios=objects) modify_kwds_func = self.preprocessor.modify_scenario_solver_keywords assert solver_dict is not None assert instance_dict is not None # setup common solve keywords common_kwds = {} common_kwds['tee'] = self.get_option("output_solver_log") common_kwds['keepfiles'] = self.get_option("keep_solver_files") common_kwds['symbolic_solver_labels'] = \ self.get_option("symbolic_solver_labels") # we always manually load solutions, so we can # control error reporting and such common_kwds['load_solutions'] = False # Load solver options solver_options = {} if type(self.get_option("solver_options")) is tuple: solver_options.update( OptSolver._options_string_to_dict( "".join(self.get_option("solver_options")))) else: solver_options.update(self.get_option("solver_options")) common_kwds['options'] = solver_options # # override "persistent" values that are included from this # classes registered options # if ephemeral_solver_options is not None: common_kwds['options'].update(ephemeral_solver_options) # maps action handles to subproblem names action_handle_data = {} for object_name in objects: if modify_kwds_func is not None: # be sure to modify a copy of the kwds solve_kwds = modify_kwds_func(object_name, dict(common_kwds)) else: solve_kwds = common_kwds opt = solver_dict[object_name] instance = instance_dict[object_name] if (not self.get_option("disable_warmstart")) and \ (not disable_warmstart) and \ opt.warm_start_capable(): new_action_handle = \ self._solver_manager.queue(instance, opt=opt, warmstart=True, **solve_kwds) else: new_action_handle = \ self._solver_manager.queue(instance, opt=opt, **solve_kwds) action_handle_data[new_action_handle] = object_name return self.manager.AsyncResult( self._solver_manager, action_handle_data=action_handle_data)
def __init__(self, *args, **kwds): if self.__class__ is _ScenarioTreeManagerSolverWorker: raise NotImplementedError( "%s is an abstract class for subclassing" % self.__class__) super(_ScenarioTreeManagerSolverWorker, self).__init__(*args, **kwds) # TODO: Does this import need to be delayed because # it is in a plugins subdirectory? from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver assert self.manager is not None # solver related objects self._scenario_solvers = {} self._bundle_solvers = {} self._preprocessor = None self._solver_manager = None # there are situations in which it is valuable to snapshot / # store the solutions associated with the scenario # instances. for example, when one wants to use a warm-start # from a particular iteration solve, following a modification # and re-solve of the problem instances in a user-defined # callback. the following nested dictionary is intended to # serve that purpose. The nesting is dependent on whether # bundling and or phpyro is in use self._cached_solutions = {} self._cached_scenariotree_solutions = {} # # initialize the preprocessor # self._preprocessor = None if not self.get_option("disable_advanced_preprocessing"): self._preprocessor = ScenarioTreePreprocessor(self._options, options_prefix=self._options_prefix) assert self._manager.preprocessor is None self._manager.preprocessor = self._preprocessor # # initialize the solver manager # self._solver_manager = SolverManagerFactory( self.get_option("solver_manager"), host=self.get_option('solver_manager_pyro_host'), port=self.get_option('solver_manager_pyro_port')) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None solver = self._scenario_solvers[scenario.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") if self._preprocessor is not None: self._preprocessor.add_scenario(scenario, scenario._instance, solver) for bundle in self.manager.scenario_tree._scenario_bundles: solver = self._bundle_solvers[bundle.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") bundle_instance = \ self.manager._bundle_binding_instance_map[bundle.name] if self._preprocessor is not None: self._preprocessor.add_bundle(bundle, bundle_instance, solver)
class _ScenarioTreeManagerSolverWorker(ScenarioTreeManagerSolver, PySPConfiguredObject): @classmethod def _declare_options(cls, options=None): if options is None: options = PySPConfigBlock() # options for controlling the solver manager # (not the scenario tree manager) safe_declare_common_option(options, "solver_manager_pyro_host") safe_declare_common_option(options, "solver_manager_pyro_port") safe_declare_common_option(options, "solver_manager_pyro_shutdown") ScenarioTreePreprocessor._declare_options(options) return options @property def preprocessor(self): return self._preprocessor def __init__(self, *args, **kwds): if self.__class__ is _ScenarioTreeManagerSolverWorker: raise NotImplementedError( "%s is an abstract class for subclassing" % self.__class__) super(_ScenarioTreeManagerSolverWorker, self).__init__(*args, **kwds) # TODO: Does this import need to be delayed because # it is in a plugins subdirectory? from pyomo.solvers.plugins.solvers.persistent_solver import \ PersistentSolver assert self.manager is not None # solver related objects self._scenario_solvers = {} self._bundle_solvers = {} self._preprocessor = None self._solver_manager = None # there are situations in which it is valuable to snapshot / # store the solutions associated with the scenario # instances. for example, when one wants to use a warm-start # from a particular iteration solve, following a modification # and re-solve of the problem instances in a user-defined # callback. the following nested dictionary is intended to # serve that purpose. The nesting is dependent on whether # bundling and or phpyro is in use self._cached_solutions = {} self._cached_scenariotree_solutions = {} # # initialize the preprocessor # self._preprocessor = None if not self.get_option("disable_advanced_preprocessing"): self._preprocessor = ScenarioTreePreprocessor(self._options, options_prefix=self._options_prefix) assert self._manager.preprocessor is None self._manager.preprocessor = self._preprocessor # # initialize the solver manager # self._solver_manager = SolverManagerFactory( self.get_option("solver_manager"), host=self.get_option('solver_manager_pyro_host'), port=self.get_option('solver_manager_pyro_port')) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None solver = self._scenario_solvers[scenario.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") if self._preprocessor is not None: self._preprocessor.add_scenario(scenario, scenario._instance, solver) for bundle in self.manager.scenario_tree._scenario_bundles: solver = self._bundle_solvers[bundle.name] = \ SolverFactory(self.get_option("solver"), solver_io=self.get_option("solver_io")) if isinstance(solver, PersistentSolver) and \ self.get_option("disable_advanced_preprocessing"): raise ValueError("Advanced preprocessing can not be disabled " "when persistent solvers are used") bundle_instance = \ self.manager._bundle_binding_instance_map[bundle.name] if self._preprocessor is not None: self._preprocessor.add_bundle(bundle, bundle_instance, solver) # # Override some methods for ScenarioTreeManager that # were implemented by _ScenarioTreeManagerWorker: # def _close_impl(self): if (self._manager is not None) and \ (self._manager.preprocessor is not None): assert self.preprocessor is self._manager.preprocessor for bundle in self.manager.scenario_tree._scenario_bundles: self._preprocessor.remove_bundle(bundle) for scenario in self.manager.scenario_tree._scenarios: assert scenario._instance is not None self._preprocessor.remove_scenario(scenario) self._manager.preprocessor = None self._preprocessor = None else: assert self._preprocessor is None if self._solver_manager is not None: #self._solver_manager.deactivate() self._solver_manager = None if self.get_option("solver_manager_pyro_shutdown"): print("Shutting down Pyro components for solver manager.") shutdown_pyro_components( host=self.get_option("solver_manager_pyro_host"), port=self.get_option("solver_manager_pyro_port"), num_retries=0, caller_name=self.__class__.__name__) #for solver in self._scenario_solvers.values(): # solver.deactivate() self._scenario_solvers = {} #for solver in self._bundle_solvers.values(): # solver.deactivate() self._bundle_solvers = {} self._preprocessor = None self._objective_sense = None # # Abstract methods for ScenarioTreeManagerSolver: # def _queue_object_solves(self, object_type, objects, ephemeral_solver_options, disable_warmstart): if self.get_option("verbose"): print("Queuing %s solves" % (object_type[:-1])) assert object_type in ('bundles', 'scenarios') solver_dict = None instance_dict = None modify_kwds_func = None if object_type == 'bundles': if objects is None: objects = self.manager.scenario_tree._scenario_bundle_map solver_dict = self._bundle_solvers instance_dict = self.manager._bundle_binding_instance_map for bundle_name in objects: for scenario_name in self.manager.scenario_tree.\ get_bundle(bundle_name).\ scenario_names: self.manager.scenario_tree.get_scenario(scenario_name).\ _instance_objective.deactivate() if self.preprocessor is not None: self.preprocessor.preprocess_bundles(bundles=objects) modify_kwds_func = self.preprocessor.modify_bundle_solver_keywords else: if objects is None: objects = self.manager.scenario_tree._scenario_map solver_dict = self._scenario_solvers instance_dict = self.manager._instances if self.manager.scenario_tree.contains_bundles(): for scenario_name in objects: self.manager.scenario_tree.get_scenario(scenario_name).\ _instance_objective.activate() if self.preprocessor is not None: self.preprocessor.preprocess_scenarios(scenarios=objects) modify_kwds_func = self.preprocessor.modify_scenario_solver_keywords assert solver_dict is not None assert instance_dict is not None # setup common solve keywords common_kwds = {} common_kwds['tee'] = self.get_option("output_solver_log") common_kwds['keepfiles'] = self.get_option("keep_solver_files") common_kwds['symbolic_solver_labels'] = \ self.get_option("symbolic_solver_labels") # we always manually load solutions, so we can # control error reporting and such common_kwds['load_solutions'] = False # Load solver options solver_options = {} if type(self.get_option("solver_options")) is tuple: solver_options.update( OptSolver._options_string_to_dict( "".join(self.get_option("solver_options")))) else: solver_options.update(self.get_option("solver_options")) common_kwds['options'] = solver_options # # override "persistent" values that are included from this # classes registered options # if ephemeral_solver_options is not None: common_kwds['options'].update(ephemeral_solver_options) # maps action handles to subproblem names action_handle_data = {} for object_name in objects: if modify_kwds_func is not None: # be sure to modify a copy of the kwds solve_kwds = modify_kwds_func(object_name, dict(common_kwds)) else: solve_kwds = common_kwds opt = solver_dict[object_name] instance = instance_dict[object_name] if (not self.get_option("disable_warmstart")) and \ (not disable_warmstart) and \ opt.warm_start_capable(): new_action_handle = \ self._solver_manager.queue(instance, opt=opt, warmstart=True, **solve_kwds) else: new_action_handle = \ self._solver_manager.queue(instance, opt=opt, **solve_kwds) action_handle_data[new_action_handle] = object_name return self.manager.AsyncResult( self._solver_manager, action_handle_data=action_handle_data)