1 // Copyright (C) 2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include "ngraph_functions/low_precision_transformations/concat_function.hpp"
7 #include <ngraph/opsets/opset1.hpp>
8 #include "ngraph_ops/type_relaxed.hpp"
9 #include "low_precision/network_helper.hpp"
11 #include "ngraph_functions/subgraph_builders.hpp"
12 #include "ngraph_functions/low_precision_transformations/common/fake_quantize_on_data.hpp"
13 #include "ngraph_functions/low_precision_transformations/common/dequantization_operations.hpp"
14 #include "ngraph_functions/low_precision_transformations/common/builders.hpp"
20 using namespace ngraph::pass;
22 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginal(
23 const ngraph::element::Type precision,
24 const ngraph::Shape& inputShape,
25 const FakeQuantizeOnData& fqOnData1,
26 const FakeQuantizeOnData& fqOnData2) {
27 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
28 input1->set_friendly_name("input1");
29 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
31 const std::vector<size_t> inputShape2 = inputShape;
32 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
33 input2->set_friendly_name("input2");
34 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
36 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
37 ngraph::OutputVector{ fakeQuantize1->output(0), fakeQuantize2->output(0) }, 1);
38 concat->set_friendly_name("output");
40 ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(concat) };
41 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
43 ngraph::ParameterVector{ input1, input2 },
44 "ConcatTransformation");
49 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalWithNeighbors(
50 const ngraph::element::Type precision,
51 const ngraph::Shape& inputShape,
52 const FakeQuantizeOnData& fqOnData1,
53 const FakeQuantizeOnData& fqOnData2,
54 const FakeQuantizeOnData& fqOnData3) {
55 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
56 input1->set_friendly_name("input1");
57 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
58 fakeQuantize1->set_friendly_name("fakeQuantize1");
60 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
61 input2->set_friendly_name("input2");
62 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
63 fakeQuantize2->set_friendly_name("fakeQuantize2");
65 const auto input3 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
66 input3->set_friendly_name("input3");
67 const auto fakeQuantize3 = makeFakeQuantize(input3, precision, fqOnData3);
68 fakeQuantize3->set_friendly_name("fakeQuantize3");
70 const auto concat1 = std::make_shared<ngraph::opset1::Concat>(
71 ngraph::OutputVector { fakeQuantize1->output(0), fakeQuantize2->output(0) },
73 concat1->set_friendly_name("concat1");
75 const auto concat2 = std::make_shared<ngraph::opset1::Concat>(
76 ngraph::OutputVector { fakeQuantize2->output(0), fakeQuantize3->output(0) },
78 concat2->set_friendly_name("concat2");
80 const ngraph::ResultVector results {
81 std::make_shared<ngraph::opset1::Result>(concat1),
82 std::make_shared<ngraph::opset1::Result>(concat2)
85 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
87 ngraph::ParameterVector { input1, input2, input3 },
88 "ConcatWithNeighborsTransformation");
93 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalWithIntermediate(
94 const ngraph::element::Type precision,
95 const ngraph::Shape& inputShape,
96 const bool transparentIntermediate,
97 const FakeQuantizeOnData& fqOnData1,
98 const FakeQuantizeOnData& fqOnData2) {
99 const std::vector<size_t> inputShape1 = {
102 inputShape[2] - (transparentIntermediate ? 2 : 0),
103 inputShape[3] - (transparentIntermediate ? 2 : 0)
106 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
107 input1->set_friendly_name("input1");
108 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
109 fakeQuantize1->set_friendly_name("fakeQuantize1");
111 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
112 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
113 input2->set_friendly_name("input2");
115 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
116 fakeQuantize2->set_friendly_name("fakeQuantize2");
118 const std::vector<size_t> kernel = { 3, 3 };
119 const std::vector<size_t> stride = { 1, 1 };
120 const std::vector<size_t> padBegin = { 0, 0 };
121 const std::vector<size_t> padEnd = { 0, 0 };
122 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
123 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
124 std::shared_ptr<ngraph::op::Op> intermediateOp;
126 if (transparentIntermediate) {
127 intermediateOp = std::make_shared<ngraph::opset1::MaxPool>(
128 fakeQuantize2->output(0),
136 auto weights = ngraph::opset1::Constant::create(
138 ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 },
139 std::vector<float>(inputShape[1] * inputShape[1], 1));
141 intermediateOp = std::make_shared<ngraph::opset1::Convolution>(
142 fakeQuantize2->output(0),
144 ngraph::Strides{ 1, 1 },
145 ngraph::CoordinateDiff{ 0, 0 },
146 ngraph::CoordinateDiff{ 0, 0 },
147 ngraph::Strides{ 1, 1 });
150 intermediateOp->set_friendly_name("intermediate");
152 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
153 ngraph::OutputVector{ fakeQuantize1->output(0), intermediateOp->output(0) }, 1);
154 concat->set_friendly_name("concat");
157 auto weights = ngraph::opset1::Constant::create(precision, ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 }, { 1 });
158 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
161 ngraph::Strides { 1, 1 },
162 ngraph::CoordinateDiff { 0, 0 },
163 ngraph::CoordinateDiff { 0, 0 },
164 ngraph::Strides { 1, 1 });
165 convolution->set_friendly_name("convolution");
167 ngraph::ResultVector results {
168 std::make_shared<ngraph::opset1::Result>(concat),
169 std::make_shared<ngraph::opset1::Result>(convolution)
172 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
174 ngraph::ParameterVector{ input1, input2 },
175 "ConcatWithIntermediateTransformation");
180 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalWithSplitedIntermediate(
181 const ngraph::element::Type precision,
182 const ngraph::Shape& inputShape,
183 const FakeQuantizeOnData& fqOnData1,
184 const FakeQuantizeOnData& fqOnData2) {
186 size_t splitedAxis = 1;
189 const std::vector<size_t> inputShape1 = {
191 inputShape[1] / numSplit,
196 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
197 input1->set_friendly_name("input1");
198 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
199 fakeQuantize1->set_friendly_name("fakeQuantize1");
201 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
202 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
203 input2->set_friendly_name("input2");
205 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
206 fakeQuantize2->set_friendly_name("fakeQuantize2");
208 std::shared_ptr<ngraph::op::Op> intermediateOp;
210 const auto constant = std::make_shared<ngraph::opset1::Constant>(element::i64, Shape{ }, splitedAxis);
211 intermediateOp = std::make_shared<ngraph::opset1::Split>(fakeQuantize2->output(0), constant, numSplit);
213 intermediateOp->set_friendly_name("intermediate");
215 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
216 ngraph::OutputVector{ fakeQuantize1->output(0), intermediateOp->output(0) }, splitedAxis);
217 concat->set_friendly_name("concat");
219 auto weights = ngraph::opset1::Constant::create(precision, ngraph::Shape{ inputShape[1] / numSplit, inputShape[1] / numSplit, 1, 1 }, { 1 });
220 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
221 intermediateOp->output(1),
223 ngraph::Strides{ 1, 1 },
224 ngraph::CoordinateDiff{ 0, 0 },
225 ngraph::CoordinateDiff{ 0, 0 },
226 ngraph::Strides{ 1, 1 });
227 convolution->set_friendly_name("convolution");
229 ngraph::ResultVector results{
230 std::make_shared<ngraph::opset1::Result>(concat),
231 std::make_shared<ngraph::opset1::Result>(convolution),
234 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
236 ngraph::ParameterVector{ input1, input2 },
237 "ConcatWithIntermediateTransformation");
242 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalSelectionWithIntermediate(
243 const ngraph::element::Type precision,
244 const ngraph::Shape& inputShape,
245 const bool transparentIntermediate,
246 const FakeQuantizeOnData& fqOnData1,
247 const FakeQuantizeOnData& fqOnData2) {
248 const std::vector<size_t> inputShape1 = {
251 inputShape[2] - (transparentIntermediate ? 2 : 0),
252 inputShape[3] - (transparentIntermediate ? 2 : 0)
255 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
256 input1->set_friendly_name("input1");
257 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
258 fakeQuantize1->set_friendly_name("fakeQuantize1");
260 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
261 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
262 input2->set_friendly_name("input2");
264 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
265 fakeQuantize2->set_friendly_name("fakeQuantize2");
267 const std::vector<size_t> kernel = { 3, 3 };
268 const std::vector<size_t> stride = { 1, 1 };
269 const std::vector<size_t> padBegin = { 0, 0 };
270 const std::vector<size_t> padEnd = { 0, 0 };
271 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
272 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
273 std::shared_ptr<ngraph::op::Op> intermediateOp;
275 if (transparentIntermediate) {
276 intermediateOp = std::make_shared<ngraph::opset1::MaxPool>(
277 fakeQuantize2->output(0),
285 auto weights = ngraph::opset1::Constant::create(
287 ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 },
288 std::vector<float>(inputShape[1] * inputShape[1], 1));
290 intermediateOp = std::make_shared<ngraph::opset1::Convolution>(
291 fakeQuantize2->output(0),
293 ngraph::Strides{ 1, 1 },
294 ngraph::CoordinateDiff{ 0, 0 },
295 ngraph::CoordinateDiff{ 0, 0 },
296 ngraph::Strides{ 1, 1 });
299 intermediateOp->set_friendly_name("intermediate");
301 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
302 ngraph::OutputVector{ fakeQuantize1->output(0), intermediateOp->output(0) }, 1);
303 concat->set_friendly_name("concat");
306 auto weights = ngraph::opset1::Constant::create(precision, ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 }, { 1 });
307 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
310 ngraph::Strides { 1, 1 },
311 ngraph::CoordinateDiff { 0, 0 },
312 ngraph::CoordinateDiff { 0, 0 },
313 ngraph::Strides { 1, 1 });
314 convolution->set_friendly_name("convolution");
316 ngraph::ResultVector results {
317 std::make_shared<ngraph::opset1::Result>(concat),
318 std::make_shared<ngraph::opset1::Result>(convolution)
321 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
323 ngraph::ParameterVector{ input1, input2 },
324 "ConcatWithIntermediateTransformation");
329 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalWithDifferentPrecisionOnChilds(
330 const ngraph::element::Type precision,
331 const ngraph::Shape& inputShape,
332 const FakeQuantizeOnData& fqOnData1,
333 const FakeQuantizeOnData& fqOnData2) {
334 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
335 input1->set_friendly_name("input1");
336 const auto fakeQuantize1 = makeFakeQuantize(input1, precision, fqOnData1);
338 const std::vector<size_t> inputShape2 = inputShape;
339 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
340 input2->set_friendly_name("input2");
341 const auto fakeQuantize2 = makeFakeQuantize(input2, precision, fqOnData2);
343 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
344 ngraph::OutputVector{ fakeQuantize1->output(0), fakeQuantize2->output(0) }, 1);
346 const std::vector<size_t> kernel = { 3, 3 };
347 const std::vector<size_t> stride = { 1, 1 };
348 const std::vector<size_t> padBegin = { 0, 0 };
349 const std::vector<size_t> padEnd = { 0, 0 };
350 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
351 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
353 const auto avgPool = std::make_shared<ngraph::opset1::AvgPool>(
362 avgPool->set_friendly_name("AvgPool");
364 const auto maxPool = std::make_shared<ngraph::opset1::MaxPool>(
372 maxPool->set_friendly_name("MaxPool");
374 ngraph::ResultVector results;
375 results.push_back(std::make_shared<ngraph::opset1::Result>(avgPool));
376 results.push_back(std::make_shared<ngraph::opset1::Result>(maxPool));
378 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
380 ngraph::ParameterVector{ input1, input2 },
381 "ConcatWithDifferentChildsTransformation");
386 std::shared_ptr<ngraph::Function> ConcatFunction::getOriginalWithIntermediateWithConstant(
387 const ngraph::element::Type precision,
388 const ngraph::Shape& inputShape,
389 const bool transparentIntermediate,
390 const FakeQuantizeOnData& fqOnData1,
391 const FakeQuantizeOnData& fqOnData2) {
392 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
393 input1->set_friendly_name("input");
394 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
395 fakeQuantize1->set_friendly_name("fakeQuantize1");
397 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
398 input2->set_friendly_name("input");
399 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
400 fakeQuantize2->set_friendly_name("fakeQuantize2");
403 std::shared_ptr<ngraph::op::Op> intermediateOp;
405 if (transparentIntermediate) {
406 const std::vector<size_t> kernel = { 3, 3 };
407 const std::vector<size_t> stride = { 1, 1 };
408 const std::vector<size_t> padBegin = { 0, 0 };
409 const std::vector<size_t> padEnd = { 0, 0 };
410 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
411 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
413 const auto pooling = std::make_shared<ngraph::opset1::MaxPool>(
414 fakeQuantize1->output(0),
422 ngraph::op::v0::InterpolateAttrs attributes;
423 attributes.axes = ngraph::AxisSet{ 2, 3 };
424 attributes.mode = "nearest";
425 attributes.align_corners = false;
426 attributes.antialias = false;
427 attributes.pads_begin = { 0 };
428 attributes.pads_end = { 0 };
429 const auto outputShape = op::Constant::create(
430 ngraph::element::i64, ngraph::Shape{ 2 },
431 ngraph::Shape{ inputShape[2], inputShape[3] });
432 intermediateOp = std::make_shared<ngraph::opset1::Interpolate>(pooling->output(0), outputShape, attributes);
433 intermediateOp->set_friendly_name("intermediate");
435 intermediateOp = fakeQuantize1;
438 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
439 ngraph::OutputVector{ fakeQuantize2->output(0), intermediateOp->output(0) }, 1);
440 concat->set_friendly_name("concat");
442 ngraph::ResultVector results{
443 std::make_shared<ngraph::opset1::Result>(concat),
446 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
448 ngraph::ParameterVector{ input1, input2 },
449 "ConcatWithIntermediateWithConstantTransformation");
454 std::shared_ptr<ngraph::Function> ConcatFunction::getReference(
455 const ngraph::element::Type precision,
456 const ngraph::Shape& inputShape,
457 const FakeQuantizeOnData& fqOnData1,
458 const FakeQuantizeOnData& fqOnData2,
459 const DequantizationOperations& dequantizationOperations) {
460 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
461 input1->set_friendly_name("input1");
462 const auto fakeQuantize1 = ngraph::builder::subgraph::makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
464 const std::vector<size_t> inputShape2 = inputShape;
465 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
466 input2->set_friendly_name("input2");
467 const auto fakeQuantize2 = ngraph::builder::subgraph::makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
469 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::op::TypeRelaxed<ngraph::opset1::Concat>>(
470 ngraph::OutputVector{ fakeQuantize1->output(0), fakeQuantize2->output(0) }, 1);
472 const std::shared_ptr<ngraph::Node> lastDequantization = makeDequantization(concat, dequantizationOperations);
473 lastDequantization->set_friendly_name("output");
475 ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(lastDequantization) };
476 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
478 ngraph::ParameterVector{ input1, input2 },
479 "ConcatTransformation");
481 if (fqOnData1.outputPrecision != fqOnData2.outputPrecision) {
482 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
484 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
485 if (fqOnDataPrecision != ngraph::element::undefined) {
486 if (fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) {
487 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
489 const ngraph::element::Type fakeQuantizePrecision = fakeQuantize1->get_output_element_type(0);
491 if (fqOnDataPrecision != fakeQuantizePrecision) {
492 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
493 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
494 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat, fqOnDataPrecision);
501 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithNeighbors(
502 const ngraph::element::Type precision,
503 const ngraph::Shape& inputShape,
504 const FakeQuantizeOnData& fqOnData1,
505 const FakeQuantizeOnData& fqOnData2,
506 const FakeQuantizeOnData& fqOnData3,
507 const DequantizationOperations& dequantizationOperations1,
508 const DequantizationOperations& dequantizationOperations2) {
509 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
510 input1->set_friendly_name("input1");
511 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
512 fakeQuantize1->set_friendly_name("fakeQuantize1");
514 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
515 input2->set_friendly_name("input2");
516 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
517 fakeQuantize2->set_friendly_name("fakeQuantize2");
519 const auto input3 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
520 input3->set_friendly_name("input3");
521 const auto fakeQuantize3 = makeFakeQuantizeTypeRelaxed(input3, precision, fqOnData3);
522 fakeQuantize3->set_friendly_name("fakeQuantize3");
524 const auto concat1 = std::make_shared<ngraph::opset1::Concat>(
525 ngraph::OutputVector { fakeQuantize1->output(0), fakeQuantize2->output(0) },
527 concat1->set_friendly_name("concat1");
529 const auto concat2 = std::make_shared<ngraph::opset1::Concat>(
530 ngraph::OutputVector { fakeQuantize2->output(0), fakeQuantize3->output(0) },
532 concat2->set_friendly_name("concat2");
534 const std::shared_ptr<ngraph::Node> lastDequantization1 = makeDequantization(concat1, dequantizationOperations1);
535 lastDequantization1->set_friendly_name("concat1");
537 const std::shared_ptr<ngraph::Node> lastDequantization2 = makeDequantization(concat2, dequantizationOperations2);
538 lastDequantization2->set_friendly_name("concat2");
540 const ngraph::ResultVector results {
541 std::make_shared<ngraph::opset1::Result>(lastDequantization1),
542 std::make_shared<ngraph::opset1::Result>(lastDequantization2)
545 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
547 ngraph::ParameterVector { input1, input2, input3 },
548 "ConcatWithNeighborsTransformation");
550 if ((fqOnData1.outputPrecision != fqOnData2.outputPrecision) || (fqOnData2.outputPrecision != fqOnData3.outputPrecision)) {
551 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
553 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
554 if (fqOnDataPrecision != ngraph::element::undefined) {
555 if ((fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) ||
556 (fakeQuantize2->get_output_element_type(0) != fakeQuantize3->get_output_element_type(0))) {
557 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
559 const ngraph::element::Type fakeQuantizePrecision = fakeQuantize1->get_output_element_type(0);
561 if (fqOnDataPrecision != fakeQuantizePrecision) {
562 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
563 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
564 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize3, fqOnDataPrecision);
565 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat1, fqOnDataPrecision);
566 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat2, fqOnDataPrecision);
573 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithIntermediate(
574 const ngraph::element::Type precision,
575 const ngraph::Shape& inputShape,
576 const bool transparentIntermediate,
577 const FakeQuantizeOnData& fqOnData1,
578 const FakeQuantizeOnData& fqOnData2,
579 const DequantizationOperations& dequantizationOperations1,
580 const DequantizationOperations& dequantizationOperations2) {
581 const std::vector<size_t> inputShape1 = {
584 inputShape[2] - (transparentIntermediate ? 2 : 0),
585 inputShape[3] - (transparentIntermediate ? 2 : 0)
588 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
589 input1->set_friendly_name("input1");
590 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
591 fakeQuantize1->set_friendly_name("fakeQuantize1");
593 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
594 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
595 input2->set_friendly_name("input2");
597 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
598 fakeQuantize2->set_friendly_name("fakeQuantize2");
600 const std::vector<size_t> kernel = { 3, 3 };
601 const std::vector<size_t> stride = { 1, 1 };
602 const std::vector<size_t> padBegin = { 0, 0 };
603 const std::vector<size_t> padEnd = { 0, 0 };
604 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
605 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
606 std::shared_ptr<Node> intermediateOp;
608 if (transparentIntermediate) {
609 intermediateOp = std::make_shared<ngraph::opset1::MaxPool>(
610 fakeQuantize2->output(0),
618 auto weights = ngraph::opset1::Constant::create(
620 ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 },
621 std::vector<float>(inputShape[1] * inputShape[1], 1));
623 intermediateOp = std::make_shared<ngraph::opset1::Convolution>(
624 fakeQuantize2->output(0),
626 ngraph::Strides{ 1, 1 },
627 ngraph::CoordinateDiff{ 0, 0 },
628 ngraph::CoordinateDiff{ 0, 0 },
629 ngraph::Strides{ 1, 1 });
632 intermediateOp->set_friendly_name("intermediate");
634 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
635 ngraph::OutputVector { fakeQuantize1->output(0), intermediateOp->output(0) },
637 concat->set_friendly_name("concat");
639 const std::shared_ptr<ngraph::Node> lastDequantization1 = dequantizationOperations1.empty() ?
641 makeDequantization(concat, dequantizationOperations1);
642 lastDequantization1->set_friendly_name("concat");
644 const std::shared_ptr<ngraph::Node> lastDequantization2 = dequantizationOperations2.empty() ?
646 makeDequantization(intermediateOp, dequantizationOperations2);
648 auto weights = ngraph::opset1::Constant::create(precision, ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 }, { 1 });
649 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
650 lastDequantization2 == nullptr ? intermediateOp : lastDequantization2,
652 ngraph::Strides{ 1, 1 },
653 ngraph::CoordinateDiff{ 0, 0 },
654 ngraph::CoordinateDiff{ 0, 0 },
655 ngraph::Strides{ 1, 1 });
656 convolution->set_friendly_name("convolution");
658 ngraph::ResultVector results {
659 std::make_shared<ngraph::opset1::Result>(lastDequantization1),
660 std::make_shared<ngraph::opset1::Result>(convolution)
663 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
665 ngraph::ParameterVector{ input1, input2 },
666 "ConcatWithIntermediateTransformation");
668 if ((fqOnData1.outputPrecision != fqOnData2.outputPrecision)) {
669 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
671 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
672 if (fqOnDataPrecision != ngraph::element::undefined) {
673 if (fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) {
674 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
676 const ngraph::element::Type fakeQuantizePrecision = fakeQuantize1->get_output_element_type(0);
678 if (fqOnDataPrecision != fakeQuantizePrecision) {
679 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
680 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
681 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat, fqOnDataPrecision);
683 auto intermediateOpTr = std::dynamic_pointer_cast<ngraph::op::TypeRelaxedBase>(intermediateOp);
684 if (intermediateOpTr != nullptr) {
685 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecisionForTypeRelaxed(intermediateOp, fqOnDataPrecision);
687 // set precision to explicitly to have updated precision during transformation
688 for (size_t i = 0; i < intermediateOp->get_output_size(); ++i) {
689 intermediateOp->set_output_type(i, fqOnDataPrecision, intermediateOp->get_output_partial_shape(i));
698 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithSplitedIntermediate(
699 const ngraph::element::Type precision,
700 const ngraph::Shape& inputShape,
701 const FakeQuantizeOnData& fqOnData1,
702 const FakeQuantizeOnData& fqOnData2,
703 const DequantizationOperations& dequantizationOperations1,
704 const DequantizationOperations& dequantizationOperations2) {
706 size_t splitedAxis = 1;
708 const std::vector<size_t> inputShape1 = {
710 inputShape[1] / numSplit,
715 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
716 input1->set_friendly_name("input1");
717 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
718 fakeQuantize1->set_friendly_name("fakeQuantize1");
721 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
722 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
723 input2->set_friendly_name("input2");
724 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
725 fakeQuantize2->set_friendly_name("fakeQuantize2");
727 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
728 if (fqOnDataPrecision != ngraph::element::undefined) {
729 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
730 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
733 std::shared_ptr<ngraph::op::Op> intermediateOp;
735 const auto constant = std::make_shared<ngraph::opset1::Constant>(element::i64, Shape{ }, splitedAxis);
736 intermediateOp = std::make_shared<ngraph::opset1::Split>(fakeQuantize2->output(0), constant, numSplit);
738 intermediateOp->set_friendly_name("intermediate");
740 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
741 ngraph::OutputVector{ fakeQuantize1->output(0), intermediateOp->output(0) }, splitedAxis);
742 concat->set_friendly_name("concat");
744 const std::shared_ptr<ngraph::Node> lastDequantization1 = dequantizationOperations1.empty() ?
746 makeDequantization(concat, dequantizationOperations1);
748 const std::shared_ptr<ngraph::Node> lastDequantization2 = dequantizationOperations2.empty() ?
750 makeDequantization(intermediateOp->output(1), dequantizationOperations2);
752 auto weights = ngraph::opset1::Constant::create(
754 ngraph::Shape{ inputShape[1] / numSplit, inputShape[1] / numSplit, 1, 1 }, { 1 });
756 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
757 lastDequantization2 == nullptr ? intermediateOp : lastDequantization2,
759 ngraph::Strides{ 1, 1 },
760 ngraph::CoordinateDiff{ 0, 0 },
761 ngraph::CoordinateDiff{ 0, 0 },
762 ngraph::Strides{ 1, 1 });
763 convolution->set_friendly_name("convolution");
765 ngraph::ResultVector results{
766 std::make_shared<ngraph::opset1::Result>(lastDequantization1),
767 std::make_shared<ngraph::opset1::Result>(convolution)
770 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
772 ngraph::ParameterVector{ input1, input2 },
773 "ConcatWithIntermediateTransformation");
775 if ((fqOnData1.outputPrecision != fqOnData2.outputPrecision)) {
776 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
778 if (fqOnDataPrecision != ngraph::element::undefined) {
779 if (fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) {
780 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
787 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceSelectionWithIntermediate(
788 const ngraph::element::Type precision,
789 const ngraph::Shape& inputShape,
790 const bool transparentIntermediate,
791 const FakeQuantizeOnData& fqOnData1,
792 const FakeQuantizeOnData& fqOnData2,
793 const DequantizationOperations& dequantizationOperations1,
794 const DequantizationOperations& dequantizationOperations2) {
795 const std::vector<size_t> inputShape1 = {
798 inputShape[2] - (transparentIntermediate ? 2 : 0),
799 inputShape[3] - (transparentIntermediate ? 2 : 0)
802 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape1));
803 input1->set_friendly_name("input1");
804 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
805 fakeQuantize1->set_friendly_name("fakeQuantize1");
807 const std::vector<size_t> inputShape2 = { inputShape[0], inputShape[1], inputShape[2], inputShape[3] };
808 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape2));
809 input2->set_friendly_name("input2");
811 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
812 fakeQuantize2->set_friendly_name("fakeQuantize2");
814 const std::vector<size_t> kernel = { 3, 3 };
815 const std::vector<size_t> stride = { 1, 1 };
816 const std::vector<size_t> padBegin = { 0, 0 };
817 const std::vector<size_t> padEnd = { 0, 0 };
818 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
819 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
820 std::shared_ptr<ngraph::op::Op> intermediateOp;
822 if (transparentIntermediate) {
823 intermediateOp = std::make_shared<ngraph::opset1::MaxPool>(
824 fakeQuantize2->output(0),
832 auto weights = ngraph::opset1::Constant::create(
834 ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 },
835 std::vector<float>(inputShape[1] * inputShape[1], 1));
837 intermediateOp = std::make_shared<ngraph::opset1::Convolution>(
838 fakeQuantize2->output(0),
840 ngraph::Strides{ 1, 1 },
841 ngraph::CoordinateDiff{ 0, 0 },
842 ngraph::CoordinateDiff{ 0, 0 },
843 ngraph::Strides{ 1, 1 });
846 intermediateOp->set_friendly_name("intermediate");
848 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
849 ngraph::OutputVector { fakeQuantize1->output(0), intermediateOp->output(0) },
851 concat->set_friendly_name("concat");
853 const std::shared_ptr<ngraph::Node> lastDequantization1 = dequantizationOperations1.empty() ?
855 makeDequantization(concat, dequantizationOperations1);
856 lastDequantization1->set_friendly_name("concat");
858 const std::shared_ptr<ngraph::Node> lastDequantization2 = dequantizationOperations2.empty() ?
860 makeDequantization(intermediateOp, dequantizationOperations2);
862 auto weights = ngraph::opset1::Constant::create(precision, ngraph::Shape{ inputShape[1], inputShape[1], 1, 1 }, { 1 });
863 auto convolution = std::make_shared<ngraph::opset1::Convolution>(
864 lastDequantization2 == nullptr ? intermediateOp : lastDequantization2,
866 ngraph::Strides{ 1, 1 },
867 ngraph::CoordinateDiff{ 0, 0 },
868 ngraph::CoordinateDiff{ 0, 0 },
869 ngraph::Strides{ 1, 1 });
870 convolution->set_friendly_name("convolution");
872 ngraph::ResultVector results {
873 std::make_shared<ngraph::opset1::Result>(lastDequantization1),
874 std::make_shared<ngraph::opset1::Result>(convolution)
877 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
879 ngraph::ParameterVector{ input1, input2 },
880 "ConcatWithIntermediateTransformation");
882 if ((fqOnData1.outputPrecision != fqOnData2.outputPrecision)) {
883 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
885 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
886 if (fqOnDataPrecision != ngraph::element::undefined) {
887 if (fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) {
888 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
890 const ngraph::element::Type fakeQuantizePrecision = fakeQuantize1->get_output_element_type(0);
892 if (fqOnDataPrecision != fakeQuantizePrecision) {
893 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
894 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
895 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat, fqOnDataPrecision);
897 auto intermediateOpTr = std::dynamic_pointer_cast<ngraph::op::TypeRelaxedBase>(intermediateOp);
898 if (intermediateOpTr != nullptr) {
899 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecisionForTypeRelaxed(intermediateOp, fqOnDataPrecision);
907 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithDifferentPrecisionOnChilds(
908 const ngraph::element::Type precision,
909 const ngraph::Shape& inputShape,
910 const bool multiChannel,
911 const FakeQuantizeOnData& fqOnData1,
912 const FakeQuantizeOnData& fqOnData2,
913 const DequantizationOperations& dequantizationOperations1,
914 const DequantizationOperations& dequantizationOperations2) {
915 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
916 input1->set_friendly_name("input1");
917 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
918 fakeQuantize1->set_friendly_name("fakeQuantize1");
920 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
921 input2->set_friendly_name("input2");
922 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
923 fakeQuantize2->set_friendly_name("fakeQuantize2");
925 const ngraph::element::Type fqOnDataPrecision = fqOnData1.outputPrecision;
926 if (fqOnDataPrecision != ngraph::element::undefined) {
927 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, fqOnDataPrecision);
928 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, fqOnDataPrecision);
931 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
932 ngraph::OutputVector{ fakeQuantize1->output(0), fakeQuantize2->output(0) }, 1);
933 concat->set_friendly_name("concat");
935 const auto lastDequantization1 = makeDequantization(concat->output(0), dequantizationOperations1);
937 const std::vector<size_t> kernel = { 3, 3 };
938 const std::vector<size_t> stride = { 1, 1 };
939 const std::vector<size_t> padBegin = { 0, 0 };
940 const std::vector<size_t> padEnd = { 0, 0 };
941 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
942 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
944 const auto avgPool = std::make_shared<ngraph::opset1::AvgPool>(
953 avgPool->set_friendly_name("AvgPool");
955 ngraph::ResultVector results;
956 results.push_back(std::make_shared<ngraph::opset1::Result>(avgPool));
958 if (!dequantizationOperations2.empty()) {
959 const std::shared_ptr<ngraph::opset1::MaxPool> maxPool = std::make_shared<ngraph::opset1::MaxPool>(
968 const std::shared_ptr<ngraph::Node> lastDequantization2 = makeDequantization(maxPool, dequantizationOperations2);
969 lastDequantization2->set_friendly_name("MaxPool");
970 results.push_back(std::make_shared<ngraph::opset1::Result>(lastDequantization2));
973 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
975 ngraph::ParameterVector{ input1, input2 },
976 "ConcatWithDifferentChildsTransformation");
978 if ((fqOnData1.outputPrecision != fqOnData2.outputPrecision)) {
979 THROW_IE_EXCEPTION << "FakeQuantize expected precisions are different";
981 if (fqOnDataPrecision != ngraph::element::undefined) {
982 if (fakeQuantize1->get_output_element_type(0) != fakeQuantize2->get_output_element_type(0)) {
983 THROW_IE_EXCEPTION << "FakeQuantize operation precisions are different";
990 std::shared_ptr<ngraph::Function> ConcatFunction::getReferenceWithIntermediateWithConstant(
991 const ngraph::element::Type precision,
992 const ngraph::Shape& inputShape,
993 const bool transparentIntermediate,
994 const FakeQuantizeOnData& fqOnData1,
995 const FakeQuantizeOnData& fqOnData2,
996 const ngraph::element::Type precisionBeforeOp,
997 const DequantizationOperations& dequantizationBefore,
998 const ngraph::element::Type precisionAfterOperation,
999 const DequantizationOperations& dequantizationAfter,
1000 const ngraph::element::Type precisionAfterDequantization) {
1001 const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
1002 input1->set_friendly_name("input");
1003 const auto fakeQuantize1 = makeFakeQuantizeTypeRelaxed(input1, precision, fqOnData1);
1004 fakeQuantize1->set_friendly_name("fakeQuantize1");
1005 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize1, precisionBeforeOp);
1007 const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, ngraph::Shape(inputShape));
1008 input2->set_friendly_name("input");
1009 const auto fakeQuantize2 = makeFakeQuantizeTypeRelaxed(input2, precision, fqOnData2);
1010 fakeQuantize2->set_friendly_name("fakeQuantize2");
1011 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(fakeQuantize2, precisionBeforeOp);
1013 std::shared_ptr<Node> intermediateOp;
1015 if (transparentIntermediate) {
1016 const auto deqBefore = makeDequantization(fakeQuantize1->output(0), dequantizationBefore);
1017 const std::vector<size_t> kernel = { 3, 3 };
1018 const std::vector<size_t> stride = { 1, 1 };
1019 const std::vector<size_t> padBegin = { 0, 0 };
1020 const std::vector<size_t> padEnd = { 0, 0 };
1021 const ngraph::op::PadType padType = ngraph::op::PadType::NOTSET;
1022 const ngraph::op::RoundingType roundingType = ngraph::op::RoundingType::FLOOR;
1024 const auto pooling = std::make_shared<ngraph::opset1::MaxPool>(
1025 fakeQuantize1->output(0),
1033 ngraph::op::v0::InterpolateAttrs attributes;
1034 attributes.axes = ngraph::AxisSet{ 2, 3 };
1035 attributes.mode = "nearest";
1036 attributes.align_corners = false;
1037 attributes.antialias = false;
1038 attributes.pads_begin = { 0 };
1039 attributes.pads_end = { 0 };
1041 const auto outputShape = op::Constant::create(
1042 ngraph::element::i64, ngraph::Shape{ 2 },
1043 ngraph::Shape{ inputShape[2], inputShape[3] });
1044 intermediateOp = std::make_shared<ngraph::opset1::Interpolate>(pooling->output(0), outputShape, attributes);
1045 intermediateOp->set_friendly_name("intermediate");
1047 intermediateOp = fakeQuantize1;
1050 const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(
1051 ngraph::OutputVector{ fakeQuantize2->output(0), intermediateOp->output(0) },
1053 concat->set_friendly_name("concat");
1054 ngraph::pass::low_precision::NetworkHelper::setOutDataPrecision(concat, precisionAfterOperation);
1056 const auto deqAfter = makeDequantization(concat->output(0), dequantizationAfter);
1057 deqAfter->set_friendly_name("concat");
1059 ngraph::ResultVector results{
1060 std::make_shared<ngraph::opset1::Result>(deqAfter)
1063 std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
1065 ngraph::ParameterVector{ input1, input2 },
1066 "ConcatWithIntermediateTransformation");
1071 } // namespace subgraph
1072 } // namespace builder
1073 } // namespace ngraph