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
|
||||
##############################################################################
|
||||
from spack import *
|
||||
import llnl.util.tty as tty
|
||||
|
||||
|
||||
class Qmcpack(CMakePackage):
|
||||
@ -33,13 +34,14 @@ class Qmcpack(CMakePackage):
|
||||
homepage = "http://www.qmcpack.org/"
|
||||
url = "https://github.com/QMCPACK/qmcpack.git"
|
||||
|
||||
# This download method is untrusted, and is not recommended
|
||||
# by the Spack manual. However, it is easier to maintain
|
||||
# because github hashes can occasionally change
|
||||
# This download method is untrusted, and is not recommended by the
|
||||
# Spack manual. However, it is easier to maintain because github hashes
|
||||
# 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.1.1', git=url, tag='v3.1.1')
|
||||
version('3.1.0', git=url, tag='v3.1.0')
|
||||
version('3.0.0', git=url, tag='v3.0.0')
|
||||
version('develop', git=url)
|
||||
|
||||
# These defaults match those in the QMCPACK manual
|
||||
@ -57,7 +59,7 @@ class Qmcpack(CMakePackage):
|
||||
'Array-of-Structure code. Only for CPU code'
|
||||
'and only in mixed precision')
|
||||
variant('timers', default=False,
|
||||
description='Build with support for timers')
|
||||
description='Build with support for timers')
|
||||
variant('da', default=False,
|
||||
description='Install with support for basic data analysis tools')
|
||||
variant('gui', default=False,
|
||||
@ -72,7 +74,9 @@ class Qmcpack(CMakePackage):
|
||||
conflicts('^openblas+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('mpi', when='+mpi')
|
||||
depends_on('libxml2')
|
||||
@ -92,7 +96,7 @@ class Qmcpack(CMakePackage):
|
||||
# blas and lapack patching fails often and so are disabled at this time
|
||||
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
|
||||
depends_on('py-matplotlib', type='run', when='+gui')
|
||||
|
||||
@ -108,6 +112,10 @@ class Qmcpack(CMakePackage):
|
||||
patches=patch(patch_url, sha256=patch_checksum),
|
||||
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):
|
||||
# FindLibxml2QMC.cmake doesn't check the environment by default
|
||||
# for libxml2, so we fix that.
|
||||
@ -116,22 +124,23 @@ def patch(self):
|
||||
'CMake/FindLibxml2QMC.cmake')
|
||||
|
||||
def cmake_args(self):
|
||||
spec = self.spec
|
||||
args = []
|
||||
|
||||
if '+mpi' in self.spec:
|
||||
mpi = self.spec['mpi']
|
||||
if '+mpi' in spec:
|
||||
mpi = spec['mpi']
|
||||
args.append('-DCMAKE_C_COMPILER={0}'.format(mpi.mpicc))
|
||||
args.append('-DCMAKE_CXX_COMPILER={0}'.format(mpi.mpicxx))
|
||||
args.append('-DMPI_BASE_DIR:PATH={0}'.format(mpi.prefix))
|
||||
|
||||
# Currently FFTW_HOME and LIBXML2_HOME are used by CMake.
|
||||
# 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_INCLUDE_DIRS={0}'.format(xml2_prefix.include))
|
||||
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_INCLUDE_DIRS={0}'.format(fftw_prefix.include))
|
||||
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))
|
||||
|
||||
# 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')
|
||||
elif '~mpi' in self.spec:
|
||||
elif '~mpi' in spec:
|
||||
args.append('-DQMC_MPI=0')
|
||||
|
||||
# Default is real-valued single particle orbitals
|
||||
if '+complex' in self.spec:
|
||||
if '+complex' in spec:
|
||||
args.append('-DQMC_COMPLEX=1')
|
||||
elif '~complex' in self.spec:
|
||||
elif '~complex' in spec:
|
||||
args.append('-DQMC_COMPLEX=0')
|
||||
|
||||
# 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
|
||||
# tested.
|
||||
|
||||
if '+cuda' in self.spec:
|
||||
if '+cuda' in spec:
|
||||
args.append('-DQMC_CUDA=1')
|
||||
elif '~cuda' in self.spec:
|
||||
elif '~cuda' in spec:
|
||||
args.append('-DQMC_CUDA=0')
|
||||
|
||||
# Mixed-precision versues double-precision CPU and GPU code
|
||||
if '+mixed' in self.spec:
|
||||
if '+mixed' in spec:
|
||||
args.append('-DQMC_MIXED_PRECISION=1')
|
||||
elif '~mixed' in self.spec:
|
||||
elif '~mixed' in spec:
|
||||
args.append('-DQMC_MIXED_PRECISION=0')
|
||||
|
||||
# New Structure-of-Array (SOA) code, much faster than default
|
||||
# Array-of-Structure (AOS) code.
|
||||
# No support for local atomic orbital basis.
|
||||
if '+soa' in self.spec:
|
||||
if '+soa' in spec:
|
||||
args.append('-DENABLE_SOA=1')
|
||||
elif '~soa' in self.spec:
|
||||
elif '~soa' in spec:
|
||||
args.append('-DENABLE_SOA=0')
|
||||
|
||||
# Manual Timers
|
||||
if '+timers' in self.spec:
|
||||
if '+timers' in spec:
|
||||
args.append('-DENABLE_TIMERS=1')
|
||||
elif '~timers' in self.spec:
|
||||
elif '~timers' in spec:
|
||||
args.append('-DENABLE_TIMERS=0')
|
||||
|
||||
# # Proper MKL detection not working.
|
||||
# # Include MKL flags
|
||||
# if 'intel-mkl' in self.spec:
|
||||
# args.append('-DBLA_VENDOR=Intel10_64lp_seq')
|
||||
# args.append('-DQMC_INCLUDE={0}'.format(join_path(env['MKLROOT'],'include')))
|
||||
return args
|
||||
# Proper detection of optimized BLAS and LAPACK.
|
||||
# Based on the code from the deal II Spack package:
|
||||
# https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/dealii/package.py
|
||||
#
|
||||
# Basically, we override CMake's auto-detection mechanism
|
||||
# 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):
|
||||
# # Add MKLROOT/lib to the CMAKE_PREFIX_PATH to enable CMake to find
|
||||
# # MKL libraries. MKLROOT environment variable must be defined for
|
||||
# # this to work properly.
|
||||
# if 'intel-mkl' in self.spec:
|
||||
# spack_env.append_path('CMAKE_PREFIX_PATH',format(join_path(env['MKLROOT'],'lib')))
|
||||
# Additionally, we need to pass the BLAS+LAPACK include directory for
|
||||
# header files. Intel MKL requires special case due to differences in
|
||||
# Darwin vs. Linux $MKLROOT naming schemes
|
||||
if 'intel-mkl' in self.spec:
|
||||
args.append(
|
||||
'-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):
|
||||
"""Make the install targets"""
|
||||
@ -228,7 +249,19 @@ def install(self, spec, prefix):
|
||||
def check(self):
|
||||
"""Run ctest after building binary.
|
||||
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):
|
||||
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