[GNA] fixed case when input connected to concat from left and const from right (...
authorAndrey Dmitriev <andrey.dmitriev@intel.com>
Tue, 10 Nov 2020 13:37:03 +0000 (16:37 +0300)
committerGitHub <noreply@github.com>
Tue, 10 Nov 2020 13:37:03 +0000 (16:37 +0300)
* Added test

* Added fix

* Fix comment

* Fix conflict

inference-engine/src/gna_plugin/gna_graph_compiler.cpp
inference-engine/src/gna_plugin/gna_graph_compiler.hpp
inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/first_connect_input_concat.cpp [new file with mode: 0644]
inference-engine/tests/functional/plugin/shared/include/subgraph_tests/first_connect_input_concat.hpp [new file with mode: 0644]
inference-engine/tests/functional/plugin/shared/src/subgraph_tests/first_connect_input_concat.cpp [new file with mode: 0644]

index 256489b..d3b522d 100644 (file)
@@ -797,22 +797,16 @@ void GNAGraphCompiler::ConcatPrimitive(InferenceEngine::CNNLayerPtr layer) {
         // auto layerInfo = LayerInfo(getCreatorLayer(concatLayerInput->insData[it].lock()).lock());
         if (layerInfo.isInput()) {
             auto & bytesAllocated = inputDesc->bytes_allocated_for_input[((InferenceEngine::CNNLayerPtr)layerInfo)->name];
-            if (concatLayerInfo.input_allocated) {
-                // for concat input allocated only once, so lets mark this specific input layer also as allocated
-                // we will bind it to offset further in connectInput
-                // size need to be equal to full layer in order to pass checks
-                bytesAllocated = concatLayerInfo.reserved_size;
-            }
 
             connectInput(layer, &concatLayerInfo.gna_ptr,
-                         concatLayerInfo.reserved_size, -static_cast<int32_t>(inputLayer.offset), idx);
+                         concatLayerInfo.reserved_size, inputLayer.offset, idx, false);
 
             // TODO: currently connectInput api accept only total size, for concat we need extension for allocated, and actual sizes
             bytesAllocated = inputLayer.tensorSize;
 
             concatLayerInfo.input_allocated = true;
         } else if (layerInfo.isMemory()) {
-            connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, -static_cast<int>(inputLayer.offset), idx);
+            connectInput(layer, &concatLayerInfo.gna_ptr, concatLayerInfo.reserved_size, inputLayer.offset, idx, false);
 
             concatLayerInfo.input_allocated = true;
         }
@@ -2021,7 +2015,7 @@ void GNAGraphCompiler::connectOutput(InferenceEngine::CNNLayerPtr layer, void *p
     }
 }
 
-GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, void *ptr, size_t num_data_bytes_in, int32_t offset, int idx) {
+GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer, void *ptr, size_t num_data_bytes_in, int32_t offset, int idx, bool connectTo) {
     // selecting particular input layers
     // auto prevLayer = CNNNetPrevLayer(layer, idx);
     auto prevLayer = CNNNetPrevLayerSkipCertain(layer, idx, [](CNNLayerPtr l) {
@@ -2041,7 +2035,7 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
             }
 
             // real allocation pointer will be kept in ptr not in ptr_inputs_global
-            if (offset < 0) {
+            if (!connectTo) {
                 gnamem->push_value(ptr,
                                    static_cast<uint8_t>(0),
                                    num_data_bytes_in,
@@ -2062,20 +2056,20 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
                     << ", and size_requested=" << num_data_bytes_in;
         }
 
-        if (offset >= 0) {
-            gnamem->bind_ptr(ptr, &inputDesc->getPtrInputsGlobal(prevLayer->name).front(), offset);
+        if (connectTo) {
+            gnamem->bind_ptr(ptr, &inputDesc->getPtrInputsGlobal(prevLayer->name).front(), offset, ALIGN(num_data_bytes_in, 64));
         } else {
-            gnamem->bind_ptr(&inputDesc->getPtrInputsGlobal(prevLayer->name).front(), ptr, -offset);
+            gnamem->bind_ptr(&inputDesc->getPtrInputsGlobal(prevLayer->name).front(), ptr, offset, ALIGN(num_data_bytes_in, 64));
         }
 
         return prevLayer;
     }
     // const input
     if (LayerInfo(prevLayer).isConst()) {
-        if (offset >= 0) {
+        if (connectTo) {
             gnamem->bind_ptr(ptr, const_connections[prevLayer->name], offset);
         } else {
-            gnamem->bind_ptr(const_connections[prevLayer->name], ptr, -offset);
+            gnamem->bind_ptr(const_connections[prevLayer->name], ptr, offset);
         }
 
         return prevLayer;
@@ -2146,17 +2140,17 @@ GNAPluginNS::ConnectionDetails GNAGraphCompiler::connectInput(CNNLayerPtr layer,
         if (memoryLayer.reserved_size == 0) {
             auto memorySize = InferenceEngine::details::product(memoryLayer.getDims()) * memoryLayer.elementSizeBytes();
 
-            // negative offset used for  indicate that memory layer should be bound to given buffer
-            if (offset >= 0) {
+            // connectTo used for  indicate that memory layer should be bound to given buffer
+            if (connectTo) {
                 memorySize = std::max(memorySize, num_data_bytes_in);
                 gnamem->reserve_ptr(&memoryLayer.gna_ptr, ALIGN64(memorySize), 64);
                 gnamem->bind_ptr(ptr, &memoryLayer.gna_ptr, offset);
             } else {
-                if (num_data_bytes_in > memorySize - offset) {
+                if (num_data_bytes_in < memorySize + offset) {
                     THROW_GNA_LAYER_EXCEPTION(layer) <<" invalid allocation request of "
-                                                     << num_data_bytes_in << " is more then state tensor size of: " << memorySize;
+                                                     << num_data_bytes_in << " is more then state tensor size of: " << memorySize + offset;
                 }
-                gnamem->bind_ptr(&memoryLayer.gna_ptr, ptr, -offset);
+                gnamem->bind_ptr(&memoryLayer.gna_ptr, ptr, offset);
             }
 
             memoryLayer.reserved_size = ALIGN64(memorySize);
index 9f8e65e..65e4c01 100644 (file)
@@ -84,13 +84,16 @@ public:
      * @param num_data_bytes_in - size
      * @param offset - num bytes to advance in buffer
      * @param idx - index of input port that we are connecting
+     * @param connectTo - connectTo is true is alternative to positive or equal to zero offset
+     * in case when we would like to use zero offset and connect from  pointer set this to negative
      * @return layer used as input
      */
     GNAPluginNS::ConnectionDetails connectInput(InferenceEngine::CNNLayerPtr layer,
                                                 void *pVoid,
                                                 size_t num_data_bytes_in,
                                                 int32_t offset = 0,
-                                                int idx = 0);
+                                                int idx = 0,
+                                                bool connectTo = true);
 
     /**
      * Fill in the Affine layer weights
diff --git a/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/first_connect_input_concat.cpp b/inference-engine/tests/functional/plugin/gna/shared_tests_instances/subgraph_tests/first_connect_input_concat.cpp
new file mode 100644 (file)
index 0000000..d9fa0eb
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include <vector>
+
+#include "subgraph_tests/first_connect_input_concat.hpp"
+#include "common_test_utils/test_constants.hpp"
+
+using namespace LayerTestsDefinitions;
+
+namespace {
+
+std::vector<std::vector<std::vector<size_t>>> inShapes = {
+        {{1, 1288}},
+        {{1, 56}},
+        {{1, 6456}}
+};
+
+const std::vector<InferenceEngine::Precision> netPrecisions = {
+        InferenceEngine::Precision::FP32,
+        InferenceEngine::Precision::FP16,
+};
+
+std::map<std::string, std::string> additional_config = {
+        {"GNA_DEVICE_MODE", "GNA_SW_EXACT"},
+        {"GNA_COMPACT_MODE", "NO"},
+};
+
+INSTANTIATE_TEST_CASE_P(smoke_concat_first_input, ConcatFirstInputTest,
+                        ::testing::Combine(
+                                ::testing::ValuesIn(inShapes),
+                                ::testing::ValuesIn(netPrecisions),
+                                ::testing::Values(CommonTestUtils::DEVICE_GNA),
+                                ::testing::Values(additional_config)),
+                        ConcatFirstInputTest::getTestCaseName);
+
+} //namespace
diff --git a/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/first_connect_input_concat.hpp b/inference-engine/tests/functional/plugin/shared/include/subgraph_tests/first_connect_input_concat.hpp
new file mode 100644 (file)
index 0000000..aeb7356
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#pragma once
+
+#include <tuple>
+#include <vector>
+#include <string>
+#include <memory>
+
+#include <ngraph_functions/builders.hpp>
+#include <functional_test_utils/layer_test_utils.hpp>
+
+typedef std::tuple<
+        std::vector<std::vector<size_t>>,   // Input shapes
+        InferenceEngine::Precision,         // Network Precision
+        std::string,                        // Target Device
+        std::map<std::string, std::string>  // Config
+> concatFirstInputParams;
+
+namespace LayerTestsDefinitions {
+
+class ConcatFirstInputTest : public testing::WithParamInterface<concatFirstInputParams>,
+                             virtual public LayerTestsUtils::LayerTestsCommon {
+public:
+    static std::string getTestCaseName(testing::TestParamInfo<concatFirstInputParams> obj);
+
+protected:
+    void SetUp() override;
+};
+
+}  // namespace LayerTestsDefinitions
diff --git a/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/first_connect_input_concat.cpp b/inference-engine/tests/functional/plugin/shared/src/subgraph_tests/first_connect_input_concat.cpp
new file mode 100644 (file)
index 0000000..01e8fbc
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include <memory>
+#include <tuple>
+#include <vector>
+#include <string>
+
+#include <ie_core.hpp>
+
+#include "common_test_utils/common_utils.hpp"
+#include "functional_test_utils/plugin_cache.hpp"
+#include "functional_test_utils/layer_test_utils.hpp"
+#include "functional_test_utils/blob_utils.hpp"
+
+#include "ngraph_functions/pass/convert_prc.hpp"
+
+#include "subgraph_tests/first_connect_input_concat.hpp"
+
+
+namespace LayerTestsDefinitions {
+
+std::string ConcatFirstInputTest::getTestCaseName(testing::TestParamInfo<concatFirstInputParams> obj) {
+    std::vector<std::vector<size_t>> inputShapes;
+    InferenceEngine::Precision netPrecision;
+    std::string targetDevice;
+    std::map<std::string, std::string> additional_config;
+    std::tie(inputShapes, netPrecision, targetDevice, additional_config) = obj.param;
+
+    std::ostringstream result;
+    result << "IS=" << CommonTestUtils::vec2str(inputShapes) << "_";
+    result << "netPRC=" << netPrecision.name() << "_";
+    result << "targetDevice=" << targetDevice;
+
+    return result.str();
+}
+
+void ConcatFirstInputTest::SetUp() {
+    std::vector<std::vector<size_t>> inputShapes;
+    InferenceEngine::Precision netPrecision;
+    std::map<std::string, std::string> additional_config;
+    std::tie(inputShapes, netPrecision, targetDevice, configuration) = this->GetParam();
+    auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
+    auto params = ngraph::builder::makeParams(ngPrc, inputShapes);
+    auto const_second_param = ngraph::builder::makeConstant(ngPrc, {1, 8}, std::vector<float>{-1.0f});
+    auto concat = std::make_shared<ngraph::opset1::Concat>(ngraph::OutputVector{params[0], const_second_param}, 1);
+    auto relu = std::make_shared<ngraph::opset1::Relu>(concat);
+
+    ngraph::ResultVector results{std::make_shared<ngraph::opset1::Result>(relu)};
+
+    function = std::make_shared<ngraph::Function>(results, params, "ConcatMultiInput");
+}
+
+TEST_P(ConcatFirstInputTest, CompareWithRefImpl) {
+    Run();
+};
+}  // namespace LayerTestsDefinitions