From 2693ed2c29937a51d14044e0c3fd26faf0a327e1 Mon Sep 17 00:00:00 2001 From: seongwoo chae Date: Tue, 10 Sep 2024 22:12:35 +0900 Subject: [PATCH] [fme-apply] Remove unused passes (#13975) This commit removes unused passes. ONE-DCO-1.0-Signed-off-by: seongwoo --- compiler/fme-apply/src/FMEqualizer.cpp | 10 - .../src/pass/ForwardPreScalePass.cpp | 95 ----- .../fme-apply/src/pass/ForwardPreScalePass.h | 53 --- .../src/pass/ForwardPreScalePass.test.cpp | 179 --------- .../src/pass/ForwardPreShiftPass.cpp | 75 ---- .../fme-apply/src/pass/ForwardPreShiftPass.h | 53 --- .../src/pass/ForwardPreShiftPass.test.cpp | 111 ------ .../fme-apply/src/pass/FusePostShiftPass.cpp | 239 ------------ .../fme-apply/src/pass/FusePostShiftPass.h | 59 --- .../src/pass/FusePostShiftPass.test.cpp | 346 ------------------ .../fme-apply/src/pass/FusePreShiftPass.cpp | 76 ---- .../fme-apply/src/pass/FusePreShiftPass.h | 56 --- .../src/pass/FusePreShiftPass.test.cpp | 129 ------- 13 files changed, 1481 deletions(-) delete mode 100644 compiler/fme-apply/src/pass/ForwardPreScalePass.cpp delete mode 100644 compiler/fme-apply/src/pass/ForwardPreScalePass.h delete mode 100644 compiler/fme-apply/src/pass/ForwardPreScalePass.test.cpp delete mode 100644 compiler/fme-apply/src/pass/ForwardPreShiftPass.cpp delete mode 100644 compiler/fme-apply/src/pass/ForwardPreShiftPass.h delete mode 100644 compiler/fme-apply/src/pass/ForwardPreShiftPass.test.cpp delete mode 100644 compiler/fme-apply/src/pass/FusePostShiftPass.cpp delete mode 100644 compiler/fme-apply/src/pass/FusePostShiftPass.h delete mode 100644 compiler/fme-apply/src/pass/FusePostShiftPass.test.cpp delete mode 100644 compiler/fme-apply/src/pass/FusePreShiftPass.cpp delete mode 100644 compiler/fme-apply/src/pass/FusePreShiftPass.h delete mode 100644 compiler/fme-apply/src/pass/FusePreShiftPass.test.cpp diff --git a/compiler/fme-apply/src/FMEqualizer.cpp b/compiler/fme-apply/src/FMEqualizer.cpp index 3d8ca2b0fb8..a8be34592a5 100644 --- a/compiler/fme-apply/src/FMEqualizer.cpp +++ b/compiler/fme-apply/src/FMEqualizer.cpp @@ -17,12 +17,8 @@ #include "FMEqualizer.h" #include "InsertScaleShift.h" #include "EqualizePatternCheck.h" -#include "pass/ForwardPreScalePass.h" -#include "pass/ForwardPreShiftPass.h" #include "pass/FusePostScalePass.h" -#include "pass/FusePostShiftPass.h" #include "pass/FusePreScalePass.h" -#include "pass/FusePreShiftPass.h" #include "ProgressReporter.h" #include @@ -82,15 +78,9 @@ void FMEqualizer::equalize(loco::Graph *g, const std::vector &p phase.emplace_back(std::make_unique()); phase.emplace_back(std::make_unique()); - // Forward PreScale/PreShift - phase.emplace_back(std::make_unique()); - phase.emplace_back(std::make_unique()); - // Fuse Pre/Post Scale/Shift phase.emplace_back(std::make_unique()); phase.emplace_back(std::make_unique()); - phase.emplace_back(std::make_unique()); - phase.emplace_back(std::make_unique()); ProgressReporter prog(g, logo::PhaseStrategy::Restart); logo::PhaseRunner phase_runner{g}; diff --git a/compiler/fme-apply/src/pass/ForwardPreScalePass.cpp b/compiler/fme-apply/src/pass/ForwardPreScalePass.cpp deleted file mode 100644 index c9324bc6b7a..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreScalePass.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ForwardPreScalePass.h" -#include "Support.Cast.h" -#include "Support.Misc.h" - -#include -#include - -using namespace fme_apply; - -namespace -{ - -class ForwardPreScale final : public luci::CircleNodeMutableVisitor -{ -protected: - bool visit(luci::CircleNode *node) { return false; } - - bool visit(luci::CirclePad *node) - { - auto pre_scale = to_pre_scale(node->input()); - if (not pre_scale) - return false; - - if (loco::succs(pre_scale).size() != 1) - return false; - - node->input(pre_scale->inputs(0)); - loco::replace(node).with(pre_scale); - pre_scale->inputs(0, node); - - // Shape should be copied, because - // shape inference does not work well for Custom Op (PreScale) - copy_shape(node, pre_scale); - - return true; - } - - bool visit(luci::CircleSlice *node) - { - auto pre_scale = to_pre_scale(node->input()); - if (not pre_scale) - return false; - - if (loco::succs(pre_scale).size() != 1) - return false; - - node->input(pre_scale->inputs(0)); - loco::replace(node).with(pre_scale); - pre_scale->inputs(0, node); - - // Shape should be copied, because - // shape inference does not work well for Custom Op (PreScale) - copy_shape(node, pre_scale); - - return true; - } -}; - -} // namespace - -namespace fme_apply -{ - -bool ForwardPreScalePass::run(loco::Graph *g) -{ - bool changed = false; - - ForwardPreScale fps; - for (auto node : loco::active_nodes(loco::output_nodes(g))) - { - auto cnode = loco::must_cast(node); - if (cnode->accept(&fps)) - changed = true; - } - - return changed; -} - -} // namespace fme_apply diff --git a/compiler/fme-apply/src/pass/ForwardPreScalePass.h b/compiler/fme-apply/src/pass/ForwardPreScalePass.h deleted file mode 100644 index bb3819669ba..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreScalePass.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FME_APPLY_FORWARD_PRE_SCALE_PASS_H__ -#define __FME_APPLY_FORWARD_PRE_SCALE_PASS_H__ - -#include - -#include - -namespace fme_apply -{ - -/** - * @brief Pass to forward CircleCustom(PreScale) to succeeding Op - * - * BEFORE - * - * CircleCustom(PreScale) - * | - * Forwardable Op (ex: Pad, Slice) - * - * AFTER - * - * Forwardable Op (ex: Pad, Slice) - * | - * CircleCustom(PreScale) - */ -class ForwardPreScalePass : public logo::Pass -{ -public: - virtual const char *name(void) const { return "fme_apply::ForwardPreScalePass"; } - -public: - bool run(loco::Graph *graph); -}; - -} // namespace fme_apply - -#endif //__FME_APPLY_FORWARD_PRE_SCALE_PASS_H__ diff --git a/compiler/fme-apply/src/pass/ForwardPreScalePass.test.cpp b/compiler/fme-apply/src/pass/ForwardPreScalePass.test.cpp deleted file mode 100644 index e6e064b1a28..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreScalePass.test.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ForwardPreScalePass.h" -#include "Support.Cast.h" - -#include - -#include - -using namespace fme_apply; - -namespace -{ - -/** - * PreScale-Pad graphlet - * - * [PreScale] - * | - * [Pad] - * - */ -class PreScalePadGraphlet -{ -public: - void init(loco::Graph *g) - { - _prescale = g->nodes()->create(2 /* arity */, 1 /* out */); - _prescale->dtype(loco::DataType::FLOAT32); - _prescale->shape({1, 4, 4, 16}); - _prescale->custom_code("PreScale"); - _prescale->name("prescale"); - - _pad = g->nodes()->create(); - _pad->input(_prescale); - _pad->dtype(loco::DataType::FLOAT32); - _pad->shape({1, 5, 5, 16}); - _pad->name("pad"); - } - -public: - luci::CircleCustom *_prescale = nullptr; - luci::CirclePad *_pad = nullptr; -}; - -class PreScalePadGraph : public luci::test::TestIOGraph, public PreScalePadGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 16}, {1, 5, 5, 16}); - PreScalePadGraphlet::init(g()); - - _prescale->inputs(0, input()); - - output()->from(_pad); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -/** - * PreScale-Slice graphlet - * - * [PreScale] - * | - * [Slice] - * - */ -class PreScaleSliceGraphlet -{ -public: - void init(loco::Graph *g) - { - _prescale = g->nodes()->create(2 /* arity */, 1 /* out */); - _prescale->dtype(loco::DataType::FLOAT32); - _prescale->shape({1, 4, 4, 16}); - _prescale->custom_code("PreScale"); - _prescale->name("prescale"); - - _slice = g->nodes()->create(); - _slice->input(_prescale); - _slice->dtype(loco::DataType::FLOAT32); - _slice->shape({1, 2, 2, 16}); - _slice->name("slice"); - } - -public: - luci::CircleCustom *_prescale = nullptr; - luci::CircleSlice *_slice = nullptr; -}; - -class PreScaleSliceGraph : public luci::test::TestIOGraph, public PreScaleSliceGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 16}, {1, 2, 2, 16}); - PreScaleSliceGraphlet::init(g()); - - _prescale->inputs(0, input()); - - output()->from(_slice); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -} // namespace - -TEST(ForwardPreScalePassTest, prescale_pad) -{ - PreScalePadGraph g; - g.init(); - - ForwardPreScalePass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto pre = to_pre_scale(g.output()->from()); - EXPECT_NE(nullptr, pre); - - auto pad = dynamic_cast(pre->inputs(0)); - EXPECT_NE(nullptr, pad); - - EXPECT_EQ(4, pre->rank()); - EXPECT_EQ(1, pre->dim(0).value()); - EXPECT_EQ(5, pre->dim(1).value()); - EXPECT_EQ(5, pre->dim(2).value()); - EXPECT_EQ(16, pre->dim(3).value()); -} - -TEST(ForwardPreScalePassTest, prescale_slice) -{ - PreScaleSliceGraph g; - g.init(); - - ForwardPreScalePass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto pre = to_pre_scale(g.output()->from()); - EXPECT_NE(nullptr, pre); - - auto slice = dynamic_cast(pre->inputs(0)); - EXPECT_NE(nullptr, slice); - - EXPECT_EQ(4, pre->rank()); - EXPECT_EQ(1, pre->dim(0).value()); - EXPECT_EQ(2, pre->dim(1).value()); - EXPECT_EQ(2, pre->dim(2).value()); - EXPECT_EQ(16, pre->dim(3).value()); -} - -TEST(ForwardPreScalePassTest, prescale_conv_NEG) -{ - PreScalePadGraph g; - g.init(); - - // Replace Pad with Conv2D - auto conv = g.g()->nodes()->create(); - conv->input(g._prescale); - g.output()->from(conv); - - ForwardPreScalePass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -} diff --git a/compiler/fme-apply/src/pass/ForwardPreShiftPass.cpp b/compiler/fme-apply/src/pass/ForwardPreShiftPass.cpp deleted file mode 100644 index 20357de8383..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreShiftPass.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ForwardPreShiftPass.h" -#include "Support.Cast.h" -#include "Support.Misc.h" - -#include -#include - -using namespace fme_apply; - -namespace -{ - -class ForwardPreShift final : public luci::CircleNodeMutableVisitor -{ -protected: - bool visit(luci::CircleNode *node) { return false; } - - bool visit(luci::CircleSlice *node) - { - auto pre_shift = to_pre_shift(node->input()); - if (not pre_shift) - return false; - - if (loco::succs(pre_shift).size() != 1) - return false; - - node->input(pre_shift->inputs(0)); - loco::replace(node).with(pre_shift); - pre_shift->inputs(0, node); - - // Shape should be copied, because - // shape inference does not work well for Custom Op (PreShift) - copy_shape(node, pre_shift); - - return true; - } -}; - -} // namespace - -namespace fme_apply -{ - -bool ForwardPreShiftPass::run(loco::Graph *g) -{ - bool changed = false; - - ForwardPreShift fps; - for (auto node : loco::active_nodes(loco::output_nodes(g))) - { - auto cnode = loco::must_cast(node); - if (cnode->accept(&fps)) - changed = true; - } - - return changed; -} - -} // namespace fme_apply diff --git a/compiler/fme-apply/src/pass/ForwardPreShiftPass.h b/compiler/fme-apply/src/pass/ForwardPreShiftPass.h deleted file mode 100644 index dbc70933842..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreShiftPass.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FME_APPLY_FORWARD_PRE_SHIFT_PASS_H__ -#define __FME_APPLY_FORWARD_PRE_SHIFT_PASS_H__ - -#include - -#include - -namespace fme_apply -{ - -/** - * @brief Pass to forward CircleCustom(PreShift) to succeeding Op - * - * BEFORE - * - * CircleCustom(PreShift) - * | - * Forwardable Op (ex: Slice) - * - * AFTER - * - * Forwardable Op (ex: Slice) - * | - * CircleCustom(PreShift) - */ -class ForwardPreShiftPass : public logo::Pass -{ -public: - virtual const char *name(void) const { return "fme_apply::ForwardPreShiftPass"; } - -public: - bool run(loco::Graph *graph); -}; - -} // namespace fme_apply - -#endif //__FME_APPLY_FORWARD_PRE_SHIFT_PASS_H__ diff --git a/compiler/fme-apply/src/pass/ForwardPreShiftPass.test.cpp b/compiler/fme-apply/src/pass/ForwardPreShiftPass.test.cpp deleted file mode 100644 index 2fdcf90ad9a..00000000000 --- a/compiler/fme-apply/src/pass/ForwardPreShiftPass.test.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ForwardPreShiftPass.h" -#include "Support.Cast.h" - -#include - -#include - -using namespace fme_apply; - -namespace -{ - -/** - * PreShift-Slice graphlet - * - * [PreShift] - * | - * [Slice] - * - */ -class PreShiftSliceGraphlet -{ -public: - void init(loco::Graph *g) - { - _preshift = g->nodes()->create(2 /* arity */, 1 /* out */); - _preshift->dtype(loco::DataType::FLOAT32); - _preshift->shape({1, 4, 4, 16}); - _preshift->custom_code("PreShift"); - _preshift->name("preshift"); - - _slice = g->nodes()->create(); - _slice->input(_preshift); - _slice->dtype(loco::DataType::FLOAT32); - _slice->shape({1, 2, 2, 16}); - _slice->name("slice"); - } - -public: - luci::CircleCustom *_preshift = nullptr; - luci::CircleSlice *_slice = nullptr; -}; - -class PreShiftSliceGraph : public luci::test::TestIOGraph, public PreShiftSliceGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 16}, {1, 2, 2, 16}); - PreShiftSliceGraphlet::init(g()); - - _preshift->inputs(0, input()); - - output()->from(_slice); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -} // namespace - -TEST(ForwardPreShiftPassTest, preshift_slice) -{ - PreShiftSliceGraph g; - g.init(); - - ForwardPreShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto pre = to_pre_shift(g.output()->from()); - EXPECT_NE(nullptr, pre); - - auto slice = dynamic_cast(pre->inputs(0)); - EXPECT_NE(nullptr, slice); - - EXPECT_EQ(4, pre->rank()); - EXPECT_EQ(1, pre->dim(0).value()); - EXPECT_EQ(2, pre->dim(1).value()); - EXPECT_EQ(2, pre->dim(2).value()); - EXPECT_EQ(16, pre->dim(3).value()); -} - -TEST(ForwardPreShiftPassTest, preshift_conv_NEG) -{ - PreShiftSliceGraph g; - g.init(); - - // Replace Pad with Conv2D - auto conv = g.g()->nodes()->create(); - conv->input(g._preshift); - g.output()->from(conv); - - ForwardPreShiftPass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -} diff --git a/compiler/fme-apply/src/pass/FusePostShiftPass.cpp b/compiler/fme-apply/src/pass/FusePostShiftPass.cpp deleted file mode 100644 index 744fede9ae2..00000000000 --- a/compiler/fme-apply/src/pass/FusePostShiftPass.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "FusePostShiftPass.h" -#include "Support.Cast.h" -#include "RandomString.h" - -#include -#include -#include -#include -#include - -using namespace fme_apply; - -namespace -{ - -// Fuse Op + CircleCustom(PostShift) -struct FusePostShift final : public luci::CircleNodeMutableVisitor -{ - bool visit(luci::CircleNode *) { return false; } - - bool visit(luci::CircleConv2D *node) - { - if (node->fusedActivationFunction() != luci::FusedActFunc::NONE) - return false; - - bool changed = false; - for (auto succ : loco::succs(node)) - { - auto post_shift = to_post_shift(succ); - if (not post_shift) - continue; - - auto param = - loco::must_cast(post_shift->inputs(1)); // FIX_PostShift_UNLESS - auto bias = dynamic_cast(node->bias()); - if (not bias) - continue; - - uint32_t channel_size = bias->size(); - if (channel_size != param->size()) - { - assert(false); // FIX_PostScale_Unless - return false; - } - - auto cloned_conv = luci::clone_node(node, node->graph()); - assert(cloned_conv != nullptr); // FIX_CALLER_UNLESS - auto fused_conv = loco::must_cast(cloned_conv); - auto fused_bias = luci::clone(bias); - - fused_conv->name(node->name() + "_" + random_str()); - fused_bias->name(bias->name() + "_" + random_str()); - - add_origin(fused_conv, luci::get_origin(node)); - add_origin(fused_bias, luci::get_origin(bias)); - - // Add param to bias - for (uint32_t c = 0; c < channel_size; ++c) - { - float shift = param->at(c); - fused_bias->at(c) = - fused_bias->at(c) + shift; - } - - fused_conv->input(node->input()); - fused_conv->filter(node->filter()); - fused_conv->bias(fused_bias); - - loco::replace(post_shift).with(fused_conv); - changed = true; - } - - return changed; - } - - bool visit(luci::CircleDepthwiseConv2D *node) - { - if (node->fusedActivationFunction() != luci::FusedActFunc::NONE) - return false; - - bool changed = false; - for (auto succ : loco::succs(node)) - { - auto post_shift = to_post_shift(succ); - if (not post_shift) - continue; - - auto param = - loco::must_cast(post_shift->inputs(1)); // FIX_PostShift_UNLESS - auto bias = dynamic_cast(node->bias()); - if (not bias) - continue; - - uint32_t channel_size = bias->size(); - if (channel_size != param->size()) - { - assert(false); // FIX_PostScale_Unless - return false; - } - - auto cloned_dconv = luci::clone_node(node, node->graph()); - assert(cloned_dconv != nullptr); // FIX_CALLER_UNLESS - auto fused_dconv = loco::must_cast(cloned_dconv); - auto fused_bias = luci::clone(bias); - - fused_dconv->name(node->name() + "_" + random_str()); - fused_bias->name(bias->name() + "_" + random_str()); - - add_origin(fused_dconv, luci::get_origin(node)); - add_origin(fused_bias, luci::get_origin(bias)); - - // Add param to bias - for (uint32_t c = 0; c < channel_size; ++c) - { - float shift = param->at(c); - fused_bias->at(c) = - fused_bias->at(c) + shift; - } - - fused_dconv->input(node->input()); - fused_dconv->filter(node->filter()); - fused_dconv->bias(fused_bias); - - loco::replace(post_shift).with(fused_dconv); - changed = true; - } - - return changed; - } - - bool visit(luci::CircleTransposeConv *node) - { - bool changed = false; - for (auto succ : loco::succs(node)) - { - auto post_shift = to_post_shift(succ); - if (not post_shift) - continue; - - auto param = - loco::must_cast(post_shift->inputs(1)); // FIX_PostShift_UNLESS - - // TConv has bias. Update bias. - if (auto bias = dynamic_cast(node->bias())) - { - uint32_t channel_size = bias->size(); - if (channel_size != param->size()) - { - assert(false); // FIX_PostScale_Unless - return false; - } - - auto cloned_tconv = luci::clone_node(node, node->graph()); - assert(cloned_tconv != nullptr); // FIX_CALLER_UNLESS - auto fused_tconv = loco::must_cast(cloned_tconv); - auto fused_bias = luci::clone(bias); - - fused_tconv->name(node->name() + "_" + random_str()); - fused_bias->name(bias->name() + "_" + random_str()); - - add_origin(fused_tconv, luci::get_origin(node)); - add_origin(fused_bias, luci::get_origin(bias)); - - // Add param to bias - for (uint32_t c = 0; c < channel_size; ++c) - { - float shift = param->at(c); - fused_bias->at(c) = - fused_bias->at(c) + shift; - } - - fused_tconv->inputSizes(node->inputSizes()); - fused_tconv->outBackprop(node->outBackprop()); - fused_tconv->filter(node->filter()); - fused_tconv->bias(fused_bias); - - loco::replace(post_shift).with(fused_tconv); - changed = true; - continue; - } - - // TConv has no bias. Just use param - if (auto bias = dynamic_cast(node->bias())) - { - auto cloned_tconv = luci::clone_node(node, node->graph()); - assert(cloned_tconv != nullptr); // FIX_CALLER_UNLESS - auto fused_tconv = loco::must_cast(cloned_tconv); - - fused_tconv->inputSizes(node->inputSizes()); - fused_tconv->outBackprop(node->outBackprop()); - fused_tconv->filter(node->filter()); - fused_tconv->bias(param); - - loco::replace(post_shift).with(fused_tconv); - changed = true; - continue; - } - } - - return changed; - } -}; - -} // namespace - -namespace fme_apply -{ - -bool FusePostShiftPass::run(loco::Graph *g) -{ - bool changed = false; - for (auto node : loco::postorder_traversal(loco::output_nodes(g))) - { - FusePostShift fps; - auto cnode = loco::must_cast(node); - if (cnode->accept(&fps)) - changed = true; - } - - return changed; -} - -} // namespace fme_apply diff --git a/compiler/fme-apply/src/pass/FusePostShiftPass.h b/compiler/fme-apply/src/pass/FusePostShiftPass.h deleted file mode 100644 index 37c0b74a246..00000000000 --- a/compiler/fme-apply/src/pass/FusePostShiftPass.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FME_APPLY_FUSE_POST_SHIFT_PASS_H__ -#define __FME_APPLY_FUSE_POST_SHIFT_PASS_H__ - -#include - -#include - -namespace fme_apply -{ - -/** - * @brief Pass to fuse CircleCustom(PostShift) to preceding Ops - * - * BEFORE - * - * [Node1] - * | - * [Op] - * / \ - * [PostShift] [Node2] - * - * AFTER - * - * [Node1] - * / \ - * [Op'] [Op] - * | - * [Node2] - * - * NOTE Op' is clone of Op with updated bias. - */ -class FusePostShiftPass : public logo::Pass -{ -public: - virtual const char *name(void) const { return "fme::FusePostShiftPass"; } - -public: - bool run(loco::Graph *graph); -}; - -} // namespace fme_apply - -#endif //__FME_APPLY_FUSE_POST_SHIFT_PASS_H__ diff --git a/compiler/fme-apply/src/pass/FusePostShiftPass.test.cpp b/compiler/fme-apply/src/pass/FusePostShiftPass.test.cpp deleted file mode 100644 index f379623bb49..00000000000 --- a/compiler/fme-apply/src/pass/FusePostShiftPass.test.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "FusePostShiftPass.h" -#include "Support.Cast.h" - -#include - -#include - -using namespace fme_apply; - -namespace -{ - -luci::CircleConst *create_const_node(loco::Graph *g, const loco::DataType dtype, - const std::vector &shape, - const std::vector &values) -{ - auto node = g->nodes()->create(); - node->dtype(dtype); - node->rank(shape.size()); - - uint32_t size = 1; - for (uint32_t i = 0; i < shape.size(); ++i) - { - node->dim(i) = shape[i]; - size *= shape[i]; - } - node->shape_status(luci::ShapeStatus::VALID); - - assert(values.size() == size); // FIX_CALLER_UNLESS - - node->size(size); - for (uint32_t i = 0; i < values.size(); ++i) - node->at(i) = values[i]; - - return node; -} - -/** - * PostShift-Conv graphlet - * - * [Conv] - * | - * [PostShift] - * - */ -class PostShiftConvGraphlet -{ -public: - void init(loco::Graph *g) - { - std::vector filter_val(3 * 3 * 3 * 3 /* size */, 1.0 /*value */); - - _conv = g->nodes()->create(); - _conv->filter( - create_const_node(g, loco::DataType::FLOAT32, {3, 3, 3, 3} /* shape */, filter_val)); - _conv->bias( - create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value*/)); - _conv->fusedActivationFunction(luci::FusedActFunc::NONE); - _conv->dtype(loco::DataType::FLOAT32); - _conv->shape({1, 4, 4, 3}); - _conv->padding(luci::Padding::SAME); - _conv->name("conv"); - - _postshift = g->nodes()->create(2 /* arity */, 1 /* out */); - _postshift->dtype(loco::DataType::FLOAT32); - _postshift->inputs(0, _conv); - _postshift->inputs( - 1, create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value */)); - _postshift->shape({1, 4, 4, 3}); - _postshift->custom_code("PostShift"); - _postshift->name("postshift"); - } - -public: - luci::CircleCustom *_postshift = nullptr; - luci::CircleConv2D *_conv = nullptr; -}; - -class PostShiftConvGraph : public luci::test::TestIOGraph, public PostShiftConvGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 3}, {1, 4, 4, 3}); - PostShiftConvGraphlet::init(g()); - - _conv->input(input()); - - output()->from(_postshift); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -/** - * PostShift-DConv graphlet - * - * [DConv] - * | - * [PostShift] - * - */ -class PostShiftDConvGraphlet -{ -public: - void init(loco::Graph *g) - { - std::vector filter_val(1 * 3 * 3 * 3 /* size */, 1.0 /*value */); - - _dconv = g->nodes()->create(); - _dconv->filter( - create_const_node(g, loco::DataType::FLOAT32, {1, 3, 3, 3} /* shape */, filter_val)); - _dconv->bias( - create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value*/)); - _dconv->fusedActivationFunction(luci::FusedActFunc::NONE); - _dconv->dtype(loco::DataType::FLOAT32); - _dconv->shape({1, 4, 4, 3}); - _dconv->padding(luci::Padding::SAME); - _dconv->name("dconv"); - - _postshift = g->nodes()->create(2 /* arity */, 1 /* out */); - _postshift->dtype(loco::DataType::FLOAT32); - _postshift->inputs(0, _dconv); - _postshift->inputs( - 1, create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value */)); - _postshift->shape({1, 4, 4, 3}); - _postshift->custom_code("PostShift"); - _postshift->name("postshift"); - } - -public: - luci::CircleCustom *_postshift = nullptr; - luci::CircleDepthwiseConv2D *_dconv = nullptr; -}; - -class PostShiftDConvGraph : public luci::test::TestIOGraph, public PostShiftDConvGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 3}, {1, 4, 4, 3}); - PostShiftDConvGraphlet::init(g()); - - _dconv->input(input()); - - output()->from(_postshift); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -/** - * PostShift-TConv graphlet - * - * [TConv] - * | - * [PostShift] - * - */ -class PostShiftTConvGraphlet -{ -public: - void init(loco::Graph *g) - { - std::vector filter_val(1 * 3 * 3 * 3 /* size */, 1.0 /*value */); - - _tconv = g->nodes()->create(); - _tconv->filter( - create_const_node(g, loco::DataType::FLOAT32, {1, 3, 3, 3} /* shape */, filter_val)); - _tconv->bias( - create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value*/)); - _tconv->dtype(loco::DataType::FLOAT32); - _tconv->shape({1, 4, 4, 3}); - _tconv->padding(luci::Padding::SAME); - _tconv->name("dconv"); - - _postshift = g->nodes()->create(2 /* arity */, 1 /* out */); - _postshift->dtype(loco::DataType::FLOAT32); - _postshift->inputs(0, _tconv); - _postshift->inputs( - 1, create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value */)); - _postshift->shape({1, 4, 4, 3}); - _postshift->custom_code("PostShift"); - _postshift->name("postshift"); - } - -public: - luci::CircleCustom *_postshift = nullptr; - luci::CircleTransposeConv *_tconv = nullptr; -}; - -class PostShiftTConvGraph : public luci::test::TestIOGraph, public PostShiftTConvGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 3}, {1, 4, 4, 3}); - PostShiftTConvGraphlet::init(g()); - - _tconv->outBackprop(input()); - - output()->from(_postshift); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -} // namespace - -TEST(FusePostShiftPassTest, postshift_conv) -{ - PostShiftConvGraph g; - g.init(); - - FusePostShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto conv = dynamic_cast(g.output()->from()); - EXPECT_NE(nullptr, conv); - - // Check bias - auto b = dynamic_cast(conv->bias()); - EXPECT_NE(nullptr, b); - EXPECT_EQ(loco::DataType::FLOAT32, b->dtype()); - EXPECT_EQ(3, b->size()); - for (uint32_t i = 0; i < 3; i++) - { - EXPECT_FLOAT_EQ(4.0, b->at(i)); - } -} - -TEST(FusePostShiftPassTest, postshift_conv_NEG) -{ - PostShiftConvGraph g; - g.init(); - g._conv->fusedActivationFunction(luci::FusedActFunc::RELU6); - - FusePostShiftPass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -} - -TEST(FusePostShiftPassTest, postshift_dconv) -{ - PostShiftDConvGraph g; - g.init(); - - FusePostShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto dconv = dynamic_cast(g.output()->from()); - EXPECT_NE(nullptr, dconv); - - // Check bias - auto b = dynamic_cast(dconv->bias()); - EXPECT_NE(nullptr, b); - EXPECT_EQ(loco::DataType::FLOAT32, b->dtype()); - EXPECT_EQ(3, b->size()); - for (uint32_t i = 0; i < 3; i++) - { - EXPECT_FLOAT_EQ(4.0, b->at(i)); - } -} - -TEST(FusePostShiftPassTest, postshift_dconv_NEG) -{ - PostShiftDConvGraph g; - g.init(); - g._dconv->fusedActivationFunction(luci::FusedActFunc::RELU6); - - FusePostShiftPass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -} - -TEST(FusePostShiftPassTest, postshift_tconv) -{ - PostShiftTConvGraph g; - g.init(); - - FusePostShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto tconv = dynamic_cast(g.output()->from()); - EXPECT_NE(nullptr, tconv); - - // Check bias - auto b = dynamic_cast(tconv->bias()); - EXPECT_NE(nullptr, b); - EXPECT_EQ(loco::DataType::FLOAT32, b->dtype()); - EXPECT_EQ(3, b->size()); - for (uint32_t i = 0; i < 3; i++) - { - EXPECT_FLOAT_EQ(4.0, b->at(i)); - } -} - -TEST(FusePostShiftPassTest, postshift_tconv_nobias) -{ - PostShiftTConvGraph g; - g.init(); - - auto no_bias = g.g()->nodes()->create(); - g._tconv->bias(no_bias); - - FusePostShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto tconv = dynamic_cast(g.output()->from()); - EXPECT_NE(nullptr, tconv); - - // Check bias - auto b = dynamic_cast(tconv->bias()); - EXPECT_NE(nullptr, b); - EXPECT_EQ(loco::DataType::FLOAT32, b->dtype()); - EXPECT_EQ(3, b->size()); - for (uint32_t i = 0; i < 3; i++) - { - EXPECT_FLOAT_EQ(2.0, b->at(i)); - } -} - -TEST(FusePostShiftPassTest, postshift_tconv_NEG) -{ - PostShiftTConvGraph g; - g.init(); - g._postshift->inputs(0, g.input()); - g.output()->from(g._tconv); - - FusePostShiftPass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -} diff --git a/compiler/fme-apply/src/pass/FusePreShiftPass.cpp b/compiler/fme-apply/src/pass/FusePreShiftPass.cpp deleted file mode 100644 index 19cd9eb7e01..00000000000 --- a/compiler/fme-apply/src/pass/FusePreShiftPass.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "FusePreShiftPass.h" -#include "Support.Cast.h" - -#include -#include -#include -#include -#include - -using namespace fme_apply; - -namespace -{ - -// Fuse CircleCustom(PreShift) + Op -struct FusePreShift final : public luci::CircleNodeMutableVisitor -{ - bool visit(luci::CircleNode *) { return false; } - - bool visit(luci::CircleInstanceNorm *node) - { - auto pre_shift = to_pre_shift(node->input()); - if (not pre_shift) - return false; - - auto param = loco::must_cast(pre_shift->inputs(1)); // FIX_PreScale_UNLESS - auto channel = node->dim(node->rank() - 1).value(); - if (channel != param->size()) - { - assert(false); // FIX_PreShift_Unless - return false; - } - - // Output of InstanceNorm is not affected by PreShift - node->input(pre_shift->inputs(0)); - - return true; - } -}; - -} // namespace - -namespace fme_apply -{ - -bool FusePreShiftPass::run(loco::Graph *g) -{ - bool changed = false; - for (auto node : loco::postorder_traversal(loco::output_nodes(g))) - { - FusePreShift fps; - auto cnode = loco::must_cast(node); - if (cnode->accept(&fps)) - changed = true; - } - - return changed; -} - -} // namespace fme_apply diff --git a/compiler/fme-apply/src/pass/FusePreShiftPass.h b/compiler/fme-apply/src/pass/FusePreShiftPass.h deleted file mode 100644 index 31e3a4c0c98..00000000000 --- a/compiler/fme-apply/src/pass/FusePreShiftPass.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FME_APPLY_FUSE_PRE_SHIFT_PASS_H__ -#define __FME_APPLY_FUSE_PRE_SHIFT_PASS_H__ - -#include - -#include - -namespace fme_apply -{ - -/** - * @brief Pass to fuse CircleCustom(PreShift) to succeeding Ops - * - * BEFORE - * - * [Node] - * | - * [PreShift] - * | - * [Op] - * - * AFTER - * - * [Node] - * | - * [Op'] - * - */ -class FusePreShiftPass : public logo::Pass -{ -public: - virtual const char *name(void) const { return "fme::FusePreShiftPass"; } - -public: - bool run(loco::Graph *graph); -}; - -} // namespace fme_apply - -#endif //__FME_APPLY_FUSE_PRE_SHIFT_PASS_H__ diff --git a/compiler/fme-apply/src/pass/FusePreShiftPass.test.cpp b/compiler/fme-apply/src/pass/FusePreShiftPass.test.cpp deleted file mode 100644 index f74f49c1cd8..00000000000 --- a/compiler/fme-apply/src/pass/FusePreShiftPass.test.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "FusePreShiftPass.h" -#include "Support.Cast.h" - -#include - -#include - -using namespace fme_apply; - -namespace -{ - -luci::CircleConst *create_const_node(loco::Graph *g, const loco::DataType dtype, - const std::vector &shape, - const std::vector &values) -{ - auto node = g->nodes()->create(); - node->dtype(dtype); - node->rank(shape.size()); - - uint32_t size = 1; - for (uint32_t i = 0; i < shape.size(); ++i) - { - node->dim(i) = shape[i]; - size *= shape[i]; - } - node->shape_status(luci::ShapeStatus::VALID); - - assert(values.size() == size); // FIX_CALLER_UNLESS - - node->size(size); - for (uint32_t i = 0; i < values.size(); ++i) - node->at(i) = values[i]; - - return node; -} - -/** - * PreShift-Instnorm graphlet - * - * [PreShift] - * | - * [Instnorm] - * - */ -class PreShiftInstnormGraphlet -{ -public: - void init(loco::Graph *g) - { - _preshift = g->nodes()->create(2 /* arity */, 1 /* out */); - _preshift->dtype(loco::DataType::FLOAT32); - _preshift->inputs( - 1, create_const_node(g, loco::DataType::FLOAT32, {3} /* shape */, {2, 2, 2} /* value */)); - _preshift->shape({1, 4, 4, 3}); - _preshift->custom_code("PreShift"); - _preshift->name("prescale"); - - _instnorm = g->nodes()->create(); - _instnorm->input(_preshift); - _instnorm->fusedActivationFunction(luci::FusedActFunc::NONE); - _instnorm->dtype(loco::DataType::FLOAT32); - _instnorm->shape({1, 4, 4, 3}); - _instnorm->name("instnorm"); - } - -public: - luci::CircleCustom *_preshift = nullptr; - luci::CircleInstanceNorm *_instnorm = nullptr; -}; - -class PreShiftInstnormGraph : public luci::test::TestIOGraph, public PreShiftInstnormGraphlet -{ -public: - void init(void) - { - luci::test::TestIOGraph::init({1, 4, 4, 3}, {1, 4, 4, 3}); - PreShiftInstnormGraphlet::init(g()); - - _preshift->inputs(0, input()); - - output()->from(_instnorm); - } - - std::unique_ptr graph(void) { return std::move(_g); } -}; - -} // namespace - -TEST(FusePreShiftPassTest, preshift_instnorm) -{ - PreShiftInstnormGraph g; - g.init(); - - FusePreShiftPass fpsp; - EXPECT_TRUE(fpsp.run(g.g())); - - auto instnorm = dynamic_cast(g.output()->from()); - EXPECT_NE(nullptr, instnorm); - - auto pre_shift = to_pre_shift(instnorm->input()); - EXPECT_EQ(nullptr, pre_shift); // No pre_shift -} - -TEST(FusePreShiftPassTest, preshift_instnorm_NEG) -{ - PreShiftInstnormGraph g; - g.init(); - g._instnorm->input(g.input()); - - FusePreShiftPass fpsp; - EXPECT_FALSE(fpsp.run(g.g())); -}