From 9c014c277afc43c28ab80b4ab5a781d91770dc32 Mon Sep 17 00:00:00 2001 From: Sebastian Achilles <s.achilles@fz-juelich.de> Date: Wed, 17 Nov 2021 15:57:28 +0100 Subject: [PATCH] add custom toolchain intelfftw --- Custom_Toolchains/fft/intelfftw.py | 134 +++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 Custom_Toolchains/fft/intelfftw.py diff --git a/Custom_Toolchains/fft/intelfftw.py b/Custom_Toolchains/fft/intelfftw.py new file mode 100644 index 000000000..f0044d9aa --- /dev/null +++ b/Custom_Toolchains/fft/intelfftw.py @@ -0,0 +1,134 @@ +## +# Copyright 2012-2021 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 <http://www.gnu.org/licenses/>. +## +""" +Support for Intel FFTW as toolchain FFT library. + +:author: Stijn De Weirdt (Ghent University) +:author: Kenneth Hoste (Ghent University) +""" +import os +from distutils.version import LooseVersion + +from easybuild.tools.build_log import EasyBuildError, dry_run_warning +from easybuild.tools.config import build_option +from easybuild.toolchains.fft.fftw import Fftw +from easybuild.tools.modules import get_software_root, get_software_version + + +class IntelFFTW(Fftw): + """FFTW wrapper functionality of Intel MKL""" + + FFT_MODULE_NAME = ['imkl'] + + FFT_LIB_GROUP = True + FFT_LIB_STATIC = True + + def _set_fftw_variables(self): + if not hasattr(self, 'BLAS_LIB_DIR'): + raise EasyBuildError( + "_set_fftw_variables: IntelFFT based on IntelMKL (no BLAS_LIB_DIR found)") + + imklver = get_software_version(self.FFT_MODULE_NAME[0]) + + picsuff = '' + if self.options.get('pic', None): + picsuff = '_pic' + bitsuff = '_lp64' + if self.options.get('i8', None): + bitsuff = '_ilp64' + + if get_software_root('icc') or get_software_root('intel-compilers'): + compsuff = '_intel' + elif get_software_root('PGI'): + compsuff = '_pgi' + elif get_software_root('GCC') or get_software_root('GCCcore'): + compsuff = '_gnu' + else: + error_msg = "Not using Intel compilers, PGI nor GCC, don't know compiler suffix for FFTW libraries." + raise EasyBuildError(error_msg) + + interface_lib = "fftw3xc%s%s" % (compsuff, picsuff) + fftw_libs = [interface_lib] + cluster_interface_lib = None + if self.options.get('usempi', False): + # add cluster interface for recent imkl versions + if LooseVersion(imklver) >= LooseVersion('10.3'): + suff = picsuff + if LooseVersion(imklver) >= LooseVersion('11.0.2'): + suff = bitsuff + suff + cluster_interface_lib = 'fftw3x_cdft%s' % suff + fftw_libs.append(cluster_interface_lib) + fftw_libs.append("mkl_cdft_core") # add cluster dft + # add BLACS; use flatten because ListOfList + fftw_libs.extend(self.variables['LIBBLACS'].flatten()) + + fftw_mt_libs = fftw_libs + [x % + self.BLAS_LIB_MAP for x in self.BLAS_LIB_MT] + + self.log.debug('fftw_libs %s' % fftw_libs.__repr__()) + # add BLAS libs (contains dft) + fftw_libs.extend(self.variables['LIBBLAS'].flatten()) + self.log.debug('fftw_libs %s' % fftw_libs.__repr__()) + + self.FFT_LIB_DIR = self.BLAS_LIB_DIR + self.FFT_INCLUDE_DIR = [os.path.join( + d, 'fftw') for d in self.BLAS_INCLUDE_DIR] + + # building the FFTW interfaces is optional, + # so make sure libraries are there before FFT_LIB is set + imklroot = get_software_root(self.FFT_MODULE_NAME[0]) + fft_lib_dirs = [os.path.join(imklroot, d) for d in self.FFT_LIB_DIR] + + def fftw_lib_exists(libname): + """Helper function to check whether FFTW library with specified name exists.""" + return any([os.path.exists(os.path.join(d, "lib%s.a" % libname)) for d in fft_lib_dirs]) + + if not fftw_lib_exists(interface_lib) and LooseVersion(imklver) >= LooseVersion("10.2"): + # interface libs can be optional: + # MKL >= 10.2 include fftw3xc and fftw3xf interfaces in LIBBLAS=libmkl_gf/libmkl_intel + # See https://software.intel.com/en-us/articles/intel-mkl-main-libraries-contain-fftw3-interfaces + # The cluster interface libs (libfftw3x_cdft*) can be omitted if the toolchain does not provide MPI-FFTW + # interfaces. + fftw_libs = [lib for lib in fftw_libs if lib not in [ + interface_lib, cluster_interface_lib]] + fftw_mt_libs = [lib for lib in fftw_mt_libs if lib not in [ + interface_lib, cluster_interface_lib]] + + # filter out libraries from list of FFTW libraries to check for if they are not provided by Intel MKL + check_fftw_libs = [ + lib for lib in fftw_libs if lib not in ['dl', 'gfortran']] + + if all([fftw_lib_exists(lib) for lib in check_fftw_libs]): + self.FFT_LIB = fftw_libs + else: + msg = "Not all FFTW interface libraries %s are found in %s" % ( + check_fftw_libs, fft_lib_dirs) + msg += ", can't set $FFT_LIB." + if self.dry_run: + dry_run_warning(msg, silent=build_option('silent')) + else: + raise EasyBuildError(msg) + + self.FFT_LIB_MT = fftw_mt_libs -- GitLab