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

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

Fix to runef involving the same issue as in the previous commit.

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