Blame view

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