[nnc] Skeleton for acl backend unit tests (#2549)
authorEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Fri, 7 Dec 2018 12:01:22 +0000 (15:01 +0300)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 7 Dec 2018 12:01:22 +0000 (15:01 +0300)
- added two groups of tests: MIR to DOM transformations and DOM to text transformation
- Declarations of checker functions
- two example tests, one for each group

Signed-off-by: Efimov Alexander <a.efimov@samsung.com>
16 files changed:
contrib/nnc/CMakeLists.txt
contrib/nnc/passes/acl_soft_backend/AclCppGenerator.cpp
contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp
contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.h [moved from contrib/nnc/include/passes/acl_soft_backend/AclCppOpGenerator.h with 100% similarity]
contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.cpp
contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.h [moved from contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppCode.h with 100% similarity]
contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.cpp
contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h [moved from contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h with 100% similarity]
contrib/nnc/passes/acl_soft_backend/ArtifactIndent.h [moved from contrib/nnc/include/passes/acl_soft_backend/ArtifactIndent.h with 100% similarity]
contrib/nnc/passes/acl_soft_backend/ArtifactModel.cpp
contrib/nnc/passes/acl_soft_backend/ArtifactModel.h [moved from contrib/nnc/include/passes/acl_soft_backend/ArtifactModel.h with 100% similarity]
contrib/nnc/passes/acl_soft_backend/IArtifactGenerator.h [moved from contrib/nnc/include/passes/acl_soft_backend/IArtifactGenerator.h with 100% similarity]
contrib/nnc/unittests/CMakeLists.txt
contrib/nnc/unittests/acl_backend/CMakeLists.txt [new file with mode: 0644]
contrib/nnc/unittests/acl_backend/DOMToText.cpp [new file with mode: 0644]
contrib/nnc/unittests/acl_backend/MIRToDOM.cpp [new file with mode: 0644]

index c19d114..41be6a6 100644 (file)
@@ -107,6 +107,7 @@ endfunction()
 # Used by unit tests
 #
 set(NNC_SOFT_BACKEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/soft_backend)
+set(NNC_ACL_BACKEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/acl_soft_backend)
 set(NNC_INTERPRETER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/interpreter)
 set(NNC_CAFFE_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/caffe_frontend)
 set(NNC_CAFFE2_FRONTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/passes/caffe2_frontend)
index 0fbe1ad..fbddafa 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include "passes/acl_soft_backend/AclCppGenerator.h"
-#include "passes/acl_soft_backend/AclCppOpGenerator.h"
+#include "AclCppOpGenerator.h"
 #include "passes/acl_soft_backend/AclCppException.h"
 #include "option/Options.h"
 
index 37a72d2..c6625bf 100644 (file)
@@ -1,4 +1,4 @@
-#include "passes/acl_soft_backend/AclCppOpGenerator.h"
+#include "AclCppOpGenerator.h"
 #include "passes/acl_soft_backend/AclCppException.h"
 #include "core/modelIR/ShapeRange.h"
 #include "core/modelIR/TensorUtil.h"
index 0a4d499..44fb100 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "passes/acl_soft_backend/ArtifactGeneratorCppCode.h"
-#include "passes/acl_soft_backend/ArtifactModel.h"
+#include "ArtifactGeneratorCppCode.h"
+#include "ArtifactModel.h"
 
 #include "AclArtifactUtilities.generated.h"
 
index a00fddd..ca9925a 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "passes/acl_soft_backend/ArtifactGeneratorCppDecl.h"
-#include "passes/acl_soft_backend/ArtifactModel.h"
+#include "ArtifactGeneratorCppDecl.h"
+#include "ArtifactModel.h"
 
 #include <cassert>
 
index 3d037bc..0aa615a 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "passes/acl_soft_backend/ArtifactModel.h"
+#include "ArtifactModel.h"
 
 namespace nnc {
 
index 93be98a..1294a9f 100644 (file)
@@ -15,6 +15,7 @@ endfunction()
 add_subdirectory(pass)
 add_subdirectory(core)
 add_subdirectory(soft_backend)
+add_subdirectory(acl_backend)
 add_subdirectory(support)
 add_subdirectory(caffe_frontend)
 add_subdirectory(tflite_frontend)
diff --git a/contrib/nnc/unittests/acl_backend/CMakeLists.txt b/contrib/nnc/unittests/acl_backend/CMakeLists.txt
new file mode 100644 (file)
index 0000000..afc430b
--- /dev/null
@@ -0,0 +1,8 @@
+set(ACL_CPP_BACKEND_UTEST_SOURCES DOMToText.cpp MIRToDOM.cpp)
+
+add_nnc_unit_test(nnc_acl_cpp_backend_test ${ACL_CPP_BACKEND_UTEST_SOURCES} ${OPTIONS_SRC})
+
+if (TARGET nnc_acl_cpp_backend_test)
+    nncc_target_link_libraries(nnc_acl_cpp_backend_test nnc_core nnc_support acl_soft_backend_cpp)
+    target_include_directories(nnc_acl_cpp_backend_test PRIVATE ${NNC_ACL_BACKEND_DIR})
+endif()
diff --git a/contrib/nnc/unittests/acl_backend/DOMToText.cpp b/contrib/nnc/unittests/acl_backend/DOMToText.cpp
new file mode 100644 (file)
index 0000000..14f99b0
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/*
+ * This is test set of text generator from DOM entities
+ * ArtifactEntity, ArtifactNamed, ArtifactExpr and ArtifactClassMember
+ * are not tested since they are abstract classes
+ */
+
+#include <sstream>
+
+#include "ArtifactModel.h"
+#include "ArtifactGeneratorCppCode.h"
+#include "ArtifactGeneratorCppDecl.h"
+
+#include "gtest/gtest.h"
+
+using namespace std;
+using namespace nnc;
+
+TEST(acl_backend_dom_to_text, ArtifactLiteral) {
+  stringstream code_out;
+  stringstream decl_out;
+  ArtifactGeneratorCppCode code_gen(code_out);
+  ArtifactGeneratorCppDecl decl_gen(decl_out);
+  const char* data = "hello_world";
+  shared_ptr<ArtifactLiteral> lit = ArtifactFactory::lit(data);
+  lit->accept(&code_gen);
+  lit->accept(&decl_gen);
+  ASSERT_EQ(code_out.str(), data);
+  // TODO why not generate data for literal in decl generator?
+  //ASSERT_EQ(decl_out.str(), data);
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactId) {
+  // TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactRef) {
+  // TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactDeref) {
+  // TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactFunctionCall) {
+  // TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactUnaryExpr) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactBinaryExpr) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactIndex) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactRet) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactBreak) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactCont) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactVariable) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactBlock) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactForLoop) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactIf) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactFunction) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactClassVariable) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactClassFunction) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactClass) {
+  //TODO
+}
+
+TEST(acl_backend_dom_to_text, DISABLED_ArtifactModule) {
+  //TODO
+}
diff --git a/contrib/nnc/unittests/acl_backend/MIRToDOM.cpp b/contrib/nnc/unittests/acl_backend/MIRToDOM.cpp
new file mode 100644 (file)
index 0000000..a4ee6bb
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * 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.
+ */
+
+/*
+ * This test set checks correctness of MIR to DOM transformation
+ */
+
+// system
+#include <functional>
+#include <vector>
+
+// ACL backend
+#include "ArtifactModel.h"
+#include "AclCppOpGenerator.h"
+
+// MIR
+#include "core/modelIR/Graph.h"
+#include "core/modelIR/operations/VariableOp.h"
+#include "core/modelIR/operations/FullyConnectedOp.h"
+#include "core/modelIR/operations/Conv2DOp.h"
+#include "core/modelIR/operations/DepthwiseConv2DOp.h"
+#include "core/modelIR/operations/PoolOp.h"
+#include "core/modelIR/operations/ReluOp.h"
+#include "core/modelIR/operations/ReduceFOp.h"
+#include "core/modelIR/operations/CappedReluOp.h"
+#include "core/modelIR/operations/ReshapeOp.h"
+#include "core/modelIR/operations/ConcatOp.h"
+#include "core/modelIR/operations/BiasAddOp.h"
+#include "core/modelIR/operations/SoftmaxOp.h"
+#include "core/modelIR/operations/ScaleOp.h"
+#include "core/modelIR/operations/EluOp.h"
+#include "core/modelIR/operations/ElementwiseOp.h"
+#include "core/modelIR/operations/Deconv2DOp.h"
+#include "core/modelIR/operations/TanhOp.h"
+#include "core/modelIR/operations/PadOp.h"
+#include "core/modelIR/operations/TransposeOp.h"
+
+#include "gtest/gtest.h"
+
+using namespace std;
+using namespace nnc;
+using namespace mir;
+
+namespace {
+
+using OpConstructor = function<Operation*(Graph& g, vector<IODescriptor>& inputs)>;
+
+const char* artifactName = "nnmodel";
+
+/**
+ * @brief Creates graph with one operation generated by opGen function and returns this operation node
+ * @param g reference to graph which should be filled with operations
+ * @param opConstr functor which creates main operations of graph
+ * @param inputShapes vector of network input shapes
+ * */
+void fillGraph(Graph& g, OpConstructor opConstr, const vector<Shape>& inputShapes) {
+  // Create inputs
+  vector<mir::IODescriptor> inputs;
+  int numInputs = inputShapes.size();
+  for (int i = 0; i < numInputs; ++i) {
+    auto inputOp = g.create<ops::VariableOp>("x" + to_string(i), inputShapes[i]);
+    inputs.push_back(inputOp->getOutput(0));
+  }
+
+  // Create operation
+  Operation* op = opConstr(g, inputs);
+
+  // Mark outputs
+  g.markOutput(op);
+}
+
+/**
+ * @brief Check that artifact DOM has all needed includes
+ * @param m Root module of DOM
+ */
+void checkDomIncludes(const ArtifactModule& m) {
+  // TODO
+}
+
+/**
+ * @brief Check that artifact DOM contains appropriate getters
+ * @param c Main artifact class
+ * @param names List of values accessible via getters
+ */
+void checkDomArtifactGetters(const ArtifactClass& c, const vector<string>& tensors) {
+  // TODO
+}
+
+/**
+ * @brief Check that artifact class constructor initializes all layers
+ * @param c Main artifact class
+ * @param layers List of NN layers
+ */
+void checkDomArtifactConstructor(const ArtifactClass& c, const vector<string>& tensors) {
+  // TODO
+}
+
+/**
+ * @brief Check that inference executes layers in appropriate order
+ * @param f Inference function description
+ * @param layers List of layers in inference
+ */
+void checkDomInference(const ArtifactFunction& f, const vector<string>& layers) {
+  // TODO
+}
+
+/**
+ * @brief Check that artifact DOM contains appropriate class
+ * @param m Root module of DOM
+ */
+void checkArtifactClass(const ArtifactClass& c,
+                        const vector<string>& layers,
+                        const vector<string>& tensors) {
+  checkDomArtifactGetters(c, tensors);
+  checkDomArtifactConstructor(c, tensors);
+  const ArtifactFunction* inf_func = nullptr;
+  for (const shared_ptr<ArtifactClassFunction>& method: c.publicFunctions()) {
+    if (method->name() == "Inference") {
+      inf_func = method.get();
+      break;
+    }
+  }
+  ASSERT_NE(inf_func, nullptr);
+  checkDomInference(*inf_func, layers);
+}
+
+/**
+ * @brief Root of check functions
+ * @param m Main artifact module
+ */
+void checkDomStructure(const ArtifactModule& m,
+                       const vector<string>& layers,
+                       const vector<string>& tensors) {
+  ASSERT_EQ(m.name(), artifactName);
+  checkDomIncludes(m);
+  ASSERT_EQ(m.entities().size(), 1);
+  ArtifactClass* cls = dynamic_cast<ArtifactClass*>(m.entities().front().get());
+  ASSERT_NE(cls, nullptr);
+  checkArtifactClass(*cls, layers, tensors);
+}
+
+}
+
+// Actual tests
+
+TEST(acl_backend_mir_to_dom, bias) {
+  const int channels = 2;
+  shared_ptr<float> data(new float[channels], default_delete<float[]>());
+  TensorVariant w({channels}, data, DTYPE::FLOAT32);
+
+  Graph g;
+  OpConstructor opGenerator = [&w](Graph& g, const vector<IODescriptor>& inputs) {
+    return g.create<mir::ops::BiasAddOp>("bias", inputs[0], w);
+  };
+  vector<Shape> inputShapes{{1, 10, 10, channels}};
+
+  fillGraph(g, opGenerator, inputShapes);
+
+  stringstream params_out;
+  AclCppOpGenerator dom_gen(artifactName, params_out);
+
+  const ArtifactModule& m = dom_gen.generate(&g);
+
+  checkDomStructure(m, {}, {});
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_scale) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_capped_relu) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_concat) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_add) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_mul) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_max) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_conv_transposed2d) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_conv2d) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_depthwise_conv) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_fully_connected) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_maxpool) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_avgpool) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_relu) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_elu) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_tanh) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_reduce_mean) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_softmax) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_reshape) {
+  // TODO
+}
+
+TEST(acl_backend_mir_to_dom, DISABLED_pad) {
+  // TODO
+}