From ec33435727399e405e3bd6058c2aee919c0de3c9 Mon Sep 17 00:00:00 2001 From: "Efimov Alexander/AI Tools Lab/./Samsung Electronics" Date: Fri, 7 Dec 2018 15:01:22 +0300 Subject: [PATCH] [nnc] Skeleton for acl backend unit tests (#2549) - 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 --- contrib/nnc/CMakeLists.txt | 1 + .../passes/acl_soft_backend/AclCppGenerator.cpp | 2 +- .../passes/acl_soft_backend/AclCppOpGenerator.cpp | 2 +- .../passes/acl_soft_backend/AclCppOpGenerator.h | 0 .../acl_soft_backend/ArtifactGeneratorCppCode.cpp | 4 +- .../acl_soft_backend/ArtifactGeneratorCppCode.h | 0 .../acl_soft_backend/ArtifactGeneratorCppDecl.cpp | 4 +- .../acl_soft_backend/ArtifactGeneratorCppDecl.h | 0 .../passes/acl_soft_backend/ArtifactIndent.h | 0 .../nnc/passes/acl_soft_backend/ArtifactModel.cpp | 2 +- .../passes/acl_soft_backend/ArtifactModel.h | 0 .../passes/acl_soft_backend/IArtifactGenerator.h | 0 contrib/nnc/unittests/CMakeLists.txt | 1 + contrib/nnc/unittests/acl_backend/CMakeLists.txt | 8 + contrib/nnc/unittests/acl_backend/DOMToText.cpp | 122 ++++++++++ contrib/nnc/unittests/acl_backend/MIRToDOM.cpp | 254 +++++++++++++++++++++ 16 files changed, 393 insertions(+), 7 deletions(-) rename contrib/nnc/{include => }/passes/acl_soft_backend/AclCppOpGenerator.h (100%) rename contrib/nnc/{include => }/passes/acl_soft_backend/ArtifactGeneratorCppCode.h (100%) rename contrib/nnc/{include => }/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h (100%) rename contrib/nnc/{include => }/passes/acl_soft_backend/ArtifactIndent.h (100%) rename contrib/nnc/{include => }/passes/acl_soft_backend/ArtifactModel.h (100%) rename contrib/nnc/{include => }/passes/acl_soft_backend/IArtifactGenerator.h (100%) create mode 100644 contrib/nnc/unittests/acl_backend/CMakeLists.txt create mode 100644 contrib/nnc/unittests/acl_backend/DOMToText.cpp create mode 100644 contrib/nnc/unittests/acl_backend/MIRToDOM.cpp diff --git a/contrib/nnc/CMakeLists.txt b/contrib/nnc/CMakeLists.txt index c19d114..41be6a6 100644 --- a/contrib/nnc/CMakeLists.txt +++ b/contrib/nnc/CMakeLists.txt @@ -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) diff --git a/contrib/nnc/passes/acl_soft_backend/AclCppGenerator.cpp b/contrib/nnc/passes/acl_soft_backend/AclCppGenerator.cpp index 0fbe1ad..fbddafa 100644 --- a/contrib/nnc/passes/acl_soft_backend/AclCppGenerator.cpp +++ b/contrib/nnc/passes/acl_soft_backend/AclCppGenerator.cpp @@ -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" diff --git a/contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp b/contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp index 37a72d2..c6625bf 100644 --- a/contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp +++ b/contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.cpp @@ -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" diff --git a/contrib/nnc/include/passes/acl_soft_backend/AclCppOpGenerator.h b/contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/AclCppOpGenerator.h rename to contrib/nnc/passes/acl_soft_backend/AclCppOpGenerator.h diff --git a/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.cpp b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.cpp index 0a4d499..44fb100 100644 --- a/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.cpp +++ b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.cpp @@ -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" diff --git a/contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppCode.h b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppCode.h rename to contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppCode.h diff --git a/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.cpp b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.cpp index a00fddd..ca9925a 100644 --- a/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.cpp +++ b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.cpp @@ -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 diff --git a/contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h b/contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h rename to contrib/nnc/passes/acl_soft_backend/ArtifactGeneratorCppDecl.h diff --git a/contrib/nnc/include/passes/acl_soft_backend/ArtifactIndent.h b/contrib/nnc/passes/acl_soft_backend/ArtifactIndent.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/ArtifactIndent.h rename to contrib/nnc/passes/acl_soft_backend/ArtifactIndent.h diff --git a/contrib/nnc/passes/acl_soft_backend/ArtifactModel.cpp b/contrib/nnc/passes/acl_soft_backend/ArtifactModel.cpp index 3d037bc..0aa615a 100644 --- a/contrib/nnc/passes/acl_soft_backend/ArtifactModel.cpp +++ b/contrib/nnc/passes/acl_soft_backend/ArtifactModel.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "passes/acl_soft_backend/ArtifactModel.h" +#include "ArtifactModel.h" namespace nnc { diff --git a/contrib/nnc/include/passes/acl_soft_backend/ArtifactModel.h b/contrib/nnc/passes/acl_soft_backend/ArtifactModel.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/ArtifactModel.h rename to contrib/nnc/passes/acl_soft_backend/ArtifactModel.h diff --git a/contrib/nnc/include/passes/acl_soft_backend/IArtifactGenerator.h b/contrib/nnc/passes/acl_soft_backend/IArtifactGenerator.h similarity index 100% rename from contrib/nnc/include/passes/acl_soft_backend/IArtifactGenerator.h rename to contrib/nnc/passes/acl_soft_backend/IArtifactGenerator.h diff --git a/contrib/nnc/unittests/CMakeLists.txt b/contrib/nnc/unittests/CMakeLists.txt index 93be98a..1294a9f 100644 --- a/contrib/nnc/unittests/CMakeLists.txt +++ b/contrib/nnc/unittests/CMakeLists.txt @@ -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 index 0000000..afc430b --- /dev/null +++ b/contrib/nnc/unittests/acl_backend/CMakeLists.txt @@ -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 index 0000000..14f99b0 --- /dev/null +++ b/contrib/nnc/unittests/acl_backend/DOMToText.cpp @@ -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 + +#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 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 index 0000000..a4ee6bb --- /dev/null +++ b/contrib/nnc/unittests/acl_backend/MIRToDOM.cpp @@ -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 +#include + +// 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& 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& inputShapes) { + // Create inputs + vector inputs; + int numInputs = inputShapes.size(); + for (int i = 0; i < numInputs; ++i) { + auto inputOp = g.create("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& 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& 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& layers) { + // TODO +} + +/** + * @brief Check that artifact DOM contains appropriate class + * @param m Root module of DOM + */ +void checkArtifactClass(const ArtifactClass& c, + const vector& layers, + const vector& tensors) { + checkDomArtifactGetters(c, tensors); + checkDomArtifactConstructor(c, tensors); + const ArtifactFunction* inf_func = nullptr; + for (const shared_ptr& 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& layers, + const vector& tensors) { + ASSERT_EQ(m.name(), artifactName); + checkDomIncludes(m); + ASSERT_EQ(m.entities().size(), 1); + ArtifactClass* cls = dynamic_cast(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 data(new float[channels], default_delete()); + TensorVariant w({channels}, data, DTYPE::FLOAT32); + + Graph g; + OpConstructor opGenerator = [&w](Graph& g, const vector& inputs) { + return g.create("bias", inputs[0], w); + }; + vector 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 +} -- 2.7.4