From 8c629ebe7b5a845cc8b1cc6f1661d043ebe7b4a8 Mon Sep 17 00:00:00 2001 From: mbosi <205839@studenti.unimore.it> Date: Sat, 14 Sep 2019 19:03:13 +0200 Subject: [PATCH 001/228] string input and flir test --- include/Layer.h | 10 +- include/models/Yolo3.h | 289 +++++++++ include/utils.h | 2 +- src/Conv2d.cpp | 2 +- src/Dense.cpp | 2 +- src/LayerWgs.cpp | 2 +- src/Region.cpp | 2 +- src/Yolo.cpp | 4 +- src/Yolo3Detection.cpp | 2 +- src/utils.cpp | 2 +- tests/yolo3_berkeley/yolo3_berkeley.cpp | 308 +--------- tests/yolo3_coco4/yolo3_coco4.cpp | 308 +--------- tests/yolo3_flir/yolo3_flir.cfg | 785 ++++++++++++++++++++++++ tests/yolo3_flir/yolo3_flir.cpp | 88 +++ 14 files changed, 1198 insertions(+), 608 deletions(-) create mode 100644 include/models/Yolo3.h create mode 100644 tests/yolo3_flir/yolo3_flir.cfg create mode 100644 tests/yolo3_flir/yolo3_flir.cpp diff --git a/include/Layer.h b/include/Layer.h index c7871b5..55729ce 100644 --- a/include/Layer.h +++ b/include/Layer.h @@ -75,7 +75,7 @@ class LayerWgs : public Layer { public: LayerWgs(Network *net, int inputs, int outputs, int kh, int kw, int kt, - const char* fname_weights, bool batchnorm = false); + std::string fname_weights, bool batchnorm = false); virtual ~LayerWgs(); int inputs, outputs; @@ -108,7 +108,7 @@ public: class Dense : public LayerWgs { public: - Dense(Network *net, int out_ch, const char* fname_weights); + Dense(Network *net, int out_ch, std::string fname_weights); virtual ~Dense(); virtual layerType_t getLayerType() { return LAYER_DENSE; }; @@ -151,7 +151,7 @@ class Conv2d : public LayerWgs { public: Conv2d( Network *net, int out_ch, int kernelH, int kernelW, int strideH, int strideW, int paddingH, int paddingW, - const char* fname_weights, bool batchnorm = false); + std::string fname_weights, bool batchnorm = false); virtual ~Conv2d(); virtual layerType_t getLayerType() { return LAYER_CONV2D; }; @@ -352,7 +352,7 @@ public: int sort_class; }; - Yolo(Network *net, int classes, int num, const char* fname_weights); + Yolo(Network *net, int classes, int num, std::string fname_weights); virtual ~Yolo(); virtual layerType_t getLayerType() { return LAYER_YOLO; }; @@ -389,7 +389,7 @@ class RegionInterpret { public: RegionInterpret(dataDim_t input_dim, dataDim_t output_dim, - int classes, int coords, int num, float thresh, const char* fname_weights); + int classes, int coords, int num, float thresh, std::string fname_weights); ~RegionInterpret(); dataDim_t input_dim, output_dim; diff --git a/include/models/Yolo3.h b/include/models/Yolo3.h new file mode 100644 index 0000000..cd69b32 --- /dev/null +++ b/include/models/Yolo3.h @@ -0,0 +1,289 @@ +int preYoloFilters = (classes+5)*3; + +std::string input_bin = bin_path + "/layers/input.bin"; +std::vector 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; \ No newline at end of file diff --git a/include/utils.h b/include/utils.h index a46b2c4..dc34a31 100644 --- a/include/utils.h +++ b/include/utils.h @@ -90,7 +90,7 @@ void printCenteredTitle(const char *title, char fill, int dim); bool fileExist(const char *fname); -void readBinaryFile(const char* fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0); +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); void printDeviceVector(int size, dnnType* vec_d, bool device = true); void resize(int size, dnnType **data); diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index bfb8316..3dfdce6 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -6,7 +6,7 @@ namespace tk { namespace dnn { Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW, int strideH, int strideW, int paddingH, int paddingW, - const char* fname_weights, bool batchnorm) : + std::string fname_weights, bool batchnorm) : LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1, fname_weights, batchnorm) { diff --git a/src/Dense.cpp b/src/Dense.cpp index f86aa4a..b6a9af2 100644 --- a/src/Dense.cpp +++ b/src/Dense.cpp @@ -4,7 +4,7 @@ namespace tk { namespace dnn { -Dense::Dense(Network *net, int out_ch, const char* fname_weights) : +Dense::Dense(Network *net, int out_ch, std::string fname_weights) : LayerWgs(net, net->getOutputDim().tot(), out_ch, 1, 1, 1, fname_weights) { output_dim.n = 1; diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index d8bb881..f27da0f 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -8,7 +8,7 @@ namespace tk { namespace dnn { LayerWgs::LayerWgs(Network *net, int inputs, int outputs, int kh, int kw, int kl, - const char* fname_weights, bool batchnorm) : Layer(net) { + std::string fname_weights, bool batchnorm) : Layer(net) { this->inputs = inputs; this->outputs = outputs; diff --git a/src/Region.cpp b/src/Region.cpp index 56010dd..1b52375 100644 --- a/src/Region.cpp +++ b/src/Region.cpp @@ -66,7 +66,7 @@ dnnType* Region::infer(dataDim_t &dim, dnnType* srcData) { /* Intepret class */ RegionInterpret::RegionInterpret(dataDim_t input_dim, dataDim_t output_dim, - int classes, int coords, int num, float thresh, const char* fname_weights) { + int classes, int coords, int num, float thresh, std::string fname_weights) { this->input_dim = input_dim; this->output_dim = output_dim; diff --git a/src/Yolo.cpp b/src/Yolo.cpp index 0dcea7e..f2ec53c 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -11,14 +11,14 @@ namespace tk { namespace dnn { -Yolo::Yolo(Network *net, int classes, int num, const char* fname_weights) : +Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights) : Layer(net) { this->classes = classes; this->num = num; // load anchors - if(fname_weights != nullptr) { + if(fname_weights != "") { int seek = 0; readBinaryFile(fname_weights, num, &mask_h, &mask_d, seek); seek += num; diff --git a/src/Yolo3Detection.cpp b/src/Yolo3Detection.cpp index e121503..ce9fd6a 100644 --- a/src/Yolo3Detection.cpp +++ b/src/Yolo3Detection.cpp @@ -32,7 +32,7 @@ bool Yolo3Detection::init(std::string tensor_path) { num = yRT->num; // make a yolo layer for interpret predictions - yolo[i] = new tk::dnn::Yolo(nullptr, classes, num, nullptr); // yolo without input and bias + yolo[i] = new tk::dnn::Yolo(nullptr, classes, num, ""); // yolo without input and bias yolo[i]->mask_h = new dnnType[num]; yolo[i]->bias_h = new dnnType[num*3*2]; memcpy(yolo[i]->mask_h, yRT->mask, sizeof(dnnType)*num); diff --git a/src/utils.cpp b/src/utils.cpp index 7955d15..e6f71f8 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -21,7 +21,7 @@ bool fileExist(const char *fname) { } -void readBinaryFile(const char* fname, int size, dnnType** data_h, dnnType** data_d, int seek) +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; diff --git a/tests/yolo3_berkeley/yolo3_berkeley.cpp b/tests/yolo3_berkeley/yolo3_berkeley.cpp index 3a69e32..43f5da5 100644 --- a/tests/yolo3_berkeley/yolo3_berkeley.cpp +++ b/tests/yolo3_berkeley/yolo3_berkeley.cpp @@ -1,295 +1,18 @@ #include +#include #include "tkdnn.h" -const char *input_bin = "../tests/yolo3_berkeley/layers/input.bin"; -const char *c0_bin = "../tests/yolo3_berkeley/layers/c0.bin"; -const char *c1_bin = "../tests/yolo3_berkeley/layers/c1.bin"; -const char *c2_bin = "../tests/yolo3_berkeley/layers/c2.bin"; -const char *c3_bin = "../tests/yolo3_berkeley/layers/c3.bin"; -const char *c5_bin = "../tests/yolo3_berkeley/layers/c5.bin"; -const char *c6_bin = "../tests/yolo3_berkeley/layers/c6.bin"; -const char *c7_bin = "../tests/yolo3_berkeley/layers/c7.bin"; -const char *c9_bin = "../tests/yolo3_berkeley/layers/c9.bin"; -const char *c10_bin = "../tests/yolo3_berkeley/layers/c10.bin"; -const char *c12_bin = "../tests/yolo3_berkeley/layers/c12.bin"; -const char *c13_bin = "../tests/yolo3_berkeley/layers/c13.bin"; -const char *c14_bin = "../tests/yolo3_berkeley/layers/c14.bin"; -const char *c16_bin = "../tests/yolo3_berkeley/layers/c16.bin"; -const char *c17_bin = "../tests/yolo3_berkeley/layers/c17.bin"; -const char *c19_bin = "../tests/yolo3_berkeley/layers/c19.bin"; -const char *c20_bin = "../tests/yolo3_berkeley/layers/c20.bin"; -const char *c22_bin = "../tests/yolo3_berkeley/layers/c22.bin"; -const char *c23_bin = "../tests/yolo3_berkeley/layers/c23.bin"; -const char *c25_bin = "../tests/yolo3_berkeley/layers/c25.bin"; -const char *c26_bin = "../tests/yolo3_berkeley/layers/c26.bin"; -const char *c28_bin = "../tests/yolo3_berkeley/layers/c28.bin"; -const char *c29_bin = "../tests/yolo3_berkeley/layers/c29.bin"; -const char *c31_bin = "../tests/yolo3_berkeley/layers/c31.bin"; -const char *c32_bin = "../tests/yolo3_berkeley/layers/c32.bin"; -const char *c34_bin = "../tests/yolo3_berkeley/layers/c34.bin"; -const char *c35_bin = "../tests/yolo3_berkeley/layers/c35.bin"; -const char *c37_bin = "../tests/yolo3_berkeley/layers/c37.bin"; -const char *c38_bin = "../tests/yolo3_berkeley/layers/c38.bin"; -const char *c39_bin = "../tests/yolo3_berkeley/layers/c39.bin"; -const char *c41_bin = "../tests/yolo3_berkeley/layers/c41.bin"; -const char *c42_bin = "../tests/yolo3_berkeley/layers/c42.bin"; -const char *c44_bin = "../tests/yolo3_berkeley/layers/c44.bin"; -const char *c45_bin = "../tests/yolo3_berkeley/layers/c45.bin"; -const char *c47_bin = "../tests/yolo3_berkeley/layers/c47.bin"; -const char *c48_bin = "../tests/yolo3_berkeley/layers/c48.bin"; -const char *c50_bin = "../tests/yolo3_berkeley/layers/c50.bin"; -const char *c51_bin = "../tests/yolo3_berkeley/layers/c51.bin"; -const char *c53_bin = "../tests/yolo3_berkeley/layers/c53.bin"; -const char *c54_bin = "../tests/yolo3_berkeley/layers/c54.bin"; -const char *c56_bin = "../tests/yolo3_berkeley/layers/c56.bin"; -const char *c57_bin = "../tests/yolo3_berkeley/layers/c57.bin"; -const char *c59_bin = "../tests/yolo3_berkeley/layers/c59.bin"; -const char *c60_bin = "../tests/yolo3_berkeley/layers/c60.bin"; -const char *c62_bin = "../tests/yolo3_berkeley/layers/c62.bin"; -const char *c63_bin = "../tests/yolo3_berkeley/layers/c63.bin"; -const char *c64_bin = "../tests/yolo3_berkeley/layers/c64.bin"; -const char *c66_bin = "../tests/yolo3_berkeley/layers/c66.bin"; -const char *c67_bin = "../tests/yolo3_berkeley/layers/c67.bin"; -const char *c69_bin = "../tests/yolo3_berkeley/layers/c69.bin"; -const char *c70_bin = "../tests/yolo3_berkeley/layers/c70.bin"; -const char *c72_bin = "../tests/yolo3_berkeley/layers/c72.bin"; -const char *c73_bin = "../tests/yolo3_berkeley/layers/c73.bin"; -const char *c75_bin = "../tests/yolo3_berkeley/layers/c75.bin"; -const char *c76_bin = "../tests/yolo3_berkeley/layers/c76.bin"; -const char *c77_bin = "../tests/yolo3_berkeley/layers/c77.bin"; -const char *c78_bin = "../tests/yolo3_berkeley/layers/c78.bin"; -const char *c79_bin = "../tests/yolo3_berkeley/layers/c79.bin"; -const char *c80_bin = "../tests/yolo3_berkeley/layers/c80.bin"; -const char *c81_bin = "../tests/yolo3_berkeley/layers/c81.bin"; -const char *g82_bin = "../tests/yolo3_berkeley/layers/g82.bin"; -const char *c84_bin = "../tests/yolo3_berkeley/layers/c84.bin"; -const char *c87_bin = "../tests/yolo3_berkeley/layers/c87.bin"; -const char *c88_bin = "../tests/yolo3_berkeley/layers/c88.bin"; -const char *c89_bin = "../tests/yolo3_berkeley/layers/c89.bin"; -const char *c90_bin = "../tests/yolo3_berkeley/layers/c90.bin"; -const char *c91_bin = "../tests/yolo3_berkeley/layers/c91.bin"; -const char *c92_bin = "../tests/yolo3_berkeley/layers/c92.bin"; -const char *c93_bin = "../tests/yolo3_berkeley/layers/c93.bin"; -const char *g94_bin = "../tests/yolo3_berkeley/layers/g94.bin"; -const char *c96_bin = "../tests/yolo3_berkeley/layers/c96.bin"; -const char *c99_bin = "../tests/yolo3_berkeley/layers/c99.bin"; -const char *c100_bin = "../tests/yolo3_berkeley/layers/c100.bin"; -const char *c101_bin = "../tests/yolo3_berkeley/layers/c101.bin"; -const char *c102_bin = "../tests/yolo3_berkeley/layers/c102.bin"; -const char *c103_bin = "../tests/yolo3_berkeley/layers/c103.bin"; -const char *c104_bin = "../tests/yolo3_berkeley/layers/c104.bin"; -const char *c105_bin = "../tests/yolo3_berkeley/layers/c105.bin"; -const char *g106_bin = "../tests/yolo3_berkeley/layers/g106.bin"; -const char *output_bins[3] = { - "../tests/yolo3_berkeley/debug/layer82_out.bin", - "../tests/yolo3_berkeley/debug/layer94_out.bin", - "../tests/yolo3_berkeley/debug/layer106_out.bin" -}; - int main() { // Network layout tk::dnn::dataDim_t dim(1, 3, 320, 544, 1); tk::dnn::Network net(dim); - 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, 45, 1, 1, 1, 1, 0, 0, c81_bin, false); - tk::dnn::Yolo yolo0 (&net, 10, 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, 45, 1, 1, 1, 1, 0, 0, c93_bin, false); - tk::dnn::Yolo yolo1 (&net, 10, 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, 45, 1, 1, 1, 1, 0, 0, c105_bin, false); - tk::dnn::Yolo yolo2 (&net, 10, 3, g106_bin); + // create yolo3 model + std::string bin_path = "../tests/yolo3_berkeley"; + int classes = 10; + tk::dnn::Yolo *yolo [3]; + #include "models/Yolo3.h" // Load input dnnType *data; @@ -304,9 +27,7 @@ int main() { // the network have 3 outputs tk::dnn::dataDim_t out_dim[3]; - out_dim[0] = yolo0.output_dim; - out_dim[1] = yolo1.output_dim; - out_dim[2] = yolo2.output_dim; + for(int i=0; i<3; i++) out_dim[i] = yolo[i]->output_dim; dnnType *cudnn_out[3], *rt_out[3]; tk::dnn::dataDim_t dim1 = dim; //input dim @@ -317,18 +38,13 @@ int main() { TIMER_STOP dim1.print(); } - cudnn_out[0] = yolo0.dstData; - cudnn_out[1] = yolo1.dstData; - cudnn_out[2] = yolo2.dstData; - + for(int i=0; i<3; i++) cudnn_out[i] = yolo[i]->dstData; + printCenteredTitle(" compute detections ", '=', 30); TIMER_START int ndets = 0; - int classes = yolo0.classes; tk::dnn::Yolo::detection *dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); - yolo0.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); - yolo1.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); - yolo2.computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); + for(int i=0; i<3; i++) yolo[i]->computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); tk::dnn::Yolo::mergeDetections(dets, ndets, classes); for(int j=0; jcomputeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); tk::dnn::Yolo::mergeDetections(dets, ndets, classes); for(int j=0; jdstData; + + printCenteredTitle(" compute detections ", '=', 30); + TIMER_START + int ndets = 0; + tk::dnn::Yolo::detection *dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); + for(int i=0; i<3; i++) yolo[i]->computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); + tk::dnn::Yolo::mergeDetections(dets, ndets, classes); + + for(int j=0; j 0) + cl = c; + } + std::cout< Date: Sun, 15 Sep 2019 16:19:30 +0200 Subject: [PATCH 002/228] yolo3 flir ok --- CMakeLists.txt | 3 +++ demo/demo/demo.cpp | 4 +++- src/Yolo3Detection.cpp | 13 +++++++------ tests/yolo3_flir/yolo3_flir.cfg | 14 +++++++------- tests/yolo3_flir/yolo3_flir.cpp | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acf3613..f94ccbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,9 @@ target_link_libraries(test_yolo3_coco4 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) ################################################################################ diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index e57a36e..82f724b 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -12,7 +12,9 @@ #include "Yolo3Detection.h" bool gRun; -std::string obj_class[10] {"person", "car", "truck", "bus", "motor", "bike", "rider", "traffic light", "traffic sign", "train"}; +//std::string obj_class[10] {"person", "car", "truck", "bus", "motor", "bike", "rider", "traffic light", "traffic sign", "train"}; +//std::string obj_class[3] {"person", "bike", "car"}; +std::string obj_class[10] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; void sig_handler(int signo) { diff --git a/src/Yolo3Detection.cpp b/src/Yolo3Detection.cpp index ce9fd6a..244aa36 100644 --- a/src/Yolo3Detection.cpp +++ b/src/Yolo3Detection.cpp @@ -68,18 +68,19 @@ void Yolo3Detection::update(cv::Mat &imageORIG) { 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); //split channels cv::split(imageF,bgr);//split source //write channels - int idx = 0; - memcpy((void*)&input[idx], (void*)bgr[2].data, imageF.rows*imageF.cols*sizeof(dnnType)); - idx = imageF.rows*imageF.cols; - memcpy((void*)&input[idx], (void*)bgr[1].data, imageF.rows*imageF.cols*sizeof(dnnType)); - idx *= 2; - memcpy((void*)&input[idx], (void*)bgr[0].data, imageF.rows*imageF.cols*sizeof(dnnType)); + for(int i=0; iinput_dim.c; i++) { + int idx = i*imageF.rows*imageF.cols; + int ch = netRT->input_dim.c-1 -i; + memcpy((void*)&input[idx], (void*)bgr[ch].data, imageF.rows*imageF.cols*sizeof(dnnType)); + } + //DO INFERENCE dnnType *rt_out[3]; diff --git a/tests/yolo3_flir/yolo3_flir.cfg b/tests/yolo3_flir/yolo3_flir.cfg index 3a39bd8..1bbf5c1 100644 --- a/tests/yolo3_flir/yolo3_flir.cfg +++ b/tests/yolo3_flir/yolo3_flir.cfg @@ -17,7 +17,7 @@ hue=.1 learning_rate=0.001 burn_in=1000 -max_batches = 10000 +max_batches = 20000 policy=steps steps=8000,9000 scales=.1,.1 @@ -602,13 +602,13 @@ activation=leaky size=1 stride=1 pad=1 -filters=30 +filters=24 activation=linear [yolo] mask = 6,7,8 anchors = 8.2087,8.5515, 18.4134,20.3391, 40.2194,29.2990, 31.6137,69.2240, 69.8497,48.3838, 108.8817,76.6316, 96.5753,145.5743, 165.9182,117.4493, 215.7497,198.4648 -classes=5 +classes=3 num=9 jitter=.3 ignore_thresh = .5 @@ -686,13 +686,13 @@ activation=leaky size=1 stride=1 pad=1 -filters=30 +filters=24 activation=linear [yolo] mask = 3,4,5 anchors = 8.2087,8.5515, 18.4134,20.3391, 40.2194,29.2990, 31.6137,69.2240, 69.8497,48.3838, 108.8817,76.6316, 96.5753,145.5743, 165.9182,117.4493, 215.7497,198.4648 -classes=5 +classes=3 num=9 jitter=.3 ignore_thresh = .5 @@ -770,13 +770,13 @@ activation=leaky size=1 stride=1 pad=1 -filters=30 +filters=24 activation=linear [yolo] mask = 0,1,2 anchors = 8.2087,8.5515, 18.4134,20.3391, 40.2194,29.2990, 31.6137,69.2240, 69.8497,48.3838, 108.8817,76.6316, 96.5753,145.5743, 165.9182,117.4493, 215.7497,198.4648 -classes=5 +classes=3 num=9 jitter=.3 ignore_thresh = .5 diff --git a/tests/yolo3_flir/yolo3_flir.cpp b/tests/yolo3_flir/yolo3_flir.cpp index 62c1889..2bc45e4 100644 --- a/tests/yolo3_flir/yolo3_flir.cpp +++ b/tests/yolo3_flir/yolo3_flir.cpp @@ -11,7 +11,7 @@ int main() { // create yolo3 model std::string bin_path = "../tests/yolo3_flir"; - int classes = 5; + int classes = 3; tk::dnn::Yolo *yolo [3]; #include "models/Yolo3.h" From 77f031c0f488c0ffb36f63a5215e39f5b3c81625 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Mon, 16 Sep 2019 10:35:29 +0200 Subject: [PATCH 003/228] save video result --- demo/demo/demo.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index 82f724b..7ed80da 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -16,6 +16,7 @@ bool gRun; //std::string obj_class[3] {"person", "bike", "car"}; std::string obj_class[10] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; +bool SAVE_RESULT = false; void sig_handler(int signo) { std::cout<<"request gateway stop\n"; @@ -46,6 +47,14 @@ int main(int argc, char *argv[]) { 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_FOURCC('M','P','4','V'), 30, cv::Size(w, h)); + } + cv::Mat frame; cv::Mat dnn_input; cv::namedWindow("detection", cv::WINDOW_NORMAL); @@ -53,7 +62,7 @@ int main(int argc, char *argv[]) { while(gRun) { cap >> frame; if(!frame.data) { - continue; + break; } // this will be resized to the net format @@ -86,6 +95,8 @@ int main(int argc, char *argv[]) { cv::imshow("detection", frame); cv::waitKey(1); + if(SAVE_RESULT) + resultVideo << frame; } std::cout<<"detection end\n"; From ec02c7292fa7113140b923c25535aca17618e670 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Mon, 16 Sep 2019 19:41:59 +0200 Subject: [PATCH 004/228] save layer names in rt file --- demo/demo/demo.cpp | 6 +----- include/Layer.h | 2 ++ include/Yolo3Detection.h | 7 +++++++ include/pluginsRT/YoloRT.h | 15 ++++++++++++++- src/NetworkRT.cpp | 9 +++++++++ src/Yolo.cpp | 6 ++++++ src/Yolo3Detection.cpp | 1 + tests/yolo3_berkeley/yolo3_berkeley.cpp | 5 +++++ tests/yolo3_flir/yolo3_flir.cpp | 5 +++++ 9 files changed, 50 insertions(+), 6 deletions(-) diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index 7ed80da..ac6c63d 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -12,10 +12,6 @@ #include "Yolo3Detection.h" bool gRun; -//std::string obj_class[10] {"person", "car", "truck", "bus", "motor", "bike", "rider", "traffic light", "traffic sign", "train"}; -//std::string obj_class[3] {"person", "bike", "car"}; -std::string obj_class[10] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; - bool SAVE_RESULT = false; void sig_handler(int signo) { @@ -77,7 +73,7 @@ int main(int argc, char *argv[]) { int x1 = b.x + b.w; int y0 = b.y; int y1 = b.y + b.h; - std::string det_class = obj_class[b.cl]; + std::string det_class = yolo.getYoloLayer()->classesNames[b.cl]; float prob = b.prob; std::cout< +#include #include "utils.h" #include "Network.h" @@ -359,6 +360,7 @@ public: int classes, num; dnnType *mask_h, *mask_d; //anchors dnnType *bias_h, *bias_d; //anchors + std::vector classesNames; virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); int computeDetections(Yolo::detection *dets, int &ndets, int netw, int neth, float thresh); diff --git a/include/Yolo3Detection.h b/include/Yolo3Detection.h index 0ff4b1e..0a7ba25 100644 --- a/include/Yolo3Detection.h +++ b/include/Yolo3Detection.h @@ -52,6 +52,13 @@ class Yolo3Detection { void update(cv::Mat &frame); + tk::dnn::Yolo* getYoloLayer(int n=0) { + if(n<3) + return yolo[n]; + else + return nullptr; + } + }; }} diff --git a/include/pluginsRT/YoloRT.h b/include/pluginsRT/YoloRT.h index 2e52142..dab7c18 100644 --- a/include/pluginsRT/YoloRT.h +++ b/include/pluginsRT/YoloRT.h @@ -1,6 +1,8 @@ #include #include "../kernels.h" +#define YOLORT_CLASSNAME_W 256 + class YoloRT : public IPlugin { @@ -16,6 +18,7 @@ public: if(yolo != nullptr) { memcpy(mask, yolo->mask_h, sizeof(dnnType)*num); memcpy(bias, yolo->bias_h, sizeof(dnnType)*num*3*2); + classesNames = yolo->classesNames; } } @@ -72,7 +75,7 @@ public: virtual size_t getSerializationSize() override { - return 5*sizeof(int) + num*sizeof(dnnType) + num*3*2*sizeof(dnnType); + return 5*sizeof(int) + num*sizeof(dnnType) + num*3*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char); } virtual void serialize(void* buffer) override { @@ -86,10 +89,20 @@ public: tk::dnn::writeBUF(buf, mask[i]); for(int i=0; i<3*2*num; i++) tk::dnn::writeBUF(buf, bias[i]); + + // save classes names + for(int i=0; i classesNames; dnnType *mask; dnnType *bias; diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 2a73efa..7430b6f 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -461,6 +461,15 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa for(int i=0; i<3*2*r->num; i++) r->bias[i] = readBUF(buf); + // save classes names + r->classesNames.resize(r->classes); + for(int i=0; iclasses; i++) { + char tmp[YOLORT_CLASSNAME_W]; + for(int j=0; j(buf); + r->classesNames[i] = std::string(tmp); + } + yolos[n_yolos++] = r; return r; } diff --git a/src/Yolo.cpp b/src/Yolo.cpp index f2ec53c..babef38 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -25,6 +25,12 @@ Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights) : readBinaryFile(fname_weights, 3*num*2, &bias_h, &bias_d, seek); } + // init default classes name + classesNames.clear(); + for(int i=0; imask_h, yRT->mask, sizeof(dnnType)*num); memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*3*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; } dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); diff --git a/tests/yolo3_berkeley/yolo3_berkeley.cpp b/tests/yolo3_berkeley/yolo3_berkeley.cpp index 43f5da5..70e8b60 100644 --- a/tests/yolo3_berkeley/yolo3_berkeley.cpp +++ b/tests/yolo3_berkeley/yolo3_berkeley.cpp @@ -14,6 +14,11 @@ int main() { tk::dnn::Yolo *yolo [3]; #include "models/Yolo3.h" + // fill classes names + for(int i=0; i<3; i++) { + yolo[i]->classesNames = {"person", "car", "truck", "bus", "motor", "bike", "rider", "traffic light", "traffic sign", "train"}; + } + // Load input dnnType *data; dnnType *input_h; diff --git a/tests/yolo3_flir/yolo3_flir.cpp b/tests/yolo3_flir/yolo3_flir.cpp index 2bc45e4..83b53af 100644 --- a/tests/yolo3_flir/yolo3_flir.cpp +++ b/tests/yolo3_flir/yolo3_flir.cpp @@ -15,6 +15,11 @@ int main() { tk::dnn::Yolo *yolo [3]; #include "models/Yolo3.h" + // fill classes names + for(int i=0; i<3; i++) { + yolo[i]->classesNames = {"person", "bike", "car"}; + } + // Load input dnnType *data; dnnType *input_h; From ca62784f57d177e3fc9e5ec360fc13d44586a2a0 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 17 Sep 2019 15:22:39 +0200 Subject: [PATCH 005/228] include dir fix, cmake dir --- CMakeLists.txt | 5 ++--- tkDNNConfig.cmake => cmake/tkDNNConfig.cmake | 0 include/{ => tkDNN}/Layer.h | 0 include/{ => tkDNN}/Network.h | 0 include/{ => tkDNN}/NetworkRT.h | 0 include/{ => tkDNN}/Yolo3Detection.h | 0 include/{ => tkDNN}/kernels.h | 0 include/{ => tkDNN}/models/Yolo3.h | 0 include/{ => tkDNN}/pluginsRT/ActivationLeakyRT.h | 0 include/{ => tkDNN}/pluginsRT/Int8Calibrator.h | 0 include/{ => tkDNN}/pluginsRT/RegionRT.h | 0 include/{ => tkDNN}/pluginsRT/ReorgRT.h | 0 include/{ => tkDNN}/pluginsRT/RouteRT.h | 0 include/{ => tkDNN}/pluginsRT/ShortcutRT.h | 0 include/{ => tkDNN}/pluginsRT/UpsampleRT.h | 0 include/{ => tkDNN}/pluginsRT/YoloRT.h | 0 include/{ => tkDNN}/tkdnn.h | 0 include/{ => tkDNN}/utils.h | 0 18 files changed, 2 insertions(+), 3 deletions(-) rename tkDNNConfig.cmake => cmake/tkDNNConfig.cmake (100%) rename include/{ => tkDNN}/Layer.h (100%) rename include/{ => tkDNN}/Network.h (100%) rename include/{ => tkDNN}/NetworkRT.h (100%) rename include/{ => tkDNN}/Yolo3Detection.h (100%) rename include/{ => tkDNN}/kernels.h (100%) rename include/{ => tkDNN}/models/Yolo3.h (100%) rename include/{ => tkDNN}/pluginsRT/ActivationLeakyRT.h (100%) rename include/{ => tkDNN}/pluginsRT/Int8Calibrator.h (100%) rename include/{ => tkDNN}/pluginsRT/RegionRT.h (100%) rename include/{ => tkDNN}/pluginsRT/ReorgRT.h (100%) rename include/{ => tkDNN}/pluginsRT/RouteRT.h (100%) rename include/{ => tkDNN}/pluginsRT/ShortcutRT.h (100%) rename include/{ => tkDNN}/pluginsRT/UpsampleRT.h (100%) rename include/{ => tkDNN}/pluginsRT/YoloRT.h (100%) rename include/{ => tkDNN}/tkdnn.h (100%) rename include/{ => tkDNN}/utils.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f94ccbb..a35264c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project (tkDNN) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/tkDNN) # project specific flags if(DEBUG) @@ -110,8 +110,7 @@ target_link_libraries(yolo3_demo tkDNN) # CACHE PATH "default install path" FORCE) #endif() message("install dir:" ${CMAKE_INSTALL_PREFIX}) -install(DIRECTORY include/ DESTINATION include/${CMAKE_PROJECT_NAME} -FILES_MATCHING PATTERN "*.h") +install(DIRECTORY include/ DESTINATION include/) install(TARGETS tkDNN kernels DESTINATION lib) install(FILES "${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}Config.cmake" # source directory DESTINATION "share/${CMAKE_PROJECT_NAME}/cmake/" # target directory diff --git a/tkDNNConfig.cmake b/cmake/tkDNNConfig.cmake similarity index 100% rename from tkDNNConfig.cmake rename to cmake/tkDNNConfig.cmake diff --git a/include/Layer.h b/include/tkDNN/Layer.h similarity index 100% rename from include/Layer.h rename to include/tkDNN/Layer.h diff --git a/include/Network.h b/include/tkDNN/Network.h similarity index 100% rename from include/Network.h rename to include/tkDNN/Network.h diff --git a/include/NetworkRT.h b/include/tkDNN/NetworkRT.h similarity index 100% rename from include/NetworkRT.h rename to include/tkDNN/NetworkRT.h diff --git a/include/Yolo3Detection.h b/include/tkDNN/Yolo3Detection.h similarity index 100% rename from include/Yolo3Detection.h rename to include/tkDNN/Yolo3Detection.h diff --git a/include/kernels.h b/include/tkDNN/kernels.h similarity index 100% rename from include/kernels.h rename to include/tkDNN/kernels.h diff --git a/include/models/Yolo3.h b/include/tkDNN/models/Yolo3.h similarity index 100% rename from include/models/Yolo3.h rename to include/tkDNN/models/Yolo3.h diff --git a/include/pluginsRT/ActivationLeakyRT.h b/include/tkDNN/pluginsRT/ActivationLeakyRT.h similarity index 100% rename from include/pluginsRT/ActivationLeakyRT.h rename to include/tkDNN/pluginsRT/ActivationLeakyRT.h diff --git a/include/pluginsRT/Int8Calibrator.h b/include/tkDNN/pluginsRT/Int8Calibrator.h similarity index 100% rename from include/pluginsRT/Int8Calibrator.h rename to include/tkDNN/pluginsRT/Int8Calibrator.h diff --git a/include/pluginsRT/RegionRT.h b/include/tkDNN/pluginsRT/RegionRT.h similarity index 100% rename from include/pluginsRT/RegionRT.h rename to include/tkDNN/pluginsRT/RegionRT.h diff --git a/include/pluginsRT/ReorgRT.h b/include/tkDNN/pluginsRT/ReorgRT.h similarity index 100% rename from include/pluginsRT/ReorgRT.h rename to include/tkDNN/pluginsRT/ReorgRT.h diff --git a/include/pluginsRT/RouteRT.h b/include/tkDNN/pluginsRT/RouteRT.h similarity index 100% rename from include/pluginsRT/RouteRT.h rename to include/tkDNN/pluginsRT/RouteRT.h diff --git a/include/pluginsRT/ShortcutRT.h b/include/tkDNN/pluginsRT/ShortcutRT.h similarity index 100% rename from include/pluginsRT/ShortcutRT.h rename to include/tkDNN/pluginsRT/ShortcutRT.h diff --git a/include/pluginsRT/UpsampleRT.h b/include/tkDNN/pluginsRT/UpsampleRT.h similarity index 100% rename from include/pluginsRT/UpsampleRT.h rename to include/tkDNN/pluginsRT/UpsampleRT.h diff --git a/include/pluginsRT/YoloRT.h b/include/tkDNN/pluginsRT/YoloRT.h similarity index 100% rename from include/pluginsRT/YoloRT.h rename to include/tkDNN/pluginsRT/YoloRT.h diff --git a/include/tkdnn.h b/include/tkDNN/tkdnn.h similarity index 100% rename from include/tkdnn.h rename to include/tkDNN/tkdnn.h diff --git a/include/utils.h b/include/tkDNN/utils.h similarity index 100% rename from include/utils.h rename to include/tkDNN/utils.h From de8b02fe5091e99c33aa5b688b11bbf4dc10fb66 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 17 Sep 2019 16:12:59 +0200 Subject: [PATCH 006/228] install fix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a35264c..20fa8d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ target_link_libraries(yolo3_demo tkDNN) message("install dir:" ${CMAKE_INSTALL_PREFIX}) install(DIRECTORY include/ DESTINATION include/) install(TARGETS tkDNN kernels DESTINATION lib) -install(FILES "${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}Config.cmake" # source directory +install(FILES "${CMAKE_SOURCE_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake" # source directory DESTINATION "share/${CMAKE_PROJECT_NAME}/cmake/" # target directory ) From bbc4dda63512486b40646d309d569fec46b2e2e9 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Tue, 17 Sep 2019 17:16:46 +0200 Subject: [PATCH 007/228] removed buildtype --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20fa8d5..e305d1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.5) project (tkDNN) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -set(CMAKE_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/tkDNN) From 92f3d1c548210978d1f14a6178a59fba93691e7a Mon Sep 17 00:00:00 2001 From: mbosi <205839@studenti.unimore.it> Date: Tue, 1 Oct 2019 18:47:31 +0200 Subject: [PATCH 008/228] fixed install cmake --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e305d1a..467e823 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,10 +111,11 @@ target_link_libraries(yolo3_demo tkDNN) message("install dir:" ${CMAKE_INSTALL_PREFIX}) install(DIRECTORY include/ DESTINATION include/) install(TARGETS tkDNN kernels DESTINATION lib) -install(FILES "${CMAKE_SOURCE_DIR}/cmake/${CMAKE_PROJECT_NAME}Config.cmake" # source directory - DESTINATION "share/${CMAKE_PROJECT_NAME}/cmake/" # target directory +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" # source directory + DESTINATION "share/tkDNN/cmake/" # target directory ) + #------------------------------------------------------------------------------- # Prepare for test #------------------------------------------------------------------------------- From 42a1ea02b9453384d17f39b44e7a56a03a0b646d Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Mon, 28 Oct 2019 18:34:17 +0100 Subject: [PATCH 009/228] resnet merge --- CMakeLists.txt | 16 + include/tkDNN/Layer.h | 4 +- src/Pooling.cpp | 7 +- tests/resnet101/resnet101.cpp | 398 +++++++++++++++++++ tests/resnet101/resnet101_weightsexporter.py | 122 ++++++ 5 files changed, 543 insertions(+), 4 deletions(-) create mode 100644 tests/resnet101/resnet101.cpp create mode 100644 tests/resnet101/resnet101_weightsexporter.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 467e823..31f5d5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,8 +89,24 @@ target_link_libraries(test_yolo3_coco4 tkDNN) add_executable(test_yolo3_berkeley tests/yolo3_berkeley/yolo3_berkeley.cpp) target_link_libraries(test_yolo3_berkeley tkDNN) +<<<<<<< HEAD add_executable(test_yolo3_flir tests/yolo3_flir/yolo3_flir.cpp) target_link_libraries(test_yolo3_flir tkDNN) +======= +add_executable(test_yolo3_tetrapack tests/yolo3_tetrapack/yolo3_tetrapack.cpp) +target_link_libraries(test_yolo3_tetrapack tkDNN) + +add_executable(test_yolo3_tetrapack_resize tests/yolo3_tetrapack_resize/yolo3_tetrapack_resize.cpp) +target_link_libraries(test_yolo3_tetrapack_resize tkDNN) + +add_executable(test_yolo3_BCDS6 tests/yolo3_BCDS6/yolo3_BCDS6.cpp) +target_link_libraries(test_yolo3_BCDS6 tkDNN) + +add_executable(test_resnet101 tests/resnet101/resnet101.cpp) +target_link_libraries(test_resnet101 tkDNN) + + +>>>>>>> e1d0fa3... resnet first try ################################################################################ diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index c6bee42..cec213f 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -227,7 +227,9 @@ public: int paddingH, paddingW; Pooling(Network *net, int winH, int winW, - int strideH, int strideW, tkdnnPoolingMode_t pool_mode); + int strideH, int strideW, + int paddingH = 0, int paddingW = 0, + tkdnnPoolingMode_t pool_mode = POOLING_MAX); virtual ~Pooling(); virtual layerType_t getLayerType() { return LAYER_POOLING; }; diff --git a/src/Pooling.cpp b/src/Pooling.cpp index 6c2afc8..98bbd42 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -6,6 +6,7 @@ namespace tk { namespace dnn { Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, + int paddingH, int paddingW, tkdnnPoolingMode_t pool_mode) : Layer(net) { @@ -14,8 +15,8 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, this->strideH = strideH; this->strideW = strideW; this->pool_mode = pool_mode; - this->paddingH = 0; - this->paddingW = 0; + this->paddingH = paddingH; + this->paddingW = paddingW; checkCUDNN( cudnnCreatePoolingDescriptor(&poolingDesc) ); @@ -38,7 +39,7 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, } checkCUDNN( cudnnSetPooling2dDescriptor(poolingDesc, cudnnPoolingMode_t(pool_mode), - CUDNN_NOT_PROPAGATE_NAN, winH, winW, 0, 0, strideH, strideW) ); + CUDNN_NOT_PROPAGATE_NAN, winH, winW, paddingH, paddingW, strideH, strideW) ); checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc, net->tensorFormat, net->dataType, n, c, h, w) ); diff --git a/tests/resnet101/resnet101.cpp b/tests/resnet101/resnet101.cpp new file mode 100644 index 0000000..da931d5 --- /dev/null +++ b/tests/resnet101/resnet101.cpp @@ -0,0 +1,398 @@ +#include +#include "tkdnn.h" + +const char *input_bin = "../tests/resnet101/debug/input.bin"; +const char *conv1_bin = "../tests/resnet101/layers/conv1.bin"; + +//layer1 +const char *layer1_0_conv1_bin = "../tests/resnet101/layers/layer1-0-conv1.bin"; +const char *layer1_0_conv2_bin = "../tests/resnet101/layers/layer1-0-conv2.bin"; +const char *layer1_0_conv3_bin = "../tests/resnet101/layers/layer1-0-conv3.bin"; +const char *layer1_0_downsample_0_bin = "../tests/resnet101/layers/layer1-0-downsample-0.bin"; + +const char *layer1_1_conv1_bin = "../tests/resnet101/layers/layer1-1-conv1.bin"; +const char *layer1_1_conv2_bin = "../tests/resnet101/layers/layer1-1-conv2.bin"; +const char *layer1_1_conv3_bin = "../tests/resnet101/layers/layer1-1-conv3.bin"; + +const char *layer1_2_conv1_bin = "../tests/resnet101/layers/layer1-2-conv1.bin"; +const char *layer1_2_conv2_bin = "../tests/resnet101/layers/layer1-2-conv2.bin"; +const char *layer1_2_conv3_bin = "../tests/resnet101/layers/layer1-2-conv3.bin"; + +//layer2 +const char *layer2_0_conv1_bin = "../tests/resnet101/layers/layer2-0-conv1.bin"; +const char *layer2_0_conv2_bin = "../tests/resnet101/layers/layer2-0-conv2.bin"; +const char *layer2_0_conv3_bin = "../tests/resnet101/layers/layer2-0-conv3.bin"; +const char *layer2_0_downsample_0_bin = "../tests/resnet101/layers/layer2-0-downsample-0.bin"; + +const char *layer2_1_conv1_bin = "../tests/resnet101/layers/layer2-1-conv1.bin"; +const char *layer2_1_conv2_bin = "../tests/resnet101/layers/layer2-1-conv2.bin"; +const char *layer2_1_conv3_bin = "../tests/resnet101/layers/layer2-1-conv3.bin"; + +const char *layer2_2_conv1_bin = "../tests/resnet101/layers/layer2-2-conv1.bin"; +const char *layer2_2_conv2_bin = "../tests/resnet101/layers/layer2-2-conv2.bin"; +const char *layer2_2_conv3_bin = "../tests/resnet101/layers/layer2-2-conv3.bin"; + +const char *layer2_3_conv1_bin = "../tests/resnet101/layers/layer2-3-conv1.bin"; +const char *layer2_3_conv2_bin = "../tests/resnet101/layers/layer2-3-conv2.bin"; +const char *layer2_3_conv3_bin = "../tests/resnet101/layers/layer2-3-conv3.bin"; + +//layer3 +const char *layer3_0_conv1_bin = "../tests/resnet101/layers/layer3-0-conv1.bin"; +const char *layer3_0_conv2_bin = "../tests/resnet101/layers/layer3-0-conv2.bin"; +const char *layer3_0_conv3_bin = "../tests/resnet101/layers/layer3-0-conv3.bin"; +const char *layer3_0_downsample_0_bin = "../tests/resnet101/layers/layer3-0-downsample-0.bin"; + +const char *layer3_1_conv1_bin = "../tests/resnet101/layers/layer3-1-conv1.bin"; +const char *layer3_1_conv2_bin = "../tests/resnet101/layers/layer3-1-conv2.bin"; +const char *layer3_1_conv3_bin = "../tests/resnet101/layers/layer3-1-conv3.bin"; + +const char *layer3_2_conv1_bin = "../tests/resnet101/layers/layer3-2-conv1.bin"; +const char *layer3_2_conv2_bin = "../tests/resnet101/layers/layer3-2-conv2.bin"; +const char *layer3_2_conv3_bin = "../tests/resnet101/layers/layer3-2-conv3.bin"; + +const char *layer3_3_conv1_bin = "../tests/resnet101/layers/layer3-3-conv1.bin"; +const char *layer3_3_conv2_bin = "../tests/resnet101/layers/layer3-3-conv2.bin"; +const char *layer3_3_conv3_bin = "../tests/resnet101/layers/layer3-3-conv3.bin"; + +const char *layer3_4_conv1_bin = "../tests/resnet101/layers/layer3-4-conv1.bin"; +const char *layer3_4_conv2_bin = "../tests/resnet101/layers/layer3-4-conv2.bin"; +const char *layer3_4_conv3_bin = "../tests/resnet101/layers/layer3-4-conv3.bin"; + +const char *layer3_5_conv1_bin = "../tests/resnet101/layers/layer3-5-conv1.bin"; +const char *layer3_5_conv2_bin = "../tests/resnet101/layers/layer3-5-conv2.bin"; +const char *layer3_5_conv3_bin = "../tests/resnet101/layers/layer3-5-conv3.bin"; + +const char *layer3_6_conv1_bin = "../tests/resnet101/layers/layer3-6-conv1.bin"; +const char *layer3_6_conv2_bin = "../tests/resnet101/layers/layer3-6-conv2.bin"; +const char *layer3_6_conv3_bin = "../tests/resnet101/layers/layer3-6-conv3.bin"; + +const char *layer3_7_conv1_bin = "../tests/resnet101/layers/layer3-7-conv1.bin"; +const char *layer3_7_conv2_bin = "../tests/resnet101/layers/layer3-7-conv2.bin"; +const char *layer3_7_conv3_bin = "../tests/resnet101/layers/layer3-7-conv3.bin"; + +const char *layer3_8_conv1_bin = "../tests/resnet101/layers/layer3-8-conv1.bin"; +const char *layer3_8_conv2_bin = "../tests/resnet101/layers/layer3-8-conv2.bin"; +const char *layer3_8_conv3_bin = "../tests/resnet101/layers/layer3-8-conv3.bin"; + +const char *layer3_9_conv1_bin = "../tests/resnet101/layers/layer3-9-conv1.bin"; +const char *layer3_9_conv2_bin = "../tests/resnet101/layers/layer3-9-conv2.bin"; +const char *layer3_9_conv3_bin = "../tests/resnet101/layers/layer3-9-conv3.bin"; + +const char *layer3_10_conv1_bin = "../tests/resnet101/layers/layer3-10-conv1.bin"; +const char *layer3_10_conv2_bin = "../tests/resnet101/layers/layer3-10-conv2.bin"; +const char *layer3_10_conv3_bin = "../tests/resnet101/layers/layer3-10-conv3.bin"; + +const char *layer3_11_conv1_bin = "../tests/resnet101/layers/layer3-11-conv1.bin"; +const char *layer3_11_conv2_bin = "../tests/resnet101/layers/layer3-11-conv2.bin"; +const char *layer3_11_conv3_bin = "../tests/resnet101/layers/layer3-11-conv3.bin"; + +const char *layer3_12_conv1_bin = "../tests/resnet101/layers/layer3-12-conv1.bin"; +const char *layer3_12_conv2_bin = "../tests/resnet101/layers/layer3-12-conv2.bin"; +const char *layer3_12_conv3_bin = "../tests/resnet101/layers/layer3-12-conv3.bin"; + +const char *layer3_13_conv1_bin = "../tests/resnet101/layers/layer3-13-conv1.bin"; +const char *layer3_13_conv2_bin = "../tests/resnet101/layers/layer3-13-conv2.bin"; +const char *layer3_13_conv3_bin = "../tests/resnet101/layers/layer3-13-conv3.bin"; + +const char *layer3_14_conv1_bin = "../tests/resnet101/layers/layer3-14-conv1.bin"; +const char *layer3_14_conv2_bin = "../tests/resnet101/layers/layer3-14-conv2.bin"; +const char *layer3_14_conv3_bin = "../tests/resnet101/layers/layer3-14-conv3.bin"; + +const char *layer3_15_conv1_bin = "../tests/resnet101/layers/layer3-15-conv1.bin"; +const char *layer3_15_conv2_bin = "../tests/resnet101/layers/layer3-15-conv2.bin"; +const char *layer3_15_conv3_bin = "../tests/resnet101/layers/layer3-15-conv3.bin"; + +const char *layer3_16_conv1_bin = "../tests/resnet101/layers/layer3-16-conv1.bin"; +const char *layer3_16_conv2_bin = "../tests/resnet101/layers/layer3-16-conv2.bin"; +const char *layer3_16_conv3_bin = "../tests/resnet101/layers/layer3-16-conv3.bin"; + +const char *layer3_17_conv1_bin = "../tests/resnet101/layers/layer3-17-conv1.bin"; +const char *layer3_17_conv2_bin = "../tests/resnet101/layers/layer3-17-conv2.bin"; +const char *layer3_17_conv3_bin = "../tests/resnet101/layers/layer3-17-conv3.bin"; + +const char *layer3_18_conv1_bin = "../tests/resnet101/layers/layer3-18-conv1.bin"; +const char *layer3_18_conv2_bin = "../tests/resnet101/layers/layer3-18-conv2.bin"; +const char *layer3_18_conv3_bin = "../tests/resnet101/layers/layer3-18-conv3.bin"; + +const char *layer3_19_conv1_bin = "../tests/resnet101/layers/layer3-19-conv1.bin"; +const char *layer3_19_conv2_bin = "../tests/resnet101/layers/layer3-19-conv2.bin"; +const char *layer3_19_conv3_bin = "../tests/resnet101/layers/layer3-19-conv3.bin"; + +const char *layer3_20_conv1_bin = "../tests/resnet101/layers/layer3-20-conv1.bin"; +const char *layer3_20_conv2_bin = "../tests/resnet101/layers/layer3-20-conv2.bin"; +const char *layer3_20_conv3_bin = "../tests/resnet101/layers/layer3-20-conv3.bin"; + +const char *layer3_21_conv1_bin = "../tests/resnet101/layers/layer3-21-conv1.bin"; +const char *layer3_21_conv2_bin = "../tests/resnet101/layers/layer3-21-conv2.bin"; +const char *layer3_21_conv3_bin = "../tests/resnet101/layers/layer3-21-conv3.bin"; + +const char *layer3_22_conv1_bin = "../tests/resnet101/layers/layer3-22-conv1.bin"; +const char *layer3_22_conv2_bin = "../tests/resnet101/layers/layer3-22-conv2.bin"; +const char *layer3_22_conv3_bin = "../tests/resnet101/layers/layer3-22-conv3.bin"; + + +//layer4 +const char *layer4_0_conv1_bin = "../tests/resnet101/layers/layer4-0-conv1.bin"; +const char *layer4_0_conv2_bin = "../tests/resnet101/layers/layer4-0-conv2.bin"; +const char *layer4_0_conv3_bin = "../tests/resnet101/layers/layer4-0-conv3.bin"; +const char *layer4_0_downsample_0_bin = "../tests/resnet101/layers/layer4-0-downsample-0.bin"; + +const char *layer4_1_conv1_bin = "../tests/resnet101/layers/layer4-1-conv1.bin"; +const char *layer4_1_conv2_bin = "../tests/resnet101/layers/layer4-1-conv2.bin"; +const char *layer4_1_conv3_bin = "../tests/resnet101/layers/layer4-1-conv3.bin"; + +const char *layer4_2_conv1_bin = "../tests/resnet101/layers/layer4-2-conv1.bin"; +const char *layer4_2_conv2_bin = "../tests/resnet101/layers/layer4-2-conv2.bin"; +const char *layer4_2_conv3_bin = "../tests/resnet101/layers/layer4-2-conv3.bin"; + +//final +const char *fc_bin = "../tests/resnet101/layers/fc.bin"; + +const char *output_bin = "../tests/resnet101/debug/layer1-0-conv3.bin"; + +int main() +{ + + // Network layout + tk::dnn::dataDim_t dim(1, 3, 224, 224, 1); + tk::dnn::Network net(dim); + + tk::dnn::Conv2d conv1(&net, 64, 7, 7, 2, 2, 3, 3, conv1_bin, true); + tk::dnn::Activation relu3(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Pooling maxpool4(&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX); + + + //layer 1 + tk::dnn::Conv2d layer1_0_conv1(&net, 64, 1, 1, 1, 1, 0, 0, layer1_0_conv1_bin, true); + tk::dnn::Conv2d layer1_0_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_0_conv2_bin, true); + tk::dnn::Conv2d layer1_0_conv3(&net, 256, 1, 1, 1, 1, 0, 0, layer1_0_conv3_bin, true); + +/* + tk::dnn::Activation layer1_0_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d layer1_0_downsample_0(&net, 256, 1, 1, 1, 1, 1, 1, layer1_0_downsample_0, true); + + tk::dnn::Conv2d layer1_1_conv1(&net, 64, 1, 1, 1, 1, 1, 1, layer1_1_conv1_bin, true); + tk::dnn::Conv2d layer1_1_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_1_conv2_bin, true); + tk::dnn::Conv2d layer1_1_conv3(&net, 256, 1, 1, 1, 1, 1, 1, layer1_1_conv3_bin, true); + tk::dnn::Activation layer1_1_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer1_2_conv1(&net, 64, 1, 1, 1, 1, 1, 1, layer1_2_conv1_bin, true); + tk::dnn::Conv2d layer1_2_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_2_conv2_bin, true); + tk::dnn::Conv2d layer1_2_conv3(&net, 256, 1, 1, 1, 1, 1, 1, layer1_2_conv3_bin, true); + tk::dnn::Activation layer1_2_relu(&net, CUDNN_ACTIVATION_RELU); + + + //layer 2 + tk::dnn::Conv2d layer2_0_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_0_conv1_bin, true); + tk::dnn::Conv2d layer2_0_conv2(&net, 128, 3, 3, 2, 2, 1, 1, layer2_0_conv2_bin, true); + tk::dnn::Conv2d layer2_0_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_0_conv3_bin, true); + tk::dnn::Activation layer2_0_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d layer2_0_downsample_0(&net, 512, 1, 1, 2, 2, 1, 1, layer2_0_downsample_0, true); + + tk::dnn::Conv2d layer2_1_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_1_conv1_bin, true); + tk::dnn::Conv2d layer2_1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_1_conv2_bin, true); + tk::dnn::Conv2d layer2_1_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_1_conv3_bin, true); + tk::dnn::Activation layer2_1_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer2_2_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_2_conv1_bin, true); + tk::dnn::Conv2d layer2_2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_2_conv2_bin, true); + tk::dnn::Conv2d layer2_2_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_2_conv3_bin, true); + tk::dnn::Activation layer2_2_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer2_3_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_3_conv1_bin, true); + tk::dnn::Conv2d layer2_3_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_3_conv2_bin, true); + tk::dnn::Conv2d layer2_3_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_3_conv3_bin, true); + tk::dnn::Activation layer2_3_relu(&net, CUDNN_ACTIVATION_RELU); + + //layer 3 + tk::dnn::Conv2d layer3_0_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_0_conv1_bin, true); + tk::dnn::Conv2d layer3_0_conv2(&net, 256, 3, 3, 2, 2, 1, 1, layer3_0_conv2_bin, true); + tk::dnn::Conv2d layer3_0_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_0_conv3_bin, true); + tk::dnn::Activation layer3_0_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d layer3_0_downsample_0(&net, 1024, 1, 1, 2, 2, 1, 1, layer3_0_downsample_0, true); + + tk::dnn::Conv2d layer3_1_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_1_conv1_bin, true); + tk::dnn::Conv2d layer3_1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_1_conv2_bin, true); + tk::dnn::Conv2d layer3_1_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_1_conv3_bin, true); + tk::dnn::Activation layer3_1_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_2_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_2_conv1_bin, true); + tk::dnn::Conv2d layer3_2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_2_conv2_bin, true); + tk::dnn::Conv2d layer3_2_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_2_conv3_bin, true); + tk::dnn::Activation layer3_2_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_3_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_3_conv1_bin, true); + tk::dnn::Conv2d layer3_3_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_3_conv2_bin, true); + tk::dnn::Conv2d layer3_3_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_3_conv3_bin, true); + tk::dnn::Activation layer3_3_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_4_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_4_conv1_bin, true); + tk::dnn::Conv2d layer3_4_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_4_conv2_bin, true); + tk::dnn::Conv2d layer3_4_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_4_conv3_bin, true); + tk::dnn::Activation layer3_4_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_5_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_5_conv1_bin, true); + tk::dnn::Conv2d layer3_5_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_5_conv2_bin, true); + tk::dnn::Conv2d layer3_5_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_5_conv3_bin, true); + tk::dnn::Activation layer3_5_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_6_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_6_conv1_bin, true); + tk::dnn::Conv2d layer3_6_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_6_conv2_bin, true); + tk::dnn::Conv2d layer3_6_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_6_conv3_bin, true); + tk::dnn::Activation layer3_6_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_7_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_7_conv1_bin, true); + tk::dnn::Conv2d layer3_7_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_7_conv2_bin, true); + tk::dnn::Conv2d layer3_7_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_7_conv3_bin, true); + tk::dnn::Activation layer3_7_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_8_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_8_conv1_bin, true); + tk::dnn::Conv2d layer3_8_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_8_conv2_bin, true); + tk::dnn::Conv2d layer3_8_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_8_conv3_bin, true); + tk::dnn::Activation layer3_8_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_9_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_9_conv1_bin, true); + tk::dnn::Conv2d layer3_9_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_9_conv2_bin, true); + tk::dnn::Conv2d layer3_9_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_9_conv3_bin, true); + tk::dnn::Activation layer3_9_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_10_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_10_conv1_bin, true); + tk::dnn::Conv2d layer3_10_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_10_conv2_bin, true); + tk::dnn::Conv2d layer3_10_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_10_conv3_bin, true); + tk::dnn::Activation layer3_10_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_11_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_11_conv1_bin, true); + tk::dnn::Conv2d layer3_11_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_11_conv2_bin, true); + tk::dnn::Conv2d layer3_11_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_11_conv3_bin, true); + tk::dnn::Activation layer3_11_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_12_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_12_conv1_bin, true); + tk::dnn::Conv2d layer3_12_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_12_conv2_bin, true); + tk::dnn::Conv2d layer3_12_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_12_conv3_bin, true); + tk::dnn::Activation layer3_12_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_13_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_13_conv1_bin, true); + tk::dnn::Conv2d layer3_13_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_13_conv2_bin, true); + tk::dnn::Conv2d layer3_13_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_13_conv3_bin, true); + tk::dnn::Activation layer3_13_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_14_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_14_conv1_bin, true); + tk::dnn::Conv2d layer3_14_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_14_conv2_bin, true); + tk::dnn::Conv2d layer3_14_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_14_conv3_bin, true); + tk::dnn::Activation layer3_14_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_15_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_15_conv1_bin, true); + tk::dnn::Conv2d layer3_15_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_15_conv2_bin, true); + tk::dnn::Conv2d layer3_15_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_15_conv3_bin, true); + tk::dnn::Activation layer3_15_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_16_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_16_conv1_bin, true); + tk::dnn::Conv2d layer3_16_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_16_conv2_bin, true); + tk::dnn::Conv2d layer3_16_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_16_conv3_bin, true); + tk::dnn::Activation layer3_16_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_17_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_17_conv1_bin, true); + tk::dnn::Conv2d layer3_17_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_17_conv2_bin, true); + tk::dnn::Conv2d layer3_17_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_17_conv3_bin, true); + tk::dnn::Activation layer3_17_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_18_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_18_conv1_bin, true); + tk::dnn::Conv2d layer3_18_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_18_conv2_bin, true); + tk::dnn::Conv2d layer3_18_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_18_conv3_bin, true); + tk::dnn::Activation layer3_18_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_19_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_19_conv1_bin, true); + tk::dnn::Conv2d layer3_19_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_19_conv2_bin, true); + tk::dnn::Conv2d layer3_19_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_19_conv3_bin, true); + tk::dnn::Activation layer3_19_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_20_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_20_conv1_bin, true); + tk::dnn::Conv2d layer3_20_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_20_conv2_bin, true); + tk::dnn::Conv2d layer3_20_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_20_conv3_bin, true); + tk::dnn::Activation layer3_20_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_21_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_21_conv1_bin, true); + tk::dnn::Conv2d layer3_21_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_21_conv2_bin, true); + tk::dnn::Conv2d layer3_21_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_21_conv3_bin, true); + tk::dnn::Activation layer3_21_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer3_22_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_22_conv1_bin, true); + tk::dnn::Conv2d layer3_22_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_22_conv2_bin, true); + tk::dnn::Conv2d layer3_22_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_22_conv3_bin, true); + tk::dnn::Activation layer3_22_relu(&net, CUDNN_ACTIVATION_RELU); + + //layer 4 + tk::dnn::Conv2d layer4_0_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_0_conv1_bin, true); + tk::dnn::Conv2d layer4_0_conv2(&net, 512, 3, 3, 2, 2, 1, 1, layer4_0_conv2_bin, true); + tk::dnn::Conv2d layer4_0_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_0_conv3_bin, true); + tk::dnn::Activation layer4_0_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d layer4_0_downsample_0(&net, 2048, 1, 1, 2, 2, 1, 1, layer4_0_downsample_0, true); + + tk::dnn::Conv2d layer4_1_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_1_conv1_bin, true); + tk::dnn::Conv2d layer4_1_conv2(&net, 512, 3, 3, 1, 1, 1, 1, layer4_1_conv2_bin, true); + tk::dnn::Conv2d layer4_1_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_1_conv3_bin, true); + tk::dnn::Activation layer4_1_relu(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d layer4_2_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_2_conv1_bin, true); + tk::dnn::Conv2d layer4_2_conv2(&net, 512, 3, 3, 1, 1, 1, 1, layer4_2_conv2_bin, true); + tk::dnn::Conv2d layer4_2_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_2_conv3_bin, true); + tk::dnn::Activation layer4_2_relu(&net, CUDNN_ACTIVATION_RELU); + + + //final + tk::dnn::Pooling avgpool(&net, 3, 3, 2, 2, tk::dnn::POOLING_AVERAGE); + tk::dnn::Dense fc(&net, 1000, fc_bin); +*/ + // Load input + dnnType *data; + dnnType *input_h; + readBinaryFile(input_bin, dim.tot(), &input_h, &data); + + //print network model + net.print(); +/* + //convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "resnet101.rt"); +*/ + + tk::dnn::dataDim_t out_dim; + out_dim = layer1_0_conv3.output_dim; + dnnType *cudnn_out, *rt_out; + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); + { + dim1.print(); + TIMER_START + net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + cudnn_out = layer1_0_conv3.dstData; +/* + tk::dnn::dataDim_t dim2 = dim; + printCenteredTitle(" TENSORRT inference ", '=', 30); + { + dim2.print(); + TIMER_START + netRT.infer(dim2, data); + TIMER_STOP + dim2.print(); + } + rt_out = (dnnType *)netRT.buffersRT[1]; +*/ + + printCenteredTitle(std::string(" RESNET CHECK RESULTS ").c_str(), '=', 30); + dnnType *out, *out_h; + int odim = out_dim.tot(); + readBinaryFile(output_bin, odim, &out_h, &out); + std::cout << "CUDNN vs correct"; + checkResult(odim, cudnn_out, out); +/* + std::cout << "TRT vs correct"; + checkResult(odim, rt_out, out); + std::cout << "CUDNN vs TRT "; + checkResult(odim, cudnn_out, rt_out); +*/ + return 0; +} diff --git a/tests/resnet101/resnet101_weightsexporter.py b/tests/resnet101/resnet101_weightsexporter.py new file mode 100644 index 0000000..592c0bb --- /dev/null +++ b/tests/resnet101/resnet101_weightsexporter.py @@ -0,0 +1,122 @@ +import torch +import urllib +from PIL import Image +from torchvision import transforms +from torchsummary import summary +import numpy as np + +def hook(module, input, output): + setattr(module, "_value_hook", output) + + + +def print_wb(model, folder): + for name, param in model.named_parameters(): + print ("Layer", name) + t = name.split('.')[0:-1] + arg = name.split('.')[-1] + t = '-'.join(t) + print (" type: ", t) + + if arg == 'weight': + w = param.data.numpy() + print (" weights shape:", np.shape(w)) + w.tofile(folder + "/" + t + ".bin", format="f") + elif arg == 'bias': + b = param.data.numpy() + print (" bias shape:", np.shape(b)) + b.tofile(folder + "/" + t + ".bias.bin", format="f") + else: + print("Ops!") + + +def print_wb_output(model, input_batch): + for n, m in model.named_modules(): + m.register_forward_hook(hook) + + model(input_batch) + i = input_batch.data.numpy() + i = np.array(i, dtype=np.float32) + print(i.shape) + i.tofile("debug/input.bin", format="f") + + for n, m in model.named_modules(): + in_output = m._value_hook + print(n, ' ----------------------------------------------------------------') + o = in_output.data.numpy() + o = np.array(o, dtype=np.float32) + t = '-'.join(n.split('.')) + o.tofile("debug/" + t + ".bin", format="f") + + # print(m._parameters) + print(m.type) + + w = np.array([]) + b = np.array([]) + + + if 'weight' in m._parameters and m._parameters['weight'] is not None: + w = m._parameters['weight'].data.numpy() + w = np.array(w, dtype=np.float32) + print (" weights shape:", np.shape(w)) + + if 'bias' in m._parameters and m._parameters['bias'] is not None: + b = m._parameters['bias'].data.numpy() + b = np.array(b, dtype=np.float32) + print (" bias shape:", np.shape(b)) + else: + b = np.array(o, dtype=np.float32)*0 + print (" bias shape:", np.shape(b)) + + if 'BatchNorm2d' in str(m.type): + s = np.array(o, dtype=np.float32)*0+1 + + f = open("layers/" + t + ".bin", mode='wb') + + if 'BatchNorm2d' in str(m.type): + s.tofile(f, format="f") + + w.tofile(f, format="f") + b.tofile(f, format="f") + f.close() + + + + + +if __name__ == '__main__': + + model = torch.hub.load('pytorch/vision', 'resnet101', pretrained=True) + model.eval() + + # Download an example image from the pytorch website + url, filename = ("https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg") + try: urllib.URLopener().retrieve(url, filename) + except: urllib.request.urlretrieve(url, filename) + + # sample execution (requires torchvision) + input_image = Image.open(filename) + preprocess = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), + ]) + input_tensor = preprocess(input_image) + input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model + + # move the input and model to GPU for speed if available + if torch.cuda.is_available(): + input_batch = input_batch.to('cuda') + model.to('cuda') + + with torch.no_grad(): + output = model(input_batch) + + # Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes + print(output) + + + print_wb_output(model, input_batch) + + print(list(model.children())) From 4ac2c87d1ccbad115c7b9898558cb3d8df69ed2b Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Mon, 28 Oct 2019 18:39:28 +0100 Subject: [PATCH 010/228] cmake fix --- CMakeLists.txt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f5d5b..27fe9cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,15 +89,8 @@ target_link_libraries(test_yolo3_coco4 tkDNN) add_executable(test_yolo3_berkeley tests/yolo3_berkeley/yolo3_berkeley.cpp) target_link_libraries(test_yolo3_berkeley tkDNN) -<<<<<<< HEAD add_executable(test_yolo3_flir tests/yolo3_flir/yolo3_flir.cpp) target_link_libraries(test_yolo3_flir tkDNN) -======= -add_executable(test_yolo3_tetrapack tests/yolo3_tetrapack/yolo3_tetrapack.cpp) -target_link_libraries(test_yolo3_tetrapack tkDNN) - -add_executable(test_yolo3_tetrapack_resize tests/yolo3_tetrapack_resize/yolo3_tetrapack_resize.cpp) -target_link_libraries(test_yolo3_tetrapack_resize tkDNN) add_executable(test_yolo3_BCDS6 tests/yolo3_BCDS6/yolo3_BCDS6.cpp) target_link_libraries(test_yolo3_BCDS6 tkDNN) @@ -105,8 +98,6 @@ target_link_libraries(test_yolo3_BCDS6 tkDNN) add_executable(test_resnet101 tests/resnet101/resnet101.cpp) target_link_libraries(test_resnet101 tkDNN) - ->>>>>>> e1d0fa3... resnet first try ################################################################################ From 058f9b795f1b34731b3b517b2ce9837db36c564b Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Mon, 28 Oct 2019 19:20:02 +0100 Subject: [PATCH 011/228] resnet weight export fix --- tests/resnet101/resnet101_weightsexporter.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/resnet101/resnet101_weightsexporter.py b/tests/resnet101/resnet101_weightsexporter.py index 592c0bb..fd5a81d 100644 --- a/tests/resnet101/resnet101_weightsexporter.py +++ b/tests/resnet101/resnet101_weightsexporter.py @@ -40,6 +40,7 @@ def print_wb_output(model, input_batch): print(i.shape) i.tofile("debug/input.bin", format="f") + f = None for n, m in model.named_modules(): in_output = m._value_hook print(n, ' ----------------------------------------------------------------') @@ -48,6 +49,12 @@ def print_wb_output(model, input_batch): t = '-'.join(n.split('.')) o.tofile("debug/" + t + ".bin", format="f") + if 'Conv2d' in str(m.type) or 'Linear' in str(m.type): + f = open("layers/" + t + ".bin", mode='wb') + + if f is None: + continue + # print(m._parameters) print(m.type) @@ -65,20 +72,19 @@ def print_wb_output(model, input_batch): b = np.array(b, dtype=np.float32) print (" bias shape:", np.shape(b)) else: - b = np.array(o, dtype=np.float32)*0 + b = np.zeros(w.shape[0], dtype=np.float32) print (" bias shape:", np.shape(b)) - - if 'BatchNorm2d' in str(m.type): - s = np.array(o, dtype=np.float32)*0+1 - - f = open("layers/" + t + ".bin", mode='wb') if 'BatchNorm2d' in str(m.type): + s = np.zeros(w.shape[0], dtype=np.float32)+1 s.tofile(f, format="f") w.tofile(f, format="f") b.tofile(f, format="f") - f.close() + + if 'BatchNorm2d' in str(m.type) or 'Linear' in str(m.type): + f.close() + f = None From e9ec582223a17c2d719e3a32f2515247555d183c Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Tue, 29 Oct 2019 15:08:44 +0100 Subject: [PATCH 012/228] Shortcat ok --- CMakeLists.txt | 2 - src/LayerWgs.cpp | 20 +++++- src/utils.cpp | 3 +- tests/resnet101/resnet101.cpp | 24 ++++--- tests/resnet101/resnet101_weightsexporter.py | 67 +++++++++++++++----- 5 files changed, 87 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27fe9cb..7c5a301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,8 +92,6 @@ 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_yolo3_BCDS6 tests/yolo3_BCDS6/yolo3_BCDS6.cpp) -target_link_libraries(test_yolo3_BCDS6 tkDNN) add_executable(test_resnet101 tests/resnet101/resnet101.cpp) target_link_libraries(test_resnet101 tkDNN) diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index f27da0f..dfdde70 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -19,7 +19,14 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs, readBinaryFile(weights_path.c_str(), inputs*outputs*kh*kw*kl, &data_h, &data_d, seek); seek += inputs*outputs*kh*kw*kl; readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek); - + +std::cout<<"w:\n"; + printDeviceVector(64, data_d, true); + +std::cout<<"b:\n"; + printDeviceVector(64, bias_d, true); +std::cout<<"step----------------------------------------\n"; + this->batchnorm = batchnorm; if(batchnorm) { seek += outputs; @@ -29,6 +36,17 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs, seek += outputs; readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek); +std::cout<<"s:\n"; + printDeviceVector(64, scales_d, true); + +std::cout<<"m:\n"; + printDeviceVector(64, mean_d, true); + +std::cout<<"v:\n"; + printDeviceVector(64, variance_d, true); + + std::cout<<"END----------------------------------------\n"; + float eps = CUDNN_BN_MIN_EPSILON; power_h = new dnnType[outputs]; diff --git a/src/utils.cpp b/src/utils.cpp index e6f71f8..c8f90d8 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -54,6 +54,7 @@ void printDeviceVector(int size, dnnType* vec_d, bool device) vec = new dnnType[size]; cudaDeviceSynchronize(); cudaMemcpy(vec, vec_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); } else { vec = vec_d; } @@ -78,7 +79,7 @@ int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device) { cudaDeviceSynchronize(); cudaMemcpy(data_h, data_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost); cudaMemcpy(correct_h, correct_d, size*sizeof(dnnType), cudaMemcpyDeviceToHost); - + cudaDeviceSynchronize(); } else { data_h = data_d; correct_h = correct_d; diff --git a/tests/resnet101/resnet101.cpp b/tests/resnet101/resnet101.cpp index da931d5..26fb3dd 100644 --- a/tests/resnet101/resnet101.cpp +++ b/tests/resnet101/resnet101.cpp @@ -148,7 +148,7 @@ const char *layer4_2_conv3_bin = "../tests/resnet101/layers/layer4-2-conv3.bin"; //final const char *fc_bin = "../tests/resnet101/layers/fc.bin"; -const char *output_bin = "../tests/resnet101/debug/layer1-0-conv3.bin"; +const char *output_bin = "../tests/resnet101/debug/layer1-0-relu.bin"; int main() { @@ -161,16 +161,21 @@ int main() tk::dnn::Activation relu3(&net, CUDNN_ACTIVATION_RELU); tk::dnn::Pooling maxpool4(&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX); - //layer 1 tk::dnn::Conv2d layer1_0_conv1(&net, 64, 1, 1, 1, 1, 0, 0, layer1_0_conv1_bin, true); + tk::dnn::Activation relu1_0_1(&net, CUDNN_ACTIVATION_RELU); tk::dnn::Conv2d layer1_0_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_0_conv2_bin, true); + tk::dnn::Activation relu1_0_2(&net, CUDNN_ACTIVATION_RELU); tk::dnn::Conv2d layer1_0_conv3(&net, 256, 1, 1, 1, 1, 0, 0, layer1_0_conv3_bin, true); - -/* + + tk::dnn::Layer *m83_layers[1] = { &maxpool4 }; + tk::dnn::Route m83 (&net, m83_layers, 1); + tk::dnn::Conv2d layer1_0_downsample_0(&net, 256, 1, 1, 1, 1, 0, 0, layer1_0_downsample_0_bin, true); + + tk::dnn::Shortcut s1_0 (&net, &layer1_0_conv3); tk::dnn::Activation layer1_0_relu(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer1_0_downsample_0(&net, 256, 1, 1, 1, 1, 1, 1, layer1_0_downsample_0, true); - +/* + tk::dnn::Conv2d layer1_1_conv1(&net, 64, 1, 1, 1, 1, 1, 1, layer1_1_conv1_bin, true); tk::dnn::Conv2d layer1_1_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_1_conv2_bin, true); tk::dnn::Conv2d layer1_1_conv3(&net, 256, 1, 1, 1, 1, 1, 1, layer1_1_conv3_bin, true); @@ -347,6 +352,7 @@ int main() dnnType *data; dnnType *input_h; readBinaryFile(input_bin, dim.tot(), &input_h, &data); + printDeviceVector(64, data, true); //print network model net.print(); @@ -356,7 +362,7 @@ int main() */ tk::dnn::dataDim_t out_dim; - out_dim = layer1_0_conv3.output_dim; + out_dim = net.layers[net.num_layers-1]->output_dim; dnnType *cudnn_out, *rt_out; tk::dnn::dataDim_t dim1 = dim; //input dim @@ -368,7 +374,9 @@ int main() TIMER_STOP dim1.print(); } - cudnn_out = layer1_0_conv3.dstData; + cudnn_out = net.layers[net.num_layers-1]->dstData; + + printDeviceVector(64, cudnn_out, true); /* tk::dnn::dataDim_t dim2 = dim; printCenteredTitle(" TENSORRT inference ", '=', 30); diff --git a/tests/resnet101/resnet101_weightsexporter.py b/tests/resnet101/resnet101_weightsexporter.py index fd5a81d..05f3ba2 100644 --- a/tests/resnet101/resnet101_weightsexporter.py +++ b/tests/resnet101/resnet101_weightsexporter.py @@ -4,6 +4,14 @@ from PIL import Image from torchvision import transforms from torchsummary import summary import numpy as np +import struct + +def bin_write(f, data): + data =data.flatten() + # print(data) + fmt = 'f'*len(data) + bin = struct.pack(fmt, *data) + f.write(bin) def hook(module, input, output): setattr(module, "_value_hook", output) @@ -12,7 +20,7 @@ def hook(module, input, output): def print_wb(model, folder): for name, param in model.named_parameters(): - print ("Layer", name) + # print ("Layer", name) t = name.split('.')[0:-1] arg = name.split('.')[-1] t = '-'.join(t) @@ -43,20 +51,22 @@ def print_wb_output(model, input_batch): f = None for n, m in model.named_modules(): in_output = m._value_hook - print(n, ' ----------------------------------------------------------------') o = in_output.data.numpy() o = np.array(o, dtype=np.float32) t = '-'.join(n.split('.')) o.tofile("debug/" + t + ".bin", format="f") - if 'Conv2d' in str(m.type) or 'Linear' in str(m.type): - f = open("layers/" + t + ".bin", mode='wb') - - if f is None: + if not(' of Conv2d' in str(m.type) or ' of Linear' in str(m.type) or ' of BatchNorm2d' in str(m.type)): continue + + if ' of Conv2d' in str(m.type) or ' of Linear' in str(m.type): + file_name = "layers/" + t + ".bin" + print("open file: ", file_name) + f = open(file_name, mode='wb') + print(n, ' ----------------------------------------------------------------') # print(m._parameters) - print(m.type) + #print(m.type) w = np.array([]) b = np.array([]) @@ -71,20 +81,43 @@ def print_wb_output(model, input_batch): b = m._parameters['bias'].data.numpy() b = np.array(b, dtype=np.float32) print (" bias shape:", np.shape(b)) - else: - b = np.zeros(w.shape[0], dtype=np.float32) - print (" bias shape:", np.shape(b)) + # else: + # b = np.zeros(w.shape[0], dtype=np.float32) + # print (" bias shape:", np.shape(b)) if 'BatchNorm2d' in str(m.type): - s = np.zeros(w.shape[0], dtype=np.float32)+1 - s.tofile(f, format="f") + b = m._parameters['bias'].data.numpy() + b = np.array(b, dtype=np.float32) + s = m._parameters['weight'].data.numpy() + s = np.array(s, dtype=np.float32) + rm = m.running_mean.data.numpy() + rm = np.array(rm, dtype=np.float32) + rv = m.running_var.data.numpy() + rv = np.array(rv, dtype=np.float32) + #s.tofile(f, format="f") + bin_write(f,b) + bin_write(f,s) + bin_write(f,rm) + bin_write(f,rv) + print (" s shape:", np.shape(s)) + print (" rm shape:", np.shape(rm)) + print (" rv shape:", np.shape(rv)) - w.tofile(f, format="f") - b.tofile(f, format="f") + else: + + # w.tofile(f, format="f") + bin_write(f,w) + # print("w- ",w) + if b.size > 0: + # b.tofile(f, format="f") + bin_write(f,b) + # print("b - ",b) - if 'BatchNorm2d' in str(m.type) or 'Linear' in str(m.type): + if ' of BatchNorm2d' in str(m.type) or ' of Linear' in str(m.type): f.close() + print("close file") f = None + # return @@ -120,9 +153,9 @@ if __name__ == '__main__': output = model(input_batch) # Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes - print(output) + # print(output) print_wb_output(model, input_batch) - print(list(model.children())) + # print(list(model.children())) From 02936fa928a78d249549709dc8de281f97262900 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Tue, 29 Oct 2019 17:21:31 +0100 Subject: [PATCH 013/228] ResNet working --- include/tkDNN/Layer.h | 5 +- src/LayerWgs.cpp | 18 -- src/NetworkRT.cpp | 8 +- src/Route.cpp | 7 +- tests/resnet101/resnet101.cpp | 521 +++++++++++++++------------------- 5 files changed, 242 insertions(+), 317 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index cec213f..bab723d 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -225,6 +225,7 @@ public: int winH, winW; int strideH, strideW; int paddingH, paddingW; + tkdnnPoolingMode_t pool_mode; Pooling(Network *net, int winH, int winW, int strideH, int strideW, @@ -238,7 +239,6 @@ public: protected: cudnnPoolingDescriptor_t poolingDesc; - tkdnnPoolingMode_t pool_mode; dnnType *tmpInputData, *tmpOutputData; bool poolOn3d; }; @@ -270,7 +270,8 @@ public: virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); public: - Layer **layers; //ids of layers to be merged + static const int MAX_INPUT_LAYERS = 16; + Layer *layers[MAX_INPUT_LAYERS]; //ids of layers to be merged int layers_n; //number of layers }; diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index dfdde70..8219e26 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -20,13 +20,6 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs, seek += inputs*outputs*kh*kw*kl; readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek); -std::cout<<"w:\n"; - printDeviceVector(64, data_d, true); - -std::cout<<"b:\n"; - printDeviceVector(64, bias_d, true); -std::cout<<"step----------------------------------------\n"; - this->batchnorm = batchnorm; if(batchnorm) { seek += outputs; @@ -36,17 +29,6 @@ std::cout<<"step----------------------------------------\n"; seek += outputs; readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek); -std::cout<<"s:\n"; - printDeviceVector(64, scales_d, true); - -std::cout<<"m:\n"; - printDeviceVector(64, mean_d, true); - -std::cout<<"v:\n"; - printDeviceVector(64, variance_d, true); - - std::cout<<"END----------------------------------------\n"; - float eps = CUDNN_BN_MIN_EPSILON; power_h = new dnnType[outputs]; diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 7430b6f..2b3319c 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -263,10 +263,16 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { //std::cout<<"convert Pooling\n"; + PoolingType ptype; + if(l->pool_mode == tkdnnPoolingMode_t::POOLING_MAX) ptype = PoolingType::kMAX; + 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; + IPoolingLayer *lRT = networkRT->addPooling(*input, - PoolingType::kMAX, DimsHW{l->winH, l->winW}); + ptype, DimsHW{l->winH, l->winW}); checkNULL(lRT); lRT->setStride(DimsHW{l->strideH, l->strideW}); + lRT->setPadding(DimsHW{l->paddingH, l->paddingW}); return lRT; } diff --git a/src/Route.cpp b/src/Route.cpp index f61335e..7a95532 100644 --- a/src/Route.cpp +++ b/src/Route.cpp @@ -7,9 +7,12 @@ namespace tk { namespace dnn { Route::Route(Network *net, Layer **layers, int layers_n) : Layer(net) { - this->layers = layers; this->layers_n = layers_n; - + if(layers_n > MAX_INPUT_LAYERS) + FatalError("Route: MAX INPUT LAYERS overload"); + for(int i=0; ilayers[i] = layers[i]; + //get dims output_dim.l = 1; output_dim.c = 0; diff --git a/tests/resnet101/resnet101.cpp b/tests/resnet101/resnet101.cpp index 26fb3dd..c0d1c5f 100644 --- a/tests/resnet101/resnet101.cpp +++ b/tests/resnet101/resnet101.cpp @@ -5,150 +5,155 @@ const char *input_bin = "../tests/resnet101/debug/input.bin"; const char *conv1_bin = "../tests/resnet101/layers/conv1.bin"; //layer1 -const char *layer1_0_conv1_bin = "../tests/resnet101/layers/layer1-0-conv1.bin"; -const char *layer1_0_conv2_bin = "../tests/resnet101/layers/layer1-0-conv2.bin"; -const char *layer1_0_conv3_bin = "../tests/resnet101/layers/layer1-0-conv3.bin"; -const char *layer1_0_downsample_0_bin = "../tests/resnet101/layers/layer1-0-downsample-0.bin"; +const char *layer1_bin[]={ +"../tests/resnet101/layers/layer1-0-conv1.bin", +"../tests/resnet101/layers/layer1-0-conv2.bin", +"../tests/resnet101/layers/layer1-0-conv3.bin", +"../tests/resnet101/layers/layer1-0-downsample-0.bin", -const char *layer1_1_conv1_bin = "../tests/resnet101/layers/layer1-1-conv1.bin"; -const char *layer1_1_conv2_bin = "../tests/resnet101/layers/layer1-1-conv2.bin"; -const char *layer1_1_conv3_bin = "../tests/resnet101/layers/layer1-1-conv3.bin"; +"../tests/resnet101/layers/layer1-1-conv1.bin", +"../tests/resnet101/layers/layer1-1-conv2.bin", +"../tests/resnet101/layers/layer1-1-conv3.bin", -const char *layer1_2_conv1_bin = "../tests/resnet101/layers/layer1-2-conv1.bin"; -const char *layer1_2_conv2_bin = "../tests/resnet101/layers/layer1-2-conv2.bin"; -const char *layer1_2_conv3_bin = "../tests/resnet101/layers/layer1-2-conv3.bin"; +"../tests/resnet101/layers/layer1-2-conv1.bin", +"../tests/resnet101/layers/layer1-2-conv2.bin", +"../tests/resnet101/layers/layer1-2-conv3.bin"}; + //layer2 -const char *layer2_0_conv1_bin = "../tests/resnet101/layers/layer2-0-conv1.bin"; -const char *layer2_0_conv2_bin = "../tests/resnet101/layers/layer2-0-conv2.bin"; -const char *layer2_0_conv3_bin = "../tests/resnet101/layers/layer2-0-conv3.bin"; -const char *layer2_0_downsample_0_bin = "../tests/resnet101/layers/layer2-0-downsample-0.bin"; +const char *layer2_bin[]={ +"../tests/resnet101/layers/layer2-0-conv1.bin", +"../tests/resnet101/layers/layer2-0-conv2.bin", +"../tests/resnet101/layers/layer2-0-conv3.bin", +"../tests/resnet101/layers/layer2-0-downsample-0.bin", -const char *layer2_1_conv1_bin = "../tests/resnet101/layers/layer2-1-conv1.bin"; -const char *layer2_1_conv2_bin = "../tests/resnet101/layers/layer2-1-conv2.bin"; -const char *layer2_1_conv3_bin = "../tests/resnet101/layers/layer2-1-conv3.bin"; +"../tests/resnet101/layers/layer2-1-conv1.bin", +"../tests/resnet101/layers/layer2-1-conv2.bin", +"../tests/resnet101/layers/layer2-1-conv3.bin", -const char *layer2_2_conv1_bin = "../tests/resnet101/layers/layer2-2-conv1.bin"; -const char *layer2_2_conv2_bin = "../tests/resnet101/layers/layer2-2-conv2.bin"; -const char *layer2_2_conv3_bin = "../tests/resnet101/layers/layer2-2-conv3.bin"; - -const char *layer2_3_conv1_bin = "../tests/resnet101/layers/layer2-3-conv1.bin"; -const char *layer2_3_conv2_bin = "../tests/resnet101/layers/layer2-3-conv2.bin"; -const char *layer2_3_conv3_bin = "../tests/resnet101/layers/layer2-3-conv3.bin"; +"../tests/resnet101/layers/layer2-2-conv1.bin", +"../tests/resnet101/layers/layer2-2-conv2.bin", +"../tests/resnet101/layers/layer2-2-conv3.bin", +"../tests/resnet101/layers/layer2-3-conv1.bin", +"../tests/resnet101/layers/layer2-3-conv2.bin", +"../tests/resnet101/layers/layer2-3-conv3.bin" +}; //layer3 -const char *layer3_0_conv1_bin = "../tests/resnet101/layers/layer3-0-conv1.bin"; -const char *layer3_0_conv2_bin = "../tests/resnet101/layers/layer3-0-conv2.bin"; -const char *layer3_0_conv3_bin = "../tests/resnet101/layers/layer3-0-conv3.bin"; -const char *layer3_0_downsample_0_bin = "../tests/resnet101/layers/layer3-0-downsample-0.bin"; +const char *layer3_bin[]={ +"../tests/resnet101/layers/layer3-0-conv1.bin", +"../tests/resnet101/layers/layer3-0-conv2.bin", +"../tests/resnet101/layers/layer3-0-conv3.bin", +"../tests/resnet101/layers/layer3-0-downsample-0.bin", -const char *layer3_1_conv1_bin = "../tests/resnet101/layers/layer3-1-conv1.bin"; -const char *layer3_1_conv2_bin = "../tests/resnet101/layers/layer3-1-conv2.bin"; -const char *layer3_1_conv3_bin = "../tests/resnet101/layers/layer3-1-conv3.bin"; +"../tests/resnet101/layers/layer3-1-conv1.bin", +"../tests/resnet101/layers/layer3-1-conv2.bin", +"../tests/resnet101/layers/layer3-1-conv3.bin", -const char *layer3_2_conv1_bin = "../tests/resnet101/layers/layer3-2-conv1.bin"; -const char *layer3_2_conv2_bin = "../tests/resnet101/layers/layer3-2-conv2.bin"; -const char *layer3_2_conv3_bin = "../tests/resnet101/layers/layer3-2-conv3.bin"; +"../tests/resnet101/layers/layer3-2-conv1.bin", +"../tests/resnet101/layers/layer3-2-conv2.bin", +"../tests/resnet101/layers/layer3-2-conv3.bin", -const char *layer3_3_conv1_bin = "../tests/resnet101/layers/layer3-3-conv1.bin"; -const char *layer3_3_conv2_bin = "../tests/resnet101/layers/layer3-3-conv2.bin"; -const char *layer3_3_conv3_bin = "../tests/resnet101/layers/layer3-3-conv3.bin"; +"../tests/resnet101/layers/layer3-3-conv1.bin", +"../tests/resnet101/layers/layer3-3-conv2.bin", +"../tests/resnet101/layers/layer3-3-conv3.bin", -const char *layer3_4_conv1_bin = "../tests/resnet101/layers/layer3-4-conv1.bin"; -const char *layer3_4_conv2_bin = "../tests/resnet101/layers/layer3-4-conv2.bin"; -const char *layer3_4_conv3_bin = "../tests/resnet101/layers/layer3-4-conv3.bin"; +"../tests/resnet101/layers/layer3-4-conv1.bin", +"../tests/resnet101/layers/layer3-4-conv2.bin", +"../tests/resnet101/layers/layer3-4-conv3.bin", -const char *layer3_5_conv1_bin = "../tests/resnet101/layers/layer3-5-conv1.bin"; -const char *layer3_5_conv2_bin = "../tests/resnet101/layers/layer3-5-conv2.bin"; -const char *layer3_5_conv3_bin = "../tests/resnet101/layers/layer3-5-conv3.bin"; +"../tests/resnet101/layers/layer3-5-conv1.bin", +"../tests/resnet101/layers/layer3-5-conv2.bin", +"../tests/resnet101/layers/layer3-5-conv3.bin", -const char *layer3_6_conv1_bin = "../tests/resnet101/layers/layer3-6-conv1.bin"; -const char *layer3_6_conv2_bin = "../tests/resnet101/layers/layer3-6-conv2.bin"; -const char *layer3_6_conv3_bin = "../tests/resnet101/layers/layer3-6-conv3.bin"; +"../tests/resnet101/layers/layer3-6-conv1.bin", +"../tests/resnet101/layers/layer3-6-conv2.bin", +"../tests/resnet101/layers/layer3-6-conv3.bin", -const char *layer3_7_conv1_bin = "../tests/resnet101/layers/layer3-7-conv1.bin"; -const char *layer3_7_conv2_bin = "../tests/resnet101/layers/layer3-7-conv2.bin"; -const char *layer3_7_conv3_bin = "../tests/resnet101/layers/layer3-7-conv3.bin"; +"../tests/resnet101/layers/layer3-7-conv1.bin", +"../tests/resnet101/layers/layer3-7-conv2.bin", +"../tests/resnet101/layers/layer3-7-conv3.bin", -const char *layer3_8_conv1_bin = "../tests/resnet101/layers/layer3-8-conv1.bin"; -const char *layer3_8_conv2_bin = "../tests/resnet101/layers/layer3-8-conv2.bin"; -const char *layer3_8_conv3_bin = "../tests/resnet101/layers/layer3-8-conv3.bin"; +"../tests/resnet101/layers/layer3-8-conv1.bin", +"../tests/resnet101/layers/layer3-8-conv2.bin", +"../tests/resnet101/layers/layer3-8-conv3.bin", -const char *layer3_9_conv1_bin = "../tests/resnet101/layers/layer3-9-conv1.bin"; -const char *layer3_9_conv2_bin = "../tests/resnet101/layers/layer3-9-conv2.bin"; -const char *layer3_9_conv3_bin = "../tests/resnet101/layers/layer3-9-conv3.bin"; +"../tests/resnet101/layers/layer3-9-conv1.bin", +"../tests/resnet101/layers/layer3-9-conv2.bin", +"../tests/resnet101/layers/layer3-9-conv3.bin", -const char *layer3_10_conv1_bin = "../tests/resnet101/layers/layer3-10-conv1.bin"; -const char *layer3_10_conv2_bin = "../tests/resnet101/layers/layer3-10-conv2.bin"; -const char *layer3_10_conv3_bin = "../tests/resnet101/layers/layer3-10-conv3.bin"; +"../tests/resnet101/layers/layer3-10-conv1.bin", +"../tests/resnet101/layers/layer3-10-conv2.bin", +"../tests/resnet101/layers/layer3-10-conv3.bin", -const char *layer3_11_conv1_bin = "../tests/resnet101/layers/layer3-11-conv1.bin"; -const char *layer3_11_conv2_bin = "../tests/resnet101/layers/layer3-11-conv2.bin"; -const char *layer3_11_conv3_bin = "../tests/resnet101/layers/layer3-11-conv3.bin"; +"../tests/resnet101/layers/layer3-11-conv1.bin", +"../tests/resnet101/layers/layer3-11-conv2.bin", +"../tests/resnet101/layers/layer3-11-conv3.bin", -const char *layer3_12_conv1_bin = "../tests/resnet101/layers/layer3-12-conv1.bin"; -const char *layer3_12_conv2_bin = "../tests/resnet101/layers/layer3-12-conv2.bin"; -const char *layer3_12_conv3_bin = "../tests/resnet101/layers/layer3-12-conv3.bin"; +"../tests/resnet101/layers/layer3-12-conv1.bin", +"../tests/resnet101/layers/layer3-12-conv2.bin", +"../tests/resnet101/layers/layer3-12-conv3.bin", -const char *layer3_13_conv1_bin = "../tests/resnet101/layers/layer3-13-conv1.bin"; -const char *layer3_13_conv2_bin = "../tests/resnet101/layers/layer3-13-conv2.bin"; -const char *layer3_13_conv3_bin = "../tests/resnet101/layers/layer3-13-conv3.bin"; +"../tests/resnet101/layers/layer3-13-conv1.bin", +"../tests/resnet101/layers/layer3-13-conv2.bin", +"../tests/resnet101/layers/layer3-13-conv3.bin", -const char *layer3_14_conv1_bin = "../tests/resnet101/layers/layer3-14-conv1.bin"; -const char *layer3_14_conv2_bin = "../tests/resnet101/layers/layer3-14-conv2.bin"; -const char *layer3_14_conv3_bin = "../tests/resnet101/layers/layer3-14-conv3.bin"; +"../tests/resnet101/layers/layer3-14-conv1.bin", +"../tests/resnet101/layers/layer3-14-conv2.bin", +"../tests/resnet101/layers/layer3-14-conv3.bin", -const char *layer3_15_conv1_bin = "../tests/resnet101/layers/layer3-15-conv1.bin"; -const char *layer3_15_conv2_bin = "../tests/resnet101/layers/layer3-15-conv2.bin"; -const char *layer3_15_conv3_bin = "../tests/resnet101/layers/layer3-15-conv3.bin"; +"../tests/resnet101/layers/layer3-15-conv1.bin", +"../tests/resnet101/layers/layer3-15-conv2.bin", +"../tests/resnet101/layers/layer3-15-conv3.bin", -const char *layer3_16_conv1_bin = "../tests/resnet101/layers/layer3-16-conv1.bin"; -const char *layer3_16_conv2_bin = "../tests/resnet101/layers/layer3-16-conv2.bin"; -const char *layer3_16_conv3_bin = "../tests/resnet101/layers/layer3-16-conv3.bin"; +"../tests/resnet101/layers/layer3-16-conv1.bin", +"../tests/resnet101/layers/layer3-16-conv2.bin", +"../tests/resnet101/layers/layer3-16-conv3.bin", -const char *layer3_17_conv1_bin = "../tests/resnet101/layers/layer3-17-conv1.bin"; -const char *layer3_17_conv2_bin = "../tests/resnet101/layers/layer3-17-conv2.bin"; -const char *layer3_17_conv3_bin = "../tests/resnet101/layers/layer3-17-conv3.bin"; +"../tests/resnet101/layers/layer3-17-conv1.bin", +"../tests/resnet101/layers/layer3-17-conv2.bin", +"../tests/resnet101/layers/layer3-17-conv3.bin", -const char *layer3_18_conv1_bin = "../tests/resnet101/layers/layer3-18-conv1.bin"; -const char *layer3_18_conv2_bin = "../tests/resnet101/layers/layer3-18-conv2.bin"; -const char *layer3_18_conv3_bin = "../tests/resnet101/layers/layer3-18-conv3.bin"; +"../tests/resnet101/layers/layer3-18-conv1.bin", +"../tests/resnet101/layers/layer3-18-conv2.bin", +"../tests/resnet101/layers/layer3-18-conv3.bin", -const char *layer3_19_conv1_bin = "../tests/resnet101/layers/layer3-19-conv1.bin"; -const char *layer3_19_conv2_bin = "../tests/resnet101/layers/layer3-19-conv2.bin"; -const char *layer3_19_conv3_bin = "../tests/resnet101/layers/layer3-19-conv3.bin"; +"../tests/resnet101/layers/layer3-19-conv1.bin", +"../tests/resnet101/layers/layer3-19-conv2.bin", +"../tests/resnet101/layers/layer3-19-conv3.bin", -const char *layer3_20_conv1_bin = "../tests/resnet101/layers/layer3-20-conv1.bin"; -const char *layer3_20_conv2_bin = "../tests/resnet101/layers/layer3-20-conv2.bin"; -const char *layer3_20_conv3_bin = "../tests/resnet101/layers/layer3-20-conv3.bin"; +"../tests/resnet101/layers/layer3-20-conv1.bin", +"../tests/resnet101/layers/layer3-20-conv2.bin", +"../tests/resnet101/layers/layer3-20-conv3.bin", -const char *layer3_21_conv1_bin = "../tests/resnet101/layers/layer3-21-conv1.bin"; -const char *layer3_21_conv2_bin = "../tests/resnet101/layers/layer3-21-conv2.bin"; -const char *layer3_21_conv3_bin = "../tests/resnet101/layers/layer3-21-conv3.bin"; +"../tests/resnet101/layers/layer3-21-conv1.bin", +"../tests/resnet101/layers/layer3-21-conv2.bin", +"../tests/resnet101/layers/layer3-21-conv3.bin", -const char *layer3_22_conv1_bin = "../tests/resnet101/layers/layer3-22-conv1.bin"; -const char *layer3_22_conv2_bin = "../tests/resnet101/layers/layer3-22-conv2.bin"; -const char *layer3_22_conv3_bin = "../tests/resnet101/layers/layer3-22-conv3.bin"; +"../tests/resnet101/layers/layer3-22-conv1.bin", +"../tests/resnet101/layers/layer3-22-conv2.bin", +"../tests/resnet101/layers/layer3-22-conv3.bin"}; //layer4 -const char *layer4_0_conv1_bin = "../tests/resnet101/layers/layer4-0-conv1.bin"; -const char *layer4_0_conv2_bin = "../tests/resnet101/layers/layer4-0-conv2.bin"; -const char *layer4_0_conv3_bin = "../tests/resnet101/layers/layer4-0-conv3.bin"; -const char *layer4_0_downsample_0_bin = "../tests/resnet101/layers/layer4-0-downsample-0.bin"; +const char *layer4_bin[]={ +"../tests/resnet101/layers/layer4-0-conv1.bin", +"../tests/resnet101/layers/layer4-0-conv2.bin", +"../tests/resnet101/layers/layer4-0-conv3.bin", +"../tests/resnet101/layers/layer4-0-downsample-0.bin", -const char *layer4_1_conv1_bin = "../tests/resnet101/layers/layer4-1-conv1.bin"; -const char *layer4_1_conv2_bin = "../tests/resnet101/layers/layer4-1-conv2.bin"; -const char *layer4_1_conv3_bin = "../tests/resnet101/layers/layer4-1-conv3.bin"; +"../tests/resnet101/layers/layer4-1-conv1.bin", +"../tests/resnet101/layers/layer4-1-conv2.bin", +"../tests/resnet101/layers/layer4-1-conv3.bin", -const char *layer4_2_conv1_bin = "../tests/resnet101/layers/layer4-2-conv1.bin"; -const char *layer4_2_conv2_bin = "../tests/resnet101/layers/layer4-2-conv2.bin"; -const char *layer4_2_conv3_bin = "../tests/resnet101/layers/layer4-2-conv3.bin"; +"../tests/resnet101/layers/layer4-2-conv1.bin", +"../tests/resnet101/layers/layer4-2-conv2.bin", +"../tests/resnet101/layers/layer4-2-conv3.bin"}; //final const char *fc_bin = "../tests/resnet101/layers/fc.bin"; -const char *output_bin = "../tests/resnet101/debug/layer1-0-relu.bin"; +const char *output_bin = "../tests/resnet101/debug/fc.bin"; int main() { @@ -162,204 +167,132 @@ int main() tk::dnn::Pooling maxpool4(&net, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX); //layer 1 - tk::dnn::Conv2d layer1_0_conv1(&net, 64, 1, 1, 1, 1, 0, 0, layer1_0_conv1_bin, true); - tk::dnn::Activation relu1_0_1(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer1_0_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_0_conv2_bin, true); - tk::dnn::Activation relu1_0_2(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer1_0_conv3(&net, 256, 1, 1, 1, 1, 0, 0, layer1_0_conv3_bin, true); + int id_layer1_bin = 0; + tk::dnn::Layer *last = &maxpool4; + for(int i=0; i<3;i++) + { + tk::dnn::Conv2d *layer1_0_conv1 = new tk::dnn::Conv2d(&net, 64, 1, 1, 1, 1, 0, 0, layer1_bin[id_layer1_bin++], true); + tk::dnn::Activation *relu1_0_1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv2 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, layer1_bin[id_layer1_bin++], true); + tk::dnn::Activation *relu1_0_2 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv3 = new tk::dnn::Conv2d(&net, 256, 1, 1, 1, 1, 0, 0, layer1_bin[id_layer1_bin++], true); + if(i==0) { + tk::dnn::Layer *route_1_0_layers[1] = { last }; + tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *layer1_0_downsample_0 = new tk::dnn::Conv2d(&net, 256, 1, 1, 1, 1, 0, 0, layer1_bin[id_layer1_bin++], true); + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, layer1_0_conv3); + } else { + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, last); + } + tk::dnn::Activation *layer1_0_relu = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + last = layer1_0_relu; + } + + // tk::dnn::Activation *last_activation = (tk::dnn::Activation *) net.layers[net.num_layers-1]; + // layer 2 + int id_layer2_bin = 0; + for(int i=0; i<4;i++) + { + tk::dnn::Conv2d *layer1_0_conv1 = new tk::dnn::Conv2d(&net, 128, 1, 1, 1, 1, 0, 0, layer2_bin[id_layer2_bin++], true); + tk::dnn::Activation *relu1_0_1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv2; + if(i==0) + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 128, 3, 3, 2, 2, 1, 1, layer2_bin[id_layer2_bin++], true); + else + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 128, 3, 3, 1, 1, 1, 1, layer2_bin[id_layer2_bin++], true); + + tk::dnn::Activation *relu1_0_2 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv3 = new tk::dnn::Conv2d(&net, 512, 1, 1, 1, 1, 0, 0, layer2_bin[id_layer2_bin++], true); + if(i==0) + { + tk::dnn::Layer *route_1_0_layers[1] = { last }; + tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *layer1_0_downsample_0 = new tk::dnn::Conv2d(&net, 512, 1, 1, 2, 2, 0, 0, layer2_bin[id_layer2_bin++], true); + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, layer1_0_conv3); + } + else + { + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, last); + } + tk::dnn::Activation *layer1_0_relu = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + last = layer1_0_relu; + } - tk::dnn::Layer *m83_layers[1] = { &maxpool4 }; - tk::dnn::Route m83 (&net, m83_layers, 1); - tk::dnn::Conv2d layer1_0_downsample_0(&net, 256, 1, 1, 1, 1, 0, 0, layer1_0_downsample_0_bin, true); - - tk::dnn::Shortcut s1_0 (&net, &layer1_0_conv3); - tk::dnn::Activation layer1_0_relu(&net, CUDNN_ACTIVATION_RELU); -/* - - tk::dnn::Conv2d layer1_1_conv1(&net, 64, 1, 1, 1, 1, 1, 1, layer1_1_conv1_bin, true); - tk::dnn::Conv2d layer1_1_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_1_conv2_bin, true); - tk::dnn::Conv2d layer1_1_conv3(&net, 256, 1, 1, 1, 1, 1, 1, layer1_1_conv3_bin, true); - tk::dnn::Activation layer1_1_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer1_2_conv1(&net, 64, 1, 1, 1, 1, 1, 1, layer1_2_conv1_bin, true); - tk::dnn::Conv2d layer1_2_conv2(&net, 64, 3, 3, 1, 1, 1, 1, layer1_2_conv2_bin, true); - tk::dnn::Conv2d layer1_2_conv3(&net, 256, 1, 1, 1, 1, 1, 1, layer1_2_conv3_bin, true); - tk::dnn::Activation layer1_2_relu(&net, CUDNN_ACTIVATION_RELU); - - - //layer 2 - tk::dnn::Conv2d layer2_0_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_0_conv1_bin, true); - tk::dnn::Conv2d layer2_0_conv2(&net, 128, 3, 3, 2, 2, 1, 1, layer2_0_conv2_bin, true); - tk::dnn::Conv2d layer2_0_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_0_conv3_bin, true); - tk::dnn::Activation layer2_0_relu(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer2_0_downsample_0(&net, 512, 1, 1, 2, 2, 1, 1, layer2_0_downsample_0, true); - - tk::dnn::Conv2d layer2_1_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_1_conv1_bin, true); - tk::dnn::Conv2d layer2_1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_1_conv2_bin, true); - tk::dnn::Conv2d layer2_1_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_1_conv3_bin, true); - tk::dnn::Activation layer2_1_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer2_2_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_2_conv1_bin, true); - tk::dnn::Conv2d layer2_2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_2_conv2_bin, true); - tk::dnn::Conv2d layer2_2_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_2_conv3_bin, true); - tk::dnn::Activation layer2_2_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer2_3_conv1(&net, 128, 1, 1, 1, 1, 1, 1, layer2_3_conv1_bin, true); - tk::dnn::Conv2d layer2_3_conv2(&net, 128, 3, 3, 1, 1, 1, 1, layer2_3_conv2_bin, true); - tk::dnn::Conv2d layer2_3_conv3(&net, 512, 1, 1, 1, 1, 1, 1, layer2_3_conv3_bin, true); - tk::dnn::Activation layer2_3_relu(&net, CUDNN_ACTIVATION_RELU); - - //layer 3 - tk::dnn::Conv2d layer3_0_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_0_conv1_bin, true); - tk::dnn::Conv2d layer3_0_conv2(&net, 256, 3, 3, 2, 2, 1, 1, layer3_0_conv2_bin, true); - tk::dnn::Conv2d layer3_0_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_0_conv3_bin, true); - tk::dnn::Activation layer3_0_relu(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer3_0_downsample_0(&net, 1024, 1, 1, 2, 2, 1, 1, layer3_0_downsample_0, true); - - tk::dnn::Conv2d layer3_1_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_1_conv1_bin, true); - tk::dnn::Conv2d layer3_1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_1_conv2_bin, true); - tk::dnn::Conv2d layer3_1_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_1_conv3_bin, true); - tk::dnn::Activation layer3_1_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_2_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_2_conv1_bin, true); - tk::dnn::Conv2d layer3_2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_2_conv2_bin, true); - tk::dnn::Conv2d layer3_2_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_2_conv3_bin, true); - tk::dnn::Activation layer3_2_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_3_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_3_conv1_bin, true); - tk::dnn::Conv2d layer3_3_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_3_conv2_bin, true); - tk::dnn::Conv2d layer3_3_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_3_conv3_bin, true); - tk::dnn::Activation layer3_3_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_4_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_4_conv1_bin, true); - tk::dnn::Conv2d layer3_4_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_4_conv2_bin, true); - tk::dnn::Conv2d layer3_4_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_4_conv3_bin, true); - tk::dnn::Activation layer3_4_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_5_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_5_conv1_bin, true); - tk::dnn::Conv2d layer3_5_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_5_conv2_bin, true); - tk::dnn::Conv2d layer3_5_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_5_conv3_bin, true); - tk::dnn::Activation layer3_5_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_6_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_6_conv1_bin, true); - tk::dnn::Conv2d layer3_6_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_6_conv2_bin, true); - tk::dnn::Conv2d layer3_6_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_6_conv3_bin, true); - tk::dnn::Activation layer3_6_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_7_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_7_conv1_bin, true); - tk::dnn::Conv2d layer3_7_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_7_conv2_bin, true); - tk::dnn::Conv2d layer3_7_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_7_conv3_bin, true); - tk::dnn::Activation layer3_7_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_8_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_8_conv1_bin, true); - tk::dnn::Conv2d layer3_8_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_8_conv2_bin, true); - tk::dnn::Conv2d layer3_8_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_8_conv3_bin, true); - tk::dnn::Activation layer3_8_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_9_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_9_conv1_bin, true); - tk::dnn::Conv2d layer3_9_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_9_conv2_bin, true); - tk::dnn::Conv2d layer3_9_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_9_conv3_bin, true); - tk::dnn::Activation layer3_9_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_10_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_10_conv1_bin, true); - tk::dnn::Conv2d layer3_10_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_10_conv2_bin, true); - tk::dnn::Conv2d layer3_10_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_10_conv3_bin, true); - tk::dnn::Activation layer3_10_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_11_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_11_conv1_bin, true); - tk::dnn::Conv2d layer3_11_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_11_conv2_bin, true); - tk::dnn::Conv2d layer3_11_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_11_conv3_bin, true); - tk::dnn::Activation layer3_11_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_12_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_12_conv1_bin, true); - tk::dnn::Conv2d layer3_12_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_12_conv2_bin, true); - tk::dnn::Conv2d layer3_12_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_12_conv3_bin, true); - tk::dnn::Activation layer3_12_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_13_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_13_conv1_bin, true); - tk::dnn::Conv2d layer3_13_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_13_conv2_bin, true); - tk::dnn::Conv2d layer3_13_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_13_conv3_bin, true); - tk::dnn::Activation layer3_13_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_14_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_14_conv1_bin, true); - tk::dnn::Conv2d layer3_14_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_14_conv2_bin, true); - tk::dnn::Conv2d layer3_14_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_14_conv3_bin, true); - tk::dnn::Activation layer3_14_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_15_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_15_conv1_bin, true); - tk::dnn::Conv2d layer3_15_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_15_conv2_bin, true); - tk::dnn::Conv2d layer3_15_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_15_conv3_bin, true); - tk::dnn::Activation layer3_15_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_16_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_16_conv1_bin, true); - tk::dnn::Conv2d layer3_16_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_16_conv2_bin, true); - tk::dnn::Conv2d layer3_16_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_16_conv3_bin, true); - tk::dnn::Activation layer3_16_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_17_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_17_conv1_bin, true); - tk::dnn::Conv2d layer3_17_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_17_conv2_bin, true); - tk::dnn::Conv2d layer3_17_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_17_conv3_bin, true); - tk::dnn::Activation layer3_17_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_18_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_18_conv1_bin, true); - tk::dnn::Conv2d layer3_18_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_18_conv2_bin, true); - tk::dnn::Conv2d layer3_18_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_18_conv3_bin, true); - tk::dnn::Activation layer3_18_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_19_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_19_conv1_bin, true); - tk::dnn::Conv2d layer3_19_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_19_conv2_bin, true); - tk::dnn::Conv2d layer3_19_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_19_conv3_bin, true); - tk::dnn::Activation layer3_19_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_20_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_20_conv1_bin, true); - tk::dnn::Conv2d layer3_20_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_20_conv2_bin, true); - tk::dnn::Conv2d layer3_20_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_20_conv3_bin, true); - tk::dnn::Activation layer3_20_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_21_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_21_conv1_bin, true); - tk::dnn::Conv2d layer3_21_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_21_conv2_bin, true); - tk::dnn::Conv2d layer3_21_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_21_conv3_bin, true); - tk::dnn::Activation layer3_21_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer3_22_conv1(&net, 256, 1, 1, 1, 1, 1, 1, layer3_22_conv1_bin, true); - tk::dnn::Conv2d layer3_22_conv2(&net, 256, 3, 3, 1, 1, 1, 1, layer3_22_conv2_bin, true); - tk::dnn::Conv2d layer3_22_conv3(&net, 1024, 1, 1, 1, 1, 1, 1, layer3_22_conv3_bin, true); - tk::dnn::Activation layer3_22_relu(&net, CUDNN_ACTIVATION_RELU); - - //layer 4 - tk::dnn::Conv2d layer4_0_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_0_conv1_bin, true); - tk::dnn::Conv2d layer4_0_conv2(&net, 512, 3, 3, 2, 2, 1, 1, layer4_0_conv2_bin, true); - tk::dnn::Conv2d layer4_0_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_0_conv3_bin, true); - tk::dnn::Activation layer4_0_relu(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d layer4_0_downsample_0(&net, 2048, 1, 1, 2, 2, 1, 1, layer4_0_downsample_0, true); - - tk::dnn::Conv2d layer4_1_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_1_conv1_bin, true); - tk::dnn::Conv2d layer4_1_conv2(&net, 512, 3, 3, 1, 1, 1, 1, layer4_1_conv2_bin, true); - tk::dnn::Conv2d layer4_1_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_1_conv3_bin, true); - tk::dnn::Activation layer4_1_relu(&net, CUDNN_ACTIVATION_RELU); - - tk::dnn::Conv2d layer4_2_conv1(&net, 512, 1, 1, 1, 1, 1, 1, layer4_2_conv1_bin, true); - tk::dnn::Conv2d layer4_2_conv2(&net, 512, 3, 3, 1, 1, 1, 1, layer4_2_conv2_bin, true); - tk::dnn::Conv2d layer4_2_conv3(&net, 2048, 1, 1, 1, 1, 1, 1, layer4_2_conv3_bin, true); - tk::dnn::Activation layer4_2_relu(&net, CUDNN_ACTIVATION_RELU); + // layer 3 + int id_layer3_bin = 0; + for(int i=0; i<23;i++) + { + tk::dnn::Conv2d *layer1_0_conv1 = new tk::dnn::Conv2d(&net, 256, 1, 1, 1, 1, 0, 0, layer3_bin[id_layer3_bin++], true); + tk::dnn::Activation *relu1_0_1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv2; + if(i==0) + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 256, 3, 3, 2, 2, 1, 1, layer3_bin[id_layer3_bin++], true); + else + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 256, 3, 3, 1, 1, 1, 1, layer3_bin[id_layer3_bin++], true); + + tk::dnn::Activation *relu1_0_2 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv3 = new tk::dnn::Conv2d(&net, 1024, 1, 1, 1, 1, 0, 0, layer3_bin[id_layer3_bin++], true); + if(i==0) + { + tk::dnn::Layer *route_1_0_layers[1] = { last }; + tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *layer1_0_downsample_0 = new tk::dnn::Conv2d(&net, 1024, 1, 1, 2, 2, 0, 0, layer3_bin[id_layer3_bin++], true); + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, layer1_0_conv3); + } + else + { + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, last); + } + tk::dnn::Activation *layer1_0_relu = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + last = layer1_0_relu; + } + // layer 4 + int id_layer4_bin = 0; + for(int i=0; i<3;i++) + { + tk::dnn::Conv2d *layer1_0_conv1 = new tk::dnn::Conv2d(&net, 512, 1, 1, 1, 1, 0, 0, layer4_bin[id_layer4_bin++], true); + tk::dnn::Activation *relu1_0_1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv2; + if(i==0) + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 512, 3, 3, 2, 2, 1, 1, layer4_bin[id_layer4_bin++], true); + else + layer1_0_conv2 = new tk::dnn::Conv2d(&net, 512, 3, 3, 1, 1, 1, 1, layer4_bin[id_layer4_bin++], true); + + tk::dnn::Activation *relu1_0_2 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *layer1_0_conv3 = new tk::dnn::Conv2d(&net, 2048, 1, 1, 1, 1, 0, 0, layer4_bin[id_layer4_bin++], true); + if(i==0) + { + tk::dnn::Layer *route_1_0_layers[1] = { last }; + tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *layer1_0_downsample_0 = new tk::dnn::Conv2d(&net, 2048, 1, 1, 2, 2, 0, 0, layer4_bin[id_layer4_bin++], true); + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, layer1_0_conv3); + } + else + { + tk::dnn::Shortcut *s1_0 = new tk::dnn::Shortcut(&net, last); + } + tk::dnn::Activation *layer1_0_relu = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + last = layer1_0_relu; + } //final - tk::dnn::Pooling avgpool(&net, 3, 3, 2, 2, tk::dnn::POOLING_AVERAGE); + tk::dnn::Pooling avgpool(&net, 7, 7, 7, 7, 0, 0, tk::dnn::POOLING_AVERAGE); tk::dnn::Dense fc(&net, 1000, fc_bin); -*/ + + // Load input dnnType *data; dnnType *input_h; readBinaryFile(input_bin, dim.tot(), &input_h, &data); - printDeviceVector(64, data, true); + //printDeviceVector(64, data, true); //print network model net.print(); -/* + //convert network to tensorRT tk::dnn::NetworkRT netRT(&net, "resnet101.rt"); -*/ + tk::dnn::dataDim_t out_dim; out_dim = net.layers[net.num_layers-1]->output_dim; @@ -376,8 +309,8 @@ int main() } cudnn_out = net.layers[net.num_layers-1]->dstData; - printDeviceVector(64, cudnn_out, true); -/* + //printDeviceVector(64, cudnn_out, true); + tk::dnn::dataDim_t dim2 = dim; printCenteredTitle(" TENSORRT inference ", '=', 30); { @@ -388,7 +321,7 @@ int main() dim2.print(); } rt_out = (dnnType *)netRT.buffersRT[1]; -*/ + printCenteredTitle(std::string(" RESNET CHECK RESULTS ").c_str(), '=', 30); dnnType *out, *out_h; @@ -396,11 +329,11 @@ int main() readBinaryFile(output_bin, odim, &out_h, &out); std::cout << "CUDNN vs correct"; checkResult(odim, cudnn_out, out); -/* + std::cout << "TRT vs correct"; checkResult(odim, rt_out, out); std::cout << "CUDNN vs TRT "; checkResult(odim, cudnn_out, rt_out); -*/ + return 0; } From f9afee2f3b16536cdcc401c3d84311284db4ff25 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Wed, 30 Oct 2019 00:05:22 +0100 Subject: [PATCH 014/228] deconv layer cudnn --- include/tkDNN/Layer.h | 30 +++++- include/tkDNN/Network.h | 1 + include/tkDNN/utils.h | 2 +- src/Conv2d.cpp | 218 ++++++++++++++++++++++++++-------------- src/LayerWgs.cpp | 10 +- src/Network.cpp | 1 + src/utils.cpp | 37 +++---- 7 files changed, 197 insertions(+), 102 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index bab723d..483b7b5 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -11,6 +11,7 @@ namespace tk { namespace dnn { enum layerType_t { LAYER_DENSE, LAYER_CONV2D, + LAYER_DECONV2D, LAYER_ACTIVATION, LAYER_FLATTEN, LAYER_MULADD, @@ -47,6 +48,7 @@ public: switch(type) { case LAYER_DENSE: return "Dense"; case LAYER_CONV2D: return "Conv2d"; + case LAYER_DECONV2D: return "DeConv2d"; case LAYER_ACTIVATION: return "Activation"; case LAYER_FLATTEN: return "Flatten"; case LAYER_MULADD: return "MulAdd"; @@ -75,7 +77,7 @@ protected: class LayerWgs : public Layer { public: - LayerWgs(Network *net, int inputs, int outputs, int kh, int kw, int kt, + LayerWgs(Network *net, int inputs, int outputs, int kh, int kw, int kt, std::string fname_weights, bool batchnorm = false); virtual ~LayerWgs(); @@ -152,7 +154,7 @@ 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); + std::string fname_weights, bool batchnorm = false, bool deConv = false); virtual ~Conv2d(); virtual layerType_t getLayerType() { return LAYER_CONV2D; }; @@ -163,11 +165,33 @@ public: protected: cudnnFilterDescriptor_t filterDesc; cudnnConvolutionDescriptor_t convDesc; - cudnnConvolutionFwdAlgo_t algo; + cudnnConvolutionFwdAlgo_t fwAlgo; + cudnnConvolutionBwdDataAlgo_t bwAlgo; cudnnTensorDescriptor_t biasTensorDesc; + void initCUDNN(bool back = false); + void inferCUDNN(dnnType* srcData, bool back = false); void* workSpace; size_t ws_sizeInBytes; + + bool deConv; +}; + + +/** + Convolutional 2D layer +*/ +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) {} + virtual ~DeConv2d() {} + virtual layerType_t getLayerType() { return LAYER_DECONV2D; }; + + virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); }; diff --git a/include/tkDNN/Network.h b/include/tkDNN/Network.h index 9da5806..c56bd2c 100644 --- a/include/tkDNN/Network.h +++ b/include/tkDNN/Network.h @@ -60,6 +60,7 @@ public: dataDim_t getOutputDim(); bool fp16, dla; + bool dontLoadWeights; }; }} diff --git a/include/tkDNN/utils.h b/include/tkDNN/utils.h index dc34a31..f0503cd 100644 --- a/include/tkDNN/utils.h +++ b/include/tkDNN/utils.h @@ -90,7 +90,7 @@ void printCenteredTitle(const char *title, char fill, int dim); bool fileExist(const char *fname); -void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0); +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 printDeviceVector(int size, dnnType* vec_d, bool device = true); void resize(int size, dnnType **data); diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index 3dfdce6..da1a4a2 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -4,9 +4,121 @@ namespace tk { namespace dnn { +void Conv2d::initCUDNN(bool back) { + + cudnnTensorDescriptor_t srcTensor = srcTensorDesc; + cudnnTensorDescriptor_t dstTensor = dstTensorDesc; + + dataDim_t idim, odim; + if(!back) { + idim = input_dim; + odim = output_dim; + } else { + idim = output_dim; + odim = input_dim; + } + idim.print(); + odim.print(); + + checkCUDNN( cudnnCreateFilterDescriptor(&filterDesc) ); + checkCUDNN( cudnnCreateConvolutionDescriptor(&convDesc) ); + checkCUDNN( cudnnCreateTensorDescriptor(&biasTensorDesc) ); + + // input tensor dim + checkCUDNN( cudnnSetTensor4dDescriptor(srcTensor, + net->tensorFormat, net->dataType, idim.n, idim.c, idim.h, idim.w) ); + + checkCUDNN( cudnnSetFilter4dDescriptor(filterDesc, + net->dataType, net->tensorFormat, odim.c, idim.c, + kernelH, kernelW) ); + + checkCUDNN( cudnnSetConvolution2dDescriptor(convDesc, + paddingH, paddingW, // padding + strideH, strideW, // stride + 1,1, // upscale + CUDNN_CROSS_CORRELATION, CUDNN_DATA_FLOAT) ); + + // 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: "; odim.print(); + std::cout<<"cudnndim: "; tmpdim.print(); + FatalError("Eror conv dimension mismatch"); + } + + checkCUDNN( cudnnSetTensor4dDescriptor(dstTensor, + net->tensorFormat, net->dataType, odim.n, odim.c, odim.h, odim.w) ); + + checkCUDNN( cudnnSetTensor4dDescriptor(biasTensorDesc, + net->tensorFormat, net->dataType, + 1, output_dim.c, 1, 1) ); + + // init workspace + workSpace = NULL; + ws_sizeInBytes = 0; + if(back) { + checkCUDNN( cudnnGetConvolutionBackwardDataAlgorithm(net->cudnnHandle, + filterDesc, dstTensor, convDesc, srcTensor, + CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST, 0, &bwAlgo) ); + checkCUDNN(cudnnGetConvolutionBackwardDataWorkspaceSize(net->cudnnHandle, + filterDesc, dstTensor, convDesc, srcTensor, + bwAlgo, &ws_sizeInBytes)); + + // invert tensors + srcTensorDesc = dstTensor; + dstTensorDesc = srcTensor; + } else { + checkCUDNN( cudnnGetConvolutionForwardAlgorithm(net->cudnnHandle, + srcTensor, filterDesc, convDesc, dstTensor, + CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &fwAlgo) ); + checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle, + srcTensor, filterDesc, convDesc, dstTensor, + fwAlgo, &ws_sizeInBytes)); + } +} + +void Conv2d::inferCUDNN(dnnType* srcData, bool back) { + + dnnType alpha = dnnType(1); + dnnType beta = dnnType(0); + if(back) { + checkCUDNN(cudnnConvolutionBackwardData(net->cudnnHandle, + &alpha, filterDesc, data_d, + srcTensorDesc, srcData, + convDesc, bwAlgo, workSpace, ws_sizeInBytes, + &beta, dstTensorDesc, dstData)); + } else { + checkCUDNN(cudnnConvolutionForward(net->cudnnHandle, + &alpha, srcTensorDesc, srcData, filterDesc, + data_d, convDesc, fwAlgo, workSpace, ws_sizeInBytes, + &beta, dstTensorDesc, dstData)); + } + + if(!batchnorm) { + // bias + alpha = dnnType(1); + beta = dnnType(0); + checkCUDNN( cudnnAddTensor(net->cudnnHandle, + &alpha, biasTensorDesc, bias_d, + &beta, dstTensorDesc, dstData) ); + } else { + alpha = dnnType(1); + beta = dnnType(0); + 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, + CUDNN_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) : + std::string fname_weights, bool batchnorm, bool deConv) : LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1, fname_weights, batchnorm) { @@ -17,64 +129,28 @@ Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW, this->strideW = strideW; this->paddingH = paddingH; this->paddingW = paddingW; + this->deConv = deConv; - checkCUDNN( cudnnCreateFilterDescriptor(&filterDesc) ); - checkCUDNN( cudnnCreateConvolutionDescriptor(&convDesc) ); - checkCUDNN( cudnnCreateTensorDescriptor(&biasTensorDesc) ); - - int n = input_dim.n; - int c = input_dim.c; - int h = input_dim.h; - int w = input_dim.w; - - checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc, - net->tensorFormat, net->dataType, n, c, h, w) ); - - checkCUDNN( cudnnSetFilter4dDescriptor(filterDesc, - net->dataType, net->tensorFormat, out_ch, input_dim.c, - kernelH, kernelW) ); - - checkCUDNN( cudnnSetConvolution2dDescriptor(convDesc, - paddingH, paddingW, // padding - strideH, strideW, // stride - 1,1, // upscale - CUDNN_CROSS_CORRELATION, CUDNN_DATA_FLOAT) ); - - // find dimension of convolution output - checkCUDNN( cudnnGetConvolution2dForwardOutputDim( - convDesc, srcTensorDesc, filterDesc, - &n, &c, &h, &w) ); - - checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, - net->tensorFormat, net->dataType, n, c, h, w) ); - - checkCUDNN( cudnnGetConvolutionForwardAlgorithm(net->cudnnHandle, - srcTensorDesc, filterDesc, convDesc, dstTensorDesc, - CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo) ); - - workSpace = NULL; - ws_sizeInBytes = 0; - - checkCUDNN( cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle, - srcTensorDesc, filterDesc, convDesc, dstTensorDesc, - algo, &ws_sizeInBytes) ); + if(!deConv) { + output_dim.n = input_dim.n; + output_dim.c = out_ch; + output_dim.h = (input_dim.h + 2 * paddingH - kernelH) / strideH + 1; + output_dim.w = (input_dim.w + 2 * paddingW - kernelW) / strideW + 1; + output_dim.l = 1; + } else { + output_dim.n = input_dim.n; + output_dim.c = out_ch; + output_dim.h = (input_dim.h * strideH) - 2*paddingH + kernelH -1; + output_dim.w = (input_dim.w * strideW) - 2*paddingW + kernelW -1; + output_dim.l = 1; + } + initCUDNN(deConv); + // allocate warkspace if (ws_sizeInBytes!=0) { checkCuda( cudaMalloc(&workSpace, ws_sizeInBytes) ); } - - checkCUDNN( cudnnSetTensor4dDescriptor(biasTensorDesc, - net->tensorFormat, net->dataType, - 1, out_ch, 1, 1) ); - - - output_dim.n = n; - output_dim.c = c; - output_dim.h = h; - output_dim.w = w; - output_dim.l = 1; - //allocate data for infer result checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); } @@ -93,35 +169,25 @@ Conv2d::~Conv2d() { dnnType* Conv2d::infer(dataDim_t &dim, dnnType* srcData) { + if(deConv) { + FatalError("you must use DeConv class for Deconvolutional layers"); + } // convolution - dnnType alpha = dnnType(1); - dnnType beta = dnnType(0); - checkCUDNN( cudnnConvolutionForward(net->cudnnHandle, - &alpha, srcTensorDesc, srcData, filterDesc, - data_d, convDesc, algo, workSpace, ws_sizeInBytes, - &beta, dstTensorDesc, dstData) ); + inferCUDNN(srcData, false); - if(!batchnorm) { - // bias - alpha = dnnType(1); - beta = dnnType(1); - checkCUDNN( cudnnAddTensor(net->cudnnHandle, - &alpha, biasTensorDesc, bias_d, - &beta, dstTensorDesc, dstData) ); - } else { - float one = 1; - float zero = 0; - cudnnBatchNormalizationForwardInference(net->cudnnHandle, - CUDNN_BATCHNORM_SPATIAL, &one, &zero, - dstTensorDesc, dstData, dstTensorDesc, - dstData, biasTensorDesc, //same tensor descriptor as bias - scales_d, bias_d, mean_d, variance_d, - CUDNN_BN_MIN_EPSILON); - } //update data dimensions dim = output_dim; + return dstData; +} +dnnType* DeConv2d::infer(dataDim_t &dim, dnnType* srcData) { + + // convolution + inferCUDNN(srcData, true); + + //update data dimensions + dim = output_dim; return dstData; } diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index 8219e26..8c739b0 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -16,18 +16,18 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs, std::cout<<"Reading weights: I="<dontLoadWeights); seek += inputs*outputs*kh*kw*kl; - readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek); + readBinaryFile(weights_path.c_str(), outputs, &bias_h, &bias_d, seek, net->dontLoadWeights); this->batchnorm = batchnorm; if(batchnorm) { seek += outputs; - readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek); + readBinaryFile(weights_path.c_str(), outputs, &scales_h, &scales_d, seek, net->dontLoadWeights); seek += outputs; - readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek); + readBinaryFile(weights_path.c_str(), outputs, &mean_h, &mean_d, seek, net->dontLoadWeights); seek += outputs; - readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek); + readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek, net->dontLoadWeights); float eps = CUDNN_BN_MIN_EPSILON; diff --git a/src/Network.cpp b/src/Network.cpp index 491e32b..f55ecca 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -17,6 +17,7 @@ Network::Network(dataDim_t input_dim) { <<", CUDNN v"< Date: Wed, 30 Oct 2019 09:40:29 +0100 Subject: [PATCH 015/228] Deconv tensorrt --- include/tkDNN/Layer.h | 3 +-- include/tkDNN/NetworkRT.h | 1 + src/NetworkRT.cpp | 25 +++++++++++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 483b7b5..6015235 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -161,6 +161,7 @@ public: virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); int kernelH, kernelW, strideH, strideW, paddingH, paddingW; + bool deConv; protected: cudnnFilterDescriptor_t filterDesc; @@ -173,8 +174,6 @@ protected: void inferCUDNN(dnnType* srcData, bool back = false); void* workSpace; size_t ws_sizeInBytes; - - bool deConv; }; diff --git a/include/tkDNN/NetworkRT.h b/include/tkDNN/NetworkRT.h index d30da03..97dd478 100644 --- a/include/tkDNN/NetworkRT.h +++ b/include/tkDNN/NetworkRT.h @@ -75,6 +75,7 @@ public: nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Layer *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Conv2d *l); + nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, DeConv2d *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Activation *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Dense *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Pooling *l); diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 2b3319c..ce29f01 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -159,7 +159,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) { if(type == LAYER_DENSE) return convert_layer(input, (Dense*) l); - if(type == LAYER_CONV2D) + if(type == LAYER_CONV2D || type == LAYER_DECONV2D) return convert_layer(input, (Conv2d*) l); if(type == LAYER_POOLING) return convert_layer(input, (Pooling*) l); @@ -232,13 +232,22 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { else b = { dtRT, nullptr, 0}; //on batchnorm bias are added later - // Add a convolution layer with 20 outputs and a 5x5 filter. - IConvolutionLayer *lRT = networkRT->addConvolution(*input, - l->outputs, DimsHW{l->kernelH, l->kernelW}, w, b); - checkNULL(lRT); - - lRT->setStride(DimsHW{l->strideH, l->strideW}); - lRT->setPadding(DimsHW{l->paddingH, l->paddingW}); + ILayer *lRT = nullptr; + if(!l->deConv) { + IConvolutionLayer *lRTconv = networkRT->addConvolution(*input, + l->outputs, DimsHW{l->kernelH, l->kernelW}, w, b); + checkNULL(lRT); + lRTconv->setStride(DimsHW{l->strideH, l->strideW}); + lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); + lRT = (ILayer*) lRTconv; + } else { + IDeconvolutionLayer *lRTconv = networkRT->addDeconvolution(*input, + l->outputs, DimsHW{l->kernelH, l->kernelW}, w, b); + checkNULL(lRT); + lRTconv->setStride(DimsHW{l->strideH, l->strideW}); + lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); + lRT = (ILayer*) lRTconv; + } if(l->batchnorm) { Weights power{dtRT, power_b, l->outputs}; From d6d93a74f8adfe482dbe49fad0b2772e8754639b Mon Sep 17 00:00:00 2001 From: fbagni Date: Wed, 30 Oct 2019 09:42:54 +0100 Subject: [PATCH 016/228] fix --- src/NetworkRT.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index ce29f01..0f38f87 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -236,14 +236,14 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { if(!l->deConv) { IConvolutionLayer *lRTconv = networkRT->addConvolution(*input, l->outputs, DimsHW{l->kernelH, l->kernelW}, w, b); - checkNULL(lRT); + checkNULL(lRTconv); lRTconv->setStride(DimsHW{l->strideH, l->strideW}); lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); lRT = (ILayer*) lRTconv; } else { IDeconvolutionLayer *lRTconv = networkRT->addDeconvolution(*input, l->outputs, DimsHW{l->kernelH, l->kernelW}, w, b); - checkNULL(lRT); + checkNULL(lRTconv); lRTconv->setStride(DimsHW{l->strideH, l->strideW}); lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); lRT = (ILayer*) lRTconv; From 8b64d1876ff63db757db3dfa1a7af1421d3c459a Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Wed, 30 Oct 2019 10:20:04 +0100 Subject: [PATCH 017/228] deformable conv cu --- include/tkDNN/kernels.h | 9 +++ src/NetworkRT.cpp | 3 + src/kernels/deformable_conv.cu | 136 +++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 src/kernels/deformable_conv.cu diff --git a/include/tkDNN/kernels.h b/include/tkDNN/kernels.h index 2b602cb..ff4a334 100644 --- a/include/tkDNN/kernels.h +++ b/include/tkDNN/kernels.h @@ -24,4 +24,13 @@ void upsampleForward(dnnType* srcData, dnnType* dstData, 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); #endif //KERNELS_H diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 2b3319c..54dfad6 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -88,8 +88,11 @@ NetworkRT::NetworkRT(Network *net, const char *name) { std::cout<<"Building tensorRT cuda engine...\n"; engineRT = builderRT->buildCudaEngine(*networkRT); + if(engineRT == nullptr) + FatalError("cloud not build cuda engine") // we don't need the network any more //networkRT->destroy(); + std::cout<<"serialize net\n"; serialize(name); } else { deserialize(name); diff --git a/src/kernels/deformable_conv.cu b/src/kernels/deformable_conv.cu new file mode 100644 index 0000000..22b4dab --- /dev/null +++ b/src/kernels/deformable_conv.cu @@ -0,0 +1,136 @@ +#include +#include +#include + +#define CUDA_KERNEL_LOOP(i, n) \ + for (int i = blockIdx.x * blockDim.x + threadIdx.x; \ + i < (n); \ + i += blockDim.x * gridDim.x) + +const int CUDA_NUM_THREADS = 1024; +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; + + 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 w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw; + + 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) +{ + CUDA_KERNEL_LOOP(index, n) + { + // 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; + + // 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; + + float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_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 float *data_mask_ptr = data_mask + (b_col * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col; + + 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(0); + const float h_im = h_in + i * dilation_h + offset_h; + const float w_im = w_in + j * dilation_w + offset_w; + //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) + { + //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 * height_col * width_col; + //data_col_ptr += height_col * width_col; + } + } + } +} + + +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) { + // 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 + <<>>( + num_kernels, data_im, data_offset, data_mask, height_im, width_im, kernel_h, kenerl_w, + pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w, channel_per_deformable_group, + batch_size, channels, deformable_group, height_col, width_col, data_col); + + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + { + printf("error in modulated_deformable_im2col_cuda: %s\n", cudaGetErrorString(err)); + } + +} From f247300469ce8d6fc478eeb6f0c985804e2e96c0 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Wed, 30 Oct 2019 15:40:48 +0100 Subject: [PATCH 018/228] test simple --- .gitignore | 1 + src/NetworkRT.cpp | 1 + tests/simple/test_simple.cpp | 53 +++++++++++++++++++++++++----------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 446d490..02f2a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ build/ *.h5 *.tar.gz *.weights +.idea/ \ No newline at end of file diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index cfc1fa3..a1ed830 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -183,6 +183,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) { if(type == LAYER_UPSAMPLE) return convert_layer(input, (Upsample*) l); + std::cout<getLayerName()<<"\n"; FatalError("Layer not implemented in tensorRT"); return NULL; } diff --git a/tests/simple/test_simple.cpp b/tests/simple/test_simple.cpp index a7628ea..d331b96 100644 --- a/tests/simple/test_simple.cpp +++ b/tests/simple/test_simple.cpp @@ -16,7 +16,6 @@ int main() { tk::dnn::Activation l1(&net, CUDNN_ACTIVATION_RELU); tk::dnn::Conv2d l2(&net, 4, 2, 2, 1, 1, 0, 0, c1_bin); tk::dnn::Activation l3(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Flatten l4(&net); tk::dnn::Dense l5(&net, 4, d2_bin); tk::dnn::Activation l6(&net, CUDNN_ACTIVATION_RELU); @@ -25,23 +24,45 @@ int main() { dnnType *input_h; readBinaryFile(input_bin, dim.tot(), &input_h, &data); + // Print input + std::cout<<"\n======= INPUT =======\n"; printDeviceVector(dim.tot(), data); - dim.print(); //print initial dimension - - TIMER_START - // Inference - data = net.infer(dim, data); dim.print(); - TIMER_STOP + std::cout<<"\n"; - // Print result - std::cout<<"\n======= RESULT =======\n"; - printDeviceVector(dim.tot(), data); + //convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "simple.rt"); - // 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); + dnnType *out_data, *out_data2; // cudnn output, tensorRT output + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); { + dim1.print(); + TIMER_START + out_data = net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + + tk::dnn::dataDim_t dim2 = dim; + printCenteredTitle(" TENSORRT inference ", '=', 30); { + dim2.print(); + TIMER_START + out_data2 = netRT.infer(dim2, data); + TIMER_STOP + dim2.print(); + } + + std::cout<<"\n======= CUDNN =======\n"; + printDeviceVector(dim.tot(), out_data); + std::cout<<"\n======= TENSORRT =======\n"; + printDeviceVector(dim.tot(), out_data2); + + printCenteredTitle(" CHECK RESULTS ", '=', 30); + dnnType *out, *out_h; + int out_dim = net.getOutputDim().tot(); + //readBinaryFile(output_bin, out_dim, &out_h, &out); + //std::cout<<"CUDNN vs correct"; checkResult(out_dim, out_data, out); + //std::cout<<"TRT vs correct"; checkResult(out_dim, out_data2, out); + std::cout<<"CUDNN vs TRT "; checkResult(out_dim, out_data, out_data2); return 0; } From 2594f59d0d20460a3ddd9aa3737e725f8ac3ed8a Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Wed, 30 Oct 2019 16:45:46 +0100 Subject: [PATCH 019/228] conv2d ok, but deconv ha different dim with tensorrt --- include/tkDNN/Layer.h | 2 +- include/tkDNN/NetworkRT.h | 1 - src/Conv2d.cpp | 12 ++++++------ tests/simple/test_simple.cpp | 2 ++ 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 6015235..31dc4d2 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -166,7 +166,7 @@ public: protected: cudnnFilterDescriptor_t filterDesc; cudnnConvolutionDescriptor_t convDesc; - cudnnConvolutionFwdAlgo_t fwAlgo; + cudnnConvolutionFwdAlgo_t algo; cudnnConvolutionBwdDataAlgo_t bwAlgo; cudnnTensorDescriptor_t biasTensorDesc; diff --git a/include/tkDNN/NetworkRT.h b/include/tkDNN/NetworkRT.h index 97dd478..d30da03 100644 --- a/include/tkDNN/NetworkRT.h +++ b/include/tkDNN/NetworkRT.h @@ -75,7 +75,6 @@ public: nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Layer *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Conv2d *l); - nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, DeConv2d *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Activation *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Dense *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Pooling *l); diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index da1a4a2..cc4fbd5 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -73,10 +73,10 @@ void Conv2d::initCUDNN(bool back) { } else { checkCUDNN( cudnnGetConvolutionForwardAlgorithm(net->cudnnHandle, srcTensor, filterDesc, convDesc, dstTensor, - CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &fwAlgo) ); + CUDNN_CONVOLUTION_FWD_PREFER_FASTEST, 0, &algo) ); checkCUDNN(cudnnGetConvolutionForwardWorkspaceSize(net->cudnnHandle, srcTensor, filterDesc, convDesc, dstTensor, - fwAlgo, &ws_sizeInBytes)); + algo, &ws_sizeInBytes)); } } @@ -93,14 +93,14 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) { } else { checkCUDNN(cudnnConvolutionForward(net->cudnnHandle, &alpha, srcTensorDesc, srcData, filterDesc, - data_d, convDesc, fwAlgo, workSpace, ws_sizeInBytes, + data_d, convDesc, algo, workSpace, ws_sizeInBytes, &beta, dstTensorDesc, dstData)); } if(!batchnorm) { // bias alpha = dnnType(1); - beta = dnnType(0); + beta = dnnType(1); checkCUDNN( cudnnAddTensor(net->cudnnHandle, &alpha, biasTensorDesc, bias_d, &beta, dstTensorDesc, dstData) ); @@ -116,7 +116,7 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) { } } -Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW, +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) : @@ -156,7 +156,7 @@ Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW, } Conv2d::~Conv2d() { - + checkCUDNN( cudnnDestroyFilterDescriptor(filterDesc) ); checkCUDNN( cudnnDestroyConvolutionDescriptor(convDesc) ); checkCUDNN( cudnnDestroyTensorDescriptor(biasTensorDesc) ); diff --git a/tests/simple/test_simple.cpp b/tests/simple/test_simple.cpp index d331b96..5634e4a 100644 --- a/tests/simple/test_simple.cpp +++ b/tests/simple/test_simple.cpp @@ -19,6 +19,8 @@ int main() { tk::dnn::Dense l5(&net, 4, d2_bin); tk::dnn::Activation l6(&net, CUDNN_ACTIVATION_RELU); + net.print(); + // Load input dnnType *data; dnnType *input_h; From aa5927d8a168b44f32a13dfa0551d78594e9fe33 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Wed, 6 Nov 2019 14:04:23 +0100 Subject: [PATCH 020/228] findCUDNN --- CMakeLists.txt | 12 +++--------- cmake/FindCUDNN.cmake | 33 +++++++++++++++++++++++++++++++++ cmake/tkDNNConfig.cmake | 16 +++++----------- 3 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 cmake/FindCUDNN.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 467e823..b4b3c38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,17 +18,11 @@ find_package(CUDA 9.0 REQUIRED) SET(CUDA_SEPARABLE_COMPILATION ON) #set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -arch=sm_30 --compiler-options '-fPIC'") -# compile Discovery only if TensorRT is installed -find_library(NVINFER NAMES nvinfer) -if(NVINFER STREQUAL "NVINFER-NOTFOUND") - set(NVINFER_INCLUDES "/usr/local/nvidia/tensorrt/include/") - link_directories(/usr/local/nvidia/tensorrt/targets/x86_64-linux-gnu/lib/ - /usr/local/cuda/targets/x86_64-linux/lib/) -endif() +find_package(CUDNN REQUIRED) # compile file(GLOB tkdnn_CUSRC "src/kernels/*.cu") -cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${NVINFER_INCLUDES}) +cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${CUDNN_INCLUDE_DIRS}) cuda_add_library(kernels SHARED ${tkdnn_CUSRC}) @@ -43,7 +37,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV") # Build Libraries #------------------------------------------------------------------------------- file(GLOB tkdnn_SRC "src/*.cpp") -set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} -lcudnn -lnvinfer ${OpenCV_LIBS}) +set(tkdnn_LIBS kernels ${CUDA_LIBRARIES} ${CUDA_CUBLAS_LIBRARIES} ${CUDNN_LIBRARIES} ${OpenCV_LIBS}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} ${NVINFER_INCLUDES}) diff --git a/cmake/FindCUDNN.cmake b/cmake/FindCUDNN.cmake new file mode 100644 index 0000000..0e99052 --- /dev/null +++ b/cmake/FindCUDNN.cmake @@ -0,0 +1,33 @@ +# Find the header files + +find_path(CUDNN_INCLUDE_DIR + ${CMAKE_SYSROOT}/usr/local/include + ${CMAKE_SYSROOT}/usr/include + /usr/local/nvidia/tensorrt/include/ + NO_DEFAULT_PATH +) + +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-2.0/targets/${CMAKE_SYSTEM_PROCESSOR}-Linux/lib + /usr/lib/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/ + NO_DEFAULT_PATH +) +find_library(CUDNN_NVLIB + NAMES "nvinfer" + PATHS + /usr/local/driveworks-2.0/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) diff --git a/cmake/tkDNNConfig.cmake b/cmake/tkDNNConfig.cmake index fd06286..4dbaf21 100644 --- a/cmake/tkDNNConfig.cmake +++ b/cmake/tkDNNConfig.cmake @@ -4,27 +4,21 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -fPIC") find_package(CUDA REQUIRED) find_package(OpenCV REQUIRED) -find_library(NVINFER NAMES nvinfer) -if(NVINFER STREQUAL "NVINFER-NOTFOUND") - set(NVINFER_INCLUDES "/usr/local/nvidia/tensorrt/include/") - link_directories(/usr/local/nvidia/tensorrt/targets/x86_64-linux-gnu/lib/ - /usr/local/cuda/targets/x86_64-linux/lib/) -endif() +find_package(CUDNN REQUIRED) set(tkDNN_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS} - ${NVINFER_INCLUDES} + ${CUDNN_INCLUDE_DIRS} ) set(tkDNN_LIBRARIES tkDNN kernels ${CUDA_LIBRARIES} - ${CUDA_CUBLAS_LIBRARIES} - -lcudnn - -lnvinfer - ${OpenCV_LIBS} + ${CUDA_CUBLAS_LIBRARIES} + ${CUDNN_LIBRARIES} + ${OpenCV_LIBS} ) set(tkDNN_FOUND true) From b218b18a02b19c4e84ef85fd312c8085b46bbdce Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Mon, 2 Dec 2019 20:24:12 +0100 Subject: [PATCH 021/228] readme update --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index b166f63..93a7574 100644 --- a/README.md +++ b/README.md @@ -48,5 +48,3 @@ this will genereate a yolo3_berkeley.rt file that can be used for live detection ./yolo3_demo # launch detection on a demo video ./yolo3_demo yolo3_berkeley.rt /dev/video0 # launch detection on device 0 ``` - - From a2db98670a90532c4b797d1acf7c8fa5193e5339 Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Wed, 4 Dec 2019 17:01:40 +0000 Subject: [PATCH 022/228] Add Yolov3 (COCO80) and Yolov3-tiny (COCO80), TensorRT for tiny not working Signed-off-by: Micaela Verucchi --- CMakeLists.txt | 6 + src/NetworkRT.cpp | 7 +- src/Pooling.cpp | 22 +- src/Yolo.cpp | 8 +- src/utils.cpp | 2 + tests/yolo3/yolo3.cpp | 92 ++++ tests/yolo3/yolov3.cfg | 789 +++++++++++++++++++++++++++++++ tests/yolo3_tiny/yolo3_tiny.cpp | 122 +++++ tests/yolo3_tiny/yolov3-tiny.cfg | 182 +++++++ 9 files changed, 1222 insertions(+), 8 deletions(-) create mode 100644 tests/yolo3/yolo3.cpp create mode 100644 tests/yolo3/yolov3.cfg create mode 100644 tests/yolo3_tiny/yolo3_tiny.cpp create mode 100644 tests/yolo3_tiny/yolov3-tiny.cfg diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c5a301..f50b96a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,12 @@ 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) diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index a1ed830..7cfa816 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -209,7 +209,9 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Dense *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { - //std::cout<<"convert conv2D\n"; + std::cout<<"convert conv2D\n"; + 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; if(dtRT == DataType::kHALF) { @@ -274,7 +276,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { } ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { - //std::cout<<"convert Pooling\n"; + std::cout<<"convert Pooling\n"; + // printf("%d %d\n", l->winW, l->winH); PoolingType ptype; if(l->pool_mode == tkdnnPoolingMode_t::POOLING_MAX) ptype = PoolingType::kMAX; diff --git a/src/Pooling.cpp b/src/Pooling.cpp index 98bbd42..ce84926 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -26,6 +26,9 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, int w = input_dim.w; int l = input_dim.l; + printf("before: %d %d\n", h, w); + + poolOn3d = false; if(l > 1) { @@ -38,6 +41,8 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, n = l; } + + checkCUDNN( cudnnSetPooling2dDescriptor(poolingDesc, cudnnPoolingMode_t(pool_mode), CUDNN_NOT_PROPAGATE_NAN, winH, winW, paddingH, paddingW, strideH, strideW) ); @@ -45,12 +50,23 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, net->tensorFormat, net->dataType, n, c, h, w) ); //get out dim - checkCUDNN( cudnnGetPooling2dForwardOutputDim(poolingDesc, srcTensorDesc, &n, &c, &h, &w)); - //h = (h + winH*this->paddingH)/strideH; - //w = (w + winW*this->paddingW)/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; + + h = (h + padH - winH)/strideH +1; + w = (w + padW - winW)/strideW +1; + + // h = (h + winH*this->paddingH)/strideH; + // w = (w + winW*this->paddingW)/strideW; checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, net->tensorFormat, net->dataType, n, c, h, w) ); + + printf("after: %d %d\n", h, w); output_dim.n = n; output_dim.c = c; diff --git a/src/Yolo.cpp b/src/Yolo.cpp index babef38..e01ed57 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -15,14 +15,16 @@ Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights) : Layer(net) { this->classes = classes; - this->num = num; + this->num = 3; // load anchors if(fname_weights != "") { int seek = 0; - readBinaryFile(fname_weights, num, &mask_h, &mask_d, seek); - seek += num; + readBinaryFile(fname_weights, 3, &mask_h, &mask_d, seek); + seek += 3; readBinaryFile(fname_weights, 3*num*2, &bias_h, &bias_d, seek); + for(int i=0; i<3*num*2; i++) + printf("%f\n", bias_h[i]); } // init default classes name diff --git a/src/utils.cpp b/src/utils.cpp index 4dac886..250cadc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -38,7 +38,9 @@ void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** dat 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()); } diff --git a/tests/yolo3/yolo3.cpp b/tests/yolo3/yolo3.cpp new file mode 100644 index 0000000..a3772e5 --- /dev/null +++ b/tests/yolo3/yolo3.cpp @@ -0,0 +1,92 @@ +#include +#include +#include "tkdnn.h" + +int main() { + + // Network layout + tk::dnn::dataDim_t dim(1, 3, 416, 416, 1); + tk::dnn::Network net(dim); + + // create yolo3 model + std::string bin_path = "../tests/yolo3"; + int classes = 80; + tk::dnn::Yolo *yolo [3]; + #include "models/Yolo3.h" + + // fill classes names + for(int i=0; i<3; i++) { + yolo[i]->classesNames = {"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"}; + } + + // Load input + dnnType *data; + dnnType *input_h; + readBinaryFile(input_bin, dim.tot(), &input_h, &data); + + //print network model + net.print(); + + //convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "yolo3.rt"); + + // the network have 3 outputs + tk::dnn::dataDim_t out_dim[3]; + for(int i=0; i<3; i++) out_dim[i] = yolo[i]->output_dim; + dnnType *cudnn_out[3], *rt_out[3]; + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); { + dim1.print(); + TIMER_START + net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + for(int i=0; i<3; i++) cudnn_out[i] = yolo[i]->dstData; + + printCenteredTitle(" compute detections ", '=', 30); + TIMER_START + int ndets = 0; + tk::dnn::Yolo::detection *dets = tk::dnn::Yolo::allocateDetections(tk::dnn::Yolo::MAX_DETECTIONS, classes); + for(int i=0; i<3; i++) yolo[i]->computeDetections(dets, ndets, net.input_dim.w, net.input_dim.h, 0.5); + tk::dnn::Yolo::mergeDetections(dets, ndets, classes); + + for(int j=0; j 0) + cl = c; + } + std::cout< +#include "tkdnn.h" + +const char *input_bin = "../tests/yolo3_tiny/layers/input.bin"; +const char *c0_bin = "../tests/yolo3_tiny/layers/c0.bin"; +const char *c2_bin = "../tests/yolo3_tiny/layers/c2.bin"; +const char *c4_bin = "../tests/yolo3_tiny/layers/c4.bin"; +const char *c6_bin = "../tests/yolo3_tiny/layers/c6.bin"; +const char *c8_bin = "../tests/yolo3_tiny/layers/c8.bin"; +const char *c10_bin = "../tests/yolo3_tiny/layers/c10.bin"; +const char *c12_bin = "../tests/yolo3_tiny/layers/c12.bin"; +const char *c13_bin = "../tests/yolo3_tiny/layers/c13.bin"; +const char *c14_bin = "../tests/yolo3_tiny/layers/c14.bin"; +const char *c15_bin = "../tests/yolo3_tiny/layers/c15.bin"; +const char *c18_bin = "../tests/yolo3_tiny/layers/c18.bin"; +const char *c21_bin = "../tests/yolo3_tiny/layers/c21.bin"; +const char *c22_bin = "../tests/yolo3_tiny/layers/c22.bin"; +const char *g16_bin = "../tests/yolo3_tiny/layers/g16.bin"; +const char *g23_bin = "../tests/yolo3_tiny/layers/g23.bin"; +// const char *output_bin = "../tests/yolo3_tiny/layers/output.bin"; + +const char *output_bin = "../tests/yolo3_tiny/debug/layer23_out.bin"; + +int main() { + + int classes = 80; + + // Network layout + tk::dnn::dataDim_t dim(1, 3, 416, 416, 1); + tk::dnn::Network net(dim); + + + tk::dnn::Conv2d c0 (&net, 16, 3, 3, 1, 1, 1, 1, c0_bin, true); + tk::dnn::Activation a0 (&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p1 (&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c2 (&net, 32, 3, 3, 1, 1, 1, 1, c2_bin, true); + tk::dnn::Activation a2 (&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p3 (&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c4 (&net, 64, 3, 3, 1, 1, 1, 1, c4_bin, true); + tk::dnn::Activation a4 (&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p5 (&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c6 (&net, 128, 3, 3, 1, 1, 1, 1, c6_bin, true); + tk::dnn::Activation a6 (&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p7(&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c8(&net, 256, 3, 3, 1, 1, 1, 1, c8_bin, true); + tk::dnn::Activation a8(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p9(&net, 2, 2, 2, 2, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c10(&net, 512, 3, 3, 1, 1, 1, 1, c10_bin, true); + tk::dnn::Activation a10(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Pooling p11(&net, 2, 2, 1, 1, tk::dnn::POOLING_MAX); + + tk::dnn::Conv2d c12(&net, 1024, 3, 3, 1, 1, 1, 1, c12_bin, true); + tk::dnn::Activation a12(&net, tk::dnn::ACTIVATION_LEAKY); + + tk::dnn::Conv2d c13(&net, 256, 1, 1, 1, 1, 0, 0, c13_bin, true); + tk::dnn::Activation a13(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Conv2d c14(&net, 512, 3, 3, 1, 1, 1, 1, c14_bin, true); + tk::dnn::Activation a14(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Conv2d c15(&net, 255, 1, 1, 1, 1, 0, 0, c15_bin, false); + + tk::dnn::Yolo yolo0 (&net, classes, 2, g16_bin); + + tk::dnn::Layer *m17_layers[1] = { &a13 }; + tk::dnn::Route m17 (&net, m17_layers, 1); + tk::dnn::Conv2d c18(&net, 128, 1, 1, 1, 1, 0, 0, c18_bin, true); + tk::dnn::Activation a18(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Upsample u19 (&net, 2); + + tk::dnn::Layer *m20_layers[2] = { &u19, &a8 }; + tk::dnn::Route m20 (&net, m20_layers, 2); + + tk::dnn::Conv2d c21(&net, 256, 3, 3, 1, 1, 1, 1, c21_bin, true); + tk::dnn::Activation a21(&net, tk::dnn::ACTIVATION_LEAKY); + tk::dnn::Conv2d c22(&net, 255, 1, 1, 1, 1, 0, 0, c22_bin, false); + + tk::dnn::Yolo yolo1 (&net, classes, 2, g23_bin); + + // Load input + dnnType *data; + dnnType *input_h; + readBinaryFile(input_bin, dim.tot(), &input_h, &data); + + //print network model + net.print(); + + // convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "yolo3_tiny.rt"); + + dnnType *out_data, *out_data2; // cudnn output, tensorRT output + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); { + dim1.print(); + TIMER_START + out_data = net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + + // tk::dnn::dataDim_t dim2 = dim; + // printCenteredTitle(" TENSORRT inference ", '=', 30); { + // dim2.print(); + // TIMER_START + // out_data2 = netRT.infer(dim2, data); + // TIMER_STOP + // dim2.print(); + // } + + printCenteredTitle(" CHECK RESULTS ", '=', 30); + dnnType *out, *out_h; + int out_dim = net.getOutputDim().tot(); + readBinaryFile(output_bin, out_dim, &out_h, &out); + std::cout<<"CUDNN vs correct"; checkResult(out_dim, out_data, out); + // std::cout<<"TRT vs correct"; checkResult(out_dim, out_data2, out); + // std::cout<<"CUDNN vs TRT "; checkResult(out_dim, out_data, out_data2); + return 0; +} diff --git a/tests/yolo3_tiny/yolov3-tiny.cfg b/tests/yolo3_tiny/yolov3-tiny.cfg new file mode 100644 index 0000000..cfca3cf --- /dev/null +++ b/tests/yolo3_tiny/yolov3-tiny.cfg @@ -0,0 +1,182 @@ +[net] +# Testing +batch=1 +subdivisions=1 +# Training +# batch=64 +# subdivisions=2 +width=416 +height=416 +channels=3 +momentum=0.9 +decay=0.0005 +angle=0 +saturation = 1.5 +exposure = 1.5 +hue=.1 + +learning_rate=0.001 +burn_in=1000 +max_batches = 500200 +policy=steps +steps=400000,450000 +scales=.1,.1 + +[convolutional] +batch_normalize=1 +filters=16 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=32 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=64 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=128 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=2 + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[maxpool] +size=2 +stride=1 + +[convolutional] +batch_normalize=1 +filters=1024 +size=3 +stride=1 +pad=1 +activation=leaky + +########### + +[convolutional] +batch_normalize=1 +filters=256 +size=1 +stride=1 +pad=1 +activation=leaky + +[convolutional] +batch_normalize=1 +filters=512 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=255 +activation=linear + + + +[yolo] +mask = 3,4,5 +anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 +classes=80 +num=6 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 + +[route] +layers = -4 + +[convolutional] +batch_normalize=1 +filters=128 +size=1 +stride=1 +pad=1 +activation=leaky + +[upsample] +stride=2 + +[route] +layers = -1, 8 + +[convolutional] +batch_normalize=1 +filters=256 +size=3 +stride=1 +pad=1 +activation=leaky + +[convolutional] +size=1 +stride=1 +pad=1 +filters=255 +activation=linear + +[yolo] +mask = 0,1,2 +anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 +classes=80 +num=6 +jitter=.3 +ignore_thresh = .7 +truth_thresh = 1 +random=1 From 44b2bce3ff98b407e91bb2abfdb308b683913624 Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Thu, 5 Dec 2019 20:43:48 +0000 Subject: [PATCH 023/228] Yolo3_tiny CUDNN works, TensorRT doesn't. Add n_masks to Yolo layer. Signed-off-by: Micaela Verucchi --- include/tkDNN/Layer.h | 4 +-- include/tkDNN/pluginsRT/YoloRT.h | 22 +++++++------- src/NetworkRT.cpp | 50 ++++++++++++++++++++++++++------ src/Yolo.cpp | 15 +++++----- tests/yolo3_tiny/yolo3_tiny.cpp | 22 +++++++------- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 31dc4d2..d001497 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -379,11 +379,11 @@ public: int sort_class; }; - Yolo(Network *net, int classes, int num, std::string fname_weights); + Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks=3); virtual ~Yolo(); virtual layerType_t getLayerType() { return LAYER_YOLO; }; - int classes, num; + int classes, num, n_masks; dnnType *mask_h, *mask_d; //anchors dnnType *bias_h, *bias_d; //anchors std::vector classesNames; diff --git a/include/tkDNN/pluginsRT/YoloRT.h b/include/tkDNN/pluginsRT/YoloRT.h index dab7c18..a8b3b7d 100644 --- a/include/tkDNN/pluginsRT/YoloRT.h +++ b/include/tkDNN/pluginsRT/YoloRT.h @@ -8,16 +8,17 @@ class YoloRT : public IPlugin { public: - YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr) { + YoloRT(int classes, int num, tk::dnn::Yolo *yolo = nullptr, int n_masks=3) { this->classes = classes; this->num = num; + this->n_masks = n_masks; - mask = new dnnType[num]; - bias = new dnnType[num*3*2]; + mask = new dnnType[n_masks]; + bias = new dnnType[num*n_masks*2]; if(yolo != nullptr) { - memcpy(mask, yolo->mask_h, sizeof(dnnType)*num); - memcpy(bias, yolo->bias_h, sizeof(dnnType)*num*3*2); + memcpy(mask, yolo->mask_h, sizeof(dnnType)*n_masks); + memcpy(bias, yolo->bias_h, sizeof(dnnType)*num*n_masks*2); classesNames = yolo->classesNames; } } @@ -60,7 +61,7 @@ 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 < num; ++n){ + 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); @@ -75,19 +76,20 @@ public: virtual size_t getSerializationSize() override { - return 5*sizeof(int) + num*sizeof(dnnType) + num*3*2*sizeof(dnnType) + YOLORT_CLASSNAME_W*classes*sizeof(char); + return 6*sizeof(int) + 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(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 classesNames; dnnType *mask; diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 7cfa816..4500be5 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -15,9 +15,9 @@ using namespace nvinfer1; // Logger for info/warning/errors class Logger : public ILogger { void log(Severity severity, const char* msg) override { -#ifdef DEBUG +// #ifdef DEBUG std::cout <<"TENSORRT LOG: "<< msg << std::endl; -#endif +// #endif } } loggerRT; @@ -253,14 +253,18 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { lRTconv->setStride(DimsHW{l->strideH, l->strideW}); lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); lRT = (ILayer*) lRTconv; + } + checkNULL(lRT); if(l->batchnorm) { Weights power{dtRT, power_b, l->outputs}; Weights shift{dtRT, mean_b, l->outputs}; Weights scale{dtRT, variance_b, l->outputs}; + std::cout<getNbOutputs()<addScale(*lRT->getOutput(0), ScaleMode::kCHANNEL, shift, scale, power); + checkNULL(lRT2); Weights shift2{dtRT, bias_b, l->outputs}; @@ -277,7 +281,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { std::cout<<"convert Pooling\n"; - // printf("%d %d\n", l->winW, l->winH); + printf("%d %d %d %d %d %d %d %d %d %d %d %d (layer)\n", l->input_dim.h, l->input_dim.w, l->output_dim.h, l->output_dim.w, l->winW, l->winH, l->strideH, l->strideW, l->paddingH, l->paddingW, l->pool_mode, tkdnnPoolingMode_t::POOLING_MAX) ; PoolingType ptype; if(l->pool_mode == tkdnnPoolingMode_t::POOLING_MAX) ptype = PoolingType::kMAX; @@ -287,8 +291,27 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { IPoolingLayer *lRT = networkRT->addPooling(*input, ptype, DimsHW{l->winH, l->winW}); checkNULL(lRT); - lRT->setStride(DimsHW{l->strideH, l->strideW}); - lRT->setPadding(DimsHW{l->paddingH, l->paddingW}); + + // if (l->input_dim.h == 13 && l->output_dim.h == 13) + // { + // lRT->setPadding(DimsHW{7, 7}); + // lRT->setStride(DimsHW{2, 2}); + // } + // else + // { + lRT->setPadding(DimsHW{l->paddingH, l->paddingW}); + lRT->setStride(DimsHW{l->strideH, l->strideW}); + // } + + // IResizeLayer *lRT = networkRT->addResize(*lRT->getOutput(0)); + // checkNULL(lRT); + // lRT->setOutputDimensions(l->output_dim); + + ITensor *t = lRT->getOutput(0); + for(int j=0; jgetDimensions().nbDims; j++) { + std::cout<getDimensions().d[j]<<" "; + } + std::cout<<" (TensorRT)\n"; return lRT; } @@ -324,12 +347,19 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Softmax *l) { } ILayer* NetworkRT::convert_layer(ITensor *input, Route *l) { - //std::cout<<"convert route\n"; + std::cout<<"convert route\n"; + + ITensor **tens = new ITensor*[l->layers_n]; for(int i=0; ilayers_n; i++) { tens[i] = tensors[l->layers[i]]; + for(int j=0; jgetDimensions().nbDims; j++) { + std::cout<getDimensions().d[j]<<" "; + } + std::cout<<"\n"; } + IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n); //IPlugin *plugin = new RouteRT(); //IPluginLayer *lRT = networkRT->addPlugin(tens, l->layers_n, *plugin); @@ -474,13 +504,15 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa if(name.find("Yolo") == 0) { YoloRT *r = new YoloRT(readBUF(buf), //classes - readBUF(buf)); //num + readBUF(buf), //num + nullptr, + readBUF(buf)); //n_masks r->c = readBUF(buf); r->h = readBUF(buf); r->w = readBUF(buf); - for(int i=0; inum; i++) + for(int i=0; in_masks; i++) r->mask[i] = readBUF(buf); - for(int i=0; i<3*2*r->num; i++) + for(int i=0; in_masks*2*r->num; i++) r->bias[i] = readBUF(buf); // save classes names diff --git a/src/Yolo.cpp b/src/Yolo.cpp index e01ed57..ae4694c 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -11,19 +11,20 @@ namespace tk { namespace dnn { -Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights) : +Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_masks) : Layer(net) { this->classes = classes; - this->num = 3; + this->num = num; + this->n_masks = n_masks; // load anchors if(fname_weights != "") { int seek = 0; - readBinaryFile(fname_weights, 3, &mask_h, &mask_d, seek); - seek += 3; - readBinaryFile(fname_weights, 3*num*2, &bias_h, &bias_d, seek); - for(int i=0; i<3*num*2; i++) + readBinaryFile(fname_weights, n_masks, &mask_h, &mask_d, seek); + seek += n_masks; + readBinaryFile(fname_weights, n_masks*num*2, &bias_h, &bias_d, seek); + for(int i=0; ioutput_dim.print(); + + dnnType *out, *out_h; + int odim = outs[i]->output_dim.tot(); + readBinaryFile(output_bin[i], odim, &out_h, &out); + // std::cout<<"OUTPUT BIN:\n"; + // printDeviceVector(odim, cudnn_out, true); + // std::cout<<"FILE BIN:\n"; + // printDeviceVector(odim, out, true); + + dnnType *cudnn_out, *rt_out; + cudnn_out = outs[i]->dstData; + + std::cout << "CUDNN vs correct"; + checkResult(odim, cudnn_out, out); + + /* std::cout << "TRT vs correct"; + checkResult(odim, rt_out, out); + std::cout << "CUDNN vs TRT "; + checkResult(odim, cudnn_out, rt_out);*/ + } + return 0; +} From e99b353d8bc2670e1f0a7aee1e9c6242192a99ae Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Thu, 19 Dec 2019 14:47:57 +0100 Subject: [PATCH 026/228] Fix the inference operation of the deformable convolutional layer. This commit removes the malloc operation in the inference method and adds the sigmoid kernel. Signed-off-by: Davide Sapienza --- include/tkDNN/Layer.h | 5 + include/tkDNN/kernels.h | 1 + src/DeformConv2d.cpp | 156 +++++++++--------------------- src/kernels/activation_sigmoid.cu | 31 ++++++ src/kernels/deformable_conv.cu | 67 +++---------- 5 files changed, 97 insertions(+), 163 deletions(-) create mode 100644 src/kernels/activation_sigmoid.cu diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 8c501f4..188cffb 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -219,7 +219,12 @@ public: int kernelH, kernelW, strideH, strideW, paddingH, paddingW; protected: + dnnType *ones_d1; + dnnType *ones_d2; cudnnTensorDescriptor_t biasTensorDesc; + int chunk_dim; + dnnType *offset, *mask; + dnnType *output_conv; void initCUDNN(); diff --git a/include/tkDNN/kernels.h b/include/tkDNN/kernels.h index dfff6e3..fa46efb 100644 --- a/include/tkDNN/kernels.h +++ b/include/tkDNN/kernels.h @@ -6,6 +6,7 @@ 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 fill(dnnType* data, int size, dnnType val, cudaStream_t stream = cudaStream_t(0)); diff --git a/src/DeformConv2d.cpp b/src/DeformConv2d.cpp index f135b40..712419d 100644 --- a/src/DeformConv2d.cpp +++ b/src/DeformConv2d.cpp @@ -14,9 +14,36 @@ void DeformConv2d::initCUDNN() { net->tensorFormat, net->dataType, 1, output_dim.c, 1, 1) ); - checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, + checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, net->tensorFormat, net->dataType, output_dim.n, output_dim.c, output_dim.h, output_dim.w)); + const int height_ones = (preconv->input_dim.h + 2 * this->paddingH - (1 * (this->kernelH - 1) + 1)) / this->strideH + 1; + const int width_ones = (preconv->input_dim.w + 2 * this->paddingW - (1 * (this->kernelW - 1) + 1)) / this->strideW + 1; + 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"; + chunk_dim = dst_dim/3; + checkCuda(cudaMalloc(&offset, 2*chunk_dim*sizeof(dnnType))); + checkCuda(cudaMalloc(&mask, chunk_dim*sizeof(dnnType))); + + // kernel ones + + cudaMallocHost(&ones_d1, (height_ones*width_ones)*sizeof(dnnType)); + float aus1[height_ones*width_ones]; + for(int i=0; iinfer(dim, srcData); - dim = preconv->output_dim; - - //split to chank - dnnType *offset, *mask; - int dst_dim = dim.tot(); - if (dst_dim % 3 != 0 ) - std::cout<<"take attention\n\n"; - int chunk_dim = dst_dim/3; - checkCuda(cudaMalloc(&offset, 2*chunk_dim*sizeof(dnnType))); - checkCuda(cudaMalloc(&mask, chunk_dim*sizeof(dnnType))); - cudaDeviceSynchronize(); - - Conv2dToChunk(chunk_dim, srcData, offset, mask); + // conv2d + output_conv = preconv->infer(dim, srcData); + // 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 - dnnType *vec; - vec = new dnnType[chunk_dim]; - cudaDeviceSynchronize(); - cudaMemcpy(vec, mask, chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToHost); - cudaDeviceSynchronize(); - for(int i=0; iinput_dim.h + 2 * this->paddingH - (1 * (this->kernelH - 1) + 1)) / this->strideH + 1; - const int width_ones = (preconv->input_dim.w + 2 * this->paddingW - (1 * (this->kernelW - 1) + 1)) / this->strideW + 1; - const int dim_ones = preconv->input_dim.c * this->kernelH * this->kernelW * 1 * height_ones * width_ones; - - // kernel ones - dnnType *ones_d1; - cudaMallocHost(&ones_d1, (height_ones*width_ones)*sizeof(dnnType)); - float aus1[height_ones*width_ones]; - for(int i=0; idata_d, + // deformable convolution + dcn_v2_cuda_forward(srcData, this->data_d, this->bias2_d, ones_d1, offset, mask, dstData, ones_d2, @@ -148,44 +107,18 @@ dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) { this->deformableGroup, 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, - dst_dim); - - cudaFree(offset); - cudaFree(mask); - cudaFree(input); - cudaFreeHost(ones_d1); - cudaFreeHost(ones_d2); - - - // dnnType *aus3; - // cudaMallocHost(&aus3, 256*7*7*sizeof(dnnType)); - // cudaMemcpy(aus3, dstData, (256*7*7)*sizeof(dnnType), cudaMemcpyDeviceToHost); - // checkCuda(cudaDeviceSynchronize()); - // std::cout<<"OutDim:\n"; - // this->output_dim.print(); - // std::cout<<"\n\n\nprint dstData: \n"; - // for (int i = 0 ; i < 256*7*7; i++){ - // if(i==294) - // std::cout<<"\n\n\n"; - // std::cout<cudnnHandle, &alpha, biasTensorDesc, bias_d, &beta, dstTensorDesc, dstData) ); } else { - std::cout<<"LOL\n"; alpha = dnnType(1); beta = dnnType(0); checkCUDNN( cudnnBatchNormalizationForwardInference(net->cudnnHandle, @@ -195,9 +128,8 @@ dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) { scales_d, bias_d, mean_d, variance_d, CUDNN_BN_MIN_EPSILON) ); } + //update data dimensions - std::cout<<"dstData BN:\n"; - printDeviceVector(64, dstData); dim = output_dim; return dstData; } diff --git a/src/kernels/activation_sigmoid.cu b/src/kernels/activation_sigmoid.cu new file mode 100644 index 0000000..ba6c997 --- /dev/null +++ b/src/kernels/activation_sigmoid.cu @@ -0,0 +1,31 @@ +#include "kernels.h" + +__device__ +__forceinline__ +double sigmoid (double a) +{ + return 1.0 / (1.0 + exp (-a)); +} + + +__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]); + } + } + + +/** + ELU activation function +*/ +void activationSIGMOIDForward(dnnType* srcData, dnnType* dstData, int size, cudaStream_t stream) +{ + int blocks = (size+255)/256; + int threads = 256; + + activation_sigmoid<<>>(srcData, dstData, size); +} \ No newline at end of file diff --git a/src/kernels/deformable_conv.cu b/src/kernels/deformable_conv.cu index 71efb0d..cb9ded0 100644 --- a/src/kernels/deformable_conv.cu +++ b/src/kernels/deformable_conv.cu @@ -149,10 +149,8 @@ void dcn_v2_cuda_forward(float *input, float *weight, const int deformable_group, 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) -{ - checkCuda(cudaDeviceSynchronize()); - cudaError_t cudaStat; + const int chunk_dim, cudaStream_t stream) +{ cublasStatus_t stat; cublasHandle_t handle; stat = cublasCreate(&handle); @@ -160,83 +158,50 @@ void dcn_v2_cuda_forward(float *input, float *weight, printf ("CUBLAS initialization failed\n"); return; } - checkCuda(cudaDeviceSynchronize()); - - const int batch = in_n; + const int channels = in_c; const int height = in_h; const int width = in_w; + const int channels_out = out_c; - const int channels_kernel = in_c; - const int kernel_h_ = kernel_h; - const int kernel_w_ = kernel_w; const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1; const int width_out = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1; - - float *input_n; - cudaMalloc(&input_n, (in_n*in_c*in_h*in_w)*sizeof(float)); - cudaMemcpy(input_n, input, (in_n*in_c*in_h*in_w)*sizeof(float), cudaMemcpyDeviceToDevice); - checkCuda(cudaDeviceSynchronize()); - - float *offset_n; - cudaMalloc(&offset_n, ((dst_dim/3)*2)*sizeof(float)); - cudaMemcpy(offset_n, offset, ((dst_dim/3)*2)*sizeof(float), cudaMemcpyDeviceToDevice); - checkCuda(cudaDeviceSynchronize()); - - float *mask_n; - cudaMalloc(&mask_n, (dst_dim/3)*sizeof(float)); - cudaMemcpy(mask_n, mask, (dst_dim/3)*sizeof(float), cudaMemcpyDeviceToDevice); - checkCuda(cudaDeviceSynchronize()); - - float *output_n; - checkCuda(cudaMalloc(&output_n, (channels_out*height_out*width_out)*sizeof(float))); - checkCuda(cudaDeviceSynchronize()); - long m_ = channels_out; - long n_ = height_out * width_out; - long k_ = 1; + long m = channels_out; + long n = height_out * width_out; + long k = 1; float alpha = 1.0; float beta = 0.0; - checkCuda(cudaDeviceSynchronize()); + stat = cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_N, - n_, m_, k_, &alpha, - ones, k_, bias, k_, - &beta, output_n, n_); + n, m, k, &alpha, + ones, k, bias, k, + &beta, output, n); if (stat != CUBLAS_STATUS_SUCCESS) { printf ("CUBLAS initialization failed\n"); return ; } - checkCuda(cudaDeviceSynchronize()); - modulated_deformable_im2col_cuda(stream, - input_n, offset_n, - mask_n, + 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); - checkCuda(cudaDeviceSynchronize()); - + //(k * m) x (m * n) // Y = WC - long m = channels_out; - long n = height_out * width_out; - long k = channels * kernel_h * kernel_w; - - alpha = 1.0; + k = channels * kernel_h * kernel_w; beta = 1.0; stat = cublasSgemm(handle, CUBLAS_OP_N, CUBLAS_OP_N, n, m, k, &alpha, columns, n, weight, k, - &beta, output_n, n); + &beta, output, n); - cudaMemcpy(output, output_n, (n*m)*sizeof(float), cudaMemcpyDeviceToDevice); - checkCuda(cudaDeviceSynchronize()); - if (stat != CUBLAS_STATUS_SUCCESS) { printf ("CUBLAS initialization failed\n"); return ; From d889ed385d55ec433468a2e49bcda0a6e67fdcf3 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Fri, 20 Dec 2019 11:05:03 +0100 Subject: [PATCH 027/228] CenterNet TensorRT works. TensorRT serialization not yet implemented Signed-oof-by: Davide Sapienza --- include/tkDNN/Layer.h | 13 ++-- include/tkDNN/NetworkRT.h | 2 + include/tkDNN/pluginsRT/DeformableConvRT.h | 80 ++++++++++++++++++++++ src/Conv2d.cpp | 4 +- src/DeformConv2d.cpp | 16 ++--- src/Layer.cpp | 4 +- src/LayerWgs.cpp | 4 +- src/NetworkRT.cpp | 53 +++++++++++++- tests/resnet101_cnet/resnet101_cnet.cpp | 26 +++---- 9 files changed, 167 insertions(+), 35 deletions(-) create mode 100644 include/tkDNN/pluginsRT/DeformableConvRT.h diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 188cffb..a6c639b 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -32,7 +32,7 @@ enum layerType_t { class Layer { public: - Layer(Network *net); + Layer(Network *net, bool final = false); virtual ~Layer(); virtual layerType_t getLayerType() = 0; @@ -43,6 +43,7 @@ public: dataDim_t input_dim, output_dim; dnnType *dstData; //where results will be putted + bool final; //if the layer is the final one std::string getLayerName() { layerType_t type = getLayerType(); @@ -80,7 +81,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); + std::string fname_weights, bool batchnorm = false, bool additional_bias = false, bool final = false); virtual ~LayerWgs(); int inputs, outputs; @@ -160,7 +161,7 @@ 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); + std::string fname_weights, bool batchnorm = false, bool deConv = false, bool final = false); virtual ~Conv2d(); virtual layerType_t getLayerType() { return LAYER_CONV2D; }; @@ -217,15 +218,15 @@ public: int out_ch; int deformableGroup; int kernelH, kernelW, strideH, strideW, paddingH, paddingW; -protected: - dnnType *ones_d1; dnnType *ones_d2; - cudnnTensorDescriptor_t biasTensorDesc; int chunk_dim; dnnType *offset, *mask; dnnType *output_conv; +protected: + + cudnnTensorDescriptor_t biasTensorDesc; void initCUDNN(); }; diff --git a/include/tkDNN/NetworkRT.h b/include/tkDNN/NetworkRT.h index d30da03..590b323 100644 --- a/include/tkDNN/NetworkRT.h +++ b/include/tkDNN/NetworkRT.h @@ -31,6 +31,7 @@ using namespace nvinfer1; #include "pluginsRT/YoloRT.h" #include "pluginsRT/UpsampleRT.h" //#include "pluginsRT/Int8Calibrator.h" +#include "pluginsRT/DeformableConvRT.h" class PluginFactory : IPluginFactory { @@ -85,6 +86,7 @@ public: nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Shortcut *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Yolo *l); nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, Upsample *l); + nvinfer1::ILayer* convert_layer(nvinfer1::ITensor *input, DeformConv2d *l); bool serialize(const char *filename); bool deserialize(const char *filename); diff --git a/include/tkDNN/pluginsRT/DeformableConvRT.h b/include/tkDNN/pluginsRT/DeformableConvRT.h new file mode 100644 index 0000000..6a85538 --- /dev/null +++ b/include/tkDNN/pluginsRT/DeformableConvRT.h @@ -0,0 +1,80 @@ +#include +#include "../kernels.h" + + +class DeformableConvRT : public IPlugin { + + + +public: + DeformableConvRT(tk::dnn::DeformConv2d *deformable) { + this->defRT = deformable; + } + + ~DeformableConvRT(){ + + } + + int getNbOutputs() const override { + return 1; + } + + Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override { + 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 { + } + + 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(inputs[0]); + dnnType *output_conv = (dnnType*)reinterpret_cast(inputs[1]); + + // split conv2d outputs into offset to mask + checkCuda(cudaMemcpy(defRT->offset, defRT->output_conv, 2*defRT->chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + checkCuda(cudaMemcpy(defRT->mask, defRT->output_conv + 2*defRT->chunk_dim, defRT->chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + // kernel sigmoide + activationSIGMOIDForward(defRT->mask, defRT->mask, defRT->chunk_dim); + + // deformable convolution + dcn_v2_cuda_forward(srcData, defRT->data_d, + defRT->bias2_d, defRT->ones_d1, + defRT->offset, defRT->mask, + reinterpret_cast(outputs[0]), defRT->ones_d2, + defRT->kernelH, defRT->kernelW, + defRT->strideH, defRT->strideW, + defRT->paddingH, defRT->paddingW, + 1, 1, + defRT->deformableGroup, + defRT->preconv->input_dim.n, defRT->preconv->input_dim.c, defRT->preconv->input_dim.h, defRT->preconv->input_dim.w, + defRT->output_dim.n, defRT->output_dim.c, defRT->output_dim.h, defRT->output_dim.w, + defRT->chunk_dim); + + return 0; + } + + + virtual size_t getSerializationSize() override { + return 0; + } + + virtual void serialize(void* buffer) override { + char *buf = reinterpret_cast(buffer); + } + + int size; + tk::dnn::DeformConv2d *defRT; +}; diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index 05fec83..b8296ac 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -119,10 +119,10 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) { 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) : + std::string fname_weights, bool batchnorm, bool deConv, bool final) : LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1, - fname_weights, batchnorm) { + fname_weights, batchnorm, false, final) { this->kernelH = kernelH; this->kernelW = kernelW; diff --git a/src/DeformConv2d.cpp b/src/DeformConv2d.cpp index 712419d..3d1fad2 100644 --- a/src/DeformConv2d.cpp +++ b/src/DeformConv2d.cpp @@ -25,25 +25,23 @@ void DeformConv2d::initCUDNN() { if (dst_dim % 3 != 0 ) std::cout<<"take attention\n\n"; chunk_dim = dst_dim/3; - checkCuda(cudaMalloc(&offset, 2*chunk_dim*sizeof(dnnType))); - checkCuda(cudaMalloc(&mask, chunk_dim*sizeof(dnnType))); + checkCuda( cudaMalloc(&offset, 2*chunk_dim*sizeof(dnnType))); + checkCuda( cudaMalloc(&mask, chunk_dim*sizeof(dnnType))); // kernel ones - cudaMallocHost(&ones_d1, (height_ones*width_ones)*sizeof(dnnType)); + checkCuda( cudaMalloc(&ones_d1, (height_ones*width_ones)*sizeof(dnnType)) ); float aus1[height_ones*width_ones]; for(int i=0; inet = net; - + this->final = final; if(net != nullptr) { this->input_dim = net->getOutputDim(); this->output_dim = input_dim; diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index 0f623c2..2f7c7fc 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -8,12 +8,12 @@ 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) : Layer(net) { + std::string fname_weights, bool batchnorm, bool additional_bias, bool final) : Layer(net, final) { this->inputs = inputs; this->outputs = outputs; this->weights_path = std::string(fname_weights); - + std::cout<<"Reading weights: I="<dontLoadWeights); diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 4500be5..884a4a3 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -75,7 +75,7 @@ NetworkRT::NetworkRT(Network *net, const char *name) { input = Ilay->getOutput(0); input->setName( (l->getLayerName() + std::to_string(i) + "_out").c_str() ); - if(l->getLayerType() == LAYER_YOLO) + if(l->getLayerType() == LAYER_YOLO || l->final) networkRT->markOutput(*input); tensors[l] = input; } @@ -182,6 +182,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Layer *l) { return convert_layer(input, (Yolo*) l); if(type == LAYER_UPSAMPLE) return convert_layer(input, (Upsample*) l); + if(type == LAYER_DEFORMCONV2D) + return convert_layer(input, (DeformConv2d*) l); std::cout<getLayerName()<<"\n"; FatalError("Layer not implemented in tensorRT"); @@ -254,6 +256,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { lRTconv->setPadding(DimsHW{l->paddingH, l->paddingW}); lRT = (ILayer*) lRTconv; + Dims d = lRTconv->getOutput(0)->getDimensions(); + std::cout<<"DECONV: "<preconv); + + ITensor **inputs = new ITensor*[2]; + inputs[0] = input; + inputs[1] = preconv->getOutput(0); + + //std::cout<<"New plugin DEFORMABLE\n"; + IPlugin *plugin = new DeformableConvRT(l); + IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); + checkNULL(lRT); + + // batchnorm + void *bias_b, *power_b, *mean_b, *variance_b, *scales_b; + if(dtRT == DataType::kHALF) { + bias_b = l->bias16_h; + power_b = l->power16_h; + mean_b = l->mean16_h; + variance_b = l->variance16_h; + scales_b = l->scales16_h; + } else { + bias_b = l->bias_h; + power_b = l->power_h; + mean_b = l->mean_h; + variance_b = l->variance_h; + scales_b = l->scales_h; + } + + Weights power{dtRT, power_b, l->outputs}; + Weights shift{dtRT, mean_b, l->outputs}; + Weights scale{dtRT, variance_b, l->outputs}; + std::cout<getNbOutputs()<addScale(*lRT->getOutput(0), ScaleMode::kCHANNEL, + shift, scale, power); + + checkNULL(lRT2); + + Weights shift2{dtRT, bias_b, l->outputs}; + Weights scale2{dtRT, scales_b, l->outputs}; + IScaleLayer *lRT3 = networkRT->addScale(*lRT2->getOutput(0), ScaleMode::kCHANNEL, + shift2, scale2, power); + checkNULL(lRT3); + + return lRT3; +} + bool NetworkRT::serialize(const char *filename) { std::ofstream p(filename); diff --git a/tests/resnet101_cnet/resnet101_cnet.cpp b/tests/resnet101_cnet/resnet101_cnet.cpp index 33d60b8..c89591a 100644 --- a/tests/resnet101_cnet/resnet101_cnet.cpp +++ b/tests/resnet101_cnet/resnet101_cnet.cpp @@ -172,9 +172,9 @@ const char *reg_conv2_bin = "../tests/resnet101_cnet/layers/reg-2.bin"; const char *fc_bin = "../tests/resnet101_cnet/layers/fc.bin"; const char *output_bin[]={ -"../tests/resnet101_cnet/debug/hm.bin", -"../tests/resnet101_cnet/debug/wh.bin", -"../tests/resnet101_cnet/debug/reg.bin"}; + "../tests/resnet101_cnet/debug/hm.bin", + "../tests/resnet101_cnet/debug/wh.bin", + "../tests/resnet101_cnet/debug/reg.bin"}; int main() { @@ -317,17 +317,17 @@ int main() tk::dnn::Layer *route_1_0_layers[1] = { layer2_deconv1_relu }; tk::dnn::Conv2d *hm_conv1 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, hm_conv1_bin, false); tk::dnn::Activation *hm_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d *hm = new tk::dnn::Conv2d(&net, 80, 1, 1, 1, 1, 0, 0, hm_conv2_bin, false); + tk::dnn::Conv2d *hm = new tk::dnn::Conv2d(&net, 80, 1, 1, 1, 1, 0, 0, hm_conv2_bin, false, false, true); tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); tk::dnn::Conv2d *wh_conv1 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, wh_conv1_bin, false); tk::dnn::Activation *wh_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d *wh = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, wh_conv2_bin, false); + tk::dnn::Conv2d *wh = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, wh_conv2_bin, false, false, true); tk::dnn::Route *route_2_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); tk::dnn::Conv2d *reg_conv1 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, reg_conv1_bin, false); tk::dnn::Activation *reg_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d *reg = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, reg_conv2_bin, false); + tk::dnn::Conv2d *reg = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, reg_conv2_bin, false, false, true); // Load input dnnType *data; @@ -339,7 +339,7 @@ int main() net.print(); //convert network to tensorRT -// tk::dnn::NetworkRT netRT(&net, "resnet101_cnet.rt"); + tk::dnn::NetworkRT netRT(&net, "resnet101_cnet.rt"); tk::dnn::dataDim_t dim1 = dim; //input dim @@ -354,7 +354,7 @@ int main() // printDeviceVector(64, cudnn_out, true); -/* tk::dnn::dataDim_t dim2 = dim; + tk::dnn::dataDim_t dim2 = dim; printCenteredTitle(" TENSORRT inference ", '=', 30); { dim2.print(); @@ -363,10 +363,9 @@ int main() TIMER_STOP dim2.print(); } - rt_out = (dnnType *)netRT.buffersRT[1]; -*/ - tk::dnn::Conv2d *outs[3] = { hm, wh, reg }; + tk::dnn::Layer *outs[3] = { hm, wh, reg }; + for(int i=0; i<3; i++) { printCenteredTitle((std::string(" RESNET CHECK RESULTS ") + std::to_string(i) + " ").c_str(), '=', 30); @@ -382,14 +381,15 @@ int main() dnnType *cudnn_out, *rt_out; cudnn_out = outs[i]->dstData; + rt_out = (dnnType *)netRT.buffersRT[i+1]; std::cout << "CUDNN vs correct"; checkResult(odim, cudnn_out, out); - /* std::cout << "TRT vs correct"; + std::cout << "TRT vs correct"; checkResult(odim, rt_out, out); std::cout << "CUDNN vs TRT "; - checkResult(odim, cudnn_out, rt_out);*/ + checkResult(odim, cudnn_out, rt_out); } return 0; } From 854a4c316a867c019a64027f9a0b42a56e7ab21a Mon Sep 17 00:00:00 2001 From: nvidia Date: Fri, 20 Dec 2019 15:27:41 +0100 Subject: [PATCH 028/228] Add ResizeLayerRT plugin Signed-off-by: nvidia --- demo/demo/demo.cpp | 2 +- include/tkDNN/NetworkRT.h | 1 + include/tkDNN/Yolo3Detection.h | 1 + include/tkDNN/kernels.h | 3 ++ include/tkDNN/pluginsRT/ResizeLayerRT.h | 67 +++++++++++++++++++++++ src/NetworkRT.cpp | 72 ++++++++++++++----------- src/Pooling.cpp | 1 - src/Yolo.cpp | 2 +- src/Yolo3Detection.cpp | 18 ++++--- src/kernels/resize.cu | 46 ++++++++++++++++ tests/yolo3_tiny/yolo3_tiny.cpp | 1 + 11 files changed, 171 insertions(+), 43 deletions(-) create mode 100644 include/tkDNN/pluginsRT/ResizeLayerRT.h create mode 100644 src/kernels/resize.cu diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index ac6c63d..295b2af 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -25,7 +25,7 @@ int main(int argc, char *argv[]) { signal(SIGINT, sig_handler); - char *net = "yolo3_berkeley.rt"; + char *net = "yolo3.rt"; if(argc > 1) net = argv[1]; char *input = "../demo/yolo_test.mp4"; diff --git a/include/tkDNN/NetworkRT.h b/include/tkDNN/NetworkRT.h index d30da03..5cdc34c 100644 --- a/include/tkDNN/NetworkRT.h +++ b/include/tkDNN/NetworkRT.h @@ -30,6 +30,7 @@ using namespace nvinfer1; #include "pluginsRT/ShortcutRT.h" #include "pluginsRT/YoloRT.h" #include "pluginsRT/UpsampleRT.h" +#include "pluginsRT/ResizeLayerRT.h" //#include "pluginsRT/Int8Calibrator.h" class PluginFactory : IPluginFactory diff --git a/include/tkDNN/Yolo3Detection.h b/include/tkDNN/Yolo3Detection.h index 0a7ba25..6c873bc 100644 --- a/include/tkDNN/Yolo3Detection.h +++ b/include/tkDNN/Yolo3Detection.h @@ -33,6 +33,7 @@ class Yolo3Detection { public: int classes = 0; int num = 0; + int n_masks = 0; float thresh = 0.3; cv::Scalar colors[256]; diff --git a/include/tkDNN/kernels.h b/include/tkDNN/kernels.h index dfff6e3..42e464f 100644 --- a/include/tkDNN/kernels.h +++ b/include/tkDNN/kernels.h @@ -9,6 +9,9 @@ void activationLOGISTICForward(dnnType* srcData, dnnType* dstData, int size, cud 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 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, diff --git a/include/tkDNN/pluginsRT/ResizeLayerRT.h b/include/tkDNN/pluginsRT/ResizeLayerRT.h new file mode 100644 index 0000000..ae87dbf --- /dev/null +++ b/include/tkDNN/pluginsRT/ResizeLayerRT.h @@ -0,0 +1,67 @@ +#include +#include "../kernels.h" + +class ResizeLayerRT : public IPlugin { + +public: + ResizeLayerRT(int c, int h, int w) { + o_c = c; + o_h = h; + o_w = w; + } + + ~ResizeLayerRT(){ + } + + int getNbOutputs() const override { + return 1; + } + + Dims getOutputDimensions(int index, const Dims* inputs, int nbInputDims) override { + return DimsCHW{o_c, o_h, o_w}; + } + + void configure(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, int maxBatchSize) override { + i_c = inputDims[0].d[0]; + i_h = inputDims[0].d[1]; + i_w = inputDims[0].d[2]; + } + + 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 { + // printf("%d %d %d %d %d %d\n", i_c, i_w, i_h, o_c, o_w, o_h); + resizeForward((dnnType*)reinterpret_cast(inputs[0]), + reinterpret_cast(outputs[0]), + batchSize, i_c, i_h, i_w, o_c, o_h, o_w, stream); + return 0; + } + + + virtual size_t getSerializationSize() override { + return 6*sizeof(int); + } + + virtual void serialize(void* buffer) override { + char *buf = reinterpret_cast(buffer); + + tk::dnn::writeBUF(buf, o_c); + tk::dnn::writeBUF(buf, o_h); + tk::dnn::writeBUF(buf, o_w); + + tk::dnn::writeBUF(buf, i_c); + tk::dnn::writeBUF(buf, i_h); + tk::dnn::writeBUF(buf, i_w); + } + + int i_c, i_h, i_w, o_c, o_h, o_w; +}; diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 4500be5..e31185a 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -15,9 +15,9 @@ using namespace nvinfer1; // Logger for info/warning/errors class Logger : public ILogger { void log(Severity severity, const char* msg) override { -// #ifdef DEBUG +#ifdef DEBUG std::cout <<"TENSORRT LOG: "<< msg << std::endl; -// #endif +#endif } } loggerRT; @@ -209,8 +209,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Dense *l) { ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { - std::cout<<"convert conv2D\n"; - printf("%d %d %d %d %d\n", l->kernelH, l->kernelW, l->inputs, l->outputs, l->batchnorm); + // std::cout<<"convert conv2D\n"; + // 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; @@ -261,7 +261,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { Weights power{dtRT, power_b, l->outputs}; Weights shift{dtRT, mean_b, l->outputs}; Weights scale{dtRT, variance_b, l->outputs}; - std::cout<getNbOutputs()<getNbOutputs()<addScale(*lRT->getOutput(0), ScaleMode::kCHANNEL, shift, scale, power); @@ -280,8 +280,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Conv2d *l) { } ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { - std::cout<<"convert Pooling\n"; - printf("%d %d %d %d %d %d %d %d %d %d %d %d (layer)\n", l->input_dim.h, l->input_dim.w, l->output_dim.h, l->output_dim.w, l->winW, l->winH, l->strideH, l->strideW, l->paddingH, l->paddingW, l->pool_mode, tkdnnPoolingMode_t::POOLING_MAX) ; + // std::cout<<"convert Pooling\n"; PoolingType ptype; if(l->pool_mode == tkdnnPoolingMode_t::POOLING_MAX) ptype = PoolingType::kMAX; @@ -291,29 +290,28 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { 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}); + - // if (l->input_dim.h == 13 && l->output_dim.h == 13) - // { - // lRT->setPadding(DimsHW{7, 7}); - // lRT->setStride(DimsHW{2, 2}); - // } - // else - // { - lRT->setPadding(DimsHW{l->paddingH, l->paddingW}); - lRT->setStride(DimsHW{l->strideH, l->strideW}); - // } - - // IResizeLayer *lRT = networkRT->addResize(*lRT->getOutput(0)); - // checkNULL(lRT); - // lRT->setOutputDimensions(l->output_dim); - ITensor *t = lRT->getOutput(0); - for(int j=0; jgetDimensions().nbDims; j++) { - std::cout<getDimensions().d[j]<<" "; - } - std::cout<<" (TensorRT)\n"; + // for(int j=0; jgetDimensions().nbDims; j++) { + // std::cout<getDimensions().d[j]<<" "; + // } + // std::cout<<" (TensorRT)\n"; - return lRT; + IPlugin *plugin = new ResizeLayerRT( l->output_dim.c,l->output_dim.h,l->output_dim.w ); + IPluginLayer *lRT1 = networkRT->addPlugin(&t, 1, *plugin); + checkNULL(lRT1); + + // ITensor *t1 = lRT1->getOutput(0); + // for(int j=0; jgetDimensions().nbDims; j++) { + // std::cout<getDimensions().d[j]<<" "; + // } + // std::cout<<" (TensorRT after resize )\n"; + + return lRT1; } ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) { @@ -347,17 +345,17 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Softmax *l) { } ILayer* NetworkRT::convert_layer(ITensor *input, Route *l) { - std::cout<<"convert route\n"; + // std::cout<<"convert route\n"; ITensor **tens = new ITensor*[l->layers_n]; for(int i=0; ilayers_n; i++) { tens[i] = tensors[l->layers[i]]; - for(int j=0; jgetDimensions().nbDims; j++) { - std::cout<getDimensions().d[j]<<" "; - } - std::cout<<"\n"; + // for(int j=0; jgetDimensions().nbDims; j++) { + // std::cout<getDimensions().d[j]<<" "; + // } + // std::cout<<"\n"; } IConcatenationLayer *lRT = networkRT->addConcatenation(tens, l->layers_n); @@ -502,6 +500,16 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa return r; } + if(name.find("Pooling") == 0) { + ResizeLayerRT *r = new ResizeLayerRT(readBUF(buf), //o_c + readBUF(buf), //o_h + readBUF(buf)); //o_w + r->i_c = readBUF(buf); + r->i_h = readBUF(buf); + r->i_w = readBUF(buf); + return r; + } + if(name.find("Yolo") == 0) { YoloRT *r = new YoloRT(readBUF(buf), //classes readBUF(buf), //num diff --git a/src/Pooling.cpp b/src/Pooling.cpp index ce84926..0f3573d 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -53,7 +53,6 @@ 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; diff --git a/src/Yolo.cpp b/src/Yolo.cpp index ae4694c..ca6ebc5 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -130,7 +130,7 @@ int Yolo::computeDetections(Yolo::detection *dets, int &ndets, int netw, int net for (i = 0; i < lw*lh; ++i){ int row = i / lw; int col = i % lw; - for(n = 0; n < num; ++n){ + for(n = 0; n < n_masks; ++n){ int obj_index = entry_index(0, n*lw*lh + i, 4, classes, input_dim, output_dim); float objectness = predictions[obj_index]; if(objectness <= thresh) continue; diff --git a/src/Yolo3Detection.cpp b/src/Yolo3Detection.cpp index ed392f7..aae23b7 100644 --- a/src/Yolo3Detection.cpp +++ b/src/Yolo3Detection.cpp @@ -22,7 +22,8 @@ bool Yolo3Detection::init(std::string tensor_path) { std::cout<<(tensor_path).c_str()<<"\n"; netRT = new tk::dnn::NetworkRT(NULL, (tensor_path).c_str() ); - if(netRT->pluginFactory->n_yolos != 3) { + + if(netRT->pluginFactory->n_yolos < 2 ) { FatalError("this is not yolo3"); } @@ -30,13 +31,14 @@ bool Yolo3Detection::init(std::string tensor_path) { YoloRT *yRT = netRT->pluginFactory->yolos[i]; classes = yRT->classes; num = yRT->num; + n_masks = yRT->n_masks; // make a yolo layer for interpret predictions - yolo[i] = new tk::dnn::Yolo(nullptr, classes, num, ""); // yolo without input and bias - yolo[i]->mask_h = new dnnType[num]; - yolo[i]->bias_h = new dnnType[num*3*2]; - memcpy(yolo[i]->mask_h, yRT->mask, sizeof(dnnType)*num); - memcpy(yolo[i]->bias_h, yRT->bias, sizeof(dnnType)*num*3*2); + 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); yolo[i]->input_dim = yolo[i]->output_dim = tk::dnn::dataDim_t(1, yRT->c, yRT->h, yRT->w); yolo[i]->classesNames = yRT->classesNames; } @@ -84,7 +86,7 @@ void Yolo3Detection::update(cv::Mat &imageORIG) { //DO INFERENCE - dnnType *rt_out[3]; + 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)); @@ -99,7 +101,7 @@ void Yolo3Detection::update(cv::Mat &imageORIG) { TIMER_START // compute dets ndets = 0; - for(int i=0; i<3; i++) { + for(int i=0; ipluginFactory->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); diff --git a/src/kernels/resize.cu b/src/kernels/resize.cu new file mode 100644 index 0000000..f637152 --- /dev/null +++ b/src/kernels/resize.cu @@ -0,0 +1,46 @@ +#include "kernels.h" +#include +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +__global__ void resize_kernel( int i_N,float *x, int i_w, int i_h, int i_c, + int o_w, int o_h, int o_c, int batch, float *out) +{ + int i = (blockIdx.x + blockIdx.y*gridDim.x) * blockDim.x + threadIdx.x; + if(i >= i_N) return; + + int out_index = i; + int out_w = i%o_w; + i = i/o_w; + int out_h = i%o_h; + i = i/o_h; + int out_c = i%o_c; + i = i/o_c; + + //copying last column/last row + int in_index = ((i*i_c + MIN(out_c,i_c-1))*i_h + MIN(out_h,i_h-1))*i_w + MIN(out_w, i_w-1); + out[out_index] = x[in_index]; +} + + +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 ) +{ + int i_size = n*i_c*i_h*i_w; + int o_size = n*o_c*o_h*o_w; + + int blocks = (o_size+255)/256; + int threads = 256; + + if(i_c == o_c && i_h == o_h && i_w == o_w ) + { + checkCuda(cudaMemcpy(dstData, srcData, i_size*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + } + else + { + checkCuda(cudaMemset(dstData, 0, o_size*sizeof(dnnType))); + resize_kernel<<>>(o_size, srcData, i_w, i_h, i_c, o_w, o_h, o_c, n, dstData); + // printDeviceVector(i_size, srcData); + // printDeviceVector(o_size, dstData); + } +} \ No newline at end of file diff --git a/tests/yolo3_tiny/yolo3_tiny.cpp b/tests/yolo3_tiny/yolo3_tiny.cpp index c04b37d..7c8a382 100644 --- a/tests/yolo3_tiny/yolo3_tiny.cpp +++ b/tests/yolo3_tiny/yolo3_tiny.cpp @@ -118,5 +118,6 @@ int main() { std::cout<<"CUDNN vs correct"; checkResult(out_dim, out_data, out); std::cout<<"TRT vs correct"; checkResult(out_dim, out_data2, out); std::cout<<"CUDNN vs TRT "; checkResult(out_dim, out_data, out_data2); + return 0; } From 5272f1cde6c5ac06a786cafac4d04102ea2971ff Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 23 Dec 2019 15:31:13 +0100 Subject: [PATCH 029/228] CenterNet TensorRT serialization works This commit adds the Deformable layer serialization. Signed-oof-by: Davide Sapienza --- include/tkDNN/Layer.h | 2 + include/tkDNN/pluginsRT/DeformableConvRT.h | 153 ++++++++++++++++++--- src/Network.cpp | 1 + src/NetworkRT.cpp | 56 +++++++- 4 files changed, 188 insertions(+), 24 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index a6c639b..f5ac6a7 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -43,6 +43,8 @@ public: dataDim_t input_dim, output_dim; dnnType *dstData; //where results will be putted + + int id = 0; bool final; //if the layer is the final one std::string getLayerName() { diff --git a/include/tkDNN/pluginsRT/DeformableConvRT.h b/include/tkDNN/pluginsRT/DeformableConvRT.h index 6a85538..b236095 100644 --- a/include/tkDNN/pluginsRT/DeformableConvRT.h +++ b/include/tkDNN/pluginsRT/DeformableConvRT.h @@ -7,8 +7,51 @@ class DeformableConvRT : public IPlugin { public: - DeformableConvRT(tk::dnn::DeformConv2d *deformable) { - this->defRT = deformable; + DeformableConvRT(int chunk_dim, int kh, int kw, int sh, int sw, int ph, int pw, + int deformableGroup, int i_n, int i_c, int i_h, int i_w, + 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; + this->sw = sw; + this->ph = ph; + this->pw = pw; + this->deformableGroup = deformableGroup; + this->i_n = i_n; + this->i_c = i_c; + this->i_h = i_h; + this->i_w = i_w; + this->o_n = o_n; + this->o_c = o_c; + this->o_h = o_h; + this->o_w = o_w; + height_ones = (i_h + 2 * ph - (1 * (kh - 1) + 1)) / sh + 1; + width_ones = (i_w + 2 * pw - (1 * (kw - 1) + 1)) / sw + 1; + dim_ones = i_c * kh * kw * 1 * height_ones * width_ones; + std::cout<defRT = deformable; + checkCuda( cudaMemcpy(data_d, deformable->data_d, sizeof(dnnType)*i_c * o_c * kh * kw * 1, cudaMemcpyDeviceToDevice) ); + checkCuda( cudaMemcpy(bias2_d, deformable->bias2_d, sizeof(dnnType)*o_c, cudaMemcpyDeviceToDevice) ); + checkCuda( cudaMemcpy(ones_d1, deformable->ones_d1, sizeof(dnnType)*height_ones*width_ones, cudaMemcpyDeviceToDevice) ); + checkCuda( cudaMemcpy(offset, deformable->offset, sizeof(dnnType)*2*chunk_dim, cudaMemcpyDeviceToDevice) ); + checkCuda( cudaMemcpy(mask, deformable->mask, sizeof(dnnType)*chunk_dim, cudaMemcpyDeviceToDevice) ); + checkCuda( cudaMemcpy(ones_d2, deformable->ones_d2, sizeof(dnnType)*dim_ones, cudaMemcpyDeviceToDevice) ); + } } ~DeformableConvRT(){ @@ -24,6 +67,14 @@ public: } 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]; } int initialize() override { @@ -39,42 +90,108 @@ public: } 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(inputs[0]); dnnType *output_conv = (dnnType*)reinterpret_cast(inputs[1]); // split conv2d outputs into offset to mask - checkCuda(cudaMemcpy(defRT->offset, defRT->output_conv, 2*defRT->chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice)); - checkCuda(cudaMemcpy(defRT->mask, defRT->output_conv + 2*defRT->chunk_dim, defRT->chunk_dim*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + 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(defRT->mask, defRT->mask, defRT->chunk_dim); + activationSIGMOIDForward(mask, mask, chunk_dim); // deformable convolution - dcn_v2_cuda_forward(srcData, defRT->data_d, - defRT->bias2_d, defRT->ones_d1, - defRT->offset, defRT->mask, - reinterpret_cast(outputs[0]), defRT->ones_d2, - defRT->kernelH, defRT->kernelW, - defRT->strideH, defRT->strideW, - defRT->paddingH, defRT->paddingW, + dcn_v2_cuda_forward(srcData, data_d, + bias2_d, ones_d1, + offset, mask, + reinterpret_cast(outputs[0]), ones_d2, + kh, kw, + sh, sw, + ph, pw, 1, 1, - defRT->deformableGroup, - defRT->preconv->input_dim.n, defRT->preconv->input_dim.c, defRT->preconv->input_dim.h, defRT->preconv->input_dim.w, - defRT->output_dim.n, defRT->output_dim.c, defRT->output_dim.h, defRT->output_dim.w, - defRT->chunk_dim); + deformableGroup, + i_n, i_c, i_h, i_w, + o_n, o_c, o_h, o_w, + chunk_dim); return 0; } virtual size_t getSerializationSize() override { - return 0; + return 16 * sizeof(int) + chunk_dim * 3 * sizeof(dnnType) + (i_c * o_c * kh * kw * 1 ) * sizeof(dnnType) + + o_c * sizeof(dnnType) + height_ones * width_ones * sizeof(dnnType) + dim_ones * sizeof(dnnType); } virtual void serialize(void* buffer) override { char *buf = reinterpret_cast(buffer); + tk::dnn::writeBUF(buf, chunk_dim); + tk::dnn::writeBUF(buf, kh); + tk::dnn::writeBUF(buf, kw); + tk::dnn::writeBUF(buf, sh); + tk::dnn::writeBUF(buf, sw); + tk::dnn::writeBUF(buf, ph); + tk::dnn::writeBUF(buf, pw); + tk::dnn::writeBUF(buf, deformableGroup); + tk::dnn::writeBUF(buf, i_n); + tk::dnn::writeBUF(buf, i_c); + tk::dnn::writeBUF(buf, i_h); + tk::dnn::writeBUF(buf, i_w); + tk::dnn::writeBUF(buf, o_n); + tk::dnn::writeBUF(buf, o_c); + tk::dnn::writeBUF(buf, o_h); + tk::dnn::writeBUF(buf, o_w); + dnnType *aus = new dnnType[chunk_dim*2]; + checkCuda( cudaMemcpy(aus, offset, sizeof(dnnType)*2*chunk_dim, cudaMemcpyDeviceToHost) ); + for(int i=0; iid = num_layers; layers[num_layers++] = l; return true; } diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index ed72c89..117121d 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -426,17 +426,21 @@ 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); ITensor **inputs = new ITensor*[2]; inputs[0] = input; inputs[1] = preconv->getOutput(0); - //std::cout<<"New plugin DEFORMABLE\n"; - IPlugin *plugin = new DeformableConvRT(l); - IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); + 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() ); // batchnorm void *bias_b, *power_b, *mean_b, *variance_b, *scales_b; @@ -515,8 +519,9 @@ bool NetworkRT::deserialize(const char *filename) { IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialData, size_t serialLength) { const char * buf = reinterpret_cast(serialData); - + std::string name(layerName); + std::cout<(buf)); //stride r->c = readBUF(buf); @@ -606,6 +610,46 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa return r; } */ + if(name.find("Deformable") == 0) { + DeformableConvRT *r = new DeformableConvRT(readBUF(buf), readBUF(buf), readBUF(buf), + readBUF(buf), readBUF(buf), readBUF(buf), + readBUF(buf), readBUF(buf), + readBUF(buf),readBUF(buf),readBUF(buf),readBUF(buf), + readBUF(buf),readBUF(buf),readBUF(buf),readBUF(buf), + nullptr); + dnnType *aus = new dnnType[r->chunk_dim*2]; + for(int i=0; ichunk_dim*2; i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->offset, aus, sizeof(dnnType)*2*r->chunk_dim, cudaMemcpyHostToDevice) ); + free(aus); + aus = new dnnType[r->chunk_dim]; + for(int i=0; ichunk_dim; i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->mask, aus, sizeof(dnnType)*r->chunk_dim, cudaMemcpyHostToDevice) ); + free(aus); + aus = new dnnType[(r->i_c * r->o_c * r->kh * r->kw * 1 )]; + for(int i=0; i<(r->i_c * r->o_c * r->kh * r->kw * 1 ); i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->data_d, aus, sizeof(dnnType)*(r->i_c * r->o_c * r->kh * r->kw * 1 ), cudaMemcpyHostToDevice) ); + free(aus); + aus = new dnnType[r->o_c]; + for(int i=0; i < r->o_c; i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->bias2_d, aus, sizeof(dnnType)*r->o_c, cudaMemcpyHostToDevice) ); + free(aus); + aus = new dnnType[r->height_ones * r->width_ones]; + for(int i=0; iheight_ones * r->width_ones; i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->ones_d1, aus, sizeof(dnnType)*r->height_ones * r->width_ones, cudaMemcpyHostToDevice) ); + free(aus); + aus = new dnnType[r->dim_ones]; + for(int i=0; idim_ones; i++) + aus[i] = readBUF(buf); + checkCuda( cudaMemcpy(r->ones_d2, aus, sizeof(dnnType)*r->dim_ones, cudaMemcpyHostToDevice) ); + free(aus); + return r; + } + FatalError("Cant deserialize Plugin"); return NULL; } From 7e7f480e2ba1856a9004477a203bdf6ee8274532 Mon Sep 17 00:00:00 2001 From: fbagni Date: Mon, 23 Dec 2019 16:11:41 +0100 Subject: [PATCH 030/228] Yolov3_tiny works on tensorRT Signed-off-by: fbagni --- src/Conv2d.cpp | 4 ++-- src/NetworkRT.cpp | 36 ++++++++++++++---------------------- src/Pooling.cpp | 4 ---- src/Yolo.cpp | 4 ++-- src/kernels/resize.cu | 4 ++-- 5 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index b8296ac..ef73e40 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -17,8 +17,8 @@ void Conv2d::initCUDNN(bool back) { idim = output_dim; odim = input_dim; } - idim.print(); - odim.print(); + //idim.print(); + //odim.print(); checkCUDNN( cudnnCreateFilterDescriptor(&filterDesc) ); checkCUDNN( cudnnCreateConvolutionDescriptor(&convDesc) ); diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index ed72c89..c744b86 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -291,31 +291,23 @@ 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; - IPoolingLayer *lRT = networkRT->addPooling(*input, - ptype, DimsHW{l->winH, l->winW}); + + if(l->input_dim.h % 2 == 1 && l->input_dim.w % 2 == 1) + { + 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); + } + + 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}); - - - ITensor *t = lRT->getOutput(0); - // for(int j=0; jgetDimensions().nbDims; j++) { - // std::cout<getDimensions().d[j]<<" "; - // } - // std::cout<<" (TensorRT)\n"; - - IPlugin *plugin = new ResizeLayerRT( l->output_dim.c,l->output_dim.h,l->output_dim.w ); - IPluginLayer *lRT1 = networkRT->addPlugin(&t, 1, *plugin); - checkNULL(lRT1); - - // ITensor *t1 = lRT1->getOutput(0); - // for(int j=0; jgetDimensions().nbDims; j++) { - // std::cout<getDimensions().d[j]<<" "; - // } - // std::cout<<" (TensorRT after resize )\n"; - - return lRT1; + return lRT; } ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) { @@ -551,7 +543,7 @@ IPlugin* PluginFactory::createPlugin(const char* layerName, const void* serialDa return r; } - if(name.find("Pooling") == 0) { + if(name.find("Resize") == 0) { ResizeLayerRT *r = new ResizeLayerRT(readBUF(buf), //o_c readBUF(buf), //o_h readBUF(buf)); //o_w diff --git a/src/Pooling.cpp b/src/Pooling.cpp index 0f3573d..236adbf 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -25,8 +25,6 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, int h = input_dim.h; int w = input_dim.w; int l = input_dim.l; - - printf("before: %d %d\n", h, w); poolOn3d = false; @@ -64,8 +62,6 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, net->tensorFormat, net->dataType, n, c, h, w) ); - - printf("after: %d %d\n", h, w); output_dim.n = n; output_dim.c = c; diff --git a/src/Yolo.cpp b/src/Yolo.cpp index ca6ebc5..634f5ff 100644 --- a/src/Yolo.cpp +++ b/src/Yolo.cpp @@ -24,8 +24,8 @@ Yolo::Yolo(Network *net, int classes, int num, std::string fname_weights, int n_ readBinaryFile(fname_weights, n_masks, &mask_h, &mask_d, seek); seek += n_masks; readBinaryFile(fname_weights, n_masks*num*2, &bias_h, &bias_d, seek); - for(int i=0; i Date: Wed, 15 Jan 2020 09:55:10 +0100 Subject: [PATCH 031/228] Change opencv funcion call (due to OpenCV 4) Signed-off-by: xavier --- demo/demo/demo.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index ac6c63d..3a9ef6e 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include "Yolo3Detection.h" @@ -46,9 +47,9 @@ int main(int argc, char *argv[]) { 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_FOURCC('M','P','4','V'), 30, cv::Size(w, h)); + 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; From c32a0be257acb29cbe4f4ef20be1bc80027a3475 Mon Sep 17 00:00:00 2001 From: xavier Date: Wed, 15 Jan 2020 18:06:02 +0100 Subject: [PATCH 032/228] Batchnorm eps fix, works on jetpack 4.3 --- README.md | 7 ++++--- include/tkDNN/Layer.h | 2 ++ src/Conv2d.cpp | 2 +- src/LayerWgs.cpp | 2 +- src/Network.cpp | 9 +++++---- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 93a7574..3b16ec3 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@ tkDNN is a Deep Neural Network library built with cuDNN primitives specifically 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 9 -* CUDNN 7.105 -* TENSORRT 4.02 +* CUDA 10.0 +* CUDNN 7.603 +* TENSORRT 6.01 +* OPENCV 4.1 ## Workflow The recommended workflow follow these step: diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index c6bee42..ee73109 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -24,6 +24,8 @@ enum layerType_t { LAYER_YOLO }; +#define TKDNN_BN_MIN_EPSILON 1e-5 + /** Simple layer Father class */ diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index 3dfdce6..b275198 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -117,7 +117,7 @@ dnnType* Conv2d::infer(dataDim_t &dim, dnnType* srcData) { dstTensorDesc, dstData, dstTensorDesc, dstData, biasTensorDesc, //same tensor descriptor as bias scales_d, bias_d, mean_d, variance_d, - CUDNN_BN_MIN_EPSILON); + TKDNN_BN_MIN_EPSILON); } //update data dimensions dim = output_dim; diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index f27da0f..7851164 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -29,7 +29,7 @@ LayerWgs::LayerWgs(Network *net, int inputs, int outputs, seek += outputs; readBinaryFile(weights_path.c_str(), outputs, &variance_h, &variance_d, seek); - float eps = CUDNN_BN_MIN_EPSILON; + float eps = TKDNN_BN_MIN_EPSILON; power_h = new dnnType[outputs]; for(int i=0; i Date: Wed, 15 Jan 2020 18:07:40 +0100 Subject: [PATCH 033/228] support clion --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 446d490..02f2a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ build/ *.h5 *.tar.gz *.weights +.idea/ \ No newline at end of file From da4f24615741b1ab1a44dd550826e8da3ec7648e Mon Sep 17 00:00:00 2001 From: xavier Date: Wed, 15 Jan 2020 21:48:18 +0100 Subject: [PATCH 034/228] add DLA, plugin for shortcut and leaky. new verison 0.4 --- demo/demo/demo.cpp | 7 +++++++ include/tkDNN/Yolo3Detection.h | 3 +++ include/tkDNN/tkdnn.h | 2 +- src/NetworkRT.cpp | 22 ++++++++++++++++++---- src/Yolo3Detection.cpp | 2 ++ 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index 3a9ef6e..ba08caa 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -97,6 +97,13 @@ int main(int argc, char *argv[]) { } std::cout<<"detection end\n"; + + + std::cout< detected; + // keep track of inference times (ms) + std::vector stats; + Yolo3Detection() {} virtual ~Yolo3Detection() {} diff --git a/include/tkDNN/tkdnn.h b/include/tkDNN/tkdnn.h index dde3126..554daa1 100644 --- a/include/tkDNN/tkdnn.h +++ b/include/tkDNN/tkdnn.h @@ -5,4 +5,4 @@ #include "Layer.h" #include "NetworkRT.h" -#define TKDNN_VERSION 300 +#define TKDNN_VERSION 400 diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 7430b6f..d4fdf90 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -35,7 +35,7 @@ NetworkRT::NetworkRT(Network *net, const char *name) { builderRT = createInferBuilder(loggerRT); std::cout<<"Float16 support: "<platformHasFastFp16()<<"\n"; std::cout<<"Int8 support: "<platformHasFastInt8()<<"\n"; - //std::cout<<"DLAs: "<getNbDLACores()<<"\n"; + std::cout<<"DLAs: "<getNbDLACores()<<"\n"; networkRT = builderRT->createNetwork(); if(!fileExist(name)) { @@ -51,7 +51,6 @@ NetworkRT::NetworkRT(Network *net, const char *name) { dtRT = DataType::kHALF; builderRT->setHalf2Mode(true); } - /* if(net->dla && builderRT->getNbDLACores() > 0) { dtRT = DataType::kHALF; builderRT->setFp16Mode(true); @@ -59,7 +58,6 @@ NetworkRT::NetworkRT(Network *net, const char *name) { builderRT->setDefaultDeviceType(DeviceType::kDLA); builderRT->setDLACore(0); } - */ //add input layer ITensor *input = networkRT->addInput("data", DataType::kFLOAT, @@ -276,10 +274,19 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) { if(l->act_mode == ACTIVATION_LEAKY) { //std::cout<<"New plugin LEAKY\n"; + + /* + // plugin version IPlugin *plugin = new ActivationLeakyRT(); IPluginLayer *lRT = networkRT->addPlugin(&input, 1, *plugin); checkNULL(lRT); return lRT; + */ + + IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kLEAKY_RELU); + lRT->setAlpha(0.1); + checkNULL(lRT); + return lRT; } else if(l->act_mode == CUDNN_ACTIVATION_RELU) { IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kRELU); @@ -340,14 +347,21 @@ 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]; + /* + // plugin version 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); + */ + + IElementWiseLayer *lRT = networkRT->addElementWise(*input, *back_tens, ElementWiseOperation::kSUM); + checkNULL(lRT); + return lRT; } diff --git a/src/Yolo3Detection.cpp b/src/Yolo3Detection.cpp index ed392f7..869c792 100644 --- a/src/Yolo3Detection.cpp +++ b/src/Yolo3Detection.cpp @@ -94,6 +94,8 @@ void Yolo3Detection::update(cv::Mat &imageORIG) { netRT->infer(dim, input_d); TIMER_STOP dim.print(); + + stats.push_back(t_ns); } TIMER_START From 2f57ba122201a256e1853382b4aa7543c6faaa7d Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 16 Jan 2020 18:21:34 +0100 Subject: [PATCH 035/228] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3b16ec3..6a0a7ff 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,4 @@ this will genereate a yolo3_berkeley.rt file that can be used for live detection ./yolo3_demo # launch detection on a demo video ./yolo3_demo yolo3_berkeley.rt /dev/video0 # launch detection on device 0 ``` +![Demo preview](https://github.com/ceccocats/tkDNN/releases/download/v0.4/demo.gif) From 146e1442495919de5627b7e4f3ad2adbacd8943c Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 16 Jan 2020 18:24:35 +0100 Subject: [PATCH 036/228] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a0a7ff..3d956a5 100644 --- a/README.md +++ b/README.md @@ -49,4 +49,4 @@ this will genereate a yolo3_berkeley.rt file that can be used for live detection ./yolo3_demo # launch detection on a demo video ./yolo3_demo yolo3_berkeley.rt /dev/video0 # launch detection on device 0 ``` -![Demo preview](https://github.com/ceccocats/tkDNN/releases/download/v0.4/demo.gif) +![demo](https://user-images.githubusercontent.com/11562617/72547657-540e7800-388d-11ea-83c6-49dfea2a0607.gif) From 7838cb49228ae42f8a1df847a06c63024da52b33 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 20 Jan 2020 12:27:49 +0100 Subject: [PATCH 037/228] Pre-process, Process and Post-process work Signed-off-by: Micaela Verucchi Signed-off-by: Davide Sapienza --- CMakeLists.txt | 2 +- demo/demo/demo.cpp | 52 +- include/sorting.h | 19 + include/tkDNN/CenternetDetection.h | 112 ++++ include/tkDNN/Layer.h | 2 +- src/CenternetDetection.cpp | 617 +++++++++++++++++++++ src/NetworkRT.cpp | 7 +- src/Pooling.cpp | 19 +- src/sorting.cu | 104 ++++ tests/resnet101_cnet/resnet101_cnet.cpp | 703 +++++++++++++++++++++++- 10 files changed, 1598 insertions(+), 39 deletions(-) create mode 100644 include/sorting.h create mode 100644 include/tkDNN/CenternetDetection.h create mode 100644 src/CenternetDetection.cpp create mode 100644 src/sorting.cu diff --git a/CMakeLists.txt b/CMakeLists.txt index 8043e4e..021189b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ if(NVINFER STREQUAL "NVINFER-NOTFOUND") endif() # compile -file(GLOB tkdnn_CUSRC "src/kernels/*.cu") +file(GLOB tkdnn_CUSRC "src/kernels/*.cu" "src/*.cu") cuda_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CUDA_INCLUDE_DIRS} ${NVINFER_INCLUDES}) cuda_add_library(kernels SHARED ${tkdnn_CUSRC}) diff --git a/demo/demo/demo.cpp b/demo/demo/demo.cpp index 295b2af..81ca865 100644 --- a/demo/demo/demo.cpp +++ b/demo/demo/demo.cpp @@ -9,7 +9,8 @@ #include #include -#include "Yolo3Detection.h" +// #include "Yolo3Detection.h" +#include "CenternetDetection.h" bool gRun; bool SAVE_RESULT = false; @@ -25,14 +26,15 @@ int main(int argc, char *argv[]) { signal(SIGINT, sig_handler); - char *net = "yolo3.rt"; + 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::Yolo3Detection yolo; + tk::dnn::CenternetDetection yolo; yolo.init(net); gRun = true; @@ -66,29 +68,31 @@ int main(int argc, char *argv[]) { // TODO: async infer yolo.update(dnn_input); - // draw dets - for(int i=0; iclassesNames[b.cl]; - float prob = b.prob; + frame = yolo.draw(dnn_input); + // // draw dets + // for(int i=0; iclassesNames[b.cl]; + // float prob = b.prob; - std::cout< +#include +#include +#include +#include +#include +#include + + +#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); diff --git a/include/tkDNN/CenternetDetection.h b/include/tkDNN/CenternetDetection.h new file mode 100644 index 0000000..8071112 --- /dev/null +++ b/include/tkDNN/CenternetDetection.h @@ -0,0 +1,112 @@ +#include +#include +#include +#include /* srand, rand */ +#include +#include +#include "utils.h" +#include +#include "kernels.h" +#include +#include // std::iota +#include // std::sort + + +#include +#include +#include + +#include "tkdnn.h" +#include "sorting.h" + +namespace tk { namespace dnn { + +/** + * + * @author Francesco Gatti + */ +class CenternetDetection { + + private: + tk::dnn::NetworkRT *netRT = nullptr; + dnnType *input_h, *input, *input_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; + + cv::Vec mean; + cv::Vec stddev; + cv::Mat src; + cv::Mat dst; + //processing + float toll = 0.000001; + int K = 100; + int width = 56; // TODO + + + 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 detected; + // draw + std::vector 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); + +}; + +}} diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index f5ac6a7..470168a 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -292,7 +292,7 @@ public: Pooling(Network *net, int winH, int winW, int strideH, int strideW, int paddingH = 0, int paddingW = 0, - tkdnnPoolingMode_t pool_mode = POOLING_MAX); + tkdnnPoolingMode_t pool_mode = POOLING_MAX, bool final = false); virtual ~Pooling(); virtual layerType_t getLayerType() { return LAYER_POOLING; }; diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp new file mode 100644 index 0000000..59bf827 --- /dev/null +++ b/src/CenternetDetection.cpp @@ -0,0 +1,617 @@ +#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) { + 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_[] = { + "person", "bicycle", "car", "motorcycle", "airplane", + "bus", "train", "truck", "boat", "traffic light", "fire hydrant", + "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", + "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack", + "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", + "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", + "skateboard", "surfboard", "tennis racket", "bottle", "wine glass", + "cup", "fork", "knife", "spoon", "bowl", "banana", "apple", "sandwich", + "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", + "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", + "laptop", "mouse", "remote", "keyboard", "cell phone", "microwave", + "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", + "scissors", "teddy bear", "hair drier", "toothbrush" + }; + 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); + // 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); + dim_wh = tk::dnn::dataDim_t(1, 2, 56, 56, 1); + dim_reg = tk::dnn::dataDim_t(1, 2, 56, 56, 1); + + checkCuda( cudaMalloc(&topk_scores, dim_hm.c * K *sizeof(float)) ); + checkCuda( cudaMalloc(&topk_inds_, dim_hm.c * K *sizeof(int)) ); + checkCuda( cudaMalloc(&topk_ys_, dim_hm.c * K *sizeof(float)) ); + checkCuda( cudaMalloc(&topk_xs_, dim_hm.c * K *sizeof(float)) ); + checkCuda( cudaMalloc(&ids_d, dim_hm.c * dim_hm.h * dim_hm.w*sizeof(int)) ); + checkCuda( cudaMalloc(&ids_2d, dim_hm.c * dim_hm.h * dim_hm.w*sizeof(int)) ); + checkCuda( cudaMallocHost(&ids_, dim_hm.c * dim_hm.h * dim_hm.w*sizeof(int)) ); + checkCuda( cudaMallocHost(&ids_2, dim_hm.c * dim_hm.h * dim_hm.w*sizeof(int)) ); + for(int i =0; iinfer(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(end_t - step_t).count() << " ms" << std::endl; + step_t = end_t; + // ------------------------------------ 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(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 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(end_t - step_t).count() << " ms" << std::endl; + step_t = end_t; + // ----------- nms end + // ----------- topk + + + // thrust::device_vector ids_d; + // int ids[dim_hm.h * dim_hm.w]; + // for(int i=0; i ids2( dim_hm.h * dim_hm.w ); + // for(int i=0; i 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; ioutput_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 "<(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(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(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); + 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(end_t - step_t).count() << " ms" << std::endl; + step_t = end_t; + + // 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(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(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]); + // 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; + 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); + // 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) = ("<(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(end_t - step_t).count() << " ms" << 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); + + + for(int i = 0; i(0,0)=static_cast(trans2.at(0,0))*bbx0[i] + + static_cast(trans2.at(0,1))*bby0[i] + + static_cast(trans2.at(0,2))*1.0; + new_pt1.at(0,1)=static_cast(trans2.at(1,0))*bbx0[i] + + static_cast(trans2.at(1,1))*bby0[i] + + static_cast(trans2.at(1,2))*1.0; + + new_pt2.at(0,0)=static_cast(trans2.at(0,0))*bbx1[i] + + static_cast(trans2.at(0,1))*bby1[i] + + static_cast(trans2.at(0,2))*1.0; + new_pt2.at(0,1)=static_cast(trans2.at(1,0))*bbx1[i] + + static_cast(trans2.at(1,1))*bby1[i] + + static_cast(trans2.at(1,2))*1.0; + + // std::cout<<"\n new: "<(0,0); + target_coords[i*4+1] = new_pt1.at(0,1); + target_coords[i*4+2] = new_pt2.at(0,0); + target_coords[i*4+3] = new_pt2.at(0,1); + // std::cout<(0,0)<<", "<(0,1)<<", "<(0,0)<<", "<(0,1)< thresh){ + std::cout<<"th: "<(end_t - step_t).count() << " ms" << std::endl; + step_t = end_t; + std::cout<<"TOTAL: \n"; + TIMER_STOP +} +}} \ No newline at end of file diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 31d57fc..33e9d62 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -292,7 +292,8 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { 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 % 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) { 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); @@ -324,6 +325,10 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Activation *l) { IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kRELU); checkNULL(lRT); return lRT; + } else if(l->act_mode == CUDNN_ACTIVATION_SIGMOID) { + IActivationLayer *lRT = networkRT->addActivation(*input, ActivationType::kSIGMOID); + checkNULL(lRT); + return lRT; } else { FatalError("this Activation mode is not yet implemented"); diff --git a/src/Pooling.cpp b/src/Pooling.cpp index 236adbf..1ad0664 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -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) : - Layer(net) { + tkdnnPoolingMode_t pool_mode, bool final) : + Layer(net, final) { this->winH = winH; this->winW = winW; @@ -53,10 +53,17 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, //compute w and h as in darknet 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; - + + if(final){ + h = (h + padH - winH)/strideH +1 +1; + w = (w + padW - winW)/strideW +1 +1; + } + else{ + h = (h + padH - winH)/strideH +1; + w = (w + padW - winW)/strideW +1; + } + + // h = (h + winH*this->paddingH)/strideH; // w = (w + winW*this->paddingW)/strideW; diff --git a/src/sorting.cu b/src/sorting.cu new file mode 100644 index 0000000..e007be1 --- /dev/null +++ b/src/sorting.cu @@ -0,0 +1,104 @@ + +#include "sorting.h" + +void sort(dnnType *src_begin, dnnType *src_end, int *idsrc) +{ + thrust::sort_by_key(thrust::device, + src_begin, src_end, idsrc, + thrust::greater()); + + // thrust::stable_sort_by_key(thrust::device, + // src_begin, src_end, idsrc, + // thrust::greater()); +} + +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); + +} + +__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()); + 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) +{ + int blocks = n_classes; + int threads = 1; + + sortAndTopK_kernel<<>>(src_begin, idsrc, topk_scores, topk_inds, topk_ys, topk_xs, size, K); + +} + +struct threshold : public thrust::binary_function +{ + __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); +} + +void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, const int wh, int *clses, int *xs, int *ys){ + thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), clses, thrust::divides()); + thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(wh), ids_begin, thrust::modulus()); + thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(size), ys, thrust::divides()); + thrust::transform(thrust::device, ids_begin, ids_end, thrust::make_constant_iterator(size), xs, thrust::modulus()); + +} + +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)) ); + 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()); + 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()); + 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()); + 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)) ); + 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()); + // x0 + thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx0, thrust::minus()); + // x1 + thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx1, thrust::plus()); + 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()); + 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()); + // y0 + thrust::transform(thrust::device, ys_begin, ys_begin + K, src_out, bby0, thrust::minus()); + // y1 + thrust::transform(thrust::device, ys_begin, ys_begin + K, src_out, bby1, thrust::plus()); + checkCuda( cudaFree(src_out) ); + checkCuda( cudaFree(ids_out) ); +} + diff --git a/tests/resnet101_cnet/resnet101_cnet.cpp b/tests/resnet101_cnet/resnet101_cnet.cpp index c89591a..061e4b6 100644 --- a/tests/resnet101_cnet/resnet101_cnet.cpp +++ b/tests/resnet101_cnet/resnet101_cnet.cpp @@ -1,5 +1,12 @@ #include + +#include "kernels.h" +#include "Yolo3Detection.h" #include "tkdnn.h" +#include +#include // std::iota +#include // std::sort +// #include "utils.h" const char *input_bin = "../tests/resnet101_cnet/debug/input.bin"; const char *conv1_bin = "../tests/resnet101_cnet/layers/conv1.bin"; @@ -172,9 +179,56 @@ const char *reg_conv2_bin = "../tests/resnet101_cnet/layers/reg-2.bin"; const char *fc_bin = "../tests/resnet101_cnet/layers/fc.bin"; const char *output_bin[]={ - "../tests/resnet101_cnet/debug/hm.bin", - "../tests/resnet101_cnet/debug/wh.bin", - "../tests/resnet101_cnet/debug/reg.bin"}; +"../tests/resnet101_cnet/debug/hm.bin", +"../tests/resnet101_cnet/debug/wh.bin", +"../tests/resnet101_cnet/debug/reg.bin"}; + + + +std::vector sort_indexes(const std::vector &v) { + + // initialize original index locations + std::vector idx(v.size()); + iota(idx.begin(), idx.end(), 0); + + // sort indexes based on comparing values in v + sort(idx.begin(), idx.end(), + [&v](size_t i1, size_t i2) {return v[i1] > v[i2];}); + + return idx; +} + +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; +} + +int computeDetections(dnnType *hm_d, dnnType *wh_d, dnnType *reg_d, int hm_dim, int wh_dim, int reg_dim, bool cat_spec_wh, int k){ + // _nms + int kernel = 3; + int pad = (kernel - 1)/2; + std::cout<<"computeDetections\n"; + // dnnType *hmax; + // tk::dnn::Pooling maxpool(&hmax, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX) + // = (dnnType *) + + // net.functional.max_pool2d( + // heat, (kernel, kernel), stride=1, padding=pad) + // keep = (hmax == heat).float() + // return heat * keep +} + +int process(dnnType *hm_d, dnnType *wh_d, dnnType *reg_d, int hm_dim, int wh_dim, int reg_dim){ + std::cout<<"process\n"; + // computeDetections(hm_d, wh_d, reg_d, hm_dim, wh_dim, reg_dim, false, 100); +} int main() { @@ -211,7 +265,6 @@ int main() last = layer1_0_relu; } - // tk::dnn::Activation *last_activation = (tk::dnn::Activation *) net.layers[net.num_layers-1]; // layer 2 int id_layer2_bin = 0; for(int i=0; i<4;i++) @@ -318,6 +371,10 @@ int main() tk::dnn::Conv2d *hm_conv1 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, hm_conv1_bin, false); tk::dnn::Activation *hm_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); tk::dnn::Conv2d *hm = new tk::dnn::Conv2d(&net, 80, 1, 1, 1, 1, 0, 0, hm_conv2_bin, false, false, true); + int kernel = 3; + int pad = (kernel - 1)/2; + tk::dnn::Activation *hm_sig = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_SIGMOID); + tk::dnn::Pooling *hmax = new tk::dnn::Pooling(&net, kernel, kernel, 1, 1, pad, pad, tk::dnn::POOLING_MAX, true); tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); tk::dnn::Conv2d *wh_conv1 = new tk::dnn::Conv2d(&net, 64, 3, 3, 1, 1, 1, 1, wh_conv1_bin, false); @@ -365,7 +422,7 @@ int main() } tk::dnn::Layer *outs[3] = { hm, wh, reg }; - + int out_count = 1; for(int i=0; i<3; i++) { printCenteredTitle((std::string(" RESNET CHECK RESULTS ") + std::to_string(i) + " ").c_str(), '=', 30); @@ -381,7 +438,10 @@ int main() dnnType *cudnn_out, *rt_out; cudnn_out = outs[i]->dstData; - rt_out = (dnnType *)netRT.buffersRT[i+1]; + rt_out = (dnnType *)netRT.buffersRT[i+out_count]; + // there is the maxpool. It isn't an output but it is necessary for the process section + if(i==0) + out_count ++; std::cout << "CUDNN vs correct"; checkResult(odim, cudnn_out, out); @@ -391,5 +451,636 @@ int main() std::cout << "CUDNN vs TRT "; checkResult(odim, cudnn_out, rt_out); } + + TIMER_START + + // -------- transofrm compose + cv::Mat imageOrig = cv::imread("/media/davide/DATA/shared_home/Projects/Professionale/repos/photo_2020-01-14_09-56-07.jpg"); + cv::Mat imageF; + imageOrig.convertTo(imageF, CV_32FC3, 1/255.0); + cv::Mat image; + cv::Size sz = imageF.size(); + std::cout<<"image: "<output_dim.tot()*sizeof(dnnType)) ); + + dnnType *rt_out[4]; + 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]; + + // checkCuda( cudaMemcpy(hm_h, rt_out[0], hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + std::cout<<"hm\n"; + hm->output_dim.print(); + // for(int i=0; ioutput_dim.tot(); i++ ){ + // std::cout<output_dim.tot()); + checkCuda( cudaDeviceSynchronize() ); + + + checkCuda( cudaMemcpy(hm_h, rt_out[0], hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + std::cout<<"hm\n"; + hm->output_dim.print(); + // for(int i=0; ioutput_dim.tot(); i++ ){ + // std::cout<infer(hmax->input_dim.tot(), rt_out[0]); + // keep = (hmax == heat).float() + // return heat * keep + + dnnType *hmax_h; + checkCuda( cudaMallocHost(&hmax_h, hmax->output_dim.tot()*sizeof(dnnType)) ); + checkCuda( cudaMemcpy(hmax_h, rt_out[1], hmax->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + + std::cout<<"hmax\n"; + hmax->output_dim.print(); + // for(int i=0; ioutput_dim.tot(); i++ ){ + // std::cout<output_dim.print(); + std::cout<<"hmax:\n"; + hmax->output_dim.print(); + // return 0; + float toll = 0.000001; + for(int i=0; i < hm->output_dim.tot(); i++){ + if(hm_h[i]-hmax_h[i] > toll || hm_h[i]-hmax_h[i] < -toll){ + hm_h[i] = 0.0f; + } + } + // std::cout<<"\n"; + // for(int i=0; ioutput_dim.tot(); i++ ){ + // std::cout<dstData, hm_h, hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) ); + checkCuda( cudaFreeHost(hmax_h) ); + // ----------- nms end + // ----------- topk + int K = 100; + int width = 56; // TODO + float *topk_scores; + int *topk_inds_; + float *topk_ys_; + float *topk_xs_; + std::cout<<"mah: "<output_dim.c * K<output_dim.c * K *sizeof(float)) ); + checkCuda( cudaMallocHost(&topk_inds_, hm->output_dim.c * K *sizeof(int)) ); + checkCuda( cudaMallocHost(&topk_ys_, hm->output_dim.c * K *sizeof(float)) ); + checkCuda( cudaMallocHost(&topk_xs_, hm->output_dim.c * K *sizeof(float)) ); + std::cout<<"1\n"; + dnnType *hm_aus; + checkCuda( cudaMallocHost(&hm_aus, hm->output_dim.h * hm->output_dim.w *sizeof(dnnType)) ); + std::cout<<"2\n"; + int count; + std::vector v = {2.0, 3.0, 9.0}; + for (auto i: sort_indexes(v)) { + std::cout << i<< "--" <output_dim.c; i++){ + count = 0; + // get the hm->output_dim.h * hm->output_dim.w elements for each channel and sort it. Then find the first 100 elements + checkCuda( cudaMemcpy(hm_aus, hm_h + i * hm->output_dim.h * hm->output_dim.w, + hm->output_dim.h * hm->output_dim.w * sizeof(dnnType), cudaMemcpyHostToHost) ); + // std::cout<<"top scores: "<output_dim.h * hm->output_dim.w<<"\n"; + // for(int k=0; koutput_dim.h * hm->output_dim.w; k++) + // std::cout< my_vector {arr, arr + arr_length} + std::vector my_vector{hm_aus, hm_aus + hm->output_dim.h * hm->output_dim.w}; + for (auto j: sort_indexes(my_vector)) { + // std::cout <<"j: "< "<< hm_aus[j] << std::endl; + topk_scores[i*K + count] = hm_aus[j]; + topk_inds_[i*K +count] = j; + topk_ys_[i*K +count] = (int)(j / width); + topk_xs_[i*K +count] = (int)(j % width); + if(++count == K) + break; + } + } + std::cout<<"topk_xs_[0]: "<output_dim.c * K; i++) + std::cout< my_vector{topk_scores, topk_scores + hm->output_dim.c * K }; + for (auto j: sort_indexes(my_vector)) { + // std::cout <<"j: "< "<< hm_aus[j] << std::endl; + scores[count] = topk_scores[j]; + clses[count] = (int)(j / K); + topk_inds[count] = topk_inds_[j]; + topk_ys[count] = topk_ys_[j]; + topk_xs[count] = topk_xs_[j]; + if(++count == K) + break; + } + checkCuda( cudaFreeHost(topk_scores) ); + checkCuda( cudaFreeHost(topk_inds_) ); + checkCuda( cudaFreeHost(topk_ys_) ); + checkCuda( cudaFreeHost(topk_xs_) ); + std::cout<<"5\n"; + // ----------- topk end + std::cout<<"topk_xs[0]: "<output_dim.tot()*sizeof(dnnType)) ); + checkCuda( cudaMemcpy(reg_aus, rt_out[3], reg->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + std::cout<<"reg:\n"; + reg->output_dim.print(); + // for(int i=0; ioutput_dim.tot(); i++ ){ + // std::cout<output_dim.h*reg->output_dim.w]; + } + std::cout<<"topk_xs[0]: "<output_dim.tot()*sizeof(dnnType)) ); + checkCuda( cudaMallocHost(&bboxes, 4 * K *sizeof(dnnType)) ); + checkCuda( cudaMemcpy(wh_aus, rt_out[2], wh->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); + std::cout<<"7\n"; + for(int i = 0; i< K; i++) + std::cout<output_dim.h*reg->output_dim.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]+reg->output_dim.h*reg->output_dim.w] / 2; + } + ////////////////// fin qui ok + + checkCuda( cudaFreeHost(wh_aus) ); + checkCuda( cudaFreeHost(topk_inds) ); + checkCuda( cudaFreeHost(topk_ys) ); + checkCuda( cudaFreeHost(topk_xs) ); + + std::cout<<"8\n"; + float *detections; + std::cout<<"bboxes:\n"; + for(int i = 0; i < K+1; i++){ + std::cout<(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) ); + std::cout<<"src: "<(0,0)<<" - "<(0,1)<<" - "<(0,2)<<"\n"<(1,0)<<" - "<(1,1)<<" - "<(1,2)<(0,0)=detections[i*4]; + // new_pt1.at(0,1)=detections[i*4+1]; + // new_pt1.at(0,2)=1.0; + // new_pt1 << detections[i], detections[i+K], 1.0; + // std::cout<<"----\ni: "<(0,0)=static_cast(trans2.at(0,0))*detections[i*4] + + static_cast(trans2.at(0,1))*detections[i*4+1] + + static_cast(trans2.at(0,2))*1.0; + new_pt1.at(0,1)=static_cast(trans2.at(1,0))*detections[i*4] + + static_cast(trans2.at(1,1))*detections[i*4+1] + + static_cast(trans2.at(1,2))*1.0; + + new_pt2.at(0,0)=static_cast(trans2.at(0,0))*detections[i*4+2] + + static_cast(trans2.at(0,1))*detections[i*4+3] + + static_cast(trans2.at(0,2))*1.0; + new_pt2.at(0,1)=static_cast(trans2.at(1,0))*detections[i*4+2] + + static_cast(trans2.at(1,1))*detections[i*4+3] + + static_cast(trans2.at(1,2))*1.0; + + + // std::cout<<"\n new: "<(0,0); + target_coords[i*4+1] = new_pt1.at(0,1); + target_coords[i*4+2] = new_pt2.at(0,0); + target_coords[i*4+3] = new_pt2.at(0,1); + // std::cout<(0,0)<<", "<(0,1)<<", "<(0,0)<<", "<(0,1)< coco_class_name(coco_class_name_, std::end( coco_class_name_ )); + int num_classes = 80; + float vis_threshold = 0.3; + // int *classes; + std::vector detected; + // checkCuda( cudaMallocHost(&classes, K *sizeof(int)) ); + // checkCuda( cudaMemcpy(classes, detections + 5 * K *sizeof(dnnType), K *sizeof(dnnType), cudaMemcpyHostToHost) ); + for(int i = 0; i i+1 (1:80); + + if(scores[j] > vis_threshold){ + std::cout<<"th: "< Date: Mon, 20 Jan 2020 14:51:38 +0100 Subject: [PATCH 038/228] compile with tensorrt 5 --- src/NetworkRT.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index d4fdf90..f27f70d 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -275,18 +275,18 @@ 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); From 7f239efdc0820f5707d923a7ce873b0bec975bfb Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Tue, 21 Jan 2020 12:50:18 +0100 Subject: [PATCH 039/228] Centernet: fix pooling problem, add centrnet demo Signed-off-by: Micaela Verucchi Signed-off-by: Davide Sapienza --- CMakeLists.txt | 5 +- demo/demo/demo_centernet.cpp | 88 +++ demo/demo/{demo.cpp => demo_yolo3.cpp} | 50 +- include/tkDNN/CenternetDetection.h | 3 + include/tkDNN/pluginsRT/ActivationSigmoidRT.h | 60 ++ include/tkDNN/pluginsRT/DeformableConvRT.h | 1 - src/CenternetDetection.cpp | 251 ++----- src/NetworkRT.cpp | 3 +- src/Pooling.cpp | 4 +- src/kernels/activation_sigmoid.cu | 16 +- src/sorting.cu | 2 +- tests/resnet101_cnet/resnet101_cnet.cpp | 681 +----------------- 12 files changed, 229 insertions(+), 935 deletions(-) create mode 100644 demo/demo/demo_centernet.cpp rename demo/demo/{demo.cpp => demo_yolo3.cpp} (57%) create mode 100644 include/tkDNN/pluginsRT/ActivationSigmoidRT.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7af66c0..8b847d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,9 +105,12 @@ 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) +add_executable(yolo3_demo demo/demo/demo_yolo3.cpp) target_link_libraries(yolo3_demo tkDNN) +add_executable(centernet_demo demo/demo/demo_centernet.cpp) +target_link_libraries(centernet_demo tkDNN) + #------------------------------------------------------------------------------- # Install diff --git a/demo/demo/demo_centernet.cpp b/demo/demo/demo_centernet.cpp new file mode 100644 index 0000000..0f9c86e --- /dev/null +++ b/demo/demo/demo_centernet.cpp @@ -0,0 +1,88 @@ +#include +#include +#include /* srand, rand */ +#include +#include +#include "utils.h" + +#include +#include +#include +#include + +#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::CenternetDetection cnet; + cnet.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 + cnet.update(dnn_input); + // draw dets + frame = cnet.draw(dnn_input); + + cv::imshow("detection", frame); + cv::waitKey(1); + if(SAVE_RESULT) + resultVideo << frame; + } + + std::cout<<"detection end\n"; + + + std::cout< #include -// #include "Yolo3Detection.h" -#include "CenternetDetection.h" +#include "Yolo3Detection.h" bool gRun; bool SAVE_RESULT = false; @@ -27,15 +26,14 @@ int main(int argc, char *argv[]) { signal(SIGINT, sig_handler); - char *net = "resnet101_cnet.rt"; + char *net = "yolo3_berkeley.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; + tk::dnn::Yolo3Detection yolo; yolo.init(net); gRun = true; @@ -69,30 +67,28 @@ int main(int argc, char *argv[]) { // TODO: async infer yolo.update(dnn_input); - frame = yolo.draw(dnn_input); - // // draw dets - // for(int i=0; iclassesNames[b.cl]; - // float prob = b.prob; + // draw dets + for(int i=0; iclassesNames[b.cl]; + float prob = b.prob; - // // std::cout< coco_class_name; + // keep track of inference times (ms) + std::vector stats; + CenternetDetection() {} virtual ~CenternetDetection() {} diff --git a/include/tkDNN/pluginsRT/ActivationSigmoidRT.h b/include/tkDNN/pluginsRT/ActivationSigmoidRT.h new file mode 100644 index 0000000..4435f08 --- /dev/null +++ b/include/tkDNN/pluginsRT/ActivationSigmoidRT.h @@ -0,0 +1,60 @@ +#include +#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(inputs[0]), + reinterpret_cast(outputs[0]), size, stream); + return 0; + } + + + virtual size_t getSerializationSize() override { + return 1*sizeof(int); + } + + virtual void serialize(void* buffer) override { + char *buf = reinterpret_cast(buffer); + tk::dnn::writeBUF(buf, size); + } + + int size; +}; diff --git a/include/tkDNN/pluginsRT/DeformableConvRT.h b/include/tkDNN/pluginsRT/DeformableConvRT.h index b236095..dca1020 100644 --- a/include/tkDNN/pluginsRT/DeformableConvRT.h +++ b/include/tkDNN/pluginsRT/DeformableConvRT.h @@ -90,7 +90,6 @@ public: } 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(inputs[0]); dnnType *output_conv = (dnnType*)reinterpret_cast(inputs[1]); diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp index 59bf827..fbc9832 100644 --- a/src/CenternetDetection.cpp +++ b/src/CenternetDetection.cpp @@ -229,58 +229,50 @@ void CenternetDetection::update(cv::Mat &imageORIG) { 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) ); - // std::cout<<"src: "<(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME gett affine trans: " << std::chrono::duration_cast(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: "<(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 ); + + 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(end_t - step_t).count() << " ms" << std::endl; step_t = end_t; + sz = imageF.size(); std::cout<<"size: "<(end_t - step_t).count() << " ms" << std::endl; - step_t = end_t; - std::cout<<"mean: "<(end_t - step_t).count() << " us" << std::endl; - step_t = end_t; - - //split channels - cv::split(imageF,bgr);//split source end_t = std::chrono::steady_clock::now(); - std::cout << " TIME split: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME convert: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; step_t = end_t; + dim2 = dim; + + //split channels + cv::split(imageF,bgr);//split source + 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(end_t - step_t).count() << " ms" << std::endl; - step_t = end_t; - //write channels for(int i=0; iinfer(dim2, input_d); TIMER_STOP dim2.print(); + + stats.push_back(t_ns); } // 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(end_t - step_t).count() << " ms" << std::endl; - step_t = end_t; + step_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(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 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(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME threshold: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; step_t = end_t; // ----------- nms end // ----------- topk - - // thrust::device_vector ids_d; - // int ids[dim_hm.h * dim_hm.w]; - // for(int i=0; i ids2( dim_hm.h * dim_hm.w ); - // for(int i=0; i 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; ioutput_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 "<(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(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(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); 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(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME sort: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; step_t = end_t; - // 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() ); + checkCuda( cudaDeviceSynchronize() ); + end_t = std::chrono::steady_clock::now(); - std::cout << " TIME topk channel: " << 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() << " ms" << std::endl; step_t = end_t; - - - checkCuda( cudaMemcpy(topk_inds, topk_inds_d, K*sizeof(int), cudaMemcpyDeviceToHost) ); - for(int i=0; i(end_t - step_t).count() << " ms" << 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(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]); // 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; 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); // 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) = ("<(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME bboxes: " << std::chrono::duration_cast(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(end_t - step_t).count() << " ms" << std::endl; - step_t = end_t; // ---------------------------------- post-process ----------------------------------------- // --------- ctdet_post_process @@ -548,12 +384,13 @@ void CenternetDetection::update(cv::Mat &imageORIG) { 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); - + cv::Mat new_pt2(cv::Size(1,2), CV_32F); for(int i = 0; i(0,0)=static_cast(trans2.at(0,0))*bbx0[i] + @@ -570,23 +407,18 @@ void CenternetDetection::update(cv::Mat &imageORIG) { static_cast(trans2.at(1,1))*bby1[i] + static_cast(trans2.at(1,2))*1.0; - // std::cout<<"\n new: "<(0,0); target_coords[i*4+1] = new_pt1.at(0,1); target_coords[i*4+2] = new_pt2.at(0,0); target_coords[i*4+3] = new_pt2.at(0,1); - // std::cout<(0,0)<<", "<(0,1)<<", "<(0,0)<<", "<(0,1)< thresh){ - std::cout<<"th: "<(end_t - step_t).count() << " ms" << std::endl; + std::cout << " TIME detections: " << std::chrono::duration_cast(end_t - step_t).count() << " ms" << std::endl; step_t = end_t; + std::cout<<"TOTAL: \n"; TIMER_STOP } diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index bec7b17..0f2d621 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -290,8 +290,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, Pooling *l) { 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->paddingH == 0 && l->paddingW == 0 && l->input_dim.h == l->output_dim.h && l->input_dim.w == l->output_dim.w) { 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); diff --git a/src/Pooling.cpp b/src/Pooling.cpp index 1ad0664..cc498df 100644 --- a/src/Pooling.cpp +++ b/src/Pooling.cpp @@ -55,8 +55,8 @@ Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW, int padW = paddingW == 0? winW -1 : paddingW; if(final){ - h = (h + padH - winH)/strideH +1 +1; - w = (w + padW - winW)/strideW +1 +1; + h = (h + 2*paddingH - winH)/strideH +1 ; + w = (w + 2*paddingW - winW)/strideW +1; } else{ h = (h + padH - winH)/strideH +1; diff --git a/src/kernels/activation_sigmoid.cu b/src/kernels/activation_sigmoid.cu index ba6c997..400a948 100644 --- a/src/kernels/activation_sigmoid.cu +++ b/src/kernels/activation_sigmoid.cu @@ -1,21 +1,13 @@ #include "kernels.h" - -__device__ -__forceinline__ -double sigmoid (double a) -{ - return 1.0 / (1.0 + exp (-a)); -} +#include __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])); } diff --git a/src/sorting.cu b/src/sorting.cu index e007be1..fd62cec 100644 --- a/src/sorting.cu +++ b/src/sorting.cu @@ -45,7 +45,7 @@ struct threshold : public thrust::binary_function { __host__ __device__ float operator()(float x, float y) { - float toll = 1e-6; + double toll = 1e-6; if(fabsf(x-y)>toll) return 0.0f; else diff --git a/tests/resnet101_cnet/resnet101_cnet.cpp b/tests/resnet101_cnet/resnet101_cnet.cpp index 061e4b6..e05f517 100644 --- a/tests/resnet101_cnet/resnet101_cnet.cpp +++ b/tests/resnet101_cnet/resnet101_cnet.cpp @@ -183,53 +183,6 @@ const char *output_bin[]={ "../tests/resnet101_cnet/debug/wh.bin", "../tests/resnet101_cnet/debug/reg.bin"}; - - -std::vector sort_indexes(const std::vector &v) { - - // initialize original index locations - std::vector idx(v.size()); - iota(idx.begin(), idx.end(), 0); - - // sort indexes based on comparing values in v - sort(idx.begin(), idx.end(), - [&v](size_t i1, size_t i2) {return v[i1] > v[i2];}); - - return idx; -} - -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; -} - -int computeDetections(dnnType *hm_d, dnnType *wh_d, dnnType *reg_d, int hm_dim, int wh_dim, int reg_dim, bool cat_spec_wh, int k){ - // _nms - int kernel = 3; - int pad = (kernel - 1)/2; - std::cout<<"computeDetections\n"; - // dnnType *hmax; - // tk::dnn::Pooling maxpool(&hmax, 3, 3, 2, 2, 1, 1, tk::dnn::POOLING_MAX) - // = (dnnType *) - - // net.functional.max_pool2d( - // heat, (kernel, kernel), stride=1, padding=pad) - // keep = (hmax == heat).float() - // return heat * keep -} - -int process(dnnType *hm_d, dnnType *wh_d, dnnType *reg_d, int hm_dim, int wh_dim, int reg_dim){ - std::cout<<"process\n"; - // computeDetections(hm_d, wh_d, reg_d, hm_dim, wh_dim, reg_dim, false, 100); -} - int main() { @@ -450,637 +403,5 @@ int main() checkResult(odim, rt_out, out); std::cout << "CUDNN vs TRT "; checkResult(odim, cudnn_out, rt_out); - } - - TIMER_START - - // -------- transofrm compose - cv::Mat imageOrig = cv::imread("/media/davide/DATA/shared_home/Projects/Professionale/repos/photo_2020-01-14_09-56-07.jpg"); - cv::Mat imageF; - imageOrig.convertTo(imageF, CV_32FC3, 1/255.0); - cv::Mat image; - cv::Size sz = imageF.size(); - std::cout<<"image: "<output_dim.tot()*sizeof(dnnType)) ); - - dnnType *rt_out[4]; - 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]; - - // checkCuda( cudaMemcpy(hm_h, rt_out[0], hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); - std::cout<<"hm\n"; - hm->output_dim.print(); - // for(int i=0; ioutput_dim.tot(); i++ ){ - // std::cout<output_dim.tot()); - checkCuda( cudaDeviceSynchronize() ); - - - checkCuda( cudaMemcpy(hm_h, rt_out[0], hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); - std::cout<<"hm\n"; - hm->output_dim.print(); - // for(int i=0; ioutput_dim.tot(); i++ ){ - // std::cout<infer(hmax->input_dim.tot(), rt_out[0]); - // keep = (hmax == heat).float() - // return heat * keep - - dnnType *hmax_h; - checkCuda( cudaMallocHost(&hmax_h, hmax->output_dim.tot()*sizeof(dnnType)) ); - checkCuda( cudaMemcpy(hmax_h, rt_out[1], hmax->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); - - std::cout<<"hmax\n"; - hmax->output_dim.print(); - // for(int i=0; ioutput_dim.tot(); i++ ){ - // std::cout<output_dim.print(); - std::cout<<"hmax:\n"; - hmax->output_dim.print(); - // return 0; - float toll = 0.000001; - for(int i=0; i < hm->output_dim.tot(); i++){ - if(hm_h[i]-hmax_h[i] > toll || hm_h[i]-hmax_h[i] < -toll){ - hm_h[i] = 0.0f; - } - } - // std::cout<<"\n"; - // for(int i=0; ioutput_dim.tot(); i++ ){ - // std::cout<dstData, hm_h, hm->output_dim.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) ); - checkCuda( cudaFreeHost(hmax_h) ); - // ----------- nms end - // ----------- topk - int K = 100; - int width = 56; // TODO - float *topk_scores; - int *topk_inds_; - float *topk_ys_; - float *topk_xs_; - std::cout<<"mah: "<output_dim.c * K<output_dim.c * K *sizeof(float)) ); - checkCuda( cudaMallocHost(&topk_inds_, hm->output_dim.c * K *sizeof(int)) ); - checkCuda( cudaMallocHost(&topk_ys_, hm->output_dim.c * K *sizeof(float)) ); - checkCuda( cudaMallocHost(&topk_xs_, hm->output_dim.c * K *sizeof(float)) ); - std::cout<<"1\n"; - dnnType *hm_aus; - checkCuda( cudaMallocHost(&hm_aus, hm->output_dim.h * hm->output_dim.w *sizeof(dnnType)) ); - std::cout<<"2\n"; - int count; - std::vector v = {2.0, 3.0, 9.0}; - for (auto i: sort_indexes(v)) { - std::cout << i<< "--" <output_dim.c; i++){ - count = 0; - // get the hm->output_dim.h * hm->output_dim.w elements for each channel and sort it. Then find the first 100 elements - checkCuda( cudaMemcpy(hm_aus, hm_h + i * hm->output_dim.h * hm->output_dim.w, - hm->output_dim.h * hm->output_dim.w * sizeof(dnnType), cudaMemcpyHostToHost) ); - // std::cout<<"top scores: "<output_dim.h * hm->output_dim.w<<"\n"; - // for(int k=0; koutput_dim.h * hm->output_dim.w; k++) - // std::cout< my_vector {arr, arr + arr_length} - std::vector my_vector{hm_aus, hm_aus + hm->output_dim.h * hm->output_dim.w}; - for (auto j: sort_indexes(my_vector)) { - // std::cout <<"j: "< "<< hm_aus[j] << std::endl; - topk_scores[i*K + count] = hm_aus[j]; - topk_inds_[i*K +count] = j; - topk_ys_[i*K +count] = (int)(j / width); - topk_xs_[i*K +count] = (int)(j % width); - if(++count == K) - break; - } - } - std::cout<<"topk_xs_[0]: "<output_dim.c * K; i++) - std::cout< my_vector{topk_scores, topk_scores + hm->output_dim.c * K }; - for (auto j: sort_indexes(my_vector)) { - // std::cout <<"j: "< "<< hm_aus[j] << std::endl; - scores[count] = topk_scores[j]; - clses[count] = (int)(j / K); - topk_inds[count] = topk_inds_[j]; - topk_ys[count] = topk_ys_[j]; - topk_xs[count] = topk_xs_[j]; - if(++count == K) - break; - } - checkCuda( cudaFreeHost(topk_scores) ); - checkCuda( cudaFreeHost(topk_inds_) ); - checkCuda( cudaFreeHost(topk_ys_) ); - checkCuda( cudaFreeHost(topk_xs_) ); - std::cout<<"5\n"; - // ----------- topk end - std::cout<<"topk_xs[0]: "<output_dim.tot()*sizeof(dnnType)) ); - checkCuda( cudaMemcpy(reg_aus, rt_out[3], reg->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); - std::cout<<"reg:\n"; - reg->output_dim.print(); - // for(int i=0; ioutput_dim.tot(); i++ ){ - // std::cout<output_dim.h*reg->output_dim.w]; - } - std::cout<<"topk_xs[0]: "<output_dim.tot()*sizeof(dnnType)) ); - checkCuda( cudaMallocHost(&bboxes, 4 * K *sizeof(dnnType)) ); - checkCuda( cudaMemcpy(wh_aus, rt_out[2], wh->output_dim.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) ); - std::cout<<"7\n"; - for(int i = 0; i< K; i++) - std::cout<output_dim.h*reg->output_dim.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]+reg->output_dim.h*reg->output_dim.w] / 2; - } - ////////////////// fin qui ok - - checkCuda( cudaFreeHost(wh_aus) ); - checkCuda( cudaFreeHost(topk_inds) ); - checkCuda( cudaFreeHost(topk_ys) ); - checkCuda( cudaFreeHost(topk_xs) ); - - std::cout<<"8\n"; - float *detections; - std::cout<<"bboxes:\n"; - for(int i = 0; i < K+1; i++){ - std::cout<(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) ); - std::cout<<"src: "<(0,0)<<" - "<(0,1)<<" - "<(0,2)<<"\n"<(1,0)<<" - "<(1,1)<<" - "<(1,2)<(0,0)=detections[i*4]; - // new_pt1.at(0,1)=detections[i*4+1]; - // new_pt1.at(0,2)=1.0; - // new_pt1 << detections[i], detections[i+K], 1.0; - // std::cout<<"----\ni: "<(0,0)=static_cast(trans2.at(0,0))*detections[i*4] + - static_cast(trans2.at(0,1))*detections[i*4+1] + - static_cast(trans2.at(0,2))*1.0; - new_pt1.at(0,1)=static_cast(trans2.at(1,0))*detections[i*4] + - static_cast(trans2.at(1,1))*detections[i*4+1] + - static_cast(trans2.at(1,2))*1.0; - - new_pt2.at(0,0)=static_cast(trans2.at(0,0))*detections[i*4+2] + - static_cast(trans2.at(0,1))*detections[i*4+3] + - static_cast(trans2.at(0,2))*1.0; - new_pt2.at(0,1)=static_cast(trans2.at(1,0))*detections[i*4+2] + - static_cast(trans2.at(1,1))*detections[i*4+3] + - static_cast(trans2.at(1,2))*1.0; - - - // std::cout<<"\n new: "<(0,0); - target_coords[i*4+1] = new_pt1.at(0,1); - target_coords[i*4+2] = new_pt2.at(0,0); - target_coords[i*4+3] = new_pt2.at(0,1); - // std::cout<(0,0)<<", "<(0,1)<<", "<(0,0)<<", "<(0,1)< coco_class_name(coco_class_name_, std::end( coco_class_name_ )); - int num_classes = 80; - float vis_threshold = 0.3; - // int *classes; - std::vector detected; - // checkCuda( cudaMallocHost(&classes, K *sizeof(int)) ); - // checkCuda( cudaMemcpy(classes, detections + 5 * K *sizeof(dnnType), K *sizeof(dnnType), cudaMemcpyHostToHost) ); - for(int i = 0; i i+1 (1:80); - - if(scores[j] > vis_threshold){ - std::cout<<"th: "< Date: Fri, 24 Jan 2020 19:30:32 +0100 Subject: [PATCH 040/228] Implement DLA34, CUDNN and TensorRT work. Signed-off-by: Davide Sapienza --- CMakeLists.txt | 3 + tests/dla34/dla34.cpp | 350 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 tests/dla34/dla34.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b847d0..b5e24df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,9 @@ 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_dla34 tests/dla34/dla34.cpp) +target_link_libraries(test_dla34 tkDNN) + ################################################################################ diff --git a/tests/dla34/dla34.cpp b/tests/dla34/dla34.cpp new file mode 100644 index 0000000..15f7b3f --- /dev/null +++ b/tests/dla34/dla34.cpp @@ -0,0 +1,350 @@ +#include +#include "tkdnn.h" + +const char *input_bin = "../tests/dla34/debug/input.bin"; +const char *conv1_bin = "../tests/dla34/layers/features-init_block-conv1-conv.bin"; +const char *conv2_bin = "../tests/dla34/layers/features-init_block-conv2-conv.bin"; +const char *conv3_bin = "../tests/dla34/layers/features-init_block-conv3-conv.bin"; +// s - stage, t - tree +const char *s1_t1_conv1_bin = "../tests/dla34/layers/features-stage1-tree1-body-conv1-conv.bin"; +const char *s1_t1_conv2_bin = "../tests/dla34/layers/features-stage1-tree1-body-conv2-conv.bin"; +const char *s1_t1_project = "../tests/dla34/layers/features-stage1-tree1-project_conv-conv.bin"; +const char *s1_t2_conv1_bin = "../tests/dla34/layers/features-stage1-tree2-body-conv1-conv.bin"; +const char *s1_t2_conv2_bin = "../tests/dla34/layers/features-stage1-tree2-body-conv2-conv.bin"; +const char *s1_root_conv1_bin = "../tests/dla34/layers/features-stage1-root-conv-conv.bin"; +const char *s2_t1_t1_conv1_bin = "../tests/dla34/layers/features-stage2-tree1-tree1-body-conv1-conv.bin"; +const char *s2_t1_t1_conv2_bin = "../tests/dla34/layers/features-stage2-tree1-tree1-body-conv2-conv.bin"; +const char *s2_t1_t1_project = "../tests/dla34/layers/features-stage2-tree1-tree1-project_conv-conv.bin"; +const char *s2_t1_t2_conv1_bin = "../tests/dla34/layers/features-stage2-tree1-tree2-body-conv1-conv.bin"; +const char *s2_t1_t2_conv2_bin = "../tests/dla34/layers/features-stage2-tree1-tree2-body-conv2-conv.bin"; +const char *s2_t1_root_conv1_bin = "../tests/dla34/layers/features-stage2-tree1-root-conv-conv.bin"; +const char *s2_t2_t1_conv1_bin = "../tests/dla34/layers/features-stage2-tree2-tree1-body-conv1-conv.bin"; +const char *s2_t2_t1_conv2_bin = "../tests/dla34/layers/features-stage2-tree2-tree1-body-conv2-conv.bin"; +const char *s2_t2_t2_conv1_bin = "../tests/dla34/layers/features-stage2-tree2-tree2-body-conv1-conv.bin"; +const char *s2_t2_t2_conv2_bin = "../tests/dla34/layers/features-stage2-tree2-tree2-body-conv2-conv.bin"; +const char *s2_t2_root_conv1_bin = "../tests/dla34/layers/features-stage2-tree2-root-conv-conv.bin"; +const char *s3_t1_t1_conv1_bin = "../tests/dla34/layers/features-stage3-tree1-tree1-body-conv1-conv.bin"; +const char *s3_t1_t1_conv2_bin = "../tests/dla34/layers/features-stage3-tree1-tree1-body-conv2-conv.bin"; +const char *s3_t1_t1_project = "../tests/dla34/layers/features-stage3-tree1-tree1-project_conv-conv.bin"; +const char *s3_t1_t2_conv1_bin = "../tests/dla34/layers/features-stage3-tree1-tree2-body-conv1-conv.bin"; +const char *s3_t1_t2_conv2_bin = "../tests/dla34/layers/features-stage3-tree1-tree2-body-conv2-conv.bin"; +const char *s3_t1_root_conv1_bin = "../tests/dla34/layers/features-stage3-tree1-root-conv-conv.bin"; +const char *s3_t2_t1_conv1_bin = "../tests/dla34/layers/features-stage3-tree2-tree1-body-conv1-conv.bin"; +const char *s3_t2_t1_conv2_bin = "../tests/dla34/layers/features-stage3-tree2-tree1-body-conv2-conv.bin"; +const char *s3_t2_t2_conv1_bin = "../tests/dla34/layers/features-stage3-tree2-tree2-body-conv1-conv.bin"; +const char *s3_t2_t2_conv2_bin = "../tests/dla34/layers/features-stage3-tree2-tree2-body-conv2-conv.bin"; +const char *s3_t2_root_conv1_bin = "../tests/dla34/layers/features-stage3-tree2-root-conv-conv.bin"; +const char *s4_t1_conv1_bin = "../tests/dla34/layers/features-stage4-tree1-body-conv1-conv.bin"; +const char *s4_t1_conv2_bin = "../tests/dla34/layers/features-stage4-tree1-body-conv2-conv.bin"; +const char *s4_t1_project = "../tests/dla34/layers/features-stage4-tree1-project_conv-conv.bin"; +const char *s4_t2_conv1_bin = "../tests/dla34/layers/features-stage4-tree2-body-conv1-conv.bin"; +const char *s4_t2_conv2_bin = "../tests/dla34/layers/features-stage4-tree2-body-conv2-conv.bin"; +const char *s4_root_conv1_bin = "../tests/dla34/layers/features-stage4-root-conv-conv.bin"; + +//final +const char *fc_bin = "../tests/dla34/layers/output.bin"; + +const char *output_bin = "../tests/dla34/debug/output.bin"; + +int main() +{ + + // Network layout + tk::dnn::dataDim_t dim(1, 3, 224, 224, 1); + tk::dnn::Network net(dim); + tk::dnn::Layer *last1, *last2, *last3, *last4; + + + tk::dnn::Conv2d conv1(&net, 16, 7, 7, 1, 1, 3, 3, conv1_bin, true); + tk::dnn::Activation relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d conv2(&net, 16, 3, 3, 1, 1, 1, 1, conv2_bin, true); + tk::dnn::Activation relu2(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d conv3(&net, 32, 3, 3, 2, 2, 1, 1, conv3_bin, true); + tk::dnn::Activation relu3(&net, CUDNN_ACTIVATION_RELU); + + last1 = &relu3; + + // level 2 + // tree 1 + tk::dnn::Conv2d s1_t1_conv1(&net, 64, 3, 3, 2, 2, 1, 1, s1_t1_conv1_bin, true); + tk::dnn::Activation s1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s1_t1_conv2(&net, 64, 3, 3, 1, 1, 1, 1, s1_t1_conv2_bin, true); + last2 = &s1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s1_t1_layers[1] = { last1 }; + tk::dnn::Route route_s1_t1(&net, route_s1_t1_layers, 1); + // downsample + tk::dnn::Pooling s1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + // project + tk::dnn::Conv2d s1_t1_residual1_conv1(&net, 64, 1, 1, 1, 1, 0, 0, s1_t1_project, true); + + tk::dnn::Shortcut s1_t1_s1(&net, last2); + tk::dnn::Activation s1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s1_t1_relu; + + // tree 2 + tk::dnn::Conv2d s1_t2_conv1(&net, 64, 3, 3, 1, 1, 1, 1, s1_t2_conv1_bin, true); + tk::dnn::Activation s1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s1_t2_conv2(&net, 64, 3, 3, 1, 1, 1, 1, s1_t2_conv2_bin, true); + + tk::dnn::Shortcut s1_t2_s1(&net, last1); + tk::dnn::Activation s1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s1_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s1_root(&net, route_s1_root_layers, 2); + tk::dnn::Conv2d s1_root_conv1(&net, 64, 1, 1, 1, 1, 0, 0, s1_root_conv1_bin, true); + tk::dnn::Activation s1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s1_root_relu; + // level 3 + // tree 1 + // tree 1 + tk::dnn::Conv2d s2_t1_t1_conv1(&net, 128, 3, 3, 2, 2, 1, 1, s2_t1_t1_conv1_bin, true); + tk::dnn::Activation s2_t1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t1_t1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t1_conv2_bin, true); + last2 = &s2_t1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s2_t1_t1_layers[1] = { last1 }; + tk::dnn::Route route_s2_t1_t1(&net, route_s2_t1_t1_layers, 1); + // downsample + tk::dnn::Pooling s2_t1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s2_t1_t1_maxpool1; + // project + tk::dnn::Conv2d s2_t1_t1_residual1_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t1_t1_project, true); + + tk::dnn::Shortcut s2_t1_t1_s1(&net, last2); + tk::dnn::Activation s2_t1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t1_t1_relu; + + // tree 2 + tk::dnn::Conv2d s2_t1_t2_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t2_conv1_bin, true); + tk::dnn::Activation s2_t1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t1_t2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t2_conv2_bin, true); + + tk::dnn::Shortcut s2_t1_t2_s1(&net, last1); + tk::dnn::Activation s2_t1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s2_t1_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s2_t1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s2_t1_root(&net, route_s2_t1_root_layers, 2); + tk::dnn::Conv2d s2_t1_root_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t1_root_conv1_bin, true); + tk::dnn::Activation s2_t1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t1_root_relu; + last3 = &s2_t1_root_relu; + // tree 2 + // tree 1 + tk::dnn::Conv2d s2_t2_t1_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t1_conv1_bin, true); + tk::dnn::Activation s2_t2_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t2_t1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t1_conv2_bin, true); + tk::dnn::Shortcut s2_t2_t1_s1(&net, last1); + tk::dnn::Activation s2_t2_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t2_t1_relu; + + // tree 2 + tk::dnn::Conv2d s2_t2_t2_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t2_conv1_bin, true); + tk::dnn::Activation s2_t2_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t2_t2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t2_conv2_bin, true); + + tk::dnn::Shortcut s2_t2_t2_s1(&net, last1); + tk::dnn::Activation s2_t2_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s2_t2_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s2_t2_root_layers[4] = { last2, last1, last4, last3}; + tk::dnn::Route route_s2_t2_root(&net, route_s2_t2_root_layers, 4); + tk::dnn::Conv2d s2_t2_root_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t2_root_conv1_bin, true); + tk::dnn::Activation s2_t2_root_relu(&net, CUDNN_ACTIVATION_RELU); + + + last1 = &s2_t2_root_relu; + // level 4 + // tree 1 + // tree 1 + tk::dnn::Conv2d s3_t1_t1_conv1(&net, 256, 3, 3, 2, 2, 1, 1, s3_t1_t1_conv1_bin, true); + tk::dnn::Activation s3_t1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t1_t1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t1_conv2_bin, true); + last2 = &s3_t1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s3_t1_t1_layers[1] = { last1 }; + tk::dnn::Route route_s3_t1_t1(&net, route_s3_t1_t1_layers, 1); + // downsample + tk::dnn::Pooling s3_t1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s3_t1_t1_maxpool1; + // project + tk::dnn::Conv2d s3_t1_t1_residual1_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t1_t1_project, true); + + tk::dnn::Shortcut s3_t1_t1_s1(&net, last2); + tk::dnn::Activation s3_t1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t1_t1_relu; + + // tree 2 + tk::dnn::Conv2d s3_t1_t2_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t2_conv1_bin, true); + tk::dnn::Activation s3_t1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t1_t2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t2_conv2_bin, true); + + tk::dnn::Shortcut s3_t1_t2_s1(&net, last1); + tk::dnn::Activation s3_t1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s3_t1_t2_relu; + + // root + // join last1 and net in single input 256, 56, 56 + tk::dnn::Layer *route_s3_t1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s3_t1_root(&net, route_s3_t1_root_layers, 2); + tk::dnn::Conv2d s3_t1_root_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t1_root_conv1_bin, true); + tk::dnn::Activation s3_t1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t1_root_relu; + last3 = &s3_t1_root_relu; + // tree 2 + // tree 1 + tk::dnn::Conv2d s3_t2_t1_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t1_conv1_bin, true); + tk::dnn::Activation s3_t2_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t2_t1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t1_conv2_bin, true); + tk::dnn::Shortcut s3_t2_t1_s1(&net, last1); + tk::dnn::Activation s3_t2_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t2_t1_relu; + + // tree 2 + tk::dnn::Conv2d s3_t2_t2_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t2_conv1_bin, true); + tk::dnn::Activation s3_t2_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t2_t2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t2_conv2_bin, true); + + tk::dnn::Shortcut s3_t2_t2_s1(&net, last1); + tk::dnn::Activation s3_t2_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s3_t2_t2_relu; + + // root + // join last1 and net in single input 256, 56, 56 + tk::dnn::Layer *route_s3_t2_root_layers[4] = { last2, last1, last4, last3}; + tk::dnn::Route route_s3_t2_root(&net, route_s3_t2_root_layers, 4); + tk::dnn::Conv2d s3_t2_root_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t2_root_conv1_bin, true); + tk::dnn::Activation s3_t2_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t2_root_relu; + // level 4 + // tree 1 + tk::dnn::Conv2d s4_t1_conv1(&net, 512, 3, 3, 2, 2, 1, 1, s4_t1_conv1_bin, true); + tk::dnn::Activation s4_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s4_t1_conv2(&net, 512, 3, 3, 1, 1, 1, 1, s4_t1_conv2_bin, true); + last2 = &s4_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s4_t1_layers[1] = { last1 }; + tk::dnn::Route route_s4_t1(&net, route_s4_t1_layers, 1); + // downsample + tk::dnn::Pooling s4_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s4_t1_maxpool1; + // project + tk::dnn::Conv2d s4_t1_residual1_conv1(&net, 512, 1, 1, 1, 1, 0, 0, s4_t1_project, true); + + tk::dnn::Shortcut s4_t1_s1(&net, last2); + tk::dnn::Activation s4_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s4_t1_relu; + + // tree 2 + tk::dnn::Conv2d s4_t2_conv1(&net, 512, 3, 3, 1, 1, 1, 1, s4_t2_conv1_bin, true); + tk::dnn::Activation s4_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s4_t2_conv2(&net, 512, 3, 3, 1, 1, 1, 1, s4_t2_conv2_bin, true); + + tk::dnn::Shortcut s4_t2_s1(&net, last1); + tk::dnn::Activation s4_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s4_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s4_root_layers[3] = { last2, last1, last4 }; + tk::dnn::Route route_s4_root(&net, route_s4_root_layers, 3); + tk::dnn::Conv2d s4_root_conv1(&net, 512, 1, 1, 1, 1, 0, 0, s4_root_conv1_bin, true); + tk::dnn::Activation s4_root_relu(&net, CUDNN_ACTIVATION_RELU); + + //final + tk::dnn::Pooling avgpool(&net, 7, 7, 7, 7, 0, 0, tk::dnn::POOLING_AVERAGE); + tk::dnn::Dense fc(&net, 1000, fc_bin); + + // Load input + dnnType *data; + dnnType *input_h; + readBinaryFile(input_bin, dim.tot(), &input_h, &data); + //printDeviceVector(64, data, true); + + //print network model + net.print(); + + //convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "dla34.rt"); + + + tk::dnn::dataDim_t out_dim; + out_dim = net.layers[net.num_layers-1]->output_dim; + dnnType *cudnn_out, *rt_out; + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); + { + dim1.print(); + TIMER_START + net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + cudnn_out = net.layers[net.num_layers-1]->dstData; + + + // printDeviceVector(64, cudnn_out, true); + + tk::dnn::dataDim_t dim2 = dim; + printCenteredTitle(" TENSORRT inference ", '=', 30); + { + dim2.print(); + TIMER_START + netRT.infer(dim2, data); + TIMER_STOP + dim2.print(); + } + rt_out = (dnnType *)netRT.buffersRT[1]; + + + printCenteredTitle(std::string(" RESNET CHECK RESULTS ").c_str(), '=', 30); + dnnType *out, *out_h; + int odim = out_dim.tot(); + readBinaryFile(output_bin, odim, &out_h, &out); + + std::cout << "CUDNN vs correct"; + checkResult(odim, cudnn_out, out); + std::cout << "TRT vs correct"; + checkResult(odim, rt_out, out); + std::cout << "CUDNN vs TRT "; + checkResult(odim, cudnn_out, rt_out); + + return 0; +} From 4616be073831cecccce0ca2ce6852eac9b4e9e96 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Wed, 5 Feb 2020 14:32:58 +0100 Subject: [PATCH 041/228] Add grouped convolutions in CUDNN and tensorRT. Signed-off-by: Davide Sapienza --- include/tkDNN/Layer.h | 9 +++++---- src/Conv2d.cpp | 16 +++++++++------- src/DeformConv2d.cpp | 4 ++-- src/LayerWgs.cpp | 9 +++++++-- src/NetworkRT.cpp | 2 ++ 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 2d84a0e..7716393 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -85,7 +85,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 final = false, bool deConv = false, int groups = 1); virtual ~LayerWgs(); int inputs, outputs; @@ -165,7 +165,7 @@ 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, bool final = false, int groups = 1); virtual ~Conv2d(); virtual layerType_t getLayerType() { return LAYER_CONV2D; }; @@ -173,6 +173,7 @@ public: int kernelH, kernelW, strideH, strideW, paddingH, paddingW; bool deConv; + int groups; protected: cudnnFilterDescriptor_t filterDesc; @@ -196,8 +197,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, false, groups) {} virtual ~DeConv2d() {} virtual layerType_t getLayerType() { return LAYER_DECONV2D; }; diff --git a/src/Conv2d.cpp b/src/Conv2d.cpp index f984f67..18e907d 100644 --- a/src/Conv2d.cpp +++ b/src/Conv2d.cpp @@ -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, @@ -119,11 +121,10 @@ void Conv2d::inferCUDNN(dnnType* srcData, bool back) { 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, bool final, int groups) : LayerWgs(net, net->getOutputDim().c, out_ch, kernelH, kernelW, 1, - fname_weights, batchnorm, false, final) { - + fname_weights, batchnorm, false, final, deConv, groups) { this->kernelH = kernelH; this->kernelW = kernelW; this->strideH = strideH; @@ -131,6 +132,7 @@ Conv2d::Conv2d( Network *net, int out_ch, int kernelH, int kernelW, this->paddingH = paddingH; this->paddingW = paddingW; this->deConv = deConv; + this->groups = groups; if(!deConv) { output_dim.n = input_dim.n; diff --git a/src/DeformConv2d.cpp b/src/DeformConv2d.cpp index 8997593..40b6b9e 100644 --- a/src/DeformConv2d.cpp +++ b/src/DeformConv2d.cpp @@ -76,8 +76,8 @@ 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) ); diff --git a/src/LayerWgs.cpp b/src/LayerWgs.cpp index a18fd53..41ca038 100644 --- a/src/LayerWgs.cpp +++ b/src/LayerWgs.cpp @@ -8,8 +8,13 @@ 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 final, bool deConv, int groups) : Layer(net, final) { + + if(deConv) + inputs = inputs/groups; + else + outputs = outputs/groups; + this->inputs = inputs; this->outputs = outputs; this->weights_path = std::string(fname_weights); diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 0f2d621..2b7377d 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -245,6 +245,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, @@ -252,6 +253,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; Dims d = lRTconv->getOutput(0)->getDimensions(); From c695d8c5d7a94e1dff531272eb8e9ccd7db42289 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Wed, 5 Feb 2020 14:38:26 +0100 Subject: [PATCH 042/228] Implement CenterNet based on DLA34, CUDNN and TensorRT work. Signed-off-by: Davide Sapienza --- CMakeLists.txt | 3 + tests/dla34_cnet/dla34_cnet.cpp | 527 ++++++++++++++++++++++++++++++++ 2 files changed, 530 insertions(+) create mode 100644 tests/dla34_cnet/dla34_cnet.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e24df..e4a5b89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,9 @@ target_link_libraries(test_resnet101_cnet tkDNN) add_executable(test_dla34 tests/dla34/dla34.cpp) target_link_libraries(test_dla34 tkDNN) +add_executable(test_dla34_cnet tests/dla34_cnet/dla34_cnet.cpp) +target_link_libraries(test_dla34_cnet tkDNN) + ################################################################################ diff --git a/tests/dla34_cnet/dla34_cnet.cpp b/tests/dla34_cnet/dla34_cnet.cpp new file mode 100644 index 0000000..bccbc09 --- /dev/null +++ b/tests/dla34_cnet/dla34_cnet.cpp @@ -0,0 +1,527 @@ +#include +#include "tkdnn.h" + +const char *input_bin = "../tests/dla34_cnet/debug/input.bin"; +const char *conv1_bin = "../tests/dla34_cnet/layers/base-base_layer-0.bin"; +const char *conv2_bin = "../tests/dla34_cnet/layers/base-level0-0.bin"; +const char *conv3_bin = "../tests/dla34_cnet/layers/base-level1-0.bin"; +// s - stage, t - tree +const char *s1_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level2-tree1-conv1.bin"; +const char *s1_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level2-tree1-conv2.bin"; +const char *s1_t1_project = "../tests/dla34_cnet/layers/base-level2-project-0.bin"; +const char *s1_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level2-tree2-conv1.bin"; +const char *s1_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level2-tree2-conv2.bin"; +const char *s1_root_conv1_bin = "../tests/dla34_cnet/layers/base-level2-root-conv.bin"; +const char *s2_t1_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree1-tree1-conv1.bin"; +const char *s2_t1_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level3-tree1-tree1-conv2.bin"; +const char *s2_t1_t1_project = "../tests/dla34_cnet/layers/base-level3-tree1-project-0.bin"; +const char *s2_t1_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree1-tree2-conv1.bin"; +const char *s2_t1_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level3-tree1-tree2-conv2.bin"; +const char *s2_t1_root_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree1-root-conv.bin"; +const char *s2_t2_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree2-tree1-conv1.bin"; +const char *s2_t2_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level3-tree2-tree1-conv2.bin"; +const char *s2_t2_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree2-tree2-conv1.bin"; +const char *s2_t2_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level3-tree2-tree2-conv2.bin"; +const char *s2_t2_root_conv1_bin = "../tests/dla34_cnet/layers/base-level3-tree2-root-conv.bin"; +const char *s3_t1_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree1-tree1-conv1.bin"; +const char *s3_t1_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level4-tree1-tree1-conv2.bin"; +const char *s3_t1_t1_project = "../tests/dla34_cnet/layers/base-level4-tree1-project-0.bin"; +const char *s3_t1_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree1-tree2-conv1.bin"; +const char *s3_t1_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level4-tree1-tree2-conv2.bin"; +const char *s3_t1_root_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree1-root-conv.bin"; +const char *s3_t2_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree2-tree1-conv1.bin"; +const char *s3_t2_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level4-tree2-tree1-conv2.bin"; +const char *s3_t2_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree2-tree2-conv1.bin"; +const char *s3_t2_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level4-tree2-tree2-conv2.bin"; +const char *s3_t2_root_conv1_bin = "../tests/dla34_cnet/layers/base-level4-tree2-root-conv.bin"; +const char *s4_t1_conv1_bin = "../tests/dla34_cnet/layers/base-level5-tree1-conv1.bin"; +const char *s4_t1_conv2_bin = "../tests/dla34_cnet/layers/base-level5-tree1-conv2.bin"; +const char *s4_t1_project = "../tests/dla34_cnet/layers/base-level5-project-0.bin"; +const char *s4_t2_conv1_bin = "../tests/dla34_cnet/layers/base-level5-tree2-conv1.bin"; +const char *s4_t2_conv2_bin = "../tests/dla34_cnet/layers/base-level5-tree2-conv2.bin"; +const char *s4_root_conv1_bin = "../tests/dla34_cnet/layers/base-level5-root-conv.bin"; + +//final +// const char *fc_bin = "../tests/dla34_cnet/layers/output.bin"; + +const char *ida_0_p_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_0-proj_1-conv.bin"; +const char *ida_0_p_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_0-proj_1-conv-conv_offset_mask.bin"; +const char *ida_0_up_1_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_0-up_1.bin"; +const char *ida_0_n_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_0-node_1-conv.bin"; +const char *ida_0_n_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_0-node_1-conv-conv_offset_mask.bin"; + +const char *ida_1_p_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-proj_1-conv.bin"; +const char *ida_1_p_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-proj_1-conv-conv_offset_mask.bin"; +const char *ida_1_up_1_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-up_1.bin"; +const char *ida_1_n_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-node_1-conv.bin"; +const char *ida_1_n_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-node_1-conv-conv_offset_mask.bin"; +const char *ida_1_p_2_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-proj_2-conv.bin"; +const char *ida_1_p_2_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-proj_2-conv-conv_offset_mask.bin"; +const char *ida_1_up_2_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-up_2.bin"; +const char *ida_1_n_2_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-node_2-conv.bin"; +const char *ida_1_n_2_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_1-node_2-conv-conv_offset_mask.bin"; + +const char *ida_2_p_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_1-conv.bin"; +const char *ida_2_p_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_1-conv-conv_offset_mask.bin"; +const char *ida_2_up_1_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-up_1.bin"; +const char *ida_2_n_1_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_1-conv.bin"; +const char *ida_2_n_1_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_1-conv-conv_offset_mask.bin"; +const char *ida_2_p_2_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_2-conv.bin"; +const char *ida_2_p_2_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_2-conv-conv_offset_mask.bin"; +const char *ida_2_up_2_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-up_2.bin"; +const char *ida_2_n_2_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_2-conv.bin"; +const char *ida_2_n_2_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_2-conv-conv_offset_mask.bin"; +const char *ida_2_p_3_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_3-conv.bin"; +const char *ida_2_p_3_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-proj_3-conv-conv_offset_mask.bin"; +const char *ida_2_up_3_deconv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-up_3.bin"; +const char *ida_2_n_3_dcn_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_3-conv.bin"; +const char *ida_2_n_3_conv_bin = "../tests/dla34_cnet/layers/dla_up-ida_2-node_3-conv-conv_offset_mask.bin"; + +const char *ida_up_p_1_dcn_bin = "../tests/dla34_cnet/layers/ida_up-proj_1-conv.bin"; +const char *ida_up_p_1_conv_bin = "../tests/dla34_cnet/layers/ida_up-proj_1-conv-conv_offset_mask.bin"; +const char *ida_up_up_1_deconv_bin = "../tests/dla34_cnet/layers/ida_up-up_1.bin"; +const char *ida_up_n_1_dcn_bin = "../tests/dla34_cnet/layers/ida_up-node_1-conv.bin"; +const char *ida_up_n_1_conv_bin = "../tests/dla34_cnet/layers/ida_up-node_1-conv-conv_offset_mask.bin"; +const char *ida_up_p_2_dcn_bin = "../tests/dla34_cnet/layers/ida_up-proj_2-conv.bin"; +const char *ida_up_p_2_conv_bin = "../tests/dla34_cnet/layers/ida_up-proj_2-conv-conv_offset_mask.bin"; +const char *ida_up_up_2_deconv_bin = "../tests/dla34_cnet/layers/ida_up-up_2.bin"; +const char *ida_up_n_2_dcn_bin = "../tests/dla34_cnet/layers/ida_up-node_2-conv.bin"; +const char *ida_up_n_2_conv_bin = "../tests/dla34_cnet/layers/ida_up-node_2-conv-conv_offset_mask.bin"; + +const char *hm_conv1_bin = "../tests/dla34_cnet/layers/hm-0.bin"; +const char *hm_conv2_bin = "../tests/dla34_cnet/layers/hm-2.bin"; +const char *wh_conv1_bin = "../tests/dla34_cnet/layers/wh-0.bin"; +const char *wh_conv2_bin = "../tests/dla34_cnet/layers/wh-2.bin"; +const char *reg_conv1_bin = "../tests/dla34_cnet/layers/reg-0.bin"; +const char *reg_conv2_bin = "../tests/dla34_cnet/layers/reg-2.bin"; + +const char *output_bin[]={ +"../tests/dla34_cnet/debug/hm.bin", +"../tests/dla34_cnet/debug/wh.bin", +"../tests/dla34_cnet/debug/reg.bin"}; + +int main() +{ + + // Network layout + tk::dnn::dataDim_t dim(1, 3, 224, 224, 1); + tk::dnn::Network net(dim); + tk::dnn::Layer *last1, *last2, *last3, *last4; + tk::dnn::Layer *base1, *base2, *base3, *base4, *base5, *base6, *ida1, *ida2_1, *ida2_2, *ida3_1, *ida3_2, *ida3_3, *idaup_1, *idaup_2; + + tk::dnn::Conv2d conv1(&net, 16, 7, 7, 1, 1, 3, 3, conv1_bin, true); + tk::dnn::Activation relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d conv2(&net, 16, 3, 3, 1, 1, 1, 1, conv2_bin, true); + tk::dnn::Activation relu2(&net, CUDNN_ACTIVATION_RELU); + base1 = &relu2; + + tk::dnn::Conv2d conv3(&net, 32, 3, 3, 2, 2, 1, 1, conv3_bin, true); + tk::dnn::Activation relu3(&net, CUDNN_ACTIVATION_RELU); + base2 = &relu3; + + // level 2 + // tree 1 + tk::dnn::Conv2d s1_t1_conv1(&net, 64, 3, 3, 2, 2, 1, 1, s1_t1_conv1_bin, true); + tk::dnn::Activation s1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s1_t1_conv2(&net, 64, 3, 3, 1, 1, 1, 1, s1_t1_conv2_bin, true); + last2 = &s1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s1_t1_layers[1] = { base2 }; + tk::dnn::Route route_s1_t1(&net, route_s1_t1_layers, 1); + // downsample + tk::dnn::Pooling s1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + // project + tk::dnn::Conv2d s1_t1_residual1_conv1(&net, 64, 1, 1, 1, 1, 0, 0, s1_t1_project, true); + + tk::dnn::Shortcut s1_t1_s1(&net, last2); + tk::dnn::Activation s1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s1_t1_relu; + // tree 2 + tk::dnn::Conv2d s1_t2_conv1(&net, 64, 3, 3, 1, 1, 1, 1, s1_t2_conv1_bin, true); + tk::dnn::Activation s1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s1_t2_conv2(&net, 64, 3, 3, 1, 1, 1, 1, s1_t2_conv2_bin, true); + + tk::dnn::Shortcut s1_t2_s1(&net, last1); + tk::dnn::Activation s1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s1_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s1_root(&net, route_s1_root_layers, 2); + tk::dnn::Conv2d s1_root_conv1(&net, 64, 1, 1, 1, 1, 0, 0, s1_root_conv1_bin, true); + tk::dnn::Activation s1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + base3 = &s1_root_relu; + + // level 3 + // tree 1 + // tree 1 + tk::dnn::Conv2d s2_t1_t1_conv1(&net, 128, 3, 3, 2, 2, 1, 1, s2_t1_t1_conv1_bin, true); + tk::dnn::Activation s2_t1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t1_t1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t1_conv2_bin, true); + last2 = &s2_t1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s2_t1_t1_layers[1] = { base3 }; + tk::dnn::Route route_s2_t1_t1(&net, route_s2_t1_t1_layers, 1); + // downsample + tk::dnn::Pooling s2_t1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s2_t1_t1_maxpool1; + // project + tk::dnn::Conv2d s2_t1_t1_residual1_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t1_t1_project, true); + + tk::dnn::Shortcut s2_t1_t1_s1(&net, last2); + tk::dnn::Activation s2_t1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t1_t1_relu; + + // tree 2 + tk::dnn::Conv2d s2_t1_t2_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t2_conv1_bin, true); + tk::dnn::Activation s2_t1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t1_t2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t1_t2_conv2_bin, true); + + tk::dnn::Shortcut s2_t1_t2_s1(&net, last1); + tk::dnn::Activation s2_t1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s2_t1_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s2_t1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s2_t1_root(&net, route_s2_t1_root_layers, 2); + tk::dnn::Conv2d s2_t1_root_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t1_root_conv1_bin, true); + tk::dnn::Activation s2_t1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t1_root_relu; + last3 = &s2_t1_root_relu; + // tree 2 + // tree 1 + tk::dnn::Conv2d s2_t2_t1_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t1_conv1_bin, true); + tk::dnn::Activation s2_t2_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t2_t1_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t1_conv2_bin, true); + tk::dnn::Shortcut s2_t2_t1_s1(&net, last1); + tk::dnn::Activation s2_t2_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s2_t2_t1_relu; + + // tree 2 + tk::dnn::Conv2d s2_t2_t2_conv1(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t2_conv1_bin, true); + tk::dnn::Activation s2_t2_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s2_t2_t2_conv2(&net, 128, 3, 3, 1, 1, 1, 1, s2_t2_t2_conv2_bin, true); + + tk::dnn::Shortcut s2_t2_t2_s1(&net, last1); + tk::dnn::Activation s2_t2_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s2_t2_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s2_t2_root_layers[4] = { last2, last1, last4, last3}; + tk::dnn::Route route_s2_t2_root(&net, route_s2_t2_root_layers, 4); + tk::dnn::Conv2d s2_t2_root_conv1(&net, 128, 1, 1, 1, 1, 0, 0, s2_t2_root_conv1_bin, true); + tk::dnn::Activation s2_t2_root_relu(&net, CUDNN_ACTIVATION_RELU); + + base4 = &s2_t2_root_relu; + + // level 4 + // tree 1 + // tree 1 + tk::dnn::Conv2d s3_t1_t1_conv1(&net, 256, 3, 3, 2, 2, 1, 1, s3_t1_t1_conv1_bin, true); + tk::dnn::Activation s3_t1_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t1_t1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t1_conv2_bin, true); + last2 = &s3_t1_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s3_t1_t1_layers[1] = { base4 }; + tk::dnn::Route route_s3_t1_t1(&net, route_s3_t1_t1_layers, 1); + // downsample + tk::dnn::Pooling s3_t1_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s3_t1_t1_maxpool1; + // project + tk::dnn::Conv2d s3_t1_t1_residual1_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t1_t1_project, true); + + tk::dnn::Shortcut s3_t1_t1_s1(&net, last2); + tk::dnn::Activation s3_t1_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t1_t1_relu; + + // tree 2 + tk::dnn::Conv2d s3_t1_t2_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t2_conv1_bin, true); + tk::dnn::Activation s3_t1_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t1_t2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t1_t2_conv2_bin, true); + + tk::dnn::Shortcut s3_t1_t2_s1(&net, last1); + tk::dnn::Activation s3_t1_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s3_t1_t2_relu; + + // root + // join last1 and net in single input 256, 56, 56 + tk::dnn::Layer *route_s3_t1_root_layers[2] = { last2, last1 }; + tk::dnn::Route route_s3_t1_root(&net, route_s3_t1_root_layers, 2); + tk::dnn::Conv2d s3_t1_root_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t1_root_conv1_bin, true); + tk::dnn::Activation s3_t1_root_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t1_root_relu; + last3 = &s3_t1_root_relu; + // tree 2 + // tree 1 + tk::dnn::Conv2d s3_t2_t1_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t1_conv1_bin, true); + tk::dnn::Activation s3_t2_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t2_t1_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t1_conv2_bin, true); + tk::dnn::Shortcut s3_t2_t1_s1(&net, last1); + tk::dnn::Activation s3_t2_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s3_t2_t1_relu; + + // tree 2 + tk::dnn::Conv2d s3_t2_t2_conv1(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t2_conv1_bin, true); + tk::dnn::Activation s3_t2_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s3_t2_t2_conv2(&net, 256, 3, 3, 1, 1, 1, 1, s3_t2_t2_conv2_bin, true); + + tk::dnn::Shortcut s3_t2_t2_s1(&net, last1); + tk::dnn::Activation s3_t2_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s3_t2_t2_relu; + + // root + // join last1 and net in single input 256, 56, 56 + tk::dnn::Layer *route_s3_t2_root_layers[4] = { last2, last1, last4, last3}; + tk::dnn::Route route_s3_t2_root(&net, route_s3_t2_root_layers, 4); + tk::dnn::Conv2d s3_t2_root_conv1(&net, 256, 1, 1, 1, 1, 0, 0, s3_t2_root_conv1_bin, true); + tk::dnn::Activation s3_t2_root_relu(&net, CUDNN_ACTIVATION_RELU); + + base5 = &s3_t2_root_relu; + + // level 5 + // tree 1 + tk::dnn::Conv2d s4_t1_conv1(&net, 512, 3, 3, 2, 2, 1, 1, s4_t1_conv1_bin, true); + tk::dnn::Activation s4_t1_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s4_t1_conv2(&net, 512, 3, 3, 1, 1, 1, 1, s4_t1_conv2_bin, true); + last2 = &s4_t1_conv2; + + // get the basicblock input and apply maxpool conv2d and relu + tk::dnn::Layer *route_s4_t1_layers[1] = { base5 }; + tk::dnn::Route route_s4_t1(&net, route_s4_t1_layers, 1); + // downsample + tk::dnn::Pooling s4_t1_maxpool1(&net, 2, 2, 2, 2, 0, 0, tk::dnn::POOLING_MAX); + last4 = &s4_t1_maxpool1; + // project + tk::dnn::Conv2d s4_t1_residual1_conv1(&net, 512, 1, 1, 1, 1, 0, 0, s4_t1_project, true); + + tk::dnn::Shortcut s4_t1_s1(&net, last2); + tk::dnn::Activation s4_t1_relu(&net, CUDNN_ACTIVATION_RELU); + + last1 = &s4_t1_relu; + + // tree 2 + tk::dnn::Conv2d s4_t2_conv1(&net, 512, 3, 3, 1, 1, 1, 1, s4_t2_conv1_bin, true); + tk::dnn::Activation s4_t2_relu1(&net, CUDNN_ACTIVATION_RELU); + + tk::dnn::Conv2d s4_t2_conv2(&net, 512, 3, 3, 1, 1, 1, 1, s4_t2_conv2_bin, true); + + tk::dnn::Shortcut s4_t2_s1(&net, last1); + tk::dnn::Activation s4_t2_relu(&net, CUDNN_ACTIVATION_RELU); + last2 = &s4_t2_relu; + + // root + // join last1 and net in single input 128, 56, 56 + tk::dnn::Layer *route_s4_root_layers[3] = { last2, last1, last4 }; + tk::dnn::Route route_s4_root(&net, route_s4_root_layers, 3); + tk::dnn::Conv2d s4_root_conv1(&net, 512, 1, 1, 1, 1, 0, 0, s4_root_conv1_bin, true); + tk::dnn::Activation s4_root_relu(&net, CUDNN_ACTIVATION_RELU); + + base6 = &s4_root_relu; + + //final + // tk::dnn::Pooling avgpool(&net, 7, 7, 7, 7, 0, 0, tk::dnn::POOLING_AVERAGE); + // tk::dnn::Dense fc(&net, 1000, fc_bin); + + //ida 0 + tk::dnn::DeformConv2d ida_0_p_1_dcn(&net, 256, 1, 3, 3, 1, 1, 1, 1, ida_0_p_1_dcn_bin, ida_0_p_1_conv_bin, true); + tk::dnn::Activation ida_0_p_1_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_0_up_1_deconv(&net, 256, 4, 4, 2, 2, 1, 1, ida_0_up_1_deconv_bin, false, 256); + tk::dnn::Shortcut ida_0_shortcut(&net, base5); + tk::dnn::DeformConv2d ida_0_n_1_dcn(&net, 256, 1, 3, 3, 1, 1, 1, 1, ida_0_n_1_dcn_bin, ida_0_n_1_conv_bin, true); + tk::dnn::Activation ida_0_n_1_relu(&net, CUDNN_ACTIVATION_RELU); + ida1 = &ida_0_n_1_relu; + + //ida1-1 + tk::dnn::Layer *route_ida1_layers_1[1] = { base5 }; + tk::dnn::Route route_ida1_1(&net, route_ida1_layers_1, 1); + + tk::dnn::DeformConv2d ida_1_p_1_dcn(&net, 128, 1, 3, 3, 1, 1, 1, 1, ida_1_p_1_dcn_bin, ida_1_p_1_conv_bin, true); + tk::dnn::Activation ida_1_p_1_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_1_up_1_deconv(&net, 128, 4, 4, 2, 2, 1, 1, ida_1_up_1_deconv_bin, false, 128); + tk::dnn::Shortcut ida_1_shortcut1(&net, base4); + tk::dnn::DeformConv2d ida_1_n_1_dcn(&net, 128, 1, 3, 3, 1, 1, 1, 1, ida_1_n_1_dcn_bin, ida_1_n_1_conv_bin, true); + tk::dnn::Activation ida_1_n_1_relu(&net, CUDNN_ACTIVATION_RELU); + ida2_1 = &ida_1_n_1_relu; + + //ida1-2 + tk::dnn::Layer *route_ida1_layers_2[1] = { ida1 }; + tk::dnn::Route route_ida1_2(&net, route_ida1_layers_2, 1); + + tk::dnn::DeformConv2d ida_1_p_2_dcn(&net, 128, 1, 3, 3, 1, 1, 1, 1, ida_1_p_2_dcn_bin, ida_1_p_2_conv_bin, true); + tk::dnn::Activation ida_1_p_2_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_1_up_2_deconv(&net, 128, 4, 4, 2, 2, 1, 1, ida_1_up_2_deconv_bin, false, 128); + tk::dnn::Shortcut ida_1_shortcut2(&net, ida2_1); + tk::dnn::DeformConv2d ida_1_n_2_dcn(&net, 128, 1, 3, 3, 1, 1, 1, 1, ida_1_n_2_dcn_bin, ida_1_n_2_conv_bin, true); + tk::dnn::Activation ida_1_n_2_relu(&net, CUDNN_ACTIVATION_RELU); + ida2_2 = &ida_1_n_2_relu; + + //ida2-1 + tk::dnn::Layer *route_ida2_layers_1[1] = { base4 }; + tk::dnn::Route route_ida2_1(&net, route_ida2_layers_1, 1); + + tk::dnn::DeformConv2d ida_2_p_1_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_p_1_dcn_bin, ida_2_p_1_conv_bin, true); + tk::dnn::Activation ida_2_p_1_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_2_up_1_deconv(&net, 64, 4, 4, 2, 2, 1, 1, ida_2_up_1_deconv_bin, false, 64); + tk::dnn::Shortcut ida_2_shortcut1(&net, base3); + tk::dnn::DeformConv2d ida_2_n_1_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_n_1_dcn_bin, ida_2_n_1_conv_bin, true); + tk::dnn::Activation ida_2_n_1_relu(&net, CUDNN_ACTIVATION_RELU); + ida3_1 = &ida_2_n_1_relu; + + //ida2-2 + tk::dnn::Layer *route_ida2_layers_2[1] = { ida2_1 }; + tk::dnn::Route route_ida2_2(&net, route_ida2_layers_2, 1); + + tk::dnn::DeformConv2d ida_2_p_2_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_p_2_dcn_bin, ida_2_p_2_conv_bin, true); + tk::dnn::Activation ida_2_p_2_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_2_up_2_deconv(&net, 64, 4, 4, 2, 2, 1, 1, ida_2_up_2_deconv_bin, false, 64); + tk::dnn::Shortcut ida_2_shortcut2(&net, ida3_1); + tk::dnn::DeformConv2d ida_2_n_2_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_n_2_dcn_bin, ida_2_n_2_conv_bin, true); + tk::dnn::Activation ida_2_n_2_relu(&net, CUDNN_ACTIVATION_RELU); + ida3_2 = &ida_2_n_2_relu; + + //ida2-3 + tk::dnn::Layer *route_ida2_layers_3[1] = { ida2_2 }; + tk::dnn::Route route_ida2_3(&net, route_ida2_layers_3, 1); + + tk::dnn::DeformConv2d ida_2_p_3_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_p_3_dcn_bin, ida_2_p_3_conv_bin, true); + tk::dnn::Activation ida_2_p_3_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d ida_2_up_3_deconv(&net, 64, 4, 4, 2, 2, 1, 1, ida_2_up_3_deconv_bin, false, 64); + tk::dnn::Shortcut ida_2_shortcut3(&net, ida3_2); + tk::dnn::DeformConv2d ida_2_n_3_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_2_n_3_dcn_bin, ida_2_n_3_conv_bin, true); + tk::dnn::Activation ida_2_n_3_relu(&net, CUDNN_ACTIVATION_RELU); + ida3_3 = &ida_2_n_3_relu; + + //idaup-1 + tk::dnn::Layer *route_idaup_layers_1[1] = { ida2_2 }; + tk::dnn::Route route_idaup_1(&net, route_idaup_layers_1, 1); + + tk::dnn::DeformConv2d idaup_p_1_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_up_p_1_dcn_bin, ida_up_p_1_conv_bin, true); + tk::dnn::Activation idaup_p_1_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d idaup_up_1_deconv(&net, 64, 4, 4, 2, 2, 1, 1, ida_up_up_1_deconv_bin, false, 64); + tk::dnn::Shortcut idaup_shortcut1(&net, ida3_3); + tk::dnn::DeformConv2d idaup_n_1_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_up_n_1_dcn_bin, ida_up_n_1_conv_bin, true); + tk::dnn::Activation idaup_n_1_relu(&net, CUDNN_ACTIVATION_RELU); + idaup_1 = &idaup_n_1_relu; + + //idaup-2 + tk::dnn::Layer *route_idaup_layers_2[1] = { ida1 }; + tk::dnn::Route route_idaup_2(&net, route_idaup_layers_2, 1); + + tk::dnn::DeformConv2d idaup_p_2_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_up_p_2_dcn_bin, ida_up_p_2_conv_bin, true); + tk::dnn::Activation idaup_p_2_relu(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::DeConv2d idaup_up_2_deconv(&net, 64, 8, 8, 4, 4, 2, 2, ida_up_up_2_deconv_bin, false, 64); + tk::dnn::Shortcut idaup_shortcut2(&net, idaup_1); + tk::dnn::DeformConv2d idaup_n_2_dcn(&net, 64, 1, 3, 3, 1, 1, 1, 1, ida_up_n_2_dcn_bin, ida_up_n_2_conv_bin, true); + tk::dnn::Activation idaup_n_2_relu(&net, CUDNN_ACTIVATION_RELU); + idaup_2 = &idaup_n_2_relu; + + tk::dnn::Layer *route_1_0_layers[1] = { idaup_2 }; + + // hm + tk::dnn::Conv2d *hm_conv1 = new tk::dnn::Conv2d(&net, 256, 3, 3, 1, 1, 1, 1, hm_conv1_bin, false); + tk::dnn::Activation *hm_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *hm = new tk::dnn::Conv2d(&net, 80, 1, 1, 1, 1, 0, 0, hm_conv2_bin, false, false, true); + int kernel = 3; + int pad = (kernel - 1)/2; + tk::dnn::Activation *hm_sig = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_SIGMOID); + tk::dnn::Pooling *hmax = new tk::dnn::Pooling(&net, kernel, kernel, 1, 1, pad, pad, tk::dnn::POOLING_MAX, true); + + // // wh + tk::dnn::Route *route_1_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *wh_conv1 = new tk::dnn::Conv2d(&net, 256, 3, 3, 1, 1, 1, 1, wh_conv1_bin, false); + tk::dnn::Activation *wh_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *wh = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, wh_conv2_bin, false, false, true); + + // // reg + tk::dnn::Route *route_2_0 = new tk::dnn::Route(&net, route_1_0_layers, 1); + tk::dnn::Conv2d *reg_conv1 = new tk::dnn::Conv2d(&net, 256, 3, 3, 1, 1, 1, 1, reg_conv1_bin, false); + tk::dnn::Activation *reg_relu1 = new tk::dnn::Activation(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d *reg = new tk::dnn::Conv2d(&net, 2, 1, 1, 1, 1, 0, 0, reg_conv2_bin, false, false, true); + + + // Load input + dnnType *data; + dnnType *input_h; + readBinaryFile(input_bin, dim.tot(), &input_h, &data); + //printDeviceVector(64, data, true); + + //print network model + net.print(); + + //convert network to tensorRT + tk::dnn::NetworkRT netRT(&net, "dla34_cnet.rt"); + + tk::dnn::dataDim_t dim1 = dim; //input dim + printCenteredTitle(" CUDNN inference ", '=', 30); + { + dim1.print(); + TIMER_START + net.infer(dim1, data); + TIMER_STOP + dim1.print(); + } + + tk::dnn::dataDim_t dim2 = dim; + printCenteredTitle(" TENSORRT inference ", '=', 30); + { + dim2.print(); + TIMER_START + netRT.infer(dim2, data); + TIMER_STOP + dim2.print(); + } + + tk::dnn::Layer *outs[3] = { hm, wh, reg }; + int out_count = 1; + for(int i=0; i<3; i++) { + printCenteredTitle((std::string(" RESNET CHECK RESULTS ") + std::to_string(i) + " ").c_str(), '=', 30); + + outs[i]->output_dim.print(); + + dnnType *out, *out_h; + int odim = outs[i]->output_dim.tot(); + readBinaryFile(output_bin[i], odim, &out_h, &out); + + dnnType *cudnn_out, *rt_out; + cudnn_out = outs[i]->dstData; + rt_out = (dnnType *)netRT.buffersRT[i+out_count]; + // there is the maxpool. It isn't an output but it is necessary for the process section + if(i==0) + out_count ++; + + std::cout << "CUDNN vs correct"; + checkResult(odim, cudnn_out, out); + std::cout << "TRT vs correct"; + checkResult(odim, rt_out, out); + std::cout << "CUDNN vs TRT "; + checkResult(odim, cudnn_out, rt_out); + } + + return 0; +} From d8eeb36d4b6f423bcf01549111205a05aa262919 Mon Sep 17 00:00:00 2001 From: xavier Date: Wed, 5 Feb 2020 18:39:13 +0100 Subject: [PATCH 043/228] Add mAP computation and demo Signed-off-by: xavier --- CMakeLists.txt | 3 + demo/demo/map.cpp | 434 ++++++++++++++++++++++++++++++++++++++++++ include/tkDNN/Layer.h | 2 +- 3 files changed, 438 insertions(+), 1 deletion(-) create mode 100644 demo/demo/map.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e24df..eae11be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,9 @@ target_link_libraries(yolo3_demo tkDNN) add_executable(centernet_demo demo/demo/demo_centernet.cpp) target_link_libraries(centernet_demo tkDNN) +add_executable(map_demo demo/demo/map.cpp) +target_link_libraries(map_demo tkDNN) + #------------------------------------------------------------------------------- # Install diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp new file mode 100644 index 0000000..15825f7 --- /dev/null +++ b/demo/demo/map.cpp @@ -0,0 +1,434 @@ + +#include +#include +#include /* srand, rand */ +#include +#include +#include "utils.h" + +#include +#include +#include +#include + +#include "Yolo3Detection.h" +#include "CenternetDetection.h" + +#include + +struct BoundigBox : public tk::dnn::box +{ + friend std::ostream& operator<<(std::ostream& os, const BoundigBox& bb); + int unique_truth_index = -1; + int truth_flag = 0; +}; + +bool boxComparison (const BoundigBox& a,const BoundigBox& b) +{ + return (a.prob>b.prob); +} + + +std::ostream& operator<<(std::ostream& os, const BoundigBox& bb) +{ + os <<"w: "<< bb.w << ", h: "<< bb.h << ", x: "<< bb.x << ", y: "<< bb.y << + ", cat: "<< bb.cl << ", conf: "<< bb.prob<< ", truth: "<< + bb.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<<"\n"; + return os; +} + +struct Frame +{ + void print() const + { + std::cout<<"labels filename: "< gt; + std::vector det; +}; + +void convertFilename(std::string &filename,const std::string l_folder, const std::string i_folder, const std::string l_ext,const std::string i_ext) +{ + filename.replace(filename.find(l_folder),l_folder.length(),i_folder); + filename.replace(filename.find(l_ext),l_ext.length(),i_ext); +} + +float overlap(float x1, float w1, float x2, float w2) +{ + float l1 = x1 - w1/2; + float l2 = x2 - w2/2; + float left = l1 > l2 ? l1 : l2; + float r1 = x1 + w1/2; + float r2 = x2 + w2/2; + float right = r1 < r2 ? r1 : r2; + return right - left; +} + +float boxIntersection(const BoundigBox &a, const BoundigBox &b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + if(w < 0 || h < 0) + return 0; + float area = w*h; + return area; +} + +float boxUnion(const BoundigBox &a, const BoundigBox &b) +{ + float i = boxIntersection(a, b); + float u = a.w*a.h + b.w*b.h - i; + return u; +} + +float boxIoU(const BoundigBox &a, const BoundigBox &b) +{ + float I = boxIntersection(a, b); + // std::cout<<"I: "< &images,const int classes,const int IoU_thresh, const int map_points, const bool verbose=false) +{ + std::cout<<"Computing mAP"< truth_classes_count(classes,0); + std::vector dets_classes_count(classes,0); + // std::vector avg_iou_per_class(classes,0); + // std::vector tp_for_thresh_per_class(classes,0); + // std::vector fp_for_thresh_per_class(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(); + } + + std::cout<<"gt_count: "< all_dets; + std::vector all_gts; + + int gt_checked = 0; + + // for each detection comput IoU with groundtruth and match detetcion and + // groundtruth with IoU greater than IoU_thresh + for(auto &img:images) + { + for(size_t i=0; i 0) + { + float maxIoU = 0; + int truth_index = -1; + for(size_t j=0; j maxIoU && img.det[i].cl == img.gt[j].cl) + { + maxIoU = currentIoU; + truth_index = j; + } + } + // std::cout<<"det i:"< -1 && maxIoU > IoU_thresh) + { + img.det[i].unique_truth_index = truth_index + gt_checked; + img.det[i].truth_flag = 1; + } + } + + 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 truth_flags(groundtruths_count,0); + + if(verbose) + for(auto d:all_dets) + std::cout<> pr( classes, std::vector(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].truth_flag == 1 && truth_flags[all_dets[rank].unique_truth_index] == 0) + { + truth_flags[all_dets[rank].unique_truth_index] = 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 "<= 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; + } + + std::cout<<"Class: "< 1) + net = argv[1]; + char *labels_path = "/media/887E650E7E64F67A/val2014/all_labels.txt"; + if(argc > 2) + labels_path = argv[2]; + + networkType_t ntype = YOLO; + bool show = false; + + tk::dnn::Yolo3Detection yolo; + tk::dnn::CenternetDetection cnet; + + switch(ntype) + { + case YOLO: + yolo.init(net); + break; + case CENTERNET: + cnet.init(net); + break; + default: + FatalError("Network type not allowed "); + } + + std::ifstream all_labels(labels_path); + std::string l_filename; + std::vector images; + + std::cout<<"Reading groundtruth and generating detections"< detected_bbox; + switch(ntype) + { + case YOLO: + yolo.update(dnn_input); + detected_bbox = yolo.detected; + break; + case CENTERNET: + cnet.update(dnn_input); + detected_bbox = cnet.detected; + break; + default: + FatalError("Network type not allowed "); + } + + // save detections labels + for(auto d:detected_bbox) + { + //convert detected bb in the same format as label + /// / / / + BoundigBox 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); + + if(show)// draw rectangle for detection + cv::rectangle(frame, cv::Point(d.x, d.y), cv::Point(d.x + d.w, d.y + d.h), cv::Scalar(255, 0, 0), 2); + } + + // read and save groundtruth labels + std::ifstream labels(l_filename); + for(std::string line; std::getline(labels, line); ) + { + std::istringstream in(line); + BoundigBox b; + in >> b.cl >> b.x >> b.y >> b.w >> b.h; + b.prob = 1; + b.truth_flag = 1; + f.gt.push_back(b); + + if(show)// draw rectangle for groundtruth + cv::rectangle(frame, cv::Point((b.x-b.w/2)*width, (b.y-b.h/2)*height), cv::Point((b.x+b.w/2)*width,(b.y+b.h/2)*height), cv::Scalar(0, 255, 0), 2); + } + + images.push_back(f); + + if(show) + { + cv::imshow("detection", frame); + cv::waitKey(0); + } + } + + std::cout<<"Done."< Date: Thu, 6 Feb 2020 18:08:06 +0100 Subject: [PATCH 044/228] Change CenterNet input dimension. This commit changes the image input dimension, it updates the CenterNet detection class. Signed-off-by: Davide Sapienza --- include/tkDNN/CenternetDetection.h | 6 +++--- src/CenternetDetection.cpp | 17 +++++++++++------ src/DeformConv2d.cpp | 9 ++++++--- tests/dla34_cnet/dla34_cnet.cpp | 2 +- tests/resnet101_cnet/resnet101_cnet.cpp | 2 +- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/tkDNN/CenternetDetection.h b/include/tkDNN/CenternetDetection.h index 46af73b..1868839 100644 --- a/include/tkDNN/CenternetDetection.h +++ b/include/tkDNN/CenternetDetection.h @@ -73,14 +73,14 @@ class CenternetDetection { //processing float toll = 0.000001; int K = 100; - int width = 56; // TODO + int width = 128;//56; // TODO public: dnnType *rt_out[4]; - float inp_height = 224;//512; - float inp_width = 224;//512; + float inp_height = 512;//224;//512; + float inp_width = 512;//224;//512; int classes = 80; int num = 0; diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp index fbc9832..c6c4bc7 100644 --- a/src/CenternetDetection.cpp +++ b/src/CenternetDetection.cpp @@ -18,7 +18,7 @@ bool CenternetDetection::init(std::string tensor_path) { 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); + dim = tk::dnn::dataDim_t(1, 3, 512, 512, 1); const char *coco_class_name_[] = { "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light", "fire hydrant", @@ -43,9 +43,12 @@ bool CenternetDetection::init(std::string tensor_path) { 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); - 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, 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)) ); @@ -93,6 +96,8 @@ bool CenternetDetection::init(std::string tensor_path) { mean << 0.408, 0.447, 0.47; stddev << 0.289, 0.274, 0.278; + // mean << 0.485, 0.456, 0.406; + // stddev << 0.229, 0.224, 0.225; } void CenternetDetection::testdog() { @@ -104,8 +109,8 @@ void CenternetDetection::testdog() { imageORIG.convertTo(imageF, CV_32FC3, 1/255.0); sz = imageF.size(); std::cout<<"image: "< Date: Thu, 6 Feb 2020 23:09:12 +0100 Subject: [PATCH 045/228] Fix memory leak This commit moves cublasCreate out from dcn_v2_cuda_forward to save some milliseconds and it adds cublasDestroy (cause of memory leak). Signed-off-by: Davide Sapienza --- include/tkDNN/Layer.h | 3 +++ include/tkDNN/kernels.h | 3 ++- include/tkDNN/pluginsRT/DeformableConvRT.h | 18 ++++++++++++++++-- src/DeformConv2d.cpp | 11 +++++++++-- src/NetworkRT.cpp | 2 +- src/kernels/deformable_conv.cu | 12 +++--------- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 7716393..f9da061 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -229,6 +229,9 @@ public: dnnType *offset, *mask; dnnType *output_conv; + cublasStatus_t stat; + cublasHandle_t handle; + protected: cudnnTensorDescriptor_t biasTensorDesc; diff --git a/include/tkDNN/kernels.h b/include/tkDNN/kernels.h index d7d5d05..94c5dcb 100644 --- a/include/tkDNN/kernels.h +++ b/include/tkDNN/kernels.h @@ -38,7 +38,8 @@ void modulated_deformable_im2col_cuda(cudaStream_t stream, 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 dcn_v2_cuda_forward(cublasStatus_t stat, cublasHandle_t handle, + float *input, float *weight, float *bias, float *ones, float *offset, float *mask, float *output, float *columns, diff --git a/include/tkDNN/pluginsRT/DeformableConvRT.h b/include/tkDNN/pluginsRT/DeformableConvRT.h index dca1020..f4d0b30 100644 --- a/include/tkDNN/pluginsRT/DeformableConvRT.h +++ b/include/tkDNN/pluginsRT/DeformableConvRT.h @@ -52,10 +52,21 @@ 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) { + printf ("CUBLAS initialization failed\n"); + return; + } } ~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 { @@ -100,7 +111,8 @@ public: activationSIGMOIDForward(mask, mask, chunk_dim); // deformable convolution - dcn_v2_cuda_forward(srcData, data_d, + dcn_v2_cuda_forward(stat, handle, + srcData, data_d, bias2_d, ones_d1, offset, mask, reinterpret_cast(outputs[0]), ones_d2, @@ -172,6 +184,8 @@ public: free(aus); } + 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; diff --git a/src/DeformConv2d.cpp b/src/DeformConv2d.cpp index 957ef24..8cf1a6d 100644 --- a/src/DeformConv2d.cpp +++ b/src/DeformConv2d.cpp @@ -9,6 +9,11 @@ namespace tk { namespace dnn { void DeformConv2d::initCUDNN() { + stat = cublasCreate(&handle); + if (stat != CUBLAS_STATUS_SUCCESS) { + printf ("CUBLAS initialization failed\n"); + return; + } checkCUDNN( cudnnCreateTensorDescriptor(&biasTensorDesc) ); checkCUDNN( cudnnSetTensor4dDescriptor(biasTensorDesc, net->tensorFormat, net->dataType, @@ -84,6 +89,7 @@ DeformConv2d::~DeformConv2d() { checkCuda( cudaFree(offset) ); checkCuda( cudaFree(mask) ); checkCuda( cudaFree(output_conv) ); + cublasDestroy(handle); } dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) { @@ -95,9 +101,10 @@ dnnType* DeformConv2d::infer(dataDim_t &dim, dnnType* srcData) { 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, this->data_d, + dcn_v2_cuda_forward(stat, handle, + srcData, this->data_d, this->bias2_d, ones_d1, offset, mask, dstData, ones_d2, diff --git a/src/NetworkRT.cpp b/src/NetworkRT.cpp index 2b7377d..5162d48 100644 --- a/src/NetworkRT.cpp +++ b/src/NetworkRT.cpp @@ -453,7 +453,7 @@ ILayer* NetworkRT::convert_layer(ITensor *input, DeformConv2d *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) { diff --git a/src/kernels/deformable_conv.cu b/src/kernels/deformable_conv.cu index cb9ded0..0579620 100644 --- a/src/kernels/deformable_conv.cu +++ b/src/kernels/deformable_conv.cu @@ -138,7 +138,8 @@ void modulated_deformable_im2col_cuda(cudaStream_t stream, } -void dcn_v2_cuda_forward(float *input, float *weight, +void dcn_v2_cuda_forward(cublasStatus_t stat, cublasHandle_t handle, + float *input, float *weight, float *bias, float *ones, float *offset, float *mask, float *output, float *columns, @@ -151,14 +152,7 @@ void dcn_v2_cuda_forward(float *input, float *weight, 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 channels = in_c; const int height = in_h; const int width = in_w; From f32d8a859bb9739864f055f713038b05e2fc89a6 Mon Sep 17 00:00:00 2001 From: xavier Date: Fri, 7 Feb 2020 09:09:40 +0100 Subject: [PATCH 046/228] Add mAP 0.5:0.95, other small fix Signed-off-by: xavier --- demo/demo/map.cpp | 73 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index 15825f7..8e4ec3f 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -21,6 +21,14 @@ struct BoundigBox : public tk::dnn::box friend std::ostream& operator<<(std::ostream& os, const BoundigBox& bb); int unique_truth_index = -1; int truth_flag = 0; + float max_IoU = 0; + + void clear() + { + unique_truth_index = -1; + truth_flag = 0; + max_IoU = 0; + } }; bool boxComparison (const BoundigBox& a,const BoundigBox& b) @@ -33,7 +41,8 @@ std::ostream& operator<<(std::ostream& os, const BoundigBox& bb) { os <<"w: "<< bb.w << ", h: "<< bb.h << ", x: "<< bb.x << ", y: "<< bb.y << ", cat: "<< bb.cl << ", conf: "<< bb.prob<< ", truth: "<< - bb.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<<"\n"; + bb.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<< + ", maxIoU: "<< bb.max_IoU<<"\n"; return os; } @@ -111,7 +120,7 @@ struct PR } }; -double computeMap(std::vector &images,const int classes,const int IoU_thresh, const int map_points, const bool verbose=false) +double computeMap(std::vector &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose=false) { std::cout<<"Computing mAP"< &images,const int classes,const int IoU_thr // std::cout<<"det i:"< -1 && maxIoU > IoU_thresh) { + // std::cout<<"(INSIDE) IoU thresh:"< IoU_thresh:"<<(maxIoU > IoU_thresh)< &images,const int classes,const int IoU_thr mean_average_precision = mean_average_precision / classes; - std::cout<<"Classes: "< 1) net = argv[1]; - char *labels_path = "/media/887E650E7E64F67A/val2014/all_labels.txt"; + char type = 'y'; if(argc > 2) - labels_path = argv[2]; + type = argv[2][0]; + char *labels_path = "/media/887E650E7E64F67A/val2017/all_labels2017.txt"; + if(argc > 3) + labels_path = argv[3]; + + + networkType_t ntype; + switch(type) + { + case 'y': + ntype = YOLO; + break; + case 'c': + ntype = CENTERNET; + break; + default: + FatalError("type not allowed (3rd parameter)"); + } - networkType_t ntype = YOLO; bool show = false; tk::dnn::Yolo3Detection yolo; @@ -342,8 +369,10 @@ int main(int argc, char *argv[]) if(show) cv::namedWindow("detection", cv::WINDOW_NORMAL); + std::vector detected_bbox; + int i=0; - while (std::getline(all_labels, l_filename) && i < 1000) + while (std::getline(all_labels, l_filename)) // && i < 1000) { Frame f; f.l_filename = l_filename; @@ -363,7 +392,9 @@ int main(int argc, char *argv[]) dnn_input = frame.clone(); //inference - std::vector detected_bbox; + + detected_bbox.clear(); + switch(ntype) { case YOLO: @@ -378,6 +409,9 @@ int main(int argc, char *argv[]) FatalError("Network type not allowed "); } + // std::ofstream myfile; + // myfile.open ("det/"+f.l_filename.substr(l_filename.find("000"))); + // save detections labels for(auto d:detected_bbox) { @@ -392,10 +426,14 @@ int main(int argc, char *argv[]) b.cl = d.cl; f.det.push_back(b); + // myfile << d.cl << " "<< d.prob << " "<< d.x << " "<< d.y << " "<< d.w << " "<< d.h <<"\n"; + if(show)// draw rectangle for detection - cv::rectangle(frame, cv::Point(d.x, d.y), cv::Point(d.x + d.w, d.y + d.h), cv::Scalar(255, 0, 0), 2); + cv::rectangle(frame, cv::Point(d.x, d.y), cv::Point(d.x + d.w, d.y + d.h), cv::Scalar(0, 0, 255), 2); } + // myfile.close(); + // read and save groundtruth labels std::ifstream labels(l_filename); for(std::string line; std::getline(labels, line); ) @@ -423,11 +461,24 @@ int main(int argc, char *argv[]) std::cout<<"Done."< -struct BoundigBox : public tk::dnn::box -{ - friend std::ostream& operator<<(std::ostream& os, const BoundigBox& bb); - int unique_truth_index = -1; - int truth_flag = 0; - float max_IoU = 0; - - void clear() - { - unique_truth_index = -1; - truth_flag = 0; - max_IoU = 0; - } -}; - -bool boxComparison (const BoundigBox& a,const BoundigBox& b) -{ - return (a.prob>b.prob); -} - - -std::ostream& operator<<(std::ostream& os, const BoundigBox& bb) -{ - os <<"w: "<< bb.w << ", h: "<< bb.h << ", x: "<< bb.x << ", y: "<< bb.y << - ", cat: "<< bb.cl << ", conf: "<< bb.prob<< ", truth: "<< - bb.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<< - ", maxIoU: "<< bb.max_IoU<<"\n"; - return os; -} - -struct Frame -{ - void print() const - { - std::cout<<"labels filename: "< gt; - std::vector det; -}; - void convertFilename(std::string &filename,const std::string l_folder, const std::string i_folder, const std::string l_ext,const std::string i_ext) { filename.replace(filename.find(l_folder),l_folder.length(),i_folder); filename.replace(filename.find(l_ext),l_ext.length(),i_ext); } -float overlap(float x1, float w1, float x2, float w2) -{ - float l1 = x1 - w1/2; - float l2 = x2 - w2/2; - float left = l1 > l2 ? l1 : l2; - float r1 = x1 + w1/2; - float r2 = x2 + w2/2; - float right = r1 < r2 ? r1 : r2; - return right - left; -} - -float boxIntersection(const BoundigBox &a, const BoundigBox &b) -{ - float w = overlap(a.x, a.w, b.x, b.w); - float h = overlap(a.y, a.h, b.y, b.h); - if(w < 0 || h < 0) - return 0; - float area = w*h; - return area; -} - -float boxUnion(const BoundigBox &a, const BoundigBox &b) -{ - float i = boxIntersection(a, b); - float u = a.w*a.h + b.w*b.h - i; - return u; -} - -float boxIoU(const BoundigBox &a, const BoundigBox &b) -{ - float I = boxIntersection(a, b); - // std::cout<<"I: "< &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose=false) -{ - std::cout<<"Computing mAP"< truth_classes_count(classes,0); - std::vector dets_classes_count(classes,0); - // std::vector avg_iou_per_class(classes,0); - // std::vector tp_for_thresh_per_class(classes,0); - // std::vector fp_for_thresh_per_class(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(); - } - - std::cout<<"gt_count: "< all_dets; - std::vector all_gts; - - int gt_checked = 0; - - // for each detection comput IoU with groundtruth and match detetcion and - // groundtruth with IoU greater than IoU_thresh - for(auto &img:images) - { - for(size_t i=0; i 0) - { - float maxIoU = 0; - int truth_index = -1; - for(size_t j=0; j maxIoU && img.det[i].cl == img.gt[j].cl) - { - maxIoU = currentIoU; - truth_index = j; - } - } - // std::cout<<"det i:"< -1 && maxIoU > IoU_thresh) - { - // std::cout<<"(INSIDE) IoU thresh:"< IoU_thresh:"<<(maxIoU > IoU_thresh)< truth_flags(groundtruths_count,0); - - if(verbose) - for(auto d:all_dets) - std::cout<> pr( classes, std::vector(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].truth_flag == 1 && truth_flags[all_dets[rank].unique_truth_index] == 0) - { - truth_flags[all_dets[rank].unique_truth_index] = 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 "<= 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; - } - - std::cout<<"Class: "< 1) net = argv[1]; - char type = 'y'; + char ntype = 'y'; if(argc > 2) - type = argv[2][0]; + ntype = argv[2][0]; + //path to txt file with all realpath of images labels char *labels_path = "/media/887E650E7E64F67A/val2017/all_labels2017.txt"; if(argc > 3) labels_path = argv[3]; - - networkType_t ntype; - switch(type) - { - case 'y': - ntype = YOLO; - break; - case 'c': - ntype = CENTERNET; - break; - default: - FatalError("type not allowed (3rd parameter)"); - } - bool show = false; + bool write_dets = false; tk::dnn::Yolo3Detection yolo; tk::dnn::CenternetDetection cnet; + switch(ntype) { - case YOLO: + case 'y': yolo.init(net); break; - case CENTERNET: + case 'c': cnet.init(net); break; default: - FatalError("Network type not allowed "); + FatalError("Network type not allowed (3rd parameter)\n"); } + std::ifstream all_labels(labels_path); std::string l_filename; std::vector images; @@ -372,14 +70,14 @@ int main(int argc, char *argv[]) std::vector detected_bbox; int i=0; - while (std::getline(all_labels, l_filename)) // && i < 1000) + while (std::getline(all_labels, l_filename) && i < 1000) { + std::cout </ / / / - BoundigBox b; + BoundingBox b; b.x = (d.x + d.w/2) / width; b.y = (d.y + d.h/2) / height; b.w = d.w / width; @@ -426,20 +123,22 @@ int main(int argc, char *argv[]) b.cl = d.cl; f.det.push_back(b); - // myfile << d.cl << " "<< d.prob << " "<< d.x << " "<< d.y << " "<< d.w << " "<< d.h <<"\n"; + if(write_dets) + myfile << d.cl << " "<< d.prob << " "<< d.x << " "<< d.y << " "<< d.w << " "<< d.h <<"\n"; if(show)// draw rectangle for detection cv::rectangle(frame, cv::Point(d.x, d.y), cv::Point(d.x + d.w, d.y + d.h), cv::Scalar(0, 0, 255), 2); } - // myfile.close(); + if(write_dets) + myfile.close(); // read and save groundtruth labels std::ifstream labels(l_filename); for(std::string line; std::getline(labels, line); ) { std::istringstream in(line); - BoundigBox b; + BoundingBox b; in >> b.cl >> b.x >> b.y >> b.w >> b.h; b.prob = 1; b.truth_flag = 1; @@ -461,23 +160,14 @@ int main(int argc, char *argv[]) std::cout<<"Done."< gt; + std::vector det; + + void print() const; +}; + +struct PR +{ + double precision = 0; + double recall = 0; + int tp = 0, fp = 0, fn = 0; + + void print(); +}; + +float overlap(float x1, float w1, float x2, float w2); +float boxIntersection(const BoundingBox &a, const BoundingBox &b); +float boxUnion(const BoundingBox &a, const BoundingBox &b); +float boxIoU(const BoundingBox &a, const BoundingBox &b); + +double computeMap(std::vector &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose=false); +double computeMapNIoULevels(std::vector &images,const int classes,const float i_IoU_thresh=0.5, const int map_points=101, const float map_step=0.05, const int map_levels=10, const bool verbose=false); + +#endif /*EVALUATION_H*/ \ No newline at end of file diff --git a/src/evaluation.cpp b/src/evaluation.cpp new file mode 100644 index 0000000..2b60449 --- /dev/null +++ b/src/evaluation.cpp @@ -0,0 +1,284 @@ +#include "evaluation.h" + + +void BoundingBox::clear() +{ + unique_truth_index = -1; + truth_flag = 0; + max_IoU = 0; +} + +bool boxComparison (const BoundingBox& a,const BoundingBox& b) +{ + return (a.prob>b.prob); +} + +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.truth_flag<< ", assignedGT: "<< bb.unique_truth_index<< + ", maxIoU: "<< bb.max_IoU<<"\n"; + return os; +} + +void Frame::print() const +{ + std::cout<<"labels filename: "< l2 ? l1 : l2; + float r1 = x1 + w1/2; + float r2 = x2 + w2/2; + float right = r1 < r2 ? r1 : r2; + return right - left; +} + +float boxIntersection(const BoundingBox &a, const BoundingBox &b) +{ + float w = overlap(a.x, a.w, b.x, b.w); + float h = overlap(a.y, a.h, b.y, b.h); + if(w < 0 || h < 0) + return 0; + float area = w*h; + return area; +} + +float boxUnion(const BoundingBox &a, const BoundingBox &b) +{ + float i = boxIntersection(a, b); + float u = a.w*a.h + b.w*b.h - i; + return u; +} + +float boxIoU(const BoundingBox &a, const BoundingBox &b) +{ + float I = boxIntersection(a, b); + // std::cout<<"I: "< &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose) +{ + + std::cout<<"Computing mAP"< truth_classes_count(classes,0); + std::vector 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(); + } + + std::cout<<"gt_count: "< all_dets; + std::vector all_gts; + + int gt_checked = 0; + + // for each detection comput IoU with groundtruth and match detetcion and + // groundtruth with IoU greater than IoU_thresh + for(auto &img:images) + { + for(size_t i=0; i 0) + { + float maxIoU = 0; + int truth_index = -1; + for(size_t j=0; j maxIoU && img.det[i].cl == img.gt[j].cl) + { + maxIoU = currentIoU; + truth_index = j; + } + } + // std::cout<<"det i:"< -1 && maxIoU > IoU_thresh) + { + // std::cout<<"(INSIDE) IoU thresh:"< IoU_thresh:"<<(maxIoU > IoU_thresh)< truth_flags(groundtruths_count,0); + + if(verbose) + for(auto d:all_dets) + std::cout<> pr( classes, std::vector(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].truth_flag == 1 && truth_flags[all_dets[rank].unique_truth_index] == 0) + { + truth_flags[all_dets[rank].unique_truth_index] = 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 "<= 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; + } + + std::cout<<"Class: "< &images,const int classes,const float i_IoU_thresh, const int map_points, const float map_step, const int map_levels, const bool verbose) +{ + double AP = 0; + float IoU_thresh = i_IoU_thresh; + for(int i=0; i Date: Fri, 7 Feb 2020 14:50:05 +0100 Subject: [PATCH 048/228] Remove mallocs and frees from the kernels Signed-off-by: Davide Sapienza --- include/sorting.h | 6 ++++-- include/tkDNN/CenternetDetection.h | 4 +++- src/CenternetDetection.cpp | 13 +++++++++---- src/sorting.cu | 20 ++++++-------------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/include/sorting.h b/include/sorting.h index d153c61..9c968f3 100644 --- a/include/sorting.h +++ b/include/sorting.h @@ -15,5 +15,7 @@ void topk(dnnType *src_begin, int *idsrc, int K, float *topk_scores, 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); +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); diff --git a/include/tkDNN/CenternetDetection.h b/include/tkDNN/CenternetDetection.h index 1868839..e39644f 100644 --- a/include/tkDNN/CenternetDetection.h +++ b/include/tkDNN/CenternetDetection.h @@ -75,7 +75,9 @@ class CenternetDetection { int K = 100; int width = 128;//56; // TODO - + // pointer used in the kernels + float *src_out; + int *ids_out; public: dnnType *rt_out[4]; diff --git a/src/CenternetDetection.cpp b/src/CenternetDetection.cpp index c6c4bc7..c707c6c 100644 --- a/src/CenternetDetection.cpp +++ b/src/CenternetDetection.cpp @@ -96,8 +96,13 @@ bool CenternetDetection::init(std::string tensor_path) { mean << 0.408, 0.447, 0.47; stddev << 0.289, 0.274, 0.278; - // mean << 0.485, 0.456, 0.406; - // stddev << 0.229, 0.224, 0.225; + + // 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() { @@ -349,14 +354,14 @@ void CenternetDetection::update(cv::Mat &imageORIG) { // ----------- topk end - 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(end_t - step_t).count() << " ms" << 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); + 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) ); diff --git a/src/sorting.cu b/src/sorting.cu index fd62cec..3ba5ac3 100644 --- a/src/sorting.cu +++ b/src/sorting.cu @@ -66,31 +66,25 @@ void topKxyclasses(int *ids_begin, int *ids_end, const int K, const int size, co } -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()); - 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()); 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()); - 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()); // x0 thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx0, thrust::minus()); // x1 thrust::transform(thrust::device, xs_begin, xs_begin + K, src_out, bbx1, thrust::plus()); - 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()); 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()); @@ -98,7 +92,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()); // y1 thrust::transform(thrust::device, ys_begin, ys_begin + K, src_out, bby1, thrust::plus()); - checkCuda( cudaFree(src_out) ); - checkCuda( cudaFree(ids_out) ); } From 62fe82ce9e905cf815eb74b02b4b5ffd47d0253e Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 10 Feb 2020 10:54:04 +0100 Subject: [PATCH 049/228] Update ResNet101 weights exporter Signed-off-by: Davide Sapienza --- tests/resnet101/resnet101_weightsexporter.py | 139 +++++++++---------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/tests/resnet101/resnet101_weightsexporter.py b/tests/resnet101/resnet101_weightsexporter.py index 140154e..e10a037 100644 --- a/tests/resnet101/resnet101_weightsexporter.py +++ b/tests/resnet101/resnet101_weightsexporter.py @@ -2,15 +2,26 @@ import torch import urllib from PIL import Image from torchvision import transforms -from torchsummary import summary import numpy as np import struct +import os +from pytorchcv.model_provider import get_model as ptcv_get_model +from torch.autograd import Variable + +from torchsummary import summary import torch.nn as nn +from torch.jit import trace + +def create_folders(): + if not os.path.exists('debug'): + os.makedirs('debug') + if not os.path.exists('layers'): + os.makedirs('layers') + def bin_write(f, data): data =data.flatten() - # print(data) fmt = 'f'*len(data) bin = struct.pack(fmt, *data) f.write(bin) @@ -18,38 +29,46 @@ def bin_write(f, data): def hook(module, input, output): setattr(module, "_value_hook", output) +def load_ex_image(model): + # Download an example image from the pytorch website + url, filename = ( + "https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg") + try: + urllib.URLopener().retrieve(url, filename) + except: + urllib.request.urlretrieve(url, filename) + + # sample execution (requires torchvision) + input_image = Image.open(filename) + print("input_image: ",input_image.size) + preprocess = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[ + 0.229, 0.224, 0.225]), + ]) + input_tensor = preprocess(input_image) + print("input_tensor: ",input_tensor.shape) + # create a mini-batch as expected by the model + input_batch = input_tensor.unsqueeze(0) + # move the input and model to GPU for speed if available + if torch.cuda.is_available(): + input_batch = input_batch.to('cuda') + model.to('cuda') + + return model, input_batch -def print_wb(model, folder): - for name, param in model.named_parameters(): - # print ("Layer", name) - t = name.split('.')[0:-1] - arg = name.split('.')[-1] - t = '-'.join(t) - print (" type: ", t) - - if arg == 'weight': - w = param.data.numpy() - print (" weights shape:", np.shape(w)) - w.tofile(folder + "/" + t + ".bin", format="f") - elif arg == 'bias': - b = param.data.numpy() - print (" bias shape:", np.shape(b)) - b.tofile(folder + "/" + t + ".bias.bin", format="f") - else: - print("Ops!") - - -def print_wb_output(model, input_batch): - for n, m in model.named_modules(): - m.register_forward_hook(hook) - +def exp_input(model, input_batch): + # Export the input batch model(input_batch) - i = input_batch.data.numpy() + i = input_batch.cpu().data.numpy() i = np.array(i, dtype=np.float32) - print(i.shape) i.tofile("debug/input.bin", format="f") + print("input: ", i.shape) +def print_wb_output(model): f = None for n, m in model.named_modules(): in_output = m._value_hook @@ -57,7 +76,9 @@ def print_wb_output(model, input_batch): o = np.array(o, dtype=np.float32) t = '-'.join(n.split('.')) o.tofile("debug/" + t + ".bin", format="f") - + print('------- ', n, ' ------') + print("debug ",o.shape) + if not(' of Conv2d' in str(m.type) or ' of Linear' in str(m.type) or ' of BatchNorm2d' in str(m.type)): continue @@ -66,14 +87,8 @@ def print_wb_output(model, input_batch): print("open file: ", file_name) f = open(file_name, mode='wb') - print(n, ' ----------------------------------------------------------------') - # print(m._parameters) - #print(m.type) - w = np.array([]) b = np.array([]) - - if 'weight' in m._parameters and m._parameters['weight'] is not None: w = m._parameters['weight'].data.numpy() w = np.array(w, dtype=np.float32) @@ -83,9 +98,6 @@ def print_wb_output(model, input_batch): b = m._parameters['bias'].data.numpy() b = np.array(b, dtype=np.float32) print (" bias shape:", np.shape(b)) - # else: - # b = np.zeros(w.shape[0], dtype=np.float32) - # print (" bias shape:", np.shape(b)) if 'BatchNorm2d' in str(m.type): b = m._parameters['bias'].data.numpy() @@ -96,30 +108,24 @@ def print_wb_output(model, input_batch): rm = np.array(rm, dtype=np.float32) rv = m.running_var.data.numpy() rv = np.array(rv, dtype=np.float32) - #s.tofile(f, format="f") bin_write(f,b) bin_write(f,s) bin_write(f,rm) bin_write(f,rv) + print (" b shape:", np.shape(b)) print (" s shape:", np.shape(s)) print (" rm shape:", np.shape(rm)) print (" rv shape:", np.shape(rv)) else: - - # w.tofile(f, format="f") bin_write(f,w) - # print("w- ",w) if b.size > 0: - # b.tofile(f, format="f") bin_write(f,b) - # print("b - ",b) if ' of BatchNorm2d' in str(m.type) or ' of Linear' in str(m.type): f.close() print("close file") f = None - # return @@ -130,34 +136,27 @@ if __name__ == '__main__': model = torch.hub.load('pytorch/vision', 'resnet101', pretrained=True) model.eval() - # Download an example image from the pytorch website - url, filename = ("https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg") - try: urllib.URLopener().retrieve(url, filename) - except: urllib.request.urlretrieve(url, filename) - - # sample execution (requires torchvision) - input_image = Image.open(filename) - preprocess = transforms.Compose([ - transforms.Resize(256), - transforms.CenterCrop(224), - transforms.ToTensor(), - transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), - ]) - input_tensor = preprocess(input_image) - input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model - - # move the input and model to GPU for speed if available - if torch.cuda.is_available(): - input_batch = input_batch.to('cuda') - model.to('cuda') - + # load an example image and load it on model + model, input_batch = load_ex_image(model) + model.eval() with torch.no_grad(): output = model(input_batch) - # Tensor of shape 1000, with confidence scores over Imagenet's 1000 classes - # print(output) + # create folders debug and layers if do not exist + create_folders() + # add output attribute to the layers + for n, m in model.named_modules(): + m.register_forward_hook(hook) - print_wb_output(model, input_batch) + # export input bin + exp_input(model, input_batch) - # print(list(model.children())) + print_wb_output(model) + + with open("resnet101.txt", 'w') as f: + for item in list(model.children()): + f.write("%s\n" % item) + + summary(model, (3, 224, 224)) + # print(trace(model, input_batch)) From e72aa348a0b571e4044a5c67141cce4fc18d462f Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 10 Feb 2020 10:56:33 +0100 Subject: [PATCH 050/228] Add DLA34 weights exporter Signed-off-by: Davide Sapienza --- tests/dla34/dla34_weightsexporter.py | 162 +++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 tests/dla34/dla34_weightsexporter.py diff --git a/tests/dla34/dla34_weightsexporter.py b/tests/dla34/dla34_weightsexporter.py new file mode 100644 index 0000000..4a412df --- /dev/null +++ b/tests/dla34/dla34_weightsexporter.py @@ -0,0 +1,162 @@ +import torch +import urllib +from PIL import Image +from torchvision import transforms +import numpy as np +import struct +import os + +from pytorchcv.model_provider import get_model as ptcv_get_model +from torch.autograd import Variable + +from torchsummary import summary +import torch.nn as nn + +from torch.jit import trace + +def create_folders(): + if not os.path.exists('debug'): + os.makedirs('debug') + if not os.path.exists('layers'): + os.makedirs('layers') + +def bin_write(f, data): + data =data.flatten() + fmt = 'f'*len(data) + bin = struct.pack(fmt, *data) + f.write(bin) + +def hook(module, input, output): + setattr(module, "_value_hook", output) + +def load_ex_image(model): + # Download an example image from the pytorch website + url, filename = ( + "https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg") + try: + urllib.URLopener().retrieve(url, filename) + except: + urllib.request.urlretrieve(url, filename) + + # sample execution (requires torchvision) + input_image = Image.open(filename) + print("input_image: ",input_image.size) + preprocess = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[ + 0.229, 0.224, 0.225]), + ]) + input_tensor = preprocess(input_image) + print("input_tensor: ",input_tensor.shape) + # create a mini-batch as expected by the model + input_batch = input_tensor.unsqueeze(0) + + # move the input and model to GPU for speed if available + if torch.cuda.is_available(): + input_batch = input_batch.to('cuda') + model.to('cuda') + + return model, input_batch + +def exp_input(model, input_batch): + # Export the input batch + model(input_batch) + i = input_batch.cpu().data.numpy() + i = np.array(i, dtype=np.float32) + i.tofile("debug/input.bin", format="f") + print("input: ", i.shape) + +def print_wb_output(model): + f = None + for n, m in model.named_modules(): + m.eval() + if 'DLAResBlock' in str(m.type): + continue + + in_output = m._value_hook + o = in_output.data.numpy() + o = np.array(o, dtype=np.float32) + + t = '-'.join(n.split('.')) + o.tofile("debug/" + t + ".bin", format="f") + print('------- ', n, ' ------') + print("debug ",o.shape) + + if not(' of Conv2d' in str(m.type) or ' of Linear' in str(m.type) or ' of BatchNorm2d' in str(m.type)): + continue + + if ' of Conv2d' in str(m.type) or ' of Linear' in str(m.type): + file_name = "layers/" + t + ".bin" + print("open file: ", file_name) + f = open(file_name, mode='wb') + + w = np.array([]) + b = np.array([]) + if 'weight' in m._parameters and m._parameters['weight'] is not None: + w = m._parameters['weight'].data.numpy() + w = np.array(w, dtype=np.float32) + print (" weights shape:", np.shape(w)) + + if 'bias' in m._parameters and m._parameters['bias'] is not None: + b = m._parameters['bias'].data.numpy() + b = np.array(b, dtype=np.float32) + print (" bias shape:", np.shape(b)) + + if 'BatchNorm2d' in str(m.type): + b = m._parameters['bias'].data.numpy() + b = np.array(b, dtype=np.float32) + s = m._parameters['weight'].data.numpy() + s = np.array(s, dtype=np.float32) + rm = m.running_mean.data.numpy() + rm = np.array(rm, dtype=np.float32) + rv = m.running_var.data.numpy() + rv = np.array(rv, dtype=np.float32) + bin_write(f,b) + bin_write(f,s) + bin_write(f,rm) + bin_write(f,rv) + print (" b shape:", np.shape(b)) + print (" s shape:", np.shape(s)) + print (" rm shape:", np.shape(rm)) + print (" rv shape:", np.shape(rv)) + + else: + bin_write(f,w) + if b.size > 0 and b is not None: + bin_write(f,b) + + if ' of BatchNorm2d' in str(m.type) or ' of Linear' in str(m.type): + f.close() + print("close file") + f = None + +if __name__ == '__main__': + model = ptcv_get_model("dla34", pretrained=True) + model.eval() + + # load an example image and load it on model + model, input_batch = load_ex_image(model) + model.eval() + with torch.no_grad(): + output = model(input_batch) + + # create folders debug and layers if do not exist + create_folders() + + # add output attribute to the layers + for n, m in model.named_modules(): + m.register_forward_hook(hook) + + # export input bin + exp_input(model, input_batch) + + print_wb_output(model) + + with open("dla34.txt", 'w') as f: + for item in list(model.children()): + f.write("%s\n" % item) + + summary(model, (3, 224, 224)) + # print(trace(model, input_batch)) From c02238ddc8cde8b62b5c2bf97d584a20e6be98e6 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 10 Feb 2020 10:58:04 +0100 Subject: [PATCH 051/228] Add Anaconda environment for ResNet101 and DLA34 weights exporter Signed-off-by: Davide Sapienza --- tests/dla34/env_dla34.yml | 60 +++++++++++++++++++++++++++++++ tests/resnet101/env_resnet101.yml | 56 +++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/dla34/env_dla34.yml create mode 100644 tests/resnet101/env_resnet101.yml diff --git a/tests/dla34/env_dla34.yml b/tests/dla34/env_dla34.yml new file mode 100644 index 0000000..4e27db2 --- /dev/null +++ b/tests/dla34/env_dla34.yml @@ -0,0 +1,60 @@ +name: dla34 +channels: + - defaults +dependencies: + - _libgcc_mutex=0.1=main + - _pytorch_select=0.2=gpu_0 + - blas=1.0=mkl + - ca-certificates=2019.10.16=0 + - certifi=2019.9.11=py36_0 + - cffi=1.13.1=py36h2e261b9_0 + - cudatoolkit=10.0.130=0 + - cudnn=7.6.0=cuda10.0_0 + - freetype=2.9.1=h8a8886c_1 + - intel-openmp=2019.4=243 + - jpeg=9b=h024ee3a_2 + - libedit=3.1.20181209=hc058e9b_0 + - libffi=3.2.1=hd88cf55_4 + - libgcc-ng=9.1.0=hdf63c60_0 + - libgfortran-ng=7.3.0=hdf63c60_0 + - libpng=1.6.37=hbc83047_0 + - libstdcxx-ng=9.1.0=hdf63c60_0 + - libtiff=4.0.10=h2733197_2 + - mkl=2019.4=243 + - mkl-service=2.3.0=py36he904b0f_0 + - mkl_fft=1.0.14=py36ha843d7b_0 + - mkl_random=1.1.0=py36hd6b4f25_0 + - ncurses=6.1=he6710b0_1 + - ninja=1.9.0=py36hfd86e86_0 + - numpy=1.17.2=py36haad9e8e_0 + - numpy-base=1.17.2=py36hde5b4d6_0 + - olefile=0.46=py36_0 + - openssl=1.1.1d=h7b6447c_3 + - pillow=6.2.0=py36h34e0f95_0 + - pip=19.3.1=py36_0 + - pycparser=2.19=py36_0 + - python=3.6.9=h265db76_0 + - readline=7.0=h7b6447c_5 + - setuptools=41.6.0=py36_0 + - six=1.12.0=py36_0 + - sqlite=3.30.1=h7b6447c_0 + - tk=8.6.8=hbc83047_0 + - wheel=0.33.6=py36_0 + - xz=5.2.4=h14c3975_4 + - zlib=1.2.11=h7b6447c_3 + - zstd=1.3.7=h0b5b093_0 + - pip: + - chardet==3.0.4 + - decorator==4.4.1 + - idna==2.8 + - lxml==4.4.2 + - networkx==2.4 + - nltk==3.4.5 + - pytorchcv==0.0.55 + - requests==2.22.0 + - summary==0.2.0 + - torch==1.3.0 + - torchsummary==1.5.1 + - torchvision==0.4.1 + - urllib3==1.25.8 + diff --git a/tests/resnet101/env_resnet101.yml b/tests/resnet101/env_resnet101.yml new file mode 100644 index 0000000..35987c3 --- /dev/null +++ b/tests/resnet101/env_resnet101.yml @@ -0,0 +1,56 @@ +name: resnet101 +channels: + - defaults +dependencies: + - _libgcc_mutex=0.1=main + - _pytorch_select=0.2=gpu_0 + - blas=1.0=mkl + - ca-certificates=2019.10.16=0 + - certifi=2019.9.11=py36_0 + - cffi=1.13.1=py36h2e261b9_0 + - cudatoolkit=10.0.130=0 + - cudnn=7.6.0=cuda10.0_0 + - freetype=2.9.1=h8a8886c_1 + - intel-openmp=2019.4=243 + - jpeg=9b=h024ee3a_2 + - libedit=3.1.20181209=hc058e9b_0 + - libffi=3.2.1=hd88cf55_4 + - libgcc-ng=9.1.0=hdf63c60_0 + - libgfortran-ng=7.3.0=hdf63c60_0 + - libpng=1.6.37=hbc83047_0 + - libstdcxx-ng=9.1.0=hdf63c60_0 + - libtiff=4.0.10=h2733197_2 + - mkl=2019.4=243 + - mkl-service=2.3.0=py36he904b0f_0 + - mkl_fft=1.0.14=py36ha843d7b_0 + - mkl_random=1.1.0=py36hd6b4f25_0 + - ncurses=6.1=he6710b0_1 + - ninja=1.9.0=py36hfd86e86_0 + - numpy=1.17.2=py36haad9e8e_0 + - numpy-base=1.17.2=py36hde5b4d6_0 + - olefile=0.46=py36_0 + - openssl=1.1.1d=h7b6447c_3 + - pillow=6.2.0=py36h34e0f95_0 + - pip=19.3.1=py36_0 + - pycparser=2.19=py36_0 + - python=3.6.9=h265db76_0 + - pytorch=1.2.0=cuda100py36h938c94c_0 + - readline=7.0=h7b6447c_5 + - setuptools=41.6.0=py36_0 + - six=1.12.0=py36_0 + - sqlite=3.30.1=h7b6447c_0 + - tk=8.6.8=hbc83047_0 + - wheel=0.33.6=py36_0 + - xz=5.2.4=h14c3975_4 + - zlib=1.2.11=h7b6447c_3 + - zstd=1.3.7=h0b5b093_0 + - pip: + - chardet==3.0.4 + - idna==2.8 + - pytorchcv==0.0.55 + - requests==2.22.0 + - torch==1.3.0 + - torchsummary==1.5.1 + - torchvision==0.4.1 + - urllib3==1.25.8 + From b06dc286e974f1fb9892dba4bf8424aa5dfa2154 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Mon, 10 Feb 2020 11:19:39 +0100 Subject: [PATCH 052/228] Update README.md Signed-off-by: Davide Sapienza --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/README.md b/README.md index 3d956a5..12bb124 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,36 @@ make during the cmake configuration it will be dowloaded the weights needed for running the tests +## DLA34 and ResNet101 weights +To get weights and outputs needed for running the tests you can use the Python +script and the Anaconda environment included in the repository. + +Create Anaconda environment and activate it: +``` +conda env create -f file_name.yml +source activate env_name +``` +Run the Python script inside the environment. + +## CenterNet weights +To get the weights needed for running the tests: + +* clone the forked repository by the original CenterNet: +``` +git clone https://github.com/sapienzadavide/CenterNet.git +``` +* follow the instruction in the README.md and INSTALL.md +* copy the weigths and outputs from /path/to/CenterNet/src/ in ./test/centernet-path/ . For example: +``` +cp /path/to/CenterNet/src/layers_dla/* ./test/dla34_cnet/layers/ +cp /path/to/CenterNet/src/debug_dla/* ./test/dla34_cnet/debug/ +``` +or +``` +cp /path/to/CenterNet/src/layers_resdcn/* ./test/resnet101_cnet/layers/ +cp /path/to/CenterNet/src/debug_resdcn/* ./test/resnet101_cnet/debug/ +``` + ## 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) @@ -35,6 +65,11 @@ Assumiung you have correctly builded the library these are the test ready to exe * 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 +* test_resnet101: ResNet101 network (CUDNN and TENSORRT) +* test_resnet101_cnet: CenterNet detection based on ResNet101 (CUDNN and TENSORRT) +* test_dla34: DLA34 network (CUDNN and TENSORRT) +* test_dla34_cnet: CenterNet detection based on DLA34 (CUDNN and TENSORRT) + ## 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: @@ -50,3 +85,31 @@ this will genereate a yolo3_berkeley.rt file that can be used for live detection ./yolo3_demo yolo3_berkeley.rt /dev/video0 # launch detection on device 0 ``` ![demo](https://user-images.githubusercontent.com/11562617/72547657-540e7800-388d-11ea-83c6-49dfea2a0607.gif) + + +## CenterNet (DLA34, ResNet101) demo detection +For the live detection you need to precompile the tensorRT file by luncing the desidered network test, this is the recommended process: +``` +export TKDNN_MODE=FP16 # set the half floating point optimization +``` + +For CenterNet based on ResNet101: +``` +rm resnet101_cnet.rt # be sure to delete(or move) old tensorRT files +./test_resnet101_cnet # run the yolo test (is slow) +# with f16 inference the result will be a bit incorrect +``` + +For CenterNet based on DLA34: +``` +rm dla34_cnet.rt # be sure to delete(or move) old tensorRT files +./test_dla34_cnet # run the yolo test (is slow) +# with f16 inference the result will be a bit incorrect +``` + +this will genereate resnet101_cnet.rt and dla34_cnet.rt file that can be used for live detection: +``` +./centernet_demo # launch detection on a demo video +./centernet_demo resnet101_cnet.rt /dev/video0 # launch detection on device 0 +./centernet_demo dla34_cnet.rt /dev/video0 # launch detection on device 0 +``` \ No newline at end of file From d601e980f62ae816d2a34cee7c8ef9c66c4360ef Mon Sep 17 00:00:00 2001 From: xavier Date: Mon, 10 Feb 2020 18:19:08 +0100 Subject: [PATCH 053/228] Add avg precision, recall, f1score computation, other minors Signed-off-by: xavier --- demo/demo/map.cpp | 5 ++- include/evaluation.h | 6 ++- src/evaluation.cpp | 99 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index f7e9e3e..bbbd77a 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -164,11 +164,14 @@ int main(int argc, char *argv[]) int map_levels = 10; float map_step = 0.05; float IoU_thresh = 0.5; + float conf_thresh = 0.3; bool verbose = false; - double AP = computeMapNIoULevels(images,classes,IoU_thresh, map_points, map_step, map_levels, verbose); + double AP = computeMapNIoULevels(images,classes,IoU_thresh,conf_thresh, map_points, map_step, map_levels, verbose); std::cout<<"mAP "< &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose=false); -double computeMapNIoULevels(std::vector &images,const int classes,const float i_IoU_thresh=0.5, const int map_points=101, const float map_step=0.05, const int map_levels=10, const bool verbose=false); +double computeMap(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh=0.3, const int map_points=101, const bool verbose=false); +double computeMapNIoULevels(std::vector &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); + +void computeTPFPFN(std::vector &images,const int classes,const float IoU_thresh=0.5, const float conf_thresh=0.3, bool verbose=false); #endif /*EVALUATION_H*/ \ No newline at end of file diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 2b60449..65f7708 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -77,11 +77,8 @@ float boxIoU(const BoundingBox &a, const BoundingBox &b) } /* Credits to https://github.com/AlexeyAB/darknet/blob/master/src/detector.c*/ -double computeMap(std::vector &images,const int classes,const float IoU_thresh, const int map_points, const bool verbose) +double computeMap(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh, const int map_points, const bool verbose) { - - std::cout<<"Computing mAP"< &images,const int classes,const float IoU_t groundtruths_count += i.gt.size(); } - std::cout<<"gt_count: "< all_dets; std::vector all_gts; @@ -117,7 +117,7 @@ double computeMap(std::vector &images,const int classes,const float IoU_t { for(size_t i=0; i 0) + if(img.det[i].prob > conf_thresh) { float maxIoU = 0; int truth_index = -1; @@ -257,17 +257,18 @@ double computeMap(std::vector &images,const int classes,const float IoU_t avg_precision = avg_precision / map_points; } - std::cout<<"Class: "< &images,const int classes,const float i_IoU_thresh, const int map_points, const float map_step, const int map_levels, const bool verbose) +double computeMapNIoULevels(std::vector &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) { double AP = 0; float IoU_thresh = i_IoU_thresh; @@ -276,9 +277,85 @@ double computeMapNIoULevels(std::vector &images,const int classes,const f for(auto& img:images) for(auto & d:img.det) d.clear(); - AP += computeMap(images,classes,IoU_thresh,map_points, verbose); + AP += computeMap(images,classes,IoU_thresh,conf_thresh,map_points, verbose); IoU_thresh +=map_step; } AP/=map_levels; return AP; +} + +void computeTPFPFN(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh, bool verbose) +{ + std::vector truth_classes_count(classes,0); + std::vector dets_classes_count(classes,0); + std::vector pr( classes); + + for(auto &img:images) + { + for(auto& tc: truth_classes_count) + tc = 0; + for(auto& dc: dets_classes_count) + dc = 0; + + std::vector det_assigned(img.det.size(), false); + for(size_t j=0; j conf_thresh) + { + float currentIoU = boxIoU(img.det[i], 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].unique_truth_index = j; + img.det[det_index].truth_flag = 1; + img.det[det_index].max_IoU = maxIoU; + det_assigned[det_index] = true; + dets_classes_count[img.det[det_index].cl]++; + } + } + + for(size_t i=0; i 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 "< 0 ? 2 * ( avg_precision * avg_recall ) / ( avg_precision + avg_recall ) : 0; + + std::cout<<"avg precision: "< Date: Tue, 11 Feb 2020 10:06:08 +0100 Subject: [PATCH 054/228] Optimize deformable kernel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off.by: Ignacio Sañudo Olmedo Signed-off-by: Davide Sapienza --- CMakeLists.txt | 1 + include/tkDNN/kernels.h | 12 +- src/kernels/deformable_conv.cu | 227 ++++++++++++++++++++++++--------- 3 files changed, 180 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27d99ea..a4a3caa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ 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) diff --git a/include/tkDNN/kernels.h b/include/tkDNN/kernels.h index 94c5dcb..f514ffc 100644 --- a/include/tkDNN/kernels.h +++ b/include/tkDNN/kernels.h @@ -30,14 +30,20 @@ void upsampleForward(dnnType* srcData, dnnType* dstData, 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 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 height_col, const int width_col, const int deformable_group, float *data_col); + void dcn_v2_cuda_forward(cublasStatus_t stat, cublasHandle_t handle, float *input, float *weight, float *bias, float *ones, diff --git a/src/kernels/deformable_conv.cu b/src/kernels/deformable_conv.cu index 0579620..88e62e9 100644 --- a/src/kernels/deformable_conv.cu +++ b/src/kernels/deformable_conv.cu @@ -9,7 +9,7 @@ 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; @@ -17,84 +17,89 @@ inline int GET_BLOCKS(const int N) __device__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width, - const int height, const int width, float h, float w) + 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; +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 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 + (b_col * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col; + const float *data_mask_ptr = data_mask + add_ptr; - for (int i = 0; i < kernel_h; ++i) + const int first_member = w_col + width_col * h_col; + float val = static_cast(0); + #pragma unroll + for (int i = 0; i < 3; ++i) { - for (int j = 0; j < kernel_w; ++j) + #pragma unroll + for (int j = 0; j < 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_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 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; + 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(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) + 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; @@ -104,7 +109,89 @@ __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_kernel2(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 ). + // printf("--- %d %d %d %d %d %d %d %d\n",kernel_h, kernel_w, pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w); + 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; + + // 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; + + float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_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; + + const int first_member = w_col + width_col * h_col; + float val = static_cast(0); + #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) { + 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; } } @@ -113,6 +200,28 @@ __global__ void modulated_deformable_im2col_gpu_kernel(const int n, 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 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 + <<>>( + 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) + { + printf("error in modulated_deformable_im2col_cuda: %s\n", cudaGetErrorString(err)); + } + +} + +void modulated_deformable_im2col_cuda2(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 +231,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_kernel2 <<>>( num_kernels, data_im, data_offset, data_mask, height_im, width_im, kernel_h, kenerl_w, @@ -137,7 +246,6 @@ void modulated_deformable_im2col_cuda(cudaStream_t stream, } - void dcn_v2_cuda_forward(cublasStatus_t stat, cublasHandle_t handle, float *input, float *weight, float *bias, float *ones, @@ -182,9 +290,14 @@ void dcn_v2_cuda_forward(cublasStatus_t stat, cublasHandle_t handle, 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); + height_out, width_out, deformable_group, columns); + // modulated_deformable_im2col_cuda2(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 From 801b8b56416436e1df0515a806c64f67b212ae66 Mon Sep 17 00:00:00 2001 From: xavier Date: Tue, 11 Feb 2020 10:32:42 +0100 Subject: [PATCH 055/228] Read parameters for mAP from yaml, add yampl-cpp dependency Signed-off-by: xavier --- CMakeLists.txt | 3 +- demo/demo/map.cpp | 75 +++++++++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27d99ea..a7eb12e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ cuda_add_library(kernels SHARED ${tkdnn_CUSRC}) find_package(OpenCV REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOPENCV") +find_package(yaml-cpp REQUIRED) #------------------------------------------------------------------------------- # Build Libraries @@ -118,7 +119,7 @@ add_executable(centernet_demo demo/demo/demo_centernet.cpp) target_link_libraries(centernet_demo tkDNN) add_executable(map_demo demo/demo/map.cpp) -target_link_libraries(map_demo tkDNN) +target_link_libraries(map_demo tkDNN yaml-cpp) #------------------------------------------------------------------------------- diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index bbbd77a..80c56dd 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -17,6 +17,8 @@ #include "evaluation.h" #include +#include + void convertFilename(std::string &filename,const std::string l_folder, const std::string i_folder, const std::string l_ext,const std::string i_ext) { @@ -24,27 +26,53 @@ void convertFilename(std::string &filename,const std::string l_folder, const std filename.replace(filename.find(l_ext),l_ext.length(),i_ext); } +void readParams(char* config_filename, std::string& net, char &ntype, std::string& labels_path, + bool &show, bool& write_dets, int& classes, int& n_images, + int& map_points, int& map_levels, float& map_step, + float& IoU_thresh, float& conf_thresh, bool& verbose) +{ + YAML::Node config = YAML::LoadFile(config_filename); + net = config["net"].as(); + ntype = config["ntype"].as(); + labels_path = config["labels_path"].as(); + show = config["show"].as(); + write_dets = config["write_dets"].as(); + classes = config["classes"].as(); + n_images = config["n_images"].as(); + map_points = config["map_points"].as(); + map_levels = config["map_levels"].as(); + map_step = config["map_step"].as(); + IoU_thresh = config["IoU_thresh"].as(); + conf_thresh = config["conf_thresh"].as(); + verbose = config["verbose"].as(); + +} + int main(int argc, char *argv[]) { - // char *net = "resnet101_cnet_FP32.rt"; - char *net = "yolo3.rt"; + + char *config_filename = "config.yaml"; if(argc > 1) - net = argv[1]; - char ntype = 'y'; + config_filename = argv[1]; + + char ntype; + std::string net, labels_path; + bool show, write_dets, verbose; + int classes, map_points, map_levels, n_images; + float map_step, IoU_thresh, conf_thresh; + + readParams( config_filename, net, ntype, labels_path, show, write_dets, + classes, n_images, map_points, map_levels, map_step, + IoU_thresh, conf_thresh, verbose); + if(argc > 2) - ntype = argv[2][0]; - //path to txt file with all realpath of images labels - char *labels_path = "/media/887E650E7E64F67A/val2017/all_labels2017.txt"; + net = argv[2]; if(argc > 3) - labels_path = argv[3]; - - bool show = false; - bool write_dets = false; + ntype = argv[3][0]; tk::dnn::Yolo3Detection yolo; tk::dnn::CenternetDetection cnet; - switch(ntype) { case 'y': @@ -57,29 +85,26 @@ int main(int argc, char *argv[]) FatalError("Network type not allowed (3rd parameter)\n"); } - std::ifstream all_labels(labels_path); std::string l_filename; std::vector images; + std::vector detected_bbox; std::cout<<"Reading groundtruth and generating detections"< detected_bbox; - - int i=0; - while (std::getline(all_labels, l_filename) && i < 1000) + for (int images_done=0 ; std::getline(all_labels, l_filename) && images_done < n_images ; ++images_done) { - std::cout < +``` +where +* : rt file of a choosen network on wich compute the mAP. +* : type of network. Right now only y(yolo) and c(centernet) are allowed +* : path to a text file containing all the paths of the groundtruth labels. It is important that all the labels of the groundtruth are in a folder called 'labels'. In the folder containing the folder 'labels' there should be also a folder 'images', containing all the groundtruth images having the same same as the labels. To better understand, if there is a label path/to/labels/000001.txt there should be a corresponding image path/to/images/000001.jpg. +* : path to a yaml file with the parameters needed for the mAP computation, similar to demo/config.yaml + +Example: + +``` +./map_demo dla34_cnet.rt c path/to/labelsCOCO_val2017.txt ../demo/config.yaml ``` \ No newline at end of file diff --git a/demo/config.yaml b/demo/config.yaml new file mode 100644 index 0000000..3577abf --- /dev/null +++ b/demo/config.yaml @@ -0,0 +1,7 @@ +classes : 80 #number of classes +map_points : 101 #number of recall points (0 for all, 101 for COCO, 11 PascalVOC) +map_levels : 10 #number of IoU step for the AP +map_step : 0.05 #step of IoU +IoU_thresh : 0.5 #starting IoU threshold +conf_thresh : 0.3 #threshold on the condifence of the bbox +verbose : false #print on screen information \ No newline at end of file diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index 80c56dd..bc578d8 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -17,7 +17,7 @@ #include "evaluation.h" #include -#include + void convertFilename(std::string &filename,const std::string l_folder, const std::string i_folder, const std::string l_ext,const std::string i_ext) @@ -26,49 +26,24 @@ void convertFilename(std::string &filename,const std::string l_folder, const std filename.replace(filename.find(l_ext),l_ext.length(),i_ext); } -void readParams(char* config_filename, std::string& net, char &ntype, std::string& labels_path, - bool &show, bool& write_dets, int& classes, int& n_images, - int& map_points, int& map_levels, float& map_step, - float& IoU_thresh, float& conf_thresh, bool& verbose) -{ - YAML::Node config = YAML::LoadFile(config_filename); - net = config["net"].as(); - ntype = config["ntype"].as(); - labels_path = config["labels_path"].as(); - show = config["show"].as(); - write_dets = config["write_dets"].as(); - classes = config["classes"].as(); - n_images = config["n_images"].as(); - map_points = config["map_points"].as(); - map_levels = config["map_levels"].as(); - map_step = config["map_step"].as(); - IoU_thresh = config["IoU_thresh"].as(); - conf_thresh = config["conf_thresh"].as(); - verbose = config["verbose"].as(); - -} - int main(int argc, char *argv[]) { - - char *config_filename = "config.yaml"; + char ntype = 'y'; + char *config_filename = "../demo/config.yaml"; + char * net = "yolo3.rt"; + char * labels_path = "/media/887E650E7E64F67A/val2017/all_labels2017.txt"; + bool show = false; + bool write_dets = false; + int n_images = 1000; + if(argc > 1) - config_filename = argv[1]; - - char ntype; - std::string net, labels_path; - bool show, write_dets, verbose; - int classes, map_points, map_levels, n_images; - float map_step, IoU_thresh, conf_thresh; - - readParams( config_filename, net, ntype, labels_path, show, write_dets, - classes, n_images, map_points, map_levels, map_step, - IoU_thresh, conf_thresh, verbose); - + net = argv[1]; if(argc > 2) - net = argv[2]; + ntype = argv[2][0]; if(argc > 3) - ntype = argv[3][0]; + labels_path = argv[3]; + if(argc > 3) + config_filename = argv[4]; tk::dnn::Yolo3Detection yolo; tk::dnn::CenternetDetection cnet; @@ -183,6 +158,14 @@ int main(int argc, char *argv[]) } std::cout<<"Done."< #include +#include + #include "tkdnn.h" @@ -45,6 +47,10 @@ float boxIntersection(const BoundingBox &a, const BoundingBox &b); float boxUnion(const BoundingBox &a, const BoundingBox &b); float boxIoU(const BoundingBox &a, const BoundingBox &b); +void readParams(char* config_filename, int& classes, int& map_points, + int& map_levels, float& map_step, float& IoU_thresh, + float& conf_thresh, bool& verbose); + double computeMap(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh=0.3, const int map_points=101, const bool verbose=false); double computeMapNIoULevels(std::vector &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); diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 65f7708..c65ce50 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -76,6 +76,21 @@ float boxIoU(const BoundingBox &a, const BoundingBox &b) return I / U; } +void readParams(char* config_filename, int& classes, int& map_points, + int& map_levels, float& map_step, float& IoU_thresh, + float& conf_thresh, bool& verbose) +{ + YAML::Node config = YAML::LoadFile(config_filename); + classes = config["classes"].as(); + map_points = config["map_points"].as(); + map_levels = config["map_levels"].as(); + map_step = config["map_step"].as(); + IoU_thresh = config["IoU_thresh"].as(); + conf_thresh = config["conf_thresh"].as(); + verbose = config["verbose"].as(); + +} + /* Credits to https://github.com/AlexeyAB/darknet/blob/master/src/detector.c*/ double computeMap(std::vector &images,const int classes,const float IoU_thresh, const float conf_thresh, const int map_points, const bool verbose) { From 6e2ff405f40e640823c1359a42aebe2d28a93820 Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Tue, 11 Feb 2020 11:28:20 +0100 Subject: [PATCH 057/228] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b4ab4a6..b798ce8 100644 --- a/README.md +++ b/README.md @@ -123,13 +123,13 @@ The following parameters are needed: ./map_demo ``` where -* : rt file of a choosen network on wich compute the mAP. -* : type of network. Right now only y(yolo) and c(centernet) are allowed -* : path to a text file containing all the paths of the groundtruth labels. It is important that all the labels of the groundtruth are in a folder called 'labels'. In the folder containing the folder 'labels' there should be also a folder 'images', containing all the groundtruth images having the same same as the labels. To better understand, if there is a label path/to/labels/000001.txt there should be a corresponding image path/to/images/000001.jpg. -* : path to a yaml file with the parameters needed for the mAP computation, similar to demo/config.yaml +* ``````: rt file of a choosen network on wich compute the mAP. +* ``````: type of network. Right now only y(yolo) and c(centernet) are allowed +* ``````: path to a text file containing all the paths of the groundtruth labels. It is important that all the labels of the groundtruth are in a folder called 'labels'. In the folder containing the folder 'labels' there should be also a folder 'images', containing all the groundtruth images having the same same as the labels. To better understand, if there is a label path/to/labels/000001.txt there should be a corresponding image path/to/images/000001.jpg. +* ``````: path to a yaml file with the parameters needed for the mAP computation, similar to demo/config.yaml Example: ``` ./map_demo dla34_cnet.rt c path/to/labelsCOCO_val2017.txt ../demo/config.yaml -``` \ No newline at end of file +``` From 7e21b10aeec4d3f302e63517ae5a5ec672a06782 Mon Sep 17 00:00:00 2001 From: xavier Date: Tue, 11 Feb 2020 14:56:54 +0100 Subject: [PATCH 058/228] Add script to download COCO val2017 Signed-off-by: xavier --- README.md | 10 ++++++++-- demo/demo/map.cpp | 4 ++-- download_validation.sh | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 download_validation.sh diff --git a/README.md b/README.md index b4ab4a6..9219939 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,12 @@ this will genereate resnet101_cnet.rt and dla34_cnet.rt file that can be used fo ## mAP demo To compute mAP, precision, recall and f1score, run the map_demo. -The following parameters are needed: +A validation set is needed. To download COCO_val2017 run (form the root folder): +``` +bash download_validation.sh +``` + +To compute the map, the following parameters are needed: ``` ./map_demo ``` @@ -131,5 +136,6 @@ where Example: ``` -./map_demo dla34_cnet.rt c path/to/labelsCOCO_val2017.txt ../demo/config.yaml +cd build +./map_demo dla34_cnet.rt c ../demo/COCO_val2017/all_labels.txt ../demo/config.yaml ``` \ No newline at end of file diff --git a/demo/demo/map.cpp b/demo/demo/map.cpp index bc578d8..13636fb 100644 --- a/demo/demo/map.cpp +++ b/demo/demo/map.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) char ntype = 'y'; char *config_filename = "../demo/config.yaml"; char * net = "yolo3.rt"; - char * labels_path = "/media/887E650E7E64F67A/val2017/all_labels2017.txt"; + char * labels_path = "../demo/COCO_val2017/all_labels.txt"; bool show = false; bool write_dets = false; int n_images = 1000; @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) ntype = argv[2][0]; if(argc > 3) labels_path = argv[3]; - if(argc > 3) + if(argc > 4) config_filename = argv[4]; tk::dnn::Yolo3Detection yolo; diff --git a/download_validation.sh b/download_validation.sh new file mode 100644 index 0000000..4e07aae --- /dev/null +++ b/download_validation.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +cd demo +wget https://cloud.hipert.unimore.it/s/LNxBDk4wzqXPL8c/download -O COCO_val2017.zip +unzip -d COCO_val2017 COCO_val2017.zip +rm COCO_val2017.zip +cd COCO_val2017/ +realpath labels/* > all_labels.txt From 4c2d2a79658195a7e2fd2949218389eb7da6ca44 Mon Sep 17 00:00:00 2001 From: Micaela Verucchi Date: Tue, 11 Feb 2020 15:12:27 +0100 Subject: [PATCH 059/228] Update README.md --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 27d4af6..f8a3262 100644 --- a/README.md +++ b/README.md @@ -136,11 +136,6 @@ where Example: ``` -<<<<<<< HEAD cd build ./map_demo dla34_cnet.rt c ../demo/COCO_val2017/all_labels.txt ../demo/config.yaml ``` -======= -./map_demo dla34_cnet.rt c path/to/labelsCOCO_val2017.txt ../demo/config.yaml -``` ->>>>>>> 6e2ff405f40e640823c1359a42aebe2d28a93820 From 97b88ef52d96da859b4ad53527357bbde735a624 Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Tue, 11 Feb 2020 16:28:17 +0100 Subject: [PATCH 060/228] Fix a bug in the deformable kernel. There was a wrong variable initialization. Fixes: 51ffcb1f50e3c9aa2b2 ("Optimize deformable kernel") Signed-off-by: Davide Sapienza --- src/kernels/deformable_conv.cu | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/kernels/deformable_conv.cu b/src/kernels/deformable_conv.cu index 88e62e9..672655f 100644 --- a/src/kernels/deformable_conv.cu +++ b/src/kernels/deformable_conv.cu @@ -67,16 +67,15 @@ __global__ void modulated_deformable_im2col_gpu_kernel(const int n, 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 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 int first_member = w_col + width_col * h_col; - float val = static_cast(0); #pragma unroll for (int i = 0; i < 3; ++i) { @@ -99,6 +98,7 @@ __global__ void modulated_deformable_im2col_gpu_kernel(const int n, 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) { + float val = static_cast(0); if (h_im < height && w_im < width && h_im > -1 && w_im > -1) { //const float map_h = i * dilation_h + offset_h; @@ -149,16 +149,16 @@ __global__ void modulated_deformable_im2col_gpu_kernel2(const int n, 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 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 int first_member = w_col + width_col * h_col; - float val = static_cast(0); + #pragma unroll for (int i = 0; i < kernel_h; ++i) { @@ -181,6 +181,7 @@ __global__ void modulated_deformable_im2col_gpu_kernel2(const int n, 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(0); if (h_im < height && w_im < width && h_im > -1 && w_im > -1) { //const float map_h = i * dilation_h + offset_h; From a9c0db0bf6abc3f21611b1c13f55aaba383159e5 Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 13 Feb 2020 19:27:18 +0100 Subject: [PATCH 061/228] LSTM cudnn test --- .gitignore | 3 +- CMakeLists.txt | 3 + include/tkDNN/Layer.h | 76 +++++++++++++++++ src/LSTM.cpp | 142 ++++++++++++++++++++++++++++++++ src/utils.cpp | 3 +- tests/imuodom/imuodom.cpp | 70 ++++++++++++++++ tests/imuodom/infer.py | 74 +++++++++++++++++ tests/simple/test_model.py | 60 +++++++------- tests/simple/test_simple.cpp | 14 +--- tests/weights_exporter.py | 153 ++++++++++++++--------------------- 10 files changed, 464 insertions(+), 134 deletions(-) create mode 100644 src/LSTM.cpp create mode 100644 tests/imuodom/imuodom.cpp create mode 100644 tests/imuodom/infer.py diff --git a/.gitignore b/.gitignore index 02f2a8e..de78410 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ build/ *.h5 *.tar.gz *.weights -.idea/ \ No newline at end of file +.idea/ +*.hdf5 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b4b3c38..e3d8607 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,9 @@ 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_imuodom tests/imuodom/imuodom.cpp) +target_link_libraries(test_imuodom tkDNN) ################################################################################ diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index ee73109..f15c781 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -9,8 +9,10 @@ namespace tk { namespace dnn { enum layerType_t { + LAYER_INPUT, LAYER_DENSE, LAYER_CONV2D, + LAYER_LSTM, LAYER_ACTIVATION, LAYER_FLATTEN, LAYER_MULADD, @@ -47,8 +49,10 @@ public: std::string getLayerName() { layerType_t type = getLayerType(); switch(type) { + case LAYER_INPUT: return "Input"; case LAYER_DENSE: return "Dense"; case LAYER_CONV2D: return "Conv2d"; + case LAYER_LSTM: return "LSTM"; case LAYER_ACTIVATION: return "Activation"; case LAYER_FLATTEN: return "Flatten"; case LAYER_MULADD: return "MulAdd"; @@ -105,6 +109,27 @@ public: }; +/** + Input layer (it doesnt need weigths) +*/ +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) { + return dstData; + } +}; + + /** Dense (full interconnection) layer */ @@ -148,6 +173,14 @@ 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 { @@ -172,6 +205,49 @@ protected: size_t ws_sizeInBytes; }; +/** + Bidirectional LSTM layer + https://github.com/jiangnanhugo/seq2seq_cuda/blob/e4dbdcfa0517c972bfd4beea9f11a5233954093c/src/rnn.cpp + + numlayers = 1 # hardcoded as 1 + + PARAMS (numlayers*2): + layer0: + ( INCH, ? ) ??? + ( HIDDEN, ? ) ??? + ( HIDDEN * 8 ) ??? + layer2: + ( INCH, ? ) ??? + ( HIDDEN, ? ) ??? + ( HIDDEN * 8 ) ??? + + output shape: ( 2*HIDDEN, INH, INW ) +*/ +class LSTM : public Layer { + +public: + LSTM(Network *net, int hiddensize, std::string fname_weights); + virtual ~LSTM(); + virtual layerType_t getLayerType() { return LAYER_LSTM; }; + + virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); + + int kernelH, kernelW, strideH, strideW, paddingH, paddingW; + +protected: + cudnnFilterDescriptor_t paramDesc; + cudnnTensorDescriptor_t hiddenStateTensorDesc, cellStateTensorDesc; + cudnnRNNDescriptor_t rnnDesc; + cudnnRNNDataDescriptor_t rnnDataDesc; + cudnnDropoutDescriptor_t dropDesc; + cudnnRNNAlgo_t algo; + + dnnType *hiddenStateData, *cellStateData; + dnnType *paramsSpace; + void* workSpace; + size_t ws_sizeInBytes; +}; + /** Flatten layer diff --git a/src/LSTM.cpp b/src/LSTM.cpp new file mode 100644 index 0000000..3176819 --- /dev/null +++ b/src/LSTM.cpp @@ -0,0 +1,142 @@ +#include + +#include "Layer.h" + +namespace tk { namespace dnn { + +LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : + Layer(net) { + + checkCUDNN( cudnnCreateFilterDescriptor(¶mDesc)); + checkCUDNN( cudnnCreateRNNDescriptor(&rnnDesc) ); + checkCUDNN( cudnnCreateRNNDataDescriptor(&rnnDataDesc) ); + checkCUDNN( cudnnCreateDropoutDescriptor(&dropDesc)); + + int n = input_dim.n; + int c = input_dim.c; + int h = input_dim.h; + int w = input_dim.w; + checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc, + net->tensorFormat, net->dataType, n, 1, h, w) ); + + int numlayers = 1; + checkCUDNN( cudnnSetRNNDescriptor(net->cudnnHandle, rnnDesc, hiddensize, numlayers, dropDesc, + cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, + cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL, cudnnRNNMode_t::CUDNN_LSTM, + cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD, net->dataType) ); + + // find dimension of params + size_t params_size = 0; + checkCUDNN( cudnnGetRNNParamsSize(net->cudnnHandle, rnnDesc, srcTensorDesc, ¶ms_size, net->dataType) ); + std::cout<<"Params size bytes: "<dataType, net->tensorFormat, 3, dimW)); + checkCuda( cudaMalloc(¶msSpace, params_size) ); + + + int numlinearlayers = 8; + + for(int i=0; icudnnHandle, rnnDesc, + i, srcTensorDesc, paramDesc, paramsSpace, + j, linLayerMatDesc, (void **)&linLayerMat)); + + if(linLayerMat == nullptr) { + FatalError("LSTM No weights in hidden layer"); + } + + cudnnDataType_t dataType; + cudnnTensorFormat_t format; + int nbDims; + int filterDimA[3]; + checkCUDNN(cudnnGetFilterNdDescriptor(linLayerMatDesc, 3, &dataType, + &format, &nbDims, filterDimA)); + std::cout<<"Wgs Dims: "<cudnnHandle, rnnDesc, + i, srcTensorDesc, paramDesc, paramsSpace, + j, linLayerBiasDesc, (void **)&linLayerBias)); + + if(linLayerMat == nullptr) { + FatalError("LSTM No bias in hidden layer"); + } + + checkCUDNN(cudnnGetFilterNdDescriptor(linLayerBiasDesc, 3, &dataType, + &format, &nbDims, filterDimA)); + std::cout<<"bias Dims: "<tensorFormat, net->dataType, 2*n, c, h, w) ); + checkCuda( cudaMalloc(&hiddenStateData, 2*input_dim.tot()*sizeof(dnnType)) ); + checkCUDNN( cudnnCreateTensorDescriptor(&cellStateTensorDesc)); + checkCUDNN( cudnnSetTensor4dDescriptor(cellStateTensorDesc, + net->tensorFormat, net->dataType, 2*n, c, h, w) ); + checkCuda( cudaMalloc(&cellStateData, 2*input_dim.tot()*sizeof(dnnType)) ); + + + output_dim = input_dim; + output_dim.c = hiddensize*2; + checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, + net->tensorFormat, net->dataType, output_dim.n, output_dim.c, output_dim.h, output_dim.w) ); + + + + + //allocate data for infer result + checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); +} + +LSTM::~LSTM() { + + checkCuda( cudaFree(dstData) ); +} + +dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) { + + checkCUDNN(cudnnRNNForwardInference( + net->cudnnHandle, rnnDesc, 1, + &srcTensorDesc, srcData, + hiddenStateTensorDesc, hiddenStateData, + cellStateTensorDesc, cellStateData, + paramDesc, paramsSpace, + &dstTensorDesc, dstData, + hiddenStateTensorDesc, hiddenStateData, + cellStateTensorDesc, cellStateData, + workSpace, ws_sizeInBytes + )); + + return dstData; +} + +}} diff --git a/src/utils.cpp b/src/utils.cpp index e6f71f8..444318d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -39,7 +39,8 @@ void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** dat *data_h = new dnnType[size]; if (!dataFile.read ((char*) *data_h, size_b)) { - error_s << "Error reading file " << fname; + error_s << "Error reading file " << fname << " with n of float: "< +#include "tkdnn.h" + +const char *i0_bin = "../tests/imuodom/layers/input0.bin"; +const char *i1_bin = "../tests/imuodom/layers/input1.bin"; +const char *i2_bin = "../tests/imuodom/layers/input2.bin"; +const char *o0_bin = "../tests/imuodom/layers/output0.bin"; +const char *o1_bin = "../tests/imuodom/layers/output1.bin"; +const char *output_bin = "../tests/imuodom/layers/output.bin"; + +const char *c0_bin = "../tests/imuodom/layers/conv1d_7.bin"; +const char *c1_bin = "../tests/imuodom/layers/conv1d_8.bin"; +const char *c2_bin = "../tests/imuodom/layers/conv1d_9.bin"; +const char *c3_bin = "../tests/imuodom/layers/conv1d_10.bin"; +const char *c4_bin = "../tests/imuodom/layers/conv1d_11.bin"; +const char *c5_bin = "../tests/imuodom/layers/conv1d_12.bin"; + +int main() { + + // Network layout + tk::dnn::dataDim_t dim0(1, 4, 1, 100); + tk::dnn::dataDim_t dim1(1, 3, 1, 100); + tk::dnn::dataDim_t dim2(1, 3, 1, 100); + + // Load input + dnnType *i0_d, *i1_d, *i2_d; + dnnType *i0_h, *i1_h, *i2_h; + readBinaryFile(i0_bin, dim0.tot(), &i0_h, &i0_d); + readBinaryFile(i1_bin, dim1.tot(), &i1_h, &i1_d); + readBinaryFile(i2_bin, dim2.tot(), &i2_h, &i2_d); + + tk::dnn::Network net(dim0); + tk::dnn::Input x0 (&net, dim0, i0_d); + tk::dnn::Conv2d x0_0(&net, 128, 1, 11, 1, 1, 0, 0, c0_bin); + tk::dnn::Conv2d x0_1(&net, 128, 1, 11, 1, 1, 0, 0, c1_bin); + tk::dnn::Pooling x0_2(&net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX); + + tk::dnn::Input x1 (&net, dim1, i1_d); + tk::dnn::Conv2d x1_0(&net, 128, 1, 11, 1, 1, 0, 0, c2_bin); + tk::dnn::Conv2d x1_1(&net, 128, 1, 11, 1, 1, 0, 0, c3_bin); + tk::dnn::Pooling x1_2(&net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX); + + tk::dnn::Input x2 (&net, dim2, i2_d); + tk::dnn::Conv2d x2_0(&net, 128, 1, 11, 1, 1, 0, 0, c4_bin); + tk::dnn::Conv2d x2_1(&net, 128, 1, 11, 1, 1, 0, 0, c5_bin); + tk::dnn::Pooling x2_2(&net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX); + + tk::dnn::Layer *concat_l[3] = { &x0_2, &x1_2, &x2_2 }; + tk::dnn::Route concat (&net, concat_l, 3); + + tk::dnn::LSTM lstm0(&net, 128, "ciao"); + + net.print(); + + dnnType *data; + tk::dnn::dataDim_t dim; + + TIMER_START + // Inference + data = net.infer(dim, data); dim.print(); + TIMER_STOP + + // Print real test + std::cout<<"\n==== CHECK RESULT ====\n"; + dnnType *out; + dnnType *out_h; + readBinaryFile(output_bin, dim.tot(), &out_h, &out); + checkResult(dim.tot(), data, out); + return 0; +} diff --git a/tests/imuodom/infer.py b/tests/imuodom/infer.py new file mode 100644 index 0000000..9d9929d --- /dev/null +++ b/tests/imuodom/infer.py @@ -0,0 +1,74 @@ +import keras +from keras.models import load_model +import keras.backend.tensorflow_backend as KTF +import numpy as np +import argparse +import tensorflow as tf +import os +import random +import struct +from keras.models import Sequential, Model + +def bin_write(f, data): + data = data.flatten() + fmt = 'f'*len(data) + bin = struct.pack(fmt, *data) + f.write(bin) + + +if __name__ == '__main__': + + + print("DATA FORMAT: ", keras.backend.image_data_format()) + + print("Load model: ", "ferrariS1.hdf5") + model = load_model("ferrariS1.hdf5") + model.summary() + + weights = model.get_weights() + + x_angle = np.random.rand(1,100,4) + x_gyro = np.random.rand(1,100,3) + x_acc = np.random.rand(1,100,3) + + [yhat_delta_p, yhat_delta_q] = model.predict([x_angle, x_gyro, x_acc], batch_size=1, verbose=1) + + layer_name = 'bidirectional_3' + intermediate_layer_model = Model(inputs=model.input, + outputs=model.get_layer(layer_name).output) + intermediate_output = intermediate_layer_model.predict([x_angle, x_gyro, x_acc]) + + x_angle = np.array([x_angle]) + x_gyro = np.array([x_gyro]) + x_acc = np.array([x_acc]) + intermediate_output = np.array([intermediate_output]) + + x_angle = x_angle.transpose(0, 3, 1, 2) + x_gyro = x_gyro.transpose(0, 3, 1, 2) + x_acc = x_acc.transpose(0, 3, 1, 2) + intermediate_output = intermediate_output.transpose(0, 3, 1, 2) + + print("x0: ", np.shape(x_angle)) + print("out: ",np.shape(intermediate_output)) + + x_angle = np.array(x_angle.flatten(), dtype=np.float32) + x_gyro = np.array(x_gyro.flatten(), dtype=np.float32) + x_acc = np.array(x_acc.flatten(), dtype=np.float32) + yhat_delta_p = np.array(yhat_delta_p.flatten(), dtype=np.float32) + yhat_delta_q = np.array(yhat_delta_q.flatten(), dtype=np.float32) + intermediate_output = np.array(intermediate_output.flatten(), dtype=np.float32) + + + f = open("layers/input0.bin", mode='wb') + bin_write(f, x_angle) + f = open("layers/input1.bin", mode='wb') + bin_write(f, x_gyro) + f = open("layers/input2.bin", mode='wb') + bin_write(f, x_acc) + f = open("layers/output0.bin", mode='wb') + bin_write(f, yhat_delta_p) + f = open("layers/output1.bin", mode='wb') + bin_write(f, yhat_delta_q) + f = open("layers/output.bin", mode='wb') + bin_write(f, intermediate_output) + diff --git a/tests/simple/test_model.py b/tests/simple/test_model.py index 60f17d8..3b1d053 100644 --- a/tests/simple/test_model.py +++ b/tests/simple/test_model.py @@ -1,43 +1,49 @@ import keras import numpy as np from keras.models import Sequential -from keras.layers import Input, Dense, Activation, Flatten, Dropout, ELU, Reshape, Lambda +from keras.layers import Input, Dense, Activation, Flatten, Dropout, ELU, Reshape, Lambda, Conv1D from keras.layers.convolutional import Convolution2D, Convolution3D from keras.layers.pooling import MaxPooling2D, MaxPooling3D, AveragePooling3D from keras.models import Sequential, Model from keras.layers import Cropping2D import keras.backend.tensorflow_backend as KTF +import struct +from keras.models import Sequential, Model -def dense_model(): - model = Sequential() +def bin_write(f, data): + data = data.flatten() + fmt = 'f'*len(data) + bin = struct.pack(fmt, *data) + f.write(bin) + +def create_model(): + x1 = Input((6, 16), name='x1') + conv = Conv1D(4, 2)(x1) + model = Model([x1], [conv]) + model.summary() - model.add(Reshape((10, 10, 1), input_shape=(10, 10))) - model.add(Convolution2D(2, (4, 4), subsample=(2, 2), - bias_initializer='random_uniform', activation="relu")) - model.add(Convolution2D(4, (2, 2), subsample=(1, 1), - bias_initializer='random_uniform', activation="relu")) - model.add(Flatten()) - model.add(Dense(4, bias_initializer='random_uniform', activation="relu")) - sgd = keras.optimizers.Adam(lr=1e-4, decay=1e-8) - model.compile(optimizer=sgd, loss="mse") return model - if __name__ == '__main__': - print "DATA FORMAT: ", keras.backend.image_data_format() + print ("DATA FORMAT: ", keras.backend.image_data_format()) - model = dense_model() - model.save("net.h5") + model = create_model() + model.save("net.hdf5") - grid = np.random.rand(10,10) - X = grid[None,:,:] - i = np.array(grid.flatten(), dtype=np.float32) - print i - i.tofile("input.bin", format="f") - print "Input: ", X + x = np.random.rand(1,1,6,16) + r = model.predict( x[0], batch_size=1) + r = np.array([r]) + + x = x.transpose(0, 3, 1, 2) + r = r.transpose(0, 3, 1, 2) + print("in: ", np.shape(x)) + print("out: ", np.shape(r)) + + x = np.array(x.flatten(), dtype=np.float32) + f = open("input.bin", mode='wb') + bin_write(f, x) + + r = np.array(r.flatten(), dtype=np.float32) + f = open("output.bin", mode='wb') + bin_write(f, r) - r = model.predict( X, batch_size=1) - print np.shape(r) - print "Result: ", r - print "Result shape: ", np.shape(r) - r.tofile("output.bin", format="f") diff --git a/tests/simple/test_simple.cpp b/tests/simple/test_simple.cpp index a7628ea..3427d6d 100644 --- a/tests/simple/test_simple.cpp +++ b/tests/simple/test_simple.cpp @@ -2,23 +2,15 @@ #include "tkdnn.h" const char *input_bin = "../tests/simple/input.bin"; -const char *c0_bin = "../tests/simple/layers/c0.bin"; -const char *c1_bin = "../tests/simple/layers/c1.bin"; -const char *d2_bin = "../tests/simple/layers/d2.bin"; +const char *c0_bin = "../tests/simple/layers/conv1d_1.bin"; const char *output_bin = "../tests/simple/output.bin"; int main() { // Network layout - tk::dnn::dataDim_t dim(1, 1, 10, 10, 1); + tk::dnn::dataDim_t dim(1, 16, 1, 6); tk::dnn::Network net(dim); - tk::dnn::Conv2d l0(&net, 2, 4, 4, 2, 2, 0, 0, c0_bin); - tk::dnn::Activation l1(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Conv2d l2(&net, 4, 2, 2, 1, 1, 0, 0, c1_bin); - tk::dnn::Activation l3(&net, CUDNN_ACTIVATION_RELU); - tk::dnn::Flatten l4(&net); - tk::dnn::Dense l5(&net, 4, d2_bin); - tk::dnn::Activation l6(&net, CUDNN_ACTIVATION_RELU); + tk::dnn::Conv2d l0(&net, 4, 1, 2, 1, 1, 0, 0, c0_bin); // Load input dnnType *data; diff --git a/tests/weights_exporter.py b/tests/weights_exporter.py index df8bab3..912ef82 100644 --- a/tests/weights_exporter.py +++ b/tests/weights_exporter.py @@ -5,96 +5,51 @@ import numpy as np import argparse import tensorflow as tf import os -import msgpack -import lmdb import random +import struct +from keras.models import Sequential, Model -def export_dense(name, weights, bias): - print "######## EXPORT", name, "LAYER ########" - print "Original weighs:" - print weights - print bias, "\n" +def bin_write(f, data): + data = data.flatten() + fmt = 'f'*len(data) + bin = struct.pack(fmt, *data) + f.write(bin) - #input, filters - I, C = np.shape(weights) - B = np.shape(bias) - print "w shape: ", I, C - print "b shape: ", B +def export_layer(name, weights, bias): + print ("######## EXPORT", name, "LAYER ########") - wgs = [ [ j[i] for j in weights ] for i in xrange(C) ] - wgs = np.array(wgs, dtype=np.float32) - - print "REPOSITIONED WEIGHTS:" - print wgs + print("wgs pretranpose: ", np.shape(weights)) + # convert NHWC to NCHW + if(weights.ndim == 4): + weights = weights.transpose(3,2,0,1) + elif(weights.ndim == 3): + weights = weights.transpose(2,1,0) + else: + print("Ndim", weights.ndim) + raise("not implemented with dim" ) + print("weights: ", np.shape(weights)) + print("bias: ", np.shape(bias)) + + weights = np.array(weights.flatten(), dtype=np.float32) bias = np.array(bias, dtype=np.float32) - wgs.tofile(name + ".bin", format="f") - bias.tofile(name + ".bias.bin", format="f") - print "WEIGHTS saved\n" + print(len(weights) + len(bias)) -def export_conv2d(name, weights, bias): - print "######## EXPORT", name, "LAYER ########" - print "Original weighs:" - print weights - print bias, "\n" - - # height, width, input, filters - H, W, N, C = np.shape(weights) - B = np.shape(bias) - print "w shape: ", N, C, H, W - print "b shape: ", B + f = open(name + ".bin", mode='wb') + bin_write(f, weights) + bin_write(f, bias) + print ("WEIGHTS saved\n") - wgs = weights.transpose() - wgs = wgs.transpose(0, 1, 3, 2) - print "Final shape:", np.shape(wgs) - wgs = np.array(wgs.flatten(), dtype=np.float32) - - print "REPOSITIONED WEIGHTS:" - print wgs - - bias = np.array(bias, dtype=np.float32) - - wgs.tofile(name + ".bin", format="f") - bias.tofile(name + ".bias.bin", format="f") - print "WEIGHTS saved\n" - -def export_conv3d(name, weights, bias): - print "######## EXPORT", name, "LAYER ########" - print "Original weighs:" - print weights - print bias, "\n" - - print np.shape(weights) - # height, width, input, thickness, filters - H, W, T, N, C = np.shape(weights) - B = np.shape(bias) - print "w shape: ", T, C, H, W #thickness is number of images for cudnn - print "b shape: ", B - - wgs = weights.transpose() - wgs = wgs.transpose(0, 1, 4, 3, 2) - print "Final shape:", np.shape(wgs) - wgs = np.array(wgs.flatten(), dtype=np.float32) - - print "REPOSITIONED WEIGHTS:" - print wgs - - bias = np.array(bias, dtype=np.float32) - - wgs.tofile(name + ".bin", format="f") - bias.tofile(name + ".bias.bin", format="f") - print "WEIGHTS saved\n" - - -def get_session(gpu_fraction=0.5): - gpu_options = tf.GPUOptions(allow_growth=True) - #per_process_gpu_memory_fraction=gpu_fraction) - return tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) +def export_bidir(name, weights): + print ("######## EXPORT", name, "LAYER ########") + + for w in weights: + print(np.shape(w)) #https://github.com/fchollet/keras/wiki/Converting-convolution-kernels-from-Theano-to-TensorFlow-and-vice-versa if __name__ == '__main__': - KTF.set_session(get_session()) + print("DATA FORMAT: ", keras.backend.image_data_format()) parser = argparse.ArgumentParser(description='KERAS WEIGHTS EXPORTER TO CUDNN') parser.add_argument('model',type=str, @@ -103,31 +58,41 @@ if __name__ == '__main__': args = parser.parse_args() - print "DATA FORMAT: ", keras.backend.image_data_format() + print("DATA FORMAT: ", keras.backend.image_data_format()) - print "Load model: ", args.model + print("Load model: ", args.model) model = load_model(args.model) + model.summary() + weights = model.get_weights() ws = np.shape(weights) - print "Weights shape:", ws + print("Weights shape:", ws) if not os.path.exists(args.output): os.makedirs(args.output) - num = 0 + name_num = 0 for l in model.layers: - name = l.name - if name.startswith("conv3d"): - export_conv3d(args.output + "/conv" + str(name_num), weights[num], weights[num+1]) - elif name.startswith("conv2d"): - export_conv2d(args.output + "/conv" + str(name_num), weights[num], weights[num+1]) - elif name.startswith("dense"): - export_dense(args.output + "/dense" + str(name_num), weights[num], weights[num+1]) - else: - print "skip:", name, "has no weights" - continue - name_num += 1 - num += 2 + print("\n\nNAME: ", l.name) + print("input: ", l.input_shape, " output: ", l.output_shape) + wgs = l.get_weights() + print("wgs num: ", len(wgs)) + + name = l.name + if name.startswith("conv3d"): + export_layer(args.output + "/" + name, wgs[0], wgs[1]) + elif name.startswith("conv2d"): + export_layer(args.output + "/" + name, wgs[0], wgs[1]) + elif name.startswith("conv1d"): + export_layer(args.output + "/" + name, wgs[0], wgs[1]) + elif name.startswith("dense"): + export_layer(args.output + "/" + name, wgs[0], wgs[1]) + elif name.startswith("bidirectional"): + export_bidir(args.output + "/" + name, wgs) + else: + print ("skip:", name, "has no weights") + continue + From 03d39d991c5932aa4c94f7b86fc8c64e9d48238b Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 13 Feb 2020 23:04:29 +0100 Subject: [PATCH 062/228] LSTM to be tested --- include/tkDNN/Layer.h | 40 ++++--- src/LSTM.cpp | 246 ++++++++++++++++++++++++------------------ 2 files changed, 170 insertions(+), 116 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index f15c781..c538fc9 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -207,9 +207,11 @@ protected: /** Bidirectional LSTM layer + + implementation info: https://github.com/jiangnanhugo/seq2seq_cuda/blob/e4dbdcfa0517c972bfd4beea9f11a5233954093c/src/rnn.cpp - - numlayers = 1 # hardcoded as 1 + https://github.com/Jeffery-Song/mxnet-test/blob/aab666faad44011f7a67b527b5f6c960367d0422/src/operator/cudnn_rnn-inl.h + https://stackoverflow.com/a/38737941 PARAMS (numlayers*2): layer0: @@ -221,7 +223,9 @@ protected: ( HIDDEN, ? ) ??? ( HIDDEN * 8 ) ??? - output shape: ( 2*HIDDEN, INH, INW ) + 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 { @@ -232,20 +236,28 @@ public: virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); - int kernelH, kernelW, strideH, strideW, paddingH, paddingW; + const bool bidirectional = 1; /**> is the net bidir */ + int stateSize = 0; /**> number of hidden states */ + int seqLen = 0; /**> number of timesteps */ + int numLayers = 1; /**> number of internal layers */ protected: - cudnnFilterDescriptor_t paramDesc; - cudnnTensorDescriptor_t hiddenStateTensorDesc, cellStateTensorDesc; - cudnnRNNDescriptor_t rnnDesc; - cudnnRNNDataDescriptor_t rnnDataDesc; - cudnnDropoutDescriptor_t dropDesc; - cudnnRNNAlgo_t algo; + cudnnRNNDescriptor_t rnnDesc; + cudnnDropoutDescriptor_t dropoutDesc; + dnnType *dropout_states_, *work_space_; - dnnType *hiddenStateData, *cellStateData; - dnnType *paramsSpace; - void* workSpace; - size_t ws_sizeInBytes; + size_t workspace_byte_, reserve_space_byte_, dropout_byte_; + int workspace_size_, dropout_size_; + + std::vector x_desc_vec_, y_desc_vec_, dx_desc_vec_, dy_desc_vec_; + cudnnTensorDescriptor_t hx_desc_, cx_desc_; + cudnnTensorDescriptor_t hy_desc_, cy_desc_; + cudnnTensorDescriptor_t dhx_desc_, dcx_desc_; + cudnnTensorDescriptor_t dhy_desc_, dcy_desc_; + dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr; + + cudnnFilterDescriptor_t w_desc_, dw_desc_; + dnnType *w_ptr, *dw_ptr; }; diff --git a/src/LSTM.cpp b/src/LSTM.cpp index 3176819..be12cec 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -7,111 +7,143 @@ namespace tk { namespace dnn { LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : Layer(net) { - checkCUDNN( cudnnCreateFilterDescriptor(¶mDesc)); - checkCUDNN( cudnnCreateRNNDescriptor(&rnnDesc) ); - checkCUDNN( cudnnCreateRNNDataDescriptor(&rnnDataDesc) ); - checkCUDNN( cudnnCreateDropoutDescriptor(&dropDesc)); + int batchSize = input_dim.n; + int inputSize = input_dim.c; + seqLen = input_dim.w; + stateSize = hiddensize; - int n = input_dim.n; - int c = input_dim.c; - int h = input_dim.h; - int w = input_dim.w; - checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc, - net->tensorFormat, net->dataType, n, 1, h, w) ); + std::cout<<"LSTM seqLen: "<cudnnHandle, rnnDesc, hiddensize, numlayers, dropDesc, - cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, - cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL, cudnnRNNMode_t::CUDNN_LSTM, - cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD, net->dataType) ); + // init Tensor Descriptors + std::vector x_vec(seqLen); + std::vector y_vec(seqLen); + std::vector dx_vec(seqLen); + std::vector dy_vec(seqLen); - // find dimension of params - size_t params_size = 0; - checkCUDNN( cudnnGetRNNParamsSize(net->cudnnHandle, rnnDesc, srcTensorDesc, ¶ms_size, net->dataType) ); - std::cout<<"Params size bytes: "<dataType, net->tensorFormat, 3, dimW)); - checkCuda( cudaMalloc(¶msSpace, params_size) ); + checkCUDNN(cudnnSetTensorNdDescriptor(x_vec[i], + net->dataType, 3, dimA, strideA)); + checkCUDNN(cudnnSetTensorNdDescriptor(dx_vec[i], + net->dataType, 3, dimA, strideA)); + dimA[0] = batchSize; + dimA[1] = bidirectional ? stateSize*2 : stateSize; + dimA[2] = 1; + strideA[0] = dimA[2] * dimA[1]; + strideA[1] = dimA[2]; + strideA[2] = 1; - - int numlinearlayers = 8; - - for(int i=0; icudnnHandle, rnnDesc, - i, srcTensorDesc, paramDesc, paramsSpace, - j, linLayerMatDesc, (void **)&linLayerMat)); - - if(linLayerMat == nullptr) { - FatalError("LSTM No weights in hidden layer"); - } - - cudnnDataType_t dataType; - cudnnTensorFormat_t format; - int nbDims; - int filterDimA[3]; - checkCUDNN(cudnnGetFilterNdDescriptor(linLayerMatDesc, 3, &dataType, - &format, &nbDims, filterDimA)); - std::cout<<"Wgs Dims: "<cudnnHandle, rnnDesc, - i, srcTensorDesc, paramDesc, paramsSpace, - j, linLayerBiasDesc, (void **)&linLayerBias)); - - if(linLayerMat == nullptr) { - FatalError("LSTM No bias in hidden layer"); - } - - checkCUDNN(cudnnGetFilterNdDescriptor(linLayerBiasDesc, 3, &dataType, - &format, &nbDims, filterDimA)); - std::cout<<"bias Dims: "<dataType, 3, dimA, strideA)); + checkCUDNN(cudnnSetTensorNdDescriptor(dy_vec[i], + net->dataType, 3, dimA, strideA)); } + // apply tensordesc + x_desc_vec_ = x_vec; + y_desc_vec_ = y_vec; + dx_desc_vec_ = dx_vec; + dy_desc_vec_ = dy_vec; + // set the state tensors + dimA[0] = numLayers * (bidirectional ? 2 : 1); + 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(cudnnCreateTensorDescriptor(&dhx_desc_)); + checkCUDNN(cudnnCreateTensorDescriptor(&dcx_desc_)); + checkCUDNN(cudnnCreateTensorDescriptor(&dhy_desc_)); + checkCUDNN(cudnnCreateTensorDescriptor(&dcy_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)); + checkCUDNN(cudnnSetTensorNdDescriptor(dhx_desc_, net->dataType, 3, dimA, strideA)); + checkCUDNN(cudnnSetTensorNdDescriptor(dcx_desc_, net->dataType, 3, dimA, strideA)); + checkCUDNN(cudnnSetTensorNdDescriptor(dhy_desc_, net->dataType, 3, dimA, strideA)); + checkCUDNN(cudnnSetTensorNdDescriptor(dcy_desc_, net->dataType, 3, dimA, strideA)); + // allocate dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr; + checkCuda( cudaMalloc(&hx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); + checkCuda( cudaMalloc(&cx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); + checkCuda( cudaMalloc(&hy_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); + checkCuda( cudaMalloc(&cy_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); - checkCUDNN( cudnnCreateTensorDescriptor(&hiddenStateTensorDesc)); - checkCUDNN( cudnnSetTensor4dDescriptor(hiddenStateTensorDesc, - net->tensorFormat, net->dataType, 2*n, c, h, w) ); - checkCuda( cudaMalloc(&hiddenStateData, 2*input_dim.tot()*sizeof(dnnType)) ); - checkCUDNN( cudnnCreateTensorDescriptor(&cellStateTensorDesc)); - checkCUDNN( cudnnSetTensor4dDescriptor(cellStateTensorDesc, - net->tensorFormat, net->dataType, 2*n, c, h, w) ); - checkCuda( cudaMalloc(&cellStateData, 2*input_dim.tot()*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)); + + checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle, + rnnDesc, stateSize, numLayers, dropoutDesc, + cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, + cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL, + cudnnRNNMode_t::CUDNN_LSTM, + cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD, + net->dataType)); + + + // 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: "<dataType, net->tensorFormat, 3, dim_w)); + checkCUDNN(cudnnSetFilterNdDescriptor(dw_desc_, + net->dataType, net->tensorFormat, 3, dim_w)); + // allocate params dnnType *w_ptr, *dw_ptr; + checkCuda( cudaMalloc(&w_ptr, cudnn_params*sizeof(dnnType)) ); + checkCuda( cudaMalloc(&dw_ptr, cudnn_params*sizeof(dnnType)) ); output_dim = input_dim; - output_dim.c = hiddensize*2; - checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc, - net->tensorFormat, net->dataType, output_dim.n, output_dim.c, output_dim.h, output_dim.w) ); - - - + output_dim.c = stateSize*2; //allocate data for infer result checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); @@ -123,19 +155,29 @@ LSTM::~LSTM() { } dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) { + std::cout<<"LSTM infer\n"; - checkCUDNN(cudnnRNNForwardInference( - net->cudnnHandle, rnnDesc, 1, - &srcTensorDesc, srcData, - hiddenStateTensorDesc, hiddenStateData, - cellStateTensorDesc, cellStateData, - paramDesc, paramsSpace, - &dstTensorDesc, dstData, - hiddenStateTensorDesc, hiddenStateData, - cellStateTensorDesc, cellStateData, - workSpace, ws_sizeInBytes - )); + checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle, + rnnDesc, + seqLen, + x_desc_vec_.data(), // input array of desc + srcData, // 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 + w_ptr, // weights pointer + y_desc_vec_.data(), // output desc + dstData, // 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 + dim = output_dim; return dstData; } From c1c2173e4d9ea4f59d95ee069fa9e0fc1f58f31b Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 13 Feb 2020 23:10:48 +0100 Subject: [PATCH 063/228] removed unused var --- include/tkDNN/Layer.h | 10 ++++------ src/LSTM.cpp | 42 +++++++++++++----------------------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index c538fc9..596fbec 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -246,18 +246,16 @@ protected: cudnnDropoutDescriptor_t dropoutDesc; dnnType *dropout_states_, *work_space_; - size_t workspace_byte_, reserve_space_byte_, dropout_byte_; + size_t workspace_byte_, dropout_byte_; int workspace_size_, dropout_size_; - std::vector x_desc_vec_, y_desc_vec_, dx_desc_vec_, dy_desc_vec_; + std::vector x_desc_vec_, y_desc_vec_; cudnnTensorDescriptor_t hx_desc_, cx_desc_; cudnnTensorDescriptor_t hy_desc_, cy_desc_; - cudnnTensorDescriptor_t dhx_desc_, dcx_desc_; - cudnnTensorDescriptor_t dhy_desc_, dcy_desc_; dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr; - cudnnFilterDescriptor_t w_desc_, dw_desc_; - dnnType *w_ptr, *dw_ptr; + cudnnFilterDescriptor_t w_desc_; + dnnType *w_ptr; }; diff --git a/src/LSTM.cpp b/src/LSTM.cpp index be12cec..46a0593 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -17,16 +17,12 @@ LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : // init Tensor Descriptors std::vector x_vec(seqLen); std::vector y_vec(seqLen); - std::vector dx_vec(seqLen); - std::vector dy_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])); - checkCUDNN(cudnnCreateTensorDescriptor(&dx_vec[i])); - checkCUDNN(cudnnCreateTensorDescriptor(&dy_vec[i])); dimA[0] = batchSize; dimA[1] = inputSize; @@ -36,29 +32,21 @@ LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : strideA[0] = dimA[2] * dimA[1]; strideA[1] = dimA[2]; strideA[2] = 1; - checkCUDNN(cudnnSetTensorNdDescriptor(x_vec[i], net->dataType, 3, dimA, strideA)); - checkCUDNN(cudnnSetTensorNdDescriptor(dx_vec[i], - net->dataType, 3, dimA, strideA)); + dimA[0] = batchSize; dimA[1] = bidirectional ? stateSize*2 : 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)); - checkCUDNN(cudnnSetTensorNdDescriptor(dy_vec[i], - net->dataType, 3, dimA, strideA)); } - // apply tensordesc x_desc_vec_ = x_vec; y_desc_vec_ = y_vec; - dx_desc_vec_ = dx_vec; - dy_desc_vec_ = dy_vec; // set the state tensors @@ -72,18 +60,10 @@ LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : checkCUDNN(cudnnCreateTensorDescriptor(&cx_desc_)); checkCUDNN(cudnnCreateTensorDescriptor(&hy_desc_)); checkCUDNN(cudnnCreateTensorDescriptor(&cy_desc_)); - checkCUDNN(cudnnCreateTensorDescriptor(&dhx_desc_)); - checkCUDNN(cudnnCreateTensorDescriptor(&dcx_desc_)); - checkCUDNN(cudnnCreateTensorDescriptor(&dhy_desc_)); - checkCUDNN(cudnnCreateTensorDescriptor(&dcy_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)); - checkCUDNN(cudnnSetTensorNdDescriptor(dhx_desc_, net->dataType, 3, dimA, strideA)); - checkCUDNN(cudnnSetTensorNdDescriptor(dcx_desc_, net->dataType, 3, dimA, strideA)); - checkCUDNN(cudnnSetTensorNdDescriptor(dhy_desc_, net->dataType, 3, dimA, strideA)); - checkCUDNN(cudnnSetTensorNdDescriptor(dcy_desc_, net->dataType, 3, dimA, strideA)); // allocate dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr; checkCuda( cudaMalloc(&hx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); checkCuda( cudaMalloc(&cx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); @@ -130,28 +110,32 @@ LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : // Set param descriptors checkCUDNN(cudnnCreateFilterDescriptor(&w_desc_)); - checkCUDNN(cudnnCreateFilterDescriptor(&dw_desc_)); int dim_w[3] = {1, 1, 1}; dim_w[0] = cudnn_params; checkCUDNN(cudnnSetFilterNdDescriptor(w_desc_, net->dataType, net->tensorFormat, 3, dim_w)); - checkCUDNN(cudnnSetFilterNdDescriptor(dw_desc_, - net->dataType, net->tensorFormat, 3, dim_w)); - // allocate params dnnType *w_ptr, *dw_ptr; + // allocate params dnnType *w_ptr; checkCuda( cudaMalloc(&w_ptr, cudnn_params*sizeof(dnnType)) ); - checkCuda( cudaMalloc(&dw_ptr, cudnn_params*sizeof(dnnType)) ); - + // set output dim output_dim = input_dim; output_dim.c = stateSize*2; - + //allocate data for infer result checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); } LSTM::~LSTM() { + checkCuda(cudaFree(hx_ptr)); + checkCuda(cudaFree(cx_ptr)); + checkCuda(cudaFree(hy_ptr)); + checkCuda(cudaFree(cy_ptr)); + checkCuda(cudaFree(w_ptr )); - checkCuda( cudaFree(dstData) ); + checkCuda(cudaFree(work_space_ )); + checkCuda(cudaFree(dropout_states_)); + + checkCuda(cudaFree(dstData)); } dnnType* LSTM::infer(dataDim_t &dim, dnnType* srcData) { From 4fa5d2c231900e8ee9bfbab908b2ac97add974db Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Thu, 13 Feb 2020 23:21:28 +0100 Subject: [PATCH 064/228] lstm return seq --- include/tkDNN/Layer.h | 3 ++- src/LSTM.cpp | 16 ++++++++++++---- tests/imuodom/imuodom.cpp | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 596fbec..240d9a2 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -230,13 +230,14 @@ protected: class LSTM : public Layer { public: - LSTM(Network *net, int hiddensize, std::string fname_weights); + 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 = 1; /**> is the net bidir */ + bool returnSeq = false; /**> if false return only the result of last timestep */ int stateSize = 0; /**> number of hidden states */ int seqLen = 0; /**> number of timesteps */ int numLayers = 1; /**> number of internal layers */ diff --git a/src/LSTM.cpp b/src/LSTM.cpp index 46a0593..c31bccf 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -4,9 +4,10 @@ namespace tk { namespace dnn { -LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : +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; @@ -117,12 +118,19 @@ LSTM::LSTM( Network *net, int hiddensize, std::string fname_weights) : // allocate params dnnType *w_ptr; checkCuda( cudaMalloc(&w_ptr, cudnn_params*sizeof(dnnType)) ); + + + //allocate data for infer result + int dstDim = input_dim.n * stateSize*2 * input_dim.h * input_dim.w; + checkCuda( cudaMalloc(&dstData, dstDim*sizeof(dnnType)) ); + // set output dim output_dim = input_dim; output_dim.c = stateSize*2; - - //allocate data for infer result - checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) ); + if(!returnSeq) { + output_dim.h = 1; + output_dim.w = 1; + } } LSTM::~LSTM() { diff --git a/tests/imuodom/imuodom.cpp b/tests/imuodom/imuodom.cpp index 14146b2..6fc3fba 100644 --- a/tests/imuodom/imuodom.cpp +++ b/tests/imuodom/imuodom.cpp @@ -48,7 +48,8 @@ int main() { tk::dnn::Layer *concat_l[3] = { &x0_2, &x1_2, &x2_2 }; tk::dnn::Route concat (&net, concat_l, 3); - tk::dnn::LSTM lstm0(&net, 128, "ciao"); + tk::dnn::LSTM lstm0(&net, 128, true, "ciao"); + tk::dnn::LSTM lstm1(&net, 128, false, "ciao"); net.print(); From 2c1df5619f4362f3922649d4430054739e81c0ed Mon Sep 17 00:00:00 2001 From: Davide Sapienza Date: Fri, 14 Feb 2020 18:44:13 +0100 Subject: [PATCH 065/228] 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); } From 4746121d438c72d0287a6ff7edb193a2da68029d Mon Sep 17 00:00:00 2001 From: Francesco Gatti Date: Sat, 15 Feb 2020 20:37:08 +0100 Subject: [PATCH 066/228] LSTM params --- include/tkDNN/Layer.h | 5 ++- src/LSTM.cpp | 94 +++++++++++++++++++++++++++++++++------ tests/imuodom/imuodom.cpp | 20 ++++++--- tests/imuodom/infer.py | 1 + tests/weights_exporter.py | 16 +++++-- 5 files changed, 111 insertions(+), 25 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 240d9a2..319df6a 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -212,6 +212,7 @@ protected: 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: @@ -236,7 +237,7 @@ public: virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); - const bool bidirectional = 1; /**> is the net bidir */ + const bool bidirectional = false; /**> is the net bidir */ bool returnSeq = false; /**> if false return only the result of last timestep */ int stateSize = 0; /**> number of hidden states */ int seqLen = 0; /**> number of timesteps */ @@ -254,9 +255,11 @@ protected: 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; }; diff --git a/src/LSTM.cpp b/src/LSTM.cpp index c31bccf..ce2a9f5 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -66,10 +66,12 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig 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; - checkCuda( cudaMalloc(&hx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); - checkCuda( cudaMalloc(&cx_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); - checkCuda( cudaMalloc(&hy_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); - checkCuda( cudaMalloc(&cy_ptr, dimA[0]*dimA[1]*dimA[2]*sizeof(dnnType)) ); + 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 ??? @@ -89,7 +91,7 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle, rnnDesc, stateSize, numLayers, dropoutDesc, cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, - cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL, + (bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL), cudnnRNNMode_t::CUDNN_LSTM, cudnnRNNAlgo_t::CUDNN_RNN_ALGO_STANDARD, net->dataType)); @@ -115,22 +117,81 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig dim_w[0] = cudnn_params; checkCUDNN(cudnnSetFilterNdDescriptor(w_desc_, net->dataType, net->tensorFormat, 3, dim_w)); - // allocate params dnnType *w_ptr; - checkCuda( cudaMalloc(&w_ptr, cudnn_params*sizeof(dnnType)) ); - + // load params + readBinaryFile(fname_weights, cudnn_params, &w_h, &w_ptr); //allocate data for infer result - int dstDim = input_dim.n * stateSize*2 * input_dim.h * input_dim.w; + int dstDim = input_dim.n * stateSize*(bidirectional ? 2 : 1) * input_dim.h * input_dim.w; checkCuda( cudaMalloc(&dstData, dstDim*sizeof(dnnType)) ); // set output dim output_dim = input_dim; - output_dim.c = stateSize*2; + output_dim.c = stateSize*(bidirectional ? 2 : 1); if(!returnSeq) { output_dim.h = 1; output_dim.w = 1; } + + + + + // 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*(bidirectional?2:1); ++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-> "< Date: Sun, 16 Feb 2020 16:28:39 +0100 Subject: [PATCH 067/228] works but it need cleaning --- include/tkDNN/Layer.h | 3 +- include/tkDNN/utils.h | 2 +- src/LSTM.cpp | 163 ++++++++++++++++++++++++++++------- src/utils.cpp | 4 +- tests/imuodom/imuodom.cpp | 26 +++--- tests/imuodom/infer.py | 25 +++--- tests/simple/test_model.py | 15 ++-- tests/simple/test_simple.cpp | 8 +- tests/weights_exporter.py | 44 ++++++++-- 9 files changed, 219 insertions(+), 71 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index 319df6a..f12027f 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -237,7 +237,7 @@ public: virtual dnnType* infer(dataDim_t &dim, dnnType* srcData); - const bool bidirectional = false; /**> is the net bidir */ + const bool bidirectional = true; /**> is the net bidir */ bool returnSeq = false; /**> if false return only the result of last timestep */ int stateSize = 0; /**> number of hidden states */ int seqLen = 0; /**> number of timesteps */ @@ -260,6 +260,7 @@ protected: cudnnFilterDescriptor_t w_desc_; dnnType *w_ptr; dnnType *w_h; + dnnType *wf_ptr, *wb_ptr; // params pointer forward and backward layer }; diff --git a/include/tkDNN/utils.h b/include/tkDNN/utils.h index dc34a31..3fa9d34 100644 --- a/include/tkDNN/utils.h +++ b/include/tkDNN/utils.h @@ -91,7 +91,7 @@ void printCenteredTitle(const char *title, char fill, int dim); bool fileExist(const char *fname); 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 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); void resize(int size, dnnType **data); diff --git a/src/LSTM.cpp b/src/LSTM.cpp index ce2a9f5..00d8f76 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -37,7 +37,7 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig net->dataType, 3, dimA, strideA)); dimA[0] = batchSize; - dimA[1] = bidirectional ? stateSize*2 : stateSize; + dimA[1] = stateSize; dimA[2] = 1; strideA[0] = dimA[2] * dimA[1]; strideA[1] = dimA[2]; @@ -51,7 +51,7 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig // set the state tensors - dimA[0] = numLayers * (bidirectional ? 2 : 1); + dimA[0] = numLayers; dimA[1] = batchSize; dimA[2] = stateSize; strideA[0] = dimA[2] * dimA[1]; @@ -91,7 +91,8 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig checkCUDNN(cudnnSetRNNDescriptor(net->cudnnHandle, rnnDesc, stateSize, numLayers, dropoutDesc, cudnnRNNInputMode_t::CUDNN_LINEAR_INPUT, - (bidirectional ? cudnnDirectionMode_t::CUDNN_BIDIRECTIONAL : cudnnDirectionMode_t::CUDNN_UNIDIRECTIONAL), + //(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)); @@ -119,23 +120,26 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig net->dataType, net->tensorFormat, 3, dim_w)); // load params - readBinaryFile(fname_weights, cudnn_params, &w_h, &w_ptr); - - //allocate data for infer result - int dstDim = input_dim.n * stateSize*(bidirectional ? 2 : 1) * input_dim.h * input_dim.w; - checkCuda( cudaMalloc(&dstData, dstDim*sizeof(dnnType)) ); + 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: "<cublasHandle, srcData, trans, dim.c, dim.h*dim.w*dim.l); + srcData = trans; + + // reposition in invered order + dnnType *srcBack; + checkCuda( cudaMalloc(&srcBack, dim.tot()*sizeof(dnnType))); + for(int i=0; icudnnHandle, + rnnDesc, + seqLen, // number of time steps (nT) + x_desc_vec_.data(), // input array of desc (nT*nC_in) + srcData, // 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 + } + std::cout<<"OUTPUT F:\n"; + printDeviceVector(singleOutput.tot(), dstF); + + std::cout<<"INPUT:\n"; + printDeviceVector(input_dim.tot(), srcBack); + + // 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) + srcBack, // 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, // 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 + } + + + // reposition in invered order + dnnType *dstBack; + checkCuda( cudaMalloc(&dstBack, singleOutput.tot()*sizeof(dnnType))); + for(int i=0; icublasHandle, dstF, trans, + singleOutput.h*singleOutput.w*singleOutput.l, singleOutput.c); + // backward transpose + matrixTranspose(net->cublasHandle, dstB, trans + singleOutput.tot(), + singleOutput.h*singleOutput.w*singleOutput.l, singleOutput.c); + dstData = trans; + } else { + // copy last of forward + checkCuda( cudaMemcpy(trans, dstF + singleOutput.tot() - singleOutput.c, singleOutput.c*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + // copy first of backward + checkCuda( cudaMemcpy(trans + singleOutput.c, dstB, singleOutput.c*sizeof(dnnType), cudaMemcpyDeviceToDevice)); + dstData = trans; + } - checkCUDNN(cudnnRNNForwardInference(net->cudnnHandle, - rnnDesc, - seqLen, // number of time steps (nT) - x_desc_vec_.data(), // input array of desc (nT*nC_in) - srcData, // 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 - w_ptr, // weights pointer - y_desc_vec_.data(), // output desc (nT*nC_out) - dstData, // 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 dim = output_dim; return dstData; diff --git a/src/utils.cpp b/src/utils.cpp index 444318d..6789e8c 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -68,7 +68,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; @@ -92,7 +92,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<<" | [ "< Date: Sun, 16 Feb 2020 17:08:19 +0100 Subject: [PATCH 068/228] structure ok, result wrong --- include/tkDNN/Layer.h | 9 +++- src/LSTM.cpp | 103 ++++++++++++++++---------------------- tests/imuodom/imuodom.cpp | 4 +- 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/include/tkDNN/Layer.h b/include/tkDNN/Layer.h index f12027f..7e827d8 100644 --- a/include/tkDNN/Layer.h +++ b/include/tkDNN/Layer.h @@ -207,7 +207,9 @@ protected: /** 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 @@ -261,6 +263,11 @@ protected: 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 }; diff --git a/src/LSTM.cpp b/src/LSTM.cpp index 00d8f76..44502fa 100644 --- a/src/LSTM.cpp +++ b/src/LSTM.cpp @@ -13,8 +13,6 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig seqLen = input_dim.w; stateSize = hiddensize; - std::cout<<"LSTM seqLen: "< x_vec(seqLen); std::vector y_vec(seqLen); @@ -110,7 +108,7 @@ LSTM::LSTM( Network *net, int hiddensize, bool returnSeq, std::string fname_weig 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: "<cudnnHandle, rnnDesc, i, x_desc_vec_[0], w_desc_, 0, j, m_desc, (void**)&p)); @@ -209,37 +217,27 @@ LSTM::~LSTM() { 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) { - std::cout<<"LSTM infer\n"; + // transpose input + matrixTranspose(net->cublasHandle, srcData, srcF, dim.c, dim.h*dim.w*dim.l); - dnnType *trans; - checkCuda( cudaMalloc(&trans, dim.tot()*sizeof(dnnType))); - matrixTranspose(net->cublasHandle, srcData, trans, dim.c, dim.h*dim.w*dim.l); - srcData = trans; - - // reposition in invered order - dnnType *srcBack; - checkCuda( cudaMalloc(&srcBack, dim.tot()*sizeof(dnnType))); + // build srcB as reversed srcF for(int i=0; i