* ceed bundle package including OCCA, MAGMA, Nek5000, mfem, and PETSc

Very preliminary, a lot of ad hoc decisions, fragile, missing functionality
All packages do build on my MacOS laptop with Cuda

Funded-by: ECP
Project: CEED
Time: 4 hours
Reported-by: Tzanio Kolev <kolev1@llnl.gov>

* Some adjustments in a few CEED-related packages.

This is still very preliminary, but with these changes I'm able to build from
scratch on a Mac laptop and a Linux desktop (RHEL7).

Note that there doesn't seem to be a good way to support CUDA in Spack, so
you'll have to install that manually yourself. You will also need a Fortran
compiler, in particular on a Mac where you also have to make sure that it
is being picked up in ~/.spack/darwin/compilers.yaml.

* ceed bundle package including OCCA, MAGMA, Nek5000, mfem, and PETSc

Very preliminary, a lot of ad hoc decisions, fragile, missing functionality
All packages do build on my MacOS laptop with Cuda

Funded-by: ECP
Project: CEED
Time: 4 hours
Reported-by: Tzanio Kolev <kolev1@llnl.gov>

* Reverting Mac-related CUDA checks in the OCCA and MAGMA packages.

A much better solution is to install CUDA manually and add it to
~/.spack/darwin/packages.yaml:

packages:
    cuda:
        paths:
            cuda@8.0.54: /usr/local/cuda

* Fix flake8 warnings

Funded-by: CEED
Project: CEED/Spack

* remove unneeded commented out code

Funded-by: CEED
Project: CEED/Spack

* Don't have PETSc use MUMPS to speedup install time, try parallel installs for Magma

Funded-by: CEED
Project: CEED/Spack

* Added libceed package and made changes to get the ceed metapackage up and running.

* Get the ceed package up and running and added installing the .h file in the libceed package.

* All packages are now pointed at specific versions (either tagged or git hashed.

* Changed some of the specific versions in the CEED metapackage.

* Some version updates.

* Applied Cameron Smith's patch for the latest pumi.

* Merge

* Nek5000: Use tarball instead of git tag

* Major update of the mfem package - needs more testing. Add a testing
shell script for mfem, test_builds.sh, in the mfem directory. It builds
a number of mfem configurations to ensure they all work.

Add 'suite-sparse' variant to petsc.

Add 'develop' version of libceed.

Add 'metis' variant of laghos.

Update the dependencies of ceed.

* Changes in petsc's handling of zlib to make the latest build work on Mac.

* [MFEM] When using '+libunwind', mfem needs '-ldl'.

* [OCCA] Remove debug print statements.

* [PETSc] Replace the check ('zlib' in spec) with ('+zlib' in spec) - the
latter checks if 'zlib' variant of petsc is enabled which is incorrect;
the former checks if petsc is configured to depend on 'zlib'.

* [MFEM] Add conduit variant.

* [libCEED] Enable testing using 'make prove'.

* [MFEM] Tweak test_builds.sh - all builds pass on fedora 27.

* Add a post install test

* Add a post installation check for NekCEM

* pumi: bump git hash, remove unused patch

* Fixed testing of Laghos package

* Adding variants in CEED package

* Empty file for URL didn't work on LLNL/LC. Replacing with bundle-package.txt -> README.md.

* [MFEM] If the spec defines the 'cxxflags' compiler flags, use that value
to set the CXXFLAGS value in the mfem build system.

* Disabling HDF5 by default.

You can still build it with "spack install ceed+hdf5".

* libceed: fix use of prefix versus DESTDIR

* Added cuda variant for libCEED (off by default)

* [libCEED] When building v0.1, fix ceed.pc before installing it.

* [CEED] Add variants for OCCA and PUMI. Replace the hdf5 variant with
a variant called quickbuild that disables variants in packages to
speedup the build - currently hdf5, boost, and superlu-dist in PETSc.

* [libCEED] Remove unused 'import os'.

* [MAGMA] Add version 2.3.0.

* [OCCA] Major update of occa/package.py.

* [libCEED] Several improvements.

* [CEED] Use fixed versions for occa and libceed.

* [OCCA] Fix a bug in CUDA setup.

* NekCEM doesn't need depends_on('python')

* [OCCA,libCEED,MFEM,CEED] Update occa and libceed versions plus a few
tweaks in occa and mfem.

* Switching to gslib-1.0.2 to fix summitdev bug.

* [Nek5000] Use the Fortran 77 compiler instead of the 'fc' compiler.
Propagate any 'fflags' and 'cflags' specifications to the Nek tools.

* [MFEM] Tweak for 'ppc64le'.

* attempt to override fips compatibility error for md5

* Compiler option changes in libCEED to fix summitdev build.

* Disable the nekcem install test until it can be fixed.

* [NekCEM] Major update of the package to fix various issues.

* [NekCEM] Fix formatting

* zoltan: remove non-portable -g0 flag

the pgi compiler does not accept it

* pumi: specify dependency on cmake > 3

* [Nek5000] Add dependency on libx11 when needed. Various hacks to
support IBM XL compilers.

* [NekCEM] Link with the pthreads library - it is required.

* [MAGMA] Add a patch for magma v2.3.0 when building with gcc <= 4.8.
Add dependency on BLAS.

* [CEED] Update to magma 2.3.0. When building with gcc < 4.9 constrain
the used suite-sparse version to <= 5.1.0 - starting with v5.2.0,
suite-sparse requires gcc >= 4.9.

* Small updates

* [libceed, gslib] Fix style

* [Nek5000] Need 'libxt' as a dependency as well.

* [MUMPS] Temporary workaround for ray.

* Updating occa and libceed to laters pre-1.0.0 and pre-0.2 hashes

* petsc: add pkg-config patch for variable quoting

Variable definitions in pkg-config are processed more like make than a
shell, so don't need quoting.  Older versions of pkg-config (<= 0.28)
did not remove the quotes when printing the value.

Freedesktop #67904 (https://bugs.freedesktop.org/show_bug.cgi?id=67904)

Reported-by: Tzanio Kolev <kolev1@llnl.gov>

* petsc: add 3.8.4 and myself as co-maintainer

* Updating libceed to latest pre-0.2 hash.

* [PETSc] Add the 'headers' and 'libs' properties.

* [MFEM] Explicitly add rpaths to link flags for external packages.
This is necessary when MFEM's exported options (in config.mk) are
used outside of Spack for linking against MFEM.

* Unset MFEM_DIR before building MFEM

* [PETSc] As observed by @jedbrown, there is no need to define the 'libs'
property explicitly - the default handler works fine too.

* Build MAGMA shared by default, install a few additional headers

* Forgot a self

* Switching to OCCA tag v1.0.0-alpha.4.

Adding urls for OCCA and libCEED ('spack uninstall' complains otherwise).

* Removed FIXMEs for OCCA tag

* [occa] Cleaned up tagged versions

* [libceed] Updated occa to v1.0.0-alpha.5

* [ceed] Updated occa to v1.0.0-alpha.5

* [libCEED] Always define the 'NDEBUG' makefile option based on the
'debug' variant setting - this should always work regardless of the
default setting inside the libceed makefile.

* [MUMPS] Revert a temporary workaround.

* [CEED, libCEED] Minor tweaks.

* libCEED v0.2 release

* [CEED] Use version 0.2 of libCEED.

* [HPGMG] Remove duplicate version.

* [CEED] Update the hpgmg version

* hpgmg: use tarball for 0.3

The Git repository contains somewhat heavy documentation so the tarballs
are much faster.

* hpgmg: +fe was default for the 0.3 release

* hpgmg: explicitly name build directory to avoid use of ambient PETSC_ARCH

* [HPGMG] Fix flake8 formatting

* libceed@0.2: work around occaFree issue
This commit is contained in:
Aaron Fisher
2018-03-31 00:47:32 -07:00
committed by Veselin Dobrev
parent b3f6015e32
commit b62ed20f3f
19 changed files with 1100 additions and 213 deletions

View File

@@ -22,22 +22,31 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import re
from spack import *
import os
import shutil
class Mfem(Package):
"""Free, lightweight, scalable C++ library for finite element methods."""
tags = ['FEM', 'finite elements', 'high-order', 'AMR', 'HPC']
homepage = 'http://www.mfem.org'
url = 'https://github.com/mfem/mfem'
maintainers = ['goxberry', 'tzanio', 'markcmiller86', 'acfisher',
'v-dobrev']
# Recommended mfem builds to test when updating this file: see the shell
# script 'test_builds.sh' in the same directory as this file.
# mfem is downloaded from a URL shortener at request of upstream
# author Tzanio Kolev <tzanio@llnl.gov>. See here:
# https://github.com/mfem/mfem/issues/53
#
# The following procedure should be used to verify security when a
# new verison is added:
# new version is added:
#
# 1. Verify that no checksums on old versions have changed.
#
@@ -51,6 +60,11 @@ class Mfem(Package):
# If this quick verification procedure fails, additional discussion
# will be required to verify the new version.
# 'develop' is a special version that is always larger (or newer) than any
# other version.
version('develop',
git='https://github.com/mfem/mfem', branch='master')
version('3.3.2',
'01a762a5d0a2bc59ce4e2f59009045a4',
url='https://goo.gl/Kd7Jk8', extension='.tar.gz',
@@ -71,8 +85,19 @@ class Mfem(Package):
'841ea5cf58de6fae4de0f553b0e01ebaab9cd9c67fa821e8a715666ecf18fc57',
url='http://goo.gl/xrScXn', extension='.tar.gz')
variant('static', default=True,
description='Build static library')
variant('shared', default=False,
description='Build shared library')
variant('mpi', default=True,
description='Enable MPI parallelism')
# Can we make the default value for 'metis' to depend on the 'mpi' value?
variant('metis', default=True,
description='Enable METIS support')
# TODO: The 'hypre' variant is the same as 'mpi', we may want to remove it.
# For now, keep the 'hypre' variant while ignoring its setting. This
# is done to preserve compatibility with other packages that refer to
# it, e.g. xSDK.
variant('hypre', default=True,
description='Required for MPI parallelism')
variant('openmp', default=False,
@@ -83,10 +108,13 @@ class Mfem(Package):
' May cause minor performance issues.'))
variant('superlu-dist', default=False,
description='Enable MPI parallel, sparse direct solvers')
# Placeholder for STRUMPACK, support added in mfem v3.3.2:
# variant('strumpack', default=False,
# description='Enable support for STRUMPACK')
variant('suite-sparse', default=False,
description='Enable serial, sparse direct solvers')
variant('petsc', default=False,
description='Enable PETSc solvers, preconditioners, etc..')
description='Enable PETSc solvers, preconditioners, etc.')
variant('sundials', default=False,
description='Enable Sundials time integrators')
variant('mpfr', default=False,
@@ -97,43 +125,77 @@ class Mfem(Package):
description='Build debug instead of optimized version')
variant('netcdf', default=False,
description='Enable Cubit/Genesis reader')
variant('conduit', default=False,
description='Enable binary data I/O using Conduit')
variant('gzstream', default=True,
description='Support zip\'d streams for I/O')
variant('gnutls', default=False,
description='Enable secure sockets using GnuTLS')
variant('libunwind', default=False,
description='Enable backtrace on error support using Libunwind')
variant('timer', default='auto',
values=('auto', 'std', 'posix', 'mac', 'mpi'),
description='Timing functions to use in mfem::StopWatch')
variant('examples', default=False,
description='Build and install examples')
variant('miniapps', default=False,
description='Build and install miniapps')
conflicts('+mpi', when='~hypre')
conflicts('+suite-sparse', when='~lapack')
conflicts('+superlu-dist', when='@:3.1')
conflicts('+netcdf', when='@:3.1')
conflicts('+shared', when='@:3.3.2')
conflicts('~static~shared')
conflicts('~threadsafe', when='+openmp')
depends_on('hypre', when='+hypre')
depends_on('blas', when='+lapack')
depends_on('blas', when='+suite-sparse')
depends_on('lapack', when='+lapack')
depends_on('lapack', when='+suite-sparse')
conflicts('+netcdf', when='@:3.1')
conflicts('+superlu-dist', when='@:3.1')
conflicts('+gnutls', when='@:3.1')
conflicts('+gzstream', when='@:3.2')
conflicts('+mpfr', when='@:3.2')
conflicts('+petsc', when='@:3.2')
conflicts('+sundials', when='@:3.2')
conflicts('timer=mac', when='@:3.3.0')
conflicts('timer=mpi', when='@:3.3.0')
conflicts('~metis+mpi', when='@:3.3.0')
conflicts('+metis~mpi', when='@:3.3.0')
conflicts('+conduit', when='@:3.3.2')
conflicts('+superlu-dist', when='~mpi')
conflicts('+petsc', when='~mpi')
conflicts('timer=mpi', when='~mpi')
depends_on('mpi', when='+mpi')
depends_on('metis')
depends_on('parmetis', when='+superlu-dist')
depends_on('metis@5:', when='+superlu-dist')
depends_on('metis@5:', when='+suite-sparse ^suite-sparse@4.5:')
depends_on('hypre', when='+mpi')
depends_on('metis', when='+metis')
depends_on('blas', when='+lapack')
depends_on('lapack', when='+lapack')
depends_on('sundials@2.7:+hypre', when='+sundials')
depends_on('sundials@2.7.0', when='@:3.3.0+sundials~mpi')
depends_on('sundials@2.7.0+mpi+hypre', when='@:3.3.0+sundials+mpi')
depends_on('sundials@2.7.0:', when='@3.3.2:+sundials~mpi')
depends_on('sundials@2.7.0:+mpi+hypre', when='@3.3.2:+sundials+mpi')
depends_on('suite-sparse', when='+suite-sparse')
depends_on('superlu-dist', when='@3.2: +superlu-dist')
depends_on('petsc@3.8:', when='+petsc')
depends_on('superlu-dist', when='+superlu-dist')
# The PETSc tests in MFEM will fail if PETSc is not configured with
# SuiteSparse and MUMPS. On the other hand, if we require the variants
# '+suite-sparse+mumps' of PETSc, the xsdk package concretization fails.
depends_on('petsc@3.8:+mpi+double+hypre', when='+petsc')
# Recommended when building outside of xsdk:
# depends_on('petsc@3.8:+mpi+double+hypre+suite-sparse+mumps',
# when='+petsc')
depends_on('mpfr', when='+mpfr')
depends_on('netcdf', when='@3.2: +netcdf')
depends_on('zlib', when='@3.2: +netcdf')
depends_on('hdf5', when='@3.2: +netcdf')
depends_on('libunwind', when='+debug')
depends_on('netcdf', when='+netcdf')
depends_on('libunwind', when='+libunwind')
depends_on('zlib', when='+gzstream')
depends_on('gnutls', when='+gnutls')
depends_on('conduit@0.3.1:', when='+conduit')
depends_on('conduit+mpi', when='+conduit+mpi')
patch('mfem_ppc_build.patch', when='@3.2:3.3 arch=ppc64le')
patch('mfem_ppc_build.patch', when='@3.2:3.3.0 arch=ppc64le')
phases = ['configure', 'build', 'install']
def setup_environment(self, spack_env, run_env):
spack_env.unset('MFEM_DIR')
spack_env.unset('MFEM_BUILD_DIR')
#
# Note: Although MFEM does support CMake configuration, MFEM
@@ -142,30 +204,42 @@ class Mfem(Package):
# likely to be up to date in supporting *all* of MFEM's
# configuration options. So, don't use CMake
#
def install(self, spec, prefix):
def configure(self, spec, prefix):
def yes_no(varstr):
return 'YES' if varstr in self.spec else 'NO'
metis5_str = 'NO'
if '+superlu-dist' in spec or \
spec.satisfies('+suite-sparse ^suite-sparse@4.5:') or \
spec['metis'].satisfies('@5:'):
metis5_str = 'YES'
# We need to add rpaths explicitly to allow proper export of link flags
# from within MFEM.
threadsafe_str = 'NO'
if '+openmp' in spec or '+threadsafe' in spec:
threadsafe_str = 'YES'
# Similar to spec[pkg].libs.ld_flags but prepends rpath flags too.
def ld_flags_from_LibraryList(libs_list):
flags = ['-Wl,-rpath,%s' % dir for dir in libs_list.directories]
flags += [libs_list.ld_flags]
return ' '.join(flags)
def ld_flags_from_dirs(pkg_dirs_list, pkg_libs_list):
flags = ['-Wl,-rpath,%s' % dir for dir in pkg_dirs_list]
flags += ['-L%s' % dir for dir in pkg_dirs_list]
flags += ['-l%s' % lib for lib in pkg_libs_list]
return ' '.join(flags)
metis5_str = 'NO'
if ('+metis' in spec) and spec['metis'].satisfies('@5:'):
metis5_str = 'YES'
options = [
'PREFIX=%s' % prefix,
'MFEM_USE_MEMALLOC=YES',
'MFEM_DEBUG=%s' % yes_no('+debug'),
# NOTE: env['CXX'] is the spack c++ compiler wrapper. The real
# compiler is defined by env['SPACK_CXX'].
'CXX=%s' % env['CXX'],
'MFEM_USE_LIBUNWIND=%s' % yes_no('+debug'),
'MFEM_USE_LIBUNWIND=%s' % yes_no('+libunwind'),
'MFEM_USE_GZSTREAM=%s' % yes_no('+gzstream'),
'MFEM_USE_METIS=%s' % yes_no('+metis'),
'MFEM_USE_METIS_5=%s' % metis5_str,
'MFEM_THREAD_SAFE=%s' % threadsafe_str,
'MFEM_THREAD_SAFE=%s' % yes_no('+threadsafe'),
'MFEM_USE_MPI=%s' % yes_no('+mpi'),
'MFEM_USE_LAPACK=%s' % yes_no('+lapack'),
'MFEM_USE_SUPERLU=%s' % yes_no('+superlu-dist'),
@@ -174,115 +248,175 @@ def yes_no(varstr):
'MFEM_USE_PETSC=%s' % yes_no('+petsc'),
'MFEM_USE_NETCDF=%s' % yes_no('+netcdf'),
'MFEM_USE_MPFR=%s' % yes_no('+mpfr'),
'MFEM_USE_OPENMP=%s' % yes_no('+openmp')]
'MFEM_USE_GNUTLS=%s' % yes_no('+gnutls'),
'MFEM_USE_OPENMP=%s' % yes_no('+openmp'),
'MFEM_USE_CONDUIT=%s' % yes_no('+conduit')]
cxxflags = spec.compiler_flags['cxxflags']
if cxxflags:
# The cxxflags are set by the spack c++ compiler wrapper. We also
# set CXXFLAGS explicitly, for clarity, and to properly export the
# cxxflags in the variable MFEM_CXXFLAGS in config.mk.
options += ['CXXFLAGS=%s' % ' '.join(cxxflags)]
if '~static' in spec:
options += ['STATIC=NO']
if '+shared' in spec:
options += ['SHARED=YES', 'PICFLAG=%s' % self.compiler.pic_flag]
if '+mpi' in spec:
options += ['MPICXX=%s' % spec['mpi'].mpicxx]
if '+hypre' in spec:
hypre = spec['hypre']
hypre_flag_list = (hypre.libs +
hypre['lapack'].libs +
hypre['blas'].libs)
options += ['HYPRE_DIR=%s' % hypre.prefix,
'HYPRE_OPT=-I%s' % hypre.prefix.include,
'HYPRE_LIB=%s' % hypre_flag_list.ld_flags]
# The hypre package always links with 'blas' and 'lapack'.
all_hypre_libs = hypre.libs + hypre['lapack'].libs + \
hypre['blas'].libs
options += [
'HYPRE_OPT=-I%s' % hypre.prefix.include,
'HYPRE_LIB=%s' % ld_flags_from_LibraryList(all_hypre_libs)]
if '+metis' in spec:
options += [
'METIS_OPT=-I%s' % spec['metis'].prefix.include,
'METIS_LIB=%s' %
ld_flags_from_dirs([spec['metis'].prefix.lib], ['metis'])]
if '+lapack' in spec:
lapack_lib = (spec['lapack'].libs + spec['blas'].libs).ld_flags # NOQA: ignore=E501
lapack_blas = spec['lapack'].libs + spec['blas'].libs
options += [
'LAPACK_OPT=-I%s' % spec['lapack'].prefix.include,
'LAPACK_LIB=%s' % lapack_lib]
# LAPACK_OPT is not used
'LAPACK_LIB=%s' % ld_flags_from_LibraryList(lapack_blas)]
if '+superlu-dist' in spec:
metis_lib = '-L%s -lparmetis -lmetis' % spec['parmetis'].prefix.lib
options += [
'METIS_DIR=%s' % spec['parmetis'].prefix,
'METIS_OPT=-I%s' % spec['parmetis'].prefix.include,
'METIS_LIB=%s' % metis_lib]
superlu_lib = '-L%s' % spec['superlu-dist'].prefix.lib
superlu_lib += ' -lsuperlu_dist'
options += [
'SUPERLU_DIR=%s' % spec['superlu-dist'].prefix,
'SUPERLU_OPT=-I%s' % spec['superlu-dist'].prefix.include,
'SUPERLU_LIB=%s' % superlu_lib]
else:
metis_lib = '-L%s -lmetis' % spec['metis'].prefix.lib
options += [
'METIS_DIR=%s' % spec['metis'].prefix,
'METIS_OPT=-I%s' % spec['metis'].prefix.include,
'METIS_LIB=%s' % metis_lib]
'SUPERLU_OPT=-I%s -I%s' %
(spec['superlu-dist'].prefix.include,
spec['parmetis'].prefix.include),
'SUPERLU_LIB=-L%s -L%s -lsuperlu_dist -lparmetis' %
(spec['superlu-dist'].prefix.lib,
spec['parmetis'].prefix.lib)]
if '+suite-sparse' in spec:
ssp = spec['suite-sparse'].prefix
ss_lib = '-L%s' % ssp.lib
if '@3.2:' in spec:
ss_lib += ' -lklu -lbtf'
ss_lib += (' -lumfpack -lcholmod -lcolamd' +
' -lamd -lcamd -lccolamd -lsuitesparseconfig')
no_rt = spec.satisfies('platform=darwin')
if not no_rt:
ss_lib += ' -lrt'
ss_lib += (' ' + metis_lib + ' ' + lapack_lib)
ss_spec = 'suite-sparse:' + self.suitesparse_components
options += [
'SUITESPARSE_DIR=%s' % ssp,
'SUITESPARSE_OPT=-I%s' % ssp.include,
'SUITESPARSE_LIB=%s' % ss_lib]
'SUITESPARSE_OPT=-I%s' % spec[ss_spec].prefix.include,
'SUITESPARSE_LIB=%s' %
ld_flags_from_LibraryList(spec[ss_spec].libs)]
if '+sundials' in spec:
sundials_libs = (
'-lsundials_arkode -lsundials_cvode'
' -lsundials_nvecserial -lsundials_kinsol')
if '+mpi' in spec:
sundials_libs += (
' -lsundials_nvecparhyp -lsundials_nvecparallel')
sun_spec = 'sundials:' + self.sundials_components
options += [
'SUNDIALS_DIR=%s' % spec['sundials'].prefix,
'SUNDIALS_OPT=-I%s' % spec['sundials'].prefix.include,
'SUNDIALS_LIB=-L%s %s' % (spec['sundials'].prefix.lib,
sundials_libs)]
'SUNDIALS_OPT=%s' % spec[sun_spec].headers.cpp_flags,
'SUNDIALS_LIB=%s' %
ld_flags_from_LibraryList(spec[sun_spec].libs)]
if '+petsc' in spec:
f = open('%s/lib/pkgconfig/PETSc.pc' % spec['petsc'].prefix, 'r')
for line in f:
if re.search('^\s*Cflags: ', line):
petsc_opts = re.sub('^\s*Cflags: (.*)', '\\1', line)
elif re.search('^\s*Libs.*: ', line):
petsc_libs = re.sub('^\s*Libs.*: (.*)', '\\1', line)
f.close()
# options += ['PETSC_DIR=%s' % spec['petsc'].prefix]
options += [
'PETSC_DIR=%s' % spec['petsc'].prefix,
'PETSC_OPT=%s' % petsc_opts,
'PETSC_LIB=-L%s -lpetsc %s' %
(spec['petsc'].prefix.lib, petsc_libs)]
'PETSC_OPT=%s' % spec['petsc'].headers.cpp_flags,
'PETSC_LIB=%s' %
ld_flags_from_LibraryList(spec['petsc'].libs)]
if '+netcdf' in spec:
np = spec['netcdf'].prefix
zp = spec['zlib'].prefix
h5p = spec['hdf5'].prefix
nlib = '-L%s -lnetcdf ' % np.lib
nlib += '-L%s -lhdf5_hl -lhdf5 ' % h5p.lib
nlib += '-L%s -lz' % zp.lib
options += [
'NETCDF_DIR=%s' % np,
'HDF5_DIR=%s' % h5p,
'ZLIB_DIR=%s' % zp,
'NETCDF_OPT=-I%s' % np.include,
'NETCDF_LIB=%s' % nlib]
'NETCDF_OPT=-I%s' % spec['netcdf'].prefix.include,
'NETCDF_LIB=%s' %
ld_flags_from_dirs([spec['netcdf'].prefix.lib], ['netcdf'])]
if '+gzstream' in spec:
if "@:3.3.2" in spec:
options += ['ZLIB_DIR=%s' % spec['zlib'].prefix]
else:
options += [
'ZLIB_OPT=-I%s' % spec['zlib'].prefix.include,
'ZLIB_LIB=%s' %
ld_flags_from_LibraryList(spec['zlib'].libs)]
if '+mpfr' in spec:
options += ['MPFR_LIB=-L%s -lmpfr' % spec['mpfr'].prefix.lib]
options += [
'MPFR_OPT=-I%s' % spec['mpfr'].prefix.include,
'MPFR_LIB=%s' %
ld_flags_from_dirs([spec['mpfr'].prefix.lib], ['mpfr'])]
if '+gnutls' in spec:
options += [
'GNUTLS_OPT=-I%s' % spec['gnutls'].prefix.include,
'GNUTLS_LIB=%s' %
ld_flags_from_dirs([spec['gnutls'].prefix.lib], ['gnutls'])]
if '+libunwind' in spec:
libunwind = spec['libunwind']
headers = find_headers('libunwind', libunwind.prefix.include)
headers.add_macro('-g')
libs = find_libraries('libunwind', libunwind.prefix.lib,
shared=True, recursive=True)
if not libs:
libs = find_libraries('libunwind', libunwind.prefix.lib,
shared=False, recursive=True)
# When mfem uses libunwind, it also needs 'libdl'.
libs += LibraryList(find_system_libraries('libdl'))
options += [
'LIBUNWIND_OPT=%s' % headers.cpp_flags,
'LIBUNWIND_LIB=%s' % ld_flags_from_LibraryList(libs)]
if '+openmp' in spec:
options += ['OPENMP_OPT = %s' % self.compiler.openmp_flag]
options += ['OPENMP_OPT=%s' % self.compiler.openmp_flag]
make('config', *options)
timer_ids = {'std': '0', 'posix': '2', 'mac': '4', 'mpi': '6'}
timer = spec.variants['timer'].value
if timer != 'auto':
options += ['MFEM_TIMER_TYPE=%s' % timer_ids[timer]]
if '+conduit' in spec:
conduit = spec['conduit']
headers = HeaderList(find(conduit.prefix.include, 'conduit.hpp',
recursive=True))
conduit_libs = ['libconduit', 'libconduit_relay',
'libconduit_blueprint']
libs = find_libraries(conduit_libs, conduit.prefix.lib,
shared=('+shared' in conduit))
libs += LibraryList(find_system_libraries('libdl'))
if '+hdf5' in conduit:
hdf5 = conduit['hdf5']
headers += find_headers('hdf5', hdf5.prefix.include)
libs += hdf5.libs
options += [
'CONDUIT_OPT=%s' % headers.cpp_flags,
'CONDUIT_LIB=%s' % ld_flags_from_LibraryList(libs)]
make('config', *options, parallel=False)
make('info', parallel=False)
def build(self, spec, prefix):
make('lib')
if self.run_tests:
make('check')
@run_after('build')
def check_or_test(self):
# Running 'make check' or 'make test' may fail if MFEM_MPIEXEC or
# MFEM_MPIEXEC_NP are not set appropriately.
if not self.run_tests:
# check we can build ex1 (~mpi) or ex1p (+mpi).
make('-C', 'examples', 'ex1p' if ('+mpi' in self.spec) else 'ex1',
parallel=False)
# make('check', parallel=False)
else:
make('all')
make('test', parallel=False)
make('install')
def install(self, spec, prefix):
make('install', parallel=False)
# TODO: The way the examples and miniapps are being installed is not
# perfect. For example, the makefiles do not work.
install_em = ('+examples' in spec) or ('+miniapps' in spec)
if install_em and ('+shared' in spec):
make('examples/clean', 'miniapps/clean')
# This is a hack to get the examples and miniapps to link with the
# installed shared mfem library:
with working_dir('config'):
os.rename('config.mk', 'config.mk.orig')
shutil.copyfile(str(self.config_mk), 'config.mk')
shutil.copystat('config.mk.orig', 'config.mk')
if '+examples' in spec:
make('examples')
@@ -291,3 +425,64 @@ def yes_no(varstr):
if '+miniapps' in spec:
make('miniapps')
install_tree('miniapps', join_path(prefix, 'miniapps'))
if install_em:
install_tree('data', join_path(prefix, 'data'))
@property
def suitesparse_components(self):
"""Return the SuiteSparse components needed by MFEM."""
ss_comps = 'umfpack,cholmod,colamd,amd,camd,ccolamd,suitesparseconfig'
if self.spec.satisfies('@3.2:'):
ss_comps = 'klu,btf,' + ss_comps
return ss_comps
@property
def sundials_components(self):
"""Return the SUNDIALS components needed by MFEM."""
sun_comps = 'arkode,cvode,nvecserial,kinsol'
if '+mpi' in self.spec:
sun_comps += ',nvecparhyp,nvecparallel'
return sun_comps
@property
def headers(self):
"""Export the main mfem header, mfem.hpp.
"""
hdrs = HeaderList(find(self.prefix.include, 'mfem.hpp',
recursive=False))
return hdrs or None
@property
def libs(self):
"""Export the mfem library file.
"""
libs = find_libraries('libmfem', root=self.prefix.lib,
shared=('+shared' in self.spec), recursive=False)
return libs or None
@property
def config_mk(self):
"""Export the location of the config.mk file.
This property can be accessed using spec['mfem'].package.config_mk
"""
dirs = [self.prefix, self.prefix.share.mfem]
for d in dirs:
f = join_path(d, 'config.mk')
if os.access(f, os.R_OK):
return FileList(f)
return FileList(find(self.prefix, 'config.mk', recursive=True))
@property
def test_mk(self):
"""Export the location of the test.mk file.
This property can be accessed using spec['mfem'].package.test_mk.
In version 3.3.2 and newer, the location of test.mk is also defined
inside config.mk, variable MFEM_TEST_MK.
"""
dirs = [self.prefix, self.prefix.share.mfem]
for d in dirs:
f = join_path(d, 'test.mk')
if os.access(f, os.R_OK):
return FileList(f)
return FileList(find(self.prefix, 'test.mk', recursive=True))

View File

@@ -0,0 +1,72 @@
#!/bin/bash
builds=(
# preferred version:
'mfem'
'mfem~mpi~metis~gzstream'
'mfem+mpi+superlu-dist+suite-sparse+petsc \
+sundials+mpfr+netcdf+gzstream+gnutls+libunwind \
^hypre~internal-superlu ^petsc~boost+suite-sparse+mumps'
'mfem~mpi+suite-sparse+sundials+mpfr+netcdf \
+gzstream+gnutls+libunwind'
# develop version:
'mfem@develop+shared~static'
'mfem@develop+shared~static~mpi~metis~gzstream'
# TODO: Replace '^conduit~python~hdf5' with '^conduit~python' when conduit
# is fixed to accept '^hdf5+mpi'.
'mfem@develop+shared~static+mpi \
+superlu-dist+suite-sparse+petsc+sundials+mpfr+netcdf+gzstream \
+gnutls+libunwind+conduit ^hypre~internal-superlu \
^petsc~boost+suite-sparse+mumps ^conduit~python~hdf5'
# TODO: The options '^netcdf~mpi ^hdf5@1.8.19~mpi' are added just to make
# conduit happy.
'mfem@develop+shared~static~mpi \
+suite-sparse+sundials+mpfr+netcdf+gzstream+gnutls+libunwind \
+conduit ^conduit~python ^netcdf~mpi ^hdf5@1.8.19~mpi'
)
builds2=(
# preferred version
'mfem+superlu-dist'
'mfem+suite-sparse~mpi'
'mfem+suite-sparse'
'mfem+sundials~mpi'
'mfem+sundials'
'mfem+netcdf~mpi'
'mfem+netcdf'
'mfem+mpfr'
'mfem+gnutls'
'mfem+petsc+mpi ^hypre~internal-superlu ^petsc~boost+suite-sparse+mumps'
# develop version
'mfem@develop+superlu-dist'
'mfem@develop+suite-sparse~mpi'
'mfem@develop+suite-sparse'
'mfem@develop+sundials~mpi'
'mfem@develop+sundials'
'mfem@develop+netcdf~mpi'
'mfem@develop+netcdf'
'mfem@develop+mpfr'
'mfem@develop+gnutls'
'mfem@develop+conduit~mpi ^conduit~python'
'mfem@develop+conduit ^conduit~python'
'mfem@develop+petsc+mpi ^hypre~internal-superlu \
^petsc~boost+suite-sparse+mumps'
)
trap 'printf "\nScript interrupted.\n"; exit 33' INT
SEP='=========================================================================='
sep='--------------------------------------------------------------------------'
for bld in "${builds[@]}" "${builds2[@]}"; do
printf "\n%s\n" "${SEP}"
printf " %s\n" "${bld}"
printf "%s\n" "${SEP}"
eval bbb="\"${bld}\""
spack spec -I $bbb || exit 1
printf "%s\n" "${sep}"
spack install --test=root $bbb || exit 2
done
# Uninstall all mfem builds:
# spack uninstall --all mfem