From: Aleksandr Korolev Date: Thu, 29 Oct 2020 12:12:10 +0000 (+0300) Subject: [IE][VPU][TESTS] Fix vpu split with unusable outputs & test (#2718) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=04b7822761c6676283c310fb2a24d1525a6239be;p=platform%2Fupstream%2Fdldt.git [IE][VPU][TESTS] Fix vpu split with unusable outputs & test (#2718) * Fix vpu split with unusable outputs & test Co-authored-by: kora6 --- diff --git a/inference-engine/src/vpu/graph_transformer/src/stages/split.cpp b/inference-engine/src/vpu/graph_transformer/src/stages/split.cpp index 4c11b82..60f8e5d 100644 --- a/inference-engine/src/vpu/graph_transformer/src/stages/split.cpp +++ b/inference-engine/src/vpu/graph_transformer/src/stages/split.cpp @@ -153,14 +153,44 @@ Stage StageBuilder::addSplitStage( const DataVector& outputs) { std::vector offsets; offsets.reserve(outputs.size()); - DimValues curOffset({{axis, 0}}); - for (const auto& output : outputs) { - offsets.emplace_back(curOffset); - curOffset.set(axis, curOffset[axis] + output->desc().dim(axis)); + + const auto haveUnusedOutput = [](const DataVector& outputs) { + return std::any_of(outputs.begin(), outputs.end(), [](const vpu::Data& out) { + return out == nullptr; + }); + }; + + std::vector outAxisSizes; + if (haveUnusedOutput(outputs)) { + VPU_THROW_UNLESS(layer != nullptr, + "Can't build split stage whith name {} with unused outputs when layer == nullptr", name); + const auto outDimsSize = layer->outData[0]->getDims().size(); + const int idx = dimToIeInd(axis, outDimsSize); + outAxisSizes.reserve(outDimsSize); + for (const auto& out : layer->outData) { + VPU_THROW_UNLESS(idx <= out->getDims().size(), + "Split stage with name {} and type {} can't have idx = {} when out dimensions size = {}", + layer->name, layer->type, idx, out->getDims().size()); + outAxisSizes.push_back(out->getDims()[idx]); + } + } else { + outAxisSizes.reserve(outputs.size()); + for (const auto& output : outputs) { + outAxisSizes.push_back(output->desc().dim(axis)); + } + } + + vpu::DataVector usedOutputs; + for (int i = 0; i < outputs.size(); ++i) { + if (outputs[i] != nullptr) { + offsets.emplace_back(curOffset); + usedOutputs.push_back(outputs[i]); + } + curOffset.set(axis, curOffset[axis] + outAxisSizes[i]); } - auto stage = addSplitStage(model, name, layer, std::move(offsets), input, outputs); + auto stage = addSplitStage(model, name, layer, std::move(offsets), input, usedOutputs); stage->attrs().set("axis", axis); diff --git a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp index 6cfd995..8ec930e 100644 --- a/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/myriad/shared_tests_instances/single_layer_tests/split.cpp @@ -27,8 +27,27 @@ INSTANTIATE_TEST_CASE_P(smoke_NumSplitsCheck, SplitLayerTest, ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), ::testing::Values(InferenceEngine::Layout::ANY), ::testing::Values(InferenceEngine::Layout::ANY), - ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({30, 30, 30, 30})), ::testing::Values(CommonTestUtils::DEVICE_MYRIAD)), SplitLayerTest::getTestCaseName); +INSTANTIATE_TEST_CASE_P(smoke_splitWithUnusedOutputsTest, splitWithUnusedOutputsTest, + ::testing::Combine( + ::testing::Values(5), + // TODO: 0-axis excluded + // Check (status == ie::StatusCode::OK) failed: Failed to reshape Network: + // Failed to infer shapes for Split layer (Split_2) with error: + // The sum of the dimensions on the axis(0) is not equal out_sizes: [30] + ::testing::Values(1, 2, 3), + ::testing::ValuesIn(netPrecisions), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Precision::UNSPECIFIED), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(InferenceEngine::Layout::ANY), + ::testing::Values(std::vector({30, 30, 30, 30})), + ::testing::Values(std::vector({0, 2}), + std::vector({0, 4}), + std::vector({2, 3})), + ::testing::Values(CommonTestUtils::DEVICE_MYRIAD)), + splitWithUnusedOutputsTest::getTestCaseName); } // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp index cd427be..65f0d4a 100644 --- a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/split.hpp @@ -35,4 +35,26 @@ protected: void SetUp() override; }; -} // namespace LayerTestsDefinitions \ No newline at end of file +typedef std::tuple< + size_t, // Num splits + size_t, // Axis + InferenceEngine::Precision, // Net precision + InferenceEngine::Precision, // Input precision + InferenceEngine::Precision, // Output precision + InferenceEngine::Layout, // Input layout + InferenceEngine::Layout, // Output layout + std::vector, // Input shapes + std::vector, // Used outputs indices + std::string // Target device name +> splitWithUnusedOutputsParams; + +class splitWithUnusedOutputsTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(testing::TestParamInfo obj); + +protected: + void SetUp() override; +}; + +} // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp index 325ebe7..0add873 100644 --- a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/split.cpp @@ -66,4 +66,52 @@ TEST_P(SplitLayerTest, CompareWithRefs) { Run(); }; -} // namespace LayerTestsDefinitions \ No newline at end of file +std::string splitWithUnusedOutputsTest::getTestCaseName(testing::TestParamInfo obj) { + size_t numSplits, axis; + InferenceEngine::Precision netPrecision; + InferenceEngine::Precision inPrc, outPrc; + InferenceEngine::Layout inLayout, outLayout; + InferenceEngine::SizeVector inputShapes; + std::vector outIndices; + std::string targetDevice; + std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShapes, outIndices, targetDevice) = obj.param; + std::ostringstream result; + result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_"; + result << "numSplits=" << numSplits << "_"; + result << "axis=" << axis << "_"; + result << "outIndices" << CommonTestUtils::vec2str(outIndices) << "_"; + result << "IS"; + result << "netPRC=" << netPrecision.name() << "_"; + result << "inPRC=" << inPrc.name() << "_"; + result << "outPRC=" << outPrc.name() << "_"; + result << "inL=" << inLayout << "_"; + result << "outL=" << outLayout << "_"; + result << "trgDev=" << targetDevice; + return result.str(); +} + +void splitWithUnusedOutputsTest::SetUp() { + SetRefMode(LayerTestsUtils::RefMode::CONSTANT_FOLDING); + size_t axis, numSplits; + std::vector inputShape; + InferenceEngine::Precision netPrecision; + std::vector outIndices; + std::tie(numSplits, axis, netPrecision, inPrc, outPrc, inLayout, outLayout, inputShape, outIndices, targetDevice) = this->GetParam(); + auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision); + auto params = ngraph::builder::makeParams(ngPrc, {inputShape}); + auto paramOuts = ngraph::helpers::convert2OutputVector( + ngraph::helpers::castOps2Nodes(params)); + auto split = std::dynamic_pointer_cast(ngraph::builder::makeSplit(paramOuts[0], + ngPrc, numSplits, axis)); + ngraph::ResultVector results; + for (int i = 0; i < outIndices.size(); i++) { + results.push_back(std::make_shared(split->output(outIndices[i]))); + } + function = std::make_shared(results, params, "split"); +} + +TEST_P(splitWithUnusedOutputsTest, CompareWithRefs) { + Run(); +}; + +} // namespace LayerTestsDefinitions