source: trunk/coopr/pyomo/main_script.py @ 1671

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

Bug fix.

  • Property svn:executable set to *
File size: 13.8 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
12import sys
13import os
14from optparse import OptionParser
15#
16# Finish imports
17#
18from coopr.pyomo import *
19from coopr.opt.base import SolverFactory
20from coopr.opt.parallel import SolverManagerFactory
21import pyutilib
22import textwrap
23import traceback
24import cProfile
25import pstats
26import gc
27
28#
29#
30# Setup command-line options
31#
32#
33solver_help=\
34"This option specifies the type of solver that is used "\
35"to solve the Pyomo model instance.  The following solver "\
36"types are are currently supported:"
37_tmp = SolverFactory()
38_tmp.sort()
39for item in _tmp:
40  if item[0] != "_":
41     solver_help += "\n.."+item
42solver_help += ".\nThe default solver is 'glpk'."
43debug_help=\
44"This option is used to turn on debugging output. This option "\
45"can be specified multiple times to turn on different debugging"\
46"output. The following debugging options can be specified:"
47debug_choices=[]
48for item in pyomo.Debug:
49  if str(item) != "none":
50     debug_choices.append( str(item) )
51     debug_help += "\n.."+str(item)
52
53parser = OptionParser()
54parser.add_option("--solver",
55    help=solver_help,
56    action="store",
57    dest="solver",
58    type="string",
59    default="glpk")
60parser.add_option("--path",
61    help="Give a path that is used to find the Pyomo python files",
62    action="store",
63    dest="path",
64    type="string",
65    default=".")
66parser.add_option("--help-components",
67        help="Print information about modeling components supported by Pyomo",
68        action="store_true",
69        dest="help_components",
70        default=False)
71parser.add_option("--debug",
72        help=debug_help,
73        action="append",
74        dest="debug",
75        choices=debug_choices)
76parser.add_option("-k","--keepfiles",
77        help="Keep temporary files",
78        action="store_true",
79        dest="keepfiles",
80        default=False)
81parser.add_option("--tempdir",
82        help="Specify the directory where temporary files are generated",
83        action="store",
84        dest="tempdir",
85        default=None)
86parser.add_option("-q","--quiet",
87        help="Turn off solver output",
88        action="store_true",
89        dest="quiet",
90        default=False)
91parser.add_option("-l","--log",
92        help="Print the solver logfile after performing optimization",
93        action="store_true",
94        dest="log",
95        default=False)
96parser.add_option("--logfile",
97        help="Redirect output to the specified logfile",
98        action="store",
99        dest="logfile",
100        default=None)
101parser.add_option("-s","--summary",
102        help="Summarize the final solution after performing optimization",
103        action="store_true",
104        dest="summary",
105        default=False)
106parser.add_option("--instance-only",
107        help="Generate a model instance, and then return",
108        action="store_true",
109        dest="only_instance",
110        default=False)
111parser.add_option("--profile",
112        help="Enable profiling of Python code.  The value of this option is the number of functions that are summarized.",
113        action="store",
114        dest="profile",
115        default=0)
116parser.add_option("--timelimit",
117        help="Limit to the number of seconds that the solver is run",
118        action="store",
119        dest="timelimit",
120        type="int",
121        default=0)
122parser.add_option("--postprocess",
123        help="Specify a Python module that gets executed after optimization.  If this option is specified multiple times, then the modules are executed in the specified order.",
124        action="append",
125        dest="postprocess",
126        default=[])
127parser.add_option("--preprocess",
128        help="Specify a Python module that gets immediately executed (before the optimization model is setup).  If this option is specified multiple times, then the modules are executed in the specified order.",
129        action="append",
130        dest="preprocess",
131        default=[])
132parser.add_option("-v","--verbose",
133        help="Make solver output verbose",
134        action="store_true",
135        dest="verbose",
136        default=False)
137parser.add_option("--solver-options",
138        help="Options passed into the solver",
139        action="append",
140        dest="solver_options",
141        type="string",
142        default=[])
143parser.add_option("--disable-gc",
144        help="Disable the garbage collecter",
145        action="store_true",
146        dest="disable_gc",
147        default=False)
148parser.add_option("--solver-manager",
149        help="Specify the technique that is used to manage solver executions.",
150        action="store",
151        dest="smanager_type",
152        default="serial")
153parser.add_option("--stream-output",
154        help="Stream the solver output to provide information about the solver's progress.",
155        action="store_true",
156        dest="tee",
157        default=False)
158parser.add_option("--save-model",
159        help="Specify the filename to which the model is saved.  The suffix of this filename specifies the file format.  If debugging is on, then this defaults to writing the file 'unknown.lp'.",
160        action="store",
161        dest="save_model",
162        default=None)
163#
164# These options are depricated until we have a specific use-case for them
165#
166if False:
167  parser.add_option("--seed",
168        help="Specify a seed to derandomize the solver",
169        action="store",
170        dest="seed",
171        type="int",
172        default=0)
173  parser.add_option("--first-feasible",
174        help="Terminate after the first feasible incumbent",
175        action="store_true",
176        dest="ff",
177        default=False)
178parser.usage="pyomo [options] <model.py> [<model.dat>]"
179
180
181def run_pyomo(options, args):
182    #
183    # Run the a command that executes a Pyomo script
184    #
185    if options.help_components:
186        print ""
187        print "----------------------------------------------------------------" 
188        print "Pyomo Model Components:"
189        print "----------------------------------------------------------------" 
190        components = pyomo.model_components()
191        index = pyutilib.sort_index(components)
192        for i in index:
193            print ""
194            print " "+components[i][0]
195            for line in textwrap.wrap(components[i][1], 59):
196                print "    "+line
197        print ""
198        print "----------------------------------------------------------------" 
199        print "Predefined Pyomo Sets:"
200        print "----------------------------------------------------------------" 
201        pyomo_sets = pyomo.predefined_sets()
202        index = pyutilib.sort_index(pyomo_sets)
203        for i in index:
204            print ""
205            print " "+pyomo_sets[i][0]
206            print "    "+pyomo_sets[i][1]
207        return
208
209    #
210    # Process command-line options
211    #
212    if options.disable_gc:
213        gc.disable()
214    if options.verbose:
215       pyomo.set_debugging("verbose")
216    if options.debug is not None:
217       for val in options.debug:
218         pyomo.set_debugging( val )
219    if not options.logfile is None:
220        pyutilib.setup_redirect(options.logfile)
221    if not options.tempdir is None:
222        if not os.path.exists(options.tempdir):
223            raise ValueError, "Directory for temporary files does not exist: "+options.tempdir
224        pyutilib.TempfileManager.tempdir = options.tempdir
225
226    filter_excepthook=True
227    def pyomo_excepthook(etype,value,tb):
228      print ""
229      if filter_excepthook:
230         print "ERROR: Unexpected exception while loading Pyomo model "+args[0]
231      else:
232         print "ERROR: Unexpected exception while running Pyomo model "+args[0]
233      print "  ",value
234      print ""
235      tb_list = traceback.extract_tb(tb,None)
236      i=0
237      if not pyomo.debug("all") and filter_excepthook:
238         while i < len(tb_list):
239           if args[0] in tb_list[i][0]:
240              break
241           i += 1
242      print "Pyomo Traceback (most recent call last):"
243      for item in tb_list[i:]:
244        print "  File \""+item[0]+"\", line "+str(item[1])+", in "+item[2]
245        if item[3] is not None:
246           print "    "+item[3]
247      sys.exit(1)
248   
249    sys.excepthook = pyomo_excepthook
250
251    #
252    # Apply preprocessing steps
253    #
254    for file in options.preprocess:
255        preprocess = pyutilib.import_file(file)
256       
257    #
258    #
259    # Setup solver and model
260    #
261    #
262    if len(args) == 0:
263       parser.print_help()
264       return
265    for file in args:
266      if not os.path.exists(file):
267         print "File "+file+" does not exist!"
268         sys.exit(1)
269
270    #
271    # Create Model
272    #
273    usermodel = pyutilib.import_file(args[0])
274    filter_excepthook=False
275    if "model" not in dir(usermodel):
276       print ""
277       print "Exiting pyomo: No 'model' object created in module "+args[0]
278       sys.exit(0)
279    if usermodel.model is None:
280       print ""
281       print "Exiting pyomo: 'model' object equals 'None' in module "+args[0]
282       sys.exit(0)
283    #
284    # Create Problem Instance
285    #
286    if len(args) == 2:
287       suffix = (args[1]).split(".")[-1]
288       if suffix == "dat":
289          instance = usermodel.model.create(args[1])
290       elif suffix == "py":
291          userdata = pyutilib.import_file(args[1])
292          if "modeldata" not in dir(userdata):
293             print ""
294             print "Exiting pyomo: No 'modeldata' object created in module "+args[1]
295             sys.exit(0)
296          if userdata.modeldata is None:
297             print ""
298             print "Exiting pyomo: 'modeldata' object equals 'None' in module "+args[1]
299             sys.exit(0)
300          userdata.modeldata.read(usermodel.model)
301          instance = usermodel.model.create(userdata.modeldata)
302       else:
303          raise ValueError, "Unknown data file type: "+args[1]
304    else:
305       instance = usermodel.model.create()
306    if pyomo.debug("instance"):
307       print "MODEL INSTANCE"
308       instance.pprint()
309       print ""
310       options.save_model = 'unknown.lp'
311       print "Model instance written in file",options.save_model,"to allow debugging"
312
313    if not options.save_model is None:
314        instance.write(filename=options.save_model, format=None)
315        if not os.path.exists(options.save_model):
316            print "ERROR: file "+options.save_model+" has not been created!"
317
318    if options.only_instance:
319        return [instance, None]
320
321    #
322    # Create Solver and Perform Optimization
323    #
324    opt = SolverFactory( options.solver )
325    if opt is None:
326       raise ValueError, "Problem constructing solver `"+str(options.solver)+"'"
327    opt.keepFiles=options.keepfiles or options.log
328    if options.timelimit == 0:
329       options.timelimit=None
330    solver_mngr = SolverManagerFactory( options.smanager_type )
331    if solver_mngr is None:
332       raise ValueError, "Problem constructing solver manager `"+str(options.smanager_type)+"'"
333    results = solver_mngr.solve(instance, opt=opt, tee=options.tee, timelimit=options.timelimit, options=" ".join(options.solver_options))
334    if results == None:
335            raise ValueError, "opt.solve returned None"
336   
337    if options.log:
338       print ""
339       print "=========================================================="
340       print "Solver Logfile:",opt.log_file
341       print "=========================================================="
342       print ""
343       INPUT = open(opt.log_file, "r")
344       for line in INPUT:
345         print line,
346       INPUT.close()
347   
348    try:
349        instance.load(results)
350    except Exception, e:
351        raise ValueError, "Problem loading solver results: "+str(e)
352    print ""
353    results.write(num=1)
354   
355    if options.summary:
356       print ""
357       print "=========================================================="
358       print "Solution Summary"
359       print "=========================================================="
360       if len(results.solution(0).variable) > 0:
361          print ""
362          display(instance)
363       else:
364          print "No solutions reported by solver."
365
366    for file in options.postprocess:
367        postprocess = pyutilib.import_file(file)
368        if "postprocess" in dir(postprocess):
369            postprocess.postprocess(instance,results)
370       
371    #
372    # Return the model instance and optimization results
373    #
374    return [instance,results]
375
376
377def run(args=None):
378    #
379    # Top-level command that executes a Pyomo script.  This
380    # is segregated from run_pyomo to enable Pyomo profiling.
381    #
382
383    #
384    #
385    # Parse command-line options
386    #
387    #
388    try:
389       (options, args) = parser.parse_args(args=args)
390    except SystemExit:
391       # the parser throws a system exit if "-h" is specified - catch
392       # it to exit gracefully.
393       return
394
395    #
396    # Call the main Pyomo runner with profiling
397    #
398    if options.profile > 0:
399        tfile = pyutilib.TempfileManager.create_tempfile(suffix=".profile")
400        tmp = cProfile.runctx('run_pyomo(options,args)',globals(),locals(),tfile)
401        p = pstats.Stats(tfile).strip_dirs()
402        p.sort_stats('time', 'cum')
403        options.profile = eval(options.profile)
404        p = p.print_stats(options.profile)
405        p.print_callers(options.profile)
406        p.print_callees(options.profile)
407        p = p.sort_stats('cum','calls')
408        p.print_stats(options.profile)
409        p.print_callers(options.profile)
410        p.print_callees(options.profile)
411        p = p.sort_stats('calls')
412        p.print_stats(options.profile)
413        p.print_callers(options.profile)
414        p.print_callees(options.profile)
415        pyutilib.TempfileManager.clear_tempfiles()
416        ans = [tmp, None]
417    else:
418        #
419        # Call the main Pyomo runner without profiling
420        #
421        ans = run_pyomo(options, args)
422
423    gc.enable()
424    return ans
425
Note: See TracBrowser for help on using the repository browser.