赞
踩
该系列文章与qwe、Dorothea一同创作,喜欢的话不妨点个赞。
在create_core
方法结束后,我们的视角回到了main.cpp中。继续来看接下来的流程。本章的重点在于pytorch导出的tensor数据的解析。
流用于表示一系列的命令(如内存传输命令和核函数执行命令)在 GPU 上的执行顺序。流中的命令按照它们被插入的顺序在 GPU 上执行,但不同流中的命令可以并行执行。这里主要用于更新数据、推理和可视化时使用。
这里会打印出执行CUDA-BEVFusion时,终端打印的信息中的网络信息。
从这里我们能清楚的看到一下几点:
输出的网络数量与onnx数量是一一对应的。
print
的具体实现在下方。
这部分用于打印这四个 engine 的信息,包含模型名称和绑定点的信息(输入输出是否为动态形状,输入输出节点索引、名称、维度和类型)。
是否计时,这里设置为true
core
是CoreImplement
的一个实例,而CoreImplement
继承了类Core
在类Core
中set_timer是一个纯虚方法。
用于后续判断是否打印推理时每个模块的用时。
nv::Tensor
、nv::format
是 Nvidia 提供在 src/common
中的工具.tensor
后缀的文件,均是从pytorch中导出,保存的二进制文件。nv::format
函数,传入格式字符串 "%s/camera2lidar.tensor"
和 data
指针。这里的 %s
是一个占位符,用于指示将在这个位置插入一个字符串。format
函数内部,函数首先定义一个字符数组 buffer[2048]
作为存储结果的缓冲区。然后,它使用 va_list vl
初始化可变参数列表,并通过 va_start(vl, fmt)
宏开始访问这些参数。vsnprintf
函数,将 data
指针所指向的字符串(即 "example-data"
)和格式字符串合并。vsnprintf
根据格式字符串 "%s/camera2lidar.tensor"
替换 %s
为 data
指向的字符串,因此格式化后的字符串将变为 "example-data/camera2lidar.tensor"
。vsnprintf
函数使用 sizeof(buffer)
确保不会向 buffer
写入超出其容量的数据,从而避免缓冲区溢出。这是一个重要的安全特性,确保即使格式化的字符串非常长,也不会导致内存损坏。buffer
中。format
函数最后将 buffer
转换为 std::string
类型并返回这个字符串。通过上图,我们就可以发现,.tensor
后缀的文件存储的数据,可以分为数据头
,和数据
两个部分。
数据头
,即描述数据
信息的属性,例如shape、numel、ndim。描述数据
的信息。
数据
,即具体的数据的起始地址。
通过数据的读取,我们可以大致看一下作者是如何设计的。
dims
来存储每个维度的数值,使用 shape
来储存形状,用于后续创建 Tensor
。计算矩阵的总参数量 volumn
,然后通过每个数据占用空间 dtype
和总参数量 volumn
来计算储存矩阵数据需要的空间 bytes
。host
上使用容器 host_data
来储存。host
上创建 Tensor
对象,并将数据拷贝到 output
中。
nv::Tensor
是一个通用的pytorch与c++数据联通的桥梁,值得一看。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。