Select Git revision
Examples.rst
mpich.py 7.25 KiB
##
# Copyright 2009-2022 Ghent University, Forschungszentrum Juelich
#
# 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),
# the Hercules foundation (http://www.herculesstichting.be/in_English)
# 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/>.
##
"""
EasyBuild support for building and installing the MPICH MPI library and derivatives, 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: Damian Alvarez (Forschungszentrum Juelich)
@author: Xavier Besseron (University of Luxembourg)
"""
import os
from distutils.version import LooseVersion
import easybuild.tools.environment as env
from easybuild.easyblocks.generic.configuremake import ConfigureMake
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.systemtools import get_shared_lib_ext
class EB_MPICH(ConfigureMake):
"""
Support for building the MPICH MPI library and derivatives.
- basically redefinition of environment variables
"""
@staticmethod
def extra_options(extra_vars=None):
"""Define custom easyconfig parameters specific to MPICH."""
extra_vars = ConfigureMake.extra_options(extra_vars)
extra_vars.update({
'debug': [False, "Enable debug build (which is slower)", CUSTOM],
})
return extra_vars
# MPICH configure script complains when F90 or F90FLAGS are set,
# they should be replaced with FC/FCFLAGS instead.
# Additionally, there are a set of variables (FCFLAGS among them) that should not be set at configure time,
# or they will leak in the mpix wrappers.
# Specific variables to be included in the wrapper exists, but they changed between MPICH 3.1.4 and MPICH 3.2
# and in a typical scenario we probably don't want them.
def correct_mpich_build_env(self):
"""
Method to correctly set the environment for MPICH and derivatives
"""
env_vars = ['CFLAGS', 'CPPFLAGS', 'CXXFLAGS', 'FCFLAGS', 'FFLAGS', 'LDFLAGS', 'LIBS']
vars_to_unset = ['F90', 'F90FLAGS']
for envvar in env_vars:
envvar_val = os.getenv(envvar)
if envvar_val:
new_envvar = 'MPICHLIB_%s' % envvar
new_envvar_val = os.getenv(new_envvar)
vars_to_unset.append(envvar)
if envvar_val == new_envvar_val:
self.log.debug("$%s == $%s, just defined $%s as empty", envvar, new_envvar, envvar)
elif new_envvar_val is None:
env.setvar(new_envvar, envvar_val)
else:
raise EasyBuildError("Both $%s and $%s set, can I overwrite $%s with $%s (%s) ?",
envvar, new_envvar, new_envvar, envvar, envvar_val)
env.unset_env_vars(vars_to_unset)
def add_mpich_configopts(self):
"""
Method to add common configure options for MPICH-based MPI libraries
"""
# additional configuration options
add_configopts = []
# use POSIX threads
add_configopts.append('--with-thread-package=pthreads')
if self.cfg['debug']:
# debug build, with error checking, timing and debug info
# note: this will affect performance
add_configopts.append('--enable-fast=none')
else:
# optimized build, no error checking, timing or debug info
add_configopts.append('--enable-fast')
# enable shared libraries, using GCC and GNU ld options
add_configopts.extend(['--enable-shared', '--enable-sharedlibs=gcc'])
# enable static libraries
add_configopts.extend(['--enable-static'])
# enable Fortran 77/90 and C++ bindings
add_configopts.extend(['--enable-f77', '--enable-fc', '--enable-cxx'])
self.cfg.update('configopts', ' '.join(add_configopts))
def configure_step(self, add_mpich_configopts=True):
"""
Custom configuration procedure for MPICH
* add common configure options for MPICH-based MPI libraries
* unset environment variables that leak into mpi* wrappers, and define $MPICHLIB_* equivalents instead
"""
# things might go wrong if a previous install dir is present, so let's get rid of it
if not self.cfg['keeppreviousinstall']:
self.log.info("Making sure any old installation is removed before we start the build...")
super(EB_MPICH, self).make_dir(self.installdir, True, dontcreateinstalldir=True)
if add_mpich_configopts:
self.add_mpich_configopts()
self.correct_mpich_build_env()
super(EB_MPICH, self).configure_step()
# make and make install are default
def sanity_check_step(self, custom_paths=None, use_new_libnames=None, check_launchers=True, check_static_libs=True):
"""
Custom sanity check for MPICH
"""
shlib_ext = get_shared_lib_ext()
if custom_paths is None:
custom_paths = {}
if use_new_libnames is None:
# cfr. http://git.mpich.org/mpich.git/blob_plain/v3.1.1:/CHANGES
# MPICH changed its library names sinceversion 3.1.1
use_new_libnames = LooseVersion(self.version) >= LooseVersion('3.1.1')
# Starting MPICH 3.1.1, libraries have been renamed
# cf http://git.mpich.org/mpich.git/blob_plain/v3.1.1:/CHANGES
if use_new_libnames:
libnames = ['mpi', 'mpicxx', 'mpifort']
else:
libnames = ['fmpich', 'mpichcxx', 'mpichf90', 'mpich', 'mpl', 'opa']
binaries = ['mpicc', 'mpicxx', 'mpif77', 'mpif90']
if check_launchers:
binaries.extend(['mpiexec', 'mpiexec.hydra', 'mpirun'])
bins = [os.path.join('bin', x) for x in binaries]
headers = [os.path.join('include', x) for x in ['mpi.h', 'mpicxx.h', 'mpif.h']]
lib_exts = [shlib_ext]
if check_static_libs:
lib_exts.append('a')
libs_fn = ['lib%s.%s' % (l, e) for l in libnames for e in lib_exts]
libs = [(os.path.join('lib', l), os.path.join('lib64', l)) for l in libs_fn]
custom_paths.setdefault('dirs', []).extend(['bin', 'include', ('lib', 'lib64')])
custom_paths.setdefault('files', []).extend(bins + headers + libs)
super(EB_MPICH, self).sanity_check_step(custom_paths=custom_paths)