diff options
Diffstat (limited to 'compiler/luci/pass/src/CircleOptimizer.cpp')
-rw-r--r-- | compiler/luci/pass/src/CircleOptimizer.cpp | 148 |
1 files changed, 105 insertions, 43 deletions
diff --git a/compiler/luci/pass/src/CircleOptimizer.cpp b/compiler/luci/pass/src/CircleOptimizer.cpp index cc9fe481c..bddad34fa 100644 --- a/compiler/luci/pass/src/CircleOptimizer.cpp +++ b/compiler/luci/pass/src/CircleOptimizer.cpp @@ -16,16 +16,28 @@ #include "luci/CircleOptimizer.h" +#include "luci/Pass/ConvertNCHWToNHWCPass.h" +#include "luci/Pass/FoldAddV2Pass.h" +#include "luci/Pass/FoldCastPass.h" #include "luci/Pass/FoldDequantizePass.h" +#include "luci/Pass/FoldSparseToDensePass.h" +#include "luci/Pass/ForwardReshapeToUnaryOpPass.h" #include "luci/Pass/FuseActivationFunctionPass.h" #include "luci/Pass/FuseAddWithTConvPass.h" -#include "luci/Pass/FuseBatchNormWithTConv.h" +#include "luci/Pass/FuseBatchNormWithConvPass.h" +#include "luci/Pass/FuseBatchNormWithDwConvPass.h" +#include "luci/Pass/FuseBatchNormWithTConvPass.h" #include "luci/Pass/FuseBCQPass.h" #include "luci/Pass/FuseInstanceNormPass.h" #include "luci/Pass/FusePreActivationBatchNormPass.h" #include "luci/Pass/MakeBatchNormGammaPositivePass.h" #include "luci/Pass/PropagateQuantParamPass.h" +#include "luci/Pass/RemoveRedundantReshapePass.h" #include "luci/Pass/RemoveRedundantTransposePass.h" +#include "luci/Pass/RemoveUnnecessaryReshapePass.h" +#include "luci/Pass/RemoveUnnecessarySlicePass.h" +#include "luci/Pass/RemoveUnnecessaryStridedSlicePass.h" +#include "luci/Pass/RemoveUnnecessarySplitPass.h" #include "luci/Pass/ReplaceMulAddWithDepthwiseConvPass.h" #include "luci/Pass/ResolveCustomOpAddPass.h" #include "luci/Pass/ResolveCustomOpBatchMatMulPass.h" @@ -36,21 +48,22 @@ #include "luci/Pass/SparsifyTensorPass.h" #include "luci/Pass/ShuffleWeightTo16x1Float32Pass.h" #include "luci/Pass/SubstitutePackToReshapePass.h" +#include "luci/Pass/SubstituteSqueezeToReshapePass.h" +#include "luci/Pass/SubstituteTransposeToReshapePass.h" +#include "luci/Pass/TransformMinMaxToRelu6Pass.h" // TODO add more passes -#include "luci/Pass/ShapeInferencePass.h" -#include "luci/Pass/ShapeSignatureInferencePass.h" -#include "luci/Pass/TypeInferencePass.h" - -// Following passes will be removed after refactoring is finished -#include "luci/Pass/MigrateLegacyShapeDtypePass.h" +#include "luci/Pass/CircleShapeInferencePass.h" +#include "luci/Pass/CircleTypeInferencePass.h" // logo passes #include <logo/RemoveDeadNodeWithQueryPass.h> #include "ModulePhase.h" #include "ProgressReporter.h" -#include "CircleOptimizerUtils.h" +#include "helpers/Strings.h" + +#include "QuantizedModelVerifier.h" #include <luci/IR/CircleNodes.h> #include <logo/Phase.h> @@ -61,20 +74,6 @@ namespace { -std::vector<int> parseIntFromCommadelimitedStr(std::string str) -{ - std::vector<int> ret; - std::istringstream is(str); - for (uint32_t i; is >> i;) - { - assert(i != ','); - ret.push_back(i); - if (is.peek() == ',') - is.ignore(); - } - return ret; -} - using namespace luci; class OptimizeOptionsImpl final : public luci::CircleOptimizer::Options @@ -138,13 +137,9 @@ void CircleOptimizer::optimize(luci::Module *m) const { luci::Phase phase; - // Following passes will be deprecated after refactoring is finished. - phase.emplace_back(std::make_unique<luci::MigrateLegacyShapeDtypePass>()); - // Following passes are needed everytime when other passes create new node or modify some nodes. - phase.emplace_back(std::make_unique<luci::ShapeInferencePass>()); - phase.emplace_back(std::make_unique<luci::ShapeSignatureInferencePass>()); - phase.emplace_back(std::make_unique<luci::TypeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleShapeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleTypeInferencePass>()); if (_options->query(Options::Algorithm::FuseBCQ)) { @@ -164,13 +159,9 @@ void CircleOptimizer::optimize(loco::Graph *g) const /* TRANSFORM DECLARATION BEGIN */ phase.emplace_back(std::make_unique<logo::RemoveDeadNodeWithQueryPass>()); - // Following passes will be deprecated after refactoring is finished. - phase.emplace_back(std::make_unique<luci::MigrateLegacyShapeDtypePass>()); - // Following passes are needed everytime when other passes create new node or modify some nodes. - phase.emplace_back(std::make_unique<luci::TypeInferencePass>()); - phase.emplace_back(std::make_unique<luci::ShapeInferencePass>()); - phase.emplace_back(std::make_unique<luci::ShapeSignatureInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleShapeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleTypeInferencePass>()); if (_options->query(Options::Algorithm::ResolveCustomOpAdd)) { @@ -188,6 +179,14 @@ void CircleOptimizer::optimize(loco::Graph *g) const { phase.emplace_back(std::make_unique<FuseInstanceNormPass>()); } + if (_options->query(Options::Algorithm::FuseBatchNormWithConv)) + { + phase.emplace_back(std::make_unique<FuseBatchNormWithConvPass>()); + } + if (_options->query(Options::Algorithm::FuseBatchNormWithDwConv)) + { + phase.emplace_back(std::make_unique<FuseBatchNormWithDwConvPass>()); + } if (_options->query(Options::Algorithm::FuseBatchNormWithTConv)) { phase.emplace_back(std::make_unique<FuseBatchNormWithTConvPass>()); @@ -200,10 +199,26 @@ void CircleOptimizer::optimize(loco::Graph *g) const { phase.emplace_back(std::make_unique<FuseActivationFunctionPass>()); } + if (_options->query(Options::Algorithm::FoldAddV2)) + { + phase.emplace_back(std::make_unique<luci::FoldAddV2Pass>()); + } + if (_options->query(Options::Algorithm::FoldCast)) + { + phase.emplace_back(std::make_unique<luci::FoldCastPass>()); + } if (_options->query(Options::Algorithm::FoldDequantize)) { phase.emplace_back(std::make_unique<luci::FoldDequantizePass>()); } + if (_options->query(Options::Algorithm::FoldSparseToDense)) + { + phase.emplace_back(std::make_unique<luci::FoldSparseToDensePass>()); + } + if (_options->query(Options::Algorithm::ForwardReshapeToUnaryOp)) + { + phase.emplace_back(std::make_unique<luci::ForwardReshapeToUnaryOpPass>()); + } if (_options->query(Options::Algorithm::FusePreActivationBatchNorm)) { phase.emplace_back(std::make_unique<luci::FusePreActivationBatchNormPass>()); @@ -216,6 +231,26 @@ void CircleOptimizer::optimize(loco::Graph *g) const { phase.emplace_back(std::make_unique<luci::ShuffleWeightTo16x1Float32Pass>()); } + if (_options->query(Options::Algorithm::RemoveUnnecessaryReshape)) + { + phase.emplace_back(std::make_unique<luci::RemoveUnnecessaryReshapePass>()); + } + if (_options->query(Options::Algorithm::RemoveUnnecessarySlice)) + { + phase.emplace_back(std::make_unique<luci::RemoveUnnecessarySlicePass>()); + } + if (_options->query(Options::Algorithm::RemoveUnnecessaryStridedSlice)) + { + phase.emplace_back(std::make_unique<luci::RemoveUnnecessaryStridedSlicePass>()); + } + if (_options->query(Options::Algorithm::RemoveUnnecessarySplit)) + { + phase.emplace_back(std::make_unique<luci::RemoveUnnecessarySplitPass>()); + } + if (_options->query(Options::Algorithm::RemoveRedundantReshape)) + { + phase.emplace_back(std::make_unique<luci::RemoveRedundantReshapePass>()); + } if (_options->query(Options::Algorithm::RemoveRedundantTranspose)) { phase.emplace_back(std::make_unique<luci::RemoveRedundantTransposePass>()); @@ -228,6 +263,28 @@ void CircleOptimizer::optimize(loco::Graph *g) const { phase.emplace_back(std::make_unique<luci::SubstitutePackToReshapePass>()); } + if (_options->query(Options::Algorithm::SubstituteSqueezeToReshape)) + { + phase.emplace_back(std::make_unique<luci::SubstituteSqueezeToReshapePass>()); + } + if (_options->query(Options::Algorithm::SubstituteTransposeToReshape)) + { + phase.emplace_back(std::make_unique<luci::SubstituteTransposeToReshapePass>()); + } + if (_options->query(Options::Algorithm::TransformMinMaxToRelu6Pass)) + { + phase.emplace_back(std::make_unique<luci::TransformMinMaxToRelu6Pass>()); + } + if (_options->query(Options::Algorithm::ConvertNCHWToNHWC)) + { + bool preserve_input = + _options->param(Options::AlgorithmParameters::NCHW_to_NHWC_preserve_input_shape) == "true"; + bool preserve_output = + _options->param(Options::AlgorithmParameters::NCHW_to_NHWC_preserve_output_shape) == "true"; + + phase.emplace_back( + std::make_unique<luci::ConvertNCHWToNHWCPass>(preserve_input, preserve_output)); + } /* TRANSFORM DECLARATION END */ @@ -275,7 +332,7 @@ void CircleOptimizer::quantize(loco::Graph *g) const } luci::QuantizeDequantizeWeightsPass fake_quantizer( - str_to_dtype(input_dtype), str_to_dtype(output_dtype), str_to_granularity(granularity)); + str_to_dtype(input_dtype), str_to_dtype(output_dtype), str_to_granularity(granularity)); fake_quantizer.run(g); } @@ -315,14 +372,19 @@ void CircleOptimizer::quantize(loco::Graph *g) const phase.emplace_back(std::make_unique<luci::PropagateQuantParamPass>()); - phase.emplace_back(std::make_unique<luci::ShapeInferencePass>()); - phase.emplace_back(std::make_unique<luci::TypeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleShapeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleTypeInferencePass>()); phase.emplace_back(std::make_unique<logo::RemoveDeadNodeWithQueryPass>()); ProgressReporter prog(g, logo::PhaseStrategy::Saturate); logo::PhaseRunner<logo::PhaseStrategy::Saturate> phase_runner{g}; phase_runner.attach(&prog); phase_runner.run(phase); + + // Verify the type/granularity of the quantized model + luci::QuantizedModelVerifier verifier(str_to_dtype(output_dtype), + str_to_granularity(granularity)); + verifier.verify(g); } // Requantize @@ -349,8 +411,8 @@ void CircleOptimizer::quantize(loco::Graph *g) const logo::Phase phase; // Do Shape/Type inference - phase.emplace_back(std::make_unique<luci::ShapeInferencePass>()); - phase.emplace_back(std::make_unique<luci::TypeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleShapeInferencePass>()); + phase.emplace_back(std::make_unique<luci::CircleTypeInferencePass>()); ProgressReporter prog(g, logo::PhaseStrategy::Saturate); logo::PhaseRunner<logo::PhaseStrategy::Saturate> phase_runner{g}; @@ -364,13 +426,13 @@ void CircleOptimizer::sparsify(loco::Graph *g) const { std::string tensor_name = _options->param(Options::AlgorithmParameters::Sparsify_tensor_name); std::string str_tarversal_order = - _options->param(Options::AlgorithmParameters::Sparsify_traversal_order); + _options->param(Options::AlgorithmParameters::Sparsify_traversal_order); std::string str_format = _options->param(Options::AlgorithmParameters::Sparsify_format); std::string str_block_size = _options->param(Options::AlgorithmParameters::Sparsify_block_size); std::string str_block_map = _options->param(Options::AlgorithmParameters::Sparsify_block_map); // traversal order - std::vector<int32_t> traversal_order = parseIntFromCommadelimitedStr(str_tarversal_order); + std::vector<int32_t> traversal_order = csv_to_vector<int32_t>(str_tarversal_order); // format std::vector<DimensionType> format; std::istringstream is(str_format); @@ -385,9 +447,9 @@ void CircleOptimizer::sparsify(loco::Graph *g) const is.ignore(); } // block size - std::vector<int32_t> block_size = parseIntFromCommadelimitedStr(str_block_size); + std::vector<int32_t> block_size = csv_to_vector<int32_t>(str_block_size); // block map - std::vector<int32_t> block_map = parseIntFromCommadelimitedStr(str_block_map); + std::vector<int32_t> block_map = csv_to_vector<int32_t>(str_block_map); luci::SparsifyTensorPass sparsifier{tensor_name, traversal_order, format, block_size, block_map}; |