写一个tensorrt的c++部署模板
时间: 2023-08-08 12:09:46 浏览: 89
基于YOLOv9 + ByteTracker目标追踪部署tensorrt源码C++版.zip
好的,以下是一个简单的TensorRT C++部署模板,你可以根据自己的需求进行修改:
```c++
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <ctime>
#include "NvInfer.h"
#include "NvOnnxParser.h"
#include "NvUffParser.h"
#include "NvInferPlugin.h"
#include "NvUtils.h"
using namespace nvinfer1;
using namespace nvonnxparser;
using namespace nvuffparser;
using namespace plugin;
// 定义输入和输出张量大小
const int BATCH_SIZE = 1;
const int INPUT_CHANNEL = 3;
const int INPUT_HEIGHT = 224;
const int INPUT_WIDTH = 224;
const int OUTPUT_SIZE = 1000;
// 定义TensorRT日志回调函数
void logCallback(const char* msg, const char* /*file*/, int /*line*/) {
std::cout << "[TensorRT] " << msg << std::endl;
}
int main(int argc, char** argv) {
// 创建Logger对象
Logger logger;
logger.log(ILogger::Severity::kINFO, "TensorRT version: " + std::to_string(getInferLibVersion()));
// 创建Builder对象
IBuilder* builder = createInferBuilder(logger);
if (!builder) {
std::cerr << "Failed to create builder." << std::endl;
return -1;
}
// 创建NetworkDefinition对象
INetworkDefinition* network = builder->createNetwork();
if (!network) {
std::cerr << "Failed to create network." << std::endl;
return -1;
}
// 创建ONNX解析器对象
IParser* parser = createParser(*network, logger);
if (!parser) {
std::cerr << "Failed to create parser." << std::endl;
return -1;
}
// 从ONNX模型文件中解析网络结构
std::string onnxModelFile = "model.onnx";
parser->parseFromFile(onnxModelFile.c_str(), static_cast<int>(ILogger::Severity::kWARNING));
if (parser->getNbErrors() > 0) {
std::cerr << "Failed to parse ONNX model." << std::endl;
return -1;
}
// 构建推理引擎
builder->setMaxBatchSize(BATCH_SIZE);
builder->setMaxWorkspaceSize(1 << 30);
builder->setFp16Mode(true);
builder->setInt8Mode(false);
ICudaEngine* engine = builder->buildCudaEngine(*network);
if (!engine) {
std::cerr << "Failed to build engine." << std::endl;
return -1;
}
// 创建ExecutionContex对象
IExecutionContext* context = engine->createExecutionContext();
if (!context) {
std::cerr << "Failed to create execution context." << std::endl;
return -1;
}
// 分配输入和输出内存
std::vector<float> inputData(BATCH_SIZE * INPUT_CHANNEL * INPUT_HEIGHT * INPUT_WIDTH);
std::vector<float> outputData(BATCH_SIZE * OUTPUT_SIZE);
// 生成随机数据作为输入
srand(time(nullptr));
for (size_t i = 0; i < inputData.size(); i++) {
inputData[i] = static_cast<float>(rand()) / RAND_MAX;
}
// 将输入数据传输到显存中
void* inputDevice = nullptr;
cudaMalloc(&inputDevice, inputData.size() * sizeof(float));
cudaMemcpy(inputDevice, inputData.data(), inputData.size() * sizeof(float), cudaMemcpyHostToDevice);
// 分配GPU内存作为输出
void* outputDevice = nullptr;
cudaMalloc(&outputDevice, outputData.size() * sizeof(float));
// 创建CUDA流
cudaStream_t stream = nullptr;
cudaStreamCreate(&stream);
// 执行推理
std::vector<void*> bindings(2);
bindings[0] = inputDevice;
bindings[1] = outputDevice;
context->enqueueV2(bindings.data(), stream, nullptr);
cudaStreamSynchronize(stream);
// 将输出数据从显存中传输回CPU内存
cudaMemcpy(outputData.data(), outputDevice, outputData.size() * sizeof(float), cudaMemcpyDeviceToHost);
// 打印输出结果
for (size_t i = 0; i < outputData.size(); i++) {
std::cout << outputData[i] << " ";
}
std::cout << std::endl;
// 释放资源
cudaStreamDestroy(stream);
cudaFree(inputDevice);
cudaFree(outputDevice);
context->destroy();
engine->destroy();
network->destroy();
parser->destroy();
builder->destroy();
return 0;
}
```
在这个模板中,我们首先创建了一个Logger对象用于记录TensorRT的日志信息,然后创建了一个Builder对象用于构建推理引擎,接着创建了一个NetworkDefinition对象用于描述网络结构,然后创建了一个ONNX解析器对象用于从ONNX模型文件中解析网络结构,接着使用Builder对象构建推理引擎,创建ExecutionContex对象用于推理,分配输入和输出内存并生成随机数据作为输入,将输入数据传输到显存中,然后执行推理,将输出数据从显存中传输回CPU内存,并打印输出结果。最后释放资源。
需要注意的是,在实际应用中,你需要根据自己的模型及数据进行修改。同时,这里使用了FP16精度模式和CUDA流进行加速,如果你的GPU不支持FP16精度模式,可以将其设置为false。如果你不需要使用CUDA流,可以直接传入nullptr。
阅读全文