deal.II: Further modernisation and improvements (#19253)

This commit is contained in:
Jean-Paul Pelteret 2020-10-11 21:48:09 +02:00 committed by GitHub
parent cc136c27a9
commit fe239c83fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -101,7 +101,7 @@ class Dealii(CMakePackage, CudaPackage):
variant('trilinos', default=True, variant('trilinos', default=True,
description='Compile with Trilinos (only with MPI)') description='Compile with Trilinos (only with MPI)')
# required dependencies, light version # Required dependencies: Light version
depends_on('blas') depends_on('blas')
# Boost 1.58 is blacklisted, require at least 1.59, see # Boost 1.58 is blacklisted, require at least 1.59, see
# https://github.com/dealii/dealii/issues/1591 # https://github.com/dealii/dealii/issues/1591
@ -144,7 +144,7 @@ class Dealii(CMakePackage, CudaPackage):
# Optional dependencies: Configuration # Optional dependencies: Configuration
depends_on('cuda@8:', when='+cuda') depends_on('cuda@8:', when='+cuda')
depends_on('cmake@3.9:', when='+cuda', type='build') depends_on('cmake@3.9:', when='+cuda', type='build')
# older version of deal.II do not build with Cmake 3.10, see # Older version of deal.II do not build with Cmake 3.10, see
# https://github.com/dealii/dealii/issues/5510 # https://github.com/dealii/dealii/issues/5510
depends_on('cmake@:3.9.99', when='@:8.99', type='build') depends_on('cmake@:3.9.99', when='@:8.99', type='build')
depends_on('mpi', when='+mpi') depends_on('mpi', when='+mpi')
@ -222,14 +222,14 @@ class Dealii(CMakePackage, CudaPackage):
conflicts('cxxstd=98', when='@9.0:') conflicts('cxxstd=98', when='@9.0:')
conflicts('cxxstd=11', when='@9.3:') conflicts('cxxstd=11', when='@9.3:')
# interfaces added in 8.5.0: # Interfaces added in 8.5.0:
for p in ['gsl', 'python']: for p in ['gsl', 'python']:
conflicts('+{0}'.format(p), when='@:8.4.2', conflicts('+{0}'.format(p), when='@:8.4.2',
msg='The interface to {0} is supported from version 8.5.0 ' msg='The interface to {0} is supported from version 8.5.0 '
'onwards. Please explicitly disable this variant ' 'onwards. Please explicitly disable this variant '
'via ~{0}'.format(p)) 'via ~{0}'.format(p))
# interfaces added in 9.0.0: # Interfaces added in 9.0.0:
for p in ['assimp', 'gmsh', 'nanoflann', 'scalapack', 'sundials', for p in ['assimp', 'gmsh', 'nanoflann', 'scalapack', 'sundials',
'adol-c']: 'adol-c']:
conflicts('+{0}'.format(p), when='@:8.5.1', conflicts('+{0}'.format(p), when='@:8.5.1',
@ -244,12 +244,12 @@ class Dealii(CMakePackage, CudaPackage):
'onwards. Please explicitly disable this variant ' 'onwards. Please explicitly disable this variant '
'via ~{0}'.format(p)) 'via ~{0}'.format(p))
# interfaces removed in 9.3.0: # Interfaces removed in 9.3.0:
conflicts('+nanoflann', when='@9.3.0:', conflicts('+nanoflann', when='@9.3.0:',
msg='The interface to nanoflann was removed from version 9.3.0. ' msg='The interface to Nanoflann was removed from version 9.3.0. '
'Please explicitly disable this variant via ~nanoflann') 'Please explicitly disable this variant via ~nanoflann')
# check that the combination of variants makes sense # Check that the combination of variants makes sense
# 64-bit BLAS: # 64-bit BLAS:
for p in ['openblas', 'intel-mkl', 'intel-parallel-studio+mkl']: for p in ['openblas', 'intel-mkl', 'intel-parallel-studio+mkl']:
conflicts('^{0}+ilp64'.format(p), when='@:8.5.1', conflicts('^{0}+ilp64'.format(p), when='@:8.5.1',
@ -274,61 +274,68 @@ class Dealii(CMakePackage, CudaPackage):
def cmake_args(self): def cmake_args(self):
spec = self.spec spec = self.spec
options = [] options = []
# release flags # Release flags
cxx_flags_release = [] cxx_flags_release = []
# debug and release flags # Debug and release flags
cxx_flags = [] cxx_flags = []
# Set directory structure: # Set directory structure:
if spec.satisfies('@:8.2.1'): if spec.satisfies('@:8.2.1'):
options.extend(['-DDEAL_II_COMPONENT_COMPAT_FILES=OFF']) options.append(
self.define('DEAL_II_COMPONENT_COMPAT_FILES', False)
)
else: else:
options.extend([ options.extend([
'-DDEAL_II_EXAMPLES_RELDIR=share/deal.II/examples', self.define(
'-DDEAL_II_DOCREADME_RELDIR=share/deal.II/', 'DEAL_II_EXAMPLES_RELDIR', 'share/deal.II/examples'
'-DDEAL_II_DOCHTML_RELDIR=share/deal.II/doc' ),
self.define('DEAL_II_DOCREADME_RELDIR', 'share/deal.II/'),
self.define('DEAL_II_DOCHTML_RELDIR', 'share/deal.II/doc')
]) ])
# Required dependencies # Required dependencies
lapack_blas_libs = spec['lapack'].libs + spec['blas'].libs lapack_blas_libs = spec['lapack'].libs + spec['blas'].libs
lapack_blas_headers = spec['lapack'].headers + spec['blas'].headers lapack_blas_headers = spec['lapack'].headers + spec['blas'].headers
options.extend([ options.extend([
'-DBOOST_DIR=%s' % spec['boost'].prefix, self.define('BOOST_DIR', spec['boost'].prefix),
# CMake's FindBlas/Lapack may pickup system's blas/lapack instead # CMake's FindBlas/Lapack may pickup system's blas/lapack instead
# of Spack's. Be more specific to avoid this. # of Spack's. Be more specific to avoid this.
# Note that both lapack and blas are provided in -DLAPACK_XYZ. # Note that both lapack and blas are provided in -DLAPACK_XYZ.
'-DLAPACK_FOUND=true', self.define('LAPACK_FOUND', True),
'-DLAPACK_INCLUDE_DIRS=%s' % ';'.join( self.define(
lapack_blas_headers.directories), 'LAPACK_INCLUDE_DIRS', lapack_blas_headers.directories
'-DLAPACK_LIBRARIES=%s' % lapack_blas_libs.joined(';'), ),
'-DUMFPACK_DIR=%s' % spec['suite-sparse'].prefix, self.define('LAPACK_LIBRARIES', lapack_blas_libs),
'-DZLIB_DIR=%s' % spec['zlib'].prefix, self.define('UMFPACK_DIR', spec['suite-sparse'].prefix),
'-DDEAL_II_ALLOW_BUNDLED=OFF' self.define('ZLIB_DIR', spec['zlib'].prefix),
self.define('DEAL_II_ALLOW_BUNDLED', False)
]) ])
if spec.satisfies('@:8.99'): if spec.satisfies('@:8.99'):
options.extend([ options.extend([
# Cmake may still pick up system's bzip2, fix this: # Cmake may still pick up system's bzip2, fix this:
'-DBZIP2_FOUND=true', self.define('BZIP2_FOUND', True),
'-DBZIP2_INCLUDE_DIRS=%s' % spec['bzip2'].prefix.include, self.define(
'-DBZIP2_LIBRARIES=%s' % spec['bzip2'].libs.joined(';') 'BZIP2_INCLUDE_DIRS', spec['bzip2'].prefix.include
),
self.define('BZIP2_LIBRARIES', spec['bzip2'].libs)
]) ])
# Doxygen documentation # Doxygen documentation
options.append(self.define_from_variant( options.append(self.define_from_variant(
'DEAL_II_COMPONENT_DOCUMENTATION', 'doc') 'DEAL_II_COMPONENT_DOCUMENTATION', 'doc'
) ))
# Examples / tutorial programs # Examples / tutorial programs
options.append(self.define_from_variant( options.append(self.define_from_variant(
'DEAL_II_COMPONENT_EXAMPLES', 'examples') 'DEAL_II_COMPONENT_EXAMPLES', 'examples'
) ))
# Enforce the specified C++ standard # Enforce the specified C++ standard
if spec.variants['cxxstd'].value != 'default': if spec.variants['cxxstd'].value != 'default':
cxxstd = spec.variants['cxxstd'].value cxxstd = spec.variants['cxxstd'].value
options.append( options.append(
'-DDEAL_II_WITH_CXX{0}:BOOL=ON'.format(cxxstd) self.define('DEAL_II_WITH_CXX{0}'.format(cxxstd), True)
) )
# Performance # Performance
@ -343,19 +350,21 @@ def cmake_args(self):
# 64 bit indices # 64 bit indices
options.append(self.define_from_variant( options.append(self.define_from_variant(
'DEAL_II_WITH_64BIT_INDICES', 'int64') 'DEAL_II_WITH_64BIT_INDICES', 'int64'
) ))
if (spec.satisfies('^openblas+ilp64') or if (spec.satisfies('^openblas+ilp64') or
spec.satisfies('^intel-mkl+ilp64') or spec.satisfies('^intel-mkl+ilp64') or
spec.satisfies('^intel-parallel-studio+mkl+ilp64')): spec.satisfies('^intel-parallel-studio+mkl+ilp64')):
options.append('-DLAPACK_WITH_64BIT_BLAS_INDICES=ON') options.append(
self.define('LAPACK_WITH_64BIT_BLAS_INDICES', True)
)
# CUDA # CUDA
options.append(self.define_from_variant(
'DEAL_II_WITH_CUDA', 'cuda'
))
if '+cuda' in spec: if '+cuda' in spec:
options.append(
'-DDEAL_II_WITH_CUDA=ON'
)
if not spec.satisfies('^cuda@9:'): if not spec.satisfies('^cuda@9:'):
options.append('-DDEAL_II_WITH_CXX14=OFF') options.append('-DDEAL_II_WITH_CXX14=OFF')
cuda_arch = spec.variants['cuda_arch'].value cuda_arch = spec.variants['cuda_arch'].value
@ -369,62 +378,58 @@ def cmake_args(self):
# with: flags = ' '.join(self.cuda_flags(cuda_arch)) # with: flags = ' '.join(self.cuda_flags(cuda_arch))
# Stick with -arch=sm_xy for now. # Stick with -arch=sm_xy for now.
options.append( options.append(
'-DDEAL_II_CUDA_FLAGS={0}'.format(flags) self.define('DEAL_II_CUDA_FLAGS', flags)
) )
else:
options.extend([
'-DDEAL_II_WITH_CUDA=OFF',
])
# MPI # MPI
options.append(self.define_from_variant(
'DEAL_II_WITH_MPI', 'mpi'
))
if '+mpi' in spec: if '+mpi' in spec:
options.extend([ options.extend([
'-DDEAL_II_WITH_MPI:BOOL=ON', self.define('CMAKE_C_COMPILER', spec['mpi'].mpicc),
'-DCMAKE_C_COMPILER=%s' % spec['mpi'].mpicc, self.define('CMAKE_CXX_COMPILER', spec['mpi'].mpicxx),
'-DCMAKE_CXX_COMPILER=%s' % spec['mpi'].mpicxx, self.define('CMAKE_Fortran_COMPILER', spec['mpi'].mpifc),
'-DCMAKE_Fortran_COMPILER=%s' % spec['mpi'].mpifc, self.define('MPI_C_COMPILER', spec['mpi'].mpicc),
'-DMPI_C_COMPILER=%s' % spec['mpi'].mpicc, self.define('MPI_CXX_COMPILER', spec['mpi'].mpicxx),
'-DMPI_CXX_COMPILER=%s' % spec['mpi'].mpicxx, self.define('MPI_Fortran_COMPILER', spec['mpi'].mpifc)
'-DMPI_Fortran_COMPILER=%s' % spec['mpi'].mpifc,
])
else:
options.extend([
'-DDEAL_II_WITH_MPI:BOOL=OFF',
]) ])
# Python bindings # Python bindings
if spec.satisfies('@8.5.0:'): if spec.satisfies('@8.5.0:'):
options.append(self.define_from_variant( options.append(self.define_from_variant(
'DEAL_II_COMPONENT_PYTHON_BINDINGS', 'python') 'DEAL_II_COMPONENT_PYTHON_BINDINGS', 'python'
) ))
if '+python' in spec: if '+python' in spec:
python_exe = spec['python'].command.path python_exe = spec['python'].command.path
python_library = spec['python'].libs[0] python_library = spec['python'].libs[0]
python_include = spec['python'].headers.directories[0] python_include = spec['python'].headers.directories[0]
options.extend([ options.extend([
'-DPYTHON_EXECUTABLE=%s' % python_exe, self.define('PYTHON_EXECUTABLE', python_exe),
'-DPYTHON_INCLUDE_DIR=%s' % python_include, self.define('PYTHON_INCLUDE_DIR', python_include),
'-DPYTHON_LIBRARY=%s' % python_library self.define('PYTHON_LIBRARY', python_library)
]) ])
# Threading # Threading
options.append(self.define_from_variant( options.append(self.define_from_variant(
'DEAL_II_WITH_THREADS', 'threads') 'DEAL_II_WITH_THREADS', 'threads'
) ))
if '+threads' in spec: if '+threads' in spec:
if (spec.satisfies('^intel-parallel-studio+tbb')): if (spec.satisfies('^intel-parallel-studio+tbb')):
# deal.II/cmake will have hard time picking up TBB from Intel. # deal.II/cmake will have hard time picking up TBB from Intel.
tbb_ver = '.'.join(('%s' % spec['tbb'].version).split('.')[1:]) tbb_ver = '.'.join(('%s' % spec['tbb'].version).split('.')[1:])
options.extend([ options.extend([
'-DTBB_FOUND=true', self.define('TBB_FOUND', True),
'-DTBB_VERSION=%s' % tbb_ver, self.define('TBB_VERSION', tbb_ver),
'-DTBB_INCLUDE_DIRS=%s' % ';'.join( self.define(
spec['tbb'].headers.directories), 'TBB_INCLUDE_DIRS', spec['tbb'].headers.directories
'-DTBB_LIBRARIES=%s' % spec['tbb'].libs.joined(';') ),
self.define('TBB_LIBRARIES', spec['tbb'].libs)
]) ])
else: else:
options.append('-DTBB_DIR=%s' % spec['tbb'].prefix) options.append(
self.define('TBB_DIR', spec['tbb'].prefix)
)
# Optional dependencies for which library names are the same as CMake # Optional dependencies for which library names are the same as CMake
# variables: # variables:
@ -432,98 +437,90 @@ def cmake_args(self):
'gsl', 'hdf5', 'p4est', 'petsc', 'slepc', 'trilinos', 'metis', 'gsl', 'hdf5', 'p4est', 'petsc', 'slepc', 'trilinos', 'metis',
'sundials', 'nanoflann', 'assimp', 'gmsh', 'muparser', 'sundials', 'nanoflann', 'assimp', 'gmsh', 'muparser',
'symengine', 'ginkgo'): 'symengine', 'ginkgo'):
options.append(self.define_from_variant(
'DEAL_II_WITH_{0}'.format(library.upper()), library
))
if ('+' + library) in spec: if ('+' + library) in spec:
options.extend([ options.append(self.define(
'-D%s_DIR=%s' % (library.upper(), spec[library].prefix), '{0}_DIR'.format(library.upper()), spec[library].prefix
'-DDEAL_II_WITH_%s:BOOL=ON' % library.upper() ))
])
else:
options.extend([
'-DDEAL_II_WITH_%s:BOOL=OFF' % library.upper()
])
# Optional dependencies that do not fit the above pattern: # Optional dependencies that do not fit the above pattern:
# ADOL-C # ADOL-C
options.append(self.define_from_variant(
'DEAL_II_WITH_ADOLC', 'adol-c'
))
if '+adol-c' in spec: if '+adol-c' in spec:
options.extend([ options.append(
'-DADOLC_DIR=%s' % spec['adol-c'].prefix, self.define('ADOLC_DIR', spec['adol-c'].prefix)
'-DDEAL_II_WITH_ADOLC=ON' )
])
else:
options.extend([
'-DDEAL_II_WITH_ADOLC=OFF'
])
# ARPACK # ARPACK
options.append(self.define_from_variant(
'DEAL_II_WITH_ARPACK', 'arpack'
))
if '+arpack' in spec and '+mpi' in spec: if '+arpack' in spec and '+mpi' in spec:
options.extend([ options.extend([
'-DARPACK_DIR=%s' % spec['arpack-ng'].prefix, self.define('ARPACK_DIR', spec['arpack-ng'].prefix),
'-DDEAL_II_WITH_ARPACK=ON', self.define('DEAL_II_ARPACK_WITH_PARPACK', True)
'-DDEAL_II_ARPACK_WITH_PARPACK=ON'
])
else:
options.extend([
'-DDEAL_II_WITH_ARPACK=OFF'
]) ])
# NetCDF # NetCDF
# since Netcdf is spread among two, need to do it by hand: # since Netcdf is spread among two, need to do it by hand:
if '+netcdf' in spec and '+mpi' in spec: if '+netcdf' in spec and '+mpi' in spec:
netcdf = spec['netcdf-cxx'].libs + spec['netcdf-c'].libs netcdf_libs = spec['netcdf-cxx'].libs + spec['netcdf-c'].libs
options.extend([ options.extend([
'-DNETCDF_FOUND=true', self.define('NETCDF_FOUND', True),
'-DNETCDF_LIBRARIES=%s' % netcdf.joined(';'), self.define('NETCDF_INCLUDE_DIRS', '{0};{1}'.format(
'-DNETCDF_INCLUDE_DIRS=%s;%s' % (
spec['netcdf-cxx'].prefix.include, spec['netcdf-cxx'].prefix.include,
spec['netcdf-c'].prefix.include), spec['netcdf-c'].prefix.include
)),
self.define('NETCDF_LIBRARIES', netcdf_libs)
]) ])
else: else:
options.extend([ options.append(
'-DDEAL_II_WITH_NETCDF=OFF' self.define('DEAL_II_WITH_NETCDF', False)
]) )
# ScaLAPACK # ScaLAPACK
options.append(self.define_from_variant(
'DEAL_II_WITH_SCALAPACK', 'scalapack'
))
if '+scalapack' in spec: if '+scalapack' in spec:
scalapack = spec['scalapack'].libs scalapack_libs = spec['scalapack'].libs
options.extend([ options.extend([
'-DSCALAPACK_FOUND=true', self.define('SCALAPACK_FOUND', True),
'-DSCALAPACK_INCLUDE_DIRS=%s' % ( self.define(
spec['scalapack'].prefix.include), 'SCALAPACK_INCLUDE_DIRS', spec['scalapack'].prefix.include
'-DSCALAPACK_LIBRARIES=%s' % scalapack.joined(';'), ),
'-DDEAL_II_WITH_SCALAPACK=ON' self.define('SCALAPACK_LIBRARIES', scalapack_libs)
])
else:
options.extend([
'-DDEAL_II_WITH_SCALAPACK=OFF'
]) ])
# Open Cascade # Open Cascade
options.append(self.define_from_variant(
'DEAL_II_WITH_OPENCASCADE', 'oce'
))
if '+oce' in spec: if '+oce' in spec:
options.extend([ options.append(
'-DOPENCASCADE_DIR=%s' % spec['oce'].prefix, self.define('OPENCASCADE_DIR', spec['oce'].prefix)
'-DDEAL_II_WITH_OPENCASCADE=ON' )
])
else:
options.extend([
'-DDEAL_II_WITH_OPENCASCADE=OFF'
])
# As a final step, collect CXX flags that may have been # As a final step, collect CXX flags that may have been
# added anywhere above: # added anywhere above:
if len(cxx_flags_release) > 0 and '+optflags' in spec: if len(cxx_flags_release) > 0 and '+optflags' in spec:
options.extend([ options.extend([
'-DCMAKE_CXX_FLAGS_RELEASE:STRING=%s' % ( self.define(
' '.join(cxx_flags_release)), 'CMAKE_CXX_FLAGS_RELEASE', ' '.join(cxx_flags_release)
'-DCMAKE_CXX_FLAGS:STRING=%s' % ( ),
' '.join(cxx_flags)) self.define('CMAKE_CXX_FLAGS', ' '.join(cxx_flags))
]) ])
# Add flags for machine vectorization, used when tutorials # Add flags for machine vectorization, used when tutorials
# and user code is built. # and user code is built.
# See https://github.com/dealii/dealii/issues/9164 # See https://github.com/dealii/dealii/issues/9164
options.extend([ options.append(
'-DDEAL_II_CXX_FLAGS=%s' % os.environ['SPACK_TARGET_ARGS'] self.define('DEAL_II_CXX_FLAGS', os.environ['SPACK_TARGET_ARGS'])
]) )
return options return options