source: coopr.plugins/trunk/coopr/plugins/smanager/pyro.py @ 2281

Last change on this file since 2281 was 2281, checked in by jwatson, 9 years ago

Adding a suffixes attribute to the base solver class. This is a list of suffixes that the solver will - assuming it can - load into a solution. Examples are rc, dual, slack, etc. I modified the derived solver plugin classes to throw an exception if provided a suffix that it can't handle. I have little doubt that this change will cause some tests to fail - I'll look at this in a bit. The change was motivated by the expense of querying a solution, loading a solution, and shipping a lot of unnecessary information across the network.

File size: 4.3 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2008 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 pyutilib.misc
15import pyutilib.component.core
16from coopr.opt.parallel.manager import *
17from coopr.opt.parallel.solver import *
18from coopr.opt.results import SolverResults
19
20import pickle
21
22try:
23    import Pyro.core
24    import pyutilib.pyro
25    using_pyro=True
26except ImportError:
27    using_pyro=False
28       
29
30class SolverManager_Pyro(AsynchronousSolverManager):
31
32    def clear(self):
33        """
34        Clear manager state
35        """
36        AsynchronousSolverManager.clear(self)
37        self.client = pyutilib.pyro.Client()
38        self._opt = None
39        self._ah = {}
40
41    def _perform_queue(self, ah, *args, **kwds):
42        """
43        Perform the queue operation.  This method returns the ActionHandle,
44        and the ActionHandle status indicates whether the queue was successful.
45        """
46       
47        if 'opt' in kwds:
48            self._opt = kwds['opt']
49            del kwds['opt']
50        else:
51            raise ActionManagerError, "No solver passed to SolverManager_Pyro, method=_perform_queue; use keyword option \"opt\""
52
53        #
54        # Force coopr.opt to ignore tests for availability, at least locally
55        #
56        kwds['available'] = True
57        self._opt._presolve(*args, **kwds)
58        problem_file_string = open(self._opt._problem_files[0],'r').read()
59
60        #
61        # Delete this option, to ensure that the remote worker does the check for
62        # availability.
63        #
64        del kwds['available']
65
66        #
67        # We can't pickl the options object itself - so extract a simple
68        # dictionary of solver options and re-construct it on the other end.
69        #
70        solver_options = {}
71        for key in self._opt.options:
72           solver_options[key]=self._opt.options[key]
73
74        # pick up the warm-start file, if available.
75        warm_start_file_string = None
76        warm_start_file_name = None
77        if hasattr(self._opt,  "warm_start_solve"):
78           if (self._opt.warm_start_solve is True) and (self._opt.warm_start_file_name is not None):
79              warm_start_file_name = self._opt.warm_start_file_name
80              warm_start_file_string = open(warm_start_file_name, 'r').read()
81
82        #
83        # Pickl everything into one big data object via the "Bunch" command
84        # and post the task!
85        #
86        data=pyutilib.misc.Bunch(opt=self._opt.type, \
87                                 file=problem_file_string, filename=self._opt._problem_files[0], \
88                                 warmstart_file=warm_start_file_string, warmstart_filename=warm_start_file_name, \
89                                 kwds=kwds, solver_options=solver_options, mipgap=self._opt.mipgap, suffixes=self._opt.suffixes)
90        task = pyutilib.pyro.Task(data=data, id=ah.id)
91        self.client.add_task(task)
92        self._ah[task.id] = ah
93       
94        return ah
95
96    def _perform_wait_any(self):
97        """
98        Perform the wait_any operation.  This method returns an
99        ActionHandle with the results of waiting.  If None is returned
100        then the ActionManager assumes that it can call this method again.
101        Note that an ActionHandle can be returned with a dummy value,
102        to indicate an error.
103        """
104        if self.client.num_results() > 0:
105            # this protects us against the case where we get an action
106            # handle that we didn't know about or expect.
107            while(True):
108               task = self.client.get_result()
109               if task.id in self._ah:
110                  ah = self._ah[task.id]
111                  self._ah[task.id] = None
112                  ah.status = ActionStatus.done
113                  #print "HERE",ah.id, task.result
114                  self.results[ah.id] = pickle.loads(task.result)
115                  #self.results[ah.id].write()
116                  return ah
117
118if using_pyro:
119    SolverManagerRegistration("pyro", SolverManager_Pyro)
120
Note: See TracBrowser for help on using the repository browser.