From 35373eb2801612767926c212944afe1f31fe7010 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9C=A4=ED=98=84=EC=8B=9D/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Principal=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Wed, 21 Nov 2018 13:44:45 +0900 Subject: [PATCH] [enco/tfl/frontend] Refactoring RELU activation (#2313) * [enco/tfl/frontend] Refactoring RELU activation RELU activation is commonly used by many operations. So this activation is extracted as a separate method. Signed-off-by: Hyun Sik Yoon * returning ifm * ofm as param * remove empty line * pr fix: remove output param * pr fix : comment, renaming vars, etc. --- contrib/enco/frontend/tflite/src/Frontend.cpp | 95 ++++++++++++++++----------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/contrib/enco/frontend/tflite/src/Frontend.cpp b/contrib/enco/frontend/tflite/src/Frontend.cpp index 00574cc..0da9dad 100644 --- a/contrib/enco/frontend/tflite/src/Frontend.cpp +++ b/contrib/enco/frontend/tflite/src/Frontend.cpp @@ -353,6 +353,60 @@ coco::Padding2D conv2D_padding(const tflite::Conv2DOptions *options, const tenso options->dilation_w_factor(), options->dilation_h_factor()); } +/** + * @brief Add coco::Eval for fused activation. + * This method creates an ofm object, appends Eval(ofm object, RELU(...)) into block, + * and returns ofm object. + */ +coco::FeatureObject *build_activation(tflite::ActivationFunctionType act, coco::Block *block, + coco::FeatureObject *ifm) +{ + assert(ifm != nullptr && ifm->asFeature() != nullptr); // support feature only in this version + + coco::Module *m = block->module(); + + auto shape = ifm->asFeature()->shape(); + + // creates output object + auto output_obj = m->entity()->object()->create(); + auto output_bag = m->entity()->bag()->create(num_elements(shape)); + output_obj->bag(output_bag); + output_obj->layout(coco::FeatureLayouts::BHWC::create(shape)); + + switch (act) + { + case tflite::ActivationFunctionType::ActivationFunctionType_NONE: + { + // Create Copy Instr (copying from ifm to output_obj), + // redundant layer but optimized by backend + auto copy_ins = instr_builder(m).copy(output_obj, ifm); + + // Append the instruction to the block + block->instr()->append(copy_ins); + break; + } + case tflite::ActivationFunctionType::ActivationFunctionType_RELU: + { + // Create Eval(output_obj, Relu(load(ifm))) + auto load_op = op_builder(m).load(ifm).pop(); + auto relu_op = m->entity()->op()->create(); + relu_op->arg(load_op); + + auto eval_ins = instr_builder(m).eval(output_obj, relu_op); + + // Append the instruction to the block + block->instr()->append(eval_ins); + break; + } + default: + // TODO support RELU6, TanH, etc + assert(false); + break; + } + + return output_obj; +} + } // namespace /** @@ -554,45 +608,12 @@ void Conv2DGraphBuilder::build(const tflite::Operator *op, GraphBuilderContext * last_obj = btmp_obj; } - // fused activation for RELU - switch (conv_params->fused_activation_function()) - { - case tflite::ActivationFunctionType::ActivationFunctionType_NONE: - break; - case tflite::ActivationFunctionType::ActivationFunctionType_RELU: - { - // When there is a relu, use btmp_obj as relu output - auto *btmp_obj = m->entity()->object()->create(); - auto *btmp_bag = m->entity()->bag()->create(num_elements(ofm_shape)); - btmp_obj->bag(btmp_bag); - btmp_obj->layout(coco::FeatureLayouts::BHWC::create(as_feature_shape(ofm_shape))); - - // Create a Load op - auto coco_load = op_builder(m).load(last_obj).pop(); - - // Create a ReLU - auto coco_relu = m->entity()->op()->create(); - - // Link ops - coco_relu->arg(coco_load); - - // Create an Eval instruction - auto coco_eval = instr_builder(m).eval(btmp_obj, coco_relu); - - // Append the instruction to the block - blk->instr()->append(coco_eval); - - // Update last_obj to btmp_obj - last_obj = btmp_obj; - break; - } - default: - assert(false); - break; - } + // fused activation + coco::FeatureObject *act_output = + build_activation(conv_params->fused_activation_function(), blk, last_obj); // Create Copy Instr of last_obj to Output Object - auto copy_ins = instr_builder(m).copy(ofm_obj, last_obj); + auto copy_ins = instr_builder(m).copy(ofm_obj, act_output); blk->instr()->append(copy_ins); } -- 2.7.4