summaryrefslogtreecommitdiff
path: root/numpy/distutils/command
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2020-12-13 14:14:49 -0700
committerGitHub <noreply@github.com>2020-12-13 14:14:49 -0700
commit3fe2d9d2627fc0f84aeed293ff8afa7c1f08d899 (patch)
tree2ea27fe06a19c39e8d7a5fe2f87cb7e05363247d /numpy/distutils/command
parent7d7e446fcbeeff70d905bde2eb0264a797488280 (diff)
parenteff302e5e8678fa17fb3d8156d49eb585b0876d9 (diff)
downloadnumpy-3fe2d9d2627fc0f84aeed293ff8afa7c1f08d899.tar.gz
Merge branch 'master' into fix-issue-10244
Diffstat (limited to 'numpy/distutils/command')
-rw-r--r--numpy/distutils/command/autodist.py33
-rw-r--r--numpy/distutils/command/build.py12
-rw-r--r--numpy/distutils/command/build_clib.py67
-rw-r--r--numpy/distutils/command/build_ext.py69
-rw-r--r--numpy/distutils/command/config.py14
5 files changed, 119 insertions, 76 deletions
diff --git a/numpy/distutils/command/autodist.py b/numpy/distutils/command/autodist.py
index 8f6436004..b72d0cab1 100644
--- a/numpy/distutils/command/autodist.py
+++ b/numpy/distutils/command/autodist.py
@@ -46,15 +46,16 @@ def check_restrict(cmd):
return ''
-def check_compiler_gcc4(cmd):
- """Return True if the C compiler is GCC 4.x."""
+def check_compiler_gcc(cmd):
+ """Check if the compiler is GCC."""
+
cmd._check_compiler()
body = textwrap.dedent("""
int
main()
{
- #if (! defined __GNUC__) || (__GNUC__ < 4)
- #error gcc >= 4 required
+ #if (! defined __GNUC__)
+ #error gcc required
#endif
return 0;
}
@@ -62,6 +63,30 @@ def check_compiler_gcc4(cmd):
return cmd.try_compile(body, None, None)
+def check_gcc_version_at_least(cmd, major, minor=0, patchlevel=0):
+ """
+ Check that the gcc version is at least the specified version."""
+
+ cmd._check_compiler()
+ version = '.'.join([str(major), str(minor), str(patchlevel)])
+ body = textwrap.dedent("""
+ int
+ main()
+ {
+ #if (! defined __GNUC__) || (__GNUC__ < %(major)d) || \\
+ (__GNUC_MINOR__ < %(minor)d) || \\
+ (__GNUC_PATCHLEVEL__ < %(patchlevel)d)
+ #error gcc >= %(version)s required
+ #endif
+ return 0;
+ }
+ """)
+ kw = {'version': version, 'major': major, 'minor': minor,
+ 'patchlevel': patchlevel}
+
+ return cmd.try_compile(body % kw, None, None)
+
+
def check_gcc_function_attribute(cmd, attribute, name):
"""Return True if the given function attribute is supported."""
cmd._check_compiler()
diff --git a/numpy/distutils/command/build.py b/numpy/distutils/command/build.py
index 60ba4c917..a4fda537d 100644
--- a/numpy/distutils/command/build.py
+++ b/numpy/distutils/command/build.py
@@ -22,6 +22,8 @@ class build(old_build):
"specify a list of dispatched CPU optimizations"),
('disable-optimization', None,
"disable CPU optimized code(dispatch,simd,fast...)"),
+ ('simd-test=', None,
+ "specify a list of CPU optimizations to be tested against NumPy SIMD interface"),
]
help_options = old_build.help_options + [
@@ -36,6 +38,16 @@ class build(old_build):
self.cpu_baseline = "min"
self.cpu_dispatch = "max -xop -fma4" # drop AMD legacy features by default
self.disable_optimization = False
+ """
+ the '_simd' module is a very large. Adding more dispatched features
+ will increase binary size and compile time. By default we minimize
+ the targeted features to those most commonly used by the NumPy SIMD interface(NPYV),
+ NOTE: any specified features will be ignored if they're:
+ - part of the baseline(--cpu-baseline)
+ - not part of dispatch-able features(--cpu-dispatch)
+ - not supported by compiler or platform
+ """
+ self.simd_test = "BASELINE SSE2 SSE42 XOP FMA4 (FMA3 AVX2) AVX512F AVX512_SKX VSX VSX2 VSX3 NEON ASIMD"
def finalize_options(self):
build_scripts = self.build_scripts
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index 87345adbc..a0db6f31f 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -259,57 +259,56 @@ class build_clib(old_build_clib):
if requiref90:
self.mkpath(module_build_dir)
- dispatch_objects = []
- if not self.disable_optimization:
- dispatch_sources = [
- c_sources.pop(c_sources.index(src))
- for src in c_sources[:] if src.endswith(".dispatch.c")
- ]
- if dispatch_sources:
- if not self.inplace:
- build_src = self.get_finalized_command("build_src").build_src
- else:
- build_src = None
- dispatch_objects = self.compiler_opt.try_dispatch(
- dispatch_sources,
- output_dir=self.build_temp,
- src_dir=build_src,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_postargs
- )
- extra_args_baseopt = extra_postargs + self.compiler_opt.cpu_baseline_flags()
- else:
- extra_args_baseopt = extra_postargs
- macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
-
if compiler.compiler_type == 'msvc':
# this hack works around the msvc compiler attributes
# problem, msvc uses its own convention :(
c_sources += cxx_sources
cxx_sources = []
+ # filtering C dispatch-table sources when optimization is not disabled,
+ # otherwise treated as normal sources.
+ copt_c_sources = []
+ copt_baseline_flags = []
+ copt_macros = []
+ if not self.disable_optimization:
+ copt_build_src = None if self.inplace else self.get_finalized_command("build_src").build_src
+ copt_c_sources = [
+ c_sources.pop(c_sources.index(src))
+ for src in c_sources[:] if src.endswith(".dispatch.c")
+ ]
+ copt_baseline_flags = self.compiler_opt.cpu_baseline_flags()
+ else:
+ copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
+
objects = []
+ if copt_c_sources:
+ log.info("compiling C dispatch-able sources")
+ objects += self.compiler_opt.try_dispatch(copt_c_sources,
+ output_dir=self.build_temp,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs)
+
if c_sources:
log.info("compiling C sources")
- objects = compiler.compile(c_sources,
- output_dir=self.build_temp,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args_baseopt)
- objects.extend(dispatch_objects)
+ objects += compiler.compile(c_sources,
+ output_dir=self.build_temp,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs + copt_baseline_flags)
if cxx_sources:
log.info("compiling C++ sources")
cxx_compiler = compiler.cxx_compiler()
cxx_objects = cxx_compiler.compile(cxx_sources,
output_dir=self.build_temp,
- macros=macros,
+ macros=macros + copt_macros,
include_dirs=include_dirs,
debug=self.debug,
- extra_postargs=extra_postargs)
+ extra_postargs=extra_postargs + copt_baseline_flags)
objects.extend(cxx_objects)
if f_sources or fmodule_sources:
diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py
index b6557fcf6..ca6f8bcd2 100644
--- a/numpy/distutils/command/build_ext.py
+++ b/numpy/distutils/command/build_ext.py
@@ -19,8 +19,7 @@ from numpy.distutils.misc_util import (
has_cxx_sources, has_f_sources, is_sequence
)
from numpy.distutils.command.config_compiler import show_fortran_compilers
-from numpy.distutils.ccompiler_opt import new_ccompiler_opt
-
+from numpy.distutils.ccompiler_opt import new_ccompiler_opt, CCompilerOpt
class build_ext (old_build_ext):
@@ -39,6 +38,8 @@ class build_ext (old_build_ext):
"specify a list of dispatched CPU optimizations"),
('disable-optimization', None,
"disable CPU optimized code(dispatch,simd,fast...)"),
+ ('simd-test=', None,
+ "specify a list of CPU optimizations to be tested against NumPy SIMD interface"),
]
help_options = old_build_ext.help_options + [
@@ -56,6 +57,7 @@ class build_ext (old_build_ext):
self.cpu_baseline = None
self.cpu_dispatch = None
self.disable_optimization = None
+ self.simd_test = None
def finalize_options(self):
if self.parallel:
@@ -87,7 +89,9 @@ class build_ext (old_build_ext):
('cpu_baseline', 'cpu_baseline'),
('cpu_dispatch', 'cpu_dispatch'),
('disable_optimization', 'disable_optimization'),
+ ('simd_test', 'simd_test')
)
+ CCompilerOpt.conf_target_groups["simd_test"] = self.simd_test
def run(self):
if not self.extensions:
@@ -406,52 +410,49 @@ class build_ext (old_build_ext):
include_dirs = ext.include_dirs + get_numpy_include_dirs()
- dispatch_objects = []
+ # filtering C dispatch-table sources when optimization is not disabled,
+ # otherwise treated as normal sources.
+ copt_c_sources = []
+ copt_baseline_flags = []
+ copt_macros = []
if not self.disable_optimization:
- dispatch_sources = [
+ copt_build_src = None if self.inplace else self.get_finalized_command("build_src").build_src
+ copt_c_sources = [
c_sources.pop(c_sources.index(src))
for src in c_sources[:] if src.endswith(".dispatch.c")
]
- if dispatch_sources:
- if not self.inplace:
- build_src = self.get_finalized_command("build_src").build_src
- else:
- build_src = None
- dispatch_objects = self.compiler_opt.try_dispatch(
- dispatch_sources,
- output_dir=output_dir,
- src_dir=build_src,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args,
- **kws
- )
- extra_args_baseopt = extra_args + self.compiler_opt.cpu_baseline_flags()
+ copt_baseline_flags = self.compiler_opt.cpu_baseline_flags()
else:
- extra_args_baseopt = extra_args
- macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
+ copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
c_objects = []
+ if copt_c_sources:
+ log.info("compiling C dispatch-able sources")
+ c_objects += self.compiler_opt.try_dispatch(copt_c_sources,
+ output_dir=output_dir,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_args,
+ **kws)
if c_sources:
log.info("compiling C sources")
- c_objects = self.compiler.compile(c_sources,
- output_dir=output_dir,
- macros=macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args_baseopt,
- **kws)
- c_objects.extend(dispatch_objects)
-
+ c_objects += self.compiler.compile(c_sources,
+ output_dir=output_dir,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_args + copt_baseline_flags,
+ **kws)
if cxx_sources:
log.info("compiling C++ sources")
c_objects += cxx_compiler.compile(cxx_sources,
output_dir=output_dir,
- macros=macros,
+ macros=macros + copt_macros,
include_dirs=include_dirs,
debug=self.debug,
- extra_postargs=extra_args,
+ extra_postargs=extra_args + copt_baseline_flags,
**kws)
extra_postargs = []
@@ -559,7 +560,7 @@ class build_ext (old_build_ext):
unlinkable_fobjects = list(unlinkable_fobjects)
# Expand possible fake static libraries to objects
- for lib in list(libraries):
+ for lib in libraries:
for libdir in library_dirs:
fake_lib = os.path.join(libdir, lib + '.fobjects')
if os.path.isfile(fake_lib):
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py
index e54a54449..60881f4a3 100644
--- a/numpy/distutils/command/config.py
+++ b/numpy/distutils/command/config.py
@@ -20,9 +20,10 @@ from numpy.distutils.mingw32ccompiler import generate_manifest
from numpy.distutils.command.autodist import (check_gcc_function_attribute,
check_gcc_function_attribute_with_intrinsics,
check_gcc_variable_attribute,
+ check_gcc_version_at_least,
check_inline,
check_restrict,
- check_compiler_gcc4)
+ check_compiler_gcc)
LANG_EXT['f77'] = '.f'
LANG_EXT['f90'] = '.f90'
@@ -416,9 +417,9 @@ class config(old_config):
otherwise."""
return check_restrict(self)
- def check_compiler_gcc4(self):
- """Return True if the C compiler is gcc >= 4."""
- return check_compiler_gcc4(self)
+ def check_compiler_gcc(self):
+ """Return True if the C compiler is gcc"""
+ return check_compiler_gcc(self)
def check_gcc_function_attribute(self, attribute, name):
return check_gcc_function_attribute(self, attribute, name)
@@ -431,6 +432,11 @@ class config(old_config):
def check_gcc_variable_attribute(self, attribute):
return check_gcc_variable_attribute(self, attribute)
+ def check_gcc_version_at_least(self, major, minor=0, patchlevel=0):
+ """Return True if the GCC version is greater than or equal to the
+ specified version."""
+ return check_gcc_version_at_least(self, major, minor, patchlevel)
+
def get_output(self, body, headers=None, include_dirs=None,
libraries=None, library_dirs=None,
lang="c", use_tee=None):