summaryrefslogtreecommitdiff
path: root/numpy/distutils
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2019-12-07 14:17:20 +0200
committerCharles Harris <charlesr.harris@gmail.com>2019-12-15 13:43:53 -0700
commit2d153beca15f29bf6844f81fbdeb70df76e663cd (patch)
tree39d7a4ebf98c9306fe8514db8c00967585889581 /numpy/distutils
parent95b6f8911586f2a14b23b9d86c2f28ae763053bd (diff)
downloadnumpy-2d153beca15f29bf6844f81fbdeb70df76e663cd.tar.gz
ENH: distutils: add support for ILP64 OpenBLAS (generic symbol suffix)
Generalize the ILP64 BLAS/LAPACK symbol name handling to deal with arbitrary prefix/suffix. The build-time behavior is changed so that HAVE_BLAS_ILP64 and BLAS_SYMBOL_SUFFIX/PREFIX defines are added to compile options as appropriate. Mainly to make autodetection of BLAS/LAPACK easier for downstream numpy.distutils users, add get_info aliases 'blas_ilp64_opt', 'blas_ilp64_plain_opt', and 'blas64__opt' for any/no/""&"64_" prefix&suffix, and the same for lapack. (Due to the way system_info works, each also gets a separate class.) In addition to openblas64_ which has a fixed suffix, add the (by default suffixless) openblas_ilp64, which correspond to the most likely cases to be present.
Diffstat (limited to 'numpy/distutils')
-rw-r--r--numpy/distutils/system_info.py163
1 files changed, 126 insertions, 37 deletions
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
index fc2902b78..4786b3a0c 100644
--- a/numpy/distutils/system_info.py
+++ b/numpy/distutils/system_info.py
@@ -22,11 +22,16 @@ classes are available:
lapack_info
openblas_info
openblas64__info
+ openblas_ilp64_info
blis_info
blas_opt_info # usage recommended
lapack_opt_info # usage recommended
- blas64__opt_info # usage recommended
- lapack64__opt_info # usage recommended
+ blas_ilp64_opt_info # usage recommended (general ILP64 BLAS)
+ lapack_ilp64_opt_info # usage recommended (general ILP64 LAPACK)
+ blas_ilp64_plain_opt_info # usage recommended (general ILP64 BLAS, no symbol suffix)
+ lapack_ilp64_plain_opt_info # usage recommended (general ILP64 LAPACK, no symbol suffix)
+ blas64__opt_info # usage recommended (general ILP64 BLAS, 64_ symbol suffix)
+ lapack64__opt_info # usage recommended (general ILP64 LAPACK, 64_ symbol suffix)
fftw_info,dfftw_info,sfftw_info
fftw_threads_info,dfftw_threads_info,sfftw_threads_info
djbfft_info
@@ -411,6 +416,8 @@ def get_info(name, notfound_action=0):
'accelerate': accelerate_info, # use blas_opt instead
'openblas64_': openblas64__info,
'openblas64__lapack': openblas64__lapack_info,
+ 'openblas_ilp64': openblas_ilp64_info,
+ 'openblas_ilp64_lapack': openblas_ilp64_lapack_info,
'x11': x11_info,
'fft_opt': fft_opt_info,
'fftw': fftw_info,
@@ -433,8 +440,12 @@ def get_info(name, notfound_action=0):
'numarray': numarray_info,
'numerix': numerix_info,
'lapack_opt': lapack_opt_info,
+ 'lapack_ilp64_opt': lapack_ilp64_opt_info,
+ 'lapack_ilp64_plain_opt': lapack_ilp64_plain_opt_info,
'lapack64__opt': lapack64__opt_info,
'blas_opt': blas_opt_info,
+ 'blas_ilp64_opt': blas_ilp64_opt_info,
+ 'blas_ilp64_plain_opt': blas_ilp64_plain_opt_info,
'blas64__opt': blas64__opt_info,
'boost_python': boost_python_info,
'agg2': agg2_info,
@@ -501,14 +512,13 @@ class LapackSrcNotFoundError(LapackNotFoundError):
the LAPACK_SRC environment variable."""
-class Lapack64_NotFoundError(NotFoundError):
+class LapackILP64NotFoundError(NotFoundError):
"""
- 64-bit Lapack libraries with '64_' symbol suffix not found.
+ 64-bit Lapack libraries not found.
Known libraries in numpy/distutils/site.cfg file are:
- openblas64_
+ openblas64_, openblas_ilp64
"""
-
class BlasOptNotFoundError(NotFoundError):
"""
Optimized (vendor) Blas libraries are not found.
@@ -523,11 +533,11 @@ class BlasNotFoundError(NotFoundError):
numpy/distutils/site.cfg file (section [blas]) or by setting
the BLAS environment variable."""
-class Blas64_NotFoundError(NotFoundError):
+class BlasILP64NotFoundError(NotFoundError):
"""
- 64-bit Blas libraries with '64_' symbol suffix not found.
+ 64-bit Blas libraries not found.
Known libraries in numpy/distutils/site.cfg file are:
- openblas64_
+ openblas64_, openblas_ilp64
"""
class BlasSrcNotFoundError(BlasNotFoundError):
@@ -1716,6 +1726,9 @@ class lapack_opt_info(system_info):
return True
return False
+ def _calc_info(self, name):
+ return getattr(self, '_calc_info_{}'.format(name))()
+
def calc_info(self):
user_order = os.environ.get(self.order_env_var_name, None)
if user_order is None:
@@ -1737,7 +1750,7 @@ class lapack_opt_info(system_info):
"values: {}".format(non_existing))
for lapack in lapack_order:
- if getattr(self, '_calc_info_{}'.format(lapack))():
+ if self._calc_info(lapack):
return
if 'lapack' not in lapack_order:
@@ -1746,19 +1759,49 @@ class lapack_opt_info(system_info):
warnings.warn(LapackNotFoundError.__doc__ or '', stacklevel=2)
warnings.warn(LapackSrcNotFoundError.__doc__ or '', stacklevel=2)
-class lapack64__opt_info(lapack_opt_info):
- notfounderror = Lapack64_NotFoundError
- lapack_order = ['openblas64_']
- order_env_var_name = 'NPY_LAPACK64__ORDER'
- def _calc_info_openblas64_(self):
- info = get_info('openblas64__lapack')
- if info:
+class _ilp64_opt_info_mixin:
+ symbol_suffix = None
+ symbol_prefix = None
+
+ def _check_info(self, info):
+ macros = dict(info.get('define_macros', []))
+ prefix = macros.get('BLAS_SYMBOL_PREFIX', '')
+ suffix = macros.get('BLAS_SYMBOL_SUFFIX', '')
+
+ if self.symbol_prefix not in (None, prefix):
+ return False
+
+ if self.symbol_suffix not in (None, suffix):
+ return False
+
+ return bool(info)
+
+
+class lapack_ilp64_opt_info(lapack_opt_info, _ilp64_opt_info_mixin):
+ notfounderror = LapackILP64NotFoundError
+ lapack_order = ['openblas64_', 'openblas_ilp64']
+ order_env_var_name = 'NPY_LAPACK_ILP64_ORDER'
+
+ def _calc_info(self, name):
+ info = get_info(name + '_lapack')
+ if self._check_info(info):
self.set_info(**info)
return True
return False
+class lapack_ilp64_plain_opt_info(lapack_ilp64_opt_info):
+ # Same as lapack_ilp64_opt_info, but fix symbol names
+ symbol_prefix = ''
+ symbol_suffix = ''
+
+
+class lapack64__opt_info(lapack_ilp64_opt_info):
+ symbol_prefix = ''
+ symbol_suffix = '64_'
+
+
class blas_opt_info(system_info):
notfounderror = BlasNotFoundError
# List of all known BLAS libraries, in the default order
@@ -1828,6 +1871,9 @@ class blas_opt_info(system_info):
self.set_info(**info)
return True
+ def _calc_info(self, name):
+ return getattr(self, '_calc_info_{}'.format(name))()
+
def calc_info(self):
user_order = os.environ.get(self.order_env_var_name, None)
if user_order is None:
@@ -1847,7 +1893,7 @@ class blas_opt_info(system_info):
raise ValueError("blas_opt_info user defined BLAS order has unacceptable values: {}".format(non_existing))
for blas in blas_order:
- if getattr(self, '_calc_info_{}'.format(blas))():
+ if self._calc_info(blas):
return
if 'blas' not in blas_order:
@@ -1857,19 +1903,29 @@ class blas_opt_info(system_info):
warnings.warn(BlasSrcNotFoundError.__doc__ or '', stacklevel=2)
-class blas64__opt_info(blas_opt_info):
- notfounderror = Blas64_NotFoundError
- blas_order = ['openblas64_']
- order_env_var_name = 'NPY_BLAS64__ORDER'
+class blas_ilp64_opt_info(blas_opt_info, _ilp64_opt_info_mixin):
+ notfounderror = BlasILP64NotFoundError
+ blas_order = ['openblas64_', 'openblas_ilp64']
+ order_env_var_name = 'NPY_BLAS_ILP64_ORDER'
- def _calc_info_openblas64_(self):
- info = get_info('openblas64_')
- if info:
+ def _calc_info(self, name):
+ info = get_info(name)
+ if self._check_info(info):
self.set_info(**info)
return True
return False
+class blas_ilp64_plain_opt_info(blas_ilp64_opt_info):
+ symbol_prefix = ''
+ symbol_suffix = ''
+
+
+class blas64__opt_info(blas_ilp64_opt_info):
+ symbol_prefix = ''
+ symbol_suffix = '64_'
+
+
class blas_info(system_info):
section = 'blas'
dir_env_var = 'BLAS'
@@ -1972,6 +2028,20 @@ class openblas_info(blas_info):
_require_symbols = []
notfounderror = BlasNotFoundError
+ @property
+ def symbol_prefix(self):
+ try:
+ return self.cp.get(self.section, 'symbol_prefix')
+ except NoOptionError:
+ return ''
+
+ @property
+ def symbol_suffix(self):
+ try:
+ return self.cp.get(self.section, 'symbol_suffix')
+ except NoOptionError:
+ return ''
+
def _calc_info(self):
c = customized_ccompiler()
@@ -2006,6 +2076,10 @@ class openblas_info(blas_info):
return None
info['define_macros'] = [('HAVE_CBLAS', None)]
+ if self.symbol_prefix:
+ info['define_macros'] += [('BLAS_SYMBOL_PREFIX', self.symbol_prefix)]
+ if self.symbol_suffix:
+ info['define_macros'] += [('BLAS_SYMBOL_SUFFIX', self.symbol_suffix)]
return info
@@ -2051,9 +2125,13 @@ class openblas_info(blas_info):
tmpdir = tempfile.mkdtemp()
- prototypes = "\n".join("void %s();" % symbol_name
+ prototypes = "\n".join("void %s%s%s();" % (self.symbol_prefix,
+ symbol_name,
+ self.symbol_suffix)
for symbol_name in self._require_symbols)
- calls = "\n".join("%s();" % symbol_name
+ calls = "\n".join("%s%s%s();" % (self.symbol_prefix,
+ symbol_name,
+ self.symbol_suffix)
for symbol_name in self._require_symbols)
s = textwrap.dedent("""\
%(prototypes)s
@@ -2096,28 +2174,39 @@ class openblas_lapack_info(openblas_info):
class openblas_clapack_info(openblas_lapack_info):
_lib_names = ['openblas', 'lapack']
-class openblas64__info(openblas_info):
- section = 'openblas64_'
- dir_env_var = 'OPENBLAS64_'
- _lib_names = ['openblas64_']
- _require_symbols = ['dgemm_64_', 'cblas_dgemm64_']
- notfounderror = Blas64_NotFoundError
+class openblas_ilp64_info(openblas_info):
+ section = 'openblas_ilp64'
+ dir_env_var = 'OPENBLAS_ILP64'
+ _lib_names = ['openblas64']
+ _require_symbols = ['dgemm_', 'cblas_dgemm']
+ notfounderror = BlasILP64NotFoundError
def _calc_info(self):
info = super()._calc_info()
if info is not None:
- info['define_macros'] = [('HAVE_CBLAS64_', None)]
+ info['define_macros'] += [('HAVE_BLAS_ILP64', None)]
return info
-class openblas64__lapack_info(openblas64__info):
- _require_symbols = ['dgemm_64_', 'cblas_dgemm64_', 'zungqr_64_', 'LAPACKE_zungqr64_']
+class openblas_ilp64_lapack_info(openblas_ilp64_info):
+ _require_symbols = ['dgemm_', 'cblas_dgemm', 'zungqr_', 'LAPACKE_zungqr']
def _calc_info(self):
info = super()._calc_info()
if info:
- info['define_macros'] += [('HAVE_LAPACKE64_', None)]
+ info['define_macros'] += [('HAVE_LAPACKE', None)]
return info
+class openblas64__info(openblas_ilp64_info):
+ # ILP64 Openblas, with default symbol suffix
+ section = 'openblas64_'
+ dir_env_var = 'OPENBLAS64_'
+ _lib_names = ['openblas64_']
+ symbol_suffix = '64_'
+ symbol_prefix = ''
+
+class openblas64__lapack_info(openblas_ilp64_lapack_info, openblas64__info):
+ pass
+
class blis_info(blas_info):
section = 'blis'
dir_env_var = 'BLIS'