remove compatibility for compiling LAMMPS with Python 2.x and Python 3.5 and older

This commit is contained in:
Axel Kohlmeyer
2025-02-08 05:05:00 -05:00
parent 86f7f6da98
commit 599ff11eb0
10 changed files with 29 additions and 52 deletions

View File

@ -1,7 +0,0 @@
# Settings that the LAMMPS build will import when this package library is used
# See the README file for more explanation
python_SYSINC = $(shell which python2-config > /dev/null 2>&1 && python2-config --includes || (which python-config > /dev/null 2>&1 && python-config --includes || :))
python_SYSLIB = $(shell which python2-config > /dev/null 2>&1 && python2-config --ldflags || (which python-config > /dev/null 2>&1 && python-config --ldflags || :))
python_SYSPATH =
PYTHON=$(shell which python2 > /dev/null 2>&1 && echo python2 || echo python)

View File

@ -9,30 +9,29 @@ installation. If needed, you can copy one of the other provided
Makefile.lammps.* files to to Makefile.lammps before building Makefile.lammps.* files to to Makefile.lammps before building
LAMMPS itself. LAMMPS itself.
The files Makefile.lammps.python2 and Makefile.lammps.python3 are The file Makefile.lammps.python3 is similar to the default file, but
similar to the default file, but meant for the case that both, meant for the case that both, python 2 and python 3, are installed
python 2 and python 3, are installed simultaneously and you want simultaneously. LAMMPS only supports python 3. If neither of these
to prefer one over the other. If neither of these files work, you files work, you may have to create a custom Makefile.lammps file
may have to create a custom Makefile.lammps file suitable for suitable for the version of Python on your system. To illustrate, these
the version of Python on your system. To illustrate, these are are example settings from the Makefile.lammps.python3.13 file:
example settings from the Makefile.lammps.python2.7 file:
python_SYSINC = -I/usr/local/include/python2.7 python_SYSINC = -I/usr/local/include/python3.13
python_SYSLIB = -lpython2.7 -lnsl -ldl -lreadline -ltermcap -lpthread -lutil -lm python_SYSLIB = -lpython3.13 -ldl -lm
python_SYSPATH = python_SYSPATH = -L/usr/lib64
PYTHON=python2.7 PYTHON=python3.13
python_SYSINC refers to the directory where Python's Python.h file is python_SYSINC refers to the directory where Python's Python.h file is
found. LAMMPS includes this file. found. LAMMPS includes this file.
python_SYSLIB refers to the libraries needed to link to from an python_SYSLIB refers to the libraries needed to link to from an
application (LAMMPS in this case) to "embed" Python in the application (LAMMPS in this case) to "embed" Python in the
application. The Python library itself is listed (-lpython2.7) are application. The Python library itself is listed (-lpython3.13) are
are several system libraries needed by Python. are several system libraries needed by Python.
python_SYSPATH refers to the path (e.g. -L/usr/local/lib) where the python_SYSPATH refers to the path (e.g. -L/usr/local/lib) where the
Python library can be found. You may not need this setting if the Python library can be found. You may not need this setting if the
path is already included in your LD_LIBRARY_PATH environment variable. path is already included in your LIBRARY_PATH environment variable.
PYTHON is the name of the python interpreter. It is used for PYTHON is the name of the python interpreter. It is used for
installing the LAMMPS python module with "make install-python" installing the LAMMPS python module with "make install-python"
@ -45,7 +44,7 @@ run in embedded mode on your machine.
Here is what this Python doc page says about it: Here is what this Python doc page says about it:
https://docs.python.org/2/extending/embedding.html#compiling-and-linking-under-unix-like-systems https://docs.python.org/3/extending/embedding.html#compiling-and-linking-under-unix-like-systems
"It is not necessarily trivial to find the right flags to pass to your "It is not necessarily trivial to find the right flags to pass to your
compiler (and linker) in order to embed the Python interpreter into compiler (and linker) in order to embed the Python interpreter into

View File

@ -68,12 +68,12 @@ MLIAPModelPythonKokkos<DeviceType>::MLIAPModelPythonKokkos(LAMMPS *lmp, char *co
// Recipe from lammps/src/pair_python.cpp : // Recipe from lammps/src/pair_python.cpp :
// add current directory to PYTHONPATH // add current directory to PYTHONPATH
PyObject *py_path = PySys_GetObject((char *) "path"); PyObject *py_path = PySys_GetObject((char *) "path");
PyList_Append(py_path, PY_STRING_FROM_STRING(".")); PyList_Append(py_path, PyUnicode_FromString("."));
// if LAMMPS_POTENTIALS environment variable is set, add it to PYTHONPATH as well // if LAMMPS_POTENTIALS environment variable is set, add it to PYTHONPATH as well
const char *potentials_path = getenv("LAMMPS_POTENTIALS"); const char *potentials_path = getenv("LAMMPS_POTENTIALS");
if (potentials_path != nullptr) { if (potentials_path != nullptr) {
PyList_Append(py_path, PY_STRING_FROM_STRING(potentials_path)); PyList_Append(py_path, PyUnicode_FromString(potentials_path));
} }
PyGILState_Release(gstate); PyGILState_Release(gstate);
if (coefffilename) read_coeffs(coefffilename); if (coefffilename) read_coeffs(coefffilename);

View File

@ -62,12 +62,12 @@ MLIAPModelPython::MLIAPModelPython(LAMMPS *lmp, char *coefffilename, bool is_chi
// Recipe from lammps/src/pair_python.cpp : // Recipe from lammps/src/pair_python.cpp :
// add current directory to PYTHONPATH // add current directory to PYTHONPATH
PyObject *py_path = PySys_GetObject((char *) "path"); PyObject *py_path = PySys_GetObject((char *) "path");
PyList_Append(py_path, PY_STRING_FROM_STRING(".")); PyList_Append(py_path, PyUnicode_FromString("."));
// if LAMMPS_POTENTIALS environment variable is set, add it to PYTHONPATH as well // if LAMMPS_POTENTIALS environment variable is set, add it to PYTHONPATH as well
const char *potentials_path = getenv("LAMMPS_POTENTIALS"); const char *potentials_path = getenv("LAMMPS_POTENTIALS");
if (potentials_path != nullptr) { if (potentials_path != nullptr) {
PyList_Append(py_path, PY_STRING_FROM_STRING(potentials_path)); PyList_Append(py_path, PyUnicode_FromString(potentials_path));
} }
PyGILState_Release(gstate); PyGILState_Release(gstate);
if (coefffilename) read_coeffs(coefffilename); if (coefffilename) read_coeffs(coefffilename);

View File

@ -70,7 +70,7 @@ FixPythonInvoke::FixPythonInvoke(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Could not find Python function"); error->all(FLERR,"Could not find Python function");
} }
lmpPtr = PY_VOID_POINTER(lmp); lmpPtr = PyCapsule_New((void *)lmp, nullptr, nullptr);
// nvalid = next step on which end_of_step or post_force does something // nvalid = next step on which end_of_step or post_force does something
// add nextvalid() to all computes that store invocation times // add nextvalid() to all computes that store invocation times

View File

@ -44,7 +44,7 @@ FixPythonMove::FixPythonMove(LAMMPS *lmp, int narg, char **arg) :
// add current directory to PYTHONPATH // add current directory to PYTHONPATH
PyObject *py_path = PySys_GetObject((char *)"path"); PyObject *py_path = PySys_GetObject((char *)"path");
PyList_Append(py_path, PY_STRING_FROM_STRING(".")); PyList_Append(py_path, PyUnicode_FromString("."));
// create integrator instance // create integrator instance
@ -73,7 +73,7 @@ FixPythonMove::FixPythonMove(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Could not find integrator class {} in module {}", cls_name, module_name); error->all(FLERR,"Could not find integrator class {} in module {}", cls_name, module_name);
} }
PyObject *ptr = PY_VOID_POINTER(lmp); PyObject *ptr = PyCapsule_New((void *)lmp, nullptr, nullptr);
PyObject *py_move_obj = PyObject_CallFunction(py_move_type, (char *)"O", ptr); PyObject *py_move_obj = PyObject_CallFunction(py_move_type, (char *)"O", ptr);
Py_CLEAR(ptr); Py_CLEAR(ptr);

View File

@ -54,14 +54,14 @@ PairPython::PairPython(LAMMPS *lmp) : Pair(lmp) {
PyUtils::GIL lock; PyUtils::GIL lock;
PyObject *py_path = PySys_GetObject((char *)"path"); PyObject *py_path = PySys_GetObject((char *)"path");
PyList_Append(py_path, PY_STRING_FROM_STRING(".")); PyList_Append(py_path, PyUnicode_FromString("."));
// if LAMMPS_POTENTIALS environment variable is set, // if LAMMPS_POTENTIALS environment variable is set,
// add it to PYTHONPATH as well // add it to PYTHONPATH as well
const char *potentials_path = getenv("LAMMPS_POTENTIALS"); const char *potentials_path = getenv("LAMMPS_POTENTIALS");
if (potentials_path != nullptr) { if (potentials_path != nullptr) {
PyList_Append(py_path, PY_STRING_FROM_STRING(potentials_path)); PyList_Append(py_path, PyUnicode_FromString(potentials_path));
} }
} }

View File

@ -16,22 +16,11 @@
#include <Python.h> #include <Python.h>
// Wrap API changes between Python 2 and 3 using macros #if PY_VERSION_HEX < 0x030600f0
#if PY_MAJOR_VERSION == 2 #error Python version 3.6 or later is required by LAMMPS
#if defined(_MSC_VER) || defined(__MINGW32__)
#define PY_INT_FROM_LONG(X) PyLong_FromLongLong(X)
#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X)
#define PY_LONG_FROM_STRING(X) std::stoll(X)
#else
#define PY_INT_FROM_LONG(X) PyInt_FromLong(X)
#define PY_INT_AS_LONG(X) PyInt_AsLong(X)
#define PY_LONG_FROM_STRING(X) std::stol(X)
#endif #endif
#define PY_STRING_FROM_STRING(X) PyString_FromString(X)
#define PY_VOID_POINTER(X) PyCObject_FromVoidPtr((void *) X, nullptr)
#define PY_STRING_AS_STRING(X) PyString_AsString(X)
#elif PY_MAJOR_VERSION == 3 // Wrap API differences between platforms using macros
#if defined(_MSC_VER) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(__MINGW32__)
#define PY_INT_FROM_LONG(X) PyLong_FromLongLong(X) #define PY_INT_FROM_LONG(X) PyLong_FromLongLong(X)
#define PY_INT_AS_LONG(X) PyLong_AsLongLong(X) #define PY_INT_AS_LONG(X) PyLong_AsLongLong(X)
@ -41,9 +30,5 @@
#define PY_INT_AS_LONG(X) PyLong_AsLong(X) #define PY_INT_AS_LONG(X) PyLong_AsLong(X)
#define PY_LONG_FROM_STRING(X) std::stol(X) #define PY_LONG_FROM_STRING(X) std::stol(X)
#endif #endif
#define PY_STRING_FROM_STRING(X) PyUnicode_FromString(X)
#define PY_VOID_POINTER(X) PyCapsule_New((void *) X, nullptr, nullptr)
#define PY_STRING_AS_STRING(X) PyUnicode_AsUTF8(X)
#endif
#endif #endif

View File

@ -361,12 +361,12 @@ void PythonImpl::invoke_function(int ifunc, char *result)
if (!str) if (!str)
error->all(FLERR, "Could not evaluate Python function {} input variable: {}", error->all(FLERR, "Could not evaluate Python function {} input variable: {}",
pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]); pfuncs[ifunc].name, pfuncs[ifunc].svalue[i]);
pValue = PY_STRING_FROM_STRING(str); pValue = PyUnicode_FromString(str);
} else { } else {
pValue = PY_STRING_FROM_STRING(pfuncs[ifunc].svalue[i]); pValue = PyUnicode_FromString(pfuncs[ifunc].svalue[i]);
} }
} else if (itype == PTR) { } else if (itype == PTR) {
pValue = PY_VOID_POINTER(lmp); pValue = PyCapsule_New((void *)lmp, nullptr, nullptr);
} else { } else {
error->all(FLERR, "Unsupported variable type: {}", itype); error->all(FLERR, "Unsupported variable type: {}", itype);
} }
@ -397,7 +397,7 @@ void PythonImpl::invoke_function(int ifunc, char *result)
auto value = fmt::format("{:.15g}", PyFloat_AsDouble(pValue)); auto value = fmt::format("{:.15g}", PyFloat_AsDouble(pValue));
strncpy(result, value.c_str(), Variable::VALUELENGTH - 1); strncpy(result, value.c_str(), Variable::VALUELENGTH - 1);
} else if (otype == STRING) { } else if (otype == STRING) {
const char *pystr = PY_STRING_AS_STRING(pValue); const char *pystr = PyUnicode_AsUTF8(pValue);
if (pfuncs[ifunc].longstr) if (pfuncs[ifunc].longstr)
strncpy(pfuncs[ifunc].longstr, pystr, pfuncs[ifunc].length_longstr); strncpy(pfuncs[ifunc].longstr, pystr, pfuncs[ifunc].length_longstr);
else else