Merge branch 'alphataubio-kokkos-bio' of https://github.com/alphataubio/lammps-alphataubio into alphataubio-kokkos-bio

This commit is contained in:
alphataubio
2024-08-04 17:38:21 -04:00
145 changed files with 1782 additions and 799 deletions

View File

@ -3,6 +3,7 @@
add_executable(test_library_open test_library_open.cpp test_main.cpp)
target_link_libraries(test_library_open PRIVATE lammps GTest::GMock)
add_test(NAME LibraryOpen COMMAND test_library_open)
set_tests_properties(LibraryOpen PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=4;OMP_PROC_BIND=false")
add_executable(test_library_commands test_library_commands.cpp test_main.cpp)
target_link_libraries(test_library_commands PRIVATE lammps GTest::GMock)
@ -16,7 +17,7 @@ add_executable(test_library_properties test_library_properties.cpp test_main.cpp
target_link_libraries(test_library_properties PRIVATE lammps GTest::GMock)
target_compile_definitions(test_library_properties PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR})
add_test(NAME LibraryProperties COMMAND test_library_properties)
set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};OMP_NUM_THREADS=4;OMP_PROC_BIND=false")
add_executable(test_library_objects test_library_objects.cpp test_main.cpp)
target_link_libraries(test_library_objects PRIVATE lammps GTest::GMock)

View File

@ -2,10 +2,12 @@
#include "lammps.h"
#define LAMMPS_LIB_MPI 1
#include "info.h"
#include "library.h"
#include <cstdio> // for stdin, stdout
#include <mpi.h>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -78,9 +80,38 @@ TEST(lammps_open, with_args)
TEST(lammps_open, with_kokkos)
{
if (!LAMMPS_NS::LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
const char *args[] = {"liblammps", "-k", "on", "t", "2", "-sf", "kk", "-log", "none", nullptr};
char **argv = (char **)args;
int argc = (sizeof(args) / sizeof(char *)) - 1;
std::vector<char *> args = {(char *)"lammps", (char *)"-log", (char *)"none", (char *)"-echo",
(char *)"screen", (char *)"-sf", (char *)"kk"};
char *one = (char *)"1";
char *four = (char *)"4";
char *tee = (char *)"t";
char *gee = (char *)"g";
char *kay = (char *)"-k";
char *yes = (char *)"on";
args.push_back(kay);
args.push_back(yes);
// when GPU support is enabled in KOKKOS, it *must* be used
if (lammps_config_accelerator("KOKKOS", "api", "hip") ||
lammps_config_accelerator("KOKKOS", "api", "cuda") ||
lammps_config_accelerator("KOKKOS", "api", "sycl")) {
args.push_back(gee);
args.push_back(one);
}
// use threads or serial
args.push_back(tee);
if (lammps_config_accelerator("KOKKOS", "api", "openmp")) {
args.push_back(four);
} else if (lammps_config_accelerator("KOKKOS", "api", "pthreads")) {
args.push_back(four);
} else {
args.push_back(one);
}
int argc = args.size();
char **argv = args.data();
::testing::internal::CaptureStdout();
void *alt_ptr;

View File

@ -7,6 +7,7 @@
#include "lmptype.h"
#include "platform.h"
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -742,14 +743,45 @@ TEST_F(AtomProperties, position)
TEST(SystemSettings, kokkos)
{
if (!lammps_config_has_package("KOKKOS")) GTEST_SKIP();
if (!lammps_config_accelerator("KOKKOS", "api", "openmp")) GTEST_SKIP();
std::vector<char *> args = {(char *)"lammps", (char *)"-log", (char *)"none",
(char *)"-echo", (char *)"screen", (char *)"-nocite",
(char *)"-sf", (char *)"kk"};
// clang-format off
const char *args[] = {"SystemSettings", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk", nullptr};
// clang-format on
char **argv = (char **)args;
int argc = (sizeof(args) / sizeof(char *)) - 1;
char *one = (char *)"1";
char *four = (char *)"4";
char *tee = (char *)"t";
char *gee = (char *)"g";
char *kay = (char *)"-k";
char *yes = (char *)"on";
args.push_back(kay);
args.push_back(yes);
bool has_gpu = false;
bool has_threads = false;
// when GPU support is enabled in KOKKOS, it *must* be used
if (lammps_config_accelerator("KOKKOS", "api", "hip") ||
lammps_config_accelerator("KOKKOS", "api", "cuda") ||
lammps_config_accelerator("KOKKOS", "api", "sycl")) {
has_gpu = true;
args.push_back(gee);
args.push_back(one);
}
// use threads or serial
args.push_back(tee);
if (lammps_config_accelerator("KOKKOS", "api", "openmp")) {
has_threads = true;
args.push_back(four);
} else if (lammps_config_accelerator("KOKKOS", "api", "pthreads")) {
has_threads = true;
args.push_back(four);
} else {
args.push_back(one);
}
int argc = args.size();
char **argv = args.data();
::testing::internal::CaptureStdout();
void *lmp = lammps_open_no_mpi(argc, argv, nullptr);
@ -758,7 +790,13 @@ TEST(SystemSettings, kokkos)
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_active"), 1);
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 4);
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0);
if (has_threads)
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 4);
else
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_nthreads"), 1);
if (has_gpu)
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 1);
else
EXPECT_EQ(lammps_extract_setting(lmp, "kokkos_ngpus"), 0);
lammps_close(lmp);
}

View File

@ -314,7 +314,7 @@ TEST_F(GroupTest, Dynamic)
command("group ramp variable grow"););
}
constexpr double EPSILON = 1.0e-13;
static constexpr double EPSILON = 1.0e-13;
TEST_F(GroupTest, VariableFunctions)
{

View File

@ -287,6 +287,7 @@ TEST_F(VariableTest, AtomicSystem)
ASSERT_DOUBLE_EQ(variable->compute_equal("f_press[1]"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("c_press"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("c_press[2]"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("c_press[1+1]"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("1.5+3.25"), 4.75);
ASSERT_DOUBLE_EQ(variable->compute_equal("-2.5*1.5"), -3.75);
@ -302,8 +303,18 @@ TEST_F(VariableTest, AtomicSystem)
variable->compute_equal("v_self"););
TEST_FAILURE(".*ERROR: Variable sum2: Inconsistent lengths in vector-style variable.*",
variable->compute_equal("max(v_sum2)"););
TEST_FAILURE("ERROR: Mismatched fix in variable formula.*",
TEST_FAILURE(".*ERROR: Mismatched fix in variable formula.*",
variable->compute_equal("f_press"););
TEST_FAILURE(".*ERROR .*Variable formula compute vector is accessed out-of-range.*",
variable->compute_equal("c_press[10]"););
TEST_FAILURE(".*ERROR: Non digit character between brackets in variable.*",
variable->compute_equal("c_press[axy]"););
TEST_FAILURE(".*ERROR: Illegal value in brackets: stoll.*",
variable->compute_equal("c_press[73786976294838206464]"););
TEST_FAILURE(".*ERROR: Index between variable brackets must be positive.*",
variable->compute_equal("c_press[-2]"););
TEST_FAILURE(".*ERROR: Index between variable brackets must be positive.*",
variable->compute_equal("c_press[0]"););
}
TEST_F(VariableTest, Expressions)

View File

@ -3,7 +3,7 @@
add_executable(test_lammps_class test_lammps_class.cpp)
target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain)
add_test(NAME LammpsClass COMMAND test_lammps_class)
set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=1")
set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=2;OMP_PROC_BIND=false")
add_executable(test_input_class test_input_class.cpp)
target_link_libraries(test_input_class PRIVATE lammps GTest::GTestMain)

View File

@ -253,6 +253,15 @@ protected:
{
LAMMPS::argv args = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none",
"-k", "on", "t", "1", "-sf", "kk"};
// when GPU support is enabled in KOKKOS, it *must* be used
if (Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) {
args = {"LAMMPS_test", "-log", "none", "-echo", "none", "-screen", "none", "-k",
"on", "t", "1", "g", "1", "-sf", "kk"};
}
if (Info::has_accelerator_feature("KOKKOS", "api", "openmp")) args[10] = "2";
if (LAMMPS::is_installed_pkg("KOKKOS")) {

View File

@ -204,11 +204,7 @@ foreach(TEST ${FIX_TIMESTEP_TESTS})
continue()
endif()
add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST})
if(WIN32)
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}\\\;${LAMMPS_PYTHON_DIR}")
else()
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1")
endif()
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}")
endforeach()
@ -225,7 +221,7 @@ foreach(TEST ${DIHEDRAL_TESTS})
continue()
endif()
add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST})
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1")
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}")
endforeach()
@ -242,7 +238,7 @@ foreach(TEST ${IMPROPER_TESTS})
continue()
endif()
add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST})
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH};PYTHONDONTWRITEBYTECODE=1")
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}")
endforeach()
@ -250,7 +246,7 @@ if(MLIAP_ENABLE_PYTHON AND (NOT WIN32))
add_executable(test_mliappy_unified test_mliappy_unified.cpp)
target_link_libraries(test_mliappy_unified PRIVATE lammps GTest::GMockMain)
add_test(NAME TestMliapPyUnified COMMAND test_mliappy_unified)
set_tests_properties(TestMliapPyUnified PROPERTIES ENVIRONMENT "PYTHONPATH=${LAMMPS_PYTHON_DIR};PYTHONDONTWRITEBYTECODE=1")
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
endif()
add_executable(test_pair_list test_pair_list.cpp)

View File

@ -530,6 +530,126 @@ TEST(AngleStyle, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(AngleStyle, kokkos_omp)
{
if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP();
LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /kk suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for KOKKOS package
double epsilon = 5.0 * test_config.epsilon;
ErrorStats stats;
auto angle = lmp->force->angle;
EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton on)", angle->virial, test_config.init_stress, epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton on)", angle->virial, test_config.run_stress, epsilon);
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(angle->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
angle = lmp->force->angle;
EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton off)", angle->virial, test_config.init_stress,
2 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton off)", angle->virial, test_config.run_stress, epsilon);
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(angle->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
restart_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
angle = lmp->force->angle;
EXPECT_FORCES("restart_forces", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("restart_stress", angle->virial, test_config.init_stress, epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "restart_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
data_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
angle = lmp->force->angle;
EXPECT_FORCES("data_forces", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("data_stress", angle->virial, test_config.init_stress, epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(angle->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "data_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(AngleStyle, numdiff)
{
if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP();

View File

@ -532,6 +532,112 @@ TEST(BondStyle, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(BondStyle, kokkos_omp)
{
if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP();
LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /kk suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for KOKKOS package
double epsilon = 5.0 * test_config.epsilon;
ErrorStats stats;
auto bond = lmp->force->bond;
EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton on)", bond->virial, test_config.init_stress, 10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton on)", bond->virial, test_config.run_stress, 10 * epsilon);
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with bond style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.bond_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(bond->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
bond = lmp->force->bond;
EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton off)", bond->virial, test_config.init_stress,
10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton off)", bond->virial, test_config.run_stress,
10 * epsilon);
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(bond->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with bond style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.bond_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(bond->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(BondStyle, numdiff)
{
if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP();

View File

@ -534,6 +534,112 @@ TEST(DihedralStyle, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(DihedralStyle, kokkos_omp)
{
if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
if (!Info::has_accelerator_feature("KOKKOS", "api", "openmp")) GTEST_SKIP();
LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /kk suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for KOKKOS package
double epsilon = 5.0 * test_config.epsilon;
ErrorStats stats;
auto dihedral = lmp->force->dihedral;
EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton on)", dihedral->virial, test_config.init_stress,
10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton on)", dihedral->virial, test_config.run_stress, 10 * epsilon);
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with dihedral style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.dihedral_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
//if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
dihedral = lmp->force->dihedral;
EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton off)", dihedral->virial, test_config.init_stress,
10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton off)", dihedral->virial, test_config.run_stress,
10 * epsilon);
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with dihedral style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.dihedral_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(DihedralStyle, numdiff)
{
if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP();

View File

@ -527,6 +527,108 @@ TEST(ImproperStyle, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(ImproperStyle, kokkos_omp)
{
if (!LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /kk suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for KOKKOS package
double epsilon = 5.0 * test_config.epsilon;
ErrorStats stats;
auto improper = lmp->force->improper;
EXPECT_FORCES("init_forces (newton on)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton on)", improper->virial, test_config.init_stress,
10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton on)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton on)", improper->virial, test_config.run_stress, 10 * epsilon);
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with improper style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.improper_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
improper = lmp->force->improper;
EXPECT_FORCES("init_forces (newton off)", lmp->atom, test_config.init_forces, epsilon);
EXPECT_STRESS("init_stress (newton off)", improper->virial, test_config.init_stress,
10 * epsilon);
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_FORCES("run_forces (newton off)", lmp->atom, test_config.run_forces, 10 * epsilon);
EXPECT_STRESS("run_stress (newton off)", improper->virial, test_config.run_stress,
10 * epsilon);
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
// FIXME: this is currently broken ??? for KOKKOS with improper style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
//if (test_config.improper_style.substr(0, 6) != "hybrid")
// EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(ImproperStyle, numdiff)
{
if (!LAMMPS::is_installed_pkg("EXTRA-FIX")) GTEST_SKIP();

View File

@ -2,7 +2,7 @@
lammps_version: 17 Feb 2022
date_generated: Fri Mar 18 22:18:02 2022
epsilon: 2.5e-13
skip_tests:
skip_tests: kokkos_omp
prerequisites: ! |
atom full
improper class2

View File

@ -88,7 +88,7 @@ static void create_molecule_files(const std::string &h2o_filename, const std::st
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
const double EPSILON = 5.0e-14;
static const double EPSILON = 5.0e-14;
namespace LAMMPS_NS {
using ::testing::Eq;

View File

@ -32,7 +32,7 @@ using testing::StrEq;
using utils::split_words;
const double EPSILON = 5.0e-14;
static constexpr double EPSILON = 5.0e-14;
#define test_name test_info_->name()

View File

@ -11,11 +11,14 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "fmt/format.h"
#include "lmptype.h"
#include "tokenizer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <cstdint>
using namespace LAMMPS_NS;
using ::testing::Eq;
@ -334,46 +337,73 @@ TEST(ValueTokenizer, move_assignment)
TEST(ValueTokenizer, bad_integer)
{
ValueTokenizer values("f10 f11 f12");
ValueTokenizer values("f10 f11 f12 0xff 109951162777 "
"36893488147419103232 36893488147419103232");
ASSERT_THROW(values.next_int(), InvalidIntegerException);
ASSERT_THROW(values.next_bigint(), InvalidIntegerException);
ASSERT_THROW(values.next_tagint(), InvalidIntegerException);
ASSERT_THROW(values.next_int(), InvalidIntegerException);
ASSERT_THROW(values.next_int(), InvalidIntegerException);
ASSERT_THROW(values.next_tagint(), InvalidIntegerException);
ASSERT_THROW(values.next_bigint(), InvalidIntegerException);
}
TEST(ValueTokenizer, bad_double)
{
ValueTokenizer values("1a.0");
ValueTokenizer values("1a.0 --2.0 2.4d3 -1e20000 1.0e-1.0");
ASSERT_THROW(values.next_double(), InvalidFloatException);
ASSERT_THROW(values.next_double(), InvalidFloatException);
ASSERT_THROW(values.next_double(), InvalidFloatException);
ASSERT_THROW(values.next_double(), InvalidFloatException);
ASSERT_THROW(values.next_double(), InvalidFloatException);
}
TEST(ValueTokenizer, valid_int)
{
ValueTokenizer values("10");
ValueTokenizer values(fmt::format("10 {} {}", -MAXSMALLINT - 1, MAXSMALLINT));
ASSERT_EQ(values.next_int(), 10);
ASSERT_EQ(values.next_int(), -MAXSMALLINT - 1);
ASSERT_EQ(values.next_int(), MAXSMALLINT);
}
TEST(ValueTokenizer, valid_tagint)
{
ValueTokenizer values("42");
ValueTokenizer values(
fmt::format("42 {} {} {} {}", -MAXSMALLINT - 1, MAXSMALLINT, -MAXTAGINT - 1, MAXTAGINT));
ASSERT_EQ(values.next_tagint(), 42);
ASSERT_EQ(values.next_tagint(), -MAXSMALLINT - 1);
ASSERT_EQ(values.next_tagint(), MAXSMALLINT);
ASSERT_EQ(values.next_tagint(), -MAXTAGINT - 1);
ASSERT_EQ(values.next_tagint(), MAXTAGINT);
}
TEST(ValueTokenizer, valid_bigint)
{
ValueTokenizer values("42");
ValueTokenizer values(
fmt::format("42 {} {} {} {}", -MAXSMALLINT - 1, MAXSMALLINT, -MAXBIGINT - 1, MAXBIGINT));
ASSERT_EQ(values.next_bigint(), 42);
ASSERT_EQ(values.next_bigint(), -MAXSMALLINT - 1);
ASSERT_EQ(values.next_bigint(), MAXSMALLINT);
ASSERT_EQ(values.next_bigint(), -MAXBIGINT - 1);
ASSERT_EQ(values.next_bigint(), MAXBIGINT);
}
TEST(ValueTokenizer, valid_double)
{
ValueTokenizer values("3.14");
ValueTokenizer values("3.14 -0.00002 .1 0xff " + std::to_string(MAXBIGINT));
ASSERT_DOUBLE_EQ(values.next_double(), 3.14);
ASSERT_DOUBLE_EQ(values.next_double(), -0.00002);
ASSERT_DOUBLE_EQ(values.next_double(), 0.1);
ASSERT_DOUBLE_EQ(values.next_double(), 255);
ASSERT_DOUBLE_EQ(values.next_double(), MAXBIGINT);
}
TEST(ValueTokenizer, valid_double_with_exponential)
{
ValueTokenizer values("3.14e22");
ValueTokenizer values(fmt::format("3.14e22 {} {}", DBL_MAX, DBL_MIN));
ASSERT_DOUBLE_EQ(values.next_double(), 3.14e22);
ASSERT_DOUBLE_EQ(values.next_double(), DBL_MAX);
ASSERT_DOUBLE_EQ(values.next_double(), DBL_MIN);
}
TEST(ValueTokenizer, contains)