diff --git a/.github/workflows/unittest-macos.yml b/.github/workflows/unittest-macos.yml index a65db7636b..f62b3046c9 100644 --- a/.github/workflows/unittest-macos.yml +++ b/.github/workflows/unittest-macos.yml @@ -24,7 +24,9 @@ jobs: shell: bash working-directory: ${{github.workspace}}/build run: | - cmake -C $GITHUB_WORKSPACE/cmake/presets/most.cmake $GITHUB_WORKSPACE/cmake \ + cmake -C $GITHUB_WORKSPACE/cmake/presets/clang.cmake \ + -C $GITHUB_WORKSPACE/cmake/presets/most.cmake \ + $GITHUB_WORKSPACE/cmake \ -DENABLE_TESTING=ON -DBUILD_SHARED_LIBS=ON -DLAMMPS_EXCEPTIONS=ON cmake --build . --parallel 2 diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 21d965ebba..4c94a5037a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -22,6 +22,11 @@ set(LAMMPS_TOOLS_DIR ${LAMMPS_DIR}/tools) set(LAMMPS_PYTHON_DIR ${LAMMPS_DIR}/python) set(LAMMPS_POTENTIALS_DIR ${LAMMPS_DIR}/potentials) +set(LAMMPS_DOWNLOADS_URL "https://download.lammps.org" CACHE STRING "Base URL for LAMMPS downloads") +set(LAMMPS_POTENTIALS_URL "${LAMMPS_DOWNLOADS_URL}/potentials") +set(LAMMPS_THIRDPARTY_URL "${LAMMPS_DOWNLOADS_URL}/thirdparty") +mark_as_advanced(LAMMPS_DOWNLOADS_URL) + find_package(Git) # by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed diff --git a/cmake/Modules/Documentation.cmake b/cmake/Modules/Documentation.cmake index 5a42244b9e..c0028676b7 100644 --- a/cmake/Modules/Documentation.cmake +++ b/cmake/Modules/Documentation.cmake @@ -55,11 +55,15 @@ if(BUILD_DOC) COMMAND ${DOCENV_BINARY_DIR}/pip $ENV{PIP_OPTIONS} install -r ${DOC_BUILD_DIR}/requirements.txt --upgrade ) + set(MATHJAX_URL "https://github.com/mathjax/MathJax/archive/3.1.2.tar.gz" CACHE STRING "URL for MathJax tarball") + set(MATHJAX_MD5 "a4a6a093a89bc2ccab1452d766b98e53" CACHE STRING "MD5 checksum of MathJax tarball") + mark_as_advanced(MATHJAX_URL) + # download mathjax distribution and unpack to folder "mathjax" if(NOT EXISTS ${DOC_BUILD_STATIC_DIR}/mathjax/es5) - file(DOWNLOAD "https://github.com/mathjax/MathJax/archive/3.1.2.tar.gz" + file(DOWNLOAD ${MATHJAX_URL} "${CMAKE_CURRENT_BINARY_DIR}/mathjax.tar.gz" - EXPECTED_MD5 a4a6a093a89bc2ccab1452d766b98e53) + EXPECTED_MD5 ${MATHJAX_MD5}) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf mathjax.tar.gz WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) file(GLOB MATHJAX_VERSION_DIR ${CMAKE_CURRENT_BINARY_DIR}/MathJax-*) execute_process(COMMAND ${CMAKE_COMMAND} -E rename ${MATHJAX_VERSION_DIR} ${DOC_BUILD_STATIC_DIR}/mathjax) diff --git a/cmake/Modules/GTest.cmake b/cmake/Modules/GTest.cmake index 0c62291d5e..677ed5f4af 100644 --- a/cmake/Modules/GTest.cmake +++ b/cmake/Modules/GTest.cmake @@ -8,10 +8,12 @@ endif() include(ExternalProject) set(GTEST_URL "https://github.com/google/googletest/archive/release-1.10.0.tar.gz" CACHE STRING "URL for GTest tarball") +set(GTEST_MD5 "ecd1fa65e7de707cd5c00bdac56022cd" CACHE STRING "MD5 checksum of GTest tarball") mark_as_advanced(GTEST_URL) +mark_as_advanced(GTEST_MD5) ExternalProject_Add(googletest - URL ${GTEST_URL} - URL_MD5 ecd1fa65e7de707cd5c00bdac56022cd + URL ${GTEST_URL} + URL_MD5 ${GTEST_MD5} SOURCE_DIR "${CMAKE_BINARY_DIR}/gtest-src" BINARY_DIR "${CMAKE_BINARY_DIR}/gtest-build" CMAKE_ARGS ${CMAKE_REQUEST_PIC} ${CMAKE_EXTRA_GTEST_OPTS} diff --git a/cmake/Modules/LAMMPSUtils.cmake b/cmake/Modules/LAMMPSUtils.cmake index 37275843fa..acaef19498 100644 --- a/cmake/Modules/LAMMPSUtils.cmake +++ b/cmake/Modules/LAMMPSUtils.cmake @@ -86,7 +86,6 @@ endfunction(GenerateBinaryHeader) # fetch missing potential files function(FetchPotentials pkgfolder potfolder) if (EXISTS "${pkgfolder}/potentials.txt") - set(LAMMPS_POTENTIALS_URL "https://download.lammps.org/potentials") file(STRINGS "${pkgfolder}/potentials.txt" linelist REGEX "^[^#].") foreach(line ${linelist}) string(FIND ${line} " " blank) diff --git a/cmake/Modules/MPI4WIN.cmake b/cmake/Modules/MPI4WIN.cmake index 529cefeab0..aa0c9e1833 100644 --- a/cmake/Modules/MPI4WIN.cmake +++ b/cmake/Modules/MPI4WIN.cmake @@ -1,16 +1,25 @@ # Download and configure custom MPICH files for Windows message(STATUS "Downloading and configuring MPICH-1.4.1 for Windows") +set(MPICH2_WIN64_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win64-devel.tar.gz" CACHE STRING "URL for MPICH2 (win64) tarball") +set(MPICH2_WIN32_DEVEL_URL "${LAMMPS_THIRDPARTY_URL}/mpich2-win32-devel.tar.gz" CACHE STRING "URL for MPICH2 (win32) tarball") +set(MPICH2_WIN64_DEVEL_MD5 "4939fdb59d13182fd5dd65211e469f14" CACHE STRING "MD5 checksum of MPICH2 (win64) tarball") +set(MPICH2_WIN32_DEVEL_MD5 "a61d153500dce44e21b755ee7257e031" CACHE STRING "MD5 checksum of MPICH2 (win32) tarball") +mark_as_advanced(MPICH2_WIN64_DEVEL_URL) +mark_as_advanced(MPICH2_WIN32_DEVEL_URL) +mark_as_advanced(MPICH2_WIN64_DEVEL_MD5) +mark_as_advanced(MPICH2_WIN32_DEVEL_MD5) + include(ExternalProject) if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") ExternalProject_Add(mpi4win_build - URL https://download.lammps.org/thirdparty/mpich2-win64-devel.tar.gz - URL_MD5 4939fdb59d13182fd5dd65211e469f14 + URL ${MPICH2_WIN64_DEVEL_URL} + URL_MD5 ${MPICH2_WIN64_DEVEL_MD5} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" BUILD_BYPRODUCTS /lib/libmpi.a) else() ExternalProject_Add(mpi4win_build - URL https://download.lammps.org/thirdparty/mpich2-win32-devel.tar.gz - URL_MD5 a61d153500dce44e21b755ee7257e031 + URL ${MPICH2_WIN32_DEVEL_URL} + URL_MD5 ${MPICH2_WIN32_DEVEL_MD5} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" BUILD_BYPRODUCTS /lib/libmpi.a) endif() diff --git a/cmake/Modules/OpenCLLoader.cmake b/cmake/Modules/OpenCLLoader.cmake index 5ab121f841..54eaab4795 100644 --- a/cmake/Modules/OpenCLLoader.cmake +++ b/cmake/Modules/OpenCLLoader.cmake @@ -1,11 +1,13 @@ message(STATUS "Downloading and building OpenCL loader library") +set(OPENCL_LOADER_URL "${LAMMPS_THIRDPARTY_URL}/opencl-loader-2020.12.18.tar.gz" CACHE STRING "URL for OpenCL loader tarball") +set(OPENCL_LOADER_MD5 "011cdcbd41030be94f3fced6d763a52a" CACHE STRING "MD5 checksum of OpenCL loader tarball") +mark_as_advanced(OPENCL_LOADER_URL) +mark_as_advanced(OPENCL_LOADER_MD5) include(ExternalProject) -set(OPENCL_LOADER_URL "https://download.lammps.org/thirdparty/opencl-loader-2020.12.18.tar.gz" CACHE STRING "URL for OpenCL loader tarball") -mark_as_advanced(OPENCL_LOADER_URL) ExternalProject_Add(opencl_loader - URL ${OPENCL_LOADER_URL} - URL_MD5 011cdcbd41030be94f3fced6d763a52a + URL ${OPENCL_LOADER_URL} + URL_MD5 ${OPENCL_LOADER_MD5} SOURCE_DIR "${CMAKE_BINARY_DIR}/opencl_loader-src" BINARY_DIR "${CMAKE_BINARY_DIR}/opencl_loader-build" CMAKE_ARGS ${CMAKE_REQUEST_PIC} ${CMAKE_EXTRA_OPENCL_LOADER_OPTS} diff --git a/cmake/Modules/Packages/GPU.cmake b/cmake/Modules/Packages/GPU.cmake index 9aa917144b..74a023685d 100644 --- a/cmake/Modules/Packages/GPU.cmake +++ b/cmake/Modules/Packages/GPU.cmake @@ -218,7 +218,7 @@ elseif(GPU_API STREQUAL "HIP") if(NOT DEFINED HIP_PLATFORM) if(NOT DEFINED ENV{HIP_PLATFORM}) - set(HIP_PLATFORM "hcc" CACHE PATH "HIP Platform to be used during compilation") + set(HIP_PLATFORM "amd" CACHE PATH "HIP Platform to be used during compilation") else() set(HIP_PLATFORM $ENV{HIP_PLATFORM} CACHE PATH "HIP Platform used during compilation") endif() @@ -226,7 +226,7 @@ elseif(GPU_API STREQUAL "HIP") set(ENV{HIP_PLATFORM} ${HIP_PLATFORM}) - if(HIP_PLATFORM STREQUAL "hcc") + if(HIP_PLATFORM STREQUAL "hcc" OR HIP_PLATFORM STREQUAL "amd") set(HIP_ARCH "gfx906" CACHE STRING "HIP target architecture") elseif(HIP_PLATFORM STREQUAL "nvcc") find_package(CUDA REQUIRED) @@ -284,7 +284,7 @@ elseif(GPU_API STREQUAL "HIP") set(CUBIN_FILE "${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}.cubin") set(CUBIN_H_FILE "${LAMMPS_LIB_BINARY_DIR}/gpu/${CU_NAME}_cubin.h") - if(HIP_PLATFORM STREQUAL "hcc") + if(HIP_PLATFORM STREQUAL "hcc" OR HIP_PLATFORM STREQUAL "amd") configure_file(${CU_FILE} ${CU_CPP_FILE} COPYONLY) if(HIP_COMPILER STREQUAL "clang") @@ -338,11 +338,16 @@ elseif(GPU_API STREQUAL "HIP") if(DOWNLOAD_CUB) message(STATUS "CUB download requested") + set(CUB_URL "https://github.com/NVlabs/cub/archive/1.12.0.tar.gz" CACHE STRING "URL for CUB tarball") + set(CUB_MD5 "1cf595beacafff104700921bac8519f3" CACHE STRING "MD5 checksum of CUB tarball") + mark_as_advanced(CUB_URL) + mark_as_advanced(CUB_MD5) + include(ExternalProject) ExternalProject_Add(CUB - GIT_REPOSITORY https://github.com/NVlabs/cub - TIMEOUT 5 + URL ${CUB_URL} + URL_MD5 ${CUB_MD5} PREFIX "${CMAKE_CURRENT_BINARY_DIR}" CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -354,7 +359,7 @@ elseif(GPU_API STREQUAL "HIP") else() find_package(CUB) if(NOT CUB_FOUND) - message(FATAL_ERROR "CUB library not found. Help CMake to find it by setting CUB_INCLUDE_DIR, or set DOWNLOAD_VORO=ON to download it") + message(FATAL_ERROR "CUB library not found. Help CMake to find it by setting CUB_INCLUDE_DIR, or set DOWNLOAD_CUB=ON to download it") endif() endif() @@ -381,6 +386,12 @@ elseif(GPU_API STREQUAL "HIP") target_compile_definitions(hip_get_devices PRIVATE -D__HIP_PLATFORM_HCC__) target_include_directories(hip_get_devices PRIVATE ${HIP_ROOT_DIR}/../include) + elseif(HIP_PLATFORM STREQUAL "amd") + target_compile_definitions(gpu PRIVATE -D__HIP_PLATFORM_AMD__) + target_include_directories(gpu PRIVATE ${HIP_ROOT_DIR}/../include) + + target_compile_definitions(hip_get_devices PRIVATE -D__HIP_PLATFORM_AMD__) + target_include_directories(hip_get_devices PRIVATE ${HIP_ROOT_DIR}/../include) endif() target_link_libraries(lammps PRIVATE gpu) diff --git a/cmake/Modules/Packages/KIM.cmake b/cmake/Modules/Packages/KIM.cmake index 5482d3071c..2a2a1cde78 100644 --- a/cmake/Modules/Packages/KIM.cmake +++ b/cmake/Modules/Packages/KIM.cmake @@ -35,9 +35,13 @@ if(DOWNLOAD_KIM) include(ExternalProject) enable_language(C) enable_language(Fortran) + set(KIM_URL "https://s3.openkim.org/kim-api/kim-api-2.2.1.txz" CACHE STRING "URL for KIM tarball") + set(KIM_MD5 "ae1ddda2ef7017ea07934e519d023dca" CACHE STRING "MD5 checksum of KIM tarball") + mark_as_advanced(KIM_URL) + mark_as_advanced(KIM_MD5) ExternalProject_Add(kim_build - URL https://s3.openkim.org/kim-api/kim-api-2.2.1.txz - URL_MD5 ae1ddda2ef7017ea07934e519d023dca + URL ${KIM_URL} + URL_MD5 ${KIM_MD5} BINARY_DIR build CMAKE_ARGS ${CMAKE_REQUEST_PIC} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index 1dfb0bf389..1f00516e08 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -37,9 +37,13 @@ if(DOWNLOAD_KOKKOS) list(APPEND KOKKOS_LIB_BUILD_ARGS "-DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}") list(APPEND KOKKOS_LIB_BUILD_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") include(ExternalProject) + set(KOKKOS_URL "https://github.com/kokkos/kokkos/archive/3.3.01.tar.gz" CACHE STRING "URL for KOKKOS tarball") + set(KOKKOS_MD5 "08201d1c7cf5bc458ce0f5b44a629d5a" CACHE STRING "MD5 checksum of KOKKOS tarball") + mark_as_advanced(KOKKOS_URL) + mark_as_advanced(KOKKOS_MD5) ExternalProject_Add(kokkos_build - URL https://github.com/kokkos/kokkos/archive/3.3.01.tar.gz - URL_MD5 08201d1c7cf5bc458ce0f5b44a629d5a + URL ${KOKKOS_URL} + URL_MD5 ${KOKKOS_MD5} CMAKE_ARGS ${KOKKOS_LIB_BUILD_ARGS} BUILD_BYPRODUCTS /lib/libkokkoscore.a ) diff --git a/cmake/Modules/Packages/LATTE.cmake b/cmake/Modules/Packages/LATTE.cmake index e66f83fa43..ddf31a68ed 100644 --- a/cmake/Modules/Packages/LATTE.cmake +++ b/cmake/Modules/Packages/LATTE.cmake @@ -15,10 +15,14 @@ endif() option(DOWNLOAD_LATTE "Download the LATTE library instead of using an already installed one" ${DOWNLOAD_LATTE_DEFAULT}) if(DOWNLOAD_LATTE) message(STATUS "LATTE download requested - we will build our own") + set(LATTE_URL "https://github.com/lanl/LATTE/archive/v1.2.2.tar.gz" CACHE STRING "URL for LATTE tarball") + set(LATTE_MD5 "820e73a457ced178c08c71389a385de7" CACHE STRING "MD5 checksum of LATTE tarball") + mark_as_advanced(LATTE_URL) + mark_as_advanced(LATTE_MD5) include(ExternalProject) ExternalProject_Add(latte_build - URL https://github.com/lanl/LATTE/archive/v1.2.2.tar.gz - URL_MD5 820e73a457ced178c08c71389a385de7 + URL ${LATTE_URL} + URL_MD5 ${LATTE_MD5} SOURCE_SUBDIR cmake CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= ${CMAKE_REQUEST_PIC} -DCMAKE_INSTALL_LIBDIR=lib -DBLAS_LIBRARIES=${BLAS_LIBRARIES} -DLAPACK_LIBRARIES=${LAPACK_LIBRARIES} diff --git a/cmake/Modules/Packages/MSCG.cmake b/cmake/Modules/Packages/MSCG.cmake index 6cb389fb13..6ac62cb012 100644 --- a/cmake/Modules/Packages/MSCG.cmake +++ b/cmake/Modules/Packages/MSCG.cmake @@ -7,10 +7,15 @@ else() endif() option(DOWNLOAD_MSCG "Download MSCG library instead of using an already installed one)" ${DOWNLOAD_MSCG_DEFAULT}) if(DOWNLOAD_MSCG) + set(MSCG_URL "https://github.com/uchicago-voth/MSCG-release/archive/1.7.3.1.tar.gz" CACHE STRING "URL for MSCG tarball") + set(MSCG_MD5 "8c45e269ee13f60b303edd7823866a91" CACHE STRING "MD5 checksum of MSCG tarball") + mark_as_advanced(MSCG_URL) + mark_as_advanced(MSCG_MD5) + include(ExternalProject) ExternalProject_Add(mscg_build - URL https://github.com/uchicago-voth/MSCG-release/archive/1.7.3.1.tar.gz - URL_MD5 8c45e269ee13f60b303edd7823866a91 + URL ${MSCG_URL} + URL_MD5 ${MSCG_MD5} SOURCE_SUBDIR src/CMake CMAKE_ARGS ${CMAKE_REQUEST_PIC} ${EXTRA_MSCG_OPTS} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} diff --git a/cmake/Modules/Packages/USER-PLUMED.cmake b/cmake/Modules/Packages/USER-PLUMED.cmake index 53abf5771a..8719e8179d 100644 --- a/cmake/Modules/Packages/USER-PLUMED.cmake +++ b/cmake/Modules/Packages/USER-PLUMED.cmake @@ -53,10 +53,16 @@ if(DOWNLOAD_PLUMED) elseif(PLUMED_MODE STREQUAL "RUNTIME") set(PLUMED_BUILD_BYPRODUCTS "/lib/libplumedWrapper.a") endif() + + set(PLUMED_URL "https://github.com/plumed/plumed2/releases/download/v2.7.0/plumed-src-2.7.0.tgz" CACHE STRING "URL for PLUMED tarball") + set(PLUMED_MD5 "95f29dd0c067577f11972ff90dfc7d12" CACHE STRING "MD5 checksum of PLUMED tarball") + mark_as_advanced(PLUMED_URL) + mark_as_advanced(PLUMED_MD5) + include(ExternalProject) ExternalProject_Add(plumed_build - URL https://github.com/plumed/plumed2/releases/download/v2.7.0/plumed-src-2.7.0.tgz - URL_MD5 95f29dd0c067577f11972ff90dfc7d12 + URL ${PLUMED_URL} + URL_MD5 ${PLUMED_MD5} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND /configure --prefix= ${CONFIGURE_REQUEST_PIC} diff --git a/cmake/Modules/Packages/USER-SCAFACOS.cmake b/cmake/Modules/Packages/USER-SCAFACOS.cmake index dc5c400c36..fd355420c3 100644 --- a/cmake/Modules/Packages/USER-SCAFACOS.cmake +++ b/cmake/Modules/Packages/USER-SCAFACOS.cmake @@ -14,15 +14,19 @@ endif() option(DOWNLOAD_SCAFACOS "Download ScaFaCoS library instead of using an already installed one" ${DOWNLOAD_SCAFACOS_DEFAULT}) if(DOWNLOAD_SCAFACOS) message(STATUS "ScaFaCoS download requested - we will build our own") + set(SCAFACOS_URL "https://github.com/scafacos/scafacos/releases/download/v1.0.1/scafacos-1.0.1.tar.gz" CACHE STRING "URL for SCAFACOS tarball") + set(SCAFACOS_MD5 "bd46d74e3296bd8a444d731bb10c1738" CACHE STRING "MD5 checksum of SCAFACOS tarball") + mark_as_advanced(SCAFACOS_URL) + mark_as_advanced(SCAFACOS_MD5) # version 1.0.1 needs a patch to compile and linke cleanly with GCC 10 and later. - file(DOWNLOAD https://download.lammps.org/thirdparty/scafacos-1.0.1-fix.diff ${CMAKE_CURRENT_BINARY_DIR}/scafacos-1.0.1.fix.diff + file(DOWNLOAD ${LAMMPS_THIRDPARTY_URL}/scafacos-1.0.1-fix.diff ${CMAKE_CURRENT_BINARY_DIR}/scafacos-1.0.1.fix.diff EXPECTED_HASH MD5=4baa1333bb28fcce102d505e1992d032) include(ExternalProject) ExternalProject_Add(scafacos_build - URL https://github.com/scafacos/scafacos/releases/download/v1.0.1/scafacos-1.0.1.tar.gz - URL_MD5 bd46d74e3296bd8a444d731bb10c1738 + URL ${SCAFACOS_URL} + URL_MD5 ${SCAFACOS_MD5} PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_BINARY_DIR}/scafacos-1.0.1.fix.diff CONFIGURE_COMMAND /configure --prefix= --disable-doc --enable-fcs-solvers=fmm,p2nfft,direct,ewald,p3m diff --git a/cmake/Modules/Packages/USER-SMD.cmake b/cmake/Modules/Packages/USER-SMD.cmake index 67f4aae99d..6d941f9798 100644 --- a/cmake/Modules/Packages/USER-SMD.cmake +++ b/cmake/Modules/Packages/USER-SMD.cmake @@ -7,10 +7,14 @@ endif() option(DOWNLOAD_EIGEN3 "Download Eigen3 instead of using an already installed one)" ${DOWNLOAD_EIGEN3_DEFAULT}) if(DOWNLOAD_EIGEN3) message(STATUS "Eigen3 download requested - we will build our own") + set(EIGEN3_URL "https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz" CACHE STRING "URL for Eigen3 tarball") + set(EIGEN3_MD5 "9e30f67e8531477de4117506fe44669b" CACHE STRING "MD5 checksum of Eigen3 tarball") + mark_as_advanced(EIGEN3_URL) + mark_as_advanced(EIGEN3_MD5) include(ExternalProject) ExternalProject_Add(Eigen3_build - URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz - URL_MD5 9e30f67e8531477de4117506fe44669b + URL ${EIGEN3_URL} + URL_MD5 ${EIGEN3_MD5} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) ExternalProject_get_property(Eigen3_build SOURCE_DIR) diff --git a/cmake/Modules/Packages/VORONOI.cmake b/cmake/Modules/Packages/VORONOI.cmake index 1d6893a978..7feea4c52e 100644 --- a/cmake/Modules/Packages/VORONOI.cmake +++ b/cmake/Modules/Packages/VORONOI.cmake @@ -7,6 +7,11 @@ endif() option(DOWNLOAD_VORO "Download and compile the Voro++ library instead of using an already installed one" ${DOWNLOAD_VORO_DEFAULT}) if(DOWNLOAD_VORO) message(STATUS "Voro++ download requested - we will build our own") + set(VORO_URL "${LAMMPS_THIRDPARTY_URL}/voro++-0.4.6.tar.gz" CACHE STRING "URL for Voro++ tarball") + set(VORO_MD5 "2338b824c3b7b25590e18e8df5d68af9" CACHE STRING "MD5 checksum for Voro++ tarball") + mark_as_advanced(VORO_URL) + mark_as_advanced(VORO_MD5) + include(ExternalProject) if(BUILD_SHARED_LIBS) @@ -22,8 +27,8 @@ if(DOWNLOAD_VORO) endif() ExternalProject_Add(voro_build - URL https://download.lammps.org/thirdparty/voro++-0.4.6.tar.gz - URL_MD5 2338b824c3b7b25590e18e8df5d68af9 + URL ${VORO_URL} + URL_MD5 ${VORO_MD5} PATCH_COMMAND patch -b -p0 < ${LAMMPS_LIB_SOURCE_DIR}/voronoi/voro-make.patch CONFIGURE_COMMAND "" BUILD_COMMAND make ${VORO_BUILD_OPTIONS} diff --git a/cmake/Modules/YAML.cmake b/cmake/Modules/YAML.cmake index f2ba34e1b6..c50773568c 100644 --- a/cmake/Modules/YAML.cmake +++ b/cmake/Modules/YAML.cmake @@ -2,10 +2,13 @@ message(STATUS "Downloading and building YAML library") include(ExternalProject) set(YAML_URL "https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz" CACHE STRING "URL for libyaml tarball") +set(YAML_MD5 "bb15429d8fb787e7d3f1c83ae129a999" CACHE STRING "MD5 checksum of libyaml tarball") mark_as_advanced(YAML_URL) +mark_as_advanced(YAML_MD5) + ExternalProject_Add(libyaml URL ${YAML_URL} - URL_MD5 bb15429d8fb787e7d3f1c83ae129a999 + URL_MD5 ${YAML_MD5} SOURCE_DIR "${CMAKE_BINARY_DIR}/yaml-src" BINARY_DIR "${CMAKE_BINARY_DIR}/yaml-build" CONFIGURE_COMMAND /configure ${CONFIGURE_REQUEST_PIC} diff --git a/doc/src/Build_extras.rst b/doc/src/Build_extras.rst index 2081dc4bcd..3af018c656 100644 --- a/doc/src/Build_extras.rst +++ b/doc/src/Build_extras.rst @@ -125,7 +125,7 @@ CMake build # default is sm_50 -D HIP_ARCH=value # primary GPU hardware choice for GPU_API=hip # value depends on selected HIP_PLATFORM - # default is 'gfx906' for HIP_PLATFORM=hcc and 'sm_50' for HIP_PLATFORM=nvcc + # default is 'gfx906' for HIP_PLATFORM=amd and 'sm_50' for HIP_PLATFORM=nvcc -D HIP_USE_DEVICE_SORT=value # enables GPU sorting # value = yes (default) or no -D CUDPP_OPT=value # use GPU binning on with CUDA (should be off for modern GPUs) @@ -169,17 +169,24 @@ desired, you can set :code:`USE_STATIC_OPENCL_LOADER` to :code:`no`. If you are compiling with HIP, note that before running CMake you will have to set appropriate environment variables. Some variables such as -:code:`HCC_AMDGPU_TARGET` or :code:`CUDA_PATH` are necessary for :code:`hipcc` +:code:`HCC_AMDGPU_TARGET` (for ROCm <= 4.0) or :code:`CUDA_PATH` are necessary for :code:`hipcc` and the linker to work correctly. .. code:: bash - # AMDGPU target + # AMDGPU target (ROCm <= 4.0) export HIP_PLATFORM=hcc export HCC_AMDGPU_TARGET=gfx906 cmake -D PKG_GPU=on -D GPU_API=HIP -D HIP_ARCH=gfx906 -D CMAKE_CXX_COMPILER=hipcc .. make -j 4 +.. code:: bash + + # AMDGPU target (ROCm >= 4.1) + export HIP_PLATFORM=amd + cmake -D PKG_GPU=on -D GPU_API=HIP -D HIP_ARCH=gfx906 -D CMAKE_CXX_COMPILER=hipcc .. + make -j 4 + .. code:: bash # CUDA target (not recommended, use GPU_ARCH=cuda) diff --git a/doc/src/Developer_unittest.rst b/doc/src/Developer_unittest.rst index 4487dff11c..52753ee1b4 100644 --- a/doc/src/Developer_unittest.rst +++ b/doc/src/Developer_unittest.rst @@ -4,10 +4,10 @@ Adding tests for unit testing This section discusses adding or expanding tests for the unit test infrastructure included into the LAMMPS source code distribution. Unlike example inputs, unit tests focus on testing the "local" behavior -of individual features, tend to run very fast, and should be set up to -cover as much of the added code as possible. When contributing code to -the distribution, the LAMMPS developers will appreciate if additions -to the integrated unit test facility are included. +of individual features, tend to run fast, and should be set up to cover +as much of the added code as possible. When contributing code to the +distribution, the LAMMPS developers will appreciate if additions to the +integrated unit test facility are included. Given the complex nature of MD simulations where many operations can only be performed when suitable "real" simulation environment has been @@ -50,6 +50,9 @@ available: * - File name: - Test name: - Description: + * - ``test_argutils.cpp`` + - ArgInfo + - Tests for ``ArgInfo`` class used by LAMMPS * - ``test_fmtlib.cpp`` - FmtLib - Tests for ``fmtlib::`` functions used by LAMMPS @@ -155,23 +158,27 @@ have the desired effect: { ASSERT_EQ(lmp->update->ntimestep, 0); - if (!verbose) ::testing::internal::CaptureStdout(); - lmp->input->one("reset_timestep 10"); - if (!verbose) ::testing::internal::GetCapturedStdout(); + BEGIN_HIDE_OUTPUT(); + command("reset_timestep 10"); + END_HIDE_OUTPUT(); ASSERT_EQ(lmp->update->ntimestep, 10); - if (!verbose) ::testing::internal::CaptureStdout(); - lmp->input->one("reset_timestep 0"); - if (!verbose) ::testing::internal::GetCapturedStdout(); + BEGIN_HIDE_OUTPUT(); + command("reset_timestep 0"); + END_HIDE_OUTPUT(); ASSERT_EQ(lmp->update->ntimestep, 0); + + TEST_FAILURE(".*ERROR: Timestep must be >= 0.*", command("reset_timestep -10");); + TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep");); + TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep 10 10");); + TEST_FAILURE(".*ERROR: Expected integer .*", command("reset_timestep xxx");); } -Please note the use of the (global) verbose variable to control whether -the LAMMPS command will be silent by capturing the output or not. In -the default case, verbose == false, the test output will be compact and -not mixed with LAMMPS output. However setting the verbose flag (via -setting the ``TEST_ARGS`` environment variable, ``TEST_ARGS=-v``) can be -helpful to understand why tests fail unexpectedly. +Please note the use of the ``BEGIN_HIDE_OUTPUT`` and ``END_HIDE_OUTPUT`` +functions that will capture output from running LAMMPS. This is normally +discarded but by setting the verbose flag (via setting the ``TEST_ARGS`` +environment variable, ``TEST_ARGS=-v``) it can be printed and used to +understand why tests fail unexpectedly. Another complexity of these tests stems from the need to capture situations where LAMMPS will stop with an error, i.e. handle so-called @@ -210,6 +217,12 @@ The following test programs are currently available: * - ``test_lattice_region.cpp`` - LatticeRegion - Tests to validate the :doc:`lattice ` and :doc:`region ` commands + * - ``test_groups.cpp`` + - GroupTest + - Tests to validate the :doc:`group ` command + * - ``test_variables.cpp`` + - VariableTest + - Tests to validate the :doc:`variable ` command * - ``test_kim_commands.cpp`` - KimCommands - Tests for several commands from the :ref:`KIM package ` diff --git a/doc/src/Packages_standard.rst b/doc/src/Packages_standard.rst index ab9be69ab3..81623c8d4a 100644 --- a/doc/src/Packages_standard.rst +++ b/doc/src/Packages_standard.rst @@ -71,6 +71,8 @@ package: +----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+ | :ref:`PERI ` | Peridynamics models | :doc:`pair_style peri ` | peri | no | +----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+ +| :ref:`PLUGIN ` | Plugin loader command | :doc:`plugin ` | plugins | no | ++----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+ | :ref:`POEMS ` | coupled rigid body motion | :doc:`fix poems ` | rigid | int | +----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+ | :ref:`PYTHON ` | embed Python code in an input script | :doc:`python ` | python | sys | diff --git a/doc/src/rerun.rst b/doc/src/rerun.rst index 7d51fba868..e9e23afba8 100644 --- a/doc/src/rerun.rst +++ b/doc/src/rerun.rst @@ -15,7 +15,7 @@ Syntax .. parsed-literal:: - keyword = *first* or *last* or *every* or *skip* or *start* or *stop* or *dump* + keyword = *first* or *last* or *every* or *skip* or *start* or *stop* or *post* or *dump* *first* args = Nfirst Nfirst = dump timestep to start on *last* args = Nlast @@ -28,6 +28,7 @@ Syntax Nstart = timestep on which pseudo run will start *stop* args = Nstop Nstop = timestep to which pseudo run will end + *post* value = *yes* or *no* *dump* args = same as :doc:`read_dump ` command starting with its field arguments Examples @@ -154,6 +155,10 @@ Also note that an error will occur if you read a snapshot from the dump file with a timestep value larger than the *stop* setting you have specified. +The *post* keyword can be used to minimize the output to the screen that +happens after a *rerun* command, similar to the post keyword of the +:doc:`run command `. It is set to *no* by default. + The *dump* keyword is required and must be the last keyword specified. Its arguments are passed internally to the :doc:`read_dump ` command. The first argument following the *dump* keyword should be @@ -226,4 +231,4 @@ Default The option defaults are first = 0, last = a huge value (effectively infinity), start = same as first, stop = same as last, every = 0, skip -= 1; += 1, post = no; diff --git a/lib/gpu/Makefile.hip b/lib/gpu/Makefile.hip index dbdef433ec..a736988596 100644 --- a/lib/gpu/Makefile.hip +++ b/lib/gpu/Makefile.hip @@ -1,6 +1,6 @@ # /* ---------------------------------------------------------------------- # Generic Linux Makefile for HIP -# - export HIP_PLATFORM=hcc (or nvcc) before execution +# - export HIP_PLATFORM=amd (or nvcc) before execution # - change HIP_ARCH for your GPU # ------------------------------------------------------------------------- */ @@ -42,6 +42,10 @@ ifeq (hcc,$(HIP_PLATFORM)) HIP_OPTS += -ffast-math # possible values: gfx803,gfx900,gfx906 HIP_ARCH = gfx906 +else ifeq (amd,$(HIP_PLATFORM)) + HIP_OPTS += -ffast-math + # possible values: gfx803,gfx900,gfx906 + HIP_ARCH = gfx906 else ifeq (nvcc,$(HIP_PLATFORM)) HIP_OPTS += --use_fast_math HIP_ARCH = -gencode arch=compute_30,code=[sm_30,compute_30] -gencode arch=compute_32,code=[sm_32,compute_32] -gencode arch=compute_35,code=[sm_35,compute_35] \ diff --git a/lib/gpu/README b/lib/gpu/README index dfffe11b81..eb22839a59 100644 --- a/lib/gpu/README +++ b/lib/gpu/README @@ -212,8 +212,8 @@ additionally requires cub (https://nvlabs.github.io/cub). Download and extract the cub directory to lammps/lib/gpu/ or specify an appropriate path in lammps/lib/gpu/Makefile.hip. 2. In Makefile.hip it is possible to specify the target platform via -export HIP_PLATFORM=hcc or HIP_PLATFORM=nvcc as well as the target -architecture (gfx803, gfx900, gfx906 etc.) +export HIP_PLATFORM=amd (ROCm >= 4.1), HIP_PLATFORM=hcc (ROCm <= 4.0) +or HIP_PLATFORM=nvcc as well as the target architecture (gfx803, gfx900, gfx906 etc.) 3. If your MPI implementation does not support `mpicxx --showme` command, it is required to specify the corresponding MPI compiler and linker flags in lammps/lib/gpu/Makefile.hip and in lammps/src/MAKE/OPTIONS/Makefile.hip. @@ -278,4 +278,3 @@ and Brown, W.M., Masako, Y. Implementing Molecular Dynamics on Hybrid High Performance Computers - Three-Body Potentials. Computer Physics Communications. 2013. 184: p. 2785–2793. - diff --git a/lib/gpu/lal_pre_cuda_hip.h b/lib/gpu/lal_pre_cuda_hip.h index d37b4a94c2..dfb6229bed 100644 --- a/lib/gpu/lal_pre_cuda_hip.h +++ b/lib/gpu/lal_pre_cuda_hip.h @@ -30,7 +30,7 @@ // ------------------------------------------------------------------------- -#ifdef __HIP_PLATFORM_HCC__ +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) #define CONFIG_ID 303 #define SIMD_SIZE 64 #else @@ -161,7 +161,7 @@ // KERNEL MACROS - TEXTURES // ------------------------------------------------------------------------- -#ifdef __HIP_PLATFORM_HCC__ +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) #define _texture(name, type) __device__ type* name #define _texture_2d(name, type) __device__ type* name #else @@ -201,7 +201,7 @@ #define mu_tex mu_ #endif -#ifdef __HIP_PLATFORM_HCC__ +#if defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) #undef fetch4 #undef fetch @@ -266,7 +266,7 @@ typedef struct _double4 double4; #endif #endif -#if defined(CUDA_PRE_NINE) || defined(__HIP_PLATFORM_HCC__) +#if defined(CUDA_PRE_NINE) || defined(__HIP_PLATFORM_HCC__) || defined(__HIP_PLATFORM_AMD__) #ifdef _SINGLE_SINGLE #define shfl_down __shfl_down diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp index fcb39b8c6e..5d04fd1cfb 100644 --- a/src/KSPACE/pair_lj_cut_coul_long.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long.cpp @@ -17,21 +17,21 @@ #include "pair_lj_cut_coul_long.h" -#include -#include #include "atom.h" #include "comm.h" +#include "error.h" #include "force.h" #include "kspace.h" -#include "update.h" -#include "respa.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" #include "math_const.h" #include "memory.h" -#include "error.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "respa.h" +#include "update.h" +#include +#include using namespace LAMMPS_NS; using namespace MathConst; diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index f0171d2108..abab3f2b43 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -25,10 +25,11 @@ ----------------------------------------------------------------------*/ #include "reaxc_tool_box.h" +#include "reaxc_defs.h" + #include #include #include -#include "reaxc_defs.h" #include "error.h" @@ -49,62 +50,58 @@ int Tokenize( char* s, char*** tok ) return count; } - - /* safe malloc */ void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name ) { void *ptr; - char errmsg[256]; if (n <= 0) { - snprintf(errmsg, 256, "Trying to allocate %ld bytes for array %s. " - "returning NULL.", n, name); + auto errmsg = fmt::format("Trying to allocate {} bytes for array {}. " + "returning NULL.", n, name); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); return nullptr; } ptr = malloc( n ); if (ptr == nullptr) { - snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n, name); + auto errmsg = fmt::format("Failed to allocate {} bytes for array {}", + n, name); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); } return ptr; } - /* safe calloc */ void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const char *name ) { void *ptr; - char errmsg[256]; if (n <= 0) { - snprintf(errmsg, 256, "Trying to allocate %ld elements for array %s. " - "returning NULL.\n", n, name ); + auto errmsg = fmt::format("Trying to allocate {} elements for array {}. " + "returning NULL.\n", n, name); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); return nullptr; } if (size <= 0) { - snprintf(errmsg, 256, "Elements size for array %s is %ld. " - "returning NULL", name, size ); + auto errmsg = fmt::format("Elements size for array {} is {}. " + "returning NULL", name, size); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); return nullptr; } ptr = calloc( n, size ); if (ptr == nullptr) { - char errmsg[256]; - snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n*size, name); + auto errmsg = fmt::format("Failed to allocate {} bytes for array {}", + n*size, name); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); } return ptr; @@ -115,14 +112,14 @@ void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const c void sfree( LAMMPS_NS::Error* error_ptr, void *ptr, const char *name ) { if (ptr == nullptr) { - char errmsg[256]; - snprintf(errmsg, 256, "Trying to free the already NULL pointer %s", name ); + auto errmsg = fmt::format("Trying to free the already free()'d pointer {}", + name); if (error_ptr) error_ptr->one(FLERR,errmsg); - else fputs(errmsg,stderr); + else fputs(errmsg.c_str(),stderr); return; } - free( ptr ); + free(ptr); ptr = nullptr; } diff --git a/src/USER-REAXC/reaxc_traj.h b/src/USER-REAXC/reaxc_traj.h index 4966bf11d8..2ff5995204 100644 --- a/src/USER-REAXC/reaxc_traj.h +++ b/src/USER-REAXC/reaxc_traj.h @@ -36,14 +36,18 @@ #define HEADER_LINE_LEN 62 #define STR_LINE "%-37s%-24s\n" #define INT_LINE "%-37s%-24d\n" -#define BIGINT_LINE "%-37s%-24ld\n" +#if defined(LAMMPS_SMALLSMALL) +#define BIGINT_LINE "%-37s%-24d\n" +#else +#define BIGINT_LINE "%-37s%-24lld\n" +#endif #define INT2_LINE "%-36s%-12d,%-12d\n" #define REAL_LINE "%-37s%-24.3f\n" #define SCI_LINE "%-37s%-24g\n" #define REAL3_LINE "%-32s%9.3f,%9.3f,%9.3f\n" #if defined(LAMMPS_BIGBIG) -#define INIT_DESC "%9ld%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass +#define INIT_DESC "%9lld%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass #else #define INIT_DESC "%9d%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass #endif @@ -56,7 +60,7 @@ #define SIZE_INFO_LEN3 31 #if defined(LAMMPS_BIGBIG) -#define ATOM_BASIC "%9ld%10.3f%10.3f%10.3f%10.3f\n" //AtomID AtomType (X Y Z) Charge +#define ATOM_BASIC "%9lld%10.3f%10.3f%10.3f%10.3f\n" //AtomID AtomType (X Y Z) Charge #define ATOM_wV "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Vx Vy Vz) Charge #define ATOM_wF "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Fx Fy Fz) Charge #define ATOM_FULL "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Vx Vy Vz) (Fx Fy Fz) Charge @@ -72,9 +76,9 @@ #define ATOM_FULL_LEN 110 #if defined(LAMMPS_BIGBIG) -#define BOND_BASIC "%9ld%9ld%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO -#define BOND_FULL "%9ld%9ld%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2 -#define ANGLE_BASIC "%9ld%9ld%9ld%10.3f\n" // Atom1 Atom2 Atom3 Theta +#define BOND_BASIC "%9lld%9lld%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO +#define BOND_FULL "%9lld%9lld%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2 +#define ANGLE_BASIC "%9lld%9lld%9lld%10.3f\n" // Atom1 Atom2 Atom3 Theta #else #define BOND_BASIC "%9d%9d%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO #define BOND_FULL "%9d%9d%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2 diff --git a/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp b/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp index 6e4c0587f7..2247a9467c 100644 --- a/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp +++ b/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp @@ -106,6 +106,7 @@ void PairLJSwitch3CoulGaussLong::compute(int eflag, int vflag) firstneigh = list->firstneigh; // loop over neighbors of my atoms + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; qtmp = q[i]; @@ -193,7 +194,7 @@ void PairLJSwitch3CoulGaussLong::compute(int eflag, int vflag) offset[itype][jtype]; } else evdwl = 0.0; - // Truncation, see Yaff Switch33 + // Truncation, see Yaff Switch3 if (truncw>0) { if (rsq < cut_ljsq[itype][jtype]) { if (r>cut_lj[itype][jtype]-truncw) { @@ -262,19 +263,18 @@ void PairLJSwitch3CoulGaussLong::allocate() void PairLJSwitch3CoulGaussLong::settings(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command"); + if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = utils::numeric(FLERR,arg[0],false,lmp); + if (narg == 2) { cut_coul = cut_lj_global; truncw = utils::numeric(FLERR,arg[1],false,lmp); - } - else { + } else { cut_coul = utils::numeric(FLERR,arg[1],false,lmp); truncw = utils::numeric(FLERR,arg[2],false,lmp); } - if (truncw>0.0) truncwi = 1.0/truncw; - else truncwi = 0.0; + // reset cutoffs that have been explicitly set if (allocated) { @@ -332,6 +332,9 @@ void PairLJSwitch3CoulGaussLong::init_style() cut_coulsq = cut_coul * cut_coul; + if (truncw>0.0) truncwi = 1.0/truncw; + else truncwi = 0.0; + // insure use of KSpace long-range solver, set g_ewald if (force->kspace == nullptr) @@ -375,8 +378,7 @@ double PairLJSwitch3CoulGaussLong::init_one(int i, int j) double r6inv = r2inv*r2inv*r2inv; double r12inv = r6inv*r6inv; offset[i][j] = lj3[i][j]*r12inv-lj4[i][j]*r6inv; - } - else {offset[i][j] = 0.0;} + } else {offset[i][j] = 0.0;} } else offset[i][j] = 0.0; cut_ljsq[j][i] = cut_ljsq[i][j]; @@ -431,8 +433,7 @@ double PairLJSwitch3CoulGaussLong::init_one(int i, int j) double t71 = -0.4e1 * cg * (0.2e1 * t10 * t11 - 0.2e1 * t10 * t14 + (cg5 - 0.2e1 * cg1) * t58 * cg5) * t26 / t4 / t41 / t9; etail_ij = 2.0*MY_PI*all[0]*all[1]*t71; ptail_ij = 2.0*MY_PI*all[0]*all[1]*t71; - } - else { + } else { double t1 = pow(cg3, 0.2e1); double t2 = t1 * t1; double t3 = t2 * t1; @@ -618,6 +619,7 @@ double PairLJSwitch3CoulGaussLong::single(int i, int j, int itype, int jtype, expn2 = 0.0; erfc2 = 0.0; forcecoul2 = 0.0; + prefactor2 = 0.0; } else { r = sqrt(rsq); rrij = lj2[itype][jtype]*r; diff --git a/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp b/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp index 67a322ca24..c7fcac855a 100644 --- a/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp +++ b/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp @@ -106,6 +106,7 @@ void PairMM3Switch3CoulGaussLong::compute(int eflag, int vflag) firstneigh = list->firstneigh; // loop over neighbors of my atoms + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; qtmp = q[i]; @@ -170,6 +171,7 @@ void PairMM3Switch3CoulGaussLong::compute(int eflag, int vflag) expn2 = 0.0; erfc2 = 0.0; forcecoul2 = 0.0; + prefactor2 = 0.0; } else { rrij = lj2[itype][jtype]*r; expn2 = exp(-rrij*rrij); @@ -263,19 +265,18 @@ void PairMM3Switch3CoulGaussLong::allocate() void PairMM3Switch3CoulGaussLong::settings(int narg, char **arg) { - if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command"); + if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command"); cut_lj_global = utils::numeric(FLERR,arg[0],false,lmp); + if (narg == 2) { cut_coul = cut_lj_global; truncw = utils::numeric(FLERR,arg[1],false,lmp); - } - else { + } else { cut_coul = utils::numeric(FLERR,arg[1],false,lmp); truncw = utils::numeric(FLERR,arg[2],false,lmp); } - if (truncw>0.0) truncwi = 1.0/truncw; - else truncwi = 0.0; + // reset cutoffs that have been explicitly set if (allocated) { @@ -333,6 +334,9 @@ void PairMM3Switch3CoulGaussLong::init_style() cut_coulsq = cut_coul * cut_coul; + if (truncw>0.0) truncwi = 1.0/truncw; + else truncwi = 0.0; + // insure use of KSpace long-range solver, set g_ewald if (force->kspace == nullptr) @@ -375,8 +379,7 @@ double PairMM3Switch3CoulGaussLong::init_one(int i, int j) double r6inv = r2inv*r2inv*r2inv; double expb = lj3[i][j]*exp(-lj1[i][j]*r); offset[i][j] = expb-lj4[i][j]*r6inv; - } - else {offset[i][j] = 0.0;} + } else {offset[i][j] = 0.0;} } else offset[i][j] = 0.0; cut_ljsq[j][i] = cut_ljsq[i][j]; @@ -426,8 +429,7 @@ double PairMM3Switch3CoulGaussLong::init_one(int i, int j) double t64 = cg * (0.6388888889e3 * ((-t3 + (0.7e1 / 0.36e2 * cg5 - t5) * t1 - 0.2e1 / 0.3e1 * t8 * (cg5 - cg1 / 0.4e1) * cg3 + cg5 * t14) * t20 + t3 + (cg5 / 0.12e2 + t5) * t1 + (cg5 + cg1 / 0.3e1) * cg1 * cg3 / 0.2e1 + t30 * cg5) * t2 * t36 * t39 - 0.225e1 * (0.2e1 * t43 * t44 - 0.2e1 * t43 * t47 + cg5 * (cg5 - 0.2e1 * cg1)) * t54 * t1 / cg1 / t8 * t39); etail_ij = 2.0*MY_PI*all[0]*all[1]*t64; ptail_ij = 2.0*MY_PI*all[0]*all[1]*t64; - } - else { + } else { double t2 = pow(cg3, 0.2e1); double t3 = t2 * t2; double t7 = 0.12e2 / cg3 * cg1; diff --git a/src/random_mars.cpp b/src/random_mars.cpp index 621d7d3008..78c6f93ba4 100644 --- a/src/random_mars.cpp +++ b/src/random_mars.cpp @@ -136,13 +136,16 @@ double RanMars::gaussian(double mu, double sigma) double RanMars::rayleigh(double sigma) { - double first,v1; + double v1; - if (sigma <= 0) error->all(FLERR,"Invalid Rayleigh parameter"); + if (sigma <= 0.0) error->all(FLERR,"Invalid Rayleigh parameter"); v1 = uniform(); - first = sigma*sqrt(-2.0*log(v1)); - return first; + // avoid a floating point exception due to log(0.0) + // and just return a very big number + if (v1 == 0.0) return 1.0e300; + + return sigma*sqrt(-2.0*log(v1)); } /* ---------------------------------------------------------------------- diff --git a/src/rerun.cpp b/src/rerun.cpp index 648874420a..8615b02d95 100644 --- a/src/rerun.cpp +++ b/src/rerun.cpp @@ -51,6 +51,7 @@ void Rerun::command(int narg, char **arg) if (strcmp(arg[iarg],"start") == 0) break; if (strcmp(arg[iarg],"stop") == 0) break; if (strcmp(arg[iarg],"dump") == 0) break; + if (strcmp(arg[iarg],"post") == 0) break; iarg++; } int nfile = iarg; @@ -65,6 +66,7 @@ void Rerun::command(int narg, char **arg) int nskip = 1; int startflag = 0; int stopflag = 0; + int postflag = 0; bigint start = -1; bigint stop = -1; @@ -101,6 +103,14 @@ void Rerun::command(int narg, char **arg) stop = utils::bnumeric(FLERR,arg[iarg+1],false,lmp); if (stop < 0) error->all(FLERR,"Illegal rerun command"); iarg += 2; + } else if (strcmp(arg[iarg],"post") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command"); + if (strcmp(arg[iarg+1],"yes") == 0) { + postflag = 1; + } else if (strcmp(arg[iarg+1],"no") == 0) { + postflag = 0; + } else error->all(FLERR,"Illegal rerun command"); + iarg += 2; } else if (strcmp(arg[iarg],"dump") == 0) { break; } else error->all(FLERR,"Illegal rerun command"); @@ -182,7 +192,7 @@ void Rerun::command(int narg, char **arg) update->nsteps = ndump; Finish finish(lmp); - finish.end(1); + finish.end(postflag); update->whichflag = 0; update->firststep = update->laststep = 0; diff --git a/src/tokenizer.h b/src/tokenizer.h index 2db9870866..b3bbf05296 100644 --- a/src/tokenizer.h +++ b/src/tokenizer.h @@ -41,7 +41,7 @@ public: Tokenizer& operator=(Tokenizer&&) = default; void reset(); - void skip(int n); + void skip(int n=1); bool has_next() const; bool contains(const std::string &str) const; std::string next(); @@ -104,7 +104,7 @@ public: bool has_next() const; bool contains(const std::string &value) const; - void skip(int ntokens); + void skip(int ntokens=1); size_t count(); }; diff --git a/src/velocity.cpp b/src/velocity.cpp index b8d2e5229a..f4483074aa 100644 --- a/src/velocity.cpp +++ b/src/velocity.cpp @@ -108,7 +108,7 @@ void Velocity::command(int narg, char **arg) int initcomm = 0; if (style == ZERO && rfix >= 0 && - utils::strmatch(modify->fix[rfix]->style,"^rigid/small")) initcomm = 1; + utils::strmatch(modify->fix[rfix]->style,"^rigid.*/small.*")) initcomm = 1; if ((style == CREATE || style == SET) && temperature && strcmp(temperature->style,"temp/cs") == 0) initcomm = 1; diff --git a/tools/singularity/ubuntu18.04_amd_rocm.def b/tools/singularity/ubuntu18.04_amd_rocm.def index bb04c738c4..7b06970110 100644 --- a/tools/singularity/ubuntu18.04_amd_rocm.def +++ b/tools/singularity/ubuntu18.04_amd_rocm.def @@ -94,7 +94,7 @@ From: ubuntu:18.04 ########################################################################### export PATH=$PATH:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64 - git clone -b rocm-3.7.x https://github.com/ROCmSoftwarePlatform/hipCUB.git + git clone -b rocm-4.1.x https://github.com/ROCmSoftwarePlatform/hipCUB.git mkdir hipCUB/build cd hipCUB/build CXX=hipcc cmake -D BUILD_TEST=off .. diff --git a/tools/singularity/ubuntu20.04_amd_rocm.def b/tools/singularity/ubuntu20.04_amd_rocm.def index 28d57be341..4eee97ffec 100644 --- a/tools/singularity/ubuntu20.04_amd_rocm.def +++ b/tools/singularity/ubuntu20.04_amd_rocm.def @@ -2,7 +2,7 @@ BootStrap: docker From: ubuntu:20.04 %environment - export PATH=/usr/lib/ccache:/usr/local/cuda-11.0/bin:${PATH}:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64 + export PATH=/usr/lib/ccache:${PATH}:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64 %post export DEBIAN_FRONTEND=noninteractive apt-get update @@ -90,7 +90,7 @@ From: ubuntu:20.04 ########################################################################### export PATH=$PATH:/opt/rocm/bin:/opt/rocm/profiler/bin:/opt/rocm/opencl/bin/x86_64 - git clone -b rocm-3.7.x https://github.com/ROCmSoftwarePlatform/hipCUB.git + git clone -b rocm-4.1.x https://github.com/ROCmSoftwarePlatform/hipCUB.git mkdir hipCUB/build cd hipCUB/build CXX=hipcc cmake -D BUILD_TEST=off .. diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 9173909806..9bd6e74c9b 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -328,11 +328,7 @@ TEST_F(SimpleCommandsTest, Units) #if defined(LMP_PLUGIN) TEST_F(SimpleCommandsTest, Plugin) { -#if defined(__APPLE__) - std::string loadfmt("plugin load {}plugin.dylib"); -#else std::string loadfmt("plugin load {}plugin.so"); -#endif ::testing::internal::CaptureStdout(); lmp->input->one(fmt::format(loadfmt, "hello")); auto text = ::testing::internal::GetCapturedStdout(); diff --git a/unittest/force-styles/tests/fix-timestep-adapt_coul.yaml b/unittest/force-styles/tests/fix-timestep-adapt_coul.yaml index 4bf25f3b33..f0ec2f1292 100644 --- a/unittest/force-styles/tests/fix-timestep-adapt_coul.yaml +++ b/unittest/force-styles/tests/fix-timestep-adapt_coul.yaml @@ -1,7 +1,7 @@ --- lammps_version: 10 Mar 2021 date_generated: Thu Mar 25 14:07:45 202 -epsilon: 1e-14 +epsilon: 5e-13 prerequisites: ! | atom full fix adapt diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 46c6b7dfa7..5161eece3e 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -15,6 +15,8 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "output.h" +#include "thermo.h" #include "utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -24,7 +26,7 @@ using ::testing::Eq; char *BINARY2TXT_BINARY = nullptr; -bool verbose = false; +bool verbose = false; class DumpAtomTest : public MeltTest { std::string dump_style = "atom"; @@ -46,7 +48,14 @@ public: command(fmt::format("dump_modify id {}", dump_modify_options)); } - command(fmt::format("run {}", ntimesteps)); + command(fmt::format("run {} post no", ntimesteps)); + END_HIDE_OUTPUT(); + } + + void continue_dump(int ntimesteps) + { + BEGIN_HIDE_OUTPUT(); + command(fmt::format("run {} pre no post no", ntimesteps)); END_HIDE_OUTPUT(); } @@ -62,7 +71,7 @@ public: command(fmt::format("dump_modify id1 {}", dump_modify_options)); } - command(fmt::format("run {}", ntimesteps)); + command(fmt::format("run {} post no", ntimesteps)); END_HIDE_OUTPUT(); } @@ -446,13 +455,16 @@ TEST_F(DumpAtomTest, binary_triclinic_with_image_run0) delete_file(converted_file); } -TEST_F(DumpAtomTest, run1) +TEST_F(DumpAtomTest, run1plus1) { - auto dump_file = "dump_run1.melt"; + auto dump_file = "dump_run1plus1.melt"; generate_dump(dump_file, "", 1); ASSERT_FILE_EXISTS(dump_file); ASSERT_EQ(count_lines(dump_file), 82); + continue_dump(1); + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 123); delete_file(dump_file); } @@ -466,6 +478,34 @@ TEST_F(DumpAtomTest, run2) delete_file(dump_file); } +TEST_F(DumpAtomTest, rerun) +{ + auto dump_file = "dump_rerun.melt"; + HIDE_OUTPUT([&] { + command("fix 1 all nve"); + }); + generate_dump(dump_file, "format line \"%d %d %20.15g %20.15g %20.15g\"", 1); + double pe_1, pe_2, pe_rerun; + lmp->output->thermo->evaluate_keyword("pe", &pe_1); + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 82); + continue_dump(1); + lmp->output->thermo->evaluate_keyword("pe", &pe_2); + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 123); + HIDE_OUTPUT([&] { + command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file)); + }); + lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); + ASSERT_DOUBLE_EQ(pe_1, pe_rerun); + HIDE_OUTPUT([&] { + command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file)); + }); + lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); + ASSERT_DOUBLE_EQ(pe_2, pe_rerun); + delete_file(dump_file); +} + TEST_F(DumpAtomTest, multi_file_run1) { auto dump_file = "dump_run1_*.melt"; diff --git a/unittest/formats/test_dump_custom.cpp b/unittest/formats/test_dump_custom.cpp index b90d77e966..f8a55bb2fb 100644 --- a/unittest/formats/test_dump_custom.cpp +++ b/unittest/formats/test_dump_custom.cpp @@ -15,6 +15,8 @@ #include "../testing/systems/melt.h" #include "../testing/utils.h" #include "fmt/format.h" +#include "output.h" +#include "thermo.h" #include "utils.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -22,7 +24,7 @@ using ::testing::Eq; char *BINARY2TXT_BINARY = nullptr; -bool verbose = false; +bool verbose = false; class DumpCustomTest : public MeltTest { std::string dump_style = "custom"; @@ -45,7 +47,14 @@ public: command(fmt::format("dump_modify id {}", dump_modify_options)); } - command(fmt::format("run {}", ntimesteps)); + command(fmt::format("run {} post no", ntimesteps)); + END_HIDE_OUTPUT(); + } + + void continue_dump(int ntimesteps) + { + BEGIN_HIDE_OUTPUT(); + command(fmt::format("run {} pre no post no", ntimesteps)); END_HIDE_OUTPUT(); } @@ -62,7 +71,7 @@ public: command(fmt::format("dump_modify id1 {}", dump_modify_options)); } - command(fmt::format("run {}", ntimesteps)); + command(fmt::format("run {} post no", ntimesteps)); END_HIDE_OUTPUT(); } @@ -262,6 +271,64 @@ TEST_F(DumpCustomTest, with_variable_run1) delete_file(dump_file); } +TEST_F(DumpCustomTest, run1plus1) +{ + auto dump_file = "dump_custom_run1plus1.melt"; + auto fields = "id type x y z"; + + generate_dump(dump_file, fields, "units yes", 1); + + ASSERT_FILE_EXISTS(dump_file); + auto lines = read_lines(dump_file); + ASSERT_EQ(lines.size(), 84); + continue_dump(1); + ASSERT_FILE_EXISTS(dump_file); + lines = read_lines(dump_file); + ASSERT_EQ(lines.size(), 125); + delete_file(dump_file); +} + +TEST_F(DumpCustomTest, run2) +{ + auto dump_file = "dump_custom_run2.melt"; + auto fields = "id type x y z"; + generate_dump(dump_file, fields, "", 2); + + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 123); + delete_file(dump_file); +} + +TEST_F(DumpCustomTest, rerun) +{ + auto dump_file = "dump_rerun.melt"; + auto fields = "id type xs ys zs"; + + HIDE_OUTPUT([&] { + command("fix 1 all nve"); + }); + generate_dump(dump_file, fields, "format float %20.15g", 1); + double pe_1, pe_2, pe_rerun; + lmp->output->thermo->evaluate_keyword("pe", &pe_1); + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 82); + continue_dump(1); + lmp->output->thermo->evaluate_keyword("pe", &pe_2); + ASSERT_FILE_EXISTS(dump_file); + ASSERT_EQ(count_lines(dump_file), 123); + HIDE_OUTPUT([&] { + command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file)); + }); + lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); + ASSERT_DOUBLE_EQ(pe_1, pe_rerun); + HIDE_OUTPUT([&] { + command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file)); + }); + lmp->output->thermo->evaluate_keyword("pe", &pe_rerun); + ASSERT_DOUBLE_EQ(pe_2, pe_rerun); + delete_file(dump_file); +} + int main(int argc, char **argv) { MPI_Init(&argc, &argv); diff --git a/unittest/formats/test_potential_file_reader.cpp b/unittest/formats/test_potential_file_reader.cpp index 1e3d96d6d7..f270f6e1f1 100644 --- a/unittest/formats/test_potential_file_reader.cpp +++ b/unittest/formats/test_potential_file_reader.cpp @@ -28,6 +28,7 @@ #include "potential_file_reader.h" #include "gmock/gmock.h" #include "gtest/gtest.h" + #include "../testing/core.h" #include @@ -257,6 +258,67 @@ TEST_F(PotentialFileReaderTest, UnitConvert) delete reader; } +class OpenPotentialTest : public LAMMPSTest { +}; + +// open for native units +TEST_F(OpenPotentialTest, Sw_native) +{ + int convert_flag = utils::get_supported_conversions(utils::ENERGY); + BEGIN_CAPTURE_OUTPUT(); + command("units metal"); + FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag); + auto text = END_CAPTURE_OUTPUT(); + double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag); + + ASSERT_NE(fp, nullptr); + ASSERT_DOUBLE_EQ(conv, 1.0); + fclose(fp); +} + +// open with supported conversion enabled +TEST_F(OpenPotentialTest, Sw_conv) +{ + int convert_flag = utils::get_supported_conversions(utils::ENERGY); + ASSERT_EQ(convert_flag, utils::METAL2REAL | utils::REAL2METAL); + BEGIN_HIDE_OUTPUT(); + command("units real"); + FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag); + auto text = END_CAPTURE_OUTPUT(); + double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag); + + ASSERT_NE(fp, nullptr); + ASSERT_EQ(convert_flag, utils::METAL2REAL); + ASSERT_DOUBLE_EQ(conv, 23.060549); + fclose(fp); +} + +// open with conversion disabled +TEST_F(OpenPotentialTest, Sw_noconv) +{ + BEGIN_HIDE_OUTPUT(); + command("units real"); + END_HIDE_OUTPUT(); + TEST_FAILURE(".*potential.*requires metal units but real.*", + utils::open_potential("Si.sw", lmp, nullptr);); + BEGIN_HIDE_OUTPUT(); + command("units lj"); + END_HIDE_OUTPUT(); + int convert_flag = utils::get_supported_conversions(utils::UNKNOWN); + ASSERT_EQ(convert_flag, utils::NOCONVERT); +} + +// open non-existing potential +TEST_F(OpenPotentialTest, No_file) +{ + int convert_flag = utils::get_supported_conversions(utils::ENERGY); + BEGIN_HIDE_OUTPUT(); + command("units metal"); + FILE *fp = utils::open_potential("Unknown.sw", lmp, &convert_flag); + END_HIDE_OUTPUT(); + ASSERT_EQ(fp,nullptr); +} + int main(int argc, char **argv) { MPI_Init(&argc, &argv); diff --git a/unittest/utils/test_tokenizer.cpp b/unittest/utils/test_tokenizer.cpp index 69ec7a55d2..ec097abf62 100644 --- a/unittest/utils/test_tokenizer.cpp +++ b/unittest/utils/test_tokenizer.cpp @@ -43,6 +43,18 @@ TEST(Tokenizer, two_words) ASSERT_EQ(t.count(), 2); } +TEST(Tokenizer, skip) +{ + Tokenizer t("test word", " "); + ASSERT_TRUE(t.has_next()); + t.skip(); + ASSERT_TRUE(t.has_next()); + t.skip(1); + ASSERT_FALSE(t.has_next()); + ASSERT_EQ(t.count(), 2); + ASSERT_THROW(t.skip(), TokenizerException); +} + TEST(Tokenizer, prefix_separators) { Tokenizer t(" test word", " "); @@ -63,6 +75,18 @@ TEST(Tokenizer, iterate_words) ASSERT_EQ(t.count(), 2); } +TEST(Tokenizer, copy_constructor) +{ + Tokenizer t(" test word ", " "); + ASSERT_THAT(t.next(), Eq("test")); + ASSERT_THAT(t.next(), Eq("word")); + ASSERT_EQ(t.count(), 2); + Tokenizer u(t); + ASSERT_THAT(u.next(), Eq("test")); + ASSERT_THAT(u.next(), Eq("word")); + ASSERT_EQ(u.count(), 2); +} + TEST(Tokenizer, no_separator_path) { Tokenizer t("one", ":"); @@ -139,6 +163,26 @@ TEST(ValueTokenizer, empty_string) ASSERT_FALSE(values.has_next()); } +TEST(ValueTokenizer, two_words) +{ + ValueTokenizer t("test word", " "); + ASSERT_THAT(t.next_string(), Eq("test")); + ASSERT_THAT(t.next_string(), Eq("word")); + ASSERT_THROW(t.next_string(), TokenizerException); +} + +TEST(ValueTokenizer, skip) +{ + ValueTokenizer t("test word", " "); + ASSERT_TRUE(t.has_next()); + t.skip(); + ASSERT_TRUE(t.has_next()); + t.skip(1); + ASSERT_FALSE(t.has_next()); + ASSERT_EQ(t.count(), 2); + ASSERT_THROW(t.skip(), TokenizerException); +} + TEST(ValueTokenizer, bad_integer) { ValueTokenizer values("f10"); diff --git a/unittest/utils/test_utils.cpp b/unittest/utils/test_utils.cpp index 81dda11615..0c6e38e342 100644 --- a/unittest/utils/test_utils.cpp +++ b/unittest/utils/test_utils.cpp @@ -331,6 +331,11 @@ TEST(Utils, valid_id7) ASSERT_TRUE(utils::is_id("___")); } +TEST(Utils, empty_id) +{ + ASSERT_FALSE(utils::is_id("")); +} + TEST(Utils, invalid_id1) { ASSERT_FALSE(utils::is_id("+abc")); @@ -780,6 +785,11 @@ TEST(Utils, unit_conversion) ASSERT_DOUBLE_EQ(factor, 1.0 / 23.060549); } +TEST(Utils, timespec2seconds_off) +{ + ASSERT_DOUBLE_EQ(utils::timespec2seconds("off"), -1.0); +} + TEST(Utils, timespec2seconds_ss) { ASSERT_DOUBLE_EQ(utils::timespec2seconds("45"), 45.0); @@ -795,6 +805,11 @@ TEST(Utils, timespec2seconds_hhmmss) ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:10:45"), 7845.0); } +TEST(Utils, timespec2seconds_invalid) +{ + ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:aa:45"), -1.0); +} + TEST(Utils, date2num) { ASSERT_EQ(utils::date2num("1Jan05"), 20050101); @@ -810,3 +825,32 @@ TEST(Utils, date2num) ASSERT_EQ(utils::date2num("30November 02"), 20021130); ASSERT_EQ(utils::date2num("31December100"), 1001231); } + +static int compare(int a, int b, void *) +{ + if (a < b) + return -1; + else if (a > b) + return 1; + else + return 0; +} + +TEST(Utils, merge_sort) +{ + int data[] = {773, 405, 490, 830, 632, 96, 428, 728, 912, 840, 878, 745, 213, 219, 249, 380, + 894, 758, 575, 690, 61, 849, 19, 577, 338, 569, 898, 873, 448, 940, 431, 780, + 472, 289, 65, 491, 641, 37, 367, 33, 407, 854, 594, 611, 845, 136, 107, 592, + 275, 865, 158, 626, 399, 703, 686, 734, 188, 559, 781, 558, 737, 281, 638, 664, + 533, 529, 62, 969, 595, 661, 837, 463, 624, 568, 615, 936, 206, 637, 91, 694, + 214, 872, 468, 66, 775, 949, 486, 576, 255, 961, 480, 138, 177, 509, 333, 705, + 10, 375, 321, 952, 210, 111, 475, 268, 708, 864, 244, 121, 988, 540, 942, 682, + 750, 473, 478, 714, 955, 911, 482, 384, 144, 757, 697, 791, 420, 605, 447, 320}; + + const int num = sizeof(data) / sizeof(int); + utils::merge_sort(data, num, nullptr, &compare); + bool sorted = true; + for (int i = 1; i < num; ++i) + if (data[i - 1] > data[i]) sorted = false; + ASSERT_TRUE(sorted); +}