From 2c1df5619f4362f3922649d4430054739e81c0ed Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Fri, 14 Feb 2020 18:44:13 +0100 Subject: [PATCH] Move pre-processing on GPU Signed-off-by: Davide Sapienza --- include/sorting.h | 19 ++- include/tkDNN/CenternetDetection.h | 23 ++- src/CenternetDetection.cpp | 245 ++++++++++++----------------- src/sorting.cu | 35 ++--- 4 files changed, 152 insertions(+), 170 deletions(-) diff --git a/include/sorting.h b/include/sorting.h index 9c968f3..23fd34b 100644 --- a/include/sorting.h +++ b/include/sorting.h @@ -6,14 +6,31 @@ #include #include +#include +#include +#include +#include "opencv2/opencv.hpp" #include "tkdnn.h" +struct threshold : public thrust::binary_function +{ + __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 subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out); +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); diff --git a/include/tkDNN/CenternetDetection.h b/include/tkDNN/CenternetDetection.h index e39644f..7fd1c17 100644 --- a/include/tkDNN/CenternetDetection.h +++ b/include/tkDNN/CenternetDetection.h @@ -15,6 +15,7 @@ #include #include #include +#include "opencv2/opencv.hpp" #include "tkdnn.h" #include "sorting.h" @@ -29,20 +30,24 @@ class CenternetDetection { private: tk::dnn::NetworkRT *netRT = nullptr; - dnnType *input_h, *input, *input_d; + dnnType *input_d; int ndets = 0; // tk::dnn::Yolo::detection *dets = nullptr; cv::Mat imageF; - cv::Mat bgr[3]; + cv::cuda::GpuMat imageF1_d, imageF2_d; + cv::cuda::GpuMat bgr[3]; + // std::vector< cv::cuda::GpuMat > bgr; // variable to test cnet on dog pictures tk::dnn::dataDim_t dim; tk::dnn::dataDim_t dim2; - cv::Size sz; + cv::Size sz, sz_old; const char *input_bin = "../tests/resnet101_cnet/debug/input.bin"; + cv::cuda::Stream stream; + struct threshold op; // pre-process tk::dnn::dataDim_t dim_hm; tk::dnn::dataDim_t dim_wh; @@ -66,10 +71,15 @@ class CenternetDetection { float *target_coords; - cv::Vec mean; - cv::Vec stddev; + float *mean_d; + float *stddev_d; + + float *d_ptrs; + cv::Mat src; - cv::Mat dst; + cv::Mat dst; + cv::Mat dst2; + cv::Mat trans, trans2; //processing float toll = 0.000001; int K = 100; @@ -108,7 +118,6 @@ class CenternetDetection { * @return Success of the initialization */ bool init(std::string tensor_path); - void testdog(); cv::Mat draw(cv::Mat &frame); void update(cv::Mat &frame); diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp index c707c6c..7840db7 100644 --- a/src/CenternetDetection.cpp +++ b/src/CenternetDetection.cpp @@ -37,10 +37,11 @@ bool CenternetDetection::init(std::string tensor_path) { coco_class_name = std::vector(coco_class_name_, std::end( coco_class_name_ )); src = cv::Mat(cv::Size(2,3), CV_32F); dst = cv::Mat(cv::Size(2,3), CV_32F); + 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); // dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); - 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())); // dim_hm = tk::dnn::dataDim_t(1, 80, 56, 56, 1); @@ -94,61 +95,31 @@ bool CenternetDetection::init(std::string tensor_path) { checkCuda( cudaMallocHost(&target_coords, 4 * K *sizeof(float)) ); - mean << 0.408, 0.447, 0.47; - stddev << 0.289, 0.274, 0.278; + 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)); + + checkCuda( cudaMalloc(&d_ptrs, dim.c * dim.h*dim.w * sizeof(float)) ); + // mean << 0.408, 0.447, 0.47; + // stddev << 0.289, 0.274, 0.278; // Alloc array used in the kernel checkCuda( cudaMalloc(&src_out, K *sizeof(float)) ); checkCuda( cudaMalloc(&ids_out, K *sizeof(int)) ); // checkCuda( cudaFree(src_out) ); // checkCuda( cudaFree(ids_out) ); - -} - -void CenternetDetection::testdog() { - - readBinaryFile(input_bin, dim.tot(), &input_h, &input_d); - - // -------- transofrm compose - cv::Mat imageORIG = cv::imread("../../dog.jpg"); - imageORIG.convertTo(imageF, CV_32FC3, 1/255.0); - sz = imageF.size(); - std::cout<<"image: "<(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME threshold: " << std::chrono::duration_cast(end_t - step_t).count() << " us" << std::endl; step_t = end_t; // ----------- nms end // ----------- topk @@ -329,7 +308,7 @@ void CenternetDetection::update(cv::Mat &imageORIG) { ids_d); checkCuda( cudaDeviceSynchronize() ); end_t = std::chrono::steady_clock::now(); - std::cout << " TIME sort: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME sort: " << std::chrono::duration_cast(end_t - step_t).count() << " us" << std::endl; step_t = end_t; topk(rt_out[0], ids_d, K, scores_d, @@ -337,14 +316,14 @@ void CenternetDetection::update(cv::Mat &imageORIG) { checkCuda( cudaDeviceSynchronize() ); end_t = std::chrono::steady_clock::now(); - std::cout << " TIME topk: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME topk: " << std::chrono::duration_cast(end_t - step_t).count() << " us" << std::endl; step_t = end_t; checkCuda( cudaMemcpy(scores, scores_d, K *sizeof(float), cudaMemcpyDeviceToHost) ); 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(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME topk x y clses 2: " << std::chrono::duration_cast(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) ); @@ -358,7 +337,7 @@ void CenternetDetection::update(cv::Mat &imageORIG) { // checkCuda( cudaDeviceSynchronize() ); end_t = std::chrono::steady_clock::now(); - std::cout << " TIME add offset: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME add offset: " << std::chrono::duration_cast(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); @@ -370,35 +349,13 @@ void CenternetDetection::update(cv::Mat &imageORIG) { checkCuda( cudaMemcpy(bby1, bby1_d, K * sizeof(float), cudaMemcpyDeviceToHost) ); end_t = std::chrono::steady_clock::now(); - std::cout << " TIME bboxes: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME bboxes: " << std::chrono::duration_cast(end_t - step_t).count() << " us" << std::endl; step_t = end_t; // ---------------------------------- post-process ----------------------------------------- // --------- ctdet_post_process // --------- transform_preds - src.at(0,0)=c[0]; - src.at(0,1)=c[1]; - src.at(1,0)=c[0]; - src.at(1,1)=c[1] + s[0] * -0.5; - dst.at(0,0)=width * 0.5; - dst.at(0,1)=width * 0.5; - dst.at(1,0)=width * 0.5; - dst.at(1,1)=width * 0.5 + width * -0.5; - - src.at(2,0)=src.at(1,0) + (-src.at(0,1)+src.at(1,1) ); - src.at(2,1)=src.at(1,1) + (src.at(0,0)-src.at(1,0) ); - dst.at(2,0)=dst.at(1,0) + (-dst.at(0,1)+dst.at(1,1) ); - dst.at(2,1)=dst.at(1,1) + (dst.at(0,0)-dst.at(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(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); @@ -422,7 +379,7 @@ void CenternetDetection::update(cv::Mat &imageORIG) { target_coords[i*4+2] = new_pt2.at(0,0); target_coords[i*4+3] = new_pt2.at(0,1); } - + detected.clear(); for(int i = 0; i(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME detections: " << std::chrono::duration_cast(end_t - step_t).count() << " us" << std::endl; step_t = end_t; std::cout<<"TOTAL: \n"; diff --git a/src/sorting.cu b/src/sorting.cu index 3ba5ac3..3c0f137 100644 --- a/src/sorting.cu +++ b/src/sorting.cu @@ -16,10 +16,7 @@ void topk(dnnType *src_begin, int *idsrc, int K, float *topk_scores, 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__ @@ -28,7 +25,6 @@ void sortAndTopK_kernel(dnnType *src_begin, int *idsrc, float *topk_scores, int thrust::sort_by_key(thrust::device, src_begin + i * size, src_begin + i * size + size, idsrc + i * size, thrust::greater()); 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 ); } @@ -41,20 +37,23 @@ void sortAndTopKonDevice(dnnType *src_begin, int *idsrc, float *topk_scores, int } -struct threshold : public thrust::binary_function -{ - __host__ __device__ - float operator()(float x, float y) { - double toll = 1e-6; - if(fabsf(x-y)>toll) - return 0.0f; - else - return x; - } -}; +__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 subtractWithThreshold(dnnType *src_begin, dnnType *src_end, dnnType *src2_begin, dnnType *src_out){ - struct threshold op; +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<<>>(bgr, h*w, mean, stddev); +} + +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); }