more debugging for plugin mode

This commit is contained in:
Steve Plimpton
2022-04-01 09:27:48 -06:00
parent 19a6eecfbb
commit 294dcc5f93
7 changed files with 104 additions and 42 deletions

View File

@ -2,32 +2,47 @@ These are examples that work the MDI package in LAMMPS which uses the
MolSSI MDI library for coupling codes together and communicating
between them with MDI messages.
To use the serial_drive.py example you will need Python 3 with Numpy
and mpi4py available in your Python. Make sure LAMMPS and Python are
using same the same version of MPI.
In MDI lingo, one code is the driver and another code is the engine.
The 2 codes can be written in any language; C++ (LAMMPS) and Python
are illustrated here. The 2 codes can be run on different numbers of
processors.
The 2 codes can communicate either via TCP (sockets) or via MPI. For
the TCP case, the driver and engine need to be launched separately,
are illustrated here. The 2 codes can each be stand-alone codes, in
which case they can be run on different numbers of processors. The 2
codes can communicate either via TCP (sockets) or via MPI. For the
TCP case, the driver and engine need to be launched separately,
e.g. in 2 windows on your desktop machine. For the MPI case, a single
mpirun command launches both codes.
The example run commands below have variants for these options.
Alternatively the engine code can be a plugin library which the driver
code loads, in which case the driver and engine run on the same
processors.
LAMMPS supports operating in all these modes. It can be an engine
operating either as a stand-alone code or as a plugin. It can also be
a driver and couple to an engine that is either a stand-alone code or
a plugin. Examples for all these use cases are in this directory.
The example run commands below illustrate all the variants.
To use LAMMPS as a plugin engine, you must build it as a shared library.
Something like this:
cd src
make yes-mdi
make mode=shlib mpi
To use the serial_driver.py example you will need Python 3 with Numpy
and mpi4py available in your Python. Make sure LAMMPS and Python are
using same the same version of MPI.
-------------------------------------------------
-------------------------------------------------
* Example #1 = run AIMD with 2 instances of LAMMPS as driver and engine
as an engine, LAMMPS is a surrogate for a quantum code
* Example #1 = run ab inito MD (AIMD)
2 instances of LAMMPS operate as a driver and engine
as an engine, LAMMPS is a surrogate for a quantum code
Note that the 2 input scripts in.aimd.alone and in.aimd.driver
have an option for running in NVE vs NPT mode. Comment in/out
the appropriate line to change modes. Nothing needs to be
changed in the 3rd input script in.aimd.engine.
changed in the in.aimd.engine or in.aimd.engine.plugin scripts.
---
@ -83,13 +98,13 @@ Run in plugin mode: 3 procs
-------------------------------------------------
* Example #2 = Python driver runs sequence of unrelated LAMMPS calculations
calcs can be single-point, MD runs, or minimizations
Each calculation can be a single-point evaluation, an MD run, or a minimization.
The sequence_driver.py code allows for optional switches in addition
to -mdi (required) and the -plugin and -plugin_args switches which are
used to link to an engine as a plugin library. The example run
commands below just use the default values of the optional switches.
The switches are also explained the top of the file; the info is
The switches are also explained at the top of the file; the info is
copied here:
# -n 10
@ -163,7 +178,7 @@ The aimd_driver.py code allows for an optional switch in addition to
-mdi (required) and the -plugin and -plugin_args swiches which are
used to link to the 2 engines as a plugin libraries. The example run
commands below use the default values of the optional switch. The
switches are also explained the top of the file; the info is copied
switch is also explained the top of the file; the info is copied
here:
# -nsteps 5

View File

@ -23,12 +23,12 @@ fix 1 all nve
# NPT
#fix 1 all npt temp 1.0 1.0 0.1 iso 1.0 1.0 1.0
fix 2 all mdi/aimd
fix 2 all mdi/aimd plugin
fix_modify 2 energy yes virial yes
thermo_style custom step temp pe etotal press vol
thermo 1
mdi/plugin lammps &
args '-mdi "-role ENGINE -name lammps -method LINK"' &
mdi/plugin lammps mdi "-role ENGINE -name lammps -method LINK" &
infile in.aimd.engine extra "-log log.aimd.engine.plugin" &
command "run 5"

View File

@ -30,7 +30,7 @@ enum{NATIVE,REAL,METAL}; // LAMMPS units which MDI supports
FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR, "Illegal fix mdi/aimd command");
if (narg > 4) error->all(FLERR, "Illegal fix mdi/aimd command");
scalar_flag = 1;
global_freq = 1;
@ -39,6 +39,14 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) :
virial_global_flag = 1;
thermo_energy = thermo_virial = 1;
// check for plugin arg
plugin = 0;
if (narg == 4) {
if (strcmp(arg[3],"plugin") == 0) plugin = 1;
else error->all(FLERR, "Illegal fix mdi/aimd command");
}
// check requirements for LAMMPS to work with MDI as an engine
if (atom->tag_enable == 0)
@ -67,10 +75,12 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) :
unit_conversions();
// connect to MDI engine
// connect to MDI engine, only if engine is stand-alone code
// MDI_Accept_communicator(&mdicomm);
// if (mdicomm <= 0) error->all(FLERR, "Unable to connect to MDI engine");
if (!plugin) {
MDI_Accept_communicator(&mdicomm);
if (mdicomm <= 0) error->all(FLERR, "Unable to connect to MDI engine");
}
nprocs = comm->nprocs;
}
@ -79,10 +89,12 @@ FixMDIAimd::FixMDIAimd(LAMMPS *lmp, int narg, char **arg) :
FixMDIAimd::~FixMDIAimd()
{
// send exit command to engine
// send exit command to engine, only if engine is stand-alone code
//int ierr = MDI_Send_command("EXIT",mdicomm);
//if (ierr) error->all(FLERR,"MDI: EXIT command");
if (!plugin) {
int ierr = MDI_Send_command("EXIT",mdicomm);
if (ierr) error->all(FLERR,"MDI: EXIT command");
}
// clean up

View File

@ -44,6 +44,8 @@ class FixMDIAimd : public Fix {
private:
int nprocs;
int plugin;
int eflag_caller;
double engine_energy;
int lmpunits;
@ -65,7 +67,6 @@ class FixMDIAimd : public Fix {
void reallocate();
void unit_conversions();
};
}

View File

@ -37,27 +37,52 @@ void MDIPlugin::command(int narg, char **arg)
if (narg < 1) error->all(FLERR,"Illegal mdi/plugin command");
char *plugin_name = arg[0];
char *plugin_args = nullptr;
plugin_command = nullptr;
printf("NARG %d\n",narg);
char *mdi_arg = nullptr;
char *infile_arg = nullptr;
char *extra_arg = nullptr;
lammps_command = nullptr;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"args") == 0) {
if (strcmp(arg[iarg],"mdi") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal mdi/plugin command");
plugin_args = arg[iarg+1];
mdi_arg = arg[iarg+1];
iarg += 2;
} else if (strcmp(arg[iarg],"infile") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal mdi/plugin command");
infile_arg = arg[iarg+1];
iarg += 2;
} else if (strcmp(arg[iarg],"extra") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal mdi/plugin command");
extra_arg = arg[iarg+1];
iarg += 2;
} else if (strcmp(arg[iarg],"command") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal mdi/plugin command");
plugin_command = arg[iarg+1];
int n = strlen(arg[iarg+1]) + 1;
lammps_command = new char[n];
strcpy(lammps_command,arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal mdi/plugin command");
}
// error if no command was specified
// error checks
if (!plugin_command) error->all(FLERR,"MDI/plugin must specify command");
if (!mdi_arg || !infile_arg || !lammps_command)
error->all(FLERR,"MDI/plugin must specify mdi, infile, command keywords");
// build full plugin_args string for args to plugin library
int n = strlen(mdi_arg) + strlen(infile_arg) + strlen(extra_arg) + 16;
char *plugin_args = new char[n];
strcat(plugin_args,"-mdi \"");
strcat(plugin_args,mdi_arg);
strcat(plugin_args,"\" -in ");
strcat(plugin_args,infile_arg);
if (extra_arg) {
strcat(plugin_args," ");
strcat(plugin_args,extra_arg);
}
// find FixMDIAimd instance so can reset its mdicomm
@ -72,6 +97,8 @@ void MDIPlugin::command(int narg, char **arg)
printf("ARGS %s\n",plugin_args);
MDI_Launch_plugin(plugin_name,plugin_args,world,plugin_wrapper,(void *)this);
delete [] plugin_args;
}
/* ----------------------------------------------------------------------
@ -81,25 +108,27 @@ void MDIPlugin::command(int narg, char **arg)
---------------------------------------------------------------------- */
int MDIPlugin::plugin_wrapper(void *pmpicomm, MDI_Comm mdicomm,
void *ptr)
void *vptr)
{
printf("INSIDE CALLBACK\n");
MPI_Comm mpicomm = *(MPI_Comm *) pmpicomm;
MDIPlugin *thisptr = (MDIPlugin *) ptr;
LAMMPS *lammps = thisptr->lmp;
MDIPlugin *ptr = (MDIPlugin *) vptr;
LAMMPS *lammps = ptr->lmp;
char *lammps_command = ptr->lammps_command;
// set FixMDIAimd mdicomm to this mdicomm
FixMDIAimd *aimdptr = (FixMDIAimd *) (thisptr->fixptr);
FixMDIAimd *aimdptr = (FixMDIAimd *) (ptr->fixptr);
aimdptr->mdicomm = mdicomm;
// invoke the specified LAMMPS command
// that operation will issue MDI commands to the plugin engine
printf("PRE RUN command\n");
printf("PRE RUN command: %s\n",lammps_command);
lammps->input->one(thisptr->plugin_command);
lammps->input->one(lammps_command);
delete [] lammps_command;
// send MDI exit to plugin, which unloads the plugin

View File

@ -31,7 +31,7 @@ class MDIPlugin : public Command {
void command(int, char **) override;
private:
char *plugin_command;
char *lammps_command;
class Fix *fixptr;
static int plugin_wrapper(void *, MDI_Comm, void *);

View File

@ -172,6 +172,9 @@ void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr)
lammps_mpi_init();
if (ptr) ptr_argument_warning();
printf("LAMMPS instantiate argc %d argv[1] %s argv[2] %s\n",
argc,argv[1],argv[2]);
#ifdef LAMMPS_EXCEPTIONS
try
{
@ -183,7 +186,9 @@ void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr)
if (ptr) *ptr = nullptr;
}
#else
printf("PRE-INSTANTIATE\n");
lmp = new LAMMPS(argc, argv, comm);
printf("POST-INSTANTIATE %p\n",lmp);
if (ptr) *ptr = (void *) lmp;
#endif
return (void *) lmp;