diff --git a/easybuild/toolchains/compiler/intel_compilers.py b/easybuild/toolchains/compiler/intel_compilers.py index 515b3920c9..50950f0552 100644 --- a/easybuild/toolchains/compiler/intel_compilers.py +++ b/easybuild/toolchains/compiler/intel_compilers.py @@ -29,6 +29,7 @@ """ import os +import easybuild.tools.systemtools as systemtools from easybuild.toolchains.compiler.inteliccifort import IntelIccIfort from easybuild.tools import LooseVersion from easybuild.tools.toolchain.compiler import Compiler @@ -42,7 +43,7 @@ class IntelCompilers(IntelIccIfort): COMPILER_MODULE_NAME = ['intel-compilers'] COMPILER_UNIQUE_OPTS = dict(IntelIccIfort.COMPILER_UNIQUE_OPTS) COMPILER_UNIQUE_OPTS.update({ - 'oneapi': (False, "Use oneAPI compilers icx/icpx/ifx instead of classic compilers"), + 'oneapi': (None, "Use oneAPI compilers icx/icpx/ifx instead of classic compilers"), 'oneapi_c_cxx': (None, "Use oneAPI C/C++ compilers icx/icpx instead of classic Intel C/C++ compilers " "(auto-enabled for Intel compilers version 2022.2.0, or newer)"), 'oneapi_fortran': (False, "Use oneAPI Fortran compiler ifx instead of classic Intel Fortran compiler"), @@ -75,7 +76,8 @@ def set_variables(self): if self.options.get('oneapi_c_cxx', None) is None: self.options['oneapi_c_cxx'] = True - if self.options.get('oneapi', False): + oneapi_tcopt = self.options.get('oneapi') + if oneapi_tcopt: oneapi = True self.COMPILER_CXX = 'icpx' self.COMPILER_CC = 'icx' @@ -84,7 +86,7 @@ def set_variables(self): self.COMPILER_FC = 'ifx' # if both 'oneapi' and 'oneapi_*' are set, the latter are ignored - else: + elif oneapi_tcopt is None: if self.options.get('oneapi_c_cxx', False): oneapi = True self.COMPILER_CC = 'icx' @@ -108,5 +110,12 @@ def set_variables(self): # recommended in porting guide self.options.options_map['openmp'] = ['fiopenmp'] + # -xSSE2 is not supported by Intel oneAPI compilers, + # so use -march=x86-64 -mtune=generic when using optarch=GENERIC + self.COMPILER_GENERIC_OPTION = { + (systemtools.X86_64, systemtools.AMD): 'march=x86-64 -mtune=generic', + (systemtools.X86_64, systemtools.INTEL): 'march=x86-64 -mtune=generic', + } + # skip IntelIccIfort.set_variables (no longer relevant for recent versions) Compiler.set_variables(self) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index e61692c06e..a26ff0c86f 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -702,29 +702,49 @@ def test_override_optarch(self): def test_optarch_generic(self): """Test whether --optarch=GENERIC works as intended.""" + + intel_generic_flags_classic = "-xSSE2 -ftz -fp-speculation=safe -fp-model source" + intel_generic_flags_oneapi_old = "-march=x86-64 -mtune=generic -fp-speculation=safe -fp-model precise" + intel_generic_flags_oneapi_new = "-march=x86-64 -mtune=generic -ftz -fp-speculation=safe -fp-model precise" + for generic in [False, True]: if generic: init_config(build_options={'optarch': 'GENERIC', 'silent': True}) flag_vars = ['CFLAGS', 'CXXFLAGS', 'FCFLAGS', 'FFLAGS', 'F90FLAGS'] tcs = { - 'gompi': ('2018a', "-march=x86-64 -mtune=generic"), - 'iccifort': ('2018.1.163', "-xSSE2 -ftz -fp-speculation=safe -fp-model source"), - 'intel-compilers': ('2021.4.0', "-xSSE2 -fp-speculation=safe -fp-model precise"), + 'gompi': ('2018a', "-march=x86-64 -mtune=generic", {}), + 'iccifort': ('2018.1.163', "-xSSE2 -ftz -fp-speculation=safe -fp-model source", {}), + # check generic compiler flags for old versions of intel-compilers with/without opting in to oneapi + 'intel-compilers@old-default': ('2021.4.0', intel_generic_flags_classic, {}), + 'intel-compilers@old-oneapi-false': ('2021.4.0', intel_generic_flags_classic, {'oneapi': False}), + 'intel-compilers@old-oneapi-true': ('2021.4.0', intel_generic_flags_oneapi_old, {'oneapi': True}), + # check generic compiler flags for recent versions of intel-compilers with/without opting in to oneapi + 'intel-compilers@new-default': ('2022.2.0', intel_generic_flags_oneapi_new, {}), + 'intel-compilers@new-oneapi-true': ('2022.2.0', intel_generic_flags_oneapi_new, {'oneapi': True}), + 'intel-compilers@new-oneapi-false': ('2022.2.0', intel_generic_flags_classic, {'oneapi': False}), } for tcopt_optarch in [False, True]: - for tcname in tcs: - tcversion, generic_flags = tcs[tcname] + for key in tcs: + tcname = key.split('@')[0] + tcversion, generic_flags, custom_tcopts = tcs[key] tc = self.get_toolchain(tcname, version=tcversion) - if tcname == 'intel-compilers': - tc.set_options({'optarch': tcopt_optarch, 'oneapi': True}) - else: - tc.set_options({'optarch': tcopt_optarch}) + + tcopts = {'optarch': tcopt_optarch} + tcopts.update(custom_tcopts) + tc.set_options(tcopts) + tc.prepare() for var in flag_vars: + val = tc.get_variable(var) + tup = (key, tcversion, tcopts, generic_flags, val) if generic: - self.assertTrue(generic_flags in tc.get_variable(var)) + error_msg = "(%s, %s, %s) '%s' flags should be found in: '%s'" + self.assertTrue(generic_flags in val, error_msg % tup) else: - self.assertFalse(generic_flags in tc.get_variable(var)) + error_msg = "(%s, %s, %s) '%s' flags should not be found in: '%s'" + self.assertFalse(generic_flags in val, error_msg % tup) + + modules.modules_tool().purge() def test_optarch_aarch64_heuristic(self): """Test whether AArch64 pre-GCC-6 optimal architecture flag heuristic works."""