git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@14328 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2015-12-09 21:10:06 +00:00
parent 6eed163c7b
commit 900a3aaf9d
2 changed files with 93 additions and 22 deletions

View File

@ -39,7 +39,8 @@ scripts in the examples sub-directory:
trivial.py read/run a LAMMPS input script thru Python
demo.py invoke various LAMMPS library interface routines
simple.py mimic operation of examples/COUPLE/simple/simple.cpp
simple.py parallel example, mimicing examples/COUPLE/simple/simple.cpp
split.py parallel example
mc.py Monte Carlo energy relaxation wrapper on LAMMPS
gui.py GUI go/stop/temperature-slider to control LAMMPS
plot.py real-time temeperature plot with GnuPlot via Pizza.py
@ -77,30 +78,53 @@ The latter link is to the open-source version.
-------------------------------------------------------------------
Each example script has more documentation in the file that explains
how to use it and what it is doing.
You can run a particular script in either of the following ways:
% trivial.py in.trivial
% python -i trivial.py in.trivial
The former assumes that you have changed the first line of the script
to point to the Python installed on your box.
to point to the Python installed on your box and made the script
exectable (e.g. chmod +x trivial.py).
Run the Python scripts with the following LAMMPS input scripts and
arguments:
The example scripts take the following arguments. The in.* args are
LAMPS input scripts.
trivial.py in.trivial
demo.py
simple.py in.simple
simple.py in.simple # can run in parallel (see below)
split.py in.simple # can run in parallel (see below)
gui.py in.gui 100
plot.py in.plot 10 1000 thermo_temp
viz_tool.py in.viz 100 5000
vizplotgui_tool.py in.viz 100 thermo_temp
You can un-comment the Pypar calls if you want to run these in
parallel. Then, for example, you can type:
To run LAMMPS in parallel from Python, so something like this:
% mpirun -np 4 simple.py in.simple
% mpirun -np 4 python split.py in.simple
If you run simple.py as-is, this will invoke P instances of a
one-processor run, where both Python and LAMMPS will run on single
processors. Each running job will read the same input file, and write
to same log.lammps file, which isn't too useful.
However, if you have either the Pypar or mpi4py packages installed in
your Python, and uncomment the Pypar or mpi4py code in simple.py, then
the above commands will invoke 1 instance of a P-processor run. Both
Python and LAMMPS will run on P processors. The job will read the
input file and write a single log.lammps file.
The split.py script can also be run in parallel. It uses mpi4py
version 2.0.0 (or later), which makes it possible to pass a
communicator when creating the LAMMPS object and thus run multiple
instances of LAMMPS at the same time, each on a different subset of
MPI ranks. Or run LAMMPS on one subset and some other program on the
rest of the MPI ranks, concurrently. See comments in the split.py
script for more details.
% mpirun -np 4 trivial.py in.trivial
% mpirun -np 4 python trivial.py in.trivial
Each script has more documentation in the file that explains how to
use it and what it is doing.

View File

@ -19,9 +19,24 @@ from os.path import dirname,abspath,join
from inspect import getsourcefile
class lammps:
def __init__(self,name="",cmdargs=None,ptr=None):
# detect if Python is using version of mpi4py that can pass a communicator
has_mpi4py_v2 = False
try:
from mpi4py import MPI
from mpi4py import __version__ as mpi4py_version
if mpi4py_version.split('.')[0] == '2':
has_mpi4py_v2 = True
except:
pass
# create instance of LAMMPS
def __init__(self,name="",cmdargs=None,ptr=None,comm=None):
# determine module location
modpath = dirname(abspath(getsourcefile(lambda:0)))
# load liblammps.so by default
@ -37,6 +52,7 @@ class lammps:
# if no ptr provided, create an instance of LAMMPS
# don't know how to pass an MPI communicator from PyPar
# but we can pass an MPI communicator from mpi4py v2.0.0 and later
# no_mpi call lets LAMMPS use MPI_COMM_WORLD
# cargs = array of C strings from args
# if ptr, then are embedding Python in LAMMPS input script
@ -44,18 +60,49 @@ class lammps:
# just convert it to ctypes ptr and store in self.lmp
if not ptr:
self.opened = 1
if cmdargs:
cmdargs.insert(0,"lammps.py")
narg = len(cmdargs)
cargs = (c_char_p*narg)(*cmdargs)
# with mpi4py v2, can pass MPI communicator to LAMMPS
# need to adjust for type of MPI communicator object
# allow for int (like MPICH) or void* (like OpenMPI)
if lammps.has_mpi4py_v2 and comm != None:
if lammps.MPI._sizeof(lammps.MPI.Comm) == sizeof(c_int):
MPI_Comm = c_int
else:
MPI_Comm = c_void_p
narg = 0
cargs = 0
if cmdargs:
cmdargs.insert(0,"lammps.py")
narg = len(cmdargs)
cargs = (c_char_p*narg)(*cmdargs)
self.lib.lammps_open.argtypes = [c_int, c_char_p*narg, \
MPI_Comm, c_void_p()]
else:
self.lib.lammps_open.argtypes = [c_int, c_int, \
MPI_Comm, c_void_p()]
self.lib.lammps_open.restype = None
self.opened = 1
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(narg,cargs,byref(self.lmp))
comm_ptr = lammps.MPI._addressof(comm)
comm_val = MPI_Comm.from_address(comm_ptr)
self.lib.lammps_open(narg,cargs,comm_val,byref(self.lmp))
else:
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(0,None,byref(self.lmp))
# could use just this if LAMMPS lib interface supported it
# self.lmp = self.lib.lammps_open_no_mpi(0,None)
self.opened = 1
if cmdargs:
cmdargs.insert(0,"lammps.py")
narg = len(cmdargs)
cargs = (c_char_p*narg)(*cmdargs)
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(narg,cargs,byref(self.lmp))
else:
self.lmp = c_void_p()
self.lib.lammps_open_no_mpi(0,None,byref(self.lmp))
# could use just this if LAMMPS lib interface supported it
# self.lmp = self.lib.lammps_open_no_mpi(0,None)
else:
self.opened = 0
# magic to convert ptr to ctypes ptr