standarize use of static methods with MDI, also plugin args

This commit is contained in:
Steve Plimpton
2022-08-05 16:05:36 -06:00
parent ade64c586e
commit 691004509a
10 changed files with 102 additions and 67 deletions

View File

@ -53,24 +53,23 @@ Building 3 codes needed to run these examples
(3) Build LAMMPS with its MDI package
also with the MOLECULE package for these example scripts
traditional make:
Build with regular make:
% cd lammps/lib/mdi
% python Install.py -m mpi # creates static libmdi.a
% python Install.py -m mpi
% cd lammps/src
% make yes-mdi
% make mpi # build LAMMPS as exe and shared lib
# shared lib for use of LAMMPS as MDI plugin
% make mpi # creates lmp_mpi
CMake build:
Build with CMake:
% cd lammps
% mkdir build; cd build
% cmake -D PKG_MDI=yes -D PKG_MOLECULE=yes ../cmake
% make
% make # creates lmp
(4) Copy LAMMPS and LATTE files into this dir
(4) Copy LAMMPS and LATTE executables into this dir
Copy the LAMMPS executable (e.g. lmp_mpi) into this dir.
Copy the LATTE executabe (LATTE_DOUBLE) into this dir.
Copy the LAMMPS executable into this dir as lmp_mpi.
Copy the LATTE executable LATTE_DOUBLE into this dir.
The run commands below assume you have done this.
------------------

18
examples/QM/README Normal file
View File

@ -0,0 +1,18 @@
Each of the directories shows how to use LAMMPS in tandem with a
specific quantum code
LATTE = semi-empirical tight-binding code from LANL
https://www.osti.gov/biblio/1526907-los-alamos-transferable-tight-binding-energetics-latte-version
https://github.com/lanl/LATTE
To be added later (as of July 2022):
DFT-FE = real-space DFT code from U Michigan
https://github.com/dftfeDevelopers/dftfe
Quantum Espresso (QE) = DFT code for materials modeling
https://www.quantum-espresso.org/
NWChem = computational chemistry code from PNNL
focus here is on DFT portion of NWChem
https://www.nwchem-sw.org

View File

@ -27,17 +27,33 @@ Examples for all these use cases, using LAMMPS as a driver and as an
engine are in this directory. The Run.sh file shows how run in all
the modes. Type "sh Run.sh" to try them all out.
Examples for using LAMMPS as a driver with the tight-binding code LATTE
are in the LATTE sub-directory. See its README file for more info.
Examples for using LAMMPS as a driver with the tight-binding code
LATTE are in the examples/QM/LATTE sub-directory. See its README file
for more info.
Note that to use LAMMPS as a plugin engine for some the examples in
this dir, you must build it as a shared library. Something like this
with traditional make, which also builds the normal LAMMPS executable
lmp_mpi:
-------------------------------------------------
cd src
make yes-mdi
make mode=shlib mpi
Here is how to build LAMMPS with MDI support. Both as an executable
and a shared library. The former is needed to use LAMMPS as an MDI
driver or as an MDI engine in stand-alone mode. The latter is needed
to use LAMMPS as an MDI engine in plugin mode.
Build via regular make:
% cd lammps/src
% make lib-mdi args="-m mpi" # download, install MDI in lib/mdi w/ MPI support
% make yes-mdi # include MDI package in LAMMPS build
% make mode=shlib mpi # creates lmp_mpi and liblammps.so
Build via CMake:
cd lammps
mkdir build; cd build
cmake -D PKG_MDI=yes -D BUILD_SHARED_LIBS=yes ../cmake
make # creates lmp and liblammps.so
Both of these build procedures build LAMMPS both as an executable
(lmp_mpi) and as a shared library (liblammps.so).
-------------------------------------------------

View File

@ -27,9 +27,7 @@ specify -m and optionally -e, order does not matter
Examples:
make lib-poems args="-m serial" # build POEMS lib with same settings as in the serial Makefile in src
make lib-colvars args="-m mpi" # build COLVARS lib with same settings as in the mpi Makefile in src
make lib-meam args="-m ifort" # build MEAM lib with custom Makefile.ifort (using Intel Fortran)
make lib-mdi args="-m mpi" # build MDI lib with same settings as in the mpi Makefile in src
"""
# settings

View File

@ -23,12 +23,8 @@
#define LAMMPS_LIB_MPI 1
#include "library.h"
#include "mdi_engine.h"
#include <cstring>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
/** Initialize an instance of LAMMPS as an MDI plugin
@ -58,6 +54,7 @@ int MDI_Plugin_init_lammps()
int mdi_argc;
char **mdi_argv;
if (MDI_Plugin_get_argc(&mdi_argc)) MPI_Abort(MPI_COMM_WORLD, 1);
if (MDI_Plugin_get_argv(&mdi_argv)) MPI_Abort(MPI_COMM_WORLD, 1);
if (MDI_Init(&mdi_argc, &mdi_argv)) MPI_Abort(MPI_COMM_WORLD, 1);
@ -90,14 +87,24 @@ int MDI_Plugin_init_lammps()
if (!found_filename) MPI_Abort(MPI_COMM_WORLD, 1);
// create and run a LAMMPS instance
// lammps_open() expects a first arg (not used) which is executable name
// same as if called from main.cpp
// need to add an initial pseudo arg to mdi_argc & mdi_argv
// b/c lammps_open() expects first arg to be an executable name
// same as if it were called from main.cpp
int mdi_argc_extra = mdi_argc + 1;
char **mdi_argv_extra = new char*[mdi_argc_extra];
mdi_argv_extra[0] = (char *) "MDI_plugin_engine";
for (int i = 0; i < mdi_argc; i++)
mdi_argv_extra[i+1] = mdi_argv[i];
void *lmp = nullptr;
if (lammps_config_has_mpi_support() > 0)
lmp = lammps_open(mdi_argc + 1, &mdi_argv[-1], mpi_world_comm, nullptr);
lmp = lammps_open(mdi_argc_extra, mdi_argv_extra, mpi_world_comm, nullptr);
else
lmp = lammps_open_no_mpi(mdi_argc + 1, &mdi_argv[-1], nullptr);
lmp = lammps_open_no_mpi(mdi_argc_extra, mdi_argv_extra, nullptr);
delete [] mdi_argv_extra;
// process the specified input script
// must contain "mdi engine" command
@ -110,25 +117,3 @@ int MDI_Plugin_init_lammps()
return 0;
}
/* ---------------------------------------------------------------------- */
/** Execute an MDI command
*
\verbatim embed:rst
This function is called by the MolSSI Driver Interface Library (MDI)
when LAMMPS is run as a plugin, and should not otherwise be used.
The function executes a single command from an external MDI driver.
\endverbatim
* \param command string buffer corresponding to the command to be executed
* \param comm MDI communicator that can be used to communicated with the driver.
* \param class_obj pointer to an instance of an mdi/engine fix cast to ``void *``.
* \return 0 on no error, 1 on error. */
int lammps_execute_mdi_command(const char *command, MDI_Comm comm, void *class_obj)
{
auto mdi_engine = (MDIEngine *) class_obj;
return mdi_engine->execute_command(command, comm);
}

View File

@ -14,13 +14,12 @@
#ifndef LAMMPS_LIBRARY_MDI_H
#define LAMMPS_LIBRARY_MDI_H
/* C style library calls to LAMMPS when a LAMMPS shared library is
* used as a plugin through MolSSI Driver Interface (MDI). */
/* C style library call to LAMMPS when a LAMMPS shared library is
* used as a plugin through MolSSI Driver Interface (MDI) */
#include <mdi.h>
extern "C" {
int MDI_Plugin_init_lammps();
int lammps_execute_mdi_command(const char *, MDI_Comm, void *);
}
#endif

View File

@ -184,10 +184,10 @@ MDIEngine::MDIEngine(LAMMPS *_lmp, int narg, char ** arg) : Pointers(_lmp)
mdi_commands();
// register the execute_command function with MDI
// only used when engine runs in plugin mode
// register a callback function with MDI used when engine runs in plugin mode
// execute_command_plugin_wrapper() must be a static method
MDI_Set_execute_command_func(lammps_execute_mdi_command, this);
MDI_Set_execute_command_func(execute_command_plugin_wrapper, this);
// one-time operation to establish a connection with the driver
@ -291,11 +291,23 @@ void MDIEngine::engine_node(const char *node)
node_match = true;
}
/* ----------------------------------------------------------------------
wrapper function on execute_command()
invoked as callback by MDI when engine operates in plugin mode
this is a static method in mdi_engine.h
---------------------------------------------------------------------- */
int MDIEngine::execute_command_plugin_wrapper(const char *command,
MDI_Comm comm, void *class_obj)
{
auto mdi_engine = (MDIEngine *) class_obj;
return mdi_engine->execute_command(command, comm);
}
/* ----------------------------------------------------------------------
process a single driver command
called by engine_node() in loop
also called by MDI itself via lib::lammps_execute_mdi_command()
when LAMMPS is running as a plugin
called by engine_node() in loop when engine runs as stand-alone code
called by execute_command_plugin_wrapper() when engine runs as plugin lib
---------------------------------------------------------------------- */
int MDIEngine::execute_command(const char *command, MDI_Comm mdicomm)

View File

@ -22,8 +22,6 @@ namespace LAMMPS_NS {
class MDIEngine : protected Pointers {
public:
MDIEngine(class LAMMPS *, int, char **);
int execute_command(const char *command, MDI_Comm mdicomm);
void engine_node(const char *node);
private:
@ -87,9 +85,13 @@ class MDIEngine : protected Pointers {
class Irregular *irregular; // irregular comm if new COORDS
// are highly displaced
// static method for MDI to callback to, when LAMMPS used as plugin engine
static int execute_command_plugin_wrapper(const char *, MDI_Comm, void *);
// class methods
void mdi_engine(int, char **);
int execute_command(const char *, MDI_Comm);
void mdi_commands();
void mdi_md();

View File

@ -98,16 +98,19 @@ MDIPlugin::MDIPlugin(LAMMPS *_lmp, int narg, char **arg) : Pointers(_lmp)
// launch the MDI plugin library
// path for lib was specified in -mdi command-line arg when LAMMPS started
// this calls back to plugin_wrapper, which must issue MDI EXIT at end
// this calls back to plugin_wrapper(), which issues MDI EXIT at end & returns
// plugin_wrapper() must be a static method
MDI_Launch_plugin(plugin_name, plugin_args, &world, plugin_wrapper, (void *) this);
MDI_Launch_plugin(plugin_name, plugin_args, &world, plugin_wrapper,
(void *) this);
delete[] plugin_args;
}
/* ----------------------------------------------------------------------
callback function from MDI_Launch_plugin()
this function wraps entire interaction of LAMMPS driver with the plugin
wrapper on entire interaction of LAMMPS as a driver with the plugin engine
invoked as a callback by MDI once plugin library engine is launched
this is a static method in mdi_plugin.h
---------------------------------------------------------------------- */
int MDIPlugin::plugin_wrapper(void * /*pmpicomm*/, MDI_Comm mdicomm, void *vptr)

View File

@ -26,6 +26,9 @@ class MDIPlugin : protected Pointers {
private:
char *lammps_command;
// static method for MDI to callback to
// when LAMMPS is a driver which launches a plugin engine
static int plugin_wrapper(void *, MDI_Comm, void *);
};