more debugging for plugin mode
This commit is contained in:
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 *);
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user