MIT-BEVFusion系列九--CUDA-BEVFusion部署3 create_core方法1

该系列文章与qwe一同创作,喜欢的话不妨点个赞。

初始化 bevfusion::CoreImplement 对象—重点之create_core()方法。

接着上次,在所有参数构建完毕够,另一个重点在于250行的,create_core方法。下面总体来看一下他的主要作用。

在这里插入图片描述

  • 输入:CoreParameter—包含了所有需要的参数
  • 返回值std::shared_ptr
  • 作用:用已经设置好参数,来配置初始化 bevfusion::Core 对象,返回 bevfusion::Core 对象共享指针

在这里插入图片描述

通过上面的图片可以看出,create_core方法主要通过init方法构建bevfusion::Core 对象共享指针。
这里使用了RAII的思想,关键点在于init方法,具体见下图

在这里插入图片描述
根据上述图片能发现,init方法中有很多具体的方法构成。分析如下:

  1. 一、反序列化各个网络的 engine、在 GPU 开辟输出数据的内存
    1. create_backbone:反序列化 camera.backbone.plan 创建 engine,并为输出分配内存
      1. 反序列化 engine、开辟输出内存。
      2. 输入内存是在预处理的时候开辟内存。
    2. create_vtransform:反序列化 camera.vtransform.plan 创建 engine,并为输出分配内存
    3. create_transfusion:反序列化 fuser.plan 创建 engine,并为输出分配内存
    4. create_transbbox:反序列化 head.bbox.plan 创建 engine。初始化检测框相关参数,并分配内存
      1. 也是给输出数据分配内存,稍微特殊点,即给 cpu 分配内存,又给 gpu 分配内存。
        1. 一个是给 output_device_size_ 以及 output_host_size_ 分配 unsigned int 大小个字节,用来记载框的数量
        2. 第二个是给 output_device_boxes_ 以及 output_host_boxes_ 分配 MAX_DETECTION_BOX_SIZE * sizeof(BoundingBox)个即 1024*44 个字节大小,用于记载框的信息。
        3. output_cache_.resize(MAX_DETECTION_BOX_SIZE); std::vector<BoundingBox> 类型的 vector 容器: output_cache_ 进行 resize(1024)
    5. create_scn:初始化体素参数,并分配内存
      1. 特殊点在于直接从 onnx 构建 spaconv::Engine
      2. 另一个特殊点是通过 create_voxelization,为后面 voxelization 操作分配哈希表等需要的数据的内存。
  2. 二、仅开辟内存,无反序列化
    1. create_bevpool:初始化 bevpool 参数,并为输出分配内存
      • 开辟 80360360 的输出内存。
    2. create_normalization:初始化图像预处理的参数,并为原始图像特征和预处理后的图像特征分配内存
      • 为原始图像分配内存:1600900361
      • 为预处理后的图像分配内存:256704361
    3. create_depth:初始化相关参数,为变换矩阵和基于点云数据的图像深度分配内存
      • 初始化相关参数,为变换矩阵和基于点云数据的图像深度分配内存
    4. create_geometry
      • 为 frustum、Geometry、内参矩阵等分配内存
      • 核函数:create_frustum_kernelc 初始化视锥点
初始化指向 bevfusion::camera ::Backbone 对象的指针

关键点仍然是看init方法。
在这里插入图片描述

在这里插入图片描述

构建推理引擎

关于相机部分,既有反序列化网络的 engine、又有在 GPU 开辟输出数据的内存

上图43行,用于构建推理引擎。内部具体分析如下

创建一个指向 bevfusion::camera::BackboneImplement 对象的智能指针,并进行初始化。

首先是构建推理引擎,通过 TensorRT::load 函数来实现,入参序列化的engine文件 的路径。变量 engine_ 是一个指向 TensorRT::Engine 对象的指针,通过 TensorRT::load 函数根据 序列化的engine文件 camera.backbone.plan 来构建推理引擎。

在这里插入图片描述

创建一个指向 TensorRT::Engine 对象 (TensorRT::EngineImplement) 的智能指针,根据数据构建 engine

在这里插入图片描述
在这里插入图片描述

序列化的engine文件 中读取数据。
在这里插入图片描述

构建一个指向 __native_engine_context 对象的指针,然后根据读取的数据、数据大小和文件名构建 engine
在这里插入图片描述

  • 109 行,将 context_engine_runtime 指针指向的对象销毁,变为空。
  • 117 行,将 runtime_ 指针指向一个指向 nvinfer1::IRuntime 对象 (通过 nvinfer1::createInferRuntime 函数构建) 的智能指针。
  • 123 行,将 engine_ 指针指向一个指向 nvinfer1::ICudaEngine 对象 (通过 deserializeCudaEngine 函数构建) 的智能指针。
  • 130 行,将 context_ 指针指向一个指向 nvinfer1::IExecutionContext 对象 (通过 createExecutionContext 函数构建) 的智能指针。

这三个指针的销毁方式都是通过 destroy_pointer 函数实现。定义好了 context_,后续可以通过 enqueue 函数来进行推理。

  • 这里我们对比下原始的 TensorRT 反序列化推理的流程。也是 runtime->engine->context 的过程。
    在这里插入图片描述

在这里插入图片描述

经过这些操作,一个指向 TensorRT::Engine 对象的指针就初始化完成了。

初始化存储输出的容器
  • 具体体现在46行与47行。以下图代码为例子。camera网络部分有两个输入,两个输出。static_dims方法输入int数值2和3,即调用两个输出的形状,具体实现见下方。
    在这里插入图片描述

  • 这里特意要注意一下 onnx 导出的时候,做了 transpose。
    在这里插入图片描述

在这里插入图片描述
static_dims中,对2和3对应输出数据,使用getBindingDimensions拿到形状,然后通过vector指针起始初始化的方式,把数据形状变成int类型的容器vector。

在这里插入图片描述

  • Camera 时,上图 216 行,对应源码 208 行。

    • 这里绑定点索引为 2 表示 camera_depth_weights 节点索引,
    • 3 表示 camera_feature 节点索引。
  • 索引作为 https://gitee.com/duanmushuangquan/feishu_img/tree/master/static_dims 函数的入参,然后调用 getBindingDimensions 就可以获取节点的维度,接着将维度信息通过容器来储存并返回。之后根据维度累乘来计算参数量,为这两个输出在 device 上分配内存。

开辟输出数据内存

第一个图的49行,52行,就是为输出数据分配gpu内存了。

最后,设置camera_shape这里的相机形状对应的是 mit 中 get_camera_feature 的输出的形状,是进行了外积操作的结果。用于后续在 bevpool 中的提供维度数值。

初始化指向 bevfusion::camera ::BEVPool 对象的指针

在这里插入图片描述
在这里插入图片描述

  • create_bevpool 的入参有三个

    • 深度信息和图像特征外积之后的输出形状(6, 80, 118, 32, 88),
    • 真实世界体素网格 x 方向的维度:360
    • y 方向的维度:360。
  • 该函数中主要是构建一个指向 bevfusion::camera ::BEVPoolImplement 对象的智能指针并进行初始化。

在这里插入图片描述

  • 126行,初始化部分主要是一些关于输入与输出部分相关的数值初始化, bevpool 的输出 分配内存
初始化指向 bevfusion::camera ::VTransform 对象的指针

在这里插入图片描述

  • create_vtransform
    • 入参:"model/resnet50int8/build/camera.vtransform.plan"
    • 返回值:camera_vtransform 的 engine
      在这里插入图片描述
      在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

根据 序列化的engine文件 camera.vtransform.plan 来构建推理引擎,接着为输出分配内存。

初始化指向 bevfusion::fuser::Transfusion 对象的指针

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

根据 序列化的engine文件 fuser.plan 来构建推理引擎。
在这里插入图片描述
之后需要检查捆绑点是否存在动态维度,这里的维度不可以是动态的。
在这里插入图片描述

在这里插入图片描述

通过上述图片,我门也能看出,对于fuser,主要也是构建engine,以及为输出数据分配内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值