在C中嵌入Tensorflow / Torch以集成到更大的项目中

时间:2016-11-14 18:24:39

标签: python c lua tensorflow torch

我即将开展一个更大的软件项目。现在我不知道有关它的许多细节。我唯一知道的是,现有代码是用C语言编写的,新模块必须无缝集成到其中。

在我的研究中,我将使用深度学习。我正在考虑Torch和Tensorflow。必须决定其中一个。两者似乎都很棒,因此它很大程度上取决于哪一个更容易集成到更大的C框架中。

我需要的(最有可能的)如下:

  • 在C语言中,Python / Lua脚本被调用,并在神经网络的推理步骤中移交一些数据进行处理
  • 推理步骤生成输出
  • 需要将输出返回到C以进一步处理

互联网上有很多文章特别涉及在C语言应用程序中嵌入Python / Lua脚本。所以似乎有可能。 Lua似乎使用了堆栈,Python使用特殊的Python对象。

我的具体问题是,由于使用了Torch和Tensorflow,嵌入这些脚本的方式是否会发生变化。我会遇到困难吗?如果是,为什么?有人可能已经使用过这样的嵌入吗?如果是这样的话 - 如果他们分享经验,我会很高兴=)

提前谢谢。

祝你好运!

编辑 15.11.2016: 现在要更加明确一点。我试图通过Lua Torch C API将C数组传递给Lua / LuaJIT。 Github Link to Lua Torch C API 不幸的是,我没有可以作为指导原则使用的工作示例。

但我在stackoverflow上找到了这个片段: Original Question about Lua Torch C API 我不是在解决Python和Lua这个问题的第二部分。我只想让Lua跑。

所以我从那里拿了代码:

tensor.lua:

require 'torch'
function hi_tensor(t)
   print(‘Hi from lua')
   torch.setdefaulttensortype('torch.FloatTensor')
   print(t)
return t*2
end

cluaf.h:

void multiply (float* array, int m, int n, float *result, int m1, int n1);

cluaf.c:

#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "luaT.h"
#include "TH/TH.h"

void multiply (float* array, int m, int n, float *result, int m1, int n1)
{
    lua_State *L = luaL_newstate();
    luaL_openlibs( L );

    // loading the lua file
    if (luaL_loadfile(L, "tensor.lua") || lua_pcall(L, 0, 0, 0))
    {
        printf("error: %s \n", lua_tostring(L, -1));
    }

    // convert the c array to Torch7 specific structure representing a tensor
    THFloatStorage* storage =  THFloatStorage_newWithData(array, m*n);
    THFloatTensor* tensor = THFloatTensor_newWithStorage2d(storage, 0, m, n, n, 1);
    luaT_newmetatable(L, "torch.FloatTensor", NULL, NULL, NULL, NULL);

    // load the lua function hi_tensor
    lua_getglobal(L, "hi_tensor");
    if(!lua_isfunction(L,-1))
    {
        lua_pop(L,1);
    }

    //this pushes data to the stack to be used as a parameter
    //to the hi_tensor function call
    luaT_pushudata(L, (void *)tensor, "torch.FloatTensor");

    // call the lua function hi_tensor
    if (lua_pcall(L, 1, 1, 0) != 0)
    {
        printf("error running function `hi_tensor': %s \n", lua_tostring(L, -1));
    }

    // get results returned from the lua function hi_tensor
    THFloatTensor* z = luaT_toudata(L, -1, "torch.FloatTensor");
    lua_pop(L, 1);
    THFloatStorage *storage_res =  z->storage;
    result = storage_res->data;

    return ;
}

还有以下main.c,OP没有给出:

#include"cluaf.h"

int main(void){
    float a[] = {2, 2, 3, 4};
    float b[] = {1,1,1,1};
    int m = 2;
    int n = 2;
    int m1 = 2;
    int n1 = 2;
    multiply(a,m,n,b,m1,n1);
    printf("c result %f\n", b[0]);
    printf("c result %f\n", b[1]);
    printf("c result %f\n", b[2]);
    printf("c result %f\n", b[3]);
    return 0;
}

我使用以下内容编译所有内容:

luajit -b tensor.lua tensor.o

gcc -w -c -Wall -Wl,-E -fpic cluaf.c -lluajit -lluaT -lTH -lm -ldl -L /home/manuel/torch/install/lib -I /home/manuel/torch/install/include

gcc -shared cluaf.o tensor.o -L/home/manuel/torch/install/lib -I /home/manuel/torch/install/include -lluajit -lluaT -lTH -lm -ldl -Wl,-E -o libcluaf.so

gcc -L. -Wall -o test main.c -lcluaf <- I placed the libcluaf.so in /usr/local/lib before running this command

我得到以下输出:

is function 1
Hi from lua
 2  2
 3  4
[torch.FloatTensor of size 2x2]

 4  4
 6  8
[torch.FloatTensor of size 2x2]

isudata 1
c result 1.000000
c result 1.000000
c result 1.000000
c result 1.000000

这意味着:第一部分已经有效。所以我可以给Torch一个C-array,它可以作为Tensor使用它。

问题:就像在stackoverflow的另一个问题(链接在上面)一样,我希望我的b数组中的结果是我的数组值的两倍。相反,我的数组b不会改变。

代码出了什么问题?

感谢阅读!

祝你好运

2 个答案:

答案 0 :(得分:0)

你提出了一个棘手的问题。首先,基于易于集成,我不赞成使用TensorFlow而不是Torch。我会使用对问题域的适用性。

关于“我的问题是,如果嵌入这些脚本的方式因使用Torch和Tensorflow而改变了”:

使用脚本调用Python,并调用TensorFlow来执行推理。结果返回到Python,Python将结果返回给C.因此,集成的一部分是集成Python和TensorFlow / Torch。传递给Python的脚本需要更改为使用TensorFlow或Torch。

答案 1 :(得分:0)

乘法函数的最后一行不执行任何操作:

result = storage_res->data;

您需要明确复制结果:

`for(size_t i=0;i<m1*n1; ++i)
   result[i]=storage_res->data[i];`