[nnc] SQRT Operation (#2514)
authorАндрей Шедько/AI Tools Lab /SRR/Engineer/삼성전자 <a.shedko@samsung.com>
Fri, 14 Dec 2018 17:20:47 +0000 (20:20 +0300)
committerEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Fri, 14 Dec 2018 17:20:47 +0000 (20:20 +0300)
- Added sqrt op to backends (interpreter and c++ SB)
- Added sqrt to tflite importer

Signed-off-by: Andrei Shedko <a.shedko@partner.samsung.com>
20 files changed:
contrib/nnc/core/modelIR/IrDotDumper.cpp
contrib/nnc/core/modelIR/Operation.cpp
contrib/nnc/include/core/modelIR/IrDotDumper.h
contrib/nnc/include/core/modelIR/operations/SqrtOp.h [new file with mode: 0644]
contrib/nnc/include/core/modelIR/operations/operations.lst.h
contrib/nnc/include/passes/interpreter/Interpreter.h
contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp
contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.h
contrib/nnc/passes/interpreter/Interpreter.cpp
contrib/nnc/passes/soft_backend/CPPGenerator.cpp
contrib/nnc/passes/soft_backend/ModelAnalyzer.cpp
contrib/nnc/passes/soft_backend/ModelAnalyzer.h
contrib/nnc/passes/soft_backend/SBSerializer.cpp
contrib/nnc/passes/soft_backend/SBSerializer.h
contrib/nnc/passes/soft_backend/code_snippets/cpp_operations.def
contrib/nnc/passes/soft_backend/code_snippets/cpp_sqrt.def [new file with mode: 0644]
contrib/nnc/passes/tflite_frontend/tflite_importer.cpp
contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp
contrib/nnc/passes/tflite_frontend/tflite_op_creator.h
contrib/nnc/unittests/soft_backend/CPPOperations.cpp

index 23731df..23669ed 100644 (file)
@@ -39,6 +39,7 @@
 #include "core/modelIR/operations/ResizeOp.h"
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/TransposeOp.h"
@@ -275,6 +276,14 @@ void mir::IrDotDumper::visit(ops::PadOp& op) {
   dotBuilder.updateWithOp(&op, node_info);
 }
 
+void IrDotDumper::visit(ops::SqrtOp& op) {
+  auto node_info = DotIrNodeInfo().withType("Sqrt", op.getName())
+    .withInShapes(getInputShapes(op))
+    .withOutShapes(getOutputShapes(op));
+
+  dotBuilder.updateWithOp(&op, node_info);
+}
+
 void IrDotDumper::visit(ops::ReduceFOp& op) {
   static const std::map<ops::ReduceFOp::FuncType, const char*> types{
     {ops::ReduceFOp::FuncType::mean, "mean"}
index 97765ae..0ecfc66 100644 (file)
@@ -38,6 +38,7 @@
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/TransposeOp.h"
 #include "core/modelIR/operations/VariableOp.h"
index dad796c..6245bb1 100644 (file)
@@ -54,6 +54,7 @@ public:
   void visit(ops::ScaleOp& op) override;
   void visit(ops::SoftmaxOp& op) override;
   void visit(ops::SqueezeOp& op) override;
+  void visit(ops::SqrtOp& op) override;
   void visit(ops::TanhOp& op) override;
   void visit(ops::TransposeOp& op) override;
   void visit(ops::VariableOp& op) override;
diff --git a/contrib/nnc/include/core/modelIR/operations/SqrtOp.h b/contrib/nnc/include/core/modelIR/operations/SqrtOp.h
new file mode 100644 (file)
index 0000000..6382695
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 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 _NNC_CORE_IR_MODEL_SQRT_H_
+#define _NNC_CORE_IR_MODEL_SQRT_H_
+
+#include "core/modelIR/Operation.h"
+#include "core/modelIR/operations/CommonProps.h"
+
+namespace nnc {
+namespace mir {
+namespace ops {
+
+class SqrtOp : public Operation {
+public:
+  SqrtOp(const IODescriptor& arg) : Operation(Type::sqrt, {arg}) {
+    setOutputShape(0, getInputShape(0));
+  };
+};
+
+} // namespace ops
+} // namespace mir
+} // namespace nnc
+
+#endif //_NNC_CORE_IR_MODEL_SQRT_H_
index 9292e71..14fa493 100644 (file)
@@ -42,5 +42,6 @@ HANDLE_OP(deConv2D, DeConv2DOp)
 HANDLE_OP(ELU, EluOp)
 HANDLE_OP(squeeze, SqueezeOp)
 HANDLE_OP(pad, PadOp)
+HANDLE_OP(sqrt, SqrtOp)
 HANDLE_OP(reduceF, ReduceFOp)
 HANDLE_OP(transpose, TransposeOp)
index 25239c2..f7136f0 100644 (file)
@@ -59,6 +59,7 @@ public:
   void visit(ops::ScaleOp& op) override;
   void visit(ops::SoftmaxOp& op) override;
   void visit(ops::SqueezeOp& op) override;
+  void visit(ops::SqrtOp& op) override;
   void visit(ops::TanhOp& op) override;
   void visit(ops::TransposeOp& op) override;
   void visit(ops::VariableOp& op) override;
index 46d5c6f..ae0fa90 100644 (file)
@@ -25,6 +25,7 @@
 #include "core/modelIR/operations/ResizeOp.h"
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/VariableOp.h"
 
@@ -854,6 +855,10 @@ void AclCppOpGenerator::visit(ops::SqueezeOp& op) {
   assert(false && "Unimplemented operation: Squeeze");
 }
 
+void AclCppOpGenerator::visit(ops::SqrtOp& op) {
+  assert(false && "Unimplemented operation: Sqrt");
+}
+
 void AclCppOpGenerator::allocate(std::shared_ptr<ArtifactId> tensor_id) {
   _allocates.push_back(tensor_id);
 }
@@ -892,6 +897,5 @@ void AclCppOpGenerator::visit(mir::ops::TransposeOp& op) {
 void AclCppOpGenerator::visit(mir::ops::GatherOp& op) {
   assert(false && "Unimplemented operation: GatherOp");
 }
-
 }
 // namespace nnc
index de10424..044cf03 100644 (file)
@@ -70,6 +70,7 @@ public:
   void visit(mir::ops::ScaleOp& op) override;
   void visit(mir::ops::SoftmaxOp& op) override;
   void visit(mir::ops::SqueezeOp& op) override;
+  void visit(mir::ops::SqrtOp& op) override;
   void visit(mir::ops::TanhOp& op) override;
   void visit(mir::ops::TransposeOp& op) override;
   void visit(mir::ops::VariableOp& op) override;
index 8db2fb6..0160b02 100644 (file)
@@ -17,6 +17,7 @@
 #include <cmath>
 #include <cassert>
 #include <vector>
+
 #include "pass/PassException.h"
 
 #include "passes/interpreter/Interpreter.h"
@@ -43,6 +44,7 @@
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/TransposeOp.h"
 #include "core/modelIR/operations/VariableOp.h"
@@ -312,6 +314,15 @@ void NNInterpreter::visit(ops::PadOp& op) {
   var(op.getId()) = Pad(input, op)();
 }
 
+void NNInterpreter::visit(ops::SqrtOp& op) {
+  mapByName(&op);
+  auto operand = op.getPrevNodes()[0];
+  auto input = Tensor<float>(var(operand.op->getId())[operand.index]);
+  var(op.getId()) = Fill<float>(op.getOutputShape(0), [&input](const Index id) {
+    return sqrt(input.at(id));
+  })();
+}
+
 void NNInterpreter::visit(ops::ResizeOp& op) {
   mapByName(&op);
   auto operand = op.getPrevNodes()[0];
index ec900bc..6f678b4 100644 (file)
@@ -36,6 +36,7 @@ using namespace std;
 #include "cpp_depthwise_conv.generated.h"
 #include "cpp_fully_connected.generated.h"
 #include "cpp_pool.generated.h"
+#include "cpp_sqrt.generated.h"
 #include "cpp_relu.generated.h"
 #include "cpp_reduce.generated.h"
 #include "cpp_softmax.generated.h"
@@ -290,6 +291,7 @@ void CPPCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma, co
   out.write(cpp_elu, sizeof(cpp_elu));
   out.write(cpp_tanh, sizeof(cpp_tanh));
   out.write(cpp_pad, sizeof(cpp_pad));
+  out.write(cpp_sqrt, sizeof(cpp_sqrt));
   out.write(cpp_conv_transpose, sizeof(cpp_conv_transpose));
   out.write(cpp_transpose, sizeof(cpp_transpose));
   out.write(cpp_gather, sizeof(cpp_gather));
index ebb0b2c..0008e8c 100644 (file)
@@ -46,6 +46,7 @@
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/TransposeOp.h"
 #include "core/modelIR/operations/VariableOp.h"
@@ -291,6 +292,10 @@ void ModelAnalyzer::visit(ops::SqueezeOp& op) {
   addOpDescr(&op, "reshape");
 }
 
+void ModelAnalyzer::visit(ops::SqrtOp& op) {
+  addOpDescr(&op, "sqrtFN");
+}
+
 void ModelAnalyzer::visit(mir::ops::PadOp& op) {
   addOpDescr(&op, "pad");
 }
index 36cb487..4f87e91 100644 (file)
@@ -112,6 +112,7 @@ public:
   void visit(mir::ops::ScaleOp& op) override;
   void visit(mir::ops::SoftmaxOp& op) override;
   void visit(mir::ops::SqueezeOp& op) override;
+  void visit(mir::ops::SqrtOp& op) override;
   void visit(mir::ops::TanhOp& op) override;
   void visit(mir::ops::TransposeOp& op) override;
   void visit(mir::ops::VariableOp& op) override;
index ee7f565..7964a4d 100644 (file)
@@ -43,6 +43,7 @@
 #include "core/modelIR/operations/ScaleOp.h"
 #include "core/modelIR/operations/SoftmaxOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/TransposeOp.h"
 
@@ -348,6 +349,11 @@ void Serializer::visit(mir::ops::PadOp& op) {
   }
 }
 
+void Serializer::visit(mir::ops::SqrtOp& op) {
+  _curOp->_paramStartOffset = _buffer.size();
+  // no parameters to dump
+}
+
 void Serializer::visit(mir::ops::ResizeOp& op) {
   throw PassException("Not implemented yet");
 }
index 2e68ebf..a5ca3ed 100644 (file)
@@ -64,6 +64,7 @@ public:
   void visit(mir::ops::ScaleOp& op) override;
   void visit(mir::ops::SoftmaxOp& op) override;
   void visit(mir::ops::SqueezeOp& op) override;
+  void visit(mir::ops::SqrtOp& op) override;
   void visit(mir::ops::TanhOp& op) override;
   void visit(mir::ops::TransposeOp& op) override;
   void visit(mir::ops::VariableOp& op) override;
index 2766ac5..508fe53 100644 (file)
@@ -592,6 +592,15 @@ void pad(Tensor& out, const char* params, const Tensor& in) {
   Pad(input, input_dims, left_paddings, right_paddings, output, output_dims);
 }
 
+void sqrtFN(Tensor& out, const char* params, const Tensor& in) {
+  const float* input = in.getData();
+  const Dims<4> inp_d = shapeToDims(in.getShape());
+  // no params to deserialize
+
+  out.reShape(in.getShape());
+  Sqrt(input, inp_d, out.getData());
+}
+
 void transpose(Tensor &out, const char *params, const Tensor &in) {
   TransposeParams transpose_params;
   transpose_params.perm_count = deserializeT<int32_t>(params);
diff --git a/contrib/nnc/passes/soft_backend/code_snippets/cpp_sqrt.def b/contrib/nnc/passes/soft_backend/code_snippets/cpp_sqrt.def
new file mode 100644 (file)
index 0000000..29c4185
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+inline void Sqrt(const float* input_data, const Dims<4>& input_dims, float* output_data) {
+
+  const auto input = MapAsVector(input_data, input_dims);
+  auto output = MapAsVector(output_data, input_dims);
+
+  output = input.array().sqrt();
+}
index 84de4e6..0e8ec98 100644 (file)
@@ -94,6 +94,7 @@ void TfliteImporter::processUnsupportedOp(const Operator* op) {
     case BuiltinOperator_RESHAPE:
     case BuiltinOperator_RESIZE_NEAREST_NEIGHBOR:
     case BuiltinOperator_SQUEEZE:
+    case BuiltinOperator_SQRT:
     case BuiltinOperator_PAD:
     case BuiltinOperator_ADD:
     case BuiltinOperator_MUL:
@@ -203,6 +204,9 @@ void TfliteImporter::walkOperator(const Operator* op) {
     case BuiltinOperator_SQUEEZE:
       outputs = _opCreator->createSqueeze(inputs, params, op->builtin_options_as<SqueezeOptions>());
       break;
+    case BuiltinOperator_SQRT:
+      outputs = _opCreator->createSqrt(inputs, params);
+      break;
     case BuiltinOperator_ADD:
       outputs = _opCreator->createAdd(inputs, params, op->builtin_options_as<AddOptions>());
       break;
index 4ed47df..83e6295 100644 (file)
@@ -34,6 +34,7 @@
 #include "core/modelIR/operations/ReshapeOp.h"
 #include "core/modelIR/operations/SqueezeOp.h"
 #include "core/modelIR/operations/PadOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 #include "core/modelIR/Tensor.h"
 #include "core/modelIR/ShapeRange.h"
 #include "pass/PassException.h"
@@ -372,4 +373,9 @@ TFLiteOpCreator::createActivation(InputOps& inputs, InputParams&,
   return {addFusedActivation(inputs[0], activationType)};
 }
 
+std::vector<mir::Operation*>
+TFLiteOpCreator::createSqrt(InputOps& inputs, InputParams&) {
+  return createOp<ops::SqrtOp>(ActivationFunctionType_NONE, inputs[0]->getOutput(0));
+}
+
 } // namespace nnc
index a8fdf30..c56a47c 100644 (file)
@@ -76,6 +76,8 @@ public:
   std::vector<mir::Operation*> convertResizeNN(InputOps, InputParams,
                                                const ::tflite::ResizeNearestNeighborOptions*);
 
+  std::vector<mir::Operation*> createSqrt(InputOps, InputParams);
+
   std::vector<mir::Operation*> createSqueeze(InputOps& inputs, InputParams& params,
                                              const ::tflite::SqueezeOptions* opts);
 
index c35ef89..b94c6b6 100644 (file)
@@ -42,6 +42,7 @@
 #include "code_snippets/cpp_reduce.def"
 #include "code_snippets/cpp_relu.def"
 #include "code_snippets/cpp_softmax.def"
+#include "code_snippets/cpp_sqrt.def"
 #include "code_snippets/cpp_tanh.def"
 #include "code_snippets/cpp_transpose.def"
 
@@ -72,6 +73,7 @@
 #include "core/modelIR/operations/Deconv2DOp.h"
 #include "core/modelIR/operations/TanhOp.h"
 #include "core/modelIR/operations/PadOp.h"
+#include "core/modelIR/operations/SqrtOp.h"
 
 // various headers
 #include "core/modelIR/TensorVariant.h"
@@ -755,7 +757,6 @@ TEST(cpp_operations_test, reduceMeanTst) {
   }
 }
 
-
 TEST(cpp_operations_test, softmax)
 {
   // iterate over number of dimensions in tensor
@@ -792,6 +793,18 @@ TEST(cpp_operations_test, reshape)
   createAndRunTestGraph(opGenerator, reshape, inputNTensors, aInputTensor);
 }
 
+TEST(cpp_operations_test, sqrtTest) {
+  // test prerequisites
+  vector<int> shape_data{2, 3, 4, 5};
+  Tensor a_input_tensor;
+  vector<unique_ptr<mir::TensorVariant>> input_n_tensor(1);
+  fillTensors(input_n_tensor[0], a_input_tensor, shape_data, 1.0f);
+  auto op_generator = [](mir::Graph& g, const std::vector<mir::IODescriptor>& inputs) {
+    return g.create<mir::ops::SqrtOp>("y", inputs[0]);
+  };
+  createAndRunTestGraph(op_generator, sqrtFN, input_n_tensor, a_input_tensor);
+}
+
 TEST(cpp_operations_test, pad) {
   // test on matrix 2x3
   vector<int> input_shape{2,3};