【嵌入式-TensorRT】TensorPriv代码解读
纵览
- cfgs //保存yaml - data //保存数据 - docs //说明文档 - tasks //各任务 |- cls |- f-track |- fairmot |- fcos |- yolov5 - tensorrt // 工具包和接口 main.cpp CMakeLists.txt
CMakeLists.txt
几个命令:
cmake_minimum_required() // 检查cmake的版本 project(tensor_priv) // 设置工程名 include() set() // 用于设定变量 variable 的值为 value file() // 把路径保存在变量中 message() // 输出信息 check_language() add_executable(<name> source1 source2 … sourceN) // 指定从一组源文件 source1 source2 … sourceN 使用gcc编译出一个可执行文件且命名为 name cuda_add_executable() // 类似,不过是用cuda编译器编译 find_package(<VAR> name1 [path1 path2 …]) find_library(<VAR> name1 [path1 path2 …]) find_path(<VAR> name1 [path1 path2 …]) // 用于查找包含包/库/文件 name1 的路径放入VAR include_directories($PATH) // 将PATH加入包含目录列表 link_directories($PATH) // 将PATH加入编译器链接阶段的搜索目录列表 target_link_libraries() // 将若干库文件链接到目标tensor_priv中,target_link_libraries里的库文件的顺序符合gcc/g++链接顺序的规则,即被依赖的库放在依赖它的库的后面,如果顺序有错,链接时会报错。
- Set variable for different ENV
- Package
- Set architecture and CUDA
- TensorRT
- Project source(Common sources/Tasks sources)
- Library and Executable(CUDA Compile/G++ Compile)
main.cpp
分块
分为三个代码块:初始化、不同任务开关设置参数、跑模型代码解读
2.1 初始化
// 在yaml-cpp包中的YAML命名空间的Node类型
namespace YAML {
Node Clone(const Node& node) {
NodeEvents events(node);
NodeBuilder builder;
events.Emit(builder);
return builder.Root();
}
} // namespace YAML
YAML::Node main_cfg = YAML::LoadFile("../cfgs/tasks.yaml");
YAML::Node task = main_cfg["tasks"];
YAML::Node f_track_cfg, fcos_cfg, fairmot_cfg, cls_cfg, yolo_cfg;
类似python的:
main_cfg = cfgNode("../cfgs/tasks.yaml")
task = cfgNode(main_cfg["tasks"])
f_track_cfg, ... = cfgNode(), ...
// 为各任务指派一个指针
F_track* f_track = nullptr;
Fcos* fcos = nullptr;
FairMOT* fairmot = nullptr;
CLS* cls = nullptr;
YOLOV5* yolo = nullptr;工程越大,名称互相冲突性的可能性越大。另外使用多个厂商的类库时,也可能导致名称冲突。为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入关键字namespace,可以更好地控制标识符的作用域。类比python不同类的同名成员变量/函数/子类。
2.2 不同任务参数设置
if (task["fcos"] && task["fcos"].as<bool>()){
// 提取对应main cfg的关键字cfg_file
string cfg_file = main_cfg["fcos"]["cfg_file"].as<string>();
fcos_cfg = YAML::LoadFile(cfg_file);
// 加载后建立Fcos类型的对象
fcos = new Fcos(fcos_cfg);
}2.3 跑模型
if(main_cfg["misc"]["multithreading"].as<bool>()) //是否开启多线程
auto thread_func_0 = [&](){
cv::Mat frame = imread(fairmot_cfg["inputs"]["img_path"].as<string>()); // 读取图片
int im_w = fairmot_cfg["inputs"]["width"].as<int>();
int im_h = fairmot_cfg["inputs"]["height"].as<int>();
cv::resize(frame, frame, cv::Size(im_w, im_h)); // 根据设置resize
int batch_size = fairmot_cfg["engine"]["bchw"].as<vector<int>>()[0];
vector<cv::Mat> imgs; // 创造一个装图的vector
for(int i = 0; i < batch_size; i++){
imgs.emplace_back(frame); // 按batchsize插入
}
auto fairmot_results = fairmot->run(imgs); // 调用任务类对象的内部函数
};
TrackRes FairMOT::run(const vector<Mat>& imgs){
data_timer->start();
if (!prepareInputs(imgs)){
mLogger.logger("Prepare Input Data Failed!", logger::LEVEL::ERROR);
} // 使用tasks预定义的函数处理
data_timer->click();
infer_timer->start();
mNet->ForwardAsync(mStream); // 调用RTengine跑前项
infer_timer->click();
post_timer->start();
auto results = processOutputs(); // 收集结果
post_timer->click();
mLogger.logger("Data time: ", data_timer->getTime(), logger::LEVEL::INFO);
mLogger.logger("Infer time: ", infer_timer->getTime(), logger::LEVEL::INFO);
mLogger.logger("Post time: ", post_timer->getTime(), logger::LEVEL::INFO);
return results;
}
查看11道真题和解析