QMCPACK package: update blas/lapack detection (#6753)
* Fix detection of blas and lapack: provide libraries/includes as arguments to CMake rather than using CMake's auto-detection. This includes a patch to QMCPACK's CMake files to refer to Spack-built blas/lapack implementations. This also includes special-case logic for the intel-mkl implementation of blas/lapack * Break up unit tests and short tests. Only hard failure if the unit tests fail, if short tests fail issue a warning only. * Add QMCPACK 3.3.0, get rid of 3.0.0
This commit is contained in:
parent
0c1f4a7997
commit
24743b7e5a
55
var/spack/repos/builtin/packages/qmcpack/cmake.diff
Normal file
55
var/spack/repos/builtin/packages/qmcpack/cmake.diff
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
diff --git a/CMake/FindMKL.cmake b/CMake/FindMKL.cmake
|
||||||
|
index a457eaba0..66dc43ce6 100644
|
||||||
|
--- a/CMake/FindMKL.cmake
|
||||||
|
+++ b/CMake/FindMKL.cmake
|
||||||
|
@@ -7,21 +7,21 @@ FILE( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl.cxx"
|
||||||
|
"#include <iostream>\n #include <mkl.h>\n int main() { return 0; }\n" )
|
||||||
|
try_compile(HAVE_MKL ${CMAKE_BINARY_DIR}
|
||||||
|
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl.cxx
|
||||||
|
- CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" )
|
||||||
|
+ CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" "-DINCLUDE_DIRECTORIES=${LAPACK_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
# Check for mkl_vml_functions.h
|
||||||
|
FILE( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl_vml.cxx"
|
||||||
|
"#include <iostream>\n #include <mkl_vml_functions.h>\n int main() { return 0; }\n" )
|
||||||
|
try_compile(HAVE_MKL_VML ${CMAKE_BINARY_DIR}
|
||||||
|
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl_vml.cxx
|
||||||
|
- CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" )
|
||||||
|
+ CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" "-DINCLUDE_DIRECTORIES=${LAPACK_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
# Check for fftw3
|
||||||
|
FILE( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl_fftw3.cxx"
|
||||||
|
"#include <iostream>\n #include <fftw/fftw3.h>\n int main() { return 0; }\n" )
|
||||||
|
try_compile(HAVE_MKL_FFTW3 ${CMAKE_BINARY_DIR}
|
||||||
|
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl_fftw3.cxx
|
||||||
|
- CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" )
|
||||||
|
+ CMAKE_FLAGS "${CMAKE_CXX_FLAGS} -mkl" "-DINCLUDE_DIRECTORIES=${LAPACK_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
IF ( HAVE_MKL )
|
||||||
|
SET( MKL_FOUND 1 )
|
||||||
|
diff --git a/CMake/FindVectorMath.cmake b/CMake/FindVectorMath.cmake
|
||||||
|
index c0c919746..f5c511253 100644
|
||||||
|
--- a/CMake/FindVectorMath.cmake
|
||||||
|
+++ b/CMake/FindVectorMath.cmake
|
||||||
|
@@ -19,7 +19,7 @@ IF ( NOT HAVE_VECTOR_MATH )
|
||||||
|
"#include <iostream>\n #include <mkl_vml_functions.h>\n int main() { return 0; }\n" )
|
||||||
|
try_compile(HAVE_MKL_VML ${CMAKE_BINARY_DIR}
|
||||||
|
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src_mkl_vml.cxx
|
||||||
|
- CMAKE_FLAGS "${CMAKE_CXX_FLAGS}" )
|
||||||
|
+ CMAKE_FLAGS "${CMAKE_CXX_FLAGS}" "-DINCLUDE_DIRECTORIES=${LAPACK_INCLUDE_DIRS}")
|
||||||
|
IF (HAVE_MKL_VML)
|
||||||
|
# enable VML only when MKL libraries have been picked up
|
||||||
|
IF (MKL_FOUND)
|
||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 570d8a01f..56d939786 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -464,6 +464,8 @@ ELSE(CMAKE_TOOLCHAIN_FILE)
|
||||||
|
MESSAGE(STATUS "LAPACK libraries: ${LAPACK_LIBRARIES}")
|
||||||
|
MESSAGE(STATUS "LAPACK linker flags: ${LAPACK_LINKER_FLAGS}")
|
||||||
|
SET(LAPACK_LIBRARY ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS})
|
||||||
|
+ MESSAGE(STATUS "LAPACK_INCLUDE_DIRS: ${LAPACK_INCLUDE_DIRS}")
|
||||||
|
+ INCLUDE_DIRECTORIES(${LAPACK_INCLUDE_DIRS})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR "Could not find required libraries LAPACK &/or BLAS")
|
||||||
|
ENDIF()
|
@ -23,6 +23,7 @@
|
|||||||
# 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 llnl.util.tty as tty
|
||||||
|
|
||||||
|
|
||||||
class Qmcpack(CMakePackage):
|
class Qmcpack(CMakePackage):
|
||||||
@ -33,13 +34,14 @@ class Qmcpack(CMakePackage):
|
|||||||
homepage = "http://www.qmcpack.org/"
|
homepage = "http://www.qmcpack.org/"
|
||||||
url = "https://github.com/QMCPACK/qmcpack.git"
|
url = "https://github.com/QMCPACK/qmcpack.git"
|
||||||
|
|
||||||
# This download method is untrusted, and is not recommended
|
# This download method is untrusted, and is not recommended by the
|
||||||
# by the Spack manual. However, it is easier to maintain
|
# Spack manual. However, it is easier to maintain because github hashes
|
||||||
# because github hashes can occasionally change
|
# can occasionally change.
|
||||||
|
# NOTE: 12/19/2017 QMCPACK 3.0.0 does not build properly with Spack.
|
||||||
|
version('3.3.0', git=url, tag='v3.3.0')
|
||||||
version('3.2.0', git=url, tag='v3.2.0')
|
version('3.2.0', git=url, tag='v3.2.0')
|
||||||
version('3.1.1', git=url, tag='v3.1.1')
|
version('3.1.1', git=url, tag='v3.1.1')
|
||||||
version('3.1.0', git=url, tag='v3.1.0')
|
version('3.1.0', git=url, tag='v3.1.0')
|
||||||
version('3.0.0', git=url, tag='v3.0.0')
|
|
||||||
version('develop', git=url)
|
version('develop', git=url)
|
||||||
|
|
||||||
# These defaults match those in the QMCPACK manual
|
# These defaults match those in the QMCPACK manual
|
||||||
@ -57,7 +59,7 @@ class Qmcpack(CMakePackage):
|
|||||||
'Array-of-Structure code. Only for CPU code'
|
'Array-of-Structure code. Only for CPU code'
|
||||||
'and only in mixed precision')
|
'and only in mixed precision')
|
||||||
variant('timers', default=False,
|
variant('timers', default=False,
|
||||||
description='Build with support for timers')
|
description='Build with support for timers')
|
||||||
variant('da', default=False,
|
variant('da', default=False,
|
||||||
description='Install with support for basic data analysis tools')
|
description='Install with support for basic data analysis tools')
|
||||||
variant('gui', default=False,
|
variant('gui', default=False,
|
||||||
@ -72,7 +74,9 @@ class Qmcpack(CMakePackage):
|
|||||||
conflicts('^openblas+ilp64')
|
conflicts('^openblas+ilp64')
|
||||||
conflicts('^intel-mkl+ilp64')
|
conflicts('^intel-mkl+ilp64')
|
||||||
|
|
||||||
# Dependencies match those in the QMCPACK manual
|
# Dependencies match those in the QMCPACK manual.
|
||||||
|
# FIXME: once concretizer can unite unconditional and conditional
|
||||||
|
# dependencies the some of the '~mpi' will not be necessary.
|
||||||
depends_on('cmake@3.4.3:', type='build')
|
depends_on('cmake@3.4.3:', type='build')
|
||||||
depends_on('mpi', when='+mpi')
|
depends_on('mpi', when='+mpi')
|
||||||
depends_on('libxml2')
|
depends_on('libxml2')
|
||||||
@ -92,7 +96,7 @@ class Qmcpack(CMakePackage):
|
|||||||
# blas and lapack patching fails often and so are disabled at this time
|
# blas and lapack patching fails often and so are disabled at this time
|
||||||
depends_on('py-numpy~blas~lapack', type='run', when='+da')
|
depends_on('py-numpy~blas~lapack', type='run', when='+da')
|
||||||
|
|
||||||
# GUI is optional fpr data anlysis
|
# GUI is optional for data anlysis
|
||||||
# py-matplotlib leads to a long complex DAG for dependencies
|
# py-matplotlib leads to a long complex DAG for dependencies
|
||||||
depends_on('py-matplotlib', type='run', when='+gui')
|
depends_on('py-matplotlib', type='run', when='+gui')
|
||||||
|
|
||||||
@ -108,6 +112,10 @@ class Qmcpack(CMakePackage):
|
|||||||
patches=patch(patch_url, sha256=patch_checksum),
|
patches=patch(patch_url, sha256=patch_checksum),
|
||||||
when='~mpi')
|
when='~mpi')
|
||||||
|
|
||||||
|
# This is Spack specific patch, we may need to enhance QMCPACK's CMake
|
||||||
|
# in the near future.
|
||||||
|
patch('cmake.diff')
|
||||||
|
|
||||||
def patch(self):
|
def patch(self):
|
||||||
# FindLibxml2QMC.cmake doesn't check the environment by default
|
# FindLibxml2QMC.cmake doesn't check the environment by default
|
||||||
# for libxml2, so we fix that.
|
# for libxml2, so we fix that.
|
||||||
@ -116,22 +124,23 @@ def patch(self):
|
|||||||
'CMake/FindLibxml2QMC.cmake')
|
'CMake/FindLibxml2QMC.cmake')
|
||||||
|
|
||||||
def cmake_args(self):
|
def cmake_args(self):
|
||||||
|
spec = self.spec
|
||||||
args = []
|
args = []
|
||||||
|
|
||||||
if '+mpi' in self.spec:
|
if '+mpi' in spec:
|
||||||
mpi = self.spec['mpi']
|
mpi = spec['mpi']
|
||||||
args.append('-DCMAKE_C_COMPILER={0}'.format(mpi.mpicc))
|
args.append('-DCMAKE_C_COMPILER={0}'.format(mpi.mpicc))
|
||||||
args.append('-DCMAKE_CXX_COMPILER={0}'.format(mpi.mpicxx))
|
args.append('-DCMAKE_CXX_COMPILER={0}'.format(mpi.mpicxx))
|
||||||
args.append('-DMPI_BASE_DIR:PATH={0}'.format(mpi.prefix))
|
args.append('-DMPI_BASE_DIR:PATH={0}'.format(mpi.prefix))
|
||||||
|
|
||||||
# Currently FFTW_HOME and LIBXML2_HOME are used by CMake.
|
# Currently FFTW_HOME and LIBXML2_HOME are used by CMake.
|
||||||
# Any CMake warnings about other variables are benign.
|
# Any CMake warnings about other variables are benign.
|
||||||
xml2_prefix = self.spec['libxml2'].prefix
|
xml2_prefix = spec['libxml2'].prefix
|
||||||
args.append('-DLIBXML2_HOME={0}'.format(xml2_prefix))
|
args.append('-DLIBXML2_HOME={0}'.format(xml2_prefix))
|
||||||
args.append('-DLibxml2_INCLUDE_DIRS={0}'.format(xml2_prefix.include))
|
args.append('-DLibxml2_INCLUDE_DIRS={0}'.format(xml2_prefix.include))
|
||||||
args.append('-DLibxml2_LIBRARY_DIRS={0}'.format(xml2_prefix.lib))
|
args.append('-DLibxml2_LIBRARY_DIRS={0}'.format(xml2_prefix.lib))
|
||||||
|
|
||||||
fftw_prefix = self.spec['fftw'].prefix
|
fftw_prefix = spec['fftw'].prefix
|
||||||
args.append('-DFFTW_HOME={0}'.format(fftw_prefix))
|
args.append('-DFFTW_HOME={0}'.format(fftw_prefix))
|
||||||
args.append('-DFFTW_INCLUDE_DIRS={0}'.format(fftw_prefix.include))
|
args.append('-DFFTW_INCLUDE_DIRS={0}'.format(fftw_prefix.include))
|
||||||
args.append('-DFFTW_LIBRARY_DIRS={0}'.format(fftw_prefix.lib))
|
args.append('-DFFTW_LIBRARY_DIRS={0}'.format(fftw_prefix.lib))
|
||||||
@ -140,15 +149,15 @@ def cmake_args(self):
|
|||||||
args.append('-DHDF5_ROOT={0}'.format(self.spec['hdf5'].prefix))
|
args.append('-DHDF5_ROOT={0}'.format(self.spec['hdf5'].prefix))
|
||||||
|
|
||||||
# Default is MPI, serial version is convenient for cases, e.g. laptops
|
# Default is MPI, serial version is convenient for cases, e.g. laptops
|
||||||
if '+mpi' in self.spec:
|
if '+mpi' in spec:
|
||||||
args.append('-DQMC_MPI=1')
|
args.append('-DQMC_MPI=1')
|
||||||
elif '~mpi' in self.spec:
|
elif '~mpi' in spec:
|
||||||
args.append('-DQMC_MPI=0')
|
args.append('-DQMC_MPI=0')
|
||||||
|
|
||||||
# Default is real-valued single particle orbitals
|
# Default is real-valued single particle orbitals
|
||||||
if '+complex' in self.spec:
|
if '+complex' in spec:
|
||||||
args.append('-DQMC_COMPLEX=1')
|
args.append('-DQMC_COMPLEX=1')
|
||||||
elif '~complex' in self.spec:
|
elif '~complex' in spec:
|
||||||
args.append('-DQMC_COMPLEX=0')
|
args.append('-DQMC_COMPLEX=0')
|
||||||
|
|
||||||
# When '-DQMC_CUDA=1', CMake automatically sets:
|
# When '-DQMC_CUDA=1', CMake automatically sets:
|
||||||
@ -157,44 +166,56 @@ def cmake_args(self):
|
|||||||
# There is a double-precision CUDA path, but it is not as well
|
# There is a double-precision CUDA path, but it is not as well
|
||||||
# tested.
|
# tested.
|
||||||
|
|
||||||
if '+cuda' in self.spec:
|
if '+cuda' in spec:
|
||||||
args.append('-DQMC_CUDA=1')
|
args.append('-DQMC_CUDA=1')
|
||||||
elif '~cuda' in self.spec:
|
elif '~cuda' in spec:
|
||||||
args.append('-DQMC_CUDA=0')
|
args.append('-DQMC_CUDA=0')
|
||||||
|
|
||||||
# Mixed-precision versues double-precision CPU and GPU code
|
# Mixed-precision versues double-precision CPU and GPU code
|
||||||
if '+mixed' in self.spec:
|
if '+mixed' in spec:
|
||||||
args.append('-DQMC_MIXED_PRECISION=1')
|
args.append('-DQMC_MIXED_PRECISION=1')
|
||||||
elif '~mixed' in self.spec:
|
elif '~mixed' in spec:
|
||||||
args.append('-DQMC_MIXED_PRECISION=0')
|
args.append('-DQMC_MIXED_PRECISION=0')
|
||||||
|
|
||||||
# New Structure-of-Array (SOA) code, much faster than default
|
# New Structure-of-Array (SOA) code, much faster than default
|
||||||
# Array-of-Structure (AOS) code.
|
# Array-of-Structure (AOS) code.
|
||||||
# No support for local atomic orbital basis.
|
# No support for local atomic orbital basis.
|
||||||
if '+soa' in self.spec:
|
if '+soa' in spec:
|
||||||
args.append('-DENABLE_SOA=1')
|
args.append('-DENABLE_SOA=1')
|
||||||
elif '~soa' in self.spec:
|
elif '~soa' in spec:
|
||||||
args.append('-DENABLE_SOA=0')
|
args.append('-DENABLE_SOA=0')
|
||||||
|
|
||||||
# Manual Timers
|
# Manual Timers
|
||||||
if '+timers' in self.spec:
|
if '+timers' in spec:
|
||||||
args.append('-DENABLE_TIMERS=1')
|
args.append('-DENABLE_TIMERS=1')
|
||||||
elif '~timers' in self.spec:
|
elif '~timers' in spec:
|
||||||
args.append('-DENABLE_TIMERS=0')
|
args.append('-DENABLE_TIMERS=0')
|
||||||
|
|
||||||
# # Proper MKL detection not working.
|
# Proper detection of optimized BLAS and LAPACK.
|
||||||
# # Include MKL flags
|
# Based on the code from the deal II Spack package:
|
||||||
# if 'intel-mkl' in self.spec:
|
# https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/dealii/package.py
|
||||||
# args.append('-DBLA_VENDOR=Intel10_64lp_seq')
|
#
|
||||||
# args.append('-DQMC_INCLUDE={0}'.format(join_path(env['MKLROOT'],'include')))
|
# Basically, we override CMake's auto-detection mechanism
|
||||||
return args
|
# and use the Spack's interface instead
|
||||||
|
lapack_blas = spec['lapack'].libs + spec['blas'].libs
|
||||||
|
args.extend([
|
||||||
|
'-DLAPACK_FOUND=true',
|
||||||
|
'-DLAPACK_LIBRARIES=%s' % lapack_blas.joined(';')
|
||||||
|
])
|
||||||
|
|
||||||
# def setup_environment(self, spack_env, run_env):
|
# Additionally, we need to pass the BLAS+LAPACK include directory for
|
||||||
# # Add MKLROOT/lib to the CMAKE_PREFIX_PATH to enable CMake to find
|
# header files. Intel MKL requires special case due to differences in
|
||||||
# # MKL libraries. MKLROOT environment variable must be defined for
|
# Darwin vs. Linux $MKLROOT naming schemes
|
||||||
# # this to work properly.
|
if 'intel-mkl' in self.spec:
|
||||||
# if 'intel-mkl' in self.spec:
|
args.append(
|
||||||
# spack_env.append_path('CMAKE_PREFIX_PATH',format(join_path(env['MKLROOT'],'lib')))
|
'-DLAPACK_INCLUDE_DIRS=%s' %
|
||||||
|
format(join_path(env['MKLROOT'], 'include')))
|
||||||
|
else:
|
||||||
|
args.append(
|
||||||
|
'-DLAPACK_INCLUDE_DIRS=%s;%s' % (
|
||||||
|
self.spec['lapack'].prefix.include,
|
||||||
|
self.spec['blas'].prefix.include))
|
||||||
|
return args
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
"""Make the install targets"""
|
"""Make the install targets"""
|
||||||
@ -228,7 +249,19 @@ def install(self, spec, prefix):
|
|||||||
def check(self):
|
def check(self):
|
||||||
"""Run ctest after building binary.
|
"""Run ctest after building binary.
|
||||||
It can take over 24 hours to run all the regression tests, here we
|
It can take over 24 hours to run all the regression tests, here we
|
||||||
only run the unit tests and short tests."""
|
only run the unit tests and short tests. If the unit tests fail,
|
||||||
|
the QMCPACK installation aborts. On the other hand, the short tests
|
||||||
|
are too strict and often fail, but are still useful to run. In the
|
||||||
|
future, the short tests will be more reasonable in terms of quality
|
||||||
|
assurance (i.e. they will not be so strict), but will be sufficient to
|
||||||
|
validate QMCPACK in production."""
|
||||||
|
|
||||||
with working_dir(self.build_directory):
|
with working_dir(self.build_directory):
|
||||||
ctest('-L', 'unit')
|
ctest('-L', 'unit')
|
||||||
ctest('-R', 'short')
|
try:
|
||||||
|
ctest('-R', 'short')
|
||||||
|
except ProcessError:
|
||||||
|
warn = 'Unit tests passed, but short tests have failed.\n'
|
||||||
|
warn += 'Please review failed tests before proceeding\n'
|
||||||
|
warn += 'with production calculations.\n'
|
||||||
|
tty.msg(warn)
|
||||||
|
Loading…
Reference in New Issue
Block a user