#include <luci/ImporterEx.h>
#include <luci/CircleOptimizer.h>
+#include <luci/DynamicBatchToSingleBatch.h>
#include <luci/Service/ChangeOutputs.h>
#include <luci/Service/Validate.h>
#include <luci/CircleExporter.h>
add_switch(arser, "--fuse_preactivation_batchnorm",
"This will fuse BatchNorm operators of pre-activations to Convolution operator");
add_switch(arser, "--fuse_prelu", "This will fuse operators to PReLU operator");
+ add_switch(arser, "--fuse_gelu", "This will fuse operators to GeLU operator");
add_switch(arser, "--remove_duplicate_const", "This will remove all duplicate constant nodes");
add_switch(arser, "--remove_fakequant", "This will remove FakeQuant operators");
add_switch(arser, "--remove_quantdequant", "This will remove Quantize-Dequantize sequence");
"Transform Minimum(6)-Maximum(0) pattern to Relu6 operator");
add_switch(arser, "--transform_min_relu_to_relu6",
"Transform Minimum(6)-Relu pattern to Relu6 operator");
+ add_switch(arser, "--decompose_hardswish",
+ "Decompose HardSwish operator to Add, Mul and Relu6 operators");
add_switch(arser, "--mute_warnings", "This will turn off warning messages");
add_switch(arser, "--disable_validation",
"This will turn off operator validations. May help input model investigation.");
add_switch(arser, "--generate_profile_data", "This will turn on profiling data generation.");
+ // Convert dynamic batch to single batch
+ // Users have to use this option only when the first dimension of rank 4 input (NHWC or NCHW)
+ // is dynamic. Remove this comment after non-rank 4 is supported.
+ add_switch(arser, "--dynamic_batch_to_single_batch",
+ "Convert dynamic batch size (first dimension) of inputs to 1.");
+
arser.add_argument("--change_outputs")
.help("Experimental: Change first subgraph output nodes to CSV names");
options->enable(Algorithms::FusePreActivationBatchNorm);
if (arser.get<bool>("--fuse_prelu"))
options->enable(Algorithms::FusePRelu);
+ if (arser.get<bool>("--fuse_gelu"))
+ options->enable(Algorithms::FuseGelu);
if (arser.get<bool>("--fuse_transpose_with_mean"))
options->enable(Algorithms::FuseTransposeWithMean);
if (arser.get<bool>("--remove_duplicate_const"))
options->enable(Algorithms::TransformMinMaxToRelu6Pass);
if (arser.get<bool>("--transform_min_relu_to_relu6"))
options->enable(Algorithms::TransformMinReluToRelu6Pass);
+ if (arser.get<bool>("--decompose_hardswish"))
+ options->enable(Algorithms::DecomposeHardSwishPass);
if (arser.get<bool>("--expand_broadcast_const"))
options->enable(Algorithms::ExpandBroadcastConst);
if (arser.get<bool>("--unroll_unidirseqlstm"))
csv_tokenize(csv_nodes, new_outputs);
}
+ bool dynamic_batch_to_single_batch = false;
+ if (arser.get<bool>("--dynamic_batch_to_single_batch"))
+ {
+ dynamic_batch_to_single_batch = true;
+ }
+
// Import from input Circle file
luci::ImporterEx importerex;
auto module = importerex.importVerifyModule(input_path);
if (module.get() == nullptr)
return EXIT_FAILURE;
+ // Convert dynamic batch to single batch
+ // Why here? It has to be done before 'optimize', because most optimization
+ // passes are written based on static shapes
+ if (dynamic_batch_to_single_batch)
+ {
+ luci::dynamic_batch_to_single_batch(module.get());
+
+ if (!luci::validate_shape(module.get()))
+ {
+ if (settings->get(luci::UserSettings::Key::DisableValidation))
+ std::cerr
+ << "WARNING: Invalid shape detected after converting dynamic batch to single batch"
+ << std::endl;
+ else
+ {
+ std::cerr << "ERROR: Invalid shape detected after converting dynamic batch to single batch"
+ << std::endl;
+ return 255;
+ }
+ }
+ }
+
if (change_outputs)
{
auto graph = module->graph(0);