diff options
author | Ben Gamari <ben@smart-cactus.org> | 2018-12-27 14:41:01 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-12-27 15:20:17 -0500 |
commit | 2d9bb67e0a42e1cfb0737de00a4a8fe2e9cc5636 (patch) | |
tree | 5f435f4e332d178031858809d81479bf84e52fd7 | |
parent | 942b501972139ed95b49b75cb8c0523b460f6d10 (diff) | |
download | haskell-wip/testsuite-cpu-features.tar.gz |
testsuite: Add predicate for CPU feature availabilitywip/testsuite-cpu-features
Previously testing code-generation for ISA extensions was nearly impossible
since we had no ability to determine whether the host supports the needed
extension. Here we fix this by introducing a simple /proc/cpuinfo-based
testsuite predicate. We really ought to
-rw-r--r-- | testsuite/driver/cpu_features.py | 71 | ||||
-rw-r--r-- | testsuite/driver/testlib.py | 1 |
2 files changed, 72 insertions, 0 deletions
diff --git a/testsuite/driver/cpu_features.py b/testsuite/driver/cpu_features.py new file mode 100644 index 0000000000..b9e43470da --- /dev/null +++ b/testsuite/driver/cpu_features.py @@ -0,0 +1,71 @@ +import os +from testglobals import config + +# Feature names generally follow the naming used by Linux's /proc/cpuinfo. +SUPPORTED_CPU_FEATURES = { + # These aren't comprehensive; they are only CPU features that we care about + + # x86: + 'sse', 'sse2', 'sse3', 'ssse3', 'sse4_1', 'sse4_2', + 'avx1', 'avx2', + 'popcnt', 'bmi1', 'bmi2' +} + +cpu_feature_cache = None + +def get_cpu_features(): + if config.os == 'Linux' and os.path.exists('/proc/cpuinfo'): + import re + f = open('/proc/cpuinfo').read() + flags = re.search(r'flags\s*:\s*.*$', f, re.M) + if flags is None: + print('get_cpu_features: failed to find cpu features') + return {} + flags = set(flags[0].split()) + if 'pni' in flags: + flags.add('sse3') + flags.remove('pni') + return flags + + elif config.os == 'Darwin': + import subprocess + out, err = subprocess.check_output(['sysctl', 'hw']) + features = {} + def check_feature(darwin_name, our_name=None): + if re.find(r'hw\.optional.%s:\s*1' % darwin_name, out): + features.add(darwin_name if our_name is None else our_name) + + for feature in SUPPORTED_CPU_FEATURES: + check_feature(feature) + + # A few annoying cases + check_feature('avx1_0', 'avx1') + check_feature('avx2_0', 'avx2') + return features + + else: + # TODO: Add Windows support + print('get_cpu_features: Lacking support for your platform') + + return {} + +def have_cpu_feature(feature): + """ + A testsuite predicate for testing the availability of CPU features. + """ + assert feature in SUPPORTED_CPU_FEATURES + if cpu_feature_cache is None: + cpu_feature_cache = get_cpu_features() + print('Found CPU features:', ' '.join(cpu_feature_cache)) + # Sanity checking + assert all(feat in SUPPORTED_CPU_FEATURES + for feat in cpu_feature_cache) + + return feature in cpu_feature_cache + + +if __name__ == '__main__': + import sys + config.os = sys.argv[1] + print(get_cpu_features()) + diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py index 5f84863070..df56d1d685 100644 --- a/testsuite/driver/testlib.py +++ b/testsuite/driver/testlib.py @@ -20,6 +20,7 @@ import subprocess from testglobals import config, ghc_env, default_testopts, brokens, t from testutil import strip_quotes, lndir, link_or_copy_file, passed, failBecause, str_fail, str_pass +from cpu_features import have_cpu_feature import perf_notes as Perf from perf_notes import MetricChange extra_src_files = {'T4198': ['exitminus1.c']} # TODO: See #12223 |