diff --git a/easybuild/easyblocks/f/fftw.py b/easybuild/easyblocks/f/fftw.py index dc66fb1528f..40fd232acde 100644 --- a/easybuild/easyblocks/f/fftw.py +++ b/easybuild/easyblocks/f/fftw.py @@ -246,13 +246,16 @@ def test_step(self): super(EB_FFTW, self).test_step() - def sanity_check_step(self): - """Custom sanity check for FFTW.""" + def sanity_check_step(self, mpionly=False): + """Custom sanity check for FFTW. mpionly=True only for FFTW.MPI""" custom_paths = { - 'files': ['bin/fftw-wisdom-to-conf', 'include/fftw3.f', 'include/fftw3.h'], - 'dirs': ['lib/pkgconfig'], + 'files': ['include/fftw3.f', 'include/fftw3.h'], + 'dirs': [], } + if not mpionly: + custom_paths['files'].insert(0, 'bin/fftw-wisdom-to-conf') + custom_paths['dirs'].insert(0, 'lib/pkgconfig') shlib_ext = get_shared_lib_ext() @@ -261,7 +264,8 @@ def sanity_check_step(self): if self.cfg['with_%s_prec' % prec]: # precision-specific binaries - extra_files.append('bin/fftw%s-wisdom' % letter) + if not mpionly: + extra_files.append('bin/fftw%s-wisdom' % letter) # precision-specific .f03 header files inc_f03 = 'include/fftw3%s.f03' % letter @@ -271,7 +275,11 @@ def sanity_check_step(self): extra_files.append(inc_f03) # libraries, one for each precision and variant (if enabled) - for variant in ['', 'mpi', 'openmp', 'threads']: + if mpionly: + variantlist = ['mpi'] + else: + variantlist = ['', 'mpi', 'openmp', 'threads'] + for variant in variantlist: if variant == 'openmp': suff = '_omp' elif variant == '': diff --git a/easybuild/easyblocks/f/fftwmpi.py b/easybuild/easyblocks/f/fftwmpi.py new file mode 100644 index 00000000000..2c7721b6551 --- /dev/null +++ b/easybuild/easyblocks/f/fftwmpi.py @@ -0,0 +1,73 @@ +## +# Copyright 2009-2022 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 only the MPI interfaces for FFTW, +implemented as an easyblock + +@author: Bart Oldeman (McGill University, Calcul Quebec, Digital Research Alliance of Canada) +""" +import os +import glob + +from easybuild.easyblocks.fftw import EB_FFTW +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.modules import get_software_root +from easybuild.tools.filetools import remove + + +class EB_FFTW_period_MPI(EB_FFTW): + """Support for building/installing FFTW.MPI""" + + @staticmethod + def extra_options(): + """Modify defaults for custom easyconfig parameters for FFTW.""" + + extra_vars = EB_FFTW.extra_options() + # change defaults for unneeded or impossible options for MPI libraries + extra_vars['with_openmp'][0] = False + extra_vars['with_threads'][0] = False + extra_vars['with_quad_prec'][0] = False + return extra_vars + + def prepare_step(self, *args, **kwargs): + """Custom prepare step: make sure FFTW is available as dependency.""" + super(EB_FFTW_period_MPI, self).prepare_step(*args, **kwargs) + + fftw_root = get_software_root('FFTW') + if not fftw_root: + raise EasyBuildError("Required FFTW dependency is missing!") + + def post_install_step(self): + """Custom post install step for FFTW.MPI""" + + # remove everything except include files that are already in non-MPI FFTW dependency. + remove(glob.glob(os.path.join(self.installdir, 'lib', 'libfftw.*')) + + glob.glob(os.path.join(self.installdir, 'lib', 'libfftw[lf].*')) + + [os.path.join(self.installdir, p) for p in ['bin', 'lib/pkgconfig', 'lib/cmake', 'share']]) + super(EB_FFTW_period_MPI, self).post_install_step() + + def sanity_check_step(self): + """Custom sanity check for FFTW.MPI: check if all libraries/headers for MPI interfaces are there.""" + super(EB_FFTW_period_MPI, self).sanity_check_step(mpionly=True) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 1bf00ff6587..034dc65961a 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -46,6 +46,7 @@ from easybuild.easyblocks.generic.pythonbundle import PythonBundle from easybuild.easyblocks.gcc import EB_GCC from easybuild.easyblocks.imod import EB_IMOD +from easybuild.easyblocks.fftwmpi import EB_FFTW_period_MPI from easybuild.easyblocks.imkl_fftw import EB_imkl_minus_FFTW from easybuild.easyblocks.openfoam import EB_OpenFOAM from easybuild.framework.easyconfig import easyconfig @@ -260,6 +261,10 @@ def template_module_only_test(self, easyblock, name, version='1.3.2', extra_txt= for base in copy.copy(bases): bases.extend(base.__bases__) + if app_class == EB_FFTW_period_MPI: + # $EBROOTFFTW must be set for FFTW.MPI, because of dependency check on FFTW in prepare_step + os.environ['EBROOTFFTW'] = '/fake/software/FFTW/3.3.10' + if app_class == EB_imkl_minus_FFTW: # $EBROOTIMKL must be set for imkl-FFTW, because of dependency check on imkl in prepare_step os.environ['EBROOTIMKL'] = '/fake/software/imkl/2021.4.0/mkl/2021.4.0'