Merge branch 'integration' into small-doc-fixes

This commit is contained in:
Axel Kohlmeyer 2016-08-31 21:42:22 -04:00
commit 2abd5ad28a
8 changed files with 215 additions and 5 deletions

View File

@ -389,6 +389,7 @@ within the LAMMPS code. The options that are currently recogized are:</p>
<li>-DLAMMPS_BIGBIG</li>
<li>-DLAMMPS_SMALLSMALL</li>
<li>-DLAMMPS_LONGLONG_TO_LONG</li>
<li>-DLAMMPS_EXCEPTIONS</li>
<li>-DPACK_ARRAY</li>
<li>-DPACK_POINTER</li>
<li>-DPACK_MEMCPY</li>
@ -457,6 +458,13 @@ be compiled with the same setting, or the link will fail.</p>
MPI version does not recognize &#8220;long long&#8221; data types. In this case a
&#8220;long&#8221; data type is likely already 64-bits, in which case this setting
will convert to that data type.</p>
<p>The -DLAMMPS_EXCEPTIONS setting can be used to activate alternative
versions of error handling inside of LAMMPS. This is useful when
external codes drive LAMMPS as a library. Using this option, LAMMPS
errors do not kill the caller. Instead, the call stack is unwound and
control returns to the caller. The library interface provides the
lammps_has_error() and lammps_get_last_error_message() functions to
detect and find out more about a LAMMPS error.</p>
<p>Using one of the -DPACK_ARRAY, -DPACK_POINTER, and -DPACK_MEMCPY
options can make for faster parallel FFTs (in the PPPM solver) on some
platforms. The -DPACK_ARRAY setting is the default. See the

View File

@ -262,6 +262,7 @@ within the LAMMPS code. The options that are currently recogized are:
-DLAMMPS_BIGBIG
-DLAMMPS_SMALLSMALL
-DLAMMPS_LONGLONG_TO_LONG
-DLAMMPS_EXCEPTIONS
-DPACK_ARRAY
-DPACK_POINTER
-DPACK_MEMCPY :ul
@ -334,6 +335,14 @@ MPI version does not recognize "long long" data types. In this case a
"long" data type is likely already 64-bits, in which case this setting
will convert to that data type.
The -DLAMMPS_EXCEPTIONS setting can be used to activate alternative
versions of error handling inside of LAMMPS. This is useful when
external codes drive LAMMPS as a library. Using this option, LAMMPS
errors do not kill the caller. Instead, the call stack is unwound and
control returns to the caller. The library interface provides the
lammps_has_error() and lammps_get_last_error_message() functions to
detect and find out more about a LAMMPS error.
Using one of the -DPACK_ARRAY, -DPACK_POINTER, and -DPACK_MEMCPY
options can make for faster parallel FFTs (in the PPPM solver) on some
platforms. The -DPACK_ARRAY setting is the default. See the

View File

@ -150,6 +150,11 @@ class lammps(object):
if cmd: cmd = cmd.encode()
self.lib.lammps_command(self.lmp,cmd)
if self.lib.lammps_has_error(self.lmp):
sb = create_string_buffer(100)
self.lib.lammps_get_last_error_message(self.lmp, sb, 100)
raise Exception(sb.value.decode().strip())
def extract_global(self,name,type):
if name: name = name.encode()
if type == 0:
@ -304,6 +309,9 @@ class OutputCapture(object):
def __exit__(self, type, value, tracebac):
os.dup2(self.stdout, self.stdout_fd)
os.close(self.stdout)
os.close(self.stdout_pipe_read)
os.close(self.stdout_pipe_write)
# check if we have more to read from the pipe
def more_data(self, pipe):
@ -345,8 +353,11 @@ class AtomList(object):
def __init__(self, lammps_wrapper_instance):
self.lmp = lammps_wrapper_instance
self.natoms = self.lmp.system.natoms
self.dimensions = self.lmp.system.dimensions
def __getitem__(self, index):
if self.dimensions == 2:
return Atom2D(self.lmp, index + 1)
return Atom(self.lmp, index + 1)
@ -377,6 +388,12 @@ class Atom(object):
self.lmp.eval("y[%d]" % self.index),
self.lmp.eval("z[%d]" % self.index))
@position.setter
def position(self, value):
self.lmp.set("atom", self.index, "x", value[0])
self.lmp.set("atom", self.index, "y", value[1])
self.lmp.set("atom", self.index, "z", value[2])
@property
def velocity(self):
return (self.lmp.eval("vx[%d]" % self.index),
@ -394,6 +411,31 @@ class Atom(object):
return self.lmp.eval("q[%d]" % self.index)
class Atom2D(Atom):
def __init__(self, lammps_wrapper_instance, index):
super(Atom2D, self).__init__(lammps_wrapper_instance, index)
@property
def position(self):
return (self.lmp.eval("x[%d]" % self.index),
self.lmp.eval("y[%d]" % self.index))
@position.setter
def position(self, value):
self.lmp.set("atom", self.index, "x", value[0])
self.lmp.set("atom", self.index, "y", value[1])
@property
def velocity(self):
return (self.lmp.eval("vx[%d]" % self.index),
self.lmp.eval("vy[%d]" % self.index))
@property
def force(self):
return (self.lmp.eval("fx[%d]" % self.index),
self.lmp.eval("fy[%d]" % self.index))
class PyLammps(object):
"""
More Python-like wrapper for LAMMPS (e.g., for iPython)
@ -603,6 +645,10 @@ class PyLammps(object):
with OutputCapture() as capture:
self.lmp.command(' '.join(cmd_args))
output = capture.output
if 'verbose' in kwargs and kwargs['verbose']:
print(output)
lines = output.splitlines()
if len(lines) > 1:
@ -657,3 +703,7 @@ class IPyLammps(PyLammps):
self.write_dump(*cmd_args)
from IPython.core.display import Image
return Image('snapshot.png')
def video(self, filename):
from IPython.display import HTML
return HTML("<video controls><source src=\"" + filename + "\"></video>")

View File

@ -13,6 +13,7 @@
#include <mpi.h>
#include <stdlib.h>
#include <string.h>
#include "error.h"
#include "universe.h"
#include "output.h"
@ -21,7 +22,7 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Error::Error(LAMMPS *lmp) : Pointers(lmp) {}
Error::Error(LAMMPS *lmp) : Pointers(lmp), last_error_message(NULL) {}
/* ----------------------------------------------------------------------
called by all procs in universe
@ -47,8 +48,14 @@ void Error::universe_all(const char *file, int line, const char *str)
}
if (universe->ulogfile) fclose(universe->ulogfile);
#ifdef LAMMPS_EXCEPTIONS
char msg[100];
sprintf(msg, "ERROR: %s (%s:%d)\n", str, file, line);
throw LAMMPSException(msg);
#else
MPI_Finalize();
exit(1);
#endif
}
/* ----------------------------------------------------------------------
@ -61,7 +68,14 @@ void Error::universe_one(const char *file, int line, const char *str)
if (universe->uscreen)
fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
universe->me,str,file,line);
#ifdef LAMMPS_EXCEPTIONS
char msg[100];
sprintf(msg, "ERROR: %s (%s:%d)\n", str, file, line);
throw LAMMPSAbortException(msg, universe->uworld);
#else
MPI_Abort(universe->uworld,1);
#endif
}
/* ----------------------------------------------------------------------
@ -95,6 +109,16 @@ void Error::all(const char *file, int line, const char *str)
if (logfile) fprintf(logfile,"ERROR: %s (%s:%d)\n",str,file,line);
}
#ifdef LAMMPS_EXCEPTIONS
char msg[100];
sprintf(msg, "ERROR: %s (%s:%d)\n", str, file, line);
if (universe->nworlds > 1) {
throw LAMMPSAbortException(msg, universe->uworld);
}
throw LAMMPSException(msg);
#else
if (output) delete output;
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
@ -102,6 +126,7 @@ void Error::all(const char *file, int line, const char *str)
if (universe->nworlds > 1) MPI_Abort(universe->uworld,1);
MPI_Finalize();
exit(1);
#endif
}
/* ----------------------------------------------------------------------
@ -121,7 +146,14 @@ void Error::one(const char *file, int line, const char *str)
if (universe->uscreen)
fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
universe->me,str,file,line);
#ifdef LAMMPS_EXCEPTIONS
char msg[100];
sprintf(msg, "ERROR on proc %d: %s (%s:%d)\n", me, str, file, line);
throw LAMMPSAbortException(msg, world);
#else
MPI_Abort(world,1);
#endif
}
/* ----------------------------------------------------------------------
@ -165,3 +197,31 @@ void Error::done(int status)
MPI_Finalize();
exit(status);
}
/* ----------------------------------------------------------------------
return the last error message reported by LAMMPS (only used if
compiled with -DLAMMPS_EXCEPTIONS)
------------------------------------------------------------------------- */
char * Error::get_last_error() const
{
return last_error_message;
}
/* ----------------------------------------------------------------------
set the last error message (only used if compiled with
-DLAMMPS_EXCEPTIONS)
------------------------------------------------------------------------- */
void Error::set_last_error(const char * msg)
{
delete [] last_error_message;
if(msg) {
last_error_message = new char[strlen(msg)+1];
strcpy(last_error_message, msg);
} else {
last_error_message = NULL;
}
}

View File

@ -15,10 +15,41 @@
#define LMP_ERROR_H
#include "pointers.h"
#include <string>
#include <exception>
namespace LAMMPS_NS {
class LAMMPSException : public std::exception
{
public:
std::string message;
LAMMPSException(std::string msg) : message(msg) {
}
~LAMMPSException() throw() {
}
virtual const char * what() const throw() {
return message.c_str();
}
};
class LAMMPSAbortException : public LAMMPSException {
public:
MPI_Comm universe;
LAMMPSAbortException(std::string msg, MPI_Comm universe) :
LAMMPSException(msg),
universe(universe)
{
}
};
class Error : protected Pointers {
char * last_error_message;
public:
Error(class LAMMPS *);
@ -31,6 +62,9 @@ class Error : protected Pointers {
void warning(const char *, int, const char *, int = 1);
void message(const char *, int, const char *, int = 1);
void done(int = 0); // 1 would be fully backwards compatible
char * get_last_error() const;
void set_last_error(const char * msg);
};
}

View File

@ -108,8 +108,15 @@ void lammps_file(void *ptr, char *str)
char *lammps_command(void *ptr, char *str)
{
LAMMPS *lmp = (LAMMPS *) ptr;
return lmp->input->one(str);
LAMMPS * lmp = (LAMMPS *) ptr;
Error * error = lmp->error;
try {
return lmp->input->one(str);
} catch(LAMMPSException & e) {
error->set_last_error(e.message.c_str());
return NULL;
}
}
/* ----------------------------------------------------------------------
@ -593,3 +600,29 @@ void lammps_scatter_atoms(void *ptr, char *name,
}
}
}
/* ----------------------------------------------------------------------
Check if a new error message
------------------------------------------------------------------------- */
int lammps_has_error(void *ptr) {
LAMMPS * lmp = (LAMMPS *) ptr;
Error * error = lmp->error;
return error->get_last_error() ? 1 : 0;
}
/* ----------------------------------------------------------------------
Copy the last error message of LAMMPS into a character buffer
------------------------------------------------------------------------- */
int lammps_get_last_error_message(void *ptr, char * buffer, int buffer_size) {
LAMMPS * lmp = (LAMMPS *) ptr;
Error * error = lmp->error;
if(error->get_last_error()) {
strncpy(buffer, error->get_last_error(), buffer_size-1);
error->set_last_error(NULL);
return 1;
}
return 0;
}

View File

@ -45,6 +45,9 @@ int lammps_get_natoms(void *);
void lammps_gather_atoms(void *, char *, int, int, void *);
void lammps_scatter_atoms(void *, char *, int, int, void *);
int lammps_has_error(void *);
int lammps_get_last_error_message(void *, char *, int);
#ifdef __cplusplus
}
#endif

View File

@ -14,7 +14,9 @@
#include <mpi.h>
#include "lammps.h"
#include "input.h"
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
using namespace LAMMPS_NS;
@ -26,11 +28,22 @@ int main(int argc, char **argv)
{
MPI_Init(&argc,&argv);
#ifdef LAMMPS_EXCEPTIONS
try {
LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD);
lammps->input->file();
delete lammps;
} catch(LAMMPSAbortException & ae) {
MPI_Abort(ae.universe, 1);
} catch(LAMMPSException & e) {
MPI_Finalize();
exit(1);
}
#else
LAMMPS *lammps = new LAMMPS(argc,argv,MPI_COMM_WORLD);
lammps->input->file();
delete lammps;
#endif
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}