-
Notifications
You must be signed in to change notification settings - Fork 145
Compiler toolchains
To build software with EasyBuild, the first thing you'll need to do is either pick a supported compiler toolchain, or construct your own and make EasyBuild support it.
Compiler toolchains are basically a (set of) compilers together with a bunch of libraries that provide additional support that is commonly required to build software. In the world of High Performance Computing where EasyBuild was born, this usually consists of an library for MPI (inter-process communication over a network), BLAS/LAPACK (linear algebra routines) and FFT (Fast Fourier Transforms).
The following sections describe how to either pick an already supported compiler toolchain, or how to construct your own toolchain and provide the necessary things so that EasyBuild can use it.
To get an overview of compiler toolchains that EasyBuild knows about, use the --list-toolchains
command line option (available since EasyBuild v1.1). This will print something like below:
$ ./eb --list-toolchains
List of known toolchains (toolchainname: module[,module...]):
ClangGCC: Clang, GCC
GCC: GCC
cgmpich: ClangGCC, MPICH
cgmpolf: BLACS, ClangGCC, FFTW, MPICH, OpenBLAS, ScaLAPACK
cgmvapich2: ClangGCC, MVAPICH2
cgmvolf: BLACS, ClangGCC, FFTW, MVAPICH2, OpenBLAS, ScaLAPACK
cgompi: ClangGCC, OpenMPI
cgoolf: BLACS, ClangGCC, FFTW, OpenBLAS, OpenMPI, ScaLAPACK
dummy:
gcccuda: CUDA, GCC
gimkl: GCC, imkl, impi
gmacml: ACML, BLACS, FFTW, GCC, MVAPICH2, ScaLAPACK
gmpich2: GCC, MPICH2
gmpolf: BLACS, FFTW, GCC, MPICH2, OpenBLAS, ScaLAPACK
gmvapich2: GCC, MVAPICH2
gmvolf: BLACS, FFTW, GCC, MVAPICH2, OpenBLAS, ScaLAPACK
goalf: ATLAS, BLACS, FFTW, GCC, OpenMPI, ScaLAPACK
gompi: GCC, OpenMPI
goolf: BLACS, FFTW, GCC, OpenBLAS, OpenMPI, ScaLAPACK
goolfc: BLACS, CUDA, FFTW, GCC, OpenBLAS, OpenMPI, ScaLAPACK
gqacml: ACML, BLACS, FFTW, GCC, QLogicMPI, ScaLAPACK
iccifort: icc, ifort
ictce: icc, ifort, imkl, impi
iiqmpi: QLogicMPI, icc, ifort
iomkl: OpenMPI, icc, ifort, imkl
iqacml: ACML, BLACS, FFTW, QLogicMPI, ScaLAPACK, icc, ifort
ismkl: MPICH2, icc, ifort, imkl
For each compiler toolchain, the constituent elements (compiler + libraries) are printed, which provides the necessary information to select a toolchain. To select a version of a particular toolchain, just check which environment modules are available for the toolchain you selected (e.g., module av goalf
), or build a toolchain environment module (using EasyBuild) featuring the versions of the compiler and libraries you need.
If none of these toolchains fits your needs, you will need to construct your own compiler toolchain.
EasyBuild has very modular support for compiler toolchains, making it very easy to construct your own toolchain and make EasyBuild use it.
If you implement support for new compiler toolchains and/or toolchain elements, please consider contributing them back to the main easybuild-framework repository.
Before you create your own compiler toolchain, you need to set up your own easybuild.toolchains
package in which you can implemented the required Python module that will provide support for your toolchain. Of course, you will only need to do this once (for every easybuild.toolchains
package).
To set up your easybuild.toolchains
package in a directory $PREFIX
, run the following commands:
for subdir in '' compiler fft linalg mpi;
do
mkdir -p $PREFIX/easybuild/toolchains/$subdir
touch $PREFIX/easybuild/toolchains/$subdir/__init__.py
done
touch easybuild/__init__.py
This will create an empty easybuild.toolchains
package, and also initialize the compiler
, fft
, linalg
and mpi
subpackages.
To make EasyBuild support your toolchain, you will need to provide Python modules that implement that support. If all of the constituent toolchain element already have Python modules available in the easybuild.toolchains
subpackages, you'll only need to provide a Python module that defines your compiler toolchain.
For each of the toolchain elements, i.e. compiler suite and each one of the libraries, a Python module should be available in the appropriate easybuild.toolchains
subpackage.
For a compiler suite (e.g. GCC or the Intel compilers), this consists of implementing a Python module in easybuild.toolchains.compiler
that specifies compiler commands, compiler options (both common and unique options), etc.
For libraries the support maybe fairly concise, e.g. only consisting of listing library files and/or minor customizations of the general support provided by EasyBuild (see the easybuild.tools.toolchain
package), or rather involved to yield different settings depending on the version of the compiler used in the toolchain (see e.g. the Intel MKL support in easybuild.toolchains.linalg.intelmkl.py
).
If you need to implement support for yet unsupported compilers and/or libraries, the best place to start is to look at the already available Python modules in easybuild.toolchains and the general support in easybuild.tools.toolchain.
If you need support from the EasyBuild developers, don't hesitate to open an issue in the easybuild-framework repository, or contact us.
Next to making sure EasyBuild supports the toolchain elements, you also need to define the toolchain itself, by implementing a very simple Python module in easybuild.toolchains
. As an example, the toolchain definition for ictce
is shown below (see also easybuild/toolchains/ictce.py).
from easybuild.toolchains.compiler.inteliccifort import IntelIccIfort
from easybuild.toolchains.fft.intelfftw import IntelFFTW
from easybuild.toolchains.mpi.intelmpi import IntelMPI
from easybuild.toolchains.linalg.intelmkl import IntelMKL
class Ictce(IntelIccIfort, IntelMPI, IntelMKL, IntelFFTW):
"""
Compiler toolchain with Intel compilers (icc/ifort), Intel MPI,
Intel Math Kernel Library (MKL) and Intel FFTW wrappers.
"""
NAME = 'ictce'
To add support for a toolchain, it suffices define a class that inherits from all of the the classes implementing support for the toolchain elements, and set a toolchain name as NAME
(that should match the name of the toolchain environment module, see below). EasyBuild will then take care of the nasty details.
You need to build a environment module for the toolchain you will be using. When instructed to use a particular toolchain, EasyBuild will try and load the corresponding environemnt module to make the compiler and libraries available for use.
First, you'll need to make sure that all of the constituent elements of the toolchain are supported by EasyBuild, i.e. that you can build and install them, and generate an environment module that can be loaded.
Assuming that that is taken care of, you create a simple easyconfig file to make EasyBuild create an environment module for your toolchain, of which the most important part is the list of dependencies. For example, the easyconfig file for the ictce
toolchain looks like this:
easyblock = "Toolchain"
name = 'ictce'
version = '4.0.6'
homepage = 'http://software.intel.com/en-us/intel-cluster-toolchain-compiler/'
description = """Intel Cluster Toolchain Compiler Edition provides Intel C,C++ and fortran compilers, Intel MPI and Intel MKL"""
toolchain = {'name': 'dummy', 'version': 'dummy'}
dependencies = [
('icc', '2011.6.233'),
('ifort', '2011.6.233'),
('impi', '4.0.2.003'),
('imkl', '10.3.6.233'),
]
Note that to 'build' a toolchain environment module, you should use the dummy
toolchain (since you won't actually be building anything, just creating an environment module file).
Important remark: the list of dependencies in the toolchain environment module should match the list of classes in the toolchain definition as implemented by the Python module in easybuild.toolchains
. More specifically, the names of the dependency modules should match the NAME
of the toolchain elements as specified in the easybuild.toolchains.*
Python classes for them.
Each toolchain is assigned a version, just like software packages.
Coming up with a sensible version number is difficult, so after giving it some thought, we figured to just run with a limited set of heuristics for versioning toolchains. I.e. for a toolchain with version x.y.z
:
- the major version number
x
is used to 'group' toolchains that feature different elements, but are from the same 'generation'; if one of the toolchain elements gets a major update,x
is increased; - e.g. for the
ictce
toolchains (Intel tools), a new major version number oficc
/ifort
compilers results in an increase of the major version number ofictce
- the minor version number
y
is increased when multiple toolchain elements get a minor update; - e.g. for the
goolf
toolchains, v1.5.14 is an updated version of v1.4.10, without any major updates in the toolchain elements - the tiny version number
z
is changed when the version of one toolchain element is adjusted; - also,
z
is picked such that downgrades of individual toolchain elements are possible while retaining a logical ordering (i.e. downgrading one element should results in a lower value forz
, and shouldn't clash with existing toolchain versions) - e.g.
goolf
v1.4.10 provides freedom to downgradeGCC
v4.7.2 an earlier v4.7.x should the need arise (e.g. for testing/benchmarking); likewise for the other toolchain elements
After you've implemented and tested the support for a new compiler toolchain (and its constituent elements), please consider contributing it back so other EasyBuilders can also benefit from it. See Contributing back for more information.