source: pyomo/trunk/pyomo/scripting/driver_help.py @ 9475

Last change on this file since 9475 was 9475, checked in by wehart, 5 years ago

Updating the version #.

Renaming transformations to 'base.*' if they didn't have a specific
naming. NOTE: these are in the pyomo.core package ... which seems
odd. But we agreed that 'core' provides a connotation that we don't
intend.

Adding some documentation changes for 'pyomo help -t'.

File size: 13.6 KB
Line 
1
2import argparse
3import os
4import os.path
5import sys
6import glob
7import datetime
8import textwrap
9import logging
10
11import pyutilib.subprocess
12
13from pyomo.util import get_pyomo_commands
14import pyomo.scripting.pyomo_parser
15
16logger = logging.getLogger('pyomo.solvers')
17
18
19def setup_command_parser(parser):
20    parser.add_argument("--list", dest="summary", action='store_true', default=False,
21                        help="List the commands that are installed with Pyomo")
22    parser.add_argument("command", nargs='*', help="The command and command-line options")
23
24def command_exec(options):
25    cmddir = os.path.dirname(os.path.abspath(sys.executable))+os.sep
26    if options.summary:
27        print("")
28        print("The following commands are installed in the Pyomo bin directory:")
29        print("----------------------------------------------------------------")
30        for file in sorted(glob.glob(cmddir+'*')):
31            print(" "+os.path.basename(file))
32        print("")
33        if len(options.command) > 0:
34            print("WARNING: ignoring command specification")
35        return
36    if len(options.command) == 0:
37        print("ERROR: no command specified")
38        return
39    if not os.path.exists(cmddir+options.command[0]):
40        print("ERROR: the command '%s' does not exist" % (cmddir+options.command[0]))
41        return
42    pyutilib.subprocess.run(cmddir+' '.join(options.command), tee=True)
43
44#
45# Add a subparser for the pyomo command
46#
47setup_command_parser(
48    pyomo.scripting.pyomo_parser.add_subparser('run',
49        func=command_exec, 
50        help='Execute a command from the Pyomo bin (or Scripts) directory.',
51        description='This pyomo subcommand is used to execute commands installed with Pyomo.',
52        epilog="""
53This subcommand can execute any command from the bin (or Script)
54directory that is created when Pyomo is installed.  Note that this
55includes any commands that are installed by other Python packages
56that are installed with Pyomo.  Thus, if Pyomo is installed in the
57Python system directories, then this command executes any command
58included with Python.
59"""
60        ))
61
62#--------------------------------------------------
63# help
64#   --command
65#   --api
66#   --transformations
67#   --solvers
68#--------------------------------------------------
69
70def help_commands():
71    print("")
72    print("The following commands are installed with Pyomo:")
73    print("-"*75)
74    registry = get_pyomo_commands()
75    d = max(len(key) for key in registry)
76    fmt = "%%-%d%%s" % d
77    for key in sorted(registry.keys(), key=lambda v: v.upper()):
78        print(fmt % (key, registry[key]))
79    print("")
80
81def help_api(options):
82    import pyomo.util
83    services = pyomo.util.PyomoAPIFactory.services()
84    #
85    f = {}
86    for name in services:
87        f[name] = pyomo.util.PyomoAPIFactory(name)
88    #
89    ns = {}
90    for name in services:
91        ns_set = ns.setdefault(f[name].__namespace__, set())
92        ns_set.add(name)
93    #
94    if options.asciidoc:
95        print("//")
96        print("// Pyomo Library API Documentation")
97        print("//")
98        print("// Generated with 'pyomo api' on ",datetime.date.today())
99        print("//")
100        print("")
101        print("== Pyomo Functor API ==")
102        for ns_ in sorted(ns.keys()):
103            print("")
104            level = ns_+" Functors"
105            print('=== %s ===' % level)
106            for name in sorted(ns[ns_]):
107                if ns_ != '':
108                    tname = name[len(ns_)+1:]
109                else:
110                    tname = name
111                print("")
112                print('==== %s ====' % tname)
113                print(f[name].__short_doc__)
114                if f[name].__long_doc__ != '':
115                    print("")
116                    print(f[name].__long_doc__)
117                print("")
118                flag=False
119                print("- [underline]#Required Keyword Arguments:#")
120                for port in sorted(f[name].inputs):
121                    if f[name].inputs[port].optional:
122                        flag=True
123                        continue
124                    print("")
125                    print('*%s*::\n %s' % (port, f[name].inputs[port].doc))
126                if flag:
127                    # A function may not have optional arguments
128                    print("")
129                    print("- [underline]#Optional Keyword Arguments:#")
130                    for port in sorted(f[name].inputs):
131                        if not f[name].inputs[port].optional:
132                            continue
133                        print("")
134                        print('*%s*::\n %s' % (port, f[name].inputs[port].doc))
135                print("")
136                print("- [underline]#Return Values:#")
137                for port in sorted(f[name].outputs):
138                    print("")
139                    print('*%s*::\n %s' % (port, f[name].outputs[port].doc))
140                print("")
141    else:
142        print("")
143        print("Pyomo Functor API")
144        print("-----------------")
145        wrapper = textwrap.TextWrapper(subsequent_indent='')
146        print(wrapper.fill("The Pyomo library contains a set of functors that define operations that are likely to be major steps in Pyomo scripts.  This API is defined with functors to ensure a consistent function syntax.  Additionally, these functors can be accessed with a factory, thereby avoiding the need to import modules throughout Pyomo."))
147        print("")
148        for ns_ in sorted(ns.keys()):
149            print("")
150            level = ns_+" Functors"
151            print("-"*len(level))
152            print(level)
153            print("-"*len(level))
154            for name in sorted(ns[ns_]):
155                if ns_ != '':
156                    tname = name[len(ns_)+1:]
157                else:
158                    tname = name
159                print(tname+':')
160                for line in f[name].__short_doc__.split('\n'):
161                    print("    "+line)
162
163def help_transformations():
164    import pyomo.environ
165    from pyomo.core import TransformationFactory
166    wrapper = textwrap.TextWrapper()
167    wrapper.initial_indent = '      '
168    wrapper.subsequent_indent = '      '
169    print("")
170    print("Pyomo Model Transformations")
171    print("---------------------------")
172    for xform in sorted(TransformationFactory.services()):
173        print("  "+xform)
174        print(wrapper.fill(TransformationFactory.doc(xform)))
175
176def help_solvers():
177    import pyomo.environ
178    wrapper = textwrap.TextWrapper(replace_whitespace=False)
179    print("")
180    print("Pyomo Solvers and Solver Managers")
181    print("---------------------------------")
182
183    print(wrapper.fill("Pyomo uses 'solver managers' to execute 'solvers' that perform optimization and other forms of model analysis.  A solver directly executes an optimizer, typically using an executable found on the user's PATH environment.  Solver managers support a flexible mechanism for asyncronously executing solvers either locally or remotely.  The following solver managers are available in Pyomo:"))
184    print("")
185    solvermgr_list = pyomo.opt.SolverManagerFactory.services()
186    solvermgr_list = sorted( filter(lambda x: '_' != x[0], solvermgr_list) )
187    n = max(map(len, solvermgr_list))
188    wrapper = textwrap.TextWrapper(subsequent_indent=' '*(n+9))
189    for s in solvermgr_list:
190        # Disable warnings
191        _level = logger.getEffectiveLevel()
192        logger.setLevel(logging.ERROR)
193        format = '    %-'+str(n)+'s     %s'
194        # Reset logging level
195        logger.setLevel(level=_level)
196        print(wrapper.fill(format % (s , pyomo.opt.SolverManagerFactory.doc(s))))
197    print("")
198    wrapper = textwrap.TextWrapper(subsequent_indent='')
199    print(wrapper.fill("If no solver manager is specified, Pyomo uses the serial solver manager to execute solvers locally.  The pyro and phpyro solver managers require the installation and configuration of the pyro software.  The neos solver manager is used to execute solvers on the NEOS optimization server."))
200    print("")
201
202    print("")
203    print("Serial Solver Interfaces")
204    print("------------------------")
205    print(wrapper.fill("The serial, pyro and phpyro solver managers support the following solver interfaces:"))
206    print("")
207    solver_list = pyomo.opt.SolverFactory.services()
208    solver_list = sorted( filter(lambda x: '_' != x[0], solver_list) )
209    n = max(map(len, solver_list))
210    wrapper = textwrap.TextWrapper(subsequent_indent=' '*(n+9))
211    for s in solver_list:
212        # Disable warnings
213        _level = logger.getEffectiveLevel()
214        logger.setLevel(logging.ERROR)
215        # Create a solver, and see if it is available
216        opt = pyomo.opt.SolverFactory(s)
217        if s == 'asl' or s == 'py' or opt.available(False):
218            format = '    %-'+str(n)+'s   * %s'
219        else:
220            format = '    %-'+str(n)+'s     %s'
221        # Reset logging level
222        logger.setLevel(level=_level)
223        print(wrapper.fill(format % (s , pyomo.opt.SolverFactory.doc(s))))
224    print("")
225    wrapper = textwrap.TextWrapper(subsequent_indent='')
226    print(wrapper.fill("An asterisk indicates that this solver is currently available to be run from Pyomo with the serial solver manager."))
227    print('')
228    print(wrapper.fill('Several solver interfaces are wrappers around third-party solver interfaces:  asl, openopt and os.  These interfaces require a subsolver specification that indicates the solver being executed.  For example, the following indicates that the OpenOpt pswarm solver is being used:'))
229    print('')
230    print('   openopt:pswarm')
231    print('')
232    print(wrapper.fill('The OpenOpt optimization package will launch the pswarm solver to perform optimization.  Similarly, the following indicates that the ipopt solver will be used:'))
233    print('')
234    print('   asl:ipopt')
235    print('')
236    print(wrapper.fill('The asl interface provides a generic wrapper for all solvers that use the AMPL Solver Library.'))
237    print('')
238    print(wrapper.fill('Note that subsolvers can not be enumerated automatically for these interfaces.  However, if a solver is specified that is not found, Pyomo assumes that the asl solver interface is being used.  Thus the following solver name will launch ipopt if the \'ipopt\' executable is on the user\'s path:'))
239    print('')
240    print('   ipopt')
241    print('')
242    _level = logger.getEffectiveLevel()
243    logger.setLevel(logging.ERROR)
244    try:
245        #logger.setLevel(logging.WARNING)
246        import pyomo.neos.kestrel
247        kestrel = pyomo.neos.kestrel.kestrelAMPL()
248        #print "HERE", solver_list
249        solver_list = list(set([name[:-5].lower() for name in kestrel.solvers() if name.endswith('AMPL')]))
250        #print "HERE", solver_list
251        if len(solver_list) > 0:
252            print("")
253            print("NEOS Solver Interfaces")
254            print("----------------------")
255            print(wrapper.fill("The neos solver manager supports solver interfaces that can be executed remotely on the NEOS optimization server.  The following solver interfaces are available with your current system configuration:"))
256            print("")
257            solver_list = sorted(solver_list)
258            n = max(map(len, solver_list))
259            format = '    %-'+str(n)+'s     %s'
260            for name in solver_list:
261                print(wrapper.fill(format % (name , pyomo.neos.doc.get(name,'Unexpected NEOS solver'))))
262            print("")
263        else:
264            print("")
265            print("NEOS Solver Interfaces")
266            print("----------------------")
267            print(wrapper.fill("The neos solver manager supports solver interfaces that can be executed remotely on the NEOS optimization server.  This server is not available with your current system configuration."))
268            print("")
269    except ImportError:
270        pass
271    logger.setLevel(level=_level)
272
273def help_exec(options):
274    flag=False
275    if options.commands:
276        if options.asciidoc:
277            print("The '--commands' help information is not printed in an asciidoc format.")
278        flag=True
279        help_commands()
280    if options.api:
281        flag=True
282        help_api(options)
283    if options.transformations:
284        if options.asciidoc:
285            print("The '--transformations' help information is not printed in an asciidoc format.")
286        flag=True
287        help_transformations()
288    if options.solvers:
289        if options.asciidoc:
290            print("The '--solvers' help information is not printed in an asciidoc format.")
291        flag=True
292        help_solvers()
293    if not flag:
294        help_parser.print_help()
295
296#
297# Add a subparser for the pyomo command
298#
299def setup_help_parser(parser):
300    parser.add_argument("-c", "--commands", dest="commands", action='store_true', default=False,
301                        help="List the commands that are installed with Pyomo")
302    parser.add_argument("-a", "--api", dest="api", action='store_true', default=False,
303                        help="Print a summary of the Pyomo Library API")
304    parser.add_argument("--asciidoc", dest="asciidoc", action='store_true', default=False,
305                        help="Generate output that is compatible with asciidoc's markup language")
306    parser.add_argument("-t", "--transformations", dest="transformations", action='store_true', default=False,
307                        help="List the available model transformations")
308    parser.add_argument("-s", "--solvers", dest="solvers", action='store_true', default=False,
309                        help="Summarize the available solvers and solver interfaces")
310    return parser
311
312help_parser = setup_help_parser(
313  pyomo.scripting.pyomo_parser.add_subparser('help',
314        func=help_exec, 
315        help='Print help information.',
316        description="This pyomo subcommand is used to print information about Pyomo's subcommands and installed Pyomo services."
317        ))
318
319
Note: See TracBrowser for help on using the repository browser.