Sometimes I'd like to build the Tensorflow application as a dynamic linked library so that it can be called by other C++ applications. Although I can use Tensorflow C++ API to build the data flow graph, I'd prefer to use it's Python API because many shared models are written by that.
Following is one of my approaches that use Cython to wrap the Tensorflow application. However, it ended up with "tensorflow.pxd not found" error.
At first, here is the python code:
#File Name: HelloTensorflow.pyx
cimport numpy as np
cimport tensorflow as tf
cdef public float ExecuteTensorFlow():
x = tf.placeholder(tf.float32, [1, 2])
w = tf.constant([0.2, 0.3], tf.float32)
b = tf.constant( -0.1, tf.float32)
linearModel = tf.matmul(x, tf.reshape(w, shape=[2, 1])) + b
session = tf.Session()
result = session.run(linearModel, feed_dict={x: np.reshape([-0.1, -0.4], [1, 2])} )
return np.reshape(result, [])
and the C++ source code that will call it:
// File Name: CppCallPython.cpp
#include <Python.h>
#include "HelloTensorflow.h"
#include <iostream>
void Run(void)
{
Py_Initialize();
initHelloTensorflow();
std::cout<<"\t Execute Tensorflow:\n";
float result = ExecuteTensorFlow();
std::cout<<"\t Result = "
<<result<<std::endl;
Py_Finalize();
}
int main(void)
{
::Run();
}
and build the python code to the dynamic library by:
# File Name: createPythonLib.py
from distutils.core import setup
from Cython.Build import cythonize
setup( ext_modules = cythonize("HelloTensorflow.pyx") )
Finally, use Makefile to execute the build:
# File Name: Makefile
Target = CppCallPython
# Compiler
CC = LC_MESSAGES=C g++
CXXFLAGS = -Wall -Wextra -g
LIB_PYTHON2 = $(shell python2-config --cflags --ldflags)
MODULE_NAME = HelloTensorflow
LIB_MODULE = -L./ $(MODULE_NAME).so
.PHONY: all
all: pythonLib cppExecutable
echo Build Finished.
pythonLib:
python createPythonLib.py build_ext --inplace
cppExecutable: $(MODULE_NAME).h
$(CC) $(CXXFLAGS) $(Target).cpp $(LIB_MODULE) $(LIB_PYTHON2) -o $(Target)
As mentioned above, it ended up with "tensorflow.pxd not found" error:
missing cimport in module 'tensorflow': HelloTensorflow.pyx
Compiling HelloTensorflow.pyx because it changed.
[1/1] Cythonizing HelloTensorflow.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cimport numpy as np
cimport tensorflow as tf
^
------------------------------------------------------------
HelloTensorflow.pyx:2:8: 'tensorflow.pxd' not found
Traceback (most recent call last):
File "createPythonLib.py", line 4, in <module>
setup( ext_modules = cythonize("HelloTensorflow.pyx") )
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 877, in cythonize
cythonize_one(*args)
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 997, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: HelloTensorflow.pyx
makefile:18: recipe for target 'pythonLib' failed
make: *** [pythonLib] Error 1
Does this mean that I can't wrap Tensorflow application with Cython, because the "*.pxd" is not provided by Tensorflow? Is there any other way?
Ubuntu 16.04 LTS
Tensorflow 1.2.0 GPU
gcc version 5.4.0
Python: Python 2.7.12
Cython version 0.23.4
cimport
is a Cython-specific mechanism for importing statically defined type information from a pxd file. It does not look like tensorflow provides such a file (hence the error message). It looks like you're just using tensorflow as a Python module, in which case you should import
it instead (this probably also applies to numpy too: it does define a .pxd file, but to access the normal numpy functions you should also import
it).
Give that all your code is basically untyped Python code you should not expect huge speed improvements from using Cython.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With