[IE][VPU]: Decompose Swish to Sigmoid + Prod (#2107)
authorRoman Vyunov (Intel) <roman.vyunov@intel.com>
Tue, 8 Sep 2020 08:52:05 +0000 (11:52 +0300)
committerGitHub <noreply@github.com>
Tue, 8 Sep 2020 08:52:05 +0000 (11:52 +0300)
* Workaround to decompose Swish to Sigmoid + Multiply

inference-engine/src/vpu/graph_transformer/include/vpu/middleend/pass_manager.hpp
inference-engine/src/vpu/graph_transformer/include/vpu/stage_builder.hpp
inference-engine/src/vpu/graph_transformer/src/middleend/pass_manager.cpp
inference-engine/src/vpu/graph_transformer/src/middleend/passes/decompose_swish.cpp [new file with mode: 0644]
inference-engine/src/vpu/graph_transformer/src/stages/eltwise.cpp
inference-engine/src/vpu/graph_transformer/src/stages/sigmoid.cpp

index 9eff84e..658ea62 100644 (file)
@@ -93,6 +93,7 @@ public:
     // Model common adaptation
     //
 
+    Pass::Ptr decomposeSwish();
     Pass::Ptr eliminateConstConcat();
     Pass::Ptr splitGroupedConv();
     Pass::Ptr splitConv3DInto2D();
index abd68f0..cb3e57f 100644 (file)
@@ -297,6 +297,21 @@ public:
         const std::string& name,
         const DataVector& inputs,
         const DataVector& outputs);
+
+    Stage addSigmoidStage(
+            const Model& model,
+            const std::string& name,
+            const ie::CNNLayerPtr& layer,
+            const DataVector& inputs,
+            const DataVector& outputs);
+
+    Stage addProdStage(
+            const Model& model,
+            const std::string& name,
+            const ie::CNNLayerPtr& layer,
+            const Data& input0,
+            const Data& input1,
+            const Data& output);
 };
 
 }  // namespace vpu
index 9130b66..ce0a645 100644 (file)
@@ -88,6 +88,12 @@ PassSet::Ptr PassManager::buildMiddleEnd() {
     ADD_DUMP_PASS("initial");
 
     //
+    // Decompose swish layer to Sigmoid + Multiply
+    //
+    ADD_PASS(decomposeSwish);
+    ADD_DUMP_PASS("decomposeSwish");
+
+    //
     // Convert shape notation
     //
     ADD_PASS(convertShapeNotation);
diff --git a/inference-engine/src/vpu/graph_transformer/src/middleend/passes/decompose_swish.cpp b/inference-engine/src/vpu/graph_transformer/src/middleend/passes/decompose_swish.cpp
new file mode 100644 (file)
index 0000000..f5c84d0
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2018-2020 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include <vpu/middleend/pass_manager.hpp>
+
+namespace vpu {
+
+namespace {
+
+class PassImpl final : public Pass {
+public:
+    explicit PassImpl(const StageBuilder::Ptr& stageBuilder) :
+            _stageBuilder(stageBuilder) {
+    }
+
+    void run(const Model& model) override;
+
+private:
+    StageBuilder::Ptr _stageBuilder;
+};
+
+void PassImpl::run(const Model& model) {
+    VPU_PROFILE(decomposeSwish);
+
+    for (const auto& swish : model->getStages()) {
+        if (swish->type() != StageType::Swish) {
+            continue;
+        }
+        const auto inputData = swish->input(0);
+        const auto outputData = swish->output(0);
+        const auto name = swish->name();
+        const auto& layer = swish->origLayer();
+
+        model->removeStage(swish);
+
+        const auto sigmoidOutput = model->addNewData(inputData->name() + "@sigmoid", inputData->desc());
+
+        _stageBuilder->addSigmoidStage(
+                model,
+                name + "@sigmoid",
+                layer,
+                {inputData},
+                {sigmoidOutput});
+        _stageBuilder->addProdStage(
+                model,
+                name + "@prod",
+                layer,
+                inputData,
+                sigmoidOutput,
+                outputData);
+    }
+}
+
+}  // namespace
+
+Pass::Ptr PassManager::decomposeSwish() {
+    return std::make_shared<PassImpl>(_stageBuilder);
+}
+
+}  // namespace vpu
index 0657063..b59e16d 100644 (file)
@@ -350,6 +350,22 @@ Stage StageBuilder::addSumStage(
         {output});
 }
 
+Stage StageBuilder::addProdStage(
+        const Model& model,
+        const std::string& name,
+        const ie::CNNLayerPtr& layer,
+        const Data& input0,
+        const Data& input1,
+        const Data& output) {
+    const Data& fakeInput2 = model->addFakeData();
+    return model->addNewStage<EltwiseStage>(
+            name,
+            StageType::Prod,
+            layer,
+            {input0, input1, fakeInput2},
+            {output});
+}
+
 Stage StageBuilder::addMaxStage(
         const Model& model,
         const std::string& name,
index bf3df84..c044230 100644 (file)
@@ -33,7 +33,16 @@ void FrontEnd::parseSigmoid(const Model& model, const ie::CNNLayerPtr& layer, co
     IE_ASSERT(inputs.size() == 1);
     IE_ASSERT(outputs.size() == 1);
 
-    model->addNewStage<SigmoidStage>(layer->name, StageType::Sigmoid, layer, inputs, outputs);
+    _stageBuilder->addSigmoidStage(model, layer->name, layer, inputs, outputs);
+}
+
+Stage StageBuilder::addSigmoidStage(
+        const Model& model,
+        const std::string& name,
+        const ie::CNNLayerPtr& layer,
+        const DataVector& inputs,
+        const DataVector& outputs) {
+    return model->addNewStage<SigmoidStage>(name, StageType::Sigmoid, layer, inputs, outputs);
 }
 
 }  // namespace vpu