Commit 450989b59d4f7fdb3c326fb15ad38956a449e21b

Authored by Hu Chunming
1 parent 78676b64

跑通算法

test/main.cpp
@@ -76,6 +76,7 @@ algorithm_type_t algor_index_to_algor_type(const int &idx) { @@ -76,6 +76,7 @@ algorithm_type_t algor_index_to_algor_type(const int &idx) {
76 } 76 }
77 } 77 }
78 78
  79 +#ifdef POST_USE_RABBITMQ
79 void init_mq_conn(void *handle) { 80 void init_mq_conn(void *handle) {
80 for (auto key : {mq_type_t::ALARM_MQ, mq_type_t::GET_TASK_MQ, mq_type_t::HEART_BEAT_MQ}) { 81 for (auto key : {mq_type_t::ALARM_MQ, mq_type_t::GET_TASK_MQ, mq_type_t::HEART_BEAT_MQ}) {
81 rabbitmq_conn_params_t mq_conn_params; 82 rabbitmq_conn_params_t mq_conn_params;
@@ -111,6 +112,7 @@ void init_mq_conn(void *handle) { @@ -111,6 +112,7 @@ void init_mq_conn(void *handle) {
111 fprintf(stderr, "ip is %s port is %d\n", mq_conn_params.ip, mq_conn_params.port); 112 fprintf(stderr, "ip is %s port is %d\n", mq_conn_params.ip, mq_conn_params.port);
112 } 113 }
113 } 114 }
  115 +#endif
114 116
115 const char* ipc_url = "/home/cmhu/tongtu/tsl_aiplatform_project_with_screenshot/data/duan1.avi"; 117 const char* ipc_url = "/home/cmhu/tongtu/tsl_aiplatform_project_with_screenshot/data/duan1.avi";
116 118
tsl_aiplatform/ai_platform/GpuRgbMemory.hpp
@@ -18,7 +18,7 @@ public: @@ -18,7 +18,7 @@ public:
18 gpuid = _gpuid; 18 gpuid = _gpuid;
19 timestamp = helpers::timer::get_timestamp<std::chrono::milliseconds>(); 19 timestamp = helpers::timer::get_timestamp<std::chrono::milliseconds>();
20 20
21 - // cudaSetDevice(atoi(gpuid.c_str())); 21 + cudaSetDevice(atoi(gpuid.c_str()));
22 CHECK(cudaMalloc((void **)&pHwRgb, size * sizeof(unsigned char))); 22 CHECK(cudaMalloc((void **)&pHwRgb, size * sizeof(unsigned char)));
23 } 23 }
24 24
tsl_aiplatform/ai_platform/MultiSourceProcess.cpp
@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 9
10 #include "authority.h" 10 #include "authority.h"
11 11
  12 +#include "NvJpegEncoder.hpp"
  13 +
12 #ifdef AUTHORIZATION 14 #ifdef AUTHORIZATION
13 #include <boost/thread.hpp> 15 #include <boost/thread.hpp>
14 #ifdef _MSC_VER 16 #ifdef _MSC_VER
@@ -261,6 +263,9 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam) { @@ -261,6 +263,9 @@ int CMultiSourceProcess::InitAlgorthim(tsl_aiplatform_param vptParam) {
261 #endif // #ifdef __linux__ 263 #endif // #ifdef __linux__
262 #endif // #ifdef AUTHORIZATION 264 #endif // #ifdef AUTHORIZATION
263 265
  266 + // 启动算法处理线程
  267 + startProcessByGpuid();
  268 +
264 return ret; 269 return ret;
265 } 270 }
266 271
@@ -329,8 +334,6 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){ @@ -329,8 +334,6 @@ bool CMultiSourceProcess::AddTask(task_param _cur_task_param){
329 // 所有参数都准备好之后再启动解码 334 // 所有参数都准备好之后再启动解码
330 pDecManager->startDecodeByName(config.name); 335 pDecManager->startDecodeByName(config.name);
331 cout << "started task: " << config.name << endl; 336 cout << "started task: " << config.name << endl;
332 - // 启动算法处理线程  
333 - startProcessByGpuid();  
334 } 337 }
335 338
336 // 启动算法处理线程 339 // 启动算法处理线程
@@ -352,8 +355,14 @@ void CMultiSourceProcess::post_decode_thread(decode_cbk_userdata* userPtr, AVFra @@ -352,8 +355,14 @@ void CMultiSourceProcess::post_decode_thread(decode_cbk_userdata* userPtr, AVFra
352 FFNvDecoder* dec = (FFNvDecoder*)ptr->opaque1; 355 FFNvDecoder* dec = (FFNvDecoder*)ptr->opaque1;
353 356
354 if (gpuFrame->format == AV_PIX_FMT_CUDA && dec != nullptr){ 357 if (gpuFrame->format == AV_PIX_FMT_CUDA && dec != nullptr){
355 - cout << "decode task: " << dec->getName() << " gpuid: " << gpu_id_ << endl; 358 + // cout << "decode task: " << dec->getName() << " gpuid: " << gpu_id_ << endl;
356 GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, dec->getName(), gpu_id_ , true); 359 GpuRgbMemory* gpuMem = new GpuRgbMemory(3, gpuFrame->width, gpuFrame->height, dec->getName(), gpu_id_ , true);
  360 +
  361 + if (gpuMem->getMem() == nullptr){
  362 + cout << "new GpuRgbMemory failed !!!" << endl;
  363 + return;
  364 + }
  365 +
357 366
358 // cudaSetDevice(atoi(gpu_id_.c_str())); 367 // cudaSetDevice(atoi(gpu_id_.c_str()));
359 // cuda_common::setColorSpace( ITU_709, 0 ); 368 // cuda_common::setColorSpace( ITU_709, 0 );
@@ -431,7 +440,11 @@ void CMultiSourceProcess::cuda_free_wrap(sy_img &amp;img) { @@ -431,7 +440,11 @@ void CMultiSourceProcess::cuda_free_wrap(sy_img &amp;img) {
431 // 算法处理函数,由算法线程调用 440 // 算法处理函数,由算法线程调用
432 void CMultiSourceProcess::algorthim_process_thread(){ 441 void CMultiSourceProcess::algorthim_process_thread(){
433 442
  443 + cudaSetDevice(atoi(gpu_id_.c_str()));
  444 +
434 map<string, int> task_id_to_n_frame; 445 map<string, int> task_id_to_n_frame;
  446 +
  447 + int sum = 0;
435 while(true){ 448 while(true){
436 /* step1. 授权check */ 449 /* step1. 授权check */
437 if (licence_status_ <= -3) { 450 if (licence_status_ <= -3) {
@@ -470,6 +483,10 @@ void CMultiSourceProcess::algorthim_process_thread(){ @@ -470,6 +483,10 @@ void CMultiSourceProcess::algorthim_process_thread(){
470 batch_img[i].set_data(gpuMem->getWidth(), gpuMem->getHeight(), gpuMem->getChannel(), gpuMem->getMem()); 483 batch_img[i].set_data(gpuMem->getWidth(), gpuMem->getHeight(), gpuMem->getChannel(), gpuMem->getMem());
471 task_list.push_back(gpuMem->getId()); 484 task_list.push_back(gpuMem->getId());
472 ++task_id_to_n_frame[gpuMem->getId()]; 485 ++task_id_to_n_frame[gpuMem->getId()];
  486 +
  487 + // string path = "/home/cmhu/data2/test/" + gpuMem->getId() + "_" + to_string(sum) + ".jpg";
  488 + // saveJpeg(path.c_str(), gpuMem->getMem(), gpuMem->getWidth(), gpuMem->getHeight(), nullptr); // 验证 CUDAToRGB
  489 + // sum ++;
473 } 490 }
474 491
475 m_QueueMtx.unlock(); 492 m_QueueMtx.unlock();
@@ -511,6 +528,8 @@ void CMultiSourceProcess::algorthim_process_thread(){ @@ -511,6 +528,8 @@ void CMultiSourceProcess::algorthim_process_thread(){
511 LOG_DEBUG("{}", msg); 528 LOG_DEBUG("{}", msg);
512 } 529 }
513 #endif 530 #endif
  531 +
  532 + cout << "algorthim_process_thread end. " << endl;
514 } 533 }
515 534
516 // VPT 检测 535 // VPT 检测
@@ -669,7 +688,6 @@ void CMultiSourceProcess::algorithm_snapshot(vector&lt;string&gt;&amp; vpt_interest_task_i @@ -669,7 +688,6 @@ void CMultiSourceProcess::algorithm_snapshot(vector&lt;string&gt;&amp; vpt_interest_task_i
669 /* 轨迹结束帧需要做的算法模块 */ 688 /* 轨迹结束帧需要做的算法模块 */
670 int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type) { 689 int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &obj_key, algorithm_type_t algor_type) {
671 auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id); 690 auto task_param_ptr = m_task_param_manager->get_task_algor_param(obj_key.video_id);
672 - auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id);  
673 691
674 // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源 692 // 该路任务开启了抓拍功能 开始抓拍保存;若未开启抓拍,清空显存资源
675 if ((task_param_ptr->human_algors.find(algorithm_type_t::HUMAN_SNAPSHOT) != task_param_ptr->human_algors.end() || 693 if ((task_param_ptr->human_algors.find(algorithm_type_t::HUMAN_SNAPSHOT) != task_param_ptr->human_algors.end() ||
@@ -884,6 +902,7 @@ int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &amp;obj_key, algorithm_ @@ -884,6 +902,7 @@ int CMultiSourceProcess::endframe_obj_process(const OBJ_KEY &amp;obj_key, algorithm_
884 } 902 }
885 #endif 903 #endif
886 904
  905 + auto task_other_param_ptr = m_task_param_manager->get_task_other_param(obj_key.video_id);
887 /* 开启人脸抓拍分析算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */ 906 /* 开启人脸抓拍分析算法模块,获取该目标的算法分析结果 返回结果+快照 最后释放资源 */
888 if (task_other_param_ptr->find(algorithm_type_t::FACE_SNAPSHOT) != task_other_param_ptr->end() && 907 if (task_other_param_ptr->find(algorithm_type_t::FACE_SNAPSHOT) != task_other_param_ptr->end() &&
889 algor_type == algorithm_type_t::FACE_SNAPSHOT) { 908 algor_type == algorithm_type_t::FACE_SNAPSHOT) {
@@ -1095,8 +1114,10 @@ void CMultiSourceProcess::algorthim_face_detect(vector&lt;string&gt;&amp; task_list, sy_im @@ -1095,8 +1114,10 @@ void CMultiSourceProcess::algorthim_face_detect(vector&lt;string&gt;&amp; task_list, sy_im
1095 std::vector<onelevel_det_result> facedet_result(image_size); 1114 std::vector<onelevel_det_result> facedet_result(image_size);
1096 std::vector<std::vector<int>> face_deleteObjectID(image_size); 1115 std::vector<std::vector<int>> face_deleteObjectID(image_size);
1097 1116
  1117 +#ifdef WITH_FACE_DET_SS
1098 m_face_det_ai_engine.ai_engine_process_batch2(face_det_interest_task_id, 1118 m_face_det_ai_engine.ai_engine_process_batch2(face_det_interest_task_id,
1099 face_det_interest_imgs.data(), face_det_interest_imgs.size(), facedet_result, face_deleteObjectID); 1119 face_det_interest_imgs.data(), face_det_interest_imgs.size(), facedet_result, face_deleteObjectID);
  1120 +#endif
1100 1121
1101 #if 0 1122 #if 0
1102 // accum 1123 // accum
@@ -1129,6 +1150,7 @@ void CMultiSourceProcess::algorthim_face_detect(vector&lt;string&gt;&amp; task_list, sy_im @@ -1129,6 +1150,7 @@ void CMultiSourceProcess::algorthim_face_detect(vector&lt;string&gt;&amp; task_list, sy_im
1129 #endif 1150 #endif
1130 } 1151 }
1131 1152
  1153 +#ifdef POST_USE_RABBITMQ
1132 /* MQ队列的初始化 */ 1154 /* MQ队列的初始化 */
1133 int CMultiSourceProcess::AddMqConn(mq_type_t mq_type, rabbitmq_conn_params_t mq_conn_param) { 1155 int CMultiSourceProcess::AddMqConn(mq_type_t mq_type, rabbitmq_conn_params_t mq_conn_param) {
1134 /* 初始化MQ队列 */ 1156 /* 初始化MQ队列 */
@@ -1170,6 +1192,7 @@ int CMultiSourceProcess::GetTaskStatus(const string taskID) { @@ -1170,6 +1192,7 @@ int CMultiSourceProcess::GetTaskStatus(const string taskID) {
1170 1192
1171 return SUCCESS; 1193 return SUCCESS;
1172 } 1194 }
  1195 +#endif
1173 1196
1174 bool CMultiSourceProcess::PauseTask(const string taskID) { 1197 bool CMultiSourceProcess::PauseTask(const string taskID) {
1175 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance(); 1198 FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
@@ -1182,15 +1205,12 @@ bool CMultiSourceProcess::RestartTask(const string taskID){ @@ -1182,15 +1205,12 @@ bool CMultiSourceProcess::RestartTask(const string taskID){
1182 } 1205 }
1183 1206
1184 bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_snapshot){ 1207 bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_snapshot){
1185 - FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();  
1186 - bool ret = pDecManager->closeDecoderByName(taskID);  
1187 -  
1188 #ifdef POST_USE_RABBITMQ 1208 #ifdef POST_USE_RABBITMQ
1189 auto json_str = helpers::gen_json::gen_office_task_heart_beat_json({taskID}); 1209 auto json_str = helpers::gen_json::gen_office_task_heart_beat_json({taskID});
1190 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true); 1210 mq_manager_->publish(mq_type_t::HEART_BEAT_MQ, json_str.c_str(), true);
1191 #endif 1211 #endif
1192 1212
1193 - #ifdef WITH_FACE_DET_SS 1213 +#ifdef WITH_FACE_DET_SS
1194 // 人脸任务结束 1214 // 人脸任务结束
1195 auto task_param_ptr = m_task_param_manager->get_task_algor_param(taskID); 1215 auto task_param_ptr = m_task_param_manager->get_task_algor_param(taskID);
1196 if (task_param_ptr->human_face_algors.find(algorithm_type_t::FACE_SNAPSHOT) != 1216 if (task_param_ptr->human_face_algors.find(algorithm_type_t::FACE_SNAPSHOT) !=
@@ -1201,7 +1221,14 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna @@ -1201,7 +1221,14 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
1201 1221
1202 m_task_param_manager->delete_task_param(taskID); 1222 m_task_param_manager->delete_task_param(taskID);
1203 1223
1204 - if (delete_snapshot) { 1224 + return true;
  1225 +}
  1226 +
  1227 +bool CMultiSourceProcess::FinishTask(const string taskID){
  1228 + FFNvDecoderManager* pDecManager = FFNvDecoderManager::getInstance();
  1229 + bool ret = pDecManager->closeDecoderByName(taskID);
  1230 +
  1231 + if (ret){
1205 m_snapshot_reprocessing->delete_finishtask_snapshot(taskID); 1232 m_snapshot_reprocessing->delete_finishtask_snapshot(taskID);
1206 ((save_snapshot_reprocessing *)m_save_snapshot_reprocessing)->delete_finishtask(taskID); 1233 ((save_snapshot_reprocessing *)m_save_snapshot_reprocessing)->delete_finishtask(taskID);
1207 } 1234 }
@@ -1209,10 +1236,6 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna @@ -1209,10 +1236,6 @@ bool CMultiSourceProcess::finish_task(const string taskID, const bool delete_sna
1209 return ret; 1236 return ret;
1210 } 1237 }
1211 1238
1212 -bool CMultiSourceProcess::FinishTask(const string taskID){  
1213 - return finish_task(taskID,true);  
1214 -}  
1215 -  
1216 void CMultiSourceProcess::CloseAllTask(){ 1239 void CMultiSourceProcess::CloseAllTask(){
1217 m_bfinish = true; 1240 m_bfinish = true;
1218 1241
tsl_aiplatform/ai_platform/NvJpegEncoder.hpp 0 → 100644
  1 +/*
  2 +*主要用于测试显卡上的数据是否正常
  3 +*/
  4 +
  5 +#include <nvjpeg.h>
  6 +
  7 +#include <fstream>
  8 +#include <vector>
  9 +#include <iostream>
  10 +
  11 +
  12 +#define CHECK_NVJPEG(S) do {nvjpegStatus_t status; \
  13 + status = S; \
  14 + if (status != NVJPEG_STATUS_SUCCESS ) std::cout << __LINE__ <<" CHECK_NVJPEG - status = " << status << std::endl; \
  15 + } while (false)
  16 +
  17 +
  18 +int saveJpeg(const char * filepath, unsigned char* d_srcBGR, int width, int height, cudaStream_t stream)
  19 +{
  20 + nvjpegHandle_t nvjpeg_handle;
  21 + nvjpegEncoderState_t encoder_state;
  22 + nvjpegEncoderParams_t encoder_params;
  23 +
  24 + cudaEvent_t ev_start, ev_end;
  25 + cudaEventCreate(&ev_start);
  26 + cudaEventCreate(&ev_end);
  27 +
  28 + nvjpegImage_t input;
  29 + nvjpegInputFormat_t input_format = NVJPEG_INPUT_BGRI;
  30 + int image_width = width;
  31 + int image_height = height;
  32 +
  33 + // int channel_size = image_width * image_height;
  34 + // for (int i = 0; i < 3; i++)
  35 + // {
  36 + // input.pitch[i] = image_width;
  37 + // (cudaMalloc((void**)&(input.channel[i]), channel_size));
  38 + // (cudaMemset(input.channel[i], 50 * 40 * i, channel_size));
  39 + // }
  40 +
  41 + input.channel[0] = d_srcBGR;
  42 + input.pitch[0] = image_width * 3;
  43 +
  44 + nvjpegBackend_t backend = NVJPEG_BACKEND_DEFAULT;
  45 +
  46 + CHECK_NVJPEG(nvjpegCreate(backend, nullptr, &nvjpeg_handle));
  47 +
  48 + CHECK_NVJPEG(nvjpegEncoderParamsCreate(nvjpeg_handle, &encoder_params, stream));
  49 + CHECK_NVJPEG(nvjpegEncoderStateCreate(nvjpeg_handle, &encoder_state, stream));
  50 +
  51 + // set params
  52 + CHECK_NVJPEG(nvjpegEncoderParamsSetEncoding(encoder_params, nvjpegJpegEncoding_t::NVJPEG_ENCODING_PROGRESSIVE_DCT_HUFFMAN, stream));
  53 + CHECK_NVJPEG(nvjpegEncoderParamsSetOptimizedHuffman(encoder_params, 1, stream));
  54 + CHECK_NVJPEG(nvjpegEncoderParamsSetQuality(encoder_params, 70, stream));
  55 + CHECK_NVJPEG(nvjpegEncoderParamsSetSamplingFactors(encoder_params, nvjpegChromaSubsampling_t::NVJPEG_CSS_420, stream));
  56 +
  57 + cudaEventRecord(ev_start);
  58 + CHECK_NVJPEG(nvjpegEncodeImage(nvjpeg_handle, encoder_state, encoder_params, &input, input_format, image_width, image_height, stream));
  59 + cudaEventRecord(ev_end);
  60 +
  61 + std::vector<unsigned char> obuffer;
  62 + size_t length;
  63 + CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream(
  64 + nvjpeg_handle,
  65 + encoder_state,
  66 + NULL,
  67 + &length,
  68 + stream));
  69 +
  70 + obuffer.resize(length);
  71 + CHECK_NVJPEG(nvjpegEncodeRetrieveBitstream(
  72 + nvjpeg_handle,
  73 + encoder_state,
  74 + obuffer.data(),
  75 + &length,
  76 + stream));
  77 +
  78 + cudaEventSynchronize(ev_end);
  79 +
  80 + // 用完销毁,避免显存泄露
  81 + nvjpegEncoderParamsDestroy(encoder_params);
  82 + nvjpegEncoderStateDestroy(encoder_state);
  83 + nvjpegDestroy(nvjpeg_handle);
  84 +
  85 + float ms;
  86 + cudaEventElapsedTime(&ms, ev_start, ev_end);
  87 + // std::cout << "time spend " << ms << " ms" << std::endl;
  88 +
  89 + std::ofstream outputFile(filepath, std::ios::out | std::ios::binary);
  90 + outputFile.write(reinterpret_cast<const char *>(obuffer.data()), static_cast<int>(length));
  91 + outputFile.close();
  92 +
  93 + return 0;
  94 +}
0 \ No newline at end of file 95 \ No newline at end of file
tsl_aiplatform/ai_platform/header.h
@@ -445,7 +445,7 @@ enum ai_log_level { @@ -445,7 +445,7 @@ enum ai_log_level {
445 #endif 445 #endif
446 446
447 447
448 -#define POST_USE_RABBITMQ 448 +// #define POST_USE_RABBITMQ
449 449
450 #ifdef POST_USE_RABBITMQ 450 #ifdef POST_USE_RABBITMQ
451 /** 451 /**
tsl_aiplatform/ai_platform/stl_aiplatform.cpp
@@ -24,7 +24,6 @@ int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_ @@ -24,7 +24,6 @@ int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_
24 int res = tools->AddMqConn(tstatus, mq_conn_param); 24 int res = tools->AddMqConn(tstatus, mq_conn_param);
25 return res; 25 return res;
26 } 26 }
27 -#endif  
28 27
29 28
30 int get_task_status(void *handle, char *task_id) 29 int get_task_status(void *handle, char *task_id)
@@ -33,6 +32,7 @@ int get_task_status(void *handle, char *task_id) @@ -33,6 +32,7 @@ int get_task_status(void *handle, char *task_id)
33 int res = tools->GetTaskStatus(task_id); 32 int res = tools->GetTaskStatus(task_id);
34 return res; 33 return res;
35 } 34 }
  35 +#endif
36 36
37 37
38 int add_task(void *handle, task_param param) 38 int add_task(void *handle, task_param param)
tsl_aiplatform/ai_platform/stl_aiplatform.h
@@ -42,11 +42,13 @@ extern &quot;C&quot; @@ -42,11 +42,13 @@ extern &quot;C&quot;
42 * @return TSL_AIPLATFORM_API 42 * @return TSL_AIPLATFORM_API
43 */ 43 */
44 TSL_AIPLATFORM_API int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_param); 44 TSL_AIPLATFORM_API int add_mq_conn(void *handle, mq_type_t tstatus, rabbitmq_conn_params_t mq_conn_param);
45 -#endif 45 +
46 46
47 47
48 TSL_AIPLATFORM_API int get_task_status(void *handle, char *task_id); 48 TSL_AIPLATFORM_API int get_task_status(void *handle, char *task_id);
49 49
  50 +#endif
  51 +
50 /************************************************************************* 52 /*************************************************************************
51 * FUNCTION: add_task 53 * FUNCTION: add_task
52 * PURPOSE: 添加任务 54 * PURPOSE: 添加任务
tsl_aiplatform/helpers/helpers.h
@@ -16,5 +16,6 @@ @@ -16,5 +16,6 @@
16 #include "logger.hpp" 16 #include "logger.hpp"
17 #include "str_helper.hpp" 17 #include "str_helper.hpp"
18 #include "os_helper.hpp" 18 #include "os_helper.hpp"
  19 +#include "timer.hpp"
19 20
20 21