treat Py_Finalize() more like MPI_Finalize()
this is done by - not automatically calling Py_Finalize() when destructing a python interpreter - adding wrapper functions so that the call to Py_Finalize() is hidden and skipped if Python support is no included. - call the Python::finalize() wrapper in main.cpp (similar to the equivalent Kokkos function) - add a wrapper of that call to the C library interface
This commit is contained in:
@ -10,6 +10,7 @@ This section documents the following functions:
|
||||
- :cpp:func:`lammps_mpi_init`
|
||||
- :cpp:func:`lammps_mpi_finalize`
|
||||
- :cpp:func:`lammps_kokkos_finalize`
|
||||
- :cpp:func:`lammps_python_finalize`
|
||||
|
||||
--------------------
|
||||
|
||||
@ -104,3 +105,13 @@ calling program.
|
||||
|
||||
.. doxygenfunction:: lammps_mpi_finalize
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_kokkos_finalize
|
||||
:project: progguide
|
||||
|
||||
-----------------------
|
||||
|
||||
.. doxygenfunction:: lammps_python_finalize
|
||||
:project: progguide
|
||||
|
||||
@ -63,10 +63,6 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// one-time initialization of Python interpreter
|
||||
// pyMain stores pointer to main module
|
||||
external_interpreter = Py_IsInitialized();
|
||||
|
||||
#ifdef MLIAP_PYTHON
|
||||
// Inform python intialization scheme of the mliappy module.
|
||||
// This -must- happen before python is initialized.
|
||||
@ -108,12 +104,6 @@ PythonImpl::~PythonImpl()
|
||||
}
|
||||
}
|
||||
|
||||
// shutdown Python interpreter
|
||||
if (!external_interpreter) {
|
||||
PyGILState_Ensure();
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
memory->sfree(pfuncs);
|
||||
}
|
||||
|
||||
@ -545,3 +535,10 @@ bool PythonImpl::has_minimum_version(int major, int minor)
|
||||
{
|
||||
return (PY_MAJOR_VERSION == major && PY_MINOR_VERSION >= minor) || (PY_MAJOR_VERSION > major);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void PythonImpl::finalize()
|
||||
{
|
||||
if (Py_IsInitialized()) Py_Finalize();
|
||||
}
|
||||
|
||||
@ -20,9 +20,8 @@
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class PythonImpl : protected Pointers, public PythonInterface {
|
||||
public:
|
||||
bool external_interpreter;
|
||||
|
||||
public:
|
||||
PythonImpl(class LAMMPS *);
|
||||
~PythonImpl();
|
||||
void command(int, char **);
|
||||
@ -33,6 +32,7 @@ class PythonImpl : protected Pointers, public PythonInterface {
|
||||
int execute_string(char *);
|
||||
int execute_file(char *);
|
||||
bool has_minimum_version(int major, int minor);
|
||||
static void finalize();
|
||||
|
||||
private:
|
||||
void *pyMain;
|
||||
|
||||
@ -33,17 +33,18 @@
|
||||
#include "group.h"
|
||||
#include "info.h"
|
||||
#include "input.h"
|
||||
#include "lmppython.h"
|
||||
#include "memory.h"
|
||||
#include "modify.h"
|
||||
#include "molecule.h"
|
||||
#include "neigh_list.h"
|
||||
#include "neighbor.h"
|
||||
#include "region.h"
|
||||
#include "respa.h"
|
||||
#include "output.h"
|
||||
#if defined(LMP_PLUGIN)
|
||||
#include "plugin.h"
|
||||
#endif
|
||||
#include "region.h"
|
||||
#include "respa.h"
|
||||
#include "thermo.h"
|
||||
#include "timer.h"
|
||||
#include "universe.h"
|
||||
@ -339,6 +340,8 @@ function no more MPI calls may be made.
|
||||
|
||||
.. versionadded:: 18Sep2020
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_kokkos_finalize`, :cpp:func:`lammps_python_finalize`
|
||||
\endverbatim */
|
||||
|
||||
void lammps_mpi_finalize()
|
||||
@ -369,6 +372,8 @@ After calling this function no Kokkos functionality may be used.
|
||||
|
||||
.. versionadded:: 2Jul2021
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_python_finalize`
|
||||
\endverbatim */
|
||||
|
||||
void lammps_kokkos_finalize()
|
||||
@ -376,6 +381,42 @@ void lammps_kokkos_finalize()
|
||||
KokkosLMP::finalize();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Clear the embedded Python environment
|
||||
*
|
||||
\verbatim embed:rst
|
||||
|
||||
This function resets and clears an embedded Python environment
|
||||
by calling the `Py_Finalize() function
|
||||
<https://docs.python.org/3/c-api/init.html#c.Py_FinalizeEx>`_
|
||||
of the embedded Python library, if enabled.
|
||||
This call would free up all allocated resources and release
|
||||
loaded shared objects.
|
||||
|
||||
However, this is **not** done when a LAMMPS instance is deleted because
|
||||
a) LAMMPS may have been used through the Python module and thus
|
||||
the Python interpreter is external and not embedded into LAMMPS
|
||||
and therefore may not be reset by LAMMPS b) some Python modules
|
||||
and extensions, most notably NumPy, are not compatible with being
|
||||
initialized multiple times, which would happen if additional
|
||||
LAMMPS instances using Python would be created *after*
|
||||
after calling Py_Finalize().
|
||||
|
||||
This function can be called to explicitly clear the Python
|
||||
environment in case it is safe to do so.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
*See also*
|
||||
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_kokkos_finalize`
|
||||
\endverbatim */
|
||||
|
||||
void lammps_python_finalize()
|
||||
{
|
||||
Python::finalize();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Library functions to process commands
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@ -95,6 +95,7 @@ void lammps_close(void *handle);
|
||||
void lammps_mpi_init();
|
||||
void lammps_mpi_finalize();
|
||||
void lammps_kokkos_finalize();
|
||||
void lammps_python_finalize();
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Library functions to process commands
|
||||
|
||||
@ -126,3 +126,12 @@ bool Python::has_minimum_version(int major, int minor)
|
||||
init();
|
||||
return impl->has_minimum_version(major, minor);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void Python::finalize()
|
||||
{
|
||||
#if defined(LMP_PYTHON)
|
||||
PythonImpl::finalize();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -47,6 +47,7 @@ class Python : protected Pointers {
|
||||
|
||||
bool is_enabled() const;
|
||||
void init();
|
||||
static void finalize();
|
||||
|
||||
private:
|
||||
PythonInterface *impl;
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
#include "accelerator_kokkos.h"
|
||||
#include "input.h"
|
||||
#include "lmppython.h"
|
||||
|
||||
#if defined(LAMMPS_EXCEPTIONS)
|
||||
#include "exceptions.h"
|
||||
#endif
|
||||
@ -79,15 +81,18 @@ int main(int argc, char **argv)
|
||||
delete lammps;
|
||||
} catch (LAMMPSAbortException &ae) {
|
||||
KokkosLMP::finalize();
|
||||
Python::finalize();
|
||||
MPI_Abort(ae.universe, 1);
|
||||
} catch (LAMMPSException &e) {
|
||||
KokkosLMP::finalize();
|
||||
Python::finalize();
|
||||
MPI_Barrier(lammps_comm);
|
||||
MPI_Finalize();
|
||||
exit(1);
|
||||
} catch (fmt::format_error &fe) {
|
||||
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
|
||||
KokkosLMP::finalize();
|
||||
Python::finalize();
|
||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
||||
exit(1);
|
||||
}
|
||||
@ -99,11 +104,13 @@ int main(int argc, char **argv)
|
||||
} catch (fmt::format_error &fe) {
|
||||
fprintf(stderr, "fmt::format_error: %s\n", fe.what());
|
||||
KokkosLMP::finalize();
|
||||
Python::finalize();
|
||||
MPI_Abort(MPI_COMM_WORLD, 1);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
KokkosLMP::finalize();
|
||||
Python::finalize();
|
||||
MPI_Barrier(lammps_comm);
|
||||
MPI_Finalize();
|
||||
}
|
||||
|
||||
@ -64,6 +64,7 @@ extern void lammps_close(void *handle);
|
||||
extern void lammps_mpi_init();
|
||||
extern void lammps_mpi_finalize();
|
||||
extern void lammps_kokkos_finalize();
|
||||
extern void lammps_python_finalize();
|
||||
extern void lammps_file(void *handle, const char *file);
|
||||
extern char *lammps_command(void *handle, const char *cmd);
|
||||
extern void lammps_commands_list(void *handle, int ncmd, const char **cmds);
|
||||
@ -199,6 +200,7 @@ extern void lammps_close(void *handle);
|
||||
extern void lammps_mpi_init();
|
||||
extern void lammps_mpi_finalize();
|
||||
extern void lammps_kokkos_finalize();
|
||||
extern void lammps_python_finalize();
|
||||
extern void lammps_file(void *handle, const char *file);
|
||||
extern char *lammps_command(void *handle, const char *cmd);
|
||||
extern void lammps_commands_list(void *handle, int ncmd, const char **cmds);
|
||||
|
||||
Reference in New Issue
Block a user