Embed a stateful Python script into C++ program using boost::python - c++

I have a C++ program that keeps generating data. I have a python class that process these data. I want to use this python class to process the data: when each time a data point is generated, I can use this python script to process the data. But this python script must be "stateful", i.e. it should be able to remember what it did before this data point.
One super basic example is, my C++ program just generates numbers, and my python class calculates the cumulative sums of the numbers generated:
Python:
class CumSum:
def addone(x):
self._cumsum += x;
print self._cumsum;
C++
[Somehow construct a CumSum instance, say c]
for (int i=0; i<100000; i++) {
int x = rand() % 1000;
[Call c.addone(x)]
}
I heard boost::python is a good way to handle this. Can anyone sketch out how to do it? I tried to read boost documents but they were too huge for me to digest.
I appreciate your help.

For basic information about how to execute your python script:
http://www.boost.org/doc/libs/1_47_0/libs/python/doc/tutorial/doc/html/python/embedding.html
For details on manipulating python objects in C++
http://www.boost.org/doc/libs/1_47_0/libs/python/doc/tutorial/doc/html/python/object.html
Much of boost-python is concerned with exporting your C++ classes to python but you aren't doing that so you can ignore it.
You may be better off using a simpler wrapper like SCXX
http://davidf.sjsoft.com/mirrors/mcmillan-inc/scxx.html

Related

Understanding tflite examples in documentation

I've been trying to figure out how to use tflite with c++ for a raspberry pi project, and I've had trouble understanding documentation and how to perform inference. I've been confused about the code shown on this page:
https://www.tensorflow.org/lite/api_docs/cc/class/tflite/interpreter
For context, I am inexperienced in c++, and usually work with python and matlab.
Here are the lines of code I'm trying to understand:
auto input = interpreter->typed_tensor(0);
for (int i = 0; i < input_size; i++) {
input[i] = ...; interpreter->Invoke();
My understanding of these lines is - They set input equal to the typed_tensor function of interpreter, with (0) as the input.
Then, they loop for values of i between 0 and input_size. For each i value, they make the inpt[i] equal to some value. They then call interpreter->Invoke(), which has the neural net perform inference, with input[i] as the input?
This is then repeated for each i value, each time calling interpreter->Invoke() with input[i] as the input to the neural net.
Is my understanding of this process correct?
What shape should the input take? For example, if I had converted a tensorflow model that takes a 1x100 input and then converted this to a tflite model, how would I create the input to feed into the tflite model in c++?
What data type should the input to the tflite model be in?
Thank you,
Simon
I've tried looking at example code of other people's uses of tflite in c++, but I haven't been able to examine the inputs to their models. I would also appreciate help with viewing the input tensors while debugging. I'm using code::blocks as an IDE for now.

How to get source code from PyCodeObject in c python api?

Hi i'm using c python api.
I want to extract function object's source code.
I want pure python code (like def func: ... ) But if it is hard then, i want to
get py byte codes at least.
Here is my c++ code that i get PyCodeObject from PyFunctionObject.
//pObject is PyFunctionObject which is python standard lib's function.
PyFunctionObject* pFunctionObject = (PyFunctionObject*)pObject;
PyCodeObject* codeObject = (PyCodeObject*)pFunctionObject->func_code;
PyObject* strObject = codeObject->co_code; //get code from code object
char * sourceCode = PyString_AsString(strObject); //convert to string
But sourceCode variable(char*) always show only 1 byte.
How should i gonna get this?
There is a lot of ways to do this in python code side, like just use 'dis' or 'inspect' module.
But i want to do this by c python api.
P.S
I guess that the PyCodeObject's co_code member is an byte array.
I used visual studio debug memory view and saw co_code member's adjoined memory byte but it seems like a byte code array(just maybe).
Firstly, PyCodeObject->co_code is the generated byte code, not pure Python source code.
In Python, we could use inspect.getsource to get pure Python source code. And in C, you could also use it via PyObject_CallMethod

Is it possible to call Matlab from QtCreator?

I am doing image analysis using C++ in the QtCreator environment. In order to build a learning model, I want to use the TreeBagger class from MATLAB, which is really powerful. Can I call MATLAB from QtCreator, give it some parameters, and get back the classification error? Can I do this without using mex files?
From QProcess's Synchronous Process API example:
QProcess gzip;
gzip.start("gzip", QStringList() << "-c");
if (!gzip.waitForStarted())
return false;
gzip.write("Qt rocks!");
gzip.closeWriteChannel();
if (!gzip.waitForFinished())
return false;
QByteArray result = gzip.readAll();
The concept to from this example is the process of being able to execute matlab w/ whatever settings that would be preferable and begin writing a script to it immediately. After the write; you can close the channel, wait for response, then read the results from matlab. Uunfortunately, I'm not experienced w/ it to provide a more direct example, but this is the concept for the most case. Please research the documentation for anything else.
Matlab has an "engine" interface described here to let standalone programs call matlab functions. It has the advantage that you can call engPutVariableand engGetVariable to transfer your data in binary format (I think it works by using shared memory between your process and matlab, but I'm not sure on this), so you don't have to convert your data to ascii and parse the result from ascii.
For c++ you might want to write a wrapper class for RAII or have a look at http://www.codeproject.com/Articles/4216/MATLAB-Engine-API, where this has already been done.

Moving matrix from c++ to Matlab

I'm trying to take a matrix from c++ and import it to Matlab to run bintprog on this matrix, call it m. My c++ code generates these matrices of a certain type, and I need to run bintprog on them quickly, and with ideally millions of matrices.
So any of the following would be great:
A way to import a bunch of matrices at once so I can run a lot of iterations thru my Matlab code.
Or
If I could implement Matlab code right in c++ nicely.
If this is not clear leave me comments and I'll update what I can.
You can call Matlab commands from C++ code (and vice versa):
Compile your C++ code into a mex function and call bintprog using mexCallMatlab.
As proposed by Mark, you may call Matlab engine from native C++ code using matlab engine.
You may compile your C++ code as a shared library and call it from Matlab using calllib.
I suggest the simple solution, assuming that your matrices are kept in 3-dimmensional array:
Build a loop in C++, to save your matrices... Something like this:
ofstream arquivoOut0("myMatrices.dat");
for(int m=0;m<numberMatrices;m++){
for (int i=0; i< numberlines;i++){
for(int j=0;j<numberColumns;j++)
if(j!=numberColumns-1) arquivoOut0<< matrices[m][i][j] << "\t";
else arquivoOut0<< matrices[m][i][j] << "\n";
}
}
}
arquivoOut0.close();
Ok. You have saved your matrices in an ascii file! Now you have to read it in Matlab!
load myMatrices.dat
for m=1:numberMatrices
for i=1:numberLines
for j=1:numberColumns
myMatricesInMatlab(m,i,j)=myMatrices((m-1)*numberLines+i,j);
end
end
end
Now, you can use the toolbox that you need:
for i=1:numberMatrices
Apply the toolbox for myMatricesInMatlab(i,:,:);
end
I think it works, it the processing time is not an issue!

how to pass a value to c++ from python and back?

i would like to pass values from python to a c++ program for an encryption from inside a python program and then return the value from there to the python program . how to do it?
If you want to use some existing Unix-style command line utility that reads from stdin and writes to stdout, you can use subprocess.Popen by using Popen.communicate():
import subprocess
p = subprocess.Popen(["/your/app"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = p.communicate(input)[0]
As said msw in the other post, the proper solution is using PyObject.
If you want to have a two-way communication between C++ & Python, Boost Python would be interesting for you. Take a look at website Boost Python,
This post would also be interesting:
How to expose a C++ class to Python without building a module