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

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

Eliminating the direct use of cProfile, which is not
backwards compatible to Python 2.4

  • 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
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("--profile",
113                     help="Enable profiling of Python code.  The value of this option is the number of functions that are summarized.",
114                     action="store",
115                     dest="profile",
116                     default=0)
117   parser.add_option("--disable-gc",
118                     help="Disable the python garbage collecter. Default is False.",
119                     action="store_true",
120                     dest="disable_gc",
121                     default=False)
122   parser.usage=usage_string
123
124   return parser
125   
126def run_ef_writer(options, args):
127
128   # if the user enabled the addition of the weighted cvar term to the objective,
129   # then validate the associated parameters.
130   generate_weighted_cvar = False
131   cvar_weight = None
132   risk_alpha = None
133
134   if options.generate_weighted_cvar is True:
135
136      generate_weighted_cvar = True
137      cvar_weight = options.cvar_weight
138      risk_alpha = options.risk_alpha
139
140   scenario_tree, binding_instance, scenario_instances = write_ef_from_scratch(os.path.expanduser(options.model_directory),
141                                                                               os.path.expanduser(options.instance_directory),
142                                                                               os.path.expanduser(options.output_file),
143                                                                               options.verbose,
144                                                                               generate_weighted_cvar, cvar_weight, risk_alpha)
145
146   if (scenario_tree is None) or (binding_instance is None) or (scenario_instances is None):
147      raise RuntimeError, "Failed to write extensive form."     
148
149   if options.solve_ef is True:
150
151      ef_solver = SolverFactory(options.solver_type)
152      if ef_solver is None:
153         raise ValueError, "Failed to create solver of type="+options.solver_type+" for use in extensive form solve"
154      if len(options.solver_options) > 0:
155         print "Initializing ef solver with options="+str(options.solver_options)         
156         ef_solver.set_options("".join(options.solver_options))
157      if options.mipgap is not None:
158         if (options.mipgap < 0.0) or (options.mipgap > 1.0):
159            raise ValueError, "Value of the mipgap parameter for the EF solve must be on the unit interval; value specified=" + `options.mipgap`
160         else:
161            ef_solver.mipgap = options.mipgap
162
163      ef_solver_manager = SolverManagerFactory(options.solver_manager_type)
164      if ef_solver is None:
165         raise ValueError, "Failed to create solver manager of type="+options.solver_type+" for use in extensive form solve"
166
167      # at this point you have a specific solver - communicate solver capabilities
168      # to the writer via the instance.
169      binding_instance.has_capability = ef_solver.has_capability
170      for scenario_name, scenario_instance in scenario_instances.items():
171         scenario_instance.has_capability = ef_solver.has_capability
172
173      print "Queuing extensive form solve"
174      ef_action_handle = ef_solver_manager.queue(os.path.expanduser(options.output_file), opt=ef_solver, warmstart=False, tee=options.output_solver_log)
175      print "Waiting for extensive form solve"
176      ef_results = ef_solver_manager.wait_for(ef_action_handle)
177      load_ef_solution(ef_results, binding_instance, scenario_instances)
178      scenario_tree.snapshotSolutionFromInstances(scenario_instances)
179      print ""
180      print "Extensive form solution:"
181      scenario_tree.pprintSolution()
182      print ""
183      print "Extensive form costs:"
184      scenario_tree.pprintCosts(scenario_instances)
185
186def run(args=None):
187
188    #
189    # Top-level command that executes the extensive form writer.
190    # This is segregated from run_ef_writer to enable profiling.
191    #
192
193    #
194    # Parse command-line options.
195    #
196    try:
197       options_parser = construct_ef_writer_options_parser("runef [options]")
198       (options, args) = options_parser.parse_args(args=args)
199    except SystemExit:
200       # the parser throws a system exit if "-h" is specified - catch
201       # it to exit gracefully.
202       return
203
204    if options.disable_gc is True:
205       gc.disable()
206    else:
207       gc.enable()
208
209    if options.profile > 0:
210        #
211        # Call the main ef writer with profiling.
212        #
213        tfile = pyutilib.services.TempfileManager.create_tempfile(suffix=".profile")
214        tmp = profile.runctx('run_ef_writer(options,args)',globals(),locals(),tfile)
215        p = pstats.Stats(tfile).strip_dirs()
216        p.sort_stats('time', 'cum')
217        options.profile = eval(options.profile)
218        p = p.print_stats(options.profile)
219        p.print_callers(options.profile)
220        p.print_callees(options.profile)
221        p = p.sort_stats('cum','calls')
222        p.print_stats(options.profile)
223        p.print_callers(options.profile)
224        p.print_callees(options.profile)
225        p = p.sort_stats('calls')
226        p.print_stats(options.profile)
227        p.print_callers(options.profile)
228        p.print_callees(options.profile)
229        pyutilib.services.TempfileManager.clear_tempfiles()
230        ans = [tmp, None]
231    else:
232        #
233        # Call the main EF writer without profiling.
234        #
235        ans = run_ef_writer(options, args)
236
237    gc.enable()
238   
239    return ans
240
Note: See TracBrowser for help on using the repository browser.