summaryrefslogtreecommitdiff
path: root/compiler/luci-interpreter/src
diff options
context:
space:
mode:
authorChunseok Lee <chunseok.lee@samsung.com>2020-10-29 13:12:50 +0900
committerChunseok Lee <chunseok.lee@samsung.com>2020-10-29 13:12:50 +0900
commitd6b371e095d737922187a518b8faba1ef6f3a2b1 (patch)
tree9d90c09c887b5111389dbedf924f59206411cd5a /compiler/luci-interpreter/src
parentc55f8a6db48cda9d3a78048338b7f18c4cca62b8 (diff)
downloadnnfw-d6b371e095d737922187a518b8faba1ef6f3a2b1.tar.gz
nnfw-d6b371e095d737922187a518b8faba1ef6f3a2b1.tar.bz2
nnfw-d6b371e095d737922187a518b8faba1ef6f3a2b1.zip
Imported Upstream version 0.4upstream/0.4
Diffstat (limited to 'compiler/luci-interpreter/src')
-rw-r--r--compiler/luci-interpreter/src/CMakeLists.txt41
-rw-r--r--compiler/luci-interpreter/src/Interpreter.cpp126
-rw-r--r--compiler/luci-interpreter/src/core/CMakeLists.txt17
-rw-r--r--compiler/luci-interpreter/src/core/EventNotifier.h36
-rw-r--r--compiler/luci-interpreter/src/core/Kernel.h75
-rw-r--r--compiler/luci-interpreter/src/core/KernelParams.h178
-rw-r--r--compiler/luci-interpreter/src/core/RuntimeGraph.cpp93
-rw-r--r--compiler/luci-interpreter/src/core/RuntimeGraph.h60
-rw-r--r--compiler/luci-interpreter/src/core/RuntimeModule.h59
-rw-r--r--compiler/luci-interpreter/src/core/Tensor.cpp68
-rw-r--r--compiler/luci-interpreter/src/kernels/Add.cpp195
-rw-r--r--compiler/luci-interpreter/src/kernels/Add.h49
-rw-r--r--compiler/luci-interpreter/src/kernels/Add.test.cpp246
-rw-r--r--compiler/luci-interpreter/src/kernels/ArgMax.cpp140
-rw-r--r--compiler/luci-interpreter/src/kernels/ArgMax.h44
-rw-r--r--compiler/luci-interpreter/src/kernels/ArgMax.test.cpp110
-rw-r--r--compiler/luci-interpreter/src/kernels/AveragePool2D.cpp157
-rw-r--r--compiler/luci-interpreter/src/kernels/AveragePool2D.h52
-rw-r--r--compiler/luci-interpreter/src/kernels/AveragePool2D.test.cpp220
-rw-r--r--compiler/luci-interpreter/src/kernels/BinaryOpCommon.h73
-rw-r--r--compiler/luci-interpreter/src/kernels/CMakeLists.txt186
-rw-r--r--compiler/luci-interpreter/src/kernels/Concatenation.cpp136
-rw-r--r--compiler/luci-interpreter/src/kernels/Concatenation.h48
-rw-r--r--compiler/luci-interpreter/src/kernels/Concatenation.test.cpp169
-rw-r--r--compiler/luci-interpreter/src/kernels/Conv2D.cpp194
-rw-r--r--compiler/luci-interpreter/src/kernels/Conv2D.h57
-rw-r--r--compiler/luci-interpreter/src/kernels/Conv2D.test.cpp314
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthToSpace.cpp80
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthToSpace.h45
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthToSpace.test.cpp105
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthwiseConv2D.cpp175
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthwiseConv2D.h54
-rw-r--r--compiler/luci-interpreter/src/kernels/DepthwiseConv2D.test.cpp303
-rw-r--r--compiler/luci-interpreter/src/kernels/Div.cpp128
-rw-r--r--compiler/luci-interpreter/src/kernels/Div.h48
-rw-r--r--compiler/luci-interpreter/src/kernels/Div.test.cpp150
-rw-r--r--compiler/luci-interpreter/src/kernels/Elu.cpp52
-rw-r--r--compiler/luci-interpreter/src/kernels/Elu.h43
-rw-r--r--compiler/luci-interpreter/src/kernels/Elu.test.cpp75
-rw-r--r--compiler/luci-interpreter/src/kernels/Equal.cpp113
-rw-r--r--compiler/luci-interpreter/src/kernels/Equal.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/Equal.test.cpp187
-rw-r--r--compiler/luci-interpreter/src/kernels/Floor.cpp57
-rw-r--r--compiler/luci-interpreter/src/kernels/Floor.h45
-rw-r--r--compiler/luci-interpreter/src/kernels/Floor.test.cpp65
-rw-r--r--compiler/luci-interpreter/src/kernels/FloorDiv.cpp85
-rw-r--r--compiler/luci-interpreter/src/kernels/FloorDiv.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/FloorDiv.test.cpp135
-rw-r--r--compiler/luci-interpreter/src/kernels/FullyConnected.cpp139
-rw-r--r--compiler/luci-interpreter/src/kernels/FullyConnected.h50
-rw-r--r--compiler/luci-interpreter/src/kernels/FullyConnected.test.cpp196
-rw-r--r--compiler/luci-interpreter/src/kernels/Greater.cpp113
-rw-r--r--compiler/luci-interpreter/src/kernels/Greater.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/Greater.test.cpp214
-rw-r--r--compiler/luci-interpreter/src/kernels/GreaterEqual.cpp116
-rw-r--r--compiler/luci-interpreter/src/kernels/GreaterEqual.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/GreaterEqual.test.cpp214
-rw-r--r--compiler/luci-interpreter/src/kernels/If.cpp90
-rw-r--r--compiler/luci-interpreter/src/kernels/If.h49
-rw-r--r--compiler/luci-interpreter/src/kernels/If.test.cpp141
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Normalize.cpp75
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Normalize.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Normalize.test.cpp116
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Pool2D.cpp88
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Pool2D.h49
-rw-r--r--compiler/luci-interpreter/src/kernels/L2Pool2D.test.cpp265
-rw-r--r--compiler/luci-interpreter/src/kernels/LeakyRelu.cpp90
-rw-r--r--compiler/luci-interpreter/src/kernels/LeakyRelu.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/LeakyRelu.test.cpp118
-rw-r--r--compiler/luci-interpreter/src/kernels/Less.cpp113
-rw-r--r--compiler/luci-interpreter/src/kernels/Less.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/Less.test.cpp214
-rw-r--r--compiler/luci-interpreter/src/kernels/LessEqual.cpp113
-rw-r--r--compiler/luci-interpreter/src/kernels/LessEqual.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/LessEqual.test.cpp214
-rw-r--r--compiler/luci-interpreter/src/kernels/LocalResponseNormalization.cpp65
-rw-r--r--compiler/luci-interpreter/src/kernels/LocalResponseNormalization.h44
-rw-r--r--compiler/luci-interpreter/src/kernels/LocalResponseNormalization.test.cpp144
-rw-r--r--compiler/luci-interpreter/src/kernels/LogSoftmax.cpp91
-rw-r--r--compiler/luci-interpreter/src/kernels/LogSoftmax.h48
-rw-r--r--compiler/luci-interpreter/src/kernels/LogSoftmax.test.cpp111
-rw-r--r--compiler/luci-interpreter/src/kernels/Logistic.cpp94
-rw-r--r--compiler/luci-interpreter/src/kernels/Logistic.h52
-rw-r--r--compiler/luci-interpreter/src/kernels/Logistic.test.cpp134
-rw-r--r--compiler/luci-interpreter/src/kernels/MaxPool2D.cpp150
-rw-r--r--compiler/luci-interpreter/src/kernels/MaxPool2D.h52
-rw-r--r--compiler/luci-interpreter/src/kernels/MaxPool2D.test.cpp125
-rw-r--r--compiler/luci-interpreter/src/kernels/Maximum.cpp65
-rw-r--r--compiler/luci-interpreter/src/kernels/Maximum.h47
-rw-r--r--compiler/luci-interpreter/src/kernels/Maximum.test.cpp67
-rw-r--r--compiler/luci-interpreter/src/kernels/Mean.cpp326
-rw-r--r--compiler/luci-interpreter/src/kernels/Mean.h56
-rw-r--r--compiler/luci-interpreter/src/kernels/Mean.test.cpp179
-rw-r--r--compiler/luci-interpreter/src/kernels/Minimum.cpp65
-rw-r--r--compiler/luci-interpreter/src/kernels/Minimum.h47
-rw-r--r--compiler/luci-interpreter/src/kernels/Minimum.test.cpp67
-rw-r--r--compiler/luci-interpreter/src/kernels/Mul.cpp83
-rw-r--r--compiler/luci-interpreter/src/kernels/Mul.h50
-rw-r--r--compiler/luci-interpreter/src/kernels/Mul.test.cpp83
-rw-r--r--compiler/luci-interpreter/src/kernels/NotEqual.cpp113
-rw-r--r--compiler/luci-interpreter/src/kernels/NotEqual.h53
-rw-r--r--compiler/luci-interpreter/src/kernels/NotEqual.test.cpp187
-rw-r--r--compiler/luci-interpreter/src/kernels/Pad.cpp102
-rw-r--r--compiler/luci-interpreter/src/kernels/Pad.h43
-rw-r--r--compiler/luci-interpreter/src/kernels/Pad.test.cpp75
-rw-r--r--compiler/luci-interpreter/src/kernels/Pow.cpp78
-rw-r--r--compiler/luci-interpreter/src/kernels/Pow.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/Pow.test.cpp101
-rw-r--r--compiler/luci-interpreter/src/kernels/Prelu.cpp153
-rw-r--r--compiler/luci-interpreter/src/kernels/Prelu.h54
-rw-r--r--compiler/luci-interpreter/src/kernels/Prelu.test.cpp246
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu.cpp114
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu.h51
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu.test.cpp152
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu6.cpp88
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu6.h50
-rw-r--r--compiler/luci-interpreter/src/kernels/Relu6.test.cpp135
-rw-r--r--compiler/luci-interpreter/src/kernels/Reshape.cpp90
-rw-r--r--compiler/luci-interpreter/src/kernels/Reshape.h43
-rw-r--r--compiler/luci-interpreter/src/kernels/Reshape.test.cpp67
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeBilinear.cpp75
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeBilinear.h45
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeBilinear.test.cpp231
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.cpp76
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.h45
-rw-r--r--compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.test.cpp211
-rw-r--r--compiler/luci-interpreter/src/kernels/Reverse.cpp81
-rw-r--r--compiler/luci-interpreter/src/kernels/Reverse.h43
-rw-r--r--compiler/luci-interpreter/src/kernels/Reverse.test.cpp66
-rw-r--r--compiler/luci-interpreter/src/kernels/Rsqrt.cpp66
-rw-r--r--compiler/luci-interpreter/src/kernels/Rsqrt.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/Rsqrt.test.cpp80
-rw-r--r--compiler/luci-interpreter/src/kernels/Slice.cpp149
-rw-r--r--compiler/luci-interpreter/src/kernels/Slice.h44
-rw-r--r--compiler/luci-interpreter/src/kernels/Slice.test.cpp64
-rw-r--r--compiler/luci-interpreter/src/kernels/Softmax.cpp90
-rw-r--r--compiler/luci-interpreter/src/kernels/Softmax.h49
-rw-r--r--compiler/luci-interpreter/src/kernels/Softmax.test.cpp102
-rw-r--r--compiler/luci-interpreter/src/kernels/SpaceToDepth.cpp79
-rw-r--r--compiler/luci-interpreter/src/kernels/SpaceToDepth.h45
-rw-r--r--compiler/luci-interpreter/src/kernels/SpaceToDepth.test.cpp60
-rw-r--r--compiler/luci-interpreter/src/kernels/Split.cpp81
-rw-r--r--compiler/luci-interpreter/src/kernels/Split.h47
-rw-r--r--compiler/luci-interpreter/src/kernels/Split.test.cpp117
-rw-r--r--compiler/luci-interpreter/src/kernels/Sqrt.cpp66
-rw-r--r--compiler/luci-interpreter/src/kernels/Sqrt.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/Sqrt.test.cpp80
-rw-r--r--compiler/luci-interpreter/src/kernels/Squeeze.cpp86
-rw-r--r--compiler/luci-interpreter/src/kernels/Squeeze.h44
-rw-r--r--compiler/luci-interpreter/src/kernels/Squeeze.test.cpp69
-rw-r--r--compiler/luci-interpreter/src/kernels/StridedSlice.cpp145
-rw-r--r--compiler/luci-interpreter/src/kernels/StridedSlice.h47
-rw-r--r--compiler/luci-interpreter/src/kernels/StridedSlice.test.cpp99
-rw-r--r--compiler/luci-interpreter/src/kernels/Sub.cpp139
-rw-r--r--compiler/luci-interpreter/src/kernels/Sub.h48
-rw-r--r--compiler/luci-interpreter/src/kernels/Sub.test.cpp180
-rw-r--r--compiler/luci-interpreter/src/kernels/Tanh.cpp93
-rw-r--r--compiler/luci-interpreter/src/kernels/Tanh.h52
-rw-r--r--compiler/luci-interpreter/src/kernels/Tanh.test.cpp102
-rw-r--r--compiler/luci-interpreter/src/kernels/TestUtils.cpp81
-rw-r--r--compiler/luci-interpreter/src/kernels/TestUtils.h212
-rw-r--r--compiler/luci-interpreter/src/kernels/Transpose.cpp84
-rw-r--r--compiler/luci-interpreter/src/kernels/Transpose.h44
-rw-r--r--compiler/luci-interpreter/src/kernels/Transpose.test.cpp110
-rw-r--r--compiler/luci-interpreter/src/kernels/TransposeConv.cpp139
-rw-r--r--compiler/luci-interpreter/src/kernels/TransposeConv.h61
-rw-r--r--compiler/luci-interpreter/src/kernels/TransposeConv.test.cpp159
-rw-r--r--compiler/luci-interpreter/src/kernels/Unpack.cpp84
-rw-r--r--compiler/luci-interpreter/src/kernels/Unpack.h46
-rw-r--r--compiler/luci-interpreter/src/kernels/Unpack.test.cpp141
-rw-r--r--compiler/luci-interpreter/src/kernels/Utils.cpp185
-rw-r--r--compiler/luci-interpreter/src/kernels/Utils.h213
-rw-r--r--compiler/luci-interpreter/src/loader/CMakeLists.txt22
-rw-r--r--compiler/luci-interpreter/src/loader/GraphLoader.cpp200
-rw-r--r--compiler/luci-interpreter/src/loader/GraphLoader.h52
-rw-r--r--compiler/luci-interpreter/src/loader/KernelBuilder.cpp842
-rw-r--r--compiler/luci-interpreter/src/loader/KernelBuilder.h116
-rw-r--r--compiler/luci-interpreter/src/loader/KernelBuilder.test.cpp1135
-rw-r--r--compiler/luci-interpreter/src/loader/ModuleLoader.cpp52
-rw-r--r--compiler/luci-interpreter/src/loader/ModuleLoader.h49
-rw-r--r--compiler/luci-interpreter/src/loader/RuntimeToIR.h38
181 files changed, 0 insertions, 19914 deletions
diff --git a/compiler/luci-interpreter/src/CMakeLists.txt b/compiler/luci-interpreter/src/CMakeLists.txt
deleted file mode 100644
index 47b68fa40..000000000
--- a/compiler/luci-interpreter/src/CMakeLists.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-nnas_find_package(TensorFlowSource EXACT 2.3.0 QUIET)
-nnas_find_package(TensorFlowGEMMLowpSource EXACT 2.3.0 QUIET)
-nnas_find_package(TensorFlowEigenSource EXACT 2.3.0 QUIET)
-nnas_find_package(TensorFlowRuySource EXACT 2.3.0 QUIET)
-
-if (NOT TensorFlowSource_FOUND)
- message(STATUS "Skipping luci-interpreter: TensorFlow not found")
- return()
-endif ()
-
-if (NOT TensorFlowGEMMLowpSource_FOUND)
- message(STATUS "Skipping luci-interpreter: gemmlowp not found")
- return()
-endif ()
-
-if (NOT TensorFlowEigenSource_FOUND)
- message(STATUS "Skipping luci-interpreter: Eigen not found")
- return()
-endif ()
-
-if (NOT TensorFlowRuySource_FOUND)
- message(STATUS "Skipping luci-interpreter: Ruy not found")
- return()
-endif ()
-
-add_subdirectory(core)
-add_subdirectory(kernels)
-add_subdirectory(loader)
-
-set(SOURCES
- "${LUCI_INTERPRETER_INCLUDE_DIR}/luci_interpreter/Interpreter.h"
- Interpreter.cpp)
-
-add_library(luci_interpreter SHARED ${SOURCES})
-target_include_directories(luci_interpreter PUBLIC "${LUCI_INTERPRETER_INCLUDE_DIR}")
-target_include_directories(luci_interpreter PRIVATE "${LUCI_INTERPRETER_SOURCE_DIR}")
-target_link_libraries(luci_interpreter
- PUBLIC luci_lang luci_interpreter_loader luci_interpreter_core
- PRIVATE nncc_common)
-
-install(TARGETS luci_interpreter DESTINATION lib)
diff --git a/compiler/luci-interpreter/src/Interpreter.cpp b/compiler/luci-interpreter/src/Interpreter.cpp
deleted file mode 100644
index 639ffc1f0..000000000
--- a/compiler/luci-interpreter/src/Interpreter.cpp
+++ /dev/null
@@ -1,126 +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 "luci_interpreter/Interpreter.h"
-
-#include "loader/ModuleLoader.h"
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace
-{
-
-class EventNotifierImpl final : public EventNotifier
-{
-public:
- EventNotifierImpl(const RuntimeToIR &runtime_to_ir,
- const std::vector<ExecutionObserver *> &observers)
- : _runtime_to_ir(runtime_to_ir), _observers(observers)
- {
- }
-
- void postTensorWrite(const Tensor *tensor) override
- {
- assert(tensor != nullptr);
- for (const auto &observer : _observers)
- {
- observer->postTensorWrite(_runtime_to_ir.tensor_to_node.at(tensor), tensor);
- }
- }
-
- void preOperatorExecute(const Kernel *kernel) override
- {
- assert(kernel != nullptr);
- for (const auto &observer : _observers)
- {
- observer->preOperatorExecute(_runtime_to_ir.kernel_to_node.at(kernel));
- }
- }
-
- void postOperatorExecute(const Kernel *kernel) override
- {
- assert(kernel != nullptr);
- for (const auto &observer : _observers)
- {
- observer->postOperatorExecute(_runtime_to_ir.kernel_to_node.at(kernel));
- }
- }
-
-private:
- const RuntimeToIR &_runtime_to_ir;
- const std::vector<ExecutionObserver *> &_observers;
-};
-
-} // namespace
-
-Interpreter::Interpreter(const luci::Module *module)
-{
- _runtime_to_ir = std::make_unique<RuntimeToIR>();
- _event_notifier = std::make_unique<EventNotifierImpl>(*_runtime_to_ir, _observers);
- _runtime_module = std::make_unique<RuntimeModule>(_event_notifier.get());
- ModuleLoader loader(module, _runtime_module.get(), *_runtime_to_ir, _node_to_tensor);
- loader.load();
-}
-
-Interpreter::~Interpreter() = default;
-
-void Interpreter::writeInputTensor(const luci::CircleInput *input_node, const void *data,
- size_t data_size)
-{
- Tensor *tensor = _runtime_module->getInputTensors()[input_node->index()];
- if (tensor == nullptr)
- {
- const std::string &name = input_node->name();
- throw std::runtime_error("Cannot find tensor for input node named \"" + name + "\".");
- }
- if (data != nullptr)
- tensor->writeData(data, data_size);
-}
-
-void Interpreter::readOutputTensor(const luci::CircleOutput *output_node, void *data,
- size_t data_size)
-{
- Tensor *tensor = _runtime_module->getOutputTensors()[output_node->index()];
- if (tensor == nullptr)
- {
- const std::string &name = output_node->name();
- throw std::runtime_error("Cannot find tensor for output node named \"" + name + "\".");
- }
- if (data != nullptr)
- tensor->readData(data, data_size);
-}
-
-void Interpreter::interpret() { _runtime_module->execute(); }
-
-void Interpreter::attachObserver(ExecutionObserver *observer)
-{
- if (std::find(_observers.cbegin(), _observers.cend(), observer) != _observers.cend())
- throw std::runtime_error("Observer is already attached.");
- _observers.push_back(observer);
-}
-
-ExecutionObserver::~ExecutionObserver() = default;
-
-void ExecutionObserver::postTensorWrite(const luci::CircleNode *, const Tensor *) {}
-
-void ExecutionObserver::preOperatorExecute(const luci::CircleNode *) {}
-
-void ExecutionObserver::postOperatorExecute(const luci::CircleNode *) {}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/core/CMakeLists.txt b/compiler/luci-interpreter/src/core/CMakeLists.txt
deleted file mode 100644
index e576dbd94..000000000
--- a/compiler/luci-interpreter/src/core/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(SOURCES
- "${LUCI_INTERPRETER_INCLUDE_DIR}/luci_interpreter/core/DataType.h"
- "${LUCI_INTERPRETER_INCLUDE_DIR}/luci_interpreter/core/Tensor.h"
- EventNotifier.h
- Kernel.h
- KernelParams.h
- RuntimeGraph.h
- RuntimeGraph.cpp
- RuntimeModule.h
- Tensor.cpp)
-
-add_library(luci_interpreter_core STATIC ${SOURCES})
-set_target_properties(luci_interpreter_core PROPERTIES POSITION_INDEPENDENT_CODE ON)
-target_include_directories(luci_interpreter_core PUBLIC "${LUCI_INTERPRETER_INCLUDE_DIR}")
-target_include_directories(luci_interpreter_core PUBLIC "${LUCI_INTERPRETER_SOURCE_DIR}")
-target_link_libraries(luci_interpreter_core PUBLIC luci_lang)
-target_link_libraries(luci_interpreter_core PRIVATE nncc_common)
diff --git a/compiler/luci-interpreter/src/core/EventNotifier.h b/compiler/luci-interpreter/src/core/EventNotifier.h
deleted file mode 100644
index 5c4fbd3be..000000000
--- a/compiler/luci-interpreter/src/core/EventNotifier.h
+++ /dev/null
@@ -1,36 +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.
- */
-
-#ifndef LUCI_INTERPRETER_CORE_EVENTNOTIFIER_H
-#define LUCI_INTERPRETER_CORE_EVENTNOTIFIER_H
-
-namespace luci_interpreter
-{
-
-// Used at execution stage to tell the interpreter that the runtime state has changed in some way.
-class EventNotifier
-{
-public:
- virtual ~EventNotifier() = default;
-
- virtual void postTensorWrite(const Tensor *tensor) = 0;
- virtual void preOperatorExecute(const Kernel *kernel) = 0;
- virtual void postOperatorExecute(const Kernel *kernel) = 0;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_CORE_EVENTNOTIFIER_H
diff --git a/compiler/luci-interpreter/src/core/Kernel.h b/compiler/luci-interpreter/src/core/Kernel.h
deleted file mode 100644
index 5f5efb219..000000000
--- a/compiler/luci-interpreter/src/core/Kernel.h
+++ /dev/null
@@ -1,75 +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.
- */
-
-#ifndef LUCI_INTERPRETER_CORE_KERNEL_H
-#define LUCI_INTERPRETER_CORE_KERNEL_H
-
-#include "luci_interpreter/core/Tensor.h"
-
-#include <vector>
-
-namespace luci_interpreter
-{
-
-// Base class for all kernels.
-class Kernel
-{
-protected:
- Kernel(std::vector<const Tensor *> inputs, std::vector<Tensor *> outputs)
- : _inputs(std::move(inputs)), _outputs(std::move(outputs))
- {
- }
-
-public:
- virtual ~Kernel() = default;
-
- std::vector<const Tensor *> getInputTensors() const { return _inputs; }
- std::vector<Tensor *> getOutputTensors() const { return _outputs; }
-
- // Configures the kernel.
- // This function is currently called once for each kernel during interpreter construction,
- // which makes it a convenient place for preparing (resizing) output tensors.
- virtual void configure() = 0;
-
- // Executes the kernel.
- virtual void execute() const = 0;
-
-protected:
- // NOTE Prefer not to use these in derived classes.
- const std::vector<const Tensor *> _inputs;
- const std::vector<Tensor *> _outputs;
-};
-
-// Base class for kernels with parameters.
-template <typename Params> class KernelWithParams : public Kernel
-{
-protected:
- KernelWithParams(std::vector<const Tensor *> inputs, std::vector<Tensor *> outputs,
- const Params &params)
- : Kernel(std::move(inputs), std::move(outputs)), _params(params)
- {
- }
-
-public:
- const Params &params() const { return _params; }
-
-protected:
- const Params _params;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_CORE_KERNEL_H
diff --git a/compiler/luci-interpreter/src/core/KernelParams.h b/compiler/luci-interpreter/src/core/KernelParams.h
deleted file mode 100644
index 06926cdc1..000000000
--- a/compiler/luci-interpreter/src/core/KernelParams.h
+++ /dev/null
@@ -1,178 +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.
- */
-
-#ifndef LUCI_INTERPRETER_CORE_KERNELPARAMS_H
-#define LUCI_INTERPRETER_CORE_KERNELPARAMS_H
-
-#include <luci/IR/AttrPadding.h>
-#include <luci/IR/AttrFusedActFunc.h>
-#include <luci_interpreter/core/DataType.h>
-
-#include <cstdint>
-#include <vector>
-
-namespace luci_interpreter
-{
-
-// Inject commonly used types into `luci_interpreter` namespace for convenience.
-using Activation = luci::FusedActFunc;
-using Padding = luci::Padding;
-
-struct AddParams
-{
- Activation activation;
-};
-
-struct ArgMaxParams
-{
- DataType output_type;
-};
-
-struct ConcatenationParams
-{
- int axis;
-};
-
-struct Conv2DParams
-{
- Padding padding;
- int32_t stride_height;
- int32_t stride_width;
- int32_t dilation_height_factor;
- int32_t dilation_width_factor;
- Activation activation;
-};
-
-struct DepthToSpaceParams
-{
- int block_size;
-};
-
-struct DepthwiseConv2DParams
-{
- Padding padding;
- int32_t depth_multiplier; // TODO Remove, as it can be calculated.
- int32_t stride_height;
- int32_t stride_width;
- int32_t dilation_height_factor;
- int32_t dilation_width_factor;
- Activation activation;
-};
-
-struct DivParams
-{
- Activation activation;
-};
-
-struct FullyConnectedParams
-{
- Activation activation;
-};
-
-struct L2NormParams
-{
- Activation activation;
-};
-
-struct LeakyReluParams
-{
- float alpha;
-};
-
-struct LocalResponseNormalizationParams
-{
- int32_t radius;
- float bias;
- float alpha;
- float beta;
-};
-
-struct MulParams
-{
- Activation activation;
-};
-
-struct Pool2DParams
-{
- Padding padding;
- int32_t filter_height;
- int32_t filter_width;
- int32_t stride_height;
- int32_t stride_width;
- Activation activation;
-};
-
-struct ReducerParams
-{
- bool keep_dims;
-};
-
-struct ResizeBilinearParams
-{
- bool align_corners;
- bool half_pixel_centers;
-};
-
-struct ResizeNearestNeighborParams
-{
- bool align_corners;
- bool half_pixel_centers;
-};
-
-struct SubParams
-{
- Activation activation;
-};
-
-struct SpaceToDepthParams
-{
- int block_size;
-};
-
-struct SoftmaxParams
-{
- float beta;
-};
-
-struct StridedSliceParams
-{
- int32_t begin_mask;
- int32_t end_mask;
- int32_t ellipsis_mask;
- int32_t new_axis_mask;
- int32_t shrink_axis_mask;
-};
-
-struct SqueezeParams
-{
- std::vector<int32_t> squeeze_dims;
-};
-
-struct TransposeConvParams
-{
- Padding padding;
- int32_t stride_height;
- int32_t stride_width;
-};
-
-struct UnpackParams
-{
- int axis;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_CORE_KERNELPARAMS_H
diff --git a/compiler/luci-interpreter/src/core/RuntimeGraph.cpp b/compiler/luci-interpreter/src/core/RuntimeGraph.cpp
deleted file mode 100644
index 06f0fed15..000000000
--- a/compiler/luci-interpreter/src/core/RuntimeGraph.cpp
+++ /dev/null
@@ -1,93 +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 "core/RuntimeGraph.h"
-
-#include "core/RuntimeModule.h"
-
-#include <algorithm>
-
-namespace luci_interpreter
-{
-
-Tensor *RuntimeGraph::addTensor(std::unique_ptr<Tensor> &&tensor)
-{
- assert(tensor != nullptr);
- _tensors.push_back(std::move(tensor));
- return _tensors.back().get();
-}
-
-void RuntimeGraph::setInputTensors(const std::vector<Tensor *> &input_tensors)
-{
- assert(std::all_of(input_tensors.cbegin(), input_tensors.cend(),
- [](Tensor *tensor) { return tensor != nullptr; }));
- _input_tensors = input_tensors;
-}
-
-void RuntimeGraph::setOutputTensors(const std::vector<Tensor *> &output_tensors)
-{
- assert(std::all_of(output_tensors.cbegin(), output_tensors.cend(),
- [](Tensor *tensor) { return tensor != nullptr; }));
- _output_tensors = output_tensors;
-}
-
-void RuntimeGraph::addKernel(std::unique_ptr<Kernel> &&kernel)
-{
- assert(kernel != nullptr);
- _kernels.push_back(std::move(kernel));
-}
-
-void RuntimeGraph::execute() const
-{
- EventNotifier *event_notifier = _owning_module->getEventNotifier();
-
- // Notify the observers that the input tensors have changed.
- if (event_notifier != nullptr)
- {
- for (const Tensor *input_tensor : getInputTensors())
- {
- event_notifier->postTensorWrite(input_tensor);
- }
- }
-
- for (const auto &kernel : _kernels)
- {
- if (event_notifier != nullptr)
- {
- event_notifier->preOperatorExecute(kernel.get());
- }
-
- // TODO The `configure` method should only be called if the outputs of an operator need to be
- // resized.
- kernel->configure();
- kernel->execute();
-
- if (event_notifier != nullptr)
- {
- event_notifier->postOperatorExecute(kernel.get());
- }
-
- for (const Tensor *tensor : kernel->getOutputTensors())
- {
- if (event_notifier != nullptr)
- {
- event_notifier->postTensorWrite(tensor);
- }
- }
- }
-}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/core/RuntimeGraph.h b/compiler/luci-interpreter/src/core/RuntimeGraph.h
deleted file mode 100644
index 6ddbea4e9..000000000
--- a/compiler/luci-interpreter/src/core/RuntimeGraph.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef LUCI_INTERPRETER_CORE_RUNTIMEGRAPH_H
-#define LUCI_INTERPRETER_CORE_RUNTIMEGRAPH_H
-
-#include "luci_interpreter/core/Tensor.h"
-#include "core/Kernel.h"
-
-#include <memory>
-#include <vector>
-
-namespace luci_interpreter
-{
-
-class RuntimeModule;
-
-class RuntimeGraph
-{
-public:
- explicit RuntimeGraph(RuntimeModule *owning_module) : _owning_module(owning_module) {}
-
- Tensor *addTensor(std::unique_ptr<Tensor> &&tensor);
-
- void setInputTensors(const std::vector<Tensor *> &input_tensors);
- void setOutputTensors(const std::vector<Tensor *> &output_tensors);
-
- const std::vector<Tensor *> &getInputTensors() const { return _input_tensors; }
- const std::vector<Tensor *> &getOutputTensors() const { return _output_tensors; }
-
- void addKernel(std::unique_ptr<Kernel> &&kernel);
-
- void execute() const;
-
-private:
- RuntimeModule *_owning_module;
- std::vector<std::unique_ptr<Tensor>> _tensors;
- std::vector<Tensor *> _input_tensors;
- std::vector<Tensor *> _output_tensors;
-
- // Kernels in execution order.
- std::vector<std::unique_ptr<Kernel>> _kernels;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_CORE_RUNTIMEGRAPH_H
diff --git a/compiler/luci-interpreter/src/core/RuntimeModule.h b/compiler/luci-interpreter/src/core/RuntimeModule.h
deleted file mode 100644
index dccc3a173..000000000
--- a/compiler/luci-interpreter/src/core/RuntimeModule.h
+++ /dev/null
@@ -1,59 +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.
- */
-
-#ifndef LUCI_INTERPRETER_CORE_RUNTIMEMODULE_H
-#define LUCI_INTERPRETER_CORE_RUNTIMEMODULE_H
-
-#include "core/RuntimeGraph.h"
-#include "core/EventNotifier.h"
-
-#include <memory>
-#include <vector>
-
-namespace luci_interpreter
-{
-
-class RuntimeModule
-{
-public:
- explicit RuntimeModule(EventNotifier *event_notifier) : _event_notifier(event_notifier) {}
-
- EventNotifier *getEventNotifier() const { return _event_notifier; }
-
- RuntimeGraph *addGraph()
- {
- _graphs.push_back(std::make_unique<RuntimeGraph>(this));
- return _graphs.back().get();
- }
-
- const std::vector<Tensor *> &getInputTensors() const { return getMainGraph()->getInputTensors(); }
- const std::vector<Tensor *> &getOutputTensors() const
- {
- return getMainGraph()->getOutputTensors();
- }
-
- void execute() const { getMainGraph()->execute(); }
-
-private:
- RuntimeGraph *getMainGraph() const { return _graphs[0].get(); }
-
- EventNotifier *const _event_notifier;
- std::vector<std::unique_ptr<RuntimeGraph>> _graphs;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_CORE_RUNTIMEMODULE_H
diff --git a/compiler/luci-interpreter/src/core/Tensor.cpp b/compiler/luci-interpreter/src/core/Tensor.cpp
deleted file mode 100644
index 4fe7479e5..000000000
--- a/compiler/luci-interpreter/src/core/Tensor.cpp
+++ /dev/null
@@ -1,68 +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 "luci_interpreter/core/Tensor.h"
-
-#include <cstring>
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-Tensor::Tensor(DataType element_type, Shape shape, AffineQuantization quantization,
- std::string name)
- : _element_type(element_type), _shape(std::move(shape)), _quantization(std::move(quantization)),
- _name(std::move(name))
-{
- const size_t element_size = getDataTypeSize(_element_type);
- const int32_t num_elements = _shape.num_elements();
- _data = std::make_unique<uint8_t[]>(num_elements * element_size);
-}
-
-void Tensor::readData(void *data_ptr, size_t data_size) const
-{
- const size_t element_size = getDataTypeSize(element_type());
- const int32_t num_elements = shape().num_elements();
- if (data_size != num_elements * element_size)
- {
- throw std::invalid_argument("Invalid data size.");
- }
- assert(data_ptr != nullptr);
- std::memcpy(data_ptr, data<void>(), data_size);
-}
-
-void Tensor::writeData(const void *data_ptr, size_t data_size)
-{
- const size_t element_size = getDataTypeSize(element_type());
- const int32_t num_elements = shape().num_elements();
- if (data_size != num_elements * element_size)
- {
- throw std::invalid_argument("Invalid data size.");
- }
- assert(data_ptr != nullptr);
- std::memcpy(data<void>(), data_ptr, data_size);
-}
-
-void Tensor::resize(const Shape &new_shape)
-{
- _shape = new_shape;
- const size_t element_size = getDataTypeSize(_element_type);
- const int32_t num_elements = _shape.num_elements();
- // NOTE: _data can be nullptr for empty tensors
- _data = std::make_unique<uint8_t[]>(num_elements * element_size);
-}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Add.cpp b/compiler/luci-interpreter/src/kernels/Add.cpp
deleted file mode 100644
index 8d119d516..000000000
--- a/compiler/luci-interpreter/src/kernels/Add.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Add.h"
-
-#include "kernels/BinaryOpCommon.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/add.h>
-#include <tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Add::Add(const Tensor *input1, const Tensor *input2, Tensor *output, const AddParams &params)
- : KernelWithParams<AddParams>({input1, input2}, {output}, params)
-{
-}
-
-void Add::configure()
-{
- LUCI_INTERPRETER_CHECK(input1()->element_type() == input2()->element_type());
- if (input1()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(input1()->zero_point() == 0 && input2()->zero_point() == 0 &&
- output()->zero_point() == 0);
- }
-
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Add::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalQuantizedS16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Add::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastAdd4DSlow(
- params, getTensorShape(input1()), getTensorData<float>(input1()), getTensorShape(input2()),
- getTensorData<float>(input2()), getTensorShape(output()), getTensorData<float>(output()));
- }
- else
- {
- tflite::reference_ops::Add(params, getTensorShape(input1()), getTensorData<float>(input1()),
- getTensorShape(input2()), getTensorData<float>(input2()),
- getTensorShape(output()), getTensorData<float>(output()));
- }
-}
-
-void Add::evalQuantized() const
-{
- const auto input1_scale = static_cast<double>(input1()->scale());
- const auto input2_scale = static_cast<double>(input2()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- const int left_shift = 20;
- const double twice_max_input_scale = 2 * std::max(input1_scale, input2_scale);
- const double real_input1_multiplier = input1_scale / twice_max_input_scale;
- const double real_input2_multiplier = input2_scale / twice_max_input_scale;
- const double real_output_multiplier = twice_max_input_scale / ((1 << left_shift) * output_scale);
-
- int32_t input1_multiplier{}, input2_multiplier{}, output_multiplier{};
- int input1_shift{}, input2_shift{}, output_shift{};
- quantizeMultiplierSmallerThanOneExp(real_input1_multiplier, &input1_multiplier, &input1_shift);
- quantizeMultiplierSmallerThanOneExp(real_input2_multiplier, &input2_multiplier, &input2_shift);
- quantizeMultiplierSmallerThanOneExp(real_output_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.left_shift = left_shift;
- // The kernel expects inputs' zero points to be negated.
- params.input1_offset = -input1()->zero_point(); // Note the '-'.
- params.input1_multiplier = input1_multiplier;
- params.input1_shift = input1_shift;
- params.input2_offset = -input2()->zero_point(); // Note the '-'.
- params.input2_multiplier = input2_multiplier;
- params.input2_shift = input2_shift;
- params.output_offset = output()->zero_point();
- params.output_multiplier = output_multiplier;
- params.output_shift = output_shift;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastAdd4DSlow(
- params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- }
- else
- {
- tflite::reference_ops::Add(params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
- }
-}
-
-void Add::evalQuantizedS16() const
-{
- const auto input1_scale = static_cast<double>(input1()->scale());
- const auto input2_scale = static_cast<double>(input2()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- constexpr int left_shift = 12;
- const double twice_max_input_scale = 2 * std::max(input1_scale, input2_scale);
- const double real_input1_multiplier = input1_scale / twice_max_input_scale;
- const double real_input2_multiplier = input2_scale / twice_max_input_scale;
- const double real_output_multiplier = twice_max_input_scale / ((1 << left_shift) * output_scale);
-
- int32_t input1_multiplier{}, input2_multiplier{}, output_multiplier{};
- int input1_shift{}, input2_shift{}, output_shift{};
- quantizeMultiplierSmallerThanOneExp(real_input1_multiplier, &input1_multiplier, &input1_shift);
- quantizeMultiplierSmallerThanOneExp(real_input2_multiplier, &input2_multiplier, &input2_shift);
- quantizeMultiplierSmallerThanOneExp(real_output_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- auto fn = [input1_multiplier, input1_shift, //
- input2_multiplier, input2_shift, //
- output_multiplier, output_shift, //
- activation_min, activation_max](int16_t input1_val, int16_t input2_val) {
- const int32_t shifted_input1_val = static_cast<int32_t>(input1_val) << left_shift;
- const int32_t shifted_input2_val = static_cast<int32_t>(input2_val) << left_shift;
- const int32_t scaled_input1_val = tflite::MultiplyByQuantizedMultiplierSmallerThanOneExp(
- shifted_input1_val, input1_multiplier, input1_shift);
- const int32_t scaled_input2_val = tflite::MultiplyByQuantizedMultiplierSmallerThanOneExp(
- shifted_input2_val, input2_multiplier, input2_shift);
- const int32_t raw_sum = scaled_input1_val + scaled_input2_val;
- const int32_t raw_output = tflite::MultiplyByQuantizedMultiplierSmallerThanOneExp(
- raw_sum, output_multiplier, output_shift);
- const int32_t clamped_output = std::min(activation_max, std::max(activation_min, raw_output));
- return static_cast<int16_t>(clamped_output);
- };
-
- BinaryOpBroadcastSlow(getTensorShape(input1()), getTensorData<int16_t>(input1()),
- getTensorShape(input2()), getTensorData<int16_t>(input2()),
- getTensorShape(output()), getTensorData<int16_t>(output()), fn);
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Add.h b/compiler/luci-interpreter/src/kernels/Add.h
deleted file mode 100644
index 79518845d..000000000
--- a/compiler/luci-interpreter/src/kernels/Add.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_ADD_H
-#define LUCI_INTERPRETER_KERNELS_ADD_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Add : public KernelWithParams<AddParams>
-{
-public:
- Add(const Tensor *input1, const Tensor *input2, Tensor *output, const AddParams &params);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalQuantizedS16() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_ADD_H
diff --git a/compiler/luci-interpreter/src/kernels/Add.test.cpp b/compiler/luci-interpreter/src/kernels/Add.test.cpp
deleted file mode 100644
index de8a3bbb0..000000000
--- a/compiler/luci-interpreter/src/kernels/Add.test.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Add.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-// for quantized Add, the error shouldn't exceed step
-float GetTolerance(float min, float max)
-{
- float kQuantizedStep = (max - min) / 255.0;
- return kQuantizedStep;
-}
-
-TEST(AddTest, Uint8)
-{
- std::initializer_list<int32_t> base_shape = {2, 3, 1, 2};
- std::initializer_list<float> base_data = {-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- std::initializer_list<int32_t> test_shapes[] = {
- {1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- std::initializer_list<float> test_data = {0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- std::initializer_list<int32_t> output_shapes[] = {
- {2, 3, 3, 2}, {2, 3, 1, 2}, {2, 3, 3, 2}, {2, 3, 1, 2}};
- std::vector<std::vector<float>> output_data = {
- {-0.1f, 2.6f, -0.7f, 2.8f, 0.7f, 3.0f, 1.1f, 0.8f, 0.5f, 1.0f, 1.9f, 1.4f,
- 1.0f, -0.8f, 0.4f, -0.6f, 1.8f, -0.2f, 1.4f, 3.0f, 0.8f, 3.0f, 2.2f, 3.0f,
- -1.4f, 0.3f, -2.0f, 0.5f, -0.6f, 0.9f, 0.9f, -1.9f, 0.3f, -1.7f, 1.7f, -1.3f},
- {-0.1f, 2.6f, 0.5f, 1.0f, 1.8f, -0.2f, 1.4f, 3.0f, -2.0f, 0.5f, 1.7f, -1.3f},
- {-0.1f, 2.5f, 0.0f, 2.6f, -0.7f, 1.9f, 1.1f, 0.7f, 1.2f, 0.8f, 0.5f, 0.1f,
- 1.0f, -0.9f, 1.1f, -0.8f, 0.4f, -1.5f, 1.7f, 3.0f, 2.2f, 3.0f, 2.1f, 3.0f,
- -1.1f, 0.5f, -0.6f, 1.0f, -0.7f, 0.9f, 1.2f, -1.7f, 1.7f, -1.2f, 1.6f, -1.3f},
- {-0.1f, 2.5f, 1.2f, 0.8f, 0.4f, -1.5f, 1.7f, 3.0f, -0.6f, 1.0f, 1.6f, -1.3f}};
- float kQuantizedTolerance = GetTolerance(-3.f, 3.f);
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-3.f, 3.f);
- for (int i = 0; i < output_data.size(); i++)
- {
- Tensor input1_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, base_data);
- Tensor input2_tensor = makeInputTensor<DataType::U8>(test_shapes[i], quant_param.first,
- quant_param.second, test_data);
- Tensor output_tensor =
- makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
-
- AddParams params{};
- params.activation = Activation::NONE;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data[i], kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shapes[i]));
- }
- // Re-run with exchanged inputs.
- for (int i = 0; i < output_data.size(); i++)
- {
- Tensor input1_tensor = makeInputTensor<DataType::U8>(test_shapes[i], quant_param.first,
- quant_param.second, test_data);
- Tensor input2_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, base_data);
- Tensor output_tensor =
- makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
-
- AddParams params{};
- params.activation = Activation::NONE;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data[i], kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shapes[i]));
- }
-}
-
-TEST(AddTest, Float)
-{
- Shape base_shape = {2, 3, 1, 2};
- std::vector<Shape> test_shapes{{1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- std::vector<std::vector<float>> test_outputs = {
- {0.0f, 2.6f, 0.0f, 2.8f, 0.7f, 3.2f, 1.1f, 0.8f, 0.5f, 1.0f, 1.9f, 1.4f,
- 1.0f, 0.0f, 0.4f, 0.0f, 1.8f, 0.0f, 1.4f, 3.1f, 0.8f, 3.3f, 2.2f, 3.7f,
- 0.0f, 0.3f, 0.0f, 0.5f, 0.0f, 0.9f, 0.9f, 0.0f, 0.3f, 0.0f, 1.7f, 0.0f},
- {0.0f, 2.6f, 0.5f, 1.0f, 1.8f, 0.0f, 1.4f, 3.1f, 0.0f, 0.5f, 1.7f, 0.0f},
- {0.0f, 2.5f, 0.0f, 2.6f, 0.0f, 1.9f, 1.1f, 0.7f, 1.2f, 0.8f, 0.5f, 0.1f,
- 1.0f, 0.0f, 1.1f, 0.0f, 0.4f, 0.0f, 1.7f, 3.3f, 2.2f, 3.8f, 2.1f, 3.7f,
- 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.9f, 1.2f, 0.0f, 1.7f, 0.0f, 1.6f, 0.0f},
- {0.0f, 2.5f, 1.2f, 0.8f, 0.4f, 0.0f, 1.7f, 3.3f, 0.0f, 1.0f, 1.6f, 0.0f}};
- std::vector<float> input1_data{-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- std::vector<float> input2_data{0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(test_shapes[i], input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs[i], 0.0001f))
- << "With shape number " << i;
- }
- // Re-run with exchanged inputs.
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(test_shapes[i], input2_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs[i], 0.0001f))
- << "With shape number " << i;
- }
-}
-
-TEST(AddTest, SInt16)
-{
- Shape base_shape = {2, 3, 1, 2};
- std::vector<Shape> test_shapes{{1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- std::vector<std::vector<int32_t>> ref_output_shapes{
- {2, 3, 3, 2}, {2, 3, 1, 2}, {2, 3, 3, 2}, {2, 3, 1, 2}};
-
- std::vector<float> input1_data{-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- std::vector<float> input2_data{0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- std::vector<std::vector<float>> ref_outputs = {
- {0.0f, 2.6f, 0.0f, 2.8f, 0.7f, 3.2f, 1.1f, 0.8f, 0.5f, 1.0f, 1.9f, 1.4f,
- 1.0f, 0.0f, 0.4f, 0.0f, 1.8f, 0.0f, 1.4f, 3.1f, 0.8f, 3.3f, 2.2f, 3.7f,
- 0.0f, 0.3f, 0.0f, 0.5f, 0.0f, 0.9f, 0.9f, 0.0f, 0.3f, 0.0f, 1.7f, 0.0f},
- {0.0f, 2.6f, 0.5f, 1.0f, 1.8f, 0.0f, 1.4f, 3.1f, 0.0f, 0.5f, 1.7f, 0.0f},
- {0.0f, 2.5f, 0.0f, 2.6f, 0.0f, 1.9f, 1.1f, 0.7f, 1.2f, 0.8f, 0.5f, 0.1f,
- 1.0f, 0.0f, 1.1f, 0.0f, 0.4f, 0.0f, 1.7f, 3.3f, 2.2f, 3.8f, 2.1f, 3.7f,
- 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.9f, 1.2f, 0.0f, 1.7f, 0.0f, 1.6f, 0.0f},
- {0.0f, 2.5f, 1.2f, 0.8f, 0.4f, 0.0f, 1.7f, 3.3f, 0.0f, 1.0f, 1.6f, 0.0f}};
-
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::S16>(base_shape, 3.0 / 32767, 0, input1_data);
- Tensor input2_tensor =
- makeInputTensor<DataType::S16>(test_shapes[i], 1.0 / 32767, 0, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 4.0 / 32767, 0);
- const float tolerance = output_tensor.scale();
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor),
- ::testing::ElementsAreArray(ref_output_shapes[i]))
- << "With shape number " << i;
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_outputs[i], tolerance))
- << "With shape number " << i;
- }
- // Re-run with exchanged inputs and different scales.
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor =
- makeInputTensor<DataType::S16>(test_shapes[i], 2.0 / 32767, 0, input2_data);
- Tensor input2_tensor = makeInputTensor<DataType::S16>(base_shape, 4.0 / 32767, 0, input1_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 5.0 / 32767, 0);
- const float tolerance = output_tensor.scale();
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor),
- ::testing::ElementsAreArray(ref_output_shapes[i]))
- << "With shape number " << i;
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_outputs[i], tolerance))
- << "With shape number " << i;
- }
-}
-
-TEST(AddTest, Input_Output_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor input2_tensor = makeInputTensor<DataType::S32>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(AddTest, Invalid_Input_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor input2_tensor = makeInputTensor<DataType::S64>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- AddParams params{};
- params.activation = Activation::RELU;
-
- Add kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ArgMax.cpp b/compiler/luci-interpreter/src/kernels/ArgMax.cpp
deleted file mode 100644
index 5c464ed09..000000000
--- a/compiler/luci-interpreter/src/kernels/ArgMax.cpp
+++ /dev/null
@@ -1,140 +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 "kernels/ArgMax.h"
-#include "kernels/Utils.h"
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-ArgMax::ArgMax(const Tensor *input, const Tensor *axis, Tensor *output, const ArgMaxParams &params)
- : KernelWithParams<ArgMaxParams>({input, axis}, {output}, params)
-{
-}
-
-void ArgMax::configure()
-{
- assert(axis()->element_type() == DataType::S32 || axis()->element_type() == DataType::S64);
- assert(input()->shape().num_dims() >= 1);
- const Shape &input_shape = input()->shape();
- const int num_dims = input_shape.num_dims();
- Shape output_shape(num_dims - 1);
-
- // If axis value is negative, then update by adding input_shape's num_dims.
- // If updated value also negative, then assert.
- assert(axis()->shape().num_elements() == 1);
- int axis_value = getTensorData<int32_t>(axis())[0];
- if (axis_value < 0)
- axis_value = axis_value + num_dims;
- assert(axis_value >= 0);
-
- int j = 0;
- for (int i = 0; i < num_dims; i++)
- {
- if (i == axis_value)
- continue;
- output_shape.dim(j++) = input_shape.dim(i);
- }
-
- assert(output()->element_type() == _params.output_type);
-
- output()->resize(output_shape);
-}
-
-void ArgMax::execute() const
-{
-
-#define TF_LITE_ARG_MAX(data_type, axis_type, output_type) \
- tflite::optimized_ops::ArgMinMax(getTensorShape(input()), getTensorData<data_type>(input()), \
- getTensorData<axis_type>(axis()), getTensorShape(output()), \
- getTensorData<output_type>(output()), \
- std::greater<data_type>())
- if (axis()->element_type() == DataType::S32)
- {
- switch (_params.output_type)
- {
- case DataType::S32:
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- TF_LITE_ARG_MAX(float, int32_t, int32_t);
- break;
- case DataType::U8:
- TF_LITE_ARG_MAX(uint8_t, int32_t, int32_t);
- break;
- default:
- throw std::runtime_error("Unsupported input type.");
- }
- break;
- case DataType::S64:
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- TF_LITE_ARG_MAX(float, int32_t, int64_t);
- break;
- case DataType::U8:
- TF_LITE_ARG_MAX(uint8_t, int32_t, int64_t);
- break;
- default:
- throw std::runtime_error("Unsupported input type.");
- }
- break;
- default:
- throw std::runtime_error("Unsupported output type.");
- }
- }
- else
- {
- switch (_params.output_type)
- {
- case DataType::S32:
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- TF_LITE_ARG_MAX(float, int64_t, int32_t);
- break;
- case DataType::U8:
- TF_LITE_ARG_MAX(uint8_t, int64_t, int32_t);
- break;
- default:
- throw std::runtime_error("Unsupported input type.");
- }
- break;
- case DataType::S64:
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- TF_LITE_ARG_MAX(float, int64_t, int64_t);
- break;
- case DataType::U8:
- TF_LITE_ARG_MAX(uint8_t, int64_t, int64_t);
- break;
- default:
- throw std::runtime_error("Unsupported input type.");
- }
- break;
- default:
- throw std::runtime_error("Unsupported output type.");
- }
- }
-#undef TF_LITE_ARG_MAX
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ArgMax.h b/compiler/luci-interpreter/src/kernels/ArgMax.h
deleted file mode 100644
index c851b5891..000000000
--- a/compiler/luci-interpreter/src/kernels/ArgMax.h
+++ /dev/null
@@ -1,44 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_ARGMAX_H
-#define LUCI_INTERPRETER_KERNELS_ARGMAX_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class ArgMax : public KernelWithParams<ArgMaxParams>
-{
-public:
- ArgMax(const Tensor *input, const Tensor *axis, Tensor *output, const ArgMaxParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *axis() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_ARGMAX_H
diff --git a/compiler/luci-interpreter/src/kernels/ArgMax.test.cpp b/compiler/luci-interpreter/src/kernels/ArgMax.test.cpp
deleted file mode 100644
index c6734a114..000000000
--- a/compiler/luci-interpreter/src/kernels/ArgMax.test.cpp
+++ /dev/null
@@ -1,110 +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 "kernels/ArgMax.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T1, typename T2>
-void Check(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> dimension_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<T1> input_data,
- std::initializer_list<int32_t> dimension_data, std::initializer_list<T2> output_data)
-{
- constexpr DataType element_type = getElementType<T1>();
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor dimension_tensor = makeInputTensor<DataType::S32>(dimension_shape, dimension_data);
- Tensor output_tensor = makeOutputTensor(getElementType<T2>());
-
- ArgMaxParams params{};
- params.output_type = getElementType<T2>();
- ArgMax kernel(&input_tensor, &dimension_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<T2>(output_tensor), ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), output_shape);
-}
-
-template <typename T> class ArgMaxTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(ArgMaxTest, DataTypes);
-
-TYPED_TEST(ArgMaxTest, Simple)
-{
- Check<TypeParam, int32_t>(/*input_shape=*/{1, 1, 1, 4}, /*dimension_shape=*/{},
- /*output_shape=*/{1, 1, 1},
- /*input_data=*/
- {
- 1, 9, 7, 3,
- },
- /*dimension_data=*/{3}, /*output_data=*/{1});
- Check<TypeParam, int64_t>(/*input_shape=*/{1, 1, 1, 4}, /*dimension_shape=*/{},
- /*output_shape=*/{1, 1, 1},
- /*input_data=*/
- {
- 1, 9, 7, 3,
- },
- /*dimension_data=*/{3}, /*output_data=*/{1});
-}
-
-TYPED_TEST(ArgMaxTest, MultiDimensions)
-{
- Check<TypeParam, int32_t>(/*input_shape=*/{1, 1, 2, 4}, /*dimension_shape=*/{},
- /*output_shape=*/{1, 1, 2},
- /*input_data=*/
- {
- 1, 2, 7, 8, 1, 9, 7, 3,
- },
- /*dimension_data=*/{3}, /*output_data=*/{3, 1});
- Check<TypeParam, int64_t>(/*input_shape=*/{1, 1, 2, 4}, /*dimension_shape=*/{},
- /*output_shape=*/{1, 1, 2},
- /*input_data=*/
- {
- 1, 2, 7, 8, 1, 9, 7, 3,
- },
- /*dimension_data=*/{3}, /*output_data=*/{3, 1});
-}
-
-TEST(ArgMaxTest, UnsupportedType_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1, 1, 2, 4}, {
- 1, 2, 7, 8, 1, 9, 7, 3,
- });
- Tensor dimension_tensor = makeInputTensor<DataType::S32>({}, {3});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- ArgMaxParams params{};
- params.output_type = DataType::U8;
- ArgMax kernel(&input_tensor, &dimension_tensor, &output_tensor, params);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/AveragePool2D.cpp b/compiler/luci-interpreter/src/kernels/AveragePool2D.cpp
deleted file mode 100644
index df54f9786..000000000
--- a/compiler/luci-interpreter/src/kernels/AveragePool2D.cpp
+++ /dev/null
@@ -1,157 +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 "kernels/AveragePool2D.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h>
-#include <tensorflow/lite/kernels/internal/reference/pooling.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-AveragePool2D::AveragePool2D(const Tensor *input, Tensor *output, const Pool2DParams &params)
- : KernelWithParams<Pool2DParams>({input}, {output}, params)
-{
-}
-
-void AveragePool2D::configure()
-{
- if (input()->element_type() != output()->element_type())
- {
- throw std::runtime_error("Input Tensor and Output Tensor Type must be same");
- }
- if (input()->shape().num_dims() != 4)
- {
- throw std::runtime_error("Input Tensor Shape must be 4-D");
- }
- const Shape &input_shape = input()->shape();
-
- const int32_t batches = input_shape.dim(0);
- const int32_t input_height = input_shape.dim(1);
- const int32_t input_width = input_shape.dim(2);
- const int32_t depth = input_shape.dim(3);
-
- const int32_t output_height = computeOutputSize(_params.padding, input_height,
- _params.filter_height, _params.stride_height);
- const int32_t output_width =
- computeOutputSize(_params.padding, input_width, _params.filter_width, _params.stride_width);
-
- _padding_height =
- computePadding(_params.stride_height, 1, input_height, _params.filter_height, output_height);
- _padding_width =
- computePadding(_params.stride_width, 1, input_width, _params.filter_width, output_width);
- if (input()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
- LUCI_INTERPRETER_CHECK(output()->zero_point() == input()->zero_point());
- }
- else if (input()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
- LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && output()->zero_point() == 0);
- }
- output()->resize({batches, output_height, output_width, depth});
-}
-
-void AveragePool2D::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalSInt16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void AveragePool2D::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- tflite::reference_ops::AveragePool(params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void AveragePool2D::evalQuantized() const
-{
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- tflite::reference_ops::AveragePool(params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
-}
-
-void AveragePool2D::evalSInt16() const
-{
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- tflite::reference_integer_ops::AveragePool(
- params, getTensorShape(input()), getTensorData<int16_t>(input()), //
- getTensorShape(output()), getTensorData<int16_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/AveragePool2D.h b/compiler/luci-interpreter/src/kernels/AveragePool2D.h
deleted file mode 100644
index 282a58797..000000000
--- a/compiler/luci-interpreter/src/kernels/AveragePool2D.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_AVERAGEPOOL2D_H
-#define LUCI_INTERPRETER_KERNELS_AVERAGEPOOL2D_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class AveragePool2D : public KernelWithParams<Pool2DParams>
-{
-public:
- AveragePool2D(const Tensor *input, Tensor *output, const Pool2DParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalSInt16() const;
-
-private:
- int32_t _padding_height{};
- int32_t _padding_width{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_AVERAGEPOOL2D_H
diff --git a/compiler/luci-interpreter/src/kernels/AveragePool2D.test.cpp b/compiler/luci-interpreter/src/kernels/AveragePool2D.test.cpp
deleted file mode 100644
index 83e48c89d..000000000
--- a/compiler/luci-interpreter/src/kernels/AveragePool2D.test.cpp
+++ /dev/null
@@ -1,220 +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 "kernels/AveragePool2D.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(AveragePool2DTest, Float)
-{
- Shape input_shape{1, 3, 5, 1};
- std::vector<float> input_data{
- -4, -3, -2, -1, 0, //
- 1, 2, 3, 4, 5, //
- 6, 7, 8, 9, 10, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 0, 1.5, //
- 4.5, 6, //
- };
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 2, 1}));
-}
-
-TEST(AveragePool2DTest, Uint8_0)
-{
- std::vector<float> input_data{
- 0, -6, 12, 4, //
- -3, -2, 10, 7, //
- };
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-15.9375f, 15.9375f);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({0.0, 6.0}));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 1, 2, 1}));
-}
-
-TEST(AveragePool2DTest, Uint8_1)
-{
- std::vector<float> input_data{
- 0, 6, 12, 4, //
- 3, 2, 10, 7, //
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-15.9375f, 15.9375f);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({2.75, 6.0}));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 1, 2, 1}));
-}
-
-TEST(AveragePool2DTest, SInt16)
-{
- Shape input_shape{1, 3, 5, 1};
- std::vector<int32_t> ref_output_shape{1, 2, 2, 1};
- std::vector<float> input_data{
- -4, -3, -2, -1, 0, //
- 1, 2, 3, 4, 5, //
- 6, 7, 8, 9, 10, //
- };
- std::vector<float> ref_output_data{
- 0, 1.5, //
- 4.5, 6, //
- };
- Tensor input_tensor = makeInputTensor<DataType::S16>(input_shape, 0.5, 0, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.5, 0);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(AveragePool2DTest, Invalid_Input_Shape_NEG)
-{
- Shape input_shape{1, 3, 5};
- std::vector<float> input_data{
- -4, -3, -2, -1, 0, //
- 1, 2, 3, 4, 5, //
- 6, 7, 8, 9, 10, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(AveragePool2DTest, In_Out_Type_NEG)
-{
- Shape input_shape{1, 3, 5, 1};
- std::vector<float> input_data{
- -4, -3, -2, -1, 0, //
- 1, 2, 3, 4, 5, //
- 6, 7, 8, 9, 10, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(AveragePool2DTest, Quant_Param_NEG)
-{
- std::vector<float> input_data{
- 0, -6, 12, 4, //
- -3, -2, 10, 7, //
- };
-
- std::pair<float, int32_t> quant_param1 = quantizationParams<uint8_t>(-15.9375f, 15.9375f);
- std::pair<float, int32_t> quant_param2 = quantizationParams<uint8_t>(-7.875f, 7.875f);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param1.first,
- quant_param1.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param2.first, quant_param2.second);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- AveragePool2D kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/BinaryOpCommon.h b/compiler/luci-interpreter/src/kernels/BinaryOpCommon.h
deleted file mode 100644
index 62bd4158e..000000000
--- a/compiler/luci-interpreter/src/kernels/BinaryOpCommon.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 LUCI_INTERPRETER_KERNELS_BINARYOPUTILS_H
-#define LUCI_INTERPRETER_KERNELS_BINARYOPUTILS_H
-
-#include "tensorflow/lite/kernels/internal/common.h"
-#include "tensorflow/lite/kernels/internal/types.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-// Derived from tensorflow/lite/kernels/internal/reference/maximum_minimum.h (v2.3.0).
-template <typename T, typename Op, int N = 5>
-void BinaryOpBroadcastSlow(const tflite::RuntimeShape &unextended_input1_shape,
- const T *input1_data,
- const tflite::RuntimeShape &unextended_input2_shape,
- const T *input2_data,
- const tflite::RuntimeShape &unextended_output_shape, T *output_data,
- Op op)
-{
- if (unextended_input1_shape == unextended_input2_shape)
- {
- const int flat_size = tflite::MatchingElementsSize(
- unextended_input1_shape, unextended_input2_shape, unextended_output_shape);
- for (int i = 0; i < flat_size; ++i)
- {
- output_data[i] = op(input1_data[i], input2_data[i]);
- }
- }
- else
- {
- assert(unextended_input1_shape.DimensionsCount() <= N);
- assert(unextended_input2_shape.DimensionsCount() <= N);
- assert(unextended_output_shape.DimensionsCount() <= N);
-
- tflite::NdArrayDesc<N> desc1{};
- tflite::NdArrayDesc<N> desc2{};
- tflite::NdArrayDesc<N> output_desc{};
- tflite::NdArrayDescsForElementwiseBroadcast(unextended_input1_shape, unextended_input2_shape,
- &desc1, &desc2);
- tflite::CopyDimsToDesc(tflite::RuntimeShape::ExtendedShape(N, unextended_output_shape),
- &output_desc);
-
- auto fn = [&](int indexes[N]) {
- output_data[SubscriptToIndex(output_desc, indexes)] =
- op(input1_data[SubscriptToIndex(desc1, indexes)],
- input2_data[SubscriptToIndex(desc2, indexes)]);
- };
- tflite::NDOpsHelper<N>(output_desc, fn);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_BINARYOPUTILS_H
diff --git a/compiler/luci-interpreter/src/kernels/CMakeLists.txt b/compiler/luci-interpreter/src/kernels/CMakeLists.txt
deleted file mode 100644
index b460321bd..000000000
--- a/compiler/luci-interpreter/src/kernels/CMakeLists.txt
+++ /dev/null
@@ -1,186 +0,0 @@
-find_package(Threads REQUIRED)
-nnas_find_package(GTest REQUIRED)
-
-set(SOURCES
- Add.h
- Add.cpp
- ArgMax.h
- ArgMax.cpp
- AveragePool2D.h
- AveragePool2D.cpp
- Concatenation.h
- Concatenation.cpp
- Conv2D.h
- Conv2D.cpp
- DepthToSpace.h
- DepthToSpace.cpp
- DepthwiseConv2D.h
- DepthwiseConv2D.cpp
- Div.h
- Div.cpp
- Elu.h
- Elu.cpp
- Floor.h
- Floor.cpp
- FloorDiv.h
- FloorDiv.cpp
- Equal.h
- Equal.cpp
- FullyConnected.h
- FullyConnected.cpp
- Greater.h
- Greater.cpp
- GreaterEqual.h
- GreaterEqual.cpp
- If.h
- If.cpp
- L2Normalize.h
- L2Normalize.cpp
- L2Pool2D.h
- L2Pool2D.cpp
- LeakyRelu.h
- LeakyRelu.cpp
- Less.h
- Less.cpp
- LessEqual.h
- LessEqual.cpp
- LocalResponseNormalization.h
- LocalResponseNormalization.cpp
- Logistic.h
- Logistic.cpp
- LogSoftmax.h
- LogSoftmax.cpp
- Maximum.h
- Maximum.cpp
- MaxPool2D.h
- MaxPool2D.cpp
- Mean.h
- Mean.cpp
- Minimum.h
- Minimum.cpp
- Mul.h
- Mul.cpp
- NotEqual.h
- NotEqual.cpp
- Pad.h
- Pad.cpp
- Pow.h
- Pow.cpp
- Prelu.h
- Prelu.cpp
- Relu.h
- Relu.cpp
- Relu6.h
- Relu6.cpp
- Reshape.h
- Reshape.cpp
- ResizeBilinear.h
- ResizeBilinear.cpp
- ResizeNearestNeighbor.h
- ResizeNearestNeighbor.cpp
- Reverse.h
- Reverse.cpp
- Rsqrt.h
- Rsqrt.cpp
- Slice.h
- Slice.cpp
- Softmax.h
- Softmax.cpp
- SpaceToDepth.h
- SpaceToDepth.cpp
- Split.h
- Split.cpp
- StridedSlice.h
- StridedSlice.cpp
- Sqrt.h
- Sqrt.cpp
- Squeeze.h
- Squeeze.cpp
- Sub.h
- Sub.cpp
- Tanh.h
- Tanh.cpp
- Transpose.h
- Transpose.cpp
- TransposeConv.h
- TransposeConv.cpp
- Unpack.h
- Unpack.cpp)
-
-list(APPEND SOURCES
- BinaryOpCommon.h
- Utils.h
- Utils.cpp
- ${TensorFlowSource_DIR}/tensorflow/lite/kernels/internal/quantization_util.cc)
-
-add_library(luci_interpreter_kernels STATIC ${SOURCES})
-set_target_properties(luci_interpreter_kernels PROPERTIES POSITION_INDEPENDENT_CODE ON)
-target_include_directories(luci_interpreter_kernels PUBLIC ${LUCI_INTERPRETER_SOURCE_DIR})
-target_include_directories(luci_interpreter_kernels SYSTEM PRIVATE
- "${TensorFlowRuySource_DIR}"
- "${TensorFlowGEMMLowpSource_DIR}"
- "${TensorFlowEigenSource_DIR}"
- "${TensorFlowSource_DIR}")
-target_link_libraries(luci_interpreter_kernels
- PUBLIC luci_interpreter_core
- PRIVATE nncc_common Threads::Threads)
-
-
-set(TEST_SOURCES
- Add.test.cpp
- ArgMax.test.cpp
- AveragePool2D.test.cpp
- Concatenation.test.cpp
- Conv2D.test.cpp
- DepthToSpace.test.cpp
- DepthwiseConv2D.test.cpp
- Div.test.cpp
- Elu.test.cpp
- Floor.test.cpp
- FloorDiv.test.cpp
- Equal.test.cpp
- FullyConnected.test.cpp
- Greater.test.cpp
- GreaterEqual.test.cpp
- If.test.cpp
- L2Normalize.test.cpp
- L2Pool2D.test.cpp
- LeakyRelu.test.cpp
- Less.test.cpp
- LessEqual.test.cpp
- LocalResponseNormalization.test.cpp
- Logistic.test.cpp
- LogSoftmax.test.cpp
- Maximum.test.cpp
- MaxPool2D.test.cpp
- Mean.test.cpp
- Minimum.test.cpp
- Mul.test.cpp
- NotEqual.test.cpp
- Pad.test.cpp
- Pow.test.cpp
- Prelu.test.cpp
- Relu.test.cpp
- Relu6.test.cpp
- Reshape.test.cpp
- ResizeBilinear.test.cpp
- ResizeNearestNeighbor.test.cpp
- Reverse.test.cpp
- Rsqrt.test.cpp
- Slice.test.cpp
- Softmax.test.cpp
- SpaceToDepth.test.cpp
- Split.test.cpp
- StridedSlice.test.cpp
- Sqrt.test.cpp
- Squeeze.test.cpp
- Sub.test.cpp
- Tanh.test.cpp
- Transpose.test.cpp
- TransposeConv.test.cpp
- Unpack.test.cpp)
-
-list(APPEND TEST_SOURCES TestUtils.h TestUtils.cpp)
-
-GTest_AddTest(luci_interpreter_kernels_test ${TEST_SOURCES})
-target_link_libraries(luci_interpreter_kernels_test luci_interpreter_kernels)
diff --git a/compiler/luci-interpreter/src/kernels/Concatenation.cpp b/compiler/luci-interpreter/src/kernels/Concatenation.cpp
deleted file mode 100644
index 6f8820446..000000000
--- a/compiler/luci-interpreter/src/kernels/Concatenation.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Concatenation.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Concatenation::Concatenation(std::vector<const Tensor *> inputs, Tensor *output,
- const ConcatenationParams &params)
- : KernelWithParams<ConcatenationParams>(std::move(inputs), {output}, params)
-{
-}
-
-void Concatenation::configure()
-{
- const int num_inputs = _inputs.size();
- LUCI_INTERPRETER_CHECK(num_inputs > 0);
- const Tensor *t0 = _inputs[0];
-
- int axis = _params.axis;
- if (axis < 0)
- axis += t0->shape().num_dims();
- LUCI_INTERPRETER_CHECK(axis >= 0 && axis < t0->shape().num_dims());
-
- int32_t sum_axis = t0->shape().dim(axis);
- for (int i = 1; i < num_inputs; ++i)
- {
- const Tensor *tensor = _inputs[i];
- LUCI_INTERPRETER_CHECK(tensor->element_type() == t0->element_type());
- LUCI_INTERPRETER_CHECK(tensor->shape().num_dims() == t0->shape().num_dims());
- for (int d = 0; d < t0->shape().num_dims(); ++d)
- {
- if (d == axis)
- {
- sum_axis += tensor->shape().dim(axis);
- }
- else
- {
- LUCI_INTERPRETER_CHECK(tensor->shape().dim(d) == t0->shape().dim(d));
- }
- }
- }
-
- Shape output_shape = t0->shape();
- output_shape.dim(axis) = sum_axis;
-
- // TODO S8 type needs more checking: quantization parameters of all input tensors and the output
- // tensor should be the same. Note that there is no such requirement for U8 type.
- if (t0->element_type() == DataType::S8)
- throw std::runtime_error("Unsupported type.");
-
- output()->resize(output_shape);
-}
-
-void Concatenation::execute() const
-{
- switch (_inputs[0]->element_type())
- {
- case DataType::FLOAT32:
- evalGeneric<float>();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S8:
- evalGeneric<int8_t>();
- break;
- case DataType::S32:
- evalGeneric<int32_t>();
- break;
- case DataType::S64:
- evalGeneric<int64_t>();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-template <typename T> void Concatenation::evalGeneric() const
-{
- int axis = _params.axis;
- if (axis < 0)
- axis += output()->shape().num_dims();
-
- VectorOfTensors<T, true> inputs(_inputs);
- tflite::ConcatenationParams params{};
- params.axis = axis;
- params.inputs_count = _inputs.size();
- tflite::reference_ops::Concatenation(params, inputs.shapes(), inputs.data(),
- getTensorShape(output()), getTensorData<T>(output()));
-}
-
-void Concatenation::evalQuantized() const
-{
- int axis = _params.axis;
- if (axis < 0)
- axis += output()->shape().num_dims();
-
- VectorOfQuantizedTensors<true> inputs(_inputs);
- tflite::ConcatenationParams params{};
- params.axis = axis;
- params.input_zeropoint = inputs.zero_point();
- params.input_scale = inputs.scale();
- params.inputs_count = _inputs.size();
- params.output_zeropoint = output()->zero_point();
- params.output_scale = output()->scale();
-
- tflite::reference_ops::ConcatenationWithScaling(params, inputs.shapes(), inputs.data(),
- getTensorShape(output()),
- getTensorData<uint8_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Concatenation.h b/compiler/luci-interpreter/src/kernels/Concatenation.h
deleted file mode 100644
index b48c8ed1e..000000000
--- a/compiler/luci-interpreter/src/kernels/Concatenation.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_CONCATENATION_H
-#define LUCI_INTERPRETER_KERNELS_CONCATENATION_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Concatenation : public KernelWithParams<ConcatenationParams>
-{
-public:
- Concatenation(std::vector<const Tensor *> inputs, Tensor *output,
- const ConcatenationParams &params);
-
- const Tensor *input(int index) const { return _inputs[index]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> void evalGeneric() const;
- void evalQuantized() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_CONCATENATION_H
diff --git a/compiler/luci-interpreter/src/kernels/Concatenation.test.cpp b/compiler/luci-interpreter/src/kernels/Concatenation.test.cpp
deleted file mode 100644
index 91707a256..000000000
--- a/compiler/luci-interpreter/src/kernels/Concatenation.test.cpp
+++ /dev/null
@@ -1,169 +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 "kernels/Concatenation.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(ConcatenationTest, Float)
-{
- std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- // Try different 'axis' and expect different results.
- {
- params.axis = 0;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
- }
- {
- params.axis = -2; // Same as '0'.
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
- }
- {
- params.axis = 1;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
- }
- {
- params.axis = -1; // Same as '1'.
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
- }
-}
-
-TEST(ConcatenationTest, Input_Number_Check_NEG)
-{
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- params.axis = -1;
-
- Concatenation kernel({}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ConcatenationTest, Invalid_Axis_NEG)
-{
- std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- params.axis = -3;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ConcatenationTest, Mismatching_Input_Type_NEG)
-{
- std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<uint8_t> input2_data{7, 8, 9, 10, 11, 12};
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::U8>({2, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- params.axis = -1;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ConcatenationTest, Mismatching_Input_Dimension_Num_NEG)
-{
- std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>({1, 2, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- params.axis = -1;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ConcatenationTest, Mismatching_Input_Dimension_NEG)
-{
- std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<float> input2_data{7, 8, 9, 10, 11, 12, 13, 14, 15};
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
- ConcatenationParams params{};
-
- params.axis = -1;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ConcatenationTest, Unsupported_Configure_Type_NEG)
-{
- std::vector<int8_t> input1_data{1, 2, 3, 4, 5, 6};
- std::vector<int8_t> input2_data{7, 8, 9, 10, 11, 12};
- Tensor input1_tensor = makeInputTensor<DataType::S8>({2, 3}, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::S8>({2, 3}, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::S8);
- ConcatenationParams params{};
-
- params.axis = -1;
-
- Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Conv2D.cpp b/compiler/luci-interpreter/src/kernels/Conv2D.cpp
deleted file mode 100644
index a51fb4afc..000000000
--- a/compiler/luci-interpreter/src/kernels/Conv2D.cpp
+++ /dev/null
@@ -1,194 +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 "kernels/Conv2D.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
-
-#include <stdexcept>
-#include <thread>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Conv2D::Conv2D(const Tensor *input, const Tensor *filter, const Tensor *bias, Tensor *output,
- const Conv2DParams &params)
- : KernelWithParams<Conv2DParams>({input, filter, bias}, {output}, params)
-{
-}
-
-void Conv2D::configure()
-{
- // TensorFlow Lite (as of v2.2.0) supports the following combinations of types:
- // | input filter bias output |
- // ----+---------------------------+
- // (1) | float float float float |
- // (2) | float int8 float float | hybrid
- // (3) | uint8 uint8 int32 uint8 | quantized
- // (4) | int8 int8 int32 int8 | quantized per channel
- //
- // We only support (1) and (3) for now.
- if (input()->element_type() == DataType::FLOAT32 && filter()->element_type() == DataType::FLOAT32)
- {
- LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::FLOAT32);
- }
- else if (input()->element_type() == DataType::U8 && filter()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::S32);
- }
- else
- {
- throw std::runtime_error("Unsupported type.");
- }
- LUCI_INTERPRETER_CHECK(output()->element_type() == input()->element_type());
-
- const Shape &input_shape = input()->shape();
- const Shape &filter_shape = filter()->shape();
- LUCI_INTERPRETER_CHECK(input_shape.num_dims() == 4 && filter_shape.num_dims() == 4);
-
- const int32_t batches = input_shape.dim(0);
- const int32_t input_height = input_shape.dim(1);
- const int32_t input_width = input_shape.dim(2);
- const int32_t output_depth = filter_shape.dim(0);
- const int32_t filter_height = filter_shape.dim(1);
- const int32_t filter_width = filter_shape.dim(2);
- LUCI_INTERPRETER_CHECK(filter_shape.dim(3) == input_shape.dim(3));
-
- LUCI_INTERPRETER_CHECK(bias() == nullptr || (bias()->shape().num_dims() == 1 &&
- bias()->shape().dim(0) == output_depth));
-
- const int32_t output_height =
- computeOutputSize(_params.padding, input_height, filter_height, _params.stride_height,
- _params.dilation_height_factor);
- const int32_t output_width =
- computeOutputSize(_params.padding, input_width, filter_width, _params.stride_width,
- _params.dilation_width_factor);
-
- _padding_height = computePadding(_params.stride_height, _params.dilation_height_factor,
- input_height, filter_height, output_height);
- _padding_width = computePadding(_params.stride_width, _params.dilation_width_factor, input_width,
- filter_width, output_width);
-
- output()->resize({batches, output_height, output_width, output_depth});
-
- // Allocate tensor for Im2Col, if needed.
- // The checks here should be aligned with the actual implementation.
- const bool need_dilated_im2col =
- _params.dilation_height_factor != 1 || _params.dilation_width_factor != 1;
- const bool need_non_dilated_im2col = _params.stride_height != 1 || _params.stride_width != 1 ||
- filter_height != 1 || filter_width != 1;
- const bool need_im2col = need_dilated_im2col || need_non_dilated_im2col;
- if (need_im2col)
- {
- const int input_depth = input_shape.dim(3);
- Shape im2col_shape{batches, output_height, output_width,
- input_depth * filter_height * filter_width};
- _im2col =
- std::make_unique<Tensor>(input()->element_type(), im2col_shape, AffineQuantization{}, "");
- }
-}
-
-void Conv2D::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- if (filter()->element_type() == DataType::FLOAT32)
- {
- evalFloat();
- break;
- }
- throw std::runtime_error("Unsupported type.");
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Conv2D::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::ConvParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.dilation_height_factor = _params.dilation_height_factor;
- params.dilation_width_factor = _params.dilation_width_factor;
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- tflite::optimized_ops::Conv(params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(filter()), getTensorData<float>(filter()),
- getTensorShape(bias()), getTensorData<float>(bias()),
- getTensorShape(output()), getTensorData<float>(output()),
- getTensorShape(_im2col.get()), getTensorData<float>(_im2col.get()));
-}
-
-void Conv2D::evalQuantized() const
-{
- const auto input_scale = static_cast<double>(input()->scale());
- const auto filter_scale = static_cast<double>(filter()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- const double real_multiplier = input_scale * filter_scale / output_scale;
- int32_t output_multiplier{};
- int output_shift{};
- quantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::ConvParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.dilation_height_factor = _params.dilation_height_factor;
- params.dilation_width_factor = _params.dilation_width_factor;
- // The kernel expects input and filter zero points to be negated.
- params.input_offset = -input()->zero_point(); // Note the '-'.
- params.weights_offset = -filter()->zero_point(); // Note the '-'.
- params.output_offset = output()->zero_point();
- params.output_multiplier = output_multiplier;
- params.output_shift = output_shift;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- // TODO This should only be done once (although it takes only a few microseconds).
- // Also, the user should be able to adjust the number of threads.
- auto gemmlowp_context = std::make_unique<gemmlowp::GemmContext>();
- gemmlowp_context->set_max_num_threads(static_cast<int>(std::thread::hardware_concurrency()));
-
- tflite::optimized_ops::Conv(
- params, getTensorShape(input()), getTensorData<uint8_t>(input()), getTensorShape(filter()),
- getTensorData<uint8_t>(filter()), getTensorShape(bias()), getTensorData<int32_t>(bias()),
- getTensorShape(output()), getTensorData<uint8_t>(output()), getTensorShape(_im2col.get()),
- getTensorData<uint8_t>(_im2col.get()), gemmlowp_context.get());
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Conv2D.h b/compiler/luci-interpreter/src/kernels/Conv2D.h
deleted file mode 100644
index 69e309852..000000000
--- a/compiler/luci-interpreter/src/kernels/Conv2D.h
+++ /dev/null
@@ -1,57 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_CONV2D_H
-#define LUCI_INTERPRETER_KERNELS_CONV2D_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <memory>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Conv2D : public KernelWithParams<Conv2DParams>
-{
-public:
- Conv2D(const Tensor *input, const Tensor *filter, const Tensor *bias, Tensor *output,
- const Conv2DParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *filter() const { return _inputs[1]; }
- const Tensor *bias() const { return _inputs[2]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- std::unique_ptr<Tensor> _im2col;
- int32_t _padding_height{};
- int32_t _padding_width{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_CONV2D_H
diff --git a/compiler/luci-interpreter/src/kernels/Conv2D.test.cpp b/compiler/luci-interpreter/src/kernels/Conv2D.test.cpp
deleted file mode 100644
index be8364528..000000000
--- a/compiler/luci-interpreter/src/kernels/Conv2D.test.cpp
+++ /dev/null
@@ -1,314 +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 "kernels/Conv2D.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(Conv2DTest, Float)
-{
- Shape input_shape{1, 4, 3, 2};
- Shape filter_shape{2, 2, 2, 2};
- Shape bias_shape{2};
- std::vector<float> input_data{
- 1, 2, 3, 4, 5, 6, // row = 0
- 7, 8, 9, 10, 11, 12, // row = 1
- 13, 14, 15, 16, 17, 18, // row = 2
- 19, 20, 21, 22, 23, 24, // row = 3
- };
- std::vector<float> filter_data{
- 1, 2, -3, -4, // out = 0, row = 0
- -5, 6, -7, 8, // out = 1, row = 0
- 4, -2, 3, -1, // out = 0, row = 1
- -8, -6, 7, 5, // out = 1, row = 1
- };
- std::vector<float> bias_data{1, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 11, 16, 7, 20, // row = 0
- 0, 40, 0, 44, // row = 1
- };
- std::vector<int32_t> ref_output_shape{1, 2, 2, 2};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(Conv2DTest, FloatCheck)
-{
- Shape input_shape{2, 2, 4, 1};
- Shape filter_shape{3, 2, 2, 1};
- Shape bias_shape{3};
- std::vector<float> input_data{
- // First batch
- 1, 1, 1, 1, // row = 1
- 2, 2, 2, 2, // row = 2
- // Second batch
- 1, 2, 3, 4, // row = 1
- 1, 2, 3, 4, // row = 2
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, // first 2x2 filter
- -1, 1, -1, 1, // second 2x2 filter
- -1, -1, 1, 1, // third 2x2 filter
- };
- std::vector<float> bias_data{1, 2, 3};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 2;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::NONE;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 18, 2, 5, // first batch, left
- 18, 2, 5, // first batch, right
- 17, 4, 3, // second batch, left
- 37, 4, 3, // second batch, right
- };
- std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(Conv2DTest, Uint8)
-{
- std::vector<float> input_data{
- // First batch
- 1, 1, 1, 1, // row = 1
- 2, 2, 2, 2, // row = 2
- // Second batch
- 1, 2, 3, 4, // row = 1
- 1, 2, 3, 4, // row = 2
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, // first 2x2 filter
- -1, 1, -1, 1, // second 2x2 filter
- -1, -1, 1, 1, // third 2x2 filter
- };
- std::vector<float> bias_data{1, 2, 3};
-
- std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(-63.5, 64);
- std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(-127, 128);
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({2, 2, 4, 1}, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::U8>({3, 2, 2, 1}, input_quant_param.first,
- input_quant_param.second, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::S32>(
- {3}, input_quant_param.first * input_quant_param.first, 0, bias_data);
- Tensor output_tensor =
- makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 2;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::NONE;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 18, 2, 5, // first batch, left
- 18, 2, 5, // first batch, right
- 17, 4, 3, // second batch, left
- 37, 4, 3, // second batch, right
- };
- std::vector<int32_t> ref_output_shape{2, 1, 2, 3};
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(Conv2DTest, Unsupported_Type_Configure_NEG)
-{
- Shape input_shape{1, 4, 3, 2};
- Shape filter_shape{2, 2, 2, 2};
- Shape bias_shape{2};
- std::vector<int32_t> input_data{
- 1, 2, 3, 4, 5, 6, // row = 0
- 7, 8, 9, 10, 11, 12, // row = 1
- 13, 14, 15, 16, 17, 18, // row = 2
- 19, 20, 21, 22, 23, 24, // row = 3
- };
- std::vector<float> filter_data{
- 1, 2, -3, -4, // out = 0, row = 0
- -5, 6, -7, 8, // out = 1, row = 0
- 4, -2, 3, -1, // out = 0, row = 1
- -8, -6, 7, 5, // out = 1, row = 1
- };
- std::vector<float> bias_data{1, 2};
- Tensor input_tensor = makeInputTensor<DataType::S32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(Conv2DTest, Invalid_Bias_Type_NEG)
-{
- Shape input_shape{1, 4, 3, 2};
- Shape filter_shape{2, 2, 2, 2};
- Shape bias_shape{2};
- std::vector<float> input_data{
- 1, 2, 3, 4, 5, 6, // row = 0
- 7, 8, 9, 10, 11, 12, // row = 1
- 13, 14, 15, 16, 17, 18, // row = 2
- 19, 20, 21, 22, 23, 24, // row = 3
- };
- std::vector<float> filter_data{
- 1, 2, -3, -4, // out = 0, row = 0
- -5, 6, -7, 8, // out = 1, row = 0
- 4, -2, 3, -1, // out = 0, row = 1
- -8, -6, 7, 5, // out = 1, row = 1
- };
- std::vector<uint8_t> bias_data{1, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::U8>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(Conv2DTest, Invalid_Bias_Data_NEG)
-{
- Shape input_shape{1, 4, 3, 2};
- Shape filter_shape{2, 2, 2, 2};
- Shape bias_shape{3};
- std::vector<float> input_data{
- 1, 2, 3, 4, 5, 6, // row = 0
- 7, 8, 9, 10, 11, 12, // row = 1
- 13, 14, 15, 16, 17, 18, // row = 2
- 19, 20, 21, 22, 23, 24, // row = 3
- };
- std::vector<float> filter_data{
- 1, 2, -3, -4, // out = 0, row = 0
- -5, 6, -7, 8, // out = 1, row = 0
- 4, -2, 3, -1, // out = 0, row = 1
- -8, -6, 7, 5, // out = 1, row = 1
- };
- std::vector<float> bias_data{1, 2, 3};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(Conv2DTest, Invalid_Input_Shape_NEG)
-{
- Shape input_shape{1, 4, 6, 1};
- Shape filter_shape{2, 2, 2, 2};
- Shape bias_shape{2};
- std::vector<float> input_data{
- 1, 2, 3, 4, 5, 6, // row = 0
- 7, 8, 9, 10, 11, 12, // row = 1
- 13, 14, 15, 16, 17, 18, // row = 2
- 19, 20, 21, 22, 23, 24, // row = 3
- };
- std::vector<float> filter_data{
- 1, 2, -3, -4, // out = 0, row = 0
- -5, 6, -7, 8, // out = 1, row = 0
- 4, -2, 3, -1, // out = 0, row = 1
- -8, -6, 7, 5, // out = 1, row = 1
- };
- std::vector<float> bias_data{1, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Conv2DParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- Conv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/DepthToSpace.cpp b/compiler/luci-interpreter/src/kernels/DepthToSpace.cpp
deleted file mode 100644
index 57238313c..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthToSpace.cpp
+++ /dev/null
@@ -1,80 +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 "DepthToSpace.h"
-#include "Utils.h"
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-DepthToSpace::DepthToSpace(const Tensor *input, Tensor *output, const DepthToSpaceParams &params)
- : KernelWithParams<DepthToSpaceParams>({input}, {output}, params)
-{
-}
-
-void DepthToSpace::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4);
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::FLOAT32 ||
- output()->element_type() == DataType::U8)
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type())
- const int block_size = params().block_size;
- const int32_t input_height = input()->shape().dim(1);
- const int32_t input_width = input()->shape().dim(2);
- const int32_t input_channels = input()->shape().dim(3);
- int32_t output_height = input_height * block_size;
- int32_t output_width = input_width * block_size;
- int32_t output_channels = input_channels / block_size / block_size;
-
- LUCI_INTERPRETER_CHECK(input_height == output_height / block_size);
- LUCI_INTERPRETER_CHECK(input_width == output_width / block_size);
- LUCI_INTERPRETER_CHECK(input_channels == output_channels * block_size * block_size);
-
- Shape output_shape(4);
- output_shape.dim(0) = input()->shape().dim(0);
- output_shape.dim(1) = output_height;
- output_shape.dim(2) = output_width;
- output_shape.dim(3) = output_channels;
-
- output()->resize(output_shape);
-}
-
-void DepthToSpace::execute() const
-{
- tflite::DepthToSpaceParams op_params;
- op_params.block_size = params().block_size;
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::optimized_ops::DepthToSpace(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::optimized_ops::DepthToSpace(op_params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported Type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/DepthToSpace.h b/compiler/luci-interpreter/src/kernels/DepthToSpace.h
deleted file mode 100644
index 63ce37610..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthToSpace.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H
-#define LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <vector>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class DepthToSpace : public KernelWithParams<DepthToSpaceParams>
-{
-public:
- DepthToSpace(const Tensor *input, Tensor *output, const DepthToSpaceParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_DEPTHTOSPACE_H
diff --git a/compiler/luci-interpreter/src/kernels/DepthToSpace.test.cpp b/compiler/luci-interpreter/src/kernels/DepthToSpace.test.cpp
deleted file mode 100644
index 3dee4ad36..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthToSpace.test.cpp
+++ /dev/null
@@ -1,105 +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 "kernels/DepthToSpace.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T> class DepthToSpaceTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(DepthToSpaceTest, DataTypes);
-
-TYPED_TEST(DepthToSpaceTest, SimpleCase)
-{
- std::vector<TypeParam> input_data{1, 2, 3, 4, 5, 6, 7, 8};
- Shape input_shape{1, 1, 2, 4};
- std::vector<TypeParam> output_data{1, 2, 5, 6, 3, 4, 7, 8};
- std::vector<int32_t> output_shape{1, 2, 4, 1};
-
- Tensor input_tensor = makeInputTensor<getElementType<TypeParam>()>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(getElementType<TypeParam>());
-
- DepthToSpaceParams params{};
- params.block_size = 2;
-
- DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<TypeParam>(output_tensor),
- ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(DepthToSpaceTest, InvalidInputShape_NEG)
-{
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8};
- Shape input_shape{1, 2, 4};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthToSpaceParams params{};
- params.block_size = 2;
-
- DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthToSpaceTest, InOutTypeMismatch_NEG)
-{
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8};
- Shape input_shape{1, 1, 2, 4};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- DepthToSpaceParams params{};
- params.block_size = 2;
-
- DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthToSpaceTest, InvalidBlockSize_NEG)
-{
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8};
- Shape input_shape{1, 1, 2, 4};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthToSpaceParams params{};
- params.block_size = 3;
-
- DepthToSpace kernel = DepthToSpace(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.cpp b/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.cpp
deleted file mode 100644
index 99d52715b..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.cpp
+++ /dev/null
@@ -1,175 +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 "kernels/DepthwiseConv2D.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h>
-#include <tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-DepthwiseConv2D::DepthwiseConv2D(const Tensor *input, const Tensor *filter, const Tensor *bias,
- Tensor *output, const DepthwiseConv2DParams &params)
- : KernelWithParams<DepthwiseConv2DParams>({input, filter, bias}, {output}, params)
-{
-}
-
-void DepthwiseConv2D::configure()
-{
- // TensorFlow Lite (as of v2.2.0) supports the following combinations of types:
- // | input filter bias output |
- // ----+---------------------------+
- // (1) | float float float float |
- // (2) | float int8 float float | hybrid
- // (3) | uint8 uint8 int32 uint8 | quantized
- // (4) | int8 int8 int32 int8 | quantized per channel
- // (5) | int16 int8 int64 int16 | quantized per channel 16x8
- //
- // We only support (1) and (3) for now.
- if (input()->element_type() == DataType::FLOAT32 && filter()->element_type() == DataType::FLOAT32)
- {
- LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::FLOAT32);
- }
- else if (input()->element_type() == DataType::U8 && filter()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::S32);
- }
- else
- {
- throw std::runtime_error("Unsupported type.");
- }
- LUCI_INTERPRETER_CHECK(output()->element_type() == input()->element_type());
-
- const Shape &input_shape = input()->shape();
- const Shape &filter_shape = filter()->shape();
- LUCI_INTERPRETER_CHECK(input_shape.num_dims() == 4 && filter_shape.num_dims() == 4);
-
- const int32_t batches = input_shape.dim(0);
- const int32_t input_height = input_shape.dim(1);
- const int32_t input_width = input_shape.dim(2);
- // Filter format: [1, H, W, O].
- LUCI_INTERPRETER_CHECK(filter_shape.dim(0) == 1);
- const int32_t filter_height = filter_shape.dim(1);
- const int32_t filter_width = filter_shape.dim(2);
- const int32_t channels_out = filter_shape.dim(3);
-
- LUCI_INTERPRETER_CHECK(bias() == nullptr || (bias()->shape().num_dims() == 1 &&
- bias()->shape().dim(0) == channels_out));
-
- const int32_t output_height =
- computeOutputSize(_params.padding, input_height, filter_height, _params.stride_height,
- _params.dilation_height_factor);
- const int32_t output_width =
- computeOutputSize(_params.padding, input_width, filter_width, _params.stride_width,
- _params.dilation_width_factor);
-
- _padding_height = computePadding(_params.stride_height, _params.dilation_height_factor,
- input_height, filter_height, output_height);
- _padding_width = computePadding(_params.stride_width, _params.dilation_width_factor, input_width,
- filter_width, output_width);
-
- output()->resize({batches, output_height, output_width, channels_out});
-}
-
-void DepthwiseConv2D::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- if (filter()->element_type() == DataType::FLOAT32)
- {
- evalFloat();
- break;
- }
- throw std::runtime_error("Unsupported type.");
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void DepthwiseConv2D::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::DepthwiseParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.dilation_height_factor = _params.dilation_height_factor;
- params.dilation_width_factor = _params.dilation_width_factor;
- params.depth_multiplier = _params.depth_multiplier;
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- tflite::reference_ops::DepthwiseConv(
- params, getTensorShape(input()), getTensorData<float>(input()), getTensorShape(filter()),
- getTensorData<float>(filter()), getTensorShape(bias()), getTensorData<float>(bias()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void DepthwiseConv2D::evalQuantized() const
-{
- const auto input_scale = static_cast<double>(input()->scale());
- const auto filter_scale = static_cast<double>(filter()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- const double real_multiplier = input_scale * filter_scale / output_scale;
- int32_t output_multiplier{};
- int output_shift{};
- quantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::DepthwiseParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.dilation_height_factor = _params.dilation_height_factor;
- params.dilation_width_factor = _params.dilation_width_factor;
- params.depth_multiplier = _params.depth_multiplier;
- // The kernel expects input and filter zero points to be negated.
- params.input_offset = -input()->zero_point(); // Note the '-'.
- params.weights_offset = -filter()->zero_point(); // Note the '-'.
- params.output_offset = output()->zero_point();
- params.output_multiplier = output_multiplier;
- params.output_shift = output_shift;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- tflite::reference_ops::DepthwiseConv(
- params, getTensorShape(input()), getTensorData<uint8_t>(input()), getTensorShape(filter()),
- getTensorData<uint8_t>(filter()), getTensorShape(bias()), getTensorData<int32_t>(bias()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.h b/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.h
deleted file mode 100644
index 62f4bff0e..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.h
+++ /dev/null
@@ -1,54 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_DEPTHWISECONV2D_H
-#define LUCI_INTERPRETER_KERNELS_DEPTHWISECONV2D_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class DepthwiseConv2D : public KernelWithParams<DepthwiseConv2DParams>
-{
-public:
- DepthwiseConv2D(const Tensor *input, const Tensor *filter, const Tensor *bias, Tensor *output,
- const DepthwiseConv2DParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *filter() const { return _inputs[1]; }
- const Tensor *bias() const { return _inputs[2]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _padding_height{};
- int32_t _padding_width{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_DEPTHWISECONV2D_H
diff --git a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.test.cpp b/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.test.cpp
deleted file mode 100644
index a5128289f..000000000
--- a/compiler/luci-interpreter/src/kernels/DepthwiseConv2D.test.cpp
+++ /dev/null
@@ -1,303 +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 "kernels/DepthwiseConv2D.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(DepthwiseConv2DTest, Float)
-{
- Shape input_shape{1, 4, 2, 2};
- Shape filter_shape{1, 2, 2, 4};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 71, 0, 99, 0, //
- 167, 0, 227, 28, //
- };
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 1, 4}));
-}
-
-TEST(DepthwiseConv2DTest, Uint8)
-{
- std::vector<float> input_data{
- 1, 2, 7, 8, // column 1
- 3, 4, 9, 10, // column 2
- 5, 6, 11, 12, // column 3
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
-
- std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(-63.5, 64);
- std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(-127, 128);
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 3, 2, 2}, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::U8>({1, 2, 2, 4}, input_quant_param.first,
- input_quant_param.second, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::S32>(
- {4}, input_quant_param.first * input_quant_param.first, 0, bias_data);
- Tensor output_tensor =
- makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 1;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::NONE;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 71, -34, 99, -20, //
- 91, -26, 127, -4, //
- };
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 1, 4}));
-}
-
-TEST(DepthwiseConv2DTest, InvalidBiasType_NEG)
-{
- Shape input_shape{1, 4, 2, 2};
- Shape filter_shape{1, 2, 2, 4};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<int32_t> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::S32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthwiseConv2DTest, InOutTypeMismatch_NEG)
-{
- Shape input_shape{1, 4, 2, 2};
- Shape filter_shape{1, 2, 2, 4};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthwiseConv2DTest, InvalidInputShape_NEG)
-{
- Shape input_shape{4, 2, 2};
- Shape filter_shape{2, 2, 4};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthwiseConv2DTest, InvalidFilterShape_NEG)
-{
- Shape input_shape{1, 4, 2, 2};
- Shape filter_shape{2, 1, 2, 4};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DepthwiseConv2DTest, InvalidBiasDim_NEG)
-{
- Shape input_shape{1, 4, 2, 2};
- Shape filter_shape{1, 2, 4, 2};
- Shape bias_shape{4};
- std::vector<float> input_data{
- 1, 2, 7, 8, //
- 3, 4, 9, 10, //
- 5, 6, 11, 12, //
- 13, 14, 15, 16, //
- };
- std::vector<float> filter_data{
- 1, 2, 3, 4, //
- -9, 10, -11, 12, //
- 5, 6, 7, 8, //
- 13, -14, 15, -16, //
- };
- std::vector<float> bias_data{1, 2, 3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::FLOAT32>(filter_shape, filter_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DepthwiseConv2DParams params{};
- params.padding = Padding::VALID;
- params.depth_multiplier = 2;
- params.stride_height = 2;
- params.stride_width = 1;
- params.dilation_height_factor = 1;
- params.dilation_width_factor = 1;
- params.activation = Activation::RELU;
-
- DepthwiseConv2D kernel(&input_tensor, &filter_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Div.cpp b/compiler/luci-interpreter/src/kernels/Div.cpp
deleted file mode 100644
index e75876b3a..000000000
--- a/compiler/luci-interpreter/src/kernels/Div.cpp
+++ /dev/null
@@ -1,128 +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 "kernels/Div.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Div::Div(const Tensor *input1, const Tensor *input2, Tensor *output, const DivParams &params)
- : KernelWithParams<DivParams>({input1, input2}, {output}, params)
-{
-}
-
-void Div::configure()
-{
- LUCI_INTERPRETER_CHECK(input1()->element_type() == input2()->element_type());
- LUCI_INTERPRETER_CHECK(input1()->element_type() == output()->element_type());
-
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Div::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Div::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastDivSlow(
- params, getTensorShape(input1()), getTensorData<float>(input1()), getTensorShape(input2()),
- getTensorData<float>(input2()), getTensorShape(output()), getTensorData<float>(output()));
- }
- else
- {
- tflite::reference_ops::Div(params, getTensorShape(input1()), getTensorData<float>(input1()),
- getTensorShape(input2()), getTensorData<float>(input2()),
- getTensorShape(output()), getTensorData<float>(output()));
- }
-}
-
-void Div::evalQuantized() const
-{
- const auto input1_scale = static_cast<double>(input1()->scale());
- const auto input2_scale = static_cast<double>(input2()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- const double real_output_multiplier = input1_scale / (input2_scale * output_scale);
-
- int32_t output_multiplier{};
- int output_shift{};
-
- quantizeMultiplier(real_output_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
-
- params.input1_offset = -input1()->zero_point(); // Note the '-'.
- params.input2_offset = -input2()->zero_point(); // Note the '-'.
- params.output_offset = output()->zero_point();
- params.output_multiplier = output_multiplier;
- params.output_shift = output_shift;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastDivSlow(
- params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- }
- else
- {
- tflite::reference_ops::Div(params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Div.h b/compiler/luci-interpreter/src/kernels/Div.h
deleted file mode 100644
index 6040cdd02..000000000
--- a/compiler/luci-interpreter/src/kernels/Div.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_DIV_H
-#define LUCI_INTERPRETER_KERNELS_DIV_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Div : public KernelWithParams<DivParams>
-{
-public:
- Div(const Tensor *input1, const Tensor *input2, Tensor *output, const DivParams &params);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_DIV_H
diff --git a/compiler/luci-interpreter/src/kernels/Div.test.cpp b/compiler/luci-interpreter/src/kernels/Div.test.cpp
deleted file mode 100644
index 77eb2e9c1..000000000
--- a/compiler/luci-interpreter/src/kernels/Div.test.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Div.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-float GetTolerance(float min, float max)
-{
- const float kQuantizedStep = (max - min) / 255.0f;
- const float kQuantizedTolerance = 2.0f * kQuantizedStep + kQuantizedStep * kQuantizedStep;
- return kQuantizedTolerance;
-}
-
-TEST(DivTest, Float)
-{
- Shape base_shape = {2, 3, 1, 1};
-
- std::vector<int32_t> output_shape = {2, 3, 1, 1};
-
- std::vector<float> input1_data{0.3f, 2.3f, 0.9f, 0.5f, 0.8f, 1.1f};
- std::vector<float> input2_data{0.2f, 1.6f, 0.5f, 0.4f, 1.6f, 0.4f};
- std::vector<float> test_outputs{1.5f, 1.4375f, 1.8f, 1.25f, 0.5f, 2.75f};
-
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input2_data);
-
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DivParams params{};
- params.activation = Activation::RELU;
-
- Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(DivTest, FloatBroadcast)
-{
- Shape input1_shape = {1, 3};
- Shape input2_shape = {3, 1};
-
- std::vector<float> input1_data{-0.3f, 2.3f, 0.9f};
- std::vector<float> input2_data{0.2f, 1.6f, 0.5f};
- std::vector<float> test_outputs{0.f, 11.5f, 4.5f, 0.f, 1.4375f, 0.5625f, 0.f, 4.6f, 1.8f};
-
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(input1_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(input2_shape, input2_data);
-
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DivParams params{};
- params.activation = Activation::RELU;
-
- Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
-}
-
-TEST(DivTest, Uint8)
-{
- Shape base_shape = {1, 2, 2, 1};
-
- std::vector<int32_t> output_shape = {1, 2, 2, 1};
-
- std::vector<float> input1_data = {-0.8f, -0.2f, 0.3f, 0.7f};
- std::vector<float> input2_data = {-0.8f, 0.4f, 0.8f, 1.0f};
- std::vector<float> test_outputs{1.0f, 0.f, 0.375f, 0.7f};
-
- const float kQuantizedTolerance = GetTolerance(-1.0, 1.0);
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.f, 1.f);
-
- Tensor input1_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, input1_data);
- Tensor input2_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, input2_data);
-
- Tensor output_tensor =
- makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
-
- DivParams params{};
- params.activation = Activation::RELU;
-
- Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(test_outputs, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(DivTest, Input_Output_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor input2_tensor = makeInputTensor<DataType::S32>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- DivParams params{};
- params.activation = Activation::RELU;
-
- Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(DivTest, Invalid_Input_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor input2_tensor = makeInputTensor<DataType::S64>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- DivParams params{};
- params.activation = Activation::RELU;
-
- Div kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Elu.cpp b/compiler/luci-interpreter/src/kernels/Elu.cpp
deleted file mode 100644
index 456396055..000000000
--- a/compiler/luci-interpreter/src/kernels/Elu.cpp
+++ /dev/null
@@ -1,52 +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 "kernels/Elu.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Elu::Elu(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Elu::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- output()->resize(input()->shape());
-}
-
-void Elu::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::optimized_ops::Elu(getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Elu.h b/compiler/luci-interpreter/src/kernels/Elu.h
deleted file mode 100644
index c844ab57f..000000000
--- a/compiler/luci-interpreter/src/kernels/Elu.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_ELU_H
-#define LUCI_INTERPRETER_KERNELS_ELU_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Elu : public Kernel
-{
-public:
- Elu(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_ELU_H
diff --git a/compiler/luci-interpreter/src/kernels/Elu.test.cpp b/compiler/luci-interpreter/src/kernels/Elu.test.cpp
deleted file mode 100644
index 0235d6552..000000000
--- a/compiler/luci-interpreter/src/kernels/Elu.test.cpp
+++ /dev/null
@@ -1,75 +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 "kernels/Elu.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Elu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- (void)output_shape;
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
-}
-
-TEST(EluTest, SimpleElu)
-{
- Check(
- /*input_shape=*/{1, 2, 4, 1}, /*output_shape=*/{1, 2, 4, 1},
- /*input_data=*/
- {
- 0, -6, 2, -4, //
- 3, -2, 10, -0.1, //
- },
- /*output_data=*/
- {
- 0.0, -0.997521, 2.0, -0.981684, //
- 3.0, -0.864665, 10.0, -0.0951626, //
- });
-}
-
-TEST(EluTest, InOutTypeMismatch_NEG)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, -6, 2, -4, //
- 3, -2, 10, -0.1, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Elu kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Equal.cpp b/compiler/luci-interpreter/src/kernels/Equal.cpp
deleted file mode 100644
index f58de1250..000000000
--- a/compiler/luci-interpreter/src/kernels/Equal.cpp
+++ /dev/null
@@ -1,113 +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 "kernels/Equal.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Equal::Equal(const Tensor *x, const Tensor *y, Tensor *output) : Kernel({x, y}, {output}) {}
-
-void Equal::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void Equal::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Equal::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowEqual(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::Equal(op_params, getTensorShape(x()), x_data, getTensorShape(y()),
- y_data, getTensorShape(output()), output_data);
- }
-}
-
-void Equal::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowEqualWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::EqualWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data, getTensorShape(output()),
- output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Equal.h b/compiler/luci-interpreter/src/kernels/Equal.h
deleted file mode 100644
index 69b3be774..000000000
--- a/compiler/luci-interpreter/src/kernels/Equal.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_EQUAL_H
-#define LUCI_INTERPRETER_KERNELS_EQUAL_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Equal : public Kernel
-{
-public:
- Equal(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_EQUAL_H
diff --git a/compiler/luci-interpreter/src/kernels/Equal.test.cpp b/compiler/luci-interpreter/src/kernels/Equal.test.cpp
deleted file mode 100644
index fb0de8bbf..000000000
--- a/compiler/luci-interpreter/src/kernels/Equal.test.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Equal.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(EqualTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, true, false, // Row 1
- false, true, false, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(EqualTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- 0.9, 0.7, 0.5, // Row 4
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, true, false, // Row 1
- false, false, false, // Row 2
- false, false, false, // Row 3
- true, true, true, // Row 4
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({4, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({4, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(EqualTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.5, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.5, 0.55, 0.5, // Row 1
- -1, 0, 0.05, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, true, false, false, // Row 1
- false, true, true, false, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
-
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 2, F_MAX * 2);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
-
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(EqualTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- -1, 0.05, 0, 1, // Row 4
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, false, false, false, // Row 1
- false, false, true, false, // Row 2
- false, false, false, false, // Row 3
- true, true, true, true, // Row 4
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 4, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 4, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(EqualTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(EqualTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Equal kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Floor.cpp b/compiler/luci-interpreter/src/kernels/Floor.cpp
deleted file mode 100644
index e3c4246cc..000000000
--- a/compiler/luci-interpreter/src/kernels/Floor.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Floor.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/floor.h>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Floor::Floor(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Floor::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- output()->resize(input()->shape());
-}
-
-void Floor::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
-
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Floor::evalFloat() const
-{
- tflite::reference_ops::Floor(getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Floor.h b/compiler/luci-interpreter/src/kernels/Floor.h
deleted file mode 100644
index ca3ad5997..000000000
--- a/compiler/luci-interpreter/src/kernels/Floor.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_FLOOR_H
-#define LUCI_INTERPRETER_KERNELS_FLOOR_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Floor : public Kernel
-{
-public:
- Floor(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_FLOOR_H
diff --git a/compiler/luci-interpreter/src/kernels/Floor.test.cpp b/compiler/luci-interpreter/src/kernels/Floor.test.cpp
deleted file mode 100644
index 3e1ab6f3a..000000000
--- a/compiler/luci-interpreter/src/kernels/Floor.test.cpp
+++ /dev/null
@@ -1,65 +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 "kernels/Floor.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(FloorTest, SimpleFloat)
-{
- std::initializer_list<int32_t> input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0.2, 8.6, 2.4, 4.3, // Row 1
- 3, 7.1, 10.5, -0.9, // Row 2
- };
-
- std::initializer_list<int32_t> ref_output_shape{1, 2, 4, 1};
- std::vector<float> ref_output_data{
- 0, 8, 2, 4, // Row 1
- 3, 7, 10, -1, // Row 2
- };
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Floor kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(FloorTest, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::S32);
-
- Floor kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/FloorDiv.cpp b/compiler/luci-interpreter/src/kernels/FloorDiv.cpp
deleted file mode 100644
index b6f36cea3..000000000
--- a/compiler/luci-interpreter/src/kernels/FloorDiv.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/FloorDiv.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/binary_function.h>
-#include <cmath>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-FloorDiv::FloorDiv(const Tensor *input, const Tensor *alpha, Tensor *output)
- : Kernel({input, alpha}, {output})
-{
-}
-
-void FloorDiv::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == output()->element_type());
- LUCI_INTERPRETER_CHECK(y()->element_type() == output()->element_type());
-
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void FloorDiv::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void FloorDiv::evalFloat() const
-{
- auto FloorDivFunc = [](float x, float y) -> float {
- return std::floor(static_cast<double>(x) / static_cast<double>(y));
- };
-
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
-
- // Check the denominator
- for (int i = 0; i < getTensorShape(y()).FlatSize(); ++i)
- {
- LUCI_INTERPRETER_CHECK(y_data[i] != 0);
- }
-
- if (x()->shape() != y()->shape())
- {
- tflite::reference_ops::BroadcastBinaryFunction4DSlow<float, float, float>(
- getTensorShape(x()), x_data, getTensorShape(y()), y_data, getTensorShape(output()),
- getTensorData<float>(output()), FloorDivFunc);
- }
- else
- {
- tflite::reference_ops::BinaryFunction<float, float, float>(
- getTensorShape(x()), x_data, getTensorShape(y()), y_data, getTensorShape(output()),
- getTensorData<float>(output()), FloorDivFunc);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/FloorDiv.h b/compiler/luci-interpreter/src/kernels/FloorDiv.h
deleted file mode 100644
index e9c47d81a..000000000
--- a/compiler/luci-interpreter/src/kernels/FloorDiv.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_FLOOR_DIV_H
-#define LUCI_INTERPRETER_KERNELS_FLOOR_DIV_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class FloorDiv : public Kernel
-{
-public:
- FloorDiv(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_FLOOR_DIV_H
diff --git a/compiler/luci-interpreter/src/kernels/FloorDiv.test.cpp b/compiler/luci-interpreter/src/kernels/FloorDiv.test.cpp
deleted file mode 100644
index a5bc700f7..000000000
--- a/compiler/luci-interpreter/src/kernels/FloorDiv.test.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/FloorDiv.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(FloorDivTest, FloatSimple)
-{
- Shape x_shape{2, 3};
- std::vector<float> x_data{
- 0.5, 2.4, 3.1, // Row 1
- 1.9, -1.9, -2.8, // Row 2
- };
-
- Shape y_shape = x_shape;
- std::vector<float> y_data{
- 2.0, 0.5, 3.0, // Row 1
- 1.0, -1.0, -2.0, // Row 2
- };
-
- std::vector<int32_t> ref_output_shape{2, 3};
- std::vector<float> ref_output_data{
- 0, 4, 1, // Row 1
- 1, 1, 1, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>(x_shape, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>(y_shape, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FloorDiv kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(FloorDivTest, FloatBroadcast)
-{
- Shape x_shape{1, 3};
- std::vector<float> x_data{
- 0.5, 2.4, -3.1, // Row 1
- };
-
- Shape y_shape{3, 3};
- std::vector<float> y_data{
- 1.0, 1.0, 1.0, // Row 1
- 2.0, -0.5, -2.0, // Row 2
- 0.3, 0.7, 0.9, // Row 3
- };
-
- std::vector<int32_t> ref_output_shape{3, 3};
- std::vector<float> ref_output_data{
- 0, 2, -4, // Row 1
- 0, -5, 1, // Row 2
- 1, 3, -4, // Row 3
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>(x_shape, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>(y_shape, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FloorDiv kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(FloorDivTest, DivByZero_NEG)
-{
- Shape shape{3};
- std::vector<float> x_data{1, 0, -1};
- std::vector<float> y_data{0, 0, 0};
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>(shape, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>(shape, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FloorDiv kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
-
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-TEST(FloorDivTest, Input_Output_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- FloorDiv kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(FloorDivTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FloorDiv kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/FullyConnected.cpp b/compiler/luci-interpreter/src/kernels/FullyConnected.cpp
deleted file mode 100644
index 7fa76d5e7..000000000
--- a/compiler/luci-interpreter/src/kernels/FullyConnected.cpp
+++ /dev/null
@@ -1,139 +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 "kernels/FullyConnected.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/fully_connected.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-FullyConnected::FullyConnected(const Tensor *input, const Tensor *weights, const Tensor *bias,
- Tensor *output, const FullyConnectedParams &params)
- : KernelWithParams<FullyConnectedParams>({input, weights, bias}, {output}, params)
-{
-}
-
-void FullyConnected::configure()
-{
- if (weights()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(input()->element_type() == DataType::U8);
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::U8);
- LUCI_INTERPRETER_CHECK(!bias() || bias()->element_type() == DataType::S32)
- }
- else if (weights()->element_type() == DataType::FLOAT32)
- {
- LUCI_INTERPRETER_CHECK(input()->element_type() == DataType::FLOAT32);
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::FLOAT32);
- LUCI_INTERPRETER_CHECK(!bias() || bias()->element_type() == DataType::FLOAT32)
- }
- else
- {
- throw std::runtime_error("Unsupported type.");
- }
-
- const Shape &input_shape = input()->shape();
- const Shape &weights_shape = weights()->shape();
-
- LUCI_INTERPRETER_CHECK(weights_shape.num_dims() == 2);
- LUCI_INTERPRETER_CHECK(bias() == nullptr ||
- bias()->shape().num_elements() == weights_shape.dim(0));
-
- LUCI_INTERPRETER_CHECK(input_shape.num_elements() % weights_shape.dim(1) == 0);
- const int32_t batch_size = input_shape.num_elements() / weights_shape.dim(1);
- const int32_t num_units = weights_shape.dim(0);
-
- if (bias())
- LUCI_INTERPRETER_CHECK(bias()->shape().num_elements() == weights()->shape().dim(0));
-
- output()->resize({batch_size, num_units});
-}
-
-void FullyConnected::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::FLOAT32:
- evalFloat();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void FullyConnected::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::FullyConnectedParams params{};
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
- params.weights_format = tflite::FullyConnectedWeightsFormat::kDefault;
-
- tflite::reference_ops::FullyConnected(
- params, getTensorShape(input()), getTensorData<float>(input()), getTensorShape(weights()),
- getTensorData<float>(weights()), getTensorShape(bias()), getTensorData<float>(bias()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void FullyConnected::evalQuantized() const
-{
- double real_multiplier = 0.0;
- int output_shift;
- int32_t output_activation_min;
- int32_t output_activation_max;
- int32_t output_multiplier;
- real_multiplier =
- getQuantizedConvolutionMultipler(input()->scale(), weights()->scale(), output()->scale());
- quantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
- calculateActivationRangeQuantized(params().activation, output(), &output_activation_min,
- &output_activation_max);
-
- int32_t input_offset = -input()->zero_point();
- int32_t filter_offset = -weights()->zero_point();
- int32_t output_offset = output()->zero_point();
-
- tflite::FullyConnectedParams op_params{};
- op_params.input_offset = input_offset;
- op_params.weights_offset = filter_offset;
- op_params.output_offset = output_offset;
- op_params.output_multiplier = output_multiplier;
- op_params.output_shift = output_shift;
- op_params.quantized_activation_min = output_activation_min;
- op_params.quantized_activation_max = output_activation_max;
- op_params.lhs_cacheable = false;
- op_params.rhs_cacheable = false;
- tflite::reference_ops::FullyConnected(
- op_params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(weights()), getTensorData<uint8_t>(weights()), getTensorShape(bias()),
- getTensorData<int32_t>(bias()), getTensorShape(output()), getTensorData<uint8_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/FullyConnected.h b/compiler/luci-interpreter/src/kernels/FullyConnected.h
deleted file mode 100644
index 204f11ebb..000000000
--- a/compiler/luci-interpreter/src/kernels/FullyConnected.h
+++ /dev/null
@@ -1,50 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_FULLYCONNECTED_H
-#define LUCI_INTERPRETER_KERNELS_FULLYCONNECTED_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class FullyConnected : public KernelWithParams<FullyConnectedParams>
-{
-public:
- FullyConnected(const Tensor *input, const Tensor *weights, const Tensor *bias, Tensor *output,
- const FullyConnectedParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *weights() const { return _inputs[1]; }
- const Tensor *bias() const { return _inputs[2]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_FULLYCONNECTED_H
diff --git a/compiler/luci-interpreter/src/kernels/FullyConnected.test.cpp b/compiler/luci-interpreter/src/kernels/FullyConnected.test.cpp
deleted file mode 100644
index d194ce1a0..000000000
--- a/compiler/luci-interpreter/src/kernels/FullyConnected.test.cpp
+++ /dev/null
@@ -1,196 +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 "kernels/FullyConnected.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> weights_shape,
- std::initializer_list<int32_t> bias_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> weights_data,
- std::initializer_list<float> bias_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor weights_tensor = makeInputTensor<DataType::FLOAT32>(weights_shape, weights_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FullyConnectedParams params{};
- params.activation = Activation::RELU;
-
- FullyConnected kernel(&input_tensor, &weights_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(extractTensorData<T>(output_tensor), FloatArrayNear(output_data));
-}
-
-template <>
-void Check<uint8_t>(
- std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> weights_shape,
- std::initializer_list<int32_t> bias_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> weights_data,
- std::initializer_list<float> bias_data, std::initializer_list<float> output_data)
-{
- const float quantized_tolerance = getTolerance(-127, 128, 255);
- std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(-63.5, 64);
- std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(-127, 128);
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor weights_tensor = makeInputTensor<DataType::U8>(weights_shape, input_quant_param.first,
- input_quant_param.second, weights_data);
- Tensor bias_tensor = makeInputTensor<DataType::S32>(
- bias_shape, input_quant_param.first * input_quant_param.first, 0, bias_data);
- Tensor output_tensor =
- makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
-
- FullyConnectedParams params{};
- params.activation = Activation::RELU;
-
- FullyConnected kernel(&input_tensor, &weights_tensor, &bias_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, quantized_tolerance));
-}
-
-template <typename T> class FullyConnectedTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(FullyConnectedTest, DataTypes);
-
-TYPED_TEST(FullyConnectedTest, Simple)
-{
- Check<TypeParam>({3, 2, 2, 1}, {3, 6}, {3}, {2, 3},
- {
- -3, -5, 5, 4, 9, -2, // batch = 0
- -3, -2, -4, 9, -8, 1, // batch = 1
- },
- {
- -3, -7, 4, -4, -6, 4, // unit = 0
- 3, 5, 2, 3, -3, -8, // unit = 1
- -3, 7, 4, 9, 0, -5, // unit = 2
- },
- {-1, -5, -8}, {
- 0, 0, 32, // batch = 0
- 22, 11, 47, // batch = 1
- });
-}
-
-TEST(FullyConnectedTest, InvalidBiasType_NEG)
-{
- Shape input_shape{3, 2, 2, 1};
- std::vector<float> input_data{
- -3, -5, 5, 4, 9, -2, // batch = 0
- -3, -2, -4, 9, -8, 1, // batch = 1
- };
- Shape weights_shape{3, 6};
- std::vector<float> weights_data{
- -3, -7, 4, -4, -6, 4, // unit = 0
- 3, 5, 2, 3, -3, -8, // unit = 1
- -3, 7, 4, 9, 0, -5, // unit = 2
- };
- Shape bias_shape{3};
- std::vector<int32_t> bias_data{-1, -5, -8};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor weights_tensor = makeInputTensor<DataType::FLOAT32>(weights_shape, weights_data);
- Tensor bias_tensor = makeInputTensor<DataType::S32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FullyConnectedParams params{};
- params.activation = Activation::RELU;
-
- FullyConnected kernel(&input_tensor, &weights_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(FullyConnectedTest, InvalidWeightShapeDim_NEG)
-{
- Shape input_shape{3, 2, 2, 1};
- std::vector<float> input_data{
- -3, -5, 5, 4, 9, -2, // batch = 0
- -3, -2, -4, 9, -8, 1, // batch = 1
- };
- Shape weights_shape{1, 3, 6};
- std::vector<float> weights_data{
- -3, -7, 4, -4, -6, 4, // unit = 0
- 3, 5, 2, 3, -3, -8, // unit = 1
- -3, 7, 4, 9, 0, -5, // unit = 2
- };
- Shape bias_shape{3};
- std::vector<float> bias_data{-1, -5, -8};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor weights_tensor = makeInputTensor<DataType::FLOAT32>(weights_shape, weights_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FullyConnectedParams params{};
- params.activation = Activation::RELU;
-
- FullyConnected kernel(&input_tensor, &weights_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(FullyConnectedTest, BiasElementNumWeightDimMismatch_NEG)
-{
- Shape input_shape{3, 2, 2, 1};
- std::vector<float> input_data{
- -3, -5, 5, 4, 9, -2, // batch = 0
- -3, -2, -4, 9, -8, 1, // batch = 1
- };
- Shape weights_shape{6, 3};
- std::vector<float> weights_data{
- -3, -7, 4, // unit = 0
- -4, -6, 4, // unit = 1
- 3, 5, 2, // unit = 2
- 3, -3, -8, // unit = 3
- -3, 7, 4, // unit = 4
- 9, 0, -5, // unit = 5
- };
- Shape bias_shape{3};
- std::vector<float> bias_data{-1, -5, -8};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor weights_tensor = makeInputTensor<DataType::FLOAT32>(weights_shape, weights_data);
- Tensor bias_tensor = makeInputTensor<DataType::FLOAT32>(bias_shape, bias_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- FullyConnectedParams params{};
- params.activation = Activation::RELU;
-
- FullyConnected kernel(&input_tensor, &weights_tensor, &bias_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Greater.cpp b/compiler/luci-interpreter/src/kernels/Greater.cpp
deleted file mode 100644
index f0dd2db36..000000000
--- a/compiler/luci-interpreter/src/kernels/Greater.cpp
+++ /dev/null
@@ -1,113 +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 "kernels/Greater.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Greater::Greater(const Tensor *x, const Tensor *y, Tensor *output) : Kernel({x, y}, {output}) {}
-
-void Greater::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void Greater::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Greater::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowGreater(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::Greater(op_params, getTensorShape(x()), x_data, getTensorShape(y()),
- y_data, getTensorShape(output()), output_data);
- }
-}
-
-void Greater::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowGreaterWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::GreaterWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data, getTensorShape(output()),
- output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Greater.h b/compiler/luci-interpreter/src/kernels/Greater.h
deleted file mode 100644
index a65d29f5c..000000000
--- a/compiler/luci-interpreter/src/kernels/Greater.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_GREATER_H
-#define LUCI_INTERPRETER_KERNELS_GREATER_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Greater : public Kernel
-{
-public:
- Greater(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_GREATER_H
diff --git a/compiler/luci-interpreter/src/kernels/Greater.test.cpp b/compiler/luci-interpreter/src/kernels/Greater.test.cpp
deleted file mode 100644
index 3122fa840..000000000
--- a/compiler/luci-interpreter/src/kernels/Greater.test.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Greater.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(GreaterTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, false, true, // Row 1
- true, false, false, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(GreaterTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, false, true, // Row 1
- true, false, false, // Row 2
- false, false, true, // Row 3
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(GreaterTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.6, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, false, true, true, // Row 1
- true, false, true, false, // Row 2
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterTest, Uint8QuantizedRescale)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.6, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, false, true, true, // Row 1
- true, false, true, false, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 2, F_MAX * 3);
-
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, false, true, false, // Row 1
- true, true, false, false, // Row 2
- true, false, true, false, // Row 3
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 3, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 3, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(GreaterTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Greater kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/GreaterEqual.cpp b/compiler/luci-interpreter/src/kernels/GreaterEqual.cpp
deleted file mode 100644
index 68135e27c..000000000
--- a/compiler/luci-interpreter/src/kernels/GreaterEqual.cpp
+++ /dev/null
@@ -1,116 +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 "kernels/GreaterEqual.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-GreaterEqual::GreaterEqual(const Tensor *x, const Tensor *y, Tensor *output)
- : Kernel({x, y}, {output})
-{
-}
-
-void GreaterEqual::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void GreaterEqual::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void GreaterEqual::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowGreaterEqual(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::GreaterEqual(op_params, getTensorShape(x()), x_data, getTensorShape(y()),
- y_data, getTensorShape(output()), output_data);
- }
-}
-
-void GreaterEqual::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowGreaterEqualWithScaling(
- op_params, getTensorShape(x()), x_data, getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::GreaterEqualWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/GreaterEqual.h b/compiler/luci-interpreter/src/kernels/GreaterEqual.h
deleted file mode 100644
index e948d698f..000000000
--- a/compiler/luci-interpreter/src/kernels/GreaterEqual.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_GREATER_EQUAL_H
-#define LUCI_INTERPRETER_KERNELS_GREATER_EQUAL_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class GreaterEqual : public Kernel
-{
-public:
- GreaterEqual(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_GREATER_EQUAL_H
diff --git a/compiler/luci-interpreter/src/kernels/GreaterEqual.test.cpp b/compiler/luci-interpreter/src/kernels/GreaterEqual.test.cpp
deleted file mode 100644
index 11e62644c..000000000
--- a/compiler/luci-interpreter/src/kernels/GreaterEqual.test.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/GreaterEqual.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(GreaterEqualTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, true, true, // Row 1
- true, true, false, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(GreaterEqualTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, true, true, // Row 1
- true, false, false, // Row 2
- false, false, true, // Row 3
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(GreaterEqualTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.55, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, true, true, true, // Row 1
- true, false, true, false, // Row 2
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterEqualTest, Uint8QuantizedRescale)
-{
- std::vector<float> x_data{
- 0.5, 0.5, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.5, 0.6, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- false, true, true, true, // Row 1
- true, false, true, false, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 1.2, F_MAX * 1.5);
-
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterEqualTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, false, true, false, // Row 1
- true, true, true, false, // Row 2
- true, false, true, false, // Row 3
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 3, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 3, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(GreaterEqualTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(GreaterEqualTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- GreaterEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/If.cpp b/compiler/luci-interpreter/src/kernels/If.cpp
deleted file mode 100644
index ca982d591..000000000
--- a/compiler/luci-interpreter/src/kernels/If.cpp
+++ /dev/null
@@ -1,90 +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 "kernels/If.h"
-#include "kernels/Utils.h"
-
-#include <cstring>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-static std::vector<const Tensor *> joinInputs(const Tensor *cond,
- const std::vector<const Tensor *> &inputs)
-{
- std::vector<const Tensor *> result{cond};
- result.insert(result.cend(), inputs.cbegin(), inputs.cend());
- return result;
-}
-
-If::If(const Tensor *cond, const std::vector<const Tensor *> &inputs, std::vector<Tensor *> outputs,
- RuntimeGraph *then_graph, RuntimeGraph *else_graph)
- : Kernel(joinInputs(cond, inputs), std::move(outputs)), _then_graph(then_graph),
- _else_graph(else_graph)
-{
-}
-
-void If::configure()
-{
- LUCI_INTERPRETER_CHECK(cond()->element_type() == DataType::BOOL);
- LUCI_INTERPRETER_CHECK(cond()->shape().num_elements() == 1);
-
- for (RuntimeGraph *graph : {_then_graph, _else_graph})
- {
- (void)graph;
- LUCI_INTERPRETER_CHECK(graph->getInputTensors().size() == getInputTensors().size() - 1);
- LUCI_INTERPRETER_CHECK(graph->getOutputTensors().size() == getOutputTensors().size());
- }
-}
-
-void If::execute() const
-{
- const bool cond_value = cond()->data<bool>()[0];
-
- RuntimeGraph *active_graph = cond_value ? _then_graph : _else_graph;
- const auto &graph_inputs = active_graph->getInputTensors();
- const auto &graph_outputs = active_graph->getOutputTensors();
-
- // Copy kernel inputs to active graph inputs.
- for (size_t i = 0; i < getInputTensors().size() - 1; ++i)
- {
- LUCI_INTERPRETER_CHECK(graph_inputs[i]->element_type() == input(i)->element_type());
- graph_inputs[i]->resize(input(i)->shape());
-
- const int32_t num_elements = input(i)->shape().num_elements();
- const std::size_t element_size = getDataTypeSize(input(i)->element_type());
- std::memcpy(graph_inputs[i]->data<void>(), input(i)->data<void>(), num_elements * element_size);
- }
-
- active_graph->execute();
-
- // Copy graph outputs to kernel outputs.
- for (size_t i = 0; i < getOutputTensors().size(); ++i)
- {
- LUCI_INTERPRETER_CHECK(graph_outputs[i]->element_type() == output(i)->element_type());
- output(i)->resize(graph_outputs[i]->shape());
-
- const int32_t num_elements = output(i)->shape().num_elements();
- const std::size_t element_size = getDataTypeSize(output(i)->element_type());
- std::memcpy(output(i)->data<void>(), graph_outputs[i]->data<void>(),
- num_elements * element_size);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/If.h b/compiler/luci-interpreter/src/kernels/If.h
deleted file mode 100644
index fa6ab371a..000000000
--- a/compiler/luci-interpreter/src/kernels/If.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_IF_H
-#define LUCI_INTERPRETER_KERNELS_IF_H
-
-#include "core/Kernel.h"
-#include "core/RuntimeGraph.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class If : public Kernel
-{
-public:
- If(const Tensor *cond, const std::vector<const Tensor *> &inputs, std::vector<Tensor *> outputs,
- RuntimeGraph *then_graph, RuntimeGraph *else_graph);
-
- const Tensor *cond() const { return _inputs[0]; }
- const Tensor *input(int index) const { return _inputs[1 + index]; }
- Tensor *output(int index) const { return _outputs[index]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- RuntimeGraph *const _then_graph;
- RuntimeGraph *const _else_graph;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_IF_H
diff --git a/compiler/luci-interpreter/src/kernels/If.test.cpp b/compiler/luci-interpreter/src/kernels/If.test.cpp
deleted file mode 100644
index 6967407fb..000000000
--- a/compiler/luci-interpreter/src/kernels/If.test.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "core/RuntimeModule.h"
-#include "kernels/Add.h"
-#include "kernels/If.h"
-#include "kernels/Mul.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-RuntimeGraph *buildAddSubgraph(RuntimeModule *module)
-{
- RuntimeGraph *graph = module->addGraph();
- Tensor *input1 = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
- Tensor *input2 = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
- Tensor *output = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
-
- graph->setInputTensors({input1, input2});
- graph->setOutputTensors({output});
-
- AddParams params{};
- params.activation = Activation::NONE;
- graph->addKernel(std::make_unique<Add>(input1, input2, output, params));
-
- return graph;
-}
-
-RuntimeGraph *buildMulSubgraph(RuntimeModule *module)
-{
- RuntimeGraph *graph = module->addGraph();
- Tensor *input1 = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
- Tensor *input2 = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
- Tensor *output = graph->addTensor(
- std::make_unique<Tensor>(DataType::FLOAT32, Shape{}, AffineQuantization{}, ""));
-
- graph->setInputTensors({input1, input2});
- graph->setOutputTensors({output});
-
- MulParams params{};
- params.activation = Activation::NONE;
- graph->addKernel(std::make_unique<Mul>(input1, input2, output, params));
-
- return graph;
-}
-
-TEST(IfTest, CondTrue)
-{
- Tensor cond = makeInputTensor<DataType::BOOL>({1}, {true});
- Tensor input1 = makeInputTensor<DataType::FLOAT32>({2}, {5, 7});
- Tensor input2 = makeInputTensor<DataType::FLOAT32>({1, 2}, {1, 2});
- Tensor output = makeOutputTensor(DataType::FLOAT32);
-
- RuntimeModule module(nullptr);
- RuntimeGraph *then_graph = buildAddSubgraph(&module);
- RuntimeGraph *else_graph = buildMulSubgraph(&module);
-
- If kernel(&cond, {&input1, &input2}, {&output}, then_graph, else_graph);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output), FloatArrayNear({6, 9}));
-}
-
-TEST(IfTest, CondFalse)
-{
- Tensor cond = makeInputTensor<DataType::BOOL>({1}, {false});
- Tensor input1 = makeInputTensor<DataType::FLOAT32>({2}, {5, 7});
- Tensor input2 = makeInputTensor<DataType::FLOAT32>({1, 2}, {1, 2});
- Tensor output = makeOutputTensor(DataType::FLOAT32);
-
- RuntimeModule module(nullptr);
- RuntimeGraph *then_graph = buildAddSubgraph(&module);
- RuntimeGraph *else_graph = buildMulSubgraph(&module);
-
- If kernel(&cond, {&input1, &input2}, {&output}, then_graph, else_graph);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output), FloatArrayNear({5, 14}));
-}
-
-TEST(IfTest, InvalidCondType_NEG)
-{
- Tensor cond = makeInputTensor<DataType::FLOAT32>({1}, {1});
- Tensor input1 = makeInputTensor<DataType::FLOAT32>({2}, {5, 7});
- Tensor input2 = makeInputTensor<DataType::FLOAT32>({1, 2}, {1, 2});
- Tensor output = makeOutputTensor(DataType::FLOAT32);
-
- RuntimeModule module(nullptr);
- RuntimeGraph *then_graph = buildAddSubgraph(&module);
- RuntimeGraph *else_graph = buildMulSubgraph(&module);
-
- If kernel(&cond, {&input1, &input2}, {&output}, then_graph, else_graph);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(IfTest, InvalidCondElementNum_NEG)
-{
- Tensor cond = makeInputTensor<DataType::BOOL>({2}, {false, true});
- Tensor input1 = makeInputTensor<DataType::FLOAT32>({2}, {5, 7});
- Tensor input2 = makeInputTensor<DataType::FLOAT32>({1, 2}, {1, 2});
- Tensor output = makeOutputTensor(DataType::FLOAT32);
-
- RuntimeModule module(nullptr);
- RuntimeGraph *then_graph = buildAddSubgraph(&module);
- RuntimeGraph *else_graph = buildMulSubgraph(&module);
-
- If kernel(&cond, {&input1, &input2}, {&output}, then_graph, else_graph);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/L2Normalize.cpp b/compiler/luci-interpreter/src/kernels/L2Normalize.cpp
deleted file mode 100644
index 0bf133d9c..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Normalize.cpp
+++ /dev/null
@@ -1,75 +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 "kernels/L2Normalize.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-L2Normalize::L2Normalize(const Tensor *input, Tensor *output, const L2NormParams &params)
- : KernelWithParams<L2NormParams>({input}, {output}, params)
-{
-}
-
-void L2Normalize::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() <= 4);
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::FLOAT32 ||
- output()->element_type() == DataType::U8);
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- if (output()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(output()->scale() == (1. / 128.));
- LUCI_INTERPRETER_CHECK(output()->zero_point() == 128);
- }
- LUCI_INTERPRETER_CHECK(params().activation == Activation::NONE);
- output()->resize(input()->shape());
-}
-
-void L2Normalize::execute() const
-{
- switch (output()->element_type())
- {
- case DataType::FLOAT32:
- eval<float>(0);
- break;
- case DataType::U8:
- eval<uint8_t>(input()->zero_point());
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-template <typename T> void L2Normalize::eval(int32_t zero_point) const
-{
- tflite::L2NormalizationParams op_params{};
- op_params.input_zero_point = zero_point;
- tflite::optimized_ops::L2Normalization(op_params, getTensorShape(input()),
- getTensorData<T>(input()), getTensorShape(output()),
- getTensorData<T>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/L2Normalize.h b/compiler/luci-interpreter/src/kernels/L2Normalize.h
deleted file mode 100644
index 6c7dac698..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Normalize.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_L2NORMALIZE_H
-#define LUCI_INTERPRETER_KERNELS_L2NORMALIZE_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class L2Normalize : public KernelWithParams<L2NormParams>
-{
-public:
- L2Normalize(const Tensor *input, Tensor *output, const L2NormParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> void eval(int32_t zero_point) const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_L2NORMALIZE_H
diff --git a/compiler/luci-interpreter/src/kernels/L2Normalize.test.cpp b/compiler/luci-interpreter/src/kernels/L2Normalize.test.cpp
deleted file mode 100644
index 8f9431182..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Normalize.test.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/L2Normalize.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- L2NormParams params{};
- params.activation = Activation::NONE;
-
- L2Normalize kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<float> output_data)
-{
- std::pair<float, int32_t> quant_param =
- quantizationParams<uint8_t>(std::min(input_data) < 0 ? std::min(input_data) : 0.f,
- std::max(input_data) > 0 ? std::max(input_data) : 0.f);
-
- Tensor input_tensor =
- makeInputTensor<DataType::U8>(input_shape, quant_param.first, quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1. / 128., 128);
-
- L2NormParams params{};
- params.activation = Activation::NONE;
-
- L2Normalize kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, output_tensor.scale()));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-template <typename T> class L2NormalizeTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(L2NormalizeTest, DataTypes);
-
-TYPED_TEST(L2NormalizeTest, Simple)
-{
- Check<TypeParam>({1, 1, 1, 6}, {1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1},
- {-0.55, 0.3, 0.35, 0.6, -0.35, 0.05});
-}
-
-TEST(L2NormalizeTest, ActivationType_NEG)
-{
- std::vector<float> input_data = {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1};
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- L2NormParams params{};
- params.activation = Activation::RELU6;
-
- L2Normalize kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(L2NormalizeTest, InvalidOutputQuantParam_NEG)
-{
- std::vector<float> input_data = {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1};
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 1, 1, 6}, 1. / 64., 127, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1. / 64., 127);
-
- L2NormParams params{};
- params.activation = Activation::NONE;
-
- L2Normalize kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/L2Pool2D.cpp b/compiler/luci-interpreter/src/kernels/L2Pool2D.cpp
deleted file mode 100644
index 979364a7f..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Pool2D.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/L2Pool2D.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-L2Pool2D::L2Pool2D(const Tensor *input, Tensor *output, const Pool2DParams &params)
- : KernelWithParams<Pool2DParams>({input}, {output}, params)
-{
-}
-
-void L2Pool2D::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4);
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
-
- int batches = input()->shape().dim(0);
- int height = input()->shape().dim(1);
- int width = input()->shape().dim(2);
- int channels_out = input()->shape().dim(3);
-
- // Matching GetWindowedOutputSize in TensorFlow.
- auto padding = params().padding;
- int out_width, out_height;
- out_width = computeOutputSize(padding, width, params().filter_width, params().stride_width, 1);
- out_height =
- computeOutputSize(padding, height, params().filter_height, params().stride_height, 1);
- _padding_width =
- computePadding(params().stride_width, 1, width, params().filter_width, out_width);
- _padding_height =
- computePadding(params().stride_height, 1, height, params().filter_height, out_height);
-
- LUCI_INTERPRETER_CHECK(input()->element_type() == DataType::FLOAT32);
- output()->resize({batches, out_height, out_width, channels_out});
-}
-
-void L2Pool2D::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- float activation_min, activation_max;
- calculateActivationRange(params().activation, &activation_min, &activation_max);
- tflite::PoolParams op_params;
- op_params.stride_height = params().stride_height;
- op_params.stride_width = params().stride_width;
- op_params.filter_height = params().filter_height;
- op_params.filter_width = params().filter_width;
- op_params.padding_values.height = _padding_height;
- op_params.padding_values.width = _padding_width;
- op_params.float_activation_min = activation_min;
- op_params.float_activation_max = activation_max;
- tflite::optimized_ops::L2Pool(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/L2Pool2D.h b/compiler/luci-interpreter/src/kernels/L2Pool2D.h
deleted file mode 100644
index d40f5f478..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Pool2D.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_L2POOL2D_H
-#define LUCI_INTERPRETER_KERNELS_L2POOL2D_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <memory>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class L2Pool2D : public KernelWithParams<Pool2DParams>
-{
-public:
- L2Pool2D(const Tensor *input, Tensor *output, const Pool2DParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- int32_t _padding_height = 0;
- int32_t _padding_width = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_L2POOL2D_H
diff --git a/compiler/luci-interpreter/src/kernels/L2Pool2D.test.cpp b/compiler/luci-interpreter/src/kernels/L2Pool2D.test.cpp
deleted file mode 100644
index 5f834e3c1..000000000
--- a/compiler/luci-interpreter/src/kernels/L2Pool2D.test.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/L2Pool2D.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(L2Pool2DTest, FloatNone)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{3.5, 6.5};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatRelu)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- -1, -6, 2, 4, //
- -3, -2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::RELU;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{3.53553, 6.5};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatRelu1)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- -0.1, -0.6, 2, 4, //
- -0.3, -0.2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::RELU_N1_TO_1;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0.353553, 1.0};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatRelu6)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- -0.1, -0.6, 2, 4, //
- -0.3, -0.2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::RELU6;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0.353553, 6.0};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatPaddingSame)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::SAME;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{3.5, 6.5};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatPaddingSameStride)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::SAME;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 1;
- params.stride_width = 1;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{3.5, 6.0, 6.5, 5.70088, 2.54951, 7.2111, 8.63134, 7.0};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, FloatPaddingValidStride)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 1;
- params.stride_width = 1;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{3.5, 6.0, 6.5};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- // TODO make a Shape checking of output_tensor.
-}
-
-TEST(L2Pool2DTest, InvalidInputShape_NEG)
-{
- Shape input_shape{1, 2, 4};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 1;
- params.stride_width = 1;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(L2Pool2DTest, InvalidInputOutputType_NEG)
-{
- Shape input_shape{1, 2, 4};
- std::vector<float> input_data{
- 0, 6, 2, 4, //
- 3, 2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.activation = Activation::NONE;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 1;
- params.stride_width = 1;
-
- L2Pool2D kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LeakyRelu.cpp b/compiler/luci-interpreter/src/kernels/LeakyRelu.cpp
deleted file mode 100644
index 919b12792..000000000
--- a/compiler/luci-interpreter/src/kernels/LeakyRelu.cpp
+++ /dev/null
@@ -1,90 +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 "kernels/LeakyRelu.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-LeakyRelu::LeakyRelu(const Tensor *input, Tensor *output, const LeakyReluParams &params)
- : KernelWithParams<LeakyReluParams>({input}, {output}, params)
-{
-}
-
-void LeakyRelu::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- if (input()->element_type() == DataType::U8)
- {
- double alpha_multiplier = input()->scale() * params().alpha / output()->scale();
- quantizeMultiplier(alpha_multiplier, &_output_multiplier_alpha, &_output_shift_alpha);
- double identity_multiplier = input()->scale() / output()->scale();
- quantizeMultiplier(identity_multiplier, &_output_multiplier_identity, &_output_shift_identity);
- }
- output()->resize(input()->shape());
-}
-
-void LeakyRelu::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void LeakyRelu::evalFloat() const
-{
- tflite::LeakyReluParams op_params{};
- op_params.alpha = params().alpha;
- tflite::optimized_ops::LeakyRelu(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
-}
-
-void LeakyRelu::evalQuantized() const
-{
- tflite::LeakyReluParams op_params{};
- op_params.input_offset = input()->zero_point();
- op_params.output_offset = output()->zero_point();
- op_params.output_multiplier_alpha = _output_multiplier_alpha;
- op_params.output_shift_alpha = _output_shift_alpha;
- op_params.output_multiplier_identity = _output_multiplier_identity;
- op_params.output_shift_identity = _output_shift_identity;
-
- tflite::reference_ops::QuantizeLeakyRelu(
- op_params, getTensorShape(input()), getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LeakyRelu.h b/compiler/luci-interpreter/src/kernels/LeakyRelu.h
deleted file mode 100644
index e66f404df..000000000
--- a/compiler/luci-interpreter/src/kernels/LeakyRelu.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LEAKYRELU_H
-#define LUCI_INTERPRETER_KERNELS_LEAKYRELU_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class LeakyRelu : public KernelWithParams<LeakyReluParams>
-{
-public:
- LeakyRelu(const Tensor *input, Tensor *output, const LeakyReluParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _output_multiplier_alpha = 0;
- int _output_shift_alpha = 0;
- int32_t _output_multiplier_identity = 0;
- int _output_shift_identity = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LEAKYRELU_H
diff --git a/compiler/luci-interpreter/src/kernels/LeakyRelu.test.cpp b/compiler/luci-interpreter/src/kernels/LeakyRelu.test.cpp
deleted file mode 100644
index 2778549ed..000000000
--- a/compiler/luci-interpreter/src/kernels/LeakyRelu.test.cpp
+++ /dev/null
@@ -1,118 +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 "kernels/LeakyRelu.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data,
- float alpha)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(element_type);
-
- LeakyReluParams params{};
- params.alpha = alpha;
-
- LeakyRelu kernel(&input_tensor, &output_tensor, params);
-
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(extractTensorData<T>(output_tensor), ::testing::ElementsAreArray(output_data));
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<float> output_data, float alpha)
-{
- const float quantized_tolerance = getTolerance(-8, 127.f / 16.f, 255);
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-8, 127.f / 16.f);
- Tensor input_tensor =
- makeInputTensor<DataType::U8>(input_shape, quant_param.first, quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- LeakyReluParams params{};
- params.alpha = alpha;
-
- LeakyRelu kernel(&input_tensor, &output_tensor, params);
-
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, quantized_tolerance));
-}
-
-template <typename T> class LeakReluTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(LeakReluTest, DataTypes);
-
-TYPED_TEST(LeakReluTest, Simple)
-{
- Check<TypeParam>(/*input_shape=*/{2, 3}, /*output_shape=*/{2, 3},
- /*input_data=*/
- {
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -1.0f, -2.0f, // Row 2
- },
- /*output_data=*/
- {
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -0.5f, -1.0f, // Row 2
- },
- /*alpha=*/0.5f);
-
- SUCCEED();
-}
-
-TEST(LeakReluTest, IvalidInputOutputType_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, {
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -1.0f, -2.0f, // Row 2
- });
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- LeakyReluParams params{};
- params.alpha = 0.5f;
-
- LeakyRelu kernel(&input_tensor, &output_tensor, params);
-
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Less.cpp b/compiler/luci-interpreter/src/kernels/Less.cpp
deleted file mode 100644
index 041444926..000000000
--- a/compiler/luci-interpreter/src/kernels/Less.cpp
+++ /dev/null
@@ -1,113 +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 "kernels/Less.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Less::Less(const Tensor *x, const Tensor *y, Tensor *output) : Kernel({x, y}, {output}) {}
-
-void Less::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void Less::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Less::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowLess(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::Less(op_params, getTensorShape(x()), x_data, getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
-}
-
-void Less::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowLessWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::LessWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data, getTensorShape(output()),
- output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Less.h b/compiler/luci-interpreter/src/kernels/Less.h
deleted file mode 100644
index fe03e10b1..000000000
--- a/compiler/luci-interpreter/src/kernels/Less.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LESS_H
-#define LUCI_INTERPRETER_KERNELS_LESS_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Less : public Kernel
-{
-public:
- Less(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LESS_H
diff --git a/compiler/luci-interpreter/src/kernels/Less.test.cpp b/compiler/luci-interpreter/src/kernels/Less.test.cpp
deleted file mode 100644
index 73aa30b36..000000000
--- a/compiler/luci-interpreter/src/kernels/Less.test.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Less.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(LessTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, false, false, // Row 1
- false, false, true, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(LessTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, false, false, // Row 1
- false, true, true, // Row 2
- true, true, false, // Row 3
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(LessTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.55, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, false, false, false, // Row 1
- false, true, false, true, // Row 2
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessTest, Uint8QuantizedRescale)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.6, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, false, false, false, // Row 1
- false, true, false, true, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 1.2, F_MAX * 1.5);
-
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, true, false, true, // Row 1
- false, false, false, true, // Row 2
- false, true, false, true, // Row 3
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 3, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 3, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(LessTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Less kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LessEqual.cpp b/compiler/luci-interpreter/src/kernels/LessEqual.cpp
deleted file mode 100644
index b8aaba178..000000000
--- a/compiler/luci-interpreter/src/kernels/LessEqual.cpp
+++ /dev/null
@@ -1,113 +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 "kernels/LessEqual.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-LessEqual::LessEqual(const Tensor *x, const Tensor *y, Tensor *output) : Kernel({x, y}, {output}) {}
-
-void LessEqual::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void LessEqual::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void LessEqual::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowLessEqual(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::LessEqual(op_params, getTensorShape(x()), x_data, getTensorShape(y()),
- y_data, getTensorShape(output()), output_data);
- }
-}
-
-void LessEqual::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowLessEqualWithScaling(
- op_params, getTensorShape(x()), x_data, getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::LessEqualWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LessEqual.h b/compiler/luci-interpreter/src/kernels/LessEqual.h
deleted file mode 100644
index ed4b0f1ea..000000000
--- a/compiler/luci-interpreter/src/kernels/LessEqual.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LESS_EQUAL_H
-#define LUCI_INTERPRETER_KERNELS_LESS_EQUAL_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class LessEqual : public Kernel
-{
-public:
- LessEqual(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LESS_EQUAL_H
diff --git a/compiler/luci-interpreter/src/kernels/LessEqual.test.cpp b/compiler/luci-interpreter/src/kernels/LessEqual.test.cpp
deleted file mode 100644
index 9184c061f..000000000
--- a/compiler/luci-interpreter/src/kernels/LessEqual.test.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/LessEqual.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(LessEqualTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, true, false, // Row 1
- false, true, true, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(LessEqualTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, true, false, // Row 1
- false, true, true, // Row 2
- true, true, false, // Row 3
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({3, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({3, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(LessEqualTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.55, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, true, false, false, // Row 1
- false, true, false, true, // Row 2
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessEqualTest, Uint8QuantizedRescale)
-{
- std::vector<float> x_data{
- 0.5, 0.6, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.6, 0.6, 0.5, // Row 1
- -1, 0.05, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, true, false, false, // Row 1
- false, true, false, true, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 1.2, F_MAX * 1.5);
-
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessEqualTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- false, true, false, true, // Row 1
- false, false, true, true, // Row 2
- false, true, false, true, // Row 3
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 3, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 3, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(LessEqualTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(LessEqualTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LessEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.cpp b/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.cpp
deleted file mode 100644
index b78e27128..000000000
--- a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.cpp
+++ /dev/null
@@ -1,65 +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 "kernels/LocalResponseNormalization.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-LocalResponseNormalization::LocalResponseNormalization(
- const Tensor *input, Tensor *output, const LocalResponseNormalizationParams &params)
- : KernelWithParams<LocalResponseNormalizationParams>({input}, {output}, params)
-{
-}
-
-void LocalResponseNormalization::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4);
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::FLOAT32);
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- output()->resize(input()->shape());
-}
-
-void LocalResponseNormalization::execute() const
-{
- switch (output()->element_type())
- {
- case DataType::FLOAT32:
- tflite::LocalResponseNormalizationParams op_params;
- op_params.range = params().radius;
- op_params.bias = params().bias;
- op_params.alpha = params().alpha;
- op_params.beta = params().beta;
- tflite::optimized_ops::LocalResponseNormalization(
- op_params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.h b/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.h
deleted file mode 100644
index 60408a104..000000000
--- a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.h
+++ /dev/null
@@ -1,44 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LOCALRESPONSENORMALIZATION_H
-#define LUCI_INTERPRETER_KERNELS_LOCALRESPONSENORMALIZATION_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class LocalResponseNormalization : public KernelWithParams<LocalResponseNormalizationParams>
-{
-public:
- LocalResponseNormalization(const Tensor *input, Tensor *output,
- const LocalResponseNormalizationParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LOCALRESPONSENORMALIZATION_H
diff --git a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.test.cpp b/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.test.cpp
deleted file mode 100644
index d98305c1a..000000000
--- a/compiler/luci-interpreter/src/kernels/LocalResponseNormalization.test.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/LocalResponseNormalization.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(LocalResponseNormalizationTest, SameAsL2Norm)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LocalResponseNormalizationParams params{};
- params.radius = 20;
- params.bias = 0.0;
- params.alpha = 1.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({-0.55, 0.3, 0.35, 0.6, -0.35, 0.05}));
-}
-
-TEST(LocalResponseNormalizationTest, WithAlpha)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LocalResponseNormalizationParams params{};
- params.radius = 20;
- params.bias = 0.0;
- params.alpha = 4.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({-0.275, 0.15, 0.175, 0.3, -0.175, 0.025}));
-}
-
-TEST(LocalResponseNormalizationTest, WithBias)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LocalResponseNormalizationParams params{};
- params.radius = 20;
- params.bias = 9.0;
- params.alpha = 4.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({-0.22, 0.12, 0.14, 0.24, -0.14, 0.02}));
-}
-
-TEST(LocalResponseNormalizationTest, SmallRadius)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LocalResponseNormalizationParams params{};
- params.radius = 2;
- params.bias = 9.0;
- params.alpha = 4.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- FloatArrayNear({-0.264926, 0.125109, 0.140112, 0.267261, -0.161788, 0.0244266}));
-}
-
-TEST(LocalResponseNormalizationTest, InvalidInputDimension_NEG)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LocalResponseNormalizationParams params{};
- params.radius = 20;
- params.bias = 0.0;
- params.alpha = 1.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(LocalResponseNormalizationTest, InvalidInputOutputType_NEG)
-{
- Tensor input_tensor =
- makeInputTensor<DataType::FLOAT32>({1, 1, 1, 6}, {-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- LocalResponseNormalizationParams params{};
- params.radius = 20;
- params.bias = 0.0;
- params.alpha = 1.0;
- params.beta = 0.5;
-
- LocalResponseNormalization kernel(&input_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LogSoftmax.cpp b/compiler/luci-interpreter/src/kernels/LogSoftmax.cpp
deleted file mode 100644
index 03d13e4ce..000000000
--- a/compiler/luci-interpreter/src/kernels/LogSoftmax.cpp
+++ /dev/null
@@ -1,91 +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 "kernels/LogSoftmax.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-LogSoftmax::LogSoftmax(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void LogSoftmax::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- if (input()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(output()->scale() == 16. / 256);
- LUCI_INTERPRETER_CHECK(output()->zero_point() == 255);
-
- tflite::SoftmaxParams params{};
-
- params.table = _table;
- params.beta = 1.0;
-
- tflite::optimized_ops::PopulateSoftmaxLookupTable(&params, input()->scale(), params.beta);
- }
- output()->resize(input()->shape());
-}
-
-void LogSoftmax::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void LogSoftmax::evalFloat() const
-{
- tflite::SoftmaxParams params{};
- tflite::reference_ops::LogSoftmax(params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void LogSoftmax::evalQuantized() const
-{
- const auto input_shape = getTensorShape(input());
- const auto output_shape = getTensorShape(output());
- const auto input_scale = input()->scale();
- uint8_t *output_data = getTensorData<uint8_t>(output());
- const uint8_t *input_data = getTensorData<uint8_t>(input());
-
- tflite::SoftmaxParams params{};
-
- params.table = const_cast<float *>(_table);
- params.zero_point = output()->zero_point();
- params.scale = output()->scale();
-
- tflite::optimized_ops::LogSoftmax(params, input_scale, input_shape, input_data, output_shape,
- output_data);
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/LogSoftmax.h b/compiler/luci-interpreter/src/kernels/LogSoftmax.h
deleted file mode 100644
index 18477fbe3..000000000
--- a/compiler/luci-interpreter/src/kernels/LogSoftmax.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LOGSOFTMAX_H
-#define LUCI_INTERPRETER_KERNELS_LOGSOFTMAX_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class LogSoftmax : public Kernel
-{
-public:
- LogSoftmax(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
- float _table[256];
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LOGSOFTMAX_H
diff --git a/compiler/luci-interpreter/src/kernels/LogSoftmax.test.cpp b/compiler/luci-interpreter/src/kernels/LogSoftmax.test.cpp
deleted file mode 100644
index d3b331dfe..000000000
--- a/compiler/luci-interpreter/src/kernels/LogSoftmax.test.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/LogSoftmax.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(LogSoftmaxTest, Float)
-{
- Shape input_shape{2, 4};
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 10, 1, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- LogSoftmax kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- -4.14297, -10.14297, -2.14297, -.142971, //
- -7.00104, -12.00104, -.00104087, -9.00104, //
- };
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(LogSoftmaxTest, Uint8)
-{
- float kMin = -10;
- float kMax = 10;
- float kLogSoftmaxQuantizedTolerance = 16. / 256;
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(kMin, kMax);
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 10, 1, //
- };
- Tensor input_tensor =
- makeInputTensor<DataType::U8>({2, 4}, quant_param.first, quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 16. / 256, 255);
-
- LogSoftmax kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- -4.14297, -10.14297, -2.14297, -.142971, //
- -7.00104, -12.00104, -.00104087, -9.00104, //
- };
- std::vector<int32_t> ref_output_shape{2, 4};
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kLogSoftmaxQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({189, 93, 221, 253, 142, 63, 255, 111}));
-}
-
-TEST(LogSoftmaxTest, InvalidInputOutputType_NEG)
-{
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 10, 1, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 4}, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 16. / 256, 255);
-
- LogSoftmax kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(LogSoftmaxTest, InvalidOutputQuantParam_NEG)
-{
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-10, 10);
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 10, 1, //
- };
- Tensor input_tensor =
- makeInputTensor<DataType::U8>({2, 4}, quant_param.first, quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 20. / 256, 255);
-
- LogSoftmax kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Logistic.cpp b/compiler/luci-interpreter/src/kernels/Logistic.cpp
deleted file mode 100644
index 97d7bf13d..000000000
--- a/compiler/luci-interpreter/src/kernels/Logistic.cpp
+++ /dev/null
@@ -1,94 +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 "kernels/Logistic.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Logistic::Logistic(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Logistic::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- if (input()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(output()->scale() == 1. / 256);
- populateLookupTable();
- }
- output()->resize(input()->shape());
-}
-
-void Logistic::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Logistic::evalFloat() const
-{
- tflite::reference_ops::Logistic(getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void Logistic::evalQuantized() const
-{
- const int size = tflite::MatchingFlatSize(getTensorShape(input()), getTensorShape(output()));
- uint8_t *output_data = getTensorData<uint8_t>(output());
- const uint8_t *input_data = getTensorData<uint8_t>(input());
- for (int i = 0; i < size; ++i)
- {
- output_data[i] = getTableValue(input_data[i]);
- }
-}
-
-void Logistic::populateLookupTable()
-{
- const auto input_scale = static_cast<double>(input()->scale());
- const auto input_zero_point = static_cast<int32_t>(input()->zero_point());
- const auto output_scale = static_cast<double>(output()->scale());
- const auto output_zero_point = static_cast<int32_t>(output()->zero_point());
- const float inverse_scale = 1 / output_scale;
- int32_t maxval = std::numeric_limits<uint8_t>::max();
- int32_t minval = std::numeric_limits<uint8_t>::min();
- for (int32_t val = minval; val <= maxval; ++val)
- {
- const float dequantized = input_scale * (val - input_zero_point);
- const float transformed = 1.0f / (1.0f + std::exp(-dequantized));
- const float rescaled = std::round(transformed * inverse_scale);
- const int32_t quantized = static_cast<int32_t>(rescaled + output_zero_point);
- setTableValue(static_cast<uint8_t>(std::max(std::min(maxval, quantized), minval)),
- static_cast<uint8_t>(val));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Logistic.h b/compiler/luci-interpreter/src/kernels/Logistic.h
deleted file mode 100644
index 31de6adf0..000000000
--- a/compiler/luci-interpreter/src/kernels/Logistic.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_LOGISTIC_H
-#define LUCI_INTERPRETER_KERNELS_LOGISTIC_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Logistic : public Kernel
-{
-public:
- Logistic(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void populateLookupTable();
- void setTableValue(uint8_t value, uint8_t idx) { _table[idx] = value; };
- uint8_t getTableValue(uint8_t idx) const { return _table[idx]; };
-
-private:
- uint8_t _table[256]{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_LOGISTIC_H
diff --git a/compiler/luci-interpreter/src/kernels/Logistic.test.cpp b/compiler/luci-interpreter/src/kernels/Logistic.test.cpp
deleted file mode 100644
index d3bbb330d..000000000
--- a/compiler/luci-interpreter/src/kernels/Logistic.test.cpp
+++ /dev/null
@@ -1,134 +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 "kernels/Logistic.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<getElementType<T>()>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(getElementType<T>());
-
- Logistic kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<float> output_data)
-{
- std::pair<float, int32_t> input_quant_param =
- quantizationParams<uint8_t>(std::min(input_data), std::max(input_data));
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1. / 256, 0);
-
- Logistic kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, output_tensor.scale() * 2));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-template <typename T> class LogisticTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(LogisticTest, DataTypes);
-
-TYPED_TEST(LogisticTest, Simple)
-{
- Check<TypeParam>(
- {89}, {89},
- {-10.0000000000, -9.7727272727, -9.5454545455, -9.3181818182, -9.0909090909, -8.8636363636,
- -8.6363636364, -8.4090909091, -8.1818181818, -7.9545454545, -7.7272727273, -7.5000000000,
- -7.2727272727, -7.0454545455, -6.8181818182, -6.5909090909, -6.3636363636, -6.1363636364,
- -5.9090909091, -5.6818181818, -5.4545454545, -5.2272727273, -5.0000000000, -4.7727272727,
- -4.5454545455, -4.3181818182, -4.0909090909, -3.8636363636, -3.6363636364, -3.4090909091,
- -3.1818181818, -2.9545454545, -2.7272727273, -2.5000000000, -2.2727272727, -2.0454545455,
- -1.8181818182, -1.5909090909, -1.3636363636, -1.1363636364, -0.9090909091, -0.6818181818,
- -0.4545454545, -0.2272727273, 0.0000000000, 0.2272727273, 0.4545454545, 0.6818181818,
- 0.9090909091, 1.1363636364, 1.3636363636, 1.5909090909, 1.8181818182, 2.0454545455,
- 2.2727272727, 2.5000000000, 2.7272727273, 2.9545454545, 3.1818181818, 3.4090909091,
- 3.6363636364, 3.8636363636, 4.0909090909, 4.3181818182, 4.5454545455, 4.7727272727,
- 5.0000000000, 5.2272727273, 5.4545454545, 5.6818181818, 5.9090909091, 6.1363636364,
- 6.3636363636, 6.5909090909, 6.8181818182, 7.0454545455, 7.2727272727, 7.5000000000,
- 7.7272727273, 7.9545454545, 8.1818181818, 8.4090909091, 8.6363636364, 8.8636363636,
- 9.0909090909, 9.3181818182, 9.5454545455, 9.7727272727, 10.0000000000},
- {0.0000453979, 0.0000569815, 0.0000715205, 0.0000897689, 0.0001126729, 0.0001414198,
- 0.0001774998, 0.0002227827, 0.0002796147, 0.0003509396, 0.0004404502, 0.0005527786,
- 0.0006937345, 0.0008706021, 0.0010925128, 0.0013709094, 0.0017201256, 0.0021581065,
- 0.0027073042, 0.0033957870, 0.0042586071, 0.0053394826, 0.0066928509, 0.0083863576,
- 0.0105038445, 0.0131488902, 0.0164489307, 0.0205599431, 0.0256715863, 0.0320125562,
- 0.0398556989, 0.0495221198, 0.0613831074, 0.0758581800, 0.0934070047, 0.1145124805,
- 0.1396521834, 0.1692560327, 0.2036499335, 0.2429886272, 0.2871859014, 0.3358556241,
- 0.3882805886, 0.4434251301, 0.5000000000, 0.5565748699, 0.6117194114, 0.6641443759,
- 0.7128140986, 0.7570113728, 0.7963500665, 0.8307439673, 0.8603478166, 0.8854875195,
- 0.9065929953, 0.9241418200, 0.9386168926, 0.9504778802, 0.9601443011, 0.9679874438,
- 0.9743284137, 0.9794400569, 0.9835510693, 0.9868511098, 0.9894961555, 0.9916136424,
- 0.9933071491, 0.9946605174, 0.9957413929, 0.9966042130, 0.9972926958, 0.9978418935,
- 0.9982798744, 0.9986290906, 0.9989074872, 0.9991293979, 0.9993062655, 0.9994472214,
- 0.9995595498, 0.9996490604, 0.9997203853, 0.9997772173, 0.9998225002, 0.9998585802,
- 0.9998873271, 0.9999102311, 0.9999284795, 0.9999430185, 0.9999546021});
-}
-
-TEST(LogisticTest, IvalidInputOutputType_NEG)
-{
- Shape input_shape = {1};
- std::vector<float> input_data{10};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1. / 256, 0);
-
- Logistic kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(LogisticTest, IvalidQuantParam_NEG)
-{
- Shape input_shape = {2};
- std::vector<float> input_data{-10, 10};
- std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(-10, 10);
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1. / 255, 0);
-
- Logistic kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/MaxPool2D.cpp b/compiler/luci-interpreter/src/kernels/MaxPool2D.cpp
deleted file mode 100644
index 123e6e1a2..000000000
--- a/compiler/luci-interpreter/src/kernels/MaxPool2D.cpp
+++ /dev/null
@@ -1,150 +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 "kernels/MaxPool2D.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h>
-#include <tensorflow/lite/kernels/internal/reference/pooling.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-MaxPool2D::MaxPool2D(const Tensor *input, Tensor *output, const Pool2DParams &params)
- : KernelWithParams<Pool2DParams>({input}, {output}, params)
-{
-}
-
-void MaxPool2D::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- assert(input()->shape().num_dims() == 4);
- const Shape &input_shape = input()->shape();
- const int32_t batches = input_shape.dim(0);
- const int32_t input_height = input_shape.dim(1);
- const int32_t input_width = input_shape.dim(2);
- const int32_t depth = input_shape.dim(3);
-
- const int32_t output_height = computeOutputSize(_params.padding, input_height,
- _params.filter_height, _params.stride_height);
- const int32_t output_width =
- computeOutputSize(_params.padding, input_width, _params.filter_width, _params.stride_width);
-
- _padding_height =
- computePadding(_params.stride_height, 1, input_height, _params.filter_height, output_height);
- _padding_width =
- computePadding(_params.stride_width, 1, input_width, _params.filter_width, output_width);
-
- output()->resize({batches, output_height, output_width, depth});
- if (input()->element_type() == DataType::U8)
- {
- LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
- LUCI_INTERPRETER_CHECK(output()->zero_point() == input()->zero_point());
- }
- else if (input()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
- LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && output()->zero_point() == 0);
- }
-}
-
-void MaxPool2D::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalSInt16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void MaxPool2D::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- tflite::reference_ops::MaxPool(params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void MaxPool2D::evalQuantized() const
-{
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- tflite::reference_ops::MaxPool(params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
-}
-
-void MaxPool2D::evalSInt16() const
-{
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::PoolParams params{};
- params.padding_values.height = _padding_height;
- params.padding_values.width = _padding_width;
- params.stride_height = _params.stride_height;
- params.stride_width = _params.stride_width;
- params.filter_height = _params.filter_height;
- params.filter_width = _params.filter_width;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- tflite::reference_integer_ops::MaxPool(
- params, getTensorShape(input()), getTensorData<int16_t>(input()), //
- getTensorShape(output()), getTensorData<int16_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/MaxPool2D.h b/compiler/luci-interpreter/src/kernels/MaxPool2D.h
deleted file mode 100644
index bb7666305..000000000
--- a/compiler/luci-interpreter/src/kernels/MaxPool2D.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_MAXPOOL2D_H
-#define LUCI_INTERPRETER_KERNELS_MAXPOOL2D_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class MaxPool2D : public KernelWithParams<Pool2DParams>
-{
-public:
- MaxPool2D(const Tensor *input, Tensor *output, const Pool2DParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalSInt16() const;
-
-private:
- int32_t _padding_height{};
- int32_t _padding_width{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_MAXPOOL2D_H
diff --git a/compiler/luci-interpreter/src/kernels/MaxPool2D.test.cpp b/compiler/luci-interpreter/src/kernels/MaxPool2D.test.cpp
deleted file mode 100644
index 1d7fe06c4..000000000
--- a/compiler/luci-interpreter/src/kernels/MaxPool2D.test.cpp
+++ /dev/null
@@ -1,125 +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 "kernels/MaxPool2D.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(MaxPool2DTest, Float)
-{
- Shape input_shape{1, 3, 5, 1};
- std::vector<float> input_data{
- 1, -1, 0, -2, 2, //
- -7, -6, -5, -4, -3, //
- 5, 4, 3, 6, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- MaxPool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 1, 2, //
- 5, 6, //
- };
- std::initializer_list<int32_t> ref_output_shape{1, 2, 2, 1};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MaxPool2DTest, Uint8)
-{
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-15.9375, 15.9375);
- std::vector<float> input_data{
- 0, -6, 12, 4, //
- -3, -2, 10, 7, //
- };
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 2;
- params.stride_height = 2;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- MaxPool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0.0, 6.0};
- std::initializer_list<int32_t> ref_output_shape{1, 1, 2, 1};
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MaxPool2DTest, SInt16)
-{
- Shape input_shape{1, 3, 5, 1};
- std::vector<int32_t> ref_output_shape{1, 2, 2, 1};
- std::vector<float> input_data{
- 1, -1, 0, -2, 2, //
- -7, -6, -5, -4, -3, //
- 5, 4, 3, 6, 7, //
- };
- std::vector<float> ref_output_data{
- 1, 2, //
- 5, 6, //
- };
-
- Tensor input_tensor = makeInputTensor<DataType::S16>(input_shape, 0.2, 0, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.2, 0);
-
- Pool2DParams params{};
- params.padding = Padding::VALID;
- params.filter_height = 2;
- params.filter_width = 3;
- params.stride_height = 1;
- params.stride_width = 2;
- params.activation = Activation::RELU6;
-
- MaxPool2D kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Maximum.cpp b/compiler/luci-interpreter/src/kernels/Maximum.cpp
deleted file mode 100644
index c522b0706..000000000
--- a/compiler/luci-interpreter/src/kernels/Maximum.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 "kernels/Maximum.h"
-
-#include "kernels/Utils.h"
-
-#include "kernels/BinaryOpCommon.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Maximum::Maximum(const Tensor *input1, const Tensor *input2, Tensor *output)
- : Kernel({input1, input2}, {output})
-{
-}
-
-void Maximum::configure()
-{
- LUCI_INTERPRETER_CHECK(input1()->element_type() == input2()->element_type())
- LUCI_INTERPRETER_CHECK(input1()->element_type() == output()->element_type())
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Maximum::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalMaximum<float>();
- break;
- case DataType::U8:
- evalMaximum<uint8_t>();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-template <typename T> inline void Maximum::evalMaximum() const
-{
- BinaryOpBroadcastSlow(getTensorShape(input1()), getTensorData<T>(input1()),
- getTensorShape(input2()), getTensorData<T>(input2()),
- getTensorShape(output()), getTensorData<T>(output()),
- [](T x, T y) { return std::max(x, y); });
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Maximum.h b/compiler/luci-interpreter/src/kernels/Maximum.h
deleted file mode 100644
index 3c99e69c7..000000000
--- a/compiler/luci-interpreter/src/kernels/Maximum.h
+++ /dev/null
@@ -1,47 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_MAXIMUM_H
-#define LUCI_INTERPRETER_KERNELS_MAXIMUM_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Maximum : public Kernel
-{
-public:
- Maximum(const Tensor *input1, const Tensor *input2, Tensor *output);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> inline void evalMaximum() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_MAXIMUM_H
diff --git a/compiler/luci-interpreter/src/kernels/Maximum.test.cpp b/compiler/luci-interpreter/src/kernels/Maximum.test.cpp
deleted file mode 100644
index 2ddaeaf04..000000000
--- a/compiler/luci-interpreter/src/kernels/Maximum.test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Maximum.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(MaximumTest, Float)
-{
- Shape input_shape{3, 1, 2};
- std::vector<float> input_data1{1.0, 0.0, -1.0, 11.0, -2.0, -1.44};
- std::vector<float> input_data2{-1.0, 0.0, 1.0, 12.0, -3.0, -1.43};
- Tensor input_tensor1 = makeInputTensor<DataType::FLOAT32>(input_shape, input_data1);
- Tensor input_tensor2 = makeInputTensor<DataType::FLOAT32>(input_shape, input_data2);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Maximum kernel(&input_tensor1, &input_tensor2, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{1.0, 0.0, 1.0, 12.0, -2.0, -1.43};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(MaximumTest, Uint8)
-{
- Shape input_shape{3, 1, 2};
- std::vector<uint8_t> input_data1{1, 0, 2, 11, 2, 23};
- std::vector<uint8_t> input_data2{0, 0, 1, 12, 255, 1};
- Tensor input_tensor1 = makeInputTensor<DataType::U8>(input_shape, input_data1);
- Tensor input_tensor2 = makeInputTensor<DataType::U8>(input_shape, input_data2);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Maximum kernel(&input_tensor1, &input_tensor2, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<int32_t> ref_output_shape{2, 4};
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({1, 0, 2, 12, 255, 23}));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Mean.cpp b/compiler/luci-interpreter/src/kernels/Mean.cpp
deleted file mode 100644
index 7d022eaf8..000000000
--- a/compiler/luci-interpreter/src/kernels/Mean.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Mean.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-static void resolveAxes(const int *axes_data, int num_axes, tflite::MeanParams *params)
-{
- params->axis_count = num_axes;
- for (int i = 0; i < num_axes; ++i)
- {
- params->axis[i] = static_cast<int16>(axes_data[i]);
- }
- for (int i = num_axes; i < 4; ++i)
- {
- params->axis[i] = 1;
- }
-}
-
-// Returns the number of axes that will be reduced. Removes duplicates.
-static int getAxisReductionCount(const int *axes_data, int num_axes, int input_num_dims)
-{
- int reduction_count = num_axes;
- for (int i = 0; i < num_axes; ++i)
- {
- int current = axes_data[i] >= 0 ? axes_data[i] : axes_data[i] + input_num_dims;
- assert(current >= 0 && current < input_num_dims);
- for (int j = 0; j < i; j++)
- {
- int previous = axes_data[j] >= 0 ? axes_data[j] : axes_data[j] + input_num_dims;
- // This checks for duplicate axis
- if (current == previous)
- {
- --reduction_count;
- break;
- }
- }
- }
- return reduction_count;
-}
-
-static Shape getOutputShape(const Shape &input_shape, const int *axes_data, int num_axes,
- bool keep_dims)
-{
- int input_num_dims = input_shape.num_dims();
- if (input_num_dims == 0)
- {
- return Shape(0);
- }
-
- if (keep_dims)
- {
- Shape output_shape(input_num_dims);
- for (int idx = 0; idx < input_num_dims; ++idx)
- {
- bool is_axis = false;
- for (int axis_idx = 0; axis_idx < num_axes; ++axis_idx)
- {
- if (axes_data[axis_idx] == idx || axes_data[axis_idx] + input_num_dims == idx)
- {
- is_axis = true;
- break;
- }
- }
- if (is_axis)
- {
- output_shape.dim(idx) = 1;
- }
- else
- {
- output_shape.dim(idx) = input_shape.dim(idx);
- }
- }
- return output_shape;
- }
- else
- {
- int num_reduce_axes = getAxisReductionCount(axes_data, num_axes, input_num_dims);
- Shape output_shape(input_num_dims - num_reduce_axes);
- int num_skip_axes = 0;
- for (int idx = 0; idx < input_num_dims; ++idx)
- {
- bool is_axis = false;
- for (int axis_idx = 0; axis_idx < num_axes; ++axis_idx)
- {
- if (axes_data[axis_idx] == idx || axes_data[axis_idx] + input_num_dims == idx)
- {
- ++num_skip_axes;
- is_axis = true;
- break;
- }
- }
- if (!is_axis)
- {
- output_shape.dim(idx - num_skip_axes) = input_shape.dim(idx);
- }
- }
- return output_shape;
- }
-}
-
-Mean::Mean(const Tensor *input, const Tensor *axes, Tensor *output, const ReducerParams &params)
- : KernelWithParams<ReducerParams>({input, axes}, {output}, params)
-{
-}
-
-void Mean::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- LUCI_INTERPRETER_CHECK(axes()->element_type() == DataType::S32);
- if (input()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && output()->zero_point() == 0);
- }
-
- const Shape &input_shape = input()->shape();
- int input_num_dims = input_shape.num_dims();
-
- const auto *axes_data = getTensorData<int32_t>(axes());
- int num_axes = axes()->shape().num_elements();
- assert(num_axes <= 4);
-
- Shape output_shape = getOutputShape(input_shape, axes_data, num_axes, _params.keep_dims);
- output()->resize(output_shape);
-
- tflite::MeanParams params{};
- resolveAxes(axes_data, num_axes, &params);
- const bool need_temporaries =
- !(_params.keep_dims && input_num_dims == 4 && params.axis_count == 2 &&
- ((params.axis[0] == 1 && params.axis[1] == 2) ||
- (params.axis[0] == 2 && params.axis[1] == 1)));
- if (need_temporaries)
- {
- _temp_index =
- std::make_unique<Tensor>(DataType::S32, Shape(input_num_dims), AffineQuantization{}, "");
- _resolved_axes =
- std::make_unique<Tensor>(DataType::S32, Shape(num_axes), AffineQuantization{}, "");
- _temp_sum = std::make_unique<Tensor>(input()->element_type(), output()->shape(),
- AffineQuantization{}, "");
- }
-}
-
-void Mean::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalQuantizedS16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Mean::evalFloat() const
-{
- const Shape &input_shape = input()->shape();
- int input_num_dims = input_shape.num_dims();
- const auto *axes_data = getTensorData<int32_t>(axes());
- int num_axes = axes()->shape().num_elements();
-
- tflite::MeanParams params{};
- resolveAxes(axes_data, num_axes, &params);
-
- // Defer to specialized implementation for 4D Mean across axes 1 & 2.
- if (_params.keep_dims && input_num_dims == 4 && params.axis_count == 2 &&
- ((params.axis[0] == 1 && params.axis[1] == 2) ||
- (params.axis[0] == 2 && params.axis[1] == 1)))
- {
- tflite::reference_ops::Mean(params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
- }
- else
- {
- tflite::reference_ops::Mean(
- getTensorData<float>(input()), getTensorShape(input()).DimsData(),
- input()->shape().num_dims(), getTensorData<float>(output()),
- getTensorShape(output()).DimsData(), output()->shape().num_dims(), axes_data, num_axes,
- _params.keep_dims, getTensorData<int>(_temp_index.get()),
- getTensorData<int>(_resolved_axes.get()), getTensorData<float>(_temp_sum.get()));
- }
-}
-
-void Mean::evalQuantized() const
-{
- const Shape &input_shape = input()->shape();
- int input_num_dims = input_shape.num_dims();
- const auto *axes_data = getTensorData<int32_t>(axes());
- int num_axes = axes()->shape().num_elements();
-
- tflite::MeanParams params{};
- resolveAxes(axes_data, num_axes, &params);
-
- // Defer to specialized implementation for 4D Mean across axes 1 & 2.
- if (_params.keep_dims && input_num_dims == 4 && params.axis_count == 2 &&
- ((params.axis[0] == 1 && params.axis[1] == 2) ||
- (params.axis[0] == 2 && params.axis[1] == 1)))
- {
- tflite::reference_ops::Mean(params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- input()->zero_point(), input()->scale(), getTensorShape(output()),
- getTensorData<uint8_t>(output()), output()->zero_point(),
- output()->scale());
- }
- else if (input()->zero_point() == output()->zero_point() && input()->scale() == output()->scale())
- {
- tflite::reference_ops::Mean(
- getTensorData<uint8_t>(input()), getTensorShape(input()).DimsData(),
- input()->shape().num_dims(), getTensorData<uint8_t>(output()),
- getTensorShape(output()).DimsData(), output()->shape().num_dims(), axes_data, num_axes,
- _params.keep_dims, getTensorData<int>(_temp_index.get()),
- getTensorData<int>(_resolved_axes.get()), getTensorData<int>(_temp_sum.get()));
- }
- else
- {
- tflite::reference_ops::QuantizedMeanOrSum<>(
- getTensorData<uint8_t>(input()), input()->zero_point(), input()->scale(),
- getTensorShape(input()).DimsData(), input()->shape().num_dims(),
- getTensorData<uint8_t>(output()), output()->zero_point(), output()->scale(),
- getTensorShape(output()).DimsData(), output()->shape().num_dims(), axes_data, num_axes,
- _params.keep_dims, getTensorData<int>(_temp_index.get()),
- getTensorData<int>(_resolved_axes.get()), getTensorData<int>(_temp_sum.get()),
- /*compute_sum=*/false);
- }
-}
-
-void Mean::evalQuantizedS16() const
-{
- const auto *input_data = getTensorData<int16_t>(input());
- auto *output_data = getTensorData<int16_t>(output());
-
- const Shape &input_shape = input()->shape();
- const Shape &output_shape = output()->shape();
-
- const auto *axes_data = getTensorData<int32_t>(axes());
- const int num_axes = axes()->shape().num_elements();
-
- constexpr int32_t output_min = -std::numeric_limits<int16_t>::max();
- constexpr int32_t output_max = std::numeric_limits<int16_t>::max();
-
- // Defer to specialized implementation for 4D Mean across axes 1 & 2.
- if (_params.keep_dims && input_shape.num_dims() == 4 && num_axes == 2 &&
- ((axes_data[0] == 1 && axes_data[1] == 2) || (axes_data[0] == 2 && axes_data[1] == 1)))
- {
- const int32_t batches = input_shape.dim(0);
- const int32_t input_height = input_shape.dim(1);
- const int32_t input_width = input_shape.dim(2);
- const int32_t depth = input_shape.dim(3);
- assert(output_shape.num_dims() == 4);
- assert(output_shape.dim(0) == batches);
- assert(output_shape.dim(1) == 1);
- assert(output_shape.dim(2) == 1);
- assert(output_shape.dim(3) == depth);
-
- const double real_multiplier =
- static_cast<double>(input()->scale()) / static_cast<double>(output()->scale());
-
- int32_t output_multiplier{};
- int output_shift{};
- quantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
-
- const int32_t num_elements_in_axes = input_height * input_width;
-
- for (int32_t batch = 0; batch < batches; ++batch)
- {
- for (int32_t c = 0; c < depth; ++c)
- {
- int32_t acc = 0;
- for (int32_t in_y = 0; in_y < input_height; ++in_y)
- {
- for (int32_t in_x = 0; in_x < input_width; ++in_x)
- {
- acc += input_data[calcOffset(input_shape, batch, in_y, in_x, c)];
- }
- }
- int32_t scaled_acc =
- tflite::MultiplyByQuantizedMultiplier(acc, output_multiplier, output_shift);
- // Divide by the number of elements rounding to the nearest integer.
- scaled_acc = scaled_acc > 0
- ? (scaled_acc + num_elements_in_axes / 2) / num_elements_in_axes
- : (scaled_acc - num_elements_in_axes / 2) / num_elements_in_axes;
-
- scaled_acc = std::max(scaled_acc, output_min);
- scaled_acc = std::min(scaled_acc, output_max);
-
- output_data[calcOffset(output_shape, batch, 0, 0, c)] = scaled_acc;
- }
- }
- }
- else
- {
- throw std::runtime_error("Unsupported configuration.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Mean.h b/compiler/luci-interpreter/src/kernels/Mean.h
deleted file mode 100644
index 1cc046894..000000000
--- a/compiler/luci-interpreter/src/kernels/Mean.h
+++ /dev/null
@@ -1,56 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_MEAN_H
-#define LUCI_INTERPRETER_KERNELS_MEAN_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <memory>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Mean : public KernelWithParams<ReducerParams>
-{
-public:
- Mean(const Tensor *input, const Tensor *axes, Tensor *output, const ReducerParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *axes() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalQuantizedS16() const;
-
-private:
- std::unique_ptr<Tensor> _temp_index;
- std::unique_ptr<Tensor> _resolved_axes;
- std::unique_ptr<Tensor> _temp_sum;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_MEAN_H
diff --git a/compiler/luci-interpreter/src/kernels/Mean.test.cpp b/compiler/luci-interpreter/src/kernels/Mean.test.cpp
deleted file mode 100644
index e81d2ad5f..000000000
--- a/compiler/luci-interpreter/src/kernels/Mean.test.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Mean.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(MeanTest, FloatKeepDims)
-{
- std::vector<float> input_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
- 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
-
- std::vector<int32_t> axis_data{0, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({4, 3, 2}, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>({2}, axis_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ReducerParams params{};
- params.keep_dims = true;
-
- Mean kernel(&input_tensor, &axis_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{10.5, 12.5, 14.5};
- std::initializer_list<int32_t> ref_output_shape{1, 3, 1};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MeanTest, FloatKeepDims4DMean)
-{
- std::vector<float> input_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
- 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
-
- std::vector<int32_t> axis_data{1, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 3, 2}, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>({2}, axis_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ReducerParams params{};
- params.keep_dims = true;
-
- Mean kernel(&input_tensor, &axis_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{6, 7, 18, 19};
- std::initializer_list<int32_t> ref_output_shape{2, 1, 1, 2};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MeanTest, FloatNotKeepDims)
-{
- std::vector<float> input_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
- 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
-
- std::vector<int32_t> axis_data{1, 0, -3, -3};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({4, 3, 2}, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>({4}, axis_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ReducerParams params{};
- params.keep_dims = false;
-
- Mean kernel(&input_tensor, &axis_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{12, 13};
- std::initializer_list<int32_t> ref_output_shape{2};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MeanTest, Uint8KeepDims)
-{
- float kQuantizedTolerance = getTolerance(-1.0, 1.0, 255);
- std::vector<float> input_data = {0.4, 0.2, 0.3, 0.4, 0.5, 0.6};
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
-
- std::vector<int32_t> axis_data{1};
- Tensor input_tensor =
- makeInputTensor<DataType::U8>({3, 2}, quant_param.first, quant_param.second, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>({1}, axis_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- ReducerParams params{};
- params.keep_dims = true;
-
- Mean kernel(&input_tensor, &axis_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0.3, 0.35, 0.55};
- std::initializer_list<int32_t> ref_output_shape{3, 1};
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MeanTest, Uint8NotKeepDims)
-{
- float kQuantizedTolerance = getTolerance(-1.0, 1.0, 255);
- std::vector<float> input_data = {0.4, 0.2, 0.3, 0.4, 0.5, 0.6};
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
-
- std::vector<int32_t> axis_data{1};
- Tensor input_tensor =
- makeInputTensor<DataType::U8>({1, 3, 2}, quant_param.first, quant_param.second, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>({1}, axis_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- ReducerParams params{};
- params.keep_dims = false;
-
- Mean kernel(&input_tensor, &axis_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0.4, 0.4};
- std::initializer_list<int32_t> ref_output_shape{1, 2};
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-TEST(MeanTest, SInt16KeepDims4D)
-{
- std::vector<float> input_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
- 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
- std::vector<int32_t> axes_data{1, 2};
- std::vector<float> ref_output_data{6, 7, 18, 19};
-
- Tensor input_tensor = makeInputTensor<DataType::S16>({2, 2, 3, 2}, 0.25, 0, input_data);
- Tensor axes_tensor = makeInputTensor<DataType::S32>({2}, axes_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.2, 0);
-
- ReducerParams params{};
- params.keep_dims = true;
-
- Mean kernel(&input_tensor, &axes_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 1, 1, 2}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Minimum.cpp b/compiler/luci-interpreter/src/kernels/Minimum.cpp
deleted file mode 100644
index 5eb13455e..000000000
--- a/compiler/luci-interpreter/src/kernels/Minimum.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 "kernels/Minimum.h"
-
-#include "kernels/Utils.h"
-
-#include "kernels/BinaryOpCommon.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Minimum::Minimum(const Tensor *input1, const Tensor *input2, Tensor *output)
- : Kernel({input1, input2}, {output})
-{
-}
-
-void Minimum::configure()
-{
- LUCI_INTERPRETER_CHECK(input1()->element_type() == input2()->element_type())
- LUCI_INTERPRETER_CHECK(input1()->element_type() == output()->element_type())
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Minimum::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalMinimum<float>();
- break;
- case DataType::U8:
- evalMinimum<uint8_t>();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-template <typename T> inline void Minimum::evalMinimum() const
-{
- BinaryOpBroadcastSlow(getTensorShape(input1()), getTensorData<T>(input1()),
- getTensorShape(input2()), getTensorData<T>(input2()),
- getTensorShape(output()), getTensorData<T>(output()),
- [](T x, T y) { return std::min(x, y); });
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Minimum.h b/compiler/luci-interpreter/src/kernels/Minimum.h
deleted file mode 100644
index 5ff4035b4..000000000
--- a/compiler/luci-interpreter/src/kernels/Minimum.h
+++ /dev/null
@@ -1,47 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_MINIMUM_H
-#define LUCI_INTERPRETER_KERNELS_MINIMUM_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Minimum : public Kernel
-{
-public:
- Minimum(const Tensor *input1, const Tensor *input2, Tensor *output);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> inline void evalMinimum() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_MINIMUM_H
diff --git a/compiler/luci-interpreter/src/kernels/Minimum.test.cpp b/compiler/luci-interpreter/src/kernels/Minimum.test.cpp
deleted file mode 100644
index b6420dd9b..000000000
--- a/compiler/luci-interpreter/src/kernels/Minimum.test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Minimum.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(MinimumTest, Float)
-{
- Shape input_shape{3, 1, 2};
- std::vector<float> input_data1{1.0, 0.0, -1.0, 11.0, -2.0, -1.44};
- std::vector<float> input_data2{-1.0, 0.0, 1.0, 12.0, -3.0, -1.43};
- Tensor input_tensor1 = makeInputTensor<DataType::FLOAT32>(input_shape, input_data1);
- Tensor input_tensor2 = makeInputTensor<DataType::FLOAT32>(input_shape, input_data2);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Minimum kernel(&input_tensor1, &input_tensor2, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{-1.0, 0.0, -1.0, 11.0, -3.0, -1.44};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(MinimumTest, Uint8)
-{
- Shape input_shape{3, 1, 2};
- std::vector<uint8_t> input_data1{1, 0, 2, 11, 2, 23};
- std::vector<uint8_t> input_data2{0, 0, 1, 12, 255, 1};
- Tensor input_tensor1 = makeInputTensor<DataType::U8>(input_shape, input_data1);
- Tensor input_tensor2 = makeInputTensor<DataType::U8>(input_shape, input_data2);
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Minimum kernel(&input_tensor1, &input_tensor2, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<int32_t> ref_output_shape{2, 4};
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({0, 0, 1, 11, 2, 1}));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Mul.cpp b/compiler/luci-interpreter/src/kernels/Mul.cpp
deleted file mode 100644
index dd31aa099..000000000
--- a/compiler/luci-interpreter/src/kernels/Mul.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Mul.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-#include <tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Mul::Mul(const Tensor *input1, const Tensor *input2, Tensor *output, const MulParams &params)
- : KernelWithParams<MulParams>({input1, input2}, {output}, params)
-{
-}
-
-void Mul::configure()
-{
- assert(input1()->element_type() == input2()->element_type());
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Mul::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Mul::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::optimized_ops::BroadcastMul4DSlow(
- params, getTensorShape(input1()), getTensorData<float>(input1()), getTensorShape(input2()),
- getTensorData<float>(input2()), getTensorShape(output()), getTensorData<float>(output()));
- }
- else
- {
- tflite::optimized_ops::Mul(params, getTensorShape(input1()), getTensorData<float>(input1()),
- getTensorShape(input2()), getTensorData<float>(input2()),
- getTensorShape(output()), getTensorData<float>(output()));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Mul.h b/compiler/luci-interpreter/src/kernels/Mul.h
deleted file mode 100644
index e46160bcb..000000000
--- a/compiler/luci-interpreter/src/kernels/Mul.h
+++ /dev/null
@@ -1,50 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_MUL_H
-#define LUCI_INTERPRETER_KERNELS_MUL_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <cstdint>
-#include <vector>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Mul : public KernelWithParams<MulParams>
-{
-public:
- Mul(const Tensor *input1, const Tensor *input2, Tensor *output, const MulParams &params);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_MUL_H
diff --git a/compiler/luci-interpreter/src/kernels/Mul.test.cpp b/compiler/luci-interpreter/src/kernels/Mul.test.cpp
deleted file mode 100644
index fbda3bece..000000000
--- a/compiler/luci-interpreter/src/kernels/Mul.test.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Mul.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(MulTest, Float)
-{
- Shape base_shape = {2, 3, 1, 2};
- std::vector<Shape> test_shapes{{1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- std::vector<std::vector<float>> test_outputs = {
- {0.00f, 0.69f, 0.12f, 1.15f, 0.00f, 2.07f, 0.18f, 0.15f, 0.00f, 0.25f, 0.90f, 0.45f,
- 0.16f, 0.00f, 0.00f, 0.00f, 0.80f, 0.00f, 0.24f, 0.84f, 0.00f, 1.40f, 1.20f, 2.52f,
- 0.00f, 0.00f, 0.64f, 0.00f, 0.00f, 0.00f, 0.14f, 0.00f, 0.00f, 0.00f, 0.70f, 0.00f},
- {0.00f, 0.69f, 0.00f, 0.25f, 0.80f, 0.00f, 0.24f, 0.84f, 0.64f, 0.00f, 0.70f, 0.00f},
- {0.00f, 0.46f, 0.00f, 0.69f, 0.12f, 0.00f, 0.18f, 0.10f, 0.27f, 0.15f, 0.00f, 0.00f,
- 0.16f, 0.00f, 0.24f, 0.00f, 0.00f, 0.44f, 0.60f, 1.40f, 1.20f, 2.80f, 1.08f, 2.52f,
- 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.35f, 0.00f, 0.70f, 0.00f, 0.63f, 0.00f},
- {0.00f, 0.46f, 0.27f, 0.15f, 0.00f, 0.44f, 0.60f, 1.40f, 0.00f, 0.00f, 0.63f, 0.00f}};
- std::vector<float> input1_data{-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- std::vector<float> input2_data{0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(test_shapes[i], input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- MulParams params{};
- params.activation = Activation::RELU;
-
- Mul kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs[i], 0.0001f))
- << "With shape number " << i;
- }
- // Re-run with exchanged inputs.
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(test_shapes[i], input2_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- MulParams params{};
- params.activation = Activation::RELU;
-
- Mul kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs[i], 0.0001f))
- << "With shape number " << i;
- }
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/NotEqual.cpp b/compiler/luci-interpreter/src/kernels/NotEqual.cpp
deleted file mode 100644
index cd2f6c2c1..000000000
--- a/compiler/luci-interpreter/src/kernels/NotEqual.cpp
+++ /dev/null
@@ -1,113 +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 "kernels/NotEqual.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/comparisons.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-NotEqual::NotEqual(const Tensor *x, const Tensor *y, Tensor *output) : Kernel({x, y}, {output}) {}
-
-void NotEqual::configure()
-{
- LUCI_INTERPRETER_CHECK(x()->element_type() == y()->element_type());
- LUCI_INTERPRETER_CHECK(output()->element_type() == DataType::BOOL);
-
- if (x()->element_type() == DataType::U8)
- {
- quantizeMultiplierSmallerThanOneExp(x()->scale(), &_x_multiplier, &_x_shift);
- quantizeMultiplierSmallerThanOneExp(y()->scale(), &_y_multiplier, &_y_shift);
- }
- output()->resize(calculateShapeForBroadcast(x()->shape(), y()->shape()));
-}
-
-void NotEqual::execute() const
-{
- switch (x()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void NotEqual::evalFloat() const
-{
- const auto x_data = getTensorData<float>(x());
- const auto y_data = getTensorData<float>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowNotEqual(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::NotEqual(op_params, getTensorShape(x()), x_data, getTensorShape(y()),
- y_data, getTensorShape(output()), output_data);
- }
-}
-
-void NotEqual::evalQuantized() const
-{
- const auto x_data = getTensorData<uint8_t>(x());
- const auto y_data = getTensorData<uint8_t>(y());
- auto output_data = getTensorData<bool>(output());
-
- tflite::ComparisonParams op_params;
- op_params.left_shift = 8;
- op_params.input1_offset = -x()->zero_point(); // Note the '-'
- op_params.input1_shift = _x_shift;
- op_params.input1_multiplier = _x_multiplier;
- op_params.input2_offset = -y()->zero_point(); // Note the '-'
- op_params.input2_shift = _y_shift;
- op_params.input2_multiplier = _y_multiplier;
- op_params.is_broadcast = x()->shape() != y()->shape();
-
- if (op_params.is_broadcast)
- {
- tflite::reference_ops::Broadcast4DSlowNotEqualWithScaling(
- op_params, getTensorShape(x()), x_data, getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
- else
- {
- tflite::reference_ops::NotEqualWithScaling(op_params, getTensorShape(x()), x_data,
- getTensorShape(y()), y_data,
- getTensorShape(output()), output_data);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/NotEqual.h b/compiler/luci-interpreter/src/kernels/NotEqual.h
deleted file mode 100644
index d729c6c14..000000000
--- a/compiler/luci-interpreter/src/kernels/NotEqual.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_NOT_EQUAL_H
-#define LUCI_INTERPRETER_KERNELS_NOT_EQUAL_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class NotEqual : public Kernel
-{
-public:
- NotEqual(const Tensor *x, const Tensor *y, Tensor *output);
-
- const Tensor *x() const { return _inputs[0]; }
- const Tensor *y() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _x_multiplier = 0;
- int32_t _x_shift = 0;
- int32_t _y_multiplier = 0;
- int32_t _y_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_NOT_EQUAL_H
diff --git a/compiler/luci-interpreter/src/kernels/NotEqual.test.cpp b/compiler/luci-interpreter/src/kernels/NotEqual.test.cpp
deleted file mode 100644
index 8c8712371..000000000
--- a/compiler/luci-interpreter/src/kernels/NotEqual.test.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/NotEqual.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(NotEqualTest, FloatSimple)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- -1, 0, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, false, true, // Row 1
- true, false, true, // Row 2
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(NotEqualTest, FloatBroardcast)
-{
- std::vector<float> x_data{
- 0.5, 0.7, 0.9, // Row 1
- 1, 0, -1, // Row 2
- -1, 0, 1, // Row 3
- 0.9, 0.7, 0.5, // Row 4
- };
-
- std::vector<float> y_data{
- 0.9, 0.7, 0.5, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, false, true, // Row 1
- true, true, true, // Row 2
- true, true, true, // Row 3
- false, false, false, // Row 4
- };
-
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({4, 3}, x_data);
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1, 3}, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({4, 3}));
-}
-
-// Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
-const float F_MIN = -128.0 / 128.0;
-const float F_MAX = 127.0 / 128.0;
-
-TEST(NotEqualTest, Uint8Quantized)
-{
- std::vector<float> x_data{
- 0.5, 0.5, 0.7, 0.9, // Row 1
- 1, 0, 0.05, -1, // Row 2
- };
-
- std::vector<float> y_data{
- 0.9, 0.5, 0.55, 0.5, // Row 1
- -1, 0, 0.05, 1, // Row 2
- };
-
- std::vector<bool> ref_output_data{
- true, false, true, true, // Row 1
- true, false, false, true, // Row 2
- };
-
- std::pair<float, int32_t> x_quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, x_quant_param.first,
- x_quant_param.second, x_data);
-
- std::pair<float, int32_t> y_quant_param = quantizationParams<uint8_t>(F_MIN * 2, F_MAX * 2);
- Tensor y_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, y_quant_param.first,
- y_quant_param.second, y_data);
-
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(NotEqualTest, Uint8QuantizedBroadcast)
-{
- std::vector<float> x_data{
- 0.4, -0.8, 0.7, 0.3, // Row 1
- -0.5, 0.1, 0, 0.5, // Row 2
- 1, 0, 0.05, -1, // Row 3
- -1, 0.05, 0, 1, // Row 4
- };
-
- std::vector<float> y_data{
- -1, 0.05, 0, 1, // Row 1
- };
-
- std::vector<bool> ref_output_data{
- true, true, true, true, // Row 1
- true, true, false, true, // Row 2
- true, true, true, true, // Row 3
- false, false, false, false, // Row 4
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(F_MIN, F_MAX);
- Tensor x_tensor =
- makeInputTensor<DataType::U8>({1, 4, 4, 1}, quant_param.first, quant_param.second, x_data);
- Tensor y_tensor =
- makeInputTensor<DataType::U8>({1, 1, 4, 1}, quant_param.first, quant_param.second, y_data);
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 4, 4, 1}));
- EXPECT_THAT(extractTensorData<bool>(output_tensor), ::testing::ElementsAreArray(ref_output_data));
-}
-
-TEST(NotEqualTest, Input_Type_Mismatch_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::BOOL);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(NotEqualTest, Input_Output_Type_NEG)
-{
- Tensor x_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor y_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- NotEqual kernel(&x_tensor, &y_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Pad.cpp b/compiler/luci-interpreter/src/kernels/Pad.cpp
deleted file mode 100644
index bdf3a2a95..000000000
--- a/compiler/luci-interpreter/src/kernels/Pad.cpp
+++ /dev/null
@@ -1,102 +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 "kernels/Pad.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Pad::Pad(const Tensor *input, const Tensor *paddings, Tensor *output)
- : Kernel({input, paddings}, {output})
-{
-}
-
-void Pad::configure()
-{
- const Shape &input_shape = input()->shape();
- const int num_dims = input_shape.num_dims();
-
- if (num_dims > 4)
- throw std::runtime_error("Unsupported number of dimensions.");
-
- assert(output()->element_type() == input()->element_type());
- assert(paddings()->element_type() == DataType::S32);
- // Paddings shape should be [N, 2].
- assert(paddings()->shape().num_dims() == 2);
- assert(paddings()->shape().dim(0) == num_dims);
- assert(paddings()->shape().dim(1) == 2);
-
- Shape output_shape(num_dims);
- const auto *paddings_data = getTensorData<int32_t>(paddings());
- for (int i = 0; i < num_dims; ++i)
- {
- const int32_t padding_before = paddings_data[i * 2];
- const int32_t padding_after = paddings_data[i * 2 + 1];
- assert(padding_before >= 0 && padding_after >= 0);
- output_shape.dim(i) = input_shape.dim(i) + padding_before + padding_after;
- }
-
- output()->resize(output_shape);
-}
-
-void Pad::execute() const
-{
- const int num_dims = input()->shape().num_dims();
-
- tflite::PadParams params{};
- params.left_padding_count = num_dims;
- params.right_padding_count = num_dims;
-
- const auto *paddings_data = getTensorData<int32_t>(paddings());
- for (int i = num_dims - 1; i >= 0; --i)
- {
- params.left_padding[i] = paddings_data[i * 2];
- params.right_padding[i] = paddings_data[i * 2 + 1];
- }
-
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- {
- const float pad_value = 0.0f;
- tflite::reference_ops::Pad(params, getTensorShape(input()), getTensorData<float>(input()),
- &pad_value, getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- }
- case DataType::U8:
- {
- assert(output()->zero_point() >= std::numeric_limits<uint8_t>::min());
- assert(output()->zero_point() <= std::numeric_limits<uint8_t>::max());
- const auto pad_value = static_cast<uint8_t>(output()->zero_point());
- tflite::reference_ops::Pad(params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- &pad_value, getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- }
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Pad.h b/compiler/luci-interpreter/src/kernels/Pad.h
deleted file mode 100644
index e05b47f29..000000000
--- a/compiler/luci-interpreter/src/kernels/Pad.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_PAD_H
-#define LUCI_INTERPRETER_KERNELS_PAD_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Pad : public Kernel
-{
-public:
- Pad(const Tensor *input, const Tensor *paddings, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *paddings() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_PAD_H
diff --git a/compiler/luci-interpreter/src/kernels/Pad.test.cpp b/compiler/luci-interpreter/src/kernels/Pad.test.cpp
deleted file mode 100644
index 4bee07629..000000000
--- a/compiler/luci-interpreter/src/kernels/Pad.test.cpp
+++ /dev/null
@@ -1,75 +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 "kernels/Pad.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-float GetTolerance(float min, float max) { return (max - min) / 255.0; }
-
-TEST(Pad, Uint8)
-{
- float kQuantizedTolerance = GetTolerance(-1.0, 1.0);
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
- std::vector<float> input_data{-0.8, 0.2, 0.9, 0.7, 0.1, -0.3};
- std::vector<int32_t> paddings_data{0, 0, 0, 2, 1, 3, 0, 0};
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 3, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor paddings_tensor = makeInputTensor<DataType::S32>({4, 2}, paddings_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Pad kernel(&input_tensor, &paddings_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0, -0.8, 0.2, 0.9, 0, 0, 0, 0, 0.7, 0.1, -0.3, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 4, 7, 1}));
-}
-
-TEST(Pad, Float)
-{
- std::vector<float> input_data{1, 2, 3, 4, 5, 6};
- std::vector<int32_t> paddings_data{1, 0, 0, 2, 0, 3, 0, 0};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1, 2, 3, 1}, input_data);
- Tensor paddings_tensor = makeInputTensor<DataType::S32>({4, 2}, paddings_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pad kernel(&input_tensor, &paddings_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5,
- 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- std::initializer_list<int32_t> ref_output_shape{2, 4, 6, 1};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Pow.cpp b/compiler/luci-interpreter/src/kernels/Pow.cpp
deleted file mode 100644
index afc10b80e..000000000
--- a/compiler/luci-interpreter/src/kernels/Pow.cpp
+++ /dev/null
@@ -1,78 +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 "kernels/Pow.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Pow::Pow(const Tensor *input1, const Tensor *input2, Tensor *output)
- : Kernel({input1, input2}, {output})
-{
-}
-
-void Pow::configure()
-{
- LUCI_INTERPRETER_CHECK(input1()->element_type() == input2()->element_type());
-
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Pow::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- eval<float>();
- break;
- case DataType::S32:
- eval<int32_t>();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-template <typename T> void Pow::eval() const
-{
- tflite::ArithmeticParams params{};
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastPow4DSlow(getTensorShape(input1()), getTensorData<T>(input1()),
- getTensorShape(input2()), getTensorData<T>(input2()),
- getTensorShape(output()), getTensorData<T>(output()));
- }
- else
- {
- tflite::reference_ops::Pow(getTensorShape(input1()), getTensorData<T>(input1()),
- getTensorShape(input2()), getTensorData<T>(input2()),
- getTensorShape(output()), getTensorData<T>(output()));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Pow.h b/compiler/luci-interpreter/src/kernels/Pow.h
deleted file mode 100644
index 8ff865e40..000000000
--- a/compiler/luci-interpreter/src/kernels/Pow.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_POW_H
-#define LUCI_INTERPRETER_KERNELS_POW_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Pow : public Kernel
-{
-public:
- Pow(const Tensor *input1, const Tensor *input2, Tensor *output);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> void eval() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_POW_H
diff --git a/compiler/luci-interpreter/src/kernels/Pow.test.cpp b/compiler/luci-interpreter/src/kernels/Pow.test.cpp
deleted file mode 100644
index 69d8946c8..000000000
--- a/compiler/luci-interpreter/src/kernels/Pow.test.cpp
+++ /dev/null
@@ -1,101 +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 "kernels/Pow.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(PowTest, SimplePow)
-{
- std::initializer_list<int32_t> base_shape = {1, 1, 3, 2};
-
- std::vector<float> input1_data{0.3f, 2.3f, 0.9f, 0.5f, 0.8f, 1.1f};
- std::vector<float> input2_data{0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- std::vector<float> test_outputs{0.786f, 1.2838f, 1.043f, 0.7071f, 0.8f, 1.08956f};
-
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pow kernel(&input1_tensor, &input2_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(base_shape));
-}
-
-TEST(PowTest, FloatBroadcastPow)
-{
- std::initializer_list<int32_t> input1_shape = {1, 3};
- std::initializer_list<int32_t> input2_shape = {3, 1};
-
- std::vector<float> input1_data{0.3f, 2.3f, 0.9f};
- std::vector<float> input2_data{0.2f, 0.3f, 0.4f};
- std::vector<float> test_outputs{0.786f, 1.18126f, 0.9791f, 0.6968f, 1.28386f,
- 0.96888f, 0.6178f, 1.3953f, 0.9587f};
-
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(input1_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(input2_shape, input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pow kernel(&input1_tensor, &input2_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs, 0.0001f));
-}
-
-TEST(PowTest, IntPow)
-{
- std::initializer_list<int32_t> base_shape = {1, 3};
-
- std::vector<int32_t> input_data{2, 3, 4};
- std::vector<int32_t> test_outputs{4, 27, 256};
-
- Tensor input1_tensor = makeInputTensor<DataType::S32>(base_shape, input_data);
- Tensor input2_tensor = makeInputTensor<DataType::S32>(base_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::S32);
-
- Pow kernel(&input1_tensor, &input2_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<int32_t>(output_tensor), ::testing::ElementsAreArray(test_outputs));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(base_shape));
-}
-
-TEST(PowTest, Input_Output_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.0f});
- Tensor input2_tensor = makeInputTensor<DataType::S32>({1}, {4});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Pow kernel(&input1_tensor, &input2_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Prelu.cpp b/compiler/luci-interpreter/src/kernels/Prelu.cpp
deleted file mode 100644
index e658d87b5..000000000
--- a/compiler/luci-interpreter/src/kernels/Prelu.cpp
+++ /dev/null
@@ -1,153 +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 "kernels/Prelu.h"
-
-#include "kernels/BinaryOpCommon.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Prelu::Prelu(const Tensor *input, const Tensor *alpha, Tensor *output)
- : Kernel({input, alpha}, {output})
-{
-}
-
-void Prelu::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- LUCI_INTERPRETER_CHECK(alpha()->element_type() == output()->element_type());
-
- if (input()->element_type() == DataType::U8 || input()->element_type() == DataType::S16)
- {
- if (input()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && alpha()->zero_point() == 0 &&
- output()->zero_point() == 0);
- }
- double alpha_multiplier = input()->scale() * alpha()->scale() / output()->scale();
- quantizeMultiplier(alpha_multiplier, &_output_multiplier_alpha, &_output_shift_alpha);
- double identity_multiplier = input()->scale() / output()->scale();
- quantizeMultiplier(identity_multiplier, &_output_multiplier_identity, &_output_shift_identity);
- }
- output()->resize(calculateShapeForBroadcast(input()->shape(), alpha()->shape()));
-}
-
-void Prelu::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalQuantizedS16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Prelu::evalFloat() const
-{
- const auto input_data = getTensorData<float>(input());
- const auto alpha_data = getTensorData<float>(alpha());
- const auto size = getTensorShape(input()).FlatSize();
- auto output_data = getTensorData<float>(output());
-
- auto PreluFunc = [](float input, float alpha) { return input >= 0.0 ? input : input * alpha; };
-
- if (input()->shape() != alpha()->shape())
- {
- tflite::reference_ops::BroadcastBinaryFunction4DSlow<float, float, float>(
- getTensorShape(input()), getTensorData<float>(input()), getTensorShape(alpha()),
- getTensorData<float>(alpha()), getTensorShape(output()), getTensorData<float>(output()),
- PreluFunc);
- }
- else
- {
- for (auto i = decltype(size){0}; i < size; ++i)
- {
- if (input_data[i] >= 0)
- output_data[i] = input_data[i];
- else
- output_data[i] = input_data[i] * alpha_data[i];
- }
- }
-}
-
-void Prelu::evalQuantized() const
-{
- tflite::PreluParams op_params{};
-
- op_params.input_offset = -input()->zero_point(); // Note the '-'.
- op_params.alpha_offset = -alpha()->zero_point(); // Note the '-'.
- op_params.output_offset = output()->zero_point();
- op_params.output_shift_1 = _output_shift_identity;
- op_params.output_multiplier_1 = _output_multiplier_identity;
- op_params.output_shift_2 = _output_shift_alpha;
- op_params.output_multiplier_2 = _output_multiplier_alpha;
-
- if (input()->shape() != alpha()->shape())
- {
- tflite::reference_ops::BroadcastPrelu4DSlow(
- op_params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(alpha()), getTensorData<uint8_t>(alpha()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- }
- else
- {
- tflite::reference_ops::Prelu<uint8_t>(op_params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(alpha()),
- getTensorData<uint8_t>(alpha()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- }
-}
-
-void Prelu::evalQuantizedS16() const
-{
- constexpr int32_t quantized_min = std::numeric_limits<int16_t>::min();
- constexpr int32_t quantized_max = std::numeric_limits<int16_t>::max();
-
- auto fn = [this, quantized_min, quantized_max](int16_t input_val, int16_t alpha_val) {
- const int32_t output_val =
- input_val >= 0
- ? tflite::MultiplyByQuantizedMultiplier(input_val, _output_multiplier_identity,
- _output_shift_identity)
- : tflite::MultiplyByQuantizedMultiplier(input_val * alpha_val, _output_multiplier_alpha,
- _output_shift_alpha);
- const int32_t clamped_output = std::min(quantized_max, std::max(quantized_min, output_val));
- return static_cast<int16_t>(clamped_output);
- };
-
- BinaryOpBroadcastSlow(getTensorShape(input()), getTensorData<int16_t>(input()),
- getTensorShape(alpha()), getTensorData<int16_t>(alpha()),
- getTensorShape(output()), getTensorData<int16_t>(output()), fn);
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Prelu.h b/compiler/luci-interpreter/src/kernels/Prelu.h
deleted file mode 100644
index c7911a63f..000000000
--- a/compiler/luci-interpreter/src/kernels/Prelu.h
+++ /dev/null
@@ -1,54 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_PRELU_H
-#define LUCI_INTERPRETER_KERNELS_PRELU_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Prelu : public Kernel
-{
-public:
- Prelu(const Tensor *input, const Tensor *alpha, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *alpha() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalQuantizedS16() const;
-
-private:
- int32_t _output_multiplier_alpha = 0;
- int32_t _output_shift_alpha = 0;
- int32_t _output_multiplier_identity = 0;
- int32_t _output_shift_identity = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_PRELU_H
diff --git a/compiler/luci-interpreter/src/kernels/Prelu.test.cpp b/compiler/luci-interpreter/src/kernels/Prelu.test.cpp
deleted file mode 100644
index 30702c826..000000000
--- a/compiler/luci-interpreter/src/kernels/Prelu.test.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Prelu.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> alpha_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<T> input_data,
- std::initializer_list<T> alpha_data, std::initializer_list<T> output_data)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor alpha_tensor = makeInputTensor<element_type>(alpha_shape, alpha_data);
- Tensor output_tensor = makeOutputTensor(element_type);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
-
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<T>(output_tensor), ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(PreluTest, FloatSimple)
-{
- Check<float>(/*input_shape=*/{2, 3}, /*alpha_shape=*/{2, 3},
- /*output_shape=*/{2, 3},
- /*input_data=*/
- {
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -1.0f, -2.0f, // Row 2
- },
- /*alpha_data=*/
- {
- 0.0f, 0.5f, 0.1f, // Row 1
- 0.0f, 0.5f, 0.1f, // Row 2
- },
- /*output_data=*/
- {
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -0.5f, -0.2f, // Row 2
- });
-
- SUCCEED();
-}
-
-TEST(PreluTest, FloatBroadcast)
-{
- Check<float>(/*input_shape=*/{1, 2, 2, 3}, /*alpha_shape=*/{1, 1, 3},
- /*output_shape=*/{1, 2, 2, 3},
- /*input_data=*/
- {
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 1.0f, 1.0f, 1.0f, // Row 1, Column 2
- -1.0f, -1.0f, -1.0f, // Row 2, Column 1
- -2.0f, -2.0f, -2.0f, // Row 2, Column 2
- },
- /*alpha_data=*/
- {0.0f, 1.0f, 2.0f},
- /*output_data=*/
- {
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 1.0f, 1.0f, 1.0f, // Row 1, Column 2
- 0.0f, -1.0f, -2.0f, // Row 2, Column 1
- 0.0f, -2.0f, -4.0f, // Row 2, Column 2
- });
-
- SUCCEED();
-}
-
-float GetTolerance(float min, float max) { return (max - min) / 255.0; }
-
-TEST(PreluTest, Uint8Simple)
-{
- std::vector<float> input_data{-0.8f, 0.2f, 0.9f, 0.7f, 0.1f, -0.4f};
- std::vector<float> alpha_data{0.5f, 0.5f, 0.5f, 0.25f, 1.0f, 0.25f};
- std::vector<float> ref_output_data{-0.4f, 0.2f, 0.9f, 0.7f, 0.1f, -0.1f};
-
- float kQuantizedTolerance = GetTolerance(-1.0, 1.0);
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 3, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor alpha_tensor = makeInputTensor<DataType::U8>({1, 2, 3, 1}, quant_param.first,
- quant_param.second, alpha_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 3, 1}));
-
- SUCCEED();
-}
-
-TEST(PreluTest, Uint8Broadcast)
-{
- std::vector<float> input_data{
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 0.5f, 0.5f, 0.5f, // Row 1, Column 2
- -1.0f, -1.0f, -1.0f, // Row 2, Column 1
- -0.25f, -0.25f, -0.25f, // Row 2, Column 2
- };
- std::vector<float> alpha_data{0.0f, 0.5f, -0.5f};
- std::vector<float> ref_output_data{
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 0.5f, 0.5f, 0.5f, // Row 1, Column 2
- 0.0f, -0.5f, 0.5f, // Row 2, Column 1
- 0.0f, -0.125f, 0.125f // Row 2, Column 2
- };
- std::vector<float> ref_quant_output_data{
- 128, 128, 128, // Row 1, Column 1
- 192, 192, 192, // Row 1, Column 2
- 128, 64, 192, // Row 2, Column 1
- 128, 112, 144 // Row 2, Column 2
- };
- float kQuantizedTolerance = 2 * (1. / 256);
- const float kMin = -1;
- const float kMax = 127.f / 128.f;
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(kMin, kMax);
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 2, 3}, quant_param.first,
- quant_param.second, input_data);
- Tensor alpha_tensor =
- makeInputTensor<DataType::U8>({1, 1, 3}, quant_param.first, quant_param.second, alpha_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(ref_output_data, kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 2, 3}));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray(ref_quant_output_data));
-}
-
-TEST(PreluTest, SInt16Simple)
-{
- std::vector<float> input_data{-0.8f, 0.2f, 0.9f, 0.7f, 0.1f, -0.4f};
- std::vector<float> alpha_data{0.5f, 0.5f, 0.5f, 0.25f, 1.0f, 0.25f};
- std::vector<float> ref_output_data{-0.4f, 0.2f, 0.9f, 0.7f, 0.1f, -0.1f};
-
- Tensor input_tensor = makeInputTensor<DataType::S16>({1, 2, 3, 1}, 0.1, 0, input_data);
- Tensor alpha_tensor = makeInputTensor<DataType::S16>({1, 2, 3, 1}, 0.1, 0, alpha_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.1, 0);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 3, 1}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(PreluTest, SInt16Broadcast)
-{
- std::vector<float> input_data{
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 0.5f, 0.5f, 0.5f, // Row 1, Column 2
- -1.0f, -1.0f, -1.0f, // Row 2, Column 1
- -0.25f, -0.25f, -0.25f, // Row 2, Column 2
- };
- std::vector<float> alpha_data{0.0f, 0.5f, -0.5f};
- std::vector<float> ref_output_data{
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 0.5f, 0.5f, 0.5f, // Row 1, Column 2
- 0.0f, -0.5f, 0.5f, // Row 2, Column 1
- 0.0f, -0.125f, 0.125f // Row 2, Column 2
- };
-
- Tensor input_tensor = makeInputTensor<DataType::S16>({1, 2, 2, 3}, 0.01, 0, input_data);
- Tensor alpha_tensor = makeInputTensor<DataType::S16>({1, 1, 3}, 0.1, 0, alpha_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.001, 0);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 2, 3}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(PreluTest, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor alpha_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(PreluTest, Input_Alpha_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor alpha_tensor = makeInputTensor<DataType::U8>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(PreluTest, Invalid_Input_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor alpha_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- Prelu kernel(&input_tensor, &alpha_tensor, &output_tensor);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Relu.cpp b/compiler/luci-interpreter/src/kernels/Relu.cpp
deleted file mode 100644
index a2e02d708..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu.cpp
+++ /dev/null
@@ -1,114 +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 "kernels/Relu.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Relu::Relu(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Relu::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- if (input()->element_type() == DataType::S16)
- {
- LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && output()->zero_point() == 0);
- }
-
- if (input()->element_type() == DataType::U8 || input()->element_type() == DataType::S16)
- {
- double multiplier = input()->scale() / output()->scale();
- quantizeMultiplier(multiplier, &_output_multiplier, &_output_shift);
- }
- output()->resize(input()->shape());
-}
-
-void Relu::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- case DataType::S16:
- evalQuantizedS16();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Relu::evalFloat() const
-{
- const auto input_data = getTensorData<float>(input());
- const auto input_shape = getTensorShape(input());
- auto output_data = getTensorData<float>(output());
- auto output_shape = getTensorShape(output());
-
- tflite::optimized_ops::Relu(input_shape, input_data, output_shape, output_data);
-}
-
-void Relu::evalQuantized() const
-{
- tflite::ReluParams params;
- params.input_offset = input()->zero_point();
- params.output_offset = output()->zero_point();
- params.output_multiplier = _output_multiplier;
- params.output_shift = _output_shift;
-
- params.quantized_activation_min =
- std::max(static_cast<int32_t>(std::numeric_limits<uint8_t>::min()), params.output_offset);
- params.quantized_activation_max = static_cast<int32_t>(std::numeric_limits<uint8_t>::max());
-
- tflite::optimized_ops::ReluX(params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
-}
-
-void Relu::evalQuantizedS16() const
-{
- const auto *input_data = getTensorData<int16_t>(input());
- auto *output_data = getTensorData<int16_t>(output());
-
- constexpr int32_t output_min = 0;
- constexpr int32_t output_max = std::numeric_limits<int16_t>::max();
-
- const int32_t num_elements = input()->shape().num_elements();
-
- for (int32_t i = 0; i < num_elements; ++i)
- {
- const int32_t input_val = input_data[i];
- int32_t output_val =
- tflite::MultiplyByQuantizedMultiplier(input_val, _output_multiplier, _output_shift);
- output_val = std::max(output_val, output_min);
- output_val = std::min(output_val, output_max);
- output_data[i] = static_cast<int16_t>(output_val);
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Relu.h b/compiler/luci-interpreter/src/kernels/Relu.h
deleted file mode 100644
index b813f0cdf..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu.h
+++ /dev/null
@@ -1,51 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RELU_H
-#define LUCI_INTERPRETER_KERNELS_RELU_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Relu : public Kernel
-{
-public:
- Relu(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void evalQuantizedS16() const;
-
-private:
- int32_t _output_multiplier{0};
- int32_t _output_shift{0};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RELU_H
diff --git a/compiler/luci-interpreter/src/kernels/Relu.test.cpp b/compiler/luci-interpreter/src/kernels/Relu.test.cpp
deleted file mode 100644
index cabefa733..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu.test.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Relu.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(ReluTest, FloatSimple)
-{
- std::vector<float> input_data{
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -1.0f, -2.0f, // Row 2
- };
-
- std::vector<float> ref_output_data{
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, 0.0f, 0.0f, // Row 2
- };
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Relu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(ReluTest, Uint8Quantized)
-{
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 7, 1, //
- };
- // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
- const float f_min = (-128.0 / 128.0) * 8;
- const float f_max = (127.0 / 128.0) * 8;
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(f_min, f_max);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Relu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({128, 128, 160, 192, 176, 128, 240, 144}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({0, 0, 2, 4, 3, 0, 7, 1}));
-}
-
-TEST(ReluTest, Uint8Requantized)
-{
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 7, 1, //
- };
-
- // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
- const float in_min = (-128.0 / 128.0) * 8;
- const float in_max = (127.0 / 128.0) * 8;
- const float out_min = (0.0 / 256.0) * 8;
- const float out_max = (255.0 / 256.0) * 8;
-
- std::pair<float, int32_t> quant_input = quantizationParams<uint8_t>(in_min, in_max);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_input.first,
- quant_input.second, input_data);
-
- std::pair<float, int32_t> quant_output = quantizationParams<uint8_t>(out_min, out_max);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_output.first, quant_output.second);
-
- Relu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({0, 0, 64, 128, 96, 0, 224, 32}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear({0, 0, 2, 4, 3, 0, 7, 1}));
-}
-
-TEST(ReluTest, SInt16)
-{
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 7, 1, //
- };
- std::vector<float> ref_output_data{
- 0, 0, 2, 4, //
- 3, 0, 7, 1, //
- };
-
- Tensor input_tensor = makeInputTensor<DataType::S16>({1, 2, 4, 1}, 0.5, 0, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::S16, 0.25, 0);
-
- Relu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(ReluTest, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Relu kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ReluTest, Invalid_Input_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- Relu kernel(&input_tensor, &output_tensor);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Relu6.cpp b/compiler/luci-interpreter/src/kernels/Relu6.cpp
deleted file mode 100644
index 1046ef27b..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu6.cpp
+++ /dev/null
@@ -1,88 +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 "kernels/Relu6.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Relu6::Relu6(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Relu6::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
-
- if (input()->element_type() == DataType::U8)
- {
- double multiplier = input()->scale() / output()->scale();
- quantizeMultiplier(multiplier, &_output_multiplier, &_output_shift);
- }
- output()->resize(input()->shape());
-}
-
-void Relu6::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Relu6::evalFloat() const
-{
- const auto input_data = getTensorData<float>(input());
- const auto input_shape = getTensorShape(input());
- auto output_data = getTensorData<float>(output());
- auto output_shape = getTensorShape(output());
-
- tflite::optimized_ops::Relu6(input_shape, input_data, output_shape, output_data);
-}
-
-void Relu6::evalQuantized() const
-{
- tflite::ReluParams params;
- params.input_offset = input()->zero_point();
- params.output_offset = output()->zero_point();
- params.output_multiplier = _output_multiplier;
- params.output_shift = _output_shift;
-
- params.quantized_activation_min =
- std::max(static_cast<int32_t>(std::numeric_limits<uint8_t>::min()), params.output_offset);
- params.quantized_activation_max =
- std::min(static_cast<int32_t>(std::numeric_limits<uint8_t>::max()),
- params.output_offset + static_cast<int32>(roundf(6.f / output()->scale())));
-
- tflite::optimized_ops::ReluX(params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Relu6.h b/compiler/luci-interpreter/src/kernels/Relu6.h
deleted file mode 100644
index f5030b588..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu6.h
+++ /dev/null
@@ -1,50 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RELU6_H
-#define LUCI_INTERPRETER_KERNELS_RELU6_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Relu6 : public Kernel
-{
-public:
- Relu6(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- int32_t _output_multiplier{0};
- int32_t _output_shift{0};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RELU6_H
diff --git a/compiler/luci-interpreter/src/kernels/Relu6.test.cpp b/compiler/luci-interpreter/src/kernels/Relu6.test.cpp
deleted file mode 100644
index a7f104d85..000000000
--- a/compiler/luci-interpreter/src/kernels/Relu6.test.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Relu6.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(Relu6Test, FloatSimple)
-{
- std::vector<float> input_data{
- 0.0f, 1.0f, 3.0f, // Row 1
- 7.0f, -1.0f, -2.0f, // Row 2
- };
-
- std::vector<float> ref_output_data{
- 0.0f, 1.0f, 3.0f, // Row 1
- 6.0f, 0.0f, 0.0f, // Row 2
- };
-
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 3}, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Relu6 kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor),
- ::testing::ElementsAreArray(ref_output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 3}));
-}
-
-TEST(Relu6Test, Uint8Quantized)
-{
- // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
- const float f_min = (-128.0 / 128.0) * 10;
- const float f_max = (127.0 / 128.0) * 10;
- const float tolerance = (f_max - f_min) / 255.0;
-
- std::vector<float> input_data{
- 0, -6, 2, 8, //
- -2, 3, 7, 1, //
- };
-
- std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(f_min, f_max);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_param.first,
- quant_param.second, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
-
- Relu6 kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({128, 128, 154, 205, 128, 166, 205, 141}));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear({0, 0, 2, 6, 0, 3, 6, 1}, tolerance));
-}
-
-TEST(Relu6Test, Uint8Requantized)
-{
- // Choose min / max in such a way that there are exactly 256 units to avoid rounding errors.
- const float in_min = (-128.0 / 128.0) * 10;
- const float in_max = (127.0 / 128.0) * 10;
- const float out_min = (0.0 / 256.0) * 0;
- const float out_max = (255.0 / 256.0) * 6;
- const float tolerance = (in_max - in_min) / 255.0;
-
- std::vector<float> input_data{
- 0, -6, 2, 8, //
- -2, 3, 7, 1, //
- };
-
- std::pair<float, int32_t> quant_input = quantizationParams<uint8_t>(in_min, in_max);
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 4, 1}, quant_input.first,
- quant_input.second, input_data);
-
- std::pair<float, int32_t> quant_output = quantizationParams<uint8_t>(out_min, out_max);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_output.first, quant_output.second);
-
- Relu6 kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({1, 2, 4, 1}));
- EXPECT_THAT(extractTensorData<uint8_t>(output_tensor),
- ::testing::ElementsAreArray({0, 0, 87, 255, 0, 127, 255, 43}));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear({0, 0, 2, 6, 0, 3, 6, 1}, tolerance));
-}
-
-TEST(Relu6Test, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::U8);
-
- Relu6 kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(Relu6Test, Invalid_Input_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- Relu6 kernel(&input_tensor, &output_tensor);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Reshape.cpp b/compiler/luci-interpreter/src/kernels/Reshape.cpp
deleted file mode 100644
index d88b5392a..000000000
--- a/compiler/luci-interpreter/src/kernels/Reshape.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Reshape.h"
-
-#include <cassert>
-#include <cstring>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-static Shape extractShapeFromTensor(const Tensor *tensor)
-{
- assert(tensor->element_type() == DataType::S32);
- Shape shape(tensor->shape().num_elements());
- const auto *shape_data = tensor->data<int32_t>();
- for (int i = 0; i < tensor->shape().num_elements(); ++i)
- {
- shape.dim(i) = shape_data[i];
- }
- return shape;
-}
-
-static void resolveUnknownDimension(const Shape &input_shape, Shape *output_shape)
-{
- const int32_t num_input_elements = input_shape.num_elements();
- int32_t num_output_elements = 1;
- int unknown_dim_index = -1;
- for (int i = 0; i < output_shape->num_dims(); ++i)
- {
- const int32_t value = output_shape->dim(i);
- if (value == -1)
- {
- assert(unknown_dim_index == -1);
- unknown_dim_index = i;
- }
- else
- {
- num_output_elements *= value;
- }
- }
- if (unknown_dim_index != -1)
- {
- output_shape->dim(unknown_dim_index) = num_input_elements / num_output_elements;
- num_output_elements *= output_shape->dim(unknown_dim_index);
- }
- assert(num_output_elements == num_input_elements);
-}
-
-Reshape::Reshape(const Tensor *input, const Tensor *shape, Tensor *output)
- : Kernel({input, shape}, {output})
-{
-}
-
-void Reshape::configure()
-{
- Shape output_shape = extractShapeFromTensor(shape());
- resolveUnknownDimension(input()->shape(), &output_shape);
- output()->resize(output_shape);
-}
-
-void Reshape::execute() const
-{
- const auto *input_data = input()->data<void>();
- auto *output_data = output()->data<void>();
-
- const size_t element_size = getDataTypeSize(input()->element_type());
- const int32_t num_elements = input()->shape().num_elements();
- std::memcpy(output_data, input_data, num_elements * element_size);
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Reshape.h b/compiler/luci-interpreter/src/kernels/Reshape.h
deleted file mode 100644
index 99b947f77..000000000
--- a/compiler/luci-interpreter/src/kernels/Reshape.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RESHAPE_H
-#define LUCI_INTERPRETER_KERNELS_RESHAPE_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Reshape : public Kernel
-{
-public:
- Reshape(const Tensor *input, const Tensor *shape, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *shape() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RESHAPE_H
diff --git a/compiler/luci-interpreter/src/kernels/Reshape.test.cpp b/compiler/luci-interpreter/src/kernels/Reshape.test.cpp
deleted file mode 100644
index 38159380f..000000000
--- a/compiler/luci-interpreter/src/kernels/Reshape.test.cpp
+++ /dev/null
@@ -1,67 +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 "kernels/Reshape.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-// TODO Test types other than FLOAT32.
-
-TEST(ReshapeTest, Regular)
-{
- Shape input_shape{1, 2, 2, 3};
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- Shape shape_shape{2};
- std::vector<int32_t> shape_data{3, 4};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor shape_tensor = makeInputTensor<DataType::S32>(shape_shape, shape_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Reshape kernel(&input_tensor, &shape_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(input_data));
-}
-
-TEST(ReshapeTest, UnknownDimension)
-{
- Shape input_shape{2, 1, 2, 3};
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- Shape shape_shape{3};
- std::vector<int32_t> shape_data{2, -1, 2};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor shape_tensor = makeInputTensor<DataType::S32>(shape_shape, shape_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Reshape kernel(&input_tensor, &shape_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(input_data));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ResizeBilinear.cpp b/compiler/luci-interpreter/src/kernels/ResizeBilinear.cpp
deleted file mode 100644
index 9385855cf..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeBilinear.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/ResizeBilinear.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-ResizeBilinear::ResizeBilinear(const Tensor *input, const Tensor *size, Tensor *output,
- const ResizeBilinearParams &params)
- : KernelWithParams<ResizeBilinearParams>({input, size}, {output}, params)
-{
-}
-
-void ResizeBilinear::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4);
- LUCI_INTERPRETER_CHECK(size()->shape().num_dims() == 1);
- LUCI_INTERPRETER_CHECK(size()->element_type() == DataType::S32);
- if (params().half_pixel_centers && params().align_corners)
- throw std::runtime_error("If half_pixel_centers is True, align_corners must be False.");
- LUCI_INTERPRETER_CHECK(size()->shape().dim(0) == 2);
- Shape output_shape(4);
- output_shape.dim(0) = input()->shape().dim(0);
- output_shape.dim(1) = getTensorData<int32_t>(size())[0];
- output_shape.dim(2) = getTensorData<int32_t>(size())[1];
- output_shape.dim(3) = input()->shape().dim(3);
- output()->resize(output_shape);
-}
-
-void ResizeBilinear::execute() const
-{
- tflite::ResizeBilinearParams op_params{};
- op_params.align_corners = params().align_corners;
- op_params.half_pixel_centers = params().half_pixel_centers;
- switch (output()->element_type())
- {
- case DataType::FLOAT32:
- tflite::optimized_ops::ResizeBilinear(
- op_params, getTensorShape(input()), getTensorData<float>(input()), getTensorShape(size()),
- getTensorData<int32_t>(size()), getTensorShape(output()), getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::optimized_ops::ResizeBilinear(
- op_params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(size()), getTensorData<int32_t>(size()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ResizeBilinear.h b/compiler/luci-interpreter/src/kernels/ResizeBilinear.h
deleted file mode 100644
index b7bdc2ab7..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeBilinear.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RESIZEBILINEAR_H
-#define LUCI_INTERPRETER_KERNELS_RESIZEBILINEAR_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class ResizeBilinear : public KernelWithParams<ResizeBilinearParams>
-{
-public:
- ResizeBilinear(const Tensor *input, const Tensor *shape, Tensor *output,
- const ResizeBilinearParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *size() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RESIZEBILINEAR_H
diff --git a/compiler/luci-interpreter/src/kernels/ResizeBilinear.test.cpp b/compiler/luci-interpreter/src/kernels/ResizeBilinear.test.cpp
deleted file mode 100644
index 51c1359da..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeBilinear.test.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/ResizeBilinear.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> size_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<float> input_data,
- std::initializer_list<int32_t> size_data, std::initializer_list<float> output_data,
- bool align_corners, bool half_pixel_centers)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor size_tensor = makeInputTensor<DataType::S32>(size_shape, size_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeBilinearParams params{};
- params.align_corners = align_corners;
- params.half_pixel_centers = half_pixel_centers;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(extractTensorData<T>(output_tensor), FloatArrayNear(output_data));
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> size_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<int32_t> size_data,
- std::initializer_list<float> output_data, bool align_corners,
- bool half_pixel_centers)
-{
- // On TFlite example use Uint8 value it self, so this means quant param scale 1.0f and zero
- // point 0.
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, 1.0, 0, input_data);
- Tensor size_tensor = makeInputTensor<DataType::S32>(size_shape, size_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1.0, 0);
-
- ResizeBilinearParams params{};
- params.align_corners = align_corners;
- params.half_pixel_centers = half_pixel_centers;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, output_tensor.scale()));
-}
-
-template <typename T> class ResizeBilinearTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(ResizeBilinearTest, DataTypes);
-
-TYPED_TEST(ResizeBilinearTest, SimpleTest)
-{
- Check<TypeParam>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- },
- {3, 3},
- {
- 3, 5, 6, //
- 7, 9, 10, //
- 9, 11, 12, //
- 4, 8, 10, //
- 8, 12, 14, //
- 10, 14, 16, //
- },
- false, false);
- SUCCEED();
-}
-
-TEST(ResizeBilinearTest, HalfPixelCenterFloatTest)
-{
- Check<float>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 1, 2, //
- 3, 4, //
- 1, 2, //
- 3, 4 //
- },
- {3, 3},
- {
- 1, 1.5, 2, //
- 2, 2.5, 3, //
- 3, 3.5, 4, //
- 1, 1.5, 2, //
- 2, 2.5, 3, //
- 3, 3.5, 4, //
- },
- false, true);
- SUCCEED();
-}
-
-TEST(ResizeBilinearTest, HalfPixelCenterUint8Test)
-{
- Check<uint8_t>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 12, 16 //
- },
- {3, 3},
- {
- 2, 4, 6, //
- 6, 7, 9, //
- 9, 10, 12, //
- 4, 7, 10, //
- 8, 10, 13, //
- 12, 14, 16, //
- },
- false, true);
- SUCCEED();
-}
-
-TEST(ResizeBilinearTest, InputShapeInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({2}, {3, 3});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeBilinearParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ResizeBilinearTest, SizeShapeInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2, 1}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({2, 1}, {3, 3});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeBilinearParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ResizeBilinearTest, SizeDimInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2, 1}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({3}, {3, 3, 1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeBilinearParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ResizeBilinearTest, InvalidParams_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2, 1}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({2}, {3, 3});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeBilinearParams params{};
- params.align_corners = true;
- params.half_pixel_centers = true;
-
- ResizeBilinear kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.cpp b/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.cpp
deleted file mode 100644
index e4ad8f742..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/ResizeNearestNeighbor.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-ResizeNearestNeighbor::ResizeNearestNeighbor(const Tensor *input, const Tensor *size,
- Tensor *output,
- const ResizeNearestNeighborParams &params)
- : KernelWithParams<ResizeNearestNeighborParams>({input, size}, {output}, params)
-{
-}
-
-void ResizeNearestNeighbor::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() == 4);
- LUCI_INTERPRETER_CHECK(size()->shape().num_dims() == 1);
- LUCI_INTERPRETER_CHECK(size()->element_type() == DataType::S32);
- LUCI_INTERPRETER_CHECK(size()->shape().dim(0) == 2);
- Shape output_shape(4);
- output_shape.dim(0) = input()->shape().dim(0);
- output_shape.dim(1) = getTensorData<int32_t>(size())[0];
- output_shape.dim(2) = getTensorData<int32_t>(size())[1];
- output_shape.dim(3) = input()->shape().dim(3);
- output()->resize(output_shape);
-}
-
-void ResizeNearestNeighbor::execute() const
-{
- tflite::ResizeNearestNeighborParams op_params{};
- op_params.align_corners = params().align_corners;
- op_params.half_pixel_centers = params().half_pixel_centers;
- switch (output()->element_type())
- {
- case DataType::FLOAT32:
- tflite::reference_ops::ResizeNearestNeighbor(
- op_params, getTensorShape(input()), getTensorData<int32_t>(input()),
- getTensorShape(size()), getTensorData<int32_t>(size()), getTensorShape(output()),
- getTensorData<int32_t>(output()));
- break;
- case DataType::U8:
- tflite::optimized_ops::ResizeNearestNeighbor(
- op_params, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(size()), getTensorData<int32_t>(size()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.h b/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.h
deleted file mode 100644
index 137d031cf..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RESIZENEARESTNEIGHBOR_H
-#define LUCI_INTERPRETER_KERNELS_RESIZENEARESTNEIGHBOR_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class ResizeNearestNeighbor : public KernelWithParams<ResizeNearestNeighborParams>
-{
-public:
- ResizeNearestNeighbor(const Tensor *input, const Tensor *shape, Tensor *output,
- const ResizeNearestNeighborParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *size() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RESIZENEARESTNEIGHBOR_H
diff --git a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.test.cpp b/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.test.cpp
deleted file mode 100644
index 9a804cca7..000000000
--- a/compiler/luci-interpreter/src/kernels/ResizeNearestNeighbor.test.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/ResizeNearestNeighbor.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> size_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<float> input_data,
- std::initializer_list<int32_t> size_data, std::initializer_list<float> output_data,
- bool align_corners, bool half_pixel_centers)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor size_tensor = makeInputTensor<DataType::S32>(size_shape, size_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = align_corners;
- params.half_pixel_centers = half_pixel_centers;
-
- ResizeNearestNeighbor kernel(&input_tensor, &size_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(extractTensorData<T>(output_tensor), FloatArrayNear(output_data));
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> size_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<int32_t> size_data,
- std::initializer_list<float> output_data, bool align_corners,
- bool half_pixel_centers)
-{
- std::pair<float, int32_t> quant_param =
- quantizationParams<uint8_t>(std::min(input_data) < 0 ? std::min(input_data) : 0.f,
- std::max(input_data) > 0 ? std::max(input_data) : 0.f);
- Tensor input_tensor =
- makeInputTensor<DataType::U8>(input_shape, quant_param.first, quant_param.second, input_data);
- Tensor size_tensor = makeInputTensor<DataType::S32>(size_shape, size_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.first);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = align_corners;
- params.half_pixel_centers = half_pixel_centers;
-
- ResizeNearestNeighbor kernel(&input_tensor, &size_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, output_tensor.scale()));
-}
-
-template <typename T> class ResizeNearestNeighborTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(ResizeNearestNeighborTest, DataTypes);
-
-TYPED_TEST(ResizeNearestNeighborTest, SimpleTest)
-{
- Check<TypeParam>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- },
- {3, 3},
- {
- 3, 3, 6, //
- 3, 3, 6, //
- 9, 9, 12, //
- 4, 4, 10, //
- 4, 4, 10, //
- 10, 10, 16, //
- },
- false, false);
-}
-
-TYPED_TEST(ResizeNearestNeighborTest, AlignCenterTest)
-{
- Check<TypeParam>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- },
- {3, 3},
- {
- 3, 6, 6, //
- 9, 12, 12, //
- 9, 12, 12, //
- 4, 10, 10, //
- 10, 16, 16, //
- 10, 16, 16, //
- },
- true, false);
-}
-
-TYPED_TEST(ResizeNearestNeighborTest, HalfPixelCenterTest)
-{
- Check<TypeParam>({2, 2, 2, 1}, {2}, {2, 3, 3, 1},
- {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- },
- {3, 3},
- {
- 3, 6, 6, //
- 9, 12, 12, //
- 9, 12, 12, //
- 4, 10, 10, //
- 10, 16, 16, //
- 10, 16, 16, //
- },
- false, true);
-}
-
-TEST(ResizeNearestNeighborTest, InputShapeInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({2}, {3, 3});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeNearestNeighbor kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ResizeNearestNeighborTest, SizeShapeInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2, 1}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({2, 1}, {3, 3});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeNearestNeighbor kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(ResizeNearestNeighborTest, SizeDimInvalid_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({2, 2, 2, 1}, {
- 3, 6, //
- 9, 12, //
- 4, 10, //
- 10, 16 //
- });
- Tensor size_tensor = makeInputTensor<DataType::S32>({3}, {3, 3, 1});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = false;
- params.half_pixel_centers = false;
-
- ResizeNearestNeighbor kernel(&input_tensor, &size_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Reverse.cpp b/compiler/luci-interpreter/src/kernels/Reverse.cpp
deleted file mode 100644
index a46308412..000000000
--- a/compiler/luci-interpreter/src/kernels/Reverse.cpp
+++ /dev/null
@@ -1,81 +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 "kernels/Reverse.h"
-#include "kernels/Utils.h"
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Reverse::Reverse(const Tensor *input, const Tensor *axes, Tensor *output)
- : Kernel({input, axes}, {output})
-{
-}
-
-void Reverse::configure()
-{
- assert(axes()->shape().num_dims() == 1);
- assert(input()->shape().num_dims() >= axes()->shape().num_elements());
- if (input()->element_type() != DataType::S32 && input()->element_type() != DataType::FLOAT32 &&
- input()->element_type() != DataType::U8 && input()->element_type() != DataType::S16 &&
- input()->element_type() != DataType::S64)
- {
- throw std::runtime_error("Unsupported input type.");
- }
- if (axes()->element_type() != DataType::S32)
- {
- throw std::runtime_error("Unsupported axes type.");
- }
- if (axes()->shape().num_elements() > 1)
- {
- throw std::runtime_error("Current implementation does not support more than 1 axis.");
- }
- int axis_value = getTensorData<int32_t>(axes())[0];
- if (axis_value < 0 || axis_value >= input()->shape().num_dims())
- {
- throw std::runtime_error("Invalid axes value");
- }
- assert(input()->element_type() == output()->element_type());
-
- output()->resize(input()->shape());
-}
-
-void Reverse::execute() const
-{
- int axis_value = getTensorData<int32_t>(axes())[0];
- switch (output()->element_type())
- {
- case DataType::FLOAT32:
- tflite::reference_ops::Reverse<float>(axis_value, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::reference_ops::Reverse<uint8_t>(
- axis_value, getTensorShape(input()), getTensorData<uint8_t>(input()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported output type");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Reverse.h b/compiler/luci-interpreter/src/kernels/Reverse.h
deleted file mode 100644
index 3489dae28..000000000
--- a/compiler/luci-interpreter/src/kernels/Reverse.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_REVERSE_H
-#define LUCI_INTERPRETER_KERNELS_REVERSE_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Reverse : public Kernel
-{
-public:
- Reverse(const Tensor *input, const Tensor *axes, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *axes() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_REVERSE_H
diff --git a/compiler/luci-interpreter/src/kernels/Reverse.test.cpp b/compiler/luci-interpreter/src/kernels/Reverse.test.cpp
deleted file mode 100644
index 5475a8bd3..000000000
--- a/compiler/luci-interpreter/src/kernels/Reverse.test.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Reverse.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T> class ReverseTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(ReverseTest, DataTypes);
-
-TYPED_TEST(ReverseTest, MultiDimensions)
-{
- // TypeParam
- std::vector<TypeParam> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
- Shape input_shape{4, 3, 2};
- std::vector<int32_t> axis_data{1};
- Shape axis_shape{1};
-
- std::vector<TypeParam> output_data{5, 6, 3, 4, 1, 2, 11, 12, 9, 10, 7, 8,
- 17, 18, 15, 16, 13, 14, 23, 24, 21, 22, 19, 20};
- std::vector<int32_t> output_shape{4, 3, 2};
-
- Tensor input_tensor = makeInputTensor<getElementType<TypeParam>()>(input_shape, input_data);
- Tensor axis_tensor = makeInputTensor<DataType::S32>(axis_shape, axis_data);
-
- Tensor output_tensor = makeOutputTensor(getElementType<TypeParam>());
-
- Reverse kernel = Reverse(&input_tensor, &axis_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<TypeParam>(output_tensor),
- ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Rsqrt.cpp b/compiler/luci-interpreter/src/kernels/Rsqrt.cpp
deleted file mode 100644
index 6dd92dc98..000000000
--- a/compiler/luci-interpreter/src/kernels/Rsqrt.cpp
+++ /dev/null
@@ -1,66 +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 "kernels/Rsqrt.h"
-#include "kernels/Utils.h"
-
-#include <stdexcept>
-#include <cmath>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Rsqrt::Rsqrt(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Rsqrt::configure()
-{
- if (input()->element_type() != output()->element_type())
- {
- throw std::runtime_error("Input/output tensor data type mismatch.");
- }
- output()->resize(input()->shape());
-}
-
-void Rsqrt::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
-
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Rsqrt::evalFloat() const
-{
- auto in = getTensorData<float>(input());
- auto out = getTensorData<float>(output());
- auto size = getTensorShape(input()).FlatSize();
- for (auto i = in; i != in + size; ++i)
- {
- *out = 1.f / std::sqrt(*i);
- ++out;
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Rsqrt.h b/compiler/luci-interpreter/src/kernels/Rsqrt.h
deleted file mode 100644
index adc5bcfa2..000000000
--- a/compiler/luci-interpreter/src/kernels/Rsqrt.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_RSQRT_H
-#define LUCI_INTERPRETER_KERNELS_RSQRT_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Rsqrt : public Kernel
-{
-public:
- Rsqrt(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_RSQRT_H
diff --git a/compiler/luci-interpreter/src/kernels/Rsqrt.test.cpp b/compiler/luci-interpreter/src/kernels/Rsqrt.test.cpp
deleted file mode 100644
index d33b800be..000000000
--- a/compiler/luci-interpreter/src/kernels/Rsqrt.test.cpp
+++ /dev/null
@@ -1,80 +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 "kernels/Rsqrt.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Rsqrt kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(RsqrtTest, SimpleRsqrt)
-{
- Check(
- /*input_shape=*/{1, 2, 4, 1}, /*output_shape=*/{1, 2, 4, 1},
- /*input_data=*/
- {
- 5, 4, 8, 2, //
- 6, 7.5, 9, 0.3, //
- },
- /*output_data=*/
- {
- 0.44721360, 0.5, 0.35355339, 0.70710678, //
- 0.40824829, 0.36514837, 0.33333333, 1.8257419, //
- });
-}
-
-TEST(RsqrtTest, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::S32);
-
- Rsqrt kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(RsqrtTest, Invalid_Input_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- Rsqrt kernel(&input_tensor, &output_tensor);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Slice.cpp b/compiler/luci-interpreter/src/kernels/Slice.cpp
deleted file mode 100644
index c4bc3c57c..000000000
--- a/compiler/luci-interpreter/src/kernels/Slice.cpp
+++ /dev/null
@@ -1,149 +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 "kernels/Slice.h"
-#include "Utils.h"
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <cassert>
-#include <cstring>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-const int max_dim = 4;
-
-Slice::Slice(const Tensor *input, const Tensor *begin, const Tensor *size, Tensor *output)
- : Kernel({input, begin, size}, {output})
-{
-}
-
-template <typename T>
-Shape calculateOutputShape(const Tensor *input, const Tensor *begin, const Tensor *size)
-{
- Shape output_shape = Shape(input->shape().num_dims());
- for (int idx = 0; idx < input->shape().num_dims(); idx++)
- {
- T size_value = getTensorData<T>(size)[idx];
- if (size_value < 0)
- {
- if (size_value != -1)
- {
- throw std::runtime_error("Invalid size.");
- }
- size_value = input->shape().dim(idx) - getTensorData<T>(begin)[idx];
- }
- else
- {
- if (input->shape().dim(idx) < getTensorData<T>(begin)[idx] + size_value)
- {
- throw std::runtime_error("Invalid begin and size.");
- }
- }
- output_shape.dim(idx) = static_cast<int>(size_value);
- }
- return output_shape;
-}
-
-template <typename T>
-void getBeginAndSizeVectors(int dimensions, const Tensor *begin, const Tensor *size,
- std::vector<int> *begins, std::vector<int> *sizes)
-{
- for (int idx = dimensions - 1; idx >= 0; --idx)
- {
- begins->push_back(getTensorData<T>(begin)[idx]);
- sizes->push_back(getTensorData<T>(size)[idx]);
- }
-}
-
-void Slice::configure()
-{
- assert(input()->element_type() == output()->element_type());
- assert(begin()->element_type() == DataType::S32 || begin()->element_type() == DataType::S64);
- assert(size()->element_type() == DataType::S32 || size()->element_type() == DataType::S64);
- assert(begin()->shape().num_dims() == 1);
- assert(size()->shape().num_dims() == 1);
- assert(input()->shape().num_dims() <= max_dim);
-
- if (begin()->element_type() == DataType::S32)
- {
- output()->resize(calculateOutputShape<int32_t>(input(), begin(), size()));
- }
- else if (begin()->element_type() == DataType::S64)
- {
- output()->resize(calculateOutputShape<int64_t>(input(), begin(), size()));
- }
- else
- {
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Slice::execute() const
-{
- std::vector<int> begins;
- begins.reserve(max_dim);
- std::vector<int> sizes;
- sizes.reserve(max_dim);
- if (begin()->element_type() == DataType::S32)
- {
- getBeginAndSizeVectors<int32_t>(input()->shape().num_dims(), begin(), size(), &begins, &sizes);
- }
- else if (begin()->element_type() == DataType::S64)
- {
- getBeginAndSizeVectors<int64_t>(input()->shape().num_dims(), begin(), size(), &begins, &sizes);
- }
- else
- {
- throw std::runtime_error("Unsupported begin type.");
- }
- for (int i = input()->shape().num_dims(); i < max_dim; ++i)
- {
- begins.push_back(0);
- sizes.push_back(1);
- }
-
- assert(begins.size() == 4);
- assert(sizes.size() == 4);
- tflite::SliceParams op_params{};
- op_params.begin_count = 4;
- op_params.size_count = 4;
- for (int i = 0; i < 4; i++)
- {
- op_params.begin[i] = begins[3 - i];
- op_params.size[i] = sizes[3 - i];
- }
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::optimized_ops::Slice(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::optimized_ops::Slice(op_params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported input type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Slice.h b/compiler/luci-interpreter/src/kernels/Slice.h
deleted file mode 100644
index 23c359608..000000000
--- a/compiler/luci-interpreter/src/kernels/Slice.h
+++ /dev/null
@@ -1,44 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SLICE_H
-#define LUCI_INTERPRETER_KERNELS_SLICE_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Slice : public Kernel
-{
-public:
- Slice(const Tensor *input, const Tensor *begin, const Tensor *size, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *begin() const { return _inputs[1]; }
- const Tensor *size() const { return _inputs[2]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SLICE_H
diff --git a/compiler/luci-interpreter/src/kernels/Slice.test.cpp b/compiler/luci-interpreter/src/kernels/Slice.test.cpp
deleted file mode 100644
index a360a29cc..000000000
--- a/compiler/luci-interpreter/src/kernels/Slice.test.cpp
+++ /dev/null
@@ -1,64 +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 "kernels/Slice.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T> class SliceTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(SliceTest, DataTypes);
-
-TYPED_TEST(SliceTest, SimpleTest)
-{
- std::vector<TypeParam> input_data{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
- Shape input_shape{3, 2, 3, 1};
- std::vector<int32_t> begin_data{1, 0, 0, 0};
- Shape begin_shape{4};
- std::vector<int32_t> size_data{2, 1, -1, 1};
- Shape size_shape{4};
- std::vector<TypeParam> output_data{3, 3, 3, 5, 5, 5};
- std::vector<int32_t> output_shape{2, 1, 3, 1};
-
- Tensor input_tensor = makeInputTensor<getElementType<TypeParam>()>(input_shape, input_data);
- Tensor begin_tensor = makeInputTensor<DataType::S32>(begin_shape, begin_data);
- Tensor size_tensor = makeInputTensor<DataType::S32>(size_shape, size_data);
-
- Tensor output_tensor = makeOutputTensor(getElementType<TypeParam>());
-
- Slice kernel(&input_tensor, &begin_tensor, &size_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<TypeParam>(output_tensor),
- ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Softmax.cpp b/compiler/luci-interpreter/src/kernels/Softmax.cpp
deleted file mode 100644
index 642c0ad75..000000000
--- a/compiler/luci-interpreter/src/kernels/Softmax.cpp
+++ /dev/null
@@ -1,90 +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 "kernels/Softmax.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/softmax.h>
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Softmax::Softmax(const Tensor *input, Tensor *output, const SoftmaxParams &params)
- : KernelWithParams<SoftmaxParams>({input}, {output}, params)
-{
-}
-
-void Softmax::configure()
-{
- LUCI_INTERPRETER_CHECK(input()->element_type() == output()->element_type());
- LUCI_INTERPRETER_CHECK(input()->shape().num_dims() >= 1);
- if (input()->element_type() == DataType::U8 || input()->element_type() == DataType::S8)
- {
- LUCI_INTERPRETER_CHECK(output()->zero_point() == 0);
- tflite::SoftmaxParams op_params{};
- op_params.table = _table;
- tflite::optimized_ops::PopulateSoftmaxLookupTable(&op_params, input()->scale(), params().beta);
- }
- output()->resize(input()->shape());
-}
-
-void Softmax::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::S8:
- evalQuantized<int8_t>();
- break;
- case DataType::U8:
- evalQuantized<uint8_t>();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Softmax::evalFloat() const
-{
- tflite::SoftmaxParams op_params{};
- op_params.beta = params().beta;
-
- tflite::reference_ops::Softmax(op_params, getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-template <typename T> void Softmax::evalQuantized() const
-{
- tflite::SoftmaxParams op_params{};
- op_params.table = const_cast<float *>(_table);
- op_params.zero_point = output()->zero_point();
- op_params.scale = output()->scale();
-
- tflite::optimized_ops::Softmax(op_params, getTensorShape(input()), getTensorData<T>(input()),
- getTensorShape(output()), getTensorData<T>(output()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Softmax.h b/compiler/luci-interpreter/src/kernels/Softmax.h
deleted file mode 100644
index 1f281df1c..000000000
--- a/compiler/luci-interpreter/src/kernels/Softmax.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SOFTMAX_H
-#define LUCI_INTERPRETER_KERNELS_SOFTMAX_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Softmax : public KernelWithParams<SoftmaxParams>
-{
-public:
- Softmax(const Tensor *input, Tensor *output, const SoftmaxParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- template <typename T> void evalQuantized() const;
-
- float _table[256];
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SOFTMAX_H
diff --git a/compiler/luci-interpreter/src/kernels/Softmax.test.cpp b/compiler/luci-interpreter/src/kernels/Softmax.test.cpp
deleted file mode 100644
index d3d8209a5..000000000
--- a/compiler/luci-interpreter/src/kernels/Softmax.test.cpp
+++ /dev/null
@@ -1,102 +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 "kernels/Softmax.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- SoftmaxParams params{};
- params.beta = 0.1;
-
- Softmax kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<T>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), output_shape);
-}
-
-template <>
-void Check<uint8_t>(std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data,
- std::initializer_list<float> output_data)
-{
- std::pair<float, int32_t> input_quant_param =
- quantizationParams<uint8_t>(std::min<float>(std::min<float>(input_data), 0.f),
- std::max<float>(std::max<float>(input_data), 0.f));
- std::pair<float, int32_t> output_quant_param =
- quantizationParams<uint8_t>(std::min<float>(std::min<float>(output_data), 0.f),
- std::max<float>(std::max<float>(output_data), 0.f));
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor output_tensor =
- makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
-
- SoftmaxParams params{};
- params.beta = 0.1;
-
- Softmax kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data, output_tensor.scale()));
-}
-
-template <typename T> class SoftmaxTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(SoftmaxTest, DataTypes);
-
-TYPED_TEST(SoftmaxTest, Simple)
-{
- Check<TypeParam>({2, 1, 2, 3}, {2, 1, 2, 3},
- {
- 5, -9, 8, //
- -7, 2, -4, //
- 1, -2, 9, //
- 3, -6, -1, //
- },
- {
- 0.38514, 0.09497, 0.51989, //
- 0.20792, 0.51141, 0.28067, //
- 0.25212, 0.18678, 0.56110, //
- 0.48149, 0.19576, 0.32275, //
- });
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/SpaceToDepth.cpp b/compiler/luci-interpreter/src/kernels/SpaceToDepth.cpp
deleted file mode 100644
index 6a5bd7cf8..000000000
--- a/compiler/luci-interpreter/src/kernels/SpaceToDepth.cpp
+++ /dev/null
@@ -1,79 +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 "SpaceToDepth.h"
-#include "Utils.h"
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-SpaceToDepth::SpaceToDepth(const Tensor *input, Tensor *output, const SpaceToDepthParams &params)
- : KernelWithParams<SpaceToDepthParams>({input}, {output}, params)
-{
-}
-
-void SpaceToDepth::configure()
-{
- assert(input()->shape().num_dims() == 4);
- assert(output()->element_type() == DataType::FLOAT32 ||
- output()->element_type() == DataType::U8 || output()->element_type() == DataType::S8 ||
- output()->element_type() == DataType::S32 || output()->element_type() == DataType::S64);
- assert(input()->element_type() == output()->element_type());
-
- const int block_size = params().block_size;
- const int32_t input_height = input()->shape().dim(1);
- const int32_t input_width = input()->shape().dim(2);
- int32_t output_height = input_height / block_size;
- int32_t output_width = input_width / block_size;
-
- assert(input_height == output_height * block_size);
- assert(input_width == output_width * block_size);
-
- Shape output_shape(4);
- output_shape.dim(0) = input()->shape().dim(0);
- output_shape.dim(1) = output_height;
- output_shape.dim(2) = output_width;
- output_shape.dim(3) = input()->shape().dim(3) * block_size * block_size;
-
- output()->resize(output_shape);
-}
-
-void SpaceToDepth::execute() const
-{
- tflite::SpaceToDepthParams op_params{};
- op_params.block_size = params().block_size;
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::optimized_ops::SpaceToDepth(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::optimized_ops::SpaceToDepth(op_params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/SpaceToDepth.h b/compiler/luci-interpreter/src/kernels/SpaceToDepth.h
deleted file mode 100644
index e66316b11..000000000
--- a/compiler/luci-interpreter/src/kernels/SpaceToDepth.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SPACETODEPTH_H
-#define LUCI_INTERPRETER_KERNELS_SPACETODEPTH_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-#include <vector>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class SpaceToDepth : public KernelWithParams<SpaceToDepthParams>
-{
-public:
- SpaceToDepth(const Tensor *input, Tensor *output, const SpaceToDepthParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SPACETODEPTH_H
diff --git a/compiler/luci-interpreter/src/kernels/SpaceToDepth.test.cpp b/compiler/luci-interpreter/src/kernels/SpaceToDepth.test.cpp
deleted file mode 100644
index 77b6655dc..000000000
--- a/compiler/luci-interpreter/src/kernels/SpaceToDepth.test.cpp
+++ /dev/null
@@ -1,60 +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 "kernels/SpaceToDepth.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T> class SpaceToDepthTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(SpaceToDepthTest, DataTypes);
-
-TYPED_TEST(SpaceToDepthTest, SimpleCase)
-{
- constexpr DataType element_type = getElementType<TypeParam>();
- std::vector<TypeParam> input_data{1, 5, 6, 7, 2, 3, 4, 8};
- Shape input_shape{1, 2, 2, 2};
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- std::vector<TypeParam> output_data{1, 5, 6, 7, 2, 3, 4, 8};
- std::vector<int32_t> output_shape{1, 1, 1, 8};
- Tensor output_tensor = makeOutputTensor(element_type);
-
- SpaceToDepthParams params{};
- params.block_size = 2;
-
- SpaceToDepth kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<TypeParam>(output_tensor),
- ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Split.cpp b/compiler/luci-interpreter/src/kernels/Split.cpp
deleted file mode 100644
index 325b1c22f..000000000
--- a/compiler/luci-interpreter/src/kernels/Split.cpp
+++ /dev/null
@@ -1,81 +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 "Split.h"
-
-#include "Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/optimized_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Split::Split(const Tensor *axis, const Tensor *input, std::vector<Tensor *> outputs)
- : Kernel({axis, input}, std::move(outputs))
-{
-}
-
-void Split::configure()
-{
- assert(axis()->shape().num_elements() == 1);
- _axis_value = getTensorData<int32_t>(axis())[0];
- if (_axis_value < 0)
- _axis_value += input()->shape().num_dims();
- assert(_axis_value >= 0 && _axis_value < input()->shape().num_dims());
-
- const int32_t input_size = input()->shape().dim(_axis_value);
- assert(input_size % _outputs.size() == 0);
- const int32_t slice_size = input_size / _outputs.size();
-
- Shape output_shape = input()->shape();
- output_shape.dim(_axis_value) = slice_size;
- for (Tensor *output : _outputs)
- {
- output->resize(output_shape);
- }
-}
-
-void Split::execute() const
-{
- tflite::SplitParams params{};
- params.num_split = _outputs.size();
- params.axis = _axis_value;
-
-#define TF_LITE_SPLIT(scalar) \
- { \
- VectorOfTensors<scalar, false> all_outputs(_outputs); \
- tflite::optimized_ops::Split(params, getTensorShape(input()), getTensorData<scalar>(input()), \
- all_outputs.shapes(), all_outputs.data()); \
- }
-
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- TF_LITE_SPLIT(float);
- break;
- case DataType::U8:
- TF_LITE_SPLIT(uint8_t);
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-#undef TF_LITE_SPLIT
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Split.h b/compiler/luci-interpreter/src/kernels/Split.h
deleted file mode 100644
index 9542b1e56..000000000
--- a/compiler/luci-interpreter/src/kernels/Split.h
+++ /dev/null
@@ -1,47 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SPLIT_H
-#define LUCI_INTERPRETER_KERNELS_SPLIT_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Split : public Kernel
-{
-public:
- Split(const Tensor *axis, const Tensor *input, std::vector<Tensor *> outputs);
-
- const Tensor *axis() const { return _inputs[0]; }
- const Tensor *input() const { return _inputs[1]; }
- Tensor *output(int index) const { return _outputs[index]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- int32_t _axis_value{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SPLIT_H
diff --git a/compiler/luci-interpreter/src/kernels/Split.test.cpp b/compiler/luci-interpreter/src/kernels/Split.test.cpp
deleted file mode 100644
index 2147d15c1..000000000
--- a/compiler/luci-interpreter/src/kernels/Split.test.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 "kernels/Split.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(int axis, int num_splits, std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<T> input_data,
- std::vector<std::vector<T>> output_data)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor axis_tensor = makeInputTensor<DataType::S32>({}, {axis});
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
-
- std::vector<Tensor> output_tensors;
- output_tensors.reserve(num_splits);
- for (int i = 0; i < num_splits; ++i)
- {
- output_tensors.emplace_back(makeOutputTensor(element_type));
- }
-
- std::vector<Tensor *> output_tensor_ptrs(num_splits);
- for (int i = 0; i < num_splits; ++i)
- {
- output_tensor_ptrs[i] = &output_tensors[i];
- }
-
- Split kernel(&axis_tensor, &input_tensor, std::move(output_tensor_ptrs));
- kernel.configure();
- kernel.execute();
-
- for (int i = 0; i < num_splits; ++i)
- {
- EXPECT_THAT(extractTensorData<T>(output_tensors[i]),
- ::testing::ElementsAreArray(output_data[i]));
- }
-}
-
-template <typename T> class SplitTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(SplitTest, DataTypes);
-
-TYPED_TEST(SplitTest, FourDimensional)
-{
- Check<TypeParam>(/*axis=*/0, /*num_splits=*/2, {2, 2, 2, 2}, {1, 2, 2, 2},
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
- {
- {1, 2, 3, 4, 5, 6, 7, 8}, //
- {9, 10, 11, 12, 13, 14, 15, 16}, //
- });
- Check<TypeParam>(
- /*axis=*/1, /*num_splits=*/2, {2, 2, 2, 2}, {2, 1, 2, 2},
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, {
- {1, 2, 3, 4, 9, 10, 11, 12}, //
- {5, 6, 7, 8, 13, 14, 15, 16}, //
- });
- Check<TypeParam>(
- /*axis=*/2, /*num_splits=*/2, {2, 2, 2, 2}, {2, 2, 1, 2},
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, {
- {1, 2, 5, 6, 9, 10, 13, 14}, //
- {3, 4, 7, 8, 11, 12, 15, 16}, //
- });
- Check<TypeParam>(
- /*axis=*/3, /*num_splits=*/2, {2, 2, 2, 2}, {2, 2, 2, 1},
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, {
- {1, 3, 5, 7, 9, 11, 13, 15}, //
- {2, 4, 6, 8, 10, 12, 14, 16}, //
- });
-}
-
-TYPED_TEST(SplitTest, OneDimensional)
-{
- Check<TypeParam>(
- /*axis=*/0, /*num_splits=*/8, {8}, {1}, {1, 2, 3, 4, 5, 6, 7, 8},
- {{1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}});
-}
-
-TYPED_TEST(SplitTest, NegativeAxis)
-{
- Check<TypeParam>(
- /*axis=*/-4, /*num_splits=*/2, {2, 2, 2, 2}, {1, 2, 2, 2},
- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, {
- {1, 2, 3, 4, 5, 6, 7, 8}, //
- {9, 10, 11, 12, 13, 14, 15, 16},
- });
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Sqrt.cpp b/compiler/luci-interpreter/src/kernels/Sqrt.cpp
deleted file mode 100644
index 46e9fc9ad..000000000
--- a/compiler/luci-interpreter/src/kernels/Sqrt.cpp
+++ /dev/null
@@ -1,66 +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 "kernels/Sqrt.h"
-#include "kernels/Utils.h"
-
-#include <stdexcept>
-#include <cmath>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Sqrt::Sqrt(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Sqrt::configure()
-{
- if (input()->element_type() != output()->element_type())
- {
- throw std::runtime_error("Input/output tensor data type mismatch.");
- }
- output()->resize(input()->shape());
-}
-
-void Sqrt::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
-
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Sqrt::evalFloat() const
-{
- auto in = getTensorData<float>(input());
- auto out = getTensorData<float>(output());
- auto size = getTensorShape(input()).FlatSize();
- for (auto i = in; i != in + size; ++i)
- {
- *out = std::sqrt(*i);
- ++out;
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Sqrt.h b/compiler/luci-interpreter/src/kernels/Sqrt.h
deleted file mode 100644
index 4034655ed..000000000
--- a/compiler/luci-interpreter/src/kernels/Sqrt.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SQRT_H
-#define LUCI_INTERPRETER_KERNELS_SQRT_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Sqrt : public Kernel
-{
-public:
- Sqrt(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SQRT_H
diff --git a/compiler/luci-interpreter/src/kernels/Sqrt.test.cpp b/compiler/luci-interpreter/src/kernels/Sqrt.test.cpp
deleted file mode 100644
index 504db4493..000000000
--- a/compiler/luci-interpreter/src/kernels/Sqrt.test.cpp
+++ /dev/null
@@ -1,80 +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 "kernels/Sqrt.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<float> input_data, std::initializer_list<float> output_data)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Sqrt kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(SqrtTest, SimpleSqrt)
-{
- Check(
- /*input_shape=*/{1, 2, 4, 1}, /*output_shape=*/{1, 2, 4, 1},
- /*input_data=*/
- {
- 0, 8, 2, 4, //
- 3, 7, 10, 0.3, //
- },
- /*output_data=*/
- {
- 0.0, 2.8284271, 1.4142136, 2, //
- 1.7320508, 2.6457513, 3.1622777, 0.54772256, //
- });
-}
-
-TEST(SqrtTest, Input_Output_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor output_tensor = makeOutputTensor(DataType::S32);
-
- Sqrt kernel(&input_tensor, &output_tensor);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(AddTest, Invalid_Input_Type_NEG)
-{
- Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- Sqrt kernel(&input_tensor, &output_tensor);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Squeeze.cpp b/compiler/luci-interpreter/src/kernels/Squeeze.cpp
deleted file mode 100644
index ce43ef789..000000000
--- a/compiler/luci-interpreter/src/kernels/Squeeze.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 "kernels/Squeeze.h"
-
-#include "kernels/Utils.h"
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Squeeze::Squeeze(const Tensor *input, Tensor *output, const SqueezeParams &params)
- : KernelWithParams<SqueezeParams>({input}, {output}, params)
-{
-}
-
-void Squeeze::configure()
-{
- int input_num_dims = input()->shape().num_dims();
- int num_squeeze_dims = params().squeeze_dims.size();
- assert(input_num_dims <= 8);
- bool should_squeeze[8] = {false};
- int num_squeezed_dims = 0;
- if (num_squeeze_dims == 0)
- {
- for (int idx = 0; idx < input_num_dims; ++idx)
- {
- if (input()->shape().dim(idx) == 1)
- {
- should_squeeze[idx] = true;
- ++num_squeezed_dims;
- }
- }
- }
- else
- {
- for (int idx = 0; idx < num_squeeze_dims; ++idx)
- {
- int current = params().squeeze_dims[idx] < 0 ? params().squeeze_dims[idx] + input_num_dims
- : params().squeeze_dims[idx];
- assert(current >= 0 && current < input_num_dims && input()->shape().dim(current) == 1);
- if (!should_squeeze[current])
- ++num_squeezed_dims;
- should_squeeze[current] = true;
- }
- }
- Shape output_shape(input_num_dims - num_squeezed_dims);
- for (int in_idx = 0, out_idx = 0; in_idx < input_num_dims; ++in_idx)
- {
- if (!should_squeeze[in_idx])
- {
- output_shape.dim(out_idx++) = input()->shape().dim(in_idx);
- }
- }
- output()->resize(output_shape);
-}
-
-void Squeeze::execute() const
-{
- assert(input()->shape().num_elements() == output()->shape().num_elements());
-
- const auto *input_data = input()->data<void>();
- auto *output_data = output()->data<void>();
- std::memcpy(output_data, input_data,
- getDataTypeSize(input()->element_type()) * input()->shape().num_elements());
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Squeeze.h b/compiler/luci-interpreter/src/kernels/Squeeze.h
deleted file mode 100644
index 687af5158..000000000
--- a/compiler/luci-interpreter/src/kernels/Squeeze.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 LUCI_INTERPRETER_KERNELS_SQUEEZE_H
-#define LUCI_INTERPRETER_KERNELS_SQUEEZE_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Squeeze : public KernelWithParams<SqueezeParams>
-{
-public:
- Squeeze(const Tensor *input, Tensor *output, const SqueezeParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SQUEEZE_H
diff --git a/compiler/luci-interpreter/src/kernels/Squeeze.test.cpp b/compiler/luci-interpreter/src/kernels/Squeeze.test.cpp
deleted file mode 100644
index ff9fb09d2..000000000
--- a/compiler/luci-interpreter/src/kernels/Squeeze.test.cpp
+++ /dev/null
@@ -1,69 +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 "kernels/Squeeze.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<T> input_data, std::initializer_list<T> output_data,
- std::initializer_list<int32_t> squeeze_dims)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(element_type);
-
- SqueezeParams params{};
- params.squeeze_dims = squeeze_dims;
-
- Squeeze kernel(&input_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<T>(output_tensor), ::testing::ElementsAreArray(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-template <typename T> class SqueezeTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(SqueezeTest, DataTypes);
-
-TYPED_TEST(SqueezeTest, TotalTest)
-{
- Check<TypeParam>(
- /*input_shape=*/{1, 24, 1}, /*output_shape=*/{24},
- /*input_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24},
- /*output_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24},
- {-1, 0});
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/StridedSlice.cpp b/compiler/luci-interpreter/src/kernels/StridedSlice.cpp
deleted file mode 100644
index 679485439..000000000
--- a/compiler/luci-interpreter/src/kernels/StridedSlice.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/StridedSlice.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-StridedSlice::StridedSlice(const Tensor *input, const Tensor *begin, const Tensor *end,
- const Tensor *strides, Tensor *output, const StridedSliceParams &params)
- : KernelWithParams<StridedSliceParams>({input, begin, end, strides}, {output}, params)
-{
-}
-
-void StridedSlice::configure()
-{
- assert(begin()->shape().num_dims() == 1);
- assert(end()->shape().num_dims() == 1);
- assert(strides()->shape().num_dims() == 1);
- assert(input()->element_type() == output()->element_type());
- assert(begin()->element_type() == DataType::S32);
- assert(end()->element_type() == DataType::S32);
- assert(strides()->element_type() == DataType::S32);
- assert(input()->shape().num_dims() <= 4);
- if (params().ellipsis_mask != 0)
- {
- throw std::runtime_error("ellipsis_mask is not implemented yet.");
- }
- if (params().new_axis_mask != 0)
- {
- throw std::runtime_error("new_axis_mask is not implemented yet.");
- }
- if (input()->element_type() == DataType::U8)
- {
- assert(input()->scale() == output()->scale());
- assert(input()->zero_point() == output()->zero_point());
- }
- tflite::StridedSliceParams op_params{};
- op_params.start_indices_count = input()->shape().num_dims();
- op_params.stop_indices_count = input()->shape().num_dims();
- op_params.strides_count = input()->shape().num_dims();
-
- for (int i = 0; i < input()->shape().num_dims(); i++)
- {
- op_params.start_indices[i] = getTensorData<int32_t>(begin())[i];
- op_params.stop_indices[i] = getTensorData<int32_t>(end())[i];
- op_params.strides[i] = getTensorData<int32_t>(strides())[i];
- }
- op_params.begin_mask = params().begin_mask;
- op_params.ellipsis_mask = 0;
- op_params.end_mask = params().end_mask;
- op_params.new_axis_mask = 0;
- op_params.shrink_axis_mask = params().shrink_axis_mask;
- std::vector<int32_t> output_shape_vector;
- for (int i = 0; i < input()->shape().num_dims(); i++)
- {
- int idx = input()->shape().num_dims() - i - 1;
- int32_t stride = getTensorData<int32_t>(strides())[idx];
- assert(stride != 0);
- int32_t begin = ::tflite::strided_slice::StartForAxis(op_params, getTensorShape(input()), idx);
- int32_t end =
- ::tflite::strided_slice::StopForAxis(op_params, getTensorShape(input()), idx, begin);
-
- const bool shrink_axis = params().shrink_axis_mask & (1 << idx);
- if (shrink_axis)
- {
- end = begin + 1;
- }
-
- int32_t dim_shape = std::ceil((end - begin) / static_cast<float>(stride));
- dim_shape = dim_shape < 0 ? 0 : dim_shape;
- if (!shrink_axis)
- {
- output_shape_vector.push_back(dim_shape);
- }
- }
- Shape output_shape = Shape(output_shape_vector.size());
- for (size_t i = 0; i < output_shape_vector.size(); i++)
- {
- output_shape.dim(i) = output_shape_vector[output_shape_vector.size() - i - 1];
- }
- output()->resize(output_shape);
-}
-
-void StridedSlice::execute() const
-{
- tflite::StridedSliceParams op_params{};
- op_params.start_indices_count = input()->shape().num_dims();
- op_params.stop_indices_count = input()->shape().num_dims();
- op_params.strides_count = input()->shape().num_dims();
-
- for (int i = 0; i < input()->shape().num_dims(); i++)
- {
- op_params.start_indices[i] = getTensorData<int32_t>(begin())[i];
- op_params.stop_indices[i] = getTensorData<int32_t>(end())[i];
- op_params.strides[i] = getTensorData<int32_t>(strides())[i];
- }
- op_params.begin_mask = params().begin_mask;
- op_params.ellipsis_mask = 0;
- op_params.end_mask = params().end_mask;
- op_params.new_axis_mask = 0;
- op_params.shrink_axis_mask = params().shrink_axis_mask;
-
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::reference_ops::StridedSlice(op_params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::reference_ops::StridedSlice(op_params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/StridedSlice.h b/compiler/luci-interpreter/src/kernels/StridedSlice.h
deleted file mode 100644
index fc96893a7..000000000
--- a/compiler/luci-interpreter/src/kernels/StridedSlice.h
+++ /dev/null
@@ -1,47 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_STRIDEDSLICE_H
-#define LUCI_INTERPRETER_KERNELS_STRIDEDSLICE_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class StridedSlice : public KernelWithParams<StridedSliceParams>
-{
-public:
- StridedSlice(const Tensor *input, const Tensor *begin, const Tensor *end, const Tensor *strides,
- Tensor *output, const StridedSliceParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *begin() const { return _inputs[1]; }
- const Tensor *end() const { return _inputs[2]; }
- const Tensor *strides() const { return _inputs[3]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_STRIDEDSLICE_H
diff --git a/compiler/luci-interpreter/src/kernels/StridedSlice.test.cpp b/compiler/luci-interpreter/src/kernels/StridedSlice.test.cpp
deleted file mode 100644
index 66dffcaf2..000000000
--- a/compiler/luci-interpreter/src/kernels/StridedSlice.test.cpp
+++ /dev/null
@@ -1,99 +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 "kernels/StridedSlice.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(StridedSliceTest, Float)
-{
- Shape input_shape{2, 3, 2};
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- Shape begin_shape{3};
- std::vector<int32_t> begin_data{0, 0, 0};
- Shape end_shape{3};
- std::vector<int32_t> end_data{1, 3, 2};
- Shape strides_shape{3};
- std::vector<int32_t> strides_data{1, 1, 1};
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor begin_tensor = makeInputTensor<DataType::S32>(begin_shape, begin_data);
- Tensor end_tensor = makeInputTensor<DataType::S32>(end_shape, end_data);
- Tensor strides_tensor = makeInputTensor<DataType::S32>(strides_shape, strides_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- StridedSliceParams params{};
- params.begin_mask = 0;
- params.end_mask = 0;
- params.ellipsis_mask = 0;
- params.new_axis_mask = 0;
- params.shrink_axis_mask = 1;
-
- StridedSlice kernel(&input_tensor, &begin_tensor, &end_tensor, &strides_tensor, &output_tensor,
- params);
- kernel.configure();
- kernel.execute();
-
- std::vector<int32_t> output_shape{3, 2};
- std::vector<float> output_data{1, 2, 3, 4, 5, 6};
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-TEST(StridedSliceTest, Uint8)
-{
- Shape input_shape{2, 3, 2};
- std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
- Shape begin_shape{3};
- std::vector<int32_t> begin_data{0, 0, 0};
- Shape end_shape{3};
- std::vector<int32_t> end_data{1, 3, 2};
- Shape strides_shape{3};
- std::vector<int32_t> strides_data{1, 1, 1};
- Tensor input_tensor = makeInputTensor<DataType::U8>(input_shape, 1.0f, 0, input_data);
- Tensor begin_tensor = makeInputTensor<DataType::S32>(begin_shape, begin_data);
- Tensor end_tensor = makeInputTensor<DataType::S32>(end_shape, end_data);
- Tensor strides_tensor = makeInputTensor<DataType::S32>(strides_shape, strides_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, 1.0f, 0);
-
- StridedSliceParams params{};
- params.begin_mask = 0;
- params.end_mask = 0;
- params.ellipsis_mask = 0;
- params.new_axis_mask = 0;
- params.shrink_axis_mask = 1;
-
- StridedSlice kernel(&input_tensor, &begin_tensor, &end_tensor, &strides_tensor, &output_tensor,
- params);
- kernel.configure();
- kernel.execute();
-
- std::vector<int32_t> output_shape{3, 2};
- std::vector<float> output_data{1, 2, 3, 4, 5, 6};
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(output_data));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Sub.cpp b/compiler/luci-interpreter/src/kernels/Sub.cpp
deleted file mode 100644
index dd9c1102f..000000000
--- a/compiler/luci-interpreter/src/kernels/Sub.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2019 The TensorFlow Authors. 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 "kernels/Sub.h"
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/optimized/legacy_optimized_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Sub::Sub(const Tensor *input1, const Tensor *input2, Tensor *output, const SubParams &params)
- : KernelWithParams<SubParams>({input1, input2}, {output}, params)
-{
-}
-
-void Sub::configure()
-{
- LUCI_INTERPRETER_CHECK(!(input1()->element_type() != input2()->element_type()))
- output()->resize(calculateShapeForBroadcast(input1()->shape(), input2()->shape()));
-}
-
-void Sub::execute() const
-{
- switch (input1()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Sub::evalFloat() const
-{
- float activation_min{};
- float activation_max{};
- calculateActivationRange(_params.activation, &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.float_activation_min = activation_min;
- params.float_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastSubSlow(
- params, getTensorShape(input1()), getTensorData<float>(input1()), getTensorShape(input2()),
- getTensorData<float>(input2()), getTensorShape(output()), getTensorData<float>(output()));
- }
- else
- {
- tflite::optimized_ops::Sub(params, getTensorShape(input1()), getTensorData<float>(input1()),
- getTensorShape(input2()), getTensorData<float>(input2()),
- getTensorShape(output()), getTensorData<float>(output()));
- }
-}
-
-void Sub::evalQuantized() const
-{
- const auto input1_scale = static_cast<double>(input1()->scale());
- const auto input2_scale = static_cast<double>(input2()->scale());
- const auto output_scale = static_cast<double>(output()->scale());
-
- const int left_shift = 20;
- const double twice_max_input_scale = 2 * std::max(input1_scale, input2_scale);
- const double real_input1_multiplier = input1_scale / twice_max_input_scale;
- const double real_input2_multiplier = input2_scale / twice_max_input_scale;
- const double real_output_multiplier = twice_max_input_scale / ((1 << left_shift) * output_scale);
-
- int32_t input1_multiplier{}, input2_multiplier{}, output_multiplier{};
- int input1_shift{}, input2_shift{}, output_shift{};
- quantizeMultiplierSmallerThanOneExp(real_input1_multiplier, &input1_multiplier, &input1_shift);
- quantizeMultiplierSmallerThanOneExp(real_input2_multiplier, &input2_multiplier, &input2_shift);
- quantizeMultiplierSmallerThanOneExp(real_output_multiplier, &output_multiplier, &output_shift);
-
- int32_t activation_min{};
- int32_t activation_max{};
- calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
-
- tflite::ArithmeticParams params{};
- params.left_shift = left_shift;
- // The kernel expects inputs' zero points to be negated.
- params.input1_offset = -input1()->zero_point(); // Note the '-'.
- params.input1_multiplier = input1_multiplier;
- params.input1_shift = input1_shift;
- params.input2_offset = -input2()->zero_point(); // Note the '-'.
- params.input2_multiplier = input2_multiplier;
- params.input2_shift = input2_shift;
- params.output_offset = output()->zero_point();
- params.output_multiplier = output_multiplier;
- params.output_shift = output_shift;
- params.quantized_activation_min = activation_min;
- params.quantized_activation_max = activation_max;
-
- const bool need_broadcast = tflite::reference_ops::ProcessBroadcastShapes(
- getTensorShape(input1()), getTensorShape(input2()), &params);
-
- if (need_broadcast)
- {
- tflite::reference_ops::BroadcastSubSlow(
- params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- }
- else
- {
- tflite::reference_ops::Sub(params, getTensorShape(input1()), getTensorData<uint8_t>(input1()),
- getTensorShape(input2()), getTensorData<uint8_t>(input2()),
- getTensorShape(output()), getTensorData<uint8_t>(output()));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Sub.h b/compiler/luci-interpreter/src/kernels/Sub.h
deleted file mode 100644
index d7940b5c6..000000000
--- a/compiler/luci-interpreter/src/kernels/Sub.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_SUB_H
-#define LUCI_INTERPRETER_KERNELS_SUB_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Sub : public KernelWithParams<SubParams>
-{
-public:
- Sub(const Tensor *input1, const Tensor *input2, Tensor *output, const SubParams &params);
-
- const Tensor *input1() const { return _inputs[0]; }
- const Tensor *input2() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_SUB_H
diff --git a/compiler/luci-interpreter/src/kernels/Sub.test.cpp b/compiler/luci-interpreter/src/kernels/Sub.test.cpp
deleted file mode 100644
index 9f77fe7e0..000000000
--- a/compiler/luci-interpreter/src/kernels/Sub.test.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Sub.h"
-#include "kernels/TestUtils.h"
-
-#include <algorithm>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-using std::pair;
-using std::vector;
-using std::transform;
-using std::initializer_list;
-
-// for quantized Add, the error shouldn't exceed step
-float GetTolerance(float min, float max)
-{
- float kQuantizedStep = (max - min) / 255.0;
- return kQuantizedStep;
-}
-
-TEST(SubTest, Uint8)
-{
- Shape base_shape = {2, 3, 1, 2};
- vector<float> base_data = {-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- vector<Shape> test_shapes = {{1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- vector<float> test_data = {0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- vector<vector<int32_t>> output_shapes = {{2, 3, 3, 2}, {2, 3, 1, 2}, {2, 3, 3, 2}, {2, 3, 1, 2}};
- vector<vector<float>> output_data = {
- {-0.5f, 2.0f, 0.1f, 1.8f, -1.3f, 1.4f, 0.7f, 0.2f, 1.3f, 0.0f, -0.1f, -0.4f,
- 0.6f, -1.4f, 1.2f, -1.6f, -0.2f, -2.0f, 1.0f, 2.5f, 1.6f, 2.3f, 0.2f, 1.9f,
- -1.8f, -0.3f, -1.2f, -0.5f, -2.6f, -0.9f, 0.5f, -2.5f, 1.1f, -2.7f, -0.3f, -3.0f},
- {-0.5f, 2.0f, 1.3f, 0.0f, -0.2f, -2.0f, 1.0f, 2.5f, -1.2f, -0.5f, -0.3f, -3.0f},
- {-0.5f, 2.1f, -0.6f, 2.0f, 0.1f, 2.7f, 0.7f, 0.3f, 0.6f, 0.2f, 1.3f, 0.9f,
- 0.6f, -1.3f, 0.5f, -1.4f, 1.2f, -0.7f, 0.7f, 2.3f, 0.2f, 1.8f, 0.3f, 1.9f,
- -2.1f, -0.5f, -2.6f, -1.0f, -2.5f, -0.9f, 0.2f, -2.7f, -0.3f, -3.0f, -0.2f, -3.0f},
- {-0.5f, 2.1f, 0.6f, 0.2f, 1.2f, -0.7f, 0.7f, 2.3f, -2.6f, -1.0f, -0.2f, -3.0f}};
-
- float kQuantizedTolerance = GetTolerance(-3.f, 3.f);
- pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-3.f, 3.f);
- for (size_t i = 0; i < output_data.size(); ++i)
- {
- Tensor input1_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, base_data);
- Tensor input2_tensor = makeInputTensor<DataType::U8>(test_shapes[i], quant_param.first,
- quant_param.second, test_data);
- Tensor output_tensor =
- makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
-
- SubParams params{};
- params.activation = Activation::NONE;
-
- Sub kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data[i], kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shapes[i]));
- }
-
- // Inversion step for output_data, because subtract is not commutative operation
- auto multiply = [](auto &i) {
- transform(i.begin(), i.end(), i.begin(), [](auto &value) { return value * -1.0f; });
- };
- for_each(output_data.begin(), output_data.end(), multiply);
-
- // Re-run with exchanged inputs.
- for (size_t i = 0; i < output_data.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::U8>(test_shapes[i], quant_param.first,
- quant_param.second, test_data);
- Tensor input2_tensor =
- makeInputTensor<DataType::U8>(base_shape, quant_param.first, quant_param.second, base_data);
- Tensor output_tensor =
- makeOutputTensor(getElementType<uint8_t>(), quant_param.first, quant_param.second);
-
- SubParams params{};
- params.activation = Activation::NONE;
-
- Sub kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(dequantizeTensorData(output_tensor),
- FloatArrayNear(output_data[i], kQuantizedTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shapes[i]));
- }
-}
-
-TEST(SubTest, Float)
-{
- Shape base_shape = {2, 3, 1, 2};
- vector<Shape> test_shapes{{1, 1, 3, 2}, {1, 3, 1, 2}, {2, 1, 3, 1}, {2, 3, 1, 1}};
- vector<vector<int32_t>> output_shapes{{2, 3, 3, 2}, {2, 3, 1, 2}, {2, 3, 3, 2}, {2, 3, 1, 2}};
- vector<vector<float>> test_outputs = {
- {0.0f, 2.0f, 0.1f, 1.8f, 0.0f, 1.4f, 0.7f, 0.2f, 1.3f, 0.0f, 0.0f, 0.0f,
- 0.6f, 0.0f, 1.2f, 0.0f, 0.0f, 0.0f, 1.0f, 2.5f, 1.6f, 2.3f, 0.2f, 1.9f,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 1.1f, 0.0f, 0.0f, 0.0f},
- {0.0f, 2.0f, 1.3f, 0.0f, 0.0f, 0.0f, 1.0f, 2.5f, 0.0f, 0.0f, 0.0f, 0.0f},
- {0.0f, 2.1f, 0.0f, 2.0f, 0.1f, 2.7f, 0.7f, 0.3f, 0.6f, 0.2f, 1.3f, 0.9f,
- 0.6f, 0.0f, 0.5f, 0.0f, 1.2f, 0.0f, 0.7f, 2.3f, 0.2f, 1.8f, 0.3f, 1.9f,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
- {0.0f, 2.1f, 0.6f, 0.2f, 1.2f, 0.0f, 0.7f, 2.3f, 0.0f, 0.0f, 0.0f, 0.0f}};
-
- vector<float> input1_data{-0.3f, 2.3f, 0.9f, 0.5f, 0.8f, -1.1f,
- 1.2f, 2.8f, -1.6f, 0.0f, 0.7f, -2.2f};
- vector<float> input2_data{0.2f, 0.3f, -0.4f, 0.5f, 1.0f, 0.9f};
- for (size_t i = 0; i < test_shapes.size(); ++i)
- {
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>(base_shape, input1_data);
- Tensor input2_tensor = makeInputTensor<DataType::FLOAT32>(test_shapes[i], input2_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- SubParams params{};
- params.activation = Activation::RELU;
-
- Sub kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(test_outputs[i], 0.0001f))
- << "With shape number " << i;
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shapes[i]));
- }
-}
-
-TEST(SubTest, Input_Output_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::FLOAT32>({1}, {1.f});
- Tensor input2_tensor = makeInputTensor<DataType::S32>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- SubParams params{};
- params.activation = Activation::RELU;
-
- Sub kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- EXPECT_ANY_THROW(kernel.configure());
-}
-
-TEST(SubTest, Invalid_Input_Type_NEG)
-{
- Tensor input1_tensor = makeInputTensor<DataType::S64>({1}, {1});
- Tensor input2_tensor = makeInputTensor<DataType::S64>({1}, {2});
- Tensor output_tensor = makeOutputTensor(DataType::S64);
-
- SubParams params{};
- params.activation = Activation::RELU;
-
- Sub kernel(&input1_tensor, &input2_tensor, &output_tensor, params);
- kernel.configure();
- EXPECT_ANY_THROW(kernel.execute());
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Tanh.cpp b/compiler/luci-interpreter/src/kernels/Tanh.cpp
deleted file mode 100644
index b649d5d2f..000000000
--- a/compiler/luci-interpreter/src/kernels/Tanh.cpp
+++ /dev/null
@@ -1,93 +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 "kernels/Tanh.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-Tanh::Tanh(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {}
-
-void Tanh::configure()
-{
- assert(input()->element_type() == output()->element_type());
- if (input()->element_type() == DataType::U8)
- {
- populateLookupTable();
- }
- output()->resize(input()->shape());
-}
-
-void Tanh::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void Tanh::evalFloat() const
-{
- tflite::reference_ops::Tanh(getTensorShape(input()), getTensorData<float>(input()),
- getTensorShape(output()), getTensorData<float>(output()));
-}
-
-void Tanh::evalQuantized() const
-{
- const int size = tflite::MatchingFlatSize(getTensorShape(input()), getTensorShape(output()));
- uint8_t *output_data = getTensorData<uint8_t>(output());
- const uint8_t *input_data = getTensorData<uint8_t>(input());
- for (int i = 0; i < size; ++i)
- {
- output_data[i] = getTableValue(input_data[i]);
- }
-}
-
-void Tanh::populateLookupTable()
-{
- const auto input_scale = static_cast<double>(input()->scale());
- const auto input_zero_point = static_cast<int32_t>(input()->zero_point());
- const auto output_scale = static_cast<double>(output()->scale());
- const auto output_zero_point = static_cast<int32_t>(output()->zero_point());
- const float inverse_scale = 1 / output_scale;
- int32_t maxval = std::numeric_limits<uint8_t>::max();
- int32_t minval = std::numeric_limits<uint8_t>::min();
- for (int32_t val = minval; val <= maxval; ++val)
- {
- const float dequantized = input_scale * (val - input_zero_point);
- const float transformed = std::tanh(dequantized);
- const float rescaled = std::round(transformed * inverse_scale);
- const int32_t quantized = static_cast<int32_t>(rescaled + output_zero_point);
- setTableValue(static_cast<uint8_t>(std::max(std::min(maxval, quantized), minval)),
- static_cast<uint8_t>(val));
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Tanh.h b/compiler/luci-interpreter/src/kernels/Tanh.h
deleted file mode 100644
index 8017c9638..000000000
--- a/compiler/luci-interpreter/src/kernels/Tanh.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_TANH_H
-#define LUCI_INTERPRETER_KERNELS_TANH_H
-
-#include "core/Kernel.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Tanh : public Kernel
-{
-public:
- Tanh(const Tensor *input, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
- void populateLookupTable();
- void setTableValue(uint8_t value, uint8_t idx) { _table[idx] = value; };
- uint8_t getTableValue(uint8_t idx) const { return _table[idx]; };
-
-private:
- uint8_t _table[256]{};
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_TANH_H
diff --git a/compiler/luci-interpreter/src/kernels/Tanh.test.cpp b/compiler/luci-interpreter/src/kernels/Tanh.test.cpp
deleted file mode 100644
index f91ffa1db..000000000
--- a/compiler/luci-interpreter/src/kernels/Tanh.test.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Tanh.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-TEST(TanhTest, Float)
-{
- Shape input_shape{1, 2, 4, 1};
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- 3, -2, 10, 1, //
- };
- Tensor input_tensor = makeInputTensor<DataType::FLOAT32>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
-
- Tanh kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 0, -0.9999877, 0.9640275, 0.999329, //
- 0.99505475, -0.9640275, 1, 0.7615941, //
- };
- EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-TEST(TanhTest, Uint8)
-{
- float kMin = -1;
- float kMax = 127.f / 128.f;
- float kTanhTolerance = 2 * (1. / 256);
- std::pair<float, int32_t> input_quant_param = quantizationParams<uint8_t>(8 * kMin, 8 * kMax);
- std::pair<float, int32_t> output_quant_param = quantizationParams<uint8_t>(kMin, kMax);
- std::vector<float> input_data{
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- 0, -6, 2, 4, //
- -4, -2, 8, 1, //
- };
- Tensor input_tensor = makeInputTensor<DataType::U8>({2, 6, 4, 1}, input_quant_param.first,
- input_quant_param.second, input_data);
- Tensor output_tensor =
- makeOutputTensor(DataType::U8, output_quant_param.first, output_quant_param.second);
-
- Tanh kernel(&input_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- std::vector<float> ref_output_data{
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- 0.0, -0.999987, 0.964027, 0.999329, //
- -0.999329, -0.96402, 0.99999, 0.76159, //
- };
- std::vector<int32_t> ref_output_shape{2, 6, 4, 1};
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data, kTanhTolerance));
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/TestUtils.cpp b/compiler/luci-interpreter/src/kernels/TestUtils.cpp
deleted file mode 100644
index 4c19c8810..000000000
--- a/compiler/luci-interpreter/src/kernels/TestUtils.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/TestUtils.h"
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace testing
-{
-
-using ::testing::FloatNear;
-using ::testing::Matcher;
-
-Tensor makeOutputTensor(DataType element_type) { return Tensor(element_type, {}, {}, ""); }
-
-Tensor makeOutputTensor(DataType element_type, float scale, int32_t zero_point)
-{
- return Tensor(element_type, {}, {{scale}, {zero_point}}, "");
-}
-
-std::vector<float> dequantizeTensorData(const Tensor &tensor)
-{
- if (tensor.element_type() == DataType::U8)
- {
- return dequantize(extractTensorData<uint8_t>(tensor), tensor.scale(), tensor.zero_point());
- }
- else if (tensor.element_type() == DataType::S16)
- {
- // S16 quantization is symmetric, so zero point should be zero.
- assert(tensor.zero_point() == 0);
- return dequantize(extractTensorData<int16_t>(tensor), tensor.scale(), 0);
- }
- else
- {
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-Matcher<std::vector<float>> FloatArrayNear(const std::vector<float> &values, float max_abs_error)
-{
- std::vector<Matcher<float>> matchers;
- matchers.reserve(values.size());
- for (const float v : values)
- {
- matchers.emplace_back(FloatNear(v, max_abs_error));
- }
- return ElementsAreArray(matchers);
-}
-
-std::vector<int32_t> extractTensorShape(const Tensor &tensor)
-{
- std::vector<int32_t> result;
- int dims = tensor.shape().num_dims();
- for (int i = 0; i < dims; i++)
- {
- result.push_back(tensor.shape().dim(i));
- }
- return result;
-}
-
-} // namespace testing
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/TestUtils.h b/compiler/luci-interpreter/src/kernels/TestUtils.h
deleted file mode 100644
index e5bd6a2db..000000000
--- a/compiler/luci-interpreter/src/kernels/TestUtils.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 LUCI_INTERPRETER_KERNELS_TESTUTILS_H
-#define LUCI_INTERPRETER_KERNELS_TESTUTILS_H
-
-#include "luci_interpreter/core/Tensor.h"
-
-#include <type_traits>
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace testing
-{
-
-template <typename T>
-std::vector<T> quantize(const std::vector<float> &data, float scale, int32_t zero_point);
-
-template <DataType DT>
-Tensor makeInputTensor(const Shape &shape, const std::vector<typename DataTypeImpl<DT>::Type> &data)
-{
- Tensor tensor(DT, shape, {}, "");
- tensor.writeData(data.data(), data.size() * sizeof(typename DataTypeImpl<DT>::Type));
- return tensor;
-}
-
-template <DataType DT>
-Tensor makeInputTensor(const Shape &shape, float scale, int32_t zero_point,
- const std::vector<float> &data)
-{
- using NativeT = typename DataTypeImpl<DT>::Type;
- Tensor tensor(DT, shape, {{scale}, {zero_point}}, "");
- std::vector<NativeT> quantized_data = quantize<NativeT>(data, scale, zero_point);
- tensor.writeData(quantized_data.data(), quantized_data.size() * sizeof(NativeT));
- return tensor;
-}
-
-Tensor makeOutputTensor(DataType element_type);
-Tensor makeOutputTensor(DataType element_type, float scale, int32_t zero_point);
-
-std::vector<int32_t> extractTensorShape(const Tensor &tensor);
-
-// Returns the corresponding DataType given the type T.
-template <typename T> constexpr DataType getElementType()
-{
- if (std::is_same<T, float>::value)
- return DataType::FLOAT32;
- if (std::is_same<T, uint8_t>::value)
- return DataType::U8;
- if (std::is_same<T, int32_t>::value)
- return DataType::S32;
- if (std::is_same<T, int64_t>::value)
- return DataType::S64;
- return DataType::Unknown;
-}
-
-template <typename T> std::vector<T> extractTensorData(const Tensor &tensor)
-{
- const auto *data_ptr = tensor.data<T>();
- return std::vector<T>(data_ptr, data_ptr + tensor.shape().num_elements());
-}
-
-std::vector<float> dequantizeTensorData(const Tensor &tensor);
-
-// Array version of `::testing::FloatNear` matcher.
-::testing::Matcher<std::vector<float>> FloatArrayNear(const std::vector<float> &values,
- float max_abs_error = 1.0e-5f);
-
-template <typename T>
-std::vector<T> quantize(const std::vector<float> &data, float scale, int32_t zero_point)
-{
- static_assert(std::is_integral<T>::value, "Integral type expected.");
-
- float q_min{}, q_max{};
- if (std::is_signed<T>::value)
- {
- // For now, assume that signed type implies signed symmetric quantization.
- assert(zero_point == 0);
- q_min = -std::numeric_limits<T>::max();
- q_max = std::numeric_limits<T>::max();
- }
- else
- {
- q_min = 0;
- q_max = std::numeric_limits<T>::max();
- }
-
- std::vector<T> q;
- for (const auto &f : data)
- {
- q.push_back(static_cast<T>(
- std::max<float>(q_min, std::min<float>(q_max, std::round(zero_point + (f / scale))))));
- }
- return q;
-}
-
-template <typename T>
-std::vector<float> dequantize(const std::vector<T> &data, float scale, int32_t zero_point)
-{
- static_assert(std::is_integral<T>::value, "Integral type expected.");
- std::vector<float> f;
- for (const T &q : data)
- {
- f.push_back(scale * (q - zero_point));
- }
- return f;
-}
-
-// NOTE Returns scale and zero point for _asymmetric_ range (both signed and unsigned).
-template <typename T> std::pair<float, int32_t> quantizationParams(float f_min, float f_max)
-{
- static_assert(std::is_integral<T>::value, "Integral type expected.");
- int32_t zero_point = 0;
- float scale = 0;
- const T qmin = std::numeric_limits<T>::lowest();
- const T qmax = std::numeric_limits<T>::max();
- const float qmin_double = qmin;
- const float qmax_double = qmax;
- // 0 should always be a representable value. Let's assume that the initial
- // min,max range contains 0.
- assert(f_max >= 0);
- assert(f_min <= 0);
- if (f_min == f_max)
- {
- // Special case where the min,max range is a point. Should be {0}.
- assert(f_max == 0);
- assert(f_min == 0);
- return {scale, zero_point};
- }
-
- // General case.
- //
- // First determine the scale.
- scale = (f_max - f_min) / (qmax_double - qmin_double);
-
- // Zero-point computation.
- // First the initial floating-point computation. The zero-point can be
- // determined from solving an affine equation for any known pair
- // (real value, corresponding quantized value).
- // We know two such pairs: (rmin, qmin) and (rmax, qmax).
- // The arithmetic error on the zero point computed from either pair
- // will be roughly machine_epsilon * (sum of absolute values of terms)
- // so we want to use the variant that adds the smaller terms.
- const float zero_point_from_min = qmin_double - f_min / scale;
- const float zero_point_from_max = qmax_double - f_max / scale;
-
- const float zero_point_from_min_error = std::abs(qmin_double) + std::abs(f_min / scale);
-
- const float zero_point_from_max_error = std::abs(qmax_double) + std::abs(f_max / scale);
-
- const float zero_point_double = zero_point_from_min_error < zero_point_from_max_error
- ? zero_point_from_min
- : zero_point_from_max;
-
- // Now we need to nudge the zero point to be an integer
- // (our zero points are integer, and this is motivated by the requirement
- // to be able to represent the real value "0" exactly as a quantized value,
- // which is required in multiple places, for example in Im2col with SAME
- // padding).
-
- T nudged_zero_point = 0;
- if (zero_point_double < qmin_double)
- {
- nudged_zero_point = qmin;
- }
- else if (zero_point_double > qmax_double)
- {
- nudged_zero_point = qmax;
- }
- else
- {
- nudged_zero_point = static_cast<T>(std::round(zero_point_double));
- }
-
- // The zero point should always be in the range of quantized value,
- // // [qmin, qmax].
- assert(qmax >= nudged_zero_point);
- assert(qmin <= nudged_zero_point);
- zero_point = nudged_zero_point;
- // finally, return the values
- return {scale, zero_point};
-}
-
-inline float getTolerance(float min, float max, int quantize_steps)
-{
- return ((max - min) / quantize_steps);
-}
-
-} // namespace testing
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_TESTUTILS_H
diff --git a/compiler/luci-interpreter/src/kernels/Transpose.cpp b/compiler/luci-interpreter/src/kernels/Transpose.cpp
deleted file mode 100644
index 8265d9937..000000000
--- a/compiler/luci-interpreter/src/kernels/Transpose.cpp
+++ /dev/null
@@ -1,84 +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 "kernels/Transpose.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Transpose::Transpose(const Tensor *input, const Tensor *perm, Tensor *output)
- : Kernel({input, perm}, {output})
-{
-}
-
-void Transpose::configure()
-{
- // Transpose op only supports 1D-4D input arrays.
- int dims = input()->shape().num_dims();
- const int *perm_data = getTensorData<int32_t>(perm());
-
- assert(input()->shape().num_dims() <= 4);
- assert(input()->element_type() == output()->element_type());
-
- assert(perm()->shape().num_dims() == 1);
- assert(perm()->shape().dim(0) == dims);
-
- Shape output_shape(dims);
- for (int i = 0; i < dims; i++)
- {
- assert(perm_data[i] < dims && perm_data[i] >= 0);
- output_shape.dim(i) = input()->shape().dim(perm_data[i]);
- }
-
- output()->resize(output_shape);
-}
-
-void Transpose::execute() const
-{
- tflite::TransposeParams params{};
- const int *perm_data = getTensorData<int32_t>(perm());
- const int size = perm()->shape().dim(0);
- params.perm_count = size;
- for (int i = 0; i < size; i++)
- params.perm[i] = perm_data[i];
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- tflite::reference_ops::Transpose(params, getTensorShape(input()),
- getTensorData<float>(input()), getTensorShape(output()),
- getTensorData<float>(output()));
- break;
- case DataType::U8:
- tflite::reference_ops::Transpose(params, getTensorShape(input()),
- getTensorData<uint8_t>(input()), getTensorShape(output()),
- getTensorData<uint8_t>(output()));
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Transpose.h b/compiler/luci-interpreter/src/kernels/Transpose.h
deleted file mode 100644
index d6f89c352..000000000
--- a/compiler/luci-interpreter/src/kernels/Transpose.h
+++ /dev/null
@@ -1,44 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_TRANSPOSE_H
-#define LUCI_INTERPRETER_KERNELS_TRANSPOSE_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Transpose : public Kernel
-{
-public:
- Transpose(const Tensor *input, const Tensor *perm, Tensor *output);
-
- const Tensor *input() const { return _inputs[0]; }
- const Tensor *perm() const { return _inputs[1]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_TRANSPOSE_H
diff --git a/compiler/luci-interpreter/src/kernels/Transpose.test.cpp b/compiler/luci-interpreter/src/kernels/Transpose.test.cpp
deleted file mode 100644
index 1c99223a8..000000000
--- a/compiler/luci-interpreter/src/kernels/Transpose.test.cpp
+++ /dev/null
@@ -1,110 +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 "kernels/Transpose.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(std::initializer_list<int32_t> input_shape, std::initializer_list<int32_t> perm_shape,
- std::initializer_list<int32_t> output_shape, std::initializer_list<T> input_data,
- std::initializer_list<int32_t> perm_data, std::initializer_list<T> output_data)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor perm_tensor = makeInputTensor<DataType::S32>(perm_shape, perm_data);
- Tensor output_tensor = makeOutputTensor(element_type);
-
- Transpose kernel(&input_tensor, &perm_tensor, &output_tensor);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorData<T>(output_tensor), ::testing::ElementsAreArray(output_data));
-}
-
-template <typename T> class TransposeTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(TransposeTest, DataTypes);
-
-TYPED_TEST(TransposeTest, Small3D)
-{
- Check<TypeParam>(/*input_shape=*/{2, 3, 4}, /*perm_shape=*/{3}, /*output_shape=*/{4, 2, 3},
- /*input_data=*/{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23},
- /*perm_data=*/{2, 0, 1},
- /*output_data=*/{0, 4, 8, 12, 16, 20, 1, 5, 9, 13, 17, 21,
- 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23});
-}
-
-TYPED_TEST(TransposeTest, Large4D)
-{
- Check<TypeParam>(
- /*input_shape=*/{2, 3, 4, 5}, /*perm_shape=*/{4}, /*output_shape=*/{4, 2, 3, 5},
- /*input_data=*/{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119},
- /*perm_data=*/{2, 0, 1, 3},
- /*output_data=*/{0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44,
- 60, 61, 62, 63, 64, 80, 81, 82, 83, 84, 100, 101, 102, 103, 104,
- 5, 6, 7, 8, 9, 25, 26, 27, 28, 29, 45, 46, 47, 48, 49,
- 65, 66, 67, 68, 69, 85, 86, 87, 88, 89, 105, 106, 107, 108, 109,
- 10, 11, 12, 13, 14, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54,
- 70, 71, 72, 73, 74, 90, 91, 92, 93, 94, 110, 111, 112, 113, 114,
- 15, 16, 17, 18, 19, 35, 36, 37, 38, 39, 55, 56, 57, 58, 59,
- 75, 76, 77, 78, 79, 95, 96, 97, 98, 99, 115, 116, 117, 118, 119});
-}
-
-TYPED_TEST(TransposeTest, Large2D)
-{
- Check<TypeParam>(
- /*input_shape=*/{10, 12}, /*perm_shape=*/{2}, /*output_shape=*/{12, 10},
- /*input_data=*/{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119},
- /*perm_data=*/{1, 0},
- /*output_data=*/{
- 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 1, 13, 25, 37, 49, 61, 73, 85, 97, 109,
- 2, 14, 26, 38, 50, 62, 74, 86, 98, 110, 3, 15, 27, 39, 51, 63, 75, 87, 99, 111,
- 4, 16, 28, 40, 52, 64, 76, 88, 100, 112, 5, 17, 29, 41, 53, 65, 77, 89, 101, 113,
- 6, 18, 30, 42, 54, 66, 78, 90, 102, 114, 7, 19, 31, 43, 55, 67, 79, 91, 103, 115,
- 8, 20, 32, 44, 56, 68, 80, 92, 104, 116, 9, 21, 33, 45, 57, 69, 81, 93, 105, 117,
- 10, 22, 34, 46, 58, 70, 82, 94, 106, 118, 11, 23, 35, 47, 59, 71, 83, 95, 107, 119});
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/TransposeConv.cpp b/compiler/luci-interpreter/src/kernels/TransposeConv.cpp
deleted file mode 100644
index 07d92f07f..000000000
--- a/compiler/luci-interpreter/src/kernels/TransposeConv.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/TransposeConv.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-TransposeConv::TransposeConv(const Tensor *output_shape, const Tensor *filter, const Tensor *input,
- const Tensor *bias, Tensor *output, const TransposeConvParams &params)
- : KernelWithParams<TransposeConvParams>({output_shape, filter, input, bias}, {output}, params)
-{
-}
-
-void TransposeConv::configure()
-{
- assert(output_shape()->shape().num_dims() == 1);
- assert(input()->shape().num_dims() == 4);
- assert(filter()->shape().num_dims() == 4);
- assert(input()->element_type() == DataType::FLOAT32 || input()->element_type() == DataType::U8);
- assert(input()->element_type() == output()->element_type());
- assert(input()->shape().dim(3) == filter()->shape().dim(3));
-
- const int num_dims = output_shape()->shape().dim(0);
- Shape out_shape(num_dims);
- const auto *shape_data = getTensorData<int32_t>(output_shape());
- for (int i = 0; i < num_dims; i++)
- out_shape.dim(i) = shape_data[i];
- output()->resize(out_shape);
-
- const int32_t filter_height = filter()->shape().dim(1);
- const int32_t filter_width = filter()->shape().dim(2);
- const int32_t output_height = out_shape.dim(1);
- const int32_t output_width = out_shape.dim(2);
-
- const int32_t unused_output_height =
- computeOutputSize(params().padding, output_height, filter_height, params().stride_height, 1);
- const int32_t unused_output_width =
- computeOutputSize(params().padding, output_width, filter_width, params().stride_width, 1);
-
- _padding_height =
- computePadding(params().stride_height, 1, output_height, filter_height, unused_output_height);
- _padding_width =
- computePadding(params().stride_width, 1, output_width, filter_width, unused_output_width);
-
- if (input()->element_type() == DataType::U8)
- {
- _scratch_tensor =
- std::make_unique<Tensor>(DataType::S32, output()->shape(), AffineQuantization{}, "");
- const double input_product_scale = input()->scale() * filter()->scale();
- assert(input_product_scale >= 0);
- const double real_multiplier = input_product_scale / output()->scale();
- quantizeMultiplier(real_multiplier, &_output_multiplier, &_output_shift);
- }
-}
-
-void TransposeConv::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- evalFloat();
- break;
- case DataType::U8:
- evalQuantized();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-void TransposeConv::evalFloat() const
-{
- tflite::ConvParams op_params{};
- op_params.padding_type = tflite::PaddingType::kSame;
- op_params.padding_values.height = _padding_height;
- op_params.padding_values.width = _padding_width;
- op_params.stride_height = params().stride_height;
- op_params.stride_width = params().stride_width;
- op_params.output_multiplier = _output_multiplier;
- tflite::reference_ops::TransposeConv(op_params, //
- getTensorShape(input()), getTensorData<float>(input()), //
- getTensorShape(filter()), getTensorData<float>(filter()), //
- getTensorShape(bias()), getTensorData<float>(bias()), //
- getTensorShape(output()), getTensorData<float>(output()), //
- tflite::RuntimeShape(), nullptr);
-}
-
-void TransposeConv::evalQuantized() const
-{
- tflite::ConvParams op_params{};
- op_params.padding_type = tflite::PaddingType::kSame;
- op_params.padding_values.height = _padding_height;
- op_params.padding_values.width = _padding_width;
- op_params.stride_height = params().stride_height;
- op_params.stride_width = params().stride_width;
- // The kernel expects input and filter zero points to be negated.
- op_params.input_offset = -input()->zero_point(); // Note the '-'.
- op_params.weights_offset = -filter()->zero_point(); // Note the '-'.
- op_params.output_offset = output()->zero_point();
- op_params.output_multiplier = _output_multiplier;
- op_params.output_shift = _output_shift;
- op_params.quantized_activation_min = std::numeric_limits<uint8_t>::min();
- op_params.quantized_activation_max = std::numeric_limits<uint8_t>::max();
-
- tflite::reference_ops::TransposeConv(op_params, //
- getTensorShape(input()), getTensorData<uint8>(input()), //
- getTensorShape(filter()), getTensorData<uint8>(filter()), //
- getTensorShape(bias()), getTensorData<int32_t>(bias()), //
- getTensorShape(output()), getTensorData<uint8>(output()), //
- tflite::RuntimeShape(), nullptr, //
- getTensorData<int32_t>(_scratch_tensor.get()));
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/TransposeConv.h b/compiler/luci-interpreter/src/kernels/TransposeConv.h
deleted file mode 100644
index 444439c65..000000000
--- a/compiler/luci-interpreter/src/kernels/TransposeConv.h
+++ /dev/null
@@ -1,61 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_TRANSPOSECONV_H
-#define LUCI_INTERPRETER_KERNELS_TRANSPOSECONV_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class TransposeConv : public KernelWithParams<TransposeConvParams>
-{
-public:
- TransposeConv(const Tensor *output_shape, const Tensor *filter, const Tensor *input,
- const Tensor *bias, Tensor *output, const TransposeConvParams &params);
-
- const Tensor *output_shape() const { return _inputs[0]; }
- const Tensor *filter() const { return _inputs[1]; }
- const Tensor *input() const { return _inputs[2]; }
- const Tensor *bias() const { return _inputs[3]; }
- Tensor *output() const { return _outputs[0]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- void evalFloat() const;
- void evalQuantized() const;
-
-private:
- std::unique_ptr<Tensor> _scratch_tensor;
-
- int32_t _padding_height{};
- int32_t _padding_width{};
- // The scaling factor from input to output (aka the 'real multiplier') can
- // be represented as a fixed point multiplier plus a left shift.
- int32_t _output_multiplier = 0;
- int _output_shift = 0;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_TRANSPOSECONV_H
diff --git a/compiler/luci-interpreter/src/kernels/TransposeConv.test.cpp b/compiler/luci-interpreter/src/kernels/TransposeConv.test.cpp
deleted file mode 100644
index 5a69e7798..000000000
--- a/compiler/luci-interpreter/src/kernels/TransposeConv.test.cpp
+++ /dev/null
@@ -1,159 +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 "kernels/TransposeConv.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T, typename B>
-void Check(std::initializer_list<int32_t> output_shape_shape,
- std::initializer_list<int32_t> weight_shape, std::initializer_list<int32_t> input_shape,
- std::initializer_list<int32_t> bias_shape, std::initializer_list<int32_t> output_shape,
- std::initializer_list<int32_t> output_shape_data, std::initializer_list<T> weight_data,
- std::initializer_list<T> input_data, std::initializer_list<B> bias_data,
- std::initializer_list<T> output_data, luci::Padding padding, int32_t stride_height,
- int32_t stride_width)
-{
- constexpr DataType element_type = getElementType<T>();
- Tensor output_shape_tensor =
- makeInputTensor<DataType::S32>(output_shape_shape, output_shape_data);
- Tensor weight_tensor = makeInputTensor<element_type>(weight_shape, weight_data);
- Tensor input_data_tensor = makeInputTensor<element_type>(input_shape, input_data);
- Tensor output_tensor = makeOutputTensor(element_type);
-
- TransposeConvParams params{};
- params.padding = padding;
- params.stride_height = stride_height;
- params.stride_width = stride_width;
-
- if (bias_data.size() != 0)
- {
- Tensor bias_tensor = makeInputTensor<getElementType<B>()>(bias_shape, bias_data);
- TransposeConv kernel(&output_shape_tensor, &weight_tensor, &input_data_tensor, &bias_tensor,
- &output_tensor, params);
- kernel.configure();
- kernel.execute();
- }
- else
- {
- TransposeConv kernel(&output_shape_tensor, &weight_tensor, &input_data_tensor, nullptr,
- &output_tensor, params);
- kernel.configure();
- kernel.execute();
- }
- EXPECT_THAT(extractTensorData<T>(output_tensor), ::testing::ElementsAreArray(output_data));
-}
-
-TEST(TransposeConvTest, FloatSimple)
-{
- Check<float, float>(
- /*output_shape_shape=*/{4}, /*weight_shape=*/{1, 3, 3, 1}, /*input_shape=*/{1, 4, 4, 1},
- /*bias_shape=*/{}, /*output_shape=*/{1, 4, 4, 1}, /*output_shape_data=*/{1, 4, 4, 1},
- /*weight_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9},
- /*input_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
- /*bias_data=*/{},
- /*output_data=*/{29, 62, 83, 75, 99, 192, 237, 198, 207, 372, 417, 330, 263, 446, 485, 365},
- /*params.padding=*/luci::Padding::SAME, /*stride_height=*/1, /*stride_width=*/1);
-
- SUCCEED();
-}
-
-TEST(TransposeConvTest, FloatTwoFiltersTest)
-{
- Check<float, float>(
- /*output_shape_shape=*/{4}, /*weight_shape=*/{1, 3, 3, 2}, /*input_shape=*/{1, 4, 4, 2},
- /*bias_shape=*/{}, /*output_shape=*/{1, 4, 4, 1}, /*output_shape_data=*/{1, 4, 4, 1},
- /*weight_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18},
- /*input_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},
- /*bias_data=*/{},
- /*output_data=*/
- {184, 412, 568, 528, 678, 1347, 1689, 1434, 1494, 2715, 3057, 2442, 1968, 3352, 3652, 2760},
- /*params.padding=*/luci::Padding::SAME, /*stride_height=*/1, /*stride_width=*/1);
-
- SUCCEED();
-}
-
-TEST(TransposeConvTest, SimpleBiasTest)
-{
- Check<float, float>(
- /*output_shape_shape=*/{4}, /*weight_shape=*/{2, 3, 3, 1},
- /*input_shape=*/{1, 2, 2, 1},
- /*bias_shape=*/{2}, /*output_shape=*/{1, 4, 4, 1}, /*output_shape_data=*/{1, 5, 5, 2},
- /*weight_data=*/{1, 3, 5, 7, 9, 11, 13, 15, 17, 2, 4, 6, 8, 10, 12, 14, 16, 18},
- /*input_data=*/{1, 2, 3, 4},
- /*bias_data=*/{3, 4},
- /*output_data=*/{4, 6, 6, 8, 10, 14, 9, 12, 13, 16, 10, 12, 12, 14, 28, 32, 21,
- 24, 25, 28, 19, 24, 27, 32, 65, 76, 45, 52, 57, 64, 24, 28, 30, 34,
- 64, 72, 39, 44, 47, 52, 42, 46, 48, 52, 106, 114, 63, 68, 71, 76},
- /*params.padding=*/luci::Padding::VALID, /*stride_height=*/2, /*stride_width=*/2);
-
- SUCCEED();
-}
-
-TEST(TransposeConvTest, UInt8)
-{
- std::vector<float> input_data{1, 2, 3, 4};
- std::vector<float> filter_data{1, 3, 5, 7, 9, 11, 13, 15, 17, 2, 4, 6, 8, 10, 12, 14, 16, 18};
- std::vector<float> bias_data{3, 4};
- std::vector<int32_t> output_shape_data{1, 5, 5, 2};
- std::vector<float> ref_output_data{
- 4, 6, 6, 8, 10, 14, 9, 12, 13, 16, //
- 10, 12, 12, 14, 28, 32, 21, 24, 25, 28, //
- 19, 24, 27, 32, 65, 76, 45, 52, 57, 64, //
- 24, 28, 30, 34, 64, 72, 39, 44, 47, 52, //
- 42, 46, 48, 52, 106, 114, 63, 68, 71, 76, //
- };
-
- // Choose quantization parameters carefully.
- auto input_quant = quantizationParams<uint8_t>(-8.0, 7.9375); // s = 1 / 16, zp = 128
- auto filter_quant = quantizationParams<uint8_t>(-24.0, 39.75); // s = 1 / 4, zp = 96
- auto output_quant = quantizationParams<uint8_t>(-64.0, 191.0); // s = 1, zp = 64
-
- Tensor input_tensor = makeInputTensor<DataType::U8>({1, 2, 2, 1}, input_quant.first,
- input_quant.second, input_data);
- Tensor filter_tensor = makeInputTensor<DataType::U8>({2, 3, 3, 1}, filter_quant.first,
- filter_quant.second, filter_data);
- Tensor bias_tensor =
- makeInputTensor<DataType::S32>({2}, input_quant.first * filter_quant.first, 0, bias_data);
- Tensor output_shape_tensor = makeInputTensor<DataType::S32>({4}, output_shape_data);
- Tensor output_tensor = makeOutputTensor(DataType::U8, output_quant.first, output_quant.second);
-
- TransposeConvParams params{};
- params.padding = Padding::VALID;
- params.stride_height = 2;
- params.stride_width = 2;
-
- TransposeConv kernel(&output_shape_tensor, &filter_tensor, &input_tensor, &bias_tensor,
- &output_tensor, params);
- kernel.configure();
- kernel.execute();
-
- EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(output_shape_data));
- EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Unpack.cpp b/compiler/luci-interpreter/src/kernels/Unpack.cpp
deleted file mode 100644
index 834b79926..000000000
--- a/compiler/luci-interpreter/src/kernels/Unpack.cpp
+++ /dev/null
@@ -1,84 +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 "kernels/Unpack.h"
-
-#include "kernels/Utils.h"
-
-#include <tensorflow/lite/kernels/internal/reference/reference_ops.h>
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-namespace kernels
-{
-
-Unpack::Unpack(const Tensor *input, std::vector<Tensor *> outputs, const UnpackParams &params)
- : KernelWithParams<UnpackParams>({input}, std::move(outputs), params)
-{
-}
-
-void Unpack::configure()
-{
- const Shape &input_shape = input()->shape();
-
- int axis = _params.axis;
- if (axis < 0)
- axis += input()->shape().num_dims();
- assert(axis >= 0 && axis < input_shape.num_dims());
-
- Shape output_shape(input_shape.num_dims() - 1);
- int out_index = 0;
- for (int in_index = 0; in_index < input_shape.num_dims(); ++in_index)
- {
- if (in_index != axis)
- output_shape.dim(out_index++) = input_shape.dim(in_index);
- }
-
- for (Tensor *output : _outputs)
- {
- assert(output->element_type() == input()->element_type());
- output->resize(output_shape);
- }
-}
-
-template <typename T> void Unpack::executeImpl() const
-{
- tflite::UnpackParams params{};
- params.axis = _params.axis;
- params.num_split = _outputs.size();
- VectorOfTensors<T, false> all_outputs(_outputs);
- tflite::reference_ops::Unpack<T>(params, getTensorShape(input()), getTensorData<T>(input()),
- **all_outputs.shapes(), all_outputs.data());
-}
-
-void Unpack::execute() const
-{
- switch (input()->element_type())
- {
- case DataType::FLOAT32:
- return executeImpl<float>();
- case DataType::U8:
- return executeImpl<uint8_t>();
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Unpack.h b/compiler/luci-interpreter/src/kernels/Unpack.h
deleted file mode 100644
index f4a44ecad..000000000
--- a/compiler/luci-interpreter/src/kernels/Unpack.h
+++ /dev/null
@@ -1,46 +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.
- */
-
-#ifndef LUCI_INTERPRETER_KERNELS_UNPACK_H
-#define LUCI_INTERPRETER_KERNELS_UNPACK_H
-
-#include "core/Kernel.h"
-#include "core/KernelParams.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-class Unpack : public KernelWithParams<UnpackParams>
-{
-public:
- Unpack(const Tensor *input, std::vector<Tensor *> outputs, const UnpackParams &params);
-
- const Tensor *input() const { return _inputs[0]; }
- Tensor *output(int index) const { return _outputs[index]; }
-
- void configure() override;
- void execute() const override;
-
-private:
- template <typename T> void executeImpl() const;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_UNPACK_H
diff --git a/compiler/luci-interpreter/src/kernels/Unpack.test.cpp b/compiler/luci-interpreter/src/kernels/Unpack.test.cpp
deleted file mode 100644
index f70c5847a..000000000
--- a/compiler/luci-interpreter/src/kernels/Unpack.test.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2018 The TensorFlow Authors. 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 "kernels/Unpack.h"
-#include "kernels/TestUtils.h"
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-namespace
-{
-
-using namespace testing;
-
-template <typename T>
-void Check(int axis, Shape input_shape, std::initializer_list<T> input_data,
- const std::vector<std::initializer_list<int32_t>> &exp_output_shape,
- std::vector<std::initializer_list<T>> exp_output_data)
-{
- constexpr DataType element_type = getElementType<T>();
- const int num_outputs = input_shape.dim(axis < 0 ? axis + input_shape.num_dims() : axis);
-
- Tensor input_tensor = makeInputTensor<element_type>(input_shape, input_data);
- std::vector<Tensor> output_tensors;
- output_tensors.reserve(num_outputs);
- for (int i = 0; i < num_outputs; ++i)
- {
- output_tensors.push_back(makeOutputTensor(element_type));
- }
-
- std::vector<Tensor *> output_tensor_ptrs(num_outputs);
- for (int i = 0; i < num_outputs; ++i)
- {
- output_tensor_ptrs[i] = &output_tensors[i];
- }
-
- UnpackParams params{};
- params.axis = axis;
-
- Unpack kernel(&input_tensor, std::move(output_tensor_ptrs), params);
- kernel.configure();
- kernel.execute();
-
- for (int i = 0; i < num_outputs; ++i)
- {
- EXPECT_THAT(extractTensorData<T>(output_tensors[i]),
- ::testing::ElementsAreArray(exp_output_data[i]));
- }
-}
-
-template <typename T> class UnpackTest : public ::testing::Test
-{
-};
-
-using DataTypes = ::testing::Types<float, uint8_t>;
-TYPED_TEST_CASE(UnpackTest, DataTypes);
-
-TYPED_TEST(UnpackTest, ThreeOutputs)
-{
- Check<TypeParam>(/*axis=*/0, /*input_shape=*/{3, 2},
- /*input_data=*/{1, 2, 3, 4, 5, 6},
- /*exp_output_shape=*/{{2}, {2}, {2}},
- /*exp_output_data=*/{{1, 2}, {3, 4}, {5, 6}});
-}
-
-TYPED_TEST(UnpackTest, ThreeOutputsAxisOne)
-{
- Check<TypeParam>(/*axis=*/1, /*input_shape=*/{3, 2},
- /*input_data=*/{1, 2, 3, 4, 5, 6},
- /*exp_output_shape=*/{{3}, {3}},
- /*exp_output_data=*/{{1, 3, 5}, {2, 4, 6}});
-}
-
-TYPED_TEST(UnpackTest, ThreeOutputsNegativeAxisOne)
-{
- Check<TypeParam>(/*axis=*/-1, /*input_shape=*/{3, 2},
- /*input_data=*/{1, 2, 3, 4, 5, 6},
- /*exp_output_shape=*/{{3}, {3}},
- /*exp_output_data=*/{{1, 3, 5}, {2, 4, 6}});
-}
-
-TYPED_TEST(UnpackTest, ThreeOutputsNegativeAxisTwo)
-{
- Check<TypeParam>(/*axis=*/-2, /*input_shape=*/{3, 2},
- /*input_data=*/{1, 2, 3, 4, 5, 6},
- /*exp_output_shape=*/{{2}, {2}, {2}},
- /*exp_output_data=*/{{1, 2}, {3, 4}, {5, 6}});
-}
-
-TYPED_TEST(UnpackTest, OneOutput)
-{
- Check<TypeParam>(/*axis=*/0, /*input_shape=*/{1, 6},
- /*input_data=*/{1, 2, 3, 4, 5, 6},
- /*exp_output_shape=*/{{6}},
- /*exp_output_data=*/{{1, 2, 3, 4, 5, 6}});
-}
-
-TYPED_TEST(UnpackTest, ThreeDimensionsTwoOutputs)
-{
- Check<TypeParam>(/*axis=*/2, /*input_shape=*/{2, 2, 2},
- /*input_data=*/{1, 2, 3, 4, 5, 6, 7, 8},
- /*exp_output_shape=*/{{2, 2}, {2, 2}},
- /*exp_output_data=*/{{1, 3, 5, 7}, {2, 4, 6, 8}});
-}
-
-TYPED_TEST(UnpackTest, FiveDimensionsTwoOutputs)
-{
- Check<TypeParam>(
- /*axis=*/2, /*input_shape=*/{2, 2, 2, 2, 1},
- /*input_data=*/{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
- /*exp_output_shape=*/{{2, 2, 2, 1}, {2, 2, 2, 1}},
- /*exp_output_data=*/
- {{1, 2, 5, 6, 9, 10, 13, 14}, {3, 4, 7, 8, 11, 12, 15, 16}});
-}
-
-TYPED_TEST(UnpackTest, VectorToScalar)
-{
- Check<TypeParam>(/*axis=*/0, /*input_shape=*/{5},
- /*input_data=*/{1, 2, 3, 4, 5},
- /*exp_output_shape=*/{{}, {}, {}, {}, {}},
- /*exp_output_data=*/{{1}, {2}, {3}, {4}, {5}});
-}
-
-} // namespace
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Utils.cpp b/compiler/luci-interpreter/src/kernels/Utils.cpp
deleted file mode 100644
index 52e76a81c..000000000
--- a/compiler/luci-interpreter/src/kernels/Utils.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 "kernels/Utils.h"
-
-#include <cassert>
-#include <cmath>
-#include <limits>
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-void calculateActivationRange(Activation activation, float *activation_min, float *activation_max)
-{
- switch (activation)
- {
- case Activation::NONE:
- *activation_min = std::numeric_limits<float>::lowest();
- *activation_max = std::numeric_limits<float>::max();
- break;
- case Activation::RELU:
- *activation_min = 0;
- *activation_max = std::numeric_limits<float>::max();
- break;
- case Activation::RELU_N1_TO_1:
- *activation_min = -1;
- *activation_max = 1;
- break;
- case Activation::RELU6:
- *activation_min = 0;
- *activation_max = 6;
- break;
- default:
- throw std::runtime_error("Unsupported activation.");
- }
-}
-
-static void calculateActivationRangeQuantizedImpl(Activation activation, int32_t qmin, int32_t qmax,
- const Tensor *output, int32_t *activation_min,
- int32_t *activation_max)
-{
- const float scale = output->scale();
- const int32_t zero_point = output->zero_point();
-
- auto quantize = [scale, zero_point](float x) {
- return zero_point + static_cast<int32_t>(std::round(x / scale));
- };
-
- switch (activation)
- {
- case Activation::NONE:
- *activation_min = qmin;
- *activation_max = qmax;
- break;
- case Activation::RELU:
- *activation_min = std::max(qmin, quantize(0.0f));
- *activation_max = qmax;
- break;
- case Activation::RELU_N1_TO_1:
- *activation_min = std::max(qmin, quantize(-1.0f));
- *activation_max = std::min(qmax, quantize(1.0f));
- break;
- case Activation::RELU6:
- *activation_min = std::max(qmin, quantize(0.0f));
- *activation_max = std::min(qmax, quantize(6.0f));
- break;
- default:
- throw std::runtime_error("Unsupported activation.");
- }
-}
-
-void calculateActivationRangeQuantized(Activation activation, const Tensor *output,
- int32_t *activation_min, int32_t *activation_max)
-{
- // For now, assume that signed type implies signed symmetric quantization.
- int32_t qmin{};
- int32_t qmax{};
- switch (output->element_type())
- {
- case DataType::U8:
- qmin = 0;
- qmax = std::numeric_limits<uint8_t>::max();
- break;
- case DataType::S8:
- assert(output->zero_point() == 0);
- qmin = -std::numeric_limits<int8_t>::max();
- qmax = std::numeric_limits<int8_t>::max();
- break;
- case DataType::S16:
- assert(output->zero_point() == 0);
- qmin = -std::numeric_limits<int16_t>::max();
- qmax = std::numeric_limits<int16_t>::max();
- break;
- default:
- throw std::runtime_error("Unsupported type.");
- }
-
- calculateActivationRangeQuantizedImpl(activation, qmin, qmax, output, activation_min,
- activation_max);
-}
-
-void quantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift)
-{
- if (double_multiplier == 0.0)
- {
- *quantized_multiplier = 0;
- *shift = 0;
- return;
- }
-
- const double q = std::frexp(double_multiplier, shift);
- auto q_fixed = static_cast<int64_t>(std::round(q * (INT64_C(1) << 31)));
-
- if (q_fixed == (INT64_C(1) << 31))
- {
- q_fixed /= 2;
- ++*shift;
- }
- assert(q_fixed <= std::numeric_limits<int32_t>::max());
- // A shift amount smaller than -31 would cause all bits to be shifted out
- // and thus all results would be zero. We implement that instead with
- // q_fixed==0, so as to avoid hitting issues with right-shift
- // operations with shift amounts greater than 31. Note that this happens
- // roughly when abs(double_multiplier) < 2^-31 and the present handling means
- // that we're effectively flushing tiny double_multiplier's to zero.
- // We could conceivably handle values in the range (roughly) [32, 63]
- // as 'denormals' i.e. (shift==0, q_fixed < 2^30). In that point of view
- // the present handling is just doing 'flush denormals to zero'. We could
- // reconsider and actually generate nonzero denormals if a need arises.
- if (*shift < -31)
- {
- *shift = 0;
- q_fixed = 0;
- }
- *quantized_multiplier = static_cast<int32_t>(q_fixed);
-}
-
-void quantizeMultiplierSmallerThanOneExp(double double_multiplier, int32_t *quantized_multiplier,
- int *left_shift)
-{
- assert(double_multiplier < 1.0);
- assert(double_multiplier > 0.0);
- int shift;
- quantizeMultiplier(double_multiplier, quantized_multiplier, &shift);
- assert(shift <= 0);
- *left_shift = shift;
-}
-
-Shape calculateShapeForBroadcast(const Shape &input1_shape, const Shape &input2_shape)
-{
- const int num_input1_dims = input1_shape.num_dims();
- const int num_input2_dims = input2_shape.num_dims();
- const int num_out_dims = std::max(num_input1_dims, num_input2_dims);
- Shape output_shape(num_out_dims);
-
- for (int i = 0; i < num_out_dims; ++i)
- {
- const int32_t input1_dim = i < num_input1_dims ? input1_shape.dim(num_input1_dims - i - 1) : 1;
- const int32_t input2_dim = i < num_input2_dims ? input2_shape.dim(num_input2_dims - i - 1) : 1;
- assert(input1_dim == input2_dim || input1_dim == 1 || input2_dim == 1);
- output_shape.dim(num_out_dims - i - 1) = std::max(input1_dim, input2_dim);
- }
-
- return output_shape;
-}
-
-} // namespace kernels
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/kernels/Utils.h b/compiler/luci-interpreter/src/kernels/Utils.h
deleted file mode 100644
index 67bb7581a..000000000
--- a/compiler/luci-interpreter/src/kernels/Utils.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
- * Copyright 2017 The TensorFlow Authors. 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 LUCI_INTERPRETER_KERNELS_UTILS_H
-#define LUCI_INTERPRETER_KERNELS_UTILS_H
-
-#include "core/KernelParams.h"
-#include "luci_interpreter/core/Tensor.h"
-
-#include <tensorflow/lite/kernels/internal/types.h>
-
-#include <cassert>
-#include <cstdint>
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-namespace kernels
-{
-
-#define LUCI_INTERPRETER_CHECK(cond) \
- if (!(cond)) \
- throw std::runtime_error(std::string(__FILE__) + ":" + std::to_string(__LINE__) + +"(" + \
- std::string(#cond) + ") was not true.");
-
-inline int32_t computePadding(int32_t stride, int32_t dilation_rate, int32_t in_size,
- int32_t filter_size, int32_t out_size)
-{
- const int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
- const int32_t padding = ((out_size - 1) * stride + effective_filter_size - in_size) / 2;
- return padding > 0 ? padding : 0;
-}
-
-inline int32_t computePaddingWithOffset(int32_t stride, int32_t dilation_rate, int32_t in_size,
- int32_t filter_size, int32_t out_size, int32_t *offset)
-{
- int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
- int32_t total_padding = ((out_size - 1) * stride + effective_filter_size - in_size);
- total_padding = total_padding > 0 ? total_padding : 0;
- *offset = total_padding % 2;
- return total_padding / 2;
-}
-
-inline int32_t computeOutputSize(Padding padding, int32_t image_size, int32_t filter_size,
- int32_t stride, int32_t dilation_rate = 1)
-{
- const int32_t effective_filter_size = (filter_size - 1) * dilation_rate + 1;
- switch (padding)
- {
- case Padding::SAME:
- return (image_size + stride - 1) / stride;
- case Padding::VALID:
- return (image_size + stride - effective_filter_size) / stride;
- default:
- assert(false);
- return 0;
- }
-}
-
-inline int32_t calcOffset(const Shape &shape, int32_t d0, int32_t d1, int32_t d2, int32_t d3)
-{
- return ((d0 * shape.dim(1) + d1) * shape.dim(2) + d2) * shape.dim(3) + d3;
-}
-
-void calculateActivationRange(Activation activation, float *activation_min, float *activation_max);
-
-void calculateActivationRangeQuantized(Activation activation, const Tensor *output,
- int32_t *activation_min, int32_t *activation_max);
-
-// Decompose a double multiplier into a Q0.31 int32 representation of its
-// significand, and shift representation of its exponent.
-//
-// Handles an arbitrary positive multiplier. The 'shift' output-value is
-// basically the 'floating-point exponent' of the multiplier:
-// Negative for a right-shift (when the multiplier is <1), positive for a
-// left-shift (when the multiplier is >1)
-void quantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift);
-
-// Decompose a double multiplier into a Q0.31 int32 representation of its
-// significand, and shift representation of NEGATIVE its exponent ---
-// this is intended as a RIGHT-shift.
-//
-// Restricted to the case where the multiplier < 1 (and non-negative).
-void quantizeMultiplierSmallerThanOneExp(double double_multiplier, int32_t *quantized_multiplier,
- int *left_shift);
-
-Shape calculateShapeForBroadcast(const Shape &input1_shape, const Shape &input2_shape);
-
-inline double getQuantizedConvolutionMultipler(float input_scale, float filter_scale,
- float output_scale)
-{
- const double input_product_scale = static_cast<double>(input_scale * filter_scale);
- LUCI_INTERPRETER_CHECK(input_product_scale >= 0);
- return input_product_scale / static_cast<double>(output_scale);
-}
-
-inline tflite::RuntimeShape getTensorShape(const Tensor *tensor)
-{
- if (tensor == nullptr)
- return tflite::RuntimeShape();
-
- const Shape &shape = tensor->shape();
- tflite::RuntimeShape runtime_shape(shape.num_dims());
- for (int i = 0; i < shape.num_dims(); ++i)
- {
- runtime_shape.SetDim(i, shape.dim(i));
- }
- return runtime_shape;
-}
-
-template <typename T> const T *getTensorData(const Tensor *tensor)
-{
- return tensor != nullptr ? tensor->data<T>() : nullptr;
-}
-
-template <typename T> T *getTensorData(Tensor *tensor)
-{
- return tensor != nullptr ? tensor->data<T>() : nullptr;
-}
-
-// A list of tensors in a format that can be used by kernels like split and
-// concatenation.
-template <typename T, bool is_const> class VectorOfTensors
-{
-public:
- using ElementT = typename std::conditional<is_const, const T, T>::type;
- using TensorT = typename std::conditional<is_const, const Tensor, Tensor>::type;
-
- // Build with the tensors in 'tensor_list'.
- explicit VectorOfTensors(const std::vector<TensorT *> &tensor_list)
- {
- const int num_tensors = tensor_list.size();
-
- all_data_.reserve(num_tensors);
- all_shape_.reserve(num_tensors);
- all_shape_ptr_.reserve(num_tensors);
-
- for (TensorT *tensor : tensor_list)
- {
- all_data_.push_back(getTensorData<T>(tensor));
- all_shape_.push_back(getTensorShape(tensor));
- }
-
- // Taking the pointer from inside a std::vector is only OK if the vector is
- // never modified, so we populate all_shape in the previous loop and then we
- // are free to grab iterators here.
- for (tflite::RuntimeShape &shape : all_shape_)
- {
- all_shape_ptr_.push_back(&shape);
- }
- }
- // Return a pointer to the data pointers of all tensors in the list. For
- // example:
- // float* const* f = v.data();
- // f[0][1] is the second element of the first tensor.
- ElementT *const *data() const { return all_data_.data(); }
-
- // Return a pointer the shape pointers of all tensors in the list. For
- // example:
- // const RuntimeShape* const* d = v.dims();
- // dims[1] are the dimensions of the second tensor in the list.
- const tflite::RuntimeShape *const *shapes() const { return all_shape_ptr_.data(); }
-
-private:
- std::vector<ElementT *> all_data_;
- std::vector<tflite::RuntimeShape> all_shape_;
- std::vector<tflite::RuntimeShape *> all_shape_ptr_;
-};
-
-// A list of quantized tensors in a format that can be used by kernels like
-// split and concatenation.
-template <bool is_const> class VectorOfQuantizedTensors : public VectorOfTensors<uint8_t, is_const>
-{
-public:
- using typename VectorOfTensors<uint8_t, is_const>::TensorT;
-
- // Build with the tensors in 'tensor_list'.
- explicit VectorOfQuantizedTensors(const std::vector<TensorT *> &tensor_list)
- : VectorOfTensors<uint8_t, is_const>(tensor_list)
- {
- for (TensorT *tensor : tensor_list)
- {
- zero_point_.push_back(tensor->zero_point());
- scale_.push_back(tensor->scale());
- }
- }
-
- const float *scale() const { return scale_.data(); }
- const int32_t *zero_point() const { return zero_point_.data(); }
-
-private:
- std::vector<int32_t> zero_point_;
- std::vector<float> scale_;
-};
-
-} // namespace kernels
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_KERNELS_UTILS_H
diff --git a/compiler/luci-interpreter/src/loader/CMakeLists.txt b/compiler/luci-interpreter/src/loader/CMakeLists.txt
deleted file mode 100644
index d99485d06..000000000
--- a/compiler/luci-interpreter/src/loader/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-nnas_find_package(GTest REQUIRED)
-
-set(SOURCES
- GraphLoader.h
- GraphLoader.cpp
- KernelBuilder.h
- KernelBuilder.cpp
- ModuleLoader.h
- ModuleLoader.cpp
- RuntimeToIR.h)
-
-add_library(luci_interpreter_loader STATIC ${SOURCES})
-set_target_properties(luci_interpreter_loader PROPERTIES POSITION_INDEPENDENT_CODE ON)
-target_include_directories(luci_interpreter_loader PUBLIC "${LUCI_INTERPRETER_SOURCE_DIR}")
-target_link_libraries(luci_interpreter_loader
- PUBLIC luci_lang luci_interpreter_core
- PRIVATE luci_interpreter_kernels nncc_common)
-
-set(TEST_SOURCES KernelBuilder.test.cpp)
-
-GTest_AddTest(luci_interpreter_loader_test ${TEST_SOURCES})
-target_link_libraries(luci_interpreter_loader_test luci_interpreter_loader)
diff --git a/compiler/luci-interpreter/src/loader/GraphLoader.cpp b/compiler/luci-interpreter/src/loader/GraphLoader.cpp
deleted file mode 100644
index 95c654769..000000000
--- a/compiler/luci-interpreter/src/loader/GraphLoader.cpp
+++ /dev/null
@@ -1,200 +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 "loader/GraphLoader.h"
-
-#include "loader/KernelBuilder.h"
-
-#include <loco/IR/Algorithm.h>
-
-namespace luci_interpreter
-{
-namespace
-{
-
-template <typename NodeT> Shape getNodeShape(const NodeT *node)
-{
- Shape shape(node->rank());
- for (uint32_t i = 0; i < node->rank(); ++i)
- {
- shape.dim(i) = node->dim(i).value();
- }
- return shape;
-}
-
-template <DataType DT> const void *getNodeDataImpl(const luci::CircleConst *node, size_t *data_size)
-{
- const size_t element_size = getDataTypeSize(DT);
- const int32_t num_elements = node->size<DT>();
-
- *data_size = num_elements * element_size;
- if (*data_size > 0)
- {
- // FIXME There is no good way to get the pointer to the data currently.
- return &node->at<DT>(0);
- }
- return nullptr;
-}
-
-const void *getNodeData(const luci::CircleConst *node, size_t *data_size)
-{
- switch (node->dtype())
- {
- case DataType::U8:
- return getNodeDataImpl<DataType::U8>(node, data_size);
- case DataType::FLOAT32:
- return getNodeDataImpl<DataType::FLOAT32>(node, data_size);
- case DataType::S32:
- return getNodeDataImpl<DataType::S32>(node, data_size);
- default:
- throw std::runtime_error("Unsupported type.");
- }
-}
-
-bool isExecutableNode(const luci::CircleNode *node)
-{
- switch (node->opcode())
- {
- // These nodes denote inputs / outputs of a graph.
- case luci::CircleOpcode::CIRCLECONST:
- case luci::CircleOpcode::CIRCLEINPUT:
- case luci::CircleOpcode::CIRCLEOUTPUT:
- case luci::CircleOpcode::CIRCLEOUTPUTEXCLUDE:
- // The following nodes denote outputs of multiple-output nodes.
- case luci::CircleOpcode::CIRCLEIFOUT:
- case luci::CircleOpcode::CIRCLESPLITOUT:
- case luci::CircleOpcode::CIRCLEUNPACKOUT:
- return false;
- default:
- return true;
- }
-}
-
-bool isTensorProducingNode(const luci::CircleNode *node)
-{
- switch (node->opcode())
- {
- // Output nodes do not produce tensors.
- case luci::CircleOpcode::CIRCLEOUTPUT:
- // The following nodes are multiple-output nodes. They do not produce tensors, the tensors
- // are produced by the corresponding *Out nodes instead.
- case luci::CircleOpcode::IF:
- case luci::CircleOpcode::SPLIT:
- case luci::CircleOpcode::UNPACK:
- return false;
- default:
- return true;
- }
-}
-
-} // namespace
-
-GraphLoader::GraphLoader(
- const loco::Graph *graph, RuntimeGraph *runtime_graph, RuntimeToIR &runtime_to_ir,
- const std::unordered_map<const loco::Graph *, RuntimeGraph *> &graph_to_runtime_graph,
- std::unordered_map<const loco::Node *, Tensor *> &node_to_tensor)
- : _graph(graph), _runtime_graph(runtime_graph), _runtime_to_ir(runtime_to_ir),
- _graph_to_runtime_graph(graph_to_runtime_graph), _node_to_tensor(node_to_tensor)
-{
-}
-
-void GraphLoader::loadTensors()
-{
- for (uint32_t i = 0; i < _graph->nodes()->size(); ++i)
- {
- const auto *node = loco::must_cast<const luci::CircleNode *>(_graph->nodes()->at(i));
-
- if (!isTensorProducingNode(node))
- continue;
-
- // Only Input and Const nodes have shapes. Shapes of intermediate tensors will be inferred.
- Shape shape{};
- if (const auto *input_node = dynamic_cast<const luci::CircleInput *>(node))
- {
- shape = getNodeShape(input_node);
- }
- else if (const auto *const_node = dynamic_cast<const luci::CircleConst *>(node))
- {
- shape = getNodeShape(const_node);
- }
-
- AffineQuantization quantization;
- if (node->quantparam() != nullptr)
- {
- const luci::CircleQuantParam *params = node->quantparam();
- quantization.scale.assign(params->scale.cbegin(), params->scale.cend());
- quantization.zero_point.assign(params->zerop.cbegin(), params->zerop.cend());
- quantization.quantized_dimension = params->quantized_dimension;
- }
-
- auto tensor = std::make_unique<Tensor>(node->dtype(), std::move(shape), std::move(quantization),
- node->name());
-
- if (const auto *const_node = dynamic_cast<const luci::CircleConst *>(node))
- {
- size_t data_size{};
- const void *const_data = getNodeData(const_node, &data_size);
- if (const_data != nullptr)
- tensor->writeData(const_data, data_size);
- }
-
- _node_to_tensor.emplace(node, tensor.get());
- _runtime_to_ir.tensor_to_node.emplace(tensor.get(), node);
-
- _runtime_graph->addTensor(std::move(tensor));
- }
-}
-
-void GraphLoader::initInputOutputTensors() const
-{
- auto input_nodes = loco::input_nodes(_graph);
- std::vector<Tensor *> input_tensors(input_nodes.size());
- for (size_t i = 0; i < input_nodes.size(); ++i)
- {
- input_tensors[i] = _node_to_tensor.at(input_nodes[i]);
- }
- _runtime_graph->setInputTensors(input_tensors);
-
- auto output_nodes = loco::output_nodes(const_cast<loco::Graph *>(_graph));
- std::vector<Tensor *> output_tensors(output_nodes.size());
- for (size_t i = 0; i < output_nodes.size(); ++i)
- {
- const auto *node = loco::must_cast<const luci::CircleOutput *>(output_nodes[i]);
- output_tensors[i] = _node_to_tensor.at(node->from());
- }
- _runtime_graph->setOutputTensors(output_tensors);
-}
-
-void GraphLoader::loadOperators()
-{
- KernelBuilder kernel_builder(_graph_to_runtime_graph, _node_to_tensor);
-
- // Create kernels for executable nodes. This has to be done in execution order.
- for (const loco::Node *loco_node :
- loco::postorder_traversal(loco::output_nodes(const_cast<loco::Graph *>(_graph))))
- {
- const auto *node = loco::must_cast<const luci::CircleNode *>(loco_node);
-
- if (isExecutableNode(node))
- {
- std::unique_ptr<Kernel> kernel = node->accept(&kernel_builder);
- _runtime_to_ir.kernel_to_node.emplace(kernel.get(), node);
- _runtime_graph->addKernel(std::move(kernel));
- }
- }
-}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/loader/GraphLoader.h b/compiler/luci-interpreter/src/loader/GraphLoader.h
deleted file mode 100644
index 89c5bcad7..000000000
--- a/compiler/luci-interpreter/src/loader/GraphLoader.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef LUCI_INTERPRETER_LOADER_GRAPHLOADER_H
-#define LUCI_INTERPRETER_LOADER_GRAPHLOADER_H
-
-#include "core/RuntimeGraph.h"
-#include "loader/RuntimeToIR.h"
-
-#include <loco/IR/Graph.h>
-
-#include <unordered_map>
-
-namespace luci_interpreter
-{
-
-class GraphLoader
-{
-public:
- GraphLoader(const loco::Graph *graph, RuntimeGraph *runtime_graph, RuntimeToIR &runtime_to_ir,
- const std::unordered_map<const loco::Graph *, RuntimeGraph *> &graph_to_runtime_graph,
- std::unordered_map<const loco::Node *, Tensor *> &node_to_tensor);
-
- void loadTensors();
- void initInputOutputTensors() const;
- void loadOperators();
-
-private:
- const loco::Graph *_graph;
- RuntimeGraph *_runtime_graph;
- RuntimeToIR &_runtime_to_ir;
-
- const std::unordered_map<const loco::Graph *, RuntimeGraph *> &_graph_to_runtime_graph;
- std::unordered_map<const loco::Node *, Tensor *> &_node_to_tensor;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_LOADER_GRAPHLOADER_H
diff --git a/compiler/luci-interpreter/src/loader/KernelBuilder.cpp b/compiler/luci-interpreter/src/loader/KernelBuilder.cpp
deleted file mode 100644
index 66aa38ff0..000000000
--- a/compiler/luci-interpreter/src/loader/KernelBuilder.cpp
+++ /dev/null
@@ -1,842 +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 "loader/KernelBuilder.h"
-
-#include "kernels/Add.h"
-#include "kernels/ArgMax.h"
-#include "kernels/AveragePool2D.h"
-#include "kernels/Concatenation.h"
-#include "kernels/Conv2D.h"
-#include "kernels/DepthToSpace.h"
-#include "kernels/DepthwiseConv2D.h"
-#include "kernels/Div.h"
-#include "kernels/Elu.h"
-#include "kernels/Floor.h"
-#include "kernels/FloorDiv.h"
-#include "kernels/Equal.h"
-#include "kernels/FullyConnected.h"
-#include "kernels/Greater.h"
-#include "kernels/GreaterEqual.h"
-#include "kernels/If.h"
-#include "kernels/L2Normalize.h"
-#include "kernels/L2Pool2D.h"
-#include "kernels/LeakyRelu.h"
-#include "kernels/Less.h"
-#include "kernels/LessEqual.h"
-#include "kernels/LocalResponseNormalization.h"
-#include "kernels/Logistic.h"
-#include "kernels/LogSoftmax.h"
-#include "kernels/Maximum.h"
-#include "kernels/MaxPool2D.h"
-#include "kernels/Mean.h"
-#include "kernels/Minimum.h"
-#include "kernels/Mul.h"
-#include "kernels/NotEqual.h"
-#include "kernels/Pad.h"
-#include "kernels/Pow.h"
-#include "kernels/Prelu.h"
-#include "kernels/Relu.h"
-#include "kernels/Relu6.h"
-#include "kernels/Reshape.h"
-#include "kernels/ResizeBilinear.h"
-#include "kernels/ResizeNearestNeighbor.h"
-#include "kernels/Reverse.h"
-#include "kernels/Rsqrt.h"
-#include "kernels/Slice.h"
-#include "kernels/Softmax.h"
-#include "kernels/SpaceToDepth.h"
-#include "kernels/Split.h"
-#include "kernels/StridedSlice.h"
-#include "kernels/Sqrt.h"
-#include "kernels/Sub.h"
-#include "kernels/Squeeze.h"
-#include "kernels/Tanh.h"
-#include "kernels/Unpack.h"
-#include "kernels/Transpose.h"
-#include "kernels/TransposeConv.h"
-
-#include <stdexcept>
-
-namespace luci_interpreter
-{
-
-template <typename CircleNodeOut>
-static std::vector<const loco::Node *> collectOutputNodes(const luci::CircleNode *node)
-{
- std::vector<const CircleNodeOut *> output_nodes;
- for (const loco::Node *loco_node : loco::succs(node))
- {
- output_nodes.push_back(loco::must_cast<const CircleNodeOut *>(loco_node));
- }
- std::sort(output_nodes.begin(), output_nodes.end(),
- [](const CircleNodeOut *node1, const CircleNodeOut *node2) {
- return node1->index() < node2->index();
- });
- return {output_nodes.cbegin(), output_nodes.cend()};
-}
-
-const Tensor *KernelBuilder::getInputTensor(const loco::Node *node) const
-{
- const Tensor *tensor = _node_to_tensor.at(node);
- assert(tensor != nullptr);
- return tensor;
-}
-
-const Tensor *KernelBuilder::getOptionalInputTensor(const loco::Node *node) const
-{
- if (dynamic_cast<const luci::CircleOutputExclude *>(node))
- {
- return nullptr;
- }
- return getInputTensor(node);
-}
-
-Tensor *KernelBuilder::getOutputTensor(const loco::Node *node) const
-{
- Tensor *tensor = _node_to_tensor.at(node);
- assert(tensor != nullptr);
- return tensor;
-}
-
-std::vector<Tensor *>
-KernelBuilder::getOutputTensors(const std::vector<const loco::Node *> &nodes) const
-{
- std::vector<Tensor *> tensors;
- tensors.reserve(nodes.size());
- for (const loco::Node *node : nodes)
- tensors.push_back(getOutputTensor(node));
- return tensors;
-}
-
-RuntimeGraph *KernelBuilder::getRuntimeGraph(const loco::Graph *graph) const
-{
- RuntimeGraph *runtime_graph = _graph_to_runtime_graph.at(graph);
- assert(runtime_graph != nullptr);
- return runtime_graph;
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleAdd *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- AddParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::Add>(input1, input2, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleArgMax *node)
-{
- assert(node->arity() == 2);
- const Tensor *input = getInputTensor(node->input());
- const Tensor *axis = getInputTensor(node->dimension());
- Tensor *output = getOutputTensor(node);
-
- ArgMaxParams params{};
- params.output_type = node->output_type();
-
- return std::make_unique<kernels::ArgMax>(input, axis, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleAveragePool2D *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->value());
- Tensor *output = getOutputTensor(node);
-
- Pool2DParams params{};
- params.padding = node->padding();
- params.filter_height = node->filter()->h();
- params.filter_width = node->filter()->w();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::AveragePool2D>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleConcatenation *node)
-{
- std::vector<const Tensor *> inputs(node->numValues());
- for (uint32_t i = 0; i < node->numValues(); ++i)
- {
- inputs[i] = getInputTensor(node->values(i));
- }
- Tensor *output = getOutputTensor(node);
-
- ConcatenationParams params{};
- params.axis = node->axis();
-
- return std::make_unique<kernels::Concatenation>(std::move(inputs), output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleConst *)
-{
- throw std::runtime_error("Const node cannot be executed.");
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleConv2D *node)
-{
- assert(node->arity() == 3);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *filter = getInputTensor(node->filter());
- const Tensor *bias = getInputTensor(node->bias());
- Tensor *output = getOutputTensor(node);
-
- Conv2DParams params{};
- params.padding = node->padding();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
- params.dilation_height_factor = node->dilation()->h();
- params.dilation_width_factor = node->dilation()->w();
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::Conv2D>(input, filter, bias, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleDepthToSpace *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->input());
- Tensor *output = getOutputTensor(node);
-
- DepthToSpaceParams params{};
- params.block_size = node->block_size();
-
- return std::make_unique<kernels::DepthToSpace>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleDepthwiseConv2D *node)
-{
- assert(node->arity() == 3);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *filter = getInputTensor(node->filter());
- const Tensor *bias = getInputTensor(node->bias());
- Tensor *output = getOutputTensor(node);
-
- DepthwiseConv2DParams params{};
- params.padding = node->padding();
- params.depth_multiplier = node->depthMultiplier();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
- params.dilation_height_factor = node->dilation()->h();
- params.dilation_width_factor = node->dilation()->w();
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::DepthwiseConv2D>(input, filter, bias, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleDiv *node)
-{
- assert(node->arity() == 2);
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- DivParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::Div>(input1, input2, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleElu *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->features());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Elu>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleFloor *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Floor>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleFloorDiv *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::FloorDiv>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleEqual *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Equal>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleFullyConnected *node)
-{
- assert(node->arity() == 3);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *weights = getInputTensor(node->weights());
- const Tensor *bias = getOptionalInputTensor(node->bias());
- Tensor *output = getOutputTensor(node);
-
- FullyConnectedParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::FullyConnected>(input, weights, bias, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleGreater *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Greater>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleGreaterEqual *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::GreaterEqual>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleIf *node)
-{
- auto output_nodes = collectOutputNodes<luci::CircleIfOut>(node);
- assert(node->arity() == 1 + node->input_count());
- assert(output_nodes.size() == static_cast<size_t>(node->output_count()));
-
- const Tensor *cond = getInputTensor(node->cond());
- std::vector<const Tensor *> inputs(node->input_count());
- for (uint32_t i = 0; i < node->input_count(); ++i)
- {
- inputs[i] = getInputTensor(node->input(i));
- }
- std::vector<Tensor *> outputs = getOutputTensors(output_nodes);
-
- RuntimeGraph *then_graph = getRuntimeGraph(node->then_graph());
- RuntimeGraph *else_graph = getRuntimeGraph(node->else_graph());
-
- return std::make_unique<kernels::If>(cond, std::move(inputs), std::move(outputs), then_graph,
- else_graph);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleInput *)
-{
- throw std::runtime_error("Input node cannot be executed.");
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleL2Normalize *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- L2NormParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::L2Normalize>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleL2Pool2D *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->value());
- Tensor *output = getOutputTensor(node);
-
- Pool2DParams params{};
- params.padding = node->padding();
- params.filter_height = node->filter()->h();
- params.filter_width = node->filter()->w();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::L2Pool2D>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLeakyRelu *node)
-{
- assert(node->arity() == 1);
- const Tensor *input = getInputTensor(node->features());
- Tensor *output = getOutputTensor(node);
-
- LeakyReluParams params{};
- params.alpha = node->alpha();
-
- return std::make_unique<kernels::LeakyRelu>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLess *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Less>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLessEqual *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::LessEqual>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLocalResponseNormalization *node)
-{
- assert(node->arity() == 1);
- const Tensor *input = getInputTensor(node->input());
- Tensor *output = getOutputTensor(node);
-
- LocalResponseNormalizationParams params{};
- params.radius = node->radius();
- params.bias = node->bias();
- params.alpha = node->alpha();
- params.beta = node->beta();
-
- return std::make_unique<kernels::LocalResponseNormalization>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLogistic *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Logistic>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleLogSoftmax *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->logits());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::LogSoftmax>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleMaximum *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Maximum>(input1, input2, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleMaxPool2D *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->value());
- Tensor *output = getOutputTensor(node);
-
- Pool2DParams params{};
- params.padding = node->padding();
- params.filter_height = node->filter()->h();
- params.filter_width = node->filter()->w();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::MaxPool2D>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleMean *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *axes = getInputTensor(node->reduction_indices());
- Tensor *output = getOutputTensor(node);
-
- ReducerParams params{};
- params.keep_dims = node->keep_dims();
-
- return std::make_unique<kernels::Mean>(input, axes, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleMinimum *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Minimum>(input1, input2, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleMul *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- MulParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::Mul>(input1, input2, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleNotEqual *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *x = getInputTensor(node->x());
- const Tensor *y = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::NotEqual>(x, y, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleOutput *)
-{
- throw std::runtime_error("Output node cannot be executed.");
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CirclePad *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *paddings = getInputTensor(node->paddings());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Pad>(input, paddings, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CirclePow *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
-
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Pow>(input1, input2, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CirclePRelu *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *alpha = getInputTensor(node->alpha());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Prelu>(input, alpha, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleRelu *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->features());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Relu>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleRelu6 *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->features());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Relu6>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleReshape *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->tensor());
- const Tensor *shape = getInputTensor(node->shape());
- Tensor *output = getOutputTensor(node);
-
- // NOTE 'newShape' attribute is ignored.
- return std::make_unique<kernels::Reshape>(input, shape, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleResizeBilinear *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *size = getInputTensor(node->size());
- Tensor *output = getOutputTensor(node);
-
- ResizeBilinearParams params{};
- params.align_corners = node->align_corners();
- params.half_pixel_centers = node->half_pixel_centers();
-
- return std::make_unique<kernels::ResizeBilinear>(input, size, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleResizeNearestNeighbor *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *size = getInputTensor(node->size());
- Tensor *output = getOutputTensor(node);
-
- ResizeNearestNeighborParams params{};
- params.align_corners = node->align_corners();
- // TODO update half_pixel_centers after CircleResizeNearestNeighbor updated
- // Current CircleResizeNearestNeighbor don't have half_pixel_centers.
- // default value on current is false.
- // it need to be updated when CircleResizeNearestNeighbor updated.
- params.half_pixel_centers = false;
-
- return std::make_unique<kernels::ResizeNearestNeighbor>(input, size, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleReverseV2 *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->tensor());
- const Tensor *axes = getInputTensor(node->axis());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Reverse>(input, axes, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleRsqrt *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Rsqrt>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSub *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input1 = getInputTensor(node->x());
- const Tensor *input2 = getInputTensor(node->y());
- Tensor *output = getOutputTensor(node);
-
- SubParams params{};
- params.activation = node->fusedActivationFunction();
-
- return std::make_unique<kernels::Sub>(input1, input2, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSlice *node)
-{
- assert(node->arity() == 3);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *begin = getInputTensor(node->begin());
- const Tensor *size = getInputTensor(node->size());
-
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Slice>(input, begin, size, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSoftmax *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->logits());
- Tensor *output = getOutputTensor(node);
-
- SoftmaxParams params{};
- params.beta = node->beta();
-
- return std::make_unique<kernels::Softmax>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSpaceToDepth *node)
-{
- assert(node->arity() == 1);
- const Tensor *input = getInputTensor(node->input());
-
- Tensor *output = getOutputTensor(node);
-
- SpaceToDepthParams params{};
- params.block_size = node->block_size();
-
- return std::make_unique<kernels::SpaceToDepth>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSplit *node)
-{
- auto output_nodes = collectOutputNodes<luci::CircleSplitOut>(node);
- assert(node->arity() == 2);
- assert(output_nodes.size() == static_cast<size_t>(node->num_split()));
-
- const Tensor *axis = getInputTensor(node->split_dim());
- const Tensor *input = getInputTensor(node->input());
- std::vector<Tensor *> outputs = getOutputTensors(output_nodes);
-
- // NOTE 'num_splits' attribute is ignored.
- return std::make_unique<kernels::Split>(axis, input, std::move(outputs));
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSqrt *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Sqrt>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleSqueeze *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->input());
- Tensor *output = getOutputTensor(node);
-
- SqueezeParams params{};
- params.squeeze_dims = node->squeeze_dims();
-
- return std::make_unique<kernels::Squeeze>(input, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleStridedSlice *node)
-{
- assert(node->arity() == 4);
-
- const Tensor *input = getInputTensor(node->input());
- const Tensor *begin = getInputTensor(node->begin());
- const Tensor *end = getInputTensor(node->end());
- const Tensor *strides = getInputTensor(node->strides());
-
- Tensor *output = getOutputTensor(node);
-
- StridedSliceParams params{};
- params.begin_mask = node->begin_mask();
- params.ellipsis_mask = node->ellipsis_mask();
- params.end_mask = node->end_mask();
- params.new_axis_mask = node->new_axis_mask();
- params.shrink_axis_mask = node->shrink_axis_mask();
-
- return std::make_unique<kernels::StridedSlice>(input, begin, end, strides, output, params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleTanh *node)
-{
- assert(node->arity() == 1);
-
- const Tensor *input = getInputTensor(node->x());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Tanh>(input, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleTranspose *node)
-{
- assert(node->arity() == 2);
-
- const Tensor *input = getInputTensor(node->a());
- const Tensor *perm = getInputTensor(node->perm());
- Tensor *output = getOutputTensor(node);
-
- return std::make_unique<kernels::Transpose>(input, perm, output);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleTransposeConv *node)
-{
- assert(node->arity() == 4);
-
- const Tensor *input_sizes = getInputTensor(node->inputSizes());
- const Tensor *filter = getInputTensor(node->filter());
- const Tensor *out_backprop = getInputTensor(node->outBackprop());
- const Tensor *bias = getOptionalInputTensor(node->bias());
-
- Tensor *output = getOutputTensor(node);
-
- TransposeConvParams params{};
- params.padding = node->padding();
- params.stride_height = node->stride()->h();
- params.stride_width = node->stride()->w();
-
- return std::make_unique<kernels::TransposeConv>(input_sizes, filter, out_backprop, bias, output,
- params);
-}
-
-std::unique_ptr<Kernel> KernelBuilder::visit(const luci::CircleUnpack *node)
-{
- auto output_nodes = collectOutputNodes<luci::CircleUnpackOut>(node);
- assert(node->arity() == 1);
- assert(output_nodes.size() == static_cast<size_t>(node->num()));
-
- const Tensor *input = getInputTensor(node->value());
- std::vector<Tensor *> outputs = getOutputTensors(output_nodes);
-
- UnpackParams params{};
- params.axis = node->axis();
-
- // NOTE 'num' attribute is ignored.
- return std::make_unique<kernels::Unpack>(input, std::move(outputs), params);
-}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/loader/KernelBuilder.h b/compiler/luci-interpreter/src/loader/KernelBuilder.h
deleted file mode 100644
index 663104700..000000000
--- a/compiler/luci-interpreter/src/loader/KernelBuilder.h
+++ /dev/null
@@ -1,116 +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.
- */
-
-#ifndef LUCI_INTERPRETER_LOADER_KERNELBUILDER_H
-#define LUCI_INTERPRETER_LOADER_KERNELBUILDER_H
-
-#include "core/Kernel.h"
-#include "core/RuntimeGraph.h"
-
-#include <luci/IR/CircleNodeVisitor.h>
-
-#include <memory>
-#include <vector>
-#include <unordered_map>
-
-namespace luci_interpreter
-{
-
-class KernelBuilder : public luci::CircleNodeVisitor<std::unique_ptr<Kernel>>
-{
-public:
- KernelBuilder(
- const std::unordered_map<const loco::Graph *, RuntimeGraph *> &graph_to_runtime_graph,
- const std::unordered_map<const loco::Node *, Tensor *> &node_to_tensor)
- : _graph_to_runtime_graph(graph_to_runtime_graph), _node_to_tensor(node_to_tensor)
- {
- }
-
- std::unique_ptr<Kernel> visit(const luci::CircleAdd *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleArgMax *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleAveragePool2D *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleConcatenation *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleConv2D *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleConst *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleDepthToSpace *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleDepthwiseConv2D *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleDiv *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleElu *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleFloor *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleFloorDiv *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleEqual *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleFullyConnected *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleGreater *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleGreaterEqual *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleIf *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleL2Normalize *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleL2Pool2D *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLeakyRelu *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLess *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLessEqual *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLocalResponseNormalization *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLogistic *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleLogSoftmax *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleInput *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleMaximum *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleMaxPool2D *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleMean *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleMinimum *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleMul *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleNotEqual *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleOutput *node) override;
- std::unique_ptr<Kernel> visit(const luci::CirclePad *node) override;
- std::unique_ptr<Kernel> visit(const luci::CirclePow *node) override;
- std::unique_ptr<Kernel> visit(const luci::CirclePRelu *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleRelu *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleRelu6 *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleReshape *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleResizeBilinear *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleResizeNearestNeighbor *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleReverseV2 *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleRsqrt *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSub *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSlice *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSoftmax *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSpaceToDepth *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSplit *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleStridedSlice *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSqrt *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleSqueeze *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleTanh *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleTranspose *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleTransposeConv *node) override;
- std::unique_ptr<Kernel> visit(const luci::CircleUnpack *node) override;
-
-private:
- const Tensor *getInputTensor(const loco::Node *node) const;
-
- const Tensor *getOptionalInputTensor(const loco::Node *node) const;
-
- Tensor *getOutputTensor(const loco::Node *node) const;
-
- std::vector<Tensor *> getOutputTensors(const std::vector<const loco::Node *> &nodes) const;
-
- RuntimeGraph *getRuntimeGraph(const loco::Graph *graph) const;
-
-private:
- const std::unordered_map<const loco::Graph *, RuntimeGraph *> &_graph_to_runtime_graph;
- const std::unordered_map<const loco::Node *, Tensor *> &_node_to_tensor;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_LOADER_KERNELBUILDER_H
diff --git a/compiler/luci-interpreter/src/loader/KernelBuilder.test.cpp b/compiler/luci-interpreter/src/loader/KernelBuilder.test.cpp
deleted file mode 100644
index ea055542d..000000000
--- a/compiler/luci-interpreter/src/loader/KernelBuilder.test.cpp
+++ /dev/null
@@ -1,1135 +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 "loader/GraphLoader.h"
-#include "loader/KernelBuilder.h"
-
-#include <kernels/Add.h>
-#include <kernels/ArgMax.h>
-#include <kernels/AveragePool2D.h>
-#include <kernels/Concatenation.h>
-#include <kernels/Conv2D.h>
-#include <kernels/DepthToSpace.h>
-#include <kernels/DepthwiseConv2D.h>
-#include <kernels/Div.h>
-#include <kernels/Elu.h>
-#include <kernels/Floor.h>
-#include <kernels/FloorDiv.h>
-#include <kernels/Equal.h>
-#include <kernels/FullyConnected.h>
-#include <kernels/Greater.h>
-#include <kernels/GreaterEqual.h>
-#include <kernels/L2Normalize.h>
-#include <kernels/L2Pool2D.h>
-#include <kernels/LeakyRelu.h>
-#include <kernels/Less.h>
-#include <kernels/LessEqual.h>
-#include <kernels/LocalResponseNormalization.h>
-#include <kernels/Logistic.h>
-#include <kernels/LogSoftmax.h>
-#include <kernels/Maximum.h>
-#include <kernels/MaxPool2D.h>
-#include <kernels/Mean.h>
-#include <kernels/Minimum.h>
-#include <kernels/Mul.h>
-#include <kernels/NotEqual.h>
-#include <kernels/Pad.h>
-#include <kernels/Pow.h>
-#include <kernels/Prelu.h>
-#include <kernels/Relu.h>
-#include <kernels/Relu6.h>
-#include <kernels/Reshape.h>
-#include <kernels/ResizeBilinear.h>
-#include <kernels/ResizeNearestNeighbor.h>
-#include <kernels/Reverse.h>
-#include <kernels/Rsqrt.h>
-#include <kernels/Slice.h>
-#include <kernels/Softmax.h>
-#include <kernels/SpaceToDepth.h>
-#include <kernels/Split.h>
-#include <kernels/Sqrt.h>
-#include <kernels/Sub.h>
-#include <kernels/Squeeze.h>
-#include <kernels/StridedSlice.h>
-#include <kernels/Tanh.h>
-#include <kernels/Transpose.h>
-#include <kernels/TransposeConv.h>
-#include <kernels/Unpack.h>
-
-#include <gmock/gmock.h>
-
-namespace luci_interpreter
-{
-namespace
-{
-
-using namespace testing;
-
-class KernelBuilderTest : public Test
-{
-protected:
- luci::CircleInput *createInputNode() { return createNode<luci::CircleInput>(); }
-
- template <typename NodeT, typename... Args> NodeT *createNode(Args &&... args)
- {
- auto *node = _graph.nodes()->create<NodeT>(std::forward<Args>(args)...);
- // The actual type does not matter for the purpose of the tests.
- // NOTE The type is meaningless for nodes with multiple outputs (corresponding *Out nodes carry
- // actual output types).
- node->dtype(loco::DataType::FLOAT32);
- return node;
- }
-
- template <typename NodeOutT> NodeOutT *createNodeOut(loco::Node *node, int index)
- {
- auto *node_out = createNode<NodeOutT>();
- node_out->input(node);
- node_out->index(index);
- return node_out;
- }
-
- template <typename KernelT> std::unique_ptr<KernelT> buildKernel(const luci::CircleNode *op)
- {
- std::unordered_map<const loco::Graph *, RuntimeGraph *> graph_to_runtime_graph;
-
- RuntimeGraph runtime_graph(nullptr);
- RuntimeToIR runtime_to_ir;
- GraphLoader graph_loader(&_graph, &runtime_graph, runtime_to_ir, graph_to_runtime_graph,
- _node_to_tensor);
- graph_loader.loadTensors();
-
- KernelBuilder kernel_builder(graph_to_runtime_graph, _node_to_tensor);
-
- auto kernel = op->accept(&kernel_builder);
- return std::unique_ptr<KernelT>(dynamic_cast<KernelT *>(kernel.release()));
- }
-
- void checkTensor(const Tensor *tensor, const loco::Node *node)
- {
- EXPECT_THAT(tensor, Eq(_node_to_tensor.at(node)));
- }
-
-private:
- loco::Graph _graph;
- std::unordered_map<const loco::Node *, Tensor *> _node_to_tensor;
-};
-
-TEST_F(KernelBuilderTest, Add)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleAdd>();
- op->x(input1);
- op->y(input2);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::Add>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, ArgMax)
-{
- auto *input = createInputNode();
- auto *axis = createInputNode();
-
- auto *op = createNode<luci::CircleArgMax>();
- op->input(input);
- op->dimension(axis);
-
- op->output_type(loco::DataType::FLOAT32);
-
- auto kernel = buildKernel<kernels::ArgMax>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->axis(), axis);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().output_type, Eq(op->output_type()));
-}
-
-TEST_F(KernelBuilderTest, AveragePool2D)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleAveragePool2D>();
- op->value(input);
-
- op->padding(luci::Padding::SAME);
- op->filter()->h(11);
- op->filter()->w(13);
- op->stride()->h(17);
- op->stride()->w(19);
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::AveragePool2D>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
- EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Concatenation)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleConcatenation>(2);
- op->values(0, input1);
- op->values(1, input2);
- op->axis(11);
-
- auto kernel = buildKernel<kernels::Concatenation>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(0), input1);
- checkTensor(kernel->input(1), input2);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
-}
-
-TEST_F(KernelBuilderTest, Conv2D)
-{
- auto *input = createInputNode();
- auto *filter = createInputNode();
- auto *bias = createInputNode();
-
- auto *op = createNode<luci::CircleConv2D>();
- op->input(input);
- op->filter(filter);
- op->bias(bias);
-
- op->padding(luci::Padding::SAME);
- op->stride()->h(11);
- op->stride()->w(13);
- op->dilation()->h(17);
- op->dilation()->w(19);
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::Conv2D>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->filter(), filter);
- checkTensor(kernel->bias(), bias);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
- EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
- EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, DepthToSpace)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleDepthToSpace>();
- op->input(input);
-
- op->block_size(11);
-
- auto kernel = buildKernel<kernels::DepthToSpace>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().block_size, Eq(op->block_size()));
-}
-
-TEST_F(KernelBuilderTest, DepthwiseConv2D)
-{
- auto *input = createInputNode();
- auto *filter = createInputNode();
- auto *bias = createInputNode();
-
- auto *op = createNode<luci::CircleDepthwiseConv2D>();
- op->input(input);
- op->filter(filter);
- op->bias(bias);
-
- op->padding(luci::Padding::SAME);
- op->depthMultiplier(11);
- op->stride()->h(13);
- op->stride()->w(17);
- op->dilation()->h(19);
- op->dilation()->w(23);
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::DepthwiseConv2D>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->filter(), filter);
- checkTensor(kernel->bias(), bias);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().depth_multiplier, Eq(op->depthMultiplier()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
- EXPECT_THAT(kernel->params().dilation_height_factor, Eq(op->dilation()->h()));
- EXPECT_THAT(kernel->params().dilation_width_factor, Eq(op->dilation()->w()));
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Div)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleDiv>();
- op->x(input1);
- op->y(input2);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::Div>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Elu)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleElu>();
- op->features(input);
-
- auto kernel = buildKernel<kernels::Elu>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Floor)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleFloor>();
- op->x(input);
-
- auto kernel = buildKernel<kernels::Floor>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, FloorDiv)
-{
- auto *x = createInputNode();
- auto *y = createInputNode();
-
- auto *op = createNode<luci::CircleFloorDiv>();
- op->x(x);
- op->y(y);
-
- auto kernel = buildKernel<kernels::FloorDiv>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x);
- checkTensor(kernel->y(), y);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Equal)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleEqual>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::Equal>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, FullyConnected)
-{
- auto *input = createInputNode();
- auto *weights = createInputNode();
- auto *bias = createInputNode();
-
- auto *op = createNode<luci::CircleFullyConnected>();
- op->input(input);
- op->weights(weights);
- op->bias(bias);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::FullyConnected>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->weights(), weights);
- checkTensor(kernel->bias(), bias);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Greater)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleGreater>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::Greater>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, GreaterEqual)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleGreaterEqual>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::GreaterEqual>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, L2Normalize)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleL2Normalize>();
- op->x(input);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::L2Normalize>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, L2Pool2D)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleL2Pool2D>();
- op->value(input);
-
- op->padding(luci::Padding::SAME);
- op->filter()->h(11);
- op->filter()->w(13);
- op->stride()->h(17);
- op->stride()->w(19);
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::L2Pool2D>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
- EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, LeakyRelu)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleLeakyRelu>();
- op->features(input);
-
- op->alpha(11.0f);
-
- auto kernel = buildKernel<kernels::LeakyRelu>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
-}
-
-TEST_F(KernelBuilderTest, Less)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleLess>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::Less>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, LessEqual)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleLessEqual>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::LessEqual>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, LocalResponseNormalization)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleLocalResponseNormalization>();
- op->input(input);
-
- op->radius(11);
- op->bias(13.0f);
- op->alpha(15.0f);
- op->beta(17.0f);
-
- auto kernel = buildKernel<kernels::LocalResponseNormalization>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().radius, Eq(op->radius()));
- EXPECT_THAT(kernel->params().bias, Eq(op->bias()));
- EXPECT_THAT(kernel->params().alpha, Eq(op->alpha()));
- EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
-}
-
-TEST_F(KernelBuilderTest, Logistic)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleLogistic>();
- op->x(input);
-
- auto kernel = buildKernel<kernels::Logistic>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, LogSoftmax)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleLogSoftmax>();
- op->logits(input);
-
- auto kernel = buildKernel<kernels::LogSoftmax>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Maximum)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleMaximum>();
- op->x(input1);
- op->y(input2);
-
- auto kernel = buildKernel<kernels::Maximum>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, MaxPool2D)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleMaxPool2D>();
- op->value(input);
-
- op->padding(luci::Padding::SAME);
- op->filter()->h(11);
- op->filter()->w(13);
- op->stride()->h(17);
- op->stride()->w(19);
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::MaxPool2D>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().filter_height, Eq(op->filter()->h()));
- EXPECT_THAT(kernel->params().filter_width, Eq(op->filter()->w()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Mean)
-{
- auto *input = createInputNode();
- auto *axes = createInputNode();
-
- auto *op = createNode<luci::CircleMean>();
- op->input(input);
- op->reduction_indices(axes);
-
- op->keep_dims(true);
-
- auto kernel = buildKernel<kernels::Mean>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->axes(), axes);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().keep_dims, Eq(op->keep_dims()));
-}
-
-TEST_F(KernelBuilderTest, Minimum)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleMinimum>();
- op->x(input1);
- op->y(input2);
-
- auto kernel = buildKernel<kernels::Minimum>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Mul)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleMul>();
- op->x(input1);
- op->y(input2);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::Mul>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, NotEqual)
-{
- auto *x_input = createInputNode();
- auto *y_input = createInputNode();
-
- auto *op = createNode<luci::CircleNotEqual>();
- op->x(x_input);
- op->y(y_input);
-
- auto kernel = buildKernel<kernels::NotEqual>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->x(), x_input);
- checkTensor(kernel->y(), y_input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Pad)
-{
- auto *input = createInputNode();
- auto *paddings = createInputNode();
-
- auto *op = createNode<luci::CirclePad>();
- op->input(input);
- op->paddings(paddings);
-
- auto kernel = buildKernel<kernels::Pad>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->paddings(), paddings);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Pow)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CirclePow>();
- op->x(input1);
- op->y(input2);
-
- auto kernel = buildKernel<kernels::Pow>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Prelu)
-{
- auto *input = createInputNode();
- auto *alpha = createInputNode();
-
- auto *op = createNode<luci::CirclePRelu>();
- op->input(input);
- op->alpha(alpha);
-
- auto kernel = buildKernel<kernels::Prelu>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->alpha(), alpha);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Relu)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleRelu>();
- op->features(input);
-
- auto kernel = buildKernel<kernels::Relu>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Relu6)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleRelu6>();
- op->features(input);
-
- auto kernel = buildKernel<kernels::Relu6>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Reshape)
-{
- auto *input = createInputNode();
- auto *shape = createInputNode();
-
- auto *op = createNode<luci::CircleReshape>();
- op->tensor(input);
- op->shape(shape);
-
- auto kernel = buildKernel<kernels::Reshape>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->shape(), shape);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, ResizeBilinear)
-{
- auto *input = createInputNode();
- auto *size = createInputNode();
-
- auto *op = createNode<luci::CircleResizeBilinear>();
- op->input(input);
- op->size(size);
- op->align_corners(true);
- op->half_pixel_centers(true);
-
- auto kernel = buildKernel<kernels::ResizeBilinear>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->size(), size);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
- EXPECT_THAT(kernel->params().half_pixel_centers, Eq(op->half_pixel_centers()));
-}
-
-TEST_F(KernelBuilderTest, ResizeNearestNeighbor)
-{
- auto *input = createInputNode();
- auto *size = createInputNode();
-
- auto *op = createNode<luci::CircleResizeNearestNeighbor>();
- op->input(input);
- op->size(size);
- op->align_corners(true);
-
- auto kernel = buildKernel<kernels::ResizeNearestNeighbor>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->size(), size);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().align_corners, Eq(op->align_corners()));
- // TODO currently half_pixel_centers are not implemented on CircleResizeNearestNeighbor
- // after adding, need to be updated.
-}
-
-TEST_F(KernelBuilderTest, ReverseV2)
-{
- auto *input = createInputNode();
- auto *axes = createInputNode();
-
- auto *op = createNode<luci::CircleReverseV2>();
- op->tensor(input);
- op->axis(axes);
-
- auto kernel = buildKernel<kernels::Reverse>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->axes(), axes);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Rsqrt)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleRsqrt>();
- op->x(input);
-
- auto kernel = buildKernel<kernels::Rsqrt>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Slice)
-{
- auto *input = createInputNode();
- auto *begin = createInputNode();
- auto *size = createInputNode();
-
- auto *op = createNode<luci::CircleSlice>();
- op->input(input);
- op->begin(begin);
- op->size(size);
-
- auto kernel = buildKernel<kernels::Slice>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->begin(), begin);
- checkTensor(kernel->size(), size);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Softmax)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleSoftmax>();
- op->logits(input);
-
- op->beta(11.0f);
-
- auto kernel = buildKernel<kernels::Softmax>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().beta, Eq(op->beta()));
-}
-
-TEST_F(KernelBuilderTest, SpaceToDepth)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleSpaceToDepth>();
- op->input(input);
-
- op->block_size(11);
-
- auto kernel = buildKernel<kernels::SpaceToDepth>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().block_size, op->block_size());
-}
-
-TEST_F(KernelBuilderTest, Split)
-{
- auto *axis = createInputNode();
- auto *input = createInputNode();
- auto *op = createNode<luci::CircleSplit>();
- auto *output1 = createNodeOut<luci::CircleSplitOut>(op, 0);
- auto *output2 = createNodeOut<luci::CircleSplitOut>(op, 1);
-
- op->split_dim(axis);
- op->input(input);
-
- op->num_split(2);
-
- auto kernel = buildKernel<kernels::Split>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->axis(), axis);
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(0), output1);
- checkTensor(kernel->output(1), output2);
-}
-
-TEST_F(KernelBuilderTest, Sqrt)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleSqrt>();
- op->x(input);
-
- auto kernel = buildKernel<kernels::Sqrt>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Sub)
-{
- auto *input1 = createInputNode();
- auto *input2 = createInputNode();
-
- auto *op = createNode<luci::CircleSub>();
- op->x(input1);
- op->y(input2);
-
- op->fusedActivationFunction(luci::FusedActFunc::RELU);
-
- auto kernel = buildKernel<kernels::Sub>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input1(), input1);
- checkTensor(kernel->input2(), input2);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().activation, Eq(op->fusedActivationFunction()));
-}
-
-TEST_F(KernelBuilderTest, Squeeze)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleSqueeze>();
- op->input(input);
-
- op->squeeze_dims({11, 13});
-
- auto kernel = buildKernel<kernels::Squeeze>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().squeeze_dims, ElementsAreArray(op->squeeze_dims()));
-}
-
-TEST_F(KernelBuilderTest, StridedSlice)
-{
- auto *input = createInputNode();
- auto *begin = createInputNode();
- auto *end = createInputNode();
- auto *strides = createInputNode();
-
- auto *op = createNode<luci::CircleStridedSlice>();
- op->input(input);
- op->begin(begin);
- op->end(end);
- op->strides(strides);
-
- op->begin_mask(11);
- op->ellipsis_mask(13);
- op->end_mask(17);
- op->new_axis_mask(19);
- op->shrink_axis_mask(23);
-
- auto kernel = buildKernel<kernels::StridedSlice>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->begin(), begin);
- checkTensor(kernel->end(), end);
- checkTensor(kernel->strides(), strides);
- checkTensor(kernel->output(), op);
- EXPECT_THAT(kernel->params().begin_mask, Eq(op->begin_mask()));
- EXPECT_THAT(kernel->params().ellipsis_mask, Eq(op->ellipsis_mask()));
- EXPECT_THAT(kernel->params().end_mask, Eq(op->end_mask()));
- EXPECT_THAT(kernel->params().new_axis_mask, Eq(op->new_axis_mask()));
- EXPECT_THAT(kernel->params().shrink_axis_mask, Eq(op->shrink_axis_mask()));
-}
-
-TEST_F(KernelBuilderTest, Tanh)
-{
- auto *input = createInputNode();
-
- auto *op = createNode<luci::CircleTanh>();
- op->x(input);
-
- auto kernel = buildKernel<kernels::Tanh>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, Transpose)
-{
- auto *input = createInputNode();
- auto *perm = createInputNode();
-
- auto *op = createNode<luci::CircleTranspose>();
- op->a(input);
- op->perm(perm);
-
- auto kernel = buildKernel<kernels::Transpose>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->perm(), perm);
- checkTensor(kernel->output(), op);
-}
-
-TEST_F(KernelBuilderTest, TransposeConv)
-{
- auto *output_shape = createInputNode();
- auto *filter = createInputNode();
- auto *input = createInputNode();
- auto *bias = createInputNode();
-
- auto *op = createNode<luci::CircleTransposeConv>();
- op->inputSizes(output_shape);
- op->filter(filter);
- op->outBackprop(input);
- op->bias(bias);
-
- op->padding(luci::Padding::SAME);
- op->stride()->h(11);
- op->stride()->w(13);
-
- auto kernel = buildKernel<kernels::TransposeConv>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->output_shape(), output_shape);
- checkTensor(kernel->filter(), filter);
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(), op);
- checkTensor(kernel->bias(), bias);
- EXPECT_THAT(kernel->params().padding, Eq(op->padding()));
- EXPECT_THAT(kernel->params().stride_height, Eq(op->stride()->h()));
- EXPECT_THAT(kernel->params().stride_width, Eq(op->stride()->w()));
-}
-
-TEST_F(KernelBuilderTest, Unpack)
-{
- auto *input = createInputNode();
- auto *op = createNode<luci::CircleUnpack>();
- auto *output1 = createNodeOut<luci::CircleUnpackOut>(op, 0);
- auto *output2 = createNodeOut<luci::CircleUnpackOut>(op, 1);
-
- op->value(input);
-
- op->num(2);
- op->axis(11);
-
- auto kernel = buildKernel<kernels::Unpack>(op);
- ASSERT_THAT(kernel, NotNull());
-
- checkTensor(kernel->input(), input);
- checkTensor(kernel->output(0), output1);
- checkTensor(kernel->output(1), output2);
- EXPECT_THAT(kernel->params().axis, Eq(op->axis()));
-}
-
-TEST_F(KernelBuilderTest, NonExisting1_NEG)
-{
- auto *op = createNode<luci::CircleConst>();
- ASSERT_ANY_THROW(buildKernel<Kernel>(op));
-}
-
-TEST_F(KernelBuilderTest, NonExisting2_NEG)
-{
- auto *op = createNode<luci::CircleInput>();
- ASSERT_ANY_THROW(buildKernel<Kernel>(op));
-}
-
-TEST_F(KernelBuilderTest, NonExisting3_NEG)
-{
- auto *op = createNode<luci::CircleOutput>();
- ASSERT_ANY_THROW(buildKernel<Kernel>(op));
-}
-
-} // namespace
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/loader/ModuleLoader.cpp b/compiler/luci-interpreter/src/loader/ModuleLoader.cpp
deleted file mode 100644
index b9a2ae0a9..000000000
--- a/compiler/luci-interpreter/src/loader/ModuleLoader.cpp
+++ /dev/null
@@ -1,52 +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 "ModuleLoader.h"
-
-#include "GraphLoader.h"
-
-namespace luci_interpreter
-{
-
-ModuleLoader::ModuleLoader(const luci::Module *module, RuntimeModule *runtime_module,
- RuntimeToIR &runtime_to_ir,
- std::unordered_map<const loco::Node *, Tensor *> &node_to_tensor)
- : _module(module), _runtime_module(runtime_module), _runtime_to_ir(runtime_to_ir),
- _node_to_tensor(node_to_tensor)
-{
-}
-
-void ModuleLoader::load()
-{
- // Runtime graphs have to be created in advance, because they will be needed during the loading
- // process for control flow nodes.
- for (size_t i = 0; i < _module->size(); ++i)
- {
- _graph_to_runtime_graph.emplace(_module->graph(i), _runtime_module->addGraph());
- }
- for (size_t i = 0; i < _module->size(); ++i)
- {
- const loco::Graph *graph = _module->graph(i);
- RuntimeGraph *runtime_graph = _graph_to_runtime_graph.at(graph);
- GraphLoader loader(graph, runtime_graph, _runtime_to_ir, _graph_to_runtime_graph,
- _node_to_tensor);
- loader.loadTensors();
- loader.initInputOutputTensors();
- loader.loadOperators();
- }
-}
-
-} // namespace luci_interpreter
diff --git a/compiler/luci-interpreter/src/loader/ModuleLoader.h b/compiler/luci-interpreter/src/loader/ModuleLoader.h
deleted file mode 100644
index 1af0ed747..000000000
--- a/compiler/luci-interpreter/src/loader/ModuleLoader.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#ifndef LUCI_INTERPRETER_LOADER_MODULELOADER_H
-#define LUCI_INTERPRETER_LOADER_MODULELOADER_H
-
-#include "core/RuntimeModule.h"
-#include "loader/RuntimeToIR.h"
-
-#include <luci/IR/Module.h>
-
-#include <unordered_map>
-
-namespace luci_interpreter
-{
-
-class ModuleLoader
-{
-public:
- ModuleLoader(const luci::Module *module, RuntimeModule *runtime_module,
- RuntimeToIR &runtime_to_ir,
- std::unordered_map<const loco::Node *, Tensor *> &node_to_tensor);
-
- void load();
-
-private:
- const luci::Module *_module;
- RuntimeModule *_runtime_module;
- RuntimeToIR &_runtime_to_ir;
- std::unordered_map<const loco::Node *, Tensor *> &_node_to_tensor;
- std::unordered_map<const loco::Graph *, RuntimeGraph *> _graph_to_runtime_graph;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_LOADER_MODULELOADER_H
diff --git a/compiler/luci-interpreter/src/loader/RuntimeToIR.h b/compiler/luci-interpreter/src/loader/RuntimeToIR.h
deleted file mode 100644
index 9ea8b1fa2..000000000
--- a/compiler/luci-interpreter/src/loader/RuntimeToIR.h
+++ /dev/null
@@ -1,38 +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.
- */
-
-#ifndef LUCI_INTERPRETER_LOADER_RUNTIMETOIR_H
-#define LUCI_INTERPRETER_LOADER_RUNTIMETOIR_H
-
-#include "luci_interpreter/core/Tensor.h"
-
-#include <luci/IR/CircleNode.h>
-
-#include <unordered_map>
-
-namespace luci_interpreter
-{
-
-// Maps runtime entities back to IR entities. It is used to implement observing functionality.
-struct RuntimeToIR
-{
- std::unordered_map<const Tensor *, const luci::CircleNode *> tensor_to_node;
- std::unordered_map<const Kernel *, const luci::CircleNode *> kernel_to_node;
-};
-
-} // namespace luci_interpreter
-
-#endif // LUCI_INTERPRETER_LOADER_RUNTIMETOIR_H