Merge pull request #3736 from lammps/always-exceptions

Always throw exceptions for errors
This commit is contained in:
Axel Kohlmeyer
2023-08-03 21:00:19 -04:00
committed by GitHub
45 changed files with 101 additions and 316 deletions

View File

@ -384,11 +384,6 @@ if(NOT ${LAMMPS_MEMALIGN} STREQUAL "0")
target_compile_definitions(lammps PRIVATE -DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN}) target_compile_definitions(lammps PRIVATE -DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN})
endif() endif()
option(LAMMPS_EXCEPTIONS "enable the use of C++ exceptions for error messages (useful for library interface)" ${ENABLE_TESTING})
if(LAMMPS_EXCEPTIONS)
target_compile_definitions(lammps PUBLIC -DLAMMPS_EXCEPTIONS)
endif()
# "hard" dependencies between packages resulting # "hard" dependencies between packages resulting
# in an error instead of skipping over files # in an error instead of skipping over files
pkg_depends(ML-IAP ML-SNAP) pkg_depends(ML-IAP ML-SNAP)

View File

@ -28,9 +28,7 @@ if(MSVC)
add_compile_options(/Zc:__cplusplus) add_compile_options(/Zc:__cplusplus)
add_compile_options(/wd4244) add_compile_options(/wd4244)
add_compile_options(/wd4267) add_compile_options(/wd4267)
if(LAMMPS_EXCEPTIONS) add_compile_options(/EHsc)
add_compile_options(/EHsc)
endif()
endif() endif()
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif() endif()

View File

@ -44,9 +44,6 @@ if(BUILD_LAMMPS_SHELL)
endif() endif()
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(READLINE IMPORTED_TARGET REQUIRED readline) pkg_check_modules(READLINE IMPORTED_TARGET REQUIRED readline)
if(NOT LAMMPS_EXCEPTIONS)
message(WARNING "The LAMMPS shell needs LAMMPS_EXCEPTIONS enabled for full functionality")
endif()
# include resource compiler to embed icons into the executable on Windows # include resource compiler to embed icons into the executable on Windows
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") if(CMAKE_SYSTEM_NAME STREQUAL "Windows")

View File

@ -459,27 +459,13 @@ those systems:
.. _exceptions: .. _exceptions:
Exception handling when using LAMMPS as a library Exception handling when using LAMMPS as a library
------------------------------------------------------------------ -------------------------------------------------
This setting is useful when external codes drive LAMMPS as a library. LAMMPS errors do not kill the calling code, but throw an exception. In
With this option enabled, LAMMPS errors do not kill the calling code. the C-library interface, the call stack is unwound and control returns
Instead, the call stack is unwound and control returns to the caller, to the caller, e.g. to Python or a code that is coupled to LAMMPS and
e.g. to Python. Of course, the calling code has to be set up to the error status can be queried. When using C++ directly, the calling
*catch* exceptions thrown from within LAMMPS. code has to be set up to *catch* exceptions thrown from within LAMMPS.
.. tabs::
.. tab:: CMake build
.. code-block:: bash
-D LAMMPS_EXCEPTIONS=value # yes or no (default)
.. tab:: Traditional make
.. code-block:: make
LMP_INC = -DLAMMPS_EXCEPTIONS <other LMP_INC settings>
.. note:: .. note::

View File

@ -2278,19 +2278,13 @@ Procedures Bound to the :f:type:`lammps` Derived Type
.. versionadded:: 3Nov2022 .. versionadded:: 3Nov2022
In case of an error, LAMMPS will either abort or throw a C++ exception. When using the library interface, the library interface functions
The latter has to be :ref:`enabled at compile time <exceptions>`. will "catch" exceptions, and then the error status can be checked by
This function checks if exceptions were enabled. calling :f:func:`has_error`. The most recent error message can be
retrieved via :f:func:`get_last_error_message`. This allows to
When using the library interface with C++ exceptions enabled, the library restart a calculation or delete and recreate the LAMMPS instance when
interface functions will "catch" them, and the error status can then be a C++ exception occurs. One application of using exceptions this way
checked by calling :f:func:`has_error`. The most recent error message can be is the :ref:`lammps_shell`.
retrieved via :f:func:`get_last_error_message`.
This can allow one to restart a calculation or delete and recreate
the LAMMPS instance when a C++ exception occurs. One application
of using exceptions this way is the :ref:`lammps_shell`. If C++
exceptions are disabled and an error happens during a call to
LAMMPS or the Fortran API, the application will terminate.
:to: :cpp:func:`lammps_config_has_exceptions` :to: :cpp:func:`lammps_config_has_exceptions`
:r has_exceptions: :r has_exceptions:

View File

@ -338,8 +338,6 @@ Some common LAMMPS specific variables
- common compiler flags, for optimization or instrumentation (default:) - common compiler flags, for optimization or instrumentation (default:)
* - ``LAMMPS_MACHINE`` * - ``LAMMPS_MACHINE``
- when set to ``name`` the LAMMPS executable and library will be called ``lmp_name`` and ``liblammps_name.a`` - when set to ``name`` the LAMMPS executable and library will be called ``lmp_name`` and ``liblammps_name.a``
* - ``LAMMPS_EXCEPTIONS``
- when set to ``on`` errors will throw a C++ exception instead of aborting (default: ``off``)
* - ``FFT`` * - ``FFT``
- select which FFT library to use: ``FFTW3``, ``MKL``, ``KISS`` (default, unless FFTW3 is found) - select which FFT library to use: ``FFTW3``, ``MKL``, ``KISS`` (default, unless FFTW3 is found)
* - ``FFT_SINGLE`` * - ``FFT_SINGLE``
@ -412,9 +410,9 @@ interface (``ccmake`` or ``cmake-gui``).
Using a preset to select a compiler package (``clang.cmake``, Using a preset to select a compiler package (``clang.cmake``,
``gcc.cmake``, ``intel.cmake``, ``oneapi.cmake``, or ``pgi.cmake``) ``gcc.cmake``, ``intel.cmake``, ``oneapi.cmake``, or ``pgi.cmake``)
are an exception to the mechanism of updating the configuration incrementally, are an exception to the mechanism of updating the configuration
as they will trigger a reset of cached internal CMake settings and thus incrementally, as they will trigger a reset of cached internal CMake
reset settings to their default values. settings and thus reset settings to their default values.
Compilation and build targets Compilation and build targets
----------------------------- -----------------------------

View File

@ -53,10 +53,10 @@ System-wide Installation
Step 1: Building LAMMPS as a shared library Step 1: Building LAMMPS as a shared library
""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""
To use LAMMPS inside of Python it has to be compiled as shared library. This To use LAMMPS inside of Python it has to be compiled as shared
library is then loaded by the Python interface. In this example we enable the library. This library is then loaded by the Python interface. In this
MOLECULE package and compile LAMMPS with C++ exceptions, PNG, JPEG and FFMPEG example we enable the MOLECULE package and compile LAMMPS with PNG, JPEG
output support enabled. and FFMPEG output support enabled.
Step 1a: For the CMake based build system, the steps are: Step 1a: For the CMake based build system, the steps are:
@ -66,7 +66,7 @@ Step 1a: For the CMake based build system, the steps are:
cd $LAMMPS_DIR/build-shared cd $LAMMPS_DIR/build-shared
# MPI, PNG, Jpeg, FFMPEG are auto-detected # MPI, PNG, Jpeg, FFMPEG are auto-detected
cmake ../cmake -DPKG_MOLECULE=yes -DLAMMPS_EXCEPTIONS=yes -DBUILD_LIB=yes -DBUILD_SHARED_LIBS=yes cmake ../cmake -DPKG_MOLECULE=yes -DBUILD_LIB=yes -DBUILD_SHARED_LIBS=yes
make make
Step 1b: For the legacy, make based build system, the steps are: Step 1b: For the legacy, make based build system, the steps are:
@ -79,7 +79,7 @@ Step 1b: For the legacy, make based build system, the steps are:
make yes-MOLECULE make yes-MOLECULE
# compile shared library using Makefile # compile shared library using Makefile
make mpi mode=shlib LMP_INC="-DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG -DLAMMPS_EXCEPTIONS" JPG_LIB="-lpng -ljpeg" make mpi mode=shlib LMP_INC="-DLAMMPS_PNG -DLAMMPS_JPEG -DLAMMPS_FFMPEG" JPG_LIB="-lpng -ljpeg"
Step 2: Installing the LAMMPS Python package Step 2: Installing the LAMMPS Python package
"""""""""""""""""""""""""""""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""
@ -356,18 +356,16 @@ Together with matplotlib plotting data out of LAMMPS becomes simple:
Error handling with PyLammps Error handling with PyLammps
---------------------------- ----------------------------
Compiling the shared library with C++ exception support provides a better error Using C++ exceptions in LAMMPS for errors allows capturing them on the
handling experience. Without exceptions the LAMMPS code will terminate the C++ side and rethrowing them on the Python side. This way you can handle
current Python process with an error message. C++ exceptions allow capturing LAMMPS errors through the Python exception handling mechanism.
them on the C++ side and rethrowing them on the Python side. This way you
can handle LAMMPS errors through the Python exception handling mechanism.
.. warning:: .. warning::
Capturing a LAMMPS exception in Python can still mean that the Capturing a LAMMPS exception in Python can still mean that the
current LAMMPS process is in an illegal state and must be terminated. It is current LAMMPS process is in an illegal state and must be
advised to save your data and terminate the Python instance as quickly as terminated. It is advised to save your data and terminate the Python
possible. instance as quickly as possible.
Using PyLammps in IPython notebooks and Jupyter Using PyLammps in IPython notebooks and Jupyter
----------------------------------------------- -----------------------------------------------

View File

@ -1,11 +1,11 @@
Handling LAMMPS errors Handling LAMMPS errors
******************************* **********************
Compiling the shared library with :ref:`C++ exception support <exceptions>` provides a better error The shared library is compiled with :ref:`C++ exception support
handling experience. Without exceptions the LAMMPS code will terminate the <exceptions>` to provide a better error handling experience. C++
current Python process with an error message. C++ exceptions allow capturing exceptions allow capturing errors on the C++ side and rethrowing them on
them on the C++ side and rethrowing them on the Python side. This way the Python side. This way LAMMPS errors can be handled through the
LAMMPS errors can be handled through the Python exception handling mechanism. Python exception handling mechanism.
.. code-block:: python .. code-block:: python
@ -31,6 +31,6 @@ LAMMPS errors can be handled through the Python exception handling mechanism.
.. warning:: .. warning::
Capturing a LAMMPS exception in Python can still mean that the Capturing a LAMMPS exception in Python can still mean that the
current LAMMPS process is in an illegal state and must be terminated. It is current LAMMPS process is in an illegal state and must be
advised to save your data and terminate the Python instance as quickly as terminated. It is advised to save your data and terminate the Python
possible. instance as quickly as possible when running in parallel with MPI.

View File

@ -23,9 +23,7 @@ endif()
# and prints lots of pointless warnings about "unsafe" functions # and prints lots of pointless warnings about "unsafe" functions
if(MSVC) if(MSVC)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if(LAMMPS_EXCEPTIONS) add_compile_options(/EHsc)
add_compile_options(/EHsc)
endif()
endif() endif()
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif() endif()

View File

@ -18,9 +18,7 @@ endif()
# and prints lots of pointless warnings about "unsafe" functions # and prints lots of pointless warnings about "unsafe" functions
if(MSVC) if(MSVC)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
if(LAMMPS_EXCEPTIONS) add_compile_options(/EHsc)
add_compile_options(/EHsc)
endif()
endif() endif()
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif() endif()

View File

@ -36,9 +36,7 @@ else()
add_compile_options(/Zc:__cplusplus) add_compile_options(/Zc:__cplusplus)
add_compile_options(/wd4244) add_compile_options(/wd4244)
add_compile_options(/wd4267) add_compile_options(/wd4267)
if(LAMMPS_EXCEPTIONS) add_compile_options(/EHsc)
add_compile_options(/EHsc)
endif()
endif() endif()
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif() endif()

View File

@ -18,10 +18,7 @@
#include "input.h" #include "input.h"
#include "output.h" #include "output.h"
#include "universe.h" #include "universe.h"
#if defined(LAMMPS_EXCEPTIONS)
#include "update.h" #include "update.h"
#endif
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -40,10 +37,8 @@ static std::string truncpath(const std::string &path)
Error::Error(LAMMPS *lmp) Error::Error(LAMMPS *lmp)
: Pointers(lmp), numwarn(0), maxwarn(100), allwarn(0) : Pointers(lmp), numwarn(0), maxwarn(100), allwarn(0)
{ {
#ifdef LAMMPS_EXCEPTIONS
last_error_message.clear(); last_error_message.clear();
last_error_type = ERROR_NONE; last_error_type = ERROR_NONE;
#endif
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -73,19 +68,11 @@ void Error::universe_all(const std::string &file, int line, const std::string &s
} }
if (universe->ulogfile) fclose(universe->ulogfile); if (universe->ulogfile) fclose(universe->ulogfile);
#ifdef LAMMPS_EXCEPTIONS
// allow commands if an exception was caught in a run // allow commands if an exception was caught in a run
// update may be a null pointer when catching command line errors // update may be a null pointer when catching command line errors
if (update) update->whichflag = 0; if (update) update->whichflag = 0;
throw LAMMPSException(mesg); throw LAMMPSException(mesg);
#else
KokkosLMP::finalize();
MPI_Finalize();
exit(1);
#endif
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -99,19 +86,11 @@ void Error::universe_one(const std::string &file, int line, const std::string &s
universe->me,str,truncpath(file),line); universe->me,str,truncpath(file),line);
if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen); if (universe->uscreen) fputs(mesg.c_str(),universe->uscreen);
#ifdef LAMMPS_EXCEPTIONS
// allow commands if an exception was caught in a run // allow commands if an exception was caught in a run
// update may be a null pointer when catching command line errors // update may be a null pointer when catching command line errors
if (update) update->whichflag = 0; if (update) update->whichflag = 0;
throw LAMMPSAbortException(mesg, universe->uworld); throw LAMMPSAbortException(mesg, universe->uworld);
#else
KokkosLMP::finalize();
MPI_Abort(universe->uworld,1);
exit(1); // to trick "smart" compilers into believing this does not return
#endif
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -155,31 +134,17 @@ void Error::all(const std::string &file, int line, const std::string &str)
utils::logmesg(lmp,mesg); utils::logmesg(lmp,mesg);
} }
#ifdef LAMMPS_EXCEPTIONS
// allow commands if an exception was caught in a run // allow commands if an exception was caught in a run
// update may be a null pointer when catching command line errors // update may be a null pointer when catching command line errors
if (update) update->whichflag = 0; if (update) update->whichflag = 0;
std::string msg = fmt::format("ERROR: {} ({}:{})\n", std::string msg = fmt::format("ERROR: {} ({}:{})\n", str, truncpath(file), line);
str, truncpath(file), line);
if (universe->nworlds > 1) { if (universe->nworlds > 1)
throw LAMMPSAbortException(msg, universe->uworld); throw LAMMPSAbortException(msg, universe->uworld);
} else
throw LAMMPSException(msg);
throw LAMMPSException(msg);
#else
if (output) delete output;
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
KokkosLMP::finalize();
if (universe->nworlds > 1) MPI_Abort(universe->uworld,1);
MPI_Finalize();
exit(1);
#endif
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -204,20 +169,11 @@ void Error::one(const std::string &file, int line, const std::string &str)
if (universe->uscreen) if (universe->uscreen)
fputs(mesg.c_str(),universe->uscreen); fputs(mesg.c_str(),universe->uscreen);
#ifdef LAMMPS_EXCEPTIONS
// allow commands if an exception was caught in a run // allow commands if an exception was caught in a run
// update may be a null pointer when catching command line errors // update may be a null pointer when catching command line errors
if (update) update->whichflag = 0; if (update) update->whichflag = 0;
throw LAMMPSAbortException(mesg, world); throw LAMMPSAbortException(mesg, world);
#else
utils::flush_buffers(lmp);
KokkosLMP::finalize();
MPI_Abort(world,1);
exit(1); // to trick "smart" compilers into believing this does not return
#endif
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -322,10 +278,8 @@ void Error::done(int status)
exit(status); exit(status);
} }
#ifdef LAMMPS_EXCEPTIONS
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
return the last error message reported by LAMMPS (only used if return the last error message reported by LAMMPS
compiled with -DLAMMPS_EXCEPTIONS)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
std::string Error::get_last_error() const std::string Error::get_last_error() const
@ -334,8 +288,7 @@ std::string Error::get_last_error() const
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
return the type of the last error reported by LAMMPS (only used if return the type of the last error reported by LAMMPS
compiled with -DLAMMPS_EXCEPTIONS)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
ErrorType Error::get_last_error_type() const ErrorType Error::get_last_error_type() const
@ -345,12 +298,10 @@ ErrorType Error::get_last_error_type() const
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
set the last error message and error type set the last error message and error type
(only used if compiled with -DLAMMPS_EXCEPTIONS)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void Error::set_last_error(const std::string &msg, ErrorType type) void Error::set_last_error(const char *msg, ErrorType type)
{ {
last_error_message = msg; last_error_message = msg;
last_error_type = type; last_error_type = type;
} }
#endif

View File

@ -15,10 +15,7 @@
#define LMP_ERROR_H #define LMP_ERROR_H
#include "pointers.h" #include "pointers.h"
#ifdef LAMMPS_EXCEPTIONS
#include "exceptions.h" #include "exceptions.h"
#endif
namespace LAMMPS_NS { namespace LAMMPS_NS {
@ -65,17 +62,14 @@ class Error : protected Pointers {
void set_maxwarn(int val) { maxwarn = val; } void set_maxwarn(int val) { maxwarn = val; }
void set_allwarn(int val) { allwarn = val; } void set_allwarn(int val) { allwarn = val; }
#ifdef LAMMPS_EXCEPTIONS
std::string get_last_error() const; std::string get_last_error() const;
ErrorType get_last_error_type() const; ErrorType get_last_error_type() const;
void set_last_error(const std::string &msg, ErrorType type = ERROR_NORMAL); void set_last_error(const char *msg, ErrorType type = ERROR_NORMAL);
private: private:
std::string last_error_message; std::string last_error_message;
ErrorType last_error_type; ErrorType last_error_type;
#endif
private:
int numwarn, maxwarn, allwarn; int numwarn, maxwarn, allwarn;
// internal versions that accept explicit fmtlib arguments // internal versions that accept explicit fmtlib arguments
[[noreturn]] void _all(const std::string &, int, fmt::string_view, fmt::format_args args); [[noreturn]] void _all(const std::string &, int, fmt::string_view, fmt::format_args args);

View File

@ -22,21 +22,23 @@ namespace LAMMPS_NS {
class LAMMPSException : public std::exception { class LAMMPSException : public std::exception {
public: public:
std::string message;
LAMMPSException(const std::string &msg) : message(msg) {} LAMMPSException(const std::string &msg) : message(msg) {}
const char *what() const noexcept override { return message.c_str(); } const char *what() const noexcept override { return message.c_str(); }
protected:
std::string message;
}; };
class LAMMPSAbortException : public LAMMPSException { class LAMMPSAbortException : public LAMMPSException {
public: public:
MPI_Comm universe;
LAMMPSAbortException(const std::string &msg, MPI_Comm _universe) : LAMMPSAbortException(const std::string &msg, MPI_Comm _universe) :
LAMMPSException(msg), universe(_universe) LAMMPSException(msg), universe(_universe)
{ {
} }
MPI_Comm get_universe() const { return universe; }
protected:
MPI_Comm universe;
}; };
enum ErrorType { ERROR_NONE = 0, ERROR_NORMAL = 1, ERROR_ABORT = 2 }; enum ErrorType { ERROR_NONE = 0, ERROR_NORMAL = 1, ERROR_ABORT = 2 };

View File

@ -298,7 +298,6 @@ void Info::command(int narg, char **arg)
if (has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",out); if (has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",out);
if (has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",out); if (has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",out);
if (has_fft_single_support()) fputs("-DFFT_SINGLE\n",out); if (has_fft_single_support()) fputs("-DFFT_SINGLE\n",out);
if (has_exceptions()) fputs("-DLAMMPS_EXCEPTIONS\n",out);
#if defined(LAMMPS_BIGBIG) #if defined(LAMMPS_BIGBIG)
fputs("-DLAMMPS_BIGBIG\n",out); fputs("-DLAMMPS_BIGBIG\n",out);
@ -1096,11 +1095,7 @@ bool Info::has_fft_single_support() {
} }
bool Info::has_exceptions() { bool Info::has_exceptions() {
#ifdef LAMMPS_EXCEPTIONS
return true; return true;
#else
return false;
#endif
} }
bool Info::has_package(const std::string &package_name) { bool Info::has_package(const std::string &package_name) {

View File

@ -1437,7 +1437,6 @@ void LAMMPS::print_config(FILE *fp)
if (Info::has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",fp); if (Info::has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",fp);
if (Info::has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",fp); if (Info::has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",fp);
if (Info::has_fft_single_support()) fputs("-DFFT_SINGLE\n",fp); if (Info::has_fft_single_support()) fputs("-DFFT_SINGLE\n",fp);
if (Info::has_exceptions()) fputs("-DLAMMPS_EXCEPTIONS\n",fp);
#if defined(LAMMPS_BIGBIG) #if defined(LAMMPS_BIGBIG)
fputs("-DLAMMPS_BIGBIG\n",fp); fputs("-DLAMMPS_BIGBIG\n",fp);
#elif defined(LAMMPS_SMALLBIG) #elif defined(LAMMPS_SMALLBIG)

View File

@ -27,6 +27,7 @@
#include "domain.h" #include "domain.h"
#include "dump.h" #include "dump.h"
#include "error.h" #include "error.h"
#include "exceptions.h"
#include "fix.h" #include "fix.h"
#include "fix_external.h" #include "fix_external.h"
#include "force.h" #include "force.h"
@ -53,10 +54,6 @@
#include <cstring> #include <cstring>
#if defined(LAMMPS_EXCEPTIONS)
#include "exceptions.h"
#endif
#if defined(LMP_PYTHON) #if defined(LMP_PYTHON)
#include <Python.h> #include <Python.h>
#endif #endif
@ -96,7 +93,6 @@ static void ptr_argument_warning()
END_CAPTURE END_CAPTURE
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#ifdef LAMMPS_EXCEPTIONS
#define BEGIN_CAPTURE \ #define BEGIN_CAPTURE \
Error *error = lmp->error; \ Error *error = lmp->error; \
try try
@ -104,20 +100,16 @@ static void ptr_argument_warning()
#define END_CAPTURE \ #define END_CAPTURE \
catch(LAMMPSAbortException &ae) { \ catch(LAMMPSAbortException &ae) { \
int nprocs = 0; \ int nprocs = 0; \
MPI_Comm_size(ae.universe, &nprocs ); \ MPI_Comm_size(ae.get_universe(), &nprocs ); \
\ \
if (nprocs > 1) { \ if (nprocs > 1) { \
error->set_last_error(ae.message, ERROR_ABORT); \ error->set_last_error(ae.what(), ERROR_ABORT); \
} else { \ } else { \
error->set_last_error(ae.message, ERROR_NORMAL); \ error->set_last_error(ae.what(), ERROR_NORMAL); \
} \ } \
} catch(LAMMPSException &e) { \ } catch(LAMMPSException &e) { \
error->set_last_error(e.message, ERROR_NORMAL); \ error->set_last_error(e.what(), ERROR_NORMAL); \
} }
#else
#define BEGIN_CAPTURE
#define END_CAPTURE
#endif
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Library functions to create/destroy an instance of LAMMPS // Library functions to create/destroy an instance of LAMMPS
@ -179,23 +171,20 @@ void *lammps_open(int argc, char **argv, MPI_Comm comm, void **ptr)
lammps_mpi_init(); lammps_mpi_init();
if (ptr) ptr_argument_warning(); if (ptr) ptr_argument_warning();
#ifdef LAMMPS_EXCEPTIONS try {
try
{
lammps_last_global_errormessage.clear(); lammps_last_global_errormessage.clear();
lmp = new LAMMPS(argc, argv, comm); lmp = new LAMMPS(argc, argv, comm);
if (ptr) *ptr = (void *) lmp; if (ptr) *ptr = (void *) lmp;
} } catch (fmt::format_error &fe) {
catch(LAMMPSException &e) { lammps_last_global_errormessage = fe.what();
lammps_last_global_errormessage = e.message; fprintf(stderr, "fmt::format_error: %s\n", fe.what());
if (ptr) *ptr = nullptr;
} catch(LAMMPSException &e) {
lammps_last_global_errormessage = e.what();
fmt::print(stderr, "LAMMPS Exception: {}", e.message); fmt::print(stderr, "LAMMPS Exception: {}", e.what());
if (ptr) *ptr = nullptr; if (ptr) *ptr = nullptr;
} }
#else
lmp = new LAMMPS(argc, argv, comm);
if (ptr) *ptr = (void *) lmp;
#endif
return (void *) lmp; return (void *) lmp;
} }
@ -490,7 +479,6 @@ void lammps_error(void *handle, int error_type, const char *error_text)
} }
END_CAPTURE END_CAPTURE
#if defined(LAMMPS_EXCEPTIONS)
// with enabled exceptions the above code will simply throw an // with enabled exceptions the above code will simply throw an
// exception and record the error message. So we have to explicitly // exception and record the error message. So we have to explicitly
// stop here like we do in main.cpp // stop here like we do in main.cpp
@ -506,7 +494,6 @@ void lammps_error(void *handle, int error_type, const char *error_text)
exit(1); exit(1);
} }
} }
#endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -2345,9 +2332,7 @@ void *lammps_extract_variable(void *handle, const char *name, const char *group)
} }
} }
END_CAPTURE END_CAPTURE
#if defined(LAMMPS_EXCEPTIONS)
return nullptr; return nullptr;
#endif
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -5483,6 +5468,13 @@ int lammps_config_has_ffmpeg_support() {
/** Check whether LAMMPS errors will throw C++ exceptions. /** Check whether LAMMPS errors will throw C++ exceptions.
* *
\verbatim embed:rst \verbatim embed:rst
.. deprecated:: TBD
LAMMPS has now exceptions always enabled, so this function
will now always return 1 and can be removed from applications
using the library interface.
In case of an error, LAMMPS will either abort or throw a C++ exception. In case of an error, LAMMPS will either abort or throw a C++ exception.
The latter has to be :ref:`enabled at compile time <exceptions>`. The latter has to be :ref:`enabled at compile time <exceptions>`.
This function checks if exceptions were enabled. This function checks if exceptions were enabled.
@ -6516,8 +6508,8 @@ has thrown a :ref:`C++ exception <exceptions>`.
* \param handle pointer to a previously created LAMMPS instance cast to ``void *`` or NULL * \param handle pointer to a previously created LAMMPS instance cast to ``void *`` or NULL
* \return 0 on no error, 1 on error. * \return 0 on no error, 1 on error.
*/ */
int lammps_has_error(void *handle) { int lammps_has_error(void *handle)
#ifdef LAMMPS_EXCEPTIONS {
if (handle) { if (handle) {
LAMMPS *lmp = (LAMMPS *) handle; LAMMPS *lmp = (LAMMPS *) handle;
Error *error = lmp->error; Error *error = lmp->error;
@ -6525,9 +6517,6 @@ int lammps_has_error(void *handle) {
} else { } else {
return lammps_last_global_errormessage.empty() ? 0 : 1; return lammps_last_global_errormessage.empty() ? 0 : 1;
} }
#else
return 0;
#endif
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -6569,8 +6558,8 @@ the failing MPI ranks to send messages.
* \param buf_size size of the provided string buffer * \param buf_size size of the provided string buffer
* \return 1 when all ranks had the error, 2 on a single rank error. */ * \return 1 when all ranks had the error, 2 on a single rank error. */
int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) { int lammps_get_last_error_message(void *handle, char *buffer, int buf_size)
#ifdef LAMMPS_EXCEPTIONS {
if (handle) { if (handle) {
LAMMPS *lmp = (LAMMPS *) handle; LAMMPS *lmp = (LAMMPS *) handle;
Error *error = lmp->error; Error *error = lmp->error;
@ -6591,7 +6580,6 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) {
return 1; return 1;
} }
} }
#endif
return 0; return 0;
} }

View File

@ -13,13 +13,10 @@
#include "lammps.h" #include "lammps.h"
#include "exceptions.h"
#include "input.h" #include "input.h"
#include "library.h" #include "library.h"
#if defined(LAMMPS_EXCEPTIONS)
#include "exceptions.h"
#endif
#include <cstdlib> #include <cstdlib>
#include <mpi.h> #include <mpi.h>
@ -75,14 +72,13 @@ int main(int argc, char **argv)
feenableexcept(FE_OVERFLOW); feenableexcept(FE_OVERFLOW);
#endif #endif
#ifdef LAMMPS_EXCEPTIONS
try { try {
auto lammps = new LAMMPS(argc, argv, lammps_comm); auto lammps = new LAMMPS(argc, argv, lammps_comm);
lammps->input->file(); lammps->input->file();
delete lammps; delete lammps;
} catch (LAMMPSAbortException &ae) { } catch (LAMMPSAbortException &ae) {
finalize(); finalize();
MPI_Abort(ae.universe, 1); MPI_Abort(ae.get_universe(), 1);
} catch (LAMMPSException &) { } catch (LAMMPSException &) {
finalize(); finalize();
MPI_Barrier(lammps_comm); MPI_Barrier(lammps_comm);
@ -99,18 +95,6 @@ int main(int argc, char **argv)
MPI_Abort(MPI_COMM_WORLD, 1); MPI_Abort(MPI_COMM_WORLD, 1);
exit(1); exit(1);
} }
#else
try {
auto lammps = new LAMMPS(argc, argv, lammps_comm);
lammps->input->file();
delete lammps;
} catch (fmt::format_error &fe) {
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
finalize();
MPI_Abort(MPI_COMM_WORLD, 1);
exit(1);
}
#endif
finalize(); finalize();
MPI_Barrier(lammps_comm); MPI_Barrier(lammps_comm);
MPI_Finalize(); MPI_Finalize();

View File

@ -13,9 +13,6 @@ option(LAMMPS_GUI_USE_PLUGIN "Load LAMMPS library dynamically at runtime" OFF)
mark_as_advanced(LAMMPS_GUI_USE_PLUGIN) mark_as_advanced(LAMMPS_GUI_USE_PLUGIN)
# checks # checks
if(NOT LAMMPS_EXCEPTIONS)
message(FATAL_ERROR "Must enable LAMMPS_EXCEPTIONS for building the LAMMPS GUI")
endif()
if(BUILD_MPI) if(BUILD_MPI)
message(FATAL_ERROR "Must disable BUILD_MPI for building the LAMMPS GUI") message(FATAL_ERROR "Must disable BUILD_MPI for building the LAMMPS GUI")
endif() endif()

View File

@ -46,13 +46,6 @@ else()
endif() endif()
list(APPEND TEST_CONFIG_DEFS -DLAMMPS_HAS_MPI=${HAS_MPI}) list(APPEND TEST_CONFIG_DEFS -DLAMMPS_HAS_MPI=${HAS_MPI})
if(LAMMPS_EXCEPTIONS)
set(HAS_EXCEPTIONS 1)
else()
set(HAS_EXCEPTIONS 0)
endif()
list(APPEND TEST_CONFIG_DEFS -DLAMMPS_HAS_EXCEPTIONS=${HAS_EXCEPTIONS})
foreach(WITH "JPEG" "PNG" "GZIP" "FFMPEG") foreach(WITH "JPEG" "PNG" "GZIP" "FFMPEG")
if(WITH_${WITH}) if(WITH_${WITH})
set(HAS_${WITH} 1) set(HAS_${WITH} 1)

View File

@ -195,7 +195,7 @@ TEST_F(LibraryConfig, force_timeout)
TEST(LAMMPSConfig, exceptions) TEST(LAMMPSConfig, exceptions)
{ {
EXPECT_EQ(lammps_config_has_exceptions(), LAMMPS_HAS_EXCEPTIONS); EXPECT_EQ(lammps_config_has_exceptions(), 1);
}; };
TEST(LAMMPSConfig, mpi_support) TEST(LAMMPSConfig, mpi_support)

View File

@ -518,9 +518,6 @@ TEST_F(LibraryProperties, neighlist)
TEST_F(LibraryProperties, has_error) TEST_F(LibraryProperties, has_error)
{ {
// need errors to throw exceptions to be able to intercept them.
if (!lammps_config_has_exceptions()) GTEST_SKIP();
EXPECT_EQ(lammps_has_error(lmp), 0); EXPECT_EQ(lammps_has_error(lmp), 0);
// trigger an error, but hide output // trigger an error, but hide output

View File

@ -402,9 +402,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -393,9 +393,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -161,9 +161,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -469,9 +469,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -683,9 +683,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -299,9 +299,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -632,9 +632,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -285,9 +285,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -806,9 +806,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -460,9 +460,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -560,9 +560,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -774,9 +774,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -224,9 +224,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -125,9 +125,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = LAMMPS_NS::utils::split_words(var); std::vector<std::string> env = LAMMPS_NS::utils::split_words(var);

View File

@ -618,9 +618,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var); std::vector<std::string> env = split_words(var);

View File

@ -409,9 +409,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var); std::vector<std::string> env = split_words(var);

View File

@ -323,9 +323,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var); std::vector<std::string> env = split_words(var);

View File

@ -166,9 +166,6 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv); ::testing::InitGoogleMock(&argc, argv);
if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n";
// handle arguments passed via environment variable // handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) { if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var); std::vector<std::string> env = split_words(var);

View File

@ -123,9 +123,6 @@ TEST_F(LAMMPS_properties, extract_setting)
TEST_F(LAMMPS_properties, has_error) TEST_F(LAMMPS_properties, has_error)
{ {
// need errors to throw exceptions to be able to intercept them.
if (!lammps_config_has_exceptions()) GTEST_SKIP();
EXPECT_EQ(f_lammps_has_error(), lammps_has_error(lmp)); EXPECT_EQ(f_lammps_has_error(), lammps_has_error(lmp));
EXPECT_EQ(f_lammps_has_error(), 0); EXPECT_EQ(f_lammps_has_error(), 0);

View File

@ -86,13 +86,10 @@ if(Python_EXECUTABLE)
WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
set_tests_properties(PythonOpen PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}") set_tests_properties(PythonOpen PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}")
# some of the tests in this file will fail without exceptions enabled add_test(NAME PythonCommands
if(LAMMPS_EXCEPTIONS) COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-commands.py -v
add_test(NAME PythonCommands WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-commands.py -v set_tests_properties(PythonCommands PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}")
WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
set_tests_properties(PythonCommands PROPERTIES ENVIRONMENT "${PYTHON_TEST_ENVIRONMENT}")
endif()
add_test(NAME PythonNumpy add_test(NAME PythonNumpy
COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-numpy.py -v COMMAND ${PYTHON_TEST_RUNNER} ${CMAKE_CURRENT_SOURCE_DIR}/python-numpy.py -v

View File

@ -4,7 +4,7 @@ from lammps import lammps
has_mpi=False has_mpi=False
has_mpi4py=False has_mpi4py=False
has_exceptions=False
try: try:
from mpi4py import __version__ as mpi4py_version from mpi4py import __version__ as mpi4py_version
# tested to work with mpi4py versions 2 and 3 # tested to work with mpi4py versions 2 and 3
@ -19,7 +19,6 @@ try:
machine = "" machine = ""
lmp = lammps(name=machine) lmp = lammps(name=machine)
has_mpi = lmp.has_mpi_support has_mpi = lmp.has_mpi_support
has_exceptions = lmp.has_exceptions
lmp.close() lmp.close()
except: except:
pass pass
@ -79,7 +78,6 @@ class PythonOpen(unittest.TestCase):
self.assertEqual(lmp.opened,1) self.assertEqual(lmp.opened,1)
lmp.close() lmp.close()
@unittest.skipIf(not has_exceptions,"Skipping death test since LAMMPS isn't compiled with exception support")
def testUnknownCommand(self): def testUnknownCommand(self):
lmp = lammps(name=self.machine) lmp = lammps(name=self.machine)
@ -88,7 +86,6 @@ class PythonOpen(unittest.TestCase):
lmp.close() lmp.close()
@unittest.skipIf(not has_exceptions,"Skipping death test since LAMMPS isn't compiled with exception support")
def testUnknownCommandInList(self): def testUnknownCommandInList(self):
lmp = lammps(name=self.machine) lmp = lammps(name=self.machine)
@ -97,7 +94,6 @@ class PythonOpen(unittest.TestCase):
lmp.close() lmp.close()
@unittest.skipIf(not has_exceptions,"Skipping death test since LAMMPS isn't compiled with exception support")
def testUnknownCommandInString(self): def testUnknownCommandInString(self):
lmp = lammps(name=self.machine) lmp = lammps(name=self.machine)

View File

@ -32,21 +32,12 @@ using LAMMPS_NS::LAMMPSException;
using ::testing::ContainsRegex; using ::testing::ContainsRegex;
#define TEST_FAILURE(errmsg, ...) \ #define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \ { \
::testing::internal::CaptureStdout(); \ ::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \ ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \ auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, ContainsRegex(errmsg)); \ ASSERT_THAT(mesg, ContainsRegex(errmsg)); \
} else { \
if (LAMMPS_NS::platform::mpi_vendor() != "Open MPI") { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, ContainsRegex(errmsg)); \
} else { \
std::cerr << "[ ] [ INFO ] Skipping death test (no exception support) \n"; \
} \
} }
// whether to print verbose output (i.e. not capturing LAMMPS screen output). // whether to print verbose output (i.e. not capturing LAMMPS screen output).

View File

@ -73,16 +73,14 @@ TEST_F(LeptonUtilsTest, substitute)
lmp->update->reset_timestep(100LL, false); lmp->update->reset_timestep(100LL, false);
ASSERT_THAT(LeptonUtils::substitute("(2.5/v_pre)", lmp), StrEq("(2.5/0.1)")); ASSERT_THAT(LeptonUtils::substitute("(2.5/v_pre)", lmp), StrEq("(2.5/0.1)"));
if (LAMMPS_NS::Info::has_exceptions()) { bool caught = false;
bool caught = false; try {
try { LeptonUtils::substitute("v_none", lmp);
LeptonUtils::substitute("v_none", lmp); } catch (std::exception &e) {
} catch (std::exception &e) { ASSERT_THAT(e.what(), StrEq("Variable none in expression v_none does not exist"));
ASSERT_THAT(e.what(), StrEq("Variable none in expression v_none does not exist")); caught = true;
caught = true;
}
ASSERT_TRUE(caught);
} }
ASSERT_TRUE(caught);
} }
// zbl() custom function // zbl() custom function