Docker api #242
+12
-1
@@ -8,4 +8,15 @@ build/
|
||||
*.h5
|
||||
*.tar.gz
|
||||
*.weights
|
||||
.idea/
|
||||
.idea/
|
||||
*.hdf5
|
||||
*.pk
|
||||
*.table
|
||||
cmake-build-release/
|
||||
demo/COCO_val2017
|
||||
demo/BDD100K_val
|
||||
/.vs
|
||||
cmake-build-minsizerel/*
|
||||
scripts/COCO_val2017/*
|
||||
scripts/COCO_val2017.zip
|
||||
scripts/all_labels.txt
|
||||
+65
-84
@@ -1,8 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(PROJ_NAME tkDNN)
|
||||
project (tkDNN)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC")
|
||||
if(UNIX)
|
||||
|
||||
####
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -Wno-deprecated-declarations -Wno-unused-variable ")
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "/O2 /FS /EHsc")
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
#add extras for baggage
|
||||
endif(WIN32)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/tkDNN)
|
||||
|
||||
# project specific flags
|
||||
@@ -10,6 +20,7 @@ if(DEBUG)
|
||||
add_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
add_definitions(-DTKDNN_PATH="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# CUDA
|
||||
@@ -17,97 +28,82 @@ endif()
|
||||
find_package(CUDA 9.0 REQUIRED)
|
||||
SET(CUDA_SEPARABLE_COMPILATION ON)
|
||||
#set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -arch=sm_30 --compiler-options '-fPIC'")
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --maxrregcount=32)
|
||||
|
||||
find_package(CUDNN REQUIRED)
|
||||
include_directories(${CUDNN_INCLUDE_DIR})
|
||||
|
||||
|
||||
# compile
|
||||
file(GLOB tkdnn_CUSRC "src/kernels/*.cu" "src/*.cu")
|
||||
file(GLOB tkdnn_CUSRC "src/kernels/*.cu" "src/sorting.cu")
|
||||
cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${CUDNN_INCLUDE_DIRS})
|
||||
cuda_add_library(kernels SHARED ${tkdnn_CUSRC})
|
||||
target_link_libraries(kernels ${CUDA_CUBLAS_LIBRARIES})
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# External Libraries
|
||||
#-------------------------------------------------------------------------------
|
||||
find_package(Eigen3 REQUIRED)
|
||||
include_directories(${EIGEN3_INCLUDE_DIR})
|
||||
|
||||
find_package(OpenCV REQUIRED)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV")
|
||||
|
||||
# gives problems in cross-compiling, probably malformed cmake config
|
||||
find_package(yaml-cpp REQUIRED)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Build Libraries
|
||||
#-------------------------------------------------------------------------------
|
||||
file(GLOB tkdnn_SRC "src/*.cpp")
|
||||
set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS})
|
||||
file(GLOB tkdnn_SRC "src/*.cpp",src/*.c)
|
||||
set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS} yaml-cpp)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} ${NVINFER_INCLUDES})
|
||||
add_library(tkDNN SHARED ${tkdnn_SRC})
|
||||
target_link_libraries(tkDNN ${tkdnn_LIBS})
|
||||
####compile
|
||||
#set(PROJ_NAME BaggageAIApi)
|
||||
# Path to BaggageAI project folder.
|
||||
set(BAGGAGEAI_PATH /home/baggageai/files)
|
||||
# Give a custom name to shared library which is provided by DIMENSIONLESS.
|
||||
#set(BAGGAGEAI_LIB_NAME libBaggageAI)
|
||||
# Define C++ level, could be 11 or 17 as well.
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
# Define compiler optimization level.
|
||||
set(CMAKE_CXX_FLAGS "-O3")
|
||||
# Do print warnings uppon compilation, let's keep our code as clean as possible.
|
||||
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
|
||||
# Apply flags.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DBOOST_LOG_DYN_LINK")
|
||||
set(Casablanca_LIBRARIES "-lboost_log -lboost_log_setup -lboost_thread -lboost_system -lcrypto -lssl -lcpprest -lpthread")
|
||||
|
||||
|
||||
# Note: We do not recommend using GLOB or GLOB_RECURSE to collect a list of source files from your source tree.
|
||||
# If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know
|
||||
# when to ask CMake to regenerate.
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES "main.cpp" "handler.cpp" "src/*.cpp","src/*.c")
|
||||
|
||||
add_executable(baggageAPI ${SOURCE_FILES})
|
||||
set(Casablanca_LIBRARIES "-lboost_log -lboost_log_setup -lboost_thread -lboost_system -lcrypto -lssl -lcpprest -lpthread" )
|
||||
set(tkdnn_LIBS kernels ${Casablanca_LIBRARIES} ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS} yaml-cpp)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
# Link BaggageAI library' include folder.
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} ${NVINFER_INCLUDES} ${Casablanca_LIBRARIES} ${CMAKE_CXX_FLAGS})
|
||||
# Define BaggageAI library' shared library.
|
||||
#add_library(${BAGGAGEAI_LIB_NAME} SHARED IMPORTED)
|
||||
# Set a path to BaggageAI library' shared library
|
||||
#set_property(TARGET ${BAGGAGEAI_LIB_NAME} PROPERTY IMPORTED_LOCATION "${BAGGAGEAI_PATH}/libBaggageAI.so")
|
||||
|
||||
# Link all libraries together.
|
||||
target_link_libraries(baggageAPI ${tkdnn_LIBS})
|
||||
|
||||
#static
|
||||
#add_library(tkDNN_static STATIC ${tkdnn_SRC})
|
||||
#target_link_libraries(tkDNN_static ${tkdnn_LIBS})
|
||||
|
||||
add_executable(test_simple tests/simple/test_simple.cpp)
|
||||
target_link_libraries(test_simple tkDNN)
|
||||
|
||||
add_executable(test_mnist tests/mnist/test_mnist.cpp)
|
||||
target_link_libraries(test_mnist tkDNN)
|
||||
|
||||
add_executable(test_mnistRT tests/mnist/test_mnistRT.cpp)
|
||||
target_link_libraries(test_mnistRT tkDNN)
|
||||
|
||||
## YOLO NETS
|
||||
add_executable(test_yolo tests/yolo/yolo.cpp)
|
||||
target_link_libraries(test_yolo tkDNN)
|
||||
|
||||
add_executable(test_yolo_voc tests/yolo_voc/yolo_voc.cpp)
|
||||
target_link_libraries(test_yolo_voc tkDNN)
|
||||
|
||||
add_executable(test_yolo_tiny tests/yolo_tiny/yolo_tiny.cpp)
|
||||
target_link_libraries(test_yolo_tiny tkDNN)
|
||||
|
||||
add_executable(test_yolo_relu tests/yolo_relu/yolo_relu.cpp)
|
||||
target_link_libraries(test_yolo_relu tkDNN)
|
||||
|
||||
|
||||
add_executable(test_yolo_224 tests/yolo_224/yolo_224.cpp)
|
||||
target_link_libraries(test_yolo_224 tkDNN)
|
||||
|
||||
add_executable(test_yolo_berkeley tests/yolo_berkeley/yolo_berkeley.cpp)
|
||||
target_link_libraries(test_yolo_berkeley tkDNN)
|
||||
|
||||
add_executable(test_yolo3_coco4 tests/yolo3_coco4/yolo3_coco4.cpp)
|
||||
target_link_libraries(test_yolo3_coco4 tkDNN)
|
||||
|
||||
add_executable(test_yolo3 tests/yolo3/yolo3.cpp)
|
||||
target_link_libraries(test_yolo3 tkDNN)
|
||||
|
||||
add_executable(test_yolo3_tiny tests/yolo3_tiny/yolo3_tiny.cpp)
|
||||
target_link_libraries(test_yolo3_tiny tkDNN)
|
||||
|
||||
add_executable(test_yolo3_berkeley tests/yolo3_berkeley/yolo3_berkeley.cpp)
|
||||
target_link_libraries(test_yolo3_berkeley tkDNN)
|
||||
|
||||
add_executable(test_yolo3_flir tests/yolo3_flir/yolo3_flir.cpp)
|
||||
target_link_libraries(test_yolo3_flir tkDNN)
|
||||
|
||||
|
||||
add_executable(test_resnet101 tests/resnet101/resnet101.cpp)
|
||||
target_link_libraries(test_resnet101 tkDNN)
|
||||
|
||||
add_executable(test_resnet101_cnet tests/resnet101_cnet/resnet101_cnet.cpp)
|
||||
target_link_libraries(test_resnet101_cnet tkDNN)
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
add_executable(test_rtinference tests/test_rtinference/rtinference.cpp)
|
||||
target_link_libraries(test_rtinference tkDNN)
|
||||
|
||||
add_executable(yolo3_demo demo/demo/demo.cpp)
|
||||
target_link_libraries(yolo3_demo tkDNN)
|
||||
|
||||
#add_executable(demo demo/inf.cpp)
|
||||
#target_link_libraries(demo tkDNN)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Install
|
||||
@@ -123,18 +119,3 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" # source directory
|
||||
DESTINATION "share/tkDNN/cmake/" # target directory
|
||||
)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Prepare for test
|
||||
#-------------------------------------------------------------------------------
|
||||
set(TEST_DATA true CACHE BOOL "If true download deps")
|
||||
if( ${TEST_DATA} )
|
||||
message("Launching pre-build dependency installer script...")
|
||||
|
||||
execute_process (COMMAND bash -c "bash build_models.sh download"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests)
|
||||
|
||||
set(TEST_DATA false CACHE BOOL "If true download deps" FORCE)
|
||||
message("Finished dowloading test weights")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,51 +1,148 @@
|
||||
# tkDNN
|
||||
tkDNN is a Deep Neural Network library built with cuDNN primitives specifically thought to work on NVIDIA TK1(and all successive) board.<br>
|
||||
The main scope is to do high performance inference on already trained models.
|
||||
|
||||
this branch actually work on every NVIDIA GPU that support the dependencies:
|
||||
* CUDA 10.0
|
||||
* CUDNN 7.603
|
||||
* TENSORRT 6.01
|
||||
* OPENCV 4.1
|
||||
# Steps to build docker image
|
||||
## Docker
|
||||
Docker version 19.03 will be required.
|
||||
|
||||
## Workflow
|
||||
The recommended workflow follow these step:
|
||||
* Build and train a model in Keras (on any PC)
|
||||
* Export weights and bias
|
||||
* Define the model on tkDNN
|
||||
* Do inference (on TK1)
|
||||
## For running with GPU
|
||||
### NVIDIA Drivers
|
||||
This drivers should be installed in the host system.
|
||||
### For Ubuntu:
|
||||
```
|
||||
$ sudo apt-get install linux-headers-$(uname -r) gcc g++ make
|
||||
$ wget http://in.download.nvidia.com/tesla/418.67/NVIDIA-Linux-x86_64-418.67.run
|
||||
$ chmod 777 NVIDIA-Linux-x86_64-418.67.run
|
||||
$ bash NVIDIA-Linux-x86_64-418.67.run
|
||||
```
|
||||
|
||||
## Compile the library
|
||||
Build with cmake
|
||||
### For CentOS
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
# use -DTEST_DATA=False to skip dataset download
|
||||
make
|
||||
$ sudo yum -y install kernel-devel-$(uname -r) kernel-header-$(uname -r) gcc make
|
||||
$ wget http://in.download.nvidia.com/tesla/418.67/NVIDIA-Linux-x86_64-418.67.run
|
||||
$ chmod 777 NVIDIA-Linux-x86_64-418.67.run
|
||||
$ bash NVIDIA-Linux-x86_64-418.67.run
|
||||
```
|
||||
during the cmake configuration it will be dowloaded the weights needed for running
|
||||
the tests
|
||||
|
||||
## Test
|
||||
Assumiung you have correctly builded the library these are the test ready to exec:
|
||||
* test_simple: a simple convolutional and dense network (CUDNN only)
|
||||
* test_mnist: the famous mnist netwok (CUDNN and TENSORRT)
|
||||
* test_mnistRT: the mnist network hardcoded in using tensorRT apis (TENSORRT only)
|
||||
* test_yolo: YOLO detection network (CUDNN and TENSORRT)
|
||||
* test_yolo_tiny: smaller version of YOLO (CUDNN and TENSRRT)
|
||||
* test_yolo3_berkeley: our yolo3 version trained with BDD100K dateset
|
||||
### NVIDIA Container Toolkit
|
||||
This toolkit should be installed in the host system.
|
||||
### For Ubuntu
|
||||
```
|
||||
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
|
||||
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
|
||||
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
|
||||
|
||||
## yolo3 berkeley demo detection
|
||||
For the live detection you need to precompile the tensorRT file by luncing the desidered network test, this is the recommended process:
|
||||
$ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
|
||||
$ sudo systemctl restart docker
|
||||
```
|
||||
export TKDNN_MODE=FP16 # set the half floating point optimization
|
||||
rm yolo3_berkeley.rt # be sure to delete(or move) old tensorRT files
|
||||
./test_yolo3_berkeley # run the yolo test (is slow)
|
||||
# with f16 inference the result will be a bit incorrect
|
||||
|
||||
### For CentOS
|
||||
```
|
||||
this will genereate a yolo3_berkeley.rt file that can be used for live detection:
|
||||
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
|
||||
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
|
||||
|
||||
$ sudo yum install -y nvidia-container-toolkit
|
||||
$ sudo systemctl restart docker
|
||||
```
|
||||
./yolo3_demo # launch detection on a demo video
|
||||
./yolo3_demo yolo3_berkeley.rt /dev/video0 # launch detection on device 0
|
||||
|
||||
### Building docker image
|
||||
|
||||
* Go to ``TKDNN/`` then run following command.
|
||||
```$ docker build -t baggageai:server -f docker/Dockerfile .```
|
||||
#### Note:
|
||||
1. have to copy weights into a TKDNN/config/ (tkdnn converted weights) current support api (fp32X4 and fp16X1)
|
||||
2. setup number of classes accrding to weights in TKDNN/config/config.yml
|
||||
3. give path of this weights into handler.cpp line number 117-121.
|
||||
|
||||
### Run docker image
|
||||
```
|
||||
$ docker run --gpus all -p 8080:8080 -d <image_id>
|
||||
```
|
||||
Now server will be started in the container. You can check server is running or not using ``docker ps``
|
||||
|
||||
|
||||
|
||||
|
||||
### Run docker image
|
||||
```
|
||||
$ docker run -p 8080:8080 -d <image_id>
|
||||
```
|
||||
|
||||
|
||||
# Using docker-compose file
|
||||
## Docker Compose
|
||||
Install docker-compose version 1.24.1
|
||||
[https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/)
|
||||
|
||||
## Create Volume
|
||||
Create a volume named ``BAI_logs`` using following command:
|
||||
```
|
||||
$ docker volume create BAI_logs
|
||||
```
|
||||
Change permission of the directory of docker volume, so that logs can be written to that directory.
|
||||
```
|
||||
$ cd /var/lib/docker/volumes/BAI_logs
|
||||
$ chmod 757 _data/
|
||||
```
|
||||
```
|
||||
## For running with GPU
|
||||
Install nvidia-container-runtime:
|
||||
```
|
||||
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
|
||||
sudo apt-key add -
|
||||
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
|
||||
$ curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
|
||||
sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install nvidia-container-runtime
|
||||
```
|
||||
|
||||
Add nvidia runtime in ``/etc/docker/daemon.json ``
|
||||
```
|
||||
{
|
||||
"runtimes": {
|
||||
"nvidia": {
|
||||
"path": "/usr/bin/nvidia-container-runtime",
|
||||
"runtimeArgs": []
|
||||
}
|
||||
},
|
||||
"default-runtime": "nvidia"
|
||||
|
||||
}
|
||||
```
|
||||
After editing changes restart the docker.
|
||||
``systemctl restart docker ``
|
||||
|
||||
Go to ``BaggageAI-Darknet-API/baggageai/dist/server/with-gpu`` and run:
|
||||
```
|
||||
$ docker-compose up -d
|
||||
```
|
||||
|
||||
## Running containers in stack
|
||||
First of all initialize a swarm.
|
||||
```
|
||||
$ docker swarm init
|
||||
```
|
||||
You can add a worker node using ``docker swarm join`` command displayed on terminal.
|
||||
|
||||
|
||||
Check the statsus using
|
||||
```
|
||||
$ docker service ls
|
||||
$ docker stack ls
|
||||
```
|
||||
|
||||
### With GPU
|
||||
Go to ``TKDNN/docker/`` and run:
|
||||
```
|
||||
$ docker stack deploy -c docker-compose.yml <service-name>
|
||||
```
|
||||
|
||||
# Calling the API
|
||||
```
|
||||
curl -X POST http://localhost:8080?name=<file_name> --data-binary "@<absolute_path_of_image>"
|
||||
```
|
||||
Example,
|
||||
```
|
||||
curl -X POST http://localhost:8080?name=S0240628297_20180812164749_L-4_3.jpg \
|
||||
--data-binary "@/home/ubuntu/BaggageAI/S0240628297_20180812164749_L-4_3.jpg"
|
||||
```
|
||||
|
||||
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_image.h"
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include "Yolo3Detection.h"
|
||||
//#include "CenternetDetection.h"
|
||||
//#include "MobilenetDetection.h"
|
||||
#include "evaluation.h"
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
|
||||
#include<sys/socket.h> //socket
|
||||
#include<sys/types.h>
|
||||
#include<netinet/in.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
#define PORT 8080
|
||||
|
||||
#define FRAME_WIDTH 640
|
||||
#define FRAME_HEIGHT 480
|
||||
|
||||
void error(const char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
} int sockfd, newsockfd, portno, n, imgSize, bytes=0, IM_HEIGHT, IM_WIDTH;;
|
||||
socklen_t clilen;
|
||||
char buffer[256];
|
||||
// struct sockaddr_in serv_addr, cli_addr;
|
||||
// sockfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
cv::Mat img;
|
||||
char ntype = 'y';
|
||||
const char *config_filename = "../demo/config.yaml";
|
||||
const char * net = "../demo/yolo4_fp32.rt";
|
||||
// const char * img_path = "../demo/demo.jpg";
|
||||
char * img_data;
|
||||
bool show = false;
|
||||
bool verbose;
|
||||
int classes, map_points, map_levels;
|
||||
float map_step, IoU_thresh, conf_thresh;
|
||||
tk::dnn::Yolo3Detection yolo;
|
||||
// tk::dnn::CenternetDetection cnet;
|
||||
// tk::dnn::MobilenetDetection mbnet;
|
||||
tk::dnn::DetectionNN *detNN;
|
||||
int n_classes = classes;
|
||||
std::vector<tk::dnn::Frame> images;
|
||||
std::vector<tk::dnn::box> detected_bbox;
|
||||
tk::dnn::Frame f;
|
||||
|
||||
void init_bag(){tk::dnn::readmAPParams(config_filename, classes, map_points, map_levels, map_step,
|
||||
IoU_thresh, conf_thresh, verbose);
|
||||
|
||||
|
||||
//extract network name from rt path
|
||||
std::string net_name;
|
||||
removePathAndExtension(net, net_name);
|
||||
std::cout<<"Network: "<<net_name<<std::endl;
|
||||
|
||||
//open files (if needed)
|
||||
//std::ofstream times, memory, coco_json;
|
||||
int n_classes = classes;
|
||||
// float conf_threshold=0.001;
|
||||
detNN = &yolo;
|
||||
detNN->init(net, n_classes, 1, conf_thresh);
|
||||
|
||||
//read images
|
||||
// std::ifstream all_labels(labels_path);
|
||||
// std::cout << timeSinceEpochMillisec() << std::endl;
|
||||
std::string l_filename;
|
||||
|
||||
if(show)
|
||||
cv::namedWindow("detection", cv::WINDOW_NORMAL);
|
||||
return;}
|
||||
// init_bag();
|
||||
// int images_done;
|
||||
// for (images_done=0 ; std::getline(all_labels, l_filename) && images_done < n_images ; ++images_done) {
|
||||
// std::cout <<COL_ORANGEB<< "Images done:\t" << images_done<< "\n"<<COL_END;
|
||||
void infr(cv::Mat image){
|
||||
|
||||
cv::Mat frame = image;
|
||||
cv::imwrite("/home/baggageai/files/build/test.png", frame);
|
||||
std::cout<<frame.channels();
|
||||
std::vector<cv::Mat> batch_frames;
|
||||
batch_frames.push_back(frame);
|
||||
int height = frame.rows;
|
||||
int width = frame.cols;
|
||||
std::cout<<height<<"width"<<width<<"\n";
|
||||
// if(!frame.data)
|
||||
// break;
|
||||
std::vector<cv::Mat> batch_dnn_input;
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
std::cout<<"test1"<<"\n";
|
||||
//inference
|
||||
detected_bbox.clear();
|
||||
detNN->update(batch_dnn_input,1);
|
||||
detNN->draw(batch_frames);
|
||||
detected_bbox = detNN->detected;
|
||||
std::cout<<"test2"<<"\n";
|
||||
//try{
|
||||
//json::value response;
|
||||
//vector<json::value> jsonArray;
|
||||
// save detections labels
|
||||
for(auto d:detected_bbox){
|
||||
//convert detected bb in the same format as label
|
||||
//<x_center>/<image_width> <y_center>/<image_width> <width>/<image_width> <height>/<image_width>
|
||||
tk::dnn::BoundingBox b;
|
||||
b.x = (d.x + d.w/2) / width;
|
||||
b.y = (d.y + d.h/2) / height;
|
||||
b.w = d.w / width;
|
||||
b.h = d.h / height;
|
||||
b.prob = d.prob;
|
||||
b.cl = d.cl;
|
||||
//f.det.push_back(b);
|
||||
|
||||
/*json::value detection;
|
||||
detection["label"] = json::value::number(b.cl);
|
||||
detection["x"] = json::value::number(b.x);
|
||||
detection["y"] = json::value::number(b.y);
|
||||
detection["w"] = json::value::number(b.w);
|
||||
detection["h"] = json::value::number(b.h);
|
||||
detection["prob"] = json::value::number(b.prob);
|
||||
jsonArray.push_back(detection);*/
|
||||
std::cout<< d.cl << " "<< d.prob << " "<< b.x << " "<< b.y << " "<< b.w << " "<< b.h <<"\n";
|
||||
|
||||
if(show)// draw rectangle for detection
|
||||
cv::rectangle(batch_frames[0], cv::Point(d.x, d.y), cv::Point(d.x + d.w, d.y + d.h), cv::Scalar(0, 0, 255), 2);
|
||||
}
|
||||
//images.push_back(f);
|
||||
|
||||
if(show){
|
||||
cv::imshow("detection", batch_frames[0]);
|
||||
cv::waitKey(0);
|
||||
}
|
||||
// response["detections"] = json::value::array(jsonArray); //JSON Response
|
||||
|
||||
// std::cout << timeSinceEpochMillisec() << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// int sockfd, newsockfd, portno, n, imgSize, bytes=0, IM_HEIGHT, IM_WIDTH;;
|
||||
// socklen_t clilen;
|
||||
char buffer[256];
|
||||
struct sockaddr_in serv_addr, cli_addr;
|
||||
//init_bag()
|
||||
// cv::Mat img;
|
||||
|
||||
sockfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd<0) error("ERROR opening socket");
|
||||
|
||||
bzero((char*)&serv_addr, sizeof(serv_addr));
|
||||
portno = PORT;
|
||||
|
||||
serv_addr.sin_family=AF_INET;
|
||||
serv_addr.sin_addr.s_addr=INADDR_ANY;
|
||||
serv_addr.sin_port=htons(portno);
|
||||
|
||||
if(bind(sockfd, (struct sockaddr *) &serv_addr,
|
||||
sizeof(serv_addr))<0) error("ERROR on binding");
|
||||
|
||||
listen(sockfd,5);
|
||||
clilen=sizeof(cli_addr);
|
||||
|
||||
newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
|
||||
if(newsockfd<0) error("ERROR on accept");
|
||||
|
||||
uchar sock[3];
|
||||
cout << sock <<endl;
|
||||
cout << sock+3 <<endl;
|
||||
|
||||
// bzero(buffer,1024);
|
||||
// n = read(newsockfd, buffer, 1023);
|
||||
// if(n<0) error("ERROR reading from socket");
|
||||
//printf("Here is the message: %s\n", buffer);
|
||||
|
||||
// n=write(newsockfd, "I got your message", 18);
|
||||
// if(n<0) error("ERROR writing to socket");
|
||||
bool running = true;
|
||||
|
||||
while(running)
|
||||
{ std::cout<<"t"<<"\n";
|
||||
IM_HEIGHT = FRAME_HEIGHT;
|
||||
IM_WIDTH = FRAME_WIDTH;
|
||||
img = Mat::zeros(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC3);
|
||||
|
||||
imgSize = img.total()*img.elemSize();
|
||||
uchar sockData[imgSize];
|
||||
std::cout<<"t2"<<"\n";
|
||||
for(int i=0;i<imgSize;i+=bytes)
|
||||
if ((bytes=recv(newsockfd, sockData+i, imgSize-i,0))==-1) error("recv failed");
|
||||
|
||||
int ptr=0;
|
||||
|
||||
for(int i=0;i<img.rows;++i)
|
||||
for(int j=0;j<img.cols;++j)
|
||||
{
|
||||
img.at<Vec3b>(i,j) = Vec3b(sockData[ptr+0],sockData[ptr+1],sockData[ptr+2]);
|
||||
ptr=ptr+3;
|
||||
}
|
||||
std::cout<<"t3"<<"\n";
|
||||
int height = img.cols;
|
||||
std::cout<<height;
|
||||
infr(img)
|
||||
// namedWindow( "Server", CV_WINDOW_AUTOSIZE );// Create a window for display.
|
||||
// imshow( "Server", img );
|
||||
// char key = waitKey(30);
|
||||
// running = key;
|
||||
//esc
|
||||
// if(key==27) running =false;
|
||||
}
|
||||
|
||||
close(newsockfd);
|
||||
close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+62
-29
@@ -1,33 +1,66 @@
|
||||
# Find the header files
|
||||
# find the library
|
||||
if(CUDA_FOUND)
|
||||
find_cuda_helper_libs(cudnn)
|
||||
set(CUDNN_LIBRARY ${CUDA_cudnn_LIBRARY} CACHE FILEPATH "location of the cuDNN library")
|
||||
unset(CUDA_cudnn_LIBRARY CACHE)
|
||||
|
||||
find_path(CUDNN_INCLUDE_DIR
|
||||
${CMAKE_SYSROOT}/usr/local/include
|
||||
${CMAKE_SYSROOT}/usr/include
|
||||
/usr/local/nvidia/tensorrt/include/
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_cuda_helper_libs(nvinfer)
|
||||
set(NVINFER_LIBRARY ${CUDA_nvinfer_LIBRARY} CACHE FILEPATH "location of the nvinfer library")
|
||||
unset(CUDA_nvinfer_LIBRARY CACHE)
|
||||
endif()
|
||||
|
||||
set(OLD_ROOT ${CMAKE_FIND_ROOT_PATH})
|
||||
list(APPEND CMAKE_FIND_ROOT_PATH /)
|
||||
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .so.7)
|
||||
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .so.5)
|
||||
find_library(CUDNN_LIB
|
||||
NAMES cudnn
|
||||
PATHS
|
||||
/usr/local/driveworks/targets/${CMAKE_SYSTEM_PROCESSOR}-Linux/lib
|
||||
/usr/lib/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/
|
||||
# find the include
|
||||
if(CUDNN_LIBRARY)
|
||||
find_path(CUDNN_INCLUDE_DIR
|
||||
cudnn.h
|
||||
PATHS ${CUDA_TOOLKIT_INCLUDE}
|
||||
DOC "location of cudnn.h"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_library(CUDNN_NVLIB
|
||||
NAMES "nvinfer"
|
||||
PATHS
|
||||
/usr/local/driveworks/targets/${CMAKE_SYSTEM_PROCESSOR}-Linux/lib
|
||||
/usr/lib/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
set(CMAKE_FIND_ROOT_PATH ${OLD_ROOT})
|
||||
)
|
||||
|
||||
set(CUDNN_LIBRARIES ${CUDNN_LIB} ${CUDNN_NVLIB})
|
||||
message("-- Found CUDNN: " ${CUDNN_LIB})
|
||||
message("-- Found NVINFER: " ${CUDNN_NVLIB})
|
||||
set(CUDNN_FOUND true)
|
||||
if(NOT CUDNN_INCLUDE_DIR)
|
||||
find_path(CUDNN_INCLUDE_DIR
|
||||
cudnn.h
|
||||
DOC "location of cudnn.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
message("-- Found CUDNN: " ${CUDNN_LIBRARY})
|
||||
message("-- Found CUDNN include: " ${CUDNN_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(NVINFER_LIBRARY)
|
||||
find_path(NVINFER_INCLUDE_DIR
|
||||
NvInfer.h
|
||||
PATHS ${CUDA_TOOLKIT_INCLUDE}
|
||||
DOC "location of NvInfer.h"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(NOT NVINFER_INCLUDE_DIR)
|
||||
find_path(NVINFER_INCLUDE_DIR
|
||||
NvInfer.h
|
||||
DOC "location of NvInfer.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
message("-- Found NVINFER: " ${NVINFER_LIBRARY})
|
||||
message("-- Found NVINFER include: " ${NVINFER_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(CUDNN
|
||||
FOUND_VAR CUDNN_FOUND
|
||||
REQUIRED_VARS
|
||||
CUDNN_LIBRARY
|
||||
CUDNN_INCLUDE_DIR
|
||||
VERSION_VAR CUDNN_VERSION
|
||||
)
|
||||
|
||||
if(CUDNN_FOUND)
|
||||
set(CUDNN_LIBRARIES ${CUDNN_LIBRARY} ${NVINFER_LIBRARY})
|
||||
set(CUDNN_INCLUDE_DIRS ${CUDNN_INCLUDE_DIR} ${NVINFER_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
set(CUDNN_FOUND true)
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
classes1 : 39 #number of classes
|
||||
conf_thresh1 : 0.3 #threshold on the condifence of the bbox
|
||||
net1 : ../demo/yolo4x_fp16.rt
|
||||
classes2 : 39 #number of classes
|
||||
conf_thresh2 : 0.3 #threshold on the condifence of the bbox
|
||||
net2 : ../demo/yolo4x_fp16.rt
|
||||
classes3 : 39 #number of classes
|
||||
conf_thresh3 : 0.3 #threshold on the condifence of the bbox
|
||||
net3 : ../demo/yolo4x_fp16.rt
|
||||
classes4 : 39 #number of classes
|
||||
conf_thresh4 : 0.3 #threshold on the condifence of the bbox
|
||||
net4 : ../demo/yolo4x_fp16.rt
|
||||
classes5 : 39 #number of classes
|
||||
conf_thresh5 : 0.3 #threshold on the condifence of the bbox
|
||||
net5 : ../demo/yolo4x_fp16.rt
|
||||
@@ -0,0 +1,15 @@
|
||||
classes1 : 39 #number of classes
|
||||
conf_thresh1 : 0.3 #threshold on the condifence of the bbox
|
||||
net1 : ../demo/yolo4x_fp16.rt
|
||||
classes2 : 39 #number of classes
|
||||
conf_thresh2 : 0.3 #threshold on the condifence of the bbox
|
||||
net2 : ../demo/yolo4x_fp16.rt
|
||||
classes3 : 39 #number of classes
|
||||
conf_thresh3 : 0.3 #threshold on the condifence of the bbox
|
||||
net3 : ../demo/yolo4x_fp16.rt
|
||||
classes4 : 39 #number of classes
|
||||
conf_thresh4 : 0.3 #threshold on the condifence of the bbox
|
||||
net4 : ../demo/yolo4x_fp16.rt
|
||||
classes5 : 39 #number of classes
|
||||
conf_thresh5 : 0.3 #threshold on the condifence of the bbox
|
||||
net5 : ../demo/yolo4x_fp16.rt
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
@@ -1,106 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
|
||||
// #include "Yolo3Detection.h"
|
||||
#include "CenternetDetection.h"
|
||||
|
||||
bool gRun;
|
||||
bool SAVE_RESULT = false;
|
||||
|
||||
void sig_handler(int signo) {
|
||||
std::cout<<"request gateway stop\n";
|
||||
gRun = false;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
std::cout<<"detection\n";
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
|
||||
char *net = "resnet101_cnet.rt";
|
||||
if(argc > 1)
|
||||
net = argv[1];
|
||||
char *input = "../demo/yolo_test.mp4";
|
||||
if(argc > 2)
|
||||
input = argv[2];
|
||||
|
||||
// tk::dnn::Yolo3Detection yolo;
|
||||
tk::dnn::CenternetDetection yolo;
|
||||
yolo.init(net);
|
||||
|
||||
gRun = true;
|
||||
|
||||
cv::VideoCapture cap(input);
|
||||
if(!cap.isOpened())
|
||||
gRun = false;
|
||||
else
|
||||
std::cout<<"camera started\n";
|
||||
|
||||
|
||||
cv::VideoWriter resultVideo;
|
||||
if(SAVE_RESULT) {
|
||||
int w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
|
||||
int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
|
||||
resultVideo.open("result.mp4", cv::VideoWriter::fourcc('M','P','4','V'), 30, cv::Size(w, h));
|
||||
}
|
||||
|
||||
cv::Mat frame;
|
||||
cv::Mat dnn_input;
|
||||
cv::namedWindow("detection", cv::WINDOW_NORMAL);
|
||||
|
||||
while(gRun) {
|
||||
cap >> frame;
|
||||
if(!frame.data) {
|
||||
break;
|
||||
}
|
||||
|
||||
// this will be resized to the net format
|
||||
dnn_input = frame.clone();
|
||||
// TODO: async infer
|
||||
yolo.update(dnn_input);
|
||||
|
||||
frame = yolo.draw(dnn_input);
|
||||
// // draw dets
|
||||
// for(int i=0; i<yolo.detected.size(); i++) {
|
||||
// tk::dnn::box b = yolo.detected[i];
|
||||
// int x0 = b.x;
|
||||
// int x1 = b.x + b.w;
|
||||
// int y0 = b.y;
|
||||
// int y1 = b.y + b.h;
|
||||
// std::string det_class = yolo.coco_class_name[b.cl];
|
||||
// // yolo.getYoloLayer()->classesNames[b.cl];
|
||||
// float prob = b.prob;
|
||||
|
||||
// // std::cout<<det_class<<" ("<<prob<<"): "<<x0<<" "<<y0<<" "<<x1<<" "<<y1<<"\n";
|
||||
// // draw rectangle
|
||||
// cv::rectangle(frame, cv::Point(x0, y0), cv::Point(x1, y1), yolo.colors[b.cl], 2);
|
||||
|
||||
// // draw label
|
||||
// int baseline = 0;
|
||||
// float fontScale = 0.5;
|
||||
// int thickness = 2;
|
||||
// cv::Size textSize = getTextSize(det_class, cv::FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
|
||||
// cv::rectangle(frame, cv::Point(x0, y0), cv::Point((x0 + textSize.width - 2), (y0 - textSize.height - 2)), yolo.colors[b.cl], -1);
|
||||
// cv::putText(frame, det_class, cv::Point(x0, (y0 - (baseline / 2))), cv::FONT_HERSHEY_SIMPLEX, fontScale, cv::Scalar(255, 255, 255), thickness);
|
||||
// }
|
||||
|
||||
cv::imshow("detection", frame);
|
||||
cv::waitKey(1);
|
||||
if(SAVE_RESULT)
|
||||
resultVideo << frame;
|
||||
}
|
||||
|
||||
std::cout<<"detection end\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
FROM mohitkhubele95/tkdnn
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y software-properties-common
|
||||
RUN add-apt-repository 'deb http://security.ubuntu.com/ubuntu xenial-security main'
|
||||
RUN apt-get -y update
|
||||
RUN apt-get -y upgrade
|
||||
|
||||
RUN apt-get -y install cmake g++ git sudo vim curl rapidjson-dev awscli zip unzip dpkg libcpprest-dev libboost-dev libboost-all-dev
|
||||
|
||||
RUN useradd -ms /bin/bash baggageai && echo "baggageai:baggageai" | chpasswd && adduser baggageai sudo
|
||||
USER baggageai
|
||||
WORKDIR /home/baggageai
|
||||
EXPOSE 8080
|
||||
|
||||
#RUN aws s3 cp s3://dim-bai-s3-dev-developer-space/smiths_29_objects/BaggageAI.zip .
|
||||
|
||||
RUN mkdir files
|
||||
#RUN mkdir files/include
|
||||
#RUN mkdir files/server
|
||||
|
||||
#Change path of include and server folder accordingly
|
||||
#COPY --chown=baggageai:baggageai src/include/ files/include
|
||||
#COPY --chown=baggageai:baggageai src/server/ files/server
|
||||
COPY --chown=baggageai:baggageai . files/
|
||||
#RUN aws s3 cp s3://dim-bai-s3-dev-developer-space/smiths_29_objects/libBaggageAI.so files/
|
||||
|
||||
WORKDIR /home/baggageai/files
|
||||
RUN chmod 777 run.sh
|
||||
ENTRYPOINT ["./run.sh"]
|
||||
@@ -0,0 +1,20 @@
|
||||
version: '3.7'
|
||||
services:
|
||||
baggageai-server-tkdnn:
|
||||
image: baggageai:server-tkdnn
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- BAI_logs:/home/baggageai/log
|
||||
environment:
|
||||
- NVIDIA_VISIBLE_DEVICES=all
|
||||
restart: on-failure
|
||||
deploy:
|
||||
replicas: 1 #Keep replicas 1 only for GPU
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
BAI_logs:
|
||||
external: true
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "stb_image.h"
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
#include "baggageDetect.hpp"
|
||||
#include "handler.h"
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include "Yolo3Detection.h"
|
||||
//#include "CenternetDetection.h"
|
||||
//#include "MobilenetDetection.h"
|
||||
#include "evaluation.h"
|
||||
#include "tkdnn.h"
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "image.h"
|
||||
void free_image(image m)
|
||||
{
|
||||
if(m.data){
|
||||
free(m.data);
|
||||
}
|
||||
}
|
||||
image make_empty_image(int w, int h, int c)
|
||||
{
|
||||
image out;
|
||||
out.data = 0;
|
||||
out.h = h;
|
||||
out.w = w;
|
||||
out.c = c;
|
||||
return out;
|
||||
}
|
||||
|
||||
image make_image(int w, int h, int c)
|
||||
{
|
||||
image out = make_empty_image(w,h,c);
|
||||
out.data = (float*)calloc(h * w * c, sizeof(float));
|
||||
return out;
|
||||
}
|
||||
int check_mistakes = 0;
|
||||
image load_image_file(unsigned char *image_data, int channels, int antilog, int gray, int width, int height)
|
||||
{
|
||||
int w, h, c;
|
||||
unsigned char *data = image_data;
|
||||
w = width;
|
||||
h = height;
|
||||
c = channels;
|
||||
|
||||
if (!image_data) {
|
||||
if (check_mistakes) getchar();
|
||||
return make_image(10, 10, 3);
|
||||
|
||||
}
|
||||
if (channels) c = channels;
|
||||
|
||||
int i,j,k;
|
||||
image im = make_image(w, h, c);
|
||||
for(k = 0; k < c; ++k){
|
||||
for(j = 0; j < h; ++j){
|
||||
for(i = 0; i < w; ++i){
|
||||
int dst_index = i + w*j + w*h*k;
|
||||
int src_index = k + c*i + c*w*j;
|
||||
(im).data[dst_index] = (float)image_data[src_index]/255.;
|
||||
}
|
||||
}
|
||||
}
|
||||
//free(data);
|
||||
return im;
|
||||
}
|
||||
cv::Mat image_to_mat(image img)
|
||||
{
|
||||
int channels = img.c;
|
||||
int width = img.w;
|
||||
int height = img.h;
|
||||
cv::Mat mat = cv::Mat(height, width, CV_8UC(channels));
|
||||
int step = mat.step;
|
||||
|
||||
for (int y = 0; y < img.h; ++y) {
|
||||
for (int x = 0; x < img.w; ++x) {
|
||||
for (int c = 0; c < img.c; ++c) {
|
||||
float val = img.data[c*img.h*img.w + y*img.w + x];
|
||||
mat.data[y*step + x*img.c + c] = (unsigned char)(val * 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
std::vector<std::string> classesNames;
|
||||
image im;
|
||||
cv::Mat frame;
|
||||
cv::Mat gray;
|
||||
int h=0;
|
||||
int w=0;
|
||||
int channels;
|
||||
const char *config_filename = "config/config.yaml";
|
||||
const char * net1="config/yolo4x_fp32.rt";
|
||||
const char * net2="config/yolo4x_fp32.rt";
|
||||
const char * net3="config/yolo4x_fp32.rt";
|
||||
const char * net4="config/yolo4x_fp32.rt";
|
||||
const char * net5="config/yolo4x_fp16.rt";
|
||||
int classes1 , classes2 , classes3 , classes4 , classes5,len;
|
||||
char * img_data;
|
||||
|
||||
string ustring;
|
||||
float conf_thresh1 , conf_thresh2 , conf_thresh3 , conf_thresh4 , conf_thresh5;
|
||||
tk::dnn::Yolo3Detection yolo1;
|
||||
tk::dnn::DetectionNN *detNN1;
|
||||
tk::dnn::Yolo3Detection yolo2;
|
||||
tk::dnn::DetectionNN *detNN2;
|
||||
tk::dnn::Yolo3Detection yolo3;
|
||||
tk::dnn::DetectionNN *detNN3;
|
||||
tk::dnn::Yolo3Detection yolo4;
|
||||
tk::dnn::DetectionNN *detNN4;
|
||||
tk::dnn::Yolo3Detection yolo5;
|
||||
tk::dnn::DetectionNN *detNN5;
|
||||
unsigned char * sockData;
|
||||
|
||||
std::vector<cv::Mat> batch_frames;
|
||||
std::vector<cv::Mat> batch_dnn_input;
|
||||
std::vector<std::string> classesNames1;
|
||||
std::vector<std::string> classesNames2;
|
||||
std::vector<std::string> classesNames3;
|
||||
std::vector<std::string> classesNames4;
|
||||
std::vector<std::string> classesNames5;
|
||||
std::vector<tk::dnn::Frame> images;
|
||||
std::vector<tk::dnn::box> detected_bbox1;
|
||||
std::vector<tk::dnn::box> detected_bbox2;
|
||||
std::vector<tk::dnn::box> detected_bbox3;
|
||||
std::vector<tk::dnn::box> detected_bbox4;
|
||||
std::vector<tk::dnn::box> detected_bbox5;
|
||||
//read parametersi
|
||||
handler::handler(utility::string_t url):m_listener(url)
|
||||
{
|
||||
m_listener.support(methods::POST, bind(&handler::handle_post, this, placeholders::_1));
|
||||
|
||||
}
|
||||
|
||||
string name_from_path(string path)
|
||||
{
|
||||
return path.substr(path.find_last_of("/\\")+1);
|
||||
}
|
||||
void handler::init_bag(){tk::dnn::readmAPParams(config_filename, classes1,conf_thresh1, classes2,conf_thresh2
|
||||
, classes3,conf_thresh3, classes4,conf_thresh4,classes5,conf_thresh5);
|
||||
|
||||
detNN1 = &yolo1;
|
||||
detNN1->init(net1, classes1, 1, conf_thresh1);
|
||||
classesNames1=detNN1-> classesNames;
|
||||
detNN2 = &yolo2;
|
||||
detNN2->init(net2, classes2, 1, conf_thresh2);
|
||||
classesNames2=detNN2-> classesNames;
|
||||
detNN3 = &yolo3;
|
||||
detNN3->init(net3, classes3, 1, conf_thresh4);
|
||||
classesNames3=detNN3-> classesNames;
|
||||
detNN4 = &yolo4;
|
||||
detNN4->init(net4, classes4, 1, conf_thresh4);
|
||||
classesNames4=detNN4-> classesNames;
|
||||
detNN5 = &yolo5;
|
||||
detNN5->init(net5, classes5, 1, conf_thresh5);
|
||||
classesNames5=detNN5-> classesNames;
|
||||
return;}
|
||||
|
||||
|
||||
void handler::handle_post(http_request request){
|
||||
BOOST_LOG_TRIVIAL(info) << "[" << name_from_path(string(__FILE__)) << " " << __LINE__ << "] " << request.to_string();
|
||||
|
||||
map<utility::string_t, utility::string_t> http_get_vars = uri::split_query(request.request_uri().query());
|
||||
map<utility::string_t, utility::string_t>::iterator it = http_get_vars.find("name");
|
||||
// int len;
|
||||
if(it == http_get_vars.end())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "[" << name_from_path(string(__FILE__)) << " " << __LINE__ << "] " << "Image name not passed in query.";
|
||||
request.reply(status_codes::UnprocessableEntity,"Please pass image name in the query.");
|
||||
return;
|
||||
}https://github.com/baggageai/baggageai-code-one.git
|
||||
// std::cout<<http_get_vars["name"]<<"\n";
|
||||
string image_name = (string)http_get_vars["name"];
|
||||
// string ustring;
|
||||
request.extract_vector().then([image_name, &ustring, &len](vector<unsigned char> v) {
|
||||
ustring = {v.begin(),v.end()};
|
||||
len = ustring.size();
|
||||
}).wait();
|
||||
unsigned char *idata;
|
||||
try { //printSize(ustring);
|
||||
BOOST_LOG_TRIVIAL(info) << "[" << name_from_path(string(__FILE__)) << " " << __LINE__ << "] " << "Detection Started";
|
||||
sockData = (unsigned char *)ustring.c_str();
|
||||
idata = stbi_load_from_memory(sockData, len, &w, &h, &channels, 0);
|
||||
im = load_image_file(idata, channels, 0, 0, w, h);
|
||||
batch_dnn_input.clear();
|
||||
//batch_frames.clear();
|
||||
gray=image_to_mat(im);
|
||||
// free(im);
|
||||
cv::Mat in[] = {gray, gray,gray};
|
||||
cv::merge(in, 3, frame);
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
json::value response;
|
||||
vector<json::value> jsonArray;
|
||||
|
||||
detected_bbox1.clear();
|
||||
detNN1->update(batch_dnn_input,1);
|
||||
detected_bbox1 = detNN1->detected;
|
||||
|
||||
for(auto d1:detected_bbox1){
|
||||
json::value detection;
|
||||
std::cout<<"1"<<" "<< d1.cl << " "<< d1.prob << " "<< d1.x << " "<< d1.y << " "<< d1.w << " "<< d1.h <<"\n";
|
||||
detection["label"] = json::value::string(classesNames1[d1.cl]);
|
||||
detection["x"] = json::value::number(d1.x);
|
||||
detection["y"] = json::value::number(d1.y);
|
||||
detection["w"] = json::value::number(d1.w);
|
||||
detection["h"] = json::value::number(d1.h);
|
||||
detection["prob"] = json::value::number(d1.prob);
|
||||
jsonArray.push_back(detection);
|
||||
}
|
||||
detected_bbox2.clear();
|
||||
batch_dnn_input.clear();
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
detNN2->update(batch_dnn_input,1);
|
||||
// std::cout<<batch_dnn_input[0].size()<<" testing3\n";
|
||||
detected_bbox2 = detNN2->detected;
|
||||
|
||||
for(auto d2:detected_bbox2){
|
||||
std::cout<<"2"<<" "<< d2.cl << " "<< d2.prob << " "<< d2.x << " "<< d2.y << " "<< d2.w << " "<< d2.h <<"\n";
|
||||
json::value detection;
|
||||
detection["label"] = json::value::string(classesNames2[d2.cl]);
|
||||
detection["x"] = json::value::number(d2.x);
|
||||
detection["y"] = json::value::number(d2.y);
|
||||
detection["w"] = json::value::number(d2.w);
|
||||
detection["h"] = json::value::number(d2.h);
|
||||
detection["prob"] = json::value::number(d2.prob);
|
||||
jsonArray.push_back(detection);
|
||||
}
|
||||
detected_bbox3.clear();
|
||||
batch_dnn_input.clear();
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
detNN3->update(batch_dnn_input,1);
|
||||
detected_bbox3 = detNN3->detected;
|
||||
for(auto d3:detected_bbox3){
|
||||
std::cout<< "3"<<" "<<d3.cl << " "<< d3.prob << " "<< d3.x << " "<< d3.y << " "<< d3.w << " "<< d3.h <<"\n";
|
||||
json::value detection;
|
||||
detection["label"] = json::value::string(classesNames3[d3.cl]);
|
||||
detection["x"] = json::value::number(d3.x);
|
||||
detection["y"] = json::value::number(d3.y);
|
||||
detection["w"] = json::value::number(d3.w);
|
||||
detection["h"] = json::value::number(d3.h);
|
||||
detection["prob"] = json::value::number(d3.prob);
|
||||
jsonArray.push_back(detection);
|
||||
}
|
||||
detected_bbox4.clear();
|
||||
batch_dnn_input.clear();
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
detNN4->update(batch_dnn_input,1);
|
||||
detected_bbox4 = detNN4->detected;
|
||||
|
||||
for(auto d4:detected_bbox4){
|
||||
std::cout<<"4"<<" "<<d4.cl<< " "<< d4.prob << " "<< d4.x << " "<< d4.y << " "<< d4.w << " "<< d4.h <<"\n";
|
||||
json::value detection;
|
||||
detection["label"] = json::value::string(classesNames4[d4.cl]);
|
||||
detection["x"] = json::value::number(d4.x);
|
||||
detection["y"] = json::value::number(d4.y);
|
||||
detection["w"] = json::value::number(d4.w);
|
||||
detection["h"] = json::value::number(d4.h);
|
||||
detection["prob"] = json::value::number(d4.prob);
|
||||
jsonArray.push_back(detection);
|
||||
}
|
||||
detected_bbox5.clear();
|
||||
batch_dnn_input.clear();
|
||||
batch_dnn_input.push_back(frame.clone());
|
||||
detNN5->update(batch_dnn_input,1);
|
||||
detected_bbox5 = detNN5->detected;
|
||||
|
||||
for(auto d5:detected_bbox5){
|
||||
std::cout<<"5"<<" "<<d5.cl<< " "<< d5.prob << " "<< d5.x << " "<< d5.y << " "<< d5.w << " "<< d5.h <<"\n";
|
||||
json::value detection;
|
||||
detection["label"] = json::value::string(classesNames5[d5.cl]);
|
||||
detection["x"] = json::value::number(d5.x);
|
||||
detection["y"] = json::value::number(d5.y);
|
||||
detection["w"] = json::value::number(d5.w);
|
||||
detection["h"] = json::value::number(d5.h);
|
||||
detection["prob"] = json::value::number(d5.prob);
|
||||
jsonArray.push_back(detection);
|
||||
}
|
||||
|
||||
response["detections"] = json::value::array(jsonArray); //JSON Response
|
||||
// free(jsonArray);
|
||||
request.reply(status_codes::OK,response.serialize());
|
||||
// free(detected_bbox);
|
||||
BOOST_LOG_TRIVIAL(info) << "[" << name_from_path(string(__FILE__)) << " " << __LINE__ << "] " << "Detection Completed and Response sent";
|
||||
}
|
||||
catch (exception const& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "[" << name_from_path(string(__FILE__)) << " " << __LINE__ << "] " << e.what();
|
||||
request.reply(status_codes::BadRequest, e.what());
|
||||
}
|
||||
// std::cout << timeSinceEpochMillisec() << std::endl;
|
||||
free(idata);
|
||||
free_image(im);
|
||||
return ;
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <thrust/sort.h>
|
||||
#include <thrust/execution_policy.h>
|
||||
#include <thrust/functional.h>
|
||||
#include <thrust/transform.h>
|
||||
#include <thrust/iterator/constant_iterator.h>
|
||||
#include <thrust/gather.h>
|
||||
#include <thrust/copy.h>
|
||||
|
||||
|
||||
#include "tkdnn.h"
|
||||
|
||||
void sort(dnnType *src_begin, dnnType *src_end, int *idsrc);
|
||||
void topk(dnnType *src_begin, int *idsrc, int K, float *topk_scores,
|
||||
int *topk_inds, float *topk_ys, float *topk_xs);
|
||||
void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int *topk_inds, float *topk_ys, float *topk_xs, const int size, const int K, const int n_classes);
|
||||
void subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out);
|
||||
void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys);
|
||||
void topKxyAddOffset(int * ids_begin, const int K, const int size, int *intxs_begin, int *intys_begin, float *xs_begin, float *ys_begin, dnnType *src_begin);
|
||||
void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin, dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1);
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef BOUNDINGBOX_H
|
||||
#define BOUNDINGBOX_H
|
||||
|
||||
#include <iostream>
|
||||
#include "tkdnn.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
class BoundingBox : public tk::dnn::box
|
||||
{
|
||||
float overlap(const float p1, const float l1, const float p2, const float l22);
|
||||
float boxesIntersection(const BoundingBox &b);
|
||||
float boxesUnion(const BoundingBox &b);
|
||||
|
||||
public:
|
||||
|
||||
int uniqueTruthIndex = -1;
|
||||
int truthFlag = 0;
|
||||
float maxIoU = 0;
|
||||
|
||||
float IoU(const BoundingBox &b);
|
||||
void clear();
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const BoundingBox& bb);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BoundingBox& bb);
|
||||
bool boxComparison (const BoundingBox& a,const BoundingBox& b) ;
|
||||
|
||||
}}
|
||||
#endif /*BOUNDINGBOX_H*/
|
||||
|
||||
@@ -1,112 +1,86 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
#include <time.h>
|
||||
#ifndef CENTERNETDETECTION_H
|
||||
#define CENTERNETDETECTION_H
|
||||
|
||||
#include "kernels.h"
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
#include <numeric> // std::iota
|
||||
#include <algorithm> // std::sort
|
||||
|
||||
#include "DetectionNN.h"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include "kernelsThrust.h"
|
||||
|
||||
#include "tkdnn.h"
|
||||
#include "sorting.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francesco Gatti
|
||||
*/
|
||||
class CenternetDetection {
|
||||
class CenternetDetection : public DetectionNN
|
||||
{
|
||||
private:
|
||||
tk::dnn::dataDim_t dim;
|
||||
tk::dnn::dataDim_t dim2;
|
||||
tk::dnn::dataDim_t dim_hm;
|
||||
tk::dnn::dataDim_t dim_wh;
|
||||
tk::dnn::dataDim_t dim_reg;
|
||||
float *topk_scores;
|
||||
int *topk_inds_;
|
||||
float *topk_ys_;
|
||||
float *topk_xs_;
|
||||
int *ids_d, *ids_, *ids_2, *ids_2d;
|
||||
|
||||
private:
|
||||
tk::dnn::NetworkRT *netRT = nullptr;
|
||||
dnnType *input_h, *input, *input_d;
|
||||
float *scores, *scores_d;
|
||||
int *clses, *clses_d;
|
||||
int *topk_inds_d;
|
||||
float *topk_ys_d;
|
||||
float *topk_xs_d;
|
||||
int *inttopk_xs_d, *inttopk_ys_d;
|
||||
|
||||
int ndets = 0;
|
||||
// tk::dnn::Yolo::detection *dets = nullptr;
|
||||
|
||||
cv::Mat imageF;
|
||||
cv::Mat bgr[3];
|
||||
|
||||
// variable to test cnet on dog pictures
|
||||
tk::dnn::dataDim_t dim;
|
||||
tk::dnn::dataDim_t dim2;
|
||||
cv::Size sz;
|
||||
const char *input_bin = "../tests/resnet101_cnet/debug/input.bin";
|
||||
|
||||
// pre-process
|
||||
tk::dnn::dataDim_t dim_hm;
|
||||
tk::dnn::dataDim_t dim_wh;
|
||||
tk::dnn::dataDim_t dim_reg;
|
||||
float *topk_scores;
|
||||
int *topk_inds_;
|
||||
float *topk_ys_;
|
||||
float *topk_xs_;
|
||||
int *ids_d, *ids_, *ids_2, *ids_2d;
|
||||
|
||||
float *scores, *scores_d;
|
||||
int *clses, *clses_d;
|
||||
int *topk_inds_d;
|
||||
float *topk_ys_d;
|
||||
float *topk_xs_d;
|
||||
int *inttopk_xs_d, *inttopk_ys_d;
|
||||
float *bbx0, *bby0, *bbx1, *bby1;
|
||||
float *bbx0_d, *bby0_d, *bbx1_d, *bby1_d;
|
||||
|
||||
float *target_coords;
|
||||
|
||||
float *bbx0, *bby0, *bbx1, *bby1;
|
||||
float *bbx0_d, *bby0_d, *bbx1_d, *bby1_d;
|
||||
|
||||
float *target_coords;
|
||||
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
float *mean_d;
|
||||
float *stddev_d;
|
||||
#else
|
||||
cv::Vec<float, 3> mean;
|
||||
cv::Vec<float, 3> stddev;
|
||||
cv::Mat src;
|
||||
cv::Mat dst;
|
||||
//processing
|
||||
float toll = 0.000001;
|
||||
int K = 100;
|
||||
int width = 56; // TODO
|
||||
dnnType *input;
|
||||
#endif
|
||||
|
||||
float *d_ptrs;
|
||||
|
||||
cv::Mat src;
|
||||
cv::Mat dst;
|
||||
cv::Mat dst2;
|
||||
cv::Mat trans, trans2;
|
||||
//processing
|
||||
float toll = 0.000001;
|
||||
int K = 100;
|
||||
int width = 128;//56; // TODO
|
||||
|
||||
// pointer used in the kernels
|
||||
float *src_out;
|
||||
int *ids_out;
|
||||
|
||||
struct threshold op;
|
||||
|
||||
|
||||
public:
|
||||
dnnType *rt_out[4];
|
||||
|
||||
float inp_height = 224;//512;
|
||||
float inp_width = 224;//512;
|
||||
|
||||
int classes = 80;
|
||||
int num = 0;
|
||||
int n_masks = 0;
|
||||
float thresh = 0.3;
|
||||
cv::Scalar colors[256];
|
||||
|
||||
// this is filled with results
|
||||
std::vector<tk::dnn::box> detected;
|
||||
// draw
|
||||
std::vector<std::string> coco_class_name;
|
||||
|
||||
CenternetDetection() {}
|
||||
|
||||
virtual ~CenternetDetection() {}
|
||||
|
||||
/**
|
||||
* Method used for inizialize the class
|
||||
*
|
||||
* @return Success of the initialization
|
||||
*/
|
||||
bool init(std::string tensor_path);
|
||||
void testdog();
|
||||
cv::Mat draw(cv::Mat &frame);
|
||||
void update(cv::Mat &frame);
|
||||
public:
|
||||
CenternetDetection() {};
|
||||
~CenternetDetection() {};
|
||||
|
||||
bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3);
|
||||
void preprocess(cv::Mat &frame, const int bi=0);
|
||||
void postprocess(const int bi=0,const bool mAP=false);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace tk
|
||||
|
||||
|
||||
#endif /*CENTERNETDETECTION_H*/
|
||||
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include "tkDNN/tkdnn.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
struct darknetFields_t{
|
||||
std::string type = "";
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int channels = 3;
|
||||
int batch_normalize=0;
|
||||
int groups = 1;
|
||||
int group_id = 0;
|
||||
int filters=1;
|
||||
int size_x=1;
|
||||
int size_y=1;
|
||||
int stride_x=1;
|
||||
int stride_y=1;
|
||||
int padding_x = 0;
|
||||
int padding_y = 0;
|
||||
int n_mask = 0;
|
||||
int classes = 20;
|
||||
int num = 1;
|
||||
int pad = 0;
|
||||
int coords = 4;
|
||||
int nms_kind = 0;
|
||||
int new_coords= 0;
|
||||
float scale_xy = 1;
|
||||
float nms_thresh = 0.45;
|
||||
std::vector<int> layers;
|
||||
std::string activation = "linear";
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const darknetFields_t& f){
|
||||
os << f.width << " " << f.height << " " << f.channels << " " << f.batch_normalize<< " " << f.filters << " " << f.activation<< " " << f.scale_xy;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
std::string darknetParseType(const std::string& line);
|
||||
bool divideNameAndValue(const std::string& line, std::string&name, std::string& value);
|
||||
std::vector<int> fromStringToIntVec(const std::string& line, const char delimiter);
|
||||
|
||||
bool darknetParseFields(const std::string& line, darknetFields_t& fields);
|
||||
tk::dnn::Network *darknetAddNet(darknetFields_t &fields);
|
||||
void darknetAddLayer(tk::dnn::Network *net, darknetFields_t &f, std::string wgs_path,
|
||||
std::vector<tk::dnn::Layer*> &netLayers, const std::vector<std::string>& names);
|
||||
std::vector<std::string> darknetReadNames(const std::string& names_file);
|
||||
tk::dnn::Network* darknetParser(const std::string& cfg_file, const std::string& wgs_path, const std::string& names_file);
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,185 @@
|
||||
#ifndef DETECTIONNN_H
|
||||
#define DETECTIONNN_H
|
||||
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
|
||||
#include "tkdnn.h"
|
||||
|
||||
//#define OPENCV_CUDACONTRIB //if OPENCV has been compiled with CUDA and contrib.
|
||||
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
#include <opencv2/cudawarping.hpp>
|
||||
#include <opencv2/cudaarithm.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
class DetectionNN {
|
||||
|
||||
protected:
|
||||
tk::dnn::NetworkRT *netRT = nullptr;
|
||||
dnnType *input_d;
|
||||
|
||||
std::vector<cv::Size> originalSize;
|
||||
|
||||
cv::Scalar colors[256];
|
||||
|
||||
int nBatches = 1;
|
||||
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
cv::cuda::GpuMat bgr[3];
|
||||
cv::cuda::GpuMat imagePreproc;
|
||||
#else
|
||||
cv::Mat bgr[3];
|
||||
cv::Mat imagePreproc;
|
||||
dnnType *input;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This method preprocess the image, before feeding it to the NN.
|
||||
*
|
||||
* @param frame original frame to adapt for inference.
|
||||
* @param bi batch index
|
||||
*/
|
||||
virtual void preprocess(cv::Mat &frame, const int bi=0) = 0;
|
||||
|
||||
/**
|
||||
* This method postprocess the output of the NN to obtain the correct
|
||||
* boundig boxes.
|
||||
*
|
||||
* @param bi batch index
|
||||
* @param mAP set to true only if all the probabilities for a bounding
|
||||
* box are needed, as in some cases for the mAP calculation
|
||||
*/
|
||||
virtual void postprocess(const int bi=0,const bool mAP=false) = 0;
|
||||
|
||||
public:
|
||||
int classes = 0;
|
||||
float confThreshold = 0.3; /*threshold on the confidence of the boxes*/
|
||||
|
||||
std::vector<tk::dnn::box> detected; /*bounding boxes in output*/
|
||||
std::vector<std::vector<tk::dnn::box>> batchDetected; /*bounding boxes in output*/
|
||||
std::vector<double> stats; /*keeps track of inference times (ms)*/
|
||||
std::vector<std::string> classesNames;
|
||||
|
||||
DetectionNN() {};
|
||||
~DetectionNN(){};
|
||||
|
||||
/**
|
||||
* Method used to initialize the class, allocate memory and compute
|
||||
* needed data.
|
||||
*
|
||||
* @param tensor_path path to the rt file of the NN.
|
||||
* @param n_classes number of classes for the given dataset.
|
||||
* @param n_batches maximum number of batches to use in inference
|
||||
* @return true if everything is correct, false otherwise.
|
||||
*/
|
||||
virtual bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3) = 0;
|
||||
|
||||
/**
|
||||
* This method performs the whole detection of the NN.
|
||||
*
|
||||
* @param frames frames to run detection on.
|
||||
* @param cur_batches number of batches to use in inference
|
||||
* @param save_times if set to true, preprocess, inference and postprocess times
|
||||
* are saved on a csv file, otherwise not.
|
||||
* @param times pointer to the output stream where to write times
|
||||
* @param mAP set to true only if all the probabilities for a bounding
|
||||
* box are needed, as in some cases for the mAP calculation
|
||||
*/
|
||||
void update(std::vector<cv::Mat>& frames, const int cur_batches=1, bool save_times=false, std::ofstream *times=nullptr, const bool mAP=false){
|
||||
if(save_times && times==nullptr)
|
||||
FatalError("save_times set to true, but no valid ofstream given");
|
||||
if(cur_batches > nBatches)
|
||||
FatalError("A batch size greater than nBatches cannot be used");
|
||||
|
||||
originalSize.clear();
|
||||
if(TKDNN_VERBOSE) printCenteredTitle(" TENSORRT detection ", '=', 30);
|
||||
{
|
||||
TKDNN_TSTART
|
||||
for(int bi=0; bi<cur_batches;++bi){
|
||||
if(!frames[bi].data)
|
||||
FatalError("No image data feed to detection");
|
||||
originalSize.push_back(frames[bi].size());
|
||||
preprocess(frames[bi], bi);
|
||||
}
|
||||
TKDNN_TSTOP
|
||||
if(save_times) *times<<t_ns<<";";
|
||||
}
|
||||
|
||||
//do inference
|
||||
tk::dnn::dataDim_t dim = netRT->input_dim;
|
||||
dim.n = cur_batches;
|
||||
{
|
||||
if(TKDNN_VERBOSE) dim.print();
|
||||
TKDNN_TSTART
|
||||
netRT->infer(dim, input_d);
|
||||
TKDNN_TSTOP
|
||||
if(TKDNN_VERBOSE) dim.print();
|
||||
stats.push_back(t_ns);
|
||||
if(save_times) *times<<t_ns<<";";
|
||||
}
|
||||
|
||||
batchDetected.clear();
|
||||
{
|
||||
TKDNN_TSTART
|
||||
for(int bi=0; bi<cur_batches;++bi)
|
||||
postprocess(bi, mAP);
|
||||
TKDNN_TSTOP
|
||||
if(save_times) *times<<t_ns<<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to draw bounding boxes and labels on a frame.
|
||||
*
|
||||
* @param frames original frame to draw bounding box on.
|
||||
*/
|
||||
void draw(std::vector<cv::Mat>& frames) {
|
||||
tk::dnn::box b;
|
||||
int x0, w, x1, y0, h, y1;
|
||||
int objClass;
|
||||
std::string det_class;
|
||||
int baseline = 0;
|
||||
float font_scale = 0.5;
|
||||
int thickness = 2;
|
||||
|
||||
for(int bi=0; bi<frames.size(); ++bi){
|
||||
// draw dets
|
||||
for(int i=0; i<batchDetected[bi].size(); i++) {
|
||||
b = batchDetected[bi][i];
|
||||
x0 = b.x;
|
||||
x1 = b.x + b.w;
|
||||
y0 = b.y;
|
||||
y1 = b.y + b.h;
|
||||
det_class = classesNames[b.cl];
|
||||
|
||||
// draw rectangle
|
||||
cv::rectangle(frames[bi], cv::Point(x0, y0), cv::Point(x1, y1), colors[b.cl], 2);
|
||||
|
||||
// draw label
|
||||
cv::Size text_size = getTextSize(det_class, cv::FONT_HERSHEY_SIMPLEX, font_scale, thickness, &baseline);
|
||||
cv::rectangle(frames[bi], cv::Point(x0, y0), cv::Point((x0 + text_size.width - 2), (y0 - text_size.height - 2)), colors[b.cl], -1);
|
||||
cv::putText(frames[bi], det_class, cv::Point(x0, (y0 - (baseline / 2))), cv::FONT_HERSHEY_SIMPLEX, font_scale, cv::Scalar(255, 255, 255), thickness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* DETECTIONNN_H*/
|
||||
@@ -0,0 +1,168 @@
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
#include <Eigen/Dense>
|
||||
#include "utils.h"
|
||||
#include "tkdnn.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francesco Gatti
|
||||
*/
|
||||
class ImuOdom {
|
||||
|
||||
public:
|
||||
tk::dnn::Network *net = nullptr;
|
||||
|
||||
// Network input dim
|
||||
tk::dnn::dataDim_t dim0;
|
||||
tk::dnn::dataDim_t dim1;
|
||||
tk::dnn::dataDim_t dim2;
|
||||
|
||||
// Network output dim
|
||||
tk::dnn::dataDim_t odim0;
|
||||
tk::dnn::dataDim_t odim1;
|
||||
|
||||
// input pointers
|
||||
dnnType *i0_d, *i1_d, *i2_d;
|
||||
// output pointers
|
||||
dnnType *o0_d, *o1_d;
|
||||
|
||||
// output eigen CPU
|
||||
Eigen::MatrixXf deltaP, deltaQ;
|
||||
|
||||
Eigen::MatrixXd odomPOS, odomEULER;
|
||||
Eigen::Matrix3d odomROT;
|
||||
Eigen::Isometry3f tf = Eigen::Isometry3f::Identity();
|
||||
|
||||
ImuOdom() {}
|
||||
|
||||
virtual ~ImuOdom() {}
|
||||
|
||||
/**
|
||||
* Method used for initialize the class
|
||||
*
|
||||
* @return Success of the initialization
|
||||
*/
|
||||
bool init(std::string layers_path) {
|
||||
|
||||
dim0 = tk::dnn::dataDim_t(1, 4, 1, 100);
|
||||
dim1 = tk::dnn::dataDim_t(1, 3, 1, 100);
|
||||
dim2 = tk::dnn::dataDim_t(1, 3, 1, 100);
|
||||
|
||||
checkCuda( cudaMalloc(&i0_d, dim0.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&i1_d, dim1.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&i2_d, dim2.tot()*sizeof(dnnType)) );
|
||||
|
||||
std::string c0_bin = layers_path + "/conv1d_7.bin";
|
||||
std::string c1_bin = layers_path + "/conv1d_8.bin";
|
||||
std::string c2_bin = layers_path + "/conv1d_9.bin";
|
||||
std::string c3_bin = layers_path + "/conv1d_10.bin";
|
||||
std::string c4_bin = layers_path + "/conv1d_11.bin";
|
||||
std::string c5_bin = layers_path + "/conv1d_12.bin";
|
||||
std::string l0_bin = layers_path + "/bidirectional_3.bin";
|
||||
std::string l1_bin = layers_path + "/bidirectional_4.bin";
|
||||
std::string d0_bin = layers_path + "/dense_3.bin";
|
||||
std::string d1_bin = layers_path + "/dense_4.bin";
|
||||
|
||||
net = new tk::dnn::Network(dim0);
|
||||
tk::dnn::Input *x0 = new tk::dnn::Input (net, dim0, i0_d);
|
||||
tk::dnn::Conv2d *x0_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c0_bin);
|
||||
tk::dnn::Conv2d *x0_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c1_bin);
|
||||
tk::dnn::Pooling *x0_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3 ,0, 0, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
|
||||
|
||||
tk::dnn::Input *x1 = new tk::dnn::Input (net, dim1, i1_d);
|
||||
tk::dnn::Conv2d *x1_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c2_bin);
|
||||
tk::dnn::Conv2d *x1_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c3_bin);
|
||||
tk::dnn::Pooling *x1_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3, 0, 0, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
|
||||
|
||||
tk::dnn::Input *x2 = new tk::dnn::Input (net, dim2, i2_d);
|
||||
tk::dnn::Conv2d *x2_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c4_bin);
|
||||
tk::dnn::Conv2d *x2_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c5_bin);
|
||||
tk::dnn::Pooling *x2_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3, 0, 0, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
|
||||
|
||||
tk::dnn::Layer *concat_l[3] = { x0_2, x1_2, x2_2 };
|
||||
tk::dnn::Route *concat = new tk::dnn::Route(net, concat_l, 3);
|
||||
|
||||
tk::dnn::LSTM *lstm0 = new tk::dnn::LSTM(net, 128, true, l0_bin);
|
||||
tk::dnn::LSTM *lstm1 = new tk::dnn::LSTM(net, 128, false, l1_bin);
|
||||
|
||||
tk::dnn::Dense *d0 = new tk::dnn::Dense(net, 3, d0_bin);
|
||||
|
||||
tk::dnn::Layer *lstm1_l[1] = { lstm1 };
|
||||
tk::dnn::Route *lstm1_link = new tk::dnn::Route(net, lstm1_l, 1);
|
||||
tk::dnn::Dense *d1 = new tk::dnn::Dense(net, 4, d1_bin);
|
||||
|
||||
net->print();
|
||||
|
||||
// output data
|
||||
o0_d = d0->dstData;
|
||||
o1_d = d1->dstData;
|
||||
odim0 = d0->output_dim;
|
||||
odim1 = d1->output_dim;
|
||||
|
||||
deltaP.resize(odim0.tot(), 1);
|
||||
deltaQ.resize(odim1.tot(), 1);
|
||||
|
||||
odomPOS = Eigen::MatrixXd::Zero(3, 1);
|
||||
odomROT = Eigen::MatrixXd::Identity(3, 3);
|
||||
odomEULER = Eigen::MatrixXd::Zero(3, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void close() {
|
||||
// TODO: dealloc :)
|
||||
}
|
||||
|
||||
void update(dnnType *x0, dnnType *x1, dnnType *x2) {
|
||||
|
||||
checkCuda( cudaMemcpy(i0_d, x0, dim0.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
checkCuda( cudaMemcpy(i1_d, x1, dim1.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
checkCuda( cudaMemcpy(i2_d, x2, dim2.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
|
||||
// Inference
|
||||
tk::dnn::dataDim_t dim;
|
||||
net->infer(dim, nullptr);
|
||||
|
||||
checkCuda( cudaMemcpy(deltaP.data(), o0_d, odim0.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
|
||||
checkCuda( cudaMemcpy(deltaQ.data(), o1_d, odim1.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
|
||||
|
||||
// compute odom
|
||||
Eigen::Quaterniond q;
|
||||
q.w() = deltaQ(0);
|
||||
q.x() = deltaQ(1);
|
||||
q.y() = deltaQ(2);
|
||||
q.z() = deltaQ(3);
|
||||
odomPOS = odomPOS + odomROT*deltaP.cast<double>(); // V1
|
||||
//odomPOS = odomPOS + deltaP.cast<double>(); // V2
|
||||
odomROT = odomROT * q.normalized().toRotationMatrix();
|
||||
|
||||
// compute Euler
|
||||
auto newEULER = odomROT.eulerAngles(0, 1, 2);
|
||||
for(int i=0; i<3; i++) {
|
||||
while( fabs(newEULER(i) - odomEULER(i)) > M_PI_2 ) {
|
||||
newEULER(i) += newEULER(i) - odomEULER(i) > 0 ? -M_PI : +M_PI;
|
||||
//std::cout<<newEULER(i)<<" "<<odomEULER(i)<<"\n";
|
||||
}
|
||||
}
|
||||
odomEULER = newEULER;
|
||||
|
||||
// compose tf
|
||||
tf.matrix().block(0, 0, 3, 3) = odomROT.cast<float>();
|
||||
tf.matrix().block(0, 3, 3, 1) = odomPOS.cast<float>();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifndef INT8BATCHSTREAM_H
|
||||
#define INT8BATCHSTREAM_H
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "NvInfer.h"
|
||||
#include "utils.h"
|
||||
#include "tkdnn.h"
|
||||
|
||||
/*
|
||||
* BatchStream implements the stream for the INT8 calibrator.
|
||||
* It reads the two files .txt with the list of image file names
|
||||
* and the list of label file names.
|
||||
* It then iterates on images and labels.
|
||||
*/
|
||||
class BatchStream {
|
||||
public:
|
||||
BatchStream(tk::dnn::dataDim_t dim, int batchSize, int maxBatches, const std::string& fileimglist, const std::string& filelabellist);
|
||||
virtual ~BatchStream() { }
|
||||
void reset(int firstBatch);
|
||||
bool next();
|
||||
void skip(int skipCount);
|
||||
float *getBatch() { return mBatch.data(); }
|
||||
float *getLabels() { return mLabels.data(); }
|
||||
int getBatchesRead() const { return mBatchCount; }
|
||||
int getBatchSize() const { return mBatchSize; }
|
||||
nvinfer1::DimsNCHW getDims() const { return mDims; }
|
||||
float* getFileBatch() { return &mFileBatch[0]; }
|
||||
float* getFileLabels() { return &mFileLabels[0]; }
|
||||
void readInListFile(const std::string& dataFilePath, std::vector<std::string>& mListIn);
|
||||
void readCVimage(std::string inputFileName, std::vector<float>& res, bool fixshape = true);
|
||||
void readLabels(std::string inputFileName ,std::vector<float>& ris);
|
||||
bool update();
|
||||
|
||||
private:
|
||||
int mBatchSize{ 0 };
|
||||
int mMaxBatches{ 0 };
|
||||
int mBatchCount{ 0 };
|
||||
int mFileCount{ 0 };
|
||||
int mFileBatchPos{ 0 };
|
||||
int mImageSize{ 0 };
|
||||
|
||||
nvinfer1::DimsNCHW mDims;
|
||||
std::vector<float> mBatch;
|
||||
std::vector<float> mLabels;
|
||||
std::vector<float> mFileBatch;
|
||||
std::vector<float> mFileLabels;
|
||||
|
||||
int mHeight;
|
||||
int mWidth;
|
||||
std::string mFileImgList;
|
||||
std::vector<std::string> mListImg;
|
||||
std::string mFileLabelList;
|
||||
std::vector<std::string> mListLabel;
|
||||
};
|
||||
|
||||
#endif //INT8BATCHSTREAM
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef INT8CALIBRATOR_H
|
||||
#define INT8CALIBRATOR_H
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "NvInfer.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Int8BatchStream.h"
|
||||
|
||||
#include "tkdnn.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
* Int8EntropyCalibrator implements the INT8 calibrator to achieve the
|
||||
* INT8 quantization. It uses a BatchStream stream to scroll through
|
||||
* images data. It also implements the calibration cache, a way to
|
||||
* save the calibration process results to reduce the running time:
|
||||
* the calibration process takes a long time.
|
||||
*/
|
||||
class Int8EntropyCalibrator : public nvinfer1::IInt8EntropyCalibrator {
|
||||
public:
|
||||
Int8EntropyCalibrator(BatchStream& stream, int firstBatch, const std::string& calibTableFilePath,
|
||||
const std::string& inputBlobName, bool readCache = true);
|
||||
virtual ~Int8EntropyCalibrator() { checkCuda(cudaFree(mDeviceInput)); }
|
||||
int getBatchSize() const override { return mStream.getBatchSize(); }
|
||||
bool getBatch(void* bindings[], const char* names[], int nbBindings) override;
|
||||
const void* readCalibrationCache(size_t& length) override;
|
||||
void writeCalibrationCache(const void* cache, size_t length) override;
|
||||
|
||||
private:
|
||||
BatchStream mStream;
|
||||
const std::string mCalibTableFilePath{ nullptr };
|
||||
const std::string mInputBlobName;
|
||||
bool mReadCache{ true };
|
||||
|
||||
size_t mInputCount;
|
||||
void* mDeviceInput{ nullptr };
|
||||
std::vector<char> mCalibrationCache;
|
||||
};
|
||||
|
||||
#endif //INT8CALIBRATOR_H
|
||||
+260
-60
@@ -9,12 +9,19 @@
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
enum layerType_t {
|
||||
LAYER_INPUT,
|
||||
LAYER_DENSE,
|
||||
LAYER_CONV2D,
|
||||
LAYER_DECONV2D,
|
||||
LAYER_DEFORMCONV2D,
|
||||
LAYER_LSTM,
|
||||
LAYER_ACTIVATION,
|
||||
LAYER_ACTIVATION_CRELU,
|
||||
LAYER_ACTIVATION_LEAKY,
|
||||
LAYER_ACTIVATION_MISH,
|
||||
LAYER_ACTIVATION_LOGISTIC,
|
||||
LAYER_FLATTEN,
|
||||
LAYER_RESHAPE,
|
||||
LAYER_MULADD,
|
||||
LAYER_POOLING,
|
||||
LAYER_SOFTMAX,
|
||||
@@ -34,7 +41,7 @@ enum layerType_t {
|
||||
class Layer {
|
||||
|
||||
public:
|
||||
Layer(Network *net, bool final = false);
|
||||
Layer(Network *net);
|
||||
virtual ~Layer();
|
||||
virtual layerType_t getLayerType() = 0;
|
||||
|
||||
@@ -42,9 +49,9 @@ public:
|
||||
std::cout<<"No infer action for this layer\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setFinal() { this->final = true; }
|
||||
dataDim_t input_dim, output_dim;
|
||||
dnnType *dstData; //where results will be putted
|
||||
dnnType *dstData = nullptr; //where results will be putted
|
||||
|
||||
int id = 0;
|
||||
bool final; //if the layer is the final one
|
||||
@@ -52,22 +59,29 @@ public:
|
||||
std::string getLayerName() {
|
||||
layerType_t type = getLayerType();
|
||||
switch(type) {
|
||||
case LAYER_DENSE: return "Dense";
|
||||
case LAYER_CONV2D: return "Conv2d";
|
||||
case LAYER_DECONV2D: return "DeConv2d";
|
||||
case LAYER_DEFORMCONV2D:return "DeformConv2d";
|
||||
case LAYER_ACTIVATION: return "Activation";
|
||||
case LAYER_FLATTEN: return "Flatten";
|
||||
case LAYER_MULADD: return "MulAdd";
|
||||
case LAYER_POOLING: return "Pooling";
|
||||
case LAYER_SOFTMAX: return "Softmax";
|
||||
case LAYER_ROUTE: return "Route";
|
||||
case LAYER_REORG: return "Reorg";
|
||||
case LAYER_SHORTCUT: return "Shortcut";
|
||||
case LAYER_UPSAMPLE: return "Upsample";
|
||||
case LAYER_REGION: return "Region";
|
||||
case LAYER_YOLO: return "Yolo";
|
||||
default: return "unknown";
|
||||
case LAYER_INPUT: return "Input";
|
||||
case LAYER_DENSE: return "Dense";
|
||||
case LAYER_CONV2D: return "Conv2d";
|
||||
case LAYER_DECONV2D: return "DeConv2d";
|
||||
case LAYER_DEFORMCONV2D: return "DeformConv2d";
|
||||
case LAYER_LSTM: return "LSTM";
|
||||
case LAYER_ACTIVATION: return "Activation";
|
||||
case LAYER_ACTIVATION_CRELU: return "ActivationCReLU";
|
||||
case LAYER_ACTIVATION_LEAKY: return "ActivationLeaky";
|
||||
case LAYER_ACTIVATION_MISH: return "ActivationMish";
|
||||
case LAYER_ACTIVATION_LOGISTIC: return "ActivationLogistic";
|
||||
case LAYER_FLATTEN: return "Flatten";
|
||||
case LAYER_RESHAPE: return "Reshape";
|
||||
case LAYER_MULADD: return "MulAdd";
|
||||
case LAYER_POOLING: return "Pooling";
|
||||
case LAYER_SOFTMAX: return "Softmax";
|
||||
case LAYER_ROUTE: return "Route";
|
||||
case LAYER_REORG: return "Reorg";
|
||||
case LAYER_SHORTCUT: return "Shortcut";
|
||||
case LAYER_UPSAMPLE: return "Upsample";
|
||||
case LAYER_REGION: return "Region";
|
||||
case LAYER_YOLO: return "Yolo";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +99,7 @@ class LayerWgs : public Layer {
|
||||
|
||||
public:
|
||||
LayerWgs(Network *net, int inputs, int outputs, int kh, int kw, int kt,
|
||||
std::string fname_weights, bool batchnorm = false, bool additional_bias = false, bool final = false);
|
||||
std::string fname_weights, bool batchnorm = false, bool additional_bias = false, bool deConv = false, int groups = 1);
|
||||
virtual ~LayerWgs();
|
||||
|
||||
int inputs, outputs;
|
||||
@@ -96,23 +110,87 @@ public:
|
||||
|
||||
// additional bias for DCN
|
||||
bool additional_bias;
|
||||
dnnType *bias2_h, *bias2_d;
|
||||
dnnType *bias2_h = nullptr, *bias2_d = nullptr;
|
||||
|
||||
//batchnorm
|
||||
bool batchnorm;
|
||||
dnnType *power_h;
|
||||
dnnType *scales_h, *scales_d;
|
||||
dnnType *mean_h, *mean_d;
|
||||
dnnType *variance_h, *variance_d;
|
||||
dnnType *power_h = nullptr;
|
||||
dnnType *scales_h = nullptr, *scales_d = nullptr;
|
||||
dnnType *mean_h = nullptr, *mean_d = nullptr;
|
||||
dnnType *variance_h = nullptr, *variance_d = nullptr;
|
||||
|
||||
//fp16
|
||||
__half *data16_h, *bias16_h;
|
||||
__half *data16_d, *bias16_d;
|
||||
__half *data16_h = nullptr, *bias16_h = nullptr;
|
||||
__half *data16_d = nullptr, *bias16_d = nullptr;
|
||||
__half *bias216_h = nullptr, *bias216_d = nullptr;
|
||||
|
||||
__half *power16_h, *power16_d;
|
||||
__half *scales16_h, *scales16_d;
|
||||
__half *mean16_h, *mean16_d;
|
||||
__half *variance16_h, *variance16_d;
|
||||
__half *power16_h = nullptr, *power16_d = nullptr;
|
||||
__half *scales16_h = nullptr, *scales16_d = nullptr;
|
||||
__half *mean16_h = nullptr, *mean16_d = nullptr;
|
||||
__half *variance16_h = nullptr, *variance16_d = nullptr;
|
||||
|
||||
void releaseHost(bool release32 = true, bool release16 = true) {
|
||||
if(release32) {
|
||||
if( data_h != nullptr) { delete [] data_h; data_h = nullptr; }
|
||||
if( bias_h != nullptr) { delete [] bias_h; bias_h = nullptr; }
|
||||
if( bias2_h != nullptr) { delete [] bias2_h; bias2_h = nullptr; }
|
||||
if( scales_h != nullptr) { delete [] scales_h; scales_h = nullptr; }
|
||||
if( mean_h != nullptr) { delete [] mean_h; mean_h = nullptr; }
|
||||
if(variance_h != nullptr) { delete [] variance_h; variance_h = nullptr; }
|
||||
if( power_h != nullptr) { delete [] power_h; power_h = nullptr; }
|
||||
}
|
||||
if(net->fp16 && release16) {
|
||||
if( data16_h != nullptr) { delete [] data16_h; data16_h = nullptr; }
|
||||
if( bias16_h != nullptr) { delete [] bias16_h; bias16_h = nullptr; }
|
||||
if( bias216_h != nullptr) { delete [] bias216_h; bias216_h = nullptr; }
|
||||
if( scales16_h != nullptr) { delete [] scales16_h; scales16_h = nullptr; }
|
||||
if( mean16_h != nullptr) { delete [] mean16_h; mean16_h = nullptr; }
|
||||
if(variance16_h != nullptr) { delete [] variance16_h; variance16_h = nullptr; }
|
||||
if( power16_h != nullptr) { delete [] power16_h; power16_h = nullptr; }
|
||||
|
||||
}
|
||||
}
|
||||
void releaseDevice(bool release32 = true, bool release16 = true) {
|
||||
if(release32) {
|
||||
if( data_d != nullptr) { cudaFree( data_d); data_d = nullptr; }
|
||||
if( bias_d != nullptr) { cudaFree( bias_d); bias_d = nullptr; }
|
||||
if( bias2_d != nullptr) { cudaFree( bias2_d); bias2_d = nullptr; }
|
||||
if( scales_d != nullptr) { cudaFree( scales_d); scales_d = nullptr; }
|
||||
if( mean_d != nullptr) { cudaFree( mean_d); mean_d = nullptr; }
|
||||
if(variance_d != nullptr) { cudaFree(variance_d); variance_d = nullptr; }
|
||||
}
|
||||
if(net->fp16 && release16) {
|
||||
if( data16_d != nullptr) { cudaFree( data16_d); data16_d = nullptr; }
|
||||
if( bias16_d != nullptr) { cudaFree( bias16_d); bias16_d = nullptr; }
|
||||
if( bias216_d != nullptr) { cudaFree( bias216_d); bias216_d = nullptr; }
|
||||
if( scales16_d != nullptr) { cudaFree( scales16_d); scales16_d = nullptr; }
|
||||
if( mean16_d != nullptr) { cudaFree( mean16_d); mean16_d = nullptr; }
|
||||
if(variance16_d != nullptr) { cudaFree(variance16_d); variance16_d = nullptr; }
|
||||
if( power16_d != nullptr) { cudaFree( power16_d); power16_d = nullptr; }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Input layer (it doesn't need weights)
|
||||
*/
|
||||
class Input : public Layer {
|
||||
|
||||
public:
|
||||
|
||||
Input(Network *net, dataDim_t &dim, dnnType* srcData) : Layer(net) {
|
||||
input_dim = dim;
|
||||
output_dim = dim;
|
||||
dstData = srcData;
|
||||
}
|
||||
virtual ~Input() {}
|
||||
virtual layerType_t getLayerType() { return LAYER_INPUT; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData) {
|
||||
dim = output_dim;
|
||||
return dstData;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -131,24 +209,38 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
Avaible activation functions
|
||||
Available activation functions
|
||||
*/
|
||||
typedef enum {
|
||||
ACTIVATION_ELU = 100,
|
||||
ACTIVATION_LEAKY = 101
|
||||
ACTIVATION_LEAKY = 101,
|
||||
ACTIVATION_MISH = 102,
|
||||
ACTIVATION_LOGISTIC = 103
|
||||
} tkdnnActivationMode_t;
|
||||
|
||||
/**
|
||||
Activation layer (it doesnt need weigths)
|
||||
Activation layer (it doesn't need weights)
|
||||
*/
|
||||
class Activation : public Layer {
|
||||
|
||||
public:
|
||||
int act_mode;
|
||||
float ceiling;
|
||||
|
||||
Activation(Network *net, int act_mode);
|
||||
Activation(Network *net, int act_mode, const float ceiling=0.0);
|
||||
virtual ~Activation();
|
||||
virtual layerType_t getLayerType() { return LAYER_ACTIVATION; };
|
||||
virtual layerType_t getLayerType() {
|
||||
if(act_mode == CUDNN_ACTIVATION_CLIPPED_RELU)
|
||||
return LAYER_ACTIVATION_CRELU;
|
||||
else if (act_mode == ACTIVATION_LEAKY)
|
||||
return LAYER_ACTIVATION_LEAKY;
|
||||
else if (act_mode == ACTIVATION_MISH)
|
||||
return LAYER_ACTIVATION_MISH;
|
||||
else if (act_mode == ACTIVATION_LOGISTIC)
|
||||
return LAYER_ACTIVATION_LOGISTIC;
|
||||
else
|
||||
return LAYER_ACTIVATION;
|
||||
};
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
|
||||
@@ -159,26 +251,35 @@ protected:
|
||||
|
||||
/**
|
||||
Convolutional 2D layer
|
||||
|
||||
WEIGHTS shape: OUTCH, INCH, KH, KW ...
|
||||
BIAS shape: OUTCH
|
||||
|
||||
with BATCHNORM:
|
||||
scales: OUTCH
|
||||
means: OUTCH
|
||||
variance: OUTCH
|
||||
*/
|
||||
class Conv2d : public LayerWgs {
|
||||
|
||||
public:
|
||||
Conv2d( Network *net, int out_ch, int kernelH, int kernelW,
|
||||
int strideH, int strideW, int paddingH, int paddingW,
|
||||
std::string fname_weights, bool batchnorm = false, bool deConv = false, bool final = false);
|
||||
std::string fname_weights, bool batchnorm = false, bool deConv = false, int groups = 1, bool additional_bias=false);
|
||||
virtual ~Conv2d();
|
||||
virtual layerType_t getLayerType() { return LAYER_CONV2D; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
|
||||
int kernelH, kernelW, strideH, strideW, paddingH, paddingW;
|
||||
bool deConv;
|
||||
bool deConv, additional_bias;
|
||||
int groups;
|
||||
|
||||
protected:
|
||||
cudnnFilterDescriptor_t filterDesc;
|
||||
cudnnConvolutionDescriptor_t convDesc;
|
||||
cudnnConvolutionFwdAlgo_t algo;
|
||||
cudnnConvolutionBwdDataAlgo_t bwAlgo;
|
||||
cudnnConvolutionFwdAlgoPerf_t algo;
|
||||
cudnnConvolutionBwdDataAlgoPerf_t bwAlgo;
|
||||
cudnnTensorDescriptor_t biasTensorDesc;
|
||||
|
||||
void initCUDNN(bool back = false);
|
||||
@@ -187,6 +288,71 @@ protected:
|
||||
size_t ws_sizeInBytes;
|
||||
};
|
||||
|
||||
/**
|
||||
Bidirectional LSTM layer
|
||||
ONLY BIDIRECTIONAL (TODO: more configurable)
|
||||
currently implemented as 2 inferences: forward and backward (TODO: only 1 cudnn inference)
|
||||
|
||||
implementation info:
|
||||
https://github.com/jiangnanhugo/seq2seq_cuda/blob/e4dbdcfa0517c972bfd4beea9f11a5233954093c/src/rnn.cpp
|
||||
https://github.com/Jeffery-Song/mxnet-test/blob/aab666faad44011f7a67b527b5f6c960367d0422/src/operator/cudnn_rnn-inl.h
|
||||
https://stackoverflow.com/a/38737941
|
||||
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
|
||||
|
||||
PARAMS (numlayers*2):
|
||||
layer0:
|
||||
( INCH, ? ) ???
|
||||
( HIDDEN, ? ) ???
|
||||
( HIDDEN * 8 ) ???
|
||||
layer2:
|
||||
( INCH, ? ) ???
|
||||
( HIDDEN, ? ) ???
|
||||
( HIDDEN * 8 ) ???
|
||||
|
||||
OUTPUT shape:
|
||||
(N, C, 1, W) ---> LSTM(HIDDEN, returnSeq=True) ---> (N, 2*HIDDEN, 1, W) # W is seqLength
|
||||
(N, C, 1, W) ---> LSTM(HIDDEN, returnSeq=False) ---> (N, 2*HIDDEN, 1, 1)
|
||||
*/
|
||||
class LSTM : public Layer {
|
||||
|
||||
public:
|
||||
LSTM(Network *net, int hiddensize, bool returnSeq, std::string fname_weights);
|
||||
virtual ~LSTM();
|
||||
virtual layerType_t getLayerType() { return LAYER_LSTM; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
|
||||
const bool bidirectional = true; /**> is the net bidir */
|
||||
bool returnSeq = false; /**> if false return only the result of last timestamp */
|
||||
int stateSize = 0; /**> number of hidden states */
|
||||
int seqLen = 0; /**> number of timestamp */
|
||||
int numLayers = 1; /**> number of internal layers */
|
||||
|
||||
protected:
|
||||
cudnnRNNDescriptor_t rnnDesc;
|
||||
cudnnDropoutDescriptor_t dropoutDesc;
|
||||
dnnType *dropout_states_, *work_space_;
|
||||
|
||||
size_t workspace_byte_, dropout_byte_;
|
||||
int workspace_size_, dropout_size_;
|
||||
|
||||
std::vector<cudnnTensorDescriptor_t> x_desc_vec_, y_desc_vec_;
|
||||
cudnnTensorDescriptor_t hx_desc_, cx_desc_;
|
||||
cudnnTensorDescriptor_t hy_desc_, cy_desc_;
|
||||
dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr;
|
||||
int stateDataDim;
|
||||
|
||||
cudnnFilterDescriptor_t w_desc_;
|
||||
dnnType *w_ptr;
|
||||
dnnType *w_h;
|
||||
dnnType *wf_ptr, *wb_ptr; // params pointer forward and backward layer
|
||||
|
||||
// used during inference
|
||||
dataDim_t one_output_dim; // output dim of as single inference
|
||||
dnnType *srcF, *srcB; // input of single inference
|
||||
dnnType *dstF, *dstB_NR, *dstB; // output of single inference, dstB_NR = dstB not reversed
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Convolutional 2D layer
|
||||
@@ -196,8 +362,8 @@ class DeConv2d : public Conv2d {
|
||||
public:
|
||||
DeConv2d( Network *net, int out_ch, int kernelH, int kernelW,
|
||||
int strideH, int strideW, int paddingH, int paddingW,
|
||||
std::string fname_weights, bool batchnorm = false) :
|
||||
Conv2d(net, out_ch, kernelH, kernelW, strideH, strideW, paddingH, paddingW, fname_weights, batchnorm, true) {}
|
||||
std::string fname_weights, bool batchnorm = false, int groups = 1) :
|
||||
Conv2d(net, out_ch, kernelH, kernelW, strideH, strideW, paddingH, paddingW, fname_weights, batchnorm, true, groups) {}
|
||||
virtual ~DeConv2d() {}
|
||||
virtual layerType_t getLayerType() { return LAYER_DECONV2D; };
|
||||
|
||||
@@ -206,7 +372,7 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
Deformable Convolutionl 2d layer
|
||||
Deformable Convolutional 2d layer
|
||||
*/
|
||||
class DeformConv2d : public LayerWgs {
|
||||
|
||||
@@ -228,6 +394,9 @@ public:
|
||||
dnnType *offset, *mask;
|
||||
dnnType *output_conv;
|
||||
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
|
||||
protected:
|
||||
|
||||
cudnnTensorDescriptor_t biasTensorDesc;
|
||||
@@ -249,6 +418,20 @@ public:
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
};
|
||||
|
||||
/**
|
||||
Reshape layer
|
||||
*/
|
||||
class Reshape : public Layer {
|
||||
|
||||
public:
|
||||
Reshape(Network *net, dataDim_t new_dim);
|
||||
virtual ~Reshape();
|
||||
virtual layerType_t getLayerType() { return LAYER_RESHAPE; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
MulAdd layer
|
||||
@@ -271,17 +454,18 @@ protected:
|
||||
|
||||
|
||||
/**
|
||||
Avaible pooling functions (padding on tkDNN is not supported)
|
||||
Available pooling functions (padding on tkDNN is not supported)
|
||||
*/
|
||||
typedef enum {
|
||||
POOLING_MAX = 0,
|
||||
POOLING_AVERAGE = 1, // count for average includes padded values
|
||||
POOLING_AVERAGE_EXCLUDE_PADDING = 2 // count for average does not include padded values
|
||||
POOLING_AVERAGE = 1, // count for average includes padded values
|
||||
POOLING_AVERAGE_EXCLUDE_PADDING = 2, // count for average does not include padded values
|
||||
POOLING_MAX_FIXEDSIZE = 100 // max pool darknet fashion
|
||||
} tkdnnPoolingMode_t;
|
||||
|
||||
/**
|
||||
Pooling layer
|
||||
currenty supported only 2d pooing (also on 3d input)
|
||||
currently supported only 2d pooing (also on 3d input)
|
||||
*/
|
||||
class Pooling : public Layer {
|
||||
|
||||
@@ -289,12 +473,13 @@ public:
|
||||
int winH, winW;
|
||||
int strideH, strideW;
|
||||
int paddingH, paddingW;
|
||||
bool size;
|
||||
tkdnnPoolingMode_t pool_mode;
|
||||
|
||||
Pooling(Network *net, int winH, int winW,
|
||||
int strideH, int strideW,
|
||||
int paddingH = 0, int paddingW = 0,
|
||||
tkdnnPoolingMode_t pool_mode = POOLING_MAX, bool final = false);
|
||||
int paddingH, int paddingW,
|
||||
tkdnnPoolingMode_t pool_mode);
|
||||
virtual ~Pooling();
|
||||
virtual layerType_t getLayerType() { return LAYER_POOLING; };
|
||||
|
||||
@@ -313,11 +498,13 @@ protected:
|
||||
class Softmax : public Layer {
|
||||
|
||||
public:
|
||||
Softmax(Network *net);
|
||||
Softmax(Network *net, const tk::dnn::dataDim_t* dim=nullptr, const cudnnSoftmaxMode_t mode=CUDNN_SOFTMAX_MODE_CHANNEL);
|
||||
virtual ~Softmax();
|
||||
virtual layerType_t getLayerType() { return LAYER_SOFTMAX; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
dataDim_t dim;
|
||||
cudnnSoftmaxMode_t mode;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -327,22 +514,24 @@ public:
|
||||
class Route : public Layer {
|
||||
|
||||
public:
|
||||
Route(Network *net, Layer **layers, int layers_n);
|
||||
Route(Network *net, Layer **layers, int layers_n, int groups = 1, int group_id = 0);
|
||||
virtual ~Route();
|
||||
virtual layerType_t getLayerType() { return LAYER_ROUTE; };
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
|
||||
public:
|
||||
static const int MAX_INPUT_LAYERS = 16;
|
||||
Layer *layers[MAX_INPUT_LAYERS]; //ids of layers to be merged
|
||||
static const int MAX_LAYERS = 32;
|
||||
Layer *layers[MAX_LAYERS]; //ids of layers to be merged
|
||||
int layers_n; //number of layers
|
||||
int groups;
|
||||
int group_id;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Reorg layer
|
||||
Mantain same dimension but change C*H*W distribution
|
||||
Maintains same dimension but change C*H*W distribution
|
||||
*/
|
||||
class Reorg : public Layer {
|
||||
|
||||
@@ -375,7 +564,7 @@ public:
|
||||
|
||||
/**
|
||||
Upsample layer
|
||||
Mantain same dimension but change C*H*W distribution
|
||||
Maintains same dimension but change C*H*W distribution
|
||||
*/
|
||||
class Upsample : public Layer {
|
||||
|
||||
@@ -394,6 +583,12 @@ struct box {
|
||||
int cl;
|
||||
float x, y, w, h;
|
||||
float prob;
|
||||
std::vector<float> probs;
|
||||
|
||||
void print()
|
||||
{
|
||||
std::cout<<"x: "<<x<<"\ty: "<<y<<"\tw: "<<w<<"\th: "<<h<<"\tcl: "<<cl<<"\tprob: "<<prob<<std::endl;
|
||||
}
|
||||
};
|
||||
struct sortable_bbox {
|
||||
int index;
|
||||
@@ -420,23 +615,28 @@ public:
|
||||
int sort_class;
|
||||
};
|
||||
|
||||
Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks=3);
|
||||
enum nmsKind_t {GREEDY_NMS=0, DIOU_NMS=1};
|
||||
|
||||
Yolo(Network *net, int classes, int num, std::string fname_weights,int n_masks=3, float scale_xy=1, double nms_thresh=0.45, nmsKind_t nsm_kind=GREEDY_NMS, int new_coords=0);
|
||||
virtual ~Yolo();
|
||||
virtual layerType_t getLayerType() { return LAYER_YOLO; };
|
||||
|
||||
int classes, num, n_masks;
|
||||
int classes, num, n_masks, new_coords;
|
||||
dnnType *mask_h, *mask_d; //anchors
|
||||
dnnType *bias_h, *bias_d; //anchors
|
||||
float scaleXY;
|
||||
double nms_thresh;
|
||||
nmsKind_t nsm_kind;
|
||||
std::vector<std::string> classesNames;
|
||||
|
||||
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
|
||||
int computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh);
|
||||
int computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh, int new_coords=0);
|
||||
|
||||
dnnType *predictions;
|
||||
|
||||
static const int MAX_DETECTIONS = 256;
|
||||
static const int MAX_DETECTIONS = 8192*2;
|
||||
static Yolo::detection *allocateDetections(int nboxes, int classes);
|
||||
static void mergeDetections(Yolo::detection *dets, int ndets, int classes);
|
||||
static void mergeDetections(Yolo::detection *dets, int ndets, int classes, double nms_thresh=0.45, nmsKind_t nsm_kind=GREEDY_NMS);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef MOBILENETDETECTION_H
|
||||
#define MOBILENETDETECTION_H
|
||||
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include "opencv2/opencv.hpp"
|
||||
|
||||
#include "DetectionNN.h"
|
||||
|
||||
#define N_COORDS 4
|
||||
#define N_SSDSPEC 6
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
struct SSDSpec
|
||||
{
|
||||
int featureSize = 0;
|
||||
int shrinkage = 0;
|
||||
int boxWidth = 0;
|
||||
int boxHeight = 0;
|
||||
int ratio1 = 0;
|
||||
int ratio2 = 0;
|
||||
|
||||
SSDSpec() {}
|
||||
SSDSpec(int feature_size, int shrinkage, int box_width, int box_height, int ratio1, int ratio2) :
|
||||
featureSize(feature_size), shrinkage(shrinkage), boxWidth(box_width),
|
||||
boxHeight(box_height), ratio1(ratio1), ratio2(ratio2) {}
|
||||
void setAll(int feature_size, int shrinkage, int box_width, int box_height, int ratio1, int ratio2)
|
||||
{
|
||||
this->featureSize = feature_size;
|
||||
this->shrinkage = shrinkage;
|
||||
this->boxWidth = box_width;
|
||||
this->boxHeight = box_height;
|
||||
this->ratio1 = ratio1;
|
||||
this->ratio2 = ratio2;
|
||||
}
|
||||
void print()
|
||||
{
|
||||
std::cout << "fsize: " << featureSize << "\tshrinkage: " << shrinkage <<
|
||||
"\t box W:" << boxWidth << "\tbox H: " << boxHeight <<
|
||||
"\t x ratio:" << ratio1 << "\t y ratio:" << ratio2 << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class MobilenetDetection : public DetectionNN
|
||||
{
|
||||
private:
|
||||
float IoUThreshold = 0.45;
|
||||
float centerVariance = 0.1;
|
||||
float sizeVariance = 0.2;
|
||||
int imageSize;
|
||||
|
||||
float *priors = nullptr;
|
||||
int nPriors = 0;
|
||||
float *locations_h, *confidences_h;
|
||||
|
||||
|
||||
|
||||
void generate_ssd_priors(const SSDSpec *specs, const int n_specs, bool clamp = true);
|
||||
void convert_locatios_to_boxes_and_center();
|
||||
float iou(const tk::dnn::box &a, const tk::dnn::box &b);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
MobilenetDetection() {};
|
||||
~MobilenetDetection() {};
|
||||
|
||||
bool init(const std::string& tensor_path, const int n_classes, const int n_batches=1, const float conf_thresh=0.3);
|
||||
void preprocess(cv::Mat &frame, const int bi=0);
|
||||
void postprocess(const int bi=0,const bool mAP=false);
|
||||
};
|
||||
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace tk
|
||||
|
||||
#endif /*MOBILENETDETECTION_H*/
|
||||
+14
-5
@@ -1,17 +1,18 @@
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include <string>
|
||||
#include "utils.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
/**
|
||||
Data rapresentation beetween layers
|
||||
Data representation between layers
|
||||
n = batch size
|
||||
c = channels
|
||||
h = heigth (lines)
|
||||
h = height (lines)
|
||||
w = width (rows)
|
||||
l = lenght (3rd dimension)
|
||||
l = length (3rd dimension)
|
||||
*/
|
||||
struct dataDim_t {
|
||||
|
||||
@@ -39,14 +40,16 @@ class Network {
|
||||
public:
|
||||
Network(dataDim_t input_dim);
|
||||
virtual ~Network();
|
||||
void releaseLayers();
|
||||
|
||||
/**
|
||||
Do inferece for every added layer
|
||||
Do inference for every added layer
|
||||
*/
|
||||
dnnType* infer(dataDim_t &dim, dnnType* data);
|
||||
|
||||
bool addLayer(Layer *l);
|
||||
void print();
|
||||
const char *getNetworkRTName(const char *network_name);
|
||||
|
||||
cudnnDataType_t dataType;
|
||||
cudnnTensorFormat_t tensorFormat;
|
||||
@@ -59,8 +62,14 @@ public:
|
||||
dataDim_t input_dim;
|
||||
dataDim_t getOutputDim();
|
||||
|
||||
bool fp16, dla;
|
||||
bool fp16, dla, int8;
|
||||
int maxBatchSize;
|
||||
bool dontLoadWeights;
|
||||
std::string fileImgList;
|
||||
std::string fileLabelList;
|
||||
std::string networkName;
|
||||
std::string networkNameRT;
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Network.h"
|
||||
#include "Layer.h"
|
||||
#include "NvInfer.h"
|
||||
#include <memory>
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
@@ -24,15 +25,20 @@ template<typename T> T readBUF(const char*& buffer)
|
||||
|
||||
using namespace nvinfer1;
|
||||
#include "pluginsRT/ActivationLeakyRT.h"
|
||||
#include "pluginsRT/ActivationLogisticRT.h"
|
||||
#include "pluginsRT/ActivationReLUCeilingRT.h"
|
||||
#include "pluginsRT/ActivationMishRT.h"
|
||||
#include "pluginsRT/ReorgRT.h"
|
||||
#include "pluginsRT/RegionRT.h"
|
||||
//#include "pluginsRT/RouteRT.h"
|
||||
#include "pluginsRT/RouteRT.h"
|
||||
#include "pluginsRT/ShortcutRT.h"
|
||||
#include "pluginsRT/YoloRT.h"
|
||||
#include "pluginsRT/UpsampleRT.h"
|
||||
#include "pluginsRT/ResizeLayerRT.h"
|
||||
//#include "pluginsRT/Int8Calibrator.h"
|
||||
#include "pluginsRT/DeformableConvRT.h"
|
||||
#include "pluginsRT/FlattenConcatRT.h"
|
||||
#include "pluginsRT/ReshapeRT.h"
|
||||
#include "pluginsRT/MaxPoolingFixedSizeRT.h"
|
||||
|
||||
class PluginFactory : IPluginFactory
|
||||
{
|
||||
@@ -52,12 +58,16 @@ public:
|
||||
nvinfer1::IBuilder *builderRT;
|
||||
nvinfer1::IRuntime *runtimeRT;
|
||||
nvinfer1::INetworkDefinition *networkRT;
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
nvinfer1::IBuilderConfig *configRT;
|
||||
#endif
|
||||
|
||||
nvinfer1::ICudaEngine *engineRT;
|
||||
nvinfer1::IExecutionContext *contextRT;
|
||||
|
||||
const static int MAX_BUFFERS_RT = 10;
|
||||
void* buffersRT[MAX_BUFFERS_RT];
|
||||
dataDim_t buffersDIM[MAX_BUFFERS_RT];
|
||||
int buf_input_idx, buf_output_idx;
|
||||
|
||||
dataDim_t input_dim, output_dim;
|
||||
@@ -69,11 +79,25 @@ public:
|
||||
NetworkRT(Network *net, const char *name);
|
||||
virtual ~NetworkRT();
|
||||
|
||||
int getMaxBatchSize() {
|
||||
if(engineRT != nullptr)
|
||||
return engineRT->getMaxBatchSize();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getBuffersN() {
|
||||
if(engineRT != nullptr)
|
||||
return engineRT->getNbBindings();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Do inferece
|
||||
Do inference
|
||||
*/
|
||||
dnnType* infer(dataDim_t &dim, dnnType* data);
|
||||
void enqueue();
|
||||
void enqueue(int batchSize = 1);
|
||||
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Layer *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Conv2d *l);
|
||||
@@ -82,6 +106,8 @@ public:
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Pooling *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Softmax *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Route *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Flatten *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reshape *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Reorg *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Region *l);
|
||||
nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Shortcut *l);
|
||||
@@ -91,6 +117,9 @@ public:
|
||||
|
||||
bool serialize(const char *filename);
|
||||
bool deserialize(const char *filename);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <opencv2/core/types.hpp>
|
||||
#include "tkdnn.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
cv::Mat vizFloat2colorMap(cv::Mat map);
|
||||
cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim);
|
||||
cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim = 1000);
|
||||
|
||||
}}
|
||||
@@ -1,65 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include "utils.h"
|
||||
#ifndef Yolo3Detection_H
|
||||
#define Yolo3Detection_H
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include "opencv2/opencv.hpp"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include "DetectionNN.h"
|
||||
|
||||
#include "tkdnn.h"
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
class Yolo3Detection : public DetectionNN
|
||||
{
|
||||
private:
|
||||
int num = 0;
|
||||
int nMasks = 0;
|
||||
int nDets = 0;
|
||||
tk::dnn::Yolo::detection *dets = nullptr;
|
||||
tk::dnn::Yolo* yolo[3];
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francesco Gatti
|
||||
*/
|
||||
class Yolo3Detection {
|
||||
tk::dnn::Yolo* getYoloLayer(int n=0);
|
||||
|
||||
private:
|
||||
tk::dnn::NetworkRT *netRT = nullptr;
|
||||
tk::dnn::Yolo* yolo[3];
|
||||
dnnType *input, *input_d;
|
||||
|
||||
int ndets = 0;
|
||||
tk::dnn::Yolo::detection *dets = nullptr;
|
||||
|
||||
cv::Mat imageF;
|
||||
cv::Mat bgr[3];
|
||||
|
||||
public:
|
||||
int classes = 0;
|
||||
int num = 0;
|
||||
int n_masks = 0;
|
||||
float thresh = 0.3;
|
||||
cv::Scalar colors[256];
|
||||
|
||||
// this is filled with results
|
||||
std::vector<tk::dnn::box> detected;
|
||||
|
||||
Yolo3Detection() {}
|
||||
|
||||
virtual ~Yolo3Detection() {}
|
||||
|
||||
/**
|
||||
* Method used for inizialize the class
|
||||
*
|
||||
* @return Success of the initialization
|
||||
*/
|
||||
bool init(std::string tensor_path);
|
||||
|
||||
void update(cv::Mat &frame);
|
||||
|
||||
tk::dnn::Yolo* getYoloLayer(int n=0) {
|
||||
if(n<3)
|
||||
return yolo[n];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
cv::Mat bgr_h;
|
||||
|
||||
public:
|
||||
Yolo3Detection() {};
|
||||
~Yolo3Detection() {};
|
||||
|
||||
bool init(const std::string& tensor_path, const int n_classes=80, const int n_batches=1, const float conf_thresh=0.3);
|
||||
void preprocess(cv::Mat &frame, const int bi=0);
|
||||
void postprocess(const int bi=0,const bool mAP=false);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace tk
|
||||
|
||||
#endif /* Yolo3Detection_H*/
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
#ifdef OS_WIN
|
||||
#pragma once
|
||||
|
||||
#ifdef LIB_EXPORTS
|
||||
#define LIB_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIB_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
#ifdef OPENCV
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/core/types_c.h>
|
||||
using namespace cv;
|
||||
#endif
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct baggagedetector {
|
||||
int x,y,w,h,size;
|
||||
char *label;
|
||||
float prob;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
class baggageAI
|
||||
{
|
||||
//std::shared_ptr<void> detector_gpu_ptr;
|
||||
public:
|
||||
//static LIB_API image_t image_load(std::string image_filename);
|
||||
#ifdef OS_WIN
|
||||
LIB_API baggageAI();
|
||||
//LIB_API ~baggageAI();
|
||||
LIB_API baggagedetector * baggageDetections(char *input);
|
||||
LIB_API baggagedetector * baggageDetections(unsigned char *input, int len, int antiLog, int gray);
|
||||
#ifdef OPENCV
|
||||
LIB_API baggagedetector * baggageDetections(Mat m);
|
||||
#endif
|
||||
#else
|
||||
baggageAI();
|
||||
//LIB_API ~baggageAI();
|
||||
baggagedetector * baggageDetections(char *input);
|
||||
baggagedetector * baggageDetections(unsigned char *input, int len,int antiLog, int gray);
|
||||
#ifdef OPENCV
|
||||
baggagedetector * baggageDetections(Mat m);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,852 @@
|
||||
#ifndef DIMENSIONLESS_API
|
||||
#define DIMENSIONLESS_API
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && !defined(_CRTDBG_MAP_ALLOC)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef LIB_API
|
||||
#ifdef LIB_EXPORTS
|
||||
#if defined(_MSC_VER)
|
||||
#define LIB_API __declspec(dllexport)
|
||||
#else
|
||||
#define LIB_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#if defined(_MSC_VER)
|
||||
#define LIB_API
|
||||
#else
|
||||
#define LIB_API
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SECRET_NUM -1234
|
||||
|
||||
#ifdef GPU
|
||||
|
||||
#include "cuda_runtime.h"
|
||||
#include "curand.h"
|
||||
#include "cublas_v2.h"
|
||||
|
||||
#ifdef CUDNN
|
||||
#include "cudnn.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct network;
|
||||
typedef struct network network;
|
||||
|
||||
struct network_state;
|
||||
typedef struct network_state network_state;
|
||||
|
||||
struct layer;
|
||||
typedef struct layer layer;
|
||||
|
||||
struct image;
|
||||
typedef struct image image;
|
||||
|
||||
struct detection;
|
||||
typedef struct detection detection;
|
||||
|
||||
struct load_args;
|
||||
typedef struct load_args load_args;
|
||||
|
||||
struct data;
|
||||
typedef struct data data;
|
||||
|
||||
struct metadata;
|
||||
typedef struct metadata metadata;
|
||||
|
||||
struct tree;
|
||||
typedef struct tree tree;
|
||||
|
||||
extern int gpu_index;
|
||||
|
||||
// option_list.h
|
||||
typedef struct metadata {
|
||||
int classes;
|
||||
char **names;
|
||||
} metadata;
|
||||
|
||||
|
||||
// tree.h
|
||||
typedef struct tree {
|
||||
int *leaf;
|
||||
int n;
|
||||
int *parent;
|
||||
int *child;
|
||||
int *group;
|
||||
char **name;
|
||||
|
||||
int groups;
|
||||
int *group_size;
|
||||
int *group_offset;
|
||||
} tree;
|
||||
|
||||
|
||||
// activations.h
|
||||
typedef enum {
|
||||
LOGISTIC, RELU, RELIE, LINEAR, RAMP, TANH, PLSE, LEAKY, ELU, LOGGY, STAIR, HARDTAN, LHTAN, SELU
|
||||
}ACTIVATION;
|
||||
|
||||
// image.h
|
||||
typedef enum{
|
||||
PNG, BMP, TGA, JPG
|
||||
} IMTYPE;
|
||||
|
||||
// activations.h
|
||||
typedef enum{
|
||||
MULT, ADD, SUB, DIV
|
||||
} BINARY_ACTIVATION;
|
||||
|
||||
// layer.h
|
||||
typedef enum {
|
||||
CONVOLUTIONAL,
|
||||
DECONVOLUTIONAL,
|
||||
CONNECTED,
|
||||
MAXPOOL,
|
||||
SOFTMAX,
|
||||
DETECTION,
|
||||
DROPOUT,
|
||||
CROP,
|
||||
ROUTE,
|
||||
COST,
|
||||
NORMALIZATION,
|
||||
AVGPOOL,
|
||||
LOCAL,
|
||||
SHORTCUT,
|
||||
ACTIVE,
|
||||
RNN,
|
||||
GRU,
|
||||
LSTM,
|
||||
CONV_LSTM,
|
||||
CRNN,
|
||||
BATCHNORM,
|
||||
NETWORK,
|
||||
XNOR,
|
||||
REGION,
|
||||
BAGGAGEAI,
|
||||
ISEG,
|
||||
REORG,
|
||||
REORG_OLD,
|
||||
UPSAMPLE,
|
||||
LOGXENT,
|
||||
L2NORM,
|
||||
BLANK
|
||||
} LAYER_TYPE;
|
||||
|
||||
// layer.h
|
||||
typedef enum{
|
||||
SSE, MASKED, L1, SEG, SMOOTH,WGAN
|
||||
} COST_TYPE;
|
||||
|
||||
// layer.h
|
||||
typedef struct update_args {
|
||||
int batch;
|
||||
float learning_rate;
|
||||
float momentum;
|
||||
float decay;
|
||||
int adam;
|
||||
float B1;
|
||||
float B2;
|
||||
float eps;
|
||||
int t;
|
||||
} update_args;
|
||||
|
||||
// layer.h
|
||||
struct layer {
|
||||
LAYER_TYPE type;
|
||||
ACTIVATION activation;
|
||||
COST_TYPE cost_type;
|
||||
void(*forward) (struct layer, struct network_state);
|
||||
void(*backward) (struct layer, struct network_state);
|
||||
void(*update) (struct layer, int, float, float, float);
|
||||
void(*forward_gpu) (struct layer, struct network_state);
|
||||
void(*backward_gpu) (struct layer, struct network_state);
|
||||
void(*update_gpu) (struct layer, int, float, float, float);
|
||||
int batch_normalize;
|
||||
int shortcut;
|
||||
int batch;
|
||||
int forced;
|
||||
int flipped;
|
||||
int inputs;
|
||||
int outputs;
|
||||
int nweights;
|
||||
int nbiases;
|
||||
int extra;
|
||||
int truths;
|
||||
int h, w, c;
|
||||
int out_h, out_w, out_c;
|
||||
int n;
|
||||
int max_boxes;
|
||||
int groups;
|
||||
int size;
|
||||
int side;
|
||||
int stride;
|
||||
int reverse;
|
||||
int flatten;
|
||||
int spatial;
|
||||
int pad;
|
||||
int sqrt;
|
||||
int flip;
|
||||
int index;
|
||||
int binary;
|
||||
int xnor;
|
||||
int peephole;
|
||||
int use_bin_output;
|
||||
int steps;
|
||||
int state_constrain;
|
||||
int hidden;
|
||||
int truth;
|
||||
float smooth;
|
||||
float dot;
|
||||
float angle;
|
||||
float jitter;
|
||||
float saturation;
|
||||
float exposure;
|
||||
float shift;
|
||||
float ratio;
|
||||
float learning_rate_scale;
|
||||
float clip;
|
||||
int focal_loss;
|
||||
int noloss;
|
||||
int softmax;
|
||||
int classes;
|
||||
int coords;
|
||||
int background;
|
||||
int rescore;
|
||||
int objectness;
|
||||
int does_cost;
|
||||
int joint;
|
||||
int noadjust;
|
||||
int reorg;
|
||||
int log;
|
||||
int tanh;
|
||||
int *mask;
|
||||
int total;
|
||||
float bflops;
|
||||
|
||||
int adam;
|
||||
float B1;
|
||||
float B2;
|
||||
float eps;
|
||||
|
||||
int t;
|
||||
|
||||
float alpha;
|
||||
float beta;
|
||||
float kappa;
|
||||
|
||||
float coord_scale;
|
||||
float object_scale;
|
||||
float noobject_scale;
|
||||
float mask_scale;
|
||||
float class_scale;
|
||||
int bias_match;
|
||||
int random;
|
||||
float ignore_thresh;
|
||||
float truth_thresh;
|
||||
float thresh;
|
||||
float focus;
|
||||
int classfix;
|
||||
int absolute;
|
||||
|
||||
int onlyforward;
|
||||
int stopbackward;
|
||||
int dontload;
|
||||
int dontsave;
|
||||
int dontloadscales;
|
||||
int numload;
|
||||
|
||||
float temperature;
|
||||
float probability;
|
||||
float scale;
|
||||
|
||||
char * cweights;
|
||||
int * indexes;
|
||||
int * input_layers;
|
||||
int * input_sizes;
|
||||
int * map;
|
||||
int * counts;
|
||||
float ** sums;
|
||||
float * rand;
|
||||
float * cost;
|
||||
float * state;
|
||||
float * prev_state;
|
||||
float * forgot_state;
|
||||
float * forgot_delta;
|
||||
float * state_delta;
|
||||
float * combine_cpu;
|
||||
float * combine_delta_cpu;
|
||||
|
||||
float *concat;
|
||||
float *concat_delta;
|
||||
|
||||
float *binary_weights;
|
||||
|
||||
float *biases;
|
||||
float *bias_updates;
|
||||
|
||||
float *scales;
|
||||
float *scale_updates;
|
||||
|
||||
float *weights;
|
||||
float *weight_updates;
|
||||
|
||||
char *align_bit_weights_gpu;
|
||||
float *mean_arr_gpu;
|
||||
float *align_workspace_gpu;
|
||||
float *transposed_align_workspace_gpu;
|
||||
int align_workspace_size;
|
||||
|
||||
char *align_bit_weights;
|
||||
float *mean_arr;
|
||||
int align_bit_weights_size;
|
||||
int lda_align;
|
||||
int new_lda;
|
||||
int bit_align;
|
||||
|
||||
float *col_image;
|
||||
float * delta;
|
||||
float * output;
|
||||
int delta_pinned;
|
||||
int output_pinned;
|
||||
float * loss;
|
||||
float * squared;
|
||||
float * norms;
|
||||
|
||||
float * spatial_mean;
|
||||
float * mean;
|
||||
float * variance;
|
||||
|
||||
float * mean_delta;
|
||||
float * variance_delta;
|
||||
|
||||
float * rolling_mean;
|
||||
float * rolling_variance;
|
||||
|
||||
float * x;
|
||||
float * x_norm;
|
||||
|
||||
float * m;
|
||||
float * v;
|
||||
|
||||
float * bias_m;
|
||||
float * bias_v;
|
||||
float * scale_m;
|
||||
float * scale_v;
|
||||
|
||||
|
||||
float *z_cpu;
|
||||
float *r_cpu;
|
||||
float *h_cpu;
|
||||
float *stored_h_cpu;
|
||||
float * prev_state_cpu;
|
||||
|
||||
float *temp_cpu;
|
||||
float *temp2_cpu;
|
||||
float *temp3_cpu;
|
||||
|
||||
float *dh_cpu;
|
||||
float *hh_cpu;
|
||||
float *prev_cell_cpu;
|
||||
float *cell_cpu;
|
||||
float *f_cpu;
|
||||
float *i_cpu;
|
||||
float *g_cpu;
|
||||
float *o_cpu;
|
||||
float *c_cpu;
|
||||
float *stored_c_cpu;
|
||||
float *dc_cpu;
|
||||
|
||||
float *binary_input;
|
||||
uint32_t *bin_re_packed_input;
|
||||
char *t_bit_input;
|
||||
|
||||
struct layer *input_layer;
|
||||
struct layer *self_layer;
|
||||
struct layer *output_layer;
|
||||
|
||||
struct layer *reset_layer;
|
||||
struct layer *update_layer;
|
||||
struct layer *state_layer;
|
||||
|
||||
struct layer *input_gate_layer;
|
||||
struct layer *state_gate_layer;
|
||||
struct layer *input_save_layer;
|
||||
struct layer *state_save_layer;
|
||||
struct layer *input_state_layer;
|
||||
struct layer *state_state_layer;
|
||||
|
||||
struct layer *input_z_layer;
|
||||
struct layer *state_z_layer;
|
||||
|
||||
struct layer *input_r_layer;
|
||||
struct layer *state_r_layer;
|
||||
|
||||
struct layer *input_h_layer;
|
||||
struct layer *state_h_layer;
|
||||
|
||||
struct layer *wz;
|
||||
struct layer *uz;
|
||||
struct layer *wr;
|
||||
struct layer *ur;
|
||||
struct layer *wh;
|
||||
struct layer *uh;
|
||||
struct layer *uo;
|
||||
struct layer *wo;
|
||||
struct layer *vo;
|
||||
struct layer *uf;
|
||||
struct layer *wf;
|
||||
struct layer *vf;
|
||||
struct layer *ui;
|
||||
struct layer *wi;
|
||||
struct layer *vi;
|
||||
struct layer *ug;
|
||||
struct layer *wg;
|
||||
|
||||
tree *softmax_tree;
|
||||
|
||||
size_t workspace_size;
|
||||
|
||||
#ifdef GPU
|
||||
int *indexes_gpu;
|
||||
|
||||
float *z_gpu;
|
||||
float *r_gpu;
|
||||
float *h_gpu;
|
||||
float *stored_h_gpu;
|
||||
|
||||
float *temp_gpu;
|
||||
float *temp2_gpu;
|
||||
float *temp3_gpu;
|
||||
|
||||
float *dh_gpu;
|
||||
float *hh_gpu;
|
||||
float *prev_cell_gpu;
|
||||
float *prev_state_gpu;
|
||||
float *last_prev_state_gpu;
|
||||
float *last_prev_cell_gpu;
|
||||
float *cell_gpu;
|
||||
float *f_gpu;
|
||||
float *i_gpu;
|
||||
float *g_gpu;
|
||||
float *o_gpu;
|
||||
float *c_gpu;
|
||||
float *stored_c_gpu;
|
||||
float *dc_gpu;
|
||||
|
||||
// adam
|
||||
float *m_gpu;
|
||||
float *v_gpu;
|
||||
float *bias_m_gpu;
|
||||
float *scale_m_gpu;
|
||||
float *bias_v_gpu;
|
||||
float *scale_v_gpu;
|
||||
|
||||
float * combine_gpu;
|
||||
float * combine_delta_gpu;
|
||||
|
||||
float * forgot_state_gpu;
|
||||
float * forgot_delta_gpu;
|
||||
float * state_gpu;
|
||||
float * state_delta_gpu;
|
||||
float * gate_gpu;
|
||||
float * gate_delta_gpu;
|
||||
float * save_gpu;
|
||||
float * save_delta_gpu;
|
||||
float * concat_gpu;
|
||||
float * concat_delta_gpu;
|
||||
|
||||
float *binary_input_gpu;
|
||||
float *binary_weights_gpu;
|
||||
float *bin_conv_shortcut_in_gpu;
|
||||
float *bin_conv_shortcut_out_gpu;
|
||||
|
||||
float * mean_gpu;
|
||||
float * variance_gpu;
|
||||
|
||||
float * rolling_mean_gpu;
|
||||
float * rolling_variance_gpu;
|
||||
|
||||
float * variance_delta_gpu;
|
||||
float * mean_delta_gpu;
|
||||
|
||||
float * col_image_gpu;
|
||||
|
||||
float * x_gpu;
|
||||
float * x_norm_gpu;
|
||||
float * weights_gpu;
|
||||
float * weight_updates_gpu;
|
||||
float * weight_change_gpu;
|
||||
|
||||
float * weights_gpu16;
|
||||
float * weight_updates_gpu16;
|
||||
|
||||
float * biases_gpu;
|
||||
float * bias_updates_gpu;
|
||||
float * bias_change_gpu;
|
||||
|
||||
float * scales_gpu;
|
||||
float * scale_updates_gpu;
|
||||
float * scale_change_gpu;
|
||||
|
||||
float * output_gpu;
|
||||
float * loss_gpu;
|
||||
float * delta_gpu;
|
||||
float * rand_gpu;
|
||||
float * squared_gpu;
|
||||
float * norms_gpu;
|
||||
#ifdef CUDNN
|
||||
cudnnTensorDescriptor_t srcTensorDesc, dstTensorDesc;
|
||||
cudnnTensorDescriptor_t srcTensorDesc16, dstTensorDesc16;
|
||||
cudnnTensorDescriptor_t dsrcTensorDesc, ddstTensorDesc;
|
||||
cudnnTensorDescriptor_t dsrcTensorDesc16, ddstTensorDesc16;
|
||||
cudnnTensorDescriptor_t normTensorDesc, normDstTensorDesc, normDstTensorDescF16;
|
||||
cudnnFilterDescriptor_t weightDesc, weightDesc16;
|
||||
cudnnFilterDescriptor_t dweightDesc, dweightDesc16;
|
||||
cudnnConvolutionDescriptor_t convDesc;
|
||||
cudnnConvolutionFwdAlgo_t fw_algo, fw_algo16;
|
||||
cudnnConvolutionBwdDataAlgo_t bd_algo, bd_algo16;
|
||||
cudnnConvolutionBwdFilterAlgo_t bf_algo, bf_algo16;
|
||||
cudnnPoolingDescriptor_t poolingDesc;
|
||||
#endif // CUDNN
|
||||
#endif // GPU
|
||||
};
|
||||
|
||||
|
||||
// network.h
|
||||
typedef enum {
|
||||
CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM, SGDR
|
||||
} learning_rate_policy;
|
||||
|
||||
// network.h
|
||||
typedef struct network {
|
||||
int n;
|
||||
int batch;
|
||||
uint64_t *seen;
|
||||
int *t;
|
||||
float epoch;
|
||||
int subdivisions;
|
||||
layer *layers;
|
||||
float *output;
|
||||
learning_rate_policy policy;
|
||||
|
||||
float learning_rate;
|
||||
float learning_rate_min;
|
||||
float learning_rate_max;
|
||||
int batches_per_cycle;
|
||||
int batches_cycle_mult;
|
||||
float momentum;
|
||||
float decay;
|
||||
float gamma;
|
||||
float scale;
|
||||
float power;
|
||||
int time_steps;
|
||||
int step;
|
||||
int max_batches;
|
||||
float *seq_scales;
|
||||
float *scales;
|
||||
int *steps;
|
||||
int num_steps;
|
||||
int burn_in;
|
||||
int cudnn_half;
|
||||
float *pre_allocated_ptr;
|
||||
int adam;
|
||||
float B1;
|
||||
float B2;
|
||||
float eps;
|
||||
|
||||
int inputs;
|
||||
int outputs;
|
||||
int truths;
|
||||
int notruth;
|
||||
int h, w, c;
|
||||
int max_crop;
|
||||
int min_crop;
|
||||
float max_ratio;
|
||||
float min_ratio;
|
||||
int center;
|
||||
int flip; // horizontal flip 50% probability augmentaiont for classifier training (default = 1)
|
||||
int blur;
|
||||
float angle;
|
||||
float aspect;
|
||||
float exposure;
|
||||
float saturation;
|
||||
float hue;
|
||||
int random;
|
||||
int track;
|
||||
int augment_speed;
|
||||
int sequential_subdivisions;
|
||||
int init_sequential_subdivisions;
|
||||
int current_subdivision;
|
||||
int try_fix_nan;
|
||||
|
||||
int gpu_index;
|
||||
tree *hierarchy;
|
||||
|
||||
float *input;
|
||||
float *truth;
|
||||
float *delta;
|
||||
float *workspace;
|
||||
int train;
|
||||
int index;
|
||||
float *cost;
|
||||
float clip;
|
||||
|
||||
#ifdef GPU
|
||||
//float *input_gpu;
|
||||
//float *truth_gpu;
|
||||
float *delta_gpu;
|
||||
float *output_gpu;
|
||||
|
||||
float *input_state_gpu;
|
||||
float *input_pinned_cpu;
|
||||
int input_pinned_cpu_flag;
|
||||
|
||||
float **input_gpu;
|
||||
float **truth_gpu;
|
||||
float **input16_gpu;
|
||||
float **output16_gpu;
|
||||
size_t *max_input16_size;
|
||||
size_t *max_output16_size;
|
||||
int wait_stream;
|
||||
#endif
|
||||
} network;
|
||||
|
||||
// network.h
|
||||
typedef struct network_state {
|
||||
float *truth;
|
||||
float *input;
|
||||
float *delta;
|
||||
float *workspace;
|
||||
int train;
|
||||
int index;
|
||||
network net;
|
||||
} network_state;
|
||||
|
||||
//typedef struct {
|
||||
// int w;
|
||||
// int h;
|
||||
// float scale;
|
||||
// float rad;
|
||||
// float dx;
|
||||
// float dy;
|
||||
// float aspect;
|
||||
//} augment_args;
|
||||
|
||||
// image.h
|
||||
typedef struct image {
|
||||
int w;
|
||||
int h;
|
||||
int c;
|
||||
float *data;
|
||||
} image;
|
||||
|
||||
//typedef struct {
|
||||
// int w;
|
||||
// int h;
|
||||
// int c;
|
||||
// float *data;
|
||||
//} image;
|
||||
|
||||
// box.h
|
||||
typedef struct box {
|
||||
float x, y, w, h;
|
||||
} box;
|
||||
|
||||
// box.h
|
||||
typedef struct detection{
|
||||
box bbox;
|
||||
int classes;
|
||||
float *prob;
|
||||
float *mask;
|
||||
float objectness;
|
||||
int sort_class;
|
||||
} detection;
|
||||
|
||||
// matrix.h
|
||||
typedef struct matrix {
|
||||
int rows, cols;
|
||||
float **vals;
|
||||
} matrix;
|
||||
|
||||
// data.h
|
||||
typedef struct data {
|
||||
int w, h;
|
||||
matrix X;
|
||||
matrix y;
|
||||
int shallow;
|
||||
int *num_boxes;
|
||||
box **boxes;
|
||||
} data;
|
||||
|
||||
// data.h
|
||||
typedef enum {
|
||||
CLASSIFICATION_DATA, DETECTION_DATA, CAPTCHA_DATA, REGION_DATA, IMAGE_DATA, COMPARE_DATA, WRITING_DATA, SWAG_DATA, TAG_DATA, OLD_CLASSIFICATION_DATA, STUDY_DATA, DET_DATA, SUPER_DATA, LETTERBOX_DATA, REGRESSION_DATA, SEGMENTATION_DATA, INSTANCE_DATA, ISEG_DATA
|
||||
} data_type;
|
||||
|
||||
// data.h
|
||||
typedef struct load_args {
|
||||
int threads;
|
||||
char **paths;
|
||||
char *path;
|
||||
int n;
|
||||
int m;
|
||||
char **labels;
|
||||
int h;
|
||||
int w;
|
||||
int c; // color depth
|
||||
int out_w;
|
||||
int out_h;
|
||||
int nh;
|
||||
int nw;
|
||||
int num_boxes;
|
||||
int min, max, size;
|
||||
int classes;
|
||||
int background;
|
||||
int scale;
|
||||
int center;
|
||||
int coords;
|
||||
int mini_batch;
|
||||
int track;
|
||||
int augment_speed;
|
||||
int show_imgs;
|
||||
float jitter;
|
||||
int flip;
|
||||
int blur;
|
||||
float angle;
|
||||
float aspect;
|
||||
float saturation;
|
||||
float exposure;
|
||||
float hue;
|
||||
data *d;
|
||||
image *im;
|
||||
image *resized;
|
||||
data_type type;
|
||||
tree *hierarchy;
|
||||
} load_args;
|
||||
|
||||
// data.h
|
||||
typedef struct box_label {
|
||||
int id;
|
||||
float x, y, w, h;
|
||||
float left, right, top, bottom;
|
||||
} box_label;
|
||||
|
||||
// list.h
|
||||
//typedef struct node {
|
||||
// void *val;
|
||||
// struct node *next;
|
||||
// struct node *prev;
|
||||
//} node;
|
||||
|
||||
// list.h
|
||||
//typedef struct list {
|
||||
// int size;
|
||||
// node *front;
|
||||
// node *back;
|
||||
//} list;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
// parser.c
|
||||
LIB_API network *load_network(char *cfg, char *weights, int clear);
|
||||
LIB_API network *load_network_custom(char *cfg, char *weights, int clear, int batch);
|
||||
LIB_API network *load_network(char *cfg, char *weights, int clear);
|
||||
|
||||
// network.c
|
||||
LIB_API load_args get_base_args(network *net);
|
||||
|
||||
// box.h
|
||||
LIB_API void do_nms_sort(detection *dets, int total, int classes, float thresh);
|
||||
LIB_API void do_nms_obj(detection *dets, int total, int classes, float thresh);
|
||||
|
||||
// network.h
|
||||
LIB_API float *network_predict(network net, float *input);
|
||||
LIB_API float *network_predict_ptr(network *net, float *input);
|
||||
LIB_API detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num, int letter);
|
||||
LIB_API void free_detections(detection *dets, int n);
|
||||
LIB_API void fuse_conv_batchnorm(network net);
|
||||
LIB_API void calculate_binary_weights(network net);
|
||||
LIB_API char *detection_to_json(detection *dets, int nboxes, int classes, char **names, long long int frame_id, char *filename);
|
||||
|
||||
LIB_API layer* get_network_layer(network* net, int i);
|
||||
//LIB_API detection *get_network_boxes(network *net, int w, int h, float thresh, float hier, int *map, int relative, int *num, int letter);
|
||||
LIB_API detection *make_network_boxes(network *net, float thresh, int *num);
|
||||
LIB_API void reset_rnn(network *net);
|
||||
LIB_API float *network_predict_image(network *net, image im);
|
||||
LIB_API float validate_detector_map(char *datacfg, char *cfgfile, char *weightfile, float thresh_calc_avg_iou, const float iou_thresh, const int map_points, network *existing_net);
|
||||
LIB_API void train_detector(char *datacfg, char *cfgfile, char *weightfile, int *gpus, int ngpus, int clear, int dont_show, int calc_map, int mjpeg_port, int show_imgs);
|
||||
LIB_API void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh,
|
||||
float hier_thresh, int dont_show, int ext_output, int save_labels, char *outfile, int letter_box);
|
||||
LIB_API int network_width(network *net);
|
||||
LIB_API int network_height(network *net);
|
||||
LIB_API void optimize_picture(network *net, image orig, int max_layer, float scale, float rate, float thresh, int norm);
|
||||
|
||||
// image.h
|
||||
LIB_API image resize_image(image im, int w, int h);
|
||||
LIB_API void copy_image_from_bytes(image im, char *pdata);
|
||||
LIB_API image letterbox_image(image im, int w, int h);
|
||||
LIB_API void rgbgr_image(image im);
|
||||
LIB_API image make_image(int w, int h, int c);
|
||||
LIB_API image load_image_color(char *filename, int w, int h);
|
||||
LIB_API void free_image(image m);
|
||||
|
||||
// layer.h
|
||||
LIB_API void free_layer(layer);
|
||||
|
||||
// data.c
|
||||
LIB_API void free_data(data d);
|
||||
LIB_API pthread_t load_data(load_args args);
|
||||
LIB_API pthread_t load_data_in_thread(load_args args);
|
||||
|
||||
// dark_cuda.h
|
||||
LIB_API void cuda_pull_array(float *x_gpu, float *x, size_t n);
|
||||
LIB_API void cuda_pull_array_async(float *x_gpu, float *x, size_t n);
|
||||
LIB_API void cuda_set_device(int n);
|
||||
LIB_API void *cuda_get_context();
|
||||
|
||||
// utils.h
|
||||
LIB_API void free_ptrs(void **ptrs, int n);
|
||||
LIB_API void top_k(float *a, int n, int k, int *index);
|
||||
|
||||
// tree.h
|
||||
LIB_API tree *read_tree(char *filename);
|
||||
|
||||
// option_list.h
|
||||
LIB_API metadata get_metadata(char *file);
|
||||
|
||||
|
||||
// http_stream.h
|
||||
LIB_API void delete_json_sender();
|
||||
LIB_API void send_json_custom(char const* send_buf, int port, int timeout);
|
||||
LIB_API double get_time_point();
|
||||
void start_timer();
|
||||
void stop_timer();
|
||||
double get_time();
|
||||
void stop_timer_and_show();
|
||||
void stop_timer_and_show_name(char *name);
|
||||
void show_total_time();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
#endif // DIMENSIONLESS_API
|
||||
@@ -0,0 +1,120 @@
|
||||
#ifndef EVALUATION_H
|
||||
#define EVALUATION_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include "tkdnn.h"
|
||||
#include "BoundingBox.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
struct Frame
|
||||
{
|
||||
std::string lFilename;
|
||||
std::string iFilename;
|
||||
std::vector<BoundingBox> gt;
|
||||
std::vector<BoundingBox> det;
|
||||
|
||||
void print() const;
|
||||
};
|
||||
|
||||
struct PR
|
||||
{
|
||||
double precision = 0;
|
||||
double recall = 0;
|
||||
int tp = 0, fp = 0, fn = 0;
|
||||
|
||||
void print();
|
||||
};
|
||||
|
||||
void readmAPParams( const char* config_filename, int& classes1,float& conf_thresh1
|
||||
, int& classes2,float& conf_thresh2
|
||||
, int& classes3,float& conf_thresh3
|
||||
, int& classes4,float& conf_thresh4
|
||||
, int& classes5,float& conf_thresh5
|
||||
);
|
||||
|
||||
/**
|
||||
* This method computes the mean Average Precision for a set of detections and
|
||||
* groundtruths. It returns the mAP for a given IoU threshold, and a given
|
||||
* confidence threshold over all the classes.
|
||||
*
|
||||
* @param images collection of frames on which to compute the metrics
|
||||
* @param classes number of classes of the considered dataset
|
||||
* @param IoU_thresh threshold used to compute Intersection over Union
|
||||
* @param conf_thresh threshold used to filter bounding boxes based on their
|
||||
* confidence (or probability)
|
||||
* @param map_points number of point used to compute the mAP. if 0 is given,
|
||||
* all the recall levels are evaluated, otherwise only
|
||||
* map_point recall levels are used. For COCO evaluation
|
||||
* 101 points are used.
|
||||
* @param verbose is set to true, prints on screen additional info
|
||||
*
|
||||
* @return mAP computed
|
||||
*/
|
||||
double computeMap( std::vector<Frame> &images,const int classes,
|
||||
const float IoU_thresh, const float conf_thresh=0.3,
|
||||
const int map_points=101, const bool verbose=false);
|
||||
|
||||
|
||||
/**
|
||||
* This method computes the mean Average Precision for a set of detections and
|
||||
* groundtruths on several IoU thresholds. It is used to compute, for example,
|
||||
* the most used metric in Object Detection, namely the mAP 0.5:0.95, which is
|
||||
* the average among the mAP for IoU level from 0.5 to 0.95 with a step of 0.05.
|
||||
*
|
||||
* @param images collection of frames on which to compute the metrics
|
||||
* @param classes number of classes of the considered dataset
|
||||
* @param IoU_thresh starting threshold used to compute Intersection over Union
|
||||
* @param conf_thresh threshold used to filter bounding boxes based on their
|
||||
* confidence (or probability)
|
||||
* @param map_points number of point used to compute the mAP. if 0 is given,
|
||||
* all the recall levels are evaluated, otherwise only
|
||||
* map_point recall levels are used. For COCO evaluation
|
||||
* 101 points are used.
|
||||
* @param map_step step used to increment IoU threshold
|
||||
* @param map_levels number of IoU step to perform
|
||||
* @param verbose is set to true, prints on screen additional info
|
||||
* @param write_on_file if set to true, the results produced by this function
|
||||
* are written on file
|
||||
* @param net name of the considered neural network
|
||||
*
|
||||
* @return mAP IoU_tresh:IoU_tresh+map_step*map_levels (e.g. mAP 0.5:0.95 when
|
||||
* map_step=0.05 and map_levels=10)
|
||||
*/
|
||||
double computeMapNIoULevels(std::vector<Frame> &images,const int classes,
|
||||
const float i_IoU_thresh=0.5, const float conf_thresh=0.3,
|
||||
const int map_points=101, const float map_step=0.05,
|
||||
const int map_levels=10, const bool verbose=false,
|
||||
const bool write_on_file = false, std::string net = "");
|
||||
/**
|
||||
* This method computes the number of True Positive (TP), False Positive (FP),
|
||||
* False Negative (FN), precision, recall and f1-score.
|
||||
* Those values are computer over all the detections, over all the classes.
|
||||
*
|
||||
* @param images collection of frames on which to compute the metrics
|
||||
* @param classes number of classes of the considered dataset
|
||||
* @param IoU_thresh threshold used to compute Intersection over Union
|
||||
* @param conf_thresh threshold used to filter bounding boxes based on their
|
||||
* confidence (or probability)
|
||||
* @param verbose is set to true, prints on screen additional info
|
||||
* @param write_on_file if set to true, the results produced by this function
|
||||
* are written on file
|
||||
* @param net name of the considered neural network
|
||||
*/
|
||||
void computeTPFPFN( std::vector<Frame> &images,const int classes,
|
||||
const float IoU_thresh=0.5, const float conf_thresh=0.3,
|
||||
bool verbose=false, const bool write_on_file=false,
|
||||
std::string net="");
|
||||
|
||||
|
||||
void printJsonCOCOFormat(std::ofstream *out_file, const std::string image_path, std::vector<tk::dnn::box> bbox, const int classes, const int w, const int h);
|
||||
|
||||
}}
|
||||
#endif /*EVALUATION_H*/
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef HANDLER_H
|
||||
#define HANDLER_H
|
||||
#include <iostream>
|
||||
#include "stdafx.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace web;
|
||||
using namespace http;
|
||||
using namespace utility;
|
||||
using namespace http::experimental::listener;
|
||||
|
||||
|
||||
class handler
|
||||
{
|
||||
public:
|
||||
handler(utility::string_t url);
|
||||
|
||||
pplx::task<void>open(){return m_listener.open();}
|
||||
pplx::task<void>close(){return m_listener.close();}
|
||||
static void init_bag();
|
||||
protected:
|
||||
|
||||
private:
|
||||
void handle_post(http_request message);
|
||||
http_listener m_listener;
|
||||
};
|
||||
|
||||
#endif // HANDLER_H
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef IMAGE_H
|
||||
#define IMAGE_H
|
||||
#include "darknet.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
//#include "image_opencv.h"
|
||||
|
||||
//#include "box.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
typedef struct {
|
||||
int w;
|
||||
int h;
|
||||
int c;
|
||||
float *data;
|
||||
} image;
|
||||
*/
|
||||
float get_color(int c, int x, int max);
|
||||
void flip_image(image a);
|
||||
void draw_box(image a, int x1, int y1, int x2, int y2, float r, float g, float b);
|
||||
void draw_box_width(image a, int x1, int y1, int x2, int y2, int w, float r, float g, float b);
|
||||
void draw_bbox(image a, box bbox, int w, float r, float g, float b);
|
||||
void draw_label(image a, int r, int c, image label, const float *rgb);
|
||||
void write_label(image a, int r, int c, image *characters, char *string, float *rgb);
|
||||
void draw_detections(image im, int num, float thresh, box *boxes, float **probs, char **names, image **labels, int classes);
|
||||
void draw_detections_v3(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes, int ext_output);
|
||||
image image_distance(image a, image b);
|
||||
void scale_image(image m, float s);
|
||||
// image crop_image(image im, int dx, int dy, int w, int h);
|
||||
image random_crop_image(image im, int w, int h);
|
||||
image random_augment_image(image im, float angle, float aspect, int low, int high, int size);
|
||||
void random_distort_image(image im, float hue, float saturation, float exposure);
|
||||
//LIB_API image resize_image(image im, int w, int h);
|
||||
//LIB_API void copy_image_from_bytes(image im, char *pdata);
|
||||
void fill_image(image m, float s);
|
||||
void letterbox_image_into(image im, int w, int h, image boxed);
|
||||
//LIB_API image letterbox_image(image im, int w, int h);
|
||||
// image resize_min(image im, int min);
|
||||
image resize_max(image im, int max);
|
||||
void translate_image(image m, float s);
|
||||
void normalize_image(image p);
|
||||
image rotate_image(image m, float rad);
|
||||
void rotate_image_cw(image im, int times);
|
||||
void embed_image(image source, image dest, int dx, int dy);
|
||||
void saturate_image(image im, float sat);
|
||||
void exposure_image(image im, float sat);
|
||||
void distort_image(image im, float hue, float sat, float val);
|
||||
void saturate_exposure_image(image im, float sat, float exposure);
|
||||
void hsv_to_rgb(image im);
|
||||
//LIB_API void rgbgr_image(image im);
|
||||
void constrain_image(image im);
|
||||
void composite_3d(char *f1, char *f2, char *out, int delta);
|
||||
int best_3d_shift_r(image a, image b, int min, int max);
|
||||
|
||||
image grayscale_image(image im);
|
||||
image threshold_image(image im, float thresh);
|
||||
|
||||
image collapse_image_layers(image source, int border);
|
||||
image collapse_images_horz(image *ims, int n);
|
||||
image collapse_images_vert(image *ims, int n);
|
||||
|
||||
void show_image(image p, const char *name);
|
||||
void show_image_normalized(image im, const char *name);
|
||||
void save_image_png(image im, const char *name);
|
||||
void save_image(image p, const char *name);
|
||||
void show_images(image *ims, int n, char *window);
|
||||
void show_image_layers(image p, char *name);
|
||||
void show_image_collapsed(image p, char *name);
|
||||
|
||||
void print_image(image m);
|
||||
|
||||
//LIB_API image make_image(int w, int h, int c);
|
||||
image make_random_image(int w, int h, int c);
|
||||
image make_empty_image(int w, int h, int c);
|
||||
image float_to_image_scaled(int w, int h, int c, float *data);
|
||||
image float_to_image(int w, int h, int c, float *data);
|
||||
image copy_image(image p);
|
||||
void copy_image_inplace(image src, image dst);
|
||||
image load_image(char *filename, int w, int h, int c);
|
||||
image load_image_stb_resize(char *filename, int w, int h, int c);
|
||||
image load_image_new(unsigned char *image_data, int len, int channels, int antiLog, int gray, int width, int height);
|
||||
image load_image_file(unsigned char *image_data, int channels, int antilog, int gray, int width, int height);
|
||||
//LIB_API image load_image_color(char *filename, int w, int h);
|
||||
image **load_alphabet();
|
||||
|
||||
//float get_pixel(image m, int x, int y, int c);
|
||||
//float get_pixel_extend(image m, int x, int y, int c);
|
||||
//void set_pixel(image m, int x, int y, int c, float val);
|
||||
//void add_pixel(image m, int x, int y, int c, float val);
|
||||
float bilinear_interpolate(image im, float x, float y, int c);
|
||||
|
||||
image get_image_layer(image m, int l);
|
||||
|
||||
//LIB_API void free_image(image m);
|
||||
void test_resize(char *filename);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+25
-27
@@ -3,42 +3,38 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void activationELUForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationLEAKYForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationLOGISTICForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationSIGMOIDForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationELUForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationLEAKYForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationReLUCeilingForward(dnnType *srcData, dnnType *dstData, int size, const float ceiling, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationLOGISTICForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationSIGMOIDForward(dnnType *srcData, dnnType *dstData, int size, cudaStream_t stream = cudaStream_t(0));
|
||||
void activationMishForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream= cudaStream_t(0));
|
||||
|
||||
void fill(dnnType* data, int size, dnnType val, cudaStream_t stream = cudaStream_t(0));
|
||||
void fill(dnnType *data, int size, dnnType val, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void resizeForward( dnnType* srcData, dnnType* dstData, int n, int i_c, int i_h, int i_w,
|
||||
int o_c, int o_h, int o_w, cudaStream_t stream = cudaStream_t(0));
|
||||
void resizeForward(dnnType *srcData, dnnType *dstData, int n, int i_c, int i_h, int i_w,
|
||||
int o_c, int o_h, int o_w, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void reorgForward( dnnType* srcData, dnnType* dstData,
|
||||
int n, int c, int h, int w, int stride, cudaStream_t stream = cudaStream_t(0));
|
||||
void softmaxForward(float *input, int n, int batch, int batch_offset,
|
||||
void reorgForward(dnnType *srcData, dnnType *dstData,
|
||||
int n, int c, int h, int w, int stride, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void MaxPoolingForward(dnnType *srcData, dnnType *dstData, int n, int c, int h, int w, int stride_x, int stride_y, int size, int padding, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void softmaxForward(float *input, int n, int batch, int batch_offset,
|
||||
int groups, int group_offset, int stride, float temp, float *output, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
|
||||
void shortcutForward(dnnType* srcData, dnnType* dstData, int n1, int c1, int h1, int w1, int s1,
|
||||
int n2, int c2, int h2, int w2, int s2,
|
||||
void shortcutForward(dnnType *srcData, dnnType *dstData, int n1, int c1, int h1, int w1, int s1,
|
||||
int n2, int c2, int h2, int w2, int s2,
|
||||
cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void upsampleForward(dnnType* srcData, dnnType* dstData,
|
||||
int n, int c, int h, int w, int s, int forward, float scale,
|
||||
void upsampleForward(dnnType *srcData, dnnType *dstData,
|
||||
int n, int c, int h, int w, int s, int forward, float scale,
|
||||
cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void float2half(float* srcData, __half* dstData, int size, const cudaStream_t stream = cudaStream_t(0));
|
||||
void float2half(float *srcData, __half *dstData, int size, const cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
|
||||
void modulated_deformable_im2col_cuda(cudaStream_t stream,
|
||||
const float *data_im, const float *data_offset, const float *data_mask,
|
||||
const int batch_size, const int channels, const int height_im, const int width_im,
|
||||
const int height_col, const int width_col, const int kernel_h, const int kenerl_w,
|
||||
const int pad_h, const int pad_w, const int stride_h, const int stride_w,
|
||||
const int dilation_h, const int dilation_w,
|
||||
const int deformable_group, float *data_col);
|
||||
|
||||
void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
void dcnV2CudaForward(cublasStatus_t stat, cublasHandle_t handle,
|
||||
float *input, float *weight,
|
||||
float *bias, float *ones,
|
||||
float *offset, float *mask,
|
||||
float *output, float *columns,
|
||||
@@ -46,8 +42,10 @@ void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
const int stride_h, const int stride_w,
|
||||
const int pad_h, const int pad_w,
|
||||
const int dilation_h, const int dilation_w,
|
||||
const int deformable_group,
|
||||
const int deformable_group, const int batch_id,
|
||||
const int in_n, const int in_c, const int in_h, const int in_w,
|
||||
const int out_n, const int out_c, const int out_h, const int out_w,
|
||||
const int dst_dim, cudaStream_t stream = cudaStream_t(0));
|
||||
|
||||
void scalAdd(dnnType* dstData, int size, float alpha, float beta, int inc, cudaStream_t stream = cudaStream_t(0));
|
||||
#endif //KERNELS_H
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef KERNELSTHRUST_H
|
||||
#define KERNELSTHRUST_H
|
||||
|
||||
|
||||
#include <thrust/sort.h>
|
||||
#include <thrust/execution_policy.h>
|
||||
#include <thrust/functional.h>
|
||||
#include <thrust/transform.h>
|
||||
#include <thrust/iterator/constant_iterator.h>
|
||||
#include <thrust/gather.h>
|
||||
#include <thrust/copy.h>
|
||||
|
||||
#include "tkdnn.h"
|
||||
|
||||
struct threshold : public thrust::binary_function<float,float,float>
|
||||
{
|
||||
__host__ __device__
|
||||
float operator()(float x, float y) {
|
||||
double toll = 1e-6;
|
||||
if(fabsf(x-y)>toll)
|
||||
return 0.0f;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
void sort(dnnType *src_begin, dnnType *src_end, int *idsrc);
|
||||
void topk(dnnType *src_begin, int *idsrc, int K, float *topk_scores,
|
||||
int *topk_inds, float *topk_ys, float *topk_xs);
|
||||
// void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int *topk_inds, float *topk_ys, float *topk_xs, const int size, const int K, const int n_classes);
|
||||
void normalize(float *bgr, const int ch, const int h, const int w, const float *mean, const float *stddev);
|
||||
void subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out, struct threshold op);
|
||||
void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys);
|
||||
void topKxyAddOffset(int * ids_begin, const int K, const int size, int *intxs_begin, int *intys_begin,
|
||||
float *xs_begin, float *ys_begin, dnnType *src_begin, float *src_out, int *ids_out);
|
||||
void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin,
|
||||
dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1, float *src_out, int *ids_out);
|
||||
|
||||
#endif //KERNELSTHRUST_H
|
||||
@@ -1,289 +0,0 @@
|
||||
int preYoloFilters = (classes+5)*3;
|
||||
|
||||
std::string input_bin = bin_path + "/layers/input.bin";
|
||||
std::vector<std::string> output_bins = {
|
||||
bin_path + "/debug/layer82_out.bin",
|
||||
bin_path + "/debug/layer94_out.bin",
|
||||
bin_path + "/debug/layer106_out.bin"
|
||||
};
|
||||
std::string c0_bin = bin_path + "/layers/c0.bin";
|
||||
std::string c1_bin = bin_path + "/layers/c1.bin";
|
||||
std::string c2_bin = bin_path + "/layers/c2.bin";
|
||||
std::string c3_bin = bin_path + "/layers/c3.bin";
|
||||
std::string c5_bin = bin_path + "/layers/c5.bin";
|
||||
std::string c6_bin = bin_path + "/layers/c6.bin";
|
||||
std::string c7_bin = bin_path + "/layers/c7.bin";
|
||||
std::string c9_bin = bin_path + "/layers/c9.bin";
|
||||
std::string c10_bin = bin_path + "/layers/c10.bin";
|
||||
std::string c12_bin = bin_path + "/layers/c12.bin";
|
||||
std::string c13_bin = bin_path + "/layers/c13.bin";
|
||||
std::string c14_bin = bin_path + "/layers/c14.bin";
|
||||
std::string c16_bin = bin_path + "/layers/c16.bin";
|
||||
std::string c17_bin = bin_path + "/layers/c17.bin";
|
||||
std::string c19_bin = bin_path + "/layers/c19.bin";
|
||||
std::string c20_bin = bin_path + "/layers/c20.bin";
|
||||
std::string c22_bin = bin_path + "/layers/c22.bin";
|
||||
std::string c23_bin = bin_path + "/layers/c23.bin";
|
||||
std::string c25_bin = bin_path + "/layers/c25.bin";
|
||||
std::string c26_bin = bin_path + "/layers/c26.bin";
|
||||
std::string c28_bin = bin_path + "/layers/c28.bin";
|
||||
std::string c29_bin = bin_path + "/layers/c29.bin";
|
||||
std::string c31_bin = bin_path + "/layers/c31.bin";
|
||||
std::string c32_bin = bin_path + "/layers/c32.bin";
|
||||
std::string c34_bin = bin_path + "/layers/c34.bin";
|
||||
std::string c35_bin = bin_path + "/layers/c35.bin";
|
||||
std::string c37_bin = bin_path + "/layers/c37.bin";
|
||||
std::string c38_bin = bin_path + "/layers/c38.bin";
|
||||
std::string c39_bin = bin_path + "/layers/c39.bin";
|
||||
std::string c41_bin = bin_path + "/layers/c41.bin";
|
||||
std::string c42_bin = bin_path + "/layers/c42.bin";
|
||||
std::string c44_bin = bin_path + "/layers/c44.bin";
|
||||
std::string c45_bin = bin_path + "/layers/c45.bin";
|
||||
std::string c47_bin = bin_path + "/layers/c47.bin";
|
||||
std::string c48_bin = bin_path + "/layers/c48.bin";
|
||||
std::string c50_bin = bin_path + "/layers/c50.bin";
|
||||
std::string c51_bin = bin_path + "/layers/c51.bin";
|
||||
std::string c53_bin = bin_path + "/layers/c53.bin";
|
||||
std::string c54_bin = bin_path + "/layers/c54.bin";
|
||||
std::string c56_bin = bin_path + "/layers/c56.bin";
|
||||
std::string c57_bin = bin_path + "/layers/c57.bin";
|
||||
std::string c59_bin = bin_path + "/layers/c59.bin";
|
||||
std::string c60_bin = bin_path + "/layers/c60.bin";
|
||||
std::string c62_bin = bin_path + "/layers/c62.bin";
|
||||
std::string c63_bin = bin_path + "/layers/c63.bin";
|
||||
std::string c64_bin = bin_path + "/layers/c64.bin";
|
||||
std::string c66_bin = bin_path + "/layers/c66.bin";
|
||||
std::string c67_bin = bin_path + "/layers/c67.bin";
|
||||
std::string c69_bin = bin_path + "/layers/c69.bin";
|
||||
std::string c70_bin = bin_path + "/layers/c70.bin";
|
||||
std::string c72_bin = bin_path + "/layers/c72.bin";
|
||||
std::string c73_bin = bin_path + "/layers/c73.bin";
|
||||
std::string c75_bin = bin_path + "/layers/c75.bin";
|
||||
std::string c76_bin = bin_path + "/layers/c76.bin";
|
||||
std::string c77_bin = bin_path + "/layers/c77.bin";
|
||||
std::string c78_bin = bin_path + "/layers/c78.bin";
|
||||
std::string c79_bin = bin_path + "/layers/c79.bin";
|
||||
std::string c80_bin = bin_path + "/layers/c80.bin";
|
||||
std::string c81_bin = bin_path + "/layers/c81.bin";
|
||||
std::string g82_bin = bin_path + "/layers/g82.bin";
|
||||
std::string c84_bin = bin_path + "/layers/c84.bin";
|
||||
std::string c87_bin = bin_path + "/layers/c87.bin";
|
||||
std::string c88_bin = bin_path + "/layers/c88.bin";
|
||||
std::string c89_bin = bin_path + "/layers/c89.bin";
|
||||
std::string c90_bin = bin_path + "/layers/c90.bin";
|
||||
std::string c91_bin = bin_path + "/layers/c91.bin";
|
||||
std::string c92_bin = bin_path + "/layers/c92.bin";
|
||||
std::string c93_bin = bin_path + "/layers/c93.bin";
|
||||
std::string g94_bin = bin_path + "/layers/g94.bin";
|
||||
std::string c96_bin = bin_path + "/layers/c96.bin";
|
||||
std::string c99_bin = bin_path + "/layers/c99.bin";
|
||||
std::string c100_bin = bin_path + "/layers/c100.bin";
|
||||
std::string c101_bin = bin_path + "/layers/c101.bin";
|
||||
std::string c102_bin = bin_path + "/layers/c102.bin";
|
||||
std::string c103_bin = bin_path + "/layers/c103.bin";
|
||||
std::string c104_bin = bin_path + "/layers/c104.bin";
|
||||
std::string c105_bin = bin_path + "/layers/c105.bin";
|
||||
std::string g106_bin = bin_path + "/layers/g106.bin";
|
||||
|
||||
tk::dnn::Conv2d c0 (&net, 32, 3, 3, 1, 1, 1, 1, c0_bin, true);
|
||||
tk::dnn::Activation a0 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c1 (&net, 64, 3, 3, 2, 2, 1, 1, c1_bin, true);
|
||||
tk::dnn::Activation a1 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c2 (&net, 32, 1, 1, 1, 1, 0, 0, c2_bin, true);
|
||||
tk::dnn::Activation a2 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c3 (&net, 64, 3, 3, 1, 1, 1, 1, c3_bin, true);
|
||||
tk::dnn::Activation a3 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s4 (&net, &a1);
|
||||
tk::dnn::Conv2d c5 (&net, 128, 3, 3, 2, 2, 1, 1, c5_bin, true);
|
||||
tk::dnn::Activation a5 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c6 (&net, 64, 1, 1, 1, 1, 0, 0, c6_bin, true);
|
||||
tk::dnn::Activation a6 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c7 (&net, 128, 3, 3, 1, 1, 1, 1, c7_bin, true);
|
||||
tk::dnn::Activation a7 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s8 (&net, &a5);
|
||||
tk::dnn::Conv2d c9 (&net, 64, 1, 1, 1, 1, 0, 0, c9_bin, true);
|
||||
tk::dnn::Activation a9 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c10 (&net, 128, 3, 3, 1, 1, 1, 1, c10_bin, true);
|
||||
tk::dnn::Activation a10 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s11 (&net, &s8);
|
||||
|
||||
tk::dnn::Conv2d c12 (&net, 256, 3, 3, 2, 2, 1, 1, c12_bin, true);
|
||||
tk::dnn::Activation a12 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c13 (&net, 128, 1, 1, 1, 1, 0, 0, c13_bin, true);
|
||||
tk::dnn::Activation a13 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c14 (&net, 256, 3, 3, 1, 1, 1, 1, c14_bin, true);
|
||||
tk::dnn::Activation a14 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s15 (&net, &a12);
|
||||
|
||||
tk::dnn::Conv2d c16 (&net, 128, 1, 1, 1, 1, 0, 0, c16_bin, true);
|
||||
tk::dnn::Activation a16 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c17 (&net, 256, 3, 3, 1, 1, 1, 1, c17_bin, true);
|
||||
tk::dnn::Activation a17 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s18 (&net, &s15);
|
||||
tk::dnn::Conv2d c19 (&net, 128, 1, 1, 1, 1, 0, 0, c19_bin, true);
|
||||
tk::dnn::Activation a19 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c20 (&net, 256, 3, 3, 1, 1, 1, 1, c20_bin, true);
|
||||
tk::dnn::Activation a20 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s21 (&net, &s18);
|
||||
tk::dnn::Conv2d c22 (&net, 128, 1, 1, 1, 1, 0, 0, c22_bin, true);
|
||||
tk::dnn::Activation a22 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c23 (&net, 256, 3, 3, 1, 1, 1, 1, c23_bin, true);
|
||||
tk::dnn::Activation a23 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s24 (&net, &s21);
|
||||
tk::dnn::Conv2d c25 (&net, 128, 1, 1, 1, 1, 0, 0, c25_bin, true);
|
||||
tk::dnn::Activation a25 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c26 (&net, 256, 3, 3, 1, 1, 1, 1, c26_bin, true);
|
||||
tk::dnn::Activation a26 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s27 (&net, &s24);
|
||||
tk::dnn::Conv2d c28 (&net, 128, 1, 1, 1, 1, 0, 0, c28_bin, true);
|
||||
tk::dnn::Activation a28 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c29 (&net, 256, 3, 3, 1, 1, 1, 1, c29_bin, true);
|
||||
tk::dnn::Activation a29 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s30 (&net, &s27);
|
||||
tk::dnn::Conv2d c31 (&net, 128, 1, 1, 1, 1, 0, 0, c31_bin, true);
|
||||
tk::dnn::Activation a31 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c32 (&net, 256, 3, 3, 1, 1, 1, 1, c32_bin, true);
|
||||
tk::dnn::Activation a32 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s33 (&net, &s30);
|
||||
tk::dnn::Conv2d c34 (&net, 128, 1, 1, 1, 1, 0, 0, c34_bin, true);
|
||||
tk::dnn::Activation a34 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c35 (&net, 256, 3, 3, 1, 1, 1, 1, c35_bin, true);
|
||||
tk::dnn::Activation a35 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s36 (&net, &s33);
|
||||
|
||||
tk::dnn::Conv2d c37 (&net, 512, 3, 3, 2, 2, 1, 1, c37_bin, true);
|
||||
tk::dnn::Activation a37 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c38 (&net, 256, 1, 1, 1, 1, 0, 0, c38_bin, true);
|
||||
tk::dnn::Activation a38 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c39 (&net, 512, 3, 3, 1, 1, 1, 1, c39_bin, true);
|
||||
tk::dnn::Activation a39 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s40 (&net, &a37);
|
||||
|
||||
tk::dnn::Conv2d c41 (&net, 256, 1, 1, 1, 1, 0, 0, c41_bin, true);
|
||||
tk::dnn::Activation a41 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c42 (&net, 512, 3, 3, 1, 1, 1, 1, c42_bin, true);
|
||||
tk::dnn::Activation a42 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s43 (&net, &s40);
|
||||
tk::dnn::Conv2d c44 (&net, 256, 1, 1, 1, 1, 0, 0, c44_bin, true);
|
||||
tk::dnn::Activation a44 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c45 (&net, 512, 3, 3, 1, 1, 1, 1, c45_bin, true);
|
||||
tk::dnn::Activation a45 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s46 (&net, &s43);
|
||||
tk::dnn::Conv2d c47 (&net, 256, 1, 1, 1, 1, 0, 0, c47_bin, true);
|
||||
tk::dnn::Activation a47 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c48 (&net, 512, 3, 3, 1, 1, 1, 1, c48_bin, true);
|
||||
tk::dnn::Activation a48 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s49 (&net, &s46);
|
||||
tk::dnn::Conv2d c50 (&net, 256, 1, 1, 1, 1, 0, 0, c50_bin, true);
|
||||
tk::dnn::Activation a50 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c51 (&net, 512, 3, 3, 1, 1, 1, 1, c51_bin, true);
|
||||
tk::dnn::Activation a51 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s52 (&net, &s49);
|
||||
tk::dnn::Conv2d c53 (&net, 256, 1, 1, 1, 1, 0, 0, c53_bin, true);
|
||||
tk::dnn::Activation a53 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c54 (&net, 512, 3, 3, 1, 1, 1, 1, c54_bin, true);
|
||||
tk::dnn::Activation a54 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s55 (&net, &s52);
|
||||
tk::dnn::Conv2d c56 (&net, 256, 1, 1, 1, 1, 0, 0, c56_bin, true);
|
||||
tk::dnn::Activation a56 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c57 (&net, 512, 3, 3, 1, 1, 1, 1, c57_bin, true);
|
||||
tk::dnn::Activation a57 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s58 (&net, &s55);
|
||||
tk::dnn::Conv2d c59 (&net, 256, 1, 1, 1, 1, 0, 0, c59_bin, true);
|
||||
tk::dnn::Activation a59 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c60 (&net, 512, 3, 3, 1, 1, 1, 1, c60_bin, true);
|
||||
tk::dnn::Activation a60 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s61 (&net, &s58);
|
||||
|
||||
tk::dnn::Conv2d c62 (&net,1024, 3, 3, 2, 2, 1, 1, c62_bin, true);
|
||||
tk::dnn::Activation a62 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c63 (&net, 512, 1, 1, 1, 1, 0, 0, c63_bin, true);
|
||||
tk::dnn::Activation a63 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c64 (&net,1024, 3, 3, 1, 1, 1, 1, c64_bin, true);
|
||||
tk::dnn::Activation a64 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s65 (&net, &a62);
|
||||
|
||||
tk::dnn::Conv2d c66 (&net, 512, 1, 1, 1, 1, 0, 0, c66_bin, true);
|
||||
tk::dnn::Activation a66 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c67 (&net,1024, 3, 3, 1, 1, 1, 1, c67_bin, true);
|
||||
tk::dnn::Activation a67 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s68 (&net, &s65);
|
||||
|
||||
tk::dnn::Conv2d c69 (&net, 512, 1, 1, 1, 1, 0, 0, c69_bin, true);
|
||||
tk::dnn::Activation a69 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c70 (&net,1024, 3, 3, 1, 1, 1, 1, c70_bin, true);
|
||||
tk::dnn::Activation a70 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s71 (&net, &s68);
|
||||
|
||||
tk::dnn::Conv2d c72 (&net, 512, 1, 1, 1, 1, 0, 0, c72_bin, true);
|
||||
tk::dnn::Activation a72 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c73 (&net,1024, 3, 3, 1, 1, 1, 1, c73_bin, true);
|
||||
tk::dnn::Activation a73 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Shortcut s74 (&net, &s71);
|
||||
|
||||
tk::dnn::Conv2d c75 (&net, 512, 1, 1, 1, 1, 0, 0, c75_bin, true);
|
||||
tk::dnn::Activation a75 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c76 (&net,1024, 3, 3, 1, 1, 1, 1, c76_bin, true);
|
||||
tk::dnn::Activation a76 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c77 (&net, 512, 1, 1, 1, 1, 0, 0, c77_bin, true);
|
||||
tk::dnn::Activation a77 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c78 (&net,1024, 3, 3, 1, 1, 1, 1, c78_bin, true);
|
||||
tk::dnn::Activation a78 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c79 (&net, 512, 1, 1, 1, 1, 0, 0, c79_bin, true);
|
||||
tk::dnn::Activation a79 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c80 (&net,1024, 3, 3, 1, 1, 1, 1, c80_bin, true);
|
||||
tk::dnn::Activation a80 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c81 (&net, preYoloFilters, 1, 1, 1, 1, 0, 0, c81_bin, false);
|
||||
tk::dnn::Yolo yolo0 (&net, classes, 3, g82_bin);
|
||||
|
||||
tk::dnn::Layer *m83_layers[1] = { &a79 };
|
||||
tk::dnn::Route m83 (&net, m83_layers, 1);
|
||||
tk::dnn::Conv2d c84 (&net, 256, 1, 1, 1, 1, 0, 0, c84_bin, true);
|
||||
tk::dnn::Activation a84 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Upsample u85 (&net, 2);
|
||||
|
||||
tk::dnn::Layer *m86_layers[2] = { &u85, &s61 };
|
||||
tk::dnn::Route m86 (&net, m86_layers, 2);
|
||||
tk::dnn::Conv2d c87 (&net, 256, 1, 1, 1, 1, 0, 0, c87_bin, true);
|
||||
tk::dnn::Activation a87 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c88 (&net, 512, 3, 3, 1, 1, 1, 1, c88_bin, true);
|
||||
tk::dnn::Activation a88 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c89 (&net, 256, 1, 1, 1, 1, 0, 0, c89_bin, true);
|
||||
tk::dnn::Activation a89 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c90 (&net, 512, 3, 3, 1, 1, 1, 1, c90_bin, true);
|
||||
tk::dnn::Activation a90 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c91 (&net, 256, 1, 1, 1, 1, 0, 0, c91_bin, true);
|
||||
tk::dnn::Activation a91 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
|
||||
tk::dnn::Conv2d c92 (&net, 512, 3, 3, 1, 1, 1, 1, c92_bin, true);
|
||||
tk::dnn::Activation a92 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c93 (&net, preYoloFilters, 1, 1, 1, 1, 0, 0, c93_bin, false);
|
||||
tk::dnn::Yolo yolo1 (&net, classes, 3, g94_bin);
|
||||
|
||||
tk::dnn::Layer *m95_layers[1] = { &a91 };
|
||||
tk::dnn::Route m95 (&net, m95_layers, 1);
|
||||
tk::dnn::Conv2d c96 (&net, 128, 1, 1, 1, 1, 0, 0, c96_bin, true);
|
||||
tk::dnn::Activation a96 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Upsample u97 (&net, 2);
|
||||
|
||||
tk::dnn::Layer *m98_layers[2] = { &u97, &s36 };
|
||||
tk::dnn::Route m98 (&net, m98_layers, 2);
|
||||
tk::dnn::Conv2d c99 (&net, 128, 1, 1, 1, 1, 0, 0, c99_bin, true);
|
||||
tk::dnn::Activation a99 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c100 (&net, 256, 3, 3, 1, 1, 1, 1, c100_bin, true);
|
||||
tk::dnn::Activation a100 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c101 (&net, 128, 1, 1, 1, 1, 0, 0, c101_bin, true);
|
||||
tk::dnn::Activation a101 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c102 (&net, 256, 3, 3, 1, 1, 1, 1, c102_bin, true);
|
||||
tk::dnn::Activation a102 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c103 (&net, 128, 1, 1, 1, 1, 0, 0, c103_bin, true);
|
||||
tk::dnn::Activation a103 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
|
||||
tk::dnn::Conv2d c104 (&net, 256, 3, 3, 1, 1, 1, 1, c104_bin, true);
|
||||
tk::dnn::Activation a104 (&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Conv2d c105 (&net, preYoloFilters, 1, 1, 1, 1, 0, 0, c105_bin, false);
|
||||
tk::dnn::Yolo yolo2 (&net, classes, 3, g106_bin);
|
||||
|
||||
yolo[0] = &yolo0;
|
||||
yolo[1] = &yolo1;
|
||||
yolo[2] = &yolo2;
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
activationLEAKYForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
|
||||
reinterpret_cast<dnnType*>(outputs[0]), size, stream);
|
||||
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,8 +52,9 @@ public:
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, size);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int size;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include<cassert>
|
||||
#include "../kernels.h"
|
||||
|
||||
class ActivationLogisticRT : public IPlugin {
|
||||
|
||||
public:
|
||||
ActivationLogisticRT() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
~ActivationLogisticRT(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return inputs[0];
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
size = 1;
|
||||
for(int i=0; i<outputDims[0].nbDims; i++)
|
||||
size *= outputDims[0].d[i];
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
activationLOGISTICForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
|
||||
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 1*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
tk::dnn::writeBUF(buf, size);
|
||||
}
|
||||
|
||||
int size;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
#include<cassert>
|
||||
#include "../kernels.h"
|
||||
|
||||
class ActivationMishRT : public IPlugin {
|
||||
|
||||
public:
|
||||
ActivationMishRT() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
~ActivationMishRT(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return inputs[0];
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
size = 1;
|
||||
for(int i=0; i<outputDims[0].nbDims; i++)
|
||||
size *= outputDims[0].d[i];
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
activationMishForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
|
||||
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 1*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, size);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int size;
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
#include<cassert>
|
||||
#include "../kernels.h"
|
||||
|
||||
class ActivationReLUCeiling : public IPlugin {
|
||||
|
||||
public:
|
||||
ActivationReLUCeiling(const float ceiling) {
|
||||
this->ceiling = ceiling;
|
||||
}
|
||||
|
||||
~ActivationReLUCeiling(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return inputs[0];
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
size = 1;
|
||||
for(int i=0; i<outputDims[0].nbDims; i++)
|
||||
size *= outputDims[0].d[i];
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
activationReLUCeilingForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
|
||||
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, ceiling, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 1*sizeof(int) + 1*sizeof(float);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, ceiling);
|
||||
tk::dnn::writeBUF(buf, size);
|
||||
assert(buf = a + getSerializationSize());
|
||||
|
||||
}
|
||||
|
||||
int size;
|
||||
float ceiling;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
#include<cassert>
|
||||
#include "../kernels.h"
|
||||
|
||||
class ActivationSigmoidRT : public IPlugin {
|
||||
|
||||
public:
|
||||
ActivationSigmoidRT() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
~ActivationSigmoidRT(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return inputs[0];
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
size = 1;
|
||||
for(int i=0; i<outputDims[0].nbDims; i++)
|
||||
size *= outputDims[0].d[i];
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
activationSIGMOIDForward((dnnType*)reinterpret_cast<const dnnType*>(inputs[0]),
|
||||
reinterpret_cast<dnnType*>(outputs[0]), batchSize*size, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 1*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, size);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int size;
|
||||
};
|
||||
@@ -12,12 +12,6 @@ public:
|
||||
int o_n, int o_c, int o_h, int o_w,
|
||||
tk::dnn::DeformConv2d *deformable = nullptr) {
|
||||
this->chunk_dim = chunk_dim;
|
||||
// int dst_dim = conv_dim.tot();
|
||||
// std::cout<<"conv_dim: \n";
|
||||
// conv_dim.print();
|
||||
// if (dst_dim % 3 != 0 )
|
||||
// std::cout<<"take attention\n\n";
|
||||
// this->chunk_dim = dst_dim/3;
|
||||
this->kh = kh;
|
||||
this->kw = kw;
|
||||
this->sh = sh;
|
||||
@@ -52,10 +46,19 @@ public:
|
||||
checkCuda( cudaMemcpy(mask, deformable->mask, sizeof(dnnType)*chunk_dim, cudaMemcpyDeviceToDevice) );
|
||||
checkCuda( cudaMemcpy(ones_d2, deformable->ones_d2, sizeof(dnnType)*dim_ones, cudaMemcpyDeviceToDevice) );
|
||||
}
|
||||
stat = cublasCreate(&handle);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS)
|
||||
FatalError("CUBLAS initialization failed\n");
|
||||
}
|
||||
|
||||
~DeformableConvRT(){
|
||||
|
||||
~DeformableConvRT() {
|
||||
checkCuda( cudaFree(data_d) );
|
||||
checkCuda( cudaFree(bias2_d) );
|
||||
checkCuda( cudaFree(ones_d1) );
|
||||
checkCuda( cudaFree(offset) );
|
||||
checkCuda( cudaFree(mask) );
|
||||
checkCuda( cudaFree(ones_d2) );
|
||||
cublasDestroy(handle);
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
@@ -66,54 +69,43 @@ public:
|
||||
return DimsCHW{defRT->output_dim.c, defRT->output_dim.h, defRT->output_dim.w};
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
// i_n = 1;
|
||||
// i_c = inputDims[0].d[0];
|
||||
// i_h = inputDims[0].d[1];
|
||||
// i_w = inputDims[0].d[2];
|
||||
// o_n = 1;
|
||||
// o_c = outputDims[0].d[0];
|
||||
// o_h = outputDims[0].d[1];
|
||||
// o_w = outputDims[0].d[2];
|
||||
}
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override { }
|
||||
|
||||
int initialize() override {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
virtual void terminate() override { }
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
std::cout<<"LOL\n";
|
||||
dnnType *srcData = (dnnType*)reinterpret_cast<const dnnType*>(inputs[0]);
|
||||
dnnType *output_conv = (dnnType*)reinterpret_cast<const dnnType*>(inputs[1]);
|
||||
|
||||
// split conv2d outputs into offset to mask
|
||||
checkCuda(cudaMemcpy(offset, output_conv, 2*chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
checkCuda(cudaMemcpy(mask, output_conv + 2*chunk_dim, chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
// kernel sigmoide
|
||||
activationSIGMOIDForward(mask, mask, chunk_dim);
|
||||
|
||||
// deformable convolution
|
||||
dcn_v2_cuda_forward(srcData, data_d,
|
||||
bias2_d, ones_d1,
|
||||
offset, mask,
|
||||
reinterpret_cast<dnnType*>(outputs[0]), ones_d2,
|
||||
kh, kw,
|
||||
sh, sw,
|
||||
ph, pw,
|
||||
1, 1,
|
||||
deformableGroup,
|
||||
i_n, i_c, i_h, i_w,
|
||||
o_n, o_c, o_h, o_w,
|
||||
chunk_dim);
|
||||
|
||||
for(int b=0; b<batchSize; b++) {
|
||||
checkCuda(cudaMemcpy(offset, output_conv + b * 3 * chunk_dim, 2*chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
checkCuda(cudaMemcpy(mask, output_conv + b * 3 * chunk_dim + 2*chunk_dim, chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
// kernel sigmoid
|
||||
activationSIGMOIDForward(mask, mask, chunk_dim);
|
||||
// deformable convolution
|
||||
dcnV2CudaForward(stat, handle,
|
||||
srcData, data_d,
|
||||
bias2_d, ones_d1,
|
||||
offset, mask,
|
||||
reinterpret_cast<dnnType*>(outputs[0]), ones_d2,
|
||||
kh, kw,
|
||||
sh, sw,
|
||||
ph, pw,
|
||||
1, 1,
|
||||
deformableGroup, b,
|
||||
i_n, i_c, i_h, i_w,
|
||||
o_n, o_c, o_h, o_w,
|
||||
chunk_dim);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,7 +116,7 @@ std::cout<<"LOL\n";
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, chunk_dim);
|
||||
tk::dnn::writeBUF(buf, kh);
|
||||
tk::dnn::writeBUF(buf, kw);
|
||||
@@ -171,8 +163,11 @@ std::cout<<"LOL\n";
|
||||
for(int i=0; i<dim_ones; i++)
|
||||
tk::dnn::writeBUF(buf, aus[i]);
|
||||
free(aus);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
int i_n, i_c, i_h, i_w;
|
||||
int o_n, o_c, o_h, o_w;
|
||||
int size;
|
||||
@@ -191,6 +186,10 @@ std::cout<<"LOL\n";
|
||||
dnnType * offset;
|
||||
dnnType * mask;
|
||||
dnnType *ones_d2;
|
||||
// dnnType *input_n;
|
||||
// dnnType *offset_n;
|
||||
// dnnType *mask_n;
|
||||
// dnnType *output_n;
|
||||
|
||||
|
||||
tk::dnn::DeformConv2d *defRT;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include<cassert>
|
||||
|
||||
class FlattenConcatRT : public IPlugin {
|
||||
|
||||
public:
|
||||
FlattenConcatRT() {
|
||||
stat = cublasCreate(&handle);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf ("CUBLAS initialization failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
~FlattenConcatRT(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return DimsCHW{ inputs[0].d[0] * inputs[0].d[1] * inputs[0].d[2], 1, 1};
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
assert(nbOutputs == 1 && nbInputs ==1);
|
||||
rows = inputDims[0].d[0];
|
||||
cols = inputDims[0].d[1] * inputDims[0].d[2];
|
||||
c = inputDims[0].d[0] * inputDims[0].d[1] * inputDims[0].d[2];
|
||||
h = 1;
|
||||
w = 1;
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
checkERROR(cublasDestroy(handle));
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
dnnType *srcData = (dnnType*)reinterpret_cast<const dnnType*>(inputs[0]);
|
||||
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
|
||||
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*rows*cols*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
|
||||
checkERROR( cublasSetStream(handle, stream) );
|
||||
for(int i=0; i<batchSize; i++) {
|
||||
float const alpha(1.0);
|
||||
float const beta(0.0);
|
||||
int offset = i*rows*cols;
|
||||
checkERROR( cublasSgeam( handle, CUBLAS_OP_T, CUBLAS_OP_N, rows, cols, &alpha, srcData + offset, cols, &beta, srcData + offset, rows, dstData + offset, rows ));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 5*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a = buf;
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
tk::dnn::writeBUF(buf, rows);
|
||||
tk::dnn::writeBUF(buf, cols);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int c, h, w;
|
||||
int rows, cols;
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
#include<cassert>
|
||||
#include "../kernels.h"
|
||||
|
||||
class MaxPoolFixedSizeRT : public IPlugin {
|
||||
|
||||
public:
|
||||
MaxPoolFixedSizeRT(int c, int h, int w, int n, int strideH, int strideW, int winSize, int padding) {
|
||||
this->c = c;
|
||||
this->h = h;
|
||||
this->w = w;
|
||||
this->n = n;
|
||||
this->stride_H = strideH;
|
||||
this->stride_W = strideW;
|
||||
this->winSize = winSize;
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
~MaxPoolFixedSizeRT(){
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return DimsCHW{this->c, this->h, this->w};
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
//std::cout<<this->n<<" "<<this->c<<" "<<this->h<<" "<<this->w<<" "<<this->stride_H<<" "<<this->stride_W<<" "<<this->winSize<<" "<<this->padding<<std::endl;
|
||||
dnnType *srcData = (dnnType*)reinterpret_cast<const dnnType*>(inputs[0]);
|
||||
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
|
||||
MaxPoolingForward(srcData, dstData, batchSize, this->c, this->h, this->w, this->stride_H, this->stride_W, this->winSize, this->padding, stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 8*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
|
||||
tk::dnn::writeBUF(buf, this->c);
|
||||
tk::dnn::writeBUF(buf, this->h);
|
||||
tk::dnn::writeBUF(buf, this->w);
|
||||
tk::dnn::writeBUF(buf, this->n);
|
||||
tk::dnn::writeBUF(buf, this->stride_H);
|
||||
tk::dnn::writeBUF(buf, this->stride_W);
|
||||
tk::dnn::writeBUF(buf, this->winSize);
|
||||
tk::dnn::writeBUF(buf, this->padding);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int n, c, h, w;
|
||||
int stride_H, stride_W;
|
||||
int winSize;
|
||||
int padding;
|
||||
};
|
||||
@@ -50,18 +50,18 @@ public:
|
||||
|
||||
for (int b = 0; b < batchSize; ++b){
|
||||
for(int n = 0; n < num; ++n){
|
||||
int index = entry_index(b, n*w*h, 0, batchSize);
|
||||
int index = entry_index(b, n*w*h, 0);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, 2*w*h, stream);
|
||||
|
||||
index = entry_index(b, n*w*h, coords, batchSize);
|
||||
index = entry_index(b, n*w*h, coords);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, w*h, stream);
|
||||
}
|
||||
}
|
||||
|
||||
//softmax start
|
||||
int index = entry_index(0, 0, coords + 1, batchSize);
|
||||
int index = entry_index(0, 0, coords + 1);
|
||||
softmaxForward( srcData + index, classes, batchSize*num,
|
||||
(batchSize*c*h*w)/num,
|
||||
(c*h*w)/num,
|
||||
w*h, 1, w*h, 1, dstData + index, stream);
|
||||
|
||||
return 0;
|
||||
@@ -73,22 +73,23 @@ public:
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, classes);
|
||||
tk::dnn::writeBUF(buf, coords);
|
||||
tk::dnn::writeBUF(buf, num);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int c, h, w;
|
||||
int classes, coords, num;
|
||||
|
||||
int entry_index(int batch, int location, int entry, int batchSize) {
|
||||
int entry_index(int batch, int location, int entry) {
|
||||
int n = location / (w*h);
|
||||
int loc = location % (w*h);
|
||||
return batch*c*h*w*batchSize + n*w*h*(coords+classes+1) + entry*w*h + loc;
|
||||
return batch*c*h*w + n*w*h*(coords+classes+1) + entry*w*h + loc;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -52,11 +52,12 @@ public:
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, stride);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int c, h, w, stride;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include<cassert>
|
||||
|
||||
class ReshapeRT : public IPlugin {
|
||||
|
||||
public:
|
||||
ReshapeRT(dataDim_t new_dim) {
|
||||
n = new_dim.n;
|
||||
c = new_dim.c;
|
||||
h = new_dim.h;
|
||||
w = new_dim.w;
|
||||
}
|
||||
|
||||
~ReshapeRT(){
|
||||
|
||||
}
|
||||
|
||||
int getNbOutputs() const override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
return DimsCHW{ c,h,w};
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void terminate() override {
|
||||
}
|
||||
|
||||
virtual size_t getWorkspaceSize(int maxBatchSize) const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
dnnType *srcData = (dnnType*)reinterpret_cast<const dnnType*>(inputs[0]);
|
||||
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
|
||||
|
||||
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 4*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a = buf;
|
||||
tk::dnn::writeBUF(buf, n);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int n, c, h, w;
|
||||
};
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
|
||||
tk::dnn::writeBUF(buf, o_c);
|
||||
tk::dnn::writeBUF(buf, o_h);
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
tk::dnn::writeBUF(buf, i_c);
|
||||
tk::dnn::writeBUF(buf, i_h);
|
||||
tk::dnn::writeBUF(buf, i_w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int i_c, i_h, i_w, o_c, o_h, o_w;
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
|
||||
class RouteRT : public IPlugin {
|
||||
|
||||
/**
|
||||
THIS IS NOT USED ANYMORE
|
||||
*/
|
||||
|
||||
public:
|
||||
RouteRT() {
|
||||
RouteRT(int groups, int group_id) {
|
||||
this->groups = groups;
|
||||
this->group_id = group_id;
|
||||
}
|
||||
|
||||
~RouteRT(){
|
||||
@@ -18,7 +24,7 @@ public:
|
||||
Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override {
|
||||
int out_c = 0;
|
||||
for(int i=0; i<nbInputDims; i++) out_c += inputs[i].d[0];
|
||||
return DimsCHW{out_c, inputs[0].d[1], inputs[0].d[2]};
|
||||
return DimsCHW{out_c/groups, inputs[0].d[1], inputs[0].d[2]};
|
||||
}
|
||||
|
||||
void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override {
|
||||
@@ -30,6 +36,7 @@ public:
|
||||
}
|
||||
h = inputDims[0].d[1];
|
||||
w = inputDims[0].d[2];
|
||||
c /= groups;
|
||||
}
|
||||
|
||||
int initialize() override {
|
||||
@@ -45,15 +52,18 @@ public:
|
||||
}
|
||||
|
||||
virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override {
|
||||
|
||||
|
||||
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
|
||||
|
||||
int offset = 0;
|
||||
for(int i=0; i<in; i++) {
|
||||
dnnType *input = (dnnType*)reinterpret_cast<const dnnType*>(inputs[i]);
|
||||
int in_dim = c_in[i]*h*w;
|
||||
checkCuda( cudaMemcpyAsync(dstData + offset, input, in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream) );
|
||||
offset += in_dim;
|
||||
for(int b=0; b<batchSize; b++) {
|
||||
int offset = 0;
|
||||
for(int i=0; i<in; i++) {
|
||||
dnnType *input = (dnnType*)reinterpret_cast<const dnnType*>(inputs[i]);
|
||||
int in_dim = c_in[i]*h*w;
|
||||
int part_in_dim = in_dim / this->groups;
|
||||
checkCuda( cudaMemcpyAsync(dstData + b*c*w*h + offset, input + b*c*w*h*groups + this->group_id*part_in_dim, part_in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream) );
|
||||
offset += part_in_dim;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -61,11 +71,13 @@ public:
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return (4+MAX_INPUTS)*sizeof(int);
|
||||
return (6+MAX_INPUTS)*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, groups);
|
||||
tk::dnn::writeBUF(buf, group_id);
|
||||
tk::dnn::writeBUF(buf, in);
|
||||
for(int i=0; i<MAX_INPUTS; i++)
|
||||
tk::dnn::writeBUF(buf, c_in[i]);
|
||||
@@ -73,10 +85,12 @@ public:
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
static const int MAX_INPUTS = 4;
|
||||
int in;
|
||||
int c_in[MAX_INPUTS];
|
||||
int c, h, w;
|
||||
int groups, group_id;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
class ShortcutRT : public IPlugin {
|
||||
|
||||
public:
|
||||
ShortcutRT() {
|
||||
ShortcutRT(tk::dnn::dataDim_t bdim) {
|
||||
this->bc = bdim.c;
|
||||
this->bh = bdim.h;
|
||||
this->bw = bdim.w;
|
||||
}
|
||||
|
||||
~ShortcutRT(){
|
||||
@@ -44,22 +47,29 @@ public:
|
||||
dnnType *dstData = reinterpret_cast<dnnType*>(outputs[0]);
|
||||
|
||||
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
shortcutForward(srcDataBack, dstData, batchSize, c, h, w, 1, batchSize, c, h, w, 1, stream);
|
||||
for(int b=0; b < batchSize; ++b)
|
||||
shortcutForward(srcDataBack + b*bc*bh*bw, dstData + b*c*h*w, 1, c, h, w, 1, 1, bc, bh, bw, 1, stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 3*sizeof(int);
|
||||
return 6*sizeof(int);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, bc);
|
||||
tk::dnn::writeBUF(buf, bh);
|
||||
tk::dnn::writeBUF(buf, bw);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
|
||||
}
|
||||
|
||||
int c, h, w;
|
||||
int bc, bh, bw;
|
||||
};
|
||||
|
||||
@@ -54,11 +54,12 @@ public:
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, stride);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int c, h, w, stride;
|
||||
|
||||
@@ -8,11 +8,15 @@ class YoloRT : public IPlugin {
|
||||
|
||||
|
||||
public:
|
||||
YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr, int n_masks=3) {
|
||||
YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr, int n_masks=3, float scale_xy=1, float nms_thresh=0.45, int nms_kind=0, int new_coords=0) {
|
||||
|
||||
this->classes = classes;
|
||||
this->num = num;
|
||||
this->n_masks = n_masks;
|
||||
this->scaleXY = scale_xy;
|
||||
this->nms_thresh = nms_thresh;
|
||||
this->nms_kind = nms_kind;
|
||||
this->new_coords = new_coords;
|
||||
|
||||
mask = new dnnType[n_masks];
|
||||
bias = new dnnType[num*n_masks*2];
|
||||
@@ -60,15 +64,23 @@ public:
|
||||
|
||||
checkCuda( cudaMemcpyAsync(dstData, srcData, batchSize*c*h*w*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
|
||||
for (int b = 0; b < batchSize; ++b){
|
||||
for(int n = 0; n < n_masks; ++n){
|
||||
int index = entry_index(b, n*w*h, 0, batchSize);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, 2*w*h, stream);
|
||||
|
||||
index = entry_index(b, n*w*h, 4, batchSize);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, stream);
|
||||
}
|
||||
}
|
||||
|
||||
for (int b = 0; b < batchSize; ++b){
|
||||
for(int n = 0; n < n_masks; ++n){
|
||||
int index = entry_index(b, n*w*h, 0);
|
||||
if (new_coords == 1){
|
||||
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
|
||||
}
|
||||
else{
|
||||
activationLOGISTICForward(srcData + index, dstData + index, 2*w*h, stream); //x,y
|
||||
|
||||
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * w*h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
|
||||
|
||||
index = entry_index(b, n*w*h, 4);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*w*h, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//std::cout<<"YOLO END\n";
|
||||
return 0;
|
||||
@@ -76,21 +88,29 @@ public:
|
||||
|
||||
|
||||
virtual size_t getSerializationSize() override {
|
||||
return 6*sizeof(int) + n_masks*sizeof(dnnType) + num*n_masks*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char);
|
||||
return 8*sizeof(int) + 2*sizeof(float)+ n_masks*sizeof(dnnType) + num*n_masks*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char);
|
||||
}
|
||||
|
||||
virtual void serialize(void* buffer) override {
|
||||
char *buf = reinterpret_cast<char*>(buffer);
|
||||
tk::dnn::writeBUF(buf, classes);
|
||||
tk::dnn::writeBUF(buf, num);
|
||||
tk::dnn::writeBUF(buf, n_masks);
|
||||
tk::dnn::writeBUF(buf, c);
|
||||
tk::dnn::writeBUF(buf, h);
|
||||
tk::dnn::writeBUF(buf, w);
|
||||
for(int i=0; i<n_masks; i++)
|
||||
tk::dnn::writeBUF(buf, mask[i]);
|
||||
for(int i=0; i<n_masks*2*num; i++)
|
||||
tk::dnn::writeBUF(buf, bias[i]);
|
||||
char *buf = reinterpret_cast<char*>(buffer),*a=buf;
|
||||
tk::dnn::writeBUF(buf, classes); //std::cout << "Classes :" << classes << std::endl;
|
||||
tk::dnn::writeBUF(buf, num); //std::cout << "Num : " << num << std::endl;
|
||||
tk::dnn::writeBUF(buf, n_masks); //std::cout << "N_Masks" << n_masks << std::endl;
|
||||
tk::dnn::writeBUF(buf, scaleXY); //std::cout << "ScaleXY :" << scaleXY << std::endl;
|
||||
tk::dnn::writeBUF(buf, nms_thresh); //std::cout << "nms_thresh :" << nms_thresh << std::endl;
|
||||
tk::dnn::writeBUF(buf, nms_kind); //std::cout << "nms_kind : " << nms_kind << std::endl;
|
||||
tk::dnn::writeBUF(buf, new_coords); //std::cout << "new_coords : " << new_coords << std::endl;
|
||||
tk::dnn::writeBUF(buf, c); //std::cout << "C : " << c << std::endl;
|
||||
tk::dnn::writeBUF(buf, h); //std::cout << "H : " << h << std::endl;
|
||||
tk::dnn::writeBUF(buf, w); //std::cout << "C : " << c << std::endl;
|
||||
for (int i = 0; i < n_masks; i++)
|
||||
{
|
||||
tk::dnn::writeBUF(buf, mask[i]); //std::cout << "mask[i] : " << mask[i] << std::endl;
|
||||
}
|
||||
for (int i = 0; i < n_masks * 2 * num; i++)
|
||||
{
|
||||
tk::dnn::writeBUF(buf, bias[i]); //std::cout << "bias[i] : " << bias[i] << std::endl;
|
||||
}
|
||||
|
||||
// save classes names
|
||||
for(int i=0; i<classes; i++) {
|
||||
@@ -100,19 +120,24 @@ public:
|
||||
tk::dnn::writeBUF(buf, tmp[j]);
|
||||
}
|
||||
}
|
||||
assert(buf == a + getSerializationSize());
|
||||
}
|
||||
|
||||
int c, h, w;
|
||||
int classes, num, n_masks;
|
||||
float scaleXY;
|
||||
float nms_thresh;
|
||||
int nms_kind;
|
||||
int new_coords;
|
||||
std::vector<std::string> classesNames;
|
||||
|
||||
dnnType *mask;
|
||||
dnnType *bias;
|
||||
|
||||
int entry_index(int batch, int location, int entry, int batchSize) {
|
||||
int entry_index(int batch, int location, int entry) {
|
||||
int n = location / (w*h);
|
||||
int loc = location % (w*h);
|
||||
return batch*c*h*w*batchSize + n*w*h*(4+classes+1) + entry*w*h + loc;
|
||||
return batch*c*h*w + n*w*h*(4+classes+1) + entry*w*h + loc;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
#ifndef STDAFX_H_INCLUDED
|
||||
#define STDAFX_H_INCLUDED
|
||||
#define BOOST_LOG_DYN_LINK 1
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "cpprest/json.h"
|
||||
#include "cpprest/http_listener.h"
|
||||
#include "cpprest/uri.h"
|
||||
#include "cpprest/asyncrt_utils.h"
|
||||
#include "cpprest/json.h"
|
||||
#include "cpprest/filestream.h"
|
||||
#include "cpprest/containerstream.h"
|
||||
#include "cpprest/producerconsumerstream.h"
|
||||
|
||||
#include <boost/log/core.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/asio/ip/host_name.hpp>
|
||||
|
||||
#pragma warning ( push )
|
||||
#pragma warning ( disable : 4457 )
|
||||
#pragma warning ( pop )
|
||||
#include <locale>
|
||||
#include <ctime>
|
||||
#endif // STDAFX_H_INCLUDED
|
||||
@@ -0,0 +1,78 @@
|
||||
|
||||
#include <tkdnn.h>
|
||||
int testInference(std::vector<std::string> input_bins, std::vector<std::string> output_bins,
|
||||
tk::dnn::Network *net, tk::dnn::NetworkRT *netRT = nullptr) {
|
||||
|
||||
std::vector<tk::dnn::Layer*> outputs;
|
||||
for(int i=0; i<net->num_layers; i++) {
|
||||
if(net->layers[i]->final)
|
||||
outputs.push_back(net->layers[i]);
|
||||
}
|
||||
// no final layers, set last as output
|
||||
if(outputs.size() == 0) {
|
||||
outputs.push_back(net->layers[net->num_layers-1]);
|
||||
}
|
||||
|
||||
|
||||
// check input
|
||||
if(input_bins.size() != 1) {
|
||||
FatalError("currently support only 1 input");
|
||||
}
|
||||
if(output_bins.size() != outputs.size()) {
|
||||
std::cout<<output_bins.size()<<" "<<outputs.size()<<"\n";
|
||||
FatalError("outputs size mismatch");
|
||||
}
|
||||
|
||||
// Load input
|
||||
dnnType *data;
|
||||
dnnType *input_h;
|
||||
readBinaryFile(input_bins[0], net->input_dim.tot(), &input_h, &data);
|
||||
|
||||
// outputs
|
||||
//dnnType *cudnn_out[outputs.size()], *rt_out[outputs.size()];
|
||||
std::vector<dnnType *> cudnn_out,rt_out;
|
||||
|
||||
tk::dnn::dataDim_t dim1 = net->input_dim; //input dim
|
||||
printCenteredTitle(" CUDNN inference ", '=', 30); {
|
||||
dim1.print();
|
||||
TKDNN_TSTART
|
||||
net->infer(dim1, data);
|
||||
TKDNN_TSTOP
|
||||
dim1.print();
|
||||
}
|
||||
for(int i=0; i<outputs.size(); i++) cudnn_out.push_back(outputs[i]->dstData);
|
||||
|
||||
if(netRT != nullptr) {
|
||||
tk::dnn::dataDim_t dim2 = net->input_dim;
|
||||
printCenteredTitle(" TENSORRT inference ", '=', 30); {
|
||||
dim2.print();
|
||||
TKDNN_TSTART
|
||||
netRT->infer(dim2, data);
|
||||
TKDNN_TSTOP
|
||||
dim2.print();
|
||||
}
|
||||
for(int i=0; i<outputs.size(); i++) rt_out.push_back((dnnType*)netRT->buffersRT[i+1]);
|
||||
}
|
||||
|
||||
int ret_cudnn = 0, ret_tensorrt = 0, ret_cudnn_tensorrt = 0;
|
||||
for(int i=0; i<outputs.size(); i++) {
|
||||
printCenteredTitle((std::string(" OUTPUT ") + std::to_string(i) + " CHECK RESULTS ").c_str(), '=', 30);
|
||||
dnnType *out, *out_h;
|
||||
int odim = outputs[i]->output_dim.tot();
|
||||
readBinaryFile(output_bins[i], odim, &out_h, &out);
|
||||
std::cout<<"CUDNN vs correct";
|
||||
ret_cudnn |= checkResult(odim, cudnn_out[i], out) == 0 ? 0: ERROR_CUDNN;
|
||||
if(netRT != nullptr) {
|
||||
std::cout<<"TRT vs correct";
|
||||
ret_tensorrt |= checkResult(odim, rt_out[i], out) == 0 ? 0 : ERROR_TENSORRT;
|
||||
std::cout<<"CUDNN vs TRT ";
|
||||
ret_cudnn_tensorrt |= checkResult(odim, cudnn_out[i], rt_out[i]) == 0 ? 0 : ERROR_CUDNNvsTENSORRT;
|
||||
}
|
||||
|
||||
delete [] out_h;
|
||||
checkCuda( cudaFree(out) );
|
||||
}
|
||||
delete [] input_h;
|
||||
checkCuda( cudaFree(data) );
|
||||
return ret_cudnn | ret_tensorrt | ret_cudnn_tensorrt;
|
||||
}
|
||||
@@ -5,4 +5,4 @@
|
||||
#include "Layer.h"
|
||||
#include "NetworkRT.h"
|
||||
|
||||
#define TKDNN_VERSION 300
|
||||
#define TKDNN_VERSION 500
|
||||
|
||||
+43
-7
@@ -12,8 +12,17 @@
|
||||
#include <cublas_v2.h>
|
||||
#include <cudnn.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <ios>
|
||||
#include <chrono>
|
||||
|
||||
|
||||
#define dnnType float
|
||||
|
||||
|
||||
// Colored output
|
||||
#define COL_END "\033[0m"
|
||||
|
||||
@@ -31,16 +40,27 @@
|
||||
#define COL_PURPLEB "\033[1;35m"
|
||||
#define COL_CYANB "\033[1;36m"
|
||||
|
||||
#define TKDNN_VERBOSE 0
|
||||
|
||||
// Simple Timer
|
||||
#define TIMER_START timespec start, end; \
|
||||
#ifdef __linux__
|
||||
#define TKDNN_TSTART timespec start, end; \
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
|
||||
#define TIMER_STOP_C(col) clock_gettime(CLOCK_MONOTONIC, &end); \
|
||||
#define TKDNN_TSTOP_C(col, show) clock_gettime(CLOCK_MONOTONIC, &end); \
|
||||
double t_ns = ((double)(end.tv_sec - start.tv_sec) * 1.0e9 + \
|
||||
(double)(end.tv_nsec - start.tv_nsec))/1.0e6; \
|
||||
std::cout<<col<<"Time:"<<std::setw(16)<<t_ns<<" ms\n"<<COL_END;
|
||||
if(show) std::cout<<col<<"Time:"<<std::setw(16)<<t_ns<<" ms\n"<<COL_END;
|
||||
|
||||
#define TKDNN_TSTOP TKDNN_TSTOP_C(COL_CYANB, TKDNN_VERBOSE)
|
||||
#elif _WIN32
|
||||
#define TKDNN_TSTART auto start = std::chrono::high_resolution_clock::now();
|
||||
#define TKDNN_TSTOP auto stop = std::chrono::high_resolution_clock::now(); \
|
||||
std::chrono::duration<double> duration = stop -start; \
|
||||
auto time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);\
|
||||
double t_ns = time_ms.count();
|
||||
#endif
|
||||
|
||||
#define TIMER_STOP TIMER_STOP_C(COL_CYANB)
|
||||
|
||||
/********************************************************
|
||||
* Prints the error message, and exits
|
||||
@@ -88,15 +108,31 @@
|
||||
} \
|
||||
}
|
||||
|
||||
void printCenteredTitle(const char *title, char fill, int dim);
|
||||
typedef enum {
|
||||
ERROR_CUDNN = 2,
|
||||
ERROR_TENSORRT = 4,
|
||||
ERROR_CUDNNvsTENSORRT = 8
|
||||
} resultError_t;
|
||||
|
||||
void printCenteredTitle(const char *title, char fill, int dim = 30);
|
||||
bool fileExist(const char *fname);
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0, bool skipLoad = false);
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device = true);
|
||||
void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string& test_folder, const std::string& weights_url);
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0);
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device = true, int limit = 10);
|
||||
void printDeviceVector(int size, dnnType* vec_d, bool device = true);
|
||||
float getColor(const int c, const int x, const int max);
|
||||
void resize(int size, dnnType **data);
|
||||
|
||||
void matrixTranspose(cublasHandle_t handle, dnnType* srcData, dnnType* dstData, int rows, int cols);
|
||||
|
||||
void matrixMulAdd( cublasHandle_t handle, dnnType* srcData, dnnType* dstData,
|
||||
dnnType* add_vector, int dim, dnnType mul);
|
||||
|
||||
void getMemUsage(double& vm_usage_kb, double& resident_set_kb);
|
||||
void printCudaMemUsage();
|
||||
void removePathAndExtension(const std::string &full_string, std::string &name);
|
||||
static inline bool isCudaPointer(void *data) {
|
||||
cudaPointerAttributes attr;
|
||||
return cudaPointerGetAttributes(&attr, data) == 0;
|
||||
}
|
||||
#endif //UTILS_H
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "handler.h"
|
||||
using namespace std;
|
||||
using namespace web;
|
||||
using namespace http;
|
||||
using namespace utility;
|
||||
using namespace http::experimental::listener;
|
||||
|
||||
namespace logging = boost::log;
|
||||
namespace keywords = boost::log::keywords;
|
||||
|
||||
std::unique_ptr<handler> g_httpHandler;
|
||||
|
||||
string get_file_name(string path)
|
||||
{
|
||||
return path.substr(path.find_last_of("/\\")+1);
|
||||
}
|
||||
|
||||
void init_logging()
|
||||
{
|
||||
logging::register_simple_formatter_factory<logging::trivial::severity_level, char>("Severity");
|
||||
|
||||
auto host_name = boost::asio::ip::host_name();
|
||||
string logFileName = "server_" + string(host_name) + ".log";
|
||||
|
||||
logging::add_file_log(
|
||||
keywords::file_name = "/home/baggageai/log/"+logFileName,
|
||||
keywords::format = "BAI-[%LineID%] [%TimeStamp%] [%Severity%] %Message%",
|
||||
keywords::auto_flush = true
|
||||
);
|
||||
|
||||
logging::core::get()->set_filter
|
||||
(
|
||||
logging::trivial::severity >= logging::trivial::info
|
||||
);
|
||||
|
||||
logging::add_common_attributes();
|
||||
}
|
||||
|
||||
void on_initialize(const string_t& address)
|
||||
{
|
||||
uri_builder uri(address);
|
||||
|
||||
try
|
||||
{
|
||||
auto addr = uri.to_uri().to_string();
|
||||
g_httpHandler = std::unique_ptr<handler>(new handler(addr));
|
||||
g_httpHandler->open().wait();
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "[" << get_file_name(string(__FILE__)) << " " << __LINE__ << "] " << "Listening for requests at: "+ string(addr);
|
||||
|
||||
while(true);
|
||||
}
|
||||
catch (exception const& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "[" << get_file_name(string(__FILE__)) << " " << __LINE__ << "] " << e.what();
|
||||
wcout << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void on_shutdown()
|
||||
{
|
||||
g_httpHandler->close().wait();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int wmain(int argc, wchar_t *argv[])
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
init_logging();
|
||||
handler::init_bag();
|
||||
utility::string_t port = U("8080");
|
||||
if(argc == 2)
|
||||
{
|
||||
port = argv[1];
|
||||
}
|
||||
|
||||
utility::string_t address = U("http://0.0.0.0:");
|
||||
address.append(port);
|
||||
|
||||
on_initialize(address);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
#Removing build folder of home directory to overcome overwriting issue
|
||||
if [ -d ~/"build/" ]; then
|
||||
rm -rf ~/build/
|
||||
fi
|
||||
|
||||
#Removing build folder of the project directory
|
||||
if [ -d "build/" ]; then
|
||||
rm -rf build/
|
||||
fi
|
||||
|
||||
mkdir build #build folder will be created and project will be build in that folder. If you want to make a folder with different name, then just change it.
|
||||
cd build #Name of the folder
|
||||
|
||||
#Building commands
|
||||
cmake ..
|
||||
make -j16
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" ../
|
||||
#cmake --build . --target BaggageAIApi -- -j4
|
||||
|
||||
#Running DemoApp application
|
||||
cd ..
|
||||
build/baggageAPI
|
||||
|
||||
+11
-2
@@ -5,10 +5,11 @@
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Activation::Activation(Network *net, int act_mode) :
|
||||
Activation::Activation(Network *net, int act_mode, const float ceiling) :
|
||||
Layer(net) {
|
||||
|
||||
this->act_mode = act_mode;
|
||||
this->ceiling = ceiling;
|
||||
checkCuda( cudaMalloc(&dstData, input_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
if(int(act_mode) < 100) {
|
||||
@@ -31,7 +32,7 @@ Activation::Activation(Network *net, int act_mode) :
|
||||
checkCUDNN( cudnnSetActivationDescriptor(activDesc,
|
||||
(cudnnActivationMode_t) act_mode,
|
||||
CUDNN_PROPAGATE_NAN,
|
||||
0.0) );
|
||||
ceiling) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +48,14 @@ dnnType* Activation::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
if(act_mode == ACTIVATION_LEAKY) {
|
||||
activationLEAKYForward(srcData, dstData, dim.tot());
|
||||
|
||||
}
|
||||
else if(act_mode == ACTIVATION_MISH) {
|
||||
activationMishForward(srcData, dstData, dim.tot());
|
||||
|
||||
}
|
||||
else if(act_mode == ACTIVATION_LOGISTIC) {
|
||||
activationLOGISTICForward(srcData, dstData, dim.tot());
|
||||
|
||||
} else {
|
||||
dnnType alpha = dnnType(1);
|
||||
dnnType beta = dnnType(0);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "BoundingBox.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
float BoundingBox::overlap(const float p1, const float d1, const float p2, const float d2){
|
||||
float l1 = p1 - d1/2;
|
||||
float l2 = p2 - d2/2;
|
||||
float left = l1 > l2 ? l1 : l2;
|
||||
float r1 = p1 + d1/2;
|
||||
float r2 = p2 + d2/2;
|
||||
float right = r1 < r2 ? r1 : r2;
|
||||
return right - left;
|
||||
}
|
||||
|
||||
float BoundingBox::boxesIntersection(const BoundingBox &b){
|
||||
float width = this->overlap(x, w, b.x, b.w);
|
||||
float height = this->overlap(y, h, b.y, b.h);
|
||||
if(width < 0 || height < 0)
|
||||
return 0;
|
||||
float area = width*height;
|
||||
return area;
|
||||
}
|
||||
|
||||
float BoundingBox::boxesUnion(const BoundingBox &b){
|
||||
float i = this->boxesIntersection(b);
|
||||
float u = w*h + b.w*b.h - i;
|
||||
return u;
|
||||
}
|
||||
|
||||
float BoundingBox::IoU(const BoundingBox &b){
|
||||
float I = this->boxesIntersection(b);
|
||||
float U = this->boxesUnion(b);
|
||||
if (I == 0 || U == 0)
|
||||
return 0;
|
||||
return I / U;
|
||||
}
|
||||
|
||||
void BoundingBox::clear(){
|
||||
uniqueTruthIndex = -1;
|
||||
truthFlag = 0;
|
||||
maxIoU = 0;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BoundingBox& bb){
|
||||
os <<"w: "<< bb.w << ", h: "<< bb.h << ", x: "<< bb.x << ", y: "<< bb.y <<
|
||||
", cat: "<< bb.cl << ", conf: "<< bb.prob<< ", truth: "<<
|
||||
bb.truthFlag<< ", assignedGT: "<< bb.uniqueTruthIndex<<
|
||||
", maxIoU: "<< bb.maxIoU<<"\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
bool boxComparison (const BoundingBox& a,const BoundingBox& b) {
|
||||
return (a.prob>b.prob);
|
||||
}
|
||||
|
||||
}}
|
||||
+226
-440
@@ -1,25 +1,18 @@
|
||||
#include "CenternetDetection.h"
|
||||
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
float __colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
|
||||
float get_color2(int c, int x, int max)
|
||||
{
|
||||
float ratio = ((float)x/max)*5;
|
||||
int i = floor(ratio);
|
||||
int j = ceil(ratio);
|
||||
ratio -= i;
|
||||
float r = (1-ratio) * __colors[i % 6][c % 3] + ratio*__colors[j % 6][c % 3];
|
||||
//printf("%f\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool CenternetDetection::init(std::string tensor_path) {
|
||||
bool CenternetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh){
|
||||
std::cout<<(tensor_path).c_str()<<"\n";
|
||||
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str() );
|
||||
|
||||
dim = tk::dnn::dataDim_t(1, 3, 224, 224, 1);
|
||||
const char *coco_class_name_[] = {
|
||||
classes = n_classes;
|
||||
nBatches = n_batches;
|
||||
confThreshold = conf_thresh;
|
||||
|
||||
dim = netRT->input_dim;
|
||||
|
||||
const char *coco_class_name[] = {
|
||||
"person", "bicycle", "car", "motorcycle", "airplane",
|
||||
"bus", "train", "truck", "boat", "traffic light", "fire hydrant",
|
||||
"stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse",
|
||||
@@ -34,18 +27,27 @@ bool CenternetDetection::init(std::string tensor_path) {
|
||||
"oven", "toaster", "sink", "refrigerator", "book", "clock", "vase",
|
||||
"scissors", "teddy bear", "hair drier", "toothbrush"
|
||||
};
|
||||
coco_class_name = std::vector<std::string>(coco_class_name_, std::end( coco_class_name_ ));
|
||||
classesNames = std::vector<std::string>(coco_class_name, std::end( coco_class_name));
|
||||
|
||||
for(int c=0; c<classes; c++) {
|
||||
int offset = c*123457 % classes;
|
||||
float r = getColor(2, offset, classes);
|
||||
float g = getColor(1, offset, classes);
|
||||
float b = getColor(0, offset, classes);
|
||||
colors[c] = cv::Scalar(int(255.0*b), int(255.0*g), int(255.0*r));
|
||||
}
|
||||
|
||||
src = cv::Mat(cv::Size(2,3), CV_32F);
|
||||
dst = cv::Mat(cv::Size(2,3), CV_32F);
|
||||
// dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes);
|
||||
dst2 = cv::Mat(cv::Size(2,3), CV_32F);
|
||||
trans = cv::Mat(cv::Size(3,2), CV_32F);
|
||||
trans2 = cv::Mat(cv::Size(3,2), CV_32F);
|
||||
|
||||
checkCuda(cudaMallocHost(&input_h, sizeof(dnnType)*netRT->input_dim.tot()));
|
||||
checkCuda(cudaMallocHost(&input, sizeof(dnnType)*netRT->input_dim.tot()));
|
||||
checkCuda(cudaMalloc(&input_d, sizeof(dnnType)*netRT->input_dim.tot()));
|
||||
checkCuda(cudaMalloc(&input_d, sizeof(dnnType)*netRT->input_dim.tot() * nBatches));
|
||||
|
||||
dim_hm = tk::dnn::dataDim_t(1, 80, 56, 56, 1);
|
||||
dim_wh = tk::dnn::dataDim_t(1, 2, 56, 56, 1);
|
||||
dim_reg = tk::dnn::dataDim_t(1, 2, 56, 56, 1);
|
||||
dim_hm = tk::dnn::dataDim_t(1, 80, 128, 128, 1);
|
||||
dim_wh = tk::dnn::dataDim_t(1, 2, 128, 128, 1);
|
||||
dim_reg = tk::dnn::dataDim_t(1, 2, 128, 128, 1);
|
||||
|
||||
checkCuda( cudaMalloc(&topk_scores, dim_hm.c * K *sizeof(float)) );
|
||||
checkCuda( cudaMalloc(&topk_inds_, dim_hm.c * K *sizeof(int)) );
|
||||
@@ -67,19 +69,16 @@ bool CenternetDetection::init(std::string tensor_path) {
|
||||
|
||||
checkCuda( cudaMallocHost(&scores, K *sizeof(float)) );
|
||||
checkCuda( cudaMalloc(&scores_d, K *sizeof(float)) );
|
||||
|
||||
checkCuda( cudaMallocHost(&clses, K *sizeof(int)) );
|
||||
checkCuda( cudaMalloc(&clses_d, K *sizeof(int)) );
|
||||
// checkCuda( cudaMallocHost(&topk_inds, K *sizeof(int)) );
|
||||
|
||||
checkCuda( cudaMalloc(&topk_inds_d, K *sizeof(int)) );
|
||||
checkCuda( cudaMalloc(&topk_ys_d, K *sizeof(float)) );
|
||||
checkCuda( cudaMalloc(&topk_xs_d, K *sizeof(float)) );
|
||||
// checkCuda( cudaMalloc(&intid, K *sizeof(int)) );
|
||||
checkCuda( cudaMalloc(&inttopk_ys_d, K *sizeof(int)) );
|
||||
checkCuda( cudaMalloc(&inttopk_xs_d, K *sizeof(int)) );
|
||||
|
||||
// checkCuda( cudaMalloc(&ids_d, dim_hm.c * K*sizeof(int)) );
|
||||
|
||||
// checkCuda( cudaMallocHost(&wh_aus, dim_wh.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMallocHost(&bbx0, K * sizeof(float)) );
|
||||
checkCuda( cudaMallocHost(&bby0, K * sizeof(float)) );
|
||||
checkCuda( cudaMallocHost(&bbx1, K * sizeof(float)) );
|
||||
@@ -91,469 +90,258 @@ bool CenternetDetection::init(std::string tensor_path) {
|
||||
|
||||
checkCuda( cudaMallocHost(&target_coords, 4 * K *sizeof(float)) );
|
||||
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
|
||||
checkCuda( cudaMalloc(&mean_d, 3 * sizeof(float)) );
|
||||
checkCuda( cudaMalloc(&stddev_d, 3 * sizeof(float)) );
|
||||
float mean[3] = {0.408, 0.447, 0.47};
|
||||
float stddev[3] = {0.289, 0.274, 0.278};
|
||||
|
||||
checkCuda(cudaMemcpy(mean_d, mean, 3*sizeof(float), cudaMemcpyHostToDevice));
|
||||
checkCuda(cudaMemcpy(stddev_d, stddev, 3*sizeof(float), cudaMemcpyHostToDevice));
|
||||
#else
|
||||
checkCuda(cudaMallocHost(&input, sizeof(dnnType)*netRT->input_dim.tot()* nBatches));
|
||||
mean << 0.408, 0.447, 0.47;
|
||||
stddev << 0.289, 0.274, 0.278;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CenternetDetection::testdog() {
|
||||
checkCuda( cudaMalloc(&d_ptrs, dim.c * dim.h*dim.w * sizeof(float)) );
|
||||
|
||||
readBinaryFile(input_bin, dim.tot(), &input_h, &input_d);
|
||||
// Alloc array used in the kernel
|
||||
checkCuda( cudaMalloc(&src_out, K *sizeof(float)) );
|
||||
checkCuda( cudaMalloc(&ids_out, K *sizeof(int)) );
|
||||
|
||||
// -------- transofrm compose
|
||||
cv::Mat imageORIG = cv::imread("../../dog.jpg");
|
||||
imageORIG.convertTo(imageF, CV_32FC3, 1/255.0);
|
||||
sz = imageF.size();
|
||||
std::cout<<"image: "<<sz.width<<", "<<sz.height<<std::endl;
|
||||
resize(imageF, imageF, cv::Size(256, 256));
|
||||
const int cropSize = 224;
|
||||
const int offsetW = (imageF.cols - cropSize) / 2;
|
||||
const int offsetH = (imageF.rows - cropSize) / 2;
|
||||
const cv::Rect roi(offsetW, offsetH, cropSize, cropSize);
|
||||
imageF = imageF(roi).clone();
|
||||
std::cout << "Cropped image dimension: " << imageF.cols << " X " << imageF.rows << std::endl;
|
||||
|
||||
mean << 0.485, 0.456, 0.406;
|
||||
stddev << 0.229, 0.224, 0.225;
|
||||
sz = imageF.size();
|
||||
// std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
// std::cout<<"mean: "<<mean<<", std: "<<stddev<<std::endl;
|
||||
cv::add(imageF, -mean, imageF);
|
||||
cv::divide(imageF, stddev, imageF);
|
||||
//split channels
|
||||
cv::split(imageF,bgr);//split source
|
||||
dim2 = dim;
|
||||
//write channels
|
||||
for(int i=0; i<dim2.c; i++) {
|
||||
int idx = i*imageF.rows*imageF.cols;
|
||||
int ch = dim2.c-1 -i;
|
||||
memcpy((void*)&input[idx], (void*)bgr[ch].data, imageF.rows*imageF.cols*sizeof(dnnType));
|
||||
}
|
||||
|
||||
checkCuda(cudaMemcpyAsync(input_d, input, dim2.tot()*sizeof(dnnType), cudaMemcpyHostToDevice));
|
||||
|
||||
printCenteredTitle(" TENSORRT inference ", '=', 30); {
|
||||
dim2.print();
|
||||
TIMER_START
|
||||
netRT->infer(dim2, input_d);
|
||||
TIMER_STOP
|
||||
dim2.print();
|
||||
}
|
||||
// checkResult(dim2.tot(), input_h, input);
|
||||
}
|
||||
|
||||
cv::Mat CenternetDetection::draw(cv::Mat &imageORIG) {
|
||||
|
||||
tk::dnn::box b;
|
||||
int x0, w, x1, y0, h, y1;
|
||||
int objClass;
|
||||
std::string det_class;
|
||||
int baseline = 0;
|
||||
float fontScale = 0.5;
|
||||
int thickness = 2;
|
||||
|
||||
for(int c=0; c<classes; c++) {
|
||||
int offset = c*123457 % classes;
|
||||
float r = get_color2(2, offset, classes);
|
||||
float g = get_color2(1, offset, classes);
|
||||
float b = get_color2(0, offset, classes);
|
||||
colors[c] = cv::Scalar(int(255.0*b), int(255.0*g), int(255.0*r));
|
||||
}
|
||||
int num_detected = detected.size();
|
||||
for (int i = 0; i < num_detected; i++){
|
||||
b = detected[i];
|
||||
x0 = b.x;
|
||||
w = b.w;
|
||||
x1 = b.x + w;
|
||||
y0 = b.y;
|
||||
h = b.h;
|
||||
y1 = b.y + h;
|
||||
objClass = b.cl;
|
||||
det_class = coco_class_name[objClass];
|
||||
cv::rectangle(imageORIG, cv::Point(x0, y0), cv::Point(x1, y1), colors[objClass], 2);
|
||||
// draw label
|
||||
cv::Size textSize = getTextSize(det_class, cv::FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
|
||||
cv::rectangle(imageORIG, cv::Point(x0, y0), cv::Point((x0 + textSize.width - 2), (y0 - textSize.height - 2)), colors[b.cl], -1);
|
||||
cv::putText(imageORIG, det_class, cv::Point(x0, (y0 - (baseline / 2))), cv::FONT_HERSHEY_SIMPLEX, fontScale, cv::Scalar(255, 255, 255), thickness);
|
||||
|
||||
}
|
||||
return imageORIG;
|
||||
// cv::namedWindow("cnet", cv::WINDOW_NORMAL);
|
||||
// cv::imshow("cnet", imageOrig);
|
||||
// cv::waitKey(10000);
|
||||
}
|
||||
|
||||
|
||||
void CenternetDetection::update(cv::Mat &imageORIG) {
|
||||
dst2.at<float>(0,0)=width * 0.5;
|
||||
dst2.at<float>(0,1)=width * 0.5;
|
||||
dst2.at<float>(1,0)=width * 0.5;
|
||||
dst2.at<float>(1,1)=width * 0.5 + width * -0.5;
|
||||
|
||||
if(!imageORIG.data) {
|
||||
std::cout<<"YOLO: NO IMAGE DATA\n";
|
||||
return;
|
||||
}
|
||||
TIMER_START
|
||||
auto start_t = std::chrono::steady_clock::now();
|
||||
auto step_t = std::chrono::steady_clock::now();
|
||||
auto end_t = std::chrono::steady_clock::now();
|
||||
// -----------------------------------pre-process ------------------------------------------
|
||||
// it will resize the images to `224 x 224` in GETTING_STARTED.md
|
||||
cv::Size sz = imageORIG.size();
|
||||
std::cout<<"image: "<<sz.width<<", "<<sz.height<<std::endl;
|
||||
dst2.at<float>(2,0)=dst2.at<float>(1,0) + (-dst2.at<float>(0,1)+dst2.at<float>(1,1) );
|
||||
dst2.at<float>(2,1)=dst2.at<float>(1,1) + (dst2.at<float>(0,0)-dst2.at<float>(1,0) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CenternetDetection::preprocess(cv::Mat &frame, const int bi){
|
||||
// -----------------------------------pre-process ------------------------------------------
|
||||
|
||||
// auto start_t = std::chrono::steady_clock::now();
|
||||
// auto step_t = std::chrono::steady_clock::now();
|
||||
// auto end_t = std::chrono::steady_clock::now();
|
||||
cv::Size sz = originalSize[bi];
|
||||
// std::cout<<"image: "<<sz.width<<", "<<sz.height<<std::endl;
|
||||
cv::Size sz_old;
|
||||
float scale = 1.0;
|
||||
float new_height = sz.height * scale;
|
||||
float new_width = sz.width * scale;
|
||||
float c[] = {new_width / 2.0, new_height /2.0};
|
||||
float s[2];
|
||||
if(sz.height != sz_old.height && sz.width != sz_old.width){
|
||||
float c[] = {new_width / 2.0f, new_height /2.0f};
|
||||
float s[2];
|
||||
|
||||
if(sz.width > sz.height){
|
||||
s[0] = sz.width * 1.0;
|
||||
s[1] = sz.width * 1.0;
|
||||
}
|
||||
else{
|
||||
s[0] = sz.height * 1.0;
|
||||
s[1] = sz.height * 1.0;
|
||||
}
|
||||
if(sz.width > sz.height){
|
||||
s[0] = sz.width * 1.0;
|
||||
s[1] = sz.width * 1.0;
|
||||
}
|
||||
else{
|
||||
s[0] = sz.height * 1.0;
|
||||
s[1] = sz.height * 1.0;
|
||||
}
|
||||
|
||||
// ----------- get_affine_transform
|
||||
// rot_rad = pi * 0 / 100 --> 0
|
||||
|
||||
src.at<float>(0,0)=c[0];
|
||||
src.at<float>(0,1)=c[1];
|
||||
src.at<float>(1,0)=c[0];
|
||||
src.at<float>(1,1)=c[1] + s[0] * -0.5;
|
||||
dst.at<float>(0,0)=inp_width * 0.5;
|
||||
dst.at<float>(0,1)=inp_height * 0.5;
|
||||
dst.at<float>(1,0)=inp_width * 0.5;
|
||||
dst.at<float>(1,1)=inp_height * 0.5 + inp_width * -0.5;
|
||||
// ----------- get_affine_transform
|
||||
// rot_rad = pi * 0 / 100 --> 0
|
||||
|
||||
src.at<float>(0,0)=c[0];
|
||||
src.at<float>(0,1)=c[1];
|
||||
src.at<float>(1,0)=c[0];
|
||||
src.at<float>(1,1)=c[1] + s[0] * -0.5;
|
||||
dst.at<float>(0,0)=netRT->input_dim.w * 0.5;
|
||||
dst.at<float>(0,1)=netRT->input_dim.h * 0.5;
|
||||
dst.at<float>(1,0)=netRT->input_dim.w * 0.5;
|
||||
dst.at<float>(1,1)=netRT->input_dim.h * 0.5 + netRT->input_dim.w * -0.5;
|
||||
|
||||
src.at<float>(2,0)=src.at<float>(1,0) + (-src.at<float>(0,1)+src.at<float>(1,1) );
|
||||
src.at<float>(2,1)=src.at<float>(1,1) + (src.at<float>(0,0)-src.at<float>(1,0) );
|
||||
dst.at<float>(2,0)=dst.at<float>(1,0) + (-dst.at<float>(0,1)+dst.at<float>(1,1) );
|
||||
dst.at<float>(2,1)=dst.at<float>(1,1) + (dst.at<float>(0,0)-dst.at<float>(1,0) );
|
||||
|
||||
trans = cv::getAffineTransform( src, dst );
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME gett affine trans: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
trans2 = cv::getAffineTransform( dst2, src );
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME getAffineTrans 2: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
}
|
||||
sz_old = sz;
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
cv::cuda::GpuMat im_Orig;
|
||||
cv::cuda::GpuMat imageF1_d, imageF2_d;
|
||||
|
||||
im_Orig = cv::cuda::GpuMat(frame);
|
||||
cv::cuda::resize (im_Orig, imageF1_d, cv::Size(new_width, new_height));
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
src.at<float>(2,0)=src.at<float>(1,0) + (-src.at<float>(0,1)+src.at<float>(1,1) );
|
||||
src.at<float>(2,1)=src.at<float>(1,1) + (src.at<float>(0,0)-src.at<float>(1,0) );
|
||||
dst.at<float>(2,0)=dst.at<float>(1,0) + (-dst.at<float>(0,1)+dst.at<float>(1,1) );
|
||||
dst.at<float>(2,1)=dst.at<float>(1,1) + (dst.at<float>(0,0)-dst.at<float>(1,0) );
|
||||
// std::cout<<"src: "<<src<<std::endl;
|
||||
// std::cout<<"dst: "<<dst<<std::endl;
|
||||
sz = imageF1_d.size();
|
||||
// std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME resize: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
cv::cuda::warpAffine(imageF1_d, imageF2_d, trans, cv::Size(netRT->input_dim.w, netRT->input_dim.h), cv::INTER_LINEAR );
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
imageF2_d.convertTo(imageF1_d, CV_32FC3, 1/255.0);
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME convert: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
dim2 = dim;
|
||||
cv::cuda::GpuMat bgr[3];
|
||||
cv::cuda::split(imageF1_d,bgr);//split source
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME split: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
for(int i=0; i<dim.c; i++)
|
||||
checkCuda( cudaMemcpy(d_ptrs + i*dim.h * dim.w, (float*)bgr[i].data, dim.h * dim.w * sizeof(float), cudaMemcpyDeviceToDevice) );
|
||||
|
||||
normalize(d_ptrs, dim.c, dim.h, dim.w, mean_d, stddev_d);
|
||||
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME normalize: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
checkCuda(cudaMemcpy(input_d+ netRT->input_dim.tot()*bi, d_ptrs, dim2.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME Memcpy to input_d: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
#else
|
||||
|
||||
cv::Mat imageF;
|
||||
resize(frame, imageF, cv::Size(new_width, new_height));
|
||||
sz = imageF.size();
|
||||
// std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME resize: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
cv::Mat trans = cv::getAffineTransform( src, dst );
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME getAffinetr : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
resize(imageORIG, imageF, cv::Size(new_width, new_height));
|
||||
sz = imageF.size();
|
||||
std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME resize: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
cv::warpAffine(imageF, imageF, trans, cv::Size(inp_width, inp_height), cv::INTER_LINEAR );
|
||||
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME warpAffine: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
cv::warpAffine(imageF, imageF, trans, cv::Size(netRT->input_dim.w, netRT->input_dim.h), cv::INTER_LINEAR );
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME warpAffine: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
sz = imageF.size();
|
||||
std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
// std::cout<<"size: "<<sz.height<<" "<<sz.width<<" - "<<std::endl;
|
||||
imageF.convertTo(imageF, CV_32FC3, 1/255.0);
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME convert_to: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
std::cout<<"mean: "<<mean<<", std: "<<stddev<<std::endl;
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME convertto: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
dim2 = dim;
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME before split: " << std::chrono::duration_cast<std::chrono::microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
//split channels
|
||||
cv::Mat bgr[3];
|
||||
cv::split(imageF,bgr);//split source
|
||||
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME split: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
for(int i=0; i<3; i++){
|
||||
bgr[i] = bgr[i] - mean[i];
|
||||
bgr[i] = bgr[i] / stddev[i];
|
||||
}
|
||||
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME mean std: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
//write channels
|
||||
for(int i=0; i<dim2.c; i++) {
|
||||
int idx = i*imageF.rows*imageF.cols;
|
||||
int ch = dim2.c-3 +i;
|
||||
std::cout<<"i: "<<i<<", idx: "<<idx<<", ch: "<<ch<<std::endl;
|
||||
memcpy((void*)&input[idx], (void*)bgr[ch].data, imageF.rows*imageF.cols*sizeof(dnnType));
|
||||
// std::cout<<"i: "<<i<<", idx: "<<idx<<", ch: "<<ch<<std::endl;
|
||||
memcpy((void*)&input[idx+ netRT->input_dim.tot()*bi], (void*)bgr[ch].data, imageF.rows*imageF.cols*sizeof(dnnType));
|
||||
}
|
||||
checkCuda(cudaMemcpyAsync(input_d+ netRT->input_dim.tot()*bi, input+ netRT->input_dim.tot()*bi, dim2.tot()*sizeof(dnnType), cudaMemcpyHostToDevice));
|
||||
#endif
|
||||
}
|
||||
|
||||
checkCuda(cudaMemcpyAsync(input_d, input, dim2.tot()*sizeof(dnnType), cudaMemcpyHostToDevice));
|
||||
void CenternetDetection::postprocess(const int bi, const bool mAP){
|
||||
dnnType *rt_out[4];
|
||||
rt_out[0] = (dnnType *)netRT->buffersRT[1]+ netRT->buffersDIM[1].tot()*bi;
|
||||
rt_out[1] = (dnnType *)netRT->buffersRT[2]+ netRT->buffersDIM[2].tot()*bi;
|
||||
rt_out[2] = (dnnType *)netRT->buffersRT[3]+ netRT->buffersDIM[3].tot()*bi;
|
||||
rt_out[3] = (dnnType *)netRT->buffersRT[4]+ netRT->buffersDIM[4].tot()*bi;
|
||||
|
||||
printCenteredTitle(" TENSORRT inference ", '=', 30); {
|
||||
dim2.print();
|
||||
TIMER_START
|
||||
netRT->infer(dim2, input_d);
|
||||
TIMER_STOP
|
||||
dim2.print();
|
||||
}
|
||||
// checkResult(dim2.tot(), input_h, input);
|
||||
std::cout<<" --- pre-process ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
// auto start_t = std::chrono::steady_clock::now();
|
||||
// auto step_t = std::chrono::steady_clock::now();
|
||||
// auto end_t = std::chrono::steady_clock::now();
|
||||
// ------------------------------------ process --------------------------------------------
|
||||
|
||||
rt_out[0] = (dnnType *)netRT->buffersRT[1];
|
||||
rt_out[1] = (dnnType *)netRT->buffersRT[2];
|
||||
rt_out[2] = (dnnType *)netRT->buffersRT[3];
|
||||
rt_out[3] = (dnnType *)netRT->buffersRT[4];
|
||||
|
||||
activationSIGMOIDForward(rt_out[0], rt_out[0], dim_hm.tot());
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME sigmoid : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
subtractWithThreshold(rt_out[0], rt_out[0] + dim_hm.tot(), rt_out[1], rt_out[0]);
|
||||
|
||||
float *prova;
|
||||
checkCuda( cudaMallocHost(&prova, K*sizeof(float)) );
|
||||
checkCuda( cudaMemcpy(prova, rt_out[0], K*sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
std::cout<<"heat:\n";
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<prova[i]<<" ";
|
||||
std::cout<<"\n\n\n";
|
||||
// for(int i=0; i < dim_hm.tot(); i++){
|
||||
// if(hm_h[i]-hmax_h[i] > toll || hm_h[i]-hmax_h[i] < -toll){
|
||||
// hm_h[i] = 0.0f;
|
||||
// }
|
||||
// }
|
||||
// checkCuda( cudaFreeHost(hmax_h) );
|
||||
std::cout<<" --- hmax ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
subtractWithThreshold(rt_out[0], rt_out[0] + dim_hm.tot(), rt_out[1], rt_out[0], op);
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME threshold: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
// ----------- nms end
|
||||
// ----------- topk
|
||||
|
||||
|
||||
// thrust::device_vector<int> ids_d;
|
||||
// int ids[dim_hm.h * dim_hm.w];
|
||||
// for(int i=0; i<dim_hm.h * dim_hm.w; i++){
|
||||
// ids[i]=i;
|
||||
// }
|
||||
// std::vector<int> ids2( dim_hm.h * dim_hm.w );
|
||||
// for(int i=0; i<dim_hm.h * dim_hm.w; i++){
|
||||
// ids2[i]=i;
|
||||
// }
|
||||
// int ids2[dim_hm.h * dim_hm.w];
|
||||
|
||||
// checkCuda( cudaMemcpy(ids2_d, ids2, dim_hm.h * dim_hm.w*sizeof(int), cudaMemcpyHostToDevice) );
|
||||
if(K > dim_hm.h * dim_hm.w){
|
||||
printf ("Error topk (K is too large)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
checkCuda( cudaMemcpy(ids_d, ids_, dim_hm.c * dim_hm.h * dim_hm.w*sizeof(int), cudaMemcpyHostToDevice) );
|
||||
// checkCuda( cudaMemcpy(ids_2d, ids_2, dim_hm.h * dim_hm.w*sizeof(int), cudaMemcpyHostToDevice) );
|
||||
|
||||
|
||||
// sortAndTopKonDevice(rt_out[0], ids_2d, topk_scores, topk_inds_ , topk_ys_ , topk_xs_ ,dim_hm.h * dim_hm.w, K, dim_hm.c);
|
||||
// checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
// for(int i=0; i<dim_hm.c; i++){
|
||||
// // get the hm->output_dim.h * hm->output_dim.w elements for each channel and sort it. Then find the first 100 elements
|
||||
// // memcpy(ids2, ids, dim_hm.h * dim_hm.w);
|
||||
// sort(rt_out[0]+ i * dim_hm.h * dim_hm.w,
|
||||
// rt_out[0]+ i * dim_hm.h * dim_hm.w + dim_hm.h * dim_hm.w,
|
||||
// ids_d);
|
||||
// // end_t = std::chrono::steady_clock::now();
|
||||
// // std::cout << " TIME sort channel "<<i<<": " << std::chrono::duration_cast<std::chrono::microseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
// // step_t = end_t;
|
||||
// topk(rt_out[0]+ i * dim_hm.h * dim_hm.w, ids_d, K, topk_scores + i*K,
|
||||
// topk_inds_ + i*K, topk_ys_ + i*K, topk_xs_ + i*K);
|
||||
// // checkCuda( cudaMemcpy(ids2, ids2_d, dim_hm.h * dim_hm.w*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
|
||||
// // for (int j=0; j<dim_hm.h * dim_hm.w; j++) {
|
||||
// // topk_scores[i*K + count] = hm_h[i * dim_hm.h * dim_hm.w + ids2[j]];
|
||||
// // topk_inds_[i*K +count] = ids2[j];
|
||||
// // topk_ys_[i*K +count] = (int)(ids2[j] / width);
|
||||
// // topk_xs_[i*K +count] = (int)(ids2[j] % width);
|
||||
// // if(++count == K)
|
||||
// // break;
|
||||
// // }
|
||||
// // end_t = std::chrono::steady_clock::now();
|
||||
// // std::cout << " TIME topk channel "<<i<<": " << std::chrono::duration_cast<std::chrono::microseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
// // step_t = end_t;
|
||||
|
||||
// }
|
||||
// checkCuda( cudaFree(ids_d ));
|
||||
std::cout<<" --- a 100 ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME sort topk on 80 channel: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
// final
|
||||
|
||||
// sort(topk_scores,
|
||||
// topk_scores + dim_hm.c * K,
|
||||
// topk_inds_);
|
||||
sort(rt_out[0],
|
||||
rt_out[0]+dim_hm.tot(),
|
||||
ids_d);
|
||||
sort(rt_out[0],rt_out[0]+dim_hm.tot(),ids_d);
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
int *topk_inds;
|
||||
checkCuda( cudaMallocHost(&topk_inds, K*sizeof(int)) );
|
||||
// checkCuda( cudaMemcpy(topk_inds, ids_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
// for(int i=0; i<K; i++)
|
||||
// std::cout<<topk_inds[i]<<" ";
|
||||
// std::cout<<"\n\n\n";
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME sort: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME sort channel: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
topk(rt_out[0], ids_d, K, scores_d, topk_inds_d, topk_ys_d, topk_xs_d);
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
// topk(topk_scores, topk_inds_, K, scores_d,
|
||||
// topk_inds_d, topk_ys_d, topk_xs_d);
|
||||
topk(rt_out[0], ids_d, K, scores_d,
|
||||
topk_inds_d, topk_ys_d, topk_xs_d);
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME topk channel: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
|
||||
checkCuda( cudaMemcpy(topk_inds, topk_inds_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<topk_inds[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
|
||||
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME topk: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
checkCuda( cudaMemcpy(scores, scores_d, K *sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
std::cout<<"\n\nscores:\n";
|
||||
for(int i=0; i<K;i++)
|
||||
std::cout<<scores[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
|
||||
|
||||
std::cout<<"\n\n\n";
|
||||
|
||||
topKxyclasses(topk_inds_d, topk_inds_d+K, K, width, dim_hm.w*dim_hm.h, clses_d, inttopk_xs_d, inttopk_ys_d);
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME topk x y clses 2: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
checkCuda( cudaMemcpy(topk_xs_d, (float *)inttopk_xs_d, K*sizeof(float), cudaMemcpyDeviceToDevice) );
|
||||
checkCuda( cudaMemcpy(topk_ys_d, (float *)inttopk_ys_d, K*sizeof(float), cudaMemcpyDeviceToDevice) );
|
||||
|
||||
checkCuda( cudaMemcpy(clses, clses_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
std::cout<<"\ntopk_ids: \n";
|
||||
checkCuda( cudaMemcpy(topk_inds, topk_inds_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<topk_inds[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
std::cout<<"\ntopk_clses: \n";
|
||||
checkCuda( cudaMemcpy(topk_inds, clses_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<topk_inds[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
std::cout<<"\nxs: \n";
|
||||
checkCuda( cudaMemcpy(topk_inds, topk_xs_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<topk_inds[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
std::cout<<"\nys: \n";
|
||||
checkCuda( cudaMemcpy(topk_inds, topk_ys_d, K*sizeof(int), cudaMemcpyDeviceToHost) );
|
||||
for(int i=0; i<K; i++)
|
||||
std::cout<<topk_inds[i]<<" ";
|
||||
std::cout<<std::endl;
|
||||
// return;
|
||||
|
||||
// checkCuda( cudaDeviceSynchronize() );
|
||||
// checkCuda( cudaFree(topk_scores) );
|
||||
// checkCuda( cudaFree(topk_inds_) );
|
||||
// checkCuda( cudaFree(topk_ys_) );
|
||||
// checkCuda( cudaFree(topk_xs_) );
|
||||
|
||||
|
||||
// checkCuda( cudaFree(scores_d) );
|
||||
// checkCuda( cudaFree(topk_inds_d) );
|
||||
|
||||
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME clses topk 1 time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
|
||||
// ----------- topk end
|
||||
|
||||
// dnnType *reg_aus;
|
||||
// checkCuda( cudaMallocHost(®_aus, dim_reg.tot()*sizeof(dnnType)) );
|
||||
// checkCuda( cudaMemcpy(reg_aus, rt_out[3], dim_reg.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
|
||||
|
||||
// for(int i = 0; i < K; i++){
|
||||
// topk_xs[i] = topk_xs[i] + reg_aus[topk_inds[i]];
|
||||
// topk_ys[i] = topk_ys[i] + reg_aus[topk_inds[i]+dim_reg.h*dim_reg.w];
|
||||
// }
|
||||
topKxyAddOffset(topk_inds_d, K, dim_reg.h*dim_reg.w, inttopk_xs_d, inttopk_ys_d, topk_xs_d, topk_ys_d, rt_out[3]);
|
||||
topKxyAddOffset(topk_inds_d, K, dim_reg.h*dim_reg.w, inttopk_xs_d, inttopk_ys_d, topk_xs_d, topk_ys_d, rt_out[3], src_out, ids_out);
|
||||
// checkCuda( cudaDeviceSynchronize() );
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME add offset: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
// checkCuda( cudaFreeHost(reg_aus) );
|
||||
|
||||
// dnnType *wh_aus;
|
||||
|
||||
// checkCuda( cudaMemcpy(wh_aus, rt_out[2], dim_wh.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
|
||||
bboxes(topk_inds_d, K, dim_wh.h*dim_wh.w, topk_xs_d, topk_ys_d, rt_out[2], bbx0_d, bbx1_d, bby0_d, bby1_d);
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME add offset: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
bboxes(topk_inds_d, K, dim_wh.h*dim_wh.w, topk_xs_d, topk_ys_d, rt_out[2], bbx0_d, bbx1_d, bby0_d, bby1_d, src_out, ids_out);
|
||||
// checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
checkCuda( cudaMemcpy(bbx0, bbx0_d, K * sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
checkCuda( cudaMemcpy(bby0, bby0_d, K * sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
checkCuda( cudaMemcpy(bbx1, bbx1_d, K * sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
checkCuda( cudaMemcpy(bby1, bby1_d, K * sizeof(float), cudaMemcpyDeviceToHost) );
|
||||
// for(int i = 0; i < K; i++){
|
||||
// bboxes[i * 4] = topk_xs[i] - wh_aus[topk_inds[i]] / 2;
|
||||
// bboxes[i * 4 + 1] = topk_ys[i] - wh_aus[topk_inds[i]+dim_reg.h*dim_reg.w] / 2;
|
||||
// bboxes[i * 4 + 2] = topk_xs[i] + wh_aus[topk_inds[i]] / 2;
|
||||
// bboxes[i * 4 + 3] = topk_ys[i] + wh_aus[topk_inds[i]+dim_reg.h*dim_reg.w] / 2;
|
||||
// }
|
||||
// for(int i = 0; i < K; i++){
|
||||
// std::cout<<"-----\n(x0, y0) = ("<<bbx0<<", "<<bby0<<")\n(x1,y1) = ("<<bbx1<<", "<<bby1<<")\n";
|
||||
|
||||
// }
|
||||
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME bboxes: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
|
||||
// checkCuda( cudaFreeHost(wh_aus) );
|
||||
// checkCuda( cudaFreeHost(topk_inds) );
|
||||
// checkCuda( cudaFreeHost(topk_ys) );
|
||||
// checkCuda( cudaFreeHost(topk_xs) );
|
||||
std::cout<<" --- bboxes ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
// servono [bboxes, scores, clses]
|
||||
// checkCuda( cudaDeviceSynchronize() );
|
||||
|
||||
std::cout<<" --- process ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
// ---------------------------------- post-process -----------------------------------------
|
||||
|
||||
// --------- ctdet_post_process
|
||||
// --------- transform_preds
|
||||
src.at<float>(0,0)=c[0];
|
||||
src.at<float>(0,1)=c[1];
|
||||
src.at<float>(1,0)=c[0];
|
||||
src.at<float>(1,1)=c[1] + s[0] * -0.5;
|
||||
dst.at<float>(0,0)=width * 0.5;
|
||||
dst.at<float>(0,1)=width * 0.5;
|
||||
dst.at<float>(1,0)=width * 0.5;
|
||||
dst.at<float>(1,1)=width * 0.5 + width * -0.5;
|
||||
|
||||
src.at<float>(2,0)=src.at<float>(1,0) + (-src.at<float>(0,1)+src.at<float>(1,1) );
|
||||
src.at<float>(2,1)=src.at<float>(1,1) + (src.at<float>(0,0)-src.at<float>(1,0) );
|
||||
dst.at<float>(2,0)=dst.at<float>(1,0) + (-dst.at<float>(0,1)+dst.at<float>(1,1) );
|
||||
dst.at<float>(2,1)=dst.at<float>(1,1) + (dst.at<float>(0,0)-dst.at<float>(1,0) );
|
||||
|
||||
|
||||
cv::Mat trans2(cv::Size(3,2), CV_32F);
|
||||
trans2 = cv::getAffineTransform( dst, src );
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME getAffineTrans 2: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
cv::Mat new_pt1(cv::Size(1,2), CV_32F);
|
||||
cv::Mat new_pt2(cv::Size(1,2), CV_32F);
|
||||
|
||||
cv::Mat new_pt2(cv::Size(1,2), CV_32F);
|
||||
|
||||
for(int i = 0; i<K; i++){
|
||||
new_pt1.at<float>(0,0)=static_cast<float>(trans2.at<double>(0,0))*bbx0[i] +
|
||||
@@ -570,29 +358,24 @@ void CenternetDetection::update(cv::Mat &imageORIG) {
|
||||
static_cast<float>(trans2.at<double>(1,1))*bby1[i] +
|
||||
static_cast<float>(trans2.at<double>(1,2))*1.0;
|
||||
|
||||
// std::cout<<"\n new: "<<new_pt1<<" - "<<new_pt2<<std::endl;
|
||||
target_coords[i*4] = new_pt1.at<float>(0,0);
|
||||
target_coords[i*4+1] = new_pt1.at<float>(0,1);
|
||||
target_coords[i*4+2] = new_pt2.at<float>(0,0);
|
||||
target_coords[i*4+3] = new_pt2.at<float>(0,1);
|
||||
// std::cout<<new_pt1.at<float>(0,0)<<", "<<new_pt1.at<float>(0,1)<<", "<<new_pt2.at<float>(0,0)<<", "<<new_pt2.at<float>(0,1)<<std::endl;
|
||||
// std::cout<<"target:cords "<<target_coords[i*4]<<" - "<<target_coords[i*4+1]<<std::endl;
|
||||
}
|
||||
|
||||
// int *classes;
|
||||
|
||||
|
||||
detected.clear();
|
||||
for(int i = 0; i<classes; i++){
|
||||
for(int j=0; j<K; j++)
|
||||
if(clses[j] == i){
|
||||
if(scores[j] > thresh){
|
||||
std::cout<<"th: "<<scores[j]<<" - cl: "<<clses[j]<<" i: "<<i<<std::endl;
|
||||
if(scores[j] > confThreshold){
|
||||
// std::cout<<"th: "<<scores[j]<<" - cl: "<<clses[j]<<" i: "<<i<<std::endl;
|
||||
//add coco bbox
|
||||
//det[0:4], i, det[4]
|
||||
int x0 = target_coords[j*4];
|
||||
int y0 = target_coords[j*4+1];
|
||||
int x1 = target_coords[j*4+2];
|
||||
int y1 = target_coords[j*4+3];
|
||||
float x0 = target_coords[j*4];
|
||||
float y0 = target_coords[j*4+1];
|
||||
float x1 = target_coords[j*4+2];
|
||||
float y1 = target_coords[j*4+3];
|
||||
int obj_class = clses[j];
|
||||
float prob = scores[j];
|
||||
// std::cout<<"("<<x0<<", "<<y0<<"),("<<x1<<", "<<y1<<")"<<std::endl;
|
||||
@@ -607,11 +390,14 @@ void CenternetDetection::update(cv::Mat &imageORIG) {
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout<<" --- post_process ---\n";
|
||||
end_t = std::chrono::steady_clock::now();
|
||||
std::cout << " TIME : " << std::chrono::duration_cast<std::chrono::milliseconds>(end_t - step_t).count() << " ms" << std::endl;
|
||||
step_t = end_t;
|
||||
std::cout<<"TOTAL: \n";
|
||||
TIMER_STOP
|
||||
|
||||
batchDetected.push_back(detected);
|
||||
// end_t = std::chrono::steady_clock::now();
|
||||
// std::cout << " TIME detections: " << std::chrono::duration_cast<std::chrono:: microseconds>(end_t - step_t).count() << " us" << std::endl;
|
||||
// step_t = end_t;
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
+48
-29
@@ -17,8 +17,6 @@ void Conv2d::initCUDNN(bool back) {
|
||||
idim = output_dim;
|
||||
odim = input_dim;
|
||||
}
|
||||
//idim.print();
|
||||
//odim.print();
|
||||
|
||||
checkCUDNN( cudnnCreateFilterDescriptor(&filterDesc) );
|
||||
checkCUDNN( cudnnCreateConvolutionDescriptor(&convDesc) );
|
||||
@@ -29,7 +27,7 @@ void Conv2d::initCUDNN(bool back) {
|
||||
net->tensorFormat, net->dataType, idim.n, idim.c, idim.h, idim.w) );
|
||||
|
||||
checkCUDNN( cudnnSetFilter4dDescriptor(filterDesc,
|
||||
net->dataType, net->tensorFormat, odim.c, idim.c,
|
||||
net->dataType, net->tensorFormat, odim.c, idim.c/groups,
|
||||
kernelH, kernelW) );
|
||||
|
||||
checkCUDNN( cudnnSetConvolution2dDescriptor(convDesc,
|
||||
@@ -38,16 +36,20 @@ void Conv2d::initCUDNN(bool back) {
|
||||
1,1, // upscale
|
||||
CUDNN_CROSS_CORRELATION, CUDNN_DATA_FLOAT) );
|
||||
|
||||
checkCUDNN( cudnnSetConvolutionGroupCount(convDesc,
|
||||
groups) );
|
||||
|
||||
// check dimension of convolution output
|
||||
dataDim_t tmpdim;
|
||||
checkCUDNN( cudnnGetConvolution2dForwardOutputDim(
|
||||
convDesc, srcTensor, filterDesc,
|
||||
&tmpdim.n, &tmpdim.c, &tmpdim.h, &tmpdim.w) );
|
||||
|
||||
if(odim.n != tmpdim.n || odim.c != tmpdim.c || odim.h != tmpdim.h || odim.w != tmpdim.w) {
|
||||
std::cout<<"tkdim input: "; idim.print();
|
||||
std::cout<<"tkdim output: "; odim.print();
|
||||
std::cout<<"cudnndim: "; tmpdim.print();
|
||||
FatalError("Eror conv dimension mismatch");
|
||||
FatalError("Error conv dimension mismatch");
|
||||
}
|
||||
|
||||
checkCUDNN( cudnnSetTensor4dDescriptor(dstTensor,
|
||||
@@ -60,25 +62,30 @@ void Conv2d::initCUDNN(bool back) {
|
||||
// init workspace
|
||||
workSpace = NULL;
|
||||
ws_sizeInBytes = 0;
|
||||
int algo_count = 0;
|
||||
if(back) {
|
||||
checkCUDNN( cudnnGetConvolutionBackwardDataAlgorithm(net->cudnnHandle,
|
||||
filterDesc, dstTensor, convDesc, srcTensor,
|
||||
CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST, 0, &bwAlgo) );
|
||||
checkCUDNN( cudnnGetConvolutionBackwardDataAlgorithm_v7(net->cudnnHandle,
|
||||
filterDesc, dstTensor, convDesc, srcTensor, 1, &algo_count, &bwAlgo) );
|
||||
checkCUDNN(cudnnGetConvolutionBackwardDataWorkspaceSize(net->cudnnHandle,
|
||||
filterDesc, dstTensor, convDesc, srcTensor,
|
||||
bwAlgo, &ws_sizeInBytes));
|
||||
filterDesc, dstTensor, convDesc, srcTensor,
|
||||
bwAlgo.algo, &ws_sizeInBytes));
|
||||
|
||||
|
||||
// invert tensors
|
||||
srcTensorDesc = dstTensor;
|
||||
dstTensorDesc = srcTensor;
|
||||
} else {
|
||||
checkCUDNN( cudnnGetConvolutionForwardAlgorithm(net->cudnnHandle,
|
||||
srcTensor, filterDesc, convDesc, dstTensor,
|
||||
CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo) );
|
||||
checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle,
|
||||
srcTensor, filterDesc, convDesc, dstTensor,
|
||||
algo, &ws_sizeInBytes));
|
||||
|
||||
checkCUDNN( cudnnGetConvolutionForwardAlgorithm_v7(net->cudnnHandle,
|
||||
srcTensor, filterDesc, convDesc, dstTensor,
|
||||
1, &algo_count, &algo) );
|
||||
checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle,
|
||||
srcTensor, filterDesc, convDesc, dstTensor,
|
||||
algo.algo, &ws_sizeInBytes));
|
||||
}
|
||||
|
||||
if(algo_count < 1)
|
||||
FatalError("Cannot retrieve convolutional algo");
|
||||
}
|
||||
|
||||
void Conv2d::inferCUDNN(dnnType* srcData, bool back) {
|
||||
@@ -89,16 +96,16 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) {
|
||||
checkCUDNN(cudnnConvolutionBackwardData(net->cudnnHandle,
|
||||
&alpha, filterDesc, data_d,
|
||||
srcTensorDesc, srcData,
|
||||
convDesc, bwAlgo, workSpace, ws_sizeInBytes,
|
||||
convDesc, bwAlgo.algo, workSpace, ws_sizeInBytes,
|
||||
&beta, dstTensorDesc, dstData));
|
||||
} else {
|
||||
checkCUDNN(cudnnConvolutionForward(net->cudnnHandle,
|
||||
&alpha, srcTensorDesc, srcData, filterDesc,
|
||||
data_d, convDesc, algo, workSpace, ws_sizeInBytes,
|
||||
data_d, convDesc, algo.algo, workSpace, ws_sizeInBytes,
|
||||
&beta, dstTensorDesc, dstData));
|
||||
}
|
||||
|
||||
if(!batchnorm) {
|
||||
if(!batchnorm && !additional_bias) { //CHECK WITH IF CORRECT
|
||||
// bias
|
||||
alpha = dnnType(1);
|
||||
beta = dnnType(1);
|
||||
@@ -106,24 +113,34 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) {
|
||||
&alpha, biasTensorDesc, bias_d,
|
||||
&beta, dstTensorDesc, dstData) );
|
||||
} else {
|
||||
alpha = dnnType(1);
|
||||
beta = dnnType(0);
|
||||
checkCUDNN( cudnnBatchNormalizationForwardInference(net->cudnnHandle,
|
||||
CUDNN_BATCHNORM_SPATIAL, &alpha, &beta,
|
||||
dstTensorDesc, dstData, dstTensorDesc,
|
||||
dstData, biasTensorDesc, //same tensor descriptor as bias
|
||||
scales_d, bias_d, mean_d, variance_d,
|
||||
TKDNN_BN_MIN_EPSILON) );
|
||||
if(additional_bias)
|
||||
{
|
||||
alpha = dnnType(1);
|
||||
beta = dnnType(1);
|
||||
checkCUDNN( cudnnAddTensor(net->cudnnHandle,
|
||||
&alpha, biasTensorDesc, bias2_d,
|
||||
&beta, dstTensorDesc, dstData) );
|
||||
}
|
||||
if(batchnorm)
|
||||
{
|
||||
alpha = dnnType(1);
|
||||
beta = dnnType(0);
|
||||
checkCUDNN( cudnnBatchNormalizationForwardInference(net->cudnnHandle,
|
||||
CUDNN_BATCHNORM_SPATIAL, &alpha, &beta,
|
||||
dstTensorDesc, dstData, dstTensorDesc,
|
||||
dstData, biasTensorDesc, //same tensor descriptor as bias
|
||||
scales_d, bias_d, mean_d, variance_d,
|
||||
TKDNN_BN_MIN_EPSILON) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW,
|
||||
int strideH, int strideW, int paddingH, int paddingW,
|
||||
std::string fname_weights, bool batchnorm, bool deConv, bool final) :
|
||||
std::string fname_weights, bool batchnorm, bool deConv, int groups, bool additional_bias) :
|
||||
|
||||
LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1,
|
||||
fname_weights, batchnorm, false, final) {
|
||||
|
||||
fname_weights, batchnorm, additional_bias, deConv, groups) {
|
||||
this->kernelH = kernelH;
|
||||
this->kernelW = kernelW;
|
||||
this->strideH = strideH;
|
||||
@@ -131,6 +148,8 @@ Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW,
|
||||
this->paddingH = paddingH;
|
||||
this->paddingW = paddingW;
|
||||
this->deConv = deConv;
|
||||
this->groups = groups;
|
||||
this->additional_bias = additional_bias;
|
||||
|
||||
if(!deConv) {
|
||||
output_dim.n = input_dim.n;
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
#include "tkDNN/DarknetParser.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
std::string darknetParseType(const std::string& line){
|
||||
size_t start = line.find("[");
|
||||
size_t end = line.find("]");
|
||||
if( start == std::string::npos || end == std::string::npos)
|
||||
return "";
|
||||
start++;
|
||||
std::string type = line.substr(start, end-start);
|
||||
return type;
|
||||
}
|
||||
|
||||
bool divideNameAndValue(const std::string& line, std::string&name, std::string& value){
|
||||
size_t sep = line.find("=");
|
||||
if(sep == std::string::npos)
|
||||
return false;
|
||||
|
||||
name = line.substr(0, sep);
|
||||
value = line.substr(sep+1, line.size() - (sep+1));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<int> fromStringToIntVec(const std::string& line, const char delimiter){
|
||||
std::stringstream linestream(line);
|
||||
std::string value;
|
||||
std::vector<int> values;
|
||||
|
||||
while(getline(linestream,value,delimiter))
|
||||
values.push_back(std::stoi(value));
|
||||
return values;
|
||||
}
|
||||
|
||||
bool darknetParseFields(const std::string& line, darknetFields_t& fields){
|
||||
|
||||
std::string name,value;
|
||||
if(!divideNameAndValue(line, name, value))
|
||||
return false;
|
||||
|
||||
if(name.find("new_coords") != std::string::npos)
|
||||
fields.new_coords = std::stoi(value);
|
||||
else if(name.find("width") != std::string::npos)
|
||||
fields.width = std::stoi(value);
|
||||
else if(name.find("height") != std::string::npos)
|
||||
fields.height = std::stoi(value);
|
||||
else if(name.find("channels") != std::string::npos)
|
||||
fields.channels = std::stoi(value);
|
||||
else if(name.find("batch_normalize") != std::string::npos)
|
||||
fields.batch_normalize = std::stoi(value);
|
||||
else if(name.find("filters") != std::string::npos)
|
||||
fields.filters = std::stoi(value);
|
||||
else if(name.find("activation") != std::string::npos)
|
||||
fields.activation = value;
|
||||
else if(name.find("size") != std::string::npos){
|
||||
fields.size_x = std::stoi(value);
|
||||
fields.size_y = std::stoi(value);
|
||||
}
|
||||
else if(name.find("size_x") != std::string::npos)
|
||||
fields.size_x = std::stoi(value);
|
||||
else if(name.find("size_y") != std::string::npos)
|
||||
fields.size_y = std::stoi(value);
|
||||
else if(name.find("stride") != std::string::npos){
|
||||
fields.stride_x = std::stoi(value);
|
||||
fields.stride_y = std::stoi(value);
|
||||
}
|
||||
else if(name.find("stride_x") != std::string::npos)
|
||||
fields.stride_x = std::stoi(value);
|
||||
else if(name.find("stride_y") != std::string::npos)
|
||||
fields.stride_y = std::stoi(value);
|
||||
else if(name.find("pad") != std::string::npos)
|
||||
fields.pad = std::stoi(value);
|
||||
else if(name.find("classes") != std::string::npos)
|
||||
fields.classes = std::stoi(value);
|
||||
else if(name.find("num") != std::string::npos)
|
||||
fields.num = std::stoi(value);
|
||||
else if(name.find("coords") != std::string::npos)
|
||||
fields.coords = std::stoi(value);
|
||||
else if(name.find("groups") != std::string::npos)
|
||||
fields.groups = std::stoi(value);
|
||||
else if(name.find("group_id") != std::string::npos)
|
||||
fields.group_id = std::stoi(value);
|
||||
else if(name.find("scale_x_y") != std::string::npos)
|
||||
fields.scale_xy = std::stof(value);
|
||||
else if(name.find("beta_nms") != std::string::npos)
|
||||
fields.nms_thresh = std::stof(value);
|
||||
else if(name.find("nms_kind") != std::string::npos){
|
||||
if(value == "greedynms") fields.nms_kind = 0;
|
||||
else if(value == "diounms") fields.nms_kind = 1;
|
||||
else std::cout<<"Not supported nms_kind "<<value<<", setting to greedynms"<<std::endl;
|
||||
}
|
||||
else if(name.find("from") != std::string::npos)
|
||||
fields.layers.push_back(std::stof(value));
|
||||
else if(name.find("mask") != std::string::npos){
|
||||
auto vec = fromStringToIntVec(value, ',');
|
||||
fields.n_mask = vec.size();
|
||||
}
|
||||
else if(name.find("layers") != std::string::npos)
|
||||
fields.layers = fromStringToIntVec(value, ',');
|
||||
|
||||
else
|
||||
std::cout<<"Not supported field: "<<line<<std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
tk::dnn::Network *darknetAddNet(darknetFields_t &fields) {
|
||||
//std::cout<<"Add Net: "<<fields.type<<"\n";
|
||||
dataDim_t dim(1, fields.channels, fields.height, fields.width);
|
||||
return new tk::dnn::Network(dim);
|
||||
}
|
||||
|
||||
|
||||
void darknetAddLayer(tk::dnn::Network *net, darknetFields_t &f, std::string wgs_path, std::vector<tk::dnn::Layer*> &netLayers, const std::vector<std::string>& names) {
|
||||
if(net == nullptr)
|
||||
FatalError("Cant add a layer without a Net\n");
|
||||
|
||||
// padding compute
|
||||
if(f.pad == 1) {
|
||||
f.padding_x = f.padding_y = f.size_x /2;
|
||||
}
|
||||
//std::cout<<"Add layer: "<<f.type<<"\n";
|
||||
if(f.type == "convolutional") {
|
||||
std::string wgs = wgs_path + "/c" + std::to_string(netLayers.size()) + ".bin";
|
||||
//printf("%d (%d,%d) (%d,%d) (%d,%d) %s %d %d\n", f.filters, f.size_x, f.size_y, f.stride_x, f.stride_y, f.padding_x, f.padding_y, wgs.c_str(), f.batch_normalize, f.groups);
|
||||
tk::dnn::Conv2d *l= new tk::dnn::Conv2d(net, f.filters, f.size_x, f.size_y, f.stride_x,
|
||||
f.stride_y, f.padding_x, f.padding_y, wgs, f.batch_normalize, false, f.groups);
|
||||
netLayers.push_back(l);
|
||||
} else if(f.type == "maxpool") {
|
||||
if(f.stride_x == 1 && f.stride_y == 1)
|
||||
netLayers.push_back(new tk::dnn::Pooling(net, f.size_x, f.size_y, f.stride_x, f.stride_y,
|
||||
f.padding_x, f.padding_y, tk::dnn::POOLING_MAX_FIXEDSIZE));
|
||||
else
|
||||
netLayers.push_back(new tk::dnn::Pooling(net, f.size_x, f.size_y, f.stride_x, f.stride_y,
|
||||
f.padding_x, f.padding_y, tk::dnn::POOLING_MAX));
|
||||
|
||||
} else if(f.type == "avgpool") {
|
||||
netLayers.push_back(new tk::dnn::Pooling(net, f.size_x, f.size_y, f.stride_x, f.stride_y,
|
||||
f.padding_x, f.padding_y, tk::dnn::POOLING_AVERAGE));
|
||||
|
||||
} else if(f.type == "shortcut") {
|
||||
if(f.layers.size() != 1) FatalError("no layers to shortcut\n");
|
||||
int layerIdx = f.layers[0];
|
||||
if(layerIdx < 0)
|
||||
layerIdx = netLayers.size() + layerIdx;
|
||||
if(layerIdx < 0 || layerIdx >= netLayers.size()) FatalError("impossible to shortcut\n");
|
||||
//std::cout<<"shortcut to "<<layerIdx<<" "<<netLayers[layerIdx]->getLayerName()<<"\n";
|
||||
netLayers.push_back(new tk::dnn::Shortcut(net, netLayers[layerIdx]));
|
||||
|
||||
} else if(f.type == "upsample") {
|
||||
netLayers.push_back(new tk::dnn::Upsample(net, f.stride_x));
|
||||
|
||||
} else if(f.type == "route") {
|
||||
if(f.layers.size() == 0) FatalError("no layers to Route\n");
|
||||
std::vector<tk::dnn::Layer*> layers;
|
||||
for(int i=0; i<f.layers.size(); i++) {
|
||||
int layerIdx = f.layers[i];
|
||||
if(layerIdx < 0)
|
||||
layerIdx = netLayers.size() + layerIdx;
|
||||
if(layerIdx < 0 || layerIdx >= netLayers.size()) FatalError("impossible to route\n");
|
||||
//std::cout<<"Route to "<<layerIdx<<" "<<netLayers[layerIdx]->getLayerName()<<"\n";
|
||||
layers.push_back(netLayers[layerIdx]);
|
||||
}
|
||||
netLayers.push_back(new tk::dnn::Route(net, layers.data(), layers.size(), f.groups, f.group_id));
|
||||
|
||||
} else if(f.type == "reorg") {
|
||||
netLayers.push_back(new tk::dnn::Reorg(net, f.stride_x));
|
||||
|
||||
} else if(f.type == "region") {
|
||||
netLayers.push_back(new tk::dnn::Region(net, f.classes, f.coords, f.num));
|
||||
|
||||
} else if(f.type == "yolo") {
|
||||
std::string wgs = wgs_path + "/g" + std::to_string(netLayers.size()) + ".bin";
|
||||
//printf("%d %d %s %d %f\n", f.classes, f.num/f.n_mask, wgs.c_str(), f.n_mask, f.scale_xy);
|
||||
tk::dnn::Yolo *l = new tk::dnn::Yolo(net, f.classes, f.num/f.n_mask, wgs, f.n_mask, f.scale_xy, f.nms_thresh, (tk::dnn::Yolo::nmsKind_t) f.nms_kind, f.new_coords);
|
||||
if(names.size() != f.classes)
|
||||
FatalError("Mismatch between number of classes and names");
|
||||
l->classesNames = names;
|
||||
netLayers.push_back(l);
|
||||
|
||||
} else{
|
||||
FatalError("layer not supported: " + f.type);
|
||||
}
|
||||
|
||||
// add activation
|
||||
if(netLayers.size() > 0 && f.activation != "linear") {
|
||||
tkdnnActivationMode_t act;
|
||||
if(f.activation == "relu") act = tkdnnActivationMode_t(CUDNN_ACTIVATION_RELU);
|
||||
else if(f.activation == "leaky") act = tk::dnn::ACTIVATION_LEAKY;
|
||||
else if(f.activation == "mish") act = tk::dnn::ACTIVATION_MISH;
|
||||
else if(f.activation == "logistic") act = tk::dnn::ACTIVATION_LOGISTIC;
|
||||
else { FatalError("activation not supported: " + f.activation); }
|
||||
netLayers[netLayers.size()-1] = new tk::dnn::Activation(net, act);
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> darknetReadNames(const std::string& names_file){
|
||||
std::ifstream if_names(names_file);
|
||||
if(!if_names.is_open())
|
||||
FatalError("cloud not open names file: " + names_file);
|
||||
|
||||
std::vector<std::string> names;
|
||||
std::string line;
|
||||
while(std::getline(if_names, line))
|
||||
if(line != "")
|
||||
names.push_back(line);
|
||||
|
||||
if_names.close();
|
||||
return names;
|
||||
}
|
||||
|
||||
tk::dnn::Network* darknetParser(const std::string& cfg_file, const std::string& wgs_path, const std::string& names_file) {
|
||||
|
||||
tk::dnn::Network *net = nullptr;
|
||||
|
||||
// layers without activations to retrieve correct id number
|
||||
std::vector<tk::dnn::Layer*> netLayers;
|
||||
|
||||
std::ifstream if_cfg(cfg_file);
|
||||
if(!if_cfg.is_open())
|
||||
FatalError("cloud not open cfg file: " + cfg_file);
|
||||
|
||||
std::vector<std::string> names = darknetReadNames(names_file);
|
||||
|
||||
darknetFields_t fields; // will be filled with layers fields
|
||||
std::string line;
|
||||
while(std::getline(if_cfg, line)) {
|
||||
// remove comments
|
||||
std::size_t found = line.find("#");
|
||||
if ( found != std::string::npos ) {
|
||||
line = line.substr(0, found);
|
||||
}
|
||||
|
||||
// skip empty lines
|
||||
if(line.size() == 0)
|
||||
continue;
|
||||
|
||||
std::string type = darknetParseType(line);
|
||||
if(type.size() > 0) {
|
||||
// end of filled type
|
||||
if(fields.type != "") {
|
||||
if(fields.type == "net")
|
||||
net = darknetAddNet(fields);
|
||||
else
|
||||
darknetAddLayer(net, fields, wgs_path, netLayers, names);
|
||||
}
|
||||
|
||||
// new type
|
||||
//std::cout<<"type: "<<type<<"\n";
|
||||
fields = darknetFields_t(); // reset to default
|
||||
fields.type = type;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(darknetParseFields(line, fields)) {
|
||||
// already parsed do nothing
|
||||
} else {
|
||||
FatalError("could not parse line: " + line);
|
||||
}
|
||||
}
|
||||
|
||||
// end of filled type
|
||||
if(fields.type != "") {
|
||||
darknetAddLayer(net, fields, wgs_path, netLayers, names);
|
||||
}
|
||||
|
||||
if(net == nullptr) {
|
||||
FatalError("net not found\n");
|
||||
}
|
||||
return net;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
||||
+27
-21
@@ -9,6 +9,10 @@ namespace tk { namespace dnn {
|
||||
|
||||
void DeformConv2d::initCUDNN() {
|
||||
|
||||
stat = cublasCreate(&handle);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS)
|
||||
FatalError("CUBLAS initialization failed\n");
|
||||
|
||||
checkCUDNN( cudnnCreateTensorDescriptor(&biasTensorDesc) );
|
||||
checkCUDNN( cudnnSetTensor4dDescriptor(biasTensorDesc,
|
||||
net->tensorFormat, net->dataType,
|
||||
@@ -22,25 +26,27 @@ void DeformConv2d::initCUDNN() {
|
||||
const int dim_ones = preconv->input_dim.c * this->kernelH * this->kernelW * 1 * height_ones * width_ones;
|
||||
|
||||
int dst_dim = preconv->output_dim.tot();
|
||||
if (dst_dim % 3 != 0 )
|
||||
std::cout<<"take attention\n\n";
|
||||
if( dst_dim % 3 != 0 )
|
||||
FatalError("DeformConv2d: the Conv2d output is not divisible by three");
|
||||
chunk_dim = dst_dim/3;
|
||||
checkCuda( cudaMalloc(&offset, 2*chunk_dim*sizeof(dnnType)));
|
||||
checkCuda( cudaMalloc(&mask, chunk_dim*sizeof(dnnType)));
|
||||
|
||||
// kernel ones
|
||||
|
||||
checkCuda( cudaMalloc(&ones_d1, (height_ones*width_ones)*sizeof(dnnType)) );
|
||||
float aus1[height_ones*width_ones];
|
||||
dnnType *ones_h1;
|
||||
checkCuda( cudaMallocHost(&ones_h1, (height_ones*width_ones)*sizeof(dnnType)) );
|
||||
for(int i=0; i<height_ones*width_ones; i++)
|
||||
aus1[i]=1.0f;
|
||||
checkCuda( cudaMemcpy(ones_d1, aus1, (height_ones*width_ones)*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
|
||||
ones_h1[i]=1.0f;
|
||||
checkCuda( cudaMemcpy(ones_d1, ones_h1, (height_ones*width_ones)*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
checkCuda( cudaFreeHost(ones_h1) );
|
||||
checkCuda( cudaMalloc(&ones_d2, dim_ones*sizeof(dnnType)) );
|
||||
float aus2[dim_ones];
|
||||
dnnType *ones_h2;
|
||||
checkCuda( cudaMallocHost(&ones_h2, dim_ones*sizeof(dnnType)) );
|
||||
for(int i=0; i<dim_ones; i++)
|
||||
aus2[i]=1.0f;
|
||||
checkCuda( cudaMemcpy(ones_d2, aus2, (dim_ones)*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
ones_h2[i]=1.0f;
|
||||
checkCuda( cudaMemcpy(ones_d2, ones_h2, (dim_ones)*sizeof(dnnType), cudaMemcpyHostToDevice) );
|
||||
checkCuda( cudaFreeHost(ones_h2) );
|
||||
checkCuda( cudaDeviceSynchronize() );
|
||||
}
|
||||
|
||||
@@ -49,8 +55,7 @@ DeformConv2d::DeformConv2d( Network *net, int out_ch, int deformable_group, int
|
||||
std::string d_fname_weights, std::string fname_weights, bool batchnorm) :
|
||||
|
||||
LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1,
|
||||
d_fname_weights, batchnorm, true){
|
||||
|
||||
d_fname_weights, batchnorm, true) {
|
||||
this->out_ch = out_ch;
|
||||
this->deformableGroup = deformable_group;
|
||||
this->kernelH = kernelH;
|
||||
@@ -73,36 +78,37 @@ DeformConv2d::DeformConv2d( Network *net, int out_ch, int deformable_group, int
|
||||
}
|
||||
|
||||
DeformConv2d::~DeformConv2d() {
|
||||
|
||||
checkCUDNN( cudnnDestroyTensorDescriptor(biasTensorDesc) );
|
||||
checkCuda( cudaFree(dstData) );
|
||||
checkCuda( cudaFreeHost(ones_d1) );
|
||||
checkCuda( cudaFreeHost(ones_d2) );
|
||||
checkCuda( cudaFree(ones_d1) );
|
||||
checkCuda( cudaFree(ones_d2) );
|
||||
checkCuda( cudaFree(offset) );
|
||||
checkCuda( cudaFree(mask) );
|
||||
checkCuda( cudaFree(output_conv) );
|
||||
cublasDestroy(handle);
|
||||
}
|
||||
|
||||
dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
|
||||
// conv2d
|
||||
output_conv = preconv->infer(dim, srcData);
|
||||
// split conv2d outputs into offset to mask
|
||||
// split conv2d outputs into offset and mask
|
||||
checkCuda(cudaMemcpy(offset, output_conv, 2*chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
checkCuda(cudaMemcpy(mask, output_conv + 2*chunk_dim, chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
// kernel sigmoide
|
||||
// kernel sigmoid
|
||||
activationSIGMOIDForward(mask, mask, chunk_dim);
|
||||
|
||||
|
||||
// deformable convolution
|
||||
dcn_v2_cuda_forward(srcData, this->data_d,
|
||||
dcnV2CudaForward(stat, handle,
|
||||
srcData, this->data_d,
|
||||
this->bias2_d, ones_d1,
|
||||
offset, mask,
|
||||
offset, mask,
|
||||
dstData, ones_d2,
|
||||
this->kernelH, this->kernelW,
|
||||
this->strideH, this->strideW,
|
||||
this->paddingH, this->paddingW,
|
||||
1, 1,
|
||||
this->deformableGroup,
|
||||
this->deformableGroup, 0, //batch_id for cudnn is set to 0 (no batch)
|
||||
preconv->input_dim.n, preconv->input_dim.c, preconv->input_dim.h, preconv->input_dim.w,
|
||||
this->output_dim.n, this->output_dim.c, this->output_dim.h, this->output_dim.w,
|
||||
chunk_dim);
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ dnnType* Dense::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
// place bias into dstData
|
||||
checkCuda( cudaMemcpy(dstData, bias_d, dim_y*sizeof(dnnType), cudaMemcpyDeviceToDevice) );
|
||||
|
||||
//do matrix moltiplication
|
||||
//do matrix multiplication
|
||||
checkERROR( cublasSgemv(net->cublasHandle, CUBLAS_OP_T,
|
||||
dim_x, dim_y,
|
||||
&alpha,
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "Int8BatchStream.h"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/dnn/dnn.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
|
||||
BatchStream::BatchStream(tk::dnn::dataDim_t dim, int batchSize, int maxBatches, const std::string& fileimglist, const std::string& filelabellist) {
|
||||
mBatchSize = batchSize;
|
||||
mMaxBatches = maxBatches;
|
||||
mDims = nvinfer1::DimsNCHW{ dim.n, dim.c, dim.h, dim.w };
|
||||
mHeight = dim.h;
|
||||
mWidth = dim.w;
|
||||
mImageSize = mDims.c()*mDims.h()*mDims.w();
|
||||
mBatch.resize(mBatchSize*mImageSize, 0);
|
||||
mLabels.resize(mBatchSize, 0);
|
||||
mFileBatch.resize(mDims.n()*mImageSize, 0);
|
||||
mFileLabels.resize(mDims.n(), 0);
|
||||
mFileImgList = fileimglist;
|
||||
readInListFile(fileimglist, mListImg);
|
||||
mFileLabelList = filelabellist;
|
||||
readInListFile(filelabellist, mListLabel);
|
||||
|
||||
reset(0);
|
||||
}
|
||||
|
||||
void BatchStream::reset(int firstBatch) {
|
||||
mBatchCount = 0;
|
||||
mFileCount = 0;
|
||||
mFileBatchPos = mDims.n();
|
||||
skip(firstBatch);
|
||||
}
|
||||
|
||||
bool BatchStream::next() {
|
||||
std::cout<<"Next batch: "<<mBatchCount<<" of "<<mMaxBatches<<"\n";
|
||||
if (mBatchCount == mMaxBatches-1)
|
||||
return false;
|
||||
|
||||
for (int csize = 1, batchPos = 0; batchPos < mBatchSize; batchPos += csize, mFileBatchPos += csize) {
|
||||
assert(mFileBatchPos > 0 && mFileBatchPos <= mDims.n());
|
||||
if (mFileBatchPos == mDims.n() && !update())
|
||||
return false;
|
||||
|
||||
csize = std::min(mBatchSize - batchPos, mDims.n() - mFileBatchPos);
|
||||
std::copy_n(getFileBatch() + mFileBatchPos * mImageSize, csize * mImageSize, getBatch() + batchPos * mImageSize);
|
||||
std::copy_n(getFileLabels() + mFileBatchPos, csize, getLabels() + batchPos);
|
||||
}
|
||||
mBatchCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BatchStream::skip(int skipCount) {
|
||||
if (mBatchSize >= mDims.n() && mBatchSize%mDims.n() == 0 && mFileBatchPos == mDims.n()) {
|
||||
mFileCount += skipCount * mBatchSize / mDims.n();
|
||||
return;
|
||||
}
|
||||
|
||||
int x = mBatchCount;
|
||||
for (int i = 0; i < skipCount; i++)
|
||||
next();
|
||||
mBatchCount = x;
|
||||
}
|
||||
|
||||
void BatchStream::readInListFile(const std::string& dataFilePath, std::vector<std::string>& mListIn) {
|
||||
// dataFilePath contains the list of image paths
|
||||
int count = 0;
|
||||
FILE* f = fopen(dataFilePath.c_str(), "r");
|
||||
if (!f)
|
||||
FatalError("failed to open " + dataFilePath);
|
||||
|
||||
char str[512];
|
||||
while (fgets(str, 512, f) != NULL) {
|
||||
for (int i = 0; str[i] != '\0'; ++i) {
|
||||
if (str[i] == '\n'){
|
||||
str[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
count ++;
|
||||
mListIn.push_back(str);
|
||||
if(count == mMaxBatches)
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void BatchStream::readCVimage(std::string inputFileName, std::vector<float>& res, bool fixshape) {
|
||||
// unaltered original DsImage
|
||||
cv::Mat m_OrigImage;
|
||||
// letterboxed DsImage given to the network as input
|
||||
cv::Mat m_LetterboxImage;
|
||||
m_OrigImage = cv::imread(inputFileName, cv::IMREAD_COLOR);
|
||||
|
||||
if (!m_OrigImage.data || m_OrigImage.cols <= 0 || m_OrigImage.rows <= 0)
|
||||
FatalError("Unable to open " + inputFileName);
|
||||
|
||||
int m_Height = m_OrigImage.rows;
|
||||
int m_Width = m_OrigImage.cols;
|
||||
if(fixshape) {
|
||||
m_Height = mHeight;
|
||||
m_Width = mWidth;
|
||||
}
|
||||
std::cout<<"image is "<<inputFileName<<": "<<m_Height<<" * "<<m_Width<<std::endl;
|
||||
// resize the DsImage with scale
|
||||
float dim = std::max(m_Height, m_Width);
|
||||
int resizeH = ((m_Height / dim) * m_Height);
|
||||
int resizeW = ((m_Width / dim) * m_Width);
|
||||
float m_ScalingFactor = static_cast<float>(resizeH) / static_cast<float>(m_Height);
|
||||
|
||||
// Additional checks for images with non even dims
|
||||
if ((m_Width - resizeW) % 2) resizeW--;
|
||||
if ((m_Height - resizeH) % 2) resizeH--;
|
||||
assert((m_Width - resizeW) % 2 == 0);
|
||||
assert((m_Height - resizeH) % 2 == 0);
|
||||
|
||||
int m_XOffset = (m_Width - resizeW) / 2;
|
||||
int m_YOffset = (m_Height - resizeH) / 2;
|
||||
|
||||
assert(2 * m_XOffset + resizeW == m_Width);
|
||||
assert(2 * m_YOffset + resizeH == m_Height);
|
||||
|
||||
// resizing
|
||||
cv::resize(m_OrigImage, m_LetterboxImage, cv::Size(resizeW, resizeH), 0, 0, cv::INTER_CUBIC);
|
||||
// letterboxing
|
||||
cv::copyMakeBorder(m_LetterboxImage, m_LetterboxImage, m_YOffset, m_YOffset, m_XOffset,
|
||||
m_XOffset, cv::BORDER_CONSTANT, cv::Scalar(128, 128, 128));
|
||||
m_LetterboxImage.convertTo(m_LetterboxImage, CV_32FC3, 1 / 255.0);
|
||||
// converting to RGB and NCHW format
|
||||
m_LetterboxImage = cv::dnn::blobFromImage(m_LetterboxImage);
|
||||
res.assign(m_LetterboxImage.begin<float>(), m_LetterboxImage.end<float>());
|
||||
}
|
||||
|
||||
void BatchStream::readLabels(std::string inputFileName, std::vector<float>& ris) {
|
||||
std::ifstream is(inputFileName.c_str());
|
||||
|
||||
std::string line;
|
||||
while (std::getline(is, line))
|
||||
{
|
||||
std::istringstream iss(line);
|
||||
float val;
|
||||
if(!(iss >> val)) { break; } // error
|
||||
ris.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
bool BatchStream::update() {
|
||||
std::string imgFileName = mListImg[mFileCount];
|
||||
std::string labelFileName = mListLabel[mFileCount];
|
||||
mFileCount++;
|
||||
|
||||
//read image
|
||||
mFileBatch.clear();
|
||||
readCVimage(imgFileName, mFileBatch);
|
||||
// std::transform(
|
||||
// singleImg_rawData.begin(), singleImg_rawData.end(), mFileBatch.begin(), [](uint8_t val) { return static_cast<float>(val); });
|
||||
|
||||
//read label
|
||||
mFileLabels.clear();
|
||||
readLabels(labelFileName, mFileLabels);
|
||||
// std::transform(
|
||||
// singleLabels_rawData.begin(), singleLabels_rawData.end(), mFileLabels.begin(), [](uint8_t val) { return static_cast<float>(val); });
|
||||
|
||||
mFileBatchPos = 0;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "Int8Calibrator.h"
|
||||
|
||||
Int8EntropyCalibrator::Int8EntropyCalibrator(BatchStream& stream, int firstBatch,
|
||||
const std::string& calibTableFilePath,
|
||||
const std::string& inputBlobName,
|
||||
bool readCache):
|
||||
mStream(stream),
|
||||
mCalibTableFilePath(calibTableFilePath),
|
||||
mInputBlobName(inputBlobName.c_str()),
|
||||
mReadCache(readCache) {
|
||||
nvinfer1::DimsNCHW dims = mStream.getDims();
|
||||
mInputCount = mStream.getBatchSize() * dims.c() * dims.h() * dims.w();
|
||||
checkCuda(cudaMalloc(&mDeviceInput, mInputCount * sizeof(float)));
|
||||
mStream.reset(firstBatch);
|
||||
}
|
||||
|
||||
bool Int8EntropyCalibrator::getBatch(void* bindings[], const char* names[], int nbBindings) {
|
||||
if (!mStream.next())
|
||||
return false;
|
||||
|
||||
checkCuda(cudaMemcpy(mDeviceInput, mStream.getBatch(), mInputCount * sizeof(float), cudaMemcpyHostToDevice));
|
||||
assert(!strcmp(names[0], mInputBlobName.c_str()));
|
||||
bindings[0] = mDeviceInput;
|
||||
return true;
|
||||
}
|
||||
|
||||
const void* Int8EntropyCalibrator::readCalibrationCache(size_t& length) {
|
||||
mCalibrationCache.clear();
|
||||
assert(!mCalibTableFilePath.empty());
|
||||
std::ifstream input(mCalibTableFilePath, std::ios::binary);
|
||||
input >> std::noskipws;
|
||||
input >> std::noskipws;
|
||||
if (mReadCache && input.good())
|
||||
std::copy(std::istream_iterator<char>(input), std::istream_iterator<char>(),
|
||||
std::back_inserter(mCalibrationCache));
|
||||
|
||||
length = mCalibrationCache.size();
|
||||
return length ? &mCalibrationCache[0] : nullptr;
|
||||
}
|
||||
|
||||
void Int8EntropyCalibrator::writeCalibrationCache(const void* cache, size_t length) {
|
||||
assert(!mCalibTableFilePath.empty());
|
||||
std::ofstream output(mCalibTableFilePath, std::ios::binary);
|
||||
output.write(reinterpret_cast<const char*>(cache), length);
|
||||
output.close();
|
||||
}
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Layer.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weights) :
|
||||
Layer(net) {
|
||||
|
||||
this->returnSeq = returnSeq;
|
||||
int batchSize = input_dim.n;
|
||||
int inputSize = input_dim.c;
|
||||
seqLen = input_dim.w;
|
||||
stateSize = hiddensize;
|
||||
|
||||
// init Tensor Descriptors
|
||||
std::vector<cudnnTensorDescriptor_t> x_vec(seqLen);
|
||||
std::vector<cudnnTensorDescriptor_t> y_vec(seqLen);
|
||||
|
||||
int dimA[3];
|
||||
int strideA[3];
|
||||
for (int i = 0; i < seqLen; i++) {
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&x_vec[i]));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&y_vec[i]));
|
||||
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = inputSize;
|
||||
dimA[2] = 1;
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = inputSize;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(x_vec[i],
|
||||
net->dataType, 3, dimA, strideA));
|
||||
|
||||
dimA[0] = batchSize;
|
||||
dimA[1] = stateSize;
|
||||
dimA[2] = 1;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(y_vec[i],
|
||||
net->dataType, 3, dimA, strideA));
|
||||
}
|
||||
// apply tensordesc
|
||||
x_desc_vec_ = x_vec;
|
||||
y_desc_vec_ = y_vec;
|
||||
|
||||
|
||||
// set the state tensors
|
||||
dimA[0] = numLayers;
|
||||
dimA[1] = batchSize;
|
||||
dimA[2] = stateSize;
|
||||
strideA[0] = dimA[2] * dimA[1];
|
||||
strideA[1] = dimA[2];
|
||||
strideA[2] = 1;
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&hx_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&cx_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&hy_desc_));
|
||||
checkCUDNN(cudnnCreateTensorDescriptor(&cy_desc_));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(hx_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(cx_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(hy_desc_, net->dataType, 3, dimA, strideA));
|
||||
checkCUDNN(cudnnSetTensorNdDescriptor(cy_desc_, net->dataType, 3, dimA, strideA));
|
||||
// allocate dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr;
|
||||
stateDataDim = dimA[0]*dimA[1]*dimA[2];
|
||||
checkCuda( cudaMalloc(&hx_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&cx_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&hy_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&cy_ptr, stateDataDim*sizeof(dnnType)) );
|
||||
|
||||
|
||||
|
||||
// Create Dropout descriptors // TODO: ??? IS IT NECESSARY ???
|
||||
float dropoutprob = 0.1f; // random val ????
|
||||
checkCUDNN(cudnnCreateDropoutDescriptor(&dropoutDesc));
|
||||
checkCUDNN(cudnnDropoutGetStatesSize(net->cudnnHandle, &dropout_byte_));
|
||||
dropout_size_ = dropout_byte_ / sizeof(dnnType);
|
||||
checkCuda( cudaMalloc(&dropout_states_, dropout_byte_) );
|
||||
uint64_t seed_ = 17 + rand() % 4096; // NOLINT(runtime/threadsafe_fn)
|
||||
checkCUDNN(cudnnSetDropoutDescriptor(dropoutDesc,
|
||||
net->cudnnHandle, dropoutprob, dropout_states_, dropout_byte_, seed_));
|
||||
|
||||
|
||||
// RNN descriptors
|
||||
checkCUDNN(cudnnCreateRNNDescriptor(&rnnDesc));
|
||||
|
||||
#if CUDNN_MAJOR > 7
|
||||
checkCUDNN(cudnnSetRNNDescriptor_v6(net->cudnnHandle,rnnDesc, stateSize, numLayers, dropoutDesc,
|
||||
cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT,
|
||||
//(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL),
|
||||
cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL,
|
||||
cudnnRNNMode_t::CUDNN_LSTM,
|
||||
cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD,
|
||||
net->dataType));
|
||||
#else
|
||||
checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle,rnnDesc, stateSize, numLayers, dropoutDesc,
|
||||
cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT,
|
||||
//(bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL),
|
||||
cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL,
|
||||
cudnnRNNMode_t::CUDNN_LSTM,
|
||||
cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD,
|
||||
net->dataType));
|
||||
#endif
|
||||
|
||||
|
||||
// Get temp space sizes
|
||||
checkCUDNN(cudnnGetRNNWorkspaceSize(net->cudnnHandle,
|
||||
rnnDesc, seqLen, x_desc_vec_.data(), &workspace_byte_));
|
||||
workspace_size_ = workspace_byte_ / sizeof(dnnType);
|
||||
checkCuda( cudaMalloc(&work_space_, workspace_byte_) );
|
||||
|
||||
|
||||
// Check that number of params are correct
|
||||
size_t cudnn_param_size;
|
||||
checkCUDNN(cudnnGetRNNParamsSize(net->cudnnHandle,
|
||||
rnnDesc,x_desc_vec_[0], &cudnn_param_size, net->dataType));
|
||||
int cudnn_params = cudnn_param_size/sizeof(dnnType);
|
||||
//std::cout<<"LSTM params size: "<<cudnn_params << ", bytes: "<<cudnn_param_size<<"\n";
|
||||
|
||||
// Set param descriptors
|
||||
checkCUDNN(cudnnCreateFilterDescriptor(&w_desc_));
|
||||
int dim_w[3] = {1, 1, 1};
|
||||
dim_w[0] = cudnn_params;
|
||||
checkCUDNN(cudnnSetFilterNdDescriptor(w_desc_,
|
||||
net->dataType, net->tensorFormat, 3, dim_w));
|
||||
|
||||
// load params
|
||||
std::cout<<"Reading weights: PARAMS="<<cudnn_params*2<<"\n";
|
||||
readBinaryFile(fname_weights, cudnn_params*2, &w_h, &w_ptr);
|
||||
// set forward and backward params
|
||||
wf_ptr = w_ptr;
|
||||
wb_ptr = w_ptr + cudnn_params;
|
||||
//std::cout<<"wf: "<<wf_ptr<<" wb "<<wb_ptr<<"\n";
|
||||
|
||||
// set output dim
|
||||
output_dim = input_dim;
|
||||
output_dim.c = stateSize*(bidirectional ? 2 : 1);
|
||||
|
||||
// if retunseq is disabled only the last timestamp is returned
|
||||
if(!returnSeq) {
|
||||
output_dim.h = 1;
|
||||
output_dim.w = 1;
|
||||
}
|
||||
|
||||
//allocate data for infer result
|
||||
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
// used during inference
|
||||
one_output_dim = input_dim;
|
||||
one_output_dim.c = stateSize;
|
||||
checkCuda( cudaMalloc(&srcF, input_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&srcB, input_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstF, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstB_NR, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
checkCuda( cudaMalloc(&dstB, one_output_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
|
||||
/*
|
||||
// Query weight layout
|
||||
cudnnFilterDescriptor_t m_desc;
|
||||
checkCUDNN(cudnnCreateFilterDescriptor(&m_desc));
|
||||
dnnType *p;
|
||||
int n = 8; // lstm layers
|
||||
|
||||
printCenteredTitle("WEIGHTS", '=', 20);
|
||||
for (int i = 0; i < numLayers; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
|
||||
checkCUDNN(cudnnGetRNNLinLayerMatrixParams(net->cudnnHandle, rnnDesc,
|
||||
i, x_desc_vec_[0], w_desc_, 0, j, m_desc, (void**)&p));
|
||||
|
||||
std::cout << "ptr: " << ((int64_t)(p - NULL))/sizeof(dnnType)<<"\n";
|
||||
|
||||
cudnnDataType_t t;
|
||||
cudnnTensorFormat_t f;
|
||||
int ndim = 5;
|
||||
int dims[5] = {0, 0, 0, 0, 0};
|
||||
checkCUDNN(cudnnGetFilterNdDescriptor(m_desc, ndim, &t, &f, &ndim, &dims[0]));
|
||||
std::cout << "(layer, linlayer): " << i << " " << j << "\n";
|
||||
|
||||
int tot = 1;
|
||||
for (int i = 0; i < ndim; ++i) {
|
||||
std::cout << dims[i] << " ";
|
||||
tot *= dims[i];
|
||||
}
|
||||
std::cout<<"\t-> "<<tot<<"\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
printCenteredTitle("BIAS", '=', 20);
|
||||
for (int i = 0; i < numLayers; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
checkCUDNN(cudnnGetRNNLinLayerBiasParams(net->cudnnHandle, rnnDesc,
|
||||
i, x_desc_vec_[0], w_desc_, 0, j, m_desc, (void**)&p));
|
||||
|
||||
std::cout << "ptr: " << ((int64_t)(p - NULL))/sizeof(dnnType)<<"\n";
|
||||
|
||||
cudnnDataType_t t;
|
||||
cudnnTensorFormat_t f;
|
||||
int ndim = 5;
|
||||
int dims[5] = {0, 0, 0, 0, 0};
|
||||
checkCUDNN(cudnnGetFilterNdDescriptor(m_desc, ndim, &t, &f, &ndim, &dims[0]));
|
||||
std::cout << "(layer, linlayer): " << i << " " << j << "\n";
|
||||
|
||||
int tot = 1;
|
||||
for (int i = 0; i < ndim; ++i) {
|
||||
std::cout << dims[i] << " ";
|
||||
tot *= dims[i];
|
||||
}
|
||||
std::cout<<"\t-> "<<tot<<"\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
checkCUDNN(cudnnDestroyFilterDescriptor(m_desc));
|
||||
*/
|
||||
}
|
||||
|
||||
LSTM::~LSTM() {
|
||||
checkCuda(cudaFree(hx_ptr));
|
||||
checkCuda(cudaFree(cx_ptr));
|
||||
checkCuda(cudaFree(hy_ptr));
|
||||
checkCuda(cudaFree(cy_ptr));
|
||||
checkCuda(cudaFree(w_ptr ));
|
||||
|
||||
checkCuda(cudaFree(work_space_ ));
|
||||
checkCuda(cudaFree(dropout_states_));
|
||||
|
||||
checkCuda(cudaFree(srcF));
|
||||
checkCuda(cudaFree(srcB));
|
||||
checkCuda(cudaFree(dstF));
|
||||
checkCuda(cudaFree(dstB_NR));
|
||||
checkCuda(cudaFree(dstB));
|
||||
checkCuda(cudaFree(dstData));
|
||||
}
|
||||
|
||||
dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
|
||||
// transpose input
|
||||
matrixTranspose(net->cublasHandle, srcData, srcF, dim.c, dim.h*dim.w*dim.l);
|
||||
|
||||
// build srcB as reversed srcF
|
||||
for(int i=0; i<input_dim.w; i++) {
|
||||
int off_0 = i*(input_dim.c);
|
||||
int off_1 = (i+1)*(input_dim.c);
|
||||
checkCuda( cudaMemcpy(srcB + dim.tot() - off_1, srcF + off_0,
|
||||
input_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
// forward
|
||||
{
|
||||
// reset states
|
||||
checkCuda( cudaMemset(hx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
checkCuda( cudaMemset(cx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
|
||||
|
||||
checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle,
|
||||
rnnDesc,
|
||||
seqLen, // number of time steps (nT)
|
||||
x_desc_vec_.data(), // input array of desc (nT*nC_in)
|
||||
srcF, // input pointer
|
||||
hx_desc_, // initial hidden state desc
|
||||
hx_ptr, // initial hidden state pointer
|
||||
cx_desc_, // initial cell state desc
|
||||
cx_ptr, // initial cell state pointer
|
||||
w_desc_, // weights desc
|
||||
wf_ptr, // weights pointer
|
||||
y_desc_vec_.data(), // output desc (nT*nC_out)
|
||||
dstF, // output pointer
|
||||
hy_desc_, // final hidden state desc
|
||||
hy_ptr, // final hidden state pointer
|
||||
cy_desc_, // final cell state desc
|
||||
cy_ptr, // final cell state pointer
|
||||
work_space_, // workspace pointer
|
||||
workspace_byte_)); // workspace size
|
||||
}
|
||||
|
||||
// backward
|
||||
{
|
||||
// reset states
|
||||
checkCuda( cudaMemset(hx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
checkCuda( cudaMemset(cx_ptr, 0, stateDataDim*sizeof(float)) );
|
||||
|
||||
checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle,
|
||||
rnnDesc,
|
||||
seqLen, // number of time steps (nT)
|
||||
x_desc_vec_.data(), // input array of desc (nT*nC_in)
|
||||
srcB, // input pointer
|
||||
hx_desc_, // initial hidden state desc
|
||||
hx_ptr, // initial hidden state pointer
|
||||
cx_desc_, // initial cell state desc
|
||||
cx_ptr, // initial cell state pointer
|
||||
w_desc_, // weights desc
|
||||
wb_ptr, // weights pointer
|
||||
y_desc_vec_.data(), // output desc (nT*nC_out)
|
||||
dstB_NR, // output pointer
|
||||
hy_desc_, // final hidden state desc
|
||||
hy_ptr, // final hidden state pointer
|
||||
cy_desc_, // final cell state desc
|
||||
cy_ptr, // final cell state pointer
|
||||
work_space_, // workspace pointer
|
||||
workspace_byte_)); // workspace size
|
||||
}
|
||||
|
||||
|
||||
// reverse order of dstB
|
||||
for(int i=0; i<one_output_dim.w; i++) {
|
||||
int off_0 = i*(one_output_dim.c);
|
||||
int off_1 = (i+1)*(one_output_dim.c);
|
||||
checkCuda( cudaMemcpy(dstB + one_output_dim.tot() - off_1, dstB_NR + off_0,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
// if retunseq is disabled only the last timestamp is returned
|
||||
if(returnSeq) {
|
||||
// forward transpose
|
||||
matrixTranspose(net->cublasHandle, dstF, dstData,
|
||||
one_output_dim.h* one_output_dim.w*one_output_dim.l, one_output_dim.c);
|
||||
// backward transpose
|
||||
matrixTranspose(net->cublasHandle, dstB, dstData + one_output_dim.tot(),
|
||||
one_output_dim.h* one_output_dim.w*one_output_dim.l, one_output_dim.c);
|
||||
} else {
|
||||
// copy last of forward
|
||||
checkCuda( cudaMemcpy(dstData, dstF + one_output_dim.tot() - one_output_dim.c,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
// copy first of backward
|
||||
checkCuda( cudaMemcpy(dstData + one_output_dim.c, dstB,
|
||||
one_output_dim.c*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
}
|
||||
|
||||
dim = output_dim;
|
||||
return dstData;
|
||||
}
|
||||
|
||||
}}
|
||||
+7
-2
@@ -4,10 +4,10 @@
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Layer::Layer(Network *net, bool final) {
|
||||
Layer::Layer(Network *net) {
|
||||
|
||||
this->net = net;
|
||||
this->final = final;
|
||||
this->final = false;
|
||||
if(net != nullptr) {
|
||||
this->input_dim = net->getOutputDim();
|
||||
this->output_dim = input_dim;
|
||||
@@ -24,6 +24,11 @@ Layer::~Layer() {
|
||||
|
||||
checkCUDNN( cudnnDestroyTensorDescriptor(srcTensorDesc) );
|
||||
checkCUDNN( cudnnDestroyTensorDescriptor(dstTensorDesc) );
|
||||
|
||||
if(dstData != nullptr) {
|
||||
cudaFree(dstData);
|
||||
dstData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
+22
-24
@@ -8,32 +8,33 @@ namespace tk { namespace dnn {
|
||||
|
||||
LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
|
||||
int kh, int kw, int kl,
|
||||
std::string fname_weights, bool batchnorm, bool additional_bias, bool final) : Layer(net, final) {
|
||||
|
||||
std::string fname_weights, bool batchnorm, bool additional_bias, bool deConv, int groups) : Layer(net) {
|
||||
inputs = inputs/groups;
|
||||
|
||||
this->inputs = inputs;
|
||||
this->outputs = outputs;
|
||||
this->weights_path = std::string(fname_weights);
|
||||
|
||||
std::cout<<"Reading weights: I="<<inputs<<" O="<<outputs<<" KERNEL="<<kh<<"x"<<kw<<"x"<<kl<<"\n";
|
||||
int seek = 0;
|
||||
readBinaryFile(weights_path.c_str(), inputs*outputs*kh*kw*kl, &data_h, &data_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), inputs*outputs*kh*kw*kl, &data_h, &data_d, seek);
|
||||
seek += inputs*outputs*kh*kw*kl;
|
||||
this->additional_bias = additional_bias;
|
||||
if(additional_bias) {
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias2_h, &bias2_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias2_h, &bias2_d, seek);
|
||||
seek += outputs;
|
||||
}
|
||||
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek);
|
||||
|
||||
this->batchnorm = batchnorm;
|
||||
if(batchnorm) {
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek);
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek);
|
||||
seek += outputs;
|
||||
readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek, net->dontLoadWeights);
|
||||
readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek);
|
||||
|
||||
float eps = TKDNN_BN_MIN_EPSILON;
|
||||
|
||||
@@ -58,6 +59,14 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
|
||||
float2half(data_d, data16_d, w_size);
|
||||
cudaMemcpy(data16_h, data16_d, w_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
|
||||
if(additional_bias){
|
||||
int b2_size = outputs;
|
||||
bias216_h = new __half[b2_size];
|
||||
cudaMalloc(&bias216_d, w_size*sizeof(__half));
|
||||
float2half(bias2_d, bias216_d, b2_size);
|
||||
cudaMemcpy(bias216_h, bias216_d, b2_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
}
|
||||
|
||||
int b_size = outputs;
|
||||
bias16_h = new __half[b_size];
|
||||
cudaMalloc(&bias16_d, w_size*sizeof(__half));
|
||||
@@ -86,7 +95,6 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
|
||||
cudaMemcpy(power16_h, power16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
|
||||
//mean array
|
||||
|
||||
cudaMemcpy(tmp_d, mean_h, b_size*sizeof(float), cudaMemcpyHostToDevice);
|
||||
float2half(tmp_d, mean16_d, b_size);
|
||||
cudaMemcpy(mean16_h, mean16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
@@ -97,27 +105,17 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs,
|
||||
float2half(tmp_d, variance16_d, b_size);
|
||||
cudaMemcpy(variance16_h, variance16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
|
||||
//conver scales
|
||||
//convert scales
|
||||
float2half(scales_d, scales16_d, b_size);
|
||||
cudaMemcpy(scales16_h, scales16_d, b_size*sizeof(__half), cudaMemcpyDeviceToHost);
|
||||
|
||||
cudaFree(tmp_d);
|
||||
}
|
||||
}
|
||||
|
||||
LayerWgs::~LayerWgs() {
|
||||
|
||||
delete [] data_h;
|
||||
delete [] bias_h;
|
||||
checkCuda( cudaFree(data_d) );
|
||||
checkCuda( cudaFree(bias_d) );
|
||||
|
||||
if(batchnorm) {
|
||||
delete [] scales_h;
|
||||
delete [] mean_h;
|
||||
delete [] variance_h;
|
||||
checkCuda( cudaFree(scales_d) );
|
||||
checkCuda( cudaFree(mean_d) );
|
||||
checkCuda( cudaFree(variance_d) );
|
||||
}
|
||||
releaseHost();
|
||||
releaseDevice();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
#include "MobilenetDetection.h"
|
||||
|
||||
bool boxProbCmp(const tk::dnn::box &a, const tk::dnn::box &b){
|
||||
return (a.prob > b.prob);
|
||||
}
|
||||
|
||||
namespace tk{ namespace dnn{
|
||||
|
||||
void MobilenetDetection::generate_ssd_priors(const SSDSpec *specs, const int n_specs, bool clamp){
|
||||
nPriors = 0;
|
||||
for (int i = 0; i < n_specs; i++){
|
||||
nPriors += specs[i].featureSize * specs[i].featureSize * 6;
|
||||
}
|
||||
|
||||
priors = (float *)malloc(N_COORDS * nPriors * sizeof(float));
|
||||
|
||||
int i_prio = 0;
|
||||
float scale, x_center, y_center, h, w, size, ratio;
|
||||
int min, max;
|
||||
for (int i = 0; i < n_specs; i++){
|
||||
scale = (float)imageSize / (float)specs[i].shrinkage;
|
||||
min = specs[i].boxHeight > specs[i].boxWidth ? specs[i].boxWidth : specs[i].boxHeight;
|
||||
max = specs[i].boxHeight < specs[i].boxWidth ? specs[i].boxWidth : specs[i].boxHeight;
|
||||
for (int j = 0; j < specs[i].featureSize; j++){
|
||||
for (int k = 0; k < specs[i].featureSize; k++){
|
||||
//small sized square box
|
||||
size = min;
|
||||
x_center = (k + 0.5f) / scale;
|
||||
y_center = (j + 0.5f) / scale;
|
||||
h = w = (float)size / (float)imageSize;
|
||||
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w;
|
||||
priors[i_prio * N_COORDS + 3] = h;
|
||||
++i_prio;
|
||||
|
||||
//big sized square box
|
||||
size = sqrt(max * min);
|
||||
h = w = (float)size / (float)imageSize;
|
||||
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w;
|
||||
priors[i_prio * N_COORDS + 3] = h;
|
||||
++i_prio;
|
||||
|
||||
//change h/w ratio of the small sized box
|
||||
size = min;
|
||||
h = w = size / (float)imageSize;
|
||||
ratio = sqrt(specs[i].ratio1);
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w * ratio;
|
||||
priors[i_prio * N_COORDS + 3] = h / ratio;
|
||||
++i_prio;
|
||||
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w / ratio;
|
||||
priors[i_prio * N_COORDS + 3] = h * ratio;
|
||||
++i_prio;
|
||||
|
||||
ratio = sqrt(specs[i].ratio2);
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w * ratio;
|
||||
priors[i_prio * N_COORDS + 3] = h / ratio;
|
||||
++i_prio;
|
||||
|
||||
priors[i_prio * N_COORDS + 0] = x_center;
|
||||
priors[i_prio * N_COORDS + 1] = y_center;
|
||||
priors[i_prio * N_COORDS + 2] = w / ratio;
|
||||
priors[i_prio * N_COORDS + 3] = h * ratio;
|
||||
++i_prio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clamp){
|
||||
for (int i = 0; i < nPriors * N_COORDS; i++){
|
||||
priors[i] = priors[i] > 1.0f ? 1.0f : priors[i];
|
||||
priors[i] = priors[i] < 0.0f ? 0.0f : priors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MobilenetDetection::convert_locatios_to_boxes_and_center(){
|
||||
float cur_x, cur_y;
|
||||
for (int i = 0; i < nPriors; i++){
|
||||
locations_h[i * N_COORDS + 0] = locations_h[i * N_COORDS + 0] * centerVariance * priors[i * N_COORDS + 2] + priors[i * N_COORDS + 0];
|
||||
locations_h[i * N_COORDS + 1] = locations_h[i * N_COORDS + 1] * centerVariance * priors[i * N_COORDS + 3] + priors[i * N_COORDS + 1];
|
||||
locations_h[i * N_COORDS + 2] = exp(locations_h[i * N_COORDS + 2] * sizeVariance) * priors[i * N_COORDS + 2];
|
||||
locations_h[i * N_COORDS + 3] = exp(locations_h[i * N_COORDS + 3] * sizeVariance) * priors[i * N_COORDS + 3];
|
||||
|
||||
cur_x = locations_h[i * N_COORDS + 0];
|
||||
cur_y = locations_h[i * N_COORDS + 1];
|
||||
|
||||
locations_h[i * N_COORDS + 0] = cur_x - locations_h[i * N_COORDS + 2] / 2;
|
||||
locations_h[i * N_COORDS + 1] = cur_y - locations_h[i * N_COORDS + 3] / 2;
|
||||
locations_h[i * N_COORDS + 2] = cur_x + locations_h[i * N_COORDS + 2] / 2;
|
||||
locations_h[i * N_COORDS + 3] = cur_y + locations_h[i * N_COORDS + 3] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
float MobilenetDetection::iou(const tk::dnn::box &a, const tk::dnn::box &b){
|
||||
float max_x = a.x > b.x ? a.x : b.x;
|
||||
float max_y = a.y > b.y ? a.y : b.y;
|
||||
float min_w = a.w < b.w ? a.w : b.w;
|
||||
float min_h = a.h < b.h ? a.h : b.h;
|
||||
|
||||
float ao_w = min_w - max_x > 0 ? min_w - max_x : 0;
|
||||
float ao_h = min_h - max_y > 0 ? min_h - max_y : 0;
|
||||
|
||||
float area_overlap = ao_w * ao_h;
|
||||
float area_0_w = a.w - a.x > 0 ? a.w - a.x : 0;
|
||||
float area_0_h = a.h - a.y > 0 ? a.h - a.y : 0;
|
||||
|
||||
float area_1_w = b.w - b.x > 0 ? b.w - b.x : 0;
|
||||
float area_1_h = b.h - b.y > 0 ? b.h - b.y : 0;
|
||||
|
||||
float area_0 = area_0_h * area_0_w;
|
||||
float area_1 = area_1_h * area_1_w;
|
||||
|
||||
float iou = area_overlap / (area_0 + area_1 - area_overlap + 1e-5);
|
||||
return iou;
|
||||
}
|
||||
|
||||
bool MobilenetDetection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh){
|
||||
std::cout<<(tensor_path).c_str()<<"\n";
|
||||
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str());
|
||||
imageSize = netRT->input_dim.h;
|
||||
classes = n_classes;
|
||||
nBatches = n_batches;
|
||||
confThreshold = conf_thresh;
|
||||
|
||||
SSDSpec specs[N_SSDSPEC];
|
||||
|
||||
if(imageSize == 300){
|
||||
specs[0].setAll(19, 16, 60, 105, 2, 3);
|
||||
specs[1].setAll(10, 32, 105, 150, 2, 3);
|
||||
specs[2].setAll(5, 64, 150, 195, 2, 3);
|
||||
specs[3].setAll(3, 100, 195, 240, 2, 3);
|
||||
specs[4].setAll(2, 150, 240, 285, 2, 3);
|
||||
specs[5].setAll(1, 300, 285, 330, 2, 3);
|
||||
}
|
||||
else if(imageSize == 512){
|
||||
specs[0].setAll(32, 16, 60, 105, 2, 3);
|
||||
specs[1].setAll(16, 32, 105, 150, 2, 3);
|
||||
specs[2].setAll(8, 64, 150, 195, 2, 3);
|
||||
specs[3].setAll(4, 100, 195, 240, 2, 3);
|
||||
specs[4].setAll(2, 150, 240, 285, 2, 3);
|
||||
specs[5].setAll(1, 300, 285, 330, 2, 3);
|
||||
}
|
||||
else{
|
||||
FatalError("Input size for mobilenet not supported");
|
||||
}
|
||||
|
||||
generate_ssd_priors(specs, N_SSDSPEC);
|
||||
|
||||
#ifndef OPENCV_CUDACONTRIB
|
||||
checkCuda(cudaMallocHost(&input, sizeof(dnnType) * netRT->input_dim.tot() * nBatches));
|
||||
#endif
|
||||
checkCuda(cudaMalloc(&input_d, sizeof(dnnType) * netRT->input_dim.tot() * nBatches));
|
||||
|
||||
locations_h = (float *)malloc(N_COORDS * nPriors * sizeof(float));
|
||||
confidences_h = (float *)malloc(nPriors * classes * sizeof(float));
|
||||
|
||||
for (int c = 0; c < classes; c++){
|
||||
int offset = c * 123457 % classes;
|
||||
float r = getColor(2, offset, classes);
|
||||
float g = getColor(1, offset, classes);
|
||||
float b = getColor(0, offset, classes);
|
||||
colors[c] = cv::Scalar(int(255.0 * b), int(255.0 * g), int(255.0 * r));
|
||||
}
|
||||
|
||||
if(classes == 11){ //BDD
|
||||
const char *classes_names_[] = {
|
||||
"person","car","truck","bus","motor","bike","rider","traffic light","traffic sign","train"};
|
||||
classesNames = std::vector<std::string>(classes_names_, std::end(classes_names_));
|
||||
}
|
||||
else if(classes == 21){ //VOC
|
||||
const char *classes_names_[] = {
|
||||
"aeroplane", "bicycle", "bird", "boat", "bottle", "bus",
|
||||
"car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike",
|
||||
"person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"};
|
||||
classesNames = std::vector<std::string>(classes_names_, std::end(classes_names_));
|
||||
|
||||
}
|
||||
else if (classes == 81){ //COCO
|
||||
const char *classes_names_[] = {
|
||||
"person" , "bicycle" , "car" , "motorbike" , "aeroplane" , "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" , "sofa" , "pottedplant" , "bed" , "diningtable" ,
|
||||
"toilet" , "tvmonitor" , "laptop" , "mouse" , "remote" , "keyboard" ,
|
||||
"cell phone" , "microwave" , "oven" , "toaster" , "sink" , "refrigerator" ,
|
||||
"book" , "clock" , "vase" , "scissors" , "teddy bear" , "hair drier" , "toothbrush"};
|
||||
classesNames = std::vector<std::string>(classes_names_, std::end(classes_names_));
|
||||
|
||||
}
|
||||
else{
|
||||
FatalError("Number of classes not supported for mobilenet");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MobilenetDetection::preprocess(cv::Mat &frame, const int bi){
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
//move original image on GPU
|
||||
cv::cuda::GpuMat orig_img, frame_nomean;
|
||||
orig_img = cv::cuda::GpuMat(frame);
|
||||
|
||||
//resize image, remove mean, divide by std
|
||||
cv::cuda::resize (orig_img, orig_img, cv::Size(netRT->input_dim.w, netRT->input_dim.h));
|
||||
orig_img.convertTo(frame_nomean, CV_32FC3, 1, -127);
|
||||
frame_nomean.convertTo(imagePreproc, CV_32FC3, 1 / 128.0, 0);
|
||||
|
||||
//copy image into tensors
|
||||
cv::cuda::split(imagePreproc, bgr);
|
||||
|
||||
for(int i=0; i < netRT->input_dim.c; i++){
|
||||
int idx = i * imagePreproc.rows * imagePreproc.cols;
|
||||
checkCuda( cudaMemcpy((void *)&input_d[idx + netRT->input_dim.tot()*bi], (void *)bgr[i].data, imagePreproc.rows * imagePreproc.cols* sizeof(float), cudaMemcpyDeviceToDevice) );
|
||||
}
|
||||
#else
|
||||
//resize image, remove mean, divide by std
|
||||
cv::Mat frame_nomean;
|
||||
resize(frame, frame, cv::Size(netRT->input_dim.w, netRT->input_dim.h));
|
||||
frame.convertTo(frame_nomean, CV_32FC3, 1, -127);
|
||||
frame_nomean.convertTo(imagePreproc, CV_32FC3, 1 / 128.0, 0);
|
||||
|
||||
//copy image into tensor and copy it into GPU
|
||||
cv::split(imagePreproc, bgr);
|
||||
for (int i = 0; i < netRT->input_dim.c; i++){
|
||||
int idx = i * imagePreproc.rows * imagePreproc.cols;
|
||||
memcpy((void *)&input[idx + netRT->input_dim.tot()*bi], (void *)bgr[i].data, imagePreproc.rows * imagePreproc.cols * sizeof(dnnType));
|
||||
}
|
||||
checkCuda(cudaMemcpyAsync(input_d+ netRT->input_dim.tot()*bi, input + netRT->input_dim.tot()*bi, netRT->input_dim.tot() * sizeof(dnnType), cudaMemcpyHostToDevice, netRT->stream));
|
||||
#endif
|
||||
}
|
||||
|
||||
void MobilenetDetection::postprocess(const int bi, const bool mAP){
|
||||
//get confidences and locations_h
|
||||
dnnType *rt_out[2];
|
||||
rt_out[0] = (dnnType *)netRT->buffersRT[3]+ netRT->buffersDIM[3].tot()*bi;
|
||||
rt_out[1] = (dnnType *)netRT->buffersRT[4]+ netRT->buffersDIM[4].tot()*bi;
|
||||
|
||||
detected.clear();
|
||||
|
||||
checkCuda(cudaMemcpy(confidences_h, rt_out[0], nPriors * classes * sizeof(float), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaMemcpy(locations_h, rt_out[1], N_COORDS * nPriors * sizeof(float), cudaMemcpyDeviceToHost));
|
||||
convert_locatios_to_boxes_and_center();
|
||||
|
||||
int width = originalSize[bi].width;
|
||||
int height = originalSize[bi].height;
|
||||
|
||||
float *conf_per_class;
|
||||
for (int i = 1; i < classes; i++){
|
||||
conf_per_class = &confidences_h[i * nPriors];
|
||||
std::vector<tk::dnn::box> boxes;
|
||||
for (int j = 0; j < nPriors; j++){
|
||||
|
||||
if (conf_per_class[j] > confThreshold){
|
||||
tk::dnn::box b;
|
||||
b.cl = i;
|
||||
b.prob = conf_per_class[j];
|
||||
b.x = locations_h[j * N_COORDS + 0];
|
||||
b.y = locations_h[j * N_COORDS + 1];
|
||||
b.w = locations_h[j * N_COORDS + 2];
|
||||
b.h = locations_h[j * N_COORDS + 3];
|
||||
|
||||
if(mAP)
|
||||
for(int c=1; c<classes; c++)
|
||||
b.probs.push_back(confidences_h[c * nPriors + j]);
|
||||
|
||||
boxes.push_back(b);
|
||||
}
|
||||
}
|
||||
std::sort(boxes.begin(), boxes.end(), boxProbCmp);
|
||||
|
||||
std::vector<tk::dnn::box> remaining;
|
||||
while (boxes.size() > 0){
|
||||
remaining.clear();
|
||||
|
||||
tk::dnn::box b;
|
||||
b.cl = boxes[0].cl -1 ; //remove background class
|
||||
b.prob = boxes[0].prob;
|
||||
b.x = boxes[0].x * width;
|
||||
b.y = boxes[0].y * height;
|
||||
b.w = boxes[0].w * width - b.x; //convert from x1 to width
|
||||
b.h = boxes[0].h * height - b.y; //convert from y1 to height
|
||||
detected.push_back(b);
|
||||
for (size_t j = 1; j < boxes.size(); j++){
|
||||
if (iou(boxes[0], boxes[j]) <= IoUThreshold){
|
||||
remaining.push_back(boxes[j]);
|
||||
}
|
||||
}
|
||||
boxes = remaining;
|
||||
}
|
||||
}
|
||||
batchDetected.push_back(detected);
|
||||
}
|
||||
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace tk
|
||||
+1
-1
@@ -12,7 +12,7 @@ MulAdd::MulAdd(Network *net, dnnType mul, dnnType add) : Layer(net) {
|
||||
|
||||
int size = input_dim.tot();
|
||||
|
||||
// create a vector with all value setted to add
|
||||
// create a vector with all value set to add
|
||||
dnnType *add_vector_h = new dnnType[size];
|
||||
for(int i=0; i<size; i++)
|
||||
add_vector_h[i] = add;
|
||||
|
||||
+58
-7
@@ -22,19 +22,35 @@ Network::Network(dataDim_t input_dim) {
|
||||
|
||||
fp16 = false;
|
||||
dla = false;
|
||||
int8 = false;
|
||||
if(const char* env_p = std::getenv("TKDNN_MODE")) {
|
||||
if(strcmp(env_p, "FP16") == 0)
|
||||
fp16 = true;
|
||||
else if(strcmp(env_p, "DLA") == 0) {
|
||||
dla = true;
|
||||
fp16 = true;
|
||||
}
|
||||
else if(strcmp(env_p, "DLA") == 0) {
|
||||
dla = true;
|
||||
fp16 = true;
|
||||
}
|
||||
else if(strcmp(env_p, "INT8") == 0) {
|
||||
int8 = true;
|
||||
}
|
||||
}
|
||||
maxBatchSize = 1;
|
||||
if(const char* env_p = std::getenv("TKDNN_BATCHSIZE")) {
|
||||
maxBatchSize = atoi(env_p);
|
||||
}
|
||||
if(const char* env_p = std::getenv("TKDNN_CALIB_IMG_PATH"))
|
||||
fileImgList = env_p;
|
||||
|
||||
if(const char* env_p = std::getenv("TKDNN_CALIB_LABEL_PATH"))
|
||||
fileLabelList = env_p;
|
||||
|
||||
|
||||
if(fp16)
|
||||
std::cout<<COL_REDB<<"!! FP16 INERENCE ENABLED !!"<<COL_END<<"\n";
|
||||
std::cout<<COL_REDB<<"!! FP16 INFERENCE ENABLED !!"<<COL_END<<"\n";
|
||||
if(dla)
|
||||
std::cout<<COL_GREENB<<"!! DLA INERENCE ENABLED !!"<<COL_END<<"\n";
|
||||
std::cout<<COL_GREENB<<"!! DLA INFERENCE ENABLED !!"<<COL_END<<"\n";
|
||||
if(int8)
|
||||
std::cout<<COL_ORANGEB<<"!! INT8 INFERENCE ENABLED !!"<<COL_END<<"\n";
|
||||
|
||||
|
||||
checkCUDNN( cudnnCreate(&cudnnHandle) );
|
||||
@@ -43,11 +59,16 @@ Network::Network(dataDim_t input_dim) {
|
||||
}
|
||||
|
||||
Network::~Network() {
|
||||
|
||||
checkCUDNN( cudnnDestroy(cudnnHandle) );
|
||||
checkERROR( cublasDestroy(cublasHandle) );
|
||||
}
|
||||
|
||||
void Network::releaseLayers() {
|
||||
for(int i=0; i<num_layers; i++)
|
||||
delete layers[i];
|
||||
num_layers = 0;
|
||||
}
|
||||
|
||||
dnnType* Network::infer(dataDim_t &dim, dnnType* data) {
|
||||
|
||||
//do infer for every layer
|
||||
@@ -107,6 +128,36 @@ void Network::print() {
|
||||
}
|
||||
printCenteredTitle("", '=', 60);
|
||||
std::cout<<"\n";
|
||||
printCudaMemUsage();
|
||||
}
|
||||
const char *Network::getNetworkRTName(const char *network_name){
|
||||
networkName = network_name;
|
||||
int network_name_len = strlen(network_name);
|
||||
char *RTName = (char *)malloc((network_name_len + 9)*sizeof(char));
|
||||
if (fp16){
|
||||
strcpy(RTName, network_name);
|
||||
strcat(RTName, "_fp16.rt");
|
||||
RTName[network_name_len + 8] = '\0';
|
||||
}
|
||||
else if (dla){
|
||||
strcpy(RTName, network_name);
|
||||
strcat(RTName, "_dla.rt");
|
||||
RTName[network_name_len + 7] = '\0';
|
||||
}
|
||||
|
||||
else if (int8){
|
||||
strcpy(RTName, network_name);
|
||||
strcat(RTName, "_int8.rt");
|
||||
RTName[network_name_len + 8] = '\0';
|
||||
}
|
||||
|
||||
else{
|
||||
strcpy(RTName, network_name);
|
||||
strcat(RTName, "_fp32.rt");
|
||||
RTName[network_name_len + 8] = '\0';
|
||||
}
|
||||
networkNameRT = RTName;
|
||||
return RTName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+317
-82
@@ -9,6 +9,7 @@
|
||||
#include "utils.h"
|
||||
#include "NvInfer.h"
|
||||
#include "NetworkRT.h"
|
||||
#include "Int8Calibrator.h"
|
||||
|
||||
using namespace nvinfer1;
|
||||
|
||||
@@ -35,23 +36,39 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
builderRT = createInferBuilder(loggerRT);
|
||||
std::cout<<"Float16 support: "<<builderRT->platformHasFastFp16()<<"\n";
|
||||
std::cout<<"Int8 support: "<<builderRT->platformHasFastInt8()<<"\n";
|
||||
//std::cout<<"DLAs: "<<builderRT->getNbDLACores()<<"\n";
|
||||
#if NV_TENSORRT_MAJOR >= 5
|
||||
std::cout<<"DLAs: "<<builderRT->getNbDLACores()<<"\n";
|
||||
#endif
|
||||
networkRT = builderRT->createNetwork();
|
||||
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
configRT = builderRT->createBuilderConfig();
|
||||
#endif
|
||||
|
||||
if(!fileExist(name)) {
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
// Calibrator life time needs to last until after the engine is built.
|
||||
std::unique_ptr<IInt8EntropyCalibrator> calibrator;
|
||||
|
||||
configRT->setAvgTimingIterations(1);
|
||||
configRT->setMinTimingIterations(1);
|
||||
configRT->setMaxWorkspaceSize(1 << 30);
|
||||
configRT->setFlag(BuilderFlag::kDEBUG);
|
||||
#endif
|
||||
//input and dataType
|
||||
dataDim_t dim = net->layers[0]->input_dim;
|
||||
dtRT = DataType::kFLOAT;
|
||||
|
||||
builderRT->setMaxBatchSize(1);
|
||||
builderRT->setMaxBatchSize(net->maxBatchSize);
|
||||
builderRT->setMaxWorkspaceSize(1 << 30);
|
||||
|
||||
if(net->fp16 && builderRT->platformHasFastFp16()) {
|
||||
dtRT = DataType::kHALF;
|
||||
builderRT->setHalf2Mode(true);
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
configRT->setFlag(BuilderFlag::kFP16);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
#if NV_TENSORRT_MAJOR >= 5
|
||||
if(net->dla && builderRT->getNbDLACores() > 0) {
|
||||
dtRT = DataType::kHALF;
|
||||
builderRT->setFp16Mode(true);
|
||||
@@ -59,9 +76,33 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
builderRT->setDefaultDeviceType(DeviceType::kDLA);
|
||||
builderRT->setDLACore(0);
|
||||
}
|
||||
*/
|
||||
|
||||
//add input layer
|
||||
#endif
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
if(net->int8 && builderRT->platformHasFastInt8()){
|
||||
// dtRT = DataType::kINT8;
|
||||
// builderRT->setInt8Mode(true);
|
||||
configRT->setFlag(BuilderFlag::kINT8);
|
||||
BatchStream calibrationStream(dim, 1, 100, //TODO: check if 100 images are sufficient to the calibration (or 4951)
|
||||
net->fileImgList, net->fileLabelList);
|
||||
|
||||
/* The calibTableFilePath contains the path+filename of the calibration table.
|
||||
* Each calibration table can be found in the corresponding network folder (../Test/*).
|
||||
* Each network is located in a folder with the same name as the network.
|
||||
* If the folder has a different name, the calibration table is saved in build/ folder.
|
||||
*/
|
||||
std::string calib_table_name = net->networkName + "/" + net->networkNameRT.substr(0, net->networkNameRT.find('.')) + "-calibration.table";
|
||||
std::string calib_table_path = net->networkName;
|
||||
if(!fileExist((const char *)calib_table_path.c_str()))
|
||||
calib_table_name = "./" + net->networkNameRT.substr(0, net->networkNameRT.find('.')) + "-calibration.table";
|
||||
|
||||
calibrator.reset(new Int8EntropyCalibrator(calibrationStream, 1,
|
||||
calib_table_name,
|
||||
"data"));
|
||||
configRT->setInt8Calibrator(calibrator.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
// add input layer
|
||||
ITensor *input = networkRT->addInput("data", DataType::kFLOAT,
|
||||
DimsCHW{ dim.c, dim.h, dim.w});
|
||||
checkNULL(input);
|
||||
@@ -70,12 +111,18 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
for(int i=0; i<net->num_layers; i++) {
|
||||
Layer *l = net->layers[i];
|
||||
ILayer *Ilay = convert_layer(input, l);
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
if(net->int8 && builderRT->platformHasFastInt8())
|
||||
{
|
||||
Ilay->setPrecision(DataType::kINT8);
|
||||
}
|
||||
#endif
|
||||
Ilay->setName( (l->getLayerName() + std::to_string(i)).c_str() );
|
||||
|
||||
input = Ilay->getOutput(0);
|
||||
input->setName( (l->getLayerName() + std::to_string(i) + "_out").c_str() );
|
||||
|
||||
if(l->getLayerType() == LAYER_YOLO || l->final)
|
||||
if(l->final)
|
||||
networkRT->markOutput(*input);
|
||||
tensors[l] = input;
|
||||
}
|
||||
@@ -86,8 +133,15 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
input->setName("out");
|
||||
networkRT->markOutput(*input);
|
||||
|
||||
std::cout<<"Selected maxBatchSize: "<<builderRT->getMaxBatchSize()<<"\n";
|
||||
printCudaMemUsage();
|
||||
std::cout<<"Building tensorRT cuda engine...\n";
|
||||
#if NV_TENSORRT_MAJOR >= 6
|
||||
engineRT = builderRT->buildEngineWithConfig(*networkRT, *configRT);
|
||||
#else
|
||||
engineRT = builderRT->buildCudaEngine(*networkRT);
|
||||
//engineRT = std::shared_ptr<nvinfer1::ICudaEngine>(builderRT->buildCudaEngine(*networkRT));
|
||||
#endif
|
||||
if(engineRT == nullptr)
|
||||
FatalError("cloud not build cuda engine")
|
||||
// we don't need the network any more
|
||||
@@ -110,7 +164,7 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
// note that indices are guaranteed to be less than IEngine::getNbBindings()
|
||||
buf_input_idx = engineRT->getBindingIndex("data");
|
||||
buf_output_idx = engineRT->getBindingIndex("out");
|
||||
std::cout<<"input idex = "<<buf_input_idx<<" -> output index = "<<buf_output_idx<<"\n";
|
||||
std::cout<<"input index = "<<buf_input_idx<<" -> output index = "<<buf_output_idx<<"\n";
|
||||
|
||||
|
||||
Dims iDim = engineRT->getBindingDimensions(buf_input_idx);
|
||||
@@ -130,9 +184,11 @@ NetworkRT::NetworkRT(Network *net, const char *name) {
|
||||
// create GPU buffers and a stream
|
||||
for(int i=0; i<engineRT->getNbBindings(); i++) {
|
||||
Dims dim = engineRT->getBindingDimensions(i);
|
||||
checkCuda(cudaMalloc(&buffersRT[i], dim.d[0]*dim.d[1]*dim.d[2]*sizeof(dnnType)));
|
||||
buffersDIM[i] = dataDim_t(1, dim.d[0], dim.d[1], dim.d[2]);
|
||||
std::cout<<"RtBuffer "<<i<<" dim: "; buffersDIM[i].print();
|
||||
checkCuda(cudaMalloc(&buffersRT[i], engineRT->getMaxBatchSize()*dim.d[0]*dim.d[1]*dim.d[2]*sizeof(dnnType)));
|
||||
}
|
||||
checkCuda(cudaMalloc(&output, output_dim.tot()*sizeof(dnnType)));
|
||||
checkCuda(cudaMalloc(&output, engineRT->getMaxBatchSize()*output_dim.tot()*sizeof(dnnType)));
|
||||
checkCuda(cudaStreamCreate(&stream));
|
||||
}
|
||||
|
||||
@@ -141,19 +197,24 @@ NetworkRT::~NetworkRT() {
|
||||
}
|
||||
|
||||
dnnType* NetworkRT::infer(dataDim_t &dim, dnnType* data) {
|
||||
int batches = dim.n;
|
||||
if(batches > getMaxBatchSize()) {
|
||||
FatalError("input batch size too large");
|
||||
}
|
||||
|
||||
checkCuda(cudaMemcpyAsync(buffersRT[buf_input_idx], data, input_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
contextRT->enqueue(1, buffersRT, stream, nullptr);
|
||||
checkCuda(cudaMemcpyAsync(output, buffersRT[buf_output_idx], output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
cudaStreamSynchronize(stream);
|
||||
checkCuda(cudaMemcpyAsync(buffersRT[buf_input_idx], data, batches*input_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
contextRT->enqueue(batches, buffersRT, stream, nullptr);
|
||||
checkCuda(cudaMemcpyAsync(output, buffersRT[buf_output_idx], batches*output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToDevice, stream));
|
||||
checkCuda(cudaStreamSynchronize(stream));
|
||||
|
||||
dim = output_dim;
|
||||
dim.n = batches;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void NetworkRT::enqueue() {
|
||||
contextRT->enqueue(1, buffersRT, stream, nullptr);
|
||||
void NetworkRT::enqueue(int batchSize) {
|
||||
contextRT->enqueue(batchSize, buffersRT, stream, nullptr);
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) {
|
||||
@@ -166,12 +227,16 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) {
|
||||
return convert_layer(input, (Conv2d*) l);
|
||||
if(type == LAYER_POOLING)
|
||||
return convert_layer(input, (Pooling*) l);
|
||||
if(type == LAYER_ACTIVATION)
|
||||
if(type == LAYER_ACTIVATION || type == LAYER_ACTIVATION_CRELU || type == LAYER_ACTIVATION_LEAKY || type == LAYER_ACTIVATION_MISH || type == LAYER_ACTIVATION_LOGISTIC)
|
||||
return convert_layer(input, (Activation*) l);
|
||||
if(type == LAYER_SOFTMAX)
|
||||
return convert_layer(input, (Softmax*) l);
|
||||
if(type == LAYER_ROUTE)
|
||||
return convert_layer(input, (Route*) l);
|
||||
if(type == LAYER_FLATTEN)
|
||||
return convert_layer(input, (Flatten*) l);
|
||||
if(type == LAYER_RESHAPE)
|
||||
return convert_layer(input, (Reshape*) l);
|
||||
if(type == LAYER_REORG)
|
||||
return convert_layer(input, (Reorg*) l);
|
||||
if(type == LAYER_REGION)
|
||||
@@ -215,10 +280,11 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) {
|
||||
// printf("%d %d %d %d %d\n", l->kernelH, l->kernelW, l->inputs, l->outputs, l->batchnorm);
|
||||
|
||||
|
||||
void *data_b, *bias_b, *power_b, *mean_b, *variance_b, *scales_b;
|
||||
void *data_b, *bias_b, *bias2_b, *power_b, *mean_b, *variance_b, *scales_b;
|
||||
if(dtRT == DataType::kHALF) {
|
||||
data_b = l->data16_h;
|
||||
bias_b = l->bias16_h;
|
||||
bias2_b = l->bias216_h;
|
||||
power_b = l->power16_h;
|
||||
mean_b = l->mean16_h;
|
||||
variance_b = l->variance16_h;
|
||||
@@ -226,6 +292,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) {
|
||||
} else {
|
||||
data_b = l->data_h;
|
||||
bias_b = l->bias_h;
|
||||
bias2_b = l->bias2_h;
|
||||
power_b = l->power_h;
|
||||
mean_b = l->mean_h;
|
||||
variance_b = l->variance_h;
|
||||
@@ -237,8 +304,12 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) {
|
||||
Weights b;
|
||||
if(!l->batchnorm)
|
||||
b = { dtRT, bias_b, l->outputs};
|
||||
else
|
||||
b = { dtRT, nullptr, 0}; //on batchnorm bias are added later
|
||||
else{
|
||||
if (l->additional_bias)
|
||||
b = { dtRT, bias2_b, l->outputs};
|
||||
else
|
||||
b = { dtRT, nullptr, 0}; //on batchnorm bias are added later
|
||||
}
|
||||
|
||||
ILayer *lRT = nullptr;
|
||||
if(!l->deConv) {
|
||||
@@ -247,6 +318,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) {
|
||||
checkNULL(lRTconv);
|
||||
lRTconv->setStride(DimsHW{l->strideH, l->strideW});
|
||||
lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW});
|
||||
lRTconv->setNbGroups(l->groups);
|
||||
lRT = (ILayer*) lRTconv;
|
||||
} else {
|
||||
IDeconvolutionLayer *lRTconv = networkRT->addDeconvolution(*input,
|
||||
@@ -254,10 +326,11 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) {
|
||||
checkNULL(lRTconv);
|
||||
lRTconv->setStride(DimsHW{l->strideH, l->strideW});
|
||||
lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW});
|
||||
lRTconv->setNbGroups(l->groups);
|
||||
lRT = (ILayer*) lRTconv;
|
||||
|
||||
Dims d = lRTconv->getOutput(0)->getDimensions();
|
||||
std::cout<<"DECONV: "<<d.d[0]<<" "<<d.d[1]<<" "<<d.d[2]<<" "<<d.d[3]<<"\n";
|
||||
//std::cout<<"DECONV: "<<d.d[0]<<" "<<d.d[1]<<" "<<d.d[2]<<" "<<d.d[3]<<"\n";
|
||||
}
|
||||
|
||||
checkNULL(lRT);
|
||||
@@ -291,24 +364,22 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) {
|
||||
if(l->pool_mode == tkdnnPoolingMode_t::POOLING_AVERAGE) ptype = PoolingType::kAVERAGE;
|
||||
if(l->pool_mode == tkdnnPoolingMode_t::POOLING_AVERAGE_EXCLUDE_PADDING) ptype = PoolingType::kMAX_AVERAGE_BLEND;
|
||||
|
||||
|
||||
// if(l->input_dim.h % 2 == 1 && l->input_dim.w % 2 == 1)
|
||||
if(l->input_dim.h == l->output_dim.h && l->input_dim.w == l->output_dim.w)
|
||||
if(l->pool_mode == tkdnnPoolingMode_t::POOLING_MAX_FIXEDSIZE)
|
||||
{
|
||||
IPlugin *plugin = new ResizeLayerRT( l->output_dim.c,l->output_dim.h+1,l->output_dim.w+1 );
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
lRT->setName( "Resize" );
|
||||
|
||||
input = lRT->getOutput(0);
|
||||
IPlugin *plugin = new MaxPoolFixedSizeRT(l->output_dim.c, l->output_dim.h, l->output_dim.w, l->output_dim.n, l->strideH, l->strideW, l->winH, l->winH-1);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPoolingLayer *lRT = networkRT->addPooling(*input, ptype, DimsHW{l->winH, l->winW});
|
||||
checkNULL(lRT);
|
||||
|
||||
IPoolingLayer *lRT = networkRT->addPooling(*input, ptype, DimsHW{l->winH, l->winW});
|
||||
checkNULL(lRT);
|
||||
|
||||
lRT->setPadding(DimsHW{l->paddingH, l->paddingW});
|
||||
lRT->setStride(DimsHW{l->strideH, l->strideW});
|
||||
return lRT;
|
||||
lRT->setPadding(DimsHW{l->paddingH, l->paddingW});
|
||||
lRT->setStride(DimsHW{l->strideH, l->strideW});
|
||||
return lRT;
|
||||
}
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
|
||||
@@ -316,10 +387,19 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
|
||||
|
||||
if(l->act_mode == ACTIVATION_LEAKY) {
|
||||
//std::cout<<"New plugin LEAKY\n";
|
||||
|
||||
#if NV_TENSORRT_MAJOR < 6
|
||||
// plugin version
|
||||
IPlugin *plugin = new ActivationLeakyRT();
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
#else
|
||||
IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kLEAKY_RELU);
|
||||
lRT->setAlpha(0.1);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
#endif
|
||||
|
||||
} else if(l->act_mode == CUDNN_ACTIVATION_RELU) {
|
||||
IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kRELU);
|
||||
@@ -329,8 +409,26 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) {
|
||||
IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kSIGMOID);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
|
||||
} else {
|
||||
}
|
||||
else if(l->act_mode == CUDNN_ACTIVATION_CLIPPED_RELU) {
|
||||
IPlugin *plugin = new ActivationReLUCeiling(l->ceiling);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
else if(l->act_mode == ACTIVATION_MISH) {
|
||||
IPlugin *plugin = new ActivationMishRT();
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
else if(l->act_mode == ACTIVATION_LOGISTIC) {
|
||||
IPlugin *plugin = new ActivationLogisticRT();
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
else {
|
||||
FatalError("this Activation mode is not yet implemented");
|
||||
return NULL;
|
||||
}
|
||||
@@ -358,12 +456,33 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Route *l) {
|
||||
// }
|
||||
// std::cout<<"\n";
|
||||
}
|
||||
|
||||
IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n);
|
||||
//IPlugin *plugin = new RouteRT();
|
||||
//IPluginLayer *lRT = networkRT->addPlugin(tens, l->layers_n, *plugin);
|
||||
checkNULL(lRT);
|
||||
|
||||
if(l->groups > 1){
|
||||
IPlugin *plugin = new RouteRT(l->groups, l->group_id);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(tens, l->layers_n, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, Flatten *l) {
|
||||
|
||||
IPlugin *plugin = new FlattenConcatRT();
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, Reshape *l) {
|
||||
// std::cout<<"convert Reshape\n";
|
||||
|
||||
l->output_dim.print();
|
||||
IPlugin *plugin = new ReshapeRT(l->output_dim);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
|
||||
@@ -391,22 +510,33 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Shortcut *l) {
|
||||
//std::cout<<"convert Shortcut\n";
|
||||
|
||||
//std::cout<<"New plugin Shortcut\n";
|
||||
|
||||
ITensor *back_tens = tensors[l->backLayer];
|
||||
IPlugin *plugin = new ShortcutRT();
|
||||
|
||||
ITensor **inputs = new ITensor*[2];
|
||||
inputs[0] = input;
|
||||
inputs[1] = back_tens;
|
||||
IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
if(l->backLayer->output_dim.c == l->output_dim.c)
|
||||
{
|
||||
IElementWiseLayer *lRT = networkRT->addElementWise(*input, *back_tens, ElementWiseOperation::kSUM);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// plugin version
|
||||
IPlugin *plugin = new ShortcutRT(l->backLayer->output_dim);
|
||||
ITensor **inputs = new ITensor*[2];
|
||||
inputs[0] = input;
|
||||
inputs[1] = back_tens;
|
||||
IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
}
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, Yolo *l) {
|
||||
//std::cout<<"convert Yolo\n";
|
||||
|
||||
//std::cout<<"New plugin YOLO\n";
|
||||
IPlugin *plugin = new YoloRT(l->classes, l->num, l);
|
||||
IPlugin *plugin = new YoloRT(l->classes, l->num, l, l->n_masks, l->scaleXY, l->nms_thresh, l->nsm_kind, l->new_coords);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin);
|
||||
checkNULL(lRT);
|
||||
return lRT;
|
||||
@@ -423,7 +553,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Upsample *l) {
|
||||
}
|
||||
|
||||
ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
|
||||
std::cout<<"convert DEFORMABLE\n";
|
||||
//std::cout<<"convert DEFORMABLE\n";
|
||||
ILayer *preconv = convert_layer(input, l->preconv);
|
||||
checkNULL(preconv);
|
||||
|
||||
@@ -431,14 +561,14 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
|
||||
inputs[0] = input;
|
||||
inputs[1] = preconv->getOutput(0);
|
||||
|
||||
std::cout<<"New plugin DEFORMABLE\n";
|
||||
//std::cout<<"New plugin DEFORMABLE\n";
|
||||
IPlugin *plugin = new DeformableConvRT(l->chunk_dim, l->kernelH, l->kernelW, l->strideH, l->strideW, l->paddingH, l->paddingW,
|
||||
l->deformableGroup, l->input_dim.n, l->input_dim.c, l->input_dim.h, l->input_dim.w,
|
||||
l->output_dim.n, l->output_dim.c, l->output_dim.h, l->output_dim.w, l);
|
||||
IPluginLayer *lRT = networkRT->addPlugin(inputs, 2, *plugin);
|
||||
checkNULL(lRT);
|
||||
lRT->setName( ("Deformable" + std::to_string(l->id)).c_str() );
|
||||
|
||||
delete[](inputs);
|
||||
// batchnorm
|
||||
void *bias_b, *power_b, *mean_b, *variance_b, *scales_b;
|
||||
if(dtRT == DataType::kHALF) {
|
||||
@@ -458,7 +588,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
|
||||
Weights power{dtRT, power_b, l->outputs};
|
||||
Weights shift{dtRT, mean_b, l->outputs};
|
||||
Weights scale{dtRT, variance_b, l->outputs};
|
||||
std::cout<<lRT->getNbOutputs()<<std::endl;
|
||||
//std::cout<<lRT->getNbOutputs()<<std::endl;
|
||||
IScaleLayer *lRT2 = networkRT->addScale(*lRT->getOutput(0), ScaleMode::kCHANNEL,
|
||||
shift, scale, power);
|
||||
|
||||
@@ -475,7 +605,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *l) {
|
||||
|
||||
bool NetworkRT::serialize(const char *filename) {
|
||||
|
||||
std::ofstream p(filename);
|
||||
std::ofstream p(filename, std::ios::binary);
|
||||
if (!p) {
|
||||
FatalError("could not open plan output file");
|
||||
return false;
|
||||
@@ -515,59 +645,145 @@ bool NetworkRT::deserialize(const char *filename) {
|
||||
|
||||
|
||||
IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialData, size_t serialLength) {
|
||||
const char * buf = reinterpret_cast<const char*>(serialData);
|
||||
const char * buf = reinterpret_cast<const char*>(serialData),*bufCheck = buf;
|
||||
|
||||
std::string name(layerName);
|
||||
std::cout<<name<<std::endl;
|
||||
//std::cout<<name<<std::endl;
|
||||
|
||||
if(name.find("Activation") == 0) {
|
||||
if(name.find("ActivationLeaky") == 0) {
|
||||
ActivationLeakyRT *a = new ActivationLeakyRT();
|
||||
a->size = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return a;
|
||||
}
|
||||
if(name.find("ActivationMish") == 0) {
|
||||
ActivationMishRT *a = new ActivationMishRT();
|
||||
a->size = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return a;
|
||||
}
|
||||
if(name.find("ActivationLogistic") == 0) {
|
||||
ActivationLogisticRT *a = new ActivationLogisticRT();
|
||||
a->size = readBUF<int>(buf);
|
||||
return a;
|
||||
}
|
||||
if(name.find("ActivationLogistic") == 0) {
|
||||
ActivationLogisticRT *a = new ActivationLogisticRT();
|
||||
a->size = readBUF<int>(buf);
|
||||
return a;
|
||||
}
|
||||
if(name.find("ActivationCReLU") == 0) {
|
||||
float activationReluTemp = readBUF<float>(buf);
|
||||
ActivationReLUCeiling* a = new ActivationReLUCeiling(activationReluTemp);
|
||||
a->size = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return a;
|
||||
}
|
||||
|
||||
if(name.find("Region") == 0) {
|
||||
RegionRT *r = new RegionRT(readBUF<int>(buf), //classes
|
||||
readBUF<int>(buf), //coords
|
||||
readBUF<int>(buf)); //num
|
||||
int classesTemp = readBUF<int>(buf);
|
||||
int coordsTemp = readBUF<int>(buf);
|
||||
int numTemp = readBUF<int>(buf);
|
||||
RegionRT* r = new RegionRT(classesTemp, coordsTemp, numTemp);
|
||||
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Reorg") == 0) {
|
||||
ReorgRT *r = new ReorgRT(readBUF<int>(buf)); //stride
|
||||
int strideTemp = readBUF<int>(buf);
|
||||
ReorgRT *r = new ReorgRT(strideTemp);
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Shortcut") == 0) {
|
||||
ShortcutRT *r = new ShortcutRT();
|
||||
tk::dnn::dataDim_t bdim;
|
||||
bdim.c = readBUF<int>(buf);
|
||||
bdim.h = readBUF<int>(buf);
|
||||
bdim.w = readBUF<int>(buf);
|
||||
bdim.l = 1;
|
||||
|
||||
ShortcutRT *r = new ShortcutRT(bdim);
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
return r;
|
||||
assert(buf == bufCheck + serialLength);
|
||||
}
|
||||
|
||||
if(name.find("Pooling") == 0) {
|
||||
int cTemp = readBUF<int>(buf);
|
||||
int hTemp = readBUF<int>(buf);
|
||||
int wTemp = readBUF<int>(buf);
|
||||
int nTemp = readBUF<int>(buf);
|
||||
int strideHTemp = readBUF<int>(buf);
|
||||
int strideWTemp = readBUF<int>(buf);
|
||||
int winSizeTemp = readBUF<int>(buf);
|
||||
int paddingTemp = readBUF<int>(buf);
|
||||
|
||||
MaxPoolFixedSizeRT* r = new MaxPoolFixedSizeRT(cTemp, hTemp, wTemp, nTemp, strideHTemp, strideWTemp, winSizeTemp, paddingTemp);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Resize") == 0) {
|
||||
ResizeLayerRT *r = new ResizeLayerRT(readBUF<int>(buf), //o_c
|
||||
readBUF<int>(buf), //o_h
|
||||
readBUF<int>(buf)); //o_w
|
||||
int o_cTemp = readBUF<int>(buf);
|
||||
int o_hTemp = readBUF<int>(buf);
|
||||
int o_wTemp = readBUF<int>(buf);
|
||||
ResizeLayerRT* r = new ResizeLayerRT(o_cTemp, o_hTemp, o_wTemp);
|
||||
|
||||
r->i_c = readBUF<int>(buf);
|
||||
r->i_h = readBUF<int>(buf);
|
||||
r->i_w = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Flatten") == 0) {
|
||||
FlattenConcatRT *r = new FlattenConcatRT();
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
r->rows = readBUF<int>(buf);
|
||||
r->cols = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Reshape") == 0) {
|
||||
|
||||
dataDim_t new_dim;
|
||||
new_dim.n = readBUF<int>(buf);
|
||||
new_dim.c = readBUF<int>(buf);
|
||||
new_dim.h = readBUF<int>(buf);
|
||||
new_dim.w = readBUF<int>(buf);
|
||||
ReshapeRT *r = new ReshapeRT(new_dim);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
if(name.find("Yolo") == 0) {
|
||||
YoloRT *r = new YoloRT(readBUF<int>(buf), //classes
|
||||
readBUF<int>(buf), //num
|
||||
nullptr,
|
||||
readBUF<int>(buf)); //n_masks
|
||||
|
||||
int classes_temp = readBUF<int>(buf);
|
||||
int num_temp = readBUF<int>(buf);
|
||||
int n_masks_temp = readBUF<int>(buf);
|
||||
float scale_xy_temp = readBUF<float>(buf);
|
||||
float nms_thresh_temp = readBUF<float>(buf);
|
||||
int nms_kind_temp = readBUF<int>(buf);
|
||||
int new_coords_temp = readBUF<int>(buf);
|
||||
|
||||
YoloRT *r = new YoloRT(classes_temp,num_temp,nullptr,n_masks_temp,scale_xy_temp,nms_thresh_temp,nms_kind_temp,new_coords_temp);
|
||||
|
||||
|
||||
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
@@ -584,36 +800,54 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
|
||||
tmp[j] = readBUF<char>(buf);
|
||||
r->classesNames[i] = std::string(tmp);
|
||||
}
|
||||
assert(buf == bufCheck + serialLength);
|
||||
|
||||
yolos[n_yolos++] = r;
|
||||
return r;
|
||||
}
|
||||
if(name.find("Upsample") == 0) {
|
||||
UpsampleRT *r = new UpsampleRT(readBUF<int>(buf)); //stride
|
||||
int strideTemp = readBUF<int>(buf);
|
||||
UpsampleRT* r = new UpsampleRT(strideTemp);
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
|
||||
if(name.find("Route") == 0) {
|
||||
RouteRT *r = new RouteRT();
|
||||
int groupsTemp = readBUF<int>(buf);
|
||||
int group_idTemp = readBUF<int>(buf);
|
||||
RouteRT* r = new RouteRT(groupsTemp, group_idTemp);
|
||||
r->in = readBUF<int>(buf);
|
||||
for(int i=0; i<RouteRT::MAX_INPUTS; i++)
|
||||
r->c_in[i] = readBUF<int>(buf);
|
||||
r->c = readBUF<int>(buf);
|
||||
r->h = readBUF<int>(buf);
|
||||
r->w = readBUF<int>(buf);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
*/
|
||||
|
||||
if(name.find("Deformable") == 0) {
|
||||
DeformableConvRT *r = new DeformableConvRT(readBUF<int>(buf), readBUF<int>(buf), readBUF<int>(buf),
|
||||
readBUF<int>(buf), readBUF<int>(buf), readBUF<int>(buf),
|
||||
readBUF<int>(buf), readBUF<int>(buf),
|
||||
readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),
|
||||
readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),readBUF<int>(buf),
|
||||
nullptr);
|
||||
int chuck_dimTemp = readBUF<int>(buf);
|
||||
int khTemp = readBUF<int>(buf);
|
||||
int kwTemp = readBUF<int>(buf);
|
||||
int shTemp = readBUF<int>(buf);
|
||||
int swTemp = readBUF<int>(buf);
|
||||
int phTemp = readBUF<int>(buf);
|
||||
int pwTemp = readBUF<int>(buf);
|
||||
int deformableGroupTemp = readBUF<int>(buf);
|
||||
int i_nTemp = readBUF<int>(buf);
|
||||
int i_cTemp = readBUF<int>(buf);
|
||||
int i_hTemp = readBUF<int>(buf);
|
||||
int i_wTemp = readBUF<int>(buf);
|
||||
int o_nTemp = readBUF<int>(buf);
|
||||
int o_cTemp = readBUF<int>(buf);
|
||||
int o_hTemp = readBUF<int>(buf);
|
||||
int o_wTemp = readBUF<int>(buf);
|
||||
|
||||
DeformableConvRT* r = new DeformableConvRT(chuck_dimTemp, khTemp, kwTemp, shTemp, swTemp, phTemp, pwTemp, deformableGroupTemp, i_nTemp, i_cTemp, i_hTemp, i_wTemp, o_nTemp, o_cTemp, o_hTemp, o_wTemp, nullptr);
|
||||
dnnType *aus = new dnnType[r->chunk_dim*2];
|
||||
for(int i=0; i<r->chunk_dim*2; i++)
|
||||
aus[i] = readBUF<dnnType>(buf);
|
||||
@@ -644,6 +878,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa
|
||||
aus[i] = readBUF<dnnType>(buf);
|
||||
checkCuda( cudaMemcpy(r->ones_d2, aus, sizeof(dnnType)*r->dim_ones, cudaMemcpyHostToDevice) );
|
||||
free(aus);
|
||||
assert(buf == bufCheck + serialLength);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include "tkDNN/NetworkViz.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
cv::Mat vizFloat2colorMap(cv::Mat map) {
|
||||
|
||||
double min;
|
||||
double max;
|
||||
cv::minMaxIdx(map, &min, &max);
|
||||
cv::Mat adjMap;
|
||||
// expand your range to 0..255. Similar to histEq();
|
||||
map.convertTo(adjMap,CV_8UC1, 255 / (max-min), -min);
|
||||
//return adjMap;
|
||||
|
||||
|
||||
cv::Mat falseColorsMap;
|
||||
applyColorMap(adjMap, falseColorsMap, cv::COLORMAP_HOT);
|
||||
return falseColorsMap;
|
||||
}
|
||||
|
||||
cv::Mat vizData2Mat(dnnType *dataInput, tk::dnn::dataDim_t dim, int imgdim) {
|
||||
dnnType *data = nullptr;
|
||||
|
||||
// copy to CPU
|
||||
if(isCudaPointer(dataInput)) {
|
||||
data = new dnnType[dim.tot()];
|
||||
checkCuda( cudaMemcpy(data, dataInput, dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
|
||||
} else {
|
||||
data = dataInput;
|
||||
}
|
||||
|
||||
int gridDim = ceil(sqrt(dim.c));
|
||||
cv::Size gridSize(dim.w*gridDim, dim.h*gridDim);
|
||||
cv::Mat grid = cv::Mat(gridSize, CV_8UC3, cv::Scalar(0));
|
||||
|
||||
for(int i=0; i<dim.c;i++) {
|
||||
cv::Mat raw = vizFloat2colorMap(cv::Mat(cv::Size(dim.w, dim.h),CV_32FC1, data + dim.w*dim.h*i));
|
||||
int r = i / gridDim;
|
||||
int c = i - r * gridDim;
|
||||
raw.copyTo(grid.rowRange(r*dim.h, r*dim.h + dim.h).colRange(c*dim.w, c*dim.w + dim.w));
|
||||
}
|
||||
|
||||
float ar = float(dim.w)/dim.h;
|
||||
cv::Size vdim(ar*imgdim, imgdim);
|
||||
cv::Mat viz;
|
||||
cv::resize(grid, viz, vdim, 0, 0, 0);
|
||||
|
||||
// free memory
|
||||
if(isCudaPointer(dataInput)) {
|
||||
delete [] data;
|
||||
}
|
||||
return viz;
|
||||
}
|
||||
|
||||
cv::Mat vizLayer2Mat(tk::dnn::Network *net, int layer, int imgdim) {
|
||||
if(layer >= net->num_layers)
|
||||
FatalError("Could not viz layer\n");
|
||||
return vizData2Mat(net->layers[layer]->dstData, net->layers[layer]->output_dim, imgdim);
|
||||
|
||||
//cv::imwrite("viz/layer" + std::to_string(layer) + ".png", viz);
|
||||
//cv::imshow("layer", viz);
|
||||
//cv::waitKey(0);
|
||||
}
|
||||
|
||||
}}
|
||||
+22
-18
@@ -7,8 +7,8 @@ namespace tk { namespace dnn {
|
||||
|
||||
Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW,
|
||||
int paddingH, int paddingW,
|
||||
tkdnnPoolingMode_t pool_mode, bool final) :
|
||||
Layer(net, final) {
|
||||
tkdnnPoolingMode_t pool_mode) :
|
||||
Layer(net) {
|
||||
|
||||
this->winH = winH;
|
||||
this->winW = winW;
|
||||
@@ -39,9 +39,10 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW,
|
||||
n = l;
|
||||
}
|
||||
|
||||
|
||||
cudnnPoolingMode_t cudnn_pool_mode = cudnnPoolingMode_t(pool_mode);
|
||||
if(pool_mode == POOLING_MAX_FIXEDSIZE) cudnn_pool_mode = cudnnPoolingMode_t(tkdnnPoolingMode_t::POOLING_MAX);
|
||||
|
||||
checkCUDNN( cudnnSetPooling2dDescriptor(poolingDesc, cudnnPoolingMode_t(pool_mode),
|
||||
checkCUDNN( cudnnSetPooling2dDescriptor(poolingDesc, cudnn_pool_mode,
|
||||
CUDNN_NOT_PROPAGATE_NAN, winH, winW, paddingH, paddingW, strideH, strideW) );
|
||||
|
||||
checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc,
|
||||
@@ -51,18 +52,16 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW,
|
||||
// checkCUDNN( cudnnGetPooling2dForwardOutputDim(poolingDesc, srcTensorDesc, &n, &c, &h, &w));
|
||||
|
||||
//compute w and h as in darknet
|
||||
int padH = paddingH == 0? winH -1 : paddingH;
|
||||
int padW = paddingW == 0? winW -1 : paddingW;
|
||||
|
||||
if(final){
|
||||
h = (h + padH - winH)/strideH +1 +1;
|
||||
w = (w + padW - winW)/strideW +1 +1;
|
||||
}
|
||||
else{
|
||||
if(pool_mode == tkdnnPoolingMode_t::POOLING_MAX_FIXEDSIZE){
|
||||
int padH = paddingH == 0? winH -1 : paddingH;
|
||||
int padW = paddingW == 0? winW -1 : paddingW;
|
||||
h = (h + padH - winH)/strideH +1;
|
||||
w = (w + padW - winW)/strideW +1;
|
||||
}
|
||||
|
||||
else{
|
||||
h = (h + 2*paddingH - winH)/strideH +1 ;
|
||||
w = (w + 2*paddingW - winW)/strideW +1;
|
||||
}
|
||||
|
||||
// h = (h + winH*this->paddingH)/strideH;
|
||||
// w = (w + winW*this->paddingW)/strideW;
|
||||
@@ -111,11 +110,16 @@ dnnType* Pooling::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
poolDst = tmpOutputData;
|
||||
}
|
||||
|
||||
dnnType alpha = dnnType(1);
|
||||
dnnType beta = dnnType(0);
|
||||
checkCUDNN( cudnnPoolingForward(net->cudnnHandle, poolingDesc,
|
||||
&alpha, srcTensorDesc, poolSrc,
|
||||
&beta, dstTensorDesc, poolDst) );
|
||||
if(pool_mode == tkdnnPoolingMode_t::POOLING_MAX_FIXEDSIZE){
|
||||
MaxPoolingForward(poolSrc, poolDst, dim.n, dim.c, dim.h, dim.w, this->strideH, this->strideW, this->winH, this->winH-1);
|
||||
}
|
||||
else{
|
||||
dnnType alpha = dnnType(1);
|
||||
dnnType beta = dnnType(0);
|
||||
checkCUDNN( cudnnPoolingForward(net->cudnnHandle, poolingDesc,
|
||||
&alpha, srcTensorDesc, poolSrc,
|
||||
&beta, dstTensorDesc, poolDst) );
|
||||
}
|
||||
|
||||
//update dim
|
||||
dim = output_dim;
|
||||
|
||||
+2
-3
@@ -12,8 +12,7 @@
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Region::Region(Network *net, int classes, int coords, int num) :
|
||||
Layer(net) {
|
||||
|
||||
Layer(net) {
|
||||
this->classes = classes;
|
||||
this->coords = coords;
|
||||
this->num = num;
|
||||
@@ -64,7 +63,7 @@ dnnType* Region::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
}
|
||||
|
||||
|
||||
/* Intepret class */
|
||||
/* Interpret class */
|
||||
RegionInterpret::RegionInterpret(dataDim_t input_dim, dataDim_t output_dim,
|
||||
int classes, int coords, int num, float thresh, std::string fname_weights) {
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Layer.h"
|
||||
#include "kernels.h"
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Reshape::Reshape(Network *net, dataDim_t new_dim) : Layer(net) {
|
||||
|
||||
checkCuda( cudaMalloc(&dstData, input_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
output_dim.n = new_dim.n;
|
||||
output_dim.c = new_dim.c;
|
||||
output_dim.h = new_dim.h;
|
||||
output_dim.w = new_dim.w;
|
||||
output_dim.l = new_dim.l;
|
||||
|
||||
}
|
||||
|
||||
Reshape::~Reshape() {
|
||||
|
||||
checkCuda( cudaFree(dstData) );
|
||||
}
|
||||
|
||||
dnnType* Reshape::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
|
||||
//just copies the data and changes the output dim
|
||||
checkCuda( cudaMemcpy(dstData, srcData, dim.n*dim.c*dim.h*dim.w*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
dim = output_dim;
|
||||
|
||||
return dstData;
|
||||
}
|
||||
|
||||
}}
|
||||
+14
-7
@@ -5,13 +5,18 @@
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) {
|
||||
Route::Route(Network *net, Layer **layers, int layers_n, int groups, int group_id) : Layer(net) {
|
||||
|
||||
this->layers_n = layers_n;
|
||||
if(layers_n > MAX_INPUT_LAYERS)
|
||||
FatalError("Route: MAX INPUT LAYERS overload");
|
||||
for(int i=0; i<layers_n; i++)
|
||||
// copy input layers
|
||||
if(layers_n > MAX_LAYERS) {
|
||||
FatalError("ROUTE: reached max number of input layers");
|
||||
}
|
||||
for(int i=0; i<layers_n; i++) {
|
||||
this->layers[i] = layers[i];
|
||||
}
|
||||
this->layers_n = layers_n;
|
||||
this->groups = groups;
|
||||
this->group_id = group_id;
|
||||
|
||||
//get dims
|
||||
output_dim.l = 1;
|
||||
@@ -29,6 +34,7 @@ Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) {
|
||||
output_dim.c += layers[i]->output_dim.c;
|
||||
}
|
||||
|
||||
output_dim.c /= this->groups;
|
||||
input_dim = output_dim;
|
||||
|
||||
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
|
||||
@@ -46,8 +52,9 @@ dnnType* Route::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
for(int i=0; i<layers_n; i++) {
|
||||
dnnType *input = layers[i]->dstData;
|
||||
int in_dim = layers[i]->output_dim.tot();
|
||||
checkCuda( cudaMemcpy(dstData + offset, input, in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
offset += in_dim;
|
||||
int part_in_dim = in_dim / this->groups;
|
||||
checkCuda( cudaMemcpy(dstData + offset, input + this->group_id*part_in_dim, part_in_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice));
|
||||
offset += part_in_dim;
|
||||
}
|
||||
|
||||
//update data dimensions
|
||||
|
||||
+2
-2
@@ -10,10 +10,10 @@ Shortcut::Shortcut(Network *net, Layer *backLayer) : Layer(net) {
|
||||
this->backLayer = backLayer;
|
||||
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
if( backLayer->output_dim.c != input_dim.c ||
|
||||
if( /*backLayer->output_dim.c != input_dim.c ||*/
|
||||
backLayer->output_dim.w != input_dim.w ||
|
||||
backLayer->output_dim.h != input_dim.h )
|
||||
FatalError("Shortcut dim missmatch");
|
||||
FatalError("Shortcut dim mismatch");
|
||||
}
|
||||
|
||||
Shortcut::~Shortcut() {
|
||||
|
||||
+26
-8
@@ -5,22 +5,40 @@
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Softmax::Softmax(Network *net) : Layer(net) {
|
||||
Softmax::Softmax(Network *net, const tk::dnn::dataDim_t* dim, const cudnnSoftmaxMode_t mode) : Layer(net) {
|
||||
|
||||
checkCuda( cudaMalloc(&dstData, input_dim.tot()*sizeof(dnnType)) );
|
||||
|
||||
this->mode = mode;
|
||||
if(dim == nullptr)
|
||||
{
|
||||
this->dim.n= input_dim.n;
|
||||
this->dim.c= input_dim.c;
|
||||
this->dim.h= input_dim.h;
|
||||
this->dim.w= input_dim.w;
|
||||
this->dim.l= input_dim.l;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->dim.n= dim->n;
|
||||
this->dim.c= dim->c;
|
||||
this->dim.h= dim->h;
|
||||
this->dim.w= dim->w;
|
||||
this->dim.l= dim->l;
|
||||
}
|
||||
|
||||
checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc,
|
||||
net->tensorFormat,
|
||||
net->dataType,
|
||||
input_dim.n*input_dim.l,
|
||||
input_dim.c,
|
||||
input_dim.h, input_dim.w) );
|
||||
this->dim.n*this->dim.l,
|
||||
this->dim.c,
|
||||
this->dim.h, this->dim.w) );
|
||||
checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc,
|
||||
net->tensorFormat,
|
||||
net->dataType,
|
||||
input_dim.n*input_dim.l,
|
||||
input_dim.c,
|
||||
input_dim.h, input_dim.w) );
|
||||
this->dim.n*this->dim.l,
|
||||
this->dim.c,
|
||||
this->dim.h, this->dim.w) );
|
||||
}
|
||||
|
||||
Softmax::~Softmax() {
|
||||
@@ -34,7 +52,7 @@ dnnType* Softmax::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
dnnType beta = dnnType(0);
|
||||
checkCUDNN( cudnnSoftmaxForward(net->cudnnHandle,
|
||||
CUDNN_SOFTMAX_ACCURATE ,
|
||||
CUDNN_SOFTMAX_MODE_CHANNEL,
|
||||
this->mode,
|
||||
&alpha,
|
||||
srcTensorDesc,
|
||||
srcData,
|
||||
|
||||
+65
-18
@@ -9,14 +9,20 @@
|
||||
#include "Layer.h"
|
||||
#include "kernels.h"
|
||||
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks) :
|
||||
Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks, float scale_xy, double nms_thresh, nmsKind_t nsm_kind, int new_coords) :
|
||||
Layer(net) {
|
||||
|
||||
this->final = true;
|
||||
|
||||
this->classes = classes;
|
||||
this->num = num;
|
||||
this->n_masks = n_masks;
|
||||
this->scaleXY = scale_xy;
|
||||
this->nms_thresh = nms_thresh;
|
||||
this->nsm_kind = nsm_kind;
|
||||
this->new_coords = new_coords;
|
||||
|
||||
// load anchors
|
||||
if(fname_weights != "") {
|
||||
@@ -57,12 +63,21 @@ int entry_index(int batch, int location, int entry,
|
||||
entry*input_dim.w*input_dim.h + loc;
|
||||
}
|
||||
|
||||
Yolo::box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride) {
|
||||
Yolo::box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride, int new_coords) {
|
||||
Yolo::box b;
|
||||
b.x = (i + x[index + 0*stride]) / lw;
|
||||
b.y = (j + x[index + 1*stride]) / lh;
|
||||
b.w = exp(x[index + 2*stride]) * biases[2*n] / w;
|
||||
b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;
|
||||
|
||||
if(new_coords == 0){
|
||||
b.x = (i + x[index + 0*stride]) / lw;
|
||||
b.y = (j + x[index + 1*stride]) / lh;
|
||||
b.w = exp(x[index + 2*stride]) * biases[2*n] / w;
|
||||
b.h = exp(x[index + 3*stride]) * biases[2*n+1] / h;
|
||||
}
|
||||
else{
|
||||
b.x = (i + x[index + 0 * stride] ) / lw;
|
||||
b.y = (j + x[index + 1 * stride] ) / lh;
|
||||
b.w = x[index + 2 * stride] * x[index + 2 * stride] * 4 * biases[2 * n] / w;
|
||||
b.h = x[index + 3 * stride] * x[index + 3 * stride] * 4 * biases[2 * n + 1] / h;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -73,10 +88,17 @@ dnnType* Yolo::infer(dataDim_t &dim, dnnType* srcData) {
|
||||
for (int b = 0; b < dim.n; ++b){
|
||||
for(int n = 0; n < n_masks; ++n){
|
||||
int index = entry_index(b, n*dim.w*dim.h, 0, classes, input_dim, output_dim);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, 2*dim.w*dim.h);
|
||||
|
||||
index = entry_index(b, n*dim.w*dim.h, 4, classes, input_dim, output_dim);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*dim.w*dim.h);
|
||||
std::cout<<"new_coords"<<new_coords<<std::endl;
|
||||
if (new_coords == 1){
|
||||
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * dim.w*dim.h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
|
||||
}
|
||||
else{
|
||||
activationLOGISTICForward(srcData + index, dstData + index, 2*dim.w*dim.h);
|
||||
|
||||
if (this->scaleXY != 1) scalAdd(dstData + index, 2 * dim.w*dim.h, this->scaleXY, -0.5*(this->scaleXY - 1), 1);
|
||||
index = entry_index(b, n*dim.w*dim.h, 4, classes, input_dim, output_dim);
|
||||
activationLOGISTICForward(srcData + index, dstData + index, (1+classes)*dim.w*dim.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +134,7 @@ void correct_yolo_boxes(Yolo::detection *dets, int n, int w, int h, int netw, in
|
||||
}
|
||||
}
|
||||
|
||||
int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh) {
|
||||
int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh, int new_coords) {
|
||||
|
||||
if(predictions == nullptr)
|
||||
predictions = new dnnType[output_dim.tot()];
|
||||
@@ -136,7 +158,7 @@ int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int net
|
||||
if(objectness <= thresh) continue;
|
||||
int box_index = entry_index(0, n*lw*lh + i, 0, classes, input_dim, output_dim);
|
||||
|
||||
dets[count].bbox = get_yolo_box(predictions, bias_h, mask_h[n], box_index, col, row, lw, lh, netw, neth, lw*lh);
|
||||
dets[count].bbox = get_yolo_box(predictions, bias_h, mask_h[n], box_index, col, row, lw, lh, netw, neth, lw*lh, new_coords);
|
||||
dets[count].objectness = objectness;
|
||||
dets[count].classes = classes;
|
||||
for(j = 0; j < classes; ++j){
|
||||
@@ -189,6 +211,32 @@ float yolo_box_iou(Yolo::box a, Yolo::box b)
|
||||
return yolo_box_intersection(a, b)/yolo_box_union(a, b);
|
||||
}
|
||||
|
||||
void box_c(const Yolo::box a, const Yolo::box b, float& top, float& bot, float& left, float& right) {
|
||||
top = (std::min)(a.y - a.h / 2, b.y - b.h / 2);
|
||||
bot = (std::max)(a.y + a.h / 2, b.y + b.h / 2);
|
||||
left = (std::min)(a.x - a.w / 2, b.x - b.w / 2);
|
||||
right = (std::max)(a.x + a.w / 2, b.x + b.w / 2);
|
||||
}
|
||||
|
||||
// https://github.com/Zzh-tju/DIoU-darknet
|
||||
// https://arxiv.org/abs/1911.08287
|
||||
float yolo_box_diou(const Yolo::box a, const Yolo::box b, const float nms_thresh=0.6)
|
||||
{
|
||||
float top, bot, left, right;
|
||||
box_c(a, b, top, bot, left, right);
|
||||
float w = right - left;
|
||||
float h = bot - top;
|
||||
float c = w * w + h * h;
|
||||
float iou = yolo_box_iou(a, b);
|
||||
if (c == 0)
|
||||
return iou;
|
||||
|
||||
float d = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
|
||||
float u = pow(d / c, nms_thresh);
|
||||
float diou_term = u;
|
||||
return iou - diou_term;
|
||||
}
|
||||
|
||||
int yolo_nms_comparator(const void *pa, const void *pb)
|
||||
{
|
||||
Yolo::detection a = *(Yolo::detection *)pa;
|
||||
@@ -215,8 +263,7 @@ Yolo::detection *Yolo::allocateDetections(int nboxes, int classes) {
|
||||
return dets;
|
||||
}
|
||||
|
||||
void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) {
|
||||
double nms_thresh = 0.45;
|
||||
void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes, double nms_thresh, nmsKind_t nsm_kind) {
|
||||
int total = ndets;
|
||||
|
||||
int i, j, k;
|
||||
@@ -242,13 +289,13 @@ void Yolo::mergeDetections(Yolo::detection *dets, int ndets, int classes) {
|
||||
box a = dets[i].bbox;
|
||||
for(j = i+1; j < total; ++j){
|
||||
box b = dets[j].bbox;
|
||||
if (yolo_box_iou(a, b) > nms_thresh){
|
||||
if (nsm_kind == GREEDY_NMS && yolo_box_iou(a, b) > nms_thresh)
|
||||
dets[j].prob[k] = 0;
|
||||
else if (nsm_kind == DIOU_NMS && yolo_box_diou(a, b, nms_thresh) > nms_thresh)
|
||||
dets[j].prob[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
+101
-91
@@ -1,27 +1,18 @@
|
||||
#include "Yolo3Detection.h"
|
||||
|
||||
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
float _colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
|
||||
float get_color(int c, int x, int max)
|
||||
{
|
||||
float ratio = ((float)x/max)*5;
|
||||
int i = floor(ratio);
|
||||
int j = ceil(ratio);
|
||||
ratio -= i;
|
||||
float r = (1-ratio) * _colors[i % 6][c % 3] + ratio*_colors[j % 6][c % 3];
|
||||
//printf("%f\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Yolo3Detection::init(std::string tensor_path) {
|
||||
|
||||
//const char *tensor_path = "../data/yolo3/yolo3_berkeley.rt";
|
||||
bool Yolo3Detection::init(const std::string& tensor_path, const int n_classes, const int n_batches, const float conf_thresh) {
|
||||
|
||||
//convert network to tensorRT
|
||||
std::cout<<(tensor_path).c_str()<<"\n";
|
||||
netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str() );
|
||||
|
||||
nBatches = n_batches;
|
||||
confThreshold = conf_thresh;
|
||||
tk::dnn::dataDim_t idim = netRT->input_dim;
|
||||
idim.n = nBatches;
|
||||
|
||||
if(netRT->pluginFactory->n_yolos < 2 ) {
|
||||
FatalError("this is not yolo3");
|
||||
@@ -31,122 +22,141 @@ bool Yolo3Detection::init(std::string tensor_path) {
|
||||
YoloRT *yRT = netRT->pluginFactory->yolos[i];
|
||||
classes = yRT->classes;
|
||||
num = yRT->num;
|
||||
n_masks = yRT->n_masks;
|
||||
nMasks = yRT->n_masks;
|
||||
|
||||
// make a yolo layer for interpret predictions
|
||||
yolo[i] = new tk::dnn::Yolo(nullptr, classes, n_masks, ""); // yolo without input and bias
|
||||
yolo[i]->mask_h = new dnnType[n_masks];
|
||||
yolo[i]->bias_h = new dnnType[num*n_masks*2];
|
||||
memcpy(yolo[i]->mask_h, yRT->mask, sizeof(dnnType)*n_masks);
|
||||
memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*n_masks*2);
|
||||
// make a yolo layer to interpret predictions
|
||||
yolo[i] = new tk::dnn::Yolo(nullptr, classes, nMasks, ""); // yolo without input and bias
|
||||
yolo[i]->mask_h = new dnnType[nMasks];
|
||||
yolo[i]->bias_h = new dnnType[num*nMasks*2];
|
||||
memcpy(yolo[i]->mask_h, yRT->mask, sizeof(dnnType)*nMasks);
|
||||
memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*nMasks*2);
|
||||
yolo[i]->input_dim = yolo[i]->output_dim = tk::dnn::dataDim_t(1, yRT->c, yRT->h, yRT->w);
|
||||
yolo[i]->classesNames = yRT->classesNames;
|
||||
yolo[i]->nms_thresh = yRT->nms_thresh;
|
||||
yolo[i]->nsm_kind = (tk::dnn::Yolo::nmsKind_t) yRT->nms_kind;
|
||||
yolo[i]->new_coords = yRT->new_coords;
|
||||
}
|
||||
|
||||
dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes);
|
||||
|
||||
checkCuda(cudaMallocHost(&input, sizeof(dnnType)*netRT->input_dim.tot()));
|
||||
checkCuda(cudaMalloc(&input_d, sizeof(dnnType)*netRT->input_dim.tot()));
|
||||
|
||||
#ifndef OPENCV_CUDACONTRIB
|
||||
checkCuda(cudaMallocHost(&input, sizeof(dnnType)*idim.tot()));
|
||||
#endif
|
||||
checkCuda(cudaMalloc(&input_d, sizeof(dnnType)*idim.tot()));
|
||||
|
||||
// class colors precompute
|
||||
for(int c=0; c<classes; c++) {
|
||||
int offset = c*123457 % classes;
|
||||
float r = get_color(2, offset, classes);
|
||||
float g = get_color(1, offset, classes);
|
||||
float b = get_color(0, offset, classes);
|
||||
float r = getColor(2, offset, classes);
|
||||
float g = getColor(1, offset, classes);
|
||||
float b = getColor(0, offset, classes);
|
||||
colors[c] = cv::Scalar(int(255.0*b), int(255.0*g), int(255.0*r));
|
||||
}
|
||||
|
||||
classesNames = getYoloLayer()->classesNames;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Yolo3Detection::preprocess(cv::Mat &frame, const int bi){
|
||||
#ifdef OPENCV_CUDACONTRIB
|
||||
cv::cuda::GpuMat orig_img, img_resized;
|
||||
orig_img = cv::cuda::GpuMat(frame);
|
||||
cv::cuda::resize(orig_img, img_resized, cv::Size(netRT->input_dim.w, netRT->input_dim.h));
|
||||
|
||||
void Yolo3Detection::update(cv::Mat &imageORIG) {
|
||||
|
||||
if(!imageORIG.data) {
|
||||
std::cout<<"YOLO: NO IMAGE DATA\n";
|
||||
return;
|
||||
}
|
||||
float xRatio = float(imageORIG.cols) / float(netRT->input_dim.w);
|
||||
float yRatio = float(imageORIG.rows) / float(netRT->input_dim.h);
|
||||
|
||||
resize(imageORIG, imageORIG, cv::Size(netRT->input_dim.w, netRT->input_dim.h));
|
||||
|
||||
imageORIG.convertTo(imageF, CV_32FC3, 1/255.0);
|
||||
img_resized.convertTo(imagePreproc, CV_32FC3, 1/255.0);
|
||||
|
||||
//split channels
|
||||
cv::split(imageF,bgr);//split source
|
||||
cv::cuda::split(imagePreproc,bgr);//split source
|
||||
|
||||
//write channels
|
||||
for(int i=0; i<netRT->input_dim.c; i++) {
|
||||
int idx = i*imageF.rows*imageF.cols;
|
||||
int size = imagePreproc.rows * imagePreproc.cols;
|
||||
int ch = netRT->input_dim.c-1 -i;
|
||||
memcpy((void*)&input[idx], (void*)bgr[ch].data, imageF.rows*imageF.cols*sizeof(dnnType));
|
||||
bgr[ch].download(bgr_h); //TODO: don't copy back on CPU
|
||||
checkCuda( cudaMemcpy(input_d + i*size + netRT->input_dim.tot()*bi, (float*)bgr_h.data, size*sizeof(dnnType), cudaMemcpyHostToDevice));
|
||||
}
|
||||
#else
|
||||
cv::resize(frame, frame, cv::Size(netRT->input_dim.w, netRT->input_dim.h));
|
||||
frame.convertTo(imagePreproc, CV_32FC3, 1/255.0);
|
||||
|
||||
//split channels
|
||||
cv::split(imagePreproc,bgr);//split source
|
||||
|
||||
//DO INFERENCE
|
||||
dnnType *rt_out[netRT->pluginFactory->n_yolos];
|
||||
tk::dnn::dataDim_t dim = netRT->input_dim;
|
||||
checkCuda(cudaMemcpyAsync(input_d, input, dim.tot()*sizeof(dnnType), cudaMemcpyHostToDevice, netRT->stream));
|
||||
|
||||
printCenteredTitle(" TENSORRT inference ", '=', 30); {
|
||||
dim.print();
|
||||
TIMER_START
|
||||
netRT->infer(dim, input_d);
|
||||
TIMER_STOP
|
||||
dim.print();
|
||||
//write channels
|
||||
for(int i=0; i<netRT->input_dim.c; i++) {
|
||||
int idx = i*imagePreproc.rows*imagePreproc.cols;
|
||||
int ch = netRT->input_dim.c-1 -i;
|
||||
memcpy((void*)&input[idx + netRT->input_dim.tot()*bi], (void*)bgr[ch].data, imagePreproc.rows*imagePreproc.cols*sizeof(dnnType));
|
||||
}
|
||||
|
||||
TIMER_START
|
||||
checkCuda(cudaMemcpyAsync(input_d + netRT->input_dim.tot()*bi, input + netRT->input_dim.tot()*bi, netRT->input_dim.tot()*sizeof(dnnType), cudaMemcpyHostToDevice, netRT->stream));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Yolo3Detection::postprocess(const int bi, const bool mAP){
|
||||
|
||||
//get yolo outputs
|
||||
std::vector<float *> rt_out;
|
||||
//dnnType *rt_out[netRT->pluginFactory->n_yolos];
|
||||
for(int i=0; i<netRT->pluginFactory->n_yolos; i++)
|
||||
rt_out.push_back((dnnType*)netRT->buffersRT[i+1] + netRT->buffersDIM[i+1].tot()*bi);
|
||||
|
||||
float x_ratio = float(originalSize[bi].width) / float(netRT->input_dim.w);
|
||||
float y_ratio = float(originalSize[bi].height) / float(netRT->input_dim.h);
|
||||
|
||||
// compute dets
|
||||
ndets = 0;
|
||||
nDets = 0;
|
||||
for(int i=0; i<netRT->pluginFactory->n_yolos; i++) {
|
||||
rt_out[i] = (dnnType*)netRT->buffersRT[i+1];
|
||||
yolo[i]->dstData = rt_out[i];
|
||||
yolo[i]->computeDetections(dets, ndets, netRT->input_dim.w, netRT->input_dim.h, thresh);
|
||||
yolo[i]->computeDetections(dets, nDets, netRT->input_dim.w, netRT->input_dim.h, confThreshold, yolo[i]->new_coords);
|
||||
}
|
||||
tk::dnn::Yolo::mergeDetections(dets, ndets, classes);
|
||||
TIMER_STOP
|
||||
tk::dnn::Yolo::mergeDetections(dets, nDets, classes, yolo[0]->nms_thresh, yolo[0]->nsm_kind);
|
||||
|
||||
// fill detected
|
||||
detected.clear();
|
||||
for(int j=0; j<ndets; j++) {
|
||||
for(int j=0; j<nDets; j++) {
|
||||
tk::dnn::Yolo::box b = dets[j].bbox;
|
||||
int x0 = (b.x-b.w/2.);
|
||||
int x1 = (b.x+b.w/2.);
|
||||
int y0 = (b.y-b.h/2.);
|
||||
int y1 = (b.y+b.h/2.);
|
||||
int obj_class = -1;
|
||||
float prob = 0;
|
||||
float x0 = (b.x-b.w/2.);
|
||||
float x1 = (b.x+b.w/2.);
|
||||
float y0 = (b.y-b.h/2.);
|
||||
float y1 = (b.y+b.h/2.);
|
||||
|
||||
// convert to image coords
|
||||
x0 = x_ratio*x0;
|
||||
x1 = x_ratio*x1;
|
||||
y0 = y_ratio*y0;
|
||||
y1 = y_ratio*y1;
|
||||
|
||||
for(int c=0; c<classes; c++) {
|
||||
if(dets[j].prob[c] >= thresh) {
|
||||
obj_class = c;
|
||||
prob = dets[j].prob[c];
|
||||
if(dets[j].prob[c] >= confThreshold) {
|
||||
int obj_class = c;
|
||||
float prob = dets[j].prob[c];
|
||||
|
||||
tk::dnn::box res;
|
||||
res.cl = obj_class;
|
||||
res.prob = prob;
|
||||
res.x = x0;
|
||||
res.y = y0;
|
||||
res.w = x1 - x0;
|
||||
res.h = y1 - y0;
|
||||
|
||||
// FIXME: this shuld be useless
|
||||
// if(mAP)
|
||||
// for(int c=0; c<classes; c++)
|
||||
// res.probs.push_back(dets[j].prob[c]);
|
||||
|
||||
detected.push_back(res);
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_class >= 0) {
|
||||
//std::cout<<obj_class<<" ("<<prob<<"): "<<x0<<" "<<y0<<" "<<x1<<" "<<y1<<"\n";
|
||||
//cv::rectangle(image, cv::Point(x0, y0), cv::Point(x1, y1), colors[obj_class], 2);
|
||||
|
||||
// convert to image coords
|
||||
x0 = xRatio*x0;
|
||||
x1 = xRatio*x1;
|
||||
y0 = yRatio*y0;
|
||||
y1 = yRatio*y1;
|
||||
|
||||
tk::dnn::box res;
|
||||
res.cl = obj_class;
|
||||
res.prob = prob;
|
||||
res.x = x0;
|
||||
res.y = y0;
|
||||
res.w = x1 - x0;
|
||||
res.h = y1 - y0;
|
||||
detected.push_back(res);
|
||||
}
|
||||
}
|
||||
batchDetected.push_back(detected);
|
||||
}
|
||||
|
||||
|
||||
tk::dnn::Yolo* Yolo3Detection::getYoloLayer(int n) {
|
||||
if(n<3)
|
||||
return yolo[n];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
#include "evaluation.h"
|
||||
#include <fstream>
|
||||
namespace tk { namespace dnn {
|
||||
|
||||
void Frame::print() const{
|
||||
std::cout<<"labels filename: "<<lFilename<<std::endl;
|
||||
std::cout<<"image filename: "<<iFilename<<std::endl;
|
||||
std::cout<<"GT: "<<std::endl;
|
||||
for(auto g: gt) std::cout<<g;
|
||||
std::cout<<"DET: "<<std::endl;
|
||||
for(auto d: det) std::cout<<d;
|
||||
}
|
||||
|
||||
void PR::print(){
|
||||
std::cout<<"precision: "<<precision<<" recall: "<<recall<<" tp: "<<tp<<" fp:"<<fp<<" fn:"<<fn<<std::endl;
|
||||
}
|
||||
|
||||
void readmAPParams( const char* config_filename, int& classes1,float& conf_thresh1
|
||||
, int& classes2,float& conf_thresh2
|
||||
, int& classes3,float& conf_thresh3
|
||||
, int& classes4,float& conf_thresh4
|
||||
, int& classes5,float& conf_thresh5
|
||||
) {
|
||||
YAML::Node config = YAML::LoadFile(config_filename);
|
||||
classes1 = config["classes1"].as<int>();
|
||||
conf_thresh1 = config["conf_thresh1"].as<float>();
|
||||
classes2 = config["classes2"].as<int>();
|
||||
conf_thresh2 = config["conf_thresh2"].as<float>();
|
||||
classes3 = config["classes3"].as<int>();
|
||||
conf_thresh3 = config["conf_thresh3"].as<float>();
|
||||
classes4 = config["classes4"].as<int>();
|
||||
conf_thresh4 = config["conf_thresh4"].as<float>();
|
||||
classes5 = config["classes5"].as<int>();
|
||||
conf_thresh5 = config["conf_thresh5"].as<float>();
|
||||
}
|
||||
|
||||
/* Credits to https://github.com/AlexeyAB/darknet/blob/master/src/detector.c*/
|
||||
double computeMap( std::vector<Frame> &images,const int classes,
|
||||
const float IoU_thresh, const float conf_thresh,
|
||||
const int map_points, const bool verbose) {
|
||||
if(verbose)
|
||||
for(auto img:images)
|
||||
img.print();
|
||||
|
||||
int detections_count = 0;
|
||||
int groundtruths_count = 0;
|
||||
int unique_truth_count = 0;
|
||||
std::vector<int> truth_classes_count(classes,0);
|
||||
std::vector<int> dets_classes_count(classes,0);
|
||||
|
||||
//count groundtruth and detections in total and for each class
|
||||
for(auto i:images){
|
||||
for(auto gt:i.gt)
|
||||
truth_classes_count[gt.cl]++;
|
||||
for(auto det:i.det)
|
||||
dets_classes_count[det.cl]++;
|
||||
detections_count += i.det.size();
|
||||
groundtruths_count += i.gt.size();
|
||||
}
|
||||
|
||||
if(verbose){
|
||||
std::cout<<"gt_count: "<<groundtruths_count<<std::endl;
|
||||
std::cout<<"det_count: "<<detections_count<<std::endl;
|
||||
}
|
||||
|
||||
std::vector<BoundingBox> all_dets;
|
||||
std::vector<BoundingBox> all_gts;
|
||||
|
||||
int gt_checked = 0;
|
||||
|
||||
// for each detection compute IoU with groundtruth and match detetcion and
|
||||
// groundtruth with IoU greater than IoU_thresh
|
||||
for(auto &img:images){
|
||||
for(size_t i=0; i<img.det.size(); i++){
|
||||
if(img.det[i].prob > conf_thresh){
|
||||
float maxIoU = 0;
|
||||
int truth_index = -1;
|
||||
for(size_t j=0; j<img.gt.size(); j++){
|
||||
float currentIoU = img.det[i].IoU(img.gt[j]);
|
||||
if(currentIoU > maxIoU && img.det[i].cl == img.gt[j].cl){
|
||||
maxIoU = currentIoU;
|
||||
truth_index = j;
|
||||
}
|
||||
}
|
||||
if(truth_index > -1 && maxIoU > IoU_thresh){
|
||||
img.det[i].uniqueTruthIndex = truth_index + gt_checked;
|
||||
img.det[i].truthFlag = 1;
|
||||
img.det[i].maxIoU = maxIoU;
|
||||
}
|
||||
}
|
||||
|
||||
all_dets.push_back(img.det[i]);
|
||||
}
|
||||
gt_checked += img.gt.size();
|
||||
}
|
||||
|
||||
if(verbose){
|
||||
for(auto img:images)
|
||||
img.print();
|
||||
std::cout<<"\n\n\n\n";
|
||||
}
|
||||
|
||||
//sort all detections by descending value of confidence
|
||||
std::sort(all_dets.begin(), all_dets.end(), boxComparison);
|
||||
std::vector<int> truth_flags(groundtruths_count,0);
|
||||
|
||||
if(verbose)
|
||||
for(auto d:all_dets)
|
||||
std::cout<<d;
|
||||
|
||||
//compute precision-recall curve
|
||||
std::vector<std::vector<PR>> pr( classes, std::vector<PR>(detections_count));
|
||||
for(int rank = 0; rank< detections_count; ++rank){
|
||||
if (rank > 0) {
|
||||
for (int class_id = 0; class_id < classes; ++class_id) {
|
||||
pr[class_id][rank].tp = pr[class_id][rank - 1].tp;
|
||||
pr[class_id][rank].fp = pr[class_id][rank - 1].fp;
|
||||
}
|
||||
}
|
||||
|
||||
//if it was detected and never detected before
|
||||
if (all_dets[rank].truthFlag == 1 && truth_flags[all_dets[rank].uniqueTruthIndex] == 0) {
|
||||
truth_flags[all_dets[rank].uniqueTruthIndex] = 1;
|
||||
pr[all_dets[rank].cl][rank].tp++; // true-positive
|
||||
}
|
||||
else {
|
||||
pr[all_dets[rank].cl][rank].fp++; // false-positive
|
||||
}
|
||||
|
||||
for (int i = 0; i < classes; ++i){
|
||||
const int tp = pr[i][rank].tp;
|
||||
const int fp = pr[i][rank].fp;
|
||||
const int fn = truth_classes_count[i] - tp; // false-negative = objects - true-positive
|
||||
pr[i][rank].fn = fn;
|
||||
|
||||
if ((tp + fp) > 0)
|
||||
pr[i][rank].precision = (double)tp / (double)(tp + fp);
|
||||
else
|
||||
pr[i][rank].precision = 0;
|
||||
|
||||
if ((tp + fn) > 0)
|
||||
pr[i][rank].recall = (double)tp / (double)(tp + fn);
|
||||
else
|
||||
pr[i][rank].recall = 0;
|
||||
|
||||
if (rank == (detections_count - 1) && dets_classes_count[i] != (tp + fp)) {
|
||||
// check for last rank
|
||||
printf(" class_id: %d - detections = %d, tp+fp = %d, tp = %d, fp = %d \n", i, dets_classes_count[i], tp+fp, tp, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(verbose){
|
||||
for(int i=0; i < pr.size(); i++) {
|
||||
std::cout<<"---------Class "<<i<<std::endl;
|
||||
for(auto r:pr[i])
|
||||
r.print();
|
||||
}
|
||||
}
|
||||
|
||||
//compute average precision for each class. Two methods are available,
|
||||
//based on map_points required
|
||||
double mean_average_precision = 0;
|
||||
double last_recall, last_precision, delta_recall;
|
||||
double cur_recall, cur_precision;
|
||||
double avg_precision = 0;
|
||||
for (int i = 0; i < classes; ++i) {
|
||||
avg_precision = 0;
|
||||
|
||||
if (map_points == 0){ //mAP calculation: ImageNet, PascalVOC 2010-2012
|
||||
last_recall = pr[i][detections_count - 1].recall;
|
||||
last_precision = pr[i][detections_count - 1].precision;
|
||||
for (int rank = detections_count - 2; rank >= 0; --rank){
|
||||
delta_recall = last_recall - pr[i][rank].recall;
|
||||
last_recall = pr[i][rank].recall;
|
||||
|
||||
if (pr[i][rank].precision > last_precision)
|
||||
last_precision = pr[i][rank].precision;
|
||||
|
||||
avg_precision += delta_recall * last_precision;
|
||||
}
|
||||
}
|
||||
else {//MSCOCO - 101 Recall-points, PascalVOC - 11 Recall-points
|
||||
for (int point = 0; point < map_points; ++point) {
|
||||
cur_recall = point * 1.0 / ( map_points - 1 );
|
||||
cur_precision = 0;
|
||||
for (int rank = 0; rank < detections_count; ++rank)
|
||||
if (pr[i][rank].recall >= cur_recall && pr[i][rank].precision > cur_precision)
|
||||
cur_precision = pr[i][rank].precision;
|
||||
|
||||
avg_precision += cur_precision;
|
||||
}
|
||||
avg_precision = avg_precision / map_points;
|
||||
}
|
||||
|
||||
if(verbose)
|
||||
std::cout<<"Class: "<<i<<" AP: "<< avg_precision<<std::endl;
|
||||
mean_average_precision += avg_precision;
|
||||
}
|
||||
|
||||
mean_average_precision = mean_average_precision / classes;
|
||||
|
||||
std::cout<<"Classes: "<<classes<<" mAP " <<IoU_thresh<<":\t"<< mean_average_precision<<std::endl;
|
||||
return mean_average_precision;
|
||||
}
|
||||
|
||||
double computeMapNIoULevels(std::vector<Frame> &images,const int classes,
|
||||
const float i_IoU_thresh, const float conf_thresh,
|
||||
const int map_points, const float map_step,
|
||||
const int map_levels, const bool verbose,
|
||||
const bool write_on_file, std::string net) {
|
||||
std::ofstream out_file;
|
||||
if(write_on_file){
|
||||
out_file.open("map.csv", std::ios_base::app);
|
||||
out_file<<net<<";";
|
||||
}
|
||||
|
||||
double AP = 0, cur_AP = 0;
|
||||
float IoU_thresh = i_IoU_thresh;
|
||||
|
||||
for(int i=0; i<map_levels; ++i){
|
||||
//clear detection-grounthuth matching
|
||||
for(auto& img:images)
|
||||
for(auto & d:img.det)
|
||||
d.clear();
|
||||
//compute mAP for the new IoU threshold
|
||||
cur_AP = computeMap(images,classes,IoU_thresh,conf_thresh,map_points, verbose);
|
||||
if(write_on_file)
|
||||
out_file<<cur_AP<<";";
|
||||
AP += cur_AP;
|
||||
IoU_thresh +=map_step;
|
||||
}
|
||||
AP/=map_levels;
|
||||
|
||||
if(write_on_file){
|
||||
out_file<<AP<<"\n";
|
||||
out_file.close();
|
||||
}
|
||||
return AP;
|
||||
}
|
||||
|
||||
void computeTPFPFN( std::vector<Frame> &images,const int classes,
|
||||
const float IoU_thresh, const float conf_thresh,
|
||||
bool verbose, const bool write_on_file, std::string net) {
|
||||
|
||||
std::ofstream out_file;
|
||||
if(write_on_file){
|
||||
out_file.open("pr.csv", std::ios_base::app);
|
||||
out_file<<net<<";";
|
||||
}
|
||||
|
||||
std::vector<int> truth_classes_count(classes,0);
|
||||
std::vector<int> dets_classes_count(classes,0);
|
||||
std::vector<PR> pr(classes);
|
||||
|
||||
//compute TP, FP, FN for each image, for each class
|
||||
for(auto &img:images){
|
||||
for(auto& tc: truth_classes_count) tc = 0;
|
||||
for(auto& dc: dets_classes_count) dc = 0;
|
||||
|
||||
std::vector<bool> det_assigned(img.det.size(), false);
|
||||
for(size_t j=0; j<img.gt.size(); j++){
|
||||
truth_classes_count[img.gt[j].cl]++;
|
||||
float maxIoU = 0;
|
||||
int det_index = -1;
|
||||
for(size_t i=0; i<img.det.size(); i++){
|
||||
if(img.det[i].prob > conf_thresh){
|
||||
float currentIoU = img.det[i].IoU(img.gt[j]);
|
||||
if(currentIoU > maxIoU && img.det[i].cl == img.gt[j].cl && !det_assigned[i]){
|
||||
maxIoU = currentIoU;
|
||||
det_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(det_index > -1 && maxIoU > IoU_thresh && !det_assigned[det_index]){
|
||||
img.det[det_index].uniqueTruthIndex = j;
|
||||
img.det[det_index].truthFlag = 1;
|
||||
img.det[det_index].maxIoU = maxIoU;
|
||||
det_assigned[det_index] = true;
|
||||
dets_classes_count[img.det[det_index].cl]++;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i<img.det.size(); i++){
|
||||
if(img.det[i].truthFlag)
|
||||
pr[img.det[i].cl].tp ++;
|
||||
else
|
||||
pr[img.det[i].cl].fp ++;
|
||||
}
|
||||
for(size_t i=0; i<classes; i++){
|
||||
pr[i].fn += truth_classes_count[i] - dets_classes_count[i];
|
||||
}
|
||||
}
|
||||
|
||||
//count all TP, FP, FN and compute precision, recall and f1-score
|
||||
double avg_precision = 0, avg_recall = 0, f1_score = 0;
|
||||
int TP = 0, FP = 0, FN = 0;
|
||||
for(size_t i=0; i<classes; i++){
|
||||
pr[i].precision = (pr[i].tp + pr[i].fp) > 0 ? (double)pr[i].tp / (double)(pr[i].tp +pr[i].fp) : 0;
|
||||
pr[i].recall = (pr[i].tp + pr[i].fn) > 0 ? (double)pr[i].tp / (double)(pr[i].tp +pr[i].fn) : 0;
|
||||
if(verbose)
|
||||
std::cout<<"Class "<<i<<"\tTP: "<<pr[i].tp<<"\tFP: "<<pr[i].fp<<"\tFN: "<<pr[i].fn<<"\tprecision: "<<pr[i].precision<<"\trecall: "<<pr[i].recall<<std::endl;
|
||||
avg_precision += pr[i].precision;
|
||||
avg_recall += pr[i].recall;
|
||||
|
||||
TP += pr[i].tp;
|
||||
FP += pr[i].fp;
|
||||
FN += pr[i].fn;
|
||||
}
|
||||
avg_precision /= classes;
|
||||
avg_recall /= classes;
|
||||
|
||||
f1_score = avg_precision + avg_recall > 0 ? 2 * ( avg_precision * avg_recall ) / ( avg_precision + avg_recall ) : 0;
|
||||
|
||||
if(write_on_file){
|
||||
out_file<<TP<<";"<<FP<<";"<<FN<<";"<<avg_precision<<";"<<avg_recall<<";"<<f1_score<<"\n";
|
||||
out_file.close();
|
||||
}
|
||||
|
||||
std::cout<<"avg precision: "<<avg_precision<<"\tavg recall: "<<avg_recall<<"\tavg f1 score:"<<f1_score<<std::endl;
|
||||
}
|
||||
|
||||
void printJsonCOCOFormat(std::ofstream *out_file, const std::string image_path, std::vector<tk::dnn::box> bbox, const int classes, const int w, const int h)
|
||||
{
|
||||
int coco_ids[] = { 1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,77,78,79,80,81,82,84,85,86,87,88,89,90 };
|
||||
std::string id = image_path.substr(image_path.find("images/")+7, image_path.find(".jpg") - image_path.find("images/") -7);
|
||||
int image_id = std::stoi(id);
|
||||
for (int i = 0; i < bbox.size(); ++i) {
|
||||
float xmin = bbox[i].x ;
|
||||
float xmax = bbox[i].x + float(bbox[i].w);
|
||||
float ymin = bbox[i].y;
|
||||
float ymax = bbox[i].y + float(bbox[i].h);
|
||||
|
||||
//limit to image borders
|
||||
if (xmin < 0) xmin = 0;
|
||||
if (ymin < 0) ymin = 0;
|
||||
if (xmax > w) xmax = w;
|
||||
if (ymax > h) ymax = h;
|
||||
|
||||
float bx = xmin;
|
||||
float by = ymin;
|
||||
float bw = xmax - xmin;
|
||||
float bh = ymax - ymin;
|
||||
|
||||
if(bbox[i].probs.size() == classes)
|
||||
for (int j = 0; j < classes; ++j) {
|
||||
//min threshold confidence is set in DetectionNN.h
|
||||
if (bbox[i].probs[j] > 0) {
|
||||
|
||||
*out_file << "{\"image_id\":" << image_id <<
|
||||
", \"category_id\":" << coco_ids[j] <<
|
||||
", \"bbox\":[" << bx << ", " << by << ", " << bw << ", " << bh <<
|
||||
"], \"score\":" << bbox[i].probs[j] << "},\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
*out_file << "{\"image_id\":" << image_id <<
|
||||
", \"category_id\":" << coco_ids[bbox[i].cl] <<
|
||||
", \"bbox\":[" << bx << ", " << by << ", " << bw << ", " << bh <<
|
||||
"], \"score\":" << bbox[i].prob << "},\n";
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
+1749
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
#include "kernels.h"
|
||||
#include <math.h>
|
||||
|
||||
#define MISH_THRESHOLD 20
|
||||
|
||||
__device__
|
||||
float tanh_activate_kernel(float x){return (2/(1 + expf(-2*x)) - 1);}
|
||||
|
||||
__device__
|
||||
float softplus_kernel(float x, float threshold = 20) {
|
||||
if (x > threshold) return x; // too large
|
||||
else if (x < -threshold) return expf(x); // too small
|
||||
return logf(expf(x) + 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
__device__
|
||||
float mish_yashas(float x) {
|
||||
float e = __expf(x);
|
||||
if (x <= -18.0f)
|
||||
return x * e;
|
||||
|
||||
float n = e * e + 2 * e;
|
||||
if (x <= -5.0f)
|
||||
return x * __fdividef(n, n + 2);
|
||||
|
||||
return x - 2 * __fdividef(x, n + 2);
|
||||
}
|
||||
|
||||
// https://github.com/digantamisra98/Mish
|
||||
// https://github.com/AlexeyAB/darknet/blob/master/src/activation_kernels.cu
|
||||
__global__
|
||||
void activation_mish(dnnType *input, dnnType *output, int size) {
|
||||
int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
|
||||
if (i < size)
|
||||
// output[i] = input[i] * tanh_activate_kernel( softplus_kernel(input[i], MISH_THRESHOLD));
|
||||
output[i] = mish_yashas(input[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
Mish activation function
|
||||
*/
|
||||
void activationMishForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream)
|
||||
{
|
||||
int blocks = (size+255)/256;
|
||||
int threads = 256;
|
||||
|
||||
activation_mish<<<blocks, threads, 0, stream>>>(srcData, dstData, size);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "kernels.h"
|
||||
|
||||
__global__
|
||||
void activation_relu_ceiling(dnnType *input, dnnType *output, int size, const float ceiling) {
|
||||
|
||||
int i = blockDim.x*blockIdx.x + threadIdx.x;
|
||||
|
||||
if(i<size) {
|
||||
if (input[i]>0)
|
||||
{
|
||||
if (input[i]>ceiling)
|
||||
output[i] = ceiling;
|
||||
else
|
||||
output[i] = input[i];
|
||||
}
|
||||
else
|
||||
output[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Relu ceiling activation function
|
||||
*/
|
||||
void activationReLUCeilingForward(dnnType* srcData, dnnType* dstData, int size, const float ceiling, cudaStream_t stream)
|
||||
{
|
||||
int blocks = (size+255)/256;
|
||||
int threads = 256;
|
||||
|
||||
activation_relu_ceiling<<<blocks, threads, 0, stream>>>(srcData, dstData, size, ceiling);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
#include "kernels.h"
|
||||
|
||||
__device__
|
||||
__forceinline__
|
||||
double sigmoid (double a)
|
||||
{
|
||||
return 1.0 / (1.0 + exp (-a));
|
||||
}
|
||||
#include <math.h>
|
||||
|
||||
|
||||
__global__
|
||||
void activation_sigmoid(dnnType *input, dnnType *output, int size) {
|
||||
|
||||
int stride = gridDim.x * blockDim.x;
|
||||
int tid = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
for (int i = tid; i < size; i += stride) {
|
||||
output[i] = sigmoid (input[i]);
|
||||
}
|
||||
int i = blockDim.x * blockIdx.x + threadIdx.x;
|
||||
if(i < size)
|
||||
output[i] = 1.0f / (1.0f + exp (-input[i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+184
-93
@@ -1,6 +1,8 @@
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "kernels.h"
|
||||
#include <errno.h>
|
||||
|
||||
@@ -9,93 +11,93 @@
|
||||
i < (n); \
|
||||
i += blockDim.x * gridDim.x)
|
||||
|
||||
const int CUDA_NUM_THREADS = 1024;
|
||||
const int CUDA_NUM_THREADS = 512;
|
||||
inline int GET_BLOCKS(const int N)
|
||||
{
|
||||
return (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS;
|
||||
}
|
||||
|
||||
|
||||
__device__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width,
|
||||
const int height, const int width, float h, float w)
|
||||
{
|
||||
int h_low = floor(h);
|
||||
int w_low = floor(w);
|
||||
int h_high = h_low + 1;
|
||||
int w_high = w_low + 1;
|
||||
__device__ __host__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width,
|
||||
const int height, const int width, float h, float w) {
|
||||
int h_low = floor(h);
|
||||
int w_low = floor(w);
|
||||
int h_high = h_low + 1;
|
||||
int w_high = w_low + 1;
|
||||
|
||||
float lh = h - h_low;
|
||||
float lw = w - w_low;
|
||||
float hh = 1 - lh, hw = 1 - lw;
|
||||
float lh = h - h_low;
|
||||
float lw = w - w_low;
|
||||
float hh = 1 - lh, hw = 1 - lw;
|
||||
|
||||
float v1 = 0;
|
||||
if (h_low >= 0 && w_low >= 0)
|
||||
v1 = bottom_data[h_low * data_width + w_low];
|
||||
float v2 = 0;
|
||||
if (h_low >= 0 && w_high <= width - 1)
|
||||
v2 = bottom_data[h_low * data_width + w_high];
|
||||
float v3 = 0;
|
||||
if (h_high <= height - 1 && w_low >= 0)
|
||||
v3 = bottom_data[h_high * data_width + w_low];
|
||||
float v4 = 0;
|
||||
if (h_high <= height - 1 && w_high <= width - 1)
|
||||
v4 = bottom_data[h_high * data_width + w_high];
|
||||
float v1 = ( (h_low >= 0 && w_low >= 0) ? bottom_data[h_low * data_width + w_low]:0);
|
||||
float v2 = ( (h_low >= 0 && w_high <= width - 1) ? bottom_data[h_low * data_width + w_high]:0);
|
||||
float v3 = ( (h_high <= height - 1 && w_low >= 0) ? bottom_data[h_high * data_width + w_low]:0);
|
||||
float v4 = ( (h_high <= height - 1 && w_high <= width - 1) ? bottom_data[h_high * data_width + w_high]:0);
|
||||
|
||||
float w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
|
||||
float w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
|
||||
|
||||
float val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
|
||||
return val;
|
||||
float val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
|
||||
return val;
|
||||
}
|
||||
|
||||
__global__ void modulated_deformable_im2col_gpu_kernel(const int n,
|
||||
const float *data_im, const float *data_offset, const float *data_mask,
|
||||
const int height, const int width, const int kernel_h, const int kernel_w,
|
||||
const int pad_h, const int pad_w,
|
||||
const int stride_h, const int stride_w,
|
||||
const int dilation_h, const int dilation_w,
|
||||
const int channel_per_deformable_group,
|
||||
const int batch_size, const int num_channels, const int deformable_group,
|
||||
const int height_col, const int width_col,
|
||||
float *data_col)
|
||||
{
|
||||
const float *data_im, const float *data_offset, const float *data_mask,
|
||||
const int height, const int width,
|
||||
const int batch_size, const int num_channels, const int deformable_group,
|
||||
const int height_col, const int width_col,
|
||||
float *data_col) {
|
||||
CUDA_KERNEL_LOOP(index, n)
|
||||
{
|
||||
//If n is a power of 2, ( i / n ) is equivalent to ( i ≫ log2 n ) and ( i % n ) is equivalent to ( i & n - 1 ).
|
||||
const int ind_on_w = index / width_col;
|
||||
const int ind_on_w_on_h = ind_on_w / height_col;
|
||||
const int kk = 3 * 3;
|
||||
// index index of output matrix
|
||||
const int w_col = index % width_col;
|
||||
const int h_col = (index / width_col) % height_col;
|
||||
const int b_col = (index / width_col / height_col) % batch_size;
|
||||
const int c_im = (index / width_col / height_col) / batch_size;
|
||||
const int c_col = c_im * kernel_h * kernel_w;
|
||||
const int h_col = (ind_on_w) % height_col;
|
||||
const int b_col = (ind_on_w_on_h) % batch_size;
|
||||
const int c_im = (ind_on_w_on_h) / batch_size;
|
||||
const int c_col = c_im * kk;
|
||||
|
||||
// compute deformable group index
|
||||
const int deformable_group_index = c_im / channel_per_deformable_group;
|
||||
const int deformable_group_index = c_im / (int)(num_channels / deformable_group);
|
||||
|
||||
const int h_in = h_col * stride_h - pad_h;
|
||||
const int w_in = w_col * stride_w - pad_w;
|
||||
const int h_in = h_col - 1;
|
||||
const int w_in = w_col - 1;
|
||||
const int s_col = height_col * width_col;
|
||||
const int s_col2 = 2 * s_col;
|
||||
|
||||
float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col;
|
||||
const int first_member = w_col + width_col * h_col;
|
||||
// float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col;
|
||||
float *data_col_ptr = data_col + first_member + s_col * (c_col * batch_size + b_col);
|
||||
//const float* data_im_ptr = data_im + ((b_col * num_channels + c_im) * height + h_in) * width + w_in;
|
||||
const float *data_im_ptr = data_im + (b_col * num_channels + c_im) * height * width;
|
||||
const float *data_offset_ptr = data_offset + (b_col * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;
|
||||
const int add_ptr = (b_col * deformable_group + deformable_group_index) * kk * s_col;
|
||||
const float *data_offset_ptr = data_offset + add_ptr + add_ptr;
|
||||
const float *data_mask_ptr = data_mask + add_ptr;
|
||||
|
||||
const float *data_mask_ptr = data_mask + (b_col * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;
|
||||
#pragma unroll
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
#pragma unroll
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
const int iter_member = (i * 3 + j);
|
||||
// const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col;
|
||||
const int data_offset_h_ptr = first_member + s_col2 * iter_member;
|
||||
|
||||
// const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + w_col;
|
||||
const int data_offset_w_ptr = s_col + first_member + s_col2 * iter_member;
|
||||
|
||||
// const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_col) * width_col + w_col;
|
||||
const int data_mask_hw_ptr = first_member + s_col * iter_member;
|
||||
|
||||
for (int i = 0; i < kernel_h; ++i)
|
||||
{
|
||||
for (int j = 0; j < kernel_w; ++j)
|
||||
{
|
||||
const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col;
|
||||
const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + w_col;
|
||||
const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_col) * width_col + w_col;
|
||||
const float offset_h = data_offset_ptr[data_offset_h_ptr];
|
||||
const float offset_w = data_offset_ptr[data_offset_w_ptr];
|
||||
const float mask = data_mask_ptr[data_mask_hw_ptr];
|
||||
float val = static_cast<float>(0);
|
||||
const float h_im = h_in + i * dilation_h + offset_h;
|
||||
const float w_im = w_in + j * dilation_w + offset_w;
|
||||
const float h_im = offset_h + h_in + i;
|
||||
const float w_im = offset_w + w_in + j;
|
||||
//if (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) {
|
||||
if (h_im > -1 && w_im > -1 && h_im < height && w_im < width)
|
||||
{
|
||||
float val = static_cast<float>(0);
|
||||
if (h_im < height && w_im < width && h_im > -1 && w_im > -1) {
|
||||
//const float map_h = i * dilation_h + offset_h;
|
||||
//const float map_w = j * dilation_w + offset_w;
|
||||
//const int cur_height = height - h_in;
|
||||
@@ -104,15 +106,111 @@ __global__ void modulated_deformable_im2col_gpu_kernel(const int n,
|
||||
val = dmcn_im2col_bilinear(data_im_ptr, width, height, width, h_im, w_im);
|
||||
}
|
||||
*data_col_ptr = val * mask;
|
||||
data_col_ptr += batch_size * height_col * width_col;
|
||||
data_col_ptr += batch_size * s_col;
|
||||
//data_col_ptr += height_col * width_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void modulated_deformable_im2col_gpu_kernel_general_version(const int n,
|
||||
const float *data_im, const float *data_offset, const float *data_mask,
|
||||
const int height, const int width, const int kernel_h, const int kernel_w,
|
||||
const int pad_h, const int pad_w,
|
||||
const int stride_h, const int stride_w,
|
||||
const int dilation_h, const int dilation_w,
|
||||
const int channel_per_deformable_group,
|
||||
const int batch_size, const int num_channels, const int deformable_group,
|
||||
const int height_col, const int width_col,
|
||||
float *data_col) {
|
||||
CUDA_KERNEL_LOOP(index, n)
|
||||
{
|
||||
//If n is a power of 2, ( i / n ) is equivalent to ( i ≫ log2 n ) and ( i % n ) is equivalent to ( i & n - 1 ).
|
||||
const int ind_on_w = index / width_col;
|
||||
const int ind_on_w_on_h = ind_on_w / height_col;
|
||||
const int kk = kernel_h * kernel_w;
|
||||
// index index of output matrix
|
||||
const int w_col = index % width_col;
|
||||
const int h_col = (ind_on_w) % height_col;
|
||||
const int b_col = (ind_on_w_on_h) % batch_size;
|
||||
const int c_im = (ind_on_w_on_h) / batch_size;
|
||||
const int c_col = c_im * kk;
|
||||
|
||||
void modulated_deformable_im2col_cuda(cudaStream_t stream,
|
||||
// compute deformable group index
|
||||
const int deformable_group_index = c_im / channel_per_deformable_group;
|
||||
|
||||
const int h_in = h_col * stride_h - pad_h;
|
||||
const int w_in = w_col * stride_w - pad_w;
|
||||
const int s_col = height_col * width_col;
|
||||
const int s_col2 = 2 * s_col;
|
||||
|
||||
const int first_member = w_col + width_col * h_col;
|
||||
// float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col;
|
||||
float *data_col_ptr = data_col + first_member + s_col * (c_col * batch_size + b_col);
|
||||
//const float* data_im_ptr = data_im + ((b_col * num_channels + c_im) * height + h_in) * width + w_in;
|
||||
const float *data_im_ptr = data_im + (b_col * num_channels + c_im) * height * width;
|
||||
const int add_ptr = (b_col * deformable_group + deformable_group_index) * kk * s_col;
|
||||
const float *data_offset_ptr = data_offset + add_ptr + add_ptr;
|
||||
|
||||
const float *data_mask_ptr = data_mask + add_ptr;
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < kernel_h; ++i) {
|
||||
#pragma unroll
|
||||
for (int j = 0; j < kernel_w; ++j) {
|
||||
const int iter_member = (i * kernel_w + j);
|
||||
// const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col;
|
||||
const int data_offset_h_ptr = first_member + s_col2 * iter_member;
|
||||
|
||||
// const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + w_col;
|
||||
const int data_offset_w_ptr = s_col + first_member + s_col2 * iter_member;
|
||||
|
||||
// const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_col) * width_col + w_col;
|
||||
const int data_mask_hw_ptr = first_member + s_col * iter_member;
|
||||
|
||||
const float offset_h = data_offset_ptr[data_offset_h_ptr];
|
||||
const float offset_w = data_offset_ptr[data_offset_w_ptr];
|
||||
const float mask = data_mask_ptr[data_mask_hw_ptr];
|
||||
const float h_im = offset_h + h_in + i * dilation_h;
|
||||
const float w_im = offset_w + w_in + j * dilation_w;
|
||||
//if (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) {
|
||||
float val = static_cast<float>(0);
|
||||
if (h_im < height && w_im < width && h_im > -1 && w_im > -1) {
|
||||
//const float map_h = i * dilation_h + offset_h;
|
||||
//const float map_w = j * dilation_w + offset_w;
|
||||
//const int cur_height = height - h_in;
|
||||
//const int cur_width = width - w_in;
|
||||
//val = dmcn_im2col_bilinear(data_im_ptr, width, cur_height, cur_width, map_h, map_w);
|
||||
val = dmcn_im2col_bilinear(data_im_ptr, width, height, width, h_im, w_im);
|
||||
}
|
||||
*data_col_ptr = val * mask;
|
||||
data_col_ptr += batch_size * s_col;
|
||||
//data_col_ptr += height_col * width_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void modulatedDeformableIm2colCuda(cudaStream_t stream,
|
||||
const float* data_im, const float* data_offset, const float* data_mask,
|
||||
const int batch_size, const int channels, const int height_im, const int width_im,
|
||||
const int height_col, const int width_col,
|
||||
const int deformable_group, float* data_col) {
|
||||
// num_axes should be smaller than block size
|
||||
// const int channel_per_deformable_group = channels / deformable_group;
|
||||
const int num_kernels = channels * batch_size * height_col * width_col;
|
||||
modulated_deformable_im2col_gpu_kernel
|
||||
<<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,
|
||||
0, stream>>>(
|
||||
num_kernels, data_im, data_offset, data_mask, height_im, width_im,
|
||||
batch_size, channels, deformable_group, height_col, width_col, data_col);
|
||||
|
||||
cudaError_t err = cudaGetLastError();
|
||||
if (err != cudaSuccess)
|
||||
FatalError("error in modulatedDeformableIm2colCuda: " + std::string(cudaGetErrorString(err)) + "\n");
|
||||
}
|
||||
|
||||
void modulatedDeformableIm2colCudaGeneralVersion(cudaStream_t stream,
|
||||
const float* data_im, const float* data_offset, const float* data_mask,
|
||||
const int batch_size, const int channels, const int height_im, const int width_im,
|
||||
const int height_col, const int width_col, const int kernel_h, const int kenerl_w,
|
||||
@@ -122,7 +220,7 @@ void modulated_deformable_im2col_cuda(cudaStream_t stream,
|
||||
// num_axes should be smaller than block size
|
||||
const int channel_per_deformable_group = channels / deformable_group;
|
||||
const int num_kernels = channels * batch_size * height_col * width_col;
|
||||
modulated_deformable_im2col_gpu_kernel
|
||||
modulated_deformable_im2col_gpu_kernel_general_version
|
||||
<<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,
|
||||
0, stream>>>(
|
||||
num_kernels, data_im, data_offset, data_mask, height_im, width_im, kernel_h, kenerl_w,
|
||||
@@ -131,14 +229,11 @@ void modulated_deformable_im2col_cuda(cudaStream_t stream,
|
||||
|
||||
cudaError_t err = cudaGetLastError();
|
||||
if (err != cudaSuccess)
|
||||
{
|
||||
printf("error in modulated_deformable_im2col_cuda: %s\n", cudaGetErrorString(err));
|
||||
}
|
||||
|
||||
FatalError("error in modulatedDeformableIm2colCudaGeneralVersion: " + std::string(cudaGetErrorString(err)) + "\n");
|
||||
}
|
||||
|
||||
|
||||
void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
void dcnV2CudaForward(cublasStatus_t stat, cublasHandle_t handle,
|
||||
float *input, float *weight,
|
||||
float *bias, float *ones,
|
||||
float *offset, float *mask,
|
||||
float *output, float *columns,
|
||||
@@ -146,24 +241,17 @@ void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
const int stride_h, const int stride_w,
|
||||
const int pad_h, const int pad_w,
|
||||
const int dilation_h, const int dilation_w,
|
||||
const int deformable_group,
|
||||
const int deformable_group, const int batch_id,
|
||||
const int in_n, const int in_c, const int in_h, const int in_w,
|
||||
const int out_n, const int out_c, const int out_h, const int out_w,
|
||||
const int chunk_dim, cudaStream_t stream)
|
||||
{
|
||||
cublasStatus_t stat;
|
||||
cublasHandle_t handle;
|
||||
stat = cublasCreate(&handle);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf ("CUBLAS initialization failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// stat and handle have be moved out to preserve 2 - 6 milliseconds every 100.
|
||||
const int batch = batch_id;
|
||||
const int channels = in_c;
|
||||
const int height = in_h;
|
||||
const int width = in_w;
|
||||
|
||||
|
||||
const int channels_out = out_c;
|
||||
|
||||
const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;
|
||||
@@ -178,19 +266,23 @@ void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
stat = cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_N,
|
||||
n, m, k, &alpha,
|
||||
ones, k, bias, k,
|
||||
&beta, output, n);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf ("CUBLAS initialization failed\n");
|
||||
return ;
|
||||
}
|
||||
&beta, output + batch * out_c * out_h * out_w, n);
|
||||
if (stat != CUBLAS_STATUS_SUCCESS)
|
||||
FatalError("CUBLAS initialization failed\n");
|
||||
|
||||
modulated_deformable_im2col_cuda(stream,
|
||||
input, offset,
|
||||
mask,
|
||||
modulatedDeformableIm2colCuda(stream,
|
||||
input + batch * channels * height * width,
|
||||
offset,// + b * 2 * int((float)chunk_dim / batch),
|
||||
mask,// + b * int((float)chunk_dim / batch),
|
||||
1, channels, height, width,
|
||||
height_out, width_out, kernel_h, kernel_w,
|
||||
pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w,
|
||||
deformable_group, columns);
|
||||
height_out, width_out, deformable_group, columns);
|
||||
// modulatedDeformableIm2colCudaGeneralVersion(stream,
|
||||
// input, offset,
|
||||
// mask,
|
||||
// 1, channels, height, width,
|
||||
// height_out, width_out, kernel_h, kernel_w,
|
||||
// pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w,
|
||||
// deformable_group, columns);
|
||||
|
||||
//(k * m) x (m * n)
|
||||
// Y = WC
|
||||
@@ -200,10 +292,9 @@ void dcn_v2_cuda_forward(float *input, float *weight,
|
||||
stat = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N,
|
||||
n, m, k, &alpha,
|
||||
columns, n, weight, k,
|
||||
&beta, output, n);
|
||||
&beta, output + batch * out_c * out_h * out_w, n);
|
||||
|
||||
if (stat != CUBLAS_STATUS_SUCCESS)
|
||||
FatalError("CUBLAS initialization failed\n");
|
||||
|
||||
if (stat != CUBLAS_STATUS_SUCCESS) {
|
||||
printf ("CUBLAS initialization failed\n");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "kernelsThrust.h"
|
||||
|
||||
__global__
|
||||
void normalize_kernel(float *bgr, const int dim, const float *mean, const float *stddev){
|
||||
int i = blockDim.x*blockIdx.x + threadIdx.x;
|
||||
int j = blockIdx.y;
|
||||
bgr[j*(dim)+i] = bgr[j*(dim)+i] - mean[j];
|
||||
bgr[j*(dim)+i] = bgr[j*(dim)+i] / stddev[j];
|
||||
|
||||
}
|
||||
|
||||
void normalize(float *bgr, const int ch, const int h, const int w, const float *mean, const float *stddev){
|
||||
int num_thread = 256;
|
||||
dim3 dimBlock(h*w/num_thread, ch);
|
||||
normalize_kernel<<<dimBlock, num_thread, 0>>>(bgr, h*w, mean, stddev);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "kernels.h"
|
||||
|
||||
__global__ void forward_maxpool_layer_kernel(int n, int in_h, int in_w, int in_c, int stride_x, int stride_y, int size, int pad, float *input, float *output)
|
||||
{
|
||||
int h = (in_h + pad - size) / stride_y + 1;
|
||||
int w = (in_w + pad - size) / stride_x + 1;
|
||||
int c = in_c;
|
||||
|
||||
int id = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
|
||||
if(id >= n) return;
|
||||
|
||||
int j = id % w;
|
||||
id /= w;
|
||||
int i = id % h;
|
||||
id /= h;
|
||||
int k = id % c;
|
||||
id /= c;
|
||||
int b = id;
|
||||
|
||||
int w_offset = -pad / 2;
|
||||
int h_offset = -pad / 2;
|
||||
|
||||
int out_index = j + w*(i + h*(k + c*b));
|
||||
float max = -9999999;
|
||||
int max_i = -1;
|
||||
int l, m;
|
||||
for(l = 0; l < size; ++l){
|
||||
for(m = 0; m < size; ++m){
|
||||
int cur_h = h_offset + i*stride_y + l;
|
||||
int cur_w = w_offset + j*stride_x + m;
|
||||
int index = cur_w + in_w*(cur_h + in_h*(k + b*in_c));
|
||||
int valid = (cur_h >= 0 && cur_h < in_h &&
|
||||
cur_w >= 0 && cur_w < in_w);
|
||||
float val = (valid != 0) ? input[index] : -9999999;
|
||||
max_i = (val > max) ? index : max_i;
|
||||
max = (val > max) ? val : max;
|
||||
}
|
||||
}
|
||||
output[out_index] = max;
|
||||
}
|
||||
|
||||
void MaxPoolingForward(dnnType* srcData, dnnType* dstData, int n, int c, int h, int w, int stride_x, int stride_y, int size, int padding, cudaStream_t stream)
|
||||
{
|
||||
|
||||
int tot_size = n*c*h*w;
|
||||
|
||||
int blocks = (tot_size+255)/256;
|
||||
int threads = 256;
|
||||
|
||||
forward_maxpool_layer_kernel<<<blocks, threads, 0, stream>>>(tot_size, h, w, c, stride_x, stride_y, size, padding, srcData, dstData);
|
||||
}
|
||||
|
||||
@@ -1,61 +1,37 @@
|
||||
#include "kernelsThrust.h"
|
||||
|
||||
#include "sorting.h"
|
||||
|
||||
void sort(dnnType *src_begin, dnnType *src_end, int *idsrc)
|
||||
{
|
||||
void subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out, struct threshold op){
|
||||
thrust::transform(thrust::device, src_begin, src_end, src2_begin, src_out, op);
|
||||
}
|
||||
|
||||
void sort(dnnType *src_begin, dnnType *src_end, int *idsrc){
|
||||
thrust::sort_by_key(thrust::device,
|
||||
src_begin, src_end, idsrc,
|
||||
thrust::greater<float>());
|
||||
|
||||
// thrust::stable_sort_by_key(thrust::device,
|
||||
// src_begin, src_end, idsrc,
|
||||
// thrust::greater<float>());
|
||||
}
|
||||
|
||||
void topk(dnnType *src_begin, int *idsrc, int K, float *topk_scores,
|
||||
int *topk_inds, float *topk_ys, float *topk_xs)
|
||||
{
|
||||
int *topk_inds, float *topk_ys, float *topk_xs){
|
||||
checkCuda( cudaMemcpy(topk_scores, (float *)src_begin, K*sizeof(float), cudaMemcpyDeviceToDevice) );
|
||||
checkCuda( cudaMemcpy(topk_inds, idsrc, K*sizeof(int), cudaMemcpyDeviceToDevice) );
|
||||
// topk_ys_[i*K +count] = (int)(ids2[j] / width);
|
||||
// topk_xs_[i*K +count] = (int)(ids2[j] % width);
|
||||
|
||||
checkCuda( cudaMemcpy(topk_inds, idsrc, K*sizeof(int), cudaMemcpyDeviceToDevice) );
|
||||
}
|
||||
|
||||
__global__
|
||||
void sortAndTopK_kernel(dnnType *src_begin, int *idsrc, float *topk_scores, int *topk_inds, float *topk_ys, float *topk_xs,const int size, const int K){
|
||||
int i = blockDim.x*blockIdx.x + threadIdx.x;
|
||||
|
||||
thrust::sort_by_key(thrust::device, src_begin + i * size, src_begin + i * size + size, idsrc + i * size, thrust::greater<float>());
|
||||
thrust::copy_n(thrust::device, src_begin + i * size, K, topk_scores + i * K);
|
||||
// thrust::copy_n(thrust::device, idsrc + i * size, K, topk_inds + i * K );
|
||||
thrust::copy_n(thrust::device, idsrc + i * size, K, topk_inds + i * K );
|
||||
}
|
||||
|
||||
void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int *topk_inds, float *topk_ys, float *topk_xs, const int size, const int K, const int n_classes)
|
||||
{
|
||||
void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int *topk_inds, float *topk_ys, float *topk_xs, const int size, const int K, const int n_classes){
|
||||
int blocks = n_classes;
|
||||
int threads = 1;
|
||||
|
||||
sortAndTopK_kernel<<<blocks, threads, 0>>>(src_begin, idsrc, topk_scores, topk_inds, topk_ys, topk_xs, size, K);
|
||||
|
||||
}
|
||||
|
||||
struct threshold : public thrust::binary_function<float,float,float>
|
||||
{
|
||||
__host__ __device__
|
||||
float operator()(float x, float y) {
|
||||
float toll = 1e-6;
|
||||
if(fabsf(x-y)>toll)
|
||||
return 0.0f;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
void subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out){
|
||||
struct threshold op;
|
||||
thrust::transform(thrust::device, src_begin, src_end, src2_begin, src_out, op);
|
||||
sortAndTopK_kernel<<<blocks, threads, 0>>>(src_begin, idsrc, topk_scores, topk_inds, topk_ys, topk_xs, size, K);
|
||||
}
|
||||
|
||||
void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys){
|
||||
@@ -63,34 +39,27 @@ void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, co
|
||||
thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), ids_begin, thrust::modulus<int>());
|
||||
thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(size), ys, thrust::divides<int>());
|
||||
thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(size), xs, thrust::modulus<int>());
|
||||
|
||||
}
|
||||
|
||||
void topKxyAddOffset(int * ids_begin, const int K, const int size, int *intxs_begin, int *intys_begin, float *xs_begin, float *ys_begin, dnnType *src_begin){
|
||||
float *src_out;
|
||||
checkCuda( cudaMalloc(&src_out, K *sizeof(float)) );
|
||||
void topKxyAddOffset(int * ids_begin, const int K, const int size,
|
||||
int *intxs_begin, int *intys_begin, float *xs_begin,
|
||||
float *ys_begin, dnnType *src_begin, float *src_out, int *ids_out){
|
||||
thrust::gather(thrust::device, ids_begin, ids_begin + K, src_begin, src_out);
|
||||
thrust::transform(thrust::device, intxs_begin, intxs_begin + K, src_out, xs_begin, thrust::plus<float>());
|
||||
int *ids_out;
|
||||
checkCuda( cudaMalloc(&ids_out, K *sizeof(int)) );
|
||||
thrust::transform(thrust::device, ids_begin, ids_begin + K, thrust::make_constant_iterator(size), ids_out, thrust::plus<int>());
|
||||
thrust::gather(thrust::device, ids_out, ids_out+K, src_begin, src_out);
|
||||
thrust::transform(thrust::device, intys_begin, intys_begin + K, src_out, ys_begin, thrust::plus<float>());
|
||||
checkCuda( cudaFree(src_out) );
|
||||
checkCuda( cudaFree(ids_out) );
|
||||
}
|
||||
|
||||
void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin, dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1){
|
||||
float *src_out;
|
||||
checkCuda( cudaMalloc(&src_out, K *sizeof(float)) );
|
||||
void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float *ys_begin,
|
||||
dnnType *src_begin, float *bbx0, float *bbx1, float *bby0, float *bby1,
|
||||
float *src_out, int *ids_out){
|
||||
thrust::gather(thrust::device, ids_begin, ids_begin + K, src_begin, src_out);
|
||||
thrust::transform(thrust::device, src_out, src_out + K, thrust::make_constant_iterator(2), src_out, thrust::divides<float>());
|
||||
// x0
|
||||
thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx0, thrust::minus<float>());
|
||||
// x1
|
||||
thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx1, thrust::plus<float>());
|
||||
int *ids_out;
|
||||
checkCuda( cudaMalloc(&ids_out, K *sizeof(int)) );
|
||||
thrust::transform(thrust::device, ids_begin, ids_begin + K, thrust::make_constant_iterator(size), ids_out, thrust::plus<int>());
|
||||
thrust::gather(thrust::device, ids_out, ids_out + K, src_begin, src_out);
|
||||
thrust::transform(thrust::device, src_out, src_out + K, thrust::make_constant_iterator(2), src_out, thrust::divides<float>());
|
||||
@@ -98,7 +67,5 @@ void bboxes(int * ids_begin, const int K, const int size, float *xs_begin, float
|
||||
thrust::transform(thrust::device, ys_begin, ys_begin + K, src_out, bby0, thrust::minus<float>());
|
||||
// y1
|
||||
thrust::transform(thrust::device, ys_begin, ys_begin + K, src_out, bby1, thrust::plus<float>());
|
||||
checkCuda( cudaFree(src_out) );
|
||||
checkCuda( cudaFree(ids_out) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "kernels.h"
|
||||
#include <math.h>
|
||||
|
||||
__global__ void scal_add_kernel(dnnType* dstData, int size, float alpha, float beta, int inc)
|
||||
{
|
||||
int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x;
|
||||
if (i < size) dstData[i*inc] = dstData[i*inc] * alpha + beta;
|
||||
}
|
||||
|
||||
void scalAdd(dnnType* dstData, int size, float alpha, float beta, int inc, cudaStream_t stream)
|
||||
{
|
||||
int blocks = (size+255)/256;
|
||||
int threads = 256;
|
||||
|
||||
scal_add_kernel<<<blocks, threads, 0, stream>>>(dstData, size, alpha, beta, inc);
|
||||
}
|
||||
+133
-35
@@ -20,46 +20,65 @@ bool fileExist(const char *fname) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string& test_folder, const std::string& weights_url){
|
||||
if(!fileExist(input_bin.c_str())){
|
||||
std::string mkdir_cmd = "mkdir " + test_folder;
|
||||
std::string wget_cmd = "curl " + weights_url + " --output " + test_folder + "/weights.zip";
|
||||
#ifdef __linux__
|
||||
std::string unzip_cmd = "unzip " + test_folder + "/weights.zip -d" + test_folder;
|
||||
std::string rm_cmd = "rm " + test_folder + "/weights.zip";
|
||||
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek, bool skipLoad)
|
||||
#elif _WIN32
|
||||
|
||||
std::string unzip_cmd = "7z x " + test_folder + "/weights.zip -o" + test_folder;
|
||||
#endif
|
||||
int err = 0;
|
||||
err = system(mkdir_cmd.c_str());
|
||||
err = system(wget_cmd.c_str());
|
||||
err = system(unzip_cmd.c_str());
|
||||
#ifdef __linux__
|
||||
err = system(rm_cmd.c_str());
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek)
|
||||
{
|
||||
std::ifstream dataFile (fname, std::ios::in | std::ios::binary);
|
||||
std::stringstream error_s;
|
||||
if (!dataFile)
|
||||
{
|
||||
error_s << "Error opening file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
if(seek != 0) {
|
||||
dataFile.seekg(seek*sizeof(dnnType), dataFile.cur);
|
||||
}
|
||||
|
||||
int size_b = size*sizeof(dnnType);
|
||||
*data_h = new dnnType[size];
|
||||
|
||||
if(!skipLoad) {
|
||||
std::ifstream dataFile(fname, std::ios::in | std::ios::binary);
|
||||
std::stringstream error_s;
|
||||
if (!dataFile) {
|
||||
error_s << "Error opening file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
if (seek != 0) {
|
||||
dataFile.seekg(seek * sizeof(dnnType), dataFile.cur);
|
||||
}
|
||||
|
||||
// printf("data_h %d size_b %d\n", *data_h,size_b);
|
||||
if (!dataFile.read((char *) *data_h, size_b)) {
|
||||
|
||||
error_s << "Error reading file " << fname;
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
} else {
|
||||
std::cout<<COL_RED<<"WARNING: skipping data load, this should only used in debug\n"<<COL_END;
|
||||
if (!dataFile.read ((char*) *data_h, size_b))
|
||||
{
|
||||
error_s << "Error reading file " << fname << " with n of float: "<<size;
|
||||
error_s << " seek: "<<seek << " size: "<<size_b<<"\n";
|
||||
FatalError(error_s.str());
|
||||
}
|
||||
|
||||
checkCuda( cudaMalloc(data_d, size_b) );
|
||||
checkCuda( cudaMemcpy(*data_d, *data_h, size_b, cudaMemcpyHostToDevice) );
|
||||
}
|
||||
|
||||
void printDeviceVector(int size, dnnType* vec_d, bool device)
|
||||
{
|
||||
|
||||
void printDeviceVector(int size, dnnType* vec_d, bool device){
|
||||
dnnType *vec;
|
||||
if(device) {
|
||||
vec = new dnnType[size];
|
||||
cudaDeviceSynchronize();
|
||||
cudaMemcpy(vec, vec_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
checkCuda(cudaMemcpy(vec, vec_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
} else {
|
||||
vec = vec_d;
|
||||
}
|
||||
@@ -73,7 +92,7 @@ void printDeviceVector(int size, dnnType* vec_d, bool device)
|
||||
delete [] vec;
|
||||
}
|
||||
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device, int limit) {
|
||||
|
||||
dnnType *data_h, *correct_h;
|
||||
const float eps = 0.02f;
|
||||
@@ -81,10 +100,11 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
if(device) {
|
||||
data_h = new dnnType[size];
|
||||
correct_h = new dnnType[size];
|
||||
cudaDeviceSynchronize();
|
||||
cudaMemcpy(data_h, data_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaMemcpy(correct_h, correct_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost);
|
||||
cudaDeviceSynchronize();
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
checkCuda(cudaMemcpy(data_h, data_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaMemcpy(correct_h, correct_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost));
|
||||
checkCuda(cudaDeviceSynchronize());
|
||||
|
||||
} else {
|
||||
data_h = data_d;
|
||||
correct_h = correct_d;
|
||||
@@ -96,7 +116,7 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
diffs += 1;
|
||||
if(diffs == 1)
|
||||
std::cout<<"\n";
|
||||
if(diffs < 10)
|
||||
if(diffs < limit)
|
||||
std::cout<<" | [ "<<i<<" ]: "<<data_h[i]<<" "<<correct_h[i]<<"\n";
|
||||
}
|
||||
}
|
||||
@@ -116,8 +136,18 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) {
|
||||
return diffs;
|
||||
}
|
||||
|
||||
void resize(int size, dnnType **data)
|
||||
{
|
||||
float getColor(const int c, const int x, const int max){
|
||||
float _colors[6][3] = { {1,0,1}, {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0,0} };
|
||||
float ratio = ((float)x/max)*5;
|
||||
int i = floor(ratio);
|
||||
int j = ceil(ratio);
|
||||
ratio -= i;
|
||||
float r = (1-ratio) * _colors[i % 6][c % 3] + ratio*_colors[j % 6][c % 3];
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void resize(int size, dnnType **data){
|
||||
if (*data != NULL)
|
||||
checkCuda( cudaFree(*data) );
|
||||
checkCuda( cudaMalloc(data, size*sizeof(dnnType)) );
|
||||
@@ -143,3 +173,71 @@ void matrixMulAdd( cublasHandle_t handle, dnnType* srcData, dnnType* dstData,
|
||||
checkERROR( cublasSaxpy(handle, dim, &alpha, srcData, 1, dstData, 1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void getMemUsage(double& vm_usage_kb, double& resident_set_kb){
|
||||
using std::ios_base;
|
||||
using std::ifstream;
|
||||
using std::string;
|
||||
|
||||
vm_usage_kb = 0.0;
|
||||
resident_set_kb = 0.0;
|
||||
|
||||
ifstream stat_stream("/proc/self/stat",ios_base::in);
|
||||
|
||||
//all the stats
|
||||
string pid, comm, state, ppid, pgrp, session, tty_nr;
|
||||
string tpgid, flags, minflt, cminflt, majflt, cmajflt;
|
||||
string utime, stime, cutime, cstime, priority, nice;
|
||||
string O, itrealvalue, starttime;
|
||||
|
||||
unsigned long vsize;
|
||||
long rss;
|
||||
|
||||
stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
|
||||
>> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
|
||||
>> utime >> stime >> cutime >> cstime >> priority >> nice
|
||||
>> O >> itrealvalue >> starttime >> vsize >> rss;
|
||||
|
||||
stat_stream.close();
|
||||
#ifdef __linux__
|
||||
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
|
||||
#elif _WIN32
|
||||
long page_size_kb = 4096/1024;
|
||||
#endif
|
||||
|
||||
vm_usage_kb = vsize / 1024.0;
|
||||
resident_set_kb = rss * page_size_kb;
|
||||
}
|
||||
|
||||
void printCudaMemUsage() {
|
||||
size_t free, total;
|
||||
checkCuda( cudaMemGetInfo(&free, &total) );
|
||||
std::cout<<"GPU free memory: "<<double(free)/1e6<<" mb.\n";
|
||||
}
|
||||
|
||||
void removePathAndExtension(const std::string &full_string, std::string &name){
|
||||
name = full_string;
|
||||
std::string tmp_str = full_string;
|
||||
std::string slash = "/";
|
||||
std::string dot = ".";
|
||||
std::size_t current, previous = 0;
|
||||
|
||||
//remove path /path/to/
|
||||
current = tmp_str.find(slash);
|
||||
if (current != std::string::npos) {
|
||||
while (current != std::string::npos) {
|
||||
name = tmp_str.substr(previous, current - previous);
|
||||
previous = current + 1;
|
||||
current = tmp_str.find(slash, previous);
|
||||
}
|
||||
name = tmp_str.substr(previous, current - previous);
|
||||
}
|
||||
// remove extension
|
||||
current = name.find(dot);
|
||||
previous = 0;
|
||||
if (current != std::string::npos)
|
||||
name = name.substr(previous, current);
|
||||
|
||||
// std::cout<<"full string: "<<full_string<<" name: "<<name<<std::endl;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ "$1" == "download" ]; then
|
||||
wget https://github.com/ceccocats/tkDNN/releases/download/testData/tkDNN_testwg.tar.gz --no-check-certificate
|
||||
tar -xf tkDNN_testwg.tar.gz
|
||||
rm tkDNN_testwg.tar.gz
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "build test Model"
|
||||
cd test
|
||||
python test_model.py
|
||||
cd ..
|
||||
cd mnist
|
||||
python mnist_model.py
|
||||
cd ..
|
||||
echo "export weights"
|
||||
python weights_exporter.py test/net.h5 --output test/layers
|
||||
python caffe_weights_exporter.py mnist/lenet.prototxt mnist/lenet.caffemodel --output mnist/layers
|
||||
@@ -1,38 +0,0 @@
|
||||
import argparse
|
||||
import os
|
||||
import msgpack
|
||||
import lmdb
|
||||
import random
|
||||
import caffe
|
||||
import numpy as np
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='CAFFE WEIGHTS EXPORTER TO CUDNN')
|
||||
parser.add_argument('model',type=str,
|
||||
help='Path to prototxt network model')
|
||||
parser.add_argument('weights',type=str,
|
||||
help='Path to caffemodel file')
|
||||
|
||||
parser.add_argument('--output', type=str, help="output directory", default="layers")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not os.path.exists(args.output):
|
||||
os.makedirs(args.output)
|
||||
|
||||
print "\n\n ====== NET LOADED ====== "
|
||||
net = caffe.Net(args.model, args.weights, caffe.TEST)
|
||||
n_lay = len(net.params)
|
||||
print "Number of layers: ", n_lay
|
||||
for i in xrange(n_lay):
|
||||
key = net.params.keys()[i]
|
||||
print "Layer", key
|
||||
t = net.layer_dict[key].type
|
||||
print " type: ", t
|
||||
w = net.params[key][0].data
|
||||
b = net.params[key][1].data
|
||||
print " weights shape:", np.shape(w)
|
||||
print " bias shape:", np.shape(b)
|
||||
|
||||
w.tofile(args.output + "/" + t + str(i) + ".bin", format="f")
|
||||
b.tofile(args.output + "/" + t + str(i) + ".bias.bin", format="f")
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# mail: admin@9crk.com
|
||||
# author: 9crk.from China.ShenZhen
|
||||
# time: 2017-03-22
|
||||
|
||||
import caffe
|
||||
import numpy as np
|
||||
import cv2
|
||||
import sys
|
||||
import Image
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
model = 'lenet.prototxt';
|
||||
weights = 'lenet.caffemodel';
|
||||
net = caffe.Net(model,weights,caffe.TEST);
|
||||
caffe.set_mode_gpu()
|
||||
img = np.array(np.random.rand(28,28), dtype=np.float32)
|
||||
#revert the image,and normalize it to 0-1 range
|
||||
|
||||
print "INPUT: ", img
|
||||
img.tofile("input.bin", format="f")
|
||||
print "SHAPE: ", np.shape(img)
|
||||
out = net.forward_all(data=np.asarray([img]))
|
||||
|
||||
out = out[out.keys()[0]]
|
||||
print out
|
||||
print np.shape(out)
|
||||
out.tofile("output.bin", format="f")
|
||||
#print out['prob'][0]
|
||||
#print out['prob'][0].argmax()
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#include<iostream>
|
||||
#include "tkdnn.h"
|
||||
|
||||
const char *input_bin = "../tests/mnist/input.bin";
|
||||
const char *c0_bin = "../tests/mnist/layers/c0.bin";
|
||||
const char *c1_bin = "../tests/mnist/layers/c1.bin";
|
||||
const char *d2_bin = "../tests/mnist/layers/d2.bin";
|
||||
const char *d3_bin = "../tests/mnist/layers/d3.bin";
|
||||
const char *output_bin = "../tests/mnist/output.bin";
|
||||
|
||||
int main() {
|
||||
|
||||
// Network layout
|
||||
tk::dnn::dataDim_t dim(1, 1, 28, 28, 1);
|
||||
tk::dnn::Network net(dim);
|
||||
tk::dnn::Conv2d l0(&net, 20, 5, 5, 1, 1, 0, 0, c0_bin);
|
||||
tk::dnn::Pooling l1(&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX);
|
||||
tk::dnn::Conv2d l2(&net, 50, 5, 5, 1, 1, 0, 0, c1_bin);
|
||||
tk::dnn::Pooling l3(&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX);
|
||||
tk::dnn::Dense l4(&net, 500, d2_bin);
|
||||
tk::dnn::Activation l5(&net, tk::dnn::ACTIVATION_LEAKY);
|
||||
tk::dnn::Dense l6(&net, 10, d3_bin);
|
||||
tk::dnn::Softmax l7(&net);
|
||||
|
||||
tk::dnn::NetworkRT netRT(&net, "mnist.rt");
|
||||
|
||||
// Load input
|
||||
dnnType *data;
|
||||
dnnType *input_h;
|
||||
readBinaryFile(input_bin, dim.tot(), &input_h, &data);
|
||||
|
||||
dnnType *out_data, *out_data2;
|
||||
|
||||
std::cout<<"CUDNN inference:\n"; {
|
||||
dim.print(); //print initial dimension
|
||||
TIMER_START
|
||||
out_data = net.infer(dim, data);
|
||||
TIMER_STOP
|
||||
dim.print();
|
||||
}
|
||||
|
||||
// Print result
|
||||
//std::cout<<"\n======= CUDNN RESULT =======\n";
|
||||
//printDeviceVector(10, out_data);
|
||||
|
||||
tk::dnn::dataDim_t dim2(1, 1, 28, 28, 1);
|
||||
|
||||
std::cout<<"TENSORRT inference:\n"; {
|
||||
dim2.print();
|
||||
TIMER_START
|
||||
out_data2 = netRT.infer(dim2, data);
|
||||
TIMER_STOP
|
||||
dim2.print();
|
||||
}
|
||||
|
||||
// Print result
|
||||
//std::cout<<"\n======= TENRT RESULT =======\n";
|
||||
//printDeviceVector(10, out_data);
|
||||
|
||||
std::cout<<"\n======= CHECK RESULT =======\n";
|
||||
checkResult(dim.tot(), out_data, out_data2);
|
||||
|
||||
/*
|
||||
// Print real test
|
||||
std::cout<<"\n==== CHECK RESULT ====\n";
|
||||
dnnType *out;
|
||||
dnnType *out_h;
|
||||
readBinaryFile(output_bin, dim.tot(), &out_h, &out);
|
||||
printDeviceVector(dim.tot(), out);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user