Skip to content
This repository was archived by the owner on Jul 18, 2024. It is now read-only.

Commit 8e95fad

Browse files
committed
Remove extra Transpose layers from the generated graph
Tranpose layers are added to every operator's input and output if layout is NHWC Instead it should be added only at the beginning and end of the graph Signed-off-by: Ritul Jasuja <ritul.jasuja@intel.com>
1 parent a2a9c70 commit 8e95fad

18 files changed

Lines changed: 266 additions & 49 deletions
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
From 9c0054c868c9953553c594fe441af33d0b492bb8 Mon Sep 17 00:00:00 2001
2+
From: Ritul Jasuja <ritul.jasuja@intel.com>
3+
Date: Tue, 9 Nov 2021 13:43:19 +0530
4+
Subject: [PATCH] Add Float16 support for Resize Bilinear and Resize Nearest
5+
Neighbor op
6+
7+
Adds Float16 support for ResizeBilinear and ResizeNearestNeighbor
8+
9+
Signed-off-by: Ritul Jasuja <ritul.jasuja@intel.com>
10+
---
11+
.../operations/src/ResizeBilinear.cpp | 23 ++++++++-----------
12+
.../operations/src/ResizeNearestNeighbor.cpp | 23 ++++++++-----------
13+
2 files changed, 18 insertions(+), 28 deletions(-)
14+
15+
diff --git a/ngraph_creator/operations/src/ResizeBilinear.cpp b/ngraph_creator/operations/src/ResizeBilinear.cpp
16+
index eee470355d6a..cddbf4c84f70 100644
17+
--- a/ngraph_creator/operations/src/ResizeBilinear.cpp
18+
+++ b/ngraph_creator/operations/src/ResizeBilinear.cpp
19+
@@ -11,18 +11,6 @@ ResizeBilinear::ResizeBilinear(int operationIndex) : OperationsBase(operationInd
20+
}
21+
22+
bool ResizeBilinear::validate() {
23+
- // TODO Add FLOAT16 check when VPUX plugin is supported
24+
- if (!checkOutputOperandType(0, (int32_t)OperandType::TENSOR_FLOAT32) &&
25+
- !checkOutputOperandType(0, (int32_t)OperandType::TENSOR_QUANT8_ASYMM)) {
26+
- ALOGE("%s check for output types failed", __func__);
27+
- return false;
28+
- }
29+
-
30+
- if (!checkInputOperandType(0, (int32_t)OperandType::TENSOR_FLOAT32) &&
31+
- !checkInputOperandType(0, (int32_t)OperandType::TENSOR_QUANT8_ASYMM)) {
32+
- return false;
33+
- }
34+
-
35+
const auto& inputDimensionsSize = getInputOperandDimensions(0).size();
36+
if (inputDimensionsSize != 4) {
37+
ALOGE("%s Invalid dimensions size for input(%lu)", __func__, inputDimensionsSize);
38+
@@ -73,8 +61,7 @@ std::shared_ptr<ngraph::Node> ResizeBilinear::createNode() {
39+
40+
if (!useNchw) inputNode = transpose(NHWC_NCHW, inputNode);
41+
// FLOAT16 type check added for future when VPUX plugin support is added
42+
- if (checkInputOperandType(1, (int32_t)OperandType::FLOAT32) ||
43+
- checkInputOperandType(1, (int32_t)OperandType::FLOAT16)) {
44+
+ if (checkInputOperandType(1, (int32_t)OperandType::FLOAT32)) {
45+
// In tensorflow lite, resizing by size is supported. Scaling factors are
46+
// calculated based on output shape.
47+
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
48+
@@ -86,6 +73,14 @@ std::shared_ptr<ngraph::Node> ResizeBilinear::createNode() {
49+
// integer
50+
width_scale = (float)out_width / (float)input_width;
51+
height_scale = (float)out_height / (float)input_height;
52+
+ } else if (checkInputOperandType(1, (int32_t)OperandType::FLOAT16)) {
53+
+ attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
54+
+ width_scale = sModelInfo->ParseOperationInput<_Float16>(mNnapiOperationIndex, 1);
55+
+ height_scale = sModelInfo->ParseOperationInput<_Float16>(mNnapiOperationIndex, 2);
56+
+ out_width = (int)(input_width * width_scale);
57+
+ out_height = (int)(input_height * height_scale);
58+
+ width_scale = (float)out_width / (float)input_width;
59+
+ height_scale = (float)out_height / (float)input_height;
60+
} else if (checkInputOperandType(1, (int32_t)OperandType::INT32)) {
61+
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
62+
out_width = sModelInfo->ParseOperationInput<int>(mNnapiOperationIndex, 1);
63+
diff --git a/ngraph_creator/operations/src/ResizeNearestNeighbor.cpp b/ngraph_creator/operations/src/ResizeNearestNeighbor.cpp
64+
index 23cb1dd3ff1e..a8eecfc03b9b 100644
65+
--- a/ngraph_creator/operations/src/ResizeNearestNeighbor.cpp
66+
+++ b/ngraph_creator/operations/src/ResizeNearestNeighbor.cpp
67+
@@ -11,18 +11,6 @@ ResizeNearestNeighbor::ResizeNearestNeighbor(int operationIndex) : OperationsBas
68+
}
69+
70+
bool ResizeNearestNeighbor::validate() {
71+
- // TODO Add FLOAT16 check when VPUX plugin is supported
72+
- if (!checkOutputOperandType(0, (int32_t)OperandType::TENSOR_FLOAT32) &&
73+
- !checkOutputOperandType(0, (int32_t)OperandType::TENSOR_QUANT8_ASYMM)) {
74+
- ALOGE("%s check for output types failed", __func__);
75+
- return false;
76+
- }
77+
-
78+
- if (!checkInputOperandType(0, (int32_t)OperandType::TENSOR_FLOAT32) &&
79+
- !checkInputOperandType(0, (int32_t)OperandType::TENSOR_QUANT8_ASYMM)) {
80+
- return false;
81+
- }
82+
-
83+
const auto& inputDimensionsSize = getInputOperandDimensions(0).size();
84+
if (inputDimensionsSize != 4) {
85+
ALOGE("%s Invalid dimensions size for input(%lu)", __func__, inputDimensionsSize);
86+
@@ -73,8 +61,7 @@ std::shared_ptr<ngraph::Node> ResizeNearestNeighbor::createNode() {
87+
88+
if (!useNchw) inputNode = transpose(NHWC_NCHW, inputNode);
89+
// FLOAT16 type check added for future when VPUX plugin support is added
90+
- if (checkInputOperandType(1, (int32_t)OperandType::FLOAT32) ||
91+
- checkInputOperandType(1, (int32_t)OperandType::FLOAT16)) {
92+
+ if (checkInputOperandType(1, (int32_t)OperandType::FLOAT32)) {
93+
// In tensorflow lite, resizing by size is supported. Scaling factors are
94+
// calculated based on output shape.
95+
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
96+
@@ -86,6 +73,14 @@ std::shared_ptr<ngraph::Node> ResizeNearestNeighbor::createNode() {
97+
// integer
98+
width_scale = (float)out_width / (float)input_width;
99+
height_scale = (float)out_height / (float)input_height;
100+
+ } else if (checkInputOperandType(1, (int32_t)OperandType::FLOAT16)) {
101+
+ attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
102+
+ width_scale = sModelInfo->ParseOperationInput<_Float16>(mNnapiOperationIndex, 1);
103+
+ height_scale = sModelInfo->ParseOperationInput<_Float16>(mNnapiOperationIndex, 2);
104+
+ out_width = (int)(input_width * width_scale);
105+
+ out_height = (int)(input_height * height_scale);
106+
+ width_scale = (float)out_width / (float)input_width;
107+
+ height_scale = (float)out_height / (float)input_height;
108+
} else if (checkInputOperandType(1, (int32_t)OperandType::INT32)) {
109+
attrs.shape_calculation_mode = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
110+
out_width = sModelInfo->ParseOperationInput<int>(mNnapiOperationIndex, 1);
111+
--
112+
2.25.1
113+

ngraph_creator/operations/include/OperationsBase.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class OperationsBase {
196196
// override connectOperationToGraph in case Operation has multiple outputs
197197
virtual void connectOperationToGraph();
198198
virtual ~OperationsBase() {}
199+
bool transposed_nchw = false;
199200
};
200201

201202
} // namespace nnhal

ngraph_creator/operations/src/AveragePool2D.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,11 @@ std::shared_ptr<ngraph::Node> AveragePool2D::createNode() {
120120
}
121121
}
122122

123-
if (!useNchw) { // No conversion needed if useNchw set
124-
inputNode = transpose(NHWC_NCHW, inputNode);
123+
if (!transposed_nchw) {
124+
if (!useNchw) { // No conversion needed if useNchw set
125+
inputNode = transpose(NHWC_NCHW, inputNode);
126+
transposed_nchw = true;
127+
}
125128
}
126129

127130
strides = {(size_t)stride_height, (size_t)stride_width};
@@ -135,7 +138,9 @@ std::shared_ptr<ngraph::Node> AveragePool2D::createNode() {
135138

136139
outputNode = applyActivation(outputNode, activationFn);
137140

138-
if (!useNchw) {
141+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
142+
const auto outputOp = sModelInfo->getOperand(outputIndex);
143+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
139144
outputNode = transpose(NCHW_NHWC, outputNode);
140145
}
141146

ngraph_creator/operations/src/BatchToSpace.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,21 @@ std::shared_ptr<ngraph::Node> BatchToSpace::createNode() {
5454
const auto crop_begin = createConstNode(ngraph::element::i64, {shape.size()}, shape);
5555
const auto crop_end = createConstNode(ngraph::element::i64, {shape.size()}, shape);
5656

57-
if (!useNchw) // No conversion needed if useNchw set
58-
inputNode = transpose(NHWC_NCHW, inputNode);
57+
if (!transposed_nchw) {
58+
if (!useNchw) { // No conversion needed if useNchw set
59+
inputNode = transpose(NHWC_NCHW, inputNode);
60+
transposed_nchw = true;
61+
}
62+
}
5963

6064
std::shared_ptr<ngraph::Node> outputNode = std::make_shared<ngraph::opset3::BatchToSpace>(
6165
inputNode, block_shape_node, crop_begin, crop_end);
6266

63-
if (!useNchw) outputNode = transpose(NCHW_NHWC, outputNode);
67+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
68+
const auto outputOp = sModelInfo->getOperand(outputIndex);
69+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
70+
outputNode = transpose(NCHW_NHWC, outputNode);
71+
}
6472

6573
return outputNode;
6674
}

ngraph_creator/operations/src/Conv2d.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,11 @@ std::shared_ptr<ngraph::Node> Conv2d::createNode() {
205205

206206
// OpenVino expects filter in OIHW format
207207
filterNode = transpose(OHWI_OIHW, filterNode);
208-
if (!useNchw) { // No conversion needed if useNchw set
209-
inputNode = transpose(NHWC_NCHW, inputNode);
208+
if (!transposed_nchw) {
209+
if (!useNchw) { // No conversion needed if useNchw set
210+
inputNode = transpose(NHWC_NCHW, inputNode);
211+
transposed_nchw = true;
212+
}
210213
}
211214

212215
strides = {(size_t)stride_height, (size_t)stride_width};
@@ -229,7 +232,9 @@ std::shared_ptr<ngraph::Node> Conv2d::createNode() {
229232
convNode, biasNode, ngraph::op::AutoBroadcastType::NUMPY);
230233
outputNode = applyActivation(outputNode, activationFn);
231234

232-
if (!useNchw) {
235+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
236+
const auto outputOp = sModelInfo->getOperand(outputIndex);
237+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
233238
outputNode = transpose(NCHW_NHWC, outputNode);
234239
}
235240

ngraph_creator/operations/src/DepthToSpace.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,23 @@ std::shared_ptr<ngraph::Node> DepthToSpace::createNode() {
2525
input = getInputNode(0);
2626
auto block_size = sModelInfo->ParseOperationInput<uint32_t>(mNnapiOperationIndex, 1);
2727

28-
if (!useNchw) // No conversion needed if useNchw set
29-
input = transpose(NHWC_NCHW, input);
28+
if (!transposed_nchw) {
29+
if (!useNchw) { // No conversion needed if useNchw set
30+
input = transpose(NHWC_NCHW, input);
31+
transposed_nchw = true;
32+
}
33+
}
3034

3135
std::shared_ptr<ngraph::Node> outputNode;
3236

3337
outputNode = std::make_shared<ngraph::opset3::DepthToSpace>(
3438
input, ngraph::op::v0::DepthToSpace::DepthToSpaceMode::BLOCKS_FIRST, block_size);
3539

36-
if (!useNchw) outputNode = transpose(NCHW_NHWC, outputNode);
40+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
41+
const auto outputOp = sModelInfo->getOperand(outputIndex);
42+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
43+
outputNode = transpose(NCHW_NHWC, outputNode);
44+
}
3745

3846
return outputNode;
3947
}

ngraph_creator/operations/src/DepthwiseConv2d.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,11 @@ std::shared_ptr<ngraph::Node> DepthwiseConv2d::createNode() {
214214

215215
// OpenVino expects filter in OIHW format
216216
filterNode = transpose(IHWO_OIHW, filterNode);
217-
if (!useNchw) { // No conversion needed if useNchw set
218-
inputNode = transpose(NHWC_NCHW, inputNode);
217+
if (!transposed_nchw) {
218+
if (!useNchw) { // No conversion needed if useNchw set
219+
inputNode = transpose(NHWC_NCHW, inputNode);
220+
transposed_nchw = true;
221+
}
219222
}
220223

221224
strides = {(size_t)stride_height, (size_t)stride_width};
@@ -249,7 +252,9 @@ std::shared_ptr<ngraph::Node> DepthwiseConv2d::createNode() {
249252
groupConvNode, biasNode, ngraph::op::AutoBroadcastType::NUMPY);
250253
outputNode = applyActivation(outputNode, activationFn);
251254

252-
if (!useNchw) {
255+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
256+
const auto outputOp = sModelInfo->getOperand(outputIndex);
257+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
253258
outputNode = transpose(NCHW_NHWC, outputNode);
254259
}
255260

ngraph_creator/operations/src/GroupedConv2d.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,11 @@ std::shared_ptr<ngraph::Node> GroupedConv2d::createNode() {
178178
// OpenVino expects filter in OIHW format
179179
filterNode = transpose(OHWI_OIHW, filterNode);
180180

181-
if (!useNchw) { // No conversion needed if useNchw set
182-
inputNode = transpose(NHWC_NCHW, inputNode);
181+
if (!transposed_nchw) {
182+
if (!useNchw) { // No conversion needed if useNchw set
183+
inputNode = transpose(NHWC_NCHW, inputNode);
184+
transposed_nchw = true;
185+
}
183186
}
184187

185188
strides = {(size_t)stride_width, (size_t)stride_height};
@@ -218,7 +221,9 @@ std::shared_ptr<ngraph::Node> GroupedConv2d::createNode() {
218221
groupConvNode, biasNode, ngraph::op::AutoBroadcastType::NUMPY);
219222
outputNode = applyActivation(outputNode, activationFn);
220223

221-
if (!useNchw) {
224+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
225+
const auto outputOp = sModelInfo->getOperand(outputIndex);
226+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
222227
outputNode = transpose(NCHW_NHWC, outputNode);
223228
}
224229

ngraph_creator/operations/src/InstanceNormalization.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ std::shared_ptr<ngraph::Node> InstanceNormalization::createNode() {
5050
auto layout = sModelInfo->ParseOperationInput<uint8_t>(mNnapiOperationIndex, 4);
5151
if (layout) useNchw = true;
5252

53-
if (!useNchw) // No conversion needed if useNchw set
54-
inputNode = transpose(NHWC_NCHW, inputNode);
53+
if (!transposed_nchw) {
54+
if (!useNchw) { // No conversion needed if useNchw set
55+
inputNode = transpose(NHWC_NCHW, inputNode);
56+
transposed_nchw = true;
57+
}
58+
}
5559

5660
// output[b, h, w, c] = (input[b, h, w, c] - mean[b, c]) * gamma /
5761
// sqrt(var[b, c] + epsilon) + beta
@@ -71,7 +75,11 @@ std::shared_ptr<ngraph::Node> InstanceNormalization::createNode() {
7175
std::shared_ptr<ngraph::Node> outputNode =
7276
std::make_shared<ngraph::opset3::Add>(mulGamma, betaNode);
7377

74-
if (!useNchw) outputNode = transpose(NCHW_NHWC, outputNode);
78+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
79+
const auto outputOp = sModelInfo->getOperand(outputIndex);
80+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
81+
outputNode = transpose(NCHW_NHWC, outputNode);
82+
}
7583
ALOGV("%s PASSED", __func__);
7684

7785
return outputNode;

ngraph_creator/operations/src/L2Pooling2D.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@ std::shared_ptr<ngraph::Node> L2Pooling2D::createNode() {
114114
inputNode = getInputNode(0);
115115
inputSquared = std::make_shared<ngraph::op::v1::Multiply>(inputNode, inputNode);
116116

117-
if (!useNchw) {
118-
ALOGD("%s Forced NCHW conversion at operationIndex %d", __func__, mNnapiOperationIndex);
119-
inputSquared = transpose(NHWC_NCHW, inputSquared);
117+
if (!transposed_nchw) {
118+
if (!useNchw) {
119+
ALOGD("%s Forced NCHW conversion at operationIndex %d", __func__, mNnapiOperationIndex);
120+
inputSquared = transpose(NHWC_NCHW, inputSquared);
121+
transposed_nchw = true;
122+
}
120123
}
121124

122125
strides = {(size_t)stride_height, (size_t)stride_width};
@@ -132,7 +135,9 @@ std::shared_ptr<ngraph::Node> L2Pooling2D::createNode() {
132135

133136
auto outputNode = applyActivation(sqrtOutput, activationFn);
134137

135-
if (!useNchw) {
138+
auto outputIndex = sModelInfo->getOperationOutput(mNnapiOperationIndex, 0);
139+
const auto outputOp = sModelInfo->getOperand(outputIndex);
140+
if (!useNchw && (outputOp.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT)) {
136141
outputNode = transpose(NCHW_NHWC, outputNode);
137142
}
138143

0 commit comments

Comments
 (0)