[pyfr] 42/88: Refactor the main script.

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Nov 16 12:05:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch master
in repository pyfr.

commit 515444a58ffbe2ce6553e19a07537e82d3886172
Author: Freddie Witherden <freddie at witherden.org>
Date:   Wed Jun 1 09:46:07 2016 -0700

    Refactor the main script.
---
 pyfr/__main__.py         | 254 +++++++++++++++++++++++++++++++++++++++++++++-
 pyfr/pyfr                |   1 +
 pyfr/scripts/__init__.py |   0
 pyfr/scripts/main.py     | 257 -----------------------------------------------
 pyfr/scripts/pyfr        |   1 -
 setup.py                 |   3 +-
 6 files changed, 254 insertions(+), 262 deletions(-)

diff --git a/pyfr/__main__.py b/pyfr/__main__.py
old mode 100644
new mode 100755
index 6a4c785..79ede1f
--- a/pyfr/__main__.py
+++ b/pyfr/__main__.py
@@ -1,7 +1,257 @@
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-import pyfr.scripts.main
+from argparse import ArgumentParser, FileType
+import itertools as it
+import os
+
+import mpi4py.rc
+mpi4py.rc.initialize = False
+
+import h5py
+
+from pyfr.backends import BaseBackend, get_backend
+from pyfr.inifile import Inifile
+from pyfr.mpiutil import register_finalize_handler
+from pyfr.partitioners import BasePartitioner, get_partitioner
+from pyfr.progress_bar import ProgressBar
+from pyfr.rank_allocator import get_rank_allocation
+from pyfr.readers import BaseReader, get_reader_by_name, get_reader_by_extn
+from pyfr.readers.native import NativeReader
+from pyfr.solvers import get_solver
+from pyfr.util import subclasses
+from pyfr.writers import BaseWriter, get_writer_by_name, get_writer_by_extn
+
+
+def main():
+    ap = ArgumentParser(prog='pyfr')
+    sp = ap.add_subparsers(dest='cmd', help='sub-command help')
+
+    # Common options
+    ap.add_argument('--verbose', '-v', action='count')
+
+    # Import command
+    ap_import = sp.add_parser('import', help='import --help')
+    ap_import.add_argument('inmesh', type=FileType('r'),
+                           help='input mesh file')
+    ap_import.add_argument('outmesh', help='output PyFR mesh file')
+    types = sorted(cls.name for cls in subclasses(BaseReader))
+    ap_import.add_argument('-t', dest='type', choices=types,
+                           help='input file type; this is usually inferred '
+                           'from the extension of inmesh')
+    ap_import.set_defaults(process=process_import)
+
+    # Partition command
+    ap_partition = sp.add_parser('partition', help='partition --help')
+    ap_partition.add_argument('np', help='number of partitions or a colon '
+                              'delimited list of weights')
+    ap_partition.add_argument('mesh', help='input mesh file')
+    ap_partition.add_argument('solns', metavar='soln', nargs='*',
+                              help='input solution files')
+    ap_partition.add_argument('outd', help='output directory')
+    partitioners = sorted(cls.name for cls in subclasses(BasePartitioner))
+    ap_partition.add_argument('-p', dest='partitioner', choices=partitioners,
+                              help='partitioner to use')
+    ap_partition.add_argument('--popt', dest='popts', action='append',
+                              default=[], metavar='key:value',
+                              help='partitioner-specific option')
+    ap_partition.add_argument('-t', dest='order', type=int, default=3,
+                              help='target polynomial order; aids in '
+                              'load-balancing mixed meshes')
+    ap_partition.set_defaults(process=process_partition)
+
+    # Export command
+    ap_export = sp.add_parser('export', help='export --help')
+    ap_export.add_argument('meshf', help='PyFR mesh file to be converted')
+    ap_export.add_argument('solnf', help='PyFR solution file to be converted')
+    ap_export.add_argument('outf', type=str, help='output file')
+    types = [cls.name for cls in subclasses(BaseWriter)]
+    ap_export.add_argument('-t', dest='type', choices=types, required=False,
+                           help='output file type; this is usually inferred '
+                           'from the extension of outf')
+    ap_export.add_argument('-d', '--divisor', type=int, default=0,
+                           help='sets the level to which high order elements '
+                           'are divided; output is linear between nodes, so '
+                           'increased resolution may be required')
+    ap_export.add_argument('-g', '--gradients', action='store_true',
+                           help='compute gradients')
+    ap_export.add_argument('-p', '--precision', choices=['single', 'double'],
+                           default='single', help='output number precision; '
+                           'defaults to single')
+    ap_export.set_defaults(process=process_export)
+
+    # Run command
+    ap_run = sp.add_parser('run', help='run --help')
+    ap_run.add_argument('mesh', help='mesh file')
+    ap_run.add_argument('cfg', type=FileType('r'), help='config file')
+    ap_run.set_defaults(process=process_run)
+
+    # Restart command
+    ap_restart = sp.add_parser('restart', help='restart --help')
+    ap_restart.add_argument('mesh', help='mesh file')
+    ap_restart.add_argument('soln', help='solution file')
+    ap_restart.add_argument('cfg', nargs='?', type=FileType('r'),
+                            help='new config file')
+    ap_restart.set_defaults(process=process_restart)
+
+    # Options common to run and restart
+    backends = sorted(cls.name for cls in subclasses(BaseBackend))
+    for p in [ap_run, ap_restart]:
+        p.add_argument('--backend', '-b', choices=backends, required=True,
+                       help='backend to use')
+        p.add_argument('--progress', '-p', action='store_true',
+                       help='show a progress bar')
+
+    # Parse the arguments
+    args = ap.parse_args()
+
+    # Invoke the process method
+    if hasattr(args, 'process'):
+        args.process(args)
+    else:
+        ap.print_help()
+
+
+def process_import(args):
+    # Get a suitable mesh reader instance
+    if args.type:
+        reader = get_reader_by_name(args.type, args.inmesh)
+    else:
+        extn = os.path.splitext(args.inmesh.name)[1]
+        reader = get_reader_by_extn(extn, args.inmesh)
+
+    # Get the mesh in the PyFR format
+    mesh = reader.to_pyfrm()
+
+    # Save to disk
+    with h5py.File(args.outmesh, 'w') as f:
+        for k, v in mesh.items():
+            f[k] = v
+
+
+def process_partition(args):
+    # Ensure outd is a directory
+    if not os.path.isdir(args.outd):
+        raise ValueError('Invalid output directory')
+
+    # Partition weights
+    if ':' in args.np:
+        pwts = [int(w) for w in args.np.split(':')]
+    else:
+        pwts = [1]*int(args.np)
+
+    # Partitioner-specific options
+    opts = dict(s.split(':', 1) for s in args.popts)
+
+    # Create the partitioner
+    if args.partitioner:
+        part = get_partitioner(args.partitioner, pwts, order=args.order,
+                               opts=opts)
+    else:
+        for name in sorted(cls.name for cls in subclasses(BasePartitioner)):
+            try:
+                part = get_partitioner(name, pwts, order=args.order)
+                break
+            except OSError:
+                pass
+        else:
+            raise RuntimeError('No partitioners available')
+
+    # Partition the mesh
+    mesh, part_soln_fn = part.partition(NativeReader(args.mesh))
+
+    # Prepare the solutions
+    solnit = (part_soln_fn(NativeReader(s)) for s in args.solns)
+
+    # Output paths/files
+    paths = it.chain([args.mesh], args.solns)
+    files = it.chain([mesh], solnit)
+
+    # Iterate over the output mesh/solutions
+    for path, data in zip(paths, files):
+        # Compute the output path
+        path = os.path.join(args.outd, os.path.basename(path.rstrip('/')))
+
+        # Save to disk
+        with h5py.File(path, 'w') as f:
+            for k, v in data.items():
+                f[k] = v
+
+
+def process_export(args):
+    # Get writer instance by specified type or outf extension
+    if args.type:
+        writer = get_writer_by_name(args.type, args)
+    else:
+        extn = os.path.splitext(args.outf)[1]
+        writer = get_writer_by_extn(extn, args)
+
+    # Write the output file
+    writer.write_out()
+
+
+def _process_common(args, mesh, soln, cfg):
+    # Prefork to allow us to exec processes after MPI is initialised
+    if hasattr(os, 'fork'):
+        from pytools.prefork import enable_prefork
+
+        enable_prefork()
+
+    # Import but do not initialise MPI
+    from mpi4py import MPI
+
+    # Manually initialise MPI
+    MPI.Init()
+
+    # Ensure MPI is suitably cleaned up
+    register_finalize_handler()
+
+    # Create a backend
+    backend = get_backend(args.backend, cfg)
+
+    # Get the mapping from physical ranks to MPI ranks
+    rallocs = get_rank_allocation(mesh, cfg)
+
+    # Construct the solver
+    solver = get_solver(backend, rallocs, mesh, soln, cfg)
+
+    # If we are running interactively then create a progress bar
+    if args.progress and MPI.COMM_WORLD.rank == 0:
+        pb = ProgressBar(solver.tstart, solver.tcurr, solver.tend)
+
+        # Register a callback to update the bar after each step
+        callb = lambda intg: pb.advance_to(intg.tcurr)
+        solver.completed_step_handlers.append(callb)
+
+    # Execute!
+    solver.run()
+
+    # Finalise MPI
+    MPI.Finalize()
+
+
+def process_run(args):
+    _process_common(
+        args, NativeReader(args.mesh), None, Inifile.load(args.cfg)
+    )
+
+
+def process_restart(args):
+    mesh = NativeReader(args.mesh)
+    soln = NativeReader(args.soln)
+
+    # Ensure the solution is from the mesh we are using
+    if soln['mesh_uuid'] != mesh['mesh_uuid']:
+        raise RuntimeError('Invalid solution for mesh.')
+
+    # Process the config file
+    if args.cfg:
+        cfg = Inifile.load(args.cfg)
+    else:
+        cfg = Inifile(soln['config'])
+
+    _process_common(args, mesh, soln, cfg)
 
 
 if __name__ == '__main__':
-    pyfr.scripts.main.main()
+    main()
diff --git a/pyfr/pyfr b/pyfr/pyfr
new file mode 120000
index 0000000..5a427d1
--- /dev/null
+++ b/pyfr/pyfr
@@ -0,0 +1 @@
+__main__.py
\ No newline at end of file
diff --git a/pyfr/scripts/__init__.py b/pyfr/scripts/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/pyfr/scripts/main.py b/pyfr/scripts/main.py
deleted file mode 100755
index 79ede1f..0000000
--- a/pyfr/scripts/main.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from argparse import ArgumentParser, FileType
-import itertools as it
-import os
-
-import mpi4py.rc
-mpi4py.rc.initialize = False
-
-import h5py
-
-from pyfr.backends import BaseBackend, get_backend
-from pyfr.inifile import Inifile
-from pyfr.mpiutil import register_finalize_handler
-from pyfr.partitioners import BasePartitioner, get_partitioner
-from pyfr.progress_bar import ProgressBar
-from pyfr.rank_allocator import get_rank_allocation
-from pyfr.readers import BaseReader, get_reader_by_name, get_reader_by_extn
-from pyfr.readers.native import NativeReader
-from pyfr.solvers import get_solver
-from pyfr.util import subclasses
-from pyfr.writers import BaseWriter, get_writer_by_name, get_writer_by_extn
-
-
-def main():
-    ap = ArgumentParser(prog='pyfr')
-    sp = ap.add_subparsers(dest='cmd', help='sub-command help')
-
-    # Common options
-    ap.add_argument('--verbose', '-v', action='count')
-
-    # Import command
-    ap_import = sp.add_parser('import', help='import --help')
-    ap_import.add_argument('inmesh', type=FileType('r'),
-                           help='input mesh file')
-    ap_import.add_argument('outmesh', help='output PyFR mesh file')
-    types = sorted(cls.name for cls in subclasses(BaseReader))
-    ap_import.add_argument('-t', dest='type', choices=types,
-                           help='input file type; this is usually inferred '
-                           'from the extension of inmesh')
-    ap_import.set_defaults(process=process_import)
-
-    # Partition command
-    ap_partition = sp.add_parser('partition', help='partition --help')
-    ap_partition.add_argument('np', help='number of partitions or a colon '
-                              'delimited list of weights')
-    ap_partition.add_argument('mesh', help='input mesh file')
-    ap_partition.add_argument('solns', metavar='soln', nargs='*',
-                              help='input solution files')
-    ap_partition.add_argument('outd', help='output directory')
-    partitioners = sorted(cls.name for cls in subclasses(BasePartitioner))
-    ap_partition.add_argument('-p', dest='partitioner', choices=partitioners,
-                              help='partitioner to use')
-    ap_partition.add_argument('--popt', dest='popts', action='append',
-                              default=[], metavar='key:value',
-                              help='partitioner-specific option')
-    ap_partition.add_argument('-t', dest='order', type=int, default=3,
-                              help='target polynomial order; aids in '
-                              'load-balancing mixed meshes')
-    ap_partition.set_defaults(process=process_partition)
-
-    # Export command
-    ap_export = sp.add_parser('export', help='export --help')
-    ap_export.add_argument('meshf', help='PyFR mesh file to be converted')
-    ap_export.add_argument('solnf', help='PyFR solution file to be converted')
-    ap_export.add_argument('outf', type=str, help='output file')
-    types = [cls.name for cls in subclasses(BaseWriter)]
-    ap_export.add_argument('-t', dest='type', choices=types, required=False,
-                           help='output file type; this is usually inferred '
-                           'from the extension of outf')
-    ap_export.add_argument('-d', '--divisor', type=int, default=0,
-                           help='sets the level to which high order elements '
-                           'are divided; output is linear between nodes, so '
-                           'increased resolution may be required')
-    ap_export.add_argument('-g', '--gradients', action='store_true',
-                           help='compute gradients')
-    ap_export.add_argument('-p', '--precision', choices=['single', 'double'],
-                           default='single', help='output number precision; '
-                           'defaults to single')
-    ap_export.set_defaults(process=process_export)
-
-    # Run command
-    ap_run = sp.add_parser('run', help='run --help')
-    ap_run.add_argument('mesh', help='mesh file')
-    ap_run.add_argument('cfg', type=FileType('r'), help='config file')
-    ap_run.set_defaults(process=process_run)
-
-    # Restart command
-    ap_restart = sp.add_parser('restart', help='restart --help')
-    ap_restart.add_argument('mesh', help='mesh file')
-    ap_restart.add_argument('soln', help='solution file')
-    ap_restart.add_argument('cfg', nargs='?', type=FileType('r'),
-                            help='new config file')
-    ap_restart.set_defaults(process=process_restart)
-
-    # Options common to run and restart
-    backends = sorted(cls.name for cls in subclasses(BaseBackend))
-    for p in [ap_run, ap_restart]:
-        p.add_argument('--backend', '-b', choices=backends, required=True,
-                       help='backend to use')
-        p.add_argument('--progress', '-p', action='store_true',
-                       help='show a progress bar')
-
-    # Parse the arguments
-    args = ap.parse_args()
-
-    # Invoke the process method
-    if hasattr(args, 'process'):
-        args.process(args)
-    else:
-        ap.print_help()
-
-
-def process_import(args):
-    # Get a suitable mesh reader instance
-    if args.type:
-        reader = get_reader_by_name(args.type, args.inmesh)
-    else:
-        extn = os.path.splitext(args.inmesh.name)[1]
-        reader = get_reader_by_extn(extn, args.inmesh)
-
-    # Get the mesh in the PyFR format
-    mesh = reader.to_pyfrm()
-
-    # Save to disk
-    with h5py.File(args.outmesh, 'w') as f:
-        for k, v in mesh.items():
-            f[k] = v
-
-
-def process_partition(args):
-    # Ensure outd is a directory
-    if not os.path.isdir(args.outd):
-        raise ValueError('Invalid output directory')
-
-    # Partition weights
-    if ':' in args.np:
-        pwts = [int(w) for w in args.np.split(':')]
-    else:
-        pwts = [1]*int(args.np)
-
-    # Partitioner-specific options
-    opts = dict(s.split(':', 1) for s in args.popts)
-
-    # Create the partitioner
-    if args.partitioner:
-        part = get_partitioner(args.partitioner, pwts, order=args.order,
-                               opts=opts)
-    else:
-        for name in sorted(cls.name for cls in subclasses(BasePartitioner)):
-            try:
-                part = get_partitioner(name, pwts, order=args.order)
-                break
-            except OSError:
-                pass
-        else:
-            raise RuntimeError('No partitioners available')
-
-    # Partition the mesh
-    mesh, part_soln_fn = part.partition(NativeReader(args.mesh))
-
-    # Prepare the solutions
-    solnit = (part_soln_fn(NativeReader(s)) for s in args.solns)
-
-    # Output paths/files
-    paths = it.chain([args.mesh], args.solns)
-    files = it.chain([mesh], solnit)
-
-    # Iterate over the output mesh/solutions
-    for path, data in zip(paths, files):
-        # Compute the output path
-        path = os.path.join(args.outd, os.path.basename(path.rstrip('/')))
-
-        # Save to disk
-        with h5py.File(path, 'w') as f:
-            for k, v in data.items():
-                f[k] = v
-
-
-def process_export(args):
-    # Get writer instance by specified type or outf extension
-    if args.type:
-        writer = get_writer_by_name(args.type, args)
-    else:
-        extn = os.path.splitext(args.outf)[1]
-        writer = get_writer_by_extn(extn, args)
-
-    # Write the output file
-    writer.write_out()
-
-
-def _process_common(args, mesh, soln, cfg):
-    # Prefork to allow us to exec processes after MPI is initialised
-    if hasattr(os, 'fork'):
-        from pytools.prefork import enable_prefork
-
-        enable_prefork()
-
-    # Import but do not initialise MPI
-    from mpi4py import MPI
-
-    # Manually initialise MPI
-    MPI.Init()
-
-    # Ensure MPI is suitably cleaned up
-    register_finalize_handler()
-
-    # Create a backend
-    backend = get_backend(args.backend, cfg)
-
-    # Get the mapping from physical ranks to MPI ranks
-    rallocs = get_rank_allocation(mesh, cfg)
-
-    # Construct the solver
-    solver = get_solver(backend, rallocs, mesh, soln, cfg)
-
-    # If we are running interactively then create a progress bar
-    if args.progress and MPI.COMM_WORLD.rank == 0:
-        pb = ProgressBar(solver.tstart, solver.tcurr, solver.tend)
-
-        # Register a callback to update the bar after each step
-        callb = lambda intg: pb.advance_to(intg.tcurr)
-        solver.completed_step_handlers.append(callb)
-
-    # Execute!
-    solver.run()
-
-    # Finalise MPI
-    MPI.Finalize()
-
-
-def process_run(args):
-    _process_common(
-        args, NativeReader(args.mesh), None, Inifile.load(args.cfg)
-    )
-
-
-def process_restart(args):
-    mesh = NativeReader(args.mesh)
-    soln = NativeReader(args.soln)
-
-    # Ensure the solution is from the mesh we are using
-    if soln['mesh_uuid'] != mesh['mesh_uuid']:
-        raise RuntimeError('Invalid solution for mesh.')
-
-    # Process the config file
-    if args.cfg:
-        cfg = Inifile.load(args.cfg)
-    else:
-        cfg = Inifile(soln['config'])
-
-    _process_common(args, mesh, soln, cfg)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/pyfr/scripts/pyfr b/pyfr/scripts/pyfr
deleted file mode 120000
index 11a5d8e..0000000
--- a/pyfr/scripts/pyfr
+++ /dev/null
@@ -1 +0,0 @@
-main.py
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 4d4b4f0..0768ea3 100755
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,6 @@ modules = [
     'pyfr.quadrules',
     'pyfr.readers',
     'pyfr.partitioners',
-    'pyfr.scripts',
     'pyfr.solvers',
     'pyfr.solvers.base',
     'pyfr.solvers.baseadvec',
@@ -109,7 +108,7 @@ extras_require = {
 
 # Scripts
 console_scripts = [
-    'pyfr = pyfr.scripts.main:main'
+    'pyfr = pyfr.__main__:main'
 ]
 
 # Info

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pyfr.git



More information about the debian-science-commits mailing list