source: coopr.pyomo/trunk/coopr/pyomo/scripting/util.py @ 2213

Last change on this file since 2213 was 2213, checked in by wehart, 10 years ago

Adding the ability to process multiple *.dat files on the Pyomo command line

File size: 10.9 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
11import sys
12import os
13import textwrap
14import traceback
15import cProfile
16import pstats
17import gc
18from coopr.pyomo import *
19from coopr.opt.base import SolverFactory
20from coopr.opt.parallel import SolverManagerFactory
21import pyutilib.services
22import pyutilib.misc
23
24filter_excepthook=False
25
26#
27# Print information about modeling components supported by Pyomo
28#
29def print_components(options):
30    print ""
31    print "----------------------------------------------------------------" 
32    print "Pyomo Model Components:"
33    print "----------------------------------------------------------------" 
34    components = pyomo.model_components()
35    index = pyutilib.misc.sort_index(components)
36    for i in index:
37        print ""
38        print " "+components[i][0]
39        for line in textwrap.wrap(components[i][1], 59):
40            print "    "+line
41    print ""
42    print "----------------------------------------------------------------" 
43    print "Pyomo Virtual Sets:"
44    print "----------------------------------------------------------------" 
45    pyomo_sets = pyomo.predefined_sets()
46    index = pyutilib.misc.sort_index(pyomo_sets)
47    for i in index:
48        print ""
49        print " "+pyomo_sets[i][0]
50        print "    "+pyomo_sets[i][1]
51
52#
53# Setup Pyomo execution environment
54#
55def setup_environment(options, args):
56    #
57    # Disable garbage collection
58    #
59    if options.disable_gc:
60        gc.disable()
61    #
62    # Setup verbose debugging mode
63    #
64    pyomo.reset_debugging()
65    #
66    # Setup debugging for specific Pyomo components
67    #
68    if options.debug is not None:
69       for val in options.debug:
70         pyomo.set_debugging( val )
71    if options.verbose:
72       pyomo.set_debugging("verbose")
73    #
74    # Setup I/O redirect to a logfile
75    #
76    if not options.logfile is None:
77        pyutilib.misc.setup_redirect(options.logfile)
78    #
79    # Setup management for temporary files
80    #
81    if not options.tempdir is None:
82        if not os.path.exists(options.tempdir):
83            raise ValueError, "Directory for temporary files does not exist: "+options.tempdir
84        pyutilib.services.TempfileManager.tempdir = options.tempdir
85    #
86    # Configure exception management
87    #
88    def pyomo_excepthook(etype,value,tb):
89        global filter_excepthook
90        model=""
91        if len(args) > 0:
92            model=args[0]
93        print ""
94        msg = "ERROR: Unexpected exception while %s %s" % ('loading' if filter_excepthook else 'running', 'model '+model if model != "" else "")
95        print msg
96        print "  ",value
97        print ""
98        tb_list = traceback.extract_tb(tb,None)
99        i=0
100        if not pyomo.debug("all") and filter_excepthook:
101            while i < len(tb_list):
102                print "Y",model,tb_list[i][0]
103                if model in tb_list[i][0]:
104                    break
105                i += 1
106        print "Traceback (most recent call last):"
107        for item in tb_list[i:]:
108            print "  File \""+item[0]+"\", line "+str(item[1])+", in "+item[2]
109            if item[3] is not None:
110                print "    "+item[3]
111        sys.exit(1)
112    sys.excepthook = pyomo_excepthook
113    return True
114
115#
116# Execute preprocessing files
117#
118def apply_preprocessing(options, parser, args):
119    #
120    #
121    # Setup solver and model
122    #
123    #
124    if len(args) == 0:
125        parser.print_help()
126        return False
127    #
128    for file in options.preprocess:
129        preprocess = pyutilib.misc.import_file(file)
130    return True
131       
132#
133# Create instance of Pyomo model
134#
135def create_model(options, args):
136    global filter_excepthook
137    #
138    # Verify that files exist
139    #
140    for file in args:
141        if not os.path.exists(file):
142            raise IOError, "File "+file+" does not exist!"
143    #
144    # Create Model
145    #
146    filter_excepthook=True
147    usermodel = pyutilib.misc.import_file(args[0])
148    filter_excepthook=False
149    if options.model_name in dir(usermodel):
150        model = getattr(usermodel, options.model_name)
151        if model is None:
152            print ""
153            raise SystemExit, "'%s' object equals 'None' in module %s" % (options.model_name, args[0])
154            sys.exit(0)
155    elif 'create_model' in dir(usermodel):
156        model = getattr(usermodel, 'create_model')( pyutilib.misc.Container(*options.model_options) )
157    else:
158       print ""
159       raise SystemExit, "Neither '%s' nor 'create_model' are available in module %s" % (options.model_name,args[0])
160       #sys.exit(0)
161    #
162    # Create Problem Instance
163    #
164    if len(args) > 2:
165        #
166        # Load a list of *.dat files
167        #
168        modeldata = ModelData()
169        for file in args[1:]:
170            suffix = (file).split(".")[-1]
171            if suffix != "dat":
172                raise SystemExit, "When specifying multiple data files, they must all be *.dat files: "+str(file)
173            modeldata.add_data_file(file)
174        modeldata.read(model)
175        instance = model.create(modeldata)
176         
177    elif len(args) == 2:
178       #
179       # Load a *.dat file or process a *.py data file
180       #
181       suffix = (args[1]).split(".")[-1]
182       if suffix == "dat":
183          instance = model.create(args[1])
184       elif suffix == "py":
185          userdata = pyutilib.misc.import_file(args[1])
186          if "modeldata" not in dir(userdata):
187             raise SystemExit, "No 'modeldata' object created in module "+args[1]
188          if userdata.modeldata is None:
189             raise SystemExit, "'modeldata' object equals 'None' in module "+args[1]
190          userdata.modeldata.read(model)
191          instance = model.create(userdata.modeldata)
192       else:
193          raise ValueError, "Unknown data file type: "+args[1]
194    else:
195       instance = model.create()
196    if pyomo.debug("instance"):
197       print "MODEL INSTANCE"
198       instance.pprint()
199       print ""
200
201    if not options.save_model is None:
202        if options.save_model == True:
203            if options.format in [ProblemFormat.cpxlp,ProblemFormat.lpxlp]:
204                fname = (args[1])[:-3]+'lp'
205            else:
206                fname = (args[1])[:-3]+str(options.format)
207            format=options.format
208        else:
209            fname = options.save_model
210            format=None
211        instance.write(filename=fname, format=format)
212        if not os.path.exists(fname):
213            print "ERROR: file "+fname+" has not been created!"
214        else:
215            print "Model written to file '"+str(fname)+"'"
216
217    return instance
218
219#
220# Perform optimization with concrete instance
221#
222def apply_optimizer(options, instance):
223    #
224    # Create Solver and Perform Optimization
225    #
226    opt = SolverFactory( options.solver )
227    if opt is None:
228       raise ValueError, "Problem constructing solver `"+str(options.solver)+"'"
229    opt.keepFiles=options.keepfiles or options.log
230    if options.timelimit == 0:
231       options.timelimit=None
232    if options.solver_mipgap is not None:
233       opt.mipgap = options.solver_mipgap
234    solver_mngr = SolverManagerFactory( options.smanager_type )
235    if solver_mngr is None:
236       raise ValueError, "Problem constructing solver manager `"+str(options.smanager_type)+"'"
237    results = solver_mngr.solve(instance, opt=opt, tee=options.tee, timelimit=options.timelimit, options=" ".join(options.solver_options))
238    if results == None:
239            raise ValueError, "opt.solve returned None"
240    return results, opt
241
242#
243# Process results
244#
245def process_results(options, instance, results, opt):
246   
247    if options.log:
248       print ""
249       print "=========================================================="
250       print "Solver Logfile:",opt.log_file
251       print "=========================================================="
252       print ""
253       INPUT = open(opt.log_file, "r")
254       for line in INPUT:
255         print line,
256       INPUT.close()
257   
258    try:
259        instance.load(results)
260    except Exception, e:
261        print "Problem loading solver results"
262        raise
263    print ""
264    results.write(num=1)
265   
266    if options.summary:
267       print ""
268       print "=========================================================="
269       print "Solution Summary"
270       print "=========================================================="
271       if len(results.solution(0).variable) > 0:
272          print ""
273          display(instance)
274       else:
275          print "No solutions reported by solver."
276    return True
277
278def apply_postprocessing(options, instance, results):
279    for file in options.postprocess:
280        postprocess = pyutilib.misc.import_file(file)
281        if "postprocess" in dir(postprocess):
282            postprocess.postprocess(instance,results)
283       
284
285def run_command(command, parser, args=None, name='unknown'):
286    #
287    # Execute a function that processes command-line arguments and then
288    # calls a command-line driver.  This
289    # is segregated from the driver to enable profiling.
290    #
291
292    #
293    #
294    # Parse command-line options
295    #
296    #
297    try:
298       (options, nargs) = parser.parse_args(args=args)
299    except SystemExit:
300       # the parser throws a system exit if "-h" is specified - catch
301       # it to exit gracefully.
302       return
303
304    #
305    # Call the main Pyomo runner with profiling
306    #
307    if options.profile > 0:
308        tfile = pyutilib.services.TempfileManager.create_tempfile(suffix=".profile")
309        tmp = cProfile.runctx(command.__name__+'(options=options,args=nargs,parser=parser)',globals(),locals(),tfile)
310        p = pstats.Stats(tfile).strip_dirs()
311        p.sort_stats('time', 'cum')
312        options.profile = eval(options.profile)
313        p = p.print_stats(options.profile)
314        p.print_callers(options.profile)
315        p.print_callees(options.profile)
316        p = p.sort_stats('cum','calls')
317        p.print_stats(options.profile)
318        p.print_callers(options.profile)
319        p.print_callees(options.profile)
320        p = p.sort_stats('calls')
321        p.print_stats(options.profile)
322        p.print_callers(options.profile)
323        p.print_callees(options.profile)
324        pyutilib.services.TempfileManager.clear_tempfiles()
325        ans = [tmp, None]
326    else:
327        #
328        # Call the main Pyomo runner without profiling
329        #
330        try:
331            ans = command(options=options, args=nargs, parser=parser)
332        except SystemExit, err:
333            if pyomo.debug('errors'):
334                sys.exit(0)
335            print 'Exiting %s: %s' % (name, str(err))
336            ans = None
337        except Exception, err:
338            if pyomo.debug('errors'):
339                raise
340            print ""
341            print "ERROR:",str(err)
342            ans = None
343
344    if options.disable_gc:
345        gc.enable()
346    return ans
347
Note: See TracBrowser for help on using the repository browser.