summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/linalg/lapack_lite/README.rst7
-rw-r--r--numpy/linalg/lapack_lite/clapack_scrub.py21
-rw-r--r--numpy/linalg/lapack_lite/fortran.py5
-rwxr-xr-xnumpy/linalg/lapack_lite/make_lite.py35
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)