cmake编译
最近使用LibTorch在调用分类模型,在配置环境时,用到了1.4版本的PyTorch,按照网上的一些教程无法成功,便把自己部署成功的经验分享出来。
1. 从官网下载已经编译好的LibTorch库
官网地址:(https://pytorch.org/)
根据自己的环境可以下载GPU版和CPU版。
2. 使用cmake命令创建项目,失败!
安装使用可参考官网文档:https://pytorch.org/cppdocs/installing.html
遇到的问题:
使用cmake命令,并不能一次成功,主要是一些配置项不成功,如下
3. 使用CMake-GUI配置项目,成功。
在使用cmake命令不成功的情况下,可以采用cmake-gui,方便配置环境。
报 CMAKE_PREFIX_PATH未设定的错误,使用Add Entry添加该条目,并设置libtorch的路径(下载后的路径)
添加Entry后,点击Configure,配置成功,然后点击Generate生成项目。
4. 直接使用Visual Studio 创建项目,成功
1) 新建C++空项目, 选择x64,Release(根据从官网下载的不同版本确定)
2) 添加新建项目,创建main.cpp文件,添加如下代码:
#include <torch/torch.h>
#include <iostream>
int main() {
torch::Tensor tensor = torch::rand({ 2, 3 });
std::cout << tensor << std::endl;
}
3) 添加包含目录和库目录
链接器-> 输入-> 附加依赖项,添加:c10.lib; torch.lib
4) 修改C++ -> 语言 -> 符合模式,为 否
5) 编译生成,成功。
6) 运行之前需要把在torch.lib目录下的所有dll拷贝到exe目录下。
注意:
使用VS2015编译报错,错误C2872 “std”: 不明确的符号。
使用vs2017编译后,解决,猜测是libtorch1.4版本需要更高的C++版本。
VS2019编译libtorch
1、引用关系
以vs下libtorch引用CUDA为例:
包含目录:
-
libtorch_dir/include
-
libtorch_dir/include/torch/csrc/api/include
库目录:
libtorch_dir/lib
动态库:
c10.lib
c10_cuda.lib
torch_cpu.lib
torch_cuda.lib
测试代码:
#include<iostream>
#include<torch/script.h>
#include <torch/torch.h> # cuda相关函数头文件
#include<memory>
int main()
{
std::cout <<"cuda::is_available():" << torch::cuda::is_available() << std::endl;
system("pause");
}
直接运行,输出: “cuda::is_available(): 0”,显卡未调用起来。
Windows10系统下使用LibTorch 1.5、1.6,使用Visual Studio进行C++开发时,Torch::cuda::is_available()返回值为0(使用cmake来构建工程,是可以正常编译和执行)。
解决方法:
1)使用VS2017及以上版本;
2)windows上装的cuda版本需要与下载的libtorch的cuda版本相对应;
3)在“属性 --> 链接器 --> 命令行 --> 其他选项”中添加:
/INCLUDE:?warp_size@cuda@at@@YAHXZ
至此,问题解决。
2、cuda相关函数
torch::cuda::is_available() // CUDA是否可用
torch::cuda::cudnn_is_available() // cuDNN 是否可用
torch::cuda::device_count() // 可使用的GPU个数
3、GPU/CPU模式
libtorch默认使用的是CPU,设为使用GPU推理,只需将数据和模型加载至GPU中,API如下:
model.to(at::kCUDA); // 模型加载至GPU
timg = torch::ones({ 1, 3, 224, 224 }).to(at::kCUDA); // 数据加载至GPU
std::vector<torch::jit::IValue> inputs;
inputs.push_back(timg);
数据/模型加载最佳方式:
torch::DeviceType device_type = at::kCPU; // 定义设备类型
if (torch::cuda::is_available())
device_type = at::kCUDA;
model.to(device_type);
std::vector<torch::jit::IValue> inputs;
inputs.push_back(torch::ones({ 1, 3, 224, 224 }).to(device_type));