From 18d73dc1d5804032262255dd244ba80e588d41e5 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Wed, 31 Jan 2018 14:01:12 +0000 Subject: [PATCH 01/12] Add -ftree-vectorize to defaultopt='-O2' for GCC. Since Intel auto-vectorizes at -O2 but not at -O1, and GCC auto-vectorizes at -O3 but not at -O2 this makes it consistent. --- easybuild/toolchains/compiler/gcc.py | 1 + test/framework/options.py | 2 +- test/framework/toolchain.py | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/easybuild/toolchains/compiler/gcc.py b/easybuild/toolchains/compiler/gcc.py index f3d2dc19c1..a494f96401 100644 --- a/easybuild/toolchains/compiler/gcc.py +++ b/easybuild/toolchains/compiler/gcc.py @@ -65,6 +65,7 @@ class Gcc(Compiler): 'defaultprec':[], 'loose': ['mrecip', 'mno-ieee-fp'], 'veryloose': ['mrecip=all', 'mno-ieee-fp'], + 'defaultopt': ['O2', 'ftree-vectorize'], } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/test/framework/options.py b/test/framework/options.py index 13e5ee09f6..1751fddff3 100644 --- a/test/framework/options.py +++ b/test/framework/options.py @@ -2961,7 +2961,7 @@ def test_dump_env_config(self): "module load hwloc/1.6.2-GCC-4.7.2", # loading of dependency module # defining build env "export FC='gfortran'", - "export CFLAGS='-O2 -march=native'", + "export CFLAGS='-O2 -ftree-vectorize -march=native'", ] for pattern in patterns: regex = re.compile("^%s$" % pattern, re.M) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 5a7add78a9..44146250b4 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -481,7 +481,7 @@ def test_precision_flags(self): tc.set_options({}) tc.prepare() for var in flag_vars: - self.assertEqual(os.getenv(var), "-O2 -march=native") + self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native") # check other precision flags prec_flags = { @@ -498,9 +498,9 @@ def test_precision_flags(self): tc.prepare() for var in flag_vars: if enable: - self.assertEqual(os.getenv(var), "-O2 -march=native %s" % prec_flags[prec]) + self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native %s" % prec_flags[prec]) else: - self.assertEqual(os.getenv(var), "-O2 -march=native") + self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native") self.modtool.purge() def test_cgoolf_toolchain(self): @@ -580,7 +580,7 @@ def test_goolfc(self): tc.prepare() nvcc_flags = r' '.join([ - r'-Xcompiler="-O2 -%s -fopenmp"' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)], + r'-Xcompiler="-O2 -ftree-vectorize -%s -fopenmp"' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)], # the use of -lcudart in -Xlinker is a bit silly but hard to avoid r'-Xlinker=".* -lm -lrt -lcudart -lpthread"', r' '.join(["-gencode %s" % x for x in opts['cuda_gencode']]), @@ -905,7 +905,7 @@ def test_independence(self): 'CrayCCE': "-O2 -homp -craype-verbose", 'CrayGNU': "-O2 -fopenmp -craype-verbose", 'CrayIntel': "-O2 -ftz -fp-speculation=safe -fp-model source -fopenmp -craype-verbose", - 'GCC': "-O2 -test -fopenmp", + 'GCC': "-O2 -ftree-vectorize -test -fopenmp", 'iccifort': "-O2 -test -ftz -fp-speculation=safe -fp-model source -fopenmp", } From 1c8842b0e01d9faf91ab0637a26fbf567a1bcaaf Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 1 Feb 2018 09:22:50 +0000 Subject: [PATCH 02/12] test_misc_flags_shared: split flags. This avoids seeing "-v" being used in "-ftree-vectorize". --- test/framework/toolchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 44146250b4..97d294c249 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -277,7 +277,7 @@ def test_misc_flags_shared(self): # we need to make sure we check for flags, not letter (e.g. 'v' vs '-v') flag = '-%s' % tc.COMPILER_SHARED_OPTION_MAP[opt] for var in flag_vars: - flags = tc.get_variable(var) + flags = tc.get_variable(var).split() if enable: self.assertTrue(flag in flags, "%s: True means %s in %s" % (opt, flag, flags)) else: From 2d44ee4e52e6c0b53c94693652786f6e3c2a14d6 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 1 Feb 2018 10:57:49 +0000 Subject: [PATCH 03/12] Use march=nocona instead of -ftree-vectorize in optarch test. As -ftree-vectorize is there by default it confuses the test case. --- test/framework/toolchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 97d294c249..82d7d11954 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -387,7 +387,7 @@ def test_compiler_dependent_optarch(self): """Test whether specifying optarch on a per compiler basis works.""" flag_vars = ['CFLAGS', 'CXXFLAGS', 'FCFLAGS', 'FFLAGS', 'F90FLAGS'] intel_options = [('intelflag', 'intelflag'), ('GENERIC', 'xSSE2'), ('', '')] - gcc_options = [('gccflag', 'gccflag'), ('-ftree-vectorize', '-ftree-vectorize'), ('', '')] + gcc_options = [('gccflag', 'gccflag'), ('march=nocona', 'march=nocona'), ('', '')] gcccore_options = [('gcccoreflag', 'gcccoreflag'), ('GENERIC', 'march=x86-64 -mtune=generic'), ('', '')] toolchains = [('iccifort', '2011.13.367'), ('GCC', '4.7.2'), ('GCCcore', '6.2.0'), ('PGI', '16.7-GCC-5.4.0-2.26')] enabled = [True, False] From 033cf942f847d288e8a928ba138fbc043fd2ff7a Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 15 Mar 2018 17:21:55 +0000 Subject: [PATCH 04/12] Add -fno-math-errno to defaultprec/loose/veryloose GCC toolchainopts Neither PGI, nor Intel, nor Clang set errno for math functions by default. I have never seen it used. Setting this allows vectorization and inlining of sqrt in particular. --- easybuild/toolchains/compiler/gcc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/toolchains/compiler/gcc.py b/easybuild/toolchains/compiler/gcc.py index a494f96401..02e5aec394 100644 --- a/easybuild/toolchains/compiler/gcc.py +++ b/easybuild/toolchains/compiler/gcc.py @@ -62,9 +62,9 @@ class Gcc(Compiler): 'ieee': ['mieee-fp', 'fno-trapping-math'], 'strict': ['mieee-fp', 'mno-recip'], 'precise':['mno-recip'], - 'defaultprec':[], - 'loose': ['mrecip', 'mno-ieee-fp'], - 'veryloose': ['mrecip=all', 'mno-ieee-fp'], + 'defaultprec':['fno-math-errno'], + 'loose': ['fno-math-errno', 'mrecip', 'mno-ieee-fp'], + 'veryloose': ['fno-math-errno', 'mrecip=all', 'mno-ieee-fp'], 'defaultopt': ['O2', 'ftree-vectorize'], } From 04a0663608663380300a698c4c8c49e033db503c Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 15 Mar 2018 18:01:27 +0000 Subject: [PATCH 05/12] Adjust test cases to deal with -fno-math-errno. --- test/framework/options.py | 2 +- test/framework/toolchain.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/framework/options.py b/test/framework/options.py index 1751fddff3..efc93afd0a 100644 --- a/test/framework/options.py +++ b/test/framework/options.py @@ -2961,7 +2961,7 @@ def test_dump_env_config(self): "module load hwloc/1.6.2-GCC-4.7.2", # loading of dependency module # defining build env "export FC='gfortran'", - "export CFLAGS='-O2 -ftree-vectorize -march=native'", + "export CFLAGS='-O2 -ftree-vectorize -march=native -fno-math-errno'", ] for pattern in patterns: regex = re.compile("^%s$" % pattern, re.M) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 82d7d11954..fb53f349b0 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -476,20 +476,20 @@ def test_precision_flags(self): flag_vars = ['CFLAGS', 'CXXFLAGS', 'FCFLAGS', 'FFLAGS', 'F90FLAGS'] - # check default precision: no specific flag for GCC + # check default precision: -fno-math-errno flag for GCC tc = self.get_toolchain("goalf", version="1.1.0-no-OFED") tc.set_options({}) tc.prepare() for var in flag_vars: - self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native") + self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native -fno-math-errno") # check other precision flags prec_flags = { 'ieee': "-mieee-fp -fno-trapping-math", 'strict': "-mieee-fp -mno-recip", 'precise': "-mno-recip", - 'loose': "-mrecip -mno-ieee-fp", - 'veryloose': "-mrecip=all -mno-ieee-fp", + 'loose': "-fno-math-errno -mrecip -mno-ieee-fp", + 'veryloose': "-fno-math-errno -mrecip=all -mno-ieee-fp", } for prec in prec_flags: for enable in [True, False]: @@ -500,7 +500,7 @@ def test_precision_flags(self): if enable: self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native %s" % prec_flags[prec]) else: - self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native") + self.assertEqual(os.getenv(var), "-O2 -ftree-vectorize -march=native -fno-math-errno") self.modtool.purge() def test_cgoolf_toolchain(self): @@ -580,7 +580,7 @@ def test_goolfc(self): tc.prepare() nvcc_flags = r' '.join([ - r'-Xcompiler="-O2 -ftree-vectorize -%s -fopenmp"' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)], + r'-Xcompiler="-O2 -ftree-vectorize -%s -fno-math-errno -fopenmp"' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)], # the use of -lcudart in -Xlinker is a bit silly but hard to avoid r'-Xlinker=".* -lm -lrt -lcudart -lpthread"', r' '.join(["-gencode %s" % x for x in opts['cuda_gencode']]), @@ -903,9 +903,9 @@ def test_independence(self): tc_cflags = { 'CrayCCE': "-O2 -homp -craype-verbose", - 'CrayGNU': "-O2 -fopenmp -craype-verbose", + 'CrayGNU': "-O2 -fno-math-errno -fopenmp -craype-verbose", 'CrayIntel': "-O2 -ftz -fp-speculation=safe -fp-model source -fopenmp -craype-verbose", - 'GCC': "-O2 -ftree-vectorize -test -fopenmp", + 'GCC': "-O2 -ftree-vectorize -test -fno-math-errno -fopenmp", 'iccifort': "-O2 -test -ftz -fp-speculation=safe -fp-model source -fopenmp", } From c7216500f4e8ead31ef91fcf9e5f9a90201cfe95 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Fri, 16 Mar 2018 00:38:13 +0000 Subject: [PATCH 06/12] Fix one last precision testcase for ieee. --- test/framework/toolchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index fb53f349b0..0bacbf7a87 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -485,7 +485,7 @@ def test_precision_flags(self): # check other precision flags prec_flags = { - 'ieee': "-mieee-fp -fno-trapping-math", + 'ieee': "-fno-math-errno -mieee-fp -fno-trapping-math", 'strict': "-mieee-fp -mno-recip", 'precise': "-mno-recip", 'loose': "-fno-math-errno -mrecip -mno-ieee-fp", From 6b32291147798115f2ea61851a35cce677bc9e1a Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 23 Mar 2018 11:11:38 +0100 Subject: [PATCH 07/12] use DEFAULT_OPT_LEVEL constant + fix minor style issues --- easybuild/toolchains/compiler/gcc.py | 8 ++++---- test/framework/toolchain.py | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/easybuild/toolchains/compiler/gcc.py b/easybuild/toolchains/compiler/gcc.py index 02e5aec394..ddce7b6962 100644 --- a/easybuild/toolchains/compiler/gcc.py +++ b/easybuild/toolchains/compiler/gcc.py @@ -35,7 +35,7 @@ import easybuild.tools.systemtools as systemtools from easybuild.tools.build_log import EasyBuildError from easybuild.tools.modules import get_software_root, get_software_version -from easybuild.tools.toolchain.compiler import Compiler +from easybuild.tools.toolchain.compiler import Compiler, DEFAULT_OPT_LEVEL TC_CONSTANT_GCC = "GCC" @@ -61,11 +61,11 @@ class Gcc(Compiler): 'lto': 'flto', 'ieee': ['mieee-fp', 'fno-trapping-math'], 'strict': ['mieee-fp', 'mno-recip'], - 'precise':['mno-recip'], - 'defaultprec':['fno-math-errno'], + 'precise': ['mno-recip'], + 'defaultprec': ['fno-math-errno'], 'loose': ['fno-math-errno', 'mrecip', 'mno-ieee-fp'], 'veryloose': ['fno-math-errno', 'mrecip=all', 'mno-ieee-fp'], - 'defaultopt': ['O2', 'ftree-vectorize'], + DEFAULT_OPT_LEVEL: ['O2', 'ftree-vectorize'], } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 0bacbf7a87..effe171b0b 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -579,8 +579,10 @@ def test_goolfc(self): tc.set_options(opts) tc.prepare() + archflags = tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)] + optflags = "-O2 -ftree-vectorize -%s -fno-math-errno -fopenmp" % archflags nvcc_flags = r' '.join([ - r'-Xcompiler="-O2 -ftree-vectorize -%s -fno-math-errno -fopenmp"' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)], + r'-Xcompiler="%s"' % optflags, # the use of -lcudart in -Xlinker is a bit silly but hard to avoid r'-Xlinker=".* -lm -lrt -lcudart -lpthread"', r' '.join(["-gencode %s" % x for x in opts['cuda_gencode']]), From 09636635ffb73a9c142863798547a4b06ef355a9 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Mon, 26 Mar 2018 17:23:18 +0000 Subject: [PATCH 08/12] Introduce 'vectorize' toolchainopt. If set to True or False, will explicitly enable or disable auto-vectorization. Otherwise (if left to None) noopt and lowopt will not vectorize and other optimzations levels will vectorize. --- easybuild/toolchains/compiler/clang.py | 2 ++ easybuild/toolchains/compiler/gcc.py | 2 ++ easybuild/toolchains/compiler/ibmxl.py | 5 ++++- .../toolchains/compiler/inteliccifort.py | 2 ++ easybuild/toolchains/compiler/pgi.py | 2 ++ easybuild/tools/toolchain/compiler.py | 22 +++++++++++++++++-- test/framework/toolchain.py | 2 +- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/easybuild/toolchains/compiler/clang.py b/easybuild/toolchains/compiler/clang.py index 8e1be062c9..36a23e4d17 100644 --- a/easybuild/toolchains/compiler/clang.py +++ b/easybuild/toolchains/compiler/clang.py @@ -85,6 +85,8 @@ class Clang(Compiler): 'defaultprec': [], 'loose': ['ffast-math', 'fno-unsafe-math-optimizations'], 'veryloose': ['ffast-math'], + 'vectorize': 'fvectorize', + 'novectorize': 'fno-vectorize', } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/easybuild/toolchains/compiler/gcc.py b/easybuild/toolchains/compiler/gcc.py index ddce7b6962..6743576a38 100644 --- a/easybuild/toolchains/compiler/gcc.py +++ b/easybuild/toolchains/compiler/gcc.py @@ -65,6 +65,8 @@ class Gcc(Compiler): 'defaultprec': ['fno-math-errno'], 'loose': ['fno-math-errno', 'mrecip', 'mno-ieee-fp'], 'veryloose': ['fno-math-errno', 'mrecip=all', 'mno-ieee-fp'], + 'vectorize': 'ftree-vectorize', + 'novectorize': 'fno-tree-vectorize', DEFAULT_OPT_LEVEL: ['O2', 'ftree-vectorize'], } diff --git a/easybuild/toolchains/compiler/ibmxl.py b/easybuild/toolchains/compiler/ibmxl.py index b4efb3ce92..441a0eef4c 100644 --- a/easybuild/toolchains/compiler/ibmxl.py +++ b/easybuild/toolchains/compiler/ibmxl.py @@ -11,7 +11,7 @@ from distutils.version import LooseVersion import easybuild.tools.systemtools as systemtools -from easybuild.tools.toolchain.compiler import Compiler +from easybuild.tools.toolchain.compiler import Compiler, DEFAULT_OPT_LEVEL TC_CONSTANT_IBMCOMP = "IBMXL" @@ -35,6 +35,9 @@ class IBMXL(Compiler): 'defaultprec': ['', '', ''], 'loose': [''], 'veryloose': [''], + 'vectorize': 'qsimd=auto', + 'novectorize': 'qsimd=noauto', + DEFAULT_OPT_LEVEL: ['O2', 'qsimd=auto'], 'ibm-static': 'qstaticlink=xllibs', 'pic': 'qpic', 'shared': 'qmkshrobj', diff --git a/easybuild/toolchains/compiler/inteliccifort.py b/easybuild/toolchains/compiler/inteliccifort.py index 0ec3cde9f1..052b223392 100644 --- a/easybuild/toolchains/compiler/inteliccifort.py +++ b/easybuild/toolchains/compiler/inteliccifort.py @@ -64,6 +64,8 @@ class IntelIccIfort(Compiler): 'defaultprec': ['ftz', 'fp-speculation=safe', 'fp-model source'], 'loose': ['fp-model fast=1'], 'veryloose': ['fp-model fast=2'], + 'vectorize': 'vec', + 'novectorize': 'no-vec', 'intel-static': 'static-intel', 'no-icc': 'no-icc', 'error-unknown-option': 'we10006', # error at warning #10006: ignoring unknown option diff --git a/easybuild/toolchains/compiler/pgi.py b/easybuild/toolchains/compiler/pgi.py index f5ec0ec94f..f197ba069a 100644 --- a/easybuild/toolchains/compiler/pgi.py +++ b/easybuild/toolchains/compiler/pgi.py @@ -65,6 +65,8 @@ class Pgi(Compiler): 'defaultprec': ['Mflushz'], 'loose': ['Mfprelaxed'], 'veryloose': ['Mfprelaxed=div,order,intrinsic,recip,sqrt,rsqrt', 'Mfpapprox'], + 'vectorize': 'Mvect', + 'novectorize': 'Mnovect', } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/easybuild/tools/toolchain/compiler.py b/easybuild/tools/toolchain/compiler.py index 3147e9ba86..cc804a74b2 100644 --- a/easybuild/tools/toolchain/compiler.py +++ b/easybuild/tools/toolchain/compiler.py @@ -88,6 +88,8 @@ class Compiler(Toolchain): 'static': (False, "Build static library"), '32bit': (False, "Compile 32bit target"), # LA, FFTW 'openmp': (False, "Enable OpenMP"), + 'vectorize': (None, "Enable compiler auto-vectorization, default except for noopt and lowopt"), + 'novectorize': (None, "Disable compiler auto-vectorization, default for noopt and lowopt"), # not set, only used to map 'packed-linker-options': (False, "Pack the linker options as comma separated list"), # ScaLAPACK mainly 'rpath': (True, "Use RPATH wrappers when --rpath is enabled in EasyBuild configuration"), } @@ -246,7 +248,23 @@ def _set_compiler_flags(self): # 1st one is the one to use. add default at the end so len is at least 1 optflags = [self.options.option(x) for x in self.COMPILER_OPT_FLAGS if self.options.get(x, False)] + \ - [self.options.option(default_opt_level)] + [self.options.option(default_opt_level)][:1] + + # only apply if the vectorize toolchainopt is explicitly set + # otherwise the individual compiler toolchain file should make sure that + # vectorization is disabled for noopt and lowopt, and enabled otherwise. + if self.options.get('vectorize') is not None: + novectorize = self.options.option('novectorize') + vectorize = self.options.option('vectorize') + if self.options['vectorize']: + vectflags = vectorize + else: + vectflags = novectorize + # avoid double use of such flags + for setting in novectorize, vectorize: + if setting in optflags[0]: + optflags[0].remove(setting) + optflags.append(vectflags) optarchflags = [] if build_option('optarch') == OPTARCH_GENERIC: @@ -259,7 +277,7 @@ def _set_compiler_flags(self): precflags = [self.options.option(x) for x in self.COMPILER_PREC_FLAGS if self.options.get(x, False)] + \ [self.options.option('defaultprec')] - self.variables.nextend('OPTFLAGS', optflags[:1] + optarchflags) + self.variables.nextend('OPTFLAGS', optflags + optarchflags) self.variables.nextend('PRECFLAGS', precflags[:1]) # precflags last diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index effe171b0b..dd480ed328 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -290,7 +290,7 @@ def test_misc_flags_unique(self): flag_vars = ['CFLAGS', 'CXXFLAGS', 'FCFLAGS', 'FFLAGS', 'F90FLAGS'] # setting option should result in corresponding flag to be set (unique options) - for opt in ['unroll', 'optarch', 'openmp']: + for opt in ['unroll', 'optarch', 'openmp', 'vectorize']: for enable in [True, False]: tc = self.get_toolchain("goalf", version="1.1.0-no-OFED") tc.set_options({opt: enable}) From 71dbf6d665f53ca2446662c219eb98994826771e Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Mon, 26 Mar 2018 18:19:36 +0000 Subject: [PATCH 09/12] We need a copy of optflags[0] instead of modifying in place. Modifying in place changes the original optflags which messes up further tests in the toolchain tests. --- easybuild/tools/toolchain/compiler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/tools/toolchain/compiler.py b/easybuild/tools/toolchain/compiler.py index cc804a74b2..6252f28df9 100644 --- a/easybuild/tools/toolchain/compiler.py +++ b/easybuild/tools/toolchain/compiler.py @@ -261,9 +261,9 @@ def _set_compiler_flags(self): else: vectflags = novectorize # avoid double use of such flags - for setting in novectorize, vectorize: - if setting in optflags[0]: - optflags[0].remove(setting) + if isinstance(optflags[0], list): + optflags[0] = [setting for setting in optflags[0] + if setting not in (novectorize, vectorize)] optflags.append(vectflags) optarchflags = [] From 6a962a24a4053d4f1738e5cfb84027d565fe0e21 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Mon, 26 Mar 2018 22:55:05 +0000 Subject: [PATCH 10/12] Use dictionary with boolean keys for 'vectorize' toolchainopt. This avoids the need for 'novectorize' and makes for more compact logic. --- easybuild/toolchains/compiler/clang.py | 3 +-- easybuild/toolchains/compiler/gcc.py | 3 +-- easybuild/toolchains/compiler/ibmxl.py | 3 +-- easybuild/toolchains/compiler/inteliccifort.py | 3 +-- easybuild/toolchains/compiler/pgi.py | 3 +-- easybuild/tools/toolchain/compiler.py | 11 ++--------- test/framework/toolchain.py | 2 ++ 7 files changed, 9 insertions(+), 19 deletions(-) diff --git a/easybuild/toolchains/compiler/clang.py b/easybuild/toolchains/compiler/clang.py index 36a23e4d17..b877fcb31c 100644 --- a/easybuild/toolchains/compiler/clang.py +++ b/easybuild/toolchains/compiler/clang.py @@ -85,8 +85,7 @@ class Clang(Compiler): 'defaultprec': [], 'loose': ['ffast-math', 'fno-unsafe-math-optimizations'], 'veryloose': ['ffast-math'], - 'vectorize': 'fvectorize', - 'novectorize': 'fno-vectorize', + 'vectorize': {False: 'fno-vectorize', True: 'fvectorize'}, } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/easybuild/toolchains/compiler/gcc.py b/easybuild/toolchains/compiler/gcc.py index 6743576a38..d92aec0191 100644 --- a/easybuild/toolchains/compiler/gcc.py +++ b/easybuild/toolchains/compiler/gcc.py @@ -65,8 +65,7 @@ class Gcc(Compiler): 'defaultprec': ['fno-math-errno'], 'loose': ['fno-math-errno', 'mrecip', 'mno-ieee-fp'], 'veryloose': ['fno-math-errno', 'mrecip=all', 'mno-ieee-fp'], - 'vectorize': 'ftree-vectorize', - 'novectorize': 'fno-tree-vectorize', + 'vectorize': {False: 'fno-tree-vectorize', True: 'ftree-vectorize'}, DEFAULT_OPT_LEVEL: ['O2', 'ftree-vectorize'], } diff --git a/easybuild/toolchains/compiler/ibmxl.py b/easybuild/toolchains/compiler/ibmxl.py index 441a0eef4c..65170d6ad7 100644 --- a/easybuild/toolchains/compiler/ibmxl.py +++ b/easybuild/toolchains/compiler/ibmxl.py @@ -35,8 +35,7 @@ class IBMXL(Compiler): 'defaultprec': ['', '', ''], 'loose': [''], 'veryloose': [''], - 'vectorize': 'qsimd=auto', - 'novectorize': 'qsimd=noauto', + 'vectorize': {False: 'qsimd=noauto', True: 'qsimd=auto'}, DEFAULT_OPT_LEVEL: ['O2', 'qsimd=auto'], 'ibm-static': 'qstaticlink=xllibs', 'pic': 'qpic', diff --git a/easybuild/toolchains/compiler/inteliccifort.py b/easybuild/toolchains/compiler/inteliccifort.py index 052b223392..86b2330ae8 100644 --- a/easybuild/toolchains/compiler/inteliccifort.py +++ b/easybuild/toolchains/compiler/inteliccifort.py @@ -64,8 +64,7 @@ class IntelIccIfort(Compiler): 'defaultprec': ['ftz', 'fp-speculation=safe', 'fp-model source'], 'loose': ['fp-model fast=1'], 'veryloose': ['fp-model fast=2'], - 'vectorize': 'vec', - 'novectorize': 'no-vec', + 'vectorize': {False: 'no-vec', True: 'vec'}, 'intel-static': 'static-intel', 'no-icc': 'no-icc', 'error-unknown-option': 'we10006', # error at warning #10006: ignoring unknown option diff --git a/easybuild/toolchains/compiler/pgi.py b/easybuild/toolchains/compiler/pgi.py index f197ba069a..338789be69 100644 --- a/easybuild/toolchains/compiler/pgi.py +++ b/easybuild/toolchains/compiler/pgi.py @@ -65,8 +65,7 @@ class Pgi(Compiler): 'defaultprec': ['Mflushz'], 'loose': ['Mfprelaxed'], 'veryloose': ['Mfprelaxed=div,order,intrinsic,recip,sqrt,rsqrt', 'Mfpapprox'], - 'vectorize': 'Mvect', - 'novectorize': 'Mnovect', + 'vectorize': {False: 'Mnovect', True: 'Mvect'}, } # used when 'optarch' toolchain option is enabled (and --optarch is not specified) diff --git a/easybuild/tools/toolchain/compiler.py b/easybuild/tools/toolchain/compiler.py index 6252f28df9..66d1f83e6f 100644 --- a/easybuild/tools/toolchain/compiler.py +++ b/easybuild/tools/toolchain/compiler.py @@ -89,7 +89,6 @@ class Compiler(Toolchain): '32bit': (False, "Compile 32bit target"), # LA, FFTW 'openmp': (False, "Enable OpenMP"), 'vectorize': (None, "Enable compiler auto-vectorization, default except for noopt and lowopt"), - 'novectorize': (None, "Disable compiler auto-vectorization, default for noopt and lowopt"), # not set, only used to map 'packed-linker-options': (False, "Pack the linker options as comma separated list"), # ScaLAPACK mainly 'rpath': (True, "Use RPATH wrappers when --rpath is enabled in EasyBuild configuration"), } @@ -254,16 +253,10 @@ def _set_compiler_flags(self): # otherwise the individual compiler toolchain file should make sure that # vectorization is disabled for noopt and lowopt, and enabled otherwise. if self.options.get('vectorize') is not None: - novectorize = self.options.option('novectorize') - vectorize = self.options.option('vectorize') - if self.options['vectorize']: - vectflags = vectorize - else: - vectflags = novectorize + vectflags = self.options.option('vectorize')[self.options['vectorize']] # avoid double use of such flags if isinstance(optflags[0], list): - optflags[0] = [setting for setting in optflags[0] - if setting not in (novectorize, vectorize)] + optflags[0] = [flag for flag in optflags[0] if flag not in self.options.option('vectorize').values()] optflags.append(vectflags) optarchflags = [] diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index dd480ed328..81677a0c10 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -297,6 +297,8 @@ def test_misc_flags_unique(self): tc.prepare() if opt == 'optarch': flag = '-%s' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)] + elif isinstance(tc.options.options_map[opt], dict): + flag = '-%s' % tc.options.options_map[opt][True] else: flag = '-%s' % tc.options.options_map[opt] for var in flag_vars: From 45f550ac5496f4878dfa9cc79da53319089c2976 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 29 Mar 2018 13:09:17 +0000 Subject: [PATCH 11/12] Test both 'vectorize': True and 'vectorize': False toolchainopts. --- test/framework/toolchain.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 81677a0c10..69579a3867 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -296,17 +296,19 @@ def test_misc_flags_unique(self): tc.set_options({opt: enable}) tc.prepare() if opt == 'optarch': - flag = '-%s' % tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)] - elif isinstance(tc.options.options_map[opt], dict): - flag = '-%s' % tc.options.options_map[opt][True] + option = tc.COMPILER_OPTIMAL_ARCHITECTURE_OPTION[(tc.arch, tc.cpu_family)] else: - flag = '-%s' % tc.options.options_map[opt] + option = tc.options.options_map[opt] + if not isinstance(option, dict): + option = {True: option} for var in flag_vars: flags = tc.get_variable(var) - if enable: - self.assertTrue(flag in flags, "%s: True means %s in %s" % (opt, flag, flags)) - else: - self.assertTrue(flag not in flags, "%s: False means no %s in %s" % (opt, flag, flags)) + for key, value in option.items(): + flag = "-%s" % value + if enable == key: + self.assertTrue(flag in flags, "%s: %s means %s in %s" % (opt, enable, flag, flags)) + else: + self.assertTrue(flag not in flags, "%s: %s means no %s in %s" % (opt, enable, flag, flags)) self.modtool.purge() def test_override_optarch(self): From ed7494dedea2ca54330c4d63c8f0a74088d66e92 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Sat, 31 Mar 2018 01:54:30 +0000 Subject: [PATCH 12/12] vectorize: fix [:1] syntax and clarify avoiding double flags. Addresses @boegel's review. --- easybuild/tools/toolchain/compiler.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/easybuild/tools/toolchain/compiler.py b/easybuild/tools/toolchain/compiler.py index 66d1f83e6f..d97a0e7e34 100644 --- a/easybuild/tools/toolchain/compiler.py +++ b/easybuild/tools/toolchain/compiler.py @@ -246,17 +246,18 @@ def _set_compiler_flags(self): (default_opt_level, self.COMPILER_OPT_FLAGS)) # 1st one is the one to use. add default at the end so len is at least 1 - optflags = [self.options.option(x) for x in self.COMPILER_OPT_FLAGS if self.options.get(x, False)] + \ - [self.options.option(default_opt_level)][:1] + optflags = ([self.options.option(x) for x in self.COMPILER_OPT_FLAGS if self.options.get(x, False)] + \ + [self.options.option(default_opt_level)])[:1] # only apply if the vectorize toolchainopt is explicitly set # otherwise the individual compiler toolchain file should make sure that # vectorization is disabled for noopt and lowopt, and enabled otherwise. if self.options.get('vectorize') is not None: - vectflags = self.options.option('vectorize')[self.options['vectorize']] - # avoid double use of such flags + vectoptions = self.options.option('vectorize') + vectflags = vectoptions[self.options['vectorize']] + # avoid double use of such flags, or e.g. -fno-tree-vectorize followed by -ftree-vectorize if isinstance(optflags[0], list): - optflags[0] = [flag for flag in optflags[0] if flag not in self.options.option('vectorize').values()] + optflags[0] = [flag for flag in optflags[0] if flag not in vectoptions.values()] optflags.append(vectflags) optarchflags = []