From 2139d0df304d4582b2b8de00dade2343f7a299fa Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B1=84=EC=84=B1=EC=9A=B0/On-Device=20Lab=28SR=29/Enginee?= =?utf8?q?r/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 20 Aug 2019 19:29:21 +0900 Subject: [PATCH] [exo-tflite] Export DepthwiseConv2D operation (#6720) This commit introduce DepthwiseConv2D operation to exporter. Signed-off-by: seongwoo --- compiler/exo-tflite/src/OperationExporter.cpp | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/compiler/exo-tflite/src/OperationExporter.cpp b/compiler/exo-tflite/src/OperationExporter.cpp index fc939ec..c322f65 100644 --- a/compiler/exo-tflite/src/OperationExporter.cpp +++ b/compiler/exo-tflite/src/OperationExporter.cpp @@ -51,6 +51,7 @@ public: void visit(loco::MaxPool2D *) final; void visit(loco::AvgPool2D *) final; void visit(loco::Conv2D *) final; + void visit(loco::DepthwiseConv2D *) final; void visit(loco::TensorConcat *) final; void visit(loco::TensorSoftmax *) final; void visit(loco::BiasEncode *) final; @@ -174,6 +175,53 @@ void OperationExporter::visit(loco::Conv2D *node) gd._operators.push_back(op_offset); } +void OperationExporter::visit(loco::DepthwiseConv2D *node) +{ + uint32_t op_idx = gd.registerBuiltinOpcode(tflite::BuiltinOperator_DEPTHWISE_CONV_2D); + + // Third input of DEPTHWISE_CONV2D of tflite should be bias. We will make (and register to gd) + // dummy zero bias. Bias would be rank 1, have size of output kernel count, and have all zero + // values, i.e. zero bias. + auto *ker = dynamic_cast(node->ker()); + assert(ker); + + int32_t bias_vec_size = ShapeInference::get(ker)._dims[3]; // output_size(C*M) + auto bias_vec_shape_offset = builder.CreateVector(std::vector{bias_vec_size}); + + size_t raw_bias_vec_size = bias_vec_size * sizeof(int32_t); + std::vector bias_vec_data(bias_vec_size); + auto bias_vec_offset = + builder.CreateVector(reinterpret_cast(bias_vec_data.data()), raw_bias_vec_size); + + auto bias_buffer_offset = CreateBuffer(builder, bias_vec_offset); + + const auto bias_buffer_id = static_cast(gd._buffers.size()); + + gd._buffers.push_back(bias_buffer_offset); + + auto bias_tensor_offset = + CreateTensor(builder, bias_vec_shape_offset, TensorType_FLOAT32, bias_buffer_id); + auto bias_tensor_id = static_cast(gd._tensors.size()); + gd._tensors.push_back(bias_tensor_offset); + + std::vector inputs_vec{get_tensor_index(node->ifm()), get_tensor_index(node->ker()), + bias_tensor_id}; + std::vector outputs_vec{get_tensor_index(static_cast(node))}; + auto inputs = builder.CreateVector(inputs_vec); + auto outputs = builder.CreateVector(outputs_vec); + tflite::Padding padding = getOpPadding(node->pad()); + + int32_t ifm_channel_size = ShapeInference::get(node->ifm())._dims[3]; + // multiplier = bias_vec_size(output_size)/ifm_channel_size + auto options = + CreateDepthwiseConv2DOptions(builder, padding, node->stride()->horizontal(), + node->stride()->vertical(), bias_vec_size / ifm_channel_size); + + auto op_offset = CreateOperator(builder, op_idx, inputs, outputs, + tflite::BuiltinOptions_DepthwiseConv2DOptions, options.Union()); + gd._operators.push_back(op_offset); +} + void OperationExporter::visit(loco::TensorSoftmax *node) { // TODO Support when the input rank of TensorSoftmax is not 2 -- 2.7.4