diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2020-05-27 06:16:24 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-27 06:16:24 -0600 |
commit | aa874275d41d924523b718b961515eb8a1665dee (patch) | |
tree | 316c5de733b01c5ebd4d5b9332a26c6092f45c26 /numpy | |
parent | 36e017194c32a53cf2965a513243cb3c348095df (diff) | |
parent | e9620b67345757576236db4da0f3b6ac0bcd3a99 (diff) | |
download | numpy-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.src | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_cpu_features.py | 39 |
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") + ) |