summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/mfem
diff options
context:
space:
mode:
Diffstat (limited to 'var/spack/repos/builtin/packages/mfem')
-rw-r--r--var/spack/repos/builtin/packages/mfem/mfem-3.3-3.4-petsc-3.9.patch71
-rw-r--r--var/spack/repos/builtin/packages/mfem/mfem-3.4.patch36
-rw-r--r--var/spack/repos/builtin/packages/mfem/package.py482
-rwxr-xr-xvar/spack/repos/builtin/packages/mfem/test_builds.sh75
4 files changed, 525 insertions, 139 deletions
diff --git a/var/spack/repos/builtin/packages/mfem/mfem-3.3-3.4-petsc-3.9.patch b/var/spack/repos/builtin/packages/mfem/mfem-3.3-3.4-petsc-3.9.patch
new file mode 100644
index 0000000000..dcf4870a25
--- /dev/null
+++ b/var/spack/repos/builtin/packages/mfem/mfem-3.3-3.4-petsc-3.9.patch
@@ -0,0 +1,71 @@
+diff --git a/examples/petsc/rc_ex3p b/examples/petsc/rc_ex3p
+index 2cbe07ef2..c585d9b52 100644
+--- a/examples/petsc/rc_ex3p
++++ b/examples/petsc/rc_ex3p
+@@ -6,4 +6,4 @@
+ # it needs PETSc configured with MUMPS
+
+ -solver_pc_type cholesky
+--solver_pc_factor_mat_solver_package mumps
++-solver_pc_factor_mat_solver_type mumps
+diff --git a/examples/petsc/rc_ex3p_bddc b/examples/petsc/rc_ex3p_bddc
+index ea887bb29..2e1eba0d5 100644
+--- a/examples/petsc/rc_ex3p_bddc
++++ b/examples/petsc/rc_ex3p_bddc
+@@ -16,7 +16,7 @@
+ #-pc_bddc_adaptive_threshold 10
+
+ # Customization of the local solvers
+-#-pc_bddc_neumann_pc_factor_mat_solver_package mumps
+-#-pc_bddc_dirichlet_pc_factor_mat_solver_package mumps
++#-pc_bddc_neumann_pc_factor_mat_solver_type mumps
++#-pc_bddc_dirichlet_pc_factor_mat_solver_type mumps
+ #-pc_bddc_coarse_pc_type cholesky
+-#-pc_bddc_coarse_pc_factor_mat_solver_package mumps
++#-pc_bddc_coarse_pc_factor_mat_solver_type mumps
+diff --git a/examples/petsc/rc_ex4p b/examples/petsc/rc_ex4p
+index f734f35fe..64fbe9427 100644
+--- a/examples/petsc/rc_ex4p
++++ b/examples/petsc/rc_ex4p
+@@ -2,4 +2,4 @@
+ # it needs PETSc configured with MUMPS
+
+ -solver_pc_type cholesky
+--solver_pc_factor_mat_solver_package mumps
++-solver_pc_factor_mat_solver_type mumps
+diff --git a/examples/petsc/rc_ex4p_bddc b/examples/petsc/rc_ex4p_bddc
+index 9507ad431..e8ef99db7 100644
+--- a/examples/petsc/rc_ex4p_bddc
++++ b/examples/petsc/rc_ex4p_bddc
+@@ -13,7 +13,7 @@
+ #-pc_bddc_adaptive_threshold 10
+
+ # Customization of the local solvers
+-#-pc_bddc_neumann_pc_factor_mat_solver_package mumps
+-#-pc_bddc_dirichlet_pc_factor_mat_solver_package mumps
++#-pc_bddc_neumann_pc_factor_mat_solver_type mumps
++#-pc_bddc_dirichlet_pc_factor_mat_solver_type mumps
+ #-pc_bddc_coarse_pc_type cholesky
+-#-pc_bddc_coarse_pc_factor_mat_solver_package mumps
++#-pc_bddc_coarse_pc_factor_mat_solver_type mumps
+diff --git a/examples/petsc/rc_ex5p_bddc b/examples/petsc/rc_ex5p_bddc
+index b243c53c8..a4bc899c3 100644
+--- a/examples/petsc/rc_ex5p_bddc
++++ b/examples/petsc/rc_ex5p_bddc
+@@ -28,13 +28,13 @@
+ # local solvers (needs PETSc compiled with support for SuiteSparse)
+ # default solvers will fail
+ -prec_pc_bddc_neumann_pc_type lu
+--prec_pc_bddc_neumann_pc_factor_mat_solver_package umfpack
++-prec_pc_bddc_neumann_pc_factor_mat_solver_type umfpack
+ -prec_pc_bddc_dirichlet_pc_type lu
+--prec_pc_bddc_dirichlet_pc_factor_mat_solver_package umfpack
++-prec_pc_bddc_dirichlet_pc_factor_mat_solver_type umfpack
+
+ # coarse solver (needs PETSc compiled with support for MUMPS)
+ # default solver may fail
+--prec_pc_bddc_coarse_pc_factor_mat_solver_package mumps
++-prec_pc_bddc_coarse_pc_factor_mat_solver_type mumps
+ -prec_pc_bddc_coarse_pc_type cholesky
+
+ # deluxe scaling (needs PETSc compiled with support for MUMPS)
diff --git a/var/spack/repos/builtin/packages/mfem/mfem-3.4.patch b/var/spack/repos/builtin/packages/mfem/mfem-3.4.patch
new file mode 100644
index 0000000000..465e0525ea
--- /dev/null
+++ b/var/spack/repos/builtin/packages/mfem/mfem-3.4.patch
@@ -0,0 +1,36 @@
+diff --git a/config/test.mk b/config/test.mk
+index 4821b084d..62479fc63 100644
+--- a/config/test.mk
++++ b/config/test.mk
+@@ -14,11 +14,13 @@
+ # Colors used below:
+ # green '\033[0;32m'
+ # red '\033[0;31m'
++# yellow '\033[0;33m'
+ # no color '\033[0m'
+ COLOR_PRINT = if [ -t 1 ]; then \
+ printf $(1)$(2)'\033[0m'$(3); else printf $(2)$(3); fi
+ PRINT_OK = $(call COLOR_PRINT,'\033[0;32m',OK," ($$1 $$2)\n")
+ PRINT_FAILED = $(call COLOR_PRINT,'\033[0;31m',FAILED," ($$1 $$2)\n")
++PRINT_SKIP = $(call COLOR_PRINT,'\033[0;33m',SKIP,"\n")
+
+ # Timing support
+ define TIMECMD_detect
+diff --git a/examples/pumi/makefile b/examples/pumi/makefile
+index 2f98eeca7..5ff652aca 100644
+--- a/examples/pumi/makefile
++++ b/examples/pumi/makefile
+@@ -51,6 +51,13 @@ endif
+ MFEM_TESTS = EXAMPLES
+ include $(MFEM_TEST_MK)
+
++ifneq (,$(filter test%,$(MAKECMDGOALS)))
++ ifeq (,$(wildcard ../../data/pumi))
++ $(info PUMI data directory not found. The PUMI tests will be SKIPPED.)
++ mfem-test = printf " $(3) [$(2) $(1) ... ]: "; $(PRINT_SKIP)
++ endif
++endif
++
+ # Testing: Parallel vs. serial runs
+ RUN_MPI_NP = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP)
+ RUN_MPI = $(RUN_MPI_NP) $(MFEM_MPI_NP)
diff --git a/var/spack/repos/builtin/packages/mfem/package.py b/var/spack/repos/builtin/packages/mfem/package.py
index 3afbd4ca2f..d6f55b6566 100644
--- a/var/spack/repos/builtin/packages/mfem/package.py
+++ b/var/spack/repos/builtin/packages/mfem/package.py
@@ -1,43 +1,33 @@
-##############################################################################
-# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
-# Produced at the Lawrence Livermore National Laboratory.
+# Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
-# This file is part of Spack.
-# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
-# LLNL-CODE-647188
-#
-# For details, see https://github.com/spack/spack
-# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License (as
-# published by the Free Software Foundation) version 2.1, February 1999.
-#
-# This program 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 terms and
-# conditions of the GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# 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
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
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'
+ git = 'https://github.com/mfem/mfem.git'
+
+ 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,13 +41,20 @@ class Mfem(Package):
# If this quick verification procedure fails, additional discussion
# will be required to verify the new version.
- version('3.3.2',
- '01a762a5d0a2bc59ce4e2f59009045a4',
- url='https://goo.gl/Kd7Jk8', extension='.tar.gz',
+ # 'develop' is a special version that is always larger (or newer) than any
+ # other version.
+ version('develop', branch='master')
+
+ version('3.4.0',
+ '4e73e4fe0482636de3c5dc983cd395839a83cb16f6f509bd88b053e8b3858e05',
+ url='https://bit.ly/mfem-3-4', extension='.tar.gz',
preferred=True)
- version('laghos-v1.0', git='https://github.com/mfem/mfem',
- tag='laghos-v1.0')
+ version('3.3.2',
+ 'b70fa3c5080b9ec514fc05f4a04ff74322b99ac4ecd6d99c229f0ed5188fc0ce',
+ url='https://goo.gl/Kd7Jk8', extension='.tar.gz')
+
+ version('laghos-v1.0', tag='laghos-v1.0')
version('3.3',
'b17bd452593aada93dc0fee748fcfbbf4f04ce3e7d77fdd0341cc9103bcacd0b',
@@ -71,8 +68,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,12 +91,17 @@ 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('pumi', default=False,
+ description='Enable functionality based on PUMI')
variant('mpfr', default=False,
description='Enable precise, 1D quadrature rules')
variant('lapack', default=False,
@@ -97,43 +110,87 @@ 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('+shared', when='@:3.3.2')
+ conflicts('~static~shared')
+ conflicts('~threadsafe', when='+openmp')
+
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('+pumi', when='@:3.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('+pumi', when='~mpi')
+ conflicts('timer=mpi', when='~mpi')
+
+ conflicts('+pumi', when='+shared')
- depends_on('hypre', when='+hypre')
+ depends_on('mpi', when='+mpi')
+ depends_on('hypre@2.10.0:2.13.999', when='@:3.3.999+mpi')
+ depends_on('hypre', when='@3.4:+mpi')
+
+ depends_on('metis', when='+metis')
depends_on('blas', when='+lapack')
- depends_on('blas', when='+suite-sparse')
depends_on('lapack', when='+lapack')
- depends_on('lapack', when='+suite-sparse')
-
- 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('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('pumi', when='+pumi')
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('unwind', 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.0 arch=ppc64le')
+ patch('mfem-3.4.patch', when='@3.4.0')
+ patch('mfem-3.3-3.4-petsc-3.9.patch',
+ when='@3.3.0:3.4.0 +petsc ^petsc@3.9.0:')
- patch('mfem_ppc_build.patch', when='@3.2:3.3 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,144 +199,230 @@ 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.
+
+ # Similar to spec[pkg].libs.ld_flags but prepends rpath flags too.
+ def ld_flags_from_library_list(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)
+
+ def find_optional_library(name, prefix):
+ for shared in [True, False]:
+ for path in ['lib64', 'lib']:
+ lib = find_libraries(name, join_path(prefix, path),
+ shared=shared, recursive=False)
+ if lib:
+ return lib
+ return LibraryList([])
- threadsafe_str = 'NO'
- if '+openmp' in spec or '+threadsafe' in spec:
- threadsafe_str = 'YES'
+ 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'),
'MFEM_USE_SUITESPARSE=%s' % yes_no('+suite-sparse'),
'MFEM_USE_SUNDIALS=%s' % yes_no('+sundials'),
'MFEM_USE_PETSC=%s' % yes_no('+petsc'),
+ 'MFEM_USE_PUMI=%s' % yes_no('+pumi'),
'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]
+ hypre = spec['hypre']
+ # 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_library_list(all_hypre_libs)]
- if '+hypre' in spec:
+ if '+metis' in spec:
options += [
- 'HYPRE_DIR=%s' % spec['hypre'].prefix,
- 'HYPRE_OPT=-I%s' % spec['hypre'].prefix.include,
- 'HYPRE_LIB=-L%s' % spec['hypre'].prefix.lib + ' -lHYPRE']
+ '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_library_list(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'
+ lapack_blas = spec['lapack'].libs + spec['blas'].libs
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 %s' %
+ (spec['superlu-dist'].prefix.lib,
+ spec['parmetis'].prefix.lib,
+ ld_flags_from_library_list(lapack_blas))]
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_library_list(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_library_list(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_library_list(spec['petsc'].libs)]
+
+ if '+pumi' in spec:
+ options += ['PUMI_DIR=%s' % spec['pumi'].prefix]
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_library_list(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['unwind']
+ headers = find_headers('libunwind', libunwind.prefix.include)
+ headers.add_macro('-g')
+ libs = find_optional_library('libunwind', libunwind.prefix)
+ # 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_library_list(libs)]
if '+openmp' in spec:
- options += ['OPENMP_OPT = %s' % self.compiler.openmp_flag]
+ options += ['OPENMP_OPT=%s' % self.compiler.openmp_flag]
+
+ 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_library_list(libs)]
+
+ make('config', *options, parallel=False)
+ make('info', parallel=False)
- make('config', *options)
+ 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)
+
+ def install(self, spec, prefix):
+ make('install', parallel=False)
- make('install')
+ # 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')
+ copy(str(self.config_mk), 'config.mk')
+ shutil.copystat('config.mk.orig', 'config.mk')
if '+examples' in spec:
make('examples')
@@ -288,3 +431,64 @@ class Mfem(Package):
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))
diff --git a/var/spack/repos/builtin/packages/mfem/test_builds.sh b/var/spack/repos/builtin/packages/mfem/test_builds.sh
new file mode 100755
index 0000000000..125fa0055c
--- /dev/null
+++ b/var/spack/repos/builtin/packages/mfem/test_builds.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+builds=(
+ # preferred version:
+ 'mfem'
+ 'mfem~mpi~metis~gzstream'
+ 'mfem+mpi+superlu-dist+suite-sparse+petsc \
+ +sundials+pumi+mpfr+netcdf+gzstream+gnutls+libunwind \
+ ^hypre~internal-superlu ^petsc+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'.
+ # NOTE: Skip PUMI since it conflicts with '+shared'.
+ 'mfem@develop+shared~static+mpi \
+ +superlu-dist+suite-sparse+petsc+sundials+mpfr+netcdf+gzstream \
+ +gnutls+libunwind+conduit ^hypre~internal-superlu \
+ ^petsc+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+pumi'
+ 'mfem+netcdf~mpi'
+ 'mfem+netcdf'
+ 'mfem+mpfr'
+ 'mfem+gnutls'
+ 'mfem+petsc+mpi ^hypre~internal-superlu ^petsc+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+pumi'
+ '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+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