Merge pull request #1040 from KineticTheory/pkg-trilinos

Make Boost an optional feature of Trilinos.
This commit is contained in:
Todd Gamblin 2016-06-15 08:57:38 -07:00 committed by GitHub
commit 08badb5a35

View file

@ -23,18 +23,23 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
from spack import * from spack import *
import os, sys, glob import os
import sys
# Trilinos is complicated to build, as an inspiration a couple of links to other repositories which build it: # Trilinos is complicated to build, as an inspiration a couple of links to
# other repositories which build it:
# https://github.com/hpcugent/easybuild-easyblocks/blob/master/easybuild/easyblocks/t/trilinos.py#L111 # https://github.com/hpcugent/easybuild-easyblocks/blob/master/easybuild/easyblocks/t/trilinos.py#L111
# https://github.com/koecher/candi/blob/master/deal.II-toolchain/packages/trilinos.package # https://github.com/koecher/candi/blob/master/deal.II-toolchain/packages/trilinos.package
# https://gitlab.com/configurations/cluster-config/blob/master/trilinos.sh # https://gitlab.com/configurations/cluster-config/blob/master/trilinos.sh
# https://github.com/Homebrew/homebrew-science/blob/master/trilinos.rb # https://github.com/Homebrew/homebrew-science/blob/master/trilinos.rb and some
# and some relevant documentation/examples: # relevant documentation/examples:
# https://github.com/trilinos/Trilinos/issues/175 # https://github.com/trilinos/Trilinos/issues/175
class Trilinos(Package): class Trilinos(Package):
"""The Trilinos Project is an effort to develop algorithms and enabling technologies within an object-oriented """The Trilinos Project is an effort to develop algorithms and enabling
software framework for the solution of large-scale, complex multi-physics engineering and scientific problems. technologies within an object-oriented software framework for the solution
of large-scale, complex multi-physics engineering and scientific problems.
A unique design feature of Trilinos is its focus on packages. A unique design feature of Trilinos is its focus on packages.
""" """
homepage = "https://trilinos.org/" homepage = "https://trilinos.org/"
@ -54,49 +59,51 @@ class Trilinos(Package):
variant('hypre', default=True, description='Compile with Hypre preconditioner') variant('hypre', default=True, description='Compile with Hypre preconditioner')
variant('hdf5', default=True, description='Compile with HDF5') variant('hdf5', default=True, description='Compile with HDF5')
variant('suite-sparse', default=True, description='Compile with SuiteSparse solvers') variant('suite-sparse', default=True, description='Compile with SuiteSparse solvers')
# not everyone has py-numpy activated, keep it disabled by default to avoid configure errors # not everyone has py-numpy activated, keep it disabled by default to avoid
# configure errors
variant('python', default=False, description='Build python wrappers') variant('python', default=False, description='Build python wrappers')
variant('shared', default=True, description='Enables the build of shared libraries') variant('shared', default=True, description='Enables the build of shared libraries')
variant('debug', default=False, description='Builds a debug version of the libraries') variant('debug', default=False, description='Builds a debug version of the libraries')
variant('boost', default=True, description='Compile with Boost')
# Everything should be compiled with -fpic # Everything should be compiled with -fpic
depends_on('blas') depends_on('blas')
depends_on('lapack') depends_on('lapack')
depends_on('boost') depends_on('boost', when='+boost')
depends_on('matio') depends_on('matio')
depends_on('glm') depends_on('glm')
depends_on('swig') depends_on('swig')
depends_on('metis@5:',when='+metis') depends_on('metis@5:', when='+metis')
depends_on('suite-sparse',when='+suite-sparse') depends_on('suite-sparse', when='+suite-sparse')
# MPI related dependencies # MPI related dependencies
depends_on('mpi') depends_on('mpi')
depends_on('netcdf+mpi') depends_on('netcdf+mpi')
depends_on('parmetis',when='+metis') depends_on('parmetis', when='+metis')
# Trilinos' Tribits config system is limited which makes it # Trilinos' Tribits config system is limited which makes it very tricky to
# very tricky to link Amesos with static MUMPS, see # link Amesos with static MUMPS, see
# https://trilinos.org/docs/dev/packages/amesos2/doc/html/classAmesos2_1_1MUMPS.html # https://trilinos.org/docs/dev/packages/amesos2/doc/html/classAmesos2_1_1MUMPS.html
# One could work it out by getting linking flags from mpif90 --showme:link (or alike) # One could work it out by getting linking flags from mpif90 --showme:link
# and adding results to -DTrilinos_EXTRA_LINK_FLAGS # (or alike) and adding results to -DTrilinos_EXTRA_LINK_FLAGS together
# together with Blas and Lapack and ScaLAPACK and Blacs and -lgfortran and # with Blas and Lapack and ScaLAPACK and Blacs and -lgfortran and it may
# it may work at the end. But let's avoid all this by simply using shared libs # work at the end. But let's avoid all this by simply using shared libs
depends_on('mumps@5.0:+mpi+shared',when='+mumps') depends_on('mumps@5.0:+mpi+shared', when='+mumps')
depends_on('scalapack',when='+mumps') depends_on('scalapack', when='+mumps')
depends_on('superlu-dist',when='+superlu-dist') depends_on('superlu-dist', when='+superlu-dist')
depends_on('hypre~internal-superlu',when='+hypre') depends_on('hypre~internal-superlu', when='+hypre')
depends_on('hdf5+mpi',when='+hdf5') depends_on('hdf5+mpi', when='+hdf5')
depends_on('python', when='+python')
depends_on('python',when='+python')
patch('umfpack_from_suitesparse.patch') patch('umfpack_from_suitesparse.patch')
# check that the combination of variants makes sense # check that the combination of variants makes sense
def variants_check(self): def variants_check(self):
if '+superlu-dist' in self.spec and self.spec.satisfies('@:11.4.3'): if '+superlu-dist' in self.spec and self.spec.satisfies('@:11.4.3'):
# For Trilinos v11 we need to force SuperLUDist=OFF, # For Trilinos v11 we need to force SuperLUDist=OFF, since only the
# since only the deprecated SuperLUDist v3.3 together with an Amesos patch # deprecated SuperLUDist v3.3 together with an Amesos patch is
# is working. # working.
raise RuntimeError('The superlu-dist variant can only be used with Trilinos @12.0.1:') raise RuntimeError('The superlu-dist variant can only be used' +
' with Trilinos @12.0.1:')
def install(self, spec, prefix): def install(self, spec, prefix):
self.variants_check() self.variants_check()
@ -106,54 +113,75 @@ def install(self, spec, prefix):
options.extend(std_cmake_args) options.extend(std_cmake_args)
mpi_bin = spec['mpi'].prefix.bin mpi_bin = spec['mpi'].prefix.bin
options.extend(['-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON', options.extend([
'-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON', '-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON',
'-DTrilinos_VERBOSE_CONFIGURE:BOOL=OFF', '-DTrilinos_ENABLE_ALL_OPTIONAL_PACKAGES:BOOL=ON',
'-DTrilinos_ENABLE_TESTS:BOOL=OFF', '-DTrilinos_VERBOSE_CONFIGURE:BOOL=OFF',
'-DTrilinos_ENABLE_EXAMPLES:BOOL=OFF', '-DTrilinos_ENABLE_TESTS:BOOL=OFF',
'-DCMAKE_BUILD_TYPE:STRING=%s' % ('DEBUG' if '+debug' in spec else 'RELEASE'), '-DTrilinos_ENABLE_EXAMPLES:BOOL=OFF',
'-DBUILD_SHARED_LIBS:BOOL=%s' % ('ON' if '+shared' in spec else 'OFF'), '-DCMAKE_BUILD_TYPE:STRING=%s' % (
'-DTPL_ENABLE_MPI:BOOL=ON', 'DEBUG' if '+debug' in spec else 'RELEASE'),
'-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix, '-DBUILD_SHARED_LIBS:BOOL=%s' % (
'-DTPL_ENABLE_BLAS=ON', 'ON' if '+shared' in spec else 'OFF'),
'-DBLAS_LIBRARY_NAMES=blas', # FIXME: don't hardcode names '-DTPL_ENABLE_MPI:BOOL=ON',
'-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib, '-DMPI_BASE_DIR:PATH=%s' % spec['mpi'].prefix,
'-DTPL_ENABLE_LAPACK=ON', '-DTPL_ENABLE_BLAS=ON',
'-DLAPACK_LIBRARY_NAMES=lapack', '-DBLAS_LIBRARY_NAMES=blas', # FIXME: don't hardcode names
'-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix, '-DBLAS_LIBRARY_DIRS=%s' % spec['blas'].prefix.lib,
'-DTPL_ENABLE_Boost:BOOL=ON', '-DTPL_ENABLE_LAPACK=ON',
'-DBoost_INCLUDE_DIRS:PATH=%s' % spec['boost'].prefix.include, '-DLAPACK_LIBRARY_NAMES=lapack',
'-DBoost_LIBRARY_DIRS:PATH=%s' % spec['boost'].prefix.lib, '-DLAPACK_LIBRARY_DIRS=%s' % spec['lapack'].prefix,
'-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON', '-DTrilinos_ENABLE_EXPLICIT_INSTANTIATION:BOOL=ON',
'-DTrilinos_ENABLE_CXX11:BOOL=ON', '-DTrilinos_ENABLE_CXX11:BOOL=ON',
'-DTPL_ENABLE_Netcdf:BOOL=ON', '-DTPL_ENABLE_Netcdf:BOOL=ON',
'-DTPL_ENABLE_HYPRE:BOOL=%s' % ('ON' if '+hypre' in spec else 'OFF'), '-DTPL_ENABLE_HYPRE:BOOL=%s' % (
'-DTPL_ENABLE_HDF5:BOOL=%s' % ('ON' if '+hdf5' in spec else 'OFF'), 'ON' if '+hypre' in spec else 'OFF'),
]) '-DTPL_ENABLE_HDF5:BOOL=%s' % (
'ON' if '+hdf5' in spec else 'OFF'),
])
if '+boost' in spec:
options.extend([
'-DTPL_ENABLE_Boost:BOOL=ON',
'-DBoost_INCLUDE_DIRS:PATH=%s' % spec['boost'].prefix.include,
'-DBoost_LIBRARY_DIRS:PATH=%s' % spec['boost'].prefix.lib
])
else:
options.extend(['-DTPL_ENABLE_Boost:BOOL=OFF'])
# Fortran lib # Fortran lib
libgfortran = os.path.dirname (os.popen('%s --print-file-name libgfortran.a' % join_path(mpi_bin,'mpif90') ).read()) libgfortran = os.path.dirname(os.popen(
'%s --print-file-name libgfortran.a' %
join_path(mpi_bin, 'mpif90')).read())
options.extend([ options.extend([
'-DTrilinos_EXTRA_LINK_FLAGS:STRING=-L%s/ -lgfortran' % libgfortran, '-DTrilinos_EXTRA_LINK_FLAGS:STRING=-L%s/ -lgfortran' % (
libgfortran),
'-DTrilinos_ENABLE_Fortran=ON' '-DTrilinos_ENABLE_Fortran=ON'
]) ])
# for build-debug only: # for build-debug only:
#options.extend([ # options.extend([
# '-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE' # '-DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE'
#]) # ])
# suite-sparse related # suite-sparse related
if '+suite-sparse' in spec: if '+suite-sparse' in spec:
options.extend([ options.extend([
'-DTPL_ENABLE_Cholmod:BOOL=OFF', # FIXME: Trilinos seems to be looking for static libs only, patch CMake TPL file? # FIXME: Trilinos seems to be looking for static libs only,
#'-DTPL_ENABLE_Cholmod:BOOL=ON', # patch CMake TPL file?
#'-DCholmod_LIBRARY_DIRS:PATH=%s' % spec['suite-sparse'].prefix.lib, '-DTPL_ENABLE_Cholmod:BOOL=OFF',
#'-DCholmod_INCLUDE_DIRS:PATH=%s' % spec['suite-sparse'].prefix.include, # '-DTPL_ENABLE_Cholmod:BOOL=ON',
# '-DCholmod_LIBRARY_DIRS:PATH=%s' % (
# spec['suite-sparse'].prefix.lib,
# '-DCholmod_INCLUDE_DIRS:PATH=%s' % (
# spec['suite-sparse'].prefix.include,
'-DTPL_ENABLE_UMFPACK:BOOL=ON', '-DTPL_ENABLE_UMFPACK:BOOL=ON',
'-DUMFPACK_LIBRARY_DIRS:PATH=%s' % spec['suite-sparse'].prefix.lib, '-DUMFPACK_LIBRARY_DIRS:PATH=%s' % (
'-DUMFPACK_INCLUDE_DIRS:PATH=%s' % spec['suite-sparse'].prefix.include, spec['suite-sparse'].prefix.lib),
'-DUMFPACK_LIBRARY_NAMES=umfpack;amd;colamd;cholmod;suitesparseconfig' '-DUMFPACK_INCLUDE_DIRS:PATH=%s' % (
spec['suite-sparse'].prefix.include),
'-DUMFPACK_LIBRARY_NAMES=umfpack;amd;colamd;cholmod;' +
'suitesparseconfig'
]) ])
else: else:
options.extend([ options.extend([
@ -169,9 +197,11 @@ def install(self, spec, prefix):
'-DMETIS_LIBRARY_NAMES=metis', '-DMETIS_LIBRARY_NAMES=metis',
'-DTPL_METIS_INCLUDE_DIRS=%s' % spec['metis'].prefix.include, '-DTPL_METIS_INCLUDE_DIRS=%s' % spec['metis'].prefix.include,
'-DTPL_ENABLE_ParMETIS:BOOL=ON', '-DTPL_ENABLE_ParMETIS:BOOL=ON',
'-DParMETIS_LIBRARY_DIRS=%s;%s' % (spec['parmetis'].prefix.lib,spec['metis'].prefix.lib), '-DParMETIS_LIBRARY_DIRS=%s;%s' % (
spec['parmetis'].prefix.lib, spec['metis'].prefix.lib),
'-DParMETIS_LIBRARY_NAMES=parmetis;metis', '-DParMETIS_LIBRARY_NAMES=parmetis;metis',
'-DTPL_ParMETIS_INCLUDE_DIRS=%s' % spec['parmetis'].prefix.include '-DTPL_ParMETIS_INCLUDE_DIRS=%s' % (
spec['parmetis'].prefix.include)
]) ])
else: else:
options.extend([ options.extend([
@ -184,11 +214,14 @@ def install(self, spec, prefix):
options.extend([ options.extend([
'-DTPL_ENABLE_MUMPS:BOOL=ON', '-DTPL_ENABLE_MUMPS:BOOL=ON',
'-DMUMPS_LIBRARY_DIRS=%s' % spec['mumps'].prefix.lib, '-DMUMPS_LIBRARY_DIRS=%s' % spec['mumps'].prefix.lib,
'-DMUMPS_LIBRARY_NAMES=dmumps;mumps_common;pord', # order is important! # order is important!
'-DMUMPS_LIBRARY_NAMES=dmumps;mumps_common;pord',
'-DTPL_ENABLE_SCALAPACK:BOOL=ON', '-DTPL_ENABLE_SCALAPACK:BOOL=ON',
'-DSCALAPACK_LIBRARY_NAMES=scalapack' # FIXME: for MKL it's mkl_scalapack_lp64;mkl_blacs_mpich_lp64 # FIXME: for MKL it's mkl_scalapack_lp64;mkl_blacs_mpich_lp64
'-DSCALAPACK_LIBRARY_NAMES=scalapack'
]) ])
# see https://github.com/trilinos/Trilinos/blob/master/packages/amesos/README-MUMPS # see
# https://github.com/trilinos/Trilinos/blob/master/packages/amesos/README-MUMPS
cxx_flags.extend([ cxx_flags.extend([
'-DMUMPS_5_0' '-DMUMPS_5_0'
]) ])
@ -201,16 +234,20 @@ def install(self, spec, prefix):
# superlu-dist: # superlu-dist:
if '+superlu-dist' in spec: if '+superlu-dist' in spec:
# Amesos, conflicting types of double and complex SLU_D # Amesos, conflicting types of double and complex SLU_D
# see https://trilinos.org/pipermail/trilinos-users/2015-March/004731.html # see
# and https://trilinos.org/pipermail/trilinos-users/2015-March/004802.html # https://trilinos.org/pipermail/trilinos-users/2015-March/004731.html
# and
# https://trilinos.org/pipermail/trilinos-users/2015-March/004802.html
options.extend([ options.extend([
'-DTeuchos_ENABLE_COMPLEX:BOOL=OFF', '-DTeuchos_ENABLE_COMPLEX:BOOL=OFF',
'-DKokkosTSQR_ENABLE_Complex:BOOL=OFF' '-DKokkosTSQR_ENABLE_Complex:BOOL=OFF'
]) ])
options.extend([ options.extend([
'-DTPL_ENABLE_SuperLUDist:BOOL=ON', '-DTPL_ENABLE_SuperLUDist:BOOL=ON',
'-DSuperLUDist_LIBRARY_DIRS=%s' % spec['superlu-dist'].prefix.lib, '-DSuperLUDist_LIBRARY_DIRS=%s' %
'-DSuperLUDist_INCLUDE_DIRS=%s' % spec['superlu-dist'].prefix.include spec['superlu-dist'].prefix.lib,
'-DSuperLUDist_INCLUDE_DIRS=%s' %
spec['superlu-dist'].prefix.include
]) ])
if spec.satisfies('^superlu-dist@4.0:'): if spec.satisfies('^superlu-dist@4.0:'):
options.extend([ options.extend([
@ -221,7 +258,6 @@ def install(self, spec, prefix):
'-DTPL_ENABLE_SuperLUDist:BOOL=OFF', '-DTPL_ENABLE_SuperLUDist:BOOL=OFF',
]) ])
# python # python
if '+python' in spec: if '+python' in spec:
options.extend([ options.extend([
@ -248,23 +284,26 @@ def install(self, spec, prefix):
'-DTrilinos_ENABLE_FEI=OFF' '-DTrilinos_ENABLE_FEI=OFF'
]) ])
with working_dir('spack-build', create=True): with working_dir('spack-build', create=True):
cmake('..', *options) cmake('..', *options)
make() make()
make('install') make('install')
# When trilinos is built with Python, libpytrilinos is included through # When trilinos is built with Python, libpytrilinos is included
# cmake configure files. Namely, Trilinos_LIBRARIES in TrilinosConfig.cmake # through cmake configure files. Namely, Trilinos_LIBRARIES in
# contains pytrilinos. This leads to a run-time error: # TrilinosConfig.cmake contains pytrilinos. This leads to a
# Symbol not found: _PyBool_Type # run-time error: Symbol not found: _PyBool_Type and prevents
# and prevents Trilinos to be used in any C++ code, which links executable # Trilinos to be used in any C++ code, which links executable
# against the libraries listed in Trilinos_LIBRARIES. # against the libraries listed in Trilinos_LIBRARIES. See
# See https://github.com/Homebrew/homebrew-science/issues/2148#issuecomment-103614509 # https://github.com/Homebrew/homebrew-science/issues/2148#issuecomment-103614509
# A workaround it to remove PyTrilinos from the COMPONENTS_LIST : # A workaround it to remove PyTrilinos from the COMPONENTS_LIST :
if '+python' in self.spec: if '+python' in self.spec:
filter_file(r'(SET\(COMPONENTS_LIST.*)(PyTrilinos;)(.*)', (r'\1\3'), '%s/cmake/Trilinos/TrilinosConfig.cmake' % prefix.lib) filter_file(r'(SET\(COMPONENTS_LIST.*)(PyTrilinos;)(.*)',
(r'\1\3'),
'%s/cmake/Trilinos/TrilinosConfig.cmake' %
prefix.lib)
# The shared libraries are not installed correctly on Darwin; correct this # The shared libraries are not installed correctly on Darwin;
# correct this
if (sys.platform == 'darwin') and ('+shared' in spec): if (sys.platform == 'darwin') and ('+shared' in spec):
fix_darwin_install_name(prefix.lib) fix_darwin_install_name(prefix.lib)