From 22969f83f3cc3cc75a94940bba96299acb59cd49 Mon Sep 17 00:00:00 2001 From: Daniele Cesarini Date: Mon, 16 Nov 2020 17:43:52 +0100 Subject: [PATCH 01/23] Fix typo --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec405a362..ad1b568ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,7 +238,7 @@ if(NOT QE_LAPACK_INTERNAL) target_link_libraries(qe_lapack INTERFACE ${_lapack_libs}) else() message(FATAL_ERROR "Failed to find a complete set of external BLAS/LAPACK library by FindLAPACK. " - "Varaibles controlling FindLAPACK can be found at CMake online documentation. " + "Variables controlling FindLAPACK can be found at CMake online documentation. " "Alternatively, '-DQE_LAPACK_INTERNAL=ON' may be used to enable reference LAPACK " "at a performance loss compared to optimized libraries.") endif() From 0079f9ffe59fc3e282b6686bda7633b5a4ee9ab6 Mon Sep 17 00:00:00 2001 From: Daniele Cesarini Date: Mon, 16 Nov 2020 17:46:04 +0100 Subject: [PATCH 02/23] Add FFTW vendor library search logic in cmake --- CMakeLists.txt | 2 + FFTXlib/CMakeLists.txt | 134 ++++++++--- cmake/FindFFTW.cmake | 475 ------------------------------------ cmake/FindFFTW3.cmake | 478 +++++++++++++++++++++++++++++++++++++ cmake/FindVendorFFTW.cmake | 179 +++++++------- 5 files changed, 679 insertions(+), 589 deletions(-) delete mode 100644 cmake/FindFFTW.cmake create mode 100644 cmake/FindFFTW3.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ad1b568ea..634555873 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,8 @@ option(QE_ENABLE_CUDA "enable CUDA acceleration on NVIDIA GPUs" OFF) option(QE_ENABLE_DOC "enable documentation building" OFF) +option(QE_FFTW_VENDOR + "select a specific FFTW library [Intel_DFTI, Intel_FFTW3, ArmPL, IBMESSL, FFTW3, Internal]" OFF) # TODO change all ifdefs throughout code base to match # cmake options diff --git a/FFTXlib/CMakeLists.txt b/FFTXlib/CMakeLists.txt index fe4a61111..801588209 100644 --- a/FFTXlib/CMakeLists.txt +++ b/FFTXlib/CMakeLists.txt @@ -5,44 +5,118 @@ add_library(qe_fft INTERFACE) add_library(QE::FFT ALIAS qe_fft) qe_install_targets(qe_fft) ########################################################### -# Try to find a vendor FFTW -find_package(VendorFFTW) -if(VendorFFTW_FOUND) - if(VendorFFTW_ID STREQUAL "Intel") - qe_add_global_compile_definitions(__DFTI) - set(qe_fft_wrappers fft_scalar.DFTI.f90) - elseif(VendorFFTW_ID STREQUAL "Arm") - ## ARMPL implements the same interface of the standard FFTW - ## no need of QE ARMPL wrapper - #qe_add_global_compile_definitions(__ARM_LIB) - #set(qe_fft_wrappers fft_scalar.ARM_LIB.f90) - qe_add_global_compile_definitions(__FFTW) +if(QE_FFTW_VENDOR) + # A vendor FFTW has been specified + if(QE_FFTW_VENDOR MATCHES "Intel") + if(QE_ENABLE_OPENMP) + SET(BLA_VENDOR Intel10_64lp) + else() + SET(BLA_VENDOR Intel10_64lp_seq) + endif() + find_package(LAPACK QUIET) + find_package(VendorFFTW REQUIRED COMPONENTS MKL) + if(VendorFFTW_FOUND) + message(STATUS "Found ${QE_FFTW_VENDOR} library") + else() + message(FATAL_ERROR "Failed to find ${QE_FFTW_VENDOR} library. " + "Alternatively, remove -DQE_FFTW_VENDOR to automatic search a FFTW library installed in the system.") + endif() + if(QE_FFTW_VENDOR MATCHES "Intel_DFTI") + qe_add_global_compile_definitions(__DFTI) + set(qe_fft_wrappers fft_scalar.DFTI.f90) + elseif(QE_FFTW_VENDOR MATCHES "Intel_FFTW3") + qe_add_global_compile_definitions(__FFTW) + set(qe_fft_wrappers fft_scalar.FFTW.f90) + endif() + target_link_libraries(qe_fft INTERFACE VendorFFTW) + elseif(QE_FFTW_VENDOR MATCHES "ArmPL") + if(QE_ENABLE_OPENMP) + SET(BLA_VENDOR Arm_mp) + else() + SET(BLA_VENDOR Arm) + endif() + find_package(LAPACK QUIET) + find_package(VendorFFTW REQUIRED COMPONENTS ArmPL) + if(VendorFFTW_FOUND) + message(STATUS "Found ${QE_FFTW_VENDOR} library") + else() + message(FATAL_ERROR "Failed to find ${QE_FFTW_VENDOR} library. " + "Alternatively, remove -DQE_FFTW_VENDOR to automatic search a FFTW library installed in the system.") + endif() + qe_add_global_compile_definitions(__FFTW) set(qe_fft_wrappers fft_scalar.FFTW.f90) - elseif(VendorFFTW_ID STREQUAL "IBMESSL") + target_link_libraries(qe_fft INTERFACE VendorFFTW) + elseif(QE_FFTW_VENDOR MATCHES "IBMESSL") + SET(BLA_VENDOR IBMESSL) + find_package(BLAS QUIET) + find_package(VendorFFTW REQUIRED COMPONENTS IBMESSL) + if(VendorFFTW_FOUND) + message(STATUS "Found ${QE_FFTW_VENDOR} library") + else() + message(FATAL_ERROR "Failed to find ${QE_FFTW_VENDOR} library. " + "Alternatively, remove -DQE_FFTW_VENDOR to automatic search a FFTW library installed in the system.") + endif() qe_add_global_compile_definitions(__LINUX_ESSL) set(qe_fft_wrappers fft_scalar.ESSL.f90) - endif() - - target_link_libraries(qe_fft INTERFACE VendorFFTW) -else() - # Try to find the official FFTW3 - message(STATUS "No vendor FFTW found") - - if(QE_ENABLE_OPENMP) - find_package(FFTW COMPONENTS DOUBLE_OPENMP) - else() - find_package(FFTW COMPONENTS DOUBLE) - endif() - - if(FFTW_FOUND) + target_link_libraries(qe_fft INTERFACE VendorFFTW) + elseif(QE_FFTW_VENDOR MATCHES "FFTW3") + if(QE_ENABLE_OPENMP) + find_package(FFTW3 REQUIRED COMPONENTS DOUBLE_OPENMP) + else() + find_package(FFTW3 REQUIRED COMPONENTS DOUBLE) + endif() + if(NOT FFTW3_FOUND) + message(FATAL_ERROR "Failed to find ${QE_FFTW_VENDOR} library. " + "Alternatively, remove -DQE_FFTW_VENDOR to automatic search a FFTW library installed in the system.") + endif() qe_add_global_compile_definitions(__FFTW3) set(qe_fft_wrappers fft_scalar.FFTW3.f90) target_link_libraries(qe_fft INTERFACE FFTW) - else() - # Cannot find anything useful, just fall back to the internal FFTW - message(STATUS "No FFTW3 library found. FFTW is falling back to QE internal implementation (FFTXLib)") + elseif(QE_FFTW_VENDOR MATCHES "Internal") + message(STATUS "QE internal implementation of FFTW (FFTXLib)") qe_add_global_compile_definitions(__FFTW) set(qe_fft_wrappers fft_scalar.FFTW.f90) + else() + message(FATAL_ERROR "The FFTW vendor library '${QE_FFTW_VENDOR}' is not supported!") + endif() +else() + # Try to find a vendor FFTW installed in the system + find_package(VendorFFTW) + if(VendorFFTW_FOUND) + if(VendorFFTW_ID STREQUAL "Intel") + qe_add_global_compile_definitions(__DFTI) + set(qe_fft_wrappers fft_scalar.DFTI.f90) + elseif(VendorFFTW_ID STREQUAL "Arm") + ## ARMPL implements the same interface of the standard FFTW + ## no need of QE ARMPL wrapper + #qe_add_global_compile_definitions(__ARM_LIB) + #set(qe_fft_wrappers fft_scalar.ARM_LIB.f90) + qe_add_global_compile_definitions(__FFTW) + set(qe_fft_wrappers fft_scalar.FFTW.f90) + elseif(VendorFFTW_ID STREQUAL "IBMESSL") + qe_add_global_compile_definitions(__LINUX_ESSL) + set(qe_fft_wrappers fft_scalar.ESSL.f90) + endif() + + target_link_libraries(qe_fft INTERFACE VendorFFTW) + else() + # Try to find the official FFTW3 + message(STATUS "No vendor FFTW found") + if(QE_ENABLE_OPENMP) + find_package(FFTW3 COMPONENTS DOUBLE_OPENMP) + else() + find_package(FFTW3 COMPONENTS DOUBLE) + endif() + if(FFTW3_FOUND) + qe_add_global_compile_definitions(__FFTW3) + set(qe_fft_wrappers fft_scalar.FFTW3.f90) + target_link_libraries(qe_fft INTERFACE FFTW3) + else() + # Cannot find anything useful, just fall back to the internal FFTW + message(STATUS "No FFTW3 library found. FFTW is falling back to QE internal implementation (FFTXLib)") + qe_add_global_compile_definitions(__FFTW) + set(qe_fft_wrappers fft_scalar.FFTW.f90) + endif() endif() endif() diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake deleted file mode 100644 index f73042f23..000000000 --- a/cmake/FindFFTW.cmake +++ /dev/null @@ -1,475 +0,0 @@ -# Find the FFTW library -# -# Original version of this file: -# Copyright (c) 2015, Wenzel Jakob -# https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake, commit 4d58bfdc28891b4f9373dfe46239dda5a0b561c6 -# Modifications: -# Copyright (c) 2017, Patrick Bos -# -# Usage: -# find_package(FFTW [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX]) -# -# It sets the following variables: -# FFTW_FOUND ... true if fftw is found on the system -# FFTW_[component]_FOUND ... true if the component is found on the system (see components below) -# FFTW_LIBRARIES ... full paths to all found fftw libraries -# FFTW_[component]_LIB ... full path to one of the components (see below) -# FFTW_INCLUDE_DIRS ... fftw include directory paths -# -# The following variables will be checked by the function -# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found, otherwise both static and shared. -# FFTW_ROOT ... if set, the libraries are exclusively searched under this path -# -# This package supports the following components: -# FLOAT -# DOUBLE -# LONGDOUBLE -# FLOAT_THREADS -# DOUBLE_THREADS -# LONGDOUBLE_THREADS -# FLOAT_OPENMP -# DOUBLE_OPENMP -# LONGDOUBLE_OPENMP -# FLOAT_MPI -# DOUBLE_MPI - -# Check whether to search static or dynamic libs -set(CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES}) - -if(${FFTW_USE_STATIC_LIBS}) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) -else() - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV}) -endif() - -# Check common variables -set(FFTW_DIRS $ENV{FFTW_HOME}) -set(FFTW_DIRS ${FFTW_DIRS} $ENV{FFTW_ROOT}) -set(FFTW_DIRS ${FFTW_DIRS} $ENV{FFTW_DIR}) -set(FFTW_DIRS ${FFTW_DIRS} $ENV{FFTW_PATH}) - -if(FFTW_DIRS) - if("DOUBLE" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE - NAMES "fftw3" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("DOUBLE_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_THREADS - NAMES "fftw3_threads" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("DOUBLE_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_OPENMP - NAMES "fftw3_omp" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("DOUBLE_MPI" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_MPI - NAMES "fftw3_mpi" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("FLOAT" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT - NAMES "fftw3f" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("FLOAT_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_THREADS - NAMES "fftw3f_threads" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("FLOAT_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_OPENMP - NAMES "fftw3f_omp" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("FLOAT_MPI" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_MPI - NAMES "fftw3f_mpi" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("LONGDOUBLE" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_LONGDOUBLE - NAMES "fftw3l" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("LONGDOUBLE_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_LONGDOUBLE_THREADS - NAMES "fftw3l_threads" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - if("LONGDOUBLE_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library(FFTW_LONGDOUBLE_OPENMP - NAMES "fftw3l_omp" - PATHS - ${FFTW_DIRS} - PATH_SUFFIXES - "lib" - "lib64" - NO_DEFAULT_PATH) - endif() - - find_path(FFTW_INCLUDE_DIRS - NAMES - "fftw3.h" - "fftw3.f" - PATHS - ${FFTW_DIRS} - $ENV{C_INCLUDE_PATH} - PATH_SUFFIXES - "include" - "inc" - NO_DEFAULT_PATH) - -else() - # Check if we can use PkgConfig - find_package(PkgConfig) - - # Determine from PKG - if(PKG_CONFIG_FOUND AND NOT FFTW_ROOT) - pkg_check_modules(PKG_FFTW QUIET "fftw3") - endif() - - # Try to find in the LD_LIBRARY_PATH - string(REPLACE ":" ";" LIBRARY_DIRS "$ENV{LD_LIBRARY_PATH}") - - if("DOUBLE" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE - NAMES "fftw3" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("DOUBLE_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_THREADS - NAMES "fftw3_threads" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("DOUBLE_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_OPENMP - NAMES "fftw3_omp" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("DOUBLE_MPI" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_DOUBLE_MPI - NAMES "fftw3_mpi" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("FLOAT" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT - NAMES "fftw3f" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("FLOAT_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_THREADS - NAMES "fftw3f_threads" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("FLOAT_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_OPENMP - NAMES "fftw3f_omp" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("FLOAT_MPI" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_FLOAT_MPI - NAMES "fftw3f_mpi" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("LONGDOUBLE" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_LONGDOUBLE - NAMES "fftw3l" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("LONGDOUBLE_THREADS" IN_LIST FFTW_FIND_COMPONENTS) - find_library( - FFTW_LONGDOUBLE_THREADS - NAMES "fftw3l_threads" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - if("LONGDOUBLE_OPENMP" IN_LIST FFTW_FIND_COMPONENTS) - find_library(FFTW_LONGDOUBLE_OPENMP - NAMES "fftw3l_omp" - PATHS - ${PKG_FFTW_LIBRARY_DIRS} - ${LIB_INSTALL_DIR} - ${LIBRARY_DIRS} - PATH_SUFFIXES - "lib" - "lib64") - endif() - - set(LD_DIRS) - foreach(_lib ${LIBRARY_DIRS}) - get_filename_component(_root_lib_dir ${_lib} DIRECTORY) - list(APPEND LD_DIRS ${_root_lib_dir}) - endforeach() - - find_path(FFTW_INCLUDE_DIRS - NAMES - "fftw3.h" - "fftw3.f" - PATHS - ${PKG_FFTW_INCLUDE_DIRS} - ${INCLUDE_INSTALL_DIR} - ${LD_DIRS} - $ENV{C_INCLUDE_PATH} - PATH_SUFFIXES - "include" - "inc") -endif() - - -# Components - -add_library(FFTW INTERFACE IMPORTED) - -if(FFTW_DOUBLE) - set(FFTW_DOUBLE_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE}) -else() - set(FFTW_DOUBLE_FOUND FALSE) -endif() - -if(FFTW_FLOAT) - set(FFTW_FLOAT_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT}) -else() - set(FFTW_FLOAT_FOUND FALSE) -endif() - -if(FFTW_LONGDOUBLE) - set(FFTW_LONGDOUBLE_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE}) -else() - set(FFTW_LONGDOUBLE_FOUND FALSE) -endif() - -if(FFTW_DOUBLE_THREADS) - set(FFTW_DOUBLE_THREADS_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_THREADS}) -else() - set(FFTW_DOUBLE_THREADS_FOUND FALSE) -endif() - -if(FFTW_FLOAT_THREADS) - set(FFTW_FLOAT_THREADS_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_THREADS}) -else() - set(FFTW_FLOAT_THREADS_FOUND FALSE) -endif() - -if(FFTW_LONGDOUBLE_THREADS) - set(FFTW_LONGDOUBLE_THREADS_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_THREADS}) -else() - set(FFTW_LONGDOUBLE_THREADS_FOUND FALSE) -endif() - -if(FFTW_DOUBLE_OPENMP) - set(FFTW_DOUBLE_OPENMP_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_OPENMP}) - add_library(FFTW::DoubleOpenMP INTERFACE IMPORTED) -else() - set(FFTW_DOUBLE_OPENMP_FOUND FALSE) -endif() - -if(FFTW_FLOAT_OPENMP) - set(FFTW_FLOAT_OPENMP_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_OPENMP}) -else() - set(FFTW_FLOAT_OPENMP_FOUND FALSE) -endif() - -if(FFTW_LONGDOUBLE_OPENMP) - set(FFTW_LONGDOUBLE_OPENMP_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_OPENMP}) -else() - set(FFTW_LONGDOUBLE_OPENMP_FOUND FALSE) -endif() - -if(FFTW_DOUBLE_MPI) - set(FFTW_DOUBLE_MPI_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_MPI}) -else() - set(FFTW_DOUBLE_MPI_FOUND FALSE) -endif() - -if(FFTW_FLOAT_MPI) - set(FFTW_FLOAT_MPI_FOUND TRUE) - set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_MPI}) -else() - set(FFTW_FLOAT_MPI_FOUND FALSE) -endif() - -target_link_libraries(FFTW INTERFACE ${FFTW_LIBRARIES}) -target_include_directories(FFTW INTERFACE ${FFTW_INCLUDE_DIRS}) - -# End components - -set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(FFTW REQUIRED_VARS FFTW_LIBRARIES FFTW_INCLUDE_DIRS) - -mark_as_advanced( - FFTW_INCLUDE_DIRS - FFTW_LIBRARIES - FFTW_FLOAT - FFTW_DOUBLE - FFTW_LONGDOUBLE - FFTW_FLOAT_THREADS - FFTW_DOUBLE_THREADS - FFTW_LONGDOUBLE_THREADS - FFTW_FLOAT_OPENMP - FFTW_DOUBLE_OPENMP - FFTW_LONGDOUBLE_OPENMP - FFTW_FLOAT_MPI - FFTW_DOUBLE_MPI) \ No newline at end of file diff --git a/cmake/FindFFTW3.cmake b/cmake/FindFFTW3.cmake new file mode 100644 index 000000000..77e41e209 --- /dev/null +++ b/cmake/FindFFTW3.cmake @@ -0,0 +1,478 @@ +# Find the FFTW3 library +# +# Original version of this file: +# Copyright (c) 2015, Wenzel Jakob +# https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake, commit 4d58bfdc28891b4f9373dfe46239dda5a0b561c6 +# Modifications: +# Copyright (c) 2017, Patrick Bos +# +# Usage: +# find_package(FFTW3 [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX]) +# +# It sets the following variables: +# FFTW3_FOUND ... true if fftw is found on the system +# FFTW3_[component]_FOUND ... true if the component is found on the system (see components below) +# FFTW3_LIBRARIES ... full paths to all found fftw libraries +# FFTW3_[component]_LIB ... full path to one of the components (see below) +# FFTW3_INCLUDE_DIRS ... fftw include directory paths +# +# The following variables will be checked by the function +# FFTW3_USE_STATIC_LIBS ... if true, only static libraries are found, otherwise both static and shared. +# FFTW3_ROOT ... if set, the libraries are exclusively searched under this path +# +# This package supports the following components: +# FLOAT +# DOUBLE +# LONGDOUBLE +# FLOAT_THREADS +# DOUBLE_THREADS +# LONGDOUBLE_THREADS +# FLOAT_OPENMP +# DOUBLE_OPENMP +# LONGDOUBLE_OPENMP +# FLOAT_MPI +# DOUBLE_MPI + +# Check whether to search static or dynamic libs +set(CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES}) + +if(${FFTW3_USE_STATIC_LIBS}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) +else() + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV}) +endif() + +# Check common variables +set(FFTW3_DIRS $ENV{FFTW_HOME}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW_ROOT}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW_DIR}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW_PATH}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW3_ROOT}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW3_DIR}) +set(FFTW3_DIRS ${FFTW_DIRS} $ENV{FFTW3_PATH}) + +if(FFTW3_DIRS) + if("DOUBLE" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE + NAMES "fftw3" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("DOUBLE_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_THREADS + NAMES "fftw3_threads" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("DOUBLE_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_OPENMP + NAMES "fftw3_omp" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("DOUBLE_MPI" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_MPI + NAMES "fftw3_mpi" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("FLOAT" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT + NAMES "fftw3f" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("FLOAT_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_THREADS + NAMES "fftw3f_threads" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("FLOAT_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_OPENMP + NAMES "fftw3f_omp" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("FLOAT_MPI" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_MPI + NAMES "fftw3f_mpi" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("LONGDOUBLE" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_LONGDOUBLE + NAMES "fftw3l" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("LONGDOUBLE_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_LONGDOUBLE_THREADS + NAMES "fftw3l_threads" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + if("LONGDOUBLE_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library(FFTW3_LONGDOUBLE_OPENMP + NAMES "fftw3l_omp" + PATHS + ${FFTW3_DIRS} + PATH_SUFFIXES + "lib" + "lib64" + NO_DEFAULT_PATH) + endif() + + find_path(FFTW3_INCLUDE_DIRS + NAMES + "fftw3.h" + "fftw3.f" + PATHS + ${FFTW3_DIRS} + $ENV{C_INCLUDE_PATH} + PATH_SUFFIXES + "include" + "inc" + NO_DEFAULT_PATH) + +else() + # Check if we can use PkgConfig + find_package(PkgConfig) + + # Determine from PKG + if(PKG_CONFIG_FOUND AND NOT FFTW3_ROOT) + pkg_check_modules(PKG_FFTW3 QUIET "fftw3") + endif() + + # Try to find in the LD_LIBRARY_PATH + string(REPLACE ":" ";" LIBRARY_DIRS "$ENV{LD_LIBRARY_PATH}") + + if("DOUBLE" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE + NAMES "fftw3" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("DOUBLE_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_THREADS + NAMES "fftw3_threads" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("DOUBLE_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_OPENMP + NAMES "fftw3_omp" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("DOUBLE_MPI" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_DOUBLE_MPI + NAMES "fftw3_mpi" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("FLOAT" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT + NAMES "fftw3f" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("FLOAT_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_THREADS + NAMES "fftw3f_threads" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("FLOAT_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_OPENMP + NAMES "fftw3f_omp" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("FLOAT_MPI" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_FLOAT_MPI + NAMES "fftw3f_mpi" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("LONGDOUBLE" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_LONGDOUBLE + NAMES "fftw3l" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("LONGDOUBLE_THREADS" IN_LIST FFTW3_FIND_COMPONENTS) + find_library( + FFTW3_LONGDOUBLE_THREADS + NAMES "fftw3l_threads" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + if("LONGDOUBLE_OPENMP" IN_LIST FFTW3_FIND_COMPONENTS) + find_library(FFTW3_LONGDOUBLE_OPENMP + NAMES "fftw3l_omp" + PATHS + ${PKG_FFTW3_LIBRARY_DIRS} + ${LIB_INSTALL_DIR} + ${LIBRARY_DIRS} + PATH_SUFFIXES + "lib" + "lib64") + endif() + + set(LD_DIRS) + foreach(_lib ${LIBRARY_DIRS}) + get_filename_component(_root_lib_dir ${_lib} DIRECTORY) + list(APPEND LD_DIRS ${_root_lib_dir}) + endforeach() + + find_path(FFTW3_INCLUDE_DIRS + NAMES + "fftw3.h" + "fftw3.f" + PATHS + ${PKG_FFTW3_INCLUDE_DIRS} + ${INCLUDE_INSTALL_DIR} + ${LD_DIRS} + $ENV{C_INCLUDE_PATH} + PATH_SUFFIXES + "include" + "inc") +endif() + + +# Components + +add_library(FFTW3 INTERFACE IMPORTED) + +if(FFTW3_DOUBLE) + set(FFTW3_DOUBLE_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_DOUBLE}) +else() + set(FFTW3_DOUBLE_FOUND FALSE) +endif() + +if(FFTW3_FLOAT) + set(FFTW3_FLOAT_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_FLOAT}) +else() + set(FFTW3_FLOAT_FOUND FALSE) +endif() + +if(FFTW3_LONGDOUBLE) + set(FFTW3_LONGDOUBLE_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_LONGDOUBLE}) +else() + set(FFTW3_LONGDOUBLE_FOUND FALSE) +endif() + +if(FFTW3_DOUBLE_THREADS) + set(FFTW3_DOUBLE_THREADS_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_DOUBLE_THREADS}) +else() + set(FFTW3_DOUBLE_THREADS_FOUND FALSE) +endif() + +if(FFTW3_FLOAT_THREADS) + set(FFTW3_FLOAT_THREADS_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_FLOAT_THREADS}) +else() + set(FFTW3_FLOAT_THREADS_FOUND FALSE) +endif() + +if(FFTW3_LONGDOUBLE_THREADS) + set(FFTW3_LONGDOUBLE_THREADS_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_LONGDOUBLE_THREADS}) +else() + set(FFTW3_LONGDOUBLE_THREADS_FOUND FALSE) +endif() + +if(FFTW3_DOUBLE_OPENMP) + set(FFTW3_DOUBLE_OPENMP_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_DOUBLE_OPENMP}) + add_library(FFTW3::DoubleOpenMP INTERFACE IMPORTED) +else() + set(FFTW3_DOUBLE_OPENMP_FOUND FALSE) +endif() + +if(FFTW3_FLOAT_OPENMP) + set(FFTW3_FLOAT_OPENMP_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_FLOAT_OPENMP}) +else() + set(FFTW3_FLOAT_OPENMP_FOUND FALSE) +endif() + +if(FFTW3_LONGDOUBLE_OPENMP) + set(FFTW3_LONGDOUBLE_OPENMP_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_LONGDOUBLE_OPENMP}) +else() + set(FFTW3_LONGDOUBLE_OPENMP_FOUND FALSE) +endif() + +if(FFTW3_DOUBLE_MPI) + set(FFTW3_DOUBLE_MPI_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_DOUBLE_MPI}) +else() + set(FFTW3_DOUBLE_MPI_FOUND FALSE) +endif() + +if(FFTW3_FLOAT_MPI) + set(FFTW3_FLOAT_MPI_FOUND TRUE) + set(FFTW3_LIBRARIES ${FFTW3_LIBRARIES} ${FFTW3_FLOAT_MPI}) +else() + set(FFTW3_FLOAT_MPI_FOUND FALSE) +endif() + +target_link_libraries(FFTW3 INTERFACE ${FFTW3_LIBRARIES}) +target_include_directories(FFTW3 INTERFACE ${FFTW3_INCLUDE_DIRS}) + +# End components + +set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(FFTW3 REQUIRED_VARS FFTW3_LIBRARIES FFTW3_INCLUDE_DIRS) + +mark_as_advanced( + FFTW3_INCLUDE_DIRS + FFTW3_LIBRARIES + FFTW3_FLOAT + FFTW3_DOUBLE + FFTW3_LONGDOUBLE + FFTW3_FLOAT_THREADS + FFTW3_DOUBLE_THREADS + FFTW3_LONGDOUBLE_THREADS + FFTW3_FLOAT_OPENMP + FFTW3_DOUBLE_OPENMP + FFTW3_LONGDOUBLE_OPENMP + FFTW3_FLOAT_MPI + FFTW3_DOUBLE_MPI) \ No newline at end of file diff --git a/cmake/FindVendorFFTW.cmake b/cmake/FindVendorFFTW.cmake index 470d1c58b..d1d49380d 100644 --- a/cmake/FindVendorFFTW.cmake +++ b/cmake/FindVendorFFTW.cmake @@ -1,3 +1,4 @@ +# This finder needs that BLAS and/or LAPACK have been founded! if(BLAS_FOUND OR LAPACK_FOUND) # Trasform spaces in semicolons string(REPLACE " " ";" _blas_libs "${BLAS_LIBRARIES}") @@ -13,7 +14,7 @@ if(BLAS_FOUND OR LAPACK_FOUND) get_filename_component(_parent_l3 ${_parent_l2} DIRECTORY) list(APPEND _search_path ${_lib} ${_parent_l1} ${_parent_l2} ${_parent_l3}) else() - # Remove first two characters '-L' and try again + # Remove first two characters '-L' (or '-l') and try again string(REGEX MATCH "/[^ ]*" _lib_clean ${_lib}) if(EXISTS "${_lib_clean}") get_filename_component(_parent_l1 ${_lib_clean} DIRECTORY) @@ -28,97 +29,107 @@ if(BLAS_FOUND OR LAPACK_FOUND) # Start to search vendor libraries and include directories # Try to find the Intel MKL - if(_search_path MATCHES "mkl") - find_path(VendorFFTW_INCLUDE_MKL_DFTI - NAMES - "mkl_dfti.f90" - HINTS - ${_search_path} - PATH_SUFFIXES - "include" - "fftw" - "include/fftw" - NO_DEFAULT_PATH - ) - find_path(VendorFFTW_INCLUDE_FFTW3 - NAMES - "fftw3.f" - "fftw3.h" - HINTS - ${_search_path} - PATH_SUFFIXES - "include" - "fftw" - "include/fftw" - NO_DEFAULT_PATH - ) - set(VendorFFTW_INCLUDE_DIRS ${VendorFFTW_INCLUDE_MKL_DFTI} ${VendorFFTW_INCLUDE_FFTW3}) + if(NOT VendorFFTW_FIND_COMPONENTS OR "MKL" IN_LIST VendorFFTW_FIND_COMPONENTS) + if(_search_path MATCHES "mkl") + find_path(VendorFFTW_INCLUDE_MKL_DFTI + NAMES + "mkl_dfti.f90" + HINTS + ${_search_path} + PATH_SUFFIXES + "include" + "fftw" + "include/fftw" + NO_DEFAULT_PATH + ) + find_path(VendorFFTW_INCLUDE_FFTW3 + NAMES + "fftw3.f" + "fftw3.h" + HINTS + ${_search_path} + PATH_SUFFIXES + "include" + "fftw" + "include/fftw" + NO_DEFAULT_PATH + ) + set(VendorFFTW_INCLUDE_DIRS ${VendorFFTW_INCLUDE_MKL_DFTI} ${VendorFFTW_INCLUDE_FFTW3}) - add_library(VendorFFTW INTERFACE IMPORTED) - list(APPEND VendorFFTW_LIBRARIES - ${BLAS_LIBRARIES} - ${BLAS_LINKER_FLAGS} - ${LAPACK_LIBRARIES} - ${LAPACK_LINKER_FLAGS}) - list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") - target_link_libraries(VendorFFTW INTERFACE ${VendorFFTW_LIBRARIES}) - target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) - set(VendorFFTW_ID "Intel") + add_library(VendorFFTW INTERFACE IMPORTED) + list(APPEND VendorFFTW_LIBRARIES + ${BLAS_LIBRARIES} + ${BLAS_LINKER_FLAGS} + ${LAPACK_LIBRARIES} + ${LAPACK_LINKER_FLAGS}) + list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") + target_link_libraries(VendorFFTW INTERFACE ${VendorFFTW_LIBRARIES}) + target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) + set(VendorFFTW_ID "Intel") + + break() + endif() + endif() - break() # Try to find the ARM Performance Library - elseif(_search_path MATCHES "armpl") - find_path(VendorFFTW_INCLUDE_DIRS - NAMES - "fftw3.f" - "fftw3.h" - HINTS - ${_search_path} - PATH_SUFFIXES - "include" - "fftw" - "include/fftw" - NO_DEFAULT_PATH - ) + if(NOT VendorFFTW_FIND_COMPONENTS OR "ArmPL" IN_LIST VendorFFTW_FIND_COMPONENTS) + if(_search_path MATCHES "armpl") + find_path(VendorFFTW_INCLUDE_DIRS + NAMES + "fftw3.f" + "fftw3.h" + HINTS + ${_search_path} + PATH_SUFFIXES + "include" + "fftw" + "include/fftw" + NO_DEFAULT_PATH + ) - add_library(VendorFFTW INTERFACE IMPORTED) - list(APPEND VendorFFTW_LIBRARIES - ${BLAS_LIBRARIES} - ${BLAS_LINKER_FLAGS} - ${LAPACK_LIBRARIES} - ${LAPACK_LINKER_FLAGS}) - list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") - target_link_libraries(VendorFFTW INTERFACE ${VendorFFTW_LIBRARIES}) - target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) - set(VendorFFTW_ID "Arm") + add_library(VendorFFTW INTERFACE IMPORTED) + list(APPEND VendorFFTW_LIBRARIES + ${BLAS_LIBRARIES} + ${BLAS_LINKER_FLAGS} + ${LAPACK_LIBRARIES} + ${LAPACK_LINKER_FLAGS}) + list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") + target_link_libraries(VendorFFTW INTERFACE ${VendorFFTW_LIBRARIES}) + target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) + set(VendorFFTW_ID "Arm") + + break() + endif() + endif() - break() # Try to find the IBM ESSL library - elseif(_search_path MATCHES "essl") - find_path(VendorFFTW_INCLUDE_DIRS - NAMES - "fftw3.f" - "fftw3.h" - HINTS - ${_search_path} - PATH_SUFFIXES - "include" - "fftw" - "include/fftw" - NO_DEFAULT_PATH - ) + if(NOT VendorFFTW_FIND_COMPONENTS OR "IBMESSL" IN_LIST VendorFFTW_FIND_COMPONENTS) + if(_search_path MATCHES "essl") + find_path(VendorFFTW_INCLUDE_DIRS + NAMES + "fftw3.f" + "fftw3.h" + HINTS + ${_search_path} + PATH_SUFFIXES + "include" + "fftw" + "include/fftw" + NO_DEFAULT_PATH + ) - add_library(VendorFFTW INTERFACE IMPORTED) - list(APPEND VendorFFTW_LIBRARIES - ${BLAS_LIBRARIES} - ${BLAS_LINKER_FLAGS} - ${LAPACK_LIBRARIES} - ${LAPACK_LINKER_FLAGS}) - list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") - target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) - set(VendorFFTW_ID "IBMESSL") + add_library(VendorFFTW INTERFACE IMPORTED) + list(APPEND VendorFFTW_LIBRARIES + ${BLAS_LIBRARIES} + ${BLAS_LINKER_FLAGS} + ${LAPACK_LIBRARIES} + ${LAPACK_LINKER_FLAGS}) + list(REMOVE_DUPLICATES "${VendorFFTW_LIBRARIES}") + target_include_directories(VendorFFTW INTERFACE ${VendorFFTW_INCLUDE_DIRS}) + set(VendorFFTW_ID "IBMESSL") - break() + break() + endif() endif() endforeach() endif() From 32f1d481c196aa609fdb21a07794505aadfcdddb Mon Sep 17 00:00:00 2001 From: Pietro Delugas Date: Tue, 17 Nov 2020 22:14:05 +0100 Subject: [PATCH 03/23] make check of compiler cuda support more robust the check is performed specifying the version number of the chosen cudaruntime instead of using the compiler default. --- install/configure | 22 ++++++++++++---------- install/m4/x_ac_qe_cuda.m4 | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/install/configure b/install/configure index 6899799f0..66337d1ef 100755 --- a/install/configure +++ b/install/configure @@ -2366,7 +2366,7 @@ $as_echo "${arch}" >&6; } try_dflags="" # Add needed include directories -try_iflags="-I\$(TOPDIR)/include -I\$(TOPDIR)/FoX/finclude" +try_iflags="-I\$(TOPDIR)/include -I\$(TOPDIR)/FoX/finclude " # Checking archiver... @@ -4252,28 +4252,30 @@ ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5' ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_fc_compiler_gnu - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Fortran compiler accepts -Mcuda" >&5 -$as_echo_n "checking whether Fortran compiler accepts -Mcuda... " >&6; } -if ${ax_cv_check_fcflags___Mcuda+:} false; then : + as_CACHEVAR=`$as_echo "ax_cv_check_fcflags__-Mcuda=cuda$with_cuda_runtime" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Fortran compiler accepts -Mcuda=cuda$with_cuda_runtime" >&5 +$as_echo_n "checking whether Fortran compiler accepts -Mcuda=cuda$with_cuda_runtime... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : $as_echo_n "(cached) " >&6 else ax_check_save_flags=$FCFLAGS - FCFLAGS="$FCFLAGS -Mcuda" + FCFLAGS="$FCFLAGS -Mcuda=cuda$with_cuda_runtime" cat > conftest.$ac_ext <<_ACEOF MODULE test; use cudafor; END MODULE _ACEOF if ac_fn_fc_try_compile "$LINENO"; then : - ax_cv_check_fcflags___Mcuda=yes + eval "$as_CACHEVAR=yes" else - ax_cv_check_fcflags___Mcuda=no + eval "$as_CACHEVAR=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext FCFLAGS=$ax_check_save_flags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_fcflags___Mcuda" >&5 -$as_echo "$ax_cv_check_fcflags___Mcuda" >&6; } -if test "x$ax_cv_check_fcflags___Mcuda" = xyes; then : +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : have_cudafor=yes else have_cudafor=no diff --git a/install/m4/x_ac_qe_cuda.m4 b/install/m4/x_ac_qe_cuda.m4 index f1f7ce88a..671f7e9ec 100644 --- a/install/m4/x_ac_qe_cuda.m4 +++ b/install/m4/x_ac_qe_cuda.m4 @@ -67,7 +67,7 @@ then # ----------------------------------------- AC_LANG_PUSH([Fortran]) AC_FC_SRCEXT([f90]) - AX_CHECK_COMPILE_FLAG([-Mcuda], [have_cudafor=yes], [have_cudafor=no], [], [MODULE test; use cudafor; END MODULE]) + AX_CHECK_COMPILE_FLAG([-Mcuda=cuda$with_cuda_runtime], [have_cudafor=yes], [have_cudafor=no], [], [MODULE test; use cudafor; END MODULE]) AC_LANG_POP([Fortran]) if test "x$have_cudafor" != "xyes" then From ca6f955060d9b42a8581fd15b5368b05431f722b Mon Sep 17 00:00:00 2001 From: afonari Date: Fri, 20 Nov 2020 12:51:54 +0000 Subject: [PATCH 04/23] Print total energy, force, pressure thresholds in PW/summary.f90 --- PW/src/summary.f90 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/PW/src/summary.f90 b/PW/src/summary.f90 index 6384021ff..999bfced6 100644 --- a/PW/src/summary.f90 +++ b/PW/src/summary.f90 @@ -20,7 +20,7 @@ SUBROUTINE summary() USE constants, ONLY : amu_ry, rytoev USE cell_base, ONLY : alat, ibrav, omega, at, bg, celldm, wmass USE ions_base, ONLY : nat, atm, zv, tau, ntyp => nsp, ityp - USE cellmd, ONLY : calc + USE cellmd, ONLY : calc, lmovecell USE ions_base, ONLY : amass USE gvect, ONLY : ecutrho, ngm, ngm_g, gcutm USE gvecs, ONLY : doublegrid, ngms, ngms_g, gcutms @@ -52,6 +52,8 @@ SUBROUTINE summary() USE exx, ONLY : ecutfock USE fcp_variables, ONLY : lfcpopt, lfcpdyn USE fcp, ONLY : fcp_summary + USE relax, ONLY : epse, epsf, epsp + USE force_mod, ONLY : lforce ! IMPLICIT NONE ! @@ -94,6 +96,8 @@ SUBROUTINE summary() WRITE( stdout, 103) nbnd, ecutwfc, ecutrho IF ( dft_is_hybrid () ) WRITE( stdout, 104) ecutfock IF ( lscf) WRITE( stdout, 105) tr2, mixing_beta, nmix, mixing_style + IF ( lforce ) WRITE (stdout, 106) epse, epsf + IF ( lmovecell ) WRITE (stdout, 107) epsp ! 100 FORMAT( /,/,5X, & & 'bravais-lattice index = ',I12,/,5X, & @@ -115,6 +119,11 @@ SUBROUTINE summary() & 'convergence threshold = ',1PE12.1,/,5X, & & 'mixing beta = ',0PF12.4,/,5X, & & 'number of iterations used = ',I12,2X,A,' mixing') +106 FORMAT(5X, & + & 'tot convergence thresh. = ',1PE12.1,/,5X, & + & 'force convergence thresh. = ',1PE12.1) +107 FORMAT(5X, & + & 'press convergence thresh. = ',1PE12.1) ! call write_dft_name ( ) ! From 2e0e906b18b57dfdfd6a004dcfb08ddeca968a95 Mon Sep 17 00:00:00 2001 From: afonari Date: Fri, 20 Nov 2020 12:55:48 +0000 Subject: [PATCH 05/23] Update bfgs_module.f90 to print errors in the current iteration --- Modules/bfgs_module.f90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/bfgs_module.f90 b/Modules/bfgs_module.f90 index 14a3264c7..1e0624728 100644 --- a/Modules/bfgs_module.f90 +++ b/Modules/bfgs_module.f90 @@ -275,6 +275,10 @@ CONTAINS WRITE( UNIT = stdout, & & FMT = '(5X,A," new",T30,"= ",F18.10," Ry",/)' ) fname,energy ! + WRITE(stdout, '(5X,"Gradient error",T30,"= ",1PE12.1)') grad_error + IF( lmovecell ) WRITE(stdout, & + '(5X,"Cell gradient error",T30,"= ",1PE12.1,/)') cell_error + ! ! ... the bfgs algorithm starts here ! IF ( .NOT. energy_wolfe_condition( energy ) .AND. (scf_iter > 1) ) THEN From ca96fe4b6cb0ccb6d566c7a4dc0dd1abda548c94 Mon Sep 17 00:00:00 2001 From: afonari Date: Fri, 20 Nov 2020 13:50:21 +0000 Subject: [PATCH 06/23] Updated threshold labels in PW/summary.f90 --- PW/src/summary.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PW/src/summary.f90 b/PW/src/summary.f90 index 999bfced6..fabba83c3 100644 --- a/PW/src/summary.f90 +++ b/PW/src/summary.f90 @@ -116,11 +116,11 @@ SUBROUTINE summary() 104 FORMAT(5X, & & 'cutoff for Fock operator = ',F12.4,' Ry') 105 FORMAT(5X, & - & 'convergence threshold = ',1PE12.1,/,5X, & + & 'scf convergence threshold = ',1PE12.1,/,5X, & & 'mixing beta = ',0PF12.4,/,5X, & & 'number of iterations used = ',I12,2X,A,' mixing') 106 FORMAT(5X, & - & 'tot convergence thresh. = ',1PE12.1,/,5X, & + & 'energy convergence thresh.= ',1PE12.1,/,5X, & & 'force convergence thresh. = ',1PE12.1) 107 FORMAT(5X, & & 'press convergence thresh. = ',1PE12.1) From 46a493082931ea9d80a199091ba64dc8cf1612bb Mon Sep 17 00:00:00 2001 From: giannozz Date: Sat, 21 Nov 2020 20:07:38 +0000 Subject: [PATCH 07/23] Small documentation updates --- Doc/developer_man.tex | 1048 +--------------------------------- Doc/user_guide.tex | 25 +- PW/Doc/user_guide.tex | 3 + PW/src/input.f90 | 4 +- PW/src/offset_atom_wfc.f90 | 21 +- TDDFPT/Doc/INPUT_Lanczos.def | 5 - test-suite/Makefile | 4 +- 7 files changed, 55 insertions(+), 1055 deletions(-) diff --git a/Doc/developer_man.tex b/Doc/developer_man.tex index 922aadd25..8d1d63ace 100644 --- a/Doc/developer_man.tex +++ b/Doc/developer_man.tex @@ -95,56 +95,6 @@ You can contribute to a better \qe, even as an ordinary user, by: \newpage -\section{\qe\ as a distribution} - -\qe\ is not a monolithic code, but a {\em distribution} -(an integrated suite) of ``packages'', with -varying degrees of integration, that can be installed on demand, -or sometimes independently. The core distribution includes: -\begin{itemize} -\item scripts, installation tools, libraries, common source files; -\item basic packages -\begin{itemize} -\item \texttt{PWscf}: self-consistent calculations, structural optimization, -molecular dynamics on the ground state; -\item \texttt{CP}: Car-Parrinello molecular dynamics; -\item \texttt{PostProc}: data analysis and plotting (requires \texttt{PWscf}). -\end{itemize} -\item additional packages, using routines from the basic packages, - developed and packaged together with the core distribution: -\begin{itemize} -\item \texttt{atomic}: pseudopotential generation -\item \texttt{PHonon}: Density-Functional Perturbation Theory -\item \texttt{NEB}: reaction pathways and energy barriers -\item \texttt{PWCOND}: ballistic conductance -\item \texttt{XSPECTRA}: calculation of X-ray spectra -\item \texttt{TDDFPT}: Time-dependent DFPT -\item \texttt{EPW}: electron-phonon coupling coefficients -\item \texttt{GWL}: GW and BSE using Lanczos chains -\end{itemize} -\end{itemize} -There are also external (separately developed) packages that make usage -of \qe\ routines: -\begin{itemize} -\item \texttt{GIPAW}: NMR coefficients and chemical shifts, -\item \texttt{West}: Many-body perturbation corrections to DFT. -\end{itemize} -or that just read data produced by \qe\ but do not need it to work: -\begin{itemize} -\item \texttt{Yambo}: Many-body perturbation Theory -\item \texttt{Wannier90}: Wannier Functions utilities -\item \texttt{WanT}: Transport with Wannier Functions -\end{itemize} -Most of them can be automatically downloaded and installed from the core -distribution using \texttt{make}. - -Finally there are {\em plugins}: these modify \qe\ packages, adding -new functionalities. Currently the following plugins are available: -\begin{itemize} -\item \texttt{Plumed}, v.1.3 only, for metadynamics; -\item \texttt{Environ}, for calculations with a solvent. -\end{itemize} - \section{How to become a developer} \label{SubSec:BeDev} @@ -173,8 +123,9 @@ There is also a GitHub mirror \texttt{github.com/QEF/q-e}, only for the official GitLab repository. The GitHub repository can be downloaded as follows: \texttt{git clone https://github.com/QEF/q-e.git}. -See Sect.\ref{Sec:git}, ``Using git'', and file \texttt{CONTRIBUTING.md}, -for instructions on how to use \texttt{git}. +See Sect.\ref{Sec:git}, ``Using git'', file \texttt{CONTRIBUTING.md}, +and the wiki page on GitLab: +\verb|https://gitlab.com/QEF/q-e/-/wikis/Contributing-to-Quantum-Espresso-using-GitLab|, for instructions on how to use \texttt{git}. \subsection{Contributing new developments} \label{SubSec:Contrib} @@ -346,6 +297,12 @@ to directory:\\ \section{Structure of the distribution} +\qe\ is not a monolithic code, but a {\em distribution} +(an integrated suite) of ``packages'', with +varying degrees of integration, that can be installed on demand, +or sometimes independently. See the User Guide for the list of packages +and a description of the contents of the various directories. + The directory structure of \qe\ reflects its organization into packages. Each package is stored into a specific subdirectory. In addition, there is a set of directories, common to all packages, @@ -362,9 +319,10 @@ directory are: \texttt{pseudo/}, \texttt{environment\_variables}, \texttt{test-suite/} \item {\em General documentation} (not package-specific):\\ \texttt{Doc/}, \texttt{License}, \texttt{README.md}, \texttt{CONTRIBUTING.md} -\item {\em Libraries: FFT, Linear Algebra, Utility, Solvers, DFT-D3}:\\ +\item {\em Libraries: FFT, Linear Algebra, Utility, Solvers, + Pseudopotentials, DFT-D3}:\\ \texttt{FFTXlib/}, \texttt{LAXlib/}, \texttt{UtilXlib/}, - \texttt{KS\_Solvers/}, \texttt{dft-d3/} + \texttt{KS\_Solvers/}, \texttt{upflib/}, \texttt{dft-d3/} \item {\em C and Fortran sources}:\\ \texttt{include/}, \texttt{clib/}, \texttt{Modules/} \item {\em utilities to call \qe\ programs from external codes}:\\ @@ -390,6 +348,10 @@ is called \texttt{src/} ). \subsection{Installation Mechanism} +NOTE: cMake is also supported since v.6.7. See the wiki page +on GitLab: +\verb|https://gitlab.com/QEF/q-e/-/wikis/CMake-build-system|. + \label{SubSec:Inst} Let us review the files related to compilation and linking: \begin{itemize} @@ -1170,84 +1132,8 @@ Integration with other packages: \subsection{Programming style (or lack of it)} -There are currently no strict guidelines for developers. You -should however follow at least the following loose ones: -\begin{itemize} -\item Preprocessing options should be capitalized and start with -two underscores. Examples: \_\_MPI, \_\_LINUX, ... Use -preprocessing syntax \verb|#if defined (XXX)|, not \verb|#if defined XXX| -or \verb|#ifdef XXX| -\item Fortran commands should be capitalized: -CALL something( ) -\item Variable names should be lowercase: \texttt{foo = bar/2} -\item Indent DO's and IF's with three white spaces (editors like emacs will do this automatically for you) -\item Do not write crammed code: leave spaces, insert empty separation lines -\item Use comments (introduced by a !) to explain what is not obvious from -the code. Remember that what is obvious to you may not be obvious to other -people. It is especially important to document what a routine does, what -it needs on input, what it produces on output. A few words of comment -may save hours of searching into the code for a piece of missing information. -\item do not use non-standard machine-dependent extensions or sloppy syntax. - An example: Standard Fortran requires that a \& is needed both at end of - line AND at the beginning of continuation line if there is a character - variable (inside ' ' or " ") spanning two lines. Some compilers do not - complain if the latter \& is missing, others do. -% Another example: empty strings are nonstandard, -% use \texttt{empty='~'}, not \texttt{empty=''}. -\item try to stick to F2003 standard: \qe\ must work even if you do not have - the latest and the greatest compiler. Use F2008 syntax only if really - useful, and after verifying that it doesn't break too many compilers. -\item use "dp" (defined in module ''kinds'') to define the type of real and - complex variables -\item all constants should be defined to be of kind "dp". Preferred syntax: - 0.0\_dp. -\item use "generic" intrinsic functions: SIN, COS, etc. -\item conversions should be explicitly indicated. For conversions to real, -use DBLE, or else REAL(...,KIND=dp). For conversions to complex, use -CMPLX(...,...,KIND=dp). For complex conjugate, use CONJG. For imaginary part, -use AIMAG. IMPORTANT: Do not use REAL or CMPLX without KIND=dp, or else you -will lose precision (except when you take the real part of a -double precision complex number). -\item Do not use automatic arrays (e.g. \texttt{REAL(dp) :: A(N)} with -\texttt{N} defined at run time) unless you are sure that the array is -small in all cases: large arrays may easily exceed the stack size, -or the memory size. -\item Do not use pointers unless you have a good reason to: -pointers may hinder optimization. Allocatable arrays should be used instead. -\item If you use pointers, nullify them before performing tests on their -status. -\item Beware fancy constructs like structures: they look great on paper, -but they also have the potential to make a code unreadable, or inefficient, -or unusable with some compilers. Avoid nested structures unless you have a -valid reason to use them. -\item Be careful with array syntax and in particular with -array sections. Passing an array section to a routine may look elegant -but it may turn out to be inefficient: a copy will be silently done -if the section is not contiguous in memory (or if the compiler -decides it is the right thing to do), increasing the memory footprint. -\item Do not pass unallocated arrays or pointers as non-optional arguments, -even in those cases where they are not actually used inside the subroutine: -some compilers don't like it. Also note that if passed as optional argument ---provided the argument has not the pointer or allocatable attribute-- -unallocated arrays or pointers are interpreted as non present (this is a -F2008 feature, already used since v.6.4). -\item Do not use any construct that is susceptible to be flagged as -out-of-bounds error, even if no actual out-of-bound error takes place. -\item Always use IMPLICIT NONE and declare all local variables. -All variables passed as arguments to a routine should be declared as -INTENT (IN), (OUT), or (INOUT). All variables from modules should be -explicitly specified via USE module, ONLY : variable. Variables used -in an array declaration must be declared first, as in the following -example: -\begin{verbatim} - INTEGER, INTENT(IN) :: N - REAL(dp), INTENT(OUT) :: A(N) -\end{verbatim} -in this order (some compilers complain if you put the second line -before the first). -\end{itemize} -The \texttt{dev-tools/} directory contains some useful tools for developers; -see the \texttt{dev-tools/README.md} file. +See the wiki page on GitLab: +\verb|https://gitlab.com/QEF/q-e/-/wikis/Programming-guidelines|. \subsection{Adding or modifying input variables} @@ -1318,902 +1204,14 @@ the release. Note that: \section{Using git} \label{Sec:git} -The following notes cover the \qe-specific work organization, plus the -essential git commands. Those interested in mastering git may consult -one of the many available on-line guides and tutorials, e.g., -\verb|git-scm.com/book/en/v2|. +See the wiki page on GitLab: +\verb|https://gitlab.com/QEF/q-e/-/wikis/Contributing-to-Quantum-Espresso-using-Gitlab|. -The git repository is hosted on GitLab: \verb|https://gitlab.com/QEF/q-e|. -A mirror, automatically aligned every week, is available -on GitHub: \verb|https://github.com/QEF/q-e|. To download the repository: -\begin{quote} - \verb|git clone https://gitlab.com/QEF/q-e.git| or\\ - \verb|git clone git@gitlab.com:QEF/q-e.git| -\end{quote} -Registration on GitLab is not needed at this stage but it is useful anyway. -GitLab accepts a number of other accounts (Google, GitHub, ...) to sign in. - -The repository contains a ``master'' and a ``develop'' branch, -plus other branches for specific goals. The ``develop'' branch is the -default and is where development goes on. The ``master'' branch is -aligned to the ``develop'' branch from time to time, when ``develop'' -looks stable enough. No other changes are allowed in ``master'' except -for serious bugs. - -\subsection{Developing with git} - -Development can proceed in different ways: -\begin{enumerate} -\item Via ``merge'' requests from a branch in the developer's repository - forked from the q-e repository ({\em recommended}) -\item Via ``merge'' requests from a branch of the q-e repository - ({\em not recommended}) -\item Directly into the ``develop'' branch, or in a ``backport'' branch - if existing ({\em strongly discouraged}). -\end{enumerate} -The first option is the recommended one. To start: -\begin{itemize} -\item Register on gitlab.com, {\em save your public ssh keys} - on your GitLab account (in this page: \verb|https://gitlab.com/profile/keys|) -\item {\em fork} the QEF/q-e project: point your browser to - \verb|https://gitlab.com/QEF/q-e|, use the ``fork'' button -\item {\em clone} your GitLab fork on your workstation, e.g.:\\ - \verb|git clone git@gitlab.com:/q-e.git| -\item optionally, switch to the ``develop'' branch of your fork - (just to keep the symmetry): - \verb|git checkout --track origin/develop| -\end{itemize} -Every time you start to do some work, align your fork to the -``develop'' branch: -\begin{quote} - \verb|git pull git@gitlab.com:QEF/q-e.git develop| -\end{quote} -then create a new branch and work on it: -\begin{quote} - \verb|git checkout -b| {\em my-new-branch} -\end{quote} -(if the branch exists, use \verb|git checkout | {\em my-branch} to -switch to it. If your local repository contains unsaved changes, -commit or "stash" them before switching branch). - -Once you have made your changes, {\em commit} (save) then: -\begin{quote} - \verb|git add| {\em list-of-changed-or-added-files} , then - \verb| git commit | , or \\ - \verb|git commit| {\em list-of-changed-files}, or \\ - \verb|git commit -a| (commits all modified files) -\end{quote} -Please when committing BE EXTREMELY CAREFUL not to add files that do -not belong to the repository, e.g.: data files, executables, objects. -These files MUST NOT BE COMMITTED. -Once you are finished with changes, you have to {\em push} (publish) -to the remote repository: -\begin{quote} - \verb|git push origin | {\em my-new-branch} -\end{quote} -or just \verb|git push| if the remote branch {\em my-new-branch} already -exists. The reply message should contain a link that allows you to make -a ``merge request'' (the link works only if you are signed in to gitlab.com). -You can also use the GitLab web interface to that end. -The branch may be automatically removed after the merge (set the appropriate -option if you approve your merge) or using \verb|git branch -d | -{\em my-new-branch}. - -Note: if a merge request is pending and you push further changes to the -branch to be merged, the merge request will be automatically updated. -If this is not what you want, commit to a different branch, or wait -until the merge is done. - -It may be a good idea to align your branch to the current development -version before the merge request. If you have modified a file that has -meanwhile been modified in the repository, a conflict will arise. You -can use \texttt{git stash} to resolve the conflict: -\begin{quote} - \verb|git stash save | (save and remove modified files)\\ - \verb|git pull ... | (update files)\\ - \verb|git stash apply| (overwrite with locally modified files) -\end{quote} -Beware! you may need to manually merge files that have been modified both -by you and in the repository. \texttt{git stash -l} list all stashed -changes in reverse chronological order. The stash can be cleared using -\texttt{git stash clear}. - -Note: if you do not change sources but only documentation, tests, examples, -add \verb|[skip ci]| in the commit message. This prevents execution of -automatic compilation on GitLab (that sometimes fails for no good reason, -blocking a subsequent merge request). - -Note: a commit message containing \verb|[fixes issue #N]| should -automatically mark issue N to as solved once it is merged. - -\subsection{Working directly into the develop branch} -NOT RECOMMENDED - only for people knowing what they are doing -(or ready to fix the mess in case they didn't know what they were doing): -\begin{itemize} -\item \verb|git clone git@gitlab.com:QEF/q-e.git| if not already done -\item Ensure you switch to the ``develop'' branch: - \verb|git checkout --track origin/develop| -\item Work on it as in the previous subsection -\item When you are ready, commit and push. -\end{itemize} - -\subsection{A few useful commands} -\begin{itemize} -\item \texttt{git status}: information on the current state of the repository -(use option \texttt{-uno} to get rid of messages about untracked file) -\item \texttt{git diff}: difference between the local copy and the repository -\item \texttt{git fetch}: - looks at the remote repository, signals if new files or conflicts are present - in case the local copy is updated -\item \texttt{git pull}: - downloads updates from the remote repository, applies them to the local one. - If there are conflicts that cannot be easily solved, conflicts are flagged - and one has to proceed with a manual merge -\item \texttt{git add}: adds files or directories to the "stage area", a pool - of files to be committed -\item \texttt{git commit}: commits files in the "stage area". Unlike - \texttt{svn commit}, files are committed only in the local repository -\item \texttt{git push}: publishes the new commits of the local repository - to one or more remote repositories -\item \texttt{git merge}: merges two branches (typically the local one and - the remote one). A merge may be easy or complex, depending upon the type of - conflicts. -\item \texttt{git branch}: information and operations on branches -\end{itemize} - -\section{The \qe \, test-suite} +\section{Test suite and test farm} \label{Sec:testfarm} -The \qe\, test-suite is used to ensure continuous integration and long-term numerical stability of the code. -The test-suite is also used by different Buildbot test-farm to automatically test the code nightly after a commit to the repository has been detected. - -The currently active test-farm machine can be accessed at -\texttt{test-farm.quantum-espresso.org} (points to a machine at CINECA: -\verb|{http://130.186.13.169:8010/#/}| - -\subsection{How to add tests for a new executable} - -Let us take the example of adding a new test for the TDDFPT module. - -\begin{description} -\item [extract-PROG\_NAME.x] This script extracts the physical quantities from the output and parse it in a format for the testcode.py script. The script need to contain all the different output you want to parse (for chain calculations). For example, in this case we want to parse the output of \texttt{pw.x}, \texttt{turbo\_lanczos.x} and \texttt{turbo\_spectrum.x}. It is crucial to add as many parameter to be tested as possible to increase the code coverability. -\item [run-PROG\_NAME.sh] This bash script contains the paths of the different programs and source the \texttt{ENVIRONMENT} file -\item [jobconfig] You need to edit this file to add all the new tests as well as the new program. You can chain different programs with different output in one test. In this case we added -\begin{verbatim} -[tddfpt_*/] -program = TDDFPT -\end{verbatim} -This means that all the new tests related to TDDFPT must be placed in a folder with a name that starts with \texttt{tddfpt\_}. You can also add it to a new category. -\item[userconfig.tmp] This file contains the accepted accuracies for the different physical quantities defined in \texttt{extract-PROG\_NAME.x}. You need to add a new section for your program. For the tolerance variable, the first column is the absolute accepted value, the second one is the relative accepted value and the third column contains the name of the physical quantity as defined earlier. Note that you need to add the values for all the code that you intend to test. In our case we need to add variable from \texttt{pw.x} as well (although already defined for other program). -To estimate the acceptable tolerance, it is advised to start with very strict tolerance (very low value, e.g. 1d-6 or so) and then make some local tests (for example comparing the results in sequential or in parallel). One can then raise slightly the accepted tolerance. -\item[Makefile] One need to add a line to check for potential pseudopotential to be downloaded by adding the line \texttt{@./check\_pseudo.sh tddfpt\_}. -\item[PROG\_NAME\_TEST\_NAME] Create one folder for each new test you want to add following the convention prog\_name and test\_name. In our case we create a folder name \texttt{tddfpt\_CH4}. The folder must contain all the input files, the pseudopotentials that are needed for that test and the reference files. The reference files must have a name that starts with \texttt{benchmark.out.git.inp=}. However, the easiest is to run the test suite for that test and the code will tell you what is the name he expects to have. You can then rename your reference output with that name. In our case we will therefore do -\begin{verbatim} -make run-custom-test testdir=tddfpt_CH4 -\end{verbatim} -We can then rename the output by doing -\begin{verbatim} -cp test.out.030117.inp=CH4.pw-in.args=1 benchmark.out.git.inp=CH4.pw-in.args=1 -\end{verbatim} -We now have a reference file for the first step of the calculation. We can do the same for the two other steps. - -Once this is done. We can clean all the unwanted files and we should be left with a clean folder that can be committed to the git repo. In our case the test folder contains the following files: -\begin{verbatim} -benchmark.out.git.inp=CH4.pw-in.args=1 -benchmark.out.git.inp=CH4.tddfpt_pp-in.args=3 -benchmark.out.git.inp=CH4.tddfpt-in.args=2 -CH4.tddfpt-in -CH4.pw-in -CH4.tddfpt_pp-in -\end{verbatim} - -It is very important to then re-run the tests in parallel (4 cores) to be sure that the results are within the accepted tolerance. - -\end{description} - - -\subsection{How to add tests for an existing executable} - -You have to create a new folder following the convention prog\_name and test\_name and then follow the structure outline above. -If you want to test new physical quantities, you need to parse them using the script \texttt{extract-PROG\_NAME.x}. Finally, the new test should -be added in \texttt{jobconfig}. - - -\section{OBSOLETE STUFF} - -\subsection{How to add support for a new architecture} - -In order to support a previously unsupported architecture, first you -have to figure out which compilers, compilation flags, libraries -etc. should be used on that architecture. -In other words, you have to write a \make.inc\ that works: you may use -the manual configuration procedure for that (see the -User Guide). Then, you have to modify \configure\ so that it can -generate that \make.inc\ automatically. - -To do that, you have to add the case for your architecture in several -places throughout \configurac: -\begin{enumerate} -\item Detect architecture - -Look for these lines: -\begin{verbatim} - if test "$arch" = "" - then - case $host in - ia64-*-linux-gnu ) arch=ia64 ;; - x86_64-*-linux-gnu ) arch=x86_64 ;; - *-pc-linux-gnu ) arch=ia32 ;; - etc. -\end{verbatim} -Here you must add an entry corresponding to your architecture and -operating system. Run \texttt{config.guess} to obtain the string identifying -your system. -For instance on a PC it may be "i686-pc-linux-gnu", while on IBM SP4 -"powerpc-ibm-aix5.1.0.0". It is convenient to put some asterisks to -account for small variations of the string for different machines of -the same family. For instance, it could be "aix4.3" instead of -"aix5.1", or "athlon" instead of "i686"... - -\item Select compilers - -Look for these lines: - -\begin{verbatim} - # candidate compilers and flags based on architecture - case $arch in - ia64 | x86_64 ) - ... - ia32 ) - ... - aix ) - ... - etc. -\end{verbatim} - -Add an entry for your value of \$arch, and set there the appropriate -values for several variables, if needed (all variables are assigned -some reasonable default value, defined before the "case" block): - -- "try\_f90" should contain the list of candidate Fortran 90 compilers, -in order of decreasing preference (i.e. configure will use the first -it finds). If your system has parallel compilers, you should list -them in "try\_mpif90". - -- "try\_ar", "try\_arflags": for these, the values "ar" and "ruv" should -be always fine, unless some special flag is required (e.g., -X64 -With sp4). - -- you should define "try\_dflags" if there is any preprocessing -option specific to your machine: for instance, on IBM machines, -"try\_dflags=-D\_\_AIX" . A list of such flags can be found in file -\texttt{include/defs.h.README}. - -You shouldn't need to define the following: -- "try\_iflags" should be set to the appropriate "-I" option(s) -needed by the preprocessor or by the compiler to locate *.h files -to be included; try\_iflags="-I../include" should be good for most cases - -For example, here's the entry for IBM machines running AIX: -\begin{verbatim} - aix ) - try_mpif90="mpxlf90_r mpxlf90" - try_f90="xlf90_r xlf90 $try_f90" - try_arflags="-X64 ruv" - try_arflags_dynamic="-X64 ruv" - try_dflags="-D__AIX -D__XLF" - ;; -\end{verbatim} -The following step is to look for both serial and parallel fortran -compilers: -\begin{verbatim} - # check serial Fortran 90 compiler... - ... - AC_PROG_F77($f90) - ... - # check parallel Fortran 90 compiler - ... - AC_PROG_F77($mpif90) - ... - echo setting F90... $f90 - echo setting MPIF90... $mpif90 -\end{verbatim} -A few compilers require some extra work here: for instance, if the -Intel Fortran compiler was selected, you need to know which version -because different versions need different flags. - -At the end of the test, - -- \$mpif90 is the parallel compiler, if any; if no parallel compiler - is found or if \texttt{--disable-parallel} was specified, \$mpif90 - is the serial compiler - -- \$f90 is the serial compiler - -Next step: the choice of (serial) C and Fortran 77 compilers. -Look for these lines: -\begin{verbatim} - # candidate C and f77 compilers good for all cases - try_cc="cc gcc" - try_f77="$f90" - - case "$arch:$f90" in - *:f90 ) - .... - etc. -\end{verbatim} -Here you have to add an entry for your architecture, and since the -correct choice of C and f77 compilers may depend on the fortran-90 -compiler, you may need to specify the f90 compiler as well. -Again, specify the compilers in try\_cc and try\_f77 in order of -decreasing preference. At the end of the test, - -- \$cc is the C compiler - -- \$f77 is the Fortran 77 compiler, used to compile *.f files -(may coincide with \$f90) - -\item Specify compilation flags. - -Look for these lines: -\begin{verbatim} - # check Fortran compiler flags - ... - case "$arch:$f90" in - ia64:ifort* | x86_64:ifort* ) - ... - ia64:ifc* ) - ... - etc. -\end{verbatim} -Add an entry for your case and define: - -- "try\_fflags": flags for Fortran 77 compiler. - -- "try\_f90flags": flags for Fortran 90 compiler. -In most cases they will be the same as in Fortran 77 plus some -others. In that case, define them as "\$(FFLAGS) -something\_else". - -- "try\_fflags\_noopt": flags for Fortran 77 with all optimizations -turned off: this is usually "-O0". -These flags used to be needed to compile LAPACK dlamch.f; likely obsolete - -- "try\_ldflags": flags for the linking phase (not including the list -of libraries: this is decided later). - -- "try\_ldflags\_static": additional flags to select static compilation -(i.e., don't use shared libraries). - -- "try\_dflags": must be defined if there is in the code any preprocessing -option specific to your compiler (for instance, -D\_\_INTEL for Intel -compilers). Define it as "\$try\_dflags -D..." so that pre-existing -flags, if any, are preserved. - -- if the Fortran compiler is not able to invoke the C preprocessor -automatically before compiling, set "have\_cpp=0" (the opposite case -is the default). The appropriate compilation rules will be generated -accordingly. If the compiler requires that any flags be specified in -order to invoke the preprocessor (for example, "-fpp " -- note the -space), specify them in "pre\_fdflags". - -For example, here's the entry for ifort on Linux PC: -\begin{verbatim} - ia32:ifort* ) - try_fflags="-O2 -tpp6 -assume byterecl" - try_f90flags="\$(FFLAGS) -nomodule" - try_fflags_noopt="-O0 -assume byterecl" - try_ldflags="" - try_ldflags_static="-static" - try_dflags="$try_dflags -D__INTEL" - pre_fdflags="-fpp " - ;; -\end{verbatim} -Next step: flags for the C compiler. Look for these lines: -\begin{verbatim} - case "$arch:$cc" in - *:icc ) - ... - *:pgcc ) - ... - etc. -\end{verbatim} -Add an entry for your case and define: - -- "try\_cflags": flags for C compiler. - -- "c\_ldflags": flags for linking, when using the C compiler as linker. -This is needed to check for libraries written in C, such as FFTW. - -- if you need a different preprocessor from the standard one (\$CC -E), -define it in "try\_cpp". - -For example for XLC on AIX: -\begin{verbatim} - aix:mpcc* | aix:xlc* | aix:cc ) - try_cflags="-q64 -O2" - c_ldflags="-q64" - ;; -\end{verbatim} -Finally, if you have to use a nonstandard preprocessor, look for these -lines: -\begin{verbatim} - echo $ECHO_N "setting CPPFLAGS... $ECHO_C" - case $cpp in - cpp) try_cppflags="-P -traditional" ;; - fpp) try_cppflags="-P" ;; - ... -\end{verbatim} -and set "try\_cppflags" as appropriate. - -\item Search for libraries - -To instruct \configure\ to search for libraries, you must tell it two -things: the names of libraries it should search for, and where it -should search. - -The following libraries are searched for: - -- BLAS or equivalent. -Some vendor replacements for BLAS that are supported by \qe\ are: -\begin{quote} - MKL on Linux, 32- and 64-bit Intel CPUs\\ - ACML on Linux, 64-bit AMD CPUs\\ - ESSL on AIX\\ - SCSL on sgi altix\\ - SUNperf on sparc -\end{quote} -Moreover, ATLAS is used over BLAS if available. - -- LAPACK or equivalent. Some vendor replacements for LAPACK are supported - by \qe, e.g.: Intel MKL, IBM ESSL - -- FFTW (version 3) or another supported FFT library (e.g Intel DFTI, - IBM ESSL) - -- the IBM MASS vector math library - -- an MPI library. This is often automatically linked by the compiler - -If you have another replacement for the above libraries, you'll have -to insert a new entry in the appropriate place. - -This is unfortunately a little bit too complex to explain. -Basic info: \\ -"AC\_SEARCH\_LIBS(function, name, ...)" looks for symbol -"function" in library "libname.a". If that is found, "-lname" is -appended to the LIBS environment variable (initially empty). -The real thing is more complicated than just that because the -"-Ldirectory" option must be added to search in a nonstandard -directory, and because a given library may require other libraries as -prerequisites (for example, Lapack requires BLAS). -\end{enumerate} - -\subsection{\qe\ restart file specifications} - -Written by Paolo Giannozzi 2005-11-11, -Last modified by Andrea Ferretti 2006-10-29 - -Format name: QEXML \\ -Format version: 1.4.0 \\ - -The "restart file" is actually a "restart directory", containing -several files and sub-directories. For CP/FPMD, the restart directory -is created as "\$prefix\_\$ndw/", where \$prefix is the value of the -variable "prefix". \$ndw the value of variable ndw, both read in -input; it is read from "\$prefix\_\$ndr/", where \$ndr the value of -variable ndr, read from input. For PWscf, both input and output -directories are called "\$prefix.save/". - -The content of the restart directory is as follows: -\begin{verbatim} -data-file.xml which contains: - - general information that doesn't require large data set: - atomic structure, lattice, k-points, symmetries, - parameters of the run, ... - - pointers to other files or directories containing bulkier - data: grids, wavefunctions, charge density, potentials, ... - -charge_density.dat contains the charge density -spin_polarization.dat contains the spin polarization (rhoup-rhodw) (LSDA case) -magnetization.x.dat -magnetization.y.dat contain the spin polarization along x,y,z -magnetization.z.dat (noncollinear calculations) -lambda.dat contains occupations (Car-Parrinello dynamics only) -mat_z.1 contains occupations (ensemble-dynamics only) - - A copy of all pseudopotential files given in input - - Subdirectories K00001/, K00002/, etc, one per k-point. -\end{verbatim} -Each k-point directory contains: -\begin{verbatim} - evc.dat wavefunctions for spin-unpolarized calculations, OR - evc1.dat - evc2.dat spin-up and spin-down wavefunctions, respectively, - for spin polarized (LSDA) calculations; - gkvectors.dat the details of specific k+G grid; - eigenval.xml eigenvalues for the corresponding k-point - for spin-unpolarized calculations, OR - eigenval1.xml spin-up and spin-down eigenvalues, - eigenval2.xml for spin-polarized calculations; -\end{verbatim} -in a molecular dynamics run, also wavefunctions at the preceding time step: -\begin{verbatim} - evcm.dat for spin-unpolarized calculations OR - evcm1.dat - evcm2.dat for spin polarized calculations; -\end{verbatim} - -\begin{itemize} -\item All files "*.xml" are XML-compliant, formatted file; -\item Files "mat\_z.1", "lambda.dat" are unformatted files, containing a single record; -\item All other files "*.dat", are XML-compliant files, but they - contain an unformatted record. -\end{itemize} - -\subsubsection{Structure of file "data-file.xml"} - -\begin{verbatim} -XML Header: whatever is needed to have a well-formed XML file - -Body: introduced by , terminated by . Contains first-level tags - only. These contain only other tags, not values. XML syntax applies. - -First-level tags: contain either - second-level tags, OR - data tags: tags containing data (values for a given variable), OR - file tags: tags pointing to a file -\end{verbatim} -data tags syntax ( [...] = optional ) : -\begin{verbatim} - - values (in appropriate units) for variable corresponding to TAG: - n elements of type vartype (if character, of length k) - -\end{verbatim} -where TAG describes the variable into which data must be read;\\ -"vartype" may be "integer", "real", "character", "logical";\\ -if type="logical", LEN=k" must be used to specify the length -of the variable character; size="n" is the dimension.\\ -Acceptable values for "units" depend on the specific tag. - -Short syntax, used only in a few cases: -\begin{verbatim} - . -\end{verbatim} -For instance: -\begin{verbatim} - -\end{verbatim} -defines the value of the FFT grid parameters nr1, nr2, nr3 -for the charge density - -\subsubsection{Sample} -Header: -\begin{verbatim} - - - - -\end{verbatim} -These are meant to be used only by iotk (actually they aren't) - -First-level tags: -\begin{verbatim} - -
(global information about fmt version) - - (miscellanea of internal information) - - (information about the status of the CP simulation) - - (lattice vector, unit cell, etc) - - (type and positions of atoms in the unit cell etc) - - (symmetry operations) - - (details for an eventual applied electric field) - - (basis set, cutoffs etc) - - (info on spin polarizaztion) - - (info about starting or constrained magnetization) - - - - (occupancy of the states) - - (k-points etc) - - (specialized info for parallel runs) - - - - (positions, velocities, nose' thermostats) - - (dimensions and basic data about band structure) - - (eigenvalues and related data) - - (eigenvectors and related data) - - -* Tag description - -
- (name and version of the format) - (name and version of the code generating the file) -
- - - (whether file is complete and suitable for post-processing) - (whether kpt-data are written in sub-directories) - (whether augmentation terms are used in real space) - (whether projectors are used in real space, not implemented) - - - (optional, written only by CP) - (number $n of steps performed, i.e. we are at step $n) -