Skip to content

Commit

Permalink
add TensorRT engine
Browse files Browse the repository at this point in the history
  • Loading branch information
gemfield committed Apr 1, 2021
1 parent 42bd787 commit 6950e43
Show file tree
Hide file tree
Showing 20 changed files with 806 additions and 92 deletions.
7 changes: 5 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ if(USE_TENSORRT)
message(STATUS "Found TensorRT headers at ${TENSORRT_INCLUDE_DIR}")
find_library(TENSORRT_LIBRARY_INFER nvinfer HINTS ${TENSORRT_ROOT} ${TENSORRT_BUILD} ${CUDA_TOOLKIT_ROOT_DIR} PATH_SUFFIXES lib lib64 lib/x64)
find_library(TENSORRT_LIBRARY_INFER_PLUGIN nvinfer_plugin HINTS ${TENSORRT_ROOT} ${TENSORRT_BUILD} ${CUDA_TOOLKIT_ROOT_DIR} PATH_SUFFIXES lib lib64 lib/x64)
find_library(TENSORRT_LIBRARY_INFER nvparsers HINTS ${TENSORRT_ROOT} ${TENSORRT_BUILD} ${CUDA_TOOLKIT_ROOT_DIR} PATH_SUFFIXES lib lib64 lib/x64)

set(TENSORRT_LIBRARY ${TENSORRT_LIBRARY_INFER} ${TENSORRT_LIBRARY_INFER_PLUGIN})
MESSAGE(STATUS "Found TensorRT libs at ${TENSORRT_LIBRARY}")
Expand Down Expand Up @@ -206,7 +207,8 @@ message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")

message(STATUS "TORCH_LIBRARIES: ${TORCH_LIBRARIES}")
message(STATUS "TORCH_HEADER: ${TORCH_INCLUDE_DIRS}")
message(STATUS "TORCH_INCLUDE_DIRS: ${TORCH_INCLUDE_DIRS}")
message(STATUS "CUDA_INCLUDE_DIRS: ${CUDA_INCLUDE_DIRS}")

set(DEEPVAC_LIBTORCH_INCLUDE_DIRS ${TORCH_INCLUDE_DIRS})
set(DEEPVAC_TENSORRT_INCLUDE_DIRS ${TENSORRT_INCLUDE_DIR})
Expand Down Expand Up @@ -259,8 +261,9 @@ endif()

target_include_directories(deepvac PUBLIC
"$<INSTALL_INTERFACE:include/deepvac>"
"$<BUILD_INTERFACE:${DEEPVAC_LIBTORCH_INCLUDE_DIRS};${HEADER_DIR_LIST};${DEEPVAC_TENSORRT_INCLUDE_DIRS};${DEEPVAC_CV_INCLUDE_DIRS}>"
"$<BUILD_INTERFACE:${DEEPVAC_LIBTORCH_INCLUDE_DIRS};${HEADER_DIR_LIST};${DEEPVAC_TENSORRT_INCLUDE_DIRS};${CUDA_INCLUDE_DIRS};${DEEPVAC_CV_INCLUDE_DIRS}>"
)

target_compile_options(deepvac PUBLIC -fopenmp)
set_target_properties(deepvac PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(deepvac PROPERTIES LINK_FLAGS_RELEASE -s)
Expand Down
11 changes: 8 additions & 3 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
# This file is part of libdeepvac, licensed under the GPLv3 (the "License")
# You may not use this file except in compliance with the License.

file(GLOB MODULE_LIST src/*.cpp)
add_syszux_sources(${MODULE_LIST})
message(STATUS "found MODULE_LIST: " ${MODULE_LIST})
file(GLOB CORE_SRC_LIST src/*.cpp)

if(NOT USE_TENSORRT)
list(FILTER CORE_SRC_LIST EXCLUDE REGEX ".*_nv.cpp$")
endif()

add_syszux_sources(${CORE_SRC_LIST})
message(STATUS "found CORE_SRC_LIST: " ${CORE_SRC_LIST})

file(GLOB HEADER_LIST include/*.h)
add_syszux_headers(${HEADER_LIST})
Expand Down
9 changes: 5 additions & 4 deletions core/include/deepvac.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@ namespace deepvac {
class SYSZUX_EXPORT Deepvac{
public:
Deepvac() = default;
explicit Deepvac(const char* model_path, std::string device);
explicit Deepvac(std::string model_path, std::string device):Deepvac(model_path.c_str(), device){}
explicit Deepvac(std::vector<unsigned char>&& buffer, std::string device);
Deepvac(const Deepvac& rhs);
Deepvac& operator=(const Deepvac& rhs);
Deepvac(Deepvac&&) = default;
Deepvac& operator=(Deepvac&&) = default;
virtual ~Deepvac() = default;
explicit Deepvac(const char* model_path, std::string device);
explicit Deepvac(std::string model_path, std::string device):Deepvac(model_path.c_str(), device){}
explicit Deepvac(std::vector<unsigned char>&& buffer, std::string device);

public:
void setDevice(std::string device){device_ = device;}
void setModel(std::string model_path);
std::string getDevice(){return device_;}
public:
template<typename T = at::Tensor>
T forward(at::Tensor& t);

Expand Down
72 changes: 72 additions & 0 deletions core/include/deepvac_nv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2020 Gemfield <gemfield@civilnet.cn>
* This file is part of libdeepvac, licensed under the GPLv3 (the "License")
* You may not use this file except in compliance with the License.
*/

#pragma once
#include <memory>
#include <vector>
#include <string>
#include "gemfield.h"
#include "syszux_tensorrt_buffers.h"
#include "NvInfer.h"

class TrtLogger : public nvinfer1::ILogger {
void log(Severity severity, const char* msg) override{
// suppress info-level messages
if (severity != Severity::kVERBOSE){
std::cout << msg << std::endl;
}
}
};

struct InferDeleter{
template <typename T>
void operator()(T* obj) const{
if (obj){
obj->destroy();
}
}
};

namespace deepvac {
class DeepvacNV{
template <typename T>
using SampleUniquePtr = std::unique_ptr<T, InferDeleter>;

public:
DeepvacNV() = default;
explicit DeepvacNV(const char* model_path, std::string device);
explicit DeepvacNV(std::string model_path, std::string device):DeepvacNV(model_path.c_str(), device){}
explicit DeepvacNV(std::vector<unsigned char>&& buffer, std::string device);
DeepvacNV(const DeepvacNV& rhs) = delete;
DeepvacNV& operator=(const DeepvacNV& rhs) = delete;
DeepvacNV(DeepvacNV&&) = default;
DeepvacNV& operator=(DeepvacNV&&) = default;
virtual ~DeepvacNV() = default;

public:
void setDevice(std::string device){device_ = device;}
void setModel(const char* model_path);
virtual void setBinding(int io_num);
void** forward(void** data) {
bool s = trt_context_->executeV2(data);
return data;
}

protected:
//all data members must be movable !!
//all data members need dynamic memory must be managed by smart ptr !!
SampleUniquePtr<nvinfer1::ICudaEngine> trt_module_;
SampleUniquePtr<nvinfer1::IExecutionContext> trt_context_;
template <typename T>
SampleUniquePtr<T> makeUnique(T* t){
return SampleUniquePtr<T>{t};
}
TrtLogger logger_;
std::vector<gemfield_org::ManagedBuffer> datas_;
std::string device_;
};

}// namespace deepvac
80 changes: 80 additions & 0 deletions core/src/deepvac_nv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 Gemfield <gemfield@civilnet.cn>
* This file is part of libdeepvac, licensed under the GPLv3 (the "License")
* You may not use this file except in compliance with the License.
*/
#include <type_traits>
#include <chrono>
#include <ctime>
#include <iostream>
#include <cassert>
#include "deepvac_nv.h"

namespace deepvac {
DeepvacNV::DeepvacNV(const char* path, std::string device){
GEMFIELD_SI;
auto start = std::chrono::system_clock::now();
try{
device_ = device;
setModel(path);
}catch(...){
std::string msg = "Internal ERROR!";
GEMFIELD_E(msg.c_str());
throw std::runtime_error(msg);
}
std::chrono::duration<double> model_loading_duration = std::chrono::system_clock::now() - start;
std::string msg = gemfield_org::format("NV Model loading time: %f", model_loading_duration.count());
GEMFIELD_DI(msg.c_str());
}

DeepvacNV::DeepvacNV(std::vector<unsigned char>&& buffer, std::string device){
GEMFIELD_SI;
auto start = std::chrono::system_clock::now();
try{
device_ = device;
nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(logger_);
trt_module_ = makeUnique(runtime->deserializeCudaEngine((void*)buffer.data(), buffer.size(), nullptr));
assert(trt_module_ != nullptr);
trt_context_ = makeUnique(trt_module_->createExecutionContext());
assert(trt_context_ != nullptr);
runtime->destroy();
runtime = nullptr;
}catch(...){
std::string msg = "Internal ERROR!";
GEMFIELD_E(msg.c_str());
throw std::runtime_error(msg);
}
std::chrono::duration<double> model_loading_duration = std::chrono::system_clock::now() - start;
std::string msg = gemfield_org::format("NV Model loading time: %f", model_loading_duration.count());
GEMFIELD_DI(msg.c_str());
}

void DeepvacNV::setBinding(int io_num) {
for(int i = 0; i < io_num; ++i) {
gemfield_org::ManagedBuffer buffer{};
datas_.emplace_back(std::move(buffer));
}
}

void DeepvacNV::setModel(const char* model_path) {
std::ifstream in(model_path, std::ifstream::binary);
if(in.is_open()) {
auto const start_pos = in.tellg();
in.ignore(std::numeric_limits<std::streamsize>::max());
size_t bufCount = in.gcount();
in.seekg(start_pos);
std::unique_ptr<char[]> engineBuf(new char[bufCount]);
in.read(engineBuf.get(), bufCount);
//initLibNvInferPlugins(&logger_, "");
nvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(logger_);
trt_module_ = makeUnique(runtime->deserializeCudaEngine((void*)engineBuf.get(), bufCount, nullptr));
assert(trt_module_ != nullptr);
trt_context_ = makeUnique(trt_module_->createExecutionContext());
assert(trt_context_ != nullptr);
//mBatchSize = trt_module_->getMaxBatchSize();
//spdlog::info("max batch size of deserialized engine: {}",mEngine->getMaxBatchSize());
runtime->destroy();
runtime = nullptr;
}
}
} //namespace deepvac
22 changes: 16 additions & 6 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# You may not use this file except in compliance with the License.

file(GLOB EXAMPLES_LIST src/*.cpp)
message(STATUS "found EXAMPLES_LIST: " ${EXAMPLES_LIST})

macro (add_syszux_flags)
foreach (_src ${ARGN})
list (APPEND FLAGS_FILE_LIST "${_src}")
Expand Down Expand Up @@ -45,6 +43,13 @@ endforeach()
if(BUILD_ALL_EXAMPLES)
set(EXAMPLES_LIST_MIN ${EXAMPLES_LIST})
endif()

if(NOT USE_TENSORRT)
list(FILTER EXAMPLES_LIST_MIN EXCLUDE REGEX ".*_nv.cpp$")
endif()

message(STATUS "found EXAMPLES_SRC_LIST: " ${EXAMPLES_LIST_MIN})

foreach( testsyszuxfile ${EXAMPLES_LIST_MIN} )
get_filename_component(testfile "${testsyszuxfile}" NAME)
message(STATUS "Add test binary: ${testfile}")
Expand All @@ -56,7 +61,11 @@ foreach( testsyszuxfile ${EXAMPLES_LIST_MIN} )
target_link_options(${testname} PRIVATE -fopenmp)
if(BUILD_STATIC)
if(USE_CUDA)
target_link_libraries( ${testname} ${DEEPVAC_LIBRARIES} ${DEEPVAC_LIBTORCH_CUDA_LIBRARIES} ${DEEPVAC_LIBCUDA_LIBRARIES} ${DEEPVAC_CV_LIBRARIES})
if(USE_TENSORRT)
target_link_libraries( ${testname} ${DEEPVAC_LIBRARIES} ${DEEPVAC_LIBTORCH_CUDA_LIBRARIES} ${DEEPVAC_LIBCUDA_LIBRARIES} ${DEEPVAC_CV_LIBRARIES} ${DEEPVAC_TENSORRT_LIBRARIES})
else()
target_link_libraries( ${testname} ${DEEPVAC_LIBRARIES} ${DEEPVAC_LIBTORCH_CUDA_LIBRARIES} ${DEEPVAC_LIBCUDA_LIBRARIES} ${DEEPVAC_CV_LIBRARIES})
endif()
else()
target_link_libraries( ${testname} ${DEEPVAC_LIBRARIES} ${DEEPVAC_LIBTORCH_CPU_LIBRARIES} ${DEEPVAC_CV_LIBRARIES})
endif()
Expand All @@ -66,9 +75,10 @@ foreach( testsyszuxfile ${EXAMPLES_LIST_MIN} )
else()
target_link_libraries( ${testname} deepvac ${TORCH_LIBRARIES} ${DEEPVAC_CV_LIBRARIES})
endif()
target_include_directories(${testname} PUBLIC

target_include_directories(${testname} PUBLIC
"$<INSTALL_INTERFACE:include/deepvac>"
"$<BUILD_INTERFACE:${DEEPVAC_LIBTORCH_INCLUDE_DIRS};${DEEPVAC_TENSORRT_INCLUDE_DIRS};${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${DEEPVAC_LIBTORCH_INCLUDE_DIRS};${DEEPVAC_TENSORRT_INCLUDE_DIRS};${CUDA_INCLUDE_DIRS};${CMAKE_CURRENT_SOURCE_DIR}/include>"
)
#install(TARGETS ${testname} DESTINATION "${examples_dest}")
endforeach( testsyszuxfile ${EXAMPLES_LIST_MIN} )
endforeach( testsyszuxfile ${EXAMPLES_LIST_MIN} )
55 changes: 55 additions & 0 deletions examples/src/test_face_retina_nv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2020 Gemfield <gemfield@civilnet.cn>
* This file is part of libdeepvac, licensed under the GPLv3 (the "License")
* You may not use this file except in compliance with the License.
*/

#include <chrono>
#include "syszux_face_retina_nv.h"
#include "syszux_face_reg_nv.h"
#include "syszux_img2tensor.h"

using namespace deepvac;
int main(int argc, const char* argv[]) {
if (argc != 3) {
GEMFIELD_E("usage: deepvac <device> <img_path>");
return -1;
}

std::string device = argv[1];
std::string img_path = argv[2];
SyszuxFaceRetinaNV face_detect("detect.trt", device);
SyszuxFaceRegNV face_reg("reg.trt", device);

auto start = std::chrono::system_clock::now();

for(int i = 0; i < 155; ++i) {
auto start1 = std::chrono::system_clock::now();
std::string img_name = img_path + std::to_string(i*10) + ".jpg";
auto mat_opt = gemfield_org::img2CvMat(img_name);

if(!mat_opt){
throw std::runtime_error("illegal image detected");
return 1;
}

auto mat_out = mat_opt.value();
auto detect_out_opt = face_detect.process(mat_out);
std::chrono::duration<double> model_loading_duration_d = std::chrono::system_clock::now() - start1;
std::string msg = gemfield_org::format("Model loading time: %f", model_loading_duration_d.count());
std::cout << msg << std::endl;

if(detect_out_opt){
face_reg.process(detect_out_opt);
}

std::chrono::duration<double> model_loading_duration_d1 = std::chrono::system_clock::now() - start1;
std::string msg1 = gemfield_org::format("Model loading time: %f", model_loading_duration_d1.count());
std::cout << msg1 << std::endl;
}

std::chrono::duration<double> model_loading_duration = std::chrono::system_clock::now() - start;
std::string msg = gemfield_org::format("Model loading time: %f", model_loading_duration.count());
std::cout << msg << std::endl;
return 0;
}
6 changes: 3 additions & 3 deletions loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# This file is part of libdeepvac, licensed under the GPLv3 (the "License")
# You may not use this file except in compliance with the License.

file(GLOB LOADER_LIST src/*.cpp)
add_syszux_sources(${LOADER_LIST})
message(STATUS "found LOADER_LIST: " ${LOADER_LIST})
file(GLOB LOADER_SRC_LIST src/*.cpp)
add_syszux_sources(${LOADER_SRC_LIST})
message(STATUS "found LOADER_SRC_LIST: " ${LOADER_SRC_LIST})

file(GLOB HEADER_LIST include/*.h)
add_syszux_headers(${HEADER_LIST})
Expand Down
11 changes: 8 additions & 3 deletions modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
# This file is part of libdeepvac, licensed under the GPLv3 (the "License")
# You may not use this file except in compliance with the License.

file(GLOB UTILS_LIST src/*.cpp)
add_syszux_sources(${UTILS_LIST})
message(STATUS "found UTILS_LIST: " ${UTILS_LIST})
file(GLOB MODULES_SRC_LIST src/*.cpp)

if(NOT USE_TENSORRT)
list(FILTER MODULES_SRC_LIST EXCLUDE REGEX ".*_nv.cpp$")
endif()

add_syszux_sources(${MODULES_SRC_LIST})
message(STATUS "found MODULES_SRC_LIST: " ${MODULES_SRC_LIST})

file(GLOB HEADER_LIST include/*.h)
add_syszux_headers(${HEADER_LIST})
Expand Down
24 changes: 24 additions & 0 deletions modules/include/syszux_face_reg_nv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <tuple>
#include <vector>
#include "deepvac_nv.h"
#include "syszux_tensorrt_buffers.h"
#include "syszux_img2tensor.h"

namespace deepvac{
class SyszuxFaceRegNV : public DeepvacNV{
public:
SyszuxFaceRegNV(std::string path, std::string device = "cpu");
SyszuxFaceRegNV(std::vector<unsigned char>&& buffer, std::string device = "cpu");
SyszuxFaceRegNV(const SyszuxFaceRegNV&) = delete;
SyszuxFaceRegNV& operator=(const SyszuxFaceRegNV&) = delete;
SyszuxFaceRegNV(SyszuxFaceRegNV&&) = default;
SyszuxFaceRegNV& operator=(SyszuxFaceRegNV&&) = default;
virtual ~SyszuxFaceRegNV() = default;
virtual std::tuple<int, std::string, float> process(cv::Mat& frame);
void initBinding();
};
}//namespace


Loading

0 comments on commit 6950e43

Please sign in to comment.