'Embed Python script (with imported modules) into C++, Error: pybind11::error_already_set at memory location
I'm attempting to embed a python script into C++. The idea is to take values from C++, send them to the python script which contains a deep learning model, have the model predict based off of the C++ values, and then send that predicted value back to C++. The code works initially, the values are sent and the prediction is made. However, this code will be called repeatedly, and when it tries to execute again, I get the following error: "Microsoft C++ exception: pybind11::error_already_set at memory location 0x006fa998.." multiple times leading to the final error: "Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt." I know it's the python code because the C++ is a much larger code that worked fine before I attempted to embed the python script.
Using PyErr_Print(); gives the following output: File "C:\Users\Cloud\Desktop\DTS GPU 4\x64\Release\py_thread.py", line 5, in module. This indicates it breaks when importing numpy. I'm guessing it has something to do with the way I am importing the modules, so when it tries to execute the script again, the module tries to reload leading to the error. Any help would be greatly appreciated! I've been troubleshooting this problem for the last two days to no avail.
Python script below:
import time
import threading
import importlib
np = importlib.import_module('numpy')
tf = importlib.import_module('tensorflow')
model = tf.keras.models.load_model("C:/Users/Cloud/.spyder-py3/AAPM_2021/weights/corrected_crayz/Dcorsur_testfixed_2fields_ts1_ep150_bs8_256re_2re.hdf5", compile = False)
z = 0
pred = 0
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self, q,w,e,r,t,y,u,i,o,p,n,l):
z = np.array([[q, w, e, r, t, y, u, i, o, p, n, l]])
pred = model.predict(z)
print(pred)
return pred
C++ Embedding code below:
void Patient::CalcLensDose()
{
double field_x, field_y, kVp, filter_type, r_l_eye, CRA_CAU, RAO_LAO, Eye_size, Nose_size, X_shift, Y_shift, Z_shift, dose;
dose = 0;
field_x = 5; field_y = 5; kVp = 70; filter_type = 3;
r_l_eye = 1.0; CRA_CAU = 30; RAO_LAO = 0; Eye_size = 3; Nose_size = 2; X_shift = 0, Y_shift = 0; Z_shift = 0;
*PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pClass, *pInstance;
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
pName = PyUnicode_FromString("py_thread");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (!pModule)
{
PyErr_Print();
std::cout << "pModule failed";
}
pDict = PyModule_GetDict(pModule);
Py_DECREF(pModule);
if (!pDict)
{
PyErr_Print();
std::cout << "pDict failed";
}
pClass = PyDict_GetItemString(pDict, "MyThread");
Py_DECREF(pDict);
if (!pClass)
{
PyErr_Print();
std::cout << "pClass failed";
}
if (PyCallable_Check(pClass))
{
pInstance = PyObject_CallObject(pClass, NULL);
Py_DECREF(pClass);
if (!pInstance)
{
PyErr_Print();
std::cout << "pInstance failed";
}
pValue = PyObject_CallMethod(pInstance, "run", "(dddddddddddd)", field_x, field_y, kVp, filter_type,
r_l_eye, CRA_CAU, RAO_LAO, Eye_size, Nose_size, X_shift, Y_shift, Z_shift);
Py_DECREF(pInstance);
PyErr_Print();
dose = (double) PyFloat_AsDouble(pValue);
PyErr_Print();
Py_DECREF(pValue);
if (!dose)
{
PyErr_Print();
std::cout << "dose failed";;
}
}
Py_Finalize();
(*LensDose) += dose;
}
I'm using Visual Studio 2010 and Python 3.8.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
