VS2015编译TensorFlow C++程序完全攻略

VS2015编译TensorFlow C++程序完全攻略

本文参考和综合了多篇网络博客文章,加以自己的实践,最终终于在windows环境下,编译出可以用于C++程序调用tensorflow API的程序,并执行成功

考虑到网络上关于这方面的资料还较少,特总结全过程如下,希望能帮助到有需要的码农朋友,文中有部分文字步骤是借鉴他人文章,引用路径在最后列出。

一、环境准备:

  1. 安装visual stduio2015
  2. 安装Swigwin-3.0.12,注意其下载解压以后即可使用,本人放置路径在D:/lib/swigwin-3.0.12,可执行文件地址为 D:/swigwin-3.0.12/swig.exe
  3. 安装python3.6,安装时注意选择将路径添加到环境变量。
  4. 安装CMake-3.8.0 ,安装时注意选择将路径添加到环境变量。
  5. 安装Git,用于在编译过程中从GitHub上下载依赖项。
  6. 将GitHub上TensorFlow的master分支 下载并解压到文件夹D:\tf中,编辑文件tensorflow/tensorflow/contrib/cmake/CMakeLists.txt,将第87行至93行修改如下:
复制代码
 1 if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH)
 2   include(CheckCXXCompilerFlag)
 3   CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
 4   if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED)
 5     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
 6   else()
 7     CHECK_CXX_COMPILER_FLAG("/arch:AVX" COMPILER_OPT_ARCH_AVX_SUPPORTED)
 8     if(COMPILER_OPT_ARCH_AVX_SUPPORTED)
 9       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX")
10     endif()
11   endif()
12 endif()
复制代码

 二、使用CMAKE设置各项编译参数

  1. 打开下载tensorflow源文件的根目录,本文路径是E:TF Code/TensorFlow,在路径下进入../tensorflow\contrib\cmake, 新建文件夹\build。
  2. 打开已安装的CMAKE-GUI工具,进行各项编译选项的配置,本文配置界面如下:
  3.             
  4. 点击configue,下方提示Configuring done后,点击Generate,等待Generating done后完成编译设置。如果中间有报错,请检测各路径设置是否正确。

三、编译生成tensorflow库文件:

  1.  打开visual studio2015,打开E:\TF Code\tensorflow\tensorflow\contrib\cmake\build下的ALL_BUILD项目。我们在此只以release版本为例,所以检查编译平台是
  2. 点击生成解决方案,编译的时间很长,我的笔记本电脑编译一次大概3到4个小时,编译到最后一般都会报错
    fatal error C1060: compiler is out of heap space 没关系,等待整个工程全部编译完成(据说内存特别大的电脑不会报)。
  3. 找到tf_core_kernels项目,右键单独编译,操作如下图。

    

  4. tf_core_kernels项目编译成功后,再同样对tensorflow_static作单独编译,最后再对tensorflow作单独编译。.

  这样tensorflow.lib和tensorflow.dll文件就可以编译出来了,生成的库文件路径在

     ..\tensorflow\tensorflow\contrib\cmake\build\Release下。

四、使用tensorflow库文件编写C++程序

  1. 在vs2015中创建一个新的Win32控制台工程TestTensorFlow,注意也必须把编译平台设置成
  2. 新建一个TestTensorFlow.h,在其中输入
    1
    2
    3
    4
    #pragma once
     
    #define COMPILER_MSVC
    #define NOMINMAX  
  3. 对应的TestTensorFlow.CPP文件中输入如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    // TestTensorFlow.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
     
    #include <vector>
    #include <eigen/Dense>
     
    #include "TestTensorFlow.h"
    #include "tensorflow/core/public/session.h"
    #include "tensorflow/cc/ops/standard_ops.h"
    using  namespace  tensorflow;
     
    GraphDef CreateGraphDef()
    {
         Scope root = Scope::NewRootScope();
     
         auto  X = ops::Placeholder(root.WithOpName( "x" ), DT_FLOAT,
             ops::Placeholder::Shape({ -1, 2 }));
         auto  A = ops::Const(root, { { 3.f, 2.f },{ -1.f, 0.f } });
     
         auto  Y = ops::MatMul(root.WithOpName( "y" ), A, X,
             ops::MatMul::TransposeB( true ));
     
         GraphDef def;
         TF_CHECK_OK(root.ToGraphDef(&def));
     
         return  def;
    }
     
    int  main()
    {
         GraphDef graph_def = CreateGraphDef();
     
         // Start up the session
         SessionOptions options;
         std::unique_ptr<Session> session(NewSession(options));
         TF_CHECK_OK(session->Create(graph_def));
     
         // Define some data.  This needs to be converted to an Eigen Tensor to be
         // fed into the placeholder.  Note that this will be broken up into two
         // separate vectors of length 2: [1, 2] and [3, 4], which will separately
         // be multiplied by the matrix.
         std::vector< float > data = { 1, 2, 3, 4 };
         auto  mapped_X_ = Eigen::TensorMap<Eigen::Tensor< float , 2, Eigen::RowMajor>>
             (&data[0], 2, 2);
         auto  eigen_X_ = Eigen::Tensor< float , 2, Eigen::RowMajor>(mapped_X_);
     
         Tensor X_(DT_FLOAT, TensorShape({ 2, 2 }));
         X_.tensor< float , 2>() = eigen_X_;
     
         std::vector<Tensor> outputs;
         TF_CHECK_OK(session->Run({ {  "x" , X_ } }, {  "y"  }, {}, &outputs));
     
         // Get the result and print it out
         Tensor Y_ = outputs[0];
         std::cout << Y_.tensor< float , 2>() << std::endl;
     
         session->Close();
         getchar ();
    } 
  4.  设置要包含的tensorflow头文件路径,右键项目属性——C/C++——附加包含目录
  5. D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build\Release
    D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build\external\nsync\public
    D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build\protobuf\src\protobuf\src
    D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build
    D:\soft\tensorflow-r1.6

    lib目录:
    D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build\Release

    PLATFORM_WINDOWS

    报错1:
    严重性 代码 说明 项目 文件 禁止显示状态
    错误 C3872 “0x3000”: 此字符不允许在标识符中使用 tf_test01 e:\project\tf_test01\tf_test01\TestTensorFlow.h 5
    原因:有中文空格

    报错2:
    严重性 代码 说明 项目 文件 禁止显示状态
    错误 C1014 包含文件太多: 深度 = 1024 tf_test01 D:\soft\tensorflow-r1.6\third_party\eigen3\unsupported\Eigen\CXX11\Tensor 1


    头文件引用重复:unsupported:

    D:\soft\tensorflow-r1.6\tensorflow\contrib\cmake\build\external\eigen_archive
    D:\soft\tensorflow-r1.6\third_party\eigen3
    删掉头文件引用:
    D:\soft\tensorflow-r1.6\third_party\eigen3
  6.  引入tensorflow.lib文件,右键项目——添加——现有项,找到..\tensorflow\tensorflow\contrib\cmake\build\Release下的tensorflow.lib 

             

  5.  设置预编译选项,右键属性——C/C++——预处理器,预处理器定义中加入PLATFORM_WINDOWS

            

  6. 编译TestTensorFlow项目,就可以成功生成TestTensorFlow.exe了。

  7.直接运行程序,会报错

  8,把..\tensorflow\tensorflow\contrib\cmake\build\Release下的tensorflow.dll拷贝到TestTensorFlow.exe同文件夹下,再运行即可成功得到输出结果如下:

     

     输出结果有一句警告,好像是我编译参数还是跟CPU功能有不匹配,但是不影响执行结果,有知道如何解决的朋友可以留言给我,谢谢。

       参考:https://www.cnblogs.com/steven_oyj/p/8259205.html


猜你喜欢

转载自blog.csdn.net/jacke121/article/details/80473648