4aea3d26695a145229b1ad7fd7d889efff8e07ef
[platform/upstream/dldt.git] / inference-engine / src / vpu / graph_transformer / src / frontend / parse_data.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <vpu/frontend/frontend.hpp>
6
7 #include <memory>
8 #include <algorithm>
9 #include <set>
10
11 #include <vpu/compile_env.hpp>
12
13 namespace vpu {
14
15 void FrontEnd::parseInputAndOutputData(const Model::Ptr& model) {
16     VPU_PROFILE(parseInputAndOutputData);
17
18     const auto& env = CompileEnv::get();
19
20     //
21     // Parse network inputs
22     //
23
24     for (const auto& inputInfo : _ieNetworkParser.networkInputs) {
25         auto netInput = inputInfo.second;
26         IE_ASSERT(netInput != nullptr);
27
28         auto ieData = netInput->getInputData();
29         IE_ASSERT(ieData != nullptr);
30
31         DataDesc vpuDesc(ieData->getTensorDesc());
32         if (vpuDesc.numDims() >= 3) {
33             if (env.config.hwOptimization || env.config.forceLayout == ComputeLayout::NCHW) {
34                 vpuDesc.moveDim(Dim::C, 2);
35             } else {
36                 vpuDesc.moveDim(Dim::C, 0);
37             }
38         }
39
40         auto vpuData = model->addInputData(ieData->getName(), vpuDesc);
41         bindData(vpuData, ieData);
42     }
43
44     model->attrs().set<int>("numInputs", _ieNetworkParser.networkInputs.size());
45
46     //
47     // Parse network outputs
48     //
49
50     for (const auto& outputInfo : _ieNetworkParser.networkOutputs) {
51         auto ieData = outputInfo.second;
52         IE_ASSERT(ieData != nullptr);
53
54         DataDesc vpuDesc(ieData->getTensorDesc());
55         if (vpuDesc.numDims() >= 3) {
56             if (env.config.hwOptimization || env.config.forceLayout == ComputeLayout::NCHW) {
57                 vpuDesc.moveDim(Dim::C, 2);
58             } else {
59                 vpuDesc.moveDim(Dim::C, 0);
60             }
61         }
62
63         auto vpuData = model->addOutputData(ieData->getName(), vpuDesc);
64         bindData(vpuData, ieData);
65
66         if (_unbatchedOutputs.count(ieData) > 0) {
67             vpuData->attrs().set<bool>("unbatched", true);
68         }
69     }
70
71     model->attrs().set<int>("numOutputs", _ieNetworkParser.networkOutputs.size());
72
73     //
74     // Parse constant data
75     //
76
77     for (const auto& constInfo : _ieNetworkParser.constDatas) {
78         auto ieData = constInfo.first;
79         IE_ASSERT(ieData != nullptr);
80
81         auto ieBlob = constInfo.second;
82         IE_ASSERT(ieBlob != nullptr);
83
84         auto ieDesc = ieData->getTensorDesc();
85
86         if (ieDesc.getPrecision() != ie::Precision::FP16) {
87             if (ieDesc.getPrecision() != ie::Precision::FP32 || !env.config.allowFP32Models) {
88                 VPU_THROW_EXCEPTION << "Unsupported precision " << ieDesc.getPrecision() << "for data " << ieData->getName();
89             }
90         }
91
92         DataDesc vpuDesc(ieDesc);
93         vpuDesc.setType(DataType::FP16);
94
95         auto vpuData = model->addConstData(
96             ieData->getName(),
97             vpuDesc,
98             ieBlobContent(ieBlob));
99
100         // User might ask to return the output from Const layer.
101         if (auto vpuOutData = getVpuData(ieData)) {
102             IE_ASSERT(vpuOutData->usage() == DataUsage::Output);
103
104             _stageBuilder->addCopyStage(
105                 model,
106                 formatString("%s@return-const", vpuData->name()),
107                 nullptr,
108                 vpuData,
109                 vpuOutData);
110         }
111
112         bindData(vpuData, ieData);
113     }
114
115     //
116     // Add Copy stages after network outputs, if they are in the middle
117     //
118
119     for (const auto& outputInfo : _ieNetworkParser.networkOutputs) {
120         auto ieData = outputInfo.second;
121         IE_ASSERT(ieData != nullptr);
122
123         auto vpuData = getVpuData(ieData);
124         IE_ASSERT(vpuData != nullptr);
125
126         // It might be Const.
127         if (vpuData->usage() != DataUsage::Output)
128             continue;
129
130         // Convert stage will be added.
131         if (vpuData->desc().type() != DataType::FP16)
132             continue;
133
134         if (!ieData->getInputTo().empty()) {
135             auto vpuTempData = model->duplicateData(
136                 vpuData,
137                 "@intermediate",
138                 vpuData->desc());
139
140             _stageBuilder->addCopyStage(
141                 model,
142                 formatString("%s@copy-to-output", vpuData->name()),
143                 nullptr,
144                 vpuTempData,
145                 vpuData);
146
147             bindData(vpuTempData, ieData);
148         }
149     }
150 }
151
152 }  // namespace vpu