diff options
author | Nichols A. Romero <naromero77@users.noreply.github.com> | 2017-12-22 18:47:49 -0600 |
---|---|---|
committer | scheibelp <scheibel1@llnl.gov> | 2017-12-22 16:47:49 -0800 |
commit | 24743b7e5a42359bf86286db71f364434a09ac31 (patch) | |
tree | 477bb84d140e40a989844aa2964bba105c7db64e | |
parent | 0c1f4a799700b92ef9bfd54d209ffb4c252f9fae (diff) | |
download | spack-24743b7e5a42359bf86286db71f364434a09ac31.tar.gz spack-24743b7e5a42359bf86286db71f364434a09ac31.tar.bz2 spack-24743b7e5a42359bf86286db71f364434a09ac31.tar.xz spack-24743b7e5a42359bf86286db71f364434a09ac31.zip |
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
-rw-r--r-- | var/spack/repos/builtin/packages/qmcpack/cmake.diff | 55 | ||||
-rw-r--r-- | var/spack/repos/builtin/packages/qmcpack/package.py | 107 |
2 files changed, 125 insertions, 37 deletions
diff --git a/var/spack/repos/builtin/packages/qmcpack/cmake.diff b/var/spack/repos/builtin/packages/qmcpack/cmake.diff new file mode 100644 index 0000000000..4eb93f4198 --- /dev/null +++ b/var/spack/repos/builtin/packages/qmcpack/cmake.diff @@ -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() diff --git a/var/spack/repos/builtin/packages/qmcpack/package.py b/var/spack/repos/builtin/packages/qmcpack/package.py index 360ae0a51d..a2080a13c4 100644 --- a/var/spack/repos/builtin/packages/qmcpack/package.py +++ b/var/spack/repos/builtin/packages/qmcpack/package.py @@ -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 @@ class Qmcpack(CMakePackage): '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 @@ class Qmcpack(CMakePackage): 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,45 +166,57 @@ class Qmcpack(CMakePackage): # 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'))) + # 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(';') + ]) + + # 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 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'))) - def install(self, spec, prefix): """Make the install targets""" @@ -228,7 +249,19 @@ class Qmcpack(CMakePackage): 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) |