如何用Cython包装Tensorflow并启用C ++调用它?

Whi*_*ers 4 python cython tensorflow

有时我想将Tensorflow应用程序构建为动态链接库,以便其他C ++应用程序可以调用它。尽管我可以使用Tensorflow C ++ API来构建数据流图,但我还是更喜欢使用它的Python API,因为许多共享模型是由该API编写的。

以下是我使用Cython包装Tensorflow应用程序的方法之一。但是,最终出现“找不到tensorflow.pxd”错误。

详情

首先,这是python代码:

#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, [])
Run Code Online (Sandbox Code Playgroud)

以及将调用它的C ++源代码:

// 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();
}
Run Code Online (Sandbox Code Playgroud)

并通过以下方式将python代码构建到动态库中:

# File Name: createPythonLib.py

from distutils.core import setup
from Cython.Build import cythonize

setup( ext_modules = cythonize("HelloTensorflow.pyx") )
Run Code Online (Sandbox Code Playgroud)

最后,使用Makefile执行构建:

# 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)
Run Code Online (Sandbox Code Playgroud)

如上所述,最终出现“找不到tensorflow.pxd”错误:

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
Run Code Online (Sandbox Code Playgroud)

这是否意味着我不能用Cython包装Tensorflow应用程序,因为Tensorflow不提供“ * .pxd”?还有其他办法吗?

系统

Ubuntu 16.04 LTS
Tensorflow 1.2.0 GPU
gcc版本5.4.0
Python:Python 2.7.12
Cython版本0.23.4

Dav*_*idW 5

cimport是特定于Cython的机制,用于从pxd文件导入静态定义的类型信息。tensorflow似乎不提供这样的文件(因此出现错误消息)。看起来您只是在使用tensorflow作为Python模块,在这种情况下,您应该import改为使用它(这也可能也适用于numpy:它确实定义了.pxd文件,但也应该使用import它来访问常规的numpy函数) 。

假设您的所有代码基本上都是无类型的Python代码,那么您不应期望使用Cython带来巨大的速度改进。