Importing a tensor stream when embedding python in C ++ returns null

I have a question about embedding python in a C ++ application. The setup is this: I have a large C ++ application that generates some data (renders images in real time) and displays them. I also trained a neural network in python using a tensor stream that will accept these images.

My idea was to embed python and send data as a numpy array, predict using a neural network, and return another processed numpy array for display (in C ++). I did some basic tests without the tensor flow on the python side to get an idea of ​​embedding python in c, etc., and it seems to work.

However, as soon as I put "importorororflow" in any python script that I want to import, I will get NULL from PyImport_ImportModule in the C ++ part.

eg.

import numpy as np def foo(img): return np.clip(img * 2.0, 0, 255).astype(np.uint8) 

works great. But the following:

 import numpy as np import tensorflow as tf #this causes the fail def foo(img): return np.clip(img * 2.0, 0, 255).astype(np.uint8) 

In the second case, I still get a message in stdout from tensorflow that he found cuda etc., but then the import of the module failed.

My setup is on Windows 10 x64, Anaconda Python 3.5, tensorflow-0.12, and CUDA 8. Has anyone encountered a similar problem? The other modules I tested (numpy, pil, scipy) seem to be loaded.

If it looks like it cannot be resolved, I resort to some kind of IPC between the C ++ part and python.

+4
source share
2 answers

I solved the problem. I needed to install argc and argv with PySys_SetArgv. I discovered this with PyErr_Occurred () and PyErr_Print () right after a failed import to see the problem.

+2
source

ref: https://docs.python.org/3.5/extending/embedding.html

main.cpp

 #include <Python.h> #include <iostream> #include <QString> #include <QDir> #include <cstring> using namespace std; int main(int argc, char *argv[]) { PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pValue; int i; if (argc < 3) { fprintf(stderr,"Usage: call pythonfile funcname [args]\n"); return 1; } Py_SetProgramName((wchar_t*)L"test"); Py_Initialize(); PySys_SetArgv(argc, (wchar_t**)argv); PyRun_SimpleString("import tensorflow as tf\n" "print(tf.__version__)\n"); PyRun_SimpleString("import cv2\n" "print(cv2.__version__)\n"); QString qs = QDir::currentPath(); std::wstring ws = qs.toStdWString(); PySys_SetPath(ws.data()); pName = PyUnicode_DecodeFSDefault(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); Py_DECREF(pName); if (pModule != NULL) { pFunc = PyObject_GetAttrString(pModule, argv[2]); /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { pArgs = PyTuple_New(argc - 3); for (i = 0; i < argc - 3; ++i) { pValue = PyLong_FromLong(atoi(argv[i + 3])); if (!pValue) { Py_DECREF(pArgs); Py_DECREF(pModule); fprintf(stderr, "Cannot convert argument\n"); return 1; } /* pValue reference stolen here: */ PyTuple_SetItem(pArgs, i, pValue); } pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); if (pValue != NULL) { printf("Result of call: %ld\n", PyLong_AsLong(pValue)); Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"Call failed\n"); return 1; } } else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); } Py_XDECREF(pFunc); Py_DECREF(pModule); } else { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", argv[1]); return 1; } Py_Finalize(); return 0; } 

multiply.py

 import tensorflow as tf import cv2 def multiply(a,b): print(tf.__version__) print(cv2.__version__) print("Will compute", a, "times", b) c = 0 for i in range(0, a): c = c + b return c 
+1
source

Source: https://habr.com/ru/post/1271724/


All Articles