1 // unit tests creating LAMMPS instances via the library interface
2 
3 #include "lammps.h"
4 #define LAMMPS_LIB_MPI 1
5 #include "library.h"
6 #include <cstdio> // for stdin, stdout
7 #include <mpi.h>
8 #include <string>
9 
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 
13 #include "test_main.h"
14 
15 using ::testing::HasSubstr;
16 using ::testing::StartsWith;
17 
TEST(lammps_open,null_args)18 TEST(lammps_open, null_args)
19 {
20     ::testing::internal::CaptureStdout();
21     void *handle       = lammps_open(0, NULL, MPI_COMM_WORLD, NULL);
22     std::string output = ::testing::internal::GetCapturedStdout();
23     EXPECT_THAT(output, StartsWith("LAMMPS ("));
24     if (verbose) std::cout << output;
25     int mpi_init = 0;
26     MPI_Initialized(&mpi_init);
27     EXPECT_GT(mpi_init, 0);
28     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
29     EXPECT_EQ(lmp->world, MPI_COMM_WORLD);
30     EXPECT_EQ(lmp->infile, stdin);
31     EXPECT_EQ(lmp->screen, stdout);
32     EXPECT_NE(lmp->citeme, nullptr);
33     ::testing::internal::CaptureStdout();
34     lammps_close(handle);
35     output = ::testing::internal::GetCapturedStdout();
36     EXPECT_THAT(output, HasSubstr("Total wall time:"));
37     if (verbose) std::cout << output;
38 }
39 
TEST(lammps_open,with_args)40 TEST(lammps_open, with_args)
41 {
42     const char *args[] = {"liblammps", "-log", "none", "-nocite"};
43     char **argv        = (char **)args;
44     int argc           = sizeof(args) / sizeof(char *);
45 
46     // MPI is already initialized
47     MPI_Comm mycomm;
48     MPI_Comm_split(MPI_COMM_WORLD, 0, 1, &mycomm);
49     ::testing::internal::CaptureStdout();
50     void *alt_ptr;
51     void *handle       = lammps_open(argc, argv, mycomm, &alt_ptr);
52     std::string output = ::testing::internal::GetCapturedStdout();
53     EXPECT_THAT(output, StartsWith("LAMMPS ("));
54     if (verbose) std::cout << output;
55     EXPECT_EQ(handle, alt_ptr);
56     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
57 
58     // MPI STUBS uses no real communicators
59 #if !defined(MPI_STUBS)
60     EXPECT_NE(lmp->world, MPI_COMM_WORLD);
61 #endif
62 
63     EXPECT_EQ(lmp->world, mycomm);
64     EXPECT_EQ(lmp->infile, stdin);
65     EXPECT_EQ(lmp->logfile, nullptr);
66     EXPECT_EQ(lmp->citeme, nullptr);
67     EXPECT_EQ(lmp->kokkos, nullptr);
68     EXPECT_EQ(lmp->atomKK, nullptr);
69     EXPECT_EQ(lmp->memoryKK, nullptr);
70     ::testing::internal::CaptureStdout();
71     lammps_close(handle);
72     output = ::testing::internal::GetCapturedStdout();
73     EXPECT_THAT(output, HasSubstr("Total wall time:"));
74     if (verbose) std::cout << output;
75     MPI_Comm_free(&mycomm);
76 }
77 
TEST(lammps_open,with_kokkos)78 TEST(lammps_open, with_kokkos)
79 {
80     if (!LAMMPS_NS::LAMMPS::is_installed_pkg("KOKKOS")) GTEST_SKIP();
81     const char *args[] = {"liblammps", "-k", "on", "t", "2", "-sf", "kk", "-log", "none"};
82     char **argv        = (char **)args;
83     int argc           = sizeof(args) / sizeof(char *);
84 
85     ::testing::internal::CaptureStdout();
86     void *alt_ptr;
87     void *handle       = lammps_open(argc, argv, MPI_COMM_WORLD, &alt_ptr);
88     std::string output = ::testing::internal::GetCapturedStdout();
89     EXPECT_THAT(output, StartsWith("LAMMPS ("));
90     if (verbose) std::cout << output;
91     EXPECT_EQ(handle, alt_ptr);
92     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
93 
94     EXPECT_EQ(lmp->world, MPI_COMM_WORLD);
95     EXPECT_EQ(lmp->infile, stdin);
96     EXPECT_EQ(lmp->logfile, nullptr);
97     EXPECT_NE(lmp->citeme, nullptr);
98     EXPECT_EQ(lmp->num_package, 0);
99     EXPECT_NE(lmp->kokkos, nullptr);
100     EXPECT_NE(lmp->atomKK, nullptr);
101     EXPECT_NE(lmp->memoryKK, nullptr);
102     ::testing::internal::CaptureStdout();
103     lammps_close(handle);
104     output = ::testing::internal::GetCapturedStdout();
105     EXPECT_THAT(output, HasSubstr("Total wall time:"));
106     if (verbose) std::cout << output;
107 }
108 
TEST(lammps_open_no_mpi,no_screen)109 TEST(lammps_open_no_mpi, no_screen)
110 {
111     const char *args[] = {"liblammps", "-log", "none", "-screen", "none", "-nocite"};
112     char **argv        = (char **)args;
113     int argc           = sizeof(args) / sizeof(char *);
114 
115     ::testing::internal::CaptureStdout();
116     void *alt_ptr;
117     void *handle       = lammps_open_no_mpi(argc, argv, &alt_ptr);
118     std::string output = ::testing::internal::GetCapturedStdout();
119     EXPECT_STREQ(output.c_str(), "");
120     EXPECT_EQ(handle, alt_ptr);
121     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
122 
123     EXPECT_EQ(lmp->world, MPI_COMM_WORLD);
124     EXPECT_EQ(lmp->infile, stdin);
125     EXPECT_EQ(lmp->screen, nullptr);
126     EXPECT_EQ(lmp->logfile, nullptr);
127     EXPECT_EQ(lmp->citeme, nullptr);
128     EXPECT_EQ(lmp->suffix_enable, 0);
129 
130     EXPECT_STREQ(lmp->exename, "liblammps");
131     EXPECT_EQ(lmp->num_package, 0);
132     ::testing::internal::CaptureStdout();
133     lammps_close(handle);
134     output = ::testing::internal::GetCapturedStdout();
135     EXPECT_STREQ(output.c_str(), "");
136 }
137 
TEST(lammps_open_no_mpi,with_omp)138 TEST(lammps_open_no_mpi, with_omp)
139 {
140     if (!LAMMPS_NS::LAMMPS::is_installed_pkg("OPENMP")) GTEST_SKIP();
141     const char *args[] = {"liblammps", "-pk", "omp",  "2",    "neigh",  "no",
142                           "-sf",       "omp", "-log", "none", "-nocite"};
143     char **argv        = (char **)args;
144     int argc           = sizeof(args) / sizeof(char *);
145 
146     ::testing::internal::CaptureStdout();
147     void *alt_ptr;
148     void *handle       = lammps_open_no_mpi(argc, argv, &alt_ptr);
149     std::string output = ::testing::internal::GetCapturedStdout();
150     EXPECT_THAT(output, StartsWith("LAMMPS ("));
151     if (verbose) std::cout << output;
152     EXPECT_EQ(handle, alt_ptr);
153     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
154 
155     EXPECT_EQ(lmp->world, MPI_COMM_WORLD);
156     EXPECT_EQ(lmp->infile, stdin);
157     EXPECT_EQ(lmp->logfile, nullptr);
158     EXPECT_EQ(lmp->citeme, nullptr);
159     EXPECT_EQ(lmp->suffix_enable, 1);
160     EXPECT_STREQ(lmp->suffix, "omp");
161     EXPECT_EQ(lmp->suffix2, nullptr);
162     EXPECT_STREQ(lmp->exename, "liblammps");
163     EXPECT_EQ(lmp->num_package, 1);
164     ::testing::internal::CaptureStdout();
165     lammps_close(handle);
166     output = ::testing::internal::GetCapturedStdout();
167     EXPECT_THAT(output, HasSubstr("Total wall time:"));
168     if (verbose) std::cout << output;
169 }
170 
TEST(lammps_open_fortran,no_args)171 TEST(lammps_open_fortran, no_args)
172 {
173     // MPI is already initialized
174     MPI_Comm mycomm;
175     MPI_Comm_split(MPI_COMM_WORLD, 0, 1, &mycomm);
176     int fcomm = MPI_Comm_c2f(mycomm);
177     ::testing::internal::CaptureStdout();
178     void *handle       = lammps_open_fortran(0, NULL, fcomm);
179     std::string output = ::testing::internal::GetCapturedStdout();
180     EXPECT_THAT(output, StartsWith("LAMMPS ("));
181     if (verbose) std::cout << output;
182     LAMMPS_NS::LAMMPS *lmp = (LAMMPS_NS::LAMMPS *)handle;
183 
184     // MPI STUBS uses no real communicators
185 #if !defined(MPI_STUBS)
186     EXPECT_NE(lmp->world, MPI_COMM_WORLD);
187 #endif
188 
189     EXPECT_EQ(lmp->world, mycomm);
190     EXPECT_EQ(lmp->infile, stdin);
191     EXPECT_EQ(lmp->screen, stdout);
192     EXPECT_NE(lmp->logfile, nullptr);
193     EXPECT_NE(lmp->citeme, nullptr);
194     ::testing::internal::CaptureStdout();
195     lammps_close(handle);
196     output = ::testing::internal::GetCapturedStdout();
197     EXPECT_THAT(output, HasSubstr("Total wall time:"));
198     if (verbose) std::cout << output;
199     MPI_Comm_free(&mycomm);
200 }
201