source: coopr.pysp/trunk/coopr/pysp/phsolvermanager.py @ 3261

Last change on this file since 3261 was 2594, checked in by wehart, 11 years ago

Rework of package to use new plugin factory mechanism
supported by pyutilib.component.core

File size: 5.2 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2010 Sandia Corporation.
5#  This software is distributed under the BSD License.
6#  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7#  the U.S. Government retains certain rights in this software.
8#  For more information, see the Coopr README.txt file.
9#  _________________________________________________________________________
10
11
12__all__ = []
13
14import Pyro.core
15import Pyro.naming
16
17from coopr.opt.parallel.manager import *
18from coopr.opt.parallel.solver import *
19from coopr.pyomo import *
20from pyutilib.component.core import alias
21
22try:
23   import cPickle as pickle
24except ImportError:
25   import pickle
26
27# a solver manager that communicates with remote PH solver servers
28# via the Pyro RMI mechanism.
29
30class PHSolverManager(AsynchronousSolverManager):
31
32    alias('ph')
33
34    def __init__(self):
35        """Constructor"""
36
37        AsynchronousSolverManager.__init__(self)
38
39        # fire up Pyro.
40        Pyro.core.initClient(banner=0)       
41
42        # locate the name server and cache it.
43        self._locator = Pyro.naming.NameServerLocator()
44        self._ns = None
45        try:
46           self._ns = self._locator.getNS()
47        except Pyro.errors.NamingError:
48           raise RuntimeError, "PHSolverManager failed to locate Pyro name server"
49
50        # the PH solver server object proxies are cached for speed.
51        # map is from scenario name to proxy object.
52        self._solver_proxy = {}
53
54    #
55    # a utility to identify (and create if necessary) the
56    # appropriate proxy object for a given scenario.
57    #
58
59    def _identify_proxy(self, scenario_name):
60
61       proxy = None
62       if scenario_name in self._solver_proxy.keys():
63          proxy = self._solver_proxy[scenario_name]
64       else:
65          uri = None
66          try:
67             uri = self._ns.resolve(scenario_name)
68          except Pyro.errors.NamingError:
69             raise RuntimeError, "***ERROR: Failed to locate PH solver server capable of processing scenario="+scenario_name
70             sys.exit(0)
71
72          proxy = Pyro.core.getProxyForURI(uri)
73          self._solver_proxy[scenario_name] = proxy
74       return proxy
75
76    def clear(self):
77        """
78        Clear manager state
79        """
80        AsynchronousSolverManager.clear(self)
81        self._ah_list = []
82        self._opt = None
83
84    def _perform_queue(self, ah, *args, **kwds):
85        """
86        Perform the queue operation.  This method returns the ActionHandle,
87        and the ActionHandle status indicates whether the queue was successful.
88        """
89       
90        # extract the instance and the scenario name.
91        if len(args) != 1:
92           raise RuntimeError, "Only one argument to _perform_queue method of class PHSolverManager expected - "+str(len(args))+" were supplied"
93        scenario_instance = args[0]
94        if isinstance(scenario_instance, Model) is False:
95           raise RuntimeError, "Argument supplied to _perform_queue method of class PHSolverManager must be a Model instance - type supplied="+str(type(scenario_instance))
96        scenario_name = scenario_instance.name
97
98        # process any keywordds - we generally don't expect any.
99        if 'opt' in kwds:
100            self._opt = kwds['opt']
101            del kwds['opt']
102        if self._opt is None:
103            raise ActionManagerError, "Undefined solver"
104
105        # TBD - we don't actually transfer any solver options
106        #       at the moment, but we will soon!
107
108        proxy = self._identify_proxy(scenario_name)
109        encoded_result = proxy.solve(scenario_name)
110        self.results[ah.id] = pickle.loads(encoded_result)
111        ah.status = ActionStatus.done
112        self._ah_list.append(ah)
113        return ah
114
115    def _perform_wait_any(self):
116        """
117        Perform the wait_any operation.  This method returns an
118        ActionHandle with the results of waiting.  If None is returned
119        then the ActionManager assumes that it can call this method again.
120        Note that an ActionHandle can be returned with a dummy value,
121        to indicate an error.
122        """
123        if len(self._ah_list) > 0:
124            return self._ah_list.pop()
125        return ActionHandle(error=True, explanation="No queued evaluations available in the PH solver manager, which only executes solvers synchronously")
126
127    def enable_ph_objective(self, scenario_instance):
128
129       proxy = self._identify_proxy(scenario_instance.name)
130       proxy.enable_ph_objective()
131
132    def transmit_weights_and_averages(self, scenario_instance, new_weights, new_averages):
133
134       proxy = self._identify_proxy(scenario_instance.name)
135       proxy.update_weights_and_averages(scenario_instance.name, new_weights, new_averages)
136
137    def transmit_rhos(self, scenario_instance, new_rhos):
138
139       proxy = self._identify_proxy(scenario_instance.name)
140       proxy.update_rhos(scenario_instance.name, new_rhos)
141
142    def transmit_tree_node_statistics(self, scenario_instance, tree_node_minimums, tree_node_maximums):
143       
144       proxy = self._identify_proxy(scenario_instance.name)
145       proxy.update_tree_node_statistics(scenario_instance.name, tree_node_minimums, tree_node_maximums)   
146
Note: See TracBrowser for help on using the repository browser.