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:
Nichols A. Romero 2017-12-22 18:47:49 -06:00 committed by scheibelp
parent 0c1f4a7997
commit 24743b7e5a
2 changed files with 125 additions and 37 deletions

View 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()

View File

@ -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)