8000 BLD, BUG: Fix detecting aarch64 on macOS by seiko2plus · Pull Request #18001 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BLD, BUG: Fix detecting aarch64 on macOS #18001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 23, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
BLD, BUG: Fix detecting aarch64 on macOS
Co-authored-by: h-vetinari <h.vetinari@gmx.com>
  • Loading branch information
seiko2plus and h-vetinari committed Dec 20, 2020
commit c5539458a06e79af6b3a96134de39336f44aa1a8
8 changes: 4 additions & 4 deletions doc/source/reference/simd/simd-optimizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from numpy.distutils.ccompiler_opt import CCompilerOpt

class FakeCCompilerOpt(CCompilerOpt):
fake_info = ""
fake_info = ("arch", "compiler", "extra_args")
# disable caching no need for it
conf_nocache = True
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -101,7 +101,7 @@ def features_table_sections(name, ftable=None, gtable=None, tab_size=4):
return content

def features_table(arch, cc="gcc", pretty_name=None, **kwargs):
FakeCCompilerOpt.fake_info = arch + cc
FakeCCompilerOpt.fake_info = (arch, cc, '')
ccopt = FakeCCompilerOpt(cpu_baseline="max")
features = ccopt.cpu_baseline_names()
ftable = ccopt.gen_features_table(features, **kwargs)
Expand All @@ -112,12 +112,12 @@ def features_table(arch, cc="gcc", pretty_name=None, **kwargs):
return features_table_sections(pretty_name, ftable, gtable, **kwargs)

def features_table_diff(arch, cc, cc_vs="gcc", pretty_name=None, **kwargs):
FakeCCompilerOpt.fake_info = arch + cc
FakeCCompilerOpt.fake_info = (arch, cc, '')
ccopt = FakeCCompilerOpt(cpu_baseline="max")
fnames = ccopt.cpu_baseline_names()
features = {f:ccopt.feature_implies(f) for f in fnames}

FakeCCompilerOpt.fake_info = arch + cc_vs
FakeCCompilerOpt.fake_info = (arch, cc_vs, '')
ccopt_vs = FakeCCompilerOpt(cpu_baseline="max")
fnames_vs = ccopt_vs.cpu_baseline_names()
features_vs = {f:ccopt_vs.feature_implies(f) for f in fnames_vs}
Expand Down
144 changes: 70 additions & 74 deletions numpy/distutils/ccompiler_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,45 +579,41 @@ def dist_test(self, source, flags):
return test

def dist_info(self):
"""Return a string containing all environment information, required
by the abstract class '_CCompiler' to discovering the platform
environment, also used as a cache factor in order to detect
any changes from outside.
"""
Return a tuple containing info about (platform, compiler, extra_args),
required by the abstract class '_CCompiler' for discovering the
platform environment. This is also used as a cache factor in order
to detect any changes happening from outside.
"""
if hasattr(self, "_dist_info"):
return self._dist_info
# play it safe
cc_info = ""
compiler = getattr(self._ccompiler, "compiler", None)
if compiler is not None:
if isinstance(compiler, str):
cc_info += compiler
elif hasattr(compiler, "__iter__"):
cc_info += ' '.join(compiler)
# in case if 'compiler' attribute doesn't provide anything
cc_type = getattr(self._ccompiler, "compiler_type", "")
if cc_type in ("intelem", "intelemw", "mingw64"):
cc_info += "x86_64"

cc_type = getattr(self._ccompiler, "compiler_type", '')
if cc_type in ("intelem", "intelemw"):
platform = "x86_64"
elif cc_type in ("intel", "intelw", "intele"):
cc_info += "x86"
elif cc_type in ("msvc", "mingw32"):
import platform
if platform.architecture()[0] == "32bit":
cc_info += "x86"
platform = "x86"
else:
from distutils.util import get_platform
platform = get_platform()

cc_info = getattr(self._ccompiler, "compiler", getattr(self._ccompiler, "compiler_so", ''))
if not cc_type or cc_type == "unix":
if hasattr(cc_info, "__iter__"):
compiler = cc_info[0]
else:
cc_info += "x86_64"
compiler = str(cc_info)
else:
# the last hope, too bad for cross-compiling
import platform
cc_info += platform.machine()
compiler = cc_type

cc_info += cc_type
cflags = os.environ.get("CFLAGS", "")
if cflags not in cc_info:
cc_info += cflags
if hasattr(cc_info, "__iter__") and len(cc_info) > 1:
extra_args = ' '.join(cc_info[1:])
else:
extra_args = os.environ.get("CFLAGS", "")
extra_args += os.environ.get("CPPFLAGS", "")

self._dist_info = cc_info
return cc_info
self._dist_info = (platform, compiler, extra_args)
return self._dist_info

@staticmethod
def dist_error(*args):
Expand Down Expand Up @@ -893,57 +889,56 @@ class _CCompiler(object):
def __init__(self):
if hasattr(self, "cc_is_cached"):
return
to_detect = (
# attr regex
(
("cc_on_x64", "^(x|x86_|amd)64"),
("cc_on_x86", "^(x86|i386|i686)"),
("cc_on_ppc64le", "^(powerpc|ppc)64(el|le)"),
("cc_on_ppc64", "^(powerpc|ppc)64"),
("cc_on_armhf", "^arm"),
("cc_on_aarch64", "^aarch64"),
# priority is given to first of string
# if it fail we search in the rest, due
# to append platform.machine() at the end,
# check method 'dist_info()' for more clarification.
("cc_on_x64", ".*(x|x86_|amd)64.*"),
("cc_on_x86", ".*(x86|i386|i686).*"),
("cc_on_ppc64le", ".*(powerpc|ppc)64(el|le).*"),
("cc_on_ppc64", ".*(powerpc|ppc)64.*"),
("cc_on_armhf", ".*arm.*"),
("cc_on_aarch64", ".*aarch64.*"),
# undefined platform
("cc_on_noarch", ""),
),
(
("cc_is_gcc", r".*(gcc|gnu\-g).*"),
("cc_is_clang", ".*clang.*"),
("cc_is_iccw", ".*(intelw|intelemw|iccw).*"), # intel msvc like
("cc_is_icc", ".*(intel|icc).*"), # intel unix like
("cc_is_msvc", ".*msvc.*"),
("cc_is_nocc", ""),
),
(("cc_has_debug", ".*(O0|Od|ggdb|coverage|debug:full).*"),),
(("cc_has_native", ".*(-march=native|-xHost|/QxHost).*"),),
# in case if the class run with -DNPY_DISABLE_OPTIMIZATION
(("cc_noopt", ".*DISABLE_OPT.*"),),
# attr regex
detect_arch = (
("cc_on_x64", ".*(x|x86_|amd)64.*"),
("cc_on_x86", ".*(win32|x86|i386|i686).*"),
("cc_on_ppc64le", ".*(powerpc|ppc)64(el|le).*"),
("cc_on_ppc64", ".*(powerpc|ppc)64.*"),
("cc_on_aarch64", ".*(aarch64|arm64).*"),
("cc_on_armhf", ".*arm.*"),
# undefined platform
("cc_on_noarch", ""),
)
detect_compiler = (
("cc_is_gcc", r".*(gcc|gnu\-g).*"),
("cc_is_clang", ".*clang.*"),
("cc_is_iccw", ".*(intelw|intelemw|iccw).*"), # intel msvc like
("cc_is_icc", ".*(intel|icc).*"), # intel unix like
("cc_is_msvc", ".*msvc.*"),
# undefined compiler will be treat it as gcc
("cc_is_nocc", ""),
)
detect_args = (
("cc_has_debug", ".*(O0|Od|ggdb|coverage|debug:full).*"),
("cc_has_native", ".*(-march=native|-xHost|/QxHost).*"),
# in case if the class run with -DNPY_DISABLE_OPTIMIZATION
("cc_noopt", ".*DISABLE_OPT.*"),
)
for section in to_detect:
for attr, rgex in section:
setattr(self, attr, False)

dist_info = self.dist_info()
for section in to_detect:
platform, compiler_info, extra_args = dist_info
# set False to all attrs
for section in (detect_arch, detect_compiler, detect_args):
for attr, rgex in section:
if rgex and not re.match(rgex, dist_info, re.IGNORECASE):
setattr(self, attr, False)

for detect, searchin in ((detect_arch, platform), (detect_compiler, compiler_info)):
for attr, rgex in detect:
if rgex and not re.match(rgex, searchin, re.IGNORECASE):
continue
setattr(self, attr, True)
break

for attr, rgex in detect_args:
if rgex and not re.match(rgex, extra_args, re.IGNORECASE):
continue
setattr(self, attr, True)

if self.cc_on_noarch:
self.dist_log(
"unable to detect CPU arch via compiler info, "
"optimization is disabled \ninfo << %s >> " % dist_info,
"unable to detect CPU architecture which lead to disable the optimization. "
f"check dist_info:<<\n{dist_info}\n>>",
stderr=True
)
self.cc_noopt = True
Expand All @@ -958,8 +953,9 @@ def __init__(self):
but still has the same gcc optimization flags.
"""
self.dist_log(
"unable to detect compiler name via info <<\n%s\n>> "
"treating it as a gcc" % dist_info,
"unable to detect compiler type which leads to treating it as GCC. "
"this is a normal behavior if you're using gcc-like compiler such as MinGW or IBM/XLC."
f"check dist_info:<<\n{dist_info}\n>>",
stderr=True
)
self.cc_is_gcc = True
Expand Down
2 changes: 1 addition & 1 deletion numpy/distutils/tests/test_ccompiler_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def setup(self):
self._opt = None

def nopt(self, *args, **kwargs):
FakeCCompilerOpt.fake_info = self.arch + '_' + self.cc
FakeCCompilerOpt.fake_info = (self.arch, self.cc, "")
return FakeCCompilerOpt(*args, **kwargs)

def opt(self):
Expand Down
4 changes: 2 additions & 2 deletions numpy/distutils/tests/test_ccompiler_opt_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
)

class FakeCCompilerOpt(CCompilerOpt):
fake_info = ""
fake_info = ("arch", "compiler", "extra_args")
def __init__(self, *args, **kwargs):
CCompilerOpt.__init__(self, None, **kwargs)
def dist_compile(self, sources, flags, **kwargs):
Expand Down Expand Up @@ -169,7 +169,7 @@ def setup(self):
def test_features(self):
for arch, compilers in arch_compilers.items():
for cc in compilers:
FakeCCompilerOpt.fake_info = arch + cc
FakeCCompilerOpt.fake_info = (arch, cc, "")
_TestConfFeatures()

if is_standalone:
Expand Down
0