diff --git a/src/PYTHON/python_impl.cpp b/src/PYTHON/python_impl.cpp index 08fba05367..983aafb16b 100644 --- a/src/PYTHON/python_impl.cpp +++ b/src/PYTHON/python_impl.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -25,8 +24,8 @@ #include "python_utils.h" #include "variable.h" +#include // IWYU pragma: export #include -#include // IWYU pragma: export #ifdef MLIAP_PYTHON #include "mliap_model_python.h" @@ -38,8 +37,7 @@ using namespace LAMMPS_NS; -enum{NONE,INT,DOUBLE,STRING,PTR}; - +enum { NONE, INT, DOUBLE, STRING, PTR }; /* ---------------------------------------------------------------------- */ @@ -53,7 +51,7 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp) #if PY_MAJOR_VERSION >= 3 #ifndef Py_LIMITED_API // check for PYTHONUNBUFFERED environment variable - const char * PYTHONUNBUFFERED = getenv("PYTHONUNBUFFERED"); + const char *PYTHONUNBUFFERED = getenv("PYTHONUNBUFFERED"); if (PYTHONUNBUFFERED != nullptr && strcmp(PYTHONUNBUFFERED, "1") == 0) { // Python Global configuration variable @@ -67,7 +65,7 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp) // Inform python intialization scheme of the mliappy module. // This -must- happen before python is initialized. int err = PyImport_AppendInittab("mliap_model_python_couple", PyInit_mliap_model_python_couple); - if (err) error->all(FLERR,"Could not register MLIAPPY embedded python module."); + if (err) error->all(FLERR, "Could not register MLIAPPY embedded python module."); #endif Py_Initialize(); @@ -76,15 +74,13 @@ PythonImpl::PythonImpl(LAMMPS *lmp) : Pointers(lmp) // With Python 3.7 this function is now called by Py_Initialize() // Deprecated since version 3.9, will be removed in version 3.11 #if PY_MAJOR_VERSION < 3 || PY_MINOR_VERSION < 7 - if (!PyEval_ThreadsInitialized()) { - PyEval_InitThreads(); - } + if (!PyEval_ThreadsInitialized()) { PyEval_InitThreads(); } #endif PyUtils::GIL lock; PyObject *pModule = PyImport_AddModule("__main__"); - if (!pModule) error->all(FLERR,"Could not initialize embedded Python"); + if (!pModule) error->all(FLERR, "Could not initialize embedded Python"); pyMain = (void *) pModule; } @@ -98,7 +94,7 @@ PythonImpl::~PythonImpl() PyUtils::GIL lock; for (int i = 0; i < nfunc; i++) { - delete [] pfuncs[i].name; + delete[] pfuncs[i].name; deallocate(i); Py_CLEAR(pfuncs[i].pFunc); } @@ -111,39 +107,37 @@ PythonImpl::~PythonImpl() void PythonImpl::command(int narg, char **arg) { - if (narg < 2) error->all(FLERR,"Invalid python command"); + if (narg < 2) error->all(FLERR, "Invalid python command"); // if invoke is only keyword, invoke the previously defined function - if (narg == 2 && strcmp(arg[1],"invoke") == 0) { + if (narg == 2 && strcmp(arg[1], "invoke") == 0) { int ifunc = find(arg[0]); - if (ifunc < 0) error->all(FLERR,"Python invoke of undefined function"); + if (ifunc < 0) error->all(FLERR, "Python invoke of undefined function"); char *str = nullptr; if (pfuncs[ifunc].noutput) { - str = input->variable->pythonstyle(pfuncs[ifunc].ovarname, - pfuncs[ifunc].name); - if (!str) - error->all(FLERR,"Python variable does not match Python function"); + str = input->variable->pythonstyle(pfuncs[ifunc].ovarname, pfuncs[ifunc].name); + if (!str) error->all(FLERR, "Python variable does not match Python function"); } - invoke_function(ifunc,str); + invoke_function(ifunc, str); return; } // if source is only keyword, execute the python code - if (narg == 3 && strcmp(arg[1],"source") == 0) { + if (narg == 3 && strcmp(arg[1], "source") == 0) { int err; - FILE *fp = fopen(arg[2],"r"); + FILE *fp = fopen(arg[2], "r"); if (fp == nullptr) err = execute_string(arg[2]); else err = execute_file(arg[2]); if (fp) fclose(fp); - if (err) error->all(FLERR,"Could not process Python source command"); + if (err) error->all(FLERR, "Could not process Python source command"); return; } @@ -162,53 +156,53 @@ void PythonImpl::command(int narg, char **arg) int iarg = 1; while (iarg < narg) { - if (strcmp(arg[iarg],"input") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); - ninput = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (ninput < 0) error->all(FLERR,"Invalid python command"); + if (strcmp(arg[iarg], "input") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + ninput = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + if (ninput < 0) error->all(FLERR, "Invalid python command"); iarg += 2; delete[] istr; - istr = new char*[ninput]; - if (iarg+ninput > narg) error->all(FLERR,"Invalid python command"); - for (int i = 0; i < ninput; i++) istr[i] = arg[iarg+i]; + istr = new char *[ninput]; + if (iarg + ninput > narg) error->all(FLERR, "Invalid python command"); + for (int i = 0; i < ninput; i++) istr[i] = arg[iarg + i]; iarg += ninput; - } else if (strcmp(arg[iarg],"return") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); + } else if (strcmp(arg[iarg], "return") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); noutput = 1; - delete[] ostr; - ostr = arg[iarg+1]; + ostr = arg[iarg + 1]; iarg += 2; - } else if (strcmp(arg[iarg],"format") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); - format = utils::strdup(arg[iarg+1]); + } else if (strcmp(arg[iarg], "format") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + format = utils::strdup(arg[iarg + 1]); iarg += 2; - } else if (strcmp(arg[iarg],"length") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); - length_longstr = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (length_longstr <= 0) error->all(FLERR,"Invalid python command"); + } else if (strcmp(arg[iarg], "length") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + length_longstr = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); + if (length_longstr <= 0) error->all(FLERR, "Invalid python command"); iarg += 2; - } else if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); + } else if (strcmp(arg[iarg], "file") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); delete[] pyfile; - pyfile = utils::strdup(arg[iarg+1]); + pyfile = utils::strdup(arg[iarg + 1]); iarg += 2; - } else if (strcmp(arg[iarg],"here") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Invalid python command"); - herestr = arg[iarg+1]; + } else if (strcmp(arg[iarg], "here") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Invalid python command"); + herestr = arg[iarg + 1]; iarg += 2; - } else if (strcmp(arg[iarg],"exists") == 0) { + } else if (strcmp(arg[iarg], "exists") == 0) { existflag = 1; iarg++; - } else error->all(FLERR,"Invalid python command"); + } else + error->all(FLERR, "Invalid python command"); } - if (pyfile && herestr) error->all(FLERR,"Invalid python command"); - if (pyfile && existflag) error->all(FLERR,"Invalid python command"); - if (herestr && existflag) error->all(FLERR,"Invalid python command"); + if (pyfile && herestr) error->all(FLERR, "Invalid python command"); + if (pyfile && existflag) error->all(FLERR, "Invalid python command"); + if (herestr && existflag) error->all(FLERR, "Invalid python command"); // create or overwrite entry in pfuncs vector with name = arg[0] - int ifunc = create_entry(arg[0],ninput,noutput,length_longstr, istr, ostr, format); + int ifunc = create_entry(arg[0], ninput, noutput, length_longstr, istr, ostr, format); PyUtils::GIL lock; @@ -218,18 +212,18 @@ void PythonImpl::command(int narg, char **arg) // exist: do nothing, assume code has already been run if (pyfile) { - FILE *fp = fopen(pyfile,"r"); + FILE *fp = fopen(pyfile, "r"); if (fp == nullptr) { PyUtils::Print_Errors(); - error->all(FLERR,"Could not open Python file"); + error->all(FLERR, "Could not open Python file"); } - int err = PyRun_SimpleFile(fp,pyfile); + int err = PyRun_SimpleFile(fp, pyfile); if (err) { PyUtils::Print_Errors(); - error->all(FLERR,"Could not process Python file"); + error->all(FLERR, "Could not process Python file"); } fclose(fp); @@ -238,34 +232,32 @@ void PythonImpl::command(int narg, char **arg) if (err) { PyUtils::Print_Errors(); - error->all(FLERR,"Could not process Python string"); + error->all(FLERR, "Could not process Python string"); } } // pFunc = function object for requested function PyObject *pModule = (PyObject *) pyMain; - PyObject *pFunc = PyObject_GetAttrString(pModule,pfuncs[ifunc].name); + PyObject *pFunc = PyObject_GetAttrString(pModule, pfuncs[ifunc].name); if (!pFunc) { PyUtils::Print_Errors(); - error->all(FLERR,"Could not find Python function {}", - pfuncs[ifunc].name); + error->all(FLERR, "Could not find Python function {}", pfuncs[ifunc].name); } if (!PyCallable_Check(pFunc)) { PyUtils::Print_Errors(); - error->all(FLERR,"Python function {} is not callable", - pfuncs[ifunc].name); + error->all(FLERR, "Python function {} is not callable", pfuncs[ifunc].name); } pfuncs[ifunc].pFunc = (void *) pFunc; // clean-up input storage - delete [] istr; - delete [] format; - delete [] pyfile; + delete[] istr; + delete[] format; + delete[] pyfile; } /* ------------------------------------------------------------------ */ @@ -283,20 +275,14 @@ void PythonImpl::invoke_function(int ifunc, char *result) int ninput = pfuncs[ifunc].ninput; PyObject *pArgs = PyTuple_New(ninput); - if (!pArgs) { - error->all(FLERR,"Could not create Python function arguments"); - } + if (!pArgs) { error->all(FLERR, "Could not create Python function arguments"); } for (int i = 0; i < ninput; i++) { int itype = pfuncs[ifunc].itype[i]; if (itype == INT) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - - if (!str) { - error->all(FLERR,"Could not evaluate Python function input variable"); - } - + if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } pValue = PY_INT_FROM_LONG(atoi(str)); } else { pValue = PY_INT_FROM_LONG(pfuncs[ifunc].ivalue[i]); @@ -304,11 +290,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == DOUBLE) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - - if (!str) { - error->all(FLERR,"Could not evaluate Python function input variable"); - } - + if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } pValue = PyFloat_FromDouble(atof(str)); } else { pValue = PyFloat_FromDouble(pfuncs[ifunc].dvalue[i]); @@ -316,10 +298,7 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == STRING) { if (pfuncs[ifunc].ivarflag[i]) { str = input->variable->retrieve(pfuncs[ifunc].svalue[i]); - if (!str) { - error->all(FLERR,"Could not evaluate Python function input variable"); - } - + if (!str) { error->all(FLERR, "Could not evaluate Python function input variable"); } pValue = PY_STRING_FROM_STRING(str); } else { pValue = PY_STRING_FROM_STRING(pfuncs[ifunc].svalue[i]); @@ -327,20 +306,20 @@ void PythonImpl::invoke_function(int ifunc, char *result) } else if (itype == PTR) { pValue = PY_VOID_POINTER(lmp); } else { - error->all(FLERR,"Unsupported variable type"); + error->all(FLERR, "Unsupported variable type"); } - PyTuple_SetItem(pArgs,i,pValue); + PyTuple_SetItem(pArgs, i, pValue); } // call the Python function // error check with one() since only some procs may fail - pValue = PyObject_CallObject(pFunc,pArgs); + pValue = PyObject_CallObject(pFunc, pArgs); Py_CLEAR(pArgs); if (!pValue) { PyUtils::Print_Errors(); - error->one(FLERR,"Python function evaluation failed"); + error->one(FLERR, "Python function evaluation failed"); } // function returned a value @@ -350,14 +329,15 @@ void PythonImpl::invoke_function(int ifunc, char *result) if (pfuncs[ifunc].noutput) { int otype = pfuncs[ifunc].otype; if (otype == INT) { - sprintf(result,"%ld",PY_INT_AS_LONG(pValue)); + sprintf(result, "%ld", PY_INT_AS_LONG(pValue)); } else if (otype == DOUBLE) { - sprintf(result,"%.15g",PyFloat_AsDouble(pValue)); + sprintf(result, "%.15g", PyFloat_AsDouble(pValue)); } else if (otype == STRING) { const char *pystr = PY_STRING_AS_STRING(pValue); if (pfuncs[ifunc].longstr) - strncpy(pfuncs[ifunc].longstr,pystr,pfuncs[ifunc].length_longstr); - else strncpy(result,pystr,Variable::VALUELENGTH-1); + strncpy(pfuncs[ifunc].longstr, pystr, pfuncs[ifunc].length_longstr); + else + strncpy(result, pystr, Variable::VALUELENGTH - 1); } } Py_CLEAR(pValue); @@ -368,19 +348,18 @@ void PythonImpl::invoke_function(int ifunc, char *result) int PythonImpl::find(const char *name) { for (int i = 0; i < nfunc; i++) - if (strcmp(name,pfuncs[i].name) == 0) return i; + if (strcmp(name, pfuncs[i].name) == 0) return i; return -1; } /* ------------------------------------------------------------------ */ -int PythonImpl::variable_match(const char *name, const char *varname, - int numeric) +int PythonImpl::variable_match(const char *name, const char *varname, int numeric) { int ifunc = find(name); if (ifunc < 0) return -1; if (pfuncs[ifunc].noutput == 0) return -1; - if (strcmp(pfuncs[ifunc].ovarname,varname) != 0) return -1; + if (strcmp(pfuncs[ifunc].ovarname, varname) != 0) return -1; if (numeric && pfuncs[ifunc].otype == STRING) return -1; return ifunc; } @@ -394,8 +373,8 @@ char *PythonImpl::long_string(int ifunc) /* ------------------------------------------------------------------ */ -int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_longstr, - char **istr, char *ostr, char *format) +int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_longstr, char **istr, + char *ostr, char *format) { // ifunc = index to entry by name in pfuncs vector, can be old or new // free old vectors if overwriting old pfunc @@ -405,18 +384,18 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon if (ifunc < 0) { ifunc = nfunc; nfunc++; - pfuncs = (PyFunc *) - memory->srealloc(pfuncs,nfunc*sizeof(struct PyFunc),"python:pfuncs"); + pfuncs = (PyFunc *) memory->srealloc(pfuncs, nfunc * sizeof(struct PyFunc), "python:pfuncs"); pfuncs[ifunc].name = utils::strdup(name); - } else deallocate(ifunc); + } else + deallocate(ifunc); pfuncs[ifunc].ninput = ninput; pfuncs[ifunc].noutput = noutput; - if (!format && ninput+noutput) - error->all(FLERR,"Invalid python command"); - else if (format && ((int) strlen(format) != ninput+noutput)) - error->all(FLERR,"Invalid python command"); + if (!format && ninput + noutput) + error->all(FLERR, "Invalid python command"); + else if (format && ((int) strlen(format) != ninput + noutput)) + error->all(FLERR, "Invalid python command"); // process inputs as values or variables @@ -424,34 +403,34 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon pfuncs[ifunc].ivarflag = new int[ninput]; pfuncs[ifunc].ivalue = new int[ninput]; pfuncs[ifunc].dvalue = new double[ninput]; - pfuncs[ifunc].svalue = new char*[ninput]; + pfuncs[ifunc].svalue = new char *[ninput]; for (int i = 0; i < ninput; i++) { pfuncs[ifunc].svalue[i] = nullptr; char type = format[i]; if (type == 'i') { pfuncs[ifunc].itype[i] = INT; - if (utils::strmatch(istr[i],"^v_")) { + if (utils::strmatch(istr[i], "^v_")) { pfuncs[ifunc].ivarflag[i] = 1; - pfuncs[ifunc].svalue[i] = utils::strdup(istr[i]+2); + pfuncs[ifunc].svalue[i] = utils::strdup(istr[i] + 2); } else { pfuncs[ifunc].ivarflag[i] = 0; - pfuncs[ifunc].ivalue[i] = utils::inumeric(FLERR,istr[i],false,lmp); + pfuncs[ifunc].ivalue[i] = utils::inumeric(FLERR, istr[i], false, lmp); } } else if (type == 'f') { pfuncs[ifunc].itype[i] = DOUBLE; - if (utils::strmatch(istr[i],"^v_")) { + if (utils::strmatch(istr[i], "^v_")) { pfuncs[ifunc].ivarflag[i] = 1; - pfuncs[ifunc].svalue[i] = utils::strdup(istr[i]+2); + pfuncs[ifunc].svalue[i] = utils::strdup(istr[i] + 2); } else { pfuncs[ifunc].ivarflag[i] = 0; - pfuncs[ifunc].dvalue[i] = utils::numeric(FLERR,istr[i],false,lmp); + pfuncs[ifunc].dvalue[i] = utils::numeric(FLERR, istr[i], false, lmp); } } else if (type == 's') { pfuncs[ifunc].itype[i] = STRING; - if (utils::strmatch(istr[i],"^v_")) { + if (utils::strmatch(istr[i], "^v_")) { pfuncs[ifunc].ivarflag[i] = 1; - pfuncs[ifunc].svalue[i] = utils::strdup(istr[i]+2); + pfuncs[ifunc].svalue[i] = utils::strdup(istr[i] + 2); } else { pfuncs[ifunc].ivarflag[i] = 0; pfuncs[ifunc].svalue[i] = utils::strdup(istr[i]); @@ -459,10 +438,10 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon } else if (type == 'p') { pfuncs[ifunc].ivarflag[i] = 0; pfuncs[ifunc].itype[i] = PTR; - if (strcmp(istr[i],"SELF") != 0) - error->all(FLERR,"Invalid python command"); + if (strcmp(istr[i], "SELF") != 0) error->all(FLERR, "Invalid python command"); - } else error->all(FLERR,"Invalid python command"); + } else + error->all(FLERR, "Invalid python command"); } // process output as value or variable @@ -472,22 +451,25 @@ int PythonImpl::create_entry(char *name, int ninput, int noutput, int length_lon if (!noutput) return ifunc; char type = format[ninput]; - if (type == 'i') pfuncs[ifunc].otype = INT; - else if (type == 'f') pfuncs[ifunc].otype = DOUBLE; - else if (type == 's') pfuncs[ifunc].otype = STRING; - else error->all(FLERR,"Invalid python command"); + if (type == 'i') + pfuncs[ifunc].otype = INT; + else if (type == 'f') + pfuncs[ifunc].otype = DOUBLE; + else if (type == 's') + pfuncs[ifunc].otype = STRING; + else + error->all(FLERR, "Invalid python command"); if (length_longstr) { if (pfuncs[ifunc].otype != STRING) - error->all(FLERR,"Python command length keyword " - "cannot be used unless output is a string"); + error->all(FLERR, "Python command length keyword cannot be used unless output is a string"); pfuncs[ifunc].length_longstr = length_longstr; - pfuncs[ifunc].longstr = new char[length_longstr+1]; + pfuncs[ifunc].longstr = new char[length_longstr + 1]; pfuncs[ifunc].longstr[length_longstr] = '\0'; } - if (strstr(ostr,"v_") != ostr) error->all(FLERR,"Invalid python command"); - pfuncs[ifunc].ovarname = utils::strdup(ostr+2); + if (strstr(ostr, "v_") != ostr) error->all(FLERR, "Invalid python command"); + pfuncs[ifunc].ovarname = utils::strdup(ostr + 2); return ifunc; } @@ -504,11 +486,11 @@ int PythonImpl::execute_string(char *cmd) int PythonImpl::execute_file(char *fname) { - FILE *fp = fopen(fname,"r"); + FILE *fp = fopen(fname, "r"); if (fp == nullptr) return -1; PyUtils::GIL lock; - int err = PyRun_SimpleFile(fp,fname); + int err = PyRun_SimpleFile(fp, fname); if (fp) fclose(fp); return err; @@ -518,27 +500,26 @@ int PythonImpl::execute_file(char *fname) void PythonImpl::deallocate(int i) { - delete [] pfuncs[i].itype; - delete [] pfuncs[i].ivarflag; - delete [] pfuncs[i].ivalue; - delete [] pfuncs[i].dvalue; - for (int j = 0; j < pfuncs[i].ninput; j++) - delete [] pfuncs[i].svalue[j]; - delete [] pfuncs[i].svalue; - delete [] pfuncs[i].ovarname; - delete [] pfuncs[i].longstr; + delete[] pfuncs[i].itype; + delete[] pfuncs[i].ivarflag; + delete[] pfuncs[i].ivalue; + delete[] pfuncs[i].dvalue; + for (int j = 0; j < pfuncs[i].ninput; j++) delete[] pfuncs[i].svalue[j]; + delete[] pfuncs[i].svalue; + delete[] pfuncs[i].ovarname; + delete[] pfuncs[i].longstr; } /* ------------------------------------------------------------------ */ bool PythonImpl::has_minimum_version(int major, int minor) { - return (PY_MAJOR_VERSION == major && PY_MINOR_VERSION >= minor) || (PY_MAJOR_VERSION > major); + return (PY_MAJOR_VERSION == major && PY_MINOR_VERSION >= minor) || (PY_MAJOR_VERSION > major); } /* ------------------------------------------------------------------ */ void PythonImpl::finalize() { - if (Py_IsInitialized()) Py_Finalize(); + if (Py_IsInitialized()) Py_Finalize(); }