123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808 |
- 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
- @contextlib.contextmanager
- 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"),
- 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
- @staticmethod
- 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).*",
- x86=".*", ppc64=".*", armhf=".*", 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_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="-maltivec -mvsx -mpower8-vector",
- 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()
|