summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2020-05-27 06:16:24 -0600
committerGitHub <noreply@github.com>2020-05-27 06:16:24 -0600
commitaa874275d41d924523b718b961515eb8a1665dee (patch)
tree316c5de733b01c5ebd4d5b9332a26c6092f45c26 /numpy
parent36e017194c32a53cf2965a513243cb3c348095df (diff)
parente9620b67345757576236db4da0f3b6ac0bcd3a99 (diff)
downloadnumpy-aa874275d41d924523b718b961515eb8a1665dee.tar.gz
Merge pull request #16304 from seiko2plus/issue_16302
TST, MAINT: Fix detecting and testing armhf features
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/common/npy_cpu_features.c.src4
-rw-r--r--numpy/core/tests/test_cpu_features.py39
2 files changed, 34 insertions, 9 deletions
diff --git a/numpy/core/src/common/npy_cpu_features.c.src b/numpy/core/src/common/npy_cpu_features.c.src
index e676932c9..bd4743905 100644
--- a/numpy/core/src/common/npy_cpu_features.c.src
+++ b/numpy/core/src/common/npy_cpu_features.c.src
@@ -349,15 +349,17 @@ npy__cpu_init_features_linux(void)
if ((hwcap2 & NPY__HWCAP2_AES) || (hwcap2 & NPY__HWCAP2_SHA1) ||
(hwcap2 & NPY__HWCAP2_SHA2) || (hwcap2 & NPY__HWCAP2_PMULL) ||
(hwcap2 & NPY__HWCAP2_CRC32))
+ {
+ hwcap = hwcap2;
#else
if (1)
-#endif
{
if (!(hwcap & (NPY__HWCAP_FP | NPY__HWCAP_ASIMD))) {
// Is this could happen? maybe disabled by kernel
// BTW this will break the baseline of AARCH64
return 1;
}
+#endif
npy__cpu_have[NPY_CPU_FEATURE_FPHP] = (hwcap & NPY__HWCAP_FPHP) != 0;
npy__cpu_have[NPY_CPU_FEATURE_ASIMDHP] = (hwcap & NPY__HWCAP_ASIMDHP) != 0;
npy__cpu_have[NPY_CPU_FEATURE_ASIMDDP] = (hwcap & NPY__HWCAP_ASIMDDP) != 0;
diff --git a/numpy/core/tests/test_cpu_features.py b/numpy/core/tests/test_cpu_features.py
index 3b5cb3157..337b7330c 100644
--- a/numpy/core/tests/test_cpu_features.py
+++ b/numpy/core/tests/test_cpu_features.py
@@ -16,23 +16,36 @@ class AbstractTest(object):
def test_features(self):
self.load_flags()
for gname, features in self.features_groups.items():
- test_features = [self.features_map.get(f, f) in self.features_flags for f in features]
+ test_features = [self.cpu_have(f) for f in features]
assert_equal(__cpu_features__.get(gname), all(test_features))
for feature_name in self.features:
- map_name = self.features_map.get(feature_name, feature_name)
- cpu_have = map_name in self.features_flags
+ cpu_have = self.cpu_have(feature_name)
npy_have = __cpu_features__.get(feature_name)
assert_equal(npy_have, cpu_have)
- def load_flags_proc(self, magic_key):
+ def cpu_have(self, feature_name):
+ map_names = self.features_map.get(feature_name, feature_name)
+ if isinstance(map_names, str):
+ return map_names in self.features_flags
+ for f in map_names:
+ if f in self.features_flags:
+ return True
+ return False
+
+ def load_flags_cpuinfo(self, magic_key):
+ self.features_flags = self.get_cpuinfo_item(magic_key)
+
+ def get_cpuinfo_item(self, magic_key):
+ values = set()
with open('/proc/cpuinfo') as fd:
for line in fd:
if not line.startswith(magic_key):
continue
flags_value = [s.strip() for s in line.split(':', 1)]
if len(flags_value) == 2:
- self.features_flags = self.features_flags.union(flags_value[1].upper().split())
+ values = values.union(flags_value[1].upper().split())
+ return values
def load_flags_auxv(self):
import subprocess
@@ -75,7 +88,7 @@ class Test_X86_Features(AbstractTest):
AVX5124FMAPS="AVX512_4FMAPS", AVX5124VNNIW="AVX512_4VNNIW", AVX512VPOPCNTDQ="AVX512_VPOPCNTDQ",
)
def load_flags(self):
- self.load_flags_proc("flags")
+ self.load_flags_cpuinfo("flags")
is_power = re.match("^(powerpc|ppc)64", machine, re.IGNORECASE)
@pytest.mark.skipif(not is_linux or not is_power, reason="Only for Linux and Power")
@@ -97,8 +110,18 @@ class Test_ARM_Features(AbstractTest):
NEON_VFPV4 = ["NEON", "VFPV4"],
)
def load_flags(self):
- self.load_flags_proc("Features")
- if re.match("^(aarch64|AARCH64)", platform.machine()):
+ self.load_flags_cpuinfo("Features")
+ arch = self.get_cpuinfo_item("CPU architecture")
+ # in case of mounting virtual filesystem of aarch64 kernel
+ is_rootfs_v8 = int('0'+next(iter(arch))) > 7 if arch else 0
+ if re.match("^(aarch64|AARCH64)", machine) or is_rootfs_v8:
self.features_map = dict(
NEON="ASIMD", HALF="ASIMD", VFPV4="ASIMD"
)
+ else:
+ self.features_map = dict(
+ # ELF auxiliary vector and /proc/cpuinfo on Linux kernel(armv8 aarch32)
+ # doesn't provide information about ASIMD, so we assume that ASIMD is supported
+ # if the kernel reports any one of the following ARM8 features.
+ ASIMD=("AES", "SHA1", "SHA2", "PMULL", "CRC32")
+ )