diff --git a/easybuild/easyblocks/a/advisor.py b/easybuild/easyblocks/a/advisor.py index 2f24500b20..63b2c526bf 100644 --- a/easybuild/easyblocks/a/advisor.py +++ b/easybuild/easyblocks/a/advisor.py @@ -34,27 +34,32 @@ from easybuild.tools import LooseVersion from easybuild.easyblocks.generic.intelbase import IntelBase +from easybuild.tools.build_log import EasyBuildError class EB_Advisor(IntelBase): """ Support for installing Intel Advisor XE + - minimum version suported: 2020.x """ def __init__(self, *args, **kwargs): """Constructor, initialize class variables.""" super(EB_Advisor, self).__init__(*args, **kwargs) - if LooseVersion(self.version) < LooseVersion('2017'): - self.subdir = 'advisor_xe' - elif LooseVersion(self.version) < LooseVersion('2021'): + + if LooseVersion(self.version) < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + + if LooseVersion(self.version) < LooseVersion('2021'): self.subdir = 'advisor' else: self.subdir = os.path.join('advisor', 'latest') def prepare_step(self, *args, **kwargs): """Since 2019u3 there is no license required.""" - if LooseVersion(self.version) >= LooseVersion('2019_update3'): - kwargs['requires_runtime_license'] = False + kwargs['requires_runtime_license'] = False super(EB_Advisor, self).prepare_step(*args, **kwargs) def make_module_req_guess(self): diff --git a/easybuild/easyblocks/generic/intelbase.py b/easybuild/easyblocks/generic/intelbase.py index 8232390e38..e2177251d7 100644 --- a/easybuild/easyblocks/generic/intelbase.py +++ b/easybuild/easyblocks/generic/intelbase.py @@ -48,7 +48,7 @@ from easybuild.framework.easyconfig.types import ensure_iterable_license_specs from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import adjust_permissions, find_flexlm_license -from easybuild.tools.filetools import mkdir, read_file, remove_file, write_file +from easybuild.tools.filetools import read_file, remove_file, write_file from easybuild.tools.run import run_shell_cmd @@ -68,20 +68,14 @@ # silent.cfg parameter name for type of license activation (cfr. options listed above) ACTIVATION_NAME = 'ACTIVATION_TYPE' # since icc/ifort v2013_sp1, impi v4.1.1, imkl v11.1 -ACTIVATION_NAME_2012 = 'ACTIVATION' # previous activation type parameter used in older versions # silent.cfg parameter name for install prefix INSTALL_DIR_NAME = 'PSET_INSTALL_DIR' # silent.cfg parameter name for install mode INSTALL_MODE_NAME = 'PSET_MODE' -# Older (2015 and previous) silent.cfg parameter name for install mode -INSTALL_MODE_NAME_2015 = 'INSTALL_MODE' -# Install mode for 2016 version +# Install mode since 2016 version INSTALL_MODE = 'install' -# Install mode for 2015 and older versions -INSTALL_MODE_2015 = 'NONRPM' # silent.cfg parameter name for license file/server specification LICENSE_FILE_NAME = 'ACTIVATION_LICENSE_FILE' # since icc/ifort v2013_sp1, impi v4.1.1, imkl v11.1 -LICENSE_FILE_NAME_2012 = 'PSET_LICENSE_FILE' # previous license file parameter used in older versions LICENSE_SERIAL_NUMBER = 'ACTIVATION_SERIAL_NUMBER' COMP_ALL = 'ALL' @@ -136,12 +130,7 @@ def get_guesses_tools(self): """Find reasonable paths for a subset of Intel tools, ignoring CPATH, LD_LIBRARY_PATH and LIBRARY_PATH""" guesses = super(IntelBase, self).make_module_req_guess() - - if self.cfg['m32']: - guesses['PATH'] = [os.path.join(self.subdir, 'bin32')] - else: - guesses['PATH'] = [os.path.join(self.subdir, 'bin64')] - + guesses['PATH'] = [os.path.join(self.subdir, 'bin64')] guesses['MANPATH'] = [os.path.join(self.subdir, 'man')] # make sure $CPATH, $LD_LIBRARY_PATH and $LIBRARY_PATH are not updated in generated module file, @@ -155,13 +144,8 @@ def get_guesses_tools(self): def get_custom_paths_tools(self, binaries): """Custom sanity check paths for certain Intel tools.""" - if self.cfg['m32']: - files = [os.path.join('bin32', b) for b in binaries] - dirs = ['lib32', 'include'] - else: - files = [os.path.join('bin64', b) for b in binaries] - dirs = ['lib64', 'include'] - + files = [os.path.join('bin64', b) for b in binaries] + dirs = ['lib64', 'include'] custom_paths = { 'files': [os.path.join(self.subdir, f) for f in files], 'dirs': [os.path.join(self.subdir, d) for d in dirs], @@ -176,12 +160,6 @@ def extra_options(extra_vars=None): 'serial_number': [None, "Serial number for the product", CUSTOM], 'requires_runtime_license': [True, "Boolean indicating whether or not a runtime license is required", CUSTOM], - # 'usetmppath': - # workaround for older SL5 version (5.5 and earlier) - # used to be True, but False since SL5.6/SL6 - # disables TMP_PATH env and command line option - 'usetmppath': [False, "Use temporary path for installation", CUSTOM], - 'm32': [False, "Enable 32-bit toolchain", CUSTOM], 'components': [None, "List of components to install", CUSTOM], }) @@ -374,8 +352,8 @@ def install_step_classic(self, silent_cfg_names_map=None, silent_cfg_extras=None ]) % { 'install_dir_name': silent_cfg_names_map.get('install_dir_name', INSTALL_DIR_NAME), 'install_dir': silent_cfg_names_map.get('install_dir', self.installdir), - 'install_mode': silent_cfg_names_map.get('install_mode', INSTALL_MODE_2015), - 'install_mode_name': silent_cfg_names_map.get('install_mode_name', INSTALL_MODE_NAME_2015), + 'install_mode': silent_cfg_names_map.get('install_mode', INSTALL_MODE), + 'install_mode_name': silent_cfg_names_map.get('install_mode_name', INSTALL_MODE_NAME), } if self.install_components is not None: @@ -404,15 +382,6 @@ def install_step_classic(self, silent_cfg_names_map=None, silent_cfg_extras=None write_file(silentcfg, silent) self.log.debug("Contents of %s:\n%s", silentcfg, silent) - # workaround for mktmp: create tmp dir and use it - tmpdir = os.path.join(self.cfg['start_dir'], 'mytmpdir') - mkdir(tmpdir, parents=True) - - tmppathopt = '' - if self.cfg['usetmppath']: - env.setvar('TMP_PATH', tmpdir) - tmppathopt = "-t %s" % tmpdir - # set some extra env variables env.setvar('LOCAL_INSTALL_VERBOSE', '1') env.setvar('VERBOSE_MODE', '1') @@ -423,7 +392,6 @@ def install_step_classic(self, silent_cfg_names_map=None, silent_cfg_extras=None cmd = ' '.join([ self.cfg['preinstallopts'], './install.sh', - tmppathopt, '-s ' + silentcfg, self.cfg['installopts'], ]) diff --git a/easybuild/easyblocks/i/icc.py b/easybuild/easyblocks/i/icc.py index d9d31b75cb..167a6646f2 100644 --- a/easybuild/easyblocks/i/icc.py +++ b/easybuild/easyblocks/i/icc.py @@ -38,9 +38,9 @@ import re from easybuild.tools import LooseVersion -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, COMP_ALL -from easybuild.easyblocks.generic.intelbase import LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase, COMP_ALL from easybuild.easyblocks.tbb import get_tbb_gccprefix +from easybuild.tools.build_log import EasyBuildError from easybuild.tools.run import run_shell_cmd from easybuild.tools.systemtools import get_shared_lib_ext @@ -57,10 +57,9 @@ def get_icc_version(): class EB_icc(IntelBase): - """Support for installing icc - - - tested with 11.1.046 - - will fail for all older versions (due to newer silent installer) + """ + Support for installing icc + - minimum version suported: 2020.0 """ def __init__(self, *args, **kwargs): @@ -75,60 +74,38 @@ def __init__(self, *args, **kwargs): # required because of support in SystemCompiler generic easyblock to specify 'system' as version, # which results in deriving the actual compiler version # comparing a non-version like 'system' with an actual version like '2016' fails with TypeError in Python 3.x - if re.match(r'^[0-9]+.*', self.version) and LooseVersion(self.version) >= LooseVersion('2016'): + if re.match(r'^[0-9]+.*', self.version): - self.comp_libs_subdir = os.path.join('compilers_and_libraries_%s' % self.version, 'linux') + if LooseVersion(self.version) < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + + self.comp_libs_subdir = os.path.join(f'compilers_and_libraries_{self.version}', 'linux') if self.cfg['components'] is None: # we need to use 'ALL' by default, # using 'DEFAULTS' results in key things not being installed (e.g. bin/icc) self.cfg['components'] = [COMP_ALL] - self.log.debug("Nothing specified for components, but required for version 2016, using %s instead", - self.cfg['components']) - - def install_step(self): - """ - Actual installation - - create silent cfg file - - execute command - """ - silent_cfg_names_map = None - - if LooseVersion(self.version) < LooseVersion('2013_sp1'): - # since icc v2013_sp1, silent.cfg has been slightly changed to be 'more standard' - - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - super(EB_icc, self).install_step(silent_cfg_names_map=silent_cfg_names_map) + self.log.debug( + f"Missing components specification, required for version {self.version}. " + f"Using {self.cfg['components']} instead." + ) def sanity_check_step(self): """Custom sanity check paths for icc.""" - binprefix = 'bin/intel64' - libprefix = 'lib/intel64' - if LooseVersion(self.version) >= LooseVersion('2011'): - if LooseVersion(self.version) <= LooseVersion('2011.3.174'): - binprefix = 'bin' - elif LooseVersion(self.version) >= LooseVersion('2013_sp1'): - binprefix = 'bin' - else: - libprefix = 'compiler/lib/intel64' - + binprefix = 'bin' binfiles = ['icc', 'icpc'] - if LooseVersion(self.version) < LooseVersion('2014'): - binfiles += ['idb'] - binaries = [os.path.join(binprefix, f) for f in binfiles] - libraries = [os.path.join(libprefix, 'lib%s' % lib) for lib in ['iomp5.a', 'iomp5.%s' % get_shared_lib_ext()]] - sanity_check_files = binaries + libraries - if LooseVersion(self.version) > LooseVersion('2015'): - sanity_check_files.append('include/omp.h') + + libprefix = 'lib/intel64' + libraries = [os.path.join(libprefix, f'lib{lib}') for lib in ['iomp5.a', f'iomp5.{get_shared_lib_ext()}']] + + headers = ['include/omp.h'] custom_paths = { - 'files': sanity_check_files, + 'files': binaries + libraries + headers, 'dirs': [], } @@ -165,59 +142,39 @@ def make_module_req_guess(self): 'TBBROOT': ['tbb'], }) - if self.cfg['m32']: - # 32-bit toolchain - guesses['PATH'].extend(['bin/ia32', 'tbb/bin/ia32']) - # in the end we set 'LIBRARY_PATH' equal to 'LD_LIBRARY_PATH' - guesses['LD_LIBRARY_PATH'].append('lib/ia32') - - else: - # 64-bit toolkit - guesses['PATH'].extend([ - 'bin/intel64', - 'debugger/gdb/intel64/bin', - 'ipp/bin/intel64', - 'mpi/intel64/bin', - 'tbb/bin/emt64', - 'tbb/bin/intel64', - ]) - - # in the end we set 'LIBRARY_PATH' equal to 'LD_LIBRARY_PATH' - guesses['LD_LIBRARY_PATH'].extend([ - 'compiler/lib/intel64', - 'debugger/ipt/intel64/lib', - 'ipp/lib/intel64', - 'mkl/lib/intel64', - 'mpi/intel64', - 'tbb/lib/intel64/%s' % get_tbb_gccprefix(os.path.join(self.installdir, 'tbb/lib/intel64')), - ]) - - if LooseVersion(self.version) < LooseVersion('2016'): - prefix = 'composer_xe_%s' % self.version - # for some older versions, name of subdirectory is slightly different - if not os.path.isdir(os.path.join(self.installdir, prefix)): - cand_prefix = 'composerxe-%s' % self.version - if os.path.isdir(os.path.join(self.installdir, cand_prefix)): - prefix = cand_prefix - - # debugger is dependent on $INTEL_PYTHONHOME since version 2015 and newer - if LooseVersion(self.version) >= LooseVersion('2015'): - self.debuggerpath = os.path.join(prefix, 'debugger') - - else: - # new directory layout for Intel Parallel Studio XE 2016 - # https://software.intel.com/en-us/articles/new-directory-layout-for-intel-parallel-studio-xe-2016 - prefix = self.comp_libs_subdir - # Debugger requires INTEL_PYTHONHOME, which only allows for a single value - self.debuggerpath = 'debugger_%s' % self.version.split('.')[0] - - guesses['LD_LIBRARY_PATH'].extend([ - os.path.join(self.debuggerpath, 'libipt/intel64/lib'), - 'daal/lib/intel64_lin', - ]) - - # 'lib/intel64' is deliberately listed last, so it gets precedence over subdirs - guesses['LD_LIBRARY_PATH'].append('lib/intel64') + # 64-bit toolkit + guesses['PATH'].extend([ + 'bin/intel64', + 'debugger/gdb/intel64/bin', + 'ipp/bin/intel64', + 'mpi/intel64/bin', + 'tbb/bin/emt64', + 'tbb/bin/intel64', + ]) + + # in the end we set 'LIBRARY_PATH' equal to 'LD_LIBRARY_PATH' + guesses['LD_LIBRARY_PATH'].extend([ + 'compiler/lib/intel64', + 'debugger/ipt/intel64/lib', + 'ipp/lib/intel64', + 'mkl/lib/intel64', + 'mpi/intel64', + 'tbb/lib/intel64/%s' % get_tbb_gccprefix(os.path.join(self.installdir, 'tbb/lib/intel64')), + ]) + + # new directory layout since Intel Parallel Studio XE 2016 + # https://software.intel.com/en-us/articles/new-directory-layout-for-intel-parallel-studio-xe-2016 + prefix = self.comp_libs_subdir + # Debugger requires INTEL_PYTHONHOME, which only allows for a single value + self.debuggerpath = 'debugger_%s' % self.version.split('.')[0] + + guesses['LD_LIBRARY_PATH'].extend([ + os.path.join(self.debuggerpath, 'libipt/intel64/lib'), + 'daal/lib/intel64_lin', + ]) + + # 'lib/intel64' is deliberately listed last, so it gets precedence over subdirs + guesses['LD_LIBRARY_PATH'].append('lib/intel64') guesses['LIBRARY_PATH'] = guesses['LD_LIBRARY_PATH'] diff --git a/easybuild/easyblocks/i/ifort.py b/easybuild/easyblocks/i/ifort.py index 6497c1124f..d2d66adf95 100644 --- a/easybuild/easyblocks/i/ifort.py +++ b/easybuild/easyblocks/i/ifort.py @@ -34,42 +34,44 @@ """ import os -from easybuild.tools import LooseVersion from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.easyblocks.icc import EB_icc # @UnresolvedImport +from easybuild.tools import LooseVersion +from easybuild.tools.build_log import EasyBuildError from easybuild.tools.systemtools import get_shared_lib_ext class EB_ifort(EB_icc, IntelBase): """ Class that can be used to install ifort - - tested with 11.1.046 - -- will fail for all older versions (due to newer silent installer) + - minimum version suported: 2020.0 + - will fail for all older versions (due to newer silent installer) """ + def __init__(self, *args, **kwargs): + """Constructor, initialize class variables.""" + super().__init__(*args, **kwargs) + + if LooseVersion(self.version) < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + def sanity_check_step(self): """Custom sanity check paths for ifort.""" shlib_ext = get_shared_lib_ext() - binprefix = 'bin/intel64' + binprefix = 'bin' + binfiles = ['ifort'] + binaries = [os.path.join(binprefix, f) for f in binfiles] + libprefix = 'lib/intel64' - if LooseVersion(self.version) >= LooseVersion('2011'): - if LooseVersion(self.version) <= LooseVersion('2011.3.174'): - binprefix = 'bin' - elif LooseVersion(self.version) >= LooseVersion('2013_sp1'): - binprefix = 'bin' - else: - libprefix = 'compiler/lib/intel64' - - bins = ['ifort'] - if LooseVersion(self.version) < LooseVersion('2013'): - # idb is not shipped with ifort anymore in 2013.x versions (it is with icc though) - bins.append('idb') - - libs = ['lib%s' % lib for lib in ['ifcore.a', 'ifcore.%s' % shlib_ext, 'iomp5.a', 'iomp5.%s' % shlib_ext]] + libfiles = [f'lib{lib}' for lib in ['ifcore.a', f'ifcore.{shlib_ext}', 'iomp5.a', f'iomp5.{shlib_ext}']] + libraries = [os.path.join(libprefix, f) for f in libfiles] + custom_paths = { - 'files': [os.path.join(binprefix, x) for x in bins] + [os.path.join(libprefix, lib) for lib in libs], + 'files': binaries + libraries, 'dirs': [], } @@ -87,8 +89,7 @@ def make_module_req_guess(self): Additional paths to consider for prepend-paths statements in module file """ guesses = super(EB_ifort, self).make_module_req_guess() - if LooseVersion(self.version) >= LooseVersion('2016'): - # This enables the creation of fortran 2008 bindings in MPI - guesses['CPATH'].append('include') + # This enables the creation of fortran 2008 bindings in MPI + guesses['CPATH'].append('include') return guesses diff --git a/easybuild/easyblocks/i/imkl.py b/easybuild/easyblocks/i/imkl.py index eebbb6081f..87f7bcb92d 100644 --- a/easybuild/easyblocks/i/imkl.py +++ b/easybuild/easyblocks/i/imkl.py @@ -43,7 +43,7 @@ import easybuild.tools.environment as env import easybuild.tools.toolchain as toolchain -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option @@ -56,7 +56,7 @@ class EB_imkl(IntelBase): """ Class that can be used to install mkl - - tested with 10.2.1.017 + - minimum version suported: 2020.x -- will fail for all older versions (due to newer silent installer) """ @@ -73,6 +73,10 @@ def extra_options(): def __init__(self, *args, **kwargs): """Constructor for imkl easyblock.""" super(EB_imkl, self).__init__(*args, **kwargs) + if LooseVersion(self.version) < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) # make sure $MKLROOT isn't set, it's known to cause problems with the installation self.cfg.update('unwanted_env_vars', ['MKLROOT']) @@ -103,17 +107,12 @@ def mkl_basedir(self, path): def prepare_step(self, *args, **kwargs): """Prepare build environment.""" - if LooseVersion(self.version) >= LooseVersion('2017.2.174'): - kwargs['requires_runtime_license'] = False - super(EB_imkl, self).prepare_step(*args, **kwargs) - else: - super(EB_imkl, self).prepare_step(*args, **kwargs) + kwargs['requires_runtime_license'] = False + super(EB_imkl, self).prepare_step(*args, **kwargs) # build the mkl interfaces, if desired if self.cfg['interfaces']: - self.cdftlibs = ['fftw2x_cdft'] - if LooseVersion(self.version) >= LooseVersion('10.3'): - self.cdftlibs.append('fftw3x_cdft') + self.cdftlibs = ['fftw2x_cdft', 'fftw3x_cdft'] # check whether MPI_FAMILY constant is defined, so mpi_family() can be used if hasattr(self.toolchain, 'MPI_FAMILY') and self.toolchain.MPI_FAMILY is not None: mpi_spec_by_fam = { @@ -146,45 +145,22 @@ def install_step(self): - create silent cfg file - execute command """ - silent_cfg_names_map = None silent_cfg_extras = None - - if LooseVersion(self.version) < LooseVersion('11.1'): - # since imkl v11.1, silent.cfg has been slightly changed to be 'more standard' - - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - if LooseVersion(self.version) >= LooseVersion('11.1') and self.install_components is None: + if self.install_components is None: silent_cfg_extras = { 'COMPONENTS': 'ALL', } - - super(EB_imkl, self).install_step( - silent_cfg_names_map=silent_cfg_names_map, - silent_cfg_extras=silent_cfg_extras) + super(EB_imkl, self).install_step(silent_cfg_extras=silent_cfg_extras) def build_mkl_fftw_interfaces(self, libdir): """Build the Intel MKL FFTW interfaces.""" - mkdir(libdir) - loosever = LooseVersion(self.version) - - if loosever >= LooseVersion('10.3'): - intsubdir = self.mkl_basedir - if loosever >= LooseVersion('2024'): - intsubdir = os.path.join(intsubdir, 'share', 'mkl') - intsubdir = os.path.join(intsubdir, 'interfaces') - inttarget = 'libintel64' - else: - intsubdir = 'interfaces' - if self.cfg['m32']: - inttarget = 'lib32' - else: - inttarget = 'libem64t' + intsubdir = self.mkl_basedir + if LooseVersion(self.version) >= LooseVersion('2024'): + intsubdir = os.path.join(intsubdir, 'share', 'mkl') + intsubdir = os.path.join(intsubdir, 'interfaces') + inttarget = 'libintel64' cmd = "make -f makefile %s" % inttarget @@ -259,12 +235,12 @@ def build_mkl_fftw_interfaces(self, libdir): buildopts.append('mpi=%s' % self.mpi_spec) precflags = [''] - if lib.startswith('fftw2x') and not self.cfg['m32']: + if lib.startswith('fftw2x'): # build both single and double precision variants precflags = ['PRECISION=MKL_DOUBLE', 'PRECISION=MKL_SINGLE'] intflags = [''] - if lib in self.cdftlibs and not self.cfg['m32']: + if lib in self.cdftlibs: # build both 32-bit and 64-bit interfaces intflags = ['interface=lp64', 'interface=ilp64'] @@ -367,35 +343,16 @@ def post_processing_step(self): shlib_ext = get_shared_lib_ext() - if self.cfg['m32']: - extra = { - 'libmkl.%s' % shlib_ext: 'GROUP (-lmkl_intel -lmkl_intel_thread -lmkl_core)', - 'libmkl_em64t.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)', - 'libmkl_solver.a': 'GROUP (libmkl_solver.a)', - 'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_core.a)', - 'libmkl_lapack.a': 'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)', - 'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)' - } - else: - extra = { - 'libmkl.%s' % shlib_ext: 'GROUP (-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core)', - 'libmkl_em64t.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', - 'libmkl_solver.a': 'GROUP (libmkl_solver_lp64.a)', - 'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_lp64.a)', - 'libmkl_lapack.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', - 'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)' - } - - loosever = LooseVersion(self.version) - - if loosever >= LooseVersion('10.3'): - libsubdir = os.path.join(self.mkl_basedir, 'lib', 'intel64') - else: - if self.cfg['m32']: - libsubdir = os.path.join('lib', '32') - else: - libsubdir = os.path.join('lib', 'em64t') + extra = { + 'libmkl.%s' % shlib_ext: 'GROUP (-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core)', + 'libmkl_em64t.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', + 'libmkl_solver.a': 'GROUP (libmkl_solver_lp64.a)', + 'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_lp64.a)', + 'libmkl_lapack.a': 'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)', + 'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)' + } + libsubdir = os.path.join(self.mkl_basedir, 'lib', 'intel64') libdir = os.path.join(self.installdir, libsubdir) for fil, txt in extra.items(): dest = os.path.join(libdir, fil) @@ -425,28 +382,15 @@ def get_mkl_fftw_interface_libs(self): "don't know compiler suffix for FFTW libraries.") precs = ['_double', '_single'] - ver = LooseVersion(self.version) - if ver < LooseVersion('11'): - # no precision suffix in libfftw2 libs before imkl v11 - precs = [''] - fftw_vers = ['2x%s%s' % (x, prec) for x in ['c', 'f'] for prec in precs] + ['3xc', '3xf'] + fftw_vers = [f'2x{x}{prec}' for x in ['c', 'f'] for prec in precs] + ['3xc', '3xf'] + pics = ['', '_pic'] - libs = ['libfftw%s%s%s.a' % (fftwver, compsuff, pic) for fftwver in fftw_vers for pic in pics] + libs = [f'libfftw{fftwver}{compsuff}{pic}.a' for fftwver in fftw_vers for pic in pics] if self.cdftlibs: - fftw_cdft_vers = ['2x_cdft_DOUBLE'] - if not self.cfg['m32']: - fftw_cdft_vers.append('2x_cdft_SINGLE') - if ver >= LooseVersion('10.3'): - fftw_cdft_vers.append('3x_cdft') - if ver >= LooseVersion('11.0.2'): - bits = ['_lp64'] - if not self.cfg['m32']: - bits.append('_ilp64') - else: - # no bits suffix in cdft libs before imkl v11.0.2 - bits = [''] - libs += ['libfftw%s%s%s.a' % x for x in itertools.product(fftw_cdft_vers, bits, pics)] + fftw_cdft_vers = ['2x_cdft_DOUBLE', '2x_cdft_SINGLE', '3x_cdft'] + bits = ['_lp64', '_ilp64'] + libs += [f'libfftw{x[0]}{x[1]}{x[2]}.a' for x in itertools.product(fftw_cdft_vers, bits, pics)] return libs @@ -456,7 +400,6 @@ def sanity_check_step(self): mklfiles = None mkldirs = None - ver = LooseVersion(self.version) libs = ['libmkl_core.%s' % shlib_ext, 'libmkl_gnu_thread.%s' % shlib_ext, 'libmkl_intel_thread.%s' % shlib_ext, 'libmkl_sequential.%s' % shlib_ext] extralibs = ['libmkl_blacs_intelmpi_%(suff)s.' + shlib_ext, 'libmkl_scalapack_%(suff)s.' + shlib_ext] @@ -468,50 +411,21 @@ def sanity_check_step(self): libs += [os.path.join('flexiblas', 'libflexiblas_imkl_%s.so' % thread) for thread in ['gnu_thread', 'intel_thread', 'sequential']] - if ver >= LooseVersion('10.3') and self.cfg['m32']: - raise EasyBuildError("Sanity check for 32-bit not implemented yet for IMKL v%s (>= 10.3)", self.version) + mkldirs = [ + os.path.join(self.mkl_basedir, 'bin'), + os.path.join(self.mkl_basedir, 'lib', 'intel64'), + os.path.join(self.mkl_basedir, 'include'), + ] + libs += [lib % {'suff': suff} for lib in extralibs for suff in ['lp64', 'ilp64']] - if ver >= LooseVersion('10.3'): - mkldirs = [ - os.path.join(self.mkl_basedir, 'bin'), - os.path.join(self.mkl_basedir, 'lib', 'intel64'), - os.path.join(self.mkl_basedir, 'include'), - ] - libs += [lib % {'suff': suff} for lib in extralibs for suff in ['lp64', 'ilp64']] - - mklfiles = [os.path.join(self.mkl_basedir, 'include', 'mkl.h')] - mklfiles.extend([os.path.join(self.mkl_basedir, 'lib', 'intel64', lib) for lib in libs]) - - if ver >= LooseVersion('2021'): + mklfiles = [os.path.join(self.mkl_basedir, 'include', 'mkl.h')] + mklfiles.extend([os.path.join(self.mkl_basedir, 'lib', 'intel64', lib) for lib in libs]) + if LooseVersion(self.version) >= LooseVersion('2021'): mklfiles.append(os.path.join(self.mkl_basedir, 'lib', 'intel64', 'libmkl_core.%s' % shlib_ext)) - - elif ver >= LooseVersion('10.3'): - if ver < LooseVersion('11.3'): - mkldirs.append(os.path.join(self.mkl_basedir, 'bin', 'intel64')) - - mklfiles.append(os.path.join(self.mkl_basedir, 'lib', 'intel64', 'libmkl.%s' % shlib_ext)) - - if ver >= LooseVersion('10.3.4') and ver < LooseVersion('11.1'): - mkldirs += [os.path.join('compiler', 'lib', 'intel64')] - elif ver >= LooseVersion('2017.0.0'): - mkldirs += [os.path.join('lib', 'intel64_lin')] - else: - mkldirs += [os.path.join('lib', 'intel64')] - else: - if self.cfg['m32']: - lib_subdir = '32' - else: - lib_subdir = 'em64t' - libs += [lib % {'suff': suff} for lib in extralibs for suff in ['lp64', 'ilp64']] - - mklfiles = [ - os.path.join('lib', lib_subdir, 'libmkl.%s' % shlib_ext), - os.path.join('include', 'mkl.h'), - ] - mklfiles.extend([os.path.join('lib', lib_subdir, lib) for lib in libs]) - mkldirs = [os.path.join('lib', lib_subdir), os.path.join('include', lib_subdir), 'interfaces'] + mklfiles.append(os.path.join(self.mkl_basedir, 'lib', 'intel64', 'libmkl.%s' % shlib_ext)) + mkldirs += [os.path.join('lib', 'intel64_lin')] custom_paths = { 'files': mklfiles, @@ -526,69 +440,37 @@ def make_module_req_guess(self): """ guesses = super(EB_imkl, self).make_module_req_guess() - if LooseVersion(self.version) >= LooseVersion('10.3'): - if self.cfg['m32']: - raise EasyBuildError("32-bit not supported yet for IMKL v%s (>= 10.3)", self.version) - else: - if LooseVersion(self.version) >= LooseVersion('2021'): - compiler_subdir = os.path.join(self.get_versioned_subdir('compiler'), self.compiler_libdir) - pkg_config_path = [os.path.join(self.mkl_basedir, 'tools', 'pkgconfig'), - os.path.join(self.mkl_basedir, 'lib', 'pkgconfig')] - else: - compiler_subdir = os.path.join('lib', 'intel64') - pkg_config_path = [os.path.join(self.mkl_basedir, 'bin', 'pkgconfig')] - guesses['MANPATH'] = ['man', os.path.join('man', 'en_US')] - if LooseVersion(self.version) >= LooseVersion('11.0'): - if LooseVersion(self.version) >= LooseVersion('11.3'): - guesses['MIC_LD_LIBRARY_PATH'] = [ - os.path.join('lib', 'intel64_lin_mic'), - os.path.join(self.mkl_basedir, 'lib', 'mic'), - ] - elif LooseVersion(self.version) >= LooseVersion('11.1'): - guesses['MIC_LD_LIBRARY_PATH'] = [ - os.path.join('lib', 'mic'), - os.path.join(self.mkl_basedir, 'lib', 'mic'), - ] - else: - guesses['MIC_LD_LIBRARY_PATH'] = [ - os.path.join('compiler', 'lib', 'mic'), - os.path.join(self.mkl_basedir, 'lib', 'mic'), - ] - library_path = [ - compiler_subdir, - os.path.join(self.mkl_basedir, 'lib', 'intel64'), - ] - cpath = [ - os.path.join(self.mkl_basedir, 'include'), - os.path.join(self.mkl_basedir, 'include', 'fftw'), - ] - cmake_prefix_path = [self.mkl_basedir] - guesses.update({ - 'PATH': [], - 'LD_LIBRARY_PATH': library_path, - 'LIBRARY_PATH': library_path, - 'CPATH': cpath, - 'CMAKE_PREFIX_PATH': cmake_prefix_path, - 'PKG_CONFIG_PATH': pkg_config_path, - }) - if self.cfg['flexiblas']: - guesses['FLEXIBLAS_LIBRARY_PATH'] = os.path.join(library_path[1], 'flexiblas') + if LooseVersion(self.version) >= LooseVersion('2021'): + compiler_subdir = os.path.join(self.get_versioned_subdir('compiler'), self.compiler_libdir) + pkg_config_path = [os.path.join(self.mkl_basedir, 'tools', 'pkgconfig'), + os.path.join(self.mkl_basedir, 'lib', 'pkgconfig')] else: - if self.cfg['m32']: - guesses.update({ - 'PATH': ['bin', 'bin/ia32', 'tbb/bin/ia32'], - 'LD_LIBRARY_PATH': ['lib', 'lib/32'], - 'LIBRARY_PATH': ['lib', 'lib/32'], - 'MANPATH': ['man', 'share/man', 'man/en_US'], - }) - - else: - guesses.update({ - 'PATH': ['bin', 'bin/intel64', 'tbb/bin/em64t'], - 'LD_LIBRARY_PATH': ['lib', 'lib/em64t'], - 'LIBRARY_PATH': ['lib', 'lib/em64t'], - 'MANPATH': ['man', 'share/man', 'man/en_US'], - }) + compiler_subdir = os.path.join('lib', 'intel64') + pkg_config_path = [os.path.join(self.mkl_basedir, 'bin', 'pkgconfig')] + guesses['MANPATH'] = ['man', os.path.join('man', 'en_US')] + guesses['MIC_LD_LIBRARY_PATH'] = [ + os.path.join('lib', 'intel64_lin_mic'), + os.path.join(self.mkl_basedir, 'lib', 'mic'), + ] + library_path = [ + compiler_subdir, + os.path.join(self.mkl_basedir, 'lib', 'intel64'), + ] + cpath = [ + os.path.join(self.mkl_basedir, 'include'), + os.path.join(self.mkl_basedir, 'include', 'fftw'), + ] + cmake_prefix_path = [self.mkl_basedir] + guesses.update({ + 'PATH': [], + 'LD_LIBRARY_PATH': library_path, + 'LIBRARY_PATH': library_path, + 'CPATH': cpath, + 'CMAKE_PREFIX_PATH': cmake_prefix_path, + 'PKG_CONFIG_PATH': pkg_config_path, + }) + if self.cfg['flexiblas']: + guesses['FLEXIBLAS_LIBRARY_PATH'] = os.path.join(library_path[1], 'flexiblas') return guesses def make_module_extra(self): diff --git a/easybuild/easyblocks/i/impi.py b/easybuild/easyblocks/i/impi.py index 429ea36139..8871a25043 100644 --- a/easybuild/easyblocks/i/impi.py +++ b/easybuild/easyblocks/i/impi.py @@ -38,11 +38,11 @@ from easybuild.tools import LooseVersion import easybuild.tools.toolchain as toolchain -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option -from easybuild.tools.filetools import apply_regex_substitutions, change_dir, extract_file, mkdir, write_file +from easybuild.tools.filetools import apply_regex_substitutions, change_dir, extract_file from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_shell_cmd from easybuild.tools.systemtools import get_shared_lib_ext @@ -52,6 +52,7 @@ class EB_impi(IntelBase): """ Support for installing Intel MPI library + - minimum version suported: 2018.x """ @staticmethod def extra_options(): @@ -67,11 +68,8 @@ def extra_options(): return IntelBase.extra_options(extra_vars) def prepare_step(self, *args, **kwargs): - if LooseVersion(self.version) >= LooseVersion('2017.2.174'): - kwargs['requires_runtime_license'] = False - super(EB_impi, self).prepare_step(*args, **kwargs) - else: - super(EB_impi, self).prepare_step(*args, **kwargs) + kwargs['requires_runtime_license'] = False + super(EB_impi, self).prepare_step(*args, **kwargs) def install_step(self): """ @@ -81,59 +79,19 @@ def install_step(self): """ impiver = LooseVersion(self.version) + if impiver < LooseVersion('2018'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2018.0." + ) + if impiver >= LooseVersion('2021'): super(EB_impi, self).install_step() - - elif impiver >= LooseVersion('4.0.1'): + else: # impi starting from version 4.0.1.x uses standard installation procedure. - silent_cfg_names_map = {} - - if impiver < LooseVersion('4.1.1'): - # since impi v4.1.1, silent.cfg has been slightly changed to be 'more standard' - silent_cfg_names_map.update({ - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - }) - super(EB_impi, self).install_step(silent_cfg_names_map=silent_cfg_names_map) - - # impi v4.1.1 and v5.0.1 installers create impi/ subdir, so stuff needs to be moved afterwards - if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'): - super(EB_impi, self).move_after_install() - else: - # impi up until version 4.0.0.x uses custom installation procedure. - silent = """[mpi] -INSTALLDIR=%(ins)s -LICENSEPATH=%(lic)s -INSTALLMODE=NONRPM -INSTALLUSER=NONROOT -UPDATE_LD_SO_CONF=NO -PROCEED_WITHOUT_PYTHON=yes -AUTOMOUNTED_CLUSTER=yes -EULA=accept -[mpi-rt] -INSTALLDIR=%(ins)s -LICENSEPATH=%(lic)s -INSTALLMODE=NONRPM -INSTALLUSER=NONROOT -UPDATE_LD_SO_CONF=NO -PROCEED_WITHOUT_PYTHON=yes -AUTOMOUNTED_CLUSTER=yes -EULA=accept - -""" % {'lic': self.license_file, 'ins': self.installdir} - - # already in correct directory - silentcfg = os.path.join(os.getcwd(), "silent.cfg") - write_file(silentcfg, silent) - self.log.debug("Contents of %s: %s", silentcfg, silent) - - tmpdir = os.path.join(os.getcwd(), self.version, 'mytmpdir') - mkdir(tmpdir, parents=True) - - cmd = "./install.sh --tmp-dir=%s --silent=%s" % (tmpdir, silentcfg) - run_shell_cmd(cmd) + # since v5.0.1 installers create impi/ subdir, so stuff needs to be moved afterwards + super(EB_impi, self).move_after_install() # recompile libfabric (if requested) # some Intel MPI versions (like 2019 update 6) no longer ship libfabric sources @@ -152,9 +110,9 @@ def install_step(self): make += ' -j %d' % self.cfg['parallel'] cmds = [ - './configure --prefix=%s %s' % (libfabric_installpath, self.cfg['libfabric_configopts']), + f"./configure --prefix={libfabric_installpath} {self.cfg['libfabric_configopts']}", make, - 'make install' + "make install", ] for cmd in cmds: run_shell_cmd(cmd) @@ -172,12 +130,8 @@ def post_processing_step(self): if impiver >= LooseVersion('2021'): self.log.info("No post-install action for impi v%s", self.version) - - elif impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'): - if impiver >= LooseVersion('2018.0.128'): - script_paths = [os.path.join('intel64', 'bin')] - else: - script_paths = [os.path.join('intel64', 'bin'), os.path.join('mic', 'bin')] + else: + script_paths = [os.path.join('intel64', 'bin')] # fix broken env scripts after the move regex_subs = [(r"^setenv I_MPI_ROOT.*", r"setenv I_MPI_ROOT %s" % self.installdir)] for script in [os.path.join(script_path, 'mpivars.csh') for script_path in script_paths]: @@ -201,12 +155,8 @@ def sanity_check_step(self): impi_ver = LooseVersion(self.version) suff = '64' - if self.cfg['m32']: - suff = '' - mpi_mods = ['mpi.mod'] - if impi_ver > LooseVersion('4.0'): - mpi_mods.extend(['mpi_base.mod', 'mpi_constants.mod', 'mpi_sizeofs.mod']) + mpi_mods = ['mpi.mod', 'mpi_base.mod', 'mpi_constants.mod', 'mpi_sizeofs.mod'] if impi_ver >= LooseVersion('2021'): mpi_subdir = self.get_versioned_subdir('mpi') @@ -215,7 +165,6 @@ def sanity_check_step(self): lib_dir = os.path.join(mpi_subdir, 'lib') if impi_ver < LooseVersion('2021.11'): lib_dir = os.path.join(lib_dir, 'release') - elif impi_ver >= LooseVersion('2019'): bin_dir = os.path.join('intel64', 'bin') include_dir = os.path.join('intel64', 'include') @@ -243,39 +192,38 @@ def sanity_check_step(self): custom_commands = [] if build_option('mpi_tests'): - if impi_ver >= LooseVersion('2017'): - # Add minimal test program to sanity checks - if build_option('sanity_check_only'): - # When only running the sanity check we need to manually make sure that - # variables for compilers and parallelism have been set - self.set_parallel() - self.prepare_step(start_dir=False) - - impi_testexe = os.path.join(tempfile.mkdtemp(), 'mpi_test') - else: - impi_testexe = os.path.join(self.builddir, 'mpi_test') + # Add minimal test program to sanity checks + if build_option('sanity_check_only'): + # When only running the sanity check we need to manually make sure that + # variables for compilers and parallelism have been set + self.set_parallel() + self.prepare_step(start_dir=False) + + impi_testexe = os.path.join(tempfile.mkdtemp(), 'mpi_test') + else: + impi_testexe = os.path.join(self.builddir, 'mpi_test') - if impi_ver >= LooseVersion('2021'): - impi_testsrc = os.path.join(self.installdir, self.get_versioned_subdir('mpi')) - if impi_ver >= LooseVersion('2021.11'): - impi_testsrc = os.path.join(impi_testsrc, 'opt', 'mpi') - impi_testsrc = os.path.join(impi_testsrc, 'test', 'test.c') - else: - impi_testsrc = os.path.join(self.installdir, 'test', 'test.c') + if impi_ver >= LooseVersion('2021'): + impi_testsrc = os.path.join(self.installdir, self.get_versioned_subdir('mpi')) + if impi_ver >= LooseVersion('2021.11'): + impi_testsrc = os.path.join(impi_testsrc, 'opt', 'mpi') + impi_testsrc = os.path.join(impi_testsrc, 'test', 'test.c') + else: + impi_testsrc = os.path.join(self.installdir, 'test', 'test.c') - self.log.info("Adding minimal MPI test program to sanity checks: %s", impi_testsrc) + self.log.info("Adding minimal MPI test program to sanity checks: %s", impi_testsrc) - # Build test program with appropriate compiler from current toolchain - build_cmd = "mpicc -cc=%s %s -o %s" % (os.getenv('CC'), impi_testsrc, impi_testexe) + # Build test program with appropriate compiler from current toolchain + build_cmd = "mpicc -cc=%s %s -o %s" % (os.getenv('CC'), impi_testsrc, impi_testexe) - # Execute test program with appropriate MPI executable for target toolchain - params = {'nr_ranks': self.cfg['parallel'], 'cmd': impi_testexe} - mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.INTELMPI, params, mpi_version=self.version) + # Execute test program with appropriate MPI executable for target toolchain + params = {'nr_ranks': self.cfg['parallel'], 'cmd': impi_testexe} + mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.INTELMPI, params, mpi_version=self.version) - custom_commands.extend([ - build_cmd, # build test program - mpi_cmd_tmpl % params, # run test program - ]) + custom_commands.extend([ + build_cmd, # build test program + mpi_cmd_tmpl % params, # run test program + ]) super(EB_impi, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands) @@ -284,65 +232,56 @@ def make_module_req_guess(self): A dictionary of possible directories to look for """ guesses = super(EB_impi, self).make_module_req_guess() - if self.cfg['m32']: - lib_dirs = ['lib', 'lib/ia32', 'ia32/lib'] - guesses.update({ - 'PATH': ['bin', 'bin/ia32', 'ia32/bin'], - 'LD_LIBRARY_PATH': lib_dirs, - 'LIBRARY_PATH': lib_dirs, - 'MIC_LD_LIBRARY_PATH': ['mic/lib'], - }) - else: - manpath = 'man' + manpath = 'man' - impi_ver = LooseVersion(self.version) - if impi_ver >= LooseVersion('2021'): - mpi_subdir = self.get_versioned_subdir('mpi') - lib_dirs = [ - os.path.join(mpi_subdir, 'lib'), - os.path.join(mpi_subdir, 'libfabric', 'lib'), - ] - if impi_ver < LooseVersion('2021.11'): - lib_dirs.insert(1, os.path.join(mpi_subdir, 'lib', 'release')) - include_dirs = [os.path.join(mpi_subdir, 'include')] - path_dirs = [ - os.path.join(mpi_subdir, 'bin'), - os.path.join(mpi_subdir, 'libfabric', 'bin'), - ] - if impi_ver >= LooseVersion('2021.11'): - manpath = os.path.join(mpi_subdir, 'share', 'man') - else: - manpath = os.path.join(mpi_subdir, 'man') - - if self.cfg['ofi_internal']: - libfabric_dir = os.path.join(mpi_subdir, 'libfabric') - lib_dirs.append(os.path.join(libfabric_dir, 'lib')) - path_dirs.append(os.path.join(libfabric_dir, 'bin')) - guesses['FI_PROVIDER_PATH'] = [os.path.join(libfabric_dir, 'lib', 'prov')] - - elif impi_ver >= LooseVersion('2019'): - # The "release" library is default in v2019. Give it precedence over intel64/lib. - # (remember paths are *prepended*, so the last path in the list has highest priority) - lib_dirs = [os.path.join('intel64', x) for x in ['lib', os.path.join('lib', 'release')]] - include_dirs = [os.path.join('intel64', 'include')] - path_dirs = [os.path.join('intel64', 'bin')] - if self.cfg['ofi_internal']: - lib_dirs.append(os.path.join('intel64', 'libfabric', 'lib')) - path_dirs.append(os.path.join('intel64', 'libfabric', 'bin')) - guesses['FI_PROVIDER_PATH'] = [os.path.join('intel64', 'libfabric', 'lib', 'prov')] + impi_ver = LooseVersion(self.version) + if impi_ver >= LooseVersion('2021'): + mpi_subdir = self.get_versioned_subdir('mpi') + lib_dirs = [ + os.path.join(mpi_subdir, 'lib'), + os.path.join(mpi_subdir, 'libfabric', 'lib'), + ] + if impi_ver < LooseVersion('2021.11'): + lib_dirs.insert(1, os.path.join(mpi_subdir, 'lib', 'release')) + include_dirs = [os.path.join(mpi_subdir, 'include')] + path_dirs = [ + os.path.join(mpi_subdir, 'bin'), + os.path.join(mpi_subdir, 'libfabric', 'bin'), + ] + if impi_ver >= LooseVersion('2021.11'): + manpath = os.path.join(mpi_subdir, 'share', 'man') else: - lib_dirs = [os.path.join('lib', 'em64t'), 'lib64'] - include_dirs = ['include64'] - path_dirs = [os.path.join('bin', 'intel64'), 'bin64'] - guesses['MIC_LD_LIBRARY_PATH'] = [os.path.join('mic', 'lib')] - - guesses.update({ - 'PATH': path_dirs, - 'LD_LIBRARY_PATH': lib_dirs, - 'LIBRARY_PATH': lib_dirs, - 'MANPATH': [manpath], - 'CPATH': include_dirs, - }) + manpath = os.path.join(mpi_subdir, 'man') + + if self.cfg['ofi_internal']: + libfabric_dir = os.path.join(mpi_subdir, 'libfabric') + lib_dirs.append(os.path.join(libfabric_dir, 'lib')) + path_dirs.append(os.path.join(libfabric_dir, 'bin')) + guesses['FI_PROVIDER_PATH'] = [os.path.join(libfabric_dir, 'lib', 'prov')] + + elif impi_ver >= LooseVersion('2019'): + # The "release" library is default in v2019. Give it precedence over intel64/lib. + # (remember paths are *prepended*, so the last path in the list has highest priority) + lib_dirs = [os.path.join('intel64', x) for x in ['lib', os.path.join('lib', 'release')]] + include_dirs = [os.path.join('intel64', 'include')] + path_dirs = [os.path.join('intel64', 'bin')] + if self.cfg['ofi_internal']: + lib_dirs.append(os.path.join('intel64', 'libfabric', 'lib')) + path_dirs.append(os.path.join('intel64', 'libfabric', 'bin')) + guesses['FI_PROVIDER_PATH'] = [os.path.join('intel64', 'libfabric', 'lib', 'prov')] + else: + lib_dirs = [os.path.join('lib', 'em64t'), 'lib64'] + include_dirs = ['include64'] + path_dirs = [os.path.join('bin', 'intel64'), 'bin64'] + guesses['MIC_LD_LIBRARY_PATH'] = [os.path.join('mic', 'lib')] + + guesses.update({ + 'PATH': path_dirs, + 'LD_LIBRARY_PATH': lib_dirs, + 'LIBRARY_PATH': lib_dirs, + 'MANPATH': [manpath], + 'CPATH': include_dirs, + }) return guesses diff --git a/easybuild/easyblocks/i/inspector.py b/easybuild/easyblocks/i/inspector.py index 7d7ddbf062..c79b88cb6b 100644 --- a/easybuild/easyblocks/i/inspector.py +++ b/easybuild/easyblocks/i/inspector.py @@ -31,24 +31,29 @@ import os from easybuild.tools import LooseVersion -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase +from easybuild.tools.build_log import EasyBuildError class EB_Inspector(IntelBase): """ Support for installing Intel Inspector + - minimum version suported: 2020.x """ def __init__(self, *args, **kwargs): """Easyblock constructor; define class variables.""" super(EB_Inspector, self).__init__(*args, **kwargs) + loosever = LooseVersion(self.version) + if loosever < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + # recent versions of Inspector are installed to a subdirectory self.subdir = '' - loosever = LooseVersion(self.version) - if loosever >= LooseVersion('2013_update7') and loosever < LooseVersion('2017'): - self.subdir = 'inspector_xe' - elif loosever >= LooseVersion('2017') and loosever < LooseVersion('2021'): + if loosever < LooseVersion('2021'): self.subdir = 'inspector' elif loosever >= LooseVersion('2021'): self.subdir = os.path.join('inspector', 'latest') @@ -57,22 +62,6 @@ def make_installdir(self): """Do not create installation directory, install script handles that already.""" super(EB_Inspector, self).make_installdir(dontcreate=True) - def install_step(self): - """ - Actual installation - - create silent cfg file - - execute command - """ - silent_cfg_names_map = None - - if LooseVersion(self.version) <= LooseVersion('2013_update6'): - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - super(EB_Inspector, self).install_step(silent_cfg_names_map=silent_cfg_names_map) - def make_module_req_guess(self): """Find reasonable paths for Inspector""" return self.get_guesses_tools() diff --git a/easybuild/easyblocks/i/ipp.py b/easybuild/easyblocks/i/ipp.py deleted file mode 100644 index d39c55b07b..0000000000 --- a/easybuild/easyblocks/i/ipp.py +++ /dev/null @@ -1,129 +0,0 @@ -## -# Copyright 2009-2024 Ghent University -# -# This file is part of EasyBuild, -# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), -# with support of Ghent University (http://ugent.be/hpc), -# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), -# Flemish Research Foundation (FWO) (http://www.fwo.be/en) -# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). -# -# https://github.com/easybuilders/easybuild -# -# EasyBuild is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation v2. -# -# EasyBuild is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with EasyBuild. If not, see . -## -""" -EasyBuild support for installing the Intel Performance Primitives (IPP) library, implemented as an easyblock - -@author: Stijn De Weirdt (Ghent University) -@author: Dries Verdegem (Ghent University) -@author: Kenneth Hoste (Ghent University) -@author: Pieter De Baets (Ghent University) -@author: Jens Timmerman (Ghent University) -@author: Lumir Jasiok (IT4Innovations) -@author: Damian Alvarez (Forschungszentrum Juelich GmbH) -""" - -from easybuild.tools import LooseVersion -import os - -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 -from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.systemtools import get_platform_name -from easybuild.tools.systemtools import get_shared_lib_ext - - -class EB_ipp(IntelBase): - """ - Support for installing Intel Integrated Performance Primitives library - """ - - def install_step(self): - """ - Actual installation - - create silent cfg file - - execute command - """ - - platform_name = get_platform_name() - if platform_name.startswith('x86_64'): - self.arch = "intel64" - elif platform_name.startswith('i386') or platform_name.startswith('i686'): - self.arch = 'ia32' - else: - raise EasyBuildError("Failed to determine system architecture based on %s", platform_name) - - silent_cfg_names_map = None - silent_cfg_extras = None - - if LooseVersion(self.version) < LooseVersion('8.0'): - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - # in case of IPP 9.x, we have to specify ARCH_SELECTED in silent.cfg - if LooseVersion(self.version) >= LooseVersion('9.0'): - silent_cfg_extras = { - 'ARCH_SELECTED': self.arch.upper() - } - - super(EB_ipp, self).install_step(silent_cfg_names_map=silent_cfg_names_map, silent_cfg_extras=silent_cfg_extras) - - def sanity_check_step(self): - """Custom sanity check paths for IPP.""" - shlib_ext = get_shared_lib_ext() - - dirs = [os.path.join('ipp', x) for x in ['bin', 'include', os.path.join('tools', 'intel64')]] - if LooseVersion(self.version) < LooseVersion('8.0'): - dirs.extend([ - os.path.join('compiler', 'lib', 'intel64'), - os.path.join('ipp', 'interfaces', 'data-compression'), - ]) - elif LooseVersion(self.version) < LooseVersion('9.0'): - dirs.extend([ - os.path.join('composerxe', 'lib', 'intel64'), - ]) - - ipp_libs = ['cc', 'ch', 'core', 'cv', 'dc', 'i', 's', 'vm'] - if LooseVersion(self.version) < LooseVersion('9.0'): - ipp_libs.extend(['ac', 'di', 'j', 'm', 'r', 'sc', 'vc']) - - custom_paths = { - 'files': [ - os.path.join('ipp', 'lib', 'intel64', 'libipp%s') % y for x in ipp_libs - for y in ['%s.a' % x, '%s.%s' % (x, shlib_ext)] - ], - 'dirs': dirs, - } - - super(EB_ipp, self).sanity_check_step(custom_paths=custom_paths) - - def make_module_req_guess(self): - """ - A dictionary of possible directories to look for - """ - guesses = super(EB_ipp, self).make_module_req_guess() - - if LooseVersion(self.version) >= LooseVersion('9.0'): - lib_path = [os.path.join('ipp', 'lib', self.arch), os.path.join('lib', self.arch)] - include_path = os.path.join('ipp', 'include') - - guesses.update({ - 'LD_LIBRARY_PATH': lib_path, - 'LIBRARY_PATH': lib_path, - 'CPATH': [include_path], - 'INCLUDE': [include_path], - }) - - return guesses diff --git a/easybuild/easyblocks/i/itac.py b/easybuild/easyblocks/i/itac.py index e39481af4a..6261ab2cfa 100644 --- a/easybuild/easyblocks/i/itac.py +++ b/easybuild/easyblocks/i/itac.py @@ -32,8 +32,6 @@ @author: Jens Timmerman (Ghent University) """ -import os - from easybuild.tools import LooseVersion from easybuild.easyblocks.generic.intelbase import IntelBase @@ -45,7 +43,7 @@ class EB_itac(IntelBase): """ Class that can be used to install itac - - tested with Intel Trace Analyzer and Collector 7.2.1.008 + - minimum version suported: 2019.x """ @staticmethod @@ -55,6 +53,15 @@ def extra_options(): } return IntelBase.extra_options(extra_vars) + def __init__(self, *args, **kwargs): + """Constructor, initialize class variables.""" + super().__init__(*args, **kwargs) + + if LooseVersion(self.version) < LooseVersion('2019'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2019.0." + ) + def prepare_step(self, *args, **kwargs): """ Custom prepare step for itac: don't require runtime license for oneAPI versions (>= 2021) @@ -71,42 +78,9 @@ def install_step_classic(self): - create silent cfg file - execute command """ - - if LooseVersion(self.version) >= LooseVersion('8.1'): - super(EB_itac, self).install_step_classic(silent_cfg_names_map=None) - - # itac v9.0.1 installer create itac/ subdir, so stuff needs to be moved afterwards - if LooseVersion(self.version) >= LooseVersion('9.0'): - super(EB_itac, self).move_after_install() - else: - silent = """ -[itac] -INSTALLDIR=%(ins)s -LICENSEPATH=%(lic)s -INSTALLMODE=NONRPM -INSTALLUSER=NONROOT -INSTALL_ITA=YES -INSTALL_ITC=YES -DEFAULT_MPI=%(mpi)s -EULA=accept -""" % {'lic': self.license_file, 'ins': self.installdir, 'mpi': self.cfg['preferredmpi']} - - # already in correct directory - silentcfg = os.path.join(os.getcwd(), "silent.cfg") - f = open(silentcfg, 'w') - f.write(silent) - f.close() - self.log.debug("Contents of %s: %s" % (silentcfg, silent)) - - tmpdir = os.path.join(os.getcwd(), self.version, 'mytmpdir') - try: - os.makedirs(tmpdir) - except OSError as err: - raise EasyBuildError("Directory %s can't be created: %s", tmpdir, err) - - cmd = "./install.sh --tmp-dir=%s --silent=%s" % (tmpdir, silentcfg) - - run_shell_cmd(cmd) + super(EB_itac, self).install_step_classic(silent_cfg_names_map=None) + # since itac v9.0.1 installer create itac/ subdir, so stuff needs to be moved afterwards + super(EB_itac, self).move_after_install() def install_step_oneapi(self, *args, **kwargs): """ @@ -150,26 +124,10 @@ def make_module_req_guess(self): """ A dictionary of possible directories to look for """ - guesses = {} - if LooseVersion(self.version) < LooseVersion('9.0'): - preferredmpi = self.cfg["preferredmpi"] - guesses.update({ - 'MANPATH': ['man'], - 'CLASSPATH': ['itac/lib_%s' % preferredmpi], - 'VT_LIB_DIR': ['itac/lib_%s' % preferredmpi], - 'VT_SLIB_DIR': ['itac/lib_s%s' % preferredmpi] - }) - - if self.cfg['m32']: - guesses.update({ - 'PATH': ['bin', 'bin/ia32', 'ia32/bin'], - 'LD_LIBRARY_PATH': ['lib', 'lib/ia32', 'ia32/lib'], - }) - else: - guesses.update({ - 'PATH': ['bin', 'bin/intel64', 'bin64'], - 'LD_LIBRARY_PATH': ['lib', 'lib/intel64', 'lib64', 'slib'], - }) + guesses = { + 'PATH': ['bin', 'bin/intel64', 'bin64'], + 'LD_LIBRARY_PATH': ['lib', 'lib/intel64', 'lib64', 'slib'], + } return guesses def make_module_extra(self): diff --git a/easybuild/easyblocks/t/tbb.py b/easybuild/easyblocks/t/tbb.py index ddd559f332..f2d7ed6d7f 100644 --- a/easybuild/easyblocks/t/tbb.py +++ b/easybuild/easyblocks/t/tbb.py @@ -34,14 +34,12 @@ @author: Simon Branford (University of Birmingham) """ -import glob import os import shutil from easybuild.tools import LooseVersion from easybuild.easyblocks.generic.configuremake import ConfigureMake -from easybuild.easyblocks.generic.intelbase import INSTALL_MODE_NAME_2015, INSTALL_MODE_2015 -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.filetools import find_glob_pattern, move_file, symlink from easybuild.tools.build_log import EasyBuildError @@ -63,18 +61,17 @@ def get_tbb_gccprefix(libpath): # TBB directory structure # https://www.threadingbuildingblocks.org/docs/help/tbb_userguide/Linux_OS.html tbb_gccprefix = 'gcc4.4' # gcc version 4.4 or higher that may or may not support exception_ptr - if gccversion: - gccversion = LooseVersion(gccversion) - if gccversion >= LooseVersion("4.1") and gccversion < LooseVersion("4.4"): - tbb_gccprefix = 'gcc4.1' # gcc version number between 4.1 and 4.4 that do not support exception_ptr - elif os.path.isdir(os.path.join(libpath, 'gcc4.8')) and gccversion >= LooseVersion("4.8"): - tbb_gccprefix = 'gcc4.8' + if os.path.isdir(os.path.join(libpath, 'gcc4.8')) and LooseVersion(gccversion) >= LooseVersion("4.8"): + tbb_gccprefix = 'gcc4.8' return tbb_gccprefix class EB_tbb(IntelBase, ConfigureMake): - """EasyBlock for tbb, threading building blocks""" + """ + EasyBlock for tbb, threading building blocks + - minimum version suported: 2020.x + """ @staticmethod def extra_options(): @@ -89,6 +86,11 @@ def __init__(self, *args, **kwargs): """Initialisation of custom class variables for tbb""" super(EB_tbb, self).__init__(*args, **kwargs) + if LooseVersion(self.version) < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + platform_name = get_platform_name() myarch = get_cpu_architecture() if platform_name.startswith('x86_64'): @@ -149,42 +151,15 @@ def install_step(self): install_tbb_lib_path = os.path.join(self.installdir, 'tbb', 'lib') if self.toolchain.is_system_toolchain(): - silent_cfg_names_map = None - silent_cfg_extras = None - - if LooseVersion(self.version) < LooseVersion('4.2'): - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - elif LooseVersion(self.version) < LooseVersion('4.4'): - silent_cfg_names_map = { - 'install_mode_name': INSTALL_MODE_NAME_2015, - 'install_mode': INSTALL_MODE_2015, - } - # In case of TBB 4.4.x and newer we have to specify ARCH_SELECTED in silent.cfg - if LooseVersion(self.version) >= LooseVersion('4.4'): - silent_cfg_extras = { - 'ARCH_SELECTED': self.arch.upper() - } - - IntelBase.install_step(self, silent_cfg_names_map=silent_cfg_names_map, silent_cfg_extras=silent_cfg_extras) + silent_cfg_extras = { + 'ARCH_SELECTED': self.arch.upper() + } + IntelBase.install_step(self, silent_cfg_extras=silent_cfg_extras) # determine libdir - libpath = os.path.join(self.installdir, 'tbb', 'libs', 'intel64') - if LooseVersion(self.version) < LooseVersion('4.1.0'): - libglob = os.path.join(libpath, 'cc*libc*_kernel*') - libs = sorted(glob.glob(libglob), key=LooseVersion) - if libs: - # take the last one, should be ordered by cc version - # we're only interested in the last bit - libpath = libs[-1] - else: - raise EasyBuildError("No libs found using %s in %s", libglob, self.installdir) - else: - libpath = os.path.join(libpath, get_tbb_gccprefix(libpath)) + libpath_parent = os.path.join(self.installdir, 'tbb', 'libs', 'intel64') + libpath = os.path.join(libpath_parent, get_tbb_gccprefix(libpath_parent)) # applications go looking into tbb/lib so we move what's in there to tbb/libs shutil.move(install_tbb_lib_path, os.path.join(self.installdir, 'tbb', 'libs')) @@ -206,7 +181,7 @@ def install_step(self): symlink(os.path.relpath(root_lib_path, os.path.dirname(libpath)), libpath, use_abspath_source=False) # Install CMake config files if possible - if self._has_cmake() and LooseVersion(self.version) >= LooseVersion('2020.0'): + if self._has_cmake(): cmake_install_dir = os.path.join(root_lib_path, 'cmake', 'TBB') cmd = [ 'cmake', diff --git a/easybuild/easyblocks/v/vtune.py b/easybuild/easyblocks/v/vtune.py index 94e6ce71fb..db62e40944 100644 --- a/easybuild/easyblocks/v/vtune.py +++ b/easybuild/easyblocks/v/vtune.py @@ -31,12 +31,14 @@ from easybuild.tools import LooseVersion import os -from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012 +from easybuild.easyblocks.generic.intelbase import IntelBase +from easybuild.tools.build_log import EasyBuildError class EB_VTune(IntelBase): """ Support for installing Intel VTune + - minimum version suported: 2020.x """ def __init__(self, *args, **kwargs): @@ -46,60 +48,35 @@ def __init__(self, *args, **kwargs): # recent versions of VTune are installed to a subdirectory self.subdir = '' loosever = LooseVersion(self.version) + if loosever < LooseVersion('2020'): + raise EasyBuildError( + f"Version {self.version} of {self.name} is unsupported. Mininum supported version is 2020.0." + ) + if loosever >= LooseVersion('2024'): self.subdir = os.path.join('vtune', '.'.join([str(loosever.version[0]), str(loosever.version[1])])) elif loosever >= LooseVersion('2021'): self.subdir = os.path.join('vtune', self.version) elif loosever >= LooseVersion('2020'): self.subdir = 'vtune_profiler' - elif loosever >= LooseVersion('2018'): - self.subdir = 'vtune_amplifier' - elif loosever >= LooseVersion('2013_update12'): - self.subdir = 'vtune_amplifier_xe' def prepare_step(self, *args, **kwargs): """Since 2019u3 there is no license required.""" - if LooseVersion(self.version) >= LooseVersion('2019_update3'): - kwargs['requires_runtime_license'] = False + kwargs['requires_runtime_license'] = False super(EB_VTune, self).prepare_step(*args, **kwargs) def make_installdir(self): """Do not create installation directory, install script handles that already.""" super(EB_VTune, self).make_installdir(dontcreate=True) - def install_step(self): - """ - Actual installation - - create silent cfg file - - execute command - """ - silent_cfg_names_map = None - - if LooseVersion(self.version) <= LooseVersion('2013_update11'): - silent_cfg_names_map = { - 'activation_name': ACTIVATION_NAME_2012, - 'license_file_name': LICENSE_FILE_NAME_2012, - } - - super(EB_VTune, self).install_step(silent_cfg_names_map=silent_cfg_names_map) - def make_module_req_guess(self): """Find reasonable paths for VTune""" return self.get_guesses_tools() def sanity_check_step(self): """Custom sanity check paths for VTune.""" - if LooseVersion(self.version) >= LooseVersion('2020'): - binaries = ['amplxe-feedback', 'amplxe-runss', 'vtune', 'vtune-gui'] - else: - binaries = ['amplxe-cl', 'amplxe-feedback', 'amplxe-gui', 'amplxe-runss'] - + binaries = ['amplxe-feedback', 'amplxe-runss', 'vtune', 'vtune-gui'] custom_paths = self.get_custom_paths_tools(binaries) - - custom_commands = [] - if LooseVersion(self.version) >= LooseVersion('2020'): - custom_commands.append('vtune --version') - else: - custom_commands.append('amplxe-cl --version') + custom_commands = ['vtune --version'] super(EB_VTune, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands) diff --git a/test/easyblocks/init_easyblocks.py b/test/easyblocks/init_easyblocks.py index 0514ef8f34..97f1bccc4e 100644 --- a/test/easyblocks/init_easyblocks.py +++ b/test/easyblocks/init_easyblocks.py @@ -228,6 +228,10 @@ def innertest(self): elif easyblock_fn == 'systemmpi.py': # use OpenMPI as name when testing SystemMPI easyblock innertest = make_inner_test(easyblock, name='OpenMPI', version='system') + elif easyblock_fn in ['advisor.py', 'icc.py', 'iccifort.py', 'ifort.py', 'imkl.py', 'imkl_fftw.py', + 'inspector.py', 'itac.py', 'tbb.py', 'vtune.py']: + # family of IntelBase easyblocks have a minimum version support based on currently supported toolchains + innertest = make_inner_test(easyblock, version='9999.9') elif easyblock_fn == 'intel_compilers.py': # custom easyblock for intel-compilers (oneAPI) requires v2021.x or newer innertest = make_inner_test(easyblock, name='intel-compilers', version='2021.1') diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 173581f7de..a4d2874305 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -458,6 +458,10 @@ def innertest(self): # exactly one dependency is included with ModuleRC generic easyblock (and name must match) extra_txt = 'dependencies = [("foo", "1.2.3.4.5")]' innertest = make_inner_test(easyblock, name='foo', version='1.2.3.4', extra_txt=extra_txt) + elif eb_fn in ['advisor.py', 'icc.py', 'iccifort.py', 'ifort.py', 'imkl.py', 'imkl_fftw.py', + 'inspector.py', 'itac.py', 'tbb.py', 'vtune.py']: + # family of IntelBase easyblocks have a minimum version support based on currently supported toolchains + innertest = make_inner_test(easyblock, name=eb_fn.replace('_', '-')[:-3], version='9999.9') elif eb_fn == 'intel_compilers.py': # custom easyblock for intel-compilers (oneAPI) requires v2021.x or newer innertest = make_inner_test(easyblock, name='intel-compilers', version='2021.1')