--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include "ngraph/node.hpp"
+
+namespace vpu {
+
+void dynamicToStaticShapeSplit(std::shared_ptr<ngraph::Node> target);
+
+} // namespace vpu
#include "vpu/ngraph/transformations/dynamic_to_static_shape_reduce.hpp"
#include "vpu/ngraph/transformations/dynamic_to_static_shape_reshape.hpp"
#include "vpu/ngraph/transformations/dynamic_to_static_shape_roialign.hpp"
+#include "vpu/ngraph/transformations/dynamic_to_static_shape_split.hpp"
#include "vpu/ngraph/transformations/dynamic_to_static_shape_squeeze.hpp"
#include "vpu/ngraph/transformations/dynamic_to_static_shape_strided_slice.hpp"
#include "vpu/ngraph/transformations/dynamic_to_static_shape_topk.hpp"
#include "vpu/utils/error.hpp"
#include "ngraph/opsets/opset3.hpp"
+#include "ngraph/opsets/opset5.hpp"
#include "vpu/ngraph/operations/dynamic_non_max_suppression.hpp"
namespace vpu {
{ngraph::opset3::Reshape::type_info, dynamicToStaticShapeReshape},
{ngraph::opset3::Broadcast::type_info, dynamicToStaticShapeBroadcast},
{ngraph::opset3::MatMul::type_info, dynamicToStaticShapeMatMul},
+ {ngraph::opset5::Split::type_info, dynamicToStaticShapeSplit},
// reduction
{ngraph::opset3::ReduceLogicalAnd::type_info, dynamicToStaticShapeReduce},
--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include "vpu/ngraph/transformations/dynamic_to_static_shape_broadcast.hpp"
+
+#include "vpu/ngraph/operations/dynamic_shape_resolver.hpp"
+#include "vpu/ngraph/utilities.hpp"
+#include "vpu/utils/error.hpp"
+
+#include "ngraph/graph_util.hpp"
+#include "ngraph/opsets/opset5.hpp"
+#include "ngraph/validation_util.hpp"
+
+namespace vpu {
+
+void dynamicToStaticShapeSplit(std::shared_ptr<ngraph::Node> target) {
+ const auto split = ngraph::as_type_ptr<ngraph::opset5::Split>(target);
+ VPU_THROW_UNLESS(split,
+ "dynamicToStaticShapeSplit transformation is not applicable for {}, "
+ "it should be {} instead",
+ target, ngraph::opset5::Split::type_info);
+
+ const auto numSplits = split->get_num_splits();
+
+ const auto dsr = ngraph::as_type_ptr<ngraph::vpu::op::DynamicShapeResolver>(target->input_value(0).get_node_shared_ptr());
+ VPU_THROW_UNLESS(dsr, "DynamicToStaticShape transformation for {} of type {} expects {} as input with index {}",
+ target->get_friendly_name(), target->get_type_info(), ngraph::vpu::op::DynamicShapeResolver::type_info, 0);
+
+ const auto dataShape = dsr->input_value(1).get_node_shared_ptr();
+ const auto dataShapeType = dataShape->get_element_type();
+ const auto axisNode = ngraph::as_type_ptr<ngraph::opset5::Constant>(target->input_value(1).get_node_shared_ptr());
+ VPU_THROW_UNLESS(axisNode, "dynamicToStaticShapeSplit transformation is not applicable for {}, dynamic axis is not supported", target);
+
+ const auto dataRank = target->get_input_partial_shape(0).rank();
+ VPU_THROW_UNLESS(dataRank.is_static(), "dynamicToStaticShapeSplit transformation for {} doesn't support dynamic rank", target);
+ const auto srcAxis = axisNode->cast_vector<int64_t>();
+ VPU_THROW_UNLESS(srcAxis.size() == 1,
+ "dynamicToStaticShapeSplit transformation for {} failed: axis node is represented as {} values while 1 is expected",
+ target, srcAxis.size());
+ const auto resultAxis = ngraph::normalize_axis(target->description(), axisNode->cast_vector<int64_t>()[0], dataRank);
+
+ const auto axisVector = ngraph::opset5::Constant::create(dataShapeType, {1}, {resultAxis});
+
+ const auto dimToSplitBy = std::make_shared<ngraph::opset5::Gather>(dataShape,
+ axisVector,
+ ngraph::opset5::Constant::create(dataShapeType, {1}, {0}));
+ const auto splittedDim = std::make_shared<ngraph::opset5::Divide>(dimToSplitBy,
+ ngraph::opset5::Constant::create(dataShapeType, {1}, {numSplits}));
+ const auto resultShape = std::make_shared<ngraph::opset5::ScatterElementsUpdate>(dataShape,
+ axisVector,
+ splittedDim,
+ ngraph::opset5::Constant::create(dataShapeType, {1}, {0}));
+
+ const auto copied = target->clone_with_new_inputs(target->input_values());
+
+ for (size_t i = 0; i < copied->get_output_size(); i++) {
+ const auto outDSR = std::make_shared<ngraph::vpu::op::DynamicShapeResolver>(copied->output(i), resultShape);
+ outDSR->set_friendly_name(target->get_friendly_name() + "." + std::to_string(i));
+ target->output(i).replace(outDSR);
+ }
+}
+
+} // namespace vpu
--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include <vpu/ngraph/transformations/dynamic_to_static_shape_split.hpp>
+
+#include <vpu/ngraph/operations/dynamic_shape_resolver.hpp>
+#include <vpu/ngraph/transformations/dynamic_to_static_shape.hpp>
+#include <common_test_utils/test_common.hpp>
+
+#include <ngraph_functions/utils/ngraph_helpers.hpp>
+#include <ngraph/opsets/opset5.hpp>
+
+namespace {
+
+using DataType = ngraph::element::Type_t;
+using DataDims = ngraph::Shape;
+
+struct SplitTestCase {
+ ngraph::Shape dataShape;
+ int64_t axis, numSplits;
+};
+
+const auto combinations = testing::Combine(
+ testing::Values(
+ ngraph::element::f16,
+ ngraph::element::f32,
+ ngraph::element::i32,
+ ngraph::element::i64,
+ ngraph::element::u8),
+ testing::Values(
+ ngraph::element::i32,
+ ngraph::element::i64),
+ testing::Values(
+ SplitTestCase{{6}, 0, 2},
+ SplitTestCase{{6, 12, 10, 24}, 1, 4},
+ SplitTestCase{{6, 12}, 1, 6},
+ SplitTestCase{{6, 12, 10, 24}, 3, 4},
+ SplitTestCase{{6, 12, 10, 24}, -1, 4}));
+
+
+class DynamicToStaticShapeSplit : public CommonTestUtils::TestsCommon,
+ public testing::WithParamInterface<std::tuple<DataType, DataType, SplitTestCase>> {
+public:
+ void SetUp() override {
+ const auto& parameters = GetParam();
+ const auto& dataType = std::get<0>(parameters);
+ const auto& idxType = std::get<1>(parameters);
+ const auto& splitSetup = std::get<2>(parameters);
+
+ ngraph::helpers::CompareFunctions(*transform(dataType, idxType, splitSetup),
+ *reference(dataType, idxType, splitSetup));
+ }
+
+protected:
+std::shared_ptr<const ngraph::Function> transform(
+ const ngraph::element::Type_t& dataType,
+ const ngraph::element::Type_t& idxType,
+ const SplitTestCase& splitSetup) const {
+ const auto data = std::make_shared<ngraph::opset5::Parameter>(dataType, splitSetup.dataShape);
+ const auto axis = ngraph::opset5::Constant::create(idxType, {}, {splitSetup.axis});
+
+ const auto dims = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::i64, ngraph::Shape{splitSetup.dataShape.size()});
+
+ const auto dsr = std::make_shared<ngraph::vpu::op::DynamicShapeResolver>(data, dims);
+ const auto node = std::make_shared<ngraph::opset5::Split>(dsr, axis, splitSetup.numSplits);
+
+ // tests are capable to compare functions with one result only
+ const auto testsWa = std::make_shared<ngraph::opset5::Concat>(node->outputs(), splitSetup.axis);
+
+ auto outputShape = node->get_output_partial_shape(0);
+ const auto function = std::make_shared<ngraph::Function>(
+ ngraph::NodeVector{testsWa},
+ ngraph::ParameterVector{data, dims},
+ "Actual");
+ node->set_output_type(0, dsr->get_input_element_type(0), ngraph::PartialShape::dynamic(splitSetup.dataShape.size()));
+
+ const auto transformations = vpu::Transformations{{node->type_info, vpu::dynamicToStaticShapeSplit}};
+ vpu::DynamicToStaticShape(transformations).run_on_function(function);
+ return function;
+}
+
+std::shared_ptr<const ngraph::Function> reference(
+ const ngraph::element::Type_t& dataType,
+ const ngraph::element::Type_t& idxType,
+ const SplitTestCase& splitSetup) const {
+ const auto data = std::make_shared<ngraph::opset5::Parameter>(dataType, splitSetup.dataShape);
+ const auto axisScalar = ngraph::opset5::Constant::create(idxType, {}, std::vector<int64_t>{splitSetup.axis});
+ const auto axisVec = ngraph::opset5::Constant::create(idxType, {1}, std::vector<int64_t>{splitSetup.axis});
+
+ const auto dims = std::make_shared<ngraph::opset5::Parameter>(ngraph::element::i64, ngraph::Shape{splitSetup.dataShape.size()});
+
+ const auto dsr = std::make_shared<ngraph::vpu::op::DynamicShapeResolver>(data, dims);
+ const auto node = std::make_shared<ngraph::opset5::Split>(dsr, axisScalar, splitSetup.numSplits);
+
+ const auto dimToSplitBy = std::make_shared<ngraph::opset5::Gather>(dims,
+ axisVec,
+ ngraph::opset5::Constant::create(dims->get_element_type(), {1}, {0}));
+ const auto splittedDim = std::make_shared<ngraph::opset5::Divide>(dimToSplitBy,
+ ngraph::opset5::Constant::create(dims->get_element_type(), {1}, {splitSetup.numSplits}));
+ const auto newShape = std::make_shared<ngraph::opset5::ScatterElementsUpdate>(dims,
+ axisVec,
+ splittedDim,
+ ngraph::opset5::Constant::create(dims->get_element_type(), {1}, {0}));
+
+ ngraph::NodeVector results;
+ for (size_t i = 0; i < node->get_output_size(); i++) {
+ results.push_back(std::make_shared<ngraph::vpu::op::DynamicShapeResolver>(node->output(i), newShape));
+ }
+
+ // tests are capable to compare functions with one result only
+ const auto testsWa = std::make_shared<ngraph::opset5::Concat>(results, splitSetup.axis);
+
+ return std::make_shared<ngraph::Function>(
+ testsWa,
+ ngraph::ParameterVector{data, dims},
+ "Expected");
+}
+};
+
+TEST_P(DynamicToStaticShapeSplit, CompareFunctions) {
+}
+
+INSTANTIATE_TEST_CASE_P(smoke_NGraph, DynamicToStaticShapeSplit, combinations);
+
+} // namespace
--- /dev/null
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include "dsr_tests_common.hpp"
+
+namespace {
+
+using namespace LayerTestsUtils::vpu;
+
+struct SplitTestCase {
+ DataShapeWithUpperBound dataShapes;
+ int64_t axis, numSplits;
+};
+
+const auto combinations = testing::Combine(
+ testing::Values(
+ ngraph::element::f16),
+ testing::Values(
+ ngraph::element::i32),
+ testing::Values(
+ SplitTestCase{{{6, 12, 10}, {6, 12, 15}}, 1, 3},
+ SplitTestCase{{{6, 12, 10}, {9, 12, 10}}, 1, 3},
+ SplitTestCase{{{6, 12}, {10, 12}}, 1, 4},
+ SplitTestCase{{{6, 12, 10, 24}, {6, 12, 10, 50}}, 0, 6},
+ SplitTestCase{{{6, 12, 10, 24}, {6, 12, 10, 50}}, -3, 2},
+ SplitTestCase{{{1, 128, 4}, {1, 256, 4}}, 2, 4}),
+ testing::Values(CommonTestUtils::DEVICE_MYRIAD));
+
+
+using Parameters = std::tuple<
+ DataType,
+ DataType,
+ SplitTestCase,
+ LayerTestsUtils::TargetDevice
+>;
+
+class DSR_Split : public testing::WithParamInterface<Parameters>, public DSR_TestsCommon {
+protected:
+ std::shared_ptr<ngraph::Node> createTestedOp() override {
+ const auto& parameters = GetParam();
+ const auto& dataType = std::get<0>(parameters);
+ const auto& idxType = std::get<1>(parameters);
+ const auto& splitSetup = std::get<2>(parameters);
+ targetDevice = std::get<3>(parameters);
+
+ const auto inputSubgraph = createInputSubgraphWithDSR(dataType, splitSetup.dataShapes);
+
+ const auto axis = ngraph::opset5::Constant::create(idxType, {}, {splitSetup.axis});
+
+ return std::make_shared<ngraph::opset5::Split>(inputSubgraph, axis, splitSetup.numSplits);
+ }
+};
+
+TEST_P(DSR_Split, CompareWithReference) {
+ Run();
+}
+
+INSTANTIATE_TEST_CASE_P(smoke_DynamicSplit, DSR_Split, combinations);
+
+} // namespace
template<class T>
void Compare(const T *expected, const T *actual, std::size_t size, T threshold) {
- std::cout << std::endl;
for (std::size_t i = 0; i < size; ++i) {
const auto &ref = expected[i];
const auto &res = actual[i];