diff options
-rw-r--r-- | numpy/linalg/lapack_lite/README.rst | 7 | ||||
-rw-r--r-- | numpy/linalg/lapack_lite/clapack_scrub.py | 21 | ||||
-rw-r--r-- | numpy/linalg/lapack_lite/fortran.py | 5 | ||||
-rwxr-xr-x | numpy/linalg/lapack_lite/make_lite.py | 35 |
4 files changed, 43 insertions, 25 deletions
diff --git a/numpy/linalg/lapack_lite/README.rst b/numpy/linalg/lapack_lite/README.rst index ed738ab86..8baa1d8ff 100644 --- a/numpy/linalg/lapack_lite/README.rst +++ b/numpy/linalg/lapack_lite/README.rst @@ -12,15 +12,18 @@ automatically from a directory of LAPACK source files. You'll need `plex 2.0.0dev`_, available from PyPI, installed to do the appropriate scrubbing. As of writing, **this is only available for python 2.7**, and is unlikely to ever be ported to python 3. +As a result, all the Python scripts in this directory must remain compatible +with Python 2.7, even though NumPy itself no longer supports this version, +until these scripts are rewritten to use something other than ``plex``. .. _plex 2.0.0dev: https://pypi.python.org/pypi/plex/ The routines that ``lapack_litemodule.c`` wraps are listed in ``wrapped_routines``, along with a few exceptions that aren't picked up properly. Assuming that you have an unpacked LAPACK source tree in -``~/LAPACK``, you generate the new routines in this directory with:: +``/tmp/lapack-3.x.x``, you generate the new routines in this directory with:: -$ python ./make_lite.py wrapped_routines ~/LAPACK +$ ./make_lite.py wrapped_routines /tmp/lapack-3.x.x This will grab the right routines, with dependencies, put them into the appropriate ``f2c_*.f`` files, run ``f2c`` over them, then do some scrubbing diff --git a/numpy/linalg/lapack_lite/clapack_scrub.py b/numpy/linalg/lapack_lite/clapack_scrub.py index 44c0d92d9..e6f2d09f4 100644 --- a/numpy/linalg/lapack_lite/clapack_scrub.py +++ b/numpy/linalg/lapack_lite/clapack_scrub.py @@ -1,12 +1,17 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python2.7 +# WARNING! This a Python 2 script. Read README.rst for rationale. import os import re import sys -from io import StringIO from plex import Scanner, Str, Lexicon, Opt, Bol, State, AnyChar, TEXT, IGNORE from plex.traditional import re as Re +try: + from io import BytesIO as UStringIO # Python 2 +except ImportError: + from io import StringIO as UStringIO # Python 3 + class MyScanner(Scanner): def __init__(self, info, name='<default>'): @@ -22,8 +27,8 @@ def sep_seq(sequence, sep): return pat def runScanner(data, scanner_class, lexicon=None): - info = StringIO(data) - outfo = StringIO() + info = UStringIO(data) + outfo = UStringIO() if lexicon is not None: scanner = scanner_class(lexicon, info) else: @@ -190,7 +195,7 @@ def cleanComments(source): return SourceLines state = SourceLines - for line in StringIO(source): + for line in UStringIO(source): state = state(line) comments.flushTo(lines) return lines.getValue() @@ -218,7 +223,7 @@ def removeHeader(source): return OutOfHeader state = LookingForHeader - for line in StringIO(source): + for line in UStringIO(source): state = state(line) return lines.getValue() @@ -227,7 +232,7 @@ def removeSubroutinePrototypes(source): r'/\* Subroutine \*/^\s*(?:(?:inline|static)\s+){0,2}(?!else|typedef|return)\w+\s+\*?\s*(\w+)\s*\([^0]+\)\s*;?' ) lines = LineQueue() - for line in StringIO(source): + for line in UStringIO(source): if not expression.match(line): lines.add(line) @@ -249,7 +254,7 @@ def removeBuiltinFunctions(source): return InBuiltInFunctions state = LookingForBuiltinFunctions - for line in StringIO(source): + for line in UStringIO(source): state = state(line) return lines.getValue() diff --git a/numpy/linalg/lapack_lite/fortran.py b/numpy/linalg/lapack_lite/fortran.py index fc09f0808..2a5c9c05e 100644 --- a/numpy/linalg/lapack_lite/fortran.py +++ b/numpy/linalg/lapack_lite/fortran.py @@ -1,3 +1,4 @@ +# WARNING! This a Python 2 script. Read README.rst for rationale. import re import itertools @@ -44,6 +45,8 @@ class LineIterator: line = line.rstrip() return line + next = __next__ + class PushbackIterator: """PushbackIterator(iterable) @@ -69,6 +72,8 @@ class PushbackIterator: def pushback(self, item): self.buffer.append(item) + next = __next__ + def fortranSourceLines(fo): """Return an iterator over statement lines of a Fortran source file. diff --git a/numpy/linalg/lapack_lite/make_lite.py b/numpy/linalg/lapack_lite/make_lite.py index 09ffaf840..398c27e94 100755 --- a/numpy/linalg/lapack_lite/make_lite.py +++ b/numpy/linalg/lapack_lite/make_lite.py @@ -1,4 +1,5 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python2.7 +# WARNING! This a Python 2 script. Read README.rst for rationale. """ Usage: make_lite.py <wrapped_routines_file> <lapack_dir> @@ -20,7 +21,10 @@ import shutil import fortran import clapack_scrub -from shutil import which +try: + from distutils.spawn import find_executable as which # Python 2 +except ImportError: + from shutil import which # Python 3 # Arguments to pass to f2c. You'll always want -A for ANSI C prototypes # Others of interest: -a to not make variables static by default @@ -81,7 +85,8 @@ class FortranRoutine: return self._dependencies def __repr__(self): - return f'FortranRoutine({self.name!r}, filename={self.filename!r})' + return "FortranRoutine({!r}, filename={!r})".format(self.name, + self.filename) class UnknownFortranRoutine(FortranRoutine): """Wrapper for a Fortran routine for which the corresponding file @@ -193,7 +198,7 @@ class LapackLibrary(FortranLibrary): def printRoutineNames(desc, routines): print(desc) for r in routines: - print(f'\t{r.name}') + print('\t%s' % r.name) def getLapackRoutines(wrapped_routines, ignores, lapack_dir): blas_src_dir = os.path.join(lapack_dir, 'BLAS', 'SRC') @@ -243,7 +248,7 @@ def dumpRoutineNames(library, output_dir): with open(filename, 'w') as fo: for r in routines: deps = r.dependencies() - fo.write(f"{r.name}: {' '.join(deps)}\n") + fo.write('%s: %s\n' % (r.name, ' '.join(deps))) def concatenateRoutines(routines, output_file): with open(output_file, 'w') as output_fo: @@ -261,8 +266,8 @@ def runF2C(fortran_filename, output_dir): subprocess.check_call( ["f2c"] + F2C_ARGS + ['-d', output_dir, fortran_filename] ) - except subprocess.CalledProcessError as e: - raise F2CError from e + except subprocess.CalledProcessError: + raise F2CError def scrubF2CSource(c_file): with open(c_file) as fo: @@ -275,8 +280,8 @@ def scrubF2CSource(c_file): def ensure_executable(name): try: which(name) - except Exception as ex: - raise SystemExit(name + ' not found') from ex + except Exception: + raise SystemExit(name + ' not found') def create_name_header(output_dir): routine_re = re.compile(r'^ (subroutine|.* function)\s+(\w+)\(.*$', @@ -316,13 +321,13 @@ def create_name_header(output_dir): # Rename BLAS/LAPACK symbols for name in sorted(symbols): - f.write(f'#define {name}_ BLAS_FUNC({name})\n') + f.write("#define %s_ BLAS_FUNC(%s)\n" % (name, name)) # Rename also symbols that f2c exports itself f.write("\n" "/* Symbols exported by f2c.c */\n") for name in sorted(f2c_symbols): - f.write(f'#define {name} numpy_lapack_lite_{name}\n') + f.write("#define %s numpy_lapack_lite_%s\n" % (name, name)) def main(): if len(sys.argv) != 3: @@ -348,9 +353,9 @@ def main(): dumpRoutineNames(library, output_dir) for typename in types: - fortran_file = os.path.join(output_dir, f'f2c_{typename}.f') + fortran_file = os.path.join(output_dir, 'f2c_%s.f' % typename) c_file = fortran_file[:-2] + '.c' - print(f'creating {c_file} ...') + print('creating %s ...' % c_file) routines = library.allRoutinesByType(typename) concatenateRoutines(routines, fortran_file) @@ -358,11 +363,11 @@ def main(): patch_file = os.path.basename(fortran_file) + '.patch' if os.path.exists(patch_file): subprocess.check_call(['patch', '-u', fortran_file, patch_file]) - print(f'Patched {fortran_file}') + print("Patched {}".format(fortran_file)) try: runF2C(fortran_file, output_dir) except F2CError: - print(f'f2c failed on {fortran_file}') + print('f2c failed on %s' % fortran_file) break scrubF2CSource(c_file) |