source: coopr.pysp/trunk/coopr/pysp/ef_writer_script.py @ 2986

Last change on this file since 2986 was 2986, checked in by jwatson, 11 years ago

Removing an inadvertent "warmstart=False" keyword argument from the solve call for the PySP runef script. GLPK doesn't recognize this keyword at all, which was causing the solve to crater. The correct answer is to not pass the argument to any solver in this context, as (1) the solver may not be warm-start capable and (2) there isn't anything to warm-start from anyway.

  • Property svn:executable set to *
File size: 10.2 KB
Line 
1#  _________________________________________________________________________
2#
3#  Coopr: A COmmon Optimization Python Repository
4#  Copyright (c) 2009 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
12import sys
13import os
14from optparse import OptionParser
15
16import pyutilib.services
17import textwrap
18import traceback
19try:
20    import cProfile as profile
21except ImportError:
22    import profile
23import pstats
24import gc
25
26from coopr.pysp.ef import *
27
28from coopr.opt.base import SolverFactory
29from coopr.opt.parallel import SolverManagerFactory
30
31#
32# utility method to construct an option parser for ef writer arguments
33#
34
35def construct_ef_writer_options_parser(usage_string):
36
37   parser = OptionParser()
38   parser.add_option("--verbose",
39                     help="Generate verbose output, beyond the usual status output. Default is False.",
40                     action="store_true",
41                     dest="verbose",
42                     default=False)
43   parser.add_option("--model-directory",
44                     help="The directory in which all model (reference and scenario) definitions are stored. Default is \".\".",
45                     action="store",
46                     dest="model_directory",
47                     type="string",
48                     default=".")
49   parser.add_option("--instance-directory",
50                     help="The directory in which all instance (reference and scenario) definitions are stored. Default is \".\".",
51                     action="store",
52                     dest="instance_directory",
53                     type="string",
54                     default=".")
55   parser.add_option("--generate-weighted-cvar",
56                     help="Add a weighted CVaR term to the primary objective",
57                     action="store_true",
58                     dest="generate_weighted_cvar",
59                     default=False)
60   parser.add_option("--cvar-weight",
61                     help="The weight associated with the CVaR term in the risk-weighted objective formulation. Default is 1.0. If the weight is 0, then *only* a non-weighted CVaR cost will appear in the EF objective - the expected cost component will be dropped.",
62                     action="store",
63                     dest="cvar_weight",
64                     type="float",
65                     default=1.0)
66   parser.add_option("--risk-alpha",
67                     help="The probability threshold associated with cvar (or any future) risk-oriented performance metrics. Default is 0.95.",
68                     action="store",
69                     dest="risk_alpha",
70                     type="float",
71                     default=0.95)
72   parser.add_option("--output-file",
73                     help="Specify the name of the extensive form output file",
74                     action="store",
75                     dest="output_file",
76                     type="string",
77                     default="efout.lp")
78   parser.add_option("--solve",
79                     help="Following write of the extensive form model, solve it.",
80                     action="store_true",
81                     dest="solve_ef",
82                     default=False)
83   parser.add_option("--solver",
84                     help="The type of solver used to solve scenario sub-problems. Default is cplex.",
85                     action="store",
86                     dest="solver_type",
87                     type="string",
88                     default="cplex")
89   parser.add_option("--solver-manager",
90                     help="The type of solver manager used to coordinate scenario sub-problem solves. Default is serial.",
91                     action="store",
92                     dest="solver_manager_type",
93                     type="string",
94                     default="serial")
95   parser.add_option("--solver-options",
96                     help="Solver options for the extension form problem.",
97                     action="append",
98                     dest="solver_options",
99                     type="string",
100                     default=[])
101   parser.add_option("--mipgap",
102                     help="Specifies the mipgap for the EF solve.",
103                     action="store",
104                     dest="mipgap",
105                     type="float",
106                     default=None)   
107   parser.add_option("--output-solver-log",
108                     help="Output solver log during the extensive form solve.",
109                     action="store_true",
110                     dest="output_solver_log",
111                     default=False)
112   parser.add_option("--keep-solver-files",
113                     help="Retain temporary input and output files for solve.",
114                     action="store_true",
115                     dest="keep_solver_files",
116                     default=False)   
117   parser.add_option("--profile",
118                     help="Enable profiling of Python code.  The value of this option is the number of functions that are summarized.",
119                     action="store",
120                     dest="profile",
121                     default=0)
122   parser.add_option("--disable-gc",
123                     help="Disable the python garbage collecter. Default is False.",
124                     action="store_true",
125                     dest="disable_gc",
126                     default=False)
127   parser.usage=usage_string
128
129   return parser
130   
131def run_ef_writer(options, args):
132
133   # if the user enabled the addition of the weighted cvar term to the objective,
134   # then validate the associated parameters.
135   generate_weighted_cvar = False
136   cvar_weight = None
137   risk_alpha = None
138
139   if options.generate_weighted_cvar is True:
140
141      generate_weighted_cvar = True
142      cvar_weight = options.cvar_weight
143      risk_alpha = options.risk_alpha
144
145   scenario_tree, binding_instance, scenario_instances = write_ef_from_scratch(os.path.expanduser(options.model_directory),
146                                                                               os.path.expanduser(options.instance_directory),
147                                                                               os.path.expanduser(options.output_file),
148                                                                               options.verbose,
149                                                                               generate_weighted_cvar, cvar_weight, risk_alpha)
150
151   if (scenario_tree is None) or (binding_instance is None) or (scenario_instances is None):
152      raise RuntimeError, "Failed to write extensive form."     
153
154   if options.solve_ef is True:
155
156      ef_solver = SolverFactory(options.solver_type)
157      if ef_solver is None:
158         raise ValueError, "Failed to create solver of type="+options.solver_type+" for use in extensive form solve"
159      if len(options.solver_options) > 0:
160         print "Initializing ef solver with options="+str(options.solver_options)         
161         ef_solver.set_options("".join(options.solver_options))
162      if options.mipgap is not None:
163         if (options.mipgap < 0.0) or (options.mipgap > 1.0):
164            raise ValueError, "Value of the mipgap parameter for the EF solve must be on the unit interval; value specified=" + `options.mipgap`
165         else:
166            ef_solver.mipgap = options.mipgap
167      if options.keep_solver_files is True:
168         ef_solver.keepFiles = True         
169
170      ef_solver_manager = SolverManagerFactory(options.solver_manager_type)
171      if ef_solver is None:
172         raise ValueError, "Failed to create solver manager of type="+options.solver_type+" for use in extensive form solve"
173
174      # at this point you have a specific solver - communicate solver capabilities
175      # to the writer via the instance.
176      binding_instance.has_capability = ef_solver.has_capability
177      for scenario_name, scenario_instance in scenario_instances.items():
178         scenario_instance.has_capability = ef_solver.has_capability
179
180      print "Queuing extensive form solve"
181      ef_action_handle = ef_solver_manager.queue(os.path.expanduser(options.output_file), opt=ef_solver, tee=options.output_solver_log)
182      print "Waiting for extensive form solve"
183      ef_results = ef_solver_manager.wait_for(ef_action_handle)
184      load_ef_solution(ef_results, binding_instance, scenario_instances)
185      scenario_tree.snapshotSolutionFromInstances(scenario_instances)
186      print ""
187      print "Extensive form solution:"
188      scenario_tree.pprintSolution()
189      print ""
190      print "Extensive form costs:"
191      scenario_tree.pprintCosts(scenario_instances)
192
193def run(args=None):
194
195    #
196    # Top-level command that executes the extensive form writer.
197    # This is segregated from run_ef_writer to enable profiling.
198    #
199
200    #
201    # Parse command-line options.
202    #
203    try:
204       options_parser = construct_ef_writer_options_parser("runef [options]")
205       (options, args) = options_parser.parse_args(args=args)
206    except SystemExit:
207       # the parser throws a system exit if "-h" is specified - catch
208       # it to exit gracefully.
209       return
210
211    if options.disable_gc is True:
212       gc.disable()
213    else:
214       gc.enable()
215
216    if options.profile > 0:
217        #
218        # Call the main ef writer with profiling.
219        #
220        tfile = pyutilib.services.TempfileManager.create_tempfile(suffix=".profile")
221        tmp = profile.runctx('run_ef_writer(options,args)',globals(),locals(),tfile)
222        p = pstats.Stats(tfile).strip_dirs()
223        p.sort_stats('time', 'cum')
224        options.profile = eval(options.profile)
225        p = p.print_stats(options.profile)
226        p.print_callers(options.profile)
227        p.print_callees(options.profile)
228        p = p.sort_stats('cum','calls')
229        p.print_stats(options.profile)
230        p.print_callers(options.profile)
231        p.print_callees(options.profile)
232        p = p.sort_stats('calls')
233        p.print_stats(options.profile)
234        p.print_callers(options.profile)
235        p.print_callees(options.profile)
236        pyutilib.services.TempfileManager.clear_tempfiles()
237        ans = [tmp, None]
238    else:
239        #
240        # Call the main EF writer without profiling.
241        #
242        ans = run_ef_writer(options, args)
243
244    gc.enable()
245   
246    return ans
247
Note: See TracBrowser for help on using the repository browser.