Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / src / mkldnn_plugin / mkldnn_graph.h
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #pragma once
6
7 #include <map>
8 #include <string>
9 #include <vector>
10 #include <memory>
11 #include <cpp_interfaces/impl/ie_executable_network_thread_safe_default.hpp>
12
13 #include "ie_parallel.hpp"
14 #include "mkldnn_memory.h"
15 #include "config.h"
16 #include "perf_count.h"
17 #include "mkldnn_dims.h"
18 #include "mean_image.h"
19 #include "mkldnn_node.h"
20 #include "mkldnn_edge.h"
21 #include "mkldnn_extension_utils.h"
22 #include "mkldnn_streams.h"
23
24 namespace MKLDNNPlugin {
25
26 class MKLDNNGraph {
27 public:
28     typedef std::shared_ptr<MKLDNNGraph> Ptr;
29
30     enum Status {
31         NotReady = 0,
32         Ready = 1,
33     };
34
35     MKLDNNGraph(): status(NotReady), eng(mkldnn::engine(mkldnn::engine::kind::cpu, 0)) {}
36
37     Status GetStatus() {
38         return status;
39     }
40
41     bool IsReady() {
42         return (GetStatus() == Ready);
43     }
44
45     void setConfig(const Config &cfg);
46     void setProperty(const std::map<std::string, std::string> &properties);
47     Config getProperty();
48
49     void getInputBlobs(InferenceEngine::BlobMap &in_map);
50     void getOutputBlobs(InferenceEngine::BlobMap &out_map);
51
52     void CreateGraph(const InferenceEngine::ICNNNetwork &network, const MKLDNNExtensionManager::Ptr& extMgr);
53
54     bool hasMeanImageFor(const std::string& name) {
55         return _meanImages.find(name) != _meanImages.end();
56     }
57
58     void PushInputData(const std::string& name, const InferenceEngine::Blob::Ptr &in);
59     void PullOutputData(InferenceEngine::BlobMap &out);
60
61     void Infer(int batch = -1);
62
63     std::vector<MKLDNNNodePtr>& GetNodes() {
64         return graphNodes;
65     }
66
67     std::vector<MKLDNNEdgePtr>& GetEdges() {
68         return graphEdges;
69     }
70
71     std::vector<MKLDNNNodePtr>& GetOutputNodes() {
72         return outputNodes;
73     }
74
75     mkldnn::engine getEngine() const {
76         return eng;
77     }
78
79     void GetPerfData(std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> &perfMap) const;
80
81     void RemoveDroppedNodes();
82     void RemoveDroppedEdges();
83     void DropNode(const MKLDNNNodePtr& node);
84
85     void CreateArena(int threads_per_stream) {
86         #if IE_THREAD == IE_THREAD_OMP
87         omp_set_num_threads(threads_per_stream);
88         #elif IE_THREAD == IE_THREAD_TBB
89         ptrArena = std::unique_ptr<tbb::task_arena>(new tbb::task_arena(threads_per_stream));
90         #endif
91     }
92
93     void CreateObserver(int _stream_id, int _threads_per_stream, int _pinning_step = 1) {
94         #if IE_THREAD == IE_THREAD_TBB
95         ptrObserver
96                 = std::unique_ptr<tbb::task_scheduler_observer>(
97                 new pinning_observer(*ptrArena.get(), _stream_id, _threads_per_stream, _pinning_step));
98         #else
99         cpu_set_t *process_mask = nullptr;
100         int ncpus = 0;
101         get_process_mask(ncpus, process_mask);
102             #if IE_THREAD == IE_THREAD_OMP
103             #pragma omp parallel for
104                     for (int thread_index = 0; thread_index < _threads_per_stream; thread_index++) {
105                         pin_thread_to_vacant_core(_stream_id * _threads_per_stream + thread_index, 1, ncpus, process_mask);
106                     }
107             #elif IE_THREAD == IE_THREAD_SEQ
108             pin_thread_to_vacant_core(_stream_id * _threads_per_stream, 1, ncpus, process_mask);
109             #endif
110         CPU_FREE(process_mask);
111         #endif
112     }
113
114     InferenceEngine::ICNNNetwork::Ptr dump() const;
115
116 protected:
117     void VisitNode(MKLDNNNodePtr node, std::vector<MKLDNNNodePtr>& sortedNodes);
118     void SortTopologically();
119
120     void ForgetGraphData() {
121         status = NotReady;
122         eng = mkldnn::engine(mkldnn::engine::kind::cpu, 0);
123
124         inputNodes.clear();
125         outputNodes.clear();
126         graphNodes.clear();
127         graphEdges.clear();
128         _meanImages.clear();
129     }
130     Status status;
131     Config config;
132
133     MKLDNNMemoryPtr memWorkspace;
134
135     std::map<std::string, MKLDNNNodePtr> inputNodes;
136     std::vector<MKLDNNNodePtr> outputNodes;
137     std::vector<MKLDNNNodePtr> graphNodes;
138     std::vector<MKLDNNEdgePtr> graphEdges;
139
140     std::map<std::string, MeanImage> _meanImages;
141
142     #if IE_THREAD == IE_THREAD_TBB
143     std::unique_ptr<tbb::task_arena> ptrArena;
144     std::unique_ptr<tbb::task_scheduler_observer> ptrObserver;
145     #endif
146     mkldnn::engine eng;
147
148     void Replicate(const ICNNNetwork &network, const MKLDNNExtensionManager::Ptr& extMgr);
149     void InitGraph();
150     void InitNodes();
151     void InitEdges();
152     void Allocate();
153     void AllocateWithReuse();
154     void CreatePrimitives();
155
156     void do_before(const std::string &dir, const MKLDNNNodePtr &node);
157     void do_after(const std::string &dir, const MKLDNNNodePtr &node);
158
159     friend class MKLDNNInferRequest;
160     friend class MKLDNNGraphlessInferRequest;
161     friend std::shared_ptr<InferenceEngine::ICNNNetwork> dump_graph_as_ie_net(const MKLDNNGraph &graph);
162
163 private:
164     void dumpToDotFile(std::string file) const;
165     struct ParsedLayer {
166         MKLDNNNodePtr parent;
167         InferenceEngine::CNNLayerPtr cnnLayer;
168         size_t outIdx;
169     };
170 };
171
172
173 class MKLDNNExecNetwork: public InferenceEngine::ExecutableNetworkThreadSafeDefault {
174 public:
175     typedef std::shared_ptr<MKLDNNExecNetwork> Ptr;
176
177     InferenceEngine::InferRequestInternal::Ptr CreateInferRequestImpl(InferenceEngine::InputsDataMap networkInputs,
178                                                                       InferenceEngine::OutputsDataMap networkOutputs) override;
179
180     void CreateInferRequest(InferenceEngine::IInferRequest::Ptr &asyncRequest) override;
181
182     MKLDNNExecNetwork(const InferenceEngine::ICNNNetwork &network, const Config &cfg,
183                       const MKLDNNExtensionManager::Ptr& extMgr);
184
185     ~MKLDNNExecNetwork() {
186         graphs.clear();
187         extensionManager.reset();
188     }
189
190     void setProperty(const std::map<std::string, std::string> &properties);
191
192     void GetExecGraphInfo(InferenceEngine::ICNNNetwork::Ptr &graphPtr) override;
193
194 protected:
195     std::vector<MKLDNNGraph::Ptr> graphs;
196     MKLDNNExtensionManager::Ptr extensionManager;
197
198     bool CanProcessDynBatch(const InferenceEngine::ICNNNetwork &network) const;
199 };
200
201 }  // namespace MKLDNNPlugin