Merge remote-tracking branch 'github/develop' into small_fixes

This commit is contained in:
Axel Kohlmeyer
2025-01-30 16:19:38 -05:00
57 changed files with 1879 additions and 322 deletions

View File

@ -3,9 +3,12 @@
#include "library.h"
#include "atom.h"
#include "compute.h"
#include "lammps.h"
#include "lmptype.h"
#include "modify.h"
#include "platform.h"
#include <string>
#include <vector>
@ -668,6 +671,77 @@ TEST_F(LibraryProperties, neighlist)
}
};
static constexpr char lj_setup[] = "lattice fcc 0.8442\n"
"region box block 0 10 0 10 0 10\n"
"create_box 1 box\n"
"create_atoms 1 box\n"
"mass 1 1.0\n"
"pair_style lj/cut 2.5\n"
"pair_coeff 1 1 1.0 1.0\n"
"fix 1 all nve\n";
TEST_F(LibraryProperties, step_compute)
{
::testing::internal::CaptureStdout();
lammps_commands_string(lmp, lj_setup);
lammps_command(lmp, "compute pr all pressure thermo_temp");
lammps_command(lmp, "fix av all ave/time 2 1 2 c_pr mode scalar");
lammps_command(lmp, "run 2 post no");
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (lammps_has_error(lmp)) {
char buf[2048];
lammps_get_last_error_message(lmp, buf, 2048);
FAIL() << buf << "\n";
}
auto lammps = (LAMMPS_NS::LAMMPS *)lmp;
auto icomp = lammps->modify->get_compute_by_id("pr");
EXPECT_EQ(icomp->ntime, 2);
EXPECT_EQ(icomp->tlist[0], 4);
EXPECT_EQ(icomp->tlist[1], 2);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, 2);
EXPECT_EQ(icomp->invoked_vector, -1);
lammps_clearstep_compute(lmp);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, 2);
EXPECT_EQ(icomp->invoked_vector, -1);
bigint nextstep = 6;
lammps_addstep_compute(lmp, (void *)&nextstep);
EXPECT_EQ(icomp->ntime, 3);
EXPECT_EQ(icomp->tlist[0], 6);
EXPECT_EQ(icomp->tlist[1], 4);
EXPECT_EQ(icomp->tlist[2], 2);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, 2);
EXPECT_EQ(icomp->invoked_vector, -1);
lammps_command(lmp, "run 4 post no");
EXPECT_EQ(icomp->ntime, 2);
EXPECT_EQ(icomp->tlist[0], 8);
EXPECT_EQ(icomp->tlist[1], 6);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, 6);
EXPECT_EQ(icomp->invoked_vector, -1);
lammps_command(lmp, "run 2 post no");
EXPECT_EQ(icomp->ntime, 2);
EXPECT_EQ(icomp->tlist[0], 10);
EXPECT_EQ(icomp->tlist[1], 8);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, 8);
EXPECT_EQ(icomp->invoked_vector, -1);
nextstep = 9;
lammps_addstep_compute(lmp, (void *)&nextstep);
lammps_command(lmp, "run 1 post no");
EXPECT_EQ(icomp->ntime, 2);
EXPECT_EQ(icomp->tlist[0], 10);
EXPECT_EQ(icomp->tlist[1], 9);
EXPECT_EQ(icomp->invoked_flag, 0);
EXPECT_EQ(icomp->invoked_scalar, -1);
EXPECT_EQ(icomp->invoked_vector, -1);
icomp->compute_scalar();
EXPECT_EQ(icomp->invoked_scalar, 9);
}
TEST_F(LibraryProperties, has_error)
{
EXPECT_EQ(lammps_has_error(lmp), 0);

View File

@ -246,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(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
set_tests_properties(TestMliapPyUnified PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}")
endif()
add_executable(test_pair_list test_pair_list.cpp)

View File

@ -53,15 +53,16 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
platform::unlink(cfg.basename + ".data");
platform::unlink(cfg.basename + "-coeffs.in");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton = true)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton)
{
LAMMPS *lmp;
@ -92,21 +93,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
try {
lmp->input->one(line);
} catch (LAMMPSAbortException &ae) {
fprintf(stderr, "LAMMPS Error: %s\n", ae.what());
exit(2);
} catch (LAMMPSException &e) {
fprintf(stderr, "LAMMPS Error: %s\n", e.what());
exit(3);
} catch (fmt::format_error &fe) {
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
exit(4);
} catch (std::exception &e) {
fprintf(stderr, "General exception: %s\n", e.what());
exit(5);
}
lmp->input->one(line);
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
@ -230,7 +217,12 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// initialize system geometry
LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, true);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -321,8 +313,14 @@ TEST(AngleStyle, plain)
LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -371,7 +369,12 @@ TEST(AngleStyle, plain)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -439,8 +442,14 @@ TEST(AngleStyle, omp)
"-pk", "omp", "4", "-sf", "omp"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -493,7 +502,12 @@ TEST(AngleStyle, omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -540,14 +554,21 @@ TEST(AngleStyle, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl"))
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
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);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -597,7 +618,12 @@ TEST(AngleStyle, kokkos_omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -664,8 +690,14 @@ TEST(AngleStyle, numdiff)
LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -717,7 +749,13 @@ TEST(AngleStyle, single)
// create a LAMMPS instance with standard settings to detect the number of atom types
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {
@ -865,7 +903,13 @@ TEST(AngleStyle, extract)
LAMMPS::argv args = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {

View File

@ -53,15 +53,16 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
platform::unlink(cfg.basename + ".data");
platform::unlink(cfg.basename + "-coeffs.in");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton = true)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton)
{
LAMMPS *lmp;
@ -92,21 +93,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
try {
lmp->input->one(line);
} catch (LAMMPSAbortException &ae) {
fprintf(stderr, "LAMMPS Error: %s\n", ae.what());
exit(2);
} catch (LAMMPSException &e) {
fprintf(stderr, "LAMMPS Error: %s\n", e.what());
exit(3);
} catch (fmt::format_error &fe) {
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
exit(4);
} catch (std::exception &e) {
fprintf(stderr, "General exception: %s\n", e.what());
exit(5);
}
lmp->input->one(line);
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
@ -230,7 +217,13 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// initialize system geometry
LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, true);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -321,8 +314,14 @@ TEST(BondStyle, plain)
LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -371,7 +370,12 @@ TEST(BondStyle, plain)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -441,8 +445,14 @@ TEST(BondStyle, omp)
"-pk", "omp", "4", "-sf", "omp"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -495,7 +505,12 @@ TEST(BondStyle, omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -542,14 +557,21 @@ TEST(BondStyle, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl"))
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
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);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -603,7 +625,12 @@ TEST(BondStyle, kokkos_omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -652,8 +679,14 @@ TEST(BondStyle, numdiff)
LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -705,7 +738,13 @@ TEST(BondStyle, single)
// create a LAMMPS instance with standard settings to detect the number of atom types
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {
@ -959,7 +998,13 @@ TEST(BondStyle, extract)
LAMMPS::argv args = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {

View File

@ -53,15 +53,16 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
platform::unlink(cfg.basename + ".data");
platform::unlink(cfg.basename + "-coeffs.in");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton = true)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton)
{
auto *lmp = new LAMMPS(args, MPI_COMM_WORLD);
@ -237,7 +238,13 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// initialize system geometry
LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, true);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -322,8 +329,14 @@ TEST(DihedralStyle, plain)
LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -372,7 +385,12 @@ TEST(DihedralStyle, plain)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -442,8 +460,14 @@ TEST(DihedralStyle, omp)
"-pk", "omp", "4", "-sf", "omp"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -497,7 +521,12 @@ TEST(DihedralStyle, omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -544,15 +573,22 @@ TEST(DihedralStyle, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl"))
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
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);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -606,7 +642,12 @@ TEST(DihedralStyle, kokkos_omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -655,8 +696,14 @@ TEST(DihedralStyle, numdiff)
LAMMPS::argv args = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;

View File

@ -56,13 +56,14 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool use_respa = false)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool use_respa)
{
LAMMPS *lmp;
@ -178,7 +179,12 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
{
// initialize system geometry
LAMMPS::argv args = {"FixIntegrate", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, false);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -272,7 +278,14 @@ TEST(FixTimestep, plain)
LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -430,14 +443,20 @@ TEST(FixTimestep, plain)
// fix nve/limit cannot work with r-RESPA
ifix = lmp->modify->get_fix_by_id("test");
if (ifix && !utils::strmatch(ifix->style, "^rigid") &&
!utils::strmatch(ifix->style, "^nve/limit") &&
!utils::strmatch(ifix->style, "^recenter")) {
!utils::strmatch(ifix->style, "^nve/limit") && !utils::strmatch(ifix->style, "^recenter")) {
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
::testing::internal::CaptureStdout();
lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -572,15 +591,26 @@ TEST(FixTimestep, omp)
"-pk", "omp", "4", "-sf", "omp"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
std::cerr << "One or more prerequisite styles with /omp suffix are not available "
"in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
if (prerequisite.first == "atom") {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
} else {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "/omp\n";
}
}
GTEST_SKIP();
}
@ -731,7 +761,13 @@ TEST(FixTimestep, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
::testing::internal::CaptureStdout();
lmp = init_lammps(args, test_config, true);
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -861,13 +897,21 @@ TEST(FixTimestep, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) {
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
}
LAMMPS::argv args = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -875,7 +919,7 @@ TEST(FixTimestep, kokkos_omp)
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";
std::cerr << prerequisite.first << "_style " << prerequisite.second << "/kk\n";
}
GTEST_SKIP();
}

View File

@ -53,15 +53,16 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
platform::unlink(cfg.basename + ".data");
platform::unlink(cfg.basename + "-coeffs.in");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton = true)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton)
{
LAMMPS *lmp;
@ -92,21 +93,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
try {
lmp->input->one(line);
} catch (LAMMPSAbortException &ae) {
fprintf(stderr, "LAMMPS Error: %s\n", ae.what());
exit(2);
} catch (LAMMPSException &e) {
fprintf(stderr, "LAMMPS Error: %s\n", e.what());
exit(3);
} catch (fmt::format_error &fe) {
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
exit(4);
} catch (std::exception &e) {
fprintf(stderr, "General exception: %s\n", e.what());
exit(5);
}
lmp->input->one(line);
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
@ -230,7 +217,12 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// initialize system geometry
LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, true);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -315,8 +307,14 @@ TEST(ImproperStyle, plain)
LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -365,7 +363,12 @@ TEST(ImproperStyle, plain)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -435,8 +438,14 @@ TEST(ImproperStyle, omp)
"-pk", "omp", "4", "-sf", "omp"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -490,7 +499,12 @@ TEST(ImproperStyle, omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -536,15 +550,22 @@ TEST(ImproperStyle, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl"))
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
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);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -597,7 +618,12 @@ TEST(ImproperStyle, kokkos_omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
@ -644,8 +670,14 @@ TEST(ImproperStyle, numdiff)
LAMMPS::argv args = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;

View File

@ -54,15 +54,16 @@ using ::testing::StartsWith;
using namespace LAMMPS_NS;
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
void cleanup_lammps(LAMMPS *&lmp, const TestConfig &cfg)
{
platform::unlink(cfg.basename + ".restart");
platform::unlink(cfg.basename + ".data");
platform::unlink(cfg.basename + "-coeffs.in");
delete lmp;
lmp = nullptr;
}
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton = true)
LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton)
{
LAMMPS *lmp;
@ -93,21 +94,7 @@ LAMMPS *init_lammps(LAMMPS::argv &args, const TestConfig &cfg, const bool newton
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
try {
lmp->input->one(line);
} catch (LAMMPSAbortException &ae) {
fprintf(stderr, "LAMMPS Error: %s\n", ae.what());
exit(2);
} catch (LAMMPSException &e) {
fprintf(stderr, "LAMMPS Error: %s\n", e.what());
exit(3);
} catch (fmt::format_error &fe) {
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
exit(4);
} catch (std::exception &e) {
fprintf(stderr, "General exception: %s\n", e.what());
exit(5);
}
lmp->input->one(line);
};
auto parse_input_script = [&](const std::string &filename) {
@ -242,8 +229,12 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
{
// initialize system geometry
LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
LAMMPS *lmp = init_lammps(args, config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, config, true);
} catch (std::exception &e) {
FAIL() << e.what();
}
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
@ -340,8 +331,14 @@ TEST(PairStyle, plain)
LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -399,7 +396,12 @@ TEST(PairStyle, plain)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton pair is forced to be on
@ -480,9 +482,14 @@ TEST(PairStyle, plain)
if (pair->respa_enable) {
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
lmp->input->one("run_style respa 2 1 inner 1 4.8 5.5 outer 2");
run_lammps(lmp);
try {
lmp = init_lammps(args, test_config, false);
lmp->input->one("run_style respa 2 1 inner 1 4.8 5.5 outer 2");
run_lammps(lmp);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
// need to relax error by a large amount with tabulation, since
@ -519,8 +526,14 @@ TEST(PairStyle, omp)
if (utils::strmatch(test_config.pair_style, "^dpd")) args[8] = "1";
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -578,7 +591,12 @@ TEST(PairStyle, omp)
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
pair = lmp->force->pair;
@ -636,7 +654,9 @@ TEST(PairStyle, kokkos_omp)
// if KOKKOS has GPU support enabled, it *must* be used. We cannot test OpenMP only.
if (Info::has_accelerator_feature("KOKKOS", "api", "cuda") ||
Info::has_accelerator_feature("KOKKOS", "api", "hip") ||
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) GTEST_SKIP();
Info::has_accelerator_feature("KOKKOS", "api", "sycl")) {
GTEST_SKIP() << "Cannot test KOKKOS/OpenMP with GPU support enabled";
}
LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite",
"-k", "on", "t", "4", "-sf", "kk"};
@ -655,8 +675,14 @@ TEST(PairStyle, kokkos_omp)
args[9] = "1";
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -713,7 +739,12 @@ TEST(PairStyle, kokkos_omp)
if (lmp->force->newton_pair == 0) {
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(args, test_config, false);
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
pair = lmp->force->pair;
@ -788,8 +819,14 @@ TEST(PairStyle, gpu)
}
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, false);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, false);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -868,8 +905,14 @@ TEST(PairStyle, intel)
if (utils::strmatch(test_config.pair_style, "^dpd")) args[12] = "1";
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -948,8 +991,14 @@ TEST(PairStyle, opt)
LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "opt"};
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
FAIL() << e.what();
}
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
@ -1032,7 +1081,13 @@ TEST(PairStyle, single)
// create a LAMMPS instance with standard settings to detect the number of atom types
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {
@ -1276,7 +1331,13 @@ TEST(PairStyle, extract)
LAMMPS::argv args = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
if (!verbose) ::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(args, test_config, true);
LAMMPS *lmp = nullptr;
try {
lmp = init_lammps(args, test_config, true);
} catch (std::exception &e) {
if (!verbose) ::testing::internal::GetCapturedStdout();
FAIL() << e.what();
}
if (!verbose) ::testing::internal::GetCapturedStdout();
if (!lmp) {

View File

@ -6,7 +6,7 @@ epsilon: 2e-13
skip_tests:
prerequisites: ! |
atom full
fix efield
fix efield/lepton
pre_commands: ! ""
post_commands: ! |
region half block 0 EDGE EDGE EDGE EDGE EDGE

View File

@ -6,7 +6,7 @@ epsilon: 2e-13
skip_tests:
prerequisites: ! |
atom full
fix efield
fix efield/lepton
pre_commands: ! ""
post_commands: ! |
region half block 0 EDGE EDGE EDGE EDGE EDGE