9ce39fb79aa5d92f944ec12018f4b96d006d011a
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / include / vpu / model / model.hpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #pragma once
6
7 #include <memory>
8 #include <string>
9 #include <functional>
10 #include <set>
11
12 #include <ie_icnn_network.hpp>
13
14 #include <vpu/model/base.hpp>
15 #include <vpu/model/edges.hpp>
16 #include <vpu/model/data.hpp>
17 #include <vpu/model/stage.hpp>
18 #include <vpu/utils/enums.hpp>
19 #include <vpu/utils/io.hpp>
20 #include <vpu/utils/dot_io.hpp>
21 #include <vpu/allocator.hpp>
22
23 namespace vpu {
24
25 //
26 // Resources
27 //
28
29 // TODO: get rid of `cmxLimit`.
30
31 struct Resources final {
32     int numCMXSlices = 0;
33     int numSHAVEs = 0;
34     int cmxLimit = 0;
35 };
36
37 void printTo(std::ostream& os, const Resources& res);
38 void printTo(DotLabel& lbl, const Resources& res);
39
40 //
41 // Model
42 //
43
44 class Model final :
45         public EnableHandleFromThis<Model>,
46         public EnableCustomAttributes {
47 private:
48     // Need to declare here to use decltype
49     DataList _dataList;
50     mutable StageList _orderedStageList;
51     std::set<Stage, StageNode::StageNameCmp> _initialStages;
52
53     //
54     // Main attributes
55     //
56
57     VPU_MODEL_ATTRIBUTE(std::string, name, std::string())
58
59     VPU_MODEL_ATTRIBUTE(int, batchSize, 1)
60
61     VPU_MODEL_ATTRIBUTE(InferenceEngine::NetworkStatsMap, nodesStats, {})
62
63 public:
64     using Ptr = ModelPtr;
65
66     //
67     // Constructor
68     //
69
70     inline explicit Model(const std::string& name) :
71             _dataList(&DataNode::_posInModel),
72             _orderedStageList(&StageNode::_posInModel),
73             _name(name) {
74     }
75
76     //
77     // Main attributes
78     //
79
80     void setBatchSize(int batchSize);
81
82     inline void setNodesStats(const ie::NetworkStatsMap& stats) { _nodesStats = stats; }
83
84     //
85     // Data nodes
86     //
87
88     Data addInputData(
89             const std::string& name,
90             const DataDesc& desc);
91
92     Data addOutputData(
93             const std::string& name,
94             const DataDesc& desc);
95
96     Data addConstData(
97             const std::string& name,
98             const DataDesc& desc,
99             const DataContent::Ptr& content);
100
101     Data addNewData(
102             const std::string& name,
103             const DataDesc& desc);
104
105     Data addFakeData();
106
107     Data duplicateData(
108             const Data& origData,
109             const std::string& postfix,
110             const DataDesc& newDesc = DataDesc(),
111             const DataContent::Ptr& newContent = nullptr);
112
113     //
114     // Stage nodes
115     //
116
117     template <class StageImpl>
118     Stage addNewStage(
119             const std::string& name,
120             StageType type,
121             const ie::CNNLayerPtr& origLayer,
122             const DataVector& inputs,
123             const DataVector& outputs);
124
125     Stage duplicateStage(
126             const std::string& name,
127             const Stage& origStage,
128             const DataVector& inputs,
129             const DataVector& outputs);
130
131     //
132     // Stage <-> Data edges
133     //
134
135     StageInput addStageInput(
136             const Stage& stage,
137             const Data& data);
138
139     StageOutput addStageOutput(
140             const Stage& stage,
141             const Data& data);
142
143     StageTempBuffer addTempBuffer(
144             const Stage& stage,
145             const DataDesc& desc);
146
147     void replaceStageInput(
148             const StageInput& edge,
149             const Data& newInput);
150
151     void replaceStageOutput(
152             const StageOutput& edge,
153             const Data& newOutput);
154
155     //
156     // Stage <-> Stage edges
157     //
158
159     class InjectStageHelper final {
160     public:
161         inline InjectStageHelper(InjectStageHelper&&) = default;
162
163         InjectStageHelper(const InjectStageHelper&) = delete;
164         InjectStageHelper& operator=(const InjectStageHelper&) = delete;
165         InjectStageHelper& operator=(InjectStageHelper&&) = delete;
166
167         ~InjectStageHelper();
168
169         InjectStageHelper& parentHW(const Stage& parent);
170         InjectStageHelper& childSW(const Stage& child);
171
172         InjectedStage done();
173
174     private:
175         inline explicit InjectStageHelper(const Handle<Model>& model) : _model(model) {}
176
177     private:
178         Handle<Model> _model;
179
180         Stage _parent;
181         Stage _child;
182
183         friend class Model;
184     };
185
186     inline InjectStageHelper injectStage() { return InjectStageHelper(handle_from_this()); }
187
188     void revertInjection(const InjectedStage& edge);
189
190     //
191     // Data<->Data edges
192     //
193
194     class DataEdgeHelper final {
195     public:
196         inline DataEdgeHelper(DataEdgeHelper&&) = default;
197
198         DataEdgeHelper(const DataEdgeHelper&) = delete;
199         DataEdgeHelper& operator=(const DataEdgeHelper&) = delete;
200         DataEdgeHelper& operator=(DataEdgeHelper&&) = delete;
201
202         ~DataEdgeHelper();
203
204         DataEdgeHelper& parent(const Data& parent);
205         DataEdgeHelper& child(const Data& child);
206
207         DataEdgeHelper& mode(SharedDataMode mode);
208         DataEdgeHelper& order(SharedDataOrder order);
209
210         DataEdgeHelper& offset(const DimValues& offset);
211
212         SharedAllocation done();
213
214     private:
215         inline explicit DataEdgeHelper(const Handle<Model>& model) : _model(model) {}
216
217     private:
218         Handle<Model> _model;
219
220         Data _parent;
221         Data _child;
222
223         SharedDataMode _mode = SharedDataMode::ROI;
224         bool _modeSet = false;
225
226         SharedDataOrder _order = SharedDataOrder::ParentWritesToChild;
227         bool _orderSet = false;
228
229         DimValues _offset;
230         bool _offsetSet = false;
231
232         friend class Model;
233     };
234
235     inline DataEdgeHelper connectDatas() { return DataEdgeHelper(handle_from_this()); }
236
237     //
238     // Nodes removal
239     //
240
241     void disconnectStageDatas(const Stage& stage);
242
243     void removeStage(const Stage& stage);
244
245     void removeUnusedData(const Data& data);
246
247     void cleanUpDatas();
248
249     //
250     // Stage order
251     //
252
253     // TODO: allow to override stage order.
254     void buildStageOrder() const;
255
256     //
257     // Nodes accessors
258     //
259
260     inline int numDatas() const { return _dataPtrList.size(); }
261     inline auto datas() const -> decltype(contRange(_dataList)) {
262         return contRange(_dataList);
263     }
264
265     inline int numStages() const { return _stagePtrList.size(); }
266     inline auto initialStages() const -> decltype(contRange(_initialStages)) {
267         return contRange(_initialStages);
268     }
269     inline auto getStages() const -> decltype(contRange(_orderedStageList)) {
270         buildStageOrder();
271         return contRange(_orderedStageList);
272     }
273
274     //
275     // Allocator
276     //
277
278     inline Allocator& getAllocator() { return _allocator; }
279
280 private:
281     Stage addNewStageImpl(
282         const std::string& name,
283         StageType type,
284         const ie::CNNLayerPtr& origLayer,
285         const DataVector& inputs,
286         const DataVector& outputs,
287         const FuncRef<StagePtr()>& creator);
288
289     InjectedStage injectStageImpl(
290             const Stage& parent,
291             const Stage& child);
292
293     SharedAllocation connectDatasImpl(
294             const Data& parent,
295             const Data& child,
296             SharedDataMode mode,
297             SharedDataOrder order,
298             const DimValues& offset);
299
300     void runDFS(
301             const Stage& stage,
302             StageMap<bool>& visitedMap) const;
303
304 private:
305     DataPtrList _dataPtrList;
306     StagePtrList _stagePtrList;
307
308     StageInputPtrList _inEdgePtrList;
309     StageOutputPtrList _outEdgePtrList;
310     StageTempBufferPtrList _tempBufferEdgePtrList;
311     SharedAllocationPtrList _dataEdgePtrList;
312     InjectedStagePtrList _stageEdgePtrList;
313
314     Allocator _allocator;
315
316     mutable bool _resetStageOrder = true;
317
318     friend class InjectStageHelper;
319     friend class DataEdgeHelper;
320 };
321
322 template <class StageImpl>
323 inline Stage Model::addNewStage(
324         const std::string& name,
325         StageType type,
326         const ie::CNNLayerPtr& origLayer,
327         const DataVector& inputs,
328         const DataVector& outputs) {
329     return addNewStageImpl(
330         name,
331         type,
332         origLayer,
333         inputs,
334         outputs,
335         []() { return std::make_shared<StageImpl>(); });
336 }
337
338 //
339 // runAllocator
340 //
341
342 AllocationResult runAllocator(
343         const Model::Ptr& model,
344         bool onlyCheckCMX = false);
345
346 }  // namespace vpu