TensorRT 를 사용하는 CMakeList 세팅

Published:

Prerequisite

먼저, 이 포스트는 Nvidia 에서 제공해주는TensorRT docker contatiner 안에서를 기준으로 작성되었다. docker를 생성하는 방법은 공식홈페이지에 잘 정리 되어있다.

Background

tensorrt에서 제공해주는 onnx parser등의 library들을 프로젝트에서 사용하고자 할때 이를 CMake를 활용하여 linking을 해주어야 할것이다.

먼저, docker 안에서 이러한 라이브러리들이 어디있는지 먼저 찾아보았다.

찾아 보니 /usr/lib/x86_64-linux-gnu 경로 안에 있었다. 예를들어 nonnxparser.so 를 찾아보자.

root@6ef8eaee5564:/usr/lib/x86_64-linux-gnu# ls | grep onnx
libnvonnxparser.so
libnvonnxparser.so.7
libnvonnxparser.so.7.1.0
libonnx_proto.a

이러한 라이브러리들을 사용하기 위해선 프로젝트의 CMakeList.txt에 불러오는 라인들을 작성해야할텐데 이를 위해선 두가지 방법이 있어보인다.

Methodologies

Method 1. 직접 작성하기

find_package(CUDA)
find_library(NVINFER  NAMES nvinfer)
find_library(NVINFERPLUGIN NAMES nvinfer_plugin)
find_library(NVPARSERS NAMES nvparsers)
find_library(NVONNXPARSER NAMES nvonnxparser)


# If it is ALL there, export libraries as a single package
if(CUDA_FOUND AND NVINFER AND NVINFERPLUGIN AND NVPARSERS AND NVONNXPARSER)
  message("TensorRT available!")
  message("CUDA Libs: ${CUDA_LIBRARIES}")
  message("CUDA Headers: ${CUDA_INCLUDE_DIRS}")
  message("NVINFER: ${NVINFER}")
  message("NVINFERPLUGIN: ${NVINFERPLUGIN}")
  message("NVPARSERS: ${NVPARSERS}")
  message("NVONNXPARSER: ${NVONNXPARSER}")
  list(APPEND TENSORRT_LIBRARIES ${CUDA_LIBRARIES} nvinfer nvinfer_plugin nvparsers nvonnxparser)
  message("All togheter now (libs): ${TENSORRT_LIBRARIES}")
  list(APPEND TENSORRT_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
  message("All togheter now (inc): ${TENSORRT_INCLUDE_DIRS}")
  set(TENSORRT_FOUND ON)
else()
  message("TensorRT NOT Available")
  set(TENSORRT_FOUND OFF)
endif()

위 라인들을 프로젝트의 CMakeList.txt에 추가하면 된다. 필자의 경우엔 NVONNXPARSERRUNTIME 가 없어서 이를 제외하고 사용했다. 파일들의 위치를 알고 싶다면

message(STATUS ${CUDA_FOUND})
message(STATUS ${NVINFER})
message(STATUS ${NVINFERPLUGIN})
message(STATUS ${NVPARSERS})
message(STATUS ${NVONNXPARSER})

위의 라인들을 추가후 cmake 하면 라이브러리들이 어디에 위치에있는지 알 수 있다.

-- TRUE
-- /usr/lib/x86_64-linux-gnu/libnvinfer.so
-- /usr/lib/x86_64-linux-gnu/libnvinfer_plugin.so
-- /usr/lib/x86_64-linux-gnu/libnvparsers.so
-- /usr/lib/x86_64-linux-gnu/libnvonnxparser.so

이제 include_directories , target_link_libraries 를 하면 된다.

include_directories(
  ${catkin_INCLUDE_DIRS}
  ${TENSORRT_INCLUDE_DIRS}
  
)
## Build executable
add_executable(
  ${PROJECT_NAME}
  ${SOURCES_CPP}
)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${TENSORRT_LIBRARIES} )

위와 같이 필요한 header들을 include하고 tensorrt library 를 linking하면 끝이다. (TENSORRT_LIBRARIES가 존재하는 이유는 list(APPEND TENSORRT_LIBRARIES ${CUDA_LIBRARIES} nvinfer nvinfer_plugin nvparsers nvonnxparser nvonnxparser_runtime) 라인을 통해 생성했기 때문이다.)

Reference repo

Method 2. 작성된 FindTensorRT.cmake 이용하기

고맙게도, learn openCV repo에서 FindTensorRT.cmake 를 작성해주었다. 이 파일을 그대로 이용하면, find_package를 이용해 손 쉽게 포팅할 수 있다. (참고: find_package)

먼저, FindTensorRT.cmake 다운받아 프로젝트의 CMakeLists.txt가 존재하는 directory 에 넣어주자.

그다음 CMakeLists.txt에

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH})
find_package(TensorRT REQUIRED)

위 두 줄을 추가하면 끝이다. set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_MODULE_PATH}) 를 하는 이유는 FindTensorRT.cmake를 찾아 주기 위함이다.

header include 와 library linking은 동일한 Method1과 동일하다.

include_directories(
  ${catkin_INCLUDE_DIRS}
  ${TensorRT_INCLUDE_DIRS}
  
)
#### Build executable
add_executable(
  ${PROJECT_NAME}
  ${SOURCES_CPP}
)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${TensorRT_LIBRARIES} )

딱 봐도 Method 2가 간결하다. 2번 방법을 추천한다.