Buckets:
ranranrunforit/build-small-hackathon-storage / pylibs /numpy /distutils /tests /test_ccompiler_opt.py
| import re, textwrap, os | |
| from os import sys, path | |
| from distutils.errors import DistutilsError | |
| is_standalone = __name__ == '__main__' and __package__ is None | |
| if is_standalone: | |
| import unittest, contextlib, tempfile, shutil | |
| sys.path.append(path.abspath(path.join(path.dirname(__file__), ".."))) | |
| from ccompiler_opt import CCompilerOpt | |
| # from numpy/testing/_private/utils.py | |
| def tempdir(*args, **kwargs): | |
| tmpdir = tempfile.mkdtemp(*args, **kwargs) | |
| try: | |
| yield tmpdir | |
| finally: | |
| shutil.rmtree(tmpdir) | |
| def assert_(expr, msg=''): | |
| if not expr: | |
| raise AssertionError(msg) | |
| else: | |
| from numpy.distutils.ccompiler_opt import CCompilerOpt | |
| from numpy.testing import assert_, tempdir | |
| # architectures and compilers to test | |
| arch_compilers = dict( | |
| x86 = ("gcc", "clang", "icc", "iccw", "msvc"), | |
| x64 = ("gcc", "clang", "icc", "iccw", "msvc"), | |
| ppc64 = ("gcc", "clang"), | |
| ppc64le = ("gcc", "clang"), | |
| armhf = ("gcc", "clang"), | |
| aarch64 = ("gcc", "clang", "fcc"), | |
| s390x = ("gcc", "clang"), | |
| noarch = ("gcc",) | |
| ) | |
| class FakeCCompilerOpt(CCompilerOpt): | |
| fake_info = "" | |
| def __init__(self, trap_files="", trap_flags="", *args, **kwargs): | |
| self.fake_trap_files = trap_files | |
| self.fake_trap_flags = trap_flags | |
| CCompilerOpt.__init__(self, None, **kwargs) | |
| def __repr__(self): | |
| return textwrap.dedent("""\ | |
| <<<< | |
| march : {} | |
| compiler : {} | |
| ---------------- | |
| {} | |
| >>>> | |
| """).format(self.cc_march, self.cc_name, self.report()) | |
| def dist_compile(self, sources, flags, **kwargs): | |
| assert(isinstance(sources, list)) | |
| assert(isinstance(flags, list)) | |
| if self.fake_trap_files: | |
| for src in sources: | |
| if re.match(self.fake_trap_files, src): | |
| self.dist_error("source is trapped by a fake interface") | |
| if self.fake_trap_flags: | |
| for f in flags: | |
| if re.match(self.fake_trap_flags, f): | |
| self.dist_error("flag is trapped by a fake interface") | |
| # fake objects | |
| return zip(sources, [' '.join(flags)] * len(sources)) | |
| def dist_info(self): | |
| return FakeCCompilerOpt.fake_info | |
| def dist_log(*args, stderr=False): | |
| pass | |
| class _Test_CCompilerOpt: | |
| arch = None # x86_64 | |
| cc = None # gcc | |
| def setup_class(self): | |
| FakeCCompilerOpt.conf_nocache = True | |
| self._opt = None | |
| def nopt(self, *args, **kwargs): | |
| FakeCCompilerOpt.fake_info = (self.arch, self.cc, "") | |
| return FakeCCompilerOpt(*args, **kwargs) | |
| def opt(self): | |
| if not self._opt: | |
| self._opt = self.nopt() | |
| return self._opt | |
| def march(self): | |
| return self.opt().cc_march | |
| def cc_name(self): | |
| return self.opt().cc_name | |
| def get_targets(self, targets, groups, **kwargs): | |
| FakeCCompilerOpt.conf_target_groups = groups | |
| opt = self.nopt( | |
| cpu_baseline=kwargs.get("baseline", "min"), | |
| cpu_dispatch=kwargs.get("dispatch", "max"), | |
| trap_files=kwargs.get("trap_files", ""), | |
| trap_flags=kwargs.get("trap_flags", "") | |
| ) | |
| with tempdir() as tmpdir: | |
| file = os.path.join(tmpdir, "test_targets.c") | |
| with open(file, 'w') as f: | |
| f.write(targets) | |
| gtargets = [] | |
| gflags = {} | |
| fake_objects = opt.try_dispatch([file]) | |
| for source, flags in fake_objects: | |
| gtar = path.basename(source).split('.')[1:-1] | |
| glen = len(gtar) | |
| if glen == 0: | |
| gtar = "baseline" | |
| elif glen == 1: | |
| gtar = gtar[0].upper() | |
| else: | |
| # converting multi-target into parentheses str format to be equivalent | |
| # to the configuration statements syntax. | |
| gtar = ('('+' '.join(gtar)+')').upper() | |
| gtargets.append(gtar) | |
| gflags[gtar] = flags | |
| has_baseline, targets = opt.sources_status[file] | |
| targets = targets + ["baseline"] if has_baseline else targets | |
| # convert tuple that represent multi-target into parentheses str format | |
| targets = [ | |
| '('+' '.join(tar)+')' if isinstance(tar, tuple) else tar | |
| for tar in targets | |
| ] | |
| if len(targets) != len(gtargets) or not all(t in gtargets for t in targets): | |
| raise AssertionError( | |
| "'sources_status' returns different targets than the compiled targets\n" | |
| "%s != %s" % (targets, gtargets) | |
| ) | |
| # return targets from 'sources_status' since the order is matters | |
| return targets, gflags | |
| def arg_regex(self, **kwargs): | |
| map2origin = dict( | |
| x64 = "x86", | |
| ppc64le = "ppc64", | |
| aarch64 = "armhf", | |
| clang = "gcc", | |
| ) | |
| march = self.march(); cc_name = self.cc_name() | |
| map_march = map2origin.get(march, march) | |
| map_cc = map2origin.get(cc_name, cc_name) | |
| for key in ( | |
| march, cc_name, map_march, map_cc, | |
| march + '_' + cc_name, | |
| map_march + '_' + cc_name, | |
| march + '_' + map_cc, | |
| map_march + '_' + map_cc, | |
| ) : | |
| regex = kwargs.pop(key, None) | |
| if regex is not None: | |
| break | |
| if regex: | |
| if isinstance(regex, dict): | |
| for k, v in regex.items(): | |
| if v[-1:] not in ')}$?\\.+*': | |
| regex[k] = v + '$' | |
| else: | |
| assert(isinstance(regex, str)) | |
| if regex[-1:] not in ')}$?\\.+*': | |
| regex += '$' | |
| return regex | |
| def expect(self, dispatch, baseline="", **kwargs): | |
| match = self.arg_regex(**kwargs) | |
| if match is None: | |
| return | |
| opt = self.nopt( | |
| cpu_baseline=baseline, cpu_dispatch=dispatch, | |
| trap_files=kwargs.get("trap_files", ""), | |
| trap_flags=kwargs.get("trap_flags", "") | |
| ) | |
| features = ' '.join(opt.cpu_dispatch_names()) | |
| if not match: | |
| if len(features) != 0: | |
| raise AssertionError( | |
| 'expected empty features, not "%s"' % features | |
| ) | |
| return | |
| if not re.match(match, features, re.IGNORECASE): | |
| raise AssertionError( | |
| 'dispatch features "%s" not match "%s"' % (features, match) | |
| ) | |
| def expect_baseline(self, baseline, dispatch="", **kwargs): | |
| match = self.arg_regex(**kwargs) | |
| if match is None: | |
| return | |
| opt = self.nopt( | |
| cpu_baseline=baseline, cpu_dispatch=dispatch, | |
| trap_files=kwargs.get("trap_files", ""), | |
| trap_flags=kwargs.get("trap_flags", "") | |
| ) | |
| features = ' '.join(opt.cpu_baseline_names()) | |
| if not match: | |
| if len(features) != 0: | |
| raise AssertionError( | |
| 'expected empty features, not "%s"' % features | |
| ) | |
| return | |
| if not re.match(match, features, re.IGNORECASE): | |
| raise AssertionError( | |
| 'baseline features "%s" not match "%s"' % (features, match) | |
| ) | |
| def expect_flags(self, baseline, dispatch="", **kwargs): | |
| match = self.arg_regex(**kwargs) | |
| if match is None: | |
| return | |
| opt = self.nopt( | |
| cpu_baseline=baseline, cpu_dispatch=dispatch, | |
| trap_files=kwargs.get("trap_files", ""), | |
| trap_flags=kwargs.get("trap_flags", "") | |
| ) | |
| flags = ' '.join(opt.cpu_baseline_flags()) | |
| if not match: | |
| if len(flags) != 0: | |
| raise AssertionError( | |
| 'expected empty flags not "%s"' % flags | |
| ) | |
| return | |
| if not re.match(match, flags): | |
| raise AssertionError( | |
| 'flags "%s" not match "%s"' % (flags, match) | |
| ) | |
| def expect_targets(self, targets, groups={}, **kwargs): | |
| match = self.arg_regex(**kwargs) | |
| if match is None: | |
| return | |
| targets, _ = self.get_targets(targets=targets, groups=groups, **kwargs) | |
| targets = ' '.join(targets) | |
| if not match: | |
| if len(targets) != 0: | |
| raise AssertionError( | |
| 'expected empty targets, not "%s"' % targets | |
| ) | |
| return | |
| if not re.match(match, targets, re.IGNORECASE): | |
| raise AssertionError( | |
| 'targets "%s" not match "%s"' % (targets, match) | |
| ) | |
| def expect_target_flags(self, targets, groups={}, **kwargs): | |
| match_dict = self.arg_regex(**kwargs) | |
| if match_dict is None: | |
| return | |
| assert(isinstance(match_dict, dict)) | |
| _, tar_flags = self.get_targets(targets=targets, groups=groups) | |
| for match_tar, match_flags in match_dict.items(): | |
| if match_tar not in tar_flags: | |
| raise AssertionError( | |
| 'expected to find target "%s"' % match_tar | |
| ) | |
| flags = tar_flags[match_tar] | |
| if not match_flags: | |
| if len(flags) != 0: | |
| raise AssertionError( | |
| 'expected to find empty flags in target "%s"' % match_tar | |
| ) | |
| if not re.match(match_flags, flags): | |
| raise AssertionError( | |
| '"%s" flags "%s" not match "%s"' % (match_tar, flags, match_flags) | |
| ) | |
| def test_interface(self): | |
| wrong_arch = "ppc64" if self.arch != "ppc64" else "x86" | |
| wrong_cc = "clang" if self.cc != "clang" else "icc" | |
| opt = self.opt() | |
| assert_(getattr(opt, "cc_on_" + self.arch)) | |
| assert_(not getattr(opt, "cc_on_" + wrong_arch)) | |
| assert_(getattr(opt, "cc_is_" + self.cc)) | |
| assert_(not getattr(opt, "cc_is_" + wrong_cc)) | |
| def test_args_empty(self): | |
| for baseline, dispatch in ( | |
| ("", "none"), | |
| (None, ""), | |
| ("none +none", "none - none"), | |
| ("none -max", "min - max"), | |
| ("+vsx2 -VSX2", "vsx avx2 avx512f -max"), | |
| ("max -vsx - avx + avx512f neon -MAX ", | |
| "min -min + max -max -vsx + avx2 -avx2 +NONE") | |
| ) : | |
| opt = self.nopt(cpu_baseline=baseline, cpu_dispatch=dispatch) | |
| assert(len(opt.cpu_baseline_names()) == 0) | |
| assert(len(opt.cpu_dispatch_names()) == 0) | |
| def test_args_validation(self): | |
| if self.march() == "unknown": | |
| return | |
| # check sanity of argument's validation | |
| for baseline, dispatch in ( | |
| ("unkown_feature - max +min", "unknown max min"), # unknowing features | |
| ("#avx2", "$vsx") # groups and polices aren't acceptable | |
| ) : | |
| try: | |
| self.nopt(cpu_baseline=baseline, cpu_dispatch=dispatch) | |
| raise AssertionError("excepted an exception for invalid arguments") | |
| except DistutilsError: | |
| pass | |
| def test_skip(self): | |
| # only takes what platform supports and skip the others | |
| # without casing exceptions | |
| self.expect( | |
| "sse vsx neon", | |
| x86="sse", ppc64="vsx", armhf="neon", unknown="" | |
| ) | |
| self.expect( | |
| "sse41 avx avx2 vsx2 vsx3 neon_vfpv4 asimd", | |
| x86 = "sse41 avx avx2", | |
| ppc64 = "vsx2 vsx3", | |
| armhf = "neon_vfpv4 asimd", | |
| unknown = "" | |
| ) | |
| # any features in cpu_dispatch must be ignored if it's part of baseline | |
| self.expect( | |
| "sse neon vsx", baseline="sse neon vsx", | |
| x86="", ppc64="", armhf="" | |
| ) | |
| self.expect( | |
| "avx2 vsx3 asimdhp", baseline="avx2 vsx3 asimdhp", | |
| x86="", ppc64="", armhf="" | |
| ) | |
| def test_implies(self): | |
| # baseline combining implied features, so we count | |
| # on it instead of testing 'feature_implies()'' directly | |
| self.expect_baseline( | |
| "fma3 avx2 asimd vsx3", | |
| # .* between two spaces can validate features in between | |
| x86 = "sse .* sse41 .* fma3.*avx2", | |
| ppc64 = "vsx vsx2 vsx3", | |
| armhf = "neon neon_fp16 neon_vfpv4 asimd" | |
| ) | |
| """ | |
| special cases | |
| """ | |
| # in icc and msvc, FMA3 and AVX2 can't be separated | |
| # both need to implies each other, same for avx512f & cd | |
| for f0, f1 in ( | |
| ("fma3", "avx2"), | |
| ("avx512f", "avx512cd"), | |
| ): | |
| diff = ".* sse42 .* %s .*%s$" % (f0, f1) | |
| self.expect_baseline(f0, | |
| x86_gcc=".* sse42 .* %s$" % f0, | |
| x86_icc=diff, x86_iccw=diff | |
| ) | |
| self.expect_baseline(f1, | |
| x86_gcc=".* avx .* %s$" % f1, | |
| x86_icc=diff, x86_iccw=diff | |
| ) | |
| # in msvc, following features can't be separated too | |
| for f in (("fma3", "avx2"), ("avx512f", "avx512cd", "avx512_skx")): | |
| for ff in f: | |
| self.expect_baseline(ff, | |
| x86_msvc=".*%s" % ' '.join(f) | |
| ) | |
| # in ppc64le VSX and VSX2 can't be separated | |
| self.expect_baseline("vsx", ppc64le="vsx vsx2") | |
| # in aarch64 following features can't be separated | |
| for f in ("neon", "neon_fp16", "neon_vfpv4", "asimd"): | |
| self.expect_baseline(f, aarch64="neon neon_fp16 neon_vfpv4 asimd") | |
| def test_args_options(self): | |
| # max & native | |
| for o in ("max", "native"): | |
| if o == "native" and self.cc_name() == "msvc": | |
| continue | |
| self.expect(o, | |
| trap_files=".*cpu_(sse|vsx|neon|vx).c", | |
| x86="", ppc64="", armhf="", s390x="" | |
| ) | |
| self.expect(o, | |
| trap_files=".*cpu_(sse3|vsx2|neon_vfpv4|vxe).c", | |
| x86="sse sse2", ppc64="vsx", armhf="neon neon_fp16", | |
| aarch64="", ppc64le="", s390x="vx" | |
| ) | |
| self.expect(o, | |
| trap_files=".*cpu_(popcnt|vsx3).c", | |
| x86="sse .* sse41", ppc64="vsx vsx2", | |
| armhf="neon neon_fp16 .* asimd .*", | |
| s390x="vx vxe vxe2" | |
| ) | |
| self.expect(o, | |
| x86_gcc=".* xop fma4 .* avx512f .* avx512_knl avx512_knm avx512_skx .*", | |
| # in icc, xop and fam4 aren't supported | |
| x86_icc=".* avx512f .* avx512_knl avx512_knm avx512_skx .*", | |
| x86_iccw=".* avx512f .* avx512_knl avx512_knm avx512_skx .*", | |
| # in msvc, avx512_knl avx512_knm aren't supported | |
| x86_msvc=".* xop fma4 .* avx512f .* avx512_skx .*", | |
| armhf=".* asimd asimdhp asimddp .*", | |
| ppc64="vsx vsx2 vsx3 vsx4.*", | |
| s390x="vx vxe vxe2.*" | |
| ) | |
| # min | |
| self.expect("min", | |
| x86="sse sse2", x64="sse sse2 sse3", | |
| armhf="", aarch64="neon neon_fp16 .* asimd", | |
| ppc64="", ppc64le="vsx vsx2", s390x="" | |
| ) | |
| self.expect( | |
| "min", trap_files=".*cpu_(sse2|vsx2).c", | |
| x86="", ppc64le="" | |
| ) | |
| # an exception must triggered if native flag isn't supported | |
| # when option "native" is activated through the args | |
| try: | |
| self.expect("native", | |
| trap_flags=".*(-march=native|-xHost|/QxHost|-mcpu=a64fx).*", | |
| x86=".*", ppc64=".*", armhf=".*", s390x=".*", aarch64=".*", | |
| ) | |
| if self.march() != "unknown": | |
| raise AssertionError( | |
| "excepted an exception for %s" % self.march() | |
| ) | |
| except DistutilsError: | |
| if self.march() == "unknown": | |
| raise AssertionError("excepted no exceptions") | |
| def test_flags(self): | |
| self.expect_flags( | |
| "sse sse2 vsx vsx2 neon neon_fp16 vx vxe", | |
| x86_gcc="-msse -msse2", x86_icc="-msse -msse2", | |
| x86_iccw="/arch:SSE2", | |
| x86_msvc="/arch:SSE2" if self.march() == "x86" else "", | |
| ppc64_gcc= "-mcpu=power8", | |
| ppc64_clang="-mcpu=power8", | |
| armhf_gcc="-mfpu=neon-fp16 -mfp16-format=ieee", | |
| aarch64="", | |
| s390x="-mzvector -march=arch12" | |
| ) | |
| # testing normalize -march | |
| self.expect_flags( | |
| "asimd", | |
| aarch64="", | |
| armhf_gcc=r"-mfp16-format=ieee -mfpu=neon-fp-armv8 -march=armv8-a\+simd" | |
| ) | |
| self.expect_flags( | |
| "asimdhp", | |
| aarch64_gcc=r"-march=armv8.2-a\+fp16", | |
| armhf_gcc=r"-mfp16-format=ieee -mfpu=neon-fp-armv8 -march=armv8.2-a\+fp16" | |
| ) | |
| self.expect_flags( | |
| "asimddp", aarch64_gcc=r"-march=armv8.2-a\+dotprod" | |
| ) | |
| self.expect_flags( | |
| # asimdfhm implies asimdhp | |
| "asimdfhm", aarch64_gcc=r"-march=armv8.2-a\+fp16\+fp16fml" | |
| ) | |
| self.expect_flags( | |
| "asimddp asimdhp asimdfhm", | |
| aarch64_gcc=r"-march=armv8.2-a\+dotprod\+fp16\+fp16fml" | |
| ) | |
| self.expect_flags( | |
| "vx vxe vxe2", | |
| s390x=r"-mzvector -march=arch13" | |
| ) | |
| def test_targets_exceptions(self): | |
| for targets in ( | |
| "bla bla", "/*@targets", | |
| "/*@targets */", | |
| "/*@targets unknown */", | |
| "/*@targets $unknown_policy avx2 */", | |
| "/*@targets #unknown_group avx2 */", | |
| "/*@targets $ */", | |
| "/*@targets # vsx */", | |
| "/*@targets #$ vsx */", | |
| "/*@targets vsx avx2 ) */", | |
| "/*@targets vsx avx2 (avx2 */", | |
| "/*@targets vsx avx2 () */", | |
| "/*@targets vsx avx2 ($autovec) */", # no features | |
| "/*@targets vsx avx2 (xxx) */", | |
| "/*@targets vsx avx2 (baseline) */", | |
| ) : | |
| try: | |
| self.expect_targets( | |
| targets, | |
| x86="", armhf="", ppc64="", s390x="" | |
| ) | |
| if self.march() != "unknown": | |
| raise AssertionError( | |
| "excepted an exception for %s" % self.march() | |
| ) | |
| except DistutilsError: | |
| if self.march() == "unknown": | |
| raise AssertionError("excepted no exceptions") | |
| def test_targets_syntax(self): | |
| for targets in ( | |
| "/*@targets $keep_baseline sse vsx neon vx*/", | |
| "/*@targets,$keep_baseline,sse,vsx,neon vx*/", | |
| "/*@targets*$keep_baseline*sse*vsx*neon*vx*/", | |
| """ | |
| /* | |
| ** @targets | |
| ** $keep_baseline, sse vsx,neon, vx | |
| */ | |
| """, | |
| """ | |
| /* | |
| ************@targets**************** | |
| ** $keep_baseline, sse vsx, neon, vx | |
| ************************************ | |
| */ | |
| """, | |
| """ | |
| /* | |
| /////////////@targets///////////////// | |
| //$keep_baseline//sse//vsx//neon//vx | |
| ///////////////////////////////////// | |
| */ | |
| """, | |
| """ | |
| /* | |
| @targets | |
| $keep_baseline | |
| SSE VSX NEON VX*/ | |
| """ | |
| ) : | |
| self.expect_targets(targets, | |
| x86="sse", ppc64="vsx", armhf="neon", s390x="vx", unknown="" | |
| ) | |
| def test_targets(self): | |
| # test skipping baseline features | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| sse sse2 sse41 avx avx2 avx512f | |
| vsx vsx2 vsx3 vsx4 | |
| neon neon_fp16 asimdhp asimddp | |
| vx vxe vxe2 | |
| */ | |
| """, | |
| baseline="avx vsx2 asimd vx vxe", | |
| x86="avx512f avx2", armhf="asimddp asimdhp", ppc64="vsx4 vsx3", | |
| s390x="vxe2" | |
| ) | |
| # test skipping non-dispatch features | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| sse41 avx avx2 avx512f | |
| vsx2 vsx3 vsx4 | |
| asimd asimdhp asimddp | |
| vx vxe vxe2 | |
| */ | |
| """, | |
| baseline="", dispatch="sse41 avx2 vsx2 asimd asimddp vxe2", | |
| x86="avx2 sse41", armhf="asimddp asimd", ppc64="vsx2", s390x="vxe2" | |
| ) | |
| # test skipping features that not supported | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| sse2 sse41 avx2 avx512f | |
| vsx2 vsx3 vsx4 | |
| neon asimdhp asimddp | |
| vx vxe vxe2 | |
| */ | |
| """, | |
| baseline="", | |
| trap_files=".*(avx2|avx512f|vsx3|vsx4|asimddp|vxe2).c", | |
| x86="sse41 sse2", ppc64="vsx2", armhf="asimdhp neon", | |
| s390x="vxe vx" | |
| ) | |
| # test skipping features that implies each other | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| sse sse2 avx fma3 avx2 avx512f avx512cd | |
| vsx vsx2 vsx3 | |
| neon neon_vfpv4 neon_fp16 neon_fp16 asimd asimdhp | |
| asimddp asimdfhm | |
| */ | |
| """, | |
| baseline="", | |
| x86_gcc="avx512cd avx512f avx2 fma3 avx sse2", | |
| x86_msvc="avx512cd avx2 avx sse2", | |
| x86_icc="avx512cd avx2 avx sse2", | |
| x86_iccw="avx512cd avx2 avx sse2", | |
| ppc64="vsx3 vsx2 vsx", | |
| ppc64le="vsx3 vsx2", | |
| armhf="asimdfhm asimddp asimdhp asimd neon_vfpv4 neon_fp16 neon", | |
| aarch64="asimdfhm asimddp asimdhp asimd" | |
| ) | |
| def test_targets_policies(self): | |
| # 'keep_baseline', generate objects for baseline features | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| $keep_baseline | |
| sse2 sse42 avx2 avx512f | |
| vsx2 vsx3 | |
| neon neon_vfpv4 asimd asimddp | |
| vx vxe vxe2 | |
| */ | |
| """, | |
| baseline="sse41 avx2 vsx2 asimd vsx3 vxe", | |
| x86="avx512f avx2 sse42 sse2", | |
| ppc64="vsx3 vsx2", | |
| armhf="asimddp asimd neon_vfpv4 neon", | |
| # neon, neon_vfpv4, asimd implies each other | |
| aarch64="asimddp asimd", | |
| s390x="vxe2 vxe vx" | |
| ) | |
| # 'keep_sort', leave the sort as-is | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| $keep_baseline $keep_sort | |
| avx512f sse42 avx2 sse2 | |
| vsx2 vsx3 | |
| asimd neon neon_vfpv4 asimddp | |
| vxe vxe2 | |
| */ | |
| """, | |
| x86="avx512f sse42 avx2 sse2", | |
| ppc64="vsx2 vsx3", | |
| armhf="asimd neon neon_vfpv4 asimddp", | |
| # neon, neon_vfpv4, asimd implies each other | |
| aarch64="asimd asimddp", | |
| s390x="vxe vxe2" | |
| ) | |
| # 'autovec', skipping features that can't be | |
| # vectorized by the compiler | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| $keep_baseline $keep_sort $autovec | |
| avx512f avx2 sse42 sse41 sse2 | |
| vsx3 vsx2 | |
| asimddp asimd neon_vfpv4 neon | |
| */ | |
| """, | |
| x86_gcc="avx512f avx2 sse42 sse41 sse2", | |
| x86_icc="avx512f avx2 sse42 sse41 sse2", | |
| x86_iccw="avx512f avx2 sse42 sse41 sse2", | |
| x86_msvc="avx512f avx2 sse2" | |
| if self.march() == 'x86' else "avx512f avx2", | |
| ppc64="vsx3 vsx2", | |
| armhf="asimddp asimd neon_vfpv4 neon", | |
| # neon, neon_vfpv4, asimd implies each other | |
| aarch64="asimddp asimd" | |
| ) | |
| for policy in ("$maxopt", "$autovec"): | |
| # 'maxopt' and autovec set the max acceptable optimization flags | |
| self.expect_target_flags( | |
| "/*@targets baseline %s */" % policy, | |
| gcc={"baseline":".*-O3.*"}, icc={"baseline":".*-O3.*"}, | |
| iccw={"baseline":".*/O3.*"}, msvc={"baseline":".*/O2.*"}, | |
| unknown={"baseline":".*"} | |
| ) | |
| # 'werror', force compilers to treat warnings as errors | |
| self.expect_target_flags( | |
| "/*@targets baseline $werror */", | |
| gcc={"baseline":".*-Werror.*"}, icc={"baseline":".*-Werror.*"}, | |
| iccw={"baseline":".*/Werror.*"}, msvc={"baseline":".*/WX.*"}, | |
| unknown={"baseline":".*"} | |
| ) | |
| def test_targets_groups(self): | |
| self.expect_targets( | |
| """ | |
| /*@targets $keep_baseline baseline #test_group */ | |
| """, | |
| groups=dict( | |
| test_group=(""" | |
| $keep_baseline | |
| asimddp sse2 vsx2 avx2 vsx3 | |
| avx512f asimdhp | |
| """) | |
| ), | |
| x86="avx512f avx2 sse2 baseline", | |
| ppc64="vsx3 vsx2 baseline", | |
| armhf="asimddp asimdhp baseline" | |
| ) | |
| # test skip duplicating and sorting | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| * sse42 avx avx512f | |
| * #test_group_1 | |
| * vsx2 | |
| * #test_group_2 | |
| * asimddp asimdfhm | |
| */ | |
| """, | |
| groups=dict( | |
| test_group_1=(""" | |
| VSX2 vsx3 asimd avx2 SSE41 | |
| """), | |
| test_group_2=(""" | |
| vsx2 vsx3 asImd aVx2 sse41 | |
| """) | |
| ), | |
| x86="avx512f avx2 avx sse42 sse41", | |
| ppc64="vsx3 vsx2", | |
| # vsx2 part of the default baseline of ppc64le, option ("min") | |
| ppc64le="vsx3", | |
| armhf="asimdfhm asimddp asimd", | |
| # asimd part of the default baseline of aarch64, option ("min") | |
| aarch64="asimdfhm asimddp" | |
| ) | |
| def test_targets_multi(self): | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| (avx512_clx avx512_cnl) (asimdhp asimddp) | |
| */ | |
| """, | |
| x86=r"\(avx512_clx avx512_cnl\)", | |
| armhf=r"\(asimdhp asimddp\)", | |
| ) | |
| # test skipping implied features and auto-sort | |
| self.expect_targets( | |
| """ | |
| /*@targets | |
| f16c (sse41 avx sse42) (sse3 avx2 avx512f) | |
| vsx2 (vsx vsx3 vsx2) | |
| (neon neon_vfpv4 asimd asimdhp asimddp) | |
| */ | |
| """, | |
| x86="avx512f f16c avx", | |
| ppc64="vsx3 vsx2", | |
| ppc64le="vsx3", # vsx2 part of baseline | |
| armhf=r"\(asimdhp asimddp\)", | |
| ) | |
| # test skipping implied features and keep sort | |
| self.expect_targets( | |
| """ | |
| /*@targets $keep_sort | |
| (sse41 avx sse42) (sse3 avx2 avx512f) | |
| (vsx vsx3 vsx2) | |
| (asimddp neon neon_vfpv4 asimd asimdhp) | |
| (vx vxe vxe2) | |
| */ | |
| """, | |
| x86="avx avx512f", | |
| ppc64="vsx3", | |
| armhf=r"\(asimdhp asimddp\)", | |
| s390x="vxe2" | |
| ) | |
| # test compiler variety and avoiding duplicating | |
| self.expect_targets( | |
| """ | |
| /*@targets $keep_sort | |
| fma3 avx2 (fma3 avx2) (avx2 fma3) avx2 fma3 | |
| */ | |
| """, | |
| x86_gcc=r"fma3 avx2 \(fma3 avx2\)", | |
| x86_icc="avx2", x86_iccw="avx2", | |
| x86_msvc="avx2" | |
| ) | |
| def new_test(arch, cc): | |
| if is_standalone: return textwrap.dedent("""\ | |
| class TestCCompilerOpt_{class_name}(_Test_CCompilerOpt, unittest.TestCase): | |
| arch = '{arch}' | |
| cc = '{cc}' | |
| def __init__(self, methodName="runTest"): | |
| unittest.TestCase.__init__(self, methodName) | |
| self.setup_class() | |
| """).format( | |
| class_name=arch + '_' + cc, arch=arch, cc=cc | |
| ) | |
| return textwrap.dedent("""\ | |
| class TestCCompilerOpt_{class_name}(_Test_CCompilerOpt): | |
| arch = '{arch}' | |
| cc = '{cc}' | |
| """).format( | |
| class_name=arch + '_' + cc, arch=arch, cc=cc | |
| ) | |
| """ | |
| if 1 and is_standalone: | |
| FakeCCompilerOpt.fake_info = "x86_icc" | |
| cco = FakeCCompilerOpt(None, cpu_baseline="avx2") | |
| print(' '.join(cco.cpu_baseline_names())) | |
| print(cco.cpu_baseline_flags()) | |
| unittest.main() | |
| sys.exit() | |
| """ | |
| for arch, compilers in arch_compilers.items(): | |
| for cc in compilers: | |
| exec(new_test(arch, cc)) | |
| if is_standalone: | |
| unittest.main() | |
Xet Storage Details
- Size:
- 28.8 kB
- Xet hash:
- 0ddf3e0ab972bf60ac919e37641d700f1e5ab58f23f5ee2433ea803a9772bc7c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.