1 // This file is part of OpenCV project. 2 // It is subject to the license terms in the LICENSE file found in the top-level directory 3 // of this distribution and at http://opencv.org/license.html. 4 // 5 // Copyright (C) 2018 Intel Corporation 6 7 #ifndef OPENCV_GAPI_FLUID_BACKEND_HPP 8 #define OPENCV_GAPI_FLUID_BACKEND_HPP 9 10 // FIXME? Actually gfluidbackend.hpp is not included anywhere 11 // and can be placed in gfluidbackend.cpp 12 13 #include <opencv2/gapi/garg.hpp> 14 #include <opencv2/gapi/gproto.hpp> 15 #include <opencv2/gapi/fluid/gfluidkernel.hpp> 16 #include <opencv2/gapi/fluid/gfluidbuffer.hpp> 17 18 // PRIVATE STUFF! 19 #include "backends/common/gbackend.hpp" 20 #include "compiler/gislandmodel.hpp" 21 22 namespace cv { namespace gimpl { 23 24 struct FluidUnit 25 { namecv::gimpl::FluidUnit26 static const char *name() { return "FluidUnit"; } 27 GFluidKernel k; 28 gapi::fluid::BorderOpt border; 29 int border_size; 30 int window; 31 std::vector<int> line_consumption; 32 double ratio; 33 }; 34 35 struct FluidUseOwnBorderBuffer 36 { namecv::gimpl::FluidUseOwnBorderBuffer37 static const char *name() { return "FluidUseOwnBorderBuffer"; } 38 bool use; 39 }; 40 41 struct FluidData 42 { namecv::gimpl::FluidData43 static const char *name() { return "FluidData"; } 44 45 // FIXME: This structure starts looking like "FluidBuffer" meta 46 int latency = 0; 47 int skew = 0; 48 int max_consumption = 1; 49 int border_size = 0; 50 int lpi_write = 1; 51 bool internal = false; // is node internal to any fluid island 52 gapi::fluid::BorderOpt border; 53 }; 54 55 struct agent_data_t { 56 GFluidKernel::Kind kind; 57 ade::NodeHandle nh; 58 std::vector<int> in_buffer_ids; 59 std::vector<int> out_buffer_ids; 60 }; 61 62 struct FluidAgent 63 { 64 public: 65 virtual ~FluidAgent() = default; 66 FluidAgent(const ade::Graph &g, ade::NodeHandle nh); 67 68 GFluidKernel k; 69 ade::NodeHandle op_handle; // FIXME: why it is here??// 70 std::string op_name; 71 72 // < 0 - not a buffer 73 // >= 0 - a buffer with RcID 74 std::vector<int> in_buffer_ids; 75 std::vector<int> out_buffer_ids; 76 77 cv::GArgs in_args; 78 std::vector<cv::gapi::fluid::View> in_views; // sparce list of IN views 79 std::vector<cv::gapi::fluid::Buffer*> out_buffers; 80 81 // FIXME Current assumption is that outputs have EQUAL SIZES 82 int m_outputLines = 0; 83 int m_producedLines = 0; 84 85 // Execution methods 86 void reset(); 87 bool canWork() const; 88 bool canRead() const; 89 bool canWrite() const; 90 void doWork(); 91 bool done() const; 92 93 void debug(std::ostream& os); 94 95 // FIXME: 96 // refactor (implement a more solid replacement or 97 // drop this method completely) 98 virtual void setRatio(double ratio) = 0; 99 100 private: 101 // FIXME!!! 102 // move to another class 103 virtual int firstWindow(std::size_t inPort) const = 0; 104 virtual std::pair<int,int> linesReadAndnextWindow(std::size_t inPort) const = 0; 105 }; 106 107 //helper data structure for accumulating graph traversal/analysis data 108 struct FluidGraphInputData { 109 110 std::vector<agent_data_t> m_agents_data; 111 std::vector<std::size_t> m_scratch_users; 112 std::unordered_map<int, std::size_t> m_id_map; // GMat id -> buffer idx map 113 std::map<std::size_t, ade::NodeHandle> m_all_gmat_ids; 114 115 std::size_t m_mat_count; 116 }; 117 //local helper function to traverse the graph once and pass the results to multiple instances of GFluidExecutable 118 FluidGraphInputData fluidExtractInputDataFromGraph(const ade::Graph &m_g, const std::vector<ade::NodeHandle> &nodes); 119 120 class GFluidExecutable final: public GIslandExecutable 121 { 122 GFluidExecutable(const GFluidExecutable&) = delete; // due std::unique_ptr in members list 123 124 const ade::Graph &m_g; 125 GModel::ConstGraph m_gm; 126 127 std::vector<std::unique_ptr<FluidAgent>> m_agents; 128 129 std::vector<FluidAgent*> m_script; 130 131 cv::gimpl::Mag m_res; 132 133 std::size_t m_num_int_buffers; // internal buffers counter (m_buffers - num_scratch) 134 std::vector<std::size_t> m_scratch_users; 135 136 std::unordered_map<int, std::size_t> m_id_map; // GMat id -> buffer idx map 137 std::map<std::size_t, ade::NodeHandle> m_all_gmat_ids; 138 139 std::vector<cv::gapi::fluid::Buffer> m_buffers; 140 141 void bindInArg (const RcDesc &rc, const GRunArg &arg); 142 void bindOutArg(const RcDesc &rc, const GRunArgP &arg); 143 void packArg (GArg &in_arg, const GArg &op_arg); 144 145 void initBufferRois(std::vector<int>& readStarts, std::vector<cv::Rect>& rois, const std::vector<cv::Rect> &out_rois); 146 void makeReshape(const std::vector<cv::Rect>& out_rois); 147 std::size_t total_buffers_size() const; 148 149 public: canReshape() const150 virtual inline bool canReshape() const override { return true; } 151 virtual void reshape(ade::Graph& g, const GCompileArgs& args) override; 152 153 virtual void run(std::vector<InObj> &&input_objs, 154 std::vector<OutObj> &&output_objs) override; 155 156 using GIslandExecutable::run; // (IInput&, IOutput&) version 157 158 void run(std::vector<InObj> &input_objs, 159 std::vector<OutObj> &output_objs); 160 161 162 GFluidExecutable(const ade::Graph &g, 163 const FluidGraphInputData &graph_data, 164 const std::vector<cv::Rect> &outputRois); 165 }; 166 167 168 class GParallelFluidExecutable final: public GIslandExecutable { 169 GParallelFluidExecutable(const GParallelFluidExecutable&) = delete; // due std::unique_ptr in members list 170 171 std::vector<std::unique_ptr<GFluidExecutable>> tiles; 172 decltype(GFluidParallelFor::parallel_for) parallel_for; 173 public: 174 GParallelFluidExecutable(const ade::Graph &g, 175 const FluidGraphInputData &graph_data, 176 const std::vector<GFluidOutputRois> ¶llelOutputRois, 177 const decltype(parallel_for) &pfor); 178 179 canReshape() const180 virtual inline bool canReshape() const override { return false; } 181 virtual void reshape(ade::Graph& g, const GCompileArgs& args) override; 182 183 virtual void run(std::vector<InObj> &&input_objs, 184 std::vector<OutObj> &&output_objs) override; 185 }; 186 }} // cv::gimpl 187 188 189 #endif // OPENCV_GAPI_FLUID_BACKEND_HPP 190