diff options
Diffstat (limited to 'runtime/onert/test')
19 files changed, 0 insertions, 2921 deletions
diff --git a/runtime/onert/test/CMakeLists.txt b/runtime/onert/test/CMakeLists.txt deleted file mode 100644 index 38899976d..000000000 --- a/runtime/onert/test/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(TEST_ONERT test_onert) - -file(GLOB_RECURSE TESTS "*.cc") - -add_executable(${TEST_ONERT} ${TESTS}) - -target_include_directories(${TEST_ONERT} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../core/src) - -target_link_libraries(${TEST_ONERT} onert_core) -target_link_libraries(${TEST_ONERT} gtest) -target_link_libraries(${TEST_ONERT} gtest_main) -target_link_libraries(${TEST_ONERT} ${LIB_PTHREAD} dl) -add_test(${TEST_ONERT} ${TEST_ONERT}) - -install(TARGETS ${TEST_ONERT} DESTINATION unittest_standalone) diff --git a/runtime/onert/test/core/compiler/HEScheduler.cc b/runtime/onert/test/core/compiler/HEScheduler.cc deleted file mode 100644 index 514c01485..000000000 --- a/runtime/onert/test/core/compiler/HEScheduler.cc +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#include <compiler/HEScheduler.h> -#include <exec/ExecTime.h> - -#include <ir/Shape.h> -#include <ir/InternalType.h> -#include <ir/TypeInfo.h> -#include <ir/DataType.h> - -#include <ir/operation/BinaryArithmetic.h> -#include <ir/operation/FullyConnected.h> - -#include <gtest/gtest.h> - -namespace -{ -using namespace onert; -using namespace ir; -using namespace backend; -using namespace operation; -using namespace exec; - -// -// Mock backends classes -// - -struct MockConfigCPU : public IConfig -{ - std::string id() override { return "cpu"; } - bool initialize() override { return true; }; - bool supportPermutation() override { return false; } - Layout supportLayout(const Operation &, Layout) override { return Layout::UNKNOWN; } - bool supportDynamicTensor() override { return false; } - bool supportFP16() override { return false; } -}; - -class MockBackendContext : public BackendContext -{ -public: - using BackendContext::BackendContext; - ITensorRegistry *genTensors() override { return nullptr; } - FunctionMap genKernels() override { return {}; } -}; - -struct MockBackendCPU : public Backend -{ - std::shared_ptr<IConfig> config() const override { return std::make_shared<MockConfigCPU>(); } - std::unique_ptr<BackendContext> newContext(ContextData &&data) const override - { - return std::make_unique<MockBackendContext>(this, std::move(data), nullptr); - } -}; - -struct MockConfigGPU : public IConfig -{ - std::string id() override { return "gpu"; } - bool initialize() override { return true; }; - bool supportPermutation() override { return false; } - ir::Layout supportLayout(const ir::Operation &, ir::Layout) override - { - return ir::Layout::UNKNOWN; - } - bool supportDynamicTensor() override { return false; } - bool supportFP16() override { return false; } -}; - -struct MockBackendGPU : public Backend -{ - std::shared_ptr<IConfig> config() const override { return std::make_shared<MockConfigGPU>(); } - std::unique_ptr<BackendContext> newContext(ContextData &&data) const override - { - return std::make_unique<MockBackendContext>(this, std::move(data), nullptr); - } -}; - -struct MockConfigNPU : public IConfig -{ - std::string id() override { return "npu"; } - bool initialize() override { return true; }; - bool supportPermutation() override { return false; } - ir::Layout supportLayout(const ir::Operation &, ir::Layout) override - { - return ir::Layout::UNKNOWN; - } - bool supportDynamicTensor() override { return false; } - bool supportFP16() override { return false; } -}; - -struct MockBackendNPU : public Backend -{ - std::shared_ptr<IConfig> config() const override { return std::make_shared<MockConfigNPU>(); } - std::unique_ptr<BackendContext> newContext(ContextData &&data) const override - { - return std::make_unique<MockBackendContext>(this, std::move(data), nullptr); - } -}; - -// -// Constants -// - -const int OPERAND_ELEMS = 268203; -const int OPERAND_SIZE = OPERAND_ELEMS * 4; -const int OPERATION_SIZE = OPERAND_SIZE * 3; - -const std::string LINEAR("Linear"); -const std::string DATAFLOW("Dataflow"); -const std::string PARALLEL("Parallel"); - -// -// Helper functions -// - -// Set executor through environment variable -void setExecutor(const std::string &executor) { setenv("EXECUTOR", executor.c_str(), true); } - -// Set profiling mode through environment variable -void setProfilingMode(const bool value) { setenv("PROFILING_MODE", value ? "1" : "0", true); } - -// Calculate operation size by addition sizes of all input and output operands -uint32_t calcOpSize(const std::shared_ptr<Graph> &graph, const OperationIndex &op_idx) -{ - uint32_t size = 0; - const auto &op = graph->operations().at(op_idx); - for (const auto &ind : op.getInputs() + op.getOutputs()) - size += graph->operands().at(ind).info().total_size(); - return size; -} - -// Set execution operation time. This method is needed since ExecutionTime has only -// 'updateOperationExecTime' method. -void setOperationExecTime(ExecTime &et, const Backend *backend, const std::string &operation, - bool quant, uint32_t op_size, int64_t time) -{ - // You shouldn't set negative time with this method since nnfw JSON deserializer can't read it - assert(time > 0); - int64_t prev_time = et.getOperationExecTime(backend, operation, quant, op_size); - int64_t time_to_set = prev_time == ExecTime::NOT_FOUND ? time : 2 * time - prev_time; - et.updateOperationExecTime(backend, operation, quant, op_size, time_to_set); - assert(et.getOperationExecTime(backend, operation, quant, op_size) == time); -} - -// Set same execution time for all given backends/operations -void setOperationsExecutionTime(const std::vector<const Backend *> &backends, - const std::vector<std::string> &op_names, - const std::vector<uint32_t> &op_sizes, int64_t exec_time) -{ - assert(op_names.size() == op_sizes.size()); - ExecTime et(backends); - for (int i = 0; i < op_names.size(); ++i) - { - for (auto &backend : backends) - setOperationExecTime(et, backend, op_names[i], false, op_sizes[i], exec_time); - } - et.storeOperationsExecTime(); -} - -// Set permute time from one backend to another. This method is needed since ExecutionTime has only -// 'updatePermuteTime' method. -void setPermutationTime(ExecTime &et, const Backend *from_backend, const Backend *to_backend, - bool quant, uint32_t op_size, int64_t time) -{ - // You shouldn't set negative time with this method since nnfw JSON deserializer can't read it - assert(time > 0); - int64_t prev_time = et.getPermuteTime(from_backend, to_backend, quant, op_size); - int64_t time_to_set = prev_time == ExecTime::NOT_FOUND ? time : 2 * time - prev_time; - et.updatePermuteTime(from_backend, to_backend, quant, op_size, time_to_set); - assert(et.getPermuteTime(from_backend, to_backend, quant, op_size) == time); -} - -// Set same permutation time between all given backends -void setPermutationsExecutionTime(const std::vector<const Backend *> &backends, - const int operand_size, const int64_t exec_time) -{ - ExecTime et(backends); - for (const auto &backend : backends) - { - for (auto &other_backend : backends) - { - if (backend == other_backend) - continue; - setPermutationTime(et, backend, other_backend, false, operand_size, exec_time); - } - } - et.storeOperationsExecTime(); -} - -// -// Functions for creating graphs -// - -using OIS = OperandIndexSequence; - -template <typename NodeT, typename... Types> -OperationIndex create(std::shared_ptr<Graph> graph, Types &&... args) -{ - auto op = std::make_unique<NodeT>(std::forward<Types>(args)...); - auto op_idx = graph->addOperation(std::move(op)); - // For now in scheduler test all operations in tested graphs has same size (for simplicity) - assert(calcOpSize(graph, op_idx) == OPERATION_SIZE); - return op_idx; -} - -// Create straight graph: Add->Sub->Mul -std::shared_ptr<Graph> createStraightGraph() -{ - auto graph = std::make_shared<Graph>(); - const TypeInfo float_op(DataType::FLOAT32); - - // Create add node - auto add_lhs_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto add_rhs_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto add_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param add_op_params{BinaryArithmetic::ArithmeticType::ADD, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{add_lhs_idx, add_rhs_idx}, OIS{add_out_idx}, add_op_params); - - // Create sub node - auto sub_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto sub_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param sub_op_params{BinaryArithmetic::ArithmeticType::SUB, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{add_out_idx, sub_const_idx}, OIS{sub_out_idx}, sub_op_params); - - // Create mul node - auto mul_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto mul_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param mul_op_params{BinaryArithmetic::ArithmeticType::MUL, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{sub_out_idx, mul_const_idx}, OIS{mul_out_idx}, mul_op_params); - - graph->verify(); - return graph; -} - -/* Create branched graph: - * [Add] - * // \\ - * [Mul1] [FC2] - * || || - * [Mul2] [FC2] - * \\ // - * [Sub] - */ -std::shared_ptr<Graph> createBranchedGraph() -{ - auto graph = std::make_shared<Graph>(); - const TypeInfo float_op(DataType::FLOAT32); - - // Create add node - auto add_lhs_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto add_rhs_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto add_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param add_op_params{BinaryArithmetic::ArithmeticType::ADD, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{add_lhs_idx, add_rhs_idx}, OIS{add_out_idx}, add_op_params); - - // Create mul1 node - auto mul1_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto mul1_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param mul1_op_params{BinaryArithmetic::ArithmeticType::MUL, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{add_out_idx, mul1_const_idx}, OIS{mul1_out_idx}, - mul1_op_params); - - // Create mul2 node - auto mul2_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto mul2_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param mul2_op_params{BinaryArithmetic::ArithmeticType::MUL, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{mul1_out_idx, mul2_const_idx}, OIS{mul2_out_idx}, - mul2_op_params); - - // Create fc1 node - auto fc1_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto fc1_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - FullyConnected::Param fc1_op_params{Activation::NONE}; - create<FullyConnected>(graph, OIS{add_out_idx, fc1_const_idx}, OIS{fc1_out_idx}, fc1_op_params); - - // Create fc2 node - auto fc2_const_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - auto fc2_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - FullyConnected::Param fc2_op_params{Activation::NONE}; - create<FullyConnected>(graph, OIS{fc1_out_idx, fc2_const_idx}, OIS{fc2_out_idx}, fc2_op_params); - - // Create sub node - auto sub_out_idx = graph->addOperand(ir::Shape{OPERAND_ELEMS}, float_op); - BinaryArithmetic::Param sub_op_params{BinaryArithmetic::ArithmeticType::SUB, Activation::NONE}; - create<BinaryArithmetic>(graph, OIS{mul2_out_idx, fc2_out_idx}, OIS{sub_out_idx}, sub_op_params); - - graph->verify(); - return graph; -} - -// -// Tests setup/teardown -// - -// SetUp/TearDown methods runs before/after each test and performs actions common for each test -class HESchedulerTest : public ::testing::Test -{ -protected: - void SetUp() override - { - // Initialize mock backends - _cpu_backend = new MockBackendCPU(); - _gpu_backend = new MockBackendGPU(); - _npu_backend = new MockBackendNPU(); - _mock_backends = {_cpu_backend, _gpu_backend, _npu_backend}; - - // Remove previous profile data if it exists - if (!remove("exec_time.json")) - { - // DO NOTHING (no profile data) - } - - // Remember original value of 'EXECUTOR' environment variable - char *executor = std::getenv("EXECUTOR"); - _original_executor = executor == nullptr ? "" : executor; - - // Remember original value of 'PROFILING_MODE' environment variable - char *profiling_mode = std::getenv("PROFILING_MODE"); - _original_profiling_mode = profiling_mode == nullptr ? "" : profiling_mode; - } - - void TearDown() override - { - delete _cpu_backend; - delete _gpu_backend; - delete _npu_backend; - EXPECT_EQ(remove("exec_time.json"), 0); - setenv("EXECUTOR", _original_executor.c_str(), true); - setenv("PROFILING_MODE", _original_profiling_mode.c_str(), true); - } - - const MockBackendCPU *_cpu_backend{nullptr}; - const MockBackendGPU *_gpu_backend{nullptr}; - const MockBackendNPU *_npu_backend{nullptr}; - std::vector<const Backend *> _mock_backends; - - std::string _original_executor; - std::string _original_profiling_mode; -}; - -// -// HEScheduler tests -// - -class HESchedulerTestWithExecutorParam : public HESchedulerTest, - public testing::WithParamInterface<std::string> -{ -}; - -// SchedulerTestWithExecutorParam tests are parameterized with executor name and runs three times - -// one time for each executor -INSTANTIATE_TEST_CASE_P(AllExecutors, HESchedulerTestWithExecutorParam, - testing::Values(LINEAR, DATAFLOW, PARALLEL)); - -// Test scheduler behavior for straight graph with known execution time of all nodes and permutes. -TEST_P(HESchedulerTestWithExecutorParam, straight_graph_known_exec_time) -{ - setExecutor(GetParam()); - - // Prepare graph - ir::Subgraphs subgs; - auto graph(createStraightGraph()); - subgs.push(ir::SubgraphIndex{0}, graph); - OperationIndex add_op_idx(0), sub_op_idx(1), mul_op_idx(2); - - // Set default execution and transfer time - setPermutationsExecutionTime(_mock_backends, OPERAND_SIZE, 1); - setOperationsExecutionTime(_mock_backends, {"Add", "Sub", "Mul"}, - {OPERATION_SIZE, OPERATION_SIZE, OPERATION_SIZE}, 1e4); - - // Test 1 - // Expected behaviour: scheduler assigns different backend to each node - { - // For each backend reduce execution time of one node - ExecTime et(_mock_backends); - setOperationExecTime(et, _cpu_backend, "Add", false, OPERATION_SIZE, 1); - setOperationExecTime(et, _gpu_backend, "Sub", false, OPERATION_SIZE, 1); - setOperationExecTime(et, _npu_backend, "Mul", false, OPERATION_SIZE, 1); - et.storeOperationsExecTime(); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - ASSERT_EQ(br->getBackend(add_op_idx)->config()->id(), "cpu"); - ASSERT_EQ(br->getBackend(sub_op_idx)->config()->id(), "gpu"); - ASSERT_EQ(br->getBackend(mul_op_idx)->config()->id(), "npu"); - } - - // Test 2 - // Expected behaviour: scheduler assigns single backend to all nodes because of big transfer time - { - // Increase transfer time - setPermutationsExecutionTime(_mock_backends, OPERAND_SIZE, 1e5); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - ASSERT_EQ(br->getBackend(add_op_idx)->config()->id(), "cpu"); - ASSERT_EQ(br->getBackend(sub_op_idx)->config()->id(), "cpu"); - ASSERT_EQ(br->getBackend(mul_op_idx)->config()->id(), "cpu"); - } -} - -// Test scheduler behavior for branched graph with known execution time of all nodes and permutes -TEST_P(HESchedulerTestWithExecutorParam, branched_graph_known_exec_time) -{ - const int64_t NPU_ET = 5000; - setExecutor(GetParam()); - - // Prepare graph - ir::Subgraphs subgs; - auto graph(createBranchedGraph()); - subgs.push(ir::SubgraphIndex{0}, graph); - OperationIndex add_op_idx(0), mul1_op_idx(1), mul2_op_idx(2), fc1_op_idx(3), fc2_op_idx(4), - sub_op_idx(5); - - // Set default execution and transfer time - setPermutationsExecutionTime(_mock_backends, OPERAND_SIZE, 1000); - setOperationsExecutionTime(_mock_backends, {"Add", "Sub", "Mul", "FullyConnected"}, - {OPERATION_SIZE, OPERATION_SIZE, OPERATION_SIZE, OPERATION_SIZE}, 1e4); - - // Test 1 - // Expected behaviour: for dataflow and linear executors scheduler assigns fastest backend to all - // nodes, in case of parallel executor scheduler assigns different backends to branches. - { - // Reduce execution time - ExecTime et(_mock_backends); - setOperationExecTime(et, _npu_backend, "Add", false, OPERATION_SIZE, NPU_ET); - setOperationExecTime(et, _npu_backend, "Mul", false, OPERATION_SIZE, NPU_ET); - setOperationExecTime(et, _npu_backend, "Sub", false, OPERATION_SIZE, NPU_ET); - setOperationExecTime(et, _npu_backend, "FullyConnected", false, OPERATION_SIZE, NPU_ET); - setOperationExecTime(et, _gpu_backend, "Mul", false, OPERATION_SIZE, NPU_ET + 1000); - setOperationExecTime(et, _gpu_backend, "FullyConnected", false, OPERATION_SIZE, NPU_ET + 1000); - et.storeOperationsExecTime(); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - - std::string branch1_expected_backend("npu"), branch2_expected_backend("npu"); - if (GetParam() == PARALLEL) - { - branch1_expected_backend = - br->getBackend(mul1_op_idx)->config()->id() == "npu" ? "npu" : "gpu"; - branch2_expected_backend = branch1_expected_backend == "npu" ? "gpu" : "npu"; - } - - ASSERT_EQ(br->getBackend(add_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(mul1_op_idx)->config()->id(), branch1_expected_backend); - ASSERT_EQ(br->getBackend(mul2_op_idx)->config()->id(), branch1_expected_backend); - ASSERT_EQ(br->getBackend(fc1_op_idx)->config()->id(), branch2_expected_backend); - ASSERT_EQ(br->getBackend(fc2_op_idx)->config()->id(), branch2_expected_backend); - ASSERT_EQ(br->getBackend(sub_op_idx)->config()->id(), "npu"); - } - - // Test 2 - // Expected behaviour: scheduler assigns single backend to all nodes - { - // Increase execution time for GPU backend - ExecTime et(_mock_backends); - /* for parallel executor: set a time, that is larger than sum_of_other_branches_nodes_cnt * - * npu_exec_time so that npu is prefered: the ith branch will wait for npu until it finishes the - * [0;i-1] branches nodes in DFS order. In each branch it goes deep intul doesn't encounter - * branching or scheduler assigns another backend to a node*/ - setOperationExecTime(et, _gpu_backend, "Mul", false, OPERATION_SIZE, NPU_ET * 3 + 1); - setOperationExecTime(et, _gpu_backend, "FullyConnected", false, OPERATION_SIZE, NPU_ET * 3 + 1); - et.storeOperationsExecTime(); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - ASSERT_EQ(br->getBackend(add_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(mul1_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(mul2_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(fc1_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(fc2_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(sub_op_idx)->config()->id(), "npu"); - } -} - -// Test scheduler behavior for branched graph and enabled profiling mode -TEST_F(HESchedulerTest, branched_graph_profiling_mode) -{ - const int ET = 1e5; - - // Turn on profiling mode - setProfilingMode(true); - setExecutor(DATAFLOW); - - // Prepare graph - ir::Subgraphs subgs; - auto graph(createBranchedGraph()); - subgs.push(ir::SubgraphIndex{0}, graph); - OperationIndex add_op_idx(0), mul1_op_idx(1), mul2_op_idx(2), fc1_op_idx(3), fc2_op_idx(4), - sub_op_idx(5); - - // Test 1 - // Expected behaviour: scheduler assigns backends to nodes with unknown execution time - { - // Set execution time for all backends/nodes except for cpu/Sub, npu/Mul, gpu/FC - ExecTime et(_mock_backends); - setOperationExecTime(et, _cpu_backend, "Add", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _cpu_backend, "Mul", false, OPERATION_SIZE, ET + 1); - setOperationExecTime(et, _cpu_backend, "FullyConnected", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _npu_backend, "Add", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _npu_backend, "FullyConnected", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _npu_backend, "Sub", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _gpu_backend, "Add", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _gpu_backend, "Mul", false, OPERATION_SIZE, ET + 1); - setOperationExecTime(et, _gpu_backend, "Sub", false, OPERATION_SIZE, ET); - et.storeOperationsExecTime(); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - ASSERT_EQ(br->getBackend(mul1_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(mul2_op_idx)->config()->id(), "npu"); - ASSERT_EQ(br->getBackend(fc1_op_idx)->config()->id(), "gpu"); - ASSERT_EQ(br->getBackend(fc2_op_idx)->config()->id(), "gpu"); - ASSERT_EQ(br->getBackend(sub_op_idx)->config()->id(), "cpu"); - } - - // Test 2 - // Expected behaviour: scheduler shuffling backends, so different backends are assigned to - // neighbor nodes - { - // Set execution time for rest backends/nodes (cpu/Sub, npu/Mul, gpu/FC) - ExecTime et(_mock_backends); - setOperationExecTime(et, _cpu_backend, "Sub", false, OPERATION_SIZE, ET); - setOperationExecTime(et, _npu_backend, "Mul", false, OPERATION_SIZE, ET + 1); - setOperationExecTime(et, _gpu_backend, "FullyConnected", false, OPERATION_SIZE, ET); - et.storeOperationsExecTime(); - - // Test scheduler - auto scheduler = - compiler::HEScheduler(_mock_backends, compiler::fetchCompilerOptionsFromGlobalConfig(subgs)); - const auto br = scheduler.schedule(*graph); - ASSERT_NE(br->getBackend(add_op_idx)->config()->id(), - br->getBackend(mul1_op_idx)->config()->id()); - ASSERT_NE(br->getBackend(add_op_idx)->config()->id(), - br->getBackend(fc1_op_idx)->config()->id()); - ASSERT_NE(br->getBackend(mul1_op_idx)->config()->id(), - br->getBackend(mul2_op_idx)->config()->id()); - ASSERT_NE(br->getBackend(fc1_op_idx)->config()->id(), - br->getBackend(fc2_op_idx)->config()->id()); - ASSERT_NE(br->getBackend(mul2_op_idx)->config()->id(), - br->getBackend(sub_op_idx)->config()->id()); - ASSERT_NE(br->getBackend(fc2_op_idx)->config()->id(), - br->getBackend(sub_op_idx)->config()->id()); - } -} - -// TODO: Add tests with unknown execution and permutation time - -} // unnamed namespace diff --git a/runtime/onert/test/core/compiler/pass/UnusedOperandEliminationPass.cc b/runtime/onert/test/core/compiler/pass/UnusedOperandEliminationPass.cc deleted file mode 100644 index b18dedd15..000000000 --- a/runtime/onert/test/core/compiler/pass/UnusedOperandEliminationPass.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#include <gtest/gtest.h> -#include "ir/Graph.h" -#include "compiler/pass/UnusedOperandEliminationPass.h" - -using namespace onert::ir; -using namespace onert::compiler::pass; - -TEST(UnusedOperandEliminationPass, Simple) -{ - Graph graph; - - // Add tensors - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - auto in = graph.addOperand(shape, type); - auto out = graph.addOperand(shape, type); - - auto unused = graph.addOperand(shape, type); - - // Set model inputs/outputs - graph.addInput(in); - graph.addOutput(out); - - UnusedOperandEliminationPass{graph}.run(); - - ASSERT_TRUE(graph.operands().exist(in)); - ASSERT_TRUE(graph.operands().exist(out)); - ASSERT_FALSE(graph.operands().exist(unused)); -} diff --git a/runtime/onert/test/core/exec/ExecInstance.cc b/runtime/onert/test/core/exec/ExecInstance.cc deleted file mode 100644 index 0183b6276..000000000 --- a/runtime/onert/test/core/exec/ExecInstance.cc +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#include <gtest/gtest.h> -#include <thread> - -#include "ir/Graph.h" -#include "compiler/Compiler.h" -#include "exec/Execution.h" -#include "ir/operation/BinaryArithmetic.h" -#include "util/TracingCtx.h" - -namespace -{ - -using namespace onert::ir; - -class CompiledMockUpModel -{ -public: - CompiledMockUpModel() - { - // Model: two elementwise add operation - // model input: lhs, rhs1 - // model output: second add result (result2) - // constant: rhs2 - // result1 <= (lhs + rhs) - // result2 <= (result1 + rhs2) - // lhs, rhs1, rh2, result1, result2 shape: {1, 2, 2, 1} - // activation: none (constant) - graph = std::make_shared<Graph>(); - // 1st add operands (result1 <= lhs + rhs1) - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - static float rhs2_data[4] = {3, 1, -1, 5}; - auto operand_lhs = graph->addOperand(shape, type); - auto operand_rhs1 = graph->addOperand(shape, type); - auto operand_result1 = graph->addOperand(shape, type); - auto operand_rhs2 = graph->addOperand(shape, type); - auto operand_result2 = graph->addOperand(shape, type); - graph->operands() - .at(operand_rhs2) - .data(std::make_unique<CachedData>(reinterpret_cast<const uint8_t *>(&rhs2_data), 16)); - // 2nd add operations (result2 <= result1 + rhs2) - operation::BinaryArithmetic::Param param1; - param1.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param1.activation = Activation::NONE; - auto input_set1 = OperandIndexSequence{operand_lhs, operand_rhs1}; - auto output_set1 = OperandIndexSequence{operand_result1}; - graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set1, output_set1, param1)); - operation::BinaryArithmetic::Param param2; - param2.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param2.activation = Activation::NONE; - auto input_set2 = OperandIndexSequence{operand_result1, operand_rhs2}; - auto output_set2 = OperandIndexSequence{operand_result2}; - graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set2, output_set2, param2)); - // Identify model inputs and outputs - graph->addInput(operand_lhs); - graph->addInput(operand_rhs1); - graph->addOutput(operand_result2); - graph->verify(); - - // Compile - auto subgs = std::make_shared<onert::ir::Subgraphs>(); - subgs->push(onert::ir::SubgraphIndex{0}, graph); - tracing_ctx = std::make_unique<onert::util::TracingCtx>(subgs.get()); - onert::compiler::Compiler compiler{subgs, tracing_ctx.get()}; - executors = compiler.compile(); - } - -public: - std::shared_ptr<Graph> graph; - std::shared_ptr<onert::exec::ExecutorMap> executors; - std::unique_ptr<onert::util::TracingCtx> tracing_ctx; -}; - -TEST(ExecInstance, simple) -{ - auto mockup = CompiledMockUpModel(); - auto graph = mockup.graph; - auto executors = mockup.executors; - - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto output = IOIndex{0}; - - const float input1_buffer[4] = {1, 0, -1, -2}; - const float input2_buffer[4] = {1, -3, 2, -4}; - float output_buffer[4] = {}; - const float output_expected[4] = {5, -2, 0, -1}; - - onert::exec::Execution execution{executors}; - - execution.setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16); - execution.setInput(input2, reinterpret_cast<const void *>(input2_buffer), 16); - execution.setOutput(output, reinterpret_cast<void *>(output_buffer), 16); - execution.execute(); - - for (auto i = 0; i < 4; i++) - { - EXPECT_EQ(output_buffer[i], output_expected[i]); - } -} - -TEST(ExecInstance, twoCompile) -{ - auto mockup = CompiledMockUpModel(); - auto graph = mockup.graph; - auto executors1 = mockup.executors; - onert::exec::Execution execution1{executors1}; - - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto output = IOIndex{0}; - - const float exe1_input1_buffer[4] = {1, 0, -1, -2}; - const float exe1_input2_buffer[4] = {1, -3, 2, -4}; - float exe1_output_buffer[4] = {}; - const float exe1_output_expected[4] = {5, -2, 0, -1}; - - execution1.setInput(input1, reinterpret_cast<const void *>(exe1_input1_buffer), 16); - execution1.setInput(input2, reinterpret_cast<const void *>(exe1_input2_buffer), 16); - execution1.setOutput(output, reinterpret_cast<void *>(exe1_output_buffer), 16); - - // Make new executor: compile again - auto subgs = std::make_shared<onert::ir::Subgraphs>(); - subgs->push(onert::ir::SubgraphIndex{0}, graph); - auto tracing_ctx = std::make_unique<onert::util::TracingCtx>(subgs.get()); - onert::compiler::Compiler compiler{subgs, tracing_ctx.get()}; - std::shared_ptr<onert::exec::ExecutorMap> executors2 = compiler.compile(); - onert::exec::Execution execution2{executors2}; - - const float exe2_input1_buffer[4] = {2, 1, -2, 0}; - const float exe2_input2_buffer[4] = {-3, 3, 1, 2}; - float exe2_output_buffer[4] = {}; - const float exe2_output_expected[4] = {2, 5, -2, 7}; - - execution2.setInput(input1, reinterpret_cast<const void *>(exe2_input1_buffer), 16); - execution2.setInput(input2, reinterpret_cast<const void *>(exe2_input2_buffer), 16); - execution2.setOutput(output, reinterpret_cast<void *>(exe2_output_buffer), 16); - - execution1.execute(); - execution2.execute(); - - for (auto i = 0; i < 4; i++) - { - EXPECT_EQ(exe1_output_buffer[i], exe1_output_expected[i]); - EXPECT_EQ(exe2_output_buffer[i], exe2_output_expected[i]); - } -} - -// Support two initialized execution instance then ordered execution -TEST(ExecInstance, twoExecution) -{ - auto mockup = CompiledMockUpModel(); - auto executors = mockup.executors; - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto output1 = IOIndex{0}; - - const float exe1_input1_buffer[4] = {1, 0, -1, -2}; - const float exe1_input2_buffer[4] = {1, -3, 2, -4}; - float exe1_output_buffer[4] = {}; - const float exe1_output_expected[4] = {5, -2, 0, -1}; - const float exe2_output_expected[4] = {2, 5, -2, 7}; - - onert::exec::Execution execution1{executors}; - execution1.setInput(input1, reinterpret_cast<const void *>(exe1_input1_buffer), 16); - execution1.setInput(input2, reinterpret_cast<const void *>(exe1_input2_buffer), 16); - execution1.setOutput(output1, reinterpret_cast<void *>(exe1_output_buffer), 16); - - const float exe2_input1_buffer[4] = {2, 1, -2, 0}; - const float exe2_input2_buffer[4] = {-3, 3, 1, 2}; - float exe2_output_buffer[4] = {}; - - // Make new execution - onert::exec::Execution execution2{executors}; - execution2.setInput(input1, reinterpret_cast<const void *>(exe2_input1_buffer), 16); - execution2.setInput(input2, reinterpret_cast<const void *>(exe2_input2_buffer), 16); - execution2.setOutput(output1, reinterpret_cast<void *>(exe2_output_buffer), 16); - - execution1.execute(); - execution2.execute(); - - for (auto i = 0; i < 4; i++) - { - EXPECT_EQ(exe1_output_buffer[i], exe1_output_expected[i]); - EXPECT_EQ(exe2_output_buffer[i], exe2_output_expected[i]); - } -} - -class Inference -{ -public: - Inference(const float (&input1)[4], const float (&input2)[4], float (&output)[4], - std::shared_ptr<onert::exec::ExecutorMap> &executors) - : _input1{input1}, _input2{input2}, _output{output}, _executors{executors} - { - // DO NOTHING - } - - void inference(void) - { - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto output1 = IOIndex{0}; - - onert::exec::Execution execution{_executors}; - execution.setInput(input1, reinterpret_cast<const void *>(_input1), 16); - execution.setInput(input2, reinterpret_cast<const void *>(_input2), 16); - execution.setOutput(output1, reinterpret_cast<void *>(_output), 16); - - execution.execute(); - } - -private: - const float (&_input1)[4]; - const float (&_input2)[4]; - float (&_output)[4]; - std::shared_ptr<onert::exec::ExecutorMap> &_executors; -}; - -// Support multi-thread execution -TEST(ExecInstance, twoThreads) -{ - auto mockup = CompiledMockUpModel(); - auto executors = mockup.executors; - - const float exe1_input1_buffer[4] = {1, 0, -1, -2}; - const float exe1_input2_buffer[4] = {1, -3, 2, -4}; - float exe1_output_buffer[4] = {}; - const float exe1_output_expected[4] = {5, -2, 0, -1}; - - Inference execution1{exe1_input1_buffer, exe1_input2_buffer, exe1_output_buffer, executors}; - - const float exe2_input1_buffer[4] = {2, 1, -2, 0}; - const float exe2_input2_buffer[4] = {-3, 3, 1, 2}; - float exe2_output_buffer[4] = {}; - const float exe2_output_expected[4] = {2, 5, -2, 7}; - - Inference execution2{exe2_input1_buffer, exe2_input2_buffer, exe2_output_buffer, executors}; - - std::thread t1{&Inference::inference, &execution1}; - std::thread t2{&Inference::inference, &execution2}; - - t1.join(); - t2.join(); - - for (auto i = 0; i < 4; i++) - { - EXPECT_EQ(exe1_output_buffer[i], exe1_output_expected[i]); - EXPECT_EQ(exe2_output_buffer[i], exe2_output_expected[i]); - } -} - -// Support asynchronous execution -TEST(ExecInstance, async) -{ - auto mockup = CompiledMockUpModel(); - auto graph = mockup.graph; - auto executors = mockup.executors; - - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto output = IOIndex{0}; - - const float input1_buffer[4] = {1, 0, -1, -2}; - const float input2_buffer[4] = {1, -3, 2, -4}; - float output_buffer[4] = {}; - const float output_expected[4] = {5, -2, 0, -1}; - - onert::exec::Execution execution{executors}; - - execution.setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16); - execution.setInput(input2, reinterpret_cast<const void *>(input2_buffer), 16); - execution.setOutput(output, reinterpret_cast<void *>(output_buffer), 16); - execution.startExecute(); - execution.waitFinish(); - - for (auto i = 0; i < 4; i++) - { - EXPECT_EQ(output_buffer[i], output_expected[i]); - } -} - -} // namespace diff --git a/runtime/onert/test/core/exec/ExecTime.test.cc b/runtime/onert/test/core/exec/ExecTime.test.cc deleted file mode 100644 index 178b61ea5..000000000 --- a/runtime/onert/test/core/exec/ExecTime.test.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#include "exec/ExecTime.h" -#include "backend/IConfig.h" -#include "backend/Backend.h" -#include <gtest/gtest.h> -#include <string> - -namespace -{ -using namespace onert; -using namespace exec; -using namespace backend; - -struct MockConfig : public IConfig -{ - std::string id() override { return "b1"; } - bool initialize() override { return true; }; - bool supportPermutation() override { return false; } - ir::Layout supportLayout(const ir::Operation &, ir::Layout) override - { - return ir::Layout::UNKNOWN; - } - bool supportDynamicTensor() override { return false; } - bool supportFP16() override { return false; } -}; - -struct MockBackend : public ::onert::backend::Backend -{ - std::shared_ptr<onert::backend::IConfig> config() const override - { - return std::make_shared<MockConfig>(); - } - std::unique_ptr<onert::backend::BackendContext> newContext(ContextData &&) const override - { - return nullptr; - } -}; - -TEST(ExecTime, roundtrip_ok) -{ - const auto *b = new MockBackend(); - std::vector<const Backend *> bs = {b}; - { - ExecTime et(bs); - et.updateOperationExecTime(b, "op1", true, 100, 100); - et.updateOperationExecTime(b, "op1", true, 200, 200); - et.updateOperationExecTime(b, "op1", false, 100, 888); - et.storeOperationsExecTime(); - } - { - ExecTime et(bs); - auto time = et.getOperationExecTime(b, "op1", true, 100); - ASSERT_EQ(time, 100); - // Check interpolation - time = et.getOperationExecTime(b, "op1", true, 150); - ASSERT_EQ(time, 150); - time = et.getOperationExecTime(b, "op1", false, 100); - ASSERT_EQ(time, 888); - et.storeOperationsExecTime(); - } - // clean up - EXPECT_EQ(remove("exec_time.json"), 0); -} - -TEST(ExecTime, structure) -{ - - const auto *b = new MockBackend(); - std::vector<const Backend *> bs = {b}; - { - ExecTime et(bs); - et.updateOperationExecTime(b, "op1", true, 100, 100); - et.updateOperationExecTime(b, "op1", true, 200, 200); - et.storeOperationsExecTime(); - } - { - ExecTime et(bs); - auto time = et.getOperationExecTime(b, "op1", true, 100); - ASSERT_EQ(time, 100); - // Check interpolation - time = et.getOperationExecTime(b, "op1", true, 200); - ASSERT_EQ(time, 200); - et.storeOperationsExecTime(); - } - // clean up - EXPECT_EQ(remove("exec_time.json"), 0); -} -} // unnamed namespace diff --git a/runtime/onert/test/core/interp/ExecManager.cc b/runtime/onert/test/core/interp/ExecManager.cc deleted file mode 100644 index a9f7cd46a..000000000 --- a/runtime/onert/test/core/interp/ExecManager.cc +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#include <gtest/gtest.h> - -#include <memory> - -#include "ir/Graph.h" -#include "interp/InterpExecutor.h" -#include "exec/Execution.h" -#include "ir/operation/BinaryArithmetic.h" - -namespace -{ - -using namespace onert::ir; -using InterpExecutor = onert::interp::InterpExecutor; -using Execution = onert::exec::Execution; -using ExecutorMap = onert::exec::ExecutorMap; - -class InterpExecutorTest : public ::testing::Test -{ -protected: - virtual void SetUp() {} - void CreateSimpleModel() - { - // Model: one elementwise add operation - // model input: lhs, rhs - // model output: add result - // lhs, rhs, result shape: {1, 2, 2, 1} - // activation: none (constant) - _graph = std::make_unique<Graph>(); - - // Add operands - - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::INT32}; - Shape shape_scalar(0); - TypeInfo type_scalar{DataType::INT32}; - - auto operand_lhs = _graph->addOperand(shape, type); - auto operand_rhs = _graph->addOperand(shape, type); - auto operand_result = _graph->addOperand(shape, type); - - // Add operations - - operation::BinaryArithmetic::Param param; - param.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param.activation = Activation::NONE; - auto input_set = OperandIndexSequence{operand_lhs, operand_rhs}; - auto output_set = OperandIndexSequence{operand_result}; - _graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set, output_set, param)); - - // Identify model inputs and outputs - - _graph->getInputs().append(operand_lhs); - _graph->getInputs().append(operand_rhs); - _graph->getOutputs().append(operand_result); - - _graph->verify(); - - auto subgs = std::make_shared<onert::ir::Subgraphs>(); - subgs->push(onert::ir::SubgraphIndex{0}, _graph); - _graph->setSubgraphs(subgs); - - _executors = std::make_shared<ExecutorMap>(); - _executors->insert( - std::make_pair(onert::ir::SubgraphIndex{0}, std::make_unique<InterpExecutor>(*_graph))); - } - - void CreateTwoStepModel() - { - // Model: two elementwise add operation - // model input: lhs, rhs1 - // model output: second add result (result2) - // constant: rhs2 - // result1 <= (lhs + rhs) - // result2 <= (result1 + rhs2) - // lhs, rhs1, rh2, result1, result2 shape: {1, 2, 2, 1} - // activation: none (constant) - _graph = std::make_unique<Graph>(); - - // 1st add operands (result1 <= lhs + rhs1) - - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::INT32}; - Shape shape_scalar(0); - TypeInfo type_scalar{DataType::INT32}; - - static int32_t rhs2_data[4] = {3, 1, -1, 5}; - - auto operand_lhs = _graph->addOperand(shape, type); - auto operand_rhs1 = _graph->addOperand(shape, type); - auto operand_result1 = _graph->addOperand(shape, type); - auto operand_rhs2 = _graph->addOperand(shape, type); - auto operand_result2 = _graph->addOperand(shape, type); - _graph->operands() - .at(operand_rhs2) - .data(std::make_unique<CachedData>(reinterpret_cast<const uint8_t *>(&rhs2_data), 16)); - - // 2nd add operations (result2 <= result1 + rhs2) - - operation::BinaryArithmetic::Param param1; - param1.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param1.activation = Activation::NONE; - auto input_set1 = OperandIndexSequence{operand_lhs, operand_rhs1}; - auto output_set1 = OperandIndexSequence{operand_result1}; - _graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set1, output_set1, param1)); - - operation::BinaryArithmetic::Param param2; - param2.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param2.activation = Activation::NONE; - auto input_set2 = OperandIndexSequence{operand_result1, operand_rhs2}; - auto output_set2 = OperandIndexSequence{operand_result2}; - _graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set2, output_set2, param2)); - - // Identify model inputs and outputs - - _graph->getInputs().append(operand_lhs); - _graph->getInputs().append(operand_rhs1); - _graph->getOutputs().append(operand_result2); - - _graph->verify(); - - auto subgs = std::make_shared<onert::ir::Subgraphs>(); - subgs->push(onert::ir::SubgraphIndex{0}, _graph); - _graph->setSubgraphs(subgs); - - _executors = std::make_shared<ExecutorMap>(); - _executors->insert( - std::make_pair(onert::ir::SubgraphIndex{0}, std::make_unique<InterpExecutor>(*_graph))); - } - - void CreateUnspecifiedDimensionsModel() - { - // Model: one elementwise add operation - // model input: lhs, rhs - // model output: add result - // lhs, rhs, result shape: {1, unknown, 2, 1} - // activation: none (constant) - _graph = std::make_unique<Graph>(); - - // Add operands - - Shape shape{1, 0, 2, 1}; - TypeInfo type{DataType::INT32}; - Shape shape_scalar(0); - TypeInfo type_scalar{DataType::INT32}; - - auto operand_lhs = _graph->addOperand(shape, type); - auto operand_rhs = _graph->addOperand(shape, type); - - auto operand_activation = _graph->addOperand(shape_scalar, type_scalar); - _graph->operands() - .at(operand_activation) - .data(std::make_unique<CachedData>(reinterpret_cast<const uint8_t *>(&_activation_value), 4)); - - auto operand_result = _graph->addOperand(shape, type); - - // Add operations - - operation::BinaryArithmetic::Param param; - param.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param.activation = Activation::NONE; - auto input_set = OperandIndexSequence{operand_lhs, operand_rhs}; - auto output_set = OperandIndexSequence{operand_result}; - _graph->addOperation( - std::make_unique<operation::BinaryArithmetic>(input_set, output_set, param)); - - // Identify model inputs and outputs - - _graph->getInputs().append(operand_lhs); - _graph->getInputs().append(operand_rhs); - _graph->getOutputs().append(operand_result); - - _graph->verify(); - - auto subgs = std::make_shared<onert::ir::Subgraphs>(); - subgs->push(onert::ir::SubgraphIndex{0}, _graph); - _graph->setSubgraphs(subgs); - - _executors = std::make_shared<ExecutorMap>(); - _executors->insert( - std::make_pair(onert::ir::SubgraphIndex{0}, std::make_unique<InterpExecutor>(*_graph))); - } - - void createExecution() { _execution = std::make_unique<Execution>(_executors); } - - virtual void TearDown() { _executors = nullptr; } - - std::shared_ptr<Graph> _graph{nullptr}; - std::shared_ptr<ExecutorMap> _executors{nullptr}; - std::unique_ptr<Execution> _execution{nullptr}; - const int32_t _activation_value{0}; -}; - -TEST_F(InterpExecutorTest, create_empty) -{ - Graph graph; - graph.verify(); - auto executor = std::make_unique<InterpExecutor>(graph); - ASSERT_NE(executor, nullptr); -} - -TEST_F(InterpExecutorTest, create_simple) -{ - CreateSimpleModel(); - ASSERT_NE(_executors, nullptr); - ASSERT_NE(_executors->at(onert::ir::SubgraphIndex{0}), nullptr); -} - -TEST_F(InterpExecutorTest, neg_setInput) -{ - CreateSimpleModel(); - createExecution(); - - auto input1 = IOIndex{0}; - const int32_t input1_buffer[4] = {1, 0, -1, -2}; - - EXPECT_THROW(_execution->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 4), - std::runtime_error); - EXPECT_THROW(_execution->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 12), - std::runtime_error); - EXPECT_NO_THROW(_execution->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16)); -} - -TEST_F(InterpExecutorTest, neg_setOutput) -{ - CreateSimpleModel(); - createExecution(); - - auto output = IOIndex{0}; - auto output_idx = _graph->getOutputs().at(output); - - int32_t output_buffer[4] = {}; - - EXPECT_THROW(_execution->setOutput(output, reinterpret_cast<void *>(output_buffer), 4), - std::runtime_error); - EXPECT_THROW(_execution->setOutput(output, reinterpret_cast<void *>(output_buffer), 12), - std::runtime_error); - EXPECT_NO_THROW(_execution->setOutput(output, reinterpret_cast<void *>(output_buffer), 16)); -} - -TEST_F(InterpExecutorTest, neg_setInputForUnspecifiedDimensions) -{ - CreateUnspecifiedDimensionsModel(); - createExecution(); - - auto input1 = IOIndex{0}; - const int32_t input1_buffer[4] = {1, 0, -1, -2}; - - TypeInfo operand_type{DataType::INT32}; - Shape operand_shape{1, 2, 2, 1}; - - EXPECT_THROW(_execution->setInput(input1, operand_type, operand_shape, - reinterpret_cast<const void *>(input1_buffer), 4), - std::runtime_error); - EXPECT_THROW(_execution->setInput(input1, operand_type, operand_shape, - reinterpret_cast<const void *>(input1_buffer), 12), - std::runtime_error); - EXPECT_NO_THROW(_execution->setInput(input1, operand_type, operand_shape, - reinterpret_cast<const void *>(input1_buffer), 16)); -} - -TEST_F(InterpExecutorTest, neg_setOutputForUnspecifiedDimensions) -{ - CreateUnspecifiedDimensionsModel(); - createExecution(); - - auto output = IOIndex{0}; - auto output_idx = _graph->getOutputs().at(output); - - TypeInfo operand_type{DataType::INT32}; - Shape operand_shape{1, 2, 2, 1}; - - int32_t output_buffer[4] = {}; - - EXPECT_THROW(_execution->setOutput(output, operand_type, operand_shape, - reinterpret_cast<void *>(output_buffer), 4), - std::runtime_error); - EXPECT_THROW(_execution->setOutput(output, operand_type, operand_shape, - reinterpret_cast<void *>(output_buffer), 12), - std::runtime_error); - EXPECT_NO_THROW(_execution->setOutput(output, operand_type, operand_shape, - reinterpret_cast<void *>(output_buffer), 16)); -} - -TEST_F(InterpExecutorTest, execute) -{ - CreateSimpleModel(); - createExecution(); - - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto input1_idx = _graph->getInputs().at(input1); - auto input2_idx = _graph->getInputs().at(input2); - - const int32_t input1_buffer[4] = {1, 0, -1, -2}; - const int32_t input2_buffer[4] = {1, -3, 2, -4}; - - auto output = IOIndex{0}; - auto output_idx = _graph->getOutputs().at(output); - - int32_t output_buffer[4] = {}; - - EXPECT_NO_THROW(_execution->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16)); - EXPECT_NO_THROW(_execution->setInput(input2, reinterpret_cast<const void *>(input2_buffer), 16)); - EXPECT_NO_THROW(_execution->setOutput(output, reinterpret_cast<void *>(output_buffer), 16)); - EXPECT_NO_THROW(_execution->execute()); - EXPECT_EQ(output_buffer[0], 2); - EXPECT_EQ(output_buffer[1], -3); - EXPECT_EQ(output_buffer[2], 1); - EXPECT_EQ(output_buffer[3], -6); -} - -TEST_F(InterpExecutorTest, executeTwoStep) -{ - CreateTwoStepModel(); - createExecution(); - - auto input1 = IOIndex{0}; - auto input2 = IOIndex{1}; - auto input1_idx = _graph->getInputs().at(input1); - auto input2_idx = _graph->getInputs().at(input2); - - const int32_t input1_buffer[4] = {1, 0, -1, -2}; - const int32_t input2_buffer[4] = {1, -3, 2, -4}; - - auto output = IOIndex{0}; - auto output_idx = _graph->getOutputs().at(output); - - int32_t output_buffer[4] = {}; - - EXPECT_NO_THROW(_execution->setInput(input1, reinterpret_cast<const void *>(input1_buffer), 16)); - EXPECT_NO_THROW(_execution->setInput(input2, reinterpret_cast<const void *>(input2_buffer), 16)); - EXPECT_NO_THROW(_execution->setOutput(output, reinterpret_cast<void *>(output_buffer), 16)); - EXPECT_NO_THROW(_execution->execute()); - EXPECT_EQ(output_buffer[0], 5); - EXPECT_EQ(output_buffer[1], -2); - EXPECT_EQ(output_buffer[2], 0); - EXPECT_EQ(output_buffer[3], -1); -} - -} // namespace diff --git a/runtime/onert/test/core/ir/Graph.cc b/runtime/onert/test/core/ir/Graph.cc deleted file mode 100644 index d6de7c0cc..000000000 --- a/runtime/onert/test/core/ir/Graph.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Graph.h" -#include "ir/operation/BinaryArithmetic.h" -#include "ir/verifier/Verifier.h" - -TEST(Graph, neg_inputs_and_outputs) -{ - onert::ir::Graph graph; - - onert::ir::OperandIndex index0{0u}; - onert::ir::OperandIndex index1{1u}; - - graph.addInput({index0}); - graph.addInput({index1}); - - onert::ir::OperandIndex index10{10u}; - onert::ir::OperandIndex index11{11u}; - onert::ir::OperandIndex index12{12u}; - - graph.addOutput({index10}); - graph.addOutput({index11}); - graph.addOutput({index12}); - - ASSERT_EQ(graph.getInputs().size(), 2); - ASSERT_EQ(graph.getOutputs().size(), 3); - - onert::ir::IOIndex io_index0{0}; - onert::ir::IOIndex io_index1{1}; - onert::ir::IOIndex io_index2{2}; - - ASSERT_EQ(graph.getInputs().at(io_index0), 0); - ASSERT_EQ(graph.getInputs().at(io_index1), 1); - - ASSERT_EQ(graph.getOutputs().at(io_index0), 10); - ASSERT_EQ(graph.getOutputs().at(io_index1), 11); - ASSERT_EQ(graph.getOutputs().at(io_index2), 12); - - EXPECT_THROW(graph.getOutputs().at(onert::ir::IOIndex{3}), std::out_of_range); -} - -using namespace onert::ir; - -OperationIndex addAddOperation(Graph &graph, const OperandIndexSequence inputs, - const OperandIndexSequence outputs) -{ - // Add "ADD" operation - operation::BinaryArithmetic::Param param; - param.arithmetic_type = operation::BinaryArithmetic::ArithmeticType::ADD; - param.activation = Activation::NONE; - return graph.addOperation(std::make_unique<operation::BinaryArithmetic>(inputs, outputs, param)); -} - -TEST(Graph, OneOpGraphSimpleValid) -{ - // Simple Graph with just one Add operation - - Graph graph; - - // Add tensors - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - auto lhs = graph.addOperand(shape, type); - auto rhs = graph.addOperand(shape, type); - auto res = graph.addOperand(shape, type); - - addAddOperation(graph, {lhs, rhs}, {res}); - - // Set model inputs/outputs - graph.addInput(lhs); - graph.addInput(rhs); - graph.addOutput(res); - - graph.verify(); - - SUCCEED(); -} - -TEST(Graph, neg_InvalidGraph_BadInput) -{ - Graph graph; - - // Add tensors - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - auto in = graph.addOperand(shape, type); - auto out = graph.addOperand(shape, type); - - // Set model inputs/outputs - graph.addInput(in); - graph.addOutput(out); - graph.addInput(OperandIndex{89}); // Non-exisiting operand! - - EXPECT_ANY_THROW(graph.verify()); -} - -TEST(Graph, neg_InvalidGraph_BadOutput) -{ - Graph graph; - - // Add tensors - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - auto in = graph.addOperand(shape, type); - auto out = graph.addOperand(shape, type); - - // Set model inputs/outputs - graph.addInput(in); - graph.addOutput(out); - graph.addOutput(OperandIndex{12}); // Non-exisiting operand! - - EXPECT_ANY_THROW(graph.verify()); -} - -TEST(Graph, neg_InvalidAddOperation_BadInputIndex) -{ - Graph graph; - - // Add tensors - Shape shape{1, 2, 2, 1}; - TypeInfo type{DataType::FLOAT32}; - auto lhs = graph.addOperand(shape, type); - auto rhs = graph.addOperand(shape, type); - auto res = graph.addOperand(shape, type); - - // Set model inputs/outputs - graph.addInput(lhs); - graph.addInput(rhs); - graph.addOutput(res); - - ASSERT_FALSE(addAddOperation(graph, {lhs, OperandIndex{99}}, {res}).valid()); -} diff --git a/runtime/onert/test/core/ir/LayoutSet.cc b/runtime/onert/test/core/ir/LayoutSet.cc deleted file mode 100644 index 591710a4d..000000000 --- a/runtime/onert/test/core/ir/LayoutSet.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/LayoutSet.h" - -using onert::ir::Layout; -using onert::ir::LayoutSet; - -TEST(ir_LayoutSet, neg_add_remove) -{ - LayoutSet set{Layout::NCHW}; - set.remove(Layout::NHWC); - ASSERT_EQ(set.size(), 1); - set.add(Layout::NHWC); - ASSERT_EQ(set.size(), 2); - set.remove(Layout::NHWC); - ASSERT_EQ(set.size(), 1); - set.remove(Layout::NCHW); - ASSERT_EQ(set.size(), 0); - set.remove(Layout::NCHW); - ASSERT_EQ(set.size(), 0); -} - -TEST(ir_LayoutSet, neg_add_twice) -{ - LayoutSet set; - set.add(Layout::NHWC); - ASSERT_EQ(set.size(), 1); - set.add(Layout::NHWC); - ASSERT_EQ(set.size(), 1); -} - -TEST(ir_LayoutSet, set_operators) -{ - LayoutSet set1{Layout::NCHW}; - LayoutSet set2{Layout::NHWC}; - LayoutSet set3 = set1 | set2; - - ASSERT_EQ(set3.size(), 2); - - ASSERT_EQ((set3 - set1).size(), 1); - ASSERT_EQ((set3 - set1).contains(Layout::NHWC), true); - ASSERT_EQ((set3 - set2).size(), 1); - ASSERT_EQ((set3 - set2).contains(Layout::NCHW), true); - ASSERT_EQ((set3 - set3).size(), 0); - - ASSERT_EQ((set3 & set1).size(), 1); - ASSERT_EQ((set3 & set1).contains(Layout::NCHW), true); - ASSERT_EQ((set3 & set2).size(), 1); - ASSERT_EQ((set3 & set2).contains(Layout::NHWC), true); - ASSERT_EQ((set1 & set2).size(), 0); -} diff --git a/runtime/onert/test/core/ir/MockNode.h b/runtime/onert/test/core/ir/MockNode.h deleted file mode 100644 index 0e7ed977b..000000000 --- a/runtime/onert/test/core/ir/MockNode.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 __ONERT_TEST_GRAPH_MOCK_NODE_H__ -#define __ONERT_TEST_GRAPH_MOCK_NODE_H__ - -#include "ir/Operation.h" -#include "ir/OperandIndexSequence.h" - -namespace onert_test -{ -namespace ir -{ - -class SimpleMock : public onert::ir::Operation -{ -public: - SimpleMock(const onert::ir::OperandIndexSequence &inputs, - const onert::ir::OperandIndexSequence &outputs) - : Operation{onert::ir::OperandConstraint::createAny()} - { - setInputs(inputs); - setOutputs(outputs); - } - -public: - void accept(onert::ir::OperationVisitor &) const override {} - onert::ir::OpCode opcode() const final { return onert::ir::OpCode::Invalid; } -}; - -} // namespace ir -} // namespace onert_test - -#endif // __ONERT_TEST_GRAPH_MOCK_NODE_H__ diff --git a/runtime/onert/test/core/ir/OperandIndexSet.cc b/runtime/onert/test/core/ir/OperandIndexSet.cc deleted file mode 100644 index c363e5472..000000000 --- a/runtime/onert/test/core/ir/OperandIndexSet.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/OperandIndexSequence.h" - -using onert::ir::OperandIndex; -using onert::ir::OperandIndexSequence; - -TEST(ir_OperandIndexSequence, neg_append) -{ - OperandIndexSequence iset{0, 2, 4, 8}; - - ASSERT_EQ(iset.size(), 4); - - iset.append(OperandIndex{10}); - - ASSERT_EQ(iset.size(), 5); - - onert::ir::IOIndex index1{1}; - onert::ir::IOIndex index2{4}; - - ASSERT_EQ(iset.at(index1), 2); - ASSERT_EQ(iset.at(index2), 10); - - ASSERT_TRUE(iset.contains(OperandIndex{2})); - ASSERT_TRUE(iset.contains(OperandIndex{10})); - ASSERT_FALSE(iset.contains(OperandIndex{11})); -} - -TEST(graph_OperandIndexSequence, neg_replace) -{ - OperandIndexSequence iset{0, 1, 2, 3}; - - iset.replace(OperandIndex{1}, OperandIndex{9}); - ASSERT_FALSE(iset.contains(OperandIndex{1})); - ASSERT_TRUE(iset.contains(OperandIndex{9})); -} diff --git a/runtime/onert/test/core/ir/OperandSet.cc b/runtime/onert/test/core/ir/OperandSet.cc deleted file mode 100644 index 6cf9c8842..000000000 --- a/runtime/onert/test/core/ir/OperandSet.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Operands.h" - -TEST(ir_Operands, neg_set_test) -{ - onert::ir::Operands set; - - onert::ir::Shape shape0{1, 2, 3}; - - onert::ir::Shape shape1(4); - shape1.dim(0) = 10; - shape1.dim(1) = 20; - shape1.dim(2) = 30; - shape1.dim(3) = 40; - - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - set.emplace(shape0, type); - set.emplace(shape1, type); - - ASSERT_EQ(set.exist(onert::ir::OperandIndex{0u}), true); - ASSERT_EQ(set.exist(onert::ir::OperandIndex{1u}), true); - ASSERT_EQ(set.exist(onert::ir::OperandIndex{2u}), false); - - ASSERT_EQ(set.at(onert::ir::OperandIndex{0u}).shape().dim(0), 1); - ASSERT_EQ(set.at(onert::ir::OperandIndex{0u}).shape().dim(1), 2); - ASSERT_EQ(set.at(onert::ir::OperandIndex{0u}).shape().dim(2), 3); -} diff --git a/runtime/onert/test/core/ir/OperationSet.cc b/runtime/onert/test/core/ir/OperationSet.cc deleted file mode 100644 index 4a17eeb33..000000000 --- a/runtime/onert/test/core/ir/OperationSet.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "MockNode.h" -#include "ir/Operations.h" - -using onert::ir::Operation; -using onert::ir::OperationIndex; -using onert::ir::Operations; - -TEST(ir_Operations, basic) -{ - Operations ops; - ops.push(std::unique_ptr<Operation>(new onert_test::ir::SimpleMock({1, 2, 3, 4}, {5, 6, 7}))); - OperationIndex idx{0u}; - ASSERT_EQ(ops.at(idx).getInputs().size(), 4); - ASSERT_EQ(ops.at(idx).getOutputs().size(), 3); -} - -TEST(ir_Operations, neg_at) -{ - Operations ops; - ops.push(std::unique_ptr<Operation>(new onert_test::ir::SimpleMock({1, 2, 3, 4}, {5, 6, 7}))); - OperationIndex idx{99u}; - EXPECT_THROW(ops.at(idx), std::out_of_range); -} diff --git a/runtime/onert/test/core/ir/SetIO.cc b/runtime/onert/test/core/ir/SetIO.cc deleted file mode 100644 index 68b477347..000000000 --- a/runtime/onert/test/core/ir/SetIO.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Graph.h" -#include "ir/Index.h" -#include "ir/OperandIndexSequence.h" -#include "ir/operation/Conv2D.h" -#include "ir/operation/Concat.h" - -#include <memory> - -#include <stdexcept> - -using Index = onert::ir::IOIndex; -using IndexSet = onert::ir::OperandIndexSequence; - -TEST(ir_Operation_setIO, operation_setIO_conv) -{ - onert::ir::Graph graph; - - onert::ir::Shape shape{3}; - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - // Add Conv - using Graph = onert::ir::operation::Conv2D; - - auto input_operand = graph.addOperand(shape, type); - auto kernel_operand = graph.addOperand(shape, type); - auto bias_operand = graph.addOperand(shape, type); - IndexSet inputs{input_operand, kernel_operand, bias_operand}; - - Graph::Param conv_params; - conv_params.padding.type = onert::ir::PaddingType::SAME; - conv_params.stride.horizontal = 1; - conv_params.stride.vertical = 1; - conv_params.activation = onert::ir::Activation::NONE; - - auto output_operand = graph.addOperand(shape, type).value(); - IndexSet outputs{output_operand}; - - auto conv = std::make_unique<Graph>(inputs, outputs, conv_params); - - ASSERT_NE(conv, nullptr); - ASSERT_EQ(conv->getInputs().at(Index{0}).value(), inputs.at(0).value()); - conv->setInputs({8, 9, 10}); - ASSERT_NE(conv->getInputs().at(Index{0}).value(), inputs.at(0).value()); - ASSERT_EQ(conv->getInputs().at(Index{0}).value(), 8); -} - -TEST(ir_Operation_setIO, neg_operation_setIO_concat) -{ - onert::ir::Graph graph; - - onert::ir::Shape shape{3}; - - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - using Graph = onert::ir::operation::Concat; - - // Add Concat - IndexSet inputs; - for (int i = 0; i < 6; ++i) - { - inputs.append(graph.addOperand(shape, type)); - } - - Graph::Param concat_params{0}; - - auto output_operand = graph.addOperand(shape, type).value(); - IndexSet outputs{output_operand}; - - auto concat = std::make_unique<Graph>(inputs, outputs, concat_params); - - ASSERT_NE(concat, nullptr); - ASSERT_EQ(concat->getInputs().size(), 6); - ASSERT_EQ(concat->getInputs().at(Index{0}).value(), inputs.at(0).value()); - - concat->setInputs({80, 6, 9, 11}); - ASSERT_EQ(concat->getInputs().size(), 4); - ASSERT_NE(concat->getInputs().at(Index{0}).value(), inputs.at(0).value()); - ASSERT_EQ(concat->getInputs().at(Index{0}).value(), 80); - ASSERT_EQ(concat->getInputs().at(Index{2}).value(), 9); - ASSERT_THROW(concat->getInputs().at(Index{5}), std::out_of_range); -} diff --git a/runtime/onert/test/core/ir/Shape.cc b/runtime/onert/test/core/ir/Shape.cc deleted file mode 100644 index c24aeda8d..000000000 --- a/runtime/onert/test/core/ir/Shape.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ - -#include <ir/Shape.h> - -#include <gtest/gtest.h> - -TEST(ShapeTest, basic_test) -{ - { - onert::ir::Shape shape(3); - - shape.dim(0) = 1; - shape.dim(1) = 2; - shape.dim(2) = 3; - - ASSERT_EQ(shape.rank(), 3); - ASSERT_EQ(shape.num_elements(), 6); - ASSERT_EQ(onert::ir::rankMaybeUnspecified(shape), false); - ASSERT_EQ(shape.hasUnspecifiedDims(), false); - } - { - onert::ir::Shape shape; // scalar or rank is unspecified - - ASSERT_EQ(shape.rank(), 0); - ASSERT_EQ(shape.num_elements(), 1); - ASSERT_EQ(onert::ir::rankMaybeUnspecified(shape), true); - ASSERT_EQ(shape.hasUnspecifiedDims(), false); - } -} - -TEST(ShapeTest, neg_basic_test) -{ - { - onert::ir::Shape shape(2); - - shape.dim(0) = 1; - shape.dim(1) = onert::ir::Shape::UNSPECIFIED_DIM; - - ASSERT_EQ(shape.rank(), 2); - ASSERT_EQ(onert::ir::rankMaybeUnspecified(shape), false); - ASSERT_EQ(shape.hasUnspecifiedDims(), true); - EXPECT_ANY_THROW(shape.num_elements()); - } -} diff --git a/runtime/onert/test/core/ir/UseDef.cc b/runtime/onert/test/core/ir/UseDef.cc deleted file mode 100644 index 47c98f939..000000000 --- a/runtime/onert/test/core/ir/UseDef.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Graph.h" -#include "ir/verifier/Verifier.h" -#include <memory> -#include "MockNode.h" - -#include <typeindex> - -namespace -{ - -using IndexSet = onert::ir::OperandIndexSequence; -using Mock = onert_test::ir::SimpleMock; - -} // namespace - -TEST(ir_Operand, neg_usedef) -{ - onert::ir::Graph graph; - onert::ir::verifier::DAGChecker verifier; - - onert::ir::Shape shape(3); - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - // Model Input/Output - auto input_operand = graph.addOperand(shape, type); - auto output_operand = graph.addOperand(shape, type); - - graph.addInput(input_operand); - graph.addOutput(output_operand); - - // MockNode1 - auto operand_index1 = graph.addOperand(shape, type); - auto mocknode_index1 = - graph.addOperation(std::make_unique<Mock>(IndexSet{input_operand}, IndexSet{operand_index1})); - - // MockNode2 - auto operand_index2 = graph.addOperand(shape, type); - auto mocknode_index2 = - graph.addOperation(std::make_unique<Mock>(IndexSet{input_operand}, IndexSet{operand_index2})); - - // MockNode3(two input) - auto multiinput_index = graph.addOperation( - std::make_unique<Mock>(IndexSet{operand_index1, operand_index2}, IndexSet{output_operand})); - - graph.verify(); - - ASSERT_TRUE(verifier.verify(graph)); - - // Check def - ASSERT_EQ(graph.operands().at(operand_index1).getDef(), mocknode_index1); - ASSERT_EQ(graph.operands().at(operand_index2).getDef(), mocknode_index2); - ASSERT_EQ(graph.operands().at(output_operand).getDef(), multiinput_index); - - ASSERT_NE(graph.operands().at(operand_index1).getDef(), mocknode_index2); - ASSERT_NE(graph.operands().at(operand_index1).getDef(), multiinput_index); - - // Check use - ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(mocknode_index1), true); - ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(mocknode_index2), true); - ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(multiinput_index), false); - ASSERT_EQ(graph.operands().at(operand_index1).getUses().contains(multiinput_index), true); - ASSERT_EQ(graph.operands().at(operand_index2).getUses().contains(multiinput_index), true); - - ASSERT_EQ(graph.operands().at(input_operand).getUses().size(), 2); - ASSERT_EQ(graph.operands().at(operand_index1).getUses().size(), 1); - ASSERT_EQ(graph.operands().at(output_operand).getUses().size(), 0); -} diff --git a/runtime/onert/test/core/ir/Verifier.cc b/runtime/onert/test/core/ir/Verifier.cc deleted file mode 100644 index b4be2d9cd..000000000 --- a/runtime/onert/test/core/ir/Verifier.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Operation.h" -#include "ir/Graph.h" -#include "ir/verifier/Verifier.h" -#include <memory> -#include "ir/Operand.h" -#include "MockNode.h" - -using IndexSet = onert::ir::OperandIndexSequence; -using Mock = onert_test::ir::SimpleMock; - -TEST(Verifier, dag_checker) -{ - onert::ir::Graph graph; - - onert::ir::Shape shape{3}; - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - auto operand1 = graph.addOperand(shape, type); - auto operand2 = graph.addOperand(shape, type); - - graph.addInput(operand1); - graph.addOutput(operand2); - - graph.addOperation(std::make_unique<Mock>(IndexSet{operand1}, IndexSet{operand2})); - - onert::ir::verifier::DAGChecker verifier; - - ASSERT_TRUE(verifier.verify(graph)); -} - -TEST(Verifier, neg_edge_consistency_checker_1) -{ - onert::ir::Graph graph; - - onert::ir::Shape shape{3}; - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - auto operand1 = graph.addOperand(shape, type); - auto operand2 = graph.addOperand(shape, type); - - graph.addInput(operand1); - graph.addOutput(operand2); - - auto mock_op = std::make_unique<Mock>(IndexSet{operand1}, IndexSet{operand2}); - auto op_ind = graph.addOperation(std::move(mock_op)); - - graph.operands().at(operand1).removeUse(op_ind); // Manipulate the operand alone - - onert::ir::verifier::EdgeChecker verifier; - ASSERT_FALSE(verifier.verify(graph)); -} - -TEST(Verifier, neg_edge_consistency_checker_2) -{ - onert::ir::Graph graph; - - onert::ir::Shape shape{3}; - onert::ir::TypeInfo type{onert::ir::DataType::INT32}; - - auto operand1 = graph.addOperand(shape, type); - auto operand2 = graph.addOperand(shape, type); - - graph.addInput(operand1); - graph.addOutput(operand2); - - auto mock_op = std::make_unique<Mock>(IndexSet{operand1}, IndexSet{operand2}); - auto mock_op_ptr = mock_op.get(); - auto op_ind = graph.addOperation(std::move(mock_op)); - - mock_op_ptr->setInputs({operand2}); // Manipulate the operation alone - - onert::ir::verifier::EdgeChecker verifier; - ASSERT_FALSE(verifier.verify(graph)); -} diff --git a/runtime/onert/test/core/util/Index.cc b/runtime/onert/test/core/util/Index.cc deleted file mode 100644 index 2d110e326..000000000 --- a/runtime/onert/test/core/util/Index.cc +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - */ - -#include <gtest/gtest.h> - -#include "util/Index.h" - -using Index = ::onert::util::Index<uint32_t, struct TestTag>; - -TEST(Index, neg_index_test) -{ - Index idx1{1u}; - Index idx2{2u}; - Index idx3{idx1}; - - ASSERT_EQ(idx1, 1); - ASSERT_EQ(idx1, 1u); - ASSERT_EQ(idx1.value(), 1u); - ASSERT_NE(idx1, idx2); - ASSERT_EQ(idx1, idx3); -} diff --git a/runtime/onert/test/core/util/ObjectManager.cc b/runtime/onert/test/core/util/ObjectManager.cc deleted file mode 100644 index 78f044e56..000000000 --- a/runtime/onert/test/core/util/ObjectManager.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2020 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. - */ - -#include <gtest/gtest.h> - -#include "util/ObjectManager.h" -#include "util/Index.h" - -using namespace onert; - -struct TestTag; -using Index = typename util::Index<uint32_t, TestTag>; - -TEST(ObjectManager, emplace) -{ - util::ObjectManager<Index, int> man; - - auto index = man.emplace(100); - ASSERT_EQ(man.at(index), 100); -} - -TEST(ObjectManager, neg_remove_1) -{ - util::ObjectManager<Index, int> man; - - Index index = man.emplace(100); - ASSERT_TRUE(man.exist(index)); - ASSERT_EQ(man.at(index), 100); - - man.remove(index); - ASSERT_FALSE(man.exist(index)); -} - -TEST(ObjectManager, neg_remove_2) -{ - util::ObjectManager<Index, int> man; - - auto index0 = man.emplace(100); - auto index1 = man.emplace(200); - ASSERT_TRUE(man.exist(index0)); - ASSERT_EQ(man.at(index0), 100); - ASSERT_TRUE(man.exist(index1)); - ASSERT_EQ(man.at(index1), 200); - - man.remove(index0); - ASSERT_FALSE(man.exist(index0)); - ASSERT_TRUE(man.exist(index1)); - ASSERT_EQ(man.at(index1), 200); -} - -TEST(ObjectManager, push) -{ - util::ObjectManager<Index, int> man; - - // Not specify index - auto index = man.push(std::make_unique<int>(100)); - ASSERT_EQ(man.at(index), 100); - - // Specify index - auto index2 = man.push(std::make_unique<int>(200), Index{33}); - ASSERT_EQ(index2.value(), 33); - ASSERT_EQ(man.at(index2), 200); - - auto index3 = man.push(std::make_unique<int>(300)); - // NOTE auto-generated index number is always (biggest index in the ObjectManager + 1) - ASSERT_EQ(index3.value(), 34); - ASSERT_EQ(man.at(index3), 300); - - auto index4 = man.push(std::make_unique<int>(400), Index{22}); - ASSERT_EQ(index4.value(), 22); - ASSERT_EQ(man.at(index4), 400); - - auto index5 = man.push(std::make_unique<int>(500)); - // NOTE auto-generated index number is always (biggest index in the ObjectManager + 1) - ASSERT_EQ(index5.value(), 35); - ASSERT_EQ(man.at(index5), 500); -} - -TEST(ObjectManager, neg_push) -{ - util::ObjectManager<Index, int> man; - - // Specify index - auto index = man.push(std::make_unique<int>(100), Index{55}); - ASSERT_EQ(index.value(), 55); - ASSERT_EQ(man.at(index), 100); - - // Specify the same index - auto index2 = man.push(std::make_unique<int>(200), Index{55}); - ASSERT_FALSE(index2.valid()); -} - -static const uint32_t kMaxUInt32 = std::numeric_limits<uint32_t>::max(); - -TEST(ObjectManager, neg_push_undefined_index) -{ - util::ObjectManager<Index, int> man; - - // Try inserting invalid(undefined) index - auto index = man.push(std::make_unique<int>(100), Index{kMaxUInt32}); - ASSERT_FALSE(index.valid()); - ASSERT_EQ(man.size(), 0); -} - -TEST(ObjectManager, neg_push_max_index) -{ - util::ObjectManager<Index, int> man; - - // Insert an object with maximum valid index - auto index = man.push(std::make_unique<int>(100), Index{kMaxUInt32 - 1}); - ASSERT_EQ(index.value(), kMaxUInt32 - 1); - ASSERT_EQ(man.at(index), 100); - ASSERT_EQ(man.size(), 1); - - // Reached to the final index so next push/emplace must fail - auto index2 = man.push(std::make_unique<int>(200)); - ASSERT_EQ(man.size(), 1); - ASSERT_FALSE(index2.valid()); -} - -TEST(ObjectManager, neg_emplace_max_index) -{ - util::ObjectManager<Index, int> man; - - // Insert an object with maximum valid index - auto index = man.push(std::make_unique<int>(100), Index{kMaxUInt32 - 1}); - ASSERT_EQ(index.value(), kMaxUInt32 - 1); - ASSERT_EQ(man.at(index), 100); - ASSERT_EQ(man.size(), 1); - - // Reached to the final index so next push/emplace must fail - auto index3 = man.emplace(200); - ASSERT_EQ(man.size(), 1); - ASSERT_FALSE(index3.valid()); -} - -TEST(ObjectManager, const_iterate) -{ - util::ObjectManager<Index, int> man; - - auto index0 = man.emplace(100); - auto index1 = man.emplace(200); - auto index2 = man.emplace(300); - - int sum = 0; - man.iterate([&](const Index &index, const int &val) { sum += val; }); - ASSERT_EQ(sum, 600); -} - -TEST(ObjectManager, non_const_iterate) -{ - util::ObjectManager<Index, int> man; - - auto index0 = man.emplace(100); - auto index1 = man.emplace(200); - auto index2 = man.emplace(300); - - man.iterate([&](const Index &index, int &val) { val += 1; }); - ASSERT_EQ(man.at(index0), 101); - ASSERT_EQ(man.at(index1), 201); - ASSERT_EQ(man.at(index2), 301); -} - -TEST(ObjectManager, set) -{ - util::ObjectManager<Index, int> man; - auto index = man.set(Index{1}, std::make_unique<int>(100)); // Insert - ASSERT_EQ(index, Index{1}); - auto index2 = man.set(index, std::make_unique<int>(200)); // Overwrite - ASSERT_EQ(index2, index); - ASSERT_EQ(man.at(index2), 200); -} - -TEST(ObjectManager, neg_set) -{ - auto v = std::make_unique<int>(100); - util::ObjectManager<Index, int> man; - auto index = man.set(Index{}, std::move(v)); // Try set with an invalid index - ASSERT_EQ(index, Index{}); - ASSERT_FALSE(index.valid()); - ASSERT_NE(v, nullptr); // v must be kept when failure -} - -TEST(ObjectManager, getRawPtr) -{ - auto v = std::make_unique<int>(100); - auto v_ptr = v.get(); - util::ObjectManager<Index, int> man; - auto index = man.push(std::move(v)); - ASSERT_EQ(v_ptr, man.getRawPtr(index)); -} - -TEST(ObjectManager, neg_getRawPtr) -{ - util::ObjectManager<Index, int> man; - auto ptr = man.getRawPtr(Index{1}); - ASSERT_EQ(ptr, nullptr); -} diff --git a/runtime/onert/test/core/util/ShapeInference.cc b/runtime/onert/test/core/util/ShapeInference.cc deleted file mode 100644 index 2ecaa2885..000000000 --- a/runtime/onert/test/core/util/ShapeInference.cc +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright (c) 2019 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. - */ - -#include <gtest/gtest.h> - -#include "ir/Layout.h" -#include "util/ShapeInference.h" - -using namespace onert::ir; - -TEST(ShapeInference, Elementwise) -{ - Shape lhs_shape{1, 299, 299, 3}; - Shape rhs_shape{3}; - auto infered_out_shape = onert::shape_inference::inferEltwiseShape(lhs_shape, rhs_shape); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.dim(0), 1); - ASSERT_EQ(infered_out_shape.dim(1), 299); - ASSERT_EQ(infered_out_shape.dim(2), 299); - ASSERT_EQ(infered_out_shape.dim(3), 3); -} - -TEST(ShapeInference, neg_Elementwise) -{ - Shape lhs_shape{1, 299, 299, 3}; - Shape rhs_shape{5, 3}; - ASSERT_THROW(onert::shape_inference::inferEltwiseShape(lhs_shape, rhs_shape), std::runtime_error); -} - -TEST(ShapeInference, Pool2DNodeSame) -{ - Shape in_shape{10, 6, 12, 20}; - Stride stride{3, 7}; - Padding padding{PaddingType::SAME}; - - operation::Pool2D::Param avg_pool_param{ - operation::Pool2D::PoolType::AVG, 3, 6, stride, padding, Activation::NONE}; - auto infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, avg_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); - - operation::Pool2D::Param max_pool_param{ - operation::Pool2D::PoolType::MAX, 3, 6, stride, padding, Activation::NONE}; - infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, max_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); -} - -TEST(ShapeInference, Pool2DNodeValid) -{ - Shape in_shape{10, 6, 12, 20}; - Stride stride{3, 7}; - Padding padding{PaddingType::VALID}; - - operation::Pool2D::Param avg_pool_param{ - operation::Pool2D::PoolType::AVG, 3, 6, stride, padding, Activation::NONE}; - auto infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, avg_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); - - operation::Pool2D::Param max_pool_param{ - operation::Pool2D::PoolType::MAX, 3, 6, stride, padding, Activation::NONE}; - infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, max_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); -} - -TEST(ShapeInference, Pool2DNodeExplicit) -{ - Shape in_shape{10, 3, 5, 20}; - - Stride stride{3, 7}; - Padding padding{4, 3, 2, 1}; - - operation::Pool2D::Param avg_pool_param{ - operation::Pool2D::PoolType::AVG, 3, 6, stride, padding, Activation::NONE}; - auto infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, avg_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); - - operation::Pool2D::Param max_pool_param{ - operation::Pool2D::PoolType::MAX, 3, 6, stride, padding, Activation::NONE}; - infered_out_shape = onert::shape_inference::inferPoolShape(in_shape, max_pool_param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 20); -} - -TEST(ShapeInference, neg_Pool2DNode_InvalidStride) -{ - Shape in_shape{10, 6, 12, 20}; - Stride stride{0, 7}; - Padding padding{PaddingType::SAME}; - - operation::Pool2D::Param avg_pool_param{ - operation::Pool2D::PoolType::AVG, 3, 6, stride, padding, Activation::NONE}; - ASSERT_THROW(onert::shape_inference::inferPoolShape(in_shape, avg_pool_param), - std::runtime_error); -} - -TEST(ShapeInference, Conv2D) -{ - Shape in_shape{10, 6, 12, 20}; - Shape ker_shape{30, 3, 6, 20}; - - operation::Conv2D::Param param{Stride{3, 7}, Padding{PaddingType::VALID}, Activation::NONE, - Dilation{1, 1}}; - auto infered_out_shape = onert::shape_inference::inferConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 30); - - param = operation::Conv2D::Param{Stride{3, 7}, Padding{PaddingType::SAME}, Activation::NONE, - Dilation{1, 1}}; - infered_out_shape = onert::shape_inference::inferConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 30); - - param = - operation::Conv2D::Param{Stride{3, 7}, Padding{4, 3, 2, 1}, Activation::NONE, Dilation{1, 1}}; - infered_out_shape = onert::shape_inference::inferConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 3); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 30); -} - -TEST(ShapeInference, neg_Conv2D_InvalidStride) -{ - Shape in_shape{10, 6, 12, 20}; - Shape ker_shape{30, 3, 6, 20}; - - operation::Conv2D::Param param{Stride{0, 0}, Padding{PaddingType::VALID}, Activation::NONE, - Dilation{1, 1}}; - ASSERT_THROW(onert::shape_inference::inferConv2DShape(in_shape, ker_shape, param), - std::runtime_error); -} - -TEST(ShapeInference, DepthwiseConv2D) -{ - Shape in_shape{10, 6, 12, 20}; - Shape ker_shape{1, 3, 6, 60}; - - operation::DepthwiseConv2D::Param param{Stride{3, 7}, Padding{PaddingType::VALID}, 3, - Activation::NONE, Dilation{1, 1}}; - auto infered_out_shape = - onert::shape_inference::inferDepthwiseConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 1); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 60); - - param = operation::DepthwiseConv2D::Param{Stride{3, 7}, Padding{PaddingType::SAME}, 3, - Activation::NONE, Dilation{1, 1}}; - infered_out_shape = onert::shape_inference::inferDepthwiseConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 60); - - param = operation::DepthwiseConv2D::Param{Stride{3, 7}, Padding{4, 3, 2, 1}, 3, Activation::NONE, - Dilation{1, 1}}; - infered_out_shape = onert::shape_inference::inferDepthwiseConv2DShape(in_shape, ker_shape, param); - - ASSERT_EQ(infered_out_shape.rank(), 4); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).N, 10); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).H, 3); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).W, 2); - ASSERT_EQ(infered_out_shape.asFeature(Layout::NHWC).C, 60); -} - -TEST(ShapeInference, neg_DepthwiseConv2D_InvalidSride) -{ - Shape in_shape{10, 6, 12, 20}; - Shape ker_shape{1, 3, 6, 60}; - - operation::DepthwiseConv2D::Param param{Stride{3, 0}, Padding{PaddingType::VALID}, 3, - Activation::NONE, Dilation{1, 1}}; - ASSERT_THROW(onert::shape_inference::inferDepthwiseConv2DShape(in_shape, ker_shape, param), - std::runtime_error); -} - -TEST(ShapeInference, Concat) -{ - { - Shape in1{10, 20, 30, 3, 50}; - Shape in2{10, 20, 30, 2, 50}; - Shape in3{10, 20, 30, 2, 50}; - - operation::Concat::Param param{3}; - auto infered_out_shape = onert::shape_inference::inferConcatShape({in1, in2, in3}, param); - - ASSERT_EQ(infered_out_shape.rank(), 5); - ASSERT_EQ(infered_out_shape.dim(0), 10); - ASSERT_EQ(infered_out_shape.dim(1), 20); - ASSERT_EQ(infered_out_shape.dim(2), 30); - ASSERT_EQ(infered_out_shape.dim(3), 7); - ASSERT_EQ(infered_out_shape.dim(4), 50); - } - { - // case 1. when axis < 0 - Shape in1{10, 20, 2}; - Shape in2{10, 20, 3}; - - operation::Concat::Param param{-1}; - auto infered_out_shape = onert::shape_inference::inferConcatShape({in1, in2}, param); - - ASSERT_EQ(infered_out_shape.rank(), 3); - ASSERT_EQ(infered_out_shape.dim(0), 10); - ASSERT_EQ(infered_out_shape.dim(1), 20); - ASSERT_EQ(infered_out_shape.dim(2), 5); - } - { - // case 2. when axis < 0 - Shape in1{2, 20, 2}; - Shape in2{3, 20, 2}; - - operation::Concat::Param param{-3}; - auto infered_out_shape = onert::shape_inference::inferConcatShape({in1, in2}, param); - - ASSERT_EQ(infered_out_shape.rank(), 3); - ASSERT_EQ(infered_out_shape.dim(0), 5); - ASSERT_EQ(infered_out_shape.dim(1), 20); - ASSERT_EQ(infered_out_shape.dim(2), 2); - } -} - -TEST(ShapeInference, neg_Concat) -{ - { - operation::Concat::Param param{2}; - Shape in1{10, 1, 3}; - Shape in2{10, 2, 4}; // dim[1] should be 1 but 2 - - EXPECT_ANY_THROW(onert::shape_inference::inferConcatShape({in1, in2}, param)); - } - { // wrong rank - operation::Concat::Param param{2}; - Shape in1{10, 2, 3, 4}; - Shape in2{10, 2, 4}; // rank should be 4 - - EXPECT_ANY_THROW(onert::shape_inference::inferConcatShape({in1, in2}, param)); - } -} - -TEST(ShapeInference, ExpandDims) -{ - Shape in_shape{30, 40}; - - auto check = [&](int32_t axis, Shape &expected) { - auto actual = onert::shape_inference::inferExpandDimsShape(in_shape, axis); - - ASSERT_EQ(actual.rank(), 3); - for (int32_t dim = 0; dim < expected.rank(); dim++) - ASSERT_EQ(actual.dim(dim), expected.dim(dim)); - }; - - { // boundary - int32_t axis = 0; - Shape expected{1, 30, 40}; - check(axis, expected); - } - { // boundary - int32_t axis = 2; - Shape expected{30, 40, 1}; - check(axis, expected); - } - { // inside - int32_t axis = 1; - Shape expected{30, 1, 40}; - check(axis, expected); - } - { // negative boundary - int32_t axis = -1; - Shape expected{30, 40, 1}; - check(axis, expected); - } - { // negative boundary - int32_t axis = -3; - Shape expected{1, 30, 40}; - check(axis, expected); - } -} - -TEST(ShapeInference, neg_ExpandDims) -{ - Shape in_shape{30, 40}; - - { // over boundary - int32_t axis = 3; - ASSERT_THROW(onert::shape_inference::inferExpandDimsShape(in_shape, axis), std::runtime_error); - } - { // over boundary - int32_t axis = -4; - ASSERT_THROW(onert::shape_inference::inferExpandDimsShape(in_shape, axis), std::runtime_error); - } -} - -TEST(ShapeInference, FullyConnected) -{ - Shape in_shape{3, 4, 5, 6}; - Shape ker_shape{3, 10}; - auto infered_out_shape = onert::shape_inference::inferFullyConnectedShape(in_shape, ker_shape); - - ASSERT_EQ(infered_out_shape.rank(), 2); - ASSERT_EQ(infered_out_shape.dim(0), 36); - ASSERT_EQ(infered_out_shape.dim(1), 3); -} - -TEST(ShapeInference, Transpose) -{ - auto check = [&](Shape &in_shape, std::vector<int> perm, Shape &expected) { - // pre-conditions - ASSERT_EQ(in_shape.rank(), perm.size()); - ASSERT_EQ(expected.rank(), perm.size()); - auto inferred_out_shape = - onert::shape_inference::inferTransposeShape(in_shape, perm.data(), perm.size()); - // post-conditions - ASSERT_EQ(inferred_out_shape.rank(), perm.size()); - for (int32_t dim = 0; dim < expected.rank(); dim++) - { - ASSERT_EQ(inferred_out_shape.dim(dim), expected.dim(dim)); - } - }; - // check for 2-D - { - Shape in_shape{2, 3}; - std::vector<int> perm = {1, 0}; - Shape expected{3, 2}; - // int32_t rank = 2; - check(in_shape, perm, expected); - } - // check for 3-D - { - Shape in_shape{1, 2, 3}; - std::vector<int> perm = {2, 0, 1}; - Shape expected{3, 1, 2}; - // int32_t rank = 3; - check(in_shape, perm, expected); - } - // check for 4-D - { - Shape in_shape{1, 2, 3, 4}; - std::vector<int> perm = {1, 3, 0, 2}; - Shape expected{2, 4, 1, 3}; - // int32_t rank = 4; - check(in_shape, perm, expected); - } -} - -TEST(ShapeInference, neg_Transpose) -{ - Shape in_shape{1, 2, 3}; - // Invalid parameter size - { - std::vector<int> perm = {2, 0, 1, 0}; - // int32_t rank = 3; - ASSERT_THROW(onert::shape_inference::inferTransposeShape(in_shape, perm.data(), perm.size()), - std::runtime_error); - } - // Invalid parameter value - { - std::vector<int> perm = {2, 0, 3}; - // int32_t rank = 3; - ASSERT_THROW(onert::shape_inference::inferTransposeShape(in_shape, perm.data(), perm.size()), - std::runtime_error); - } -} - -TEST(ShapeInference, Gather) -{ - auto check = [&](Shape &input, Shape &indices, Shape &expected, int32_t axis) { - int rank = input.rank(); - auto actual = onert::shape_inference::inferGatherShape(input, indices, axis, rank); - - ASSERT_EQ(actual.rank(), expected.rank()); - - for (int32_t dim = 0; dim < expected.rank(); dim++) - ASSERT_EQ(actual.dim(dim), expected.dim(dim)); - }; - - // check for 2-D, 3-D, axis 0 - { - Shape input{3, 4}; - Shape indices{1, 1, 2}; - int32_t axis = 0; - Shape expected{1, 1, 2, 4}; - check(input, indices, expected, axis); - } - - // check for 2-D, 3-D, axis 1 - { - Shape input{3, 4}; - Shape indices{1, 2, 1}; - int32_t axis = 1; - Shape expected{3, 1, 2, 1}; - check(input, indices, expected, axis); - } - - // check for 3-D, 2-D, axis 0 - { - Shape input{2, 3, 4}; - Shape indices{1, 2}; - int32_t axis = 0; - Shape expected{1, 2, 3, 4}; - check(input, indices, expected, axis); - } - - // check for 3-D, 2-D, axis 2 - { - Shape input{2, 3, 4}; - Shape indices{2, 1}; - int32_t axis = 2; - Shape expected{2, 3, 2, 1}; - check(input, indices, expected, axis); - } - - // check for 4D, axis 0 - { - Shape input{1, 2, 3, 4}; - Shape indices{2}; - int32_t axis = 0; - Shape expected{2, 2, 3, 4}; - check(input, indices, expected, axis); - } -} - -TEST(ShapeInference, BCQFullyConnected) -{ - auto check = [&](Shape &in_shape, Shape &cluster_shape, std::vector<int> cluster, - Shape &expected) { - auto actual = - onert::shape_inference::inferBCQFullyConnectedShape(in_shape, cluster_shape, cluster.data()); - ASSERT_EQ(actual.rank(), expected.rank()); - - for (int32_t dim = 0; dim < expected.rank(); dim++) - ASSERT_EQ(actual.dim(dim), expected.dim(dim)); - }; - - { - Shape in_shape{10, 1}; - Shape cluster_shape{3, 2}; - std::vector<int> cluster = {1, 10, 2, 10, 3, 10}; - - Shape expected{30, 1}; - check(in_shape, cluster_shape, cluster, expected); - } - - { - Shape in_shape{1, 1}; - Shape cluster_shape{1, 2}; - std::vector<int> cluster = {3, 50}; - - Shape expected{50, 1}; - check(in_shape, cluster_shape, cluster, expected); - } -} - -TEST(ShapeInference, BCQGather) -{ - auto check = [&](Shape &indices_shape, Shape &cluster_shape, std::vector<int> cluster, - uint32_t hidden_size, uint32_t axis, int rank, Shape &expected) { - operation::BCQGather::Param param{hidden_size, axis}; - auto actual = onert::shape_inference::inferBCQGatherShape(indices_shape, cluster_shape, - cluster.data(), rank, param); - ASSERT_EQ(actual.rank(), expected.rank()); - - for (int32_t dim = 0; dim < expected.rank(); dim++) - ASSERT_EQ(actual.dim(dim), expected.dim(dim)); - }; - - { - Shape indices_shape{5, 1}; - Shape cluster_shape{3, 2}; - std::vector<int> cluster = {1, 10, 2, 10, 3, 10}; - uint32_t hidden_size = 10; - uint32_t axis = 0; - int rank = 2; - - Shape expected{5, 1, 10}; - check(indices_shape, cluster_shape, cluster, hidden_size, axis, rank, expected); - } - - { - Shape indices_shape{5, 1}; - Shape cluster_shape{3, 2}; - std::vector<int> cluster = {1, 10, 2, 10, 3, 10}; - uint32_t hidden_size = 10; - uint32_t axis = 1; - int rank = 2; - - Shape expected{30, 5, 1}; - check(indices_shape, cluster_shape, cluster, hidden_size, axis, rank, expected); - } -} |