【部署】TensorRT(二)TensorRT的C++接口

2023-11-10

1.配置
qt的pro配置文件

#TensorRT
#头文件路径
INCLUDEPATH += /usr/include/x86_64-linux-gnu
#查找:sudo find / -name "NvInfer.h"

#链接TensorRT的库文件
LIBS += -L/lib/x86_64-linux-gnu -lnvinfer
LIBS += -L/lib/x86_64-linux-gnu -lnvonnxparser
LIBS += -L/lib/x86_64-linux-gnu -lnvinfer_plugin
#查找方式ldconfig -p | grep libnvinfer

2.构建模型
【参考官网】https://developer.nvidia.com/zh-cn/blog/tensorrt-c-interface-cn/

void build_model()
{
    IBuilder* builder = createInferBuilder(logger);

    //【创建网络定义】
    uint32_t flag = 1U <<static_cast<uint32_t>
        (NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);

    INetworkDefinition* network = builder->createNetworkV2(flag);

    //【创建网络定义】
    IParser*  parser = createParser(*network, logger);
     const char* modelFile="";
    parser->parseFromFile(modelFile,static_cast<int32_t>(ILogger::Severity::kWARNING));
    for(int32_t i = 0; i < parser->getNbErrors(); ++i)
    {
        std::cout << parser->getError(i)->desc() << std::endl;
    }

    //【构建配置】
    IBuilderConfig* config = builder->createBuilderConfig();
    config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1U << 20);

    IHostMemory*  serializedModel = builder->buildSerializedNetwork(*network, *config);

    delete parser;
    delete network;
    delete config;
    delete builder;
    //【保存模型】....
    delete serializedModel;
}

2.1 构建模型
构建模型可以进一步细化

bool constructNetwork(nvinfer1::IBuilder *builder, nvinfer1::INetworkDefinition *network, nvinfer1::IBuilderConfig *config, nvonnxparser::IParser *parser)
{
    // 解析onnx文件
    if (!parser->parseFromFile(modelFile,static_cast<int32_t>(ILogger::Severity::kWARNING)))
    {
        return false;
    }

    if (RUN_FP16)
    {
        config->setFlag(nvinfer1::BuilderFlag::kFP16);
    }
    if (RUN_INT8)
    {
        config->setFlag(nvinfer1::BuilderFlag::kINT8);
    }

    return true;
}

2.2 保存模型

	// 保存plan文件数据
	bool saveEngineFile(nvinfer1::IHostMemory *data)
	{
	    std::ofstream file;
	    file.open(m_engine_file, std::ios::binary | std::ios::out);
	    cout << "writing engine file..." << endl;
	    file.write((const char *)data->data(), data->size());
	    cout << "save engine file done" << endl;
	    file.close();
	    return true;
	}

    nvinfer1::ICudaEngine *m_engine;
    trt_model_stream = m_engine->serialize();
    nvinfer1::IHostMemory *data = builder->buildSerializedNetwork(*network,*config);
    saveEngineFile(data);

3.运行时
直接加载Engine

nvinfer1::ICudaEngine *m_engine;
bool loadEngineFromFile()
{
    int length = 0; // 记录data的长度
    std::unique_ptr<char[]> data = readEngineFile(length);
    nvinfer1::IRuntime *runtime = nvinfer1::createInferRuntime(sample::gLogger.getTRTLogger());
    m_engine = runtime->deserializeCudaEngine(data.get(), length);
    if (!m_engine)
    {
        std::cout << "Failed to create engine" << std::endl;
        return false;
    }
    return true;
}

运行推理应该至少包含以下几步

  1. 创建nvinfer1::IExecutionContext
  2. 为输入和输出创建空间:用于后面宿主机和设备机数据的传递
  3. 推理:图片处理+数据传递+推理
  4. 后处理:后处理每种问题各不相同

3.2.1 创建nvinfer1

    nvinfer1::IExecutionContext *context = m_engine->createExecutionContext();
    assert(context != nullptr);

3.2.2 为输入和输出创建空间

int nbBindings = m_engine->getNbBindings();
assert(nbBindings == 2); // 输入和输出,一共是2个

// 为输入和输出创建空间
void *buffers[2];                 // 待创建的空间  为指针数组
std::vector<int64_t> buffer_size; // 要创建的空间大小
buffer_size.resize(nbBindings);
for (int i = 0; i < nbBindings; i++)
{
    nvinfer1::Dims dims = m_engine->getBindingDimensions(i);    // (3, 224, 224)  (1000)
    nvinfer1::DataType dtype = m_engine->getBindingDataType(i); // 0, 0 也就是两个都是kFloat类型
    // std::cout << static_cast<int>(dtype) << endl;
    int64_t total_size = volume(dims) * 1 * getElementSize(dtype);
    buffer_size[i] = total_size;
    CHECK(cudaMalloc(&buffers[i], total_size));
}

3.2.3 推理


    // 将输入传递到GPU
    CHECK(cudaMemcpyAsync(buffers[0], cur_input.data(), buffer_size[0], cudaMemcpyHostToDevice, stream));

    // 异步执行
    t_start = std::chrono::high_resolution_clock::now();
    context->enqueueV2(&buffers[0],stream,nullptr);
   
    // 输出传回给CPU
    CHECK(cudaMemcpyAsync(out, buffers[1], buffer_size[1], cudaMemcpyDeviceToHost, stream));
    cudaStreamSynchronize(stream);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【部署】TensorRT(二)TensorRT的C++接口 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • MySQL调优学习笔记(三):组合索引和函数索引

    目录 什么是组合索引 组合索引的优势 什么是函数索引 函数索引的优势 总结 参考资料 姜承尧的MySQL实战宝典 什么是组合索引 组合索引是指由多个列所组合而成的B 树索引 组合索引既可以是主键索引 也可以是二级索引 组合索引 a b 和组
  • python3爬虫系列之使用requests爬取LOL英雄图片

    我们最终目的就是要把抓取到的图片保存到本地 所以先写一个保存图片的方法 可以保存任何二进制文件 注意在windows下文件命名包含 可能会发生错误 有的英雄皮肤名称确实包含 所以这里使用正则表达式替换下 方法包含文件路径 文件名称 文件内容
  • 多益网络社招iq_多益网络2018秋招iq测试题(二)

    我也来发一下我的秋招笔试题 不知道能不能收到礼物 1 从所给选项中选一个最合适的填入问号处使其呈现一定规律 A A B B C C D D E E 2 一个人花8块钱买了一只鸡 9块钱卖掉了 然后他觉得不划算 花10块钱又买回来了 11块卖
  • Prometheus+Grafana监控K8S 监控pod的解决方案(监控 java-JVM-pod)

    prometheus 监控 k8s pod 容器服务状态 Prometheus Grafana 作为监控K8S的解决方案 大部分都是在K8S集群内部部署 所以监控起来很方便 可以直接调用集群内的cert及各种监控url 但是增加了集群的资源
  • 杭电OJ 1071(C++)

    纯数学题 定积分 include
  • 功率放大电路

    1 什么是功率放大电路 功率放大电路与电压放大电路的主要区别是要求电路向负载提供足够大的输出功率 特点是 功率放大电路的输出电压和输出电流都应足够大的变化 其次是具有较高的效率 在功率放大电路主要解决的问题是 三极管通常工作在大信号状态 使
  • Qt使用事件(event)与定时器实现字幕滚动

    目录 1 效果展示 2 实现思路 3 滚动窗口部件 3 1 成员变量 3 2 事件重写 3 3 成员方法 3 3 方法实现 1 效果展示 我们经常能够在外面看到那种滚动字幕 那么就拿qt来做一个吧 2 实现思路 实现一个窗口部件 这个窗口部
  • 一文彻底说清楚MySQL报1055 - SELECT list is not in GROUP BY incompatible with sql_mode=only_full_group_by的问题

    先说结论 这个问题根本原因是SQL不严谨造成的 由于5 7版本之前没有严格限制所以没有报错 但5 7之后默认进行了限制 需要DBA根据实际生产情况决定是忽略该错误 还是优化SQL解决该错误 如果是要忽略该错误 那么就把5 7版本加入的默认限
  • [python] Python枚举模块enum总结

    枚举是一种数据类型 在编程中用于表示一组相关的常量 枚举中的每个常量都有一个名称和一个对应的值 可以用于增强代码的可读性和可维护性 在Python中 枚举是由enum模块提供的 而不是Python提供专用的枚举语法 关于enum模块介绍见
  • C学习点滴

    char c 8 apple orange banana printf d sizeof c printf d strlen c 答案 24 5 printf d sizeof c 这个为什么是24 很好理解 sizeof是判断类型占用大小
  • App UI自动化元素定位工具之三__weditor

    App UI自动化元素定位工具之一 weditor 1 App UI自动化的核心逻辑 1 1 查看元素 根据元素特征定位元素 1 2 操作元素 点击 输入 获取元素信息等操作 1 3 根据返回做进一步处理 代码逻辑 2 用途 2 1 and
  • JS复习-21-sql语句使用

    查询的 sql 语句 1 查询所有 SELECT FROM 表 查询这个表里面的所有数据 每一个数据的每一个字段都要 sql SELECT FROM student 2 查询所有数据 但是只要几个字段 SELECT 字段1 字段2 FROM
  • nt服务器虚拟,NT 下虚拟域名的实现-ASP教程,系统相关

    虚拟域名实际上是虚拟主机的一种 虚拟主机的出现是为了节省硬件的投资 如果 isp 为每个申请了域名的用户都使用一台单独的机器 显然费用会很高 而且对于访问不是很频繁的站点来说也是一种浪费 所以就出现了大家公用一台机器 但每个用户之间相互独立
  • windows 平台下编译openssl 最新版本-3.0.5

    根据openssl 官方仓库的描述 他们不提供二进制版本的文件 需要我们自己针对不同的平台打包 环境配置 安装好以下软件 并配置好环境变量 Perl Nasm namke exe cl exe 最后两个可以通过安装好vs2022 自动可以使
  • 分号与逗号的区别及举例_如何掌握分号的用法 和顿号有什么区别

    如何掌握分号的用法 和顿号有什么区别2019 03 08 15 57 09文 李男 考试中作文成绩因为标点符号丢分的情况时有发生 看到这样丢分的情况 令人叹息 下面小编整理了一些关于分号的用法 供大家参考 分号的用法有哪些 下列几种情况使用
  • 关于捕食者方程在matlab中的应用

    由于是非专业人士 直接找到一个例子 copy如下 首先自定义一个函数 function z weifen bulie t y z 1 y 1 0 05 y 1 y 2 z 2 y 2 0 03 y 1 y 2 end 之后直接运行 捕食者与
  • 主流性能测试工具

    目前市场上的性能测试工具较多 主流的性能测试工具有 LoadRunner QALoad SilkPerformer 和 Rational Performance Tester 这类都为负载性能测试工具 其原理都相同 首先是录制脚本 通过录制
  • android下拉框

    下拉列表的方式 layout中的 xml文件
  • 【springboot test】springboot 单元测试配置文件加载顺序及覆盖关系

    springboot test 配置文件加载顺序及覆盖关系 参照目录结构 1 配置文件加载基础原则 2 application yml主配置文件加载原则 3 application yml中指定spring profiles active
  • 【部署】TensorRT(二)TensorRT的C++接口

    1 配置 qt的pro配置文件 TensorRT 头文件路径 INCLUDEPATH usr include x86 64 linux gnu 查找 sudo find name NvInfer h 链接TensorRT的库文件 LIBS