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) 2019 Intel Corporation 6 7 #include "precomp.hpp" 8 9 #include <iostream> // cout 10 #include <sstream> // stringstream 11 #include <fstream> // ofstream 12 #include <map> 13 14 #include <ade/passes/check_cycles.hpp> 15 #include <ade/util/zip_range.hpp> // indexed() 16 17 #include <opencv2/gapi/gproto.hpp> 18 #include "compiler/gmodel.hpp" 19 #include "compiler/gislandmodel.hpp" 20 #include "compiler/passes/passes.hpp" 21 22 namespace cv { namespace gimpl { namespace passes { 23 24 /** 25 * This pass extends a GIslandModel with streaming-oriented 26 * information. 27 * 28 * Every input data object (according to the protocol) is connected to 29 * a new "Emitter" node which becomes its _consumer_. 30 * 31 * Every output data object (again, according to the protocol) is 32 * connected to a new "Sink" node which becomes its _consumer_. 33 * 34 * These extra nodes are required to streamline the queues 35 * initialization by the GStreamingIntrinExecutable and its derivatives. 36 */ addStreaming(ade::passes::PassContext & ctx)37void addStreaming(ade::passes::PassContext &ctx) 38 { 39 GModel::Graph gm(ctx.graph); 40 if (!gm.metadata().contains<Streaming>()) { 41 return; 42 } 43 44 // Note: This pass is working on a GIslandModel. 45 // FIXME: May be introduce a new variant of GIslandModel to 46 // deal with streams? 47 auto igr = gm.metadata().get<IslandModel>().model; 48 GIslandModel::Graph igm(*igr); 49 50 // First collect all data slots & their respective original 51 // data objects 52 using M = std::unordered_map 53 < ade::NodeHandle // key: a GModel's data object node 54 , ade::NodeHandle // value: an appropriate GIslandModel's slot node 55 , ade::HandleHasher<ade::Node> 56 >; 57 M orig_to_isl; 58 for (auto &&nh : igm.nodes()) { 59 if (igm.metadata(nh).get<NodeKind>().k == NodeKind::SLOT) { 60 const auto &orig_nh = igm.metadata(nh).get<DataSlot>().original_data_node; 61 orig_to_isl[orig_nh] = nh; 62 } 63 } 64 65 // Now walk through the list of input slots and connect those 66 // to a Streaming source. 67 const auto proto = gm.metadata().get<Protocol>(); 68 for (auto &&it : ade::util::indexed(proto.in_nhs)) { 69 const auto in_idx = ade::util::index(it); 70 const auto in_nh = ade::util::value(it); 71 auto emit_nh = GIslandModel::mkEmitNode(igm, in_idx); 72 igm.link(emit_nh, orig_to_isl.at(in_nh)); 73 } 74 75 // Same for output slots 76 for (auto &&it : ade::util::indexed(proto.out_nhs)) { 77 const auto out_idx = ade::util::index(it); 78 const auto out_nh = ade::util::value(it); 79 auto sink_nh = GIslandModel::mkSinkNode(igm, out_idx); 80 igm.link(orig_to_isl.at(out_nh), sink_nh); 81 } 82 } 83 84 }}} // cv::gimpl::passes 85