diff options
Diffstat (limited to 'compiler/tflchef')
171 files changed, 8722 insertions, 0 deletions
diff --git a/compiler/tflchef/CMakeLists.txt b/compiler/tflchef/CMakeLists.txt new file mode 100644 index 000000000..71c5e2ab1 --- /dev/null +++ b/compiler/tflchef/CMakeLists.txt @@ -0,0 +1,19 @@ +nnas_find_package(Protobuf QUIET) + +if(NOT Protobuf_FOUND) + return() +endif(NOT Protobuf_FOUND) + +if(NOT TARGET mio_tflite) + return() +endif(NOT TARGET mio_tflite) + +# Recipe Parser +add_subdirectory(proto) +# Core Library +add_subdirectory(core) +# TFlite Library +add_subdirectory(tflite) +# Tools +add_subdirectory(tools) +add_subdirectory(tests) diff --git a/compiler/tflchef/README.md b/compiler/tflchef/README.md new file mode 100644 index 000000000..c940f2203 --- /dev/null +++ b/compiler/tflchef/README.md @@ -0,0 +1,76 @@ +# tflchef + +## What is tflchef? + +Do you need a tensorflow lite model for testing? Ask it to _tflchef_. +Given a recipe, _tflchef_ will cook a tensorflow lite model for you. + +**NOTE** A model that _tflchef_ generates is compatible with TensorFlow Lite in TensorFlow v1.12.0 release + +## Tutorial: How to use? + +This example explains how to generate a tensorflow lite model with a single Conv2D operation +with a kernel filled with random values generated according to normal (or gaussian) distribution (mean = 0.0f / stddev = 1.0f) and bias with constant values (1.1f) with _tflchef_. + +The first step is to write a recipe! +Type the following command, and then you may get ``sample.recipe``: +``` +$ cat > sample.recipe <<END +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } +} +operand { + name: "ker" + type: FLOAT32 + shape { dim: 1 dim: 1 dim: 1 dim: 2 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "bias" + type: FLOAT32 + shape { dim: 1 } + filler { + tag: "constant" + arg: "1.1" + } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 1 } +} +operation { + type: "Conv2D" + conv2d_options { + padding: VALID + stride_w: 1 + stride_h: 1 + } + input: "ifm" + input: "ker" + input: "bias" + output: "ofm" +} +input: "ifm" +input: "ker" +output: "ofm" +END +``` + +Generate ``sample.tflite`` from ``sample.recipe`` with one of the following commands: +- With redirection +``` +$ cat sample.recipe | tflchef > sample.tflite +``` +- Without redirection +``` +$ tflchef-file sample.recipe sample.tflite +``` + +Done :) diff --git a/compiler/tflchef/core/CMakeLists.txt b/compiler/tflchef/core/CMakeLists.txt new file mode 100644 index 000000000..6a6282027 --- /dev/null +++ b/compiler/tflchef/core/CMakeLists.txt @@ -0,0 +1,7 @@ +file(GLOB_RECURSE SOURCES "src/*.cpp") + +add_library(tflchef_core STATIC ${SOURCES}) +target_include_directories(tflchef_core PUBLIC include) +target_include_directories(tflchef_core PRIVATE src) +target_link_libraries(tflchef_core tflchef_proto) +target_link_libraries(tflchef_core mio_tflite) diff --git a/compiler/tflchef/core/include/tflchef/ModelChef.h b/compiler/tflchef/core/include/tflchef/ModelChef.h new file mode 100644 index 000000000..4e22f7555 --- /dev/null +++ b/compiler/tflchef/core/include/tflchef/ModelChef.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MODEL_CHEF_H__ +#define __MODEL_CHEF_H__ + +#include <tflchef.pb.h> + +#include <memory> + +namespace tflchef +{ + +class GeneratedModel final +{ +public: + struct Impl + { + virtual ~Impl() = default; + + virtual const char *base(void) const = 0; + virtual size_t size(void) const = 0; + }; + +public: + GeneratedModel(std::unique_ptr<Impl> &&impl) : _impl{std::move(impl)} + { + // DO NOTHING + } + +public: + const char *base(void) const { return _impl->base(); } + size_t size(void) const { return _impl->size(); } + +private: + std::unique_ptr<Impl> _impl; +}; + +GeneratedModel cook(const ModelRecipe &model_recipe); + +} // namespace tflchef + +#endif // __MODEL_CHEF_H__ diff --git a/compiler/tflchef/core/src/Arguments.h b/compiler/tflchef/core/src/Arguments.h new file mode 100644 index 000000000..341aea6c9 --- /dev/null +++ b/compiler/tflchef/core/src/Arguments.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ARGUMENTS_H__ +#define __ARGUMENTS_H__ + +#include <cstdint> +#include <string> + +/** + * @brief Read-only string sequence view + */ +struct Arguments +{ + virtual ~Arguments() = default; + + virtual uint32_t count(void) const = 0; + virtual const std::string &value(uint32_t n) const = 0; +}; + +#endif // __ARGUMENTS_H__ diff --git a/compiler/tflchef/core/src/Convert.cpp b/compiler/tflchef/core/src/Convert.cpp new file mode 100644 index 000000000..86a31d9b7 --- /dev/null +++ b/compiler/tflchef/core/src/Convert.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Convert.h" + +#include <stdexcept> + +tflite::Padding as_tflite_padding(const tflchef::Padding &value) +{ + switch (value) + { + case tflchef::SAME: + return tflite::Padding_SAME; + case tflchef::VALID: + return tflite::Padding_VALID; + default: + break; + } + + throw std::runtime_error{"Unknown padding value"}; +} + +tflite::ActivationFunctionType as_tflite_activation(const tflchef::Activation &value) +{ + switch (value) + { + case tflchef::NONE: + return tflite::ActivationFunctionType_NONE; + case tflchef::RELU: + return tflite::ActivationFunctionType_RELU; + case tflchef::RELU6: + return tflite::ActivationFunctionType_RELU6; + default: + break; + } + + throw std::runtime_error{"Unknown activation"}; +} + +tflite::TensorType as_tflite_tensortype(const tflchef::TensorType &value) +{ + switch (value) + { + case tflchef::FLOAT32: + return tflite::TensorType_FLOAT32; + case tflchef::INT32: + return tflite::TensorType_INT32; + case tflchef::UINT8: + return tflite::TensorType_UINT8; + case tflchef::INT64: + return tflite::TensorType_INT64; + case tflchef::BOOL: + return tflite::TensorType_BOOL; + default: + break; + } + + throw std::runtime_error{"Unknown tensor type"}; +} diff --git a/compiler/tflchef/core/src/Convert.h b/compiler/tflchef/core/src/Convert.h new file mode 100644 index 000000000..ed15a5572 --- /dev/null +++ b/compiler/tflchef/core/src/Convert.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Convert.h + * @brief This header declares various as_tflite_TYPE functions + */ +#ifndef __CONVERT_H__ +#define __CONVERT_H__ + +#include <tflchef.pb.h> +#include <mio/tflite/schema_generated.h> + +tflite::Padding as_tflite_padding(const tflchef::Padding &value); +tflite::ActivationFunctionType as_tflite_activation(const tflchef::Activation &value); +tflite::TensorType as_tflite_tensortype(const tflchef::TensorType &value); + +#endif // __CONVERT_H__ diff --git a/compiler/tflchef/core/src/Data/Constant.h b/compiler/tflchef/core/src/Data/Constant.h new file mode 100644 index 000000000..ebe1f3d93 --- /dev/null +++ b/compiler/tflchef/core/src/Data/Constant.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONSTANT_FILLER_H__ +#define __CONSTANT_FILLER_H__ + +#include "DataChef.h" +#include "LexicalCast.h" + +template <typename T> class ConstantDataChef final : public DataChef +{ +public: + ConstantDataChef(const T &value) : _value{value} + { + // DO NOTHING + } + +public: + std::vector<uint8_t> generate(int32_t count) const override + { + std::vector<uint8_t> res; + + for (uint32_t n = 0; n < count; ++n) + { + const uint8_t *arr = reinterpret_cast<const uint8_t *>(&_value); + + for (uint32_t b = 0; b < sizeof(T); ++b) + { + res.emplace_back(arr[b]); + } + } + + return res; + } + +private: + T _value; +}; + +template <typename T> struct ConstantDataChefFactory : public DataChefFactory +{ + std::unique_ptr<DataChef> create(const Arguments &args) const + { + auto const value = to_number<T>(args.value(0)); + return std::unique_ptr<DataChef>{new ConstantDataChef<T>{value}}; + } +}; + +#endif // __CONSTANT_FILLER_H__ diff --git a/compiler/tflchef/core/src/Data/Explicit.h b/compiler/tflchef/core/src/Data/Explicit.h new file mode 100644 index 000000000..088e791b9 --- /dev/null +++ b/compiler/tflchef/core/src/Data/Explicit.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __EXPLICIT_FILLER_H__ +#define __EXPLICIT_FILLER_H__ + +#include "DataChef.h" +#include "LexicalCast.h" + +#include <vector> + +template <typename T> class ExplicitDataChef final : public DataChef +{ +public: + ExplicitDataChef() + { + // DO NOTHING + } + +public: + std::vector<uint8_t> generate(int32_t count) const override + { + std::vector<uint8_t> res; + + for (uint32_t n = 0; n < count; ++n) + { + T const value = (n < _values.size()) ? _values.at(n) : T{}; + const uint8_t *arr = reinterpret_cast<const uint8_t *>(&value); + + for (uint32_t b = 0; b < sizeof(T); ++b) + { + res.emplace_back(arr[b]); + } + } + + return res; + } + +public: + void insert(const T &value) { _values.emplace_back(value); } + +private: + std::vector<T> _values; +}; + +template <typename T> struct ExplicitDataChefFactory : public DataChefFactory +{ + std::unique_ptr<DataChef> create(const Arguments &args) const + { + std::unique_ptr<ExplicitDataChef<T>> res{new ExplicitDataChef<T>}; + + for (uint32_t n = 0; n < args.count(); ++n) + { + auto const value = to_number<T>(args.value(n)); + res->insert(value); + } + + return std::move(res); + } +}; + +#endif // __EXPLICIT_FILLER_H__ diff --git a/compiler/tflchef/core/src/Data/Gaussian.cpp b/compiler/tflchef/core/src/Data/Gaussian.cpp new file mode 100644 index 000000000..c515d1104 --- /dev/null +++ b/compiler/tflchef/core/src/Data/Gaussian.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Gaussian.h" +#include "LexicalCast.h" + +#include <random> +#include <chrono> + +#include <cassert> +#include <stdexcept> + +std::vector<uint8_t> GaussianFloat32DataChef::generate(int32_t count) const +{ + // TODO Support seed value override + int seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::minstd_rand rand{seed}; + std::normal_distribution<float> dist{_mean, _stddev}; + + std::vector<uint8_t> res; + + for (uint32_t n = 0; n < count; ++n) + { + auto const value = dist(rand); + auto const arr = reinterpret_cast<const uint8_t *>(&value); + + for (uint32_t b = 0; b < sizeof(float); ++b) + { + res.emplace_back(arr[b]); + } + } + + return res; +} + +std::vector<uint8_t> GaussianInt32DataChef::generate(int32_t count) const +{ + // TODO Support seed value override + int seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::minstd_rand rand{seed}; + std::normal_distribution<float> dist{_mean, _stddev}; + + std::vector<uint8_t> res; + + for (uint32_t n = 0; n < count; ++n) + { + auto const value = static_cast<int32_t>(dist(rand)); + auto const arr = reinterpret_cast<const uint8_t *>(&value); + + for (uint32_t b = 0; b < sizeof(int32_t); ++b) + { + res.emplace_back(arr[b]); + } + } + + return res; +} + +std::vector<uint8_t> GaussianUint8DataChef::generate(int32_t count) const +{ + // TODO Support seed value override + int seed = std::chrono::system_clock::now().time_since_epoch().count(); + + std::minstd_rand rand{seed}; + std::normal_distribution<float> dist{_mean, _stddev}; + + std::vector<uint8_t> res; + + for (uint32_t n = 0; n < count; ++n) + { + auto const value = static_cast<uint8_t>(dist(rand)); // uint8_t for data type + auto const arr = reinterpret_cast<const uint8_t *>(&value); // uint8_t for byte streaming + + for (uint32_t b = 0; b < sizeof(uint8_t); ++b) + { + res.emplace_back(arr[b]); + } + } + + return res; +} + +std::unique_ptr<DataChef> GaussianFloat32DataChefFactory::create(const Arguments &args) const +{ + if (args.count() != 2) + { + throw std::runtime_error{"invalid argument count: two arguments (mean/stddev) are expected"}; + } + + auto const mean = to_number<float>(args.value(0)); + auto const stddev = to_number<float>(args.value(1)); + + return std::unique_ptr<DataChef>{new GaussianFloat32DataChef{mean, stddev}}; +} + +std::unique_ptr<DataChef> GaussianInt32DataChefFactory::create(const Arguments &args) const +{ + if (args.count() != 2) + { + throw std::runtime_error{"invalid argument count: two arguments (mean/stddev) are expected"}; + } + + auto const mean = to_number<float>(args.value(0)); + auto const stddev = to_number<float>(args.value(1)); + + return std::unique_ptr<DataChef>{new GaussianInt32DataChef{mean, stddev}}; +} + +std::unique_ptr<DataChef> GaussianUint8DataChefFactory::create(const Arguments &args) const +{ + if (args.count() != 2) + { + throw std::runtime_error{"invalid argument count: two arguments (mean/stddev) are expected"}; + } + + auto const mean = to_number<float>(args.value(0)); + auto const stddev = to_number<float>(args.value(1)); + + return std::unique_ptr<DataChef>{new GaussianUint8DataChef{mean, stddev}}; +} diff --git a/compiler/tflchef/core/src/Data/Gaussian.h b/compiler/tflchef/core/src/Data/Gaussian.h new file mode 100644 index 000000000..81a28d2d1 --- /dev/null +++ b/compiler/tflchef/core/src/Data/Gaussian.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GAUSSIAN_FILLER_H__ +#define __GAUSSIAN_FILLER_H__ + +#include "DataChef.h" + +/** + * @brief Generate a sequence of random values according to the gaussian(=normal) distribution + */ +class GaussianFloat32DataChef final : public DataChef +{ +public: + GaussianFloat32DataChef(float mean, float stddev) : _mean{mean}, _stddev{stddev} + { + // DO NOTHING + } + +public: + std::vector<uint8_t> generate(int32_t count) const override; + +private: + float _mean; + float _stddev; +}; + +class GaussianInt32DataChef final : public DataChef +{ +public: + GaussianInt32DataChef(float mean, float stddev) : _mean{mean}, _stddev{stddev} + { + // DO NOTHING + } + +public: + std::vector<uint8_t> generate(int32_t count) const override; + +private: + float _mean; + float _stddev; +}; + +class GaussianUint8DataChef final : public DataChef +{ +public: + GaussianUint8DataChef(float mean, float stddev) : _mean{mean}, _stddev{stddev} + { + // DO NOTHING + } + +public: + std::vector<uint8_t> generate(int32_t count) const override; + +private: + float _mean; + float _stddev; +}; + +struct GaussianFloat32DataChefFactory : public DataChefFactory +{ + std::unique_ptr<DataChef> create(const Arguments &args) const; +}; + +struct GaussianInt32DataChefFactory : public DataChefFactory +{ + std::unique_ptr<DataChef> create(const Arguments &args) const; +}; + +struct GaussianUint8DataChefFactory : public DataChefFactory +{ + std::unique_ptr<DataChef> create(const Arguments &args) const; +}; + +#endif // __GAUSSIAN_FILLER_H__ diff --git a/compiler/tflchef/core/src/DataChef.def b/compiler/tflchef/core/src/DataChef.def new file mode 100644 index 000000000..89d34a202 --- /dev/null +++ b/compiler/tflchef/core/src/DataChef.def @@ -0,0 +1,15 @@ +#ifndef DATA_CHEF +#error "Define DATA_CHEF first" +#endif // DATA_CHEF + +// DATA_CHEF(TYPE, NAME, FACTORY_CLASS) +// "TYPE" SHOULD BE an enum tag of tflchef::TensorType +DATA_CHEF(FLOAT32, constant, ConstantDataChefFactory<float>) +DATA_CHEF(BOOL, constant, ConstantDataChefFactory<bool>) +DATA_CHEF(INT32, explicit, ExplicitDataChefFactory<int>) +DATA_CHEF(UINT8, explicit, ExplicitDataChefFactory<uint8_t>) +DATA_CHEF(BOOL, explicit, ExplicitDataChefFactory<bool>) +DATA_CHEF(FLOAT32, explicit, ExplicitDataChefFactory<float>) +DATA_CHEF(FLOAT32, gaussian, GaussianFloat32DataChefFactory) +DATA_CHEF(INT32, gaussian, GaussianInt32DataChefFactory) +DATA_CHEF(UINT8, gaussian, GaussianUint8DataChefFactory) diff --git a/compiler/tflchef/core/src/DataChef.h b/compiler/tflchef/core/src/DataChef.h new file mode 100644 index 000000000..d0571028a --- /dev/null +++ b/compiler/tflchef/core/src/DataChef.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DATA_CHEF_H__ +#define __DATA_CHEF_H__ + +#include "Arguments.h" + +#include <cstdint> +#include <memory> +#include <vector> + +using Data = std::vector<uint8_t>; + +/** + * @brief Data Generator + */ +struct DataChef +{ + virtual ~DataChef() = default; + + // TODO Allow users to query the type of elements that this DataChef generates + + /** + * @brief Generate a sequence of 'count' elements as a byte sequence + * + * Let D be the return value of generate(N). + * Then, D.size() == N * sizeof(T) where T is the element type. + */ + virtual Data generate(int32_t count) const = 0; +}; + +/** + * @brief Data Generator Factory + */ +struct DataChefFactory +{ + virtual ~DataChefFactory() = default; + + virtual std::unique_ptr<DataChef> create(const Arguments &args) const = 0; +}; + +#endif // __DATA_CHEF_H__ diff --git a/compiler/tflchef/core/src/DataChefs.h b/compiler/tflchef/core/src/DataChefs.h new file mode 100644 index 000000000..2310ae89d --- /dev/null +++ b/compiler/tflchef/core/src/DataChefs.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DATA_CHEFS_H__ +#define __DATA_CHEFS_H__ + +#include "Data/Constant.h" +#include "Data/Explicit.h" +#include "Data/Gaussian.h" + +#endif // __DATA_CHEFS_H__ diff --git a/compiler/tflchef/core/src/Dataset.h b/compiler/tflchef/core/src/Dataset.h new file mode 100644 index 000000000..9d5c7a43f --- /dev/null +++ b/compiler/tflchef/core/src/Dataset.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DATASET_H__ +#define __DATASET_H__ + +#include <vector> + +template <typename T> class Dataset +{ +public: + Dataset(const std::vector<T> &vec) : _vec{vec} + { + // DO NOTHING + } + +public: + Dataset(std::vector<T> &&vec) : _vec{std::move(vec)} + { + // DO NOTHING + } + +public: + template <typename Func> auto map(Func f) const -> Dataset<decltype(f(std::declval<T>()))> + { + using U = decltype(f(std::declval<T>())); + std::vector<U> res; + + for (const auto &elem : _vec) + { + res.emplace_back(f(elem)); + } + + return Dataset<U>(std::move(res)); + } + +public: + const std::vector<T> &vectorize(void) const { return _vec; } + +private: + std::vector<T> _vec; +}; + +#endif // __DATASET_H__ diff --git a/compiler/tflchef/core/src/LexicalCast.cpp b/compiler/tflchef/core/src/LexicalCast.cpp new file mode 100644 index 000000000..38a5f9290 --- /dev/null +++ b/compiler/tflchef/core/src/LexicalCast.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LexicalCast.h" + +#include <cassert> +#include <limits> + +template <> float to_number(const std::string &s) { return std::stof(s); } +template <> int to_number(const std::string &s) { return std::stoi(s); } +template <> uint8_t to_number(const std::string &s) +{ + int temp = std::stoi(s); + assert(temp >= 0); + assert(temp <= std::numeric_limits<uint8_t>::max()); + return static_cast<uint8_t>(temp); +} +template <> bool to_number(const std::string &s) +{ + if (std::stoi(s) || s == "T" || s == "t" || s == "TRUE" || s == "true") + return true; + return false; +} diff --git a/compiler/tflchef/core/src/LexicalCast.h b/compiler/tflchef/core/src/LexicalCast.h new file mode 100644 index 000000000..4aeccb482 --- /dev/null +++ b/compiler/tflchef/core/src/LexicalCast.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @brief This file provides string <-> number cast helpers + */ +#ifndef __LEXICAL_CAST_H__ +#define __LEXICAL_CAST_H__ + +#include <string> + +/** + * @brief Return a numeric value that corresponds to a given string + * + * @note This function will throw an exception on casting failure + */ +template <typename Number> Number to_number(const std::string &s); + +#endif // __LEXICAL_CAST_H__ diff --git a/compiler/tflchef/core/src/ModelChef.cpp b/compiler/tflchef/core/src/ModelChef.cpp new file mode 100644 index 000000000..2c69efd4b --- /dev/null +++ b/compiler/tflchef/core/src/ModelChef.cpp @@ -0,0 +1,765 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tflchef/ModelChef.h" +#include "Arguments.h" + +#include "Convert.h" + +#include "DataChef.h" +#include "DataChefs.h" + +#include "OpChef.h" +#include "OpChefs.h" + +#include "Dataset.h" + +#include <iterator> +#include <map> +#include <string> +#include <vector> + +#include <cassert> +#include <fstream> +#include <iostream> +#include <numeric> +#include <sstream> +#include <stdexcept> + +namespace +{ + +template <typename InputIt> class RangedArguments : public Arguments +{ +public: + RangedArguments(InputIt beg, InputIt end) : _beg{beg}, _end{end} + { + // DO NOTHING + } + +public: + uint32_t count(void) const override { return _end - _beg; } + +public: + const std::string &value(uint32_t n) const override { return *(_beg + n); } + +private: + InputIt _beg; + InputIt _end; +}; + +template <typename InputIt> RangedArguments<InputIt> ranged_arguments(InputIt beg, InputIt end) +{ + return RangedArguments<InputIt>{beg, end}; +} + +} // namespace + +namespace +{ + +template <typename T> std::vector<T> as_vector(const ::google::protobuf::RepeatedPtrField<T> &field) +{ + std::vector<T> res; + for (const auto &elem : field) + { + res.emplace_back(elem); + } + return res; +} + +template <typename T> Dataset<T> as_dataset(const ::google::protobuf::RepeatedPtrField<T> &field) +{ + return Dataset<T>(as_vector<T>(field)); +} + +} // namespace + +namespace +{ + +template <typename T> using Dims = std::vector<T>; + +Dims<int32_t> as_dims(const tflchef::TensorShape &shape) +{ + std::vector<int32_t> res; + + for (auto &dim : shape.dim()) + { + res.emplace_back(static_cast<int32_t>(dim)); + } + + return res; +} + +int32_t element_count(const Dims<int32_t> &dims) +{ + return std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int32_t>()); +} + +} // namespace + +namespace +{ + +class GeneratedModelImpl final : public tflchef::GeneratedModel::Impl +{ +public: + GeneratedModelImpl(std::unique_ptr<flatbuffers::FlatBufferBuilder> &&builder) + : _builder{std::move(builder)} + { + // DO NOTHING + } + +public: + const char *base(void) const override + { + // Return the base address of generated flatbuffer model + return reinterpret_cast<const char *>(_builder->GetBufferPointer()); + } + +public: + size_t size(void) const override + { + // Return the size of generated flatbuffer model + return _builder->GetSize(); + } + +private: + std::unique_ptr<flatbuffers::FlatBufferBuilder> _builder; +}; + +} // namespace + +namespace +{ + +template <typename T> class Registry +{ +public: + void add(const std::string &name, std::unique_ptr<T> &&entry) + { + _content[name] = std::move(entry); + } + + const T &lookup(const std::string &name) const { return *(_content.at(name)); } + +private: + std::map<std::string, std::unique_ptr<T>> _content; +}; + +struct DataChefRegistry final : public Registry<DataChefFactory> +{ +}; + +DataChefRegistry &data_chef_registry(const tflchef::TensorType &type) +{ + static DataChefRegistry s32; + static DataChefRegistry fp32; + static DataChefRegistry u8; + static DataChefRegistry boolean; + + switch (type) + { + case tflchef::INT32: + return s32; + case tflchef::FLOAT32: + return fp32; + case tflchef::UINT8: + return u8; + case tflchef::BOOL: + return boolean; + default: + break; + } + + throw std::runtime_error{"Unknown tensor type"}; +} + +struct OpChefRegistry final : public Registry<OpChefFactory> +{ +}; + +OpChefRegistry &op_chef_registry(void) +{ + static OpChefRegistry registry; + return registry; +} + +// @brief This will prepare a set of unique operator codes in the mode recipe +std::set<tflite::BuiltinOperator> gather_opcode_set(const ::tflchef::ModelRecipe &model_recipe) +{ + std::set<tflite::BuiltinOperator> opcode_set; + for (const auto &operation : model_recipe.operation()) + { + auto op_chef = op_chef_registry().lookup(operation.type()).create(&operation); + opcode_set.insert(op_chef->code()); + } + + // Add ops used in Graphs(subgraphs) + for (int g = 0; g < model_recipe.graph_size(); ++g) + { + const auto &graph = model_recipe.graph(g); + for (const auto &operation : graph.operation()) + { + auto op_chef = op_chef_registry().lookup(operation.type()).create(&operation); + opcode_set.insert(op_chef->code()); + } + } + + return opcode_set; +} + +} // namespace + +namespace tflchef +{ + +/** + * @brief Generate a (in-memory) TensorFlow Lite model from a given model recipe + */ +GeneratedModel cook(const ::tflchef::ModelRecipe &model_recipe) +{ +// Initialize Op Chef Registry +#define OP_CHEF(NAME, FACTORY_CLASS) \ + op_chef_registry().add(#NAME, std::unique_ptr<FACTORY_CLASS>(new FACTORY_CLASS())); +#include "OpChef.def" +#undef OP_CHEF + +// Initialize Data Chef Registry +#define DATA_CHEF(TYPE, NAME, FACTORY_CLASS) \ + data_chef_registry(::tflchef::TYPE) \ + .add(#NAME, std::unique_ptr<FACTORY_CLASS>(new FACTORY_CLASS())); +#include "DataChef.def" +#undef DATA_CHEF + + // + // Create FlatBufferBuilder + // + auto flatbuffer_builder = + std::unique_ptr<flatbuffers::FlatBufferBuilder>(new flatbuffers::FlatBufferBuilder(1024)); + + // Operand-related + std::vector<flatbuffers::Offset<::tflite::Buffer>> buffer_vec; + + // Operation-related + std::vector<flatbuffers::Offset<::tflite::OperatorCode>> code_vec; + + // Graphs-related + std::vector<flatbuffers::Offset<::tflite::SubGraph>> subgraph_vec; + + // Create OperatorCode + std::set<tflite::BuiltinOperator> opcode_set = gather_opcode_set(model_recipe); + for (auto opcode : opcode_set) + { + tflite::OperatorCodeBuilder code_builder{*flatbuffer_builder}; + code_builder.add_builtin_code(opcode); + auto code = code_builder.Finish(); + // Update OperatorCode vector + code_vec.emplace_back(code); + } + + // Create an Empty Buffer + // + // Buffer 0 SHOULD be an empty buffer in TensorFlow Lite model file + // (Please refer to the comment for Tensor.buffer field in schema) + { + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_vec.emplace_back(buffer_builder.Finish()); + } + + // + // Create Main graph + // + { + // Operand-related + std::vector<flatbuffers::Offset<::tflite::Tensor>> tensor_vec; + + // Operation-related + std::vector<flatbuffers::Offset<::tflite::Operator>> operator_vec; + + // Tensor Name -> Tensor ID mapping (per Graph) + std::map<std::string, int32_t> symbol_table; + + auto lookup = [&symbol_table](const std::string &name) { return symbol_table.at(name); }; + + int32_t buffer_start = buffer_vec.size(); + int32_t buffer_index = 0; + + // Create buffer(s) 1~n(I) for input(s) + const auto size_input = model_recipe.input_size(); + for (int ci = 0; ci < size_input; ++ci) + { + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_vec.emplace_back(buffer_builder.Finish()); + } + // Create buffer(s) n(I)+1~n(I)+n(O) for output(s) + const auto size_output = model_recipe.output_size(); + for (int co = 0; co < size_output; ++co) + { + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_vec.emplace_back(buffer_builder.Finish()); + } + + // default name for main graph + std::string graph_name = "main"; + if (model_recipe.has_name()) + graph_name = model_recipe.name(); + + auto input_names = as_dataset(model_recipe.input()).vectorize(); + auto output_names = as_dataset(model_recipe.output()).vectorize(); + + for (const auto &operand : model_recipe.operand()) + { + assert(operand.has_name()); + + assert(operand.has_type()); + assert(operand.has_shape()); + + std::vector<int32_t> dims = as_dims(operand.shape()); + + auto shape = flatbuffer_builder->CreateVector(dims); + auto name = flatbuffer_builder->CreateString(operand.name()); + + buffer_index = 0; + + // Create Buffer if filler is specified + if (operand.has_filler()) + { + const auto &filler = operand.filler(); + + assert(filler.has_tag()); + + auto args = ranged_arguments(filler.arg().begin(), filler.arg().end()); + auto chef = data_chef_registry(operand.type()).lookup(filler.tag()).create(args); + + assert(chef != nullptr); + + // Create Data + auto data_vec = chef->generate(element_count(dims)); + auto data = flatbuffer_builder->CreateVector(data_vec); + + // Create Buffer + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_builder.add_data(data); + auto buffer = buffer_builder.Finish(); + + // Update Buffer Index & Vector + buffer_index = buffer_vec.size(); + buffer_vec.emplace_back(buffer); + } + else + { + // if this is input or output, assign to that buffer_index + int idx = 0; + for (auto it = input_names.begin(); it != input_names.end(); ++it, ++idx) + { + if (*it == operand.name()) + { + buffer_index = buffer_start + idx; + break; + } + } + if (buffer_index == 0) + { + idx = 0; + for (auto it = output_names.begin(); it != output_names.end(); ++it, ++idx) + { + if (*it == operand.name()) + { + buffer_index = buffer_start + size_input + idx; + break; + } + } + } + } + + flatbuffers::Offset<tflite::QuantizationParameters> quant_index; + + // Create QuantizationParameters if quant is specified + if (operand.has_quant()) + { + const auto &quant = operand.quant(); + + // Create each parameters + // NOTE if some parameters are not given, those will be set to default value + std::vector<float> quant_max_vec(quant.max_size()); + std::vector<float> quant_min_vec(quant.min_size()); + std::vector<float> quant_scale_vec(quant.scale_size()); + std::vector<int64_t> quant_zero_point_vec(quant.zero_point_size()); + + for (uint32_t i = 0; i < quant.max_size(); ++i) + quant_max_vec.at(i) = quant.max(i); + for (uint32_t i = 0; i < quant.min_size(); ++i) + quant_min_vec.at(i) = quant.min(i); + for (uint32_t i = 0; i < quant.scale_size(); ++i) + quant_scale_vec.at(i) = quant.scale(i); + for (uint32_t i = 0; i < quant.zero_point_size(); ++i) + quant_zero_point_vec.at(i) = quant.zero_point(i); + + auto quant_max = flatbuffer_builder->CreateVector(quant_max_vec); + auto quant_min = flatbuffer_builder->CreateVector(quant_min_vec); + auto quant_scale = flatbuffer_builder->CreateVector(quant_scale_vec); + auto quant_zero_point = flatbuffer_builder->CreateVector(quant_zero_point_vec); + + // Create QuantizationParameters + tflite::QuantizationParametersBuilder quant_builder{*flatbuffer_builder}; + quant_builder.add_max(quant_max); + quant_builder.add_min(quant_min); + quant_builder.add_scale(quant_scale); + quant_builder.add_zero_point(quant_zero_point); + + // Update QuantizationParameters Index + quant_index = quant_builder.Finish(); + } + + // Create Tensor + tflite::TensorBuilder tensor_builder{*flatbuffer_builder}; + + tensor_builder.add_shape(shape); + tensor_builder.add_type(as_tflite_tensortype(operand.type())); + tensor_builder.add_buffer(buffer_index); + tensor_builder.add_name(name); + if (operand.has_quant()) + tensor_builder.add_quantization(quant_index); + + // Append! + tensor_vec.emplace_back(tensor_builder.Finish()); + + // Update Tensor Name -> Tensor Index Map + int32_t tensor_index = symbol_table.size(); + const auto &tensor_name = operand.name(); + + symbol_table[tensor_name] = tensor_index; + } + + // Create Operator + for (const auto &operation : model_recipe.operation()) + { + assert(operation.has_type()); + + auto op_chef = op_chef_registry().lookup(operation.type()).create(&operation); + + // Create 'inputs' + std::vector<int32_t> input_vec = as_dataset(operation.input()).map(lookup).vectorize(); + auto inputs = flatbuffer_builder->CreateVector(input_vec); + + // Create 'outputs' + std::vector<int32_t> output_vec = as_dataset(operation.output()).map(lookup).vectorize(); + auto outputs = flatbuffer_builder->CreateVector(output_vec); + + // Create Option + auto options = op_chef->value(*flatbuffer_builder); + + // Create Operator + tflite::OperatorBuilder op_builder{*flatbuffer_builder}; + + // Get operator code index from opcode_set with assumption, order of + // opcode_set is same as that of code_vec + auto op_it = opcode_set.find(op_chef->code()); + assert(op_it != opcode_set.end()); + uint32_t opcode_index = std::distance(opcode_set.begin(), op_it); + + op_builder.add_opcode_index(opcode_index); + op_builder.add_inputs(inputs); + op_builder.add_outputs(outputs); + op_builder.add_builtin_options_type(op_chef->type()); + op_builder.add_builtin_options(options); + + // Append Operator + operator_vec.emplace_back(op_builder.Finish()); + } + + // Create network input/output vector + std::vector<int32_t> input_vec = as_dataset(model_recipe.input()).map(lookup).vectorize(); + std::vector<int32_t> output_vec = as_dataset(model_recipe.output()).map(lookup).vectorize(); + + // Create "SubGraph" arguments + auto tensors = flatbuffer_builder->CreateVector(tensor_vec); + auto inputs = flatbuffer_builder->CreateVector(input_vec); + auto outputs = flatbuffer_builder->CreateVector(output_vec); + auto operators = flatbuffer_builder->CreateVector(operator_vec); + auto name = flatbuffer_builder->CreateString(graph_name); + + tflite::SubGraphBuilder subgraph_builder{*flatbuffer_builder}; + + subgraph_builder.add_tensors(tensors); + subgraph_builder.add_inputs(inputs); + subgraph_builder.add_outputs(outputs); + subgraph_builder.add_operators(operators); + subgraph_builder.add_name(name); + + subgraph_vec.emplace_back(subgraph_builder.Finish()); + } + + // + // Create subgraphs if exist + // TODO refactor main graph and subgraphs generation to reduce duplicate codes + // + for (int g = 0; g < model_recipe.graph_size(); ++g) + { + // Operand-related + std::vector<flatbuffers::Offset<::tflite::Tensor>> tensor_vec; + + // Operation-related + std::vector<flatbuffers::Offset<::tflite::Operator>> operator_vec; + + // Tensor Name -> Tensor ID mapping (per Graph) + std::map<std::string, int32_t> symbol_table; + + auto lookup = [&symbol_table](const std::string &name) { return symbol_table.at(name); }; + + const auto &graph = model_recipe.graph(g); + + int32_t buffer_start = buffer_vec.size(); + int32_t buffer_index = 0; + + // Create buffer(s) for input(s) + const auto size_input = graph.input_size(); + for (int ci = 0; ci < size_input; ++ci) + { + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_vec.emplace_back(buffer_builder.Finish()); + } + // Create buffer(s) for output(s) + const auto size_output = graph.output_size(); + for (int co = 0; co < size_output; ++co) + { + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_vec.emplace_back(buffer_builder.Finish()); + } + + // default name for sub graph + // TODO naming rule here may have conflit if recipe file provides it. + // fix this when this happens. + std::ostringstream stringStream; + stringStream << "sub_" << (g + 1); + std::string graph_name = stringStream.str(); + if (graph.has_name()) + graph_name = graph.name(); + + auto input_names = as_dataset(graph.input()).vectorize(); + auto output_names = as_dataset(graph.output()).vectorize(); + + for (const auto &operand : graph.operand()) + { + assert(operand.has_name()); + + assert(operand.has_type()); + assert(operand.has_shape()); + + std::vector<int32_t> dims = as_dims(operand.shape()); + + auto shape = flatbuffer_builder->CreateVector(dims); + auto name = flatbuffer_builder->CreateString(operand.name()); + + // Create Buffer if filler is specified + if (operand.has_filler()) + { + const auto &filler = operand.filler(); + + assert(filler.has_tag()); + + auto args = ranged_arguments(filler.arg().begin(), filler.arg().end()); + auto chef = data_chef_registry(operand.type()).lookup(filler.tag()).create(args); + + assert(chef != nullptr); + + // Create Data + auto data_vec = chef->generate(element_count(dims)); + auto data = flatbuffer_builder->CreateVector(data_vec); + + // Create Buffer + tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + buffer_builder.add_data(data); + auto buffer = buffer_builder.Finish(); + + // Update Buffer Index & Vector + buffer_index = buffer_vec.size(); + buffer_vec.emplace_back(buffer); + } + else + { + // if this is input or output, assign to that buffer_index + int idx = 0; + buffer_index = 0; + for (auto it = input_names.begin(); it != input_names.end(); ++it, ++idx) + { + if (*it == operand.name()) + { + buffer_index = buffer_start + idx; + break; + } + } + if (buffer_index == 0) + { + idx = 0; + for (auto it = output_names.begin(); it != output_names.end(); ++it, ++idx) + { + if (*it == operand.name()) + { + buffer_index = buffer_start + size_input + idx; + break; + } + } + } + } + // NOTE buffer_index can be 0 when this operand does not have a filler or not I/O + + flatbuffers::Offset<tflite::QuantizationParameters> quant_index; + + // Create QuantizationParameters if quant is specified + if (operand.has_quant()) + { + const auto &quant = operand.quant(); + + // Create each parameters + // NOTE if some parameters are not given, those will be set to default value + std::vector<float> quant_max_vec(quant.max_size()); + std::vector<float> quant_min_vec(quant.min_size()); + std::vector<float> quant_scale_vec(quant.scale_size()); + std::vector<int64_t> quant_zero_point_vec(quant.zero_point_size()); + + for (uint32_t i = 0; i < quant.max_size(); ++i) + quant_max_vec.at(i) = quant.max(i); + for (uint32_t i = 0; i < quant.min_size(); ++i) + quant_min_vec.at(i) = quant.min(i); + for (uint32_t i = 0; i < quant.scale_size(); ++i) + quant_scale_vec.at(i) = quant.scale(i); + for (uint32_t i = 0; i < quant.zero_point_size(); ++i) + quant_zero_point_vec.at(i) = quant.zero_point(i); + + auto quant_max = flatbuffer_builder->CreateVector(quant_max_vec); + auto quant_min = flatbuffer_builder->CreateVector(quant_min_vec); + auto quant_scale = flatbuffer_builder->CreateVector(quant_scale_vec); + auto quant_zero_point = flatbuffer_builder->CreateVector(quant_zero_point_vec); + + // Create QuantizationParameters + tflite::QuantizationParametersBuilder quant_builder{*flatbuffer_builder}; + quant_builder.add_max(quant_max); + quant_builder.add_min(quant_min); + quant_builder.add_scale(quant_scale); + quant_builder.add_zero_point(quant_zero_point); + + // Update QuantizationParameters Index + quant_index = quant_builder.Finish(); + } + + // Create Tensor + tflite::TensorBuilder tensor_builder{*flatbuffer_builder}; + + tensor_builder.add_shape(shape); + tensor_builder.add_type(as_tflite_tensortype(operand.type())); + tensor_builder.add_buffer(buffer_index); + tensor_builder.add_name(name); + if (operand.has_quant()) + tensor_builder.add_quantization(quant_index); + + // Append! + tensor_vec.emplace_back(tensor_builder.Finish()); + + // Update Tensor Name -> Tensor Index Map + int32_t tensor_index = symbol_table.size(); + const auto &tensor_name = operand.name(); + + symbol_table[tensor_name] = tensor_index; + } + + // Create Operator + for (const auto &operation : graph.operation()) + { + assert(operation.has_type()); + + auto op_chef = op_chef_registry().lookup(operation.type()).create(&operation); + + // Create 'inputs' + std::vector<int32_t> input_vec = as_dataset(operation.input()).map(lookup).vectorize(); + auto inputs = flatbuffer_builder->CreateVector(input_vec); + + // Create 'outputs' + std::vector<int32_t> output_vec = as_dataset(operation.output()).map(lookup).vectorize(); + auto outputs = flatbuffer_builder->CreateVector(output_vec); + + // Create Option + auto options = op_chef->value(*flatbuffer_builder); + + // Create Operator + tflite::OperatorBuilder op_builder{*flatbuffer_builder}; + + // Get operator code index from opcode_set with assumption, order of + // opcode_set is same as that of code_vec + auto op_it = opcode_set.find(op_chef->code()); + assert(op_it != opcode_set.end()); + uint32_t opcode_index = std::distance(opcode_set.begin(), op_it); + + op_builder.add_opcode_index(opcode_index); + op_builder.add_inputs(inputs); + op_builder.add_outputs(outputs); + op_builder.add_builtin_options_type(op_chef->type()); + op_builder.add_builtin_options(options); + + // Append Operator + operator_vec.emplace_back(op_builder.Finish()); + } + + // Create network input/output vector + std::vector<int32_t> input_vec = as_dataset(graph.input()).map(lookup).vectorize(); + std::vector<int32_t> output_vec = as_dataset(graph.output()).map(lookup).vectorize(); + + // Create "SubGraph" arguments + auto tensors = flatbuffer_builder->CreateVector(tensor_vec); + auto inputs = flatbuffer_builder->CreateVector(input_vec); + auto outputs = flatbuffer_builder->CreateVector(output_vec); + auto operators = flatbuffer_builder->CreateVector(operator_vec); + auto name = flatbuffer_builder->CreateString(graph_name); + + tflite::SubGraphBuilder subgraph_builder{*flatbuffer_builder}; + + subgraph_builder.add_tensors(tensors); + subgraph_builder.add_inputs(inputs); + subgraph_builder.add_outputs(outputs); + subgraph_builder.add_operators(operators); + subgraph_builder.add_name(name); + + subgraph_vec.emplace_back(subgraph_builder.Finish()); + } + + // Create "Model" arguments + auto buffers = flatbuffer_builder->CreateVector(buffer_vec); + auto operator_codes = flatbuffer_builder->CreateVector(code_vec); + auto subgraphs = flatbuffer_builder->CreateVector(subgraph_vec); + auto description = flatbuffer_builder->CreateString("Generated by tflchef"); + + // Create "Model" + tflite::ModelBuilder model_builder{*flatbuffer_builder}; + + model_builder.add_version(3); + model_builder.add_operator_codes(operator_codes); + model_builder.add_subgraphs(subgraphs); + model_builder.add_description(description); + model_builder.add_buffers(buffers); + + auto model = model_builder.Finish(); + + // Finalize + ::tflite::FinishModelBuffer(*flatbuffer_builder, model); + + // Return "GenerateModel" + return GeneratedModel{ + std::unique_ptr<GeneratedModelImpl>(new GeneratedModelImpl(std::move(flatbuffer_builder)))}; +} + +} // namespace tflchef diff --git a/compiler/tflchef/core/src/Op/Abs.cpp b/compiler/tflchef/core/src/Op/Abs.cpp new file mode 100644 index 000000000..dcb27784c --- /dev/null +++ b/compiler/tflchef/core/src/Op/Abs.cpp @@ -0,0 +1,30 @@ +/* + * 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 "Abs.h" +#include "Convert.h" + +flatbuffers::Offset<void> AbsChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::AbsOptionsBuilder abs_options_builder{fbb}; + + return abs_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> AbsChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new AbsChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Abs.h b/compiler/tflchef/core/src/Op/Abs.h new file mode 100644 index 000000000..5b694c6b6 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Abs.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_ABS_H__ +#define __OP_ABS_H__ + +#include "OpChef.h" + +class AbsChef final : public OpChef +{ +public: + explicit AbsChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_ABS; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_AbsOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct AbsChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_ABS_H__ diff --git a/compiler/tflchef/core/src/Op/Add.cpp b/compiler/tflchef/core/src/Op/Add.cpp new file mode 100644 index 000000000..8679ba35e --- /dev/null +++ b/compiler/tflchef/core/src/Op/Add.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Add.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> AddChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_add_options()); + + auto tflite_activation = as_tflite_activation(operation.add_options().activation()); + + tflite::AddOptionsBuilder add_options_builder{fbb}; + add_options_builder.add_fused_activation_function(tflite_activation); + + return add_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> AddChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new AddChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Add.h b/compiler/tflchef/core/src/Op/Add.h new file mode 100644 index 000000000..29ddb9470 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Add.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_ADD_H__ +#define __OP_ADD_H__ + +#include "OpChef.h" + +class AddChef final : public OpChef +{ +public: + explicit AddChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_ADD; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_AddOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct AddChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_ADD_H__ diff --git a/compiler/tflchef/core/src/Op/ArgMax.cpp b/compiler/tflchef/core/src/Op/ArgMax.cpp new file mode 100644 index 000000000..2c2995da5 --- /dev/null +++ b/compiler/tflchef/core/src/Op/ArgMax.cpp @@ -0,0 +1,39 @@ +/* + * 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 "ArgMax.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> ArgMaxChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_argmax_options()); + + auto tflite_output_type = as_tflite_tensortype(operation.argmax_options().output_type()); + + tflite::ArgMaxOptionsBuilder argmax_options_builder{fbb}; + argmax_options_builder.add_output_type(tflite_output_type); + + return argmax_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> ArgMaxChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ArgMaxChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/ArgMax.h b/compiler/tflchef/core/src/Op/ArgMax.h new file mode 100644 index 000000000..4033e0f6c --- /dev/null +++ b/compiler/tflchef/core/src/Op/ArgMax.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_ARGMAX_H__ +#define __OP_ARGMAX_H__ + +#include "OpChef.h" + +class ArgMaxChef final : public OpChef +{ +public: + explicit ArgMaxChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_ARG_MAX; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_ArgMaxOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ArgMaxChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_ARGMAX_H__ diff --git a/compiler/tflchef/core/src/Op/AveragePool2D.cpp b/compiler/tflchef/core/src/Op/AveragePool2D.cpp new file mode 100644 index 000000000..84d6a7571 --- /dev/null +++ b/compiler/tflchef/core/src/Op/AveragePool2D.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AveragePool2D.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> AveragePool2DChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_averagepool2d_options()); + + auto options = operation.averagepool2d_options(); + + auto tflite_padding = as_tflite_padding(options.padding()); + auto tflite_activation = as_tflite_activation(options.activation()); + + tflite::Pool2DOptionsBuilder options_builder{fbb}; + options_builder.add_padding(tflite_padding); + options_builder.add_stride_h(options.stride_h()); + options_builder.add_stride_w(options.stride_w()); + options_builder.add_filter_width(options.filter_width()); + options_builder.add_filter_height(options.filter_height()); + options_builder.add_fused_activation_function(tflite_activation); + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> AveragePool2DChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new AveragePool2DChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/AveragePool2D.h b/compiler/tflchef/core/src/Op/AveragePool2D.h new file mode 100644 index 000000000..652fae28b --- /dev/null +++ b/compiler/tflchef/core/src/Op/AveragePool2D.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_AVERAGE_POOL_2D_H__ +#define __OP_AVERAGE_POOL_2D_H__ + +#include "OpChef.h" + +class AveragePool2DChef final : public OpChef +{ +public: + explicit AveragePool2DChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override + { + return tflite::BuiltinOperator_AVERAGE_POOL_2D; + } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_Pool2DOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct AveragePool2DChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_AVERAGE_POOL_2D_H__ diff --git a/compiler/tflchef/core/src/Op/BatchToSpaceND.cpp b/compiler/tflchef/core/src/Op/BatchToSpaceND.cpp new file mode 100644 index 000000000..972f93256 --- /dev/null +++ b/compiler/tflchef/core/src/Op/BatchToSpaceND.cpp @@ -0,0 +1,31 @@ +/* + * 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 "BatchToSpaceND.h" + +#include <cassert> + +flatbuffers::Offset<void> BatchToSpaceNDChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::BatchToSpaceNDOptionsBuilder batch_to_space_nd_options_builder{fbb}; + + return batch_to_space_nd_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> BatchToSpaceNDChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new BatchToSpaceNDChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/BatchToSpaceND.h b/compiler/tflchef/core/src/Op/BatchToSpaceND.h new file mode 100644 index 000000000..6ba1352ab --- /dev/null +++ b/compiler/tflchef/core/src/Op/BatchToSpaceND.h @@ -0,0 +1,52 @@ +/* + * 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 __OP_BATCHTOSPACEND_H__ +#define __OP_BATCHTOSPACEND_H__ + +#include "OpChef.h" + +class BatchToSpaceNDChef final : public OpChef +{ +public: + explicit BatchToSpaceNDChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override + { + return tflite::BuiltinOperator_BATCH_TO_SPACE_ND; + } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_BatchToSpaceNDOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct BatchToSpaceNDChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_BATCHTOSPACEND_H__ diff --git a/compiler/tflchef/core/src/Op/Concatenation.cpp b/compiler/tflchef/core/src/Op/Concatenation.cpp new file mode 100644 index 000000000..89b8a6122 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Concatenation.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Concatenation.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> ConcatenationChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_concatenation_options()); + + auto options = operation.concatenation_options(); + + auto tflite_activation = as_tflite_activation(options.activation()); + + tflite::ConcatenationOptionsBuilder options_builder{fbb}; + + options_builder.add_axis(options.axis()); + options_builder.add_fused_activation_function(tflite_activation); + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> ConcatenationChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ConcatenationChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Concatenation.h b/compiler/tflchef/core/src/Op/Concatenation.h new file mode 100644 index 000000000..a59310a1d --- /dev/null +++ b/compiler/tflchef/core/src/Op/Concatenation.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_CONCATENATION_H__ +#define __OP_CONCATENATION_H__ + +#include "OpChef.h" + +class ConcatenationChef final : public OpChef +{ +public: + explicit ConcatenationChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override + { + return tflite::BuiltinOperator_CONCATENATION; + } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_ConcatenationOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ConcatenationChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_CONCATENATION_H__ diff --git a/compiler/tflchef/core/src/Op/Conv2D.cpp b/compiler/tflchef/core/src/Op/Conv2D.cpp new file mode 100644 index 000000000..d99c53351 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Conv2D.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conv2D.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> Conv2DChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_conv2d_options()); + + auto tflite_padding = as_tflite_padding(operation.conv2d_options().padding()); + auto tflite_activation = as_tflite_activation(operation.conv2d_options().activation()); + + tflite::Conv2DOptionsBuilder conv2d_options_builder{fbb}; + conv2d_options_builder.add_padding(tflite_padding); + conv2d_options_builder.add_stride_h(operation.conv2d_options().stride_h()); + conv2d_options_builder.add_stride_w(operation.conv2d_options().stride_w()); + conv2d_options_builder.add_fused_activation_function(tflite_activation); + + return conv2d_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> Conv2DChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new Conv2DChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Conv2D.h b/compiler/tflchef/core/src/Op/Conv2D.h new file mode 100644 index 000000000..22c45e89a --- /dev/null +++ b/compiler/tflchef/core/src/Op/Conv2D.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_CONV2D_H__ +#define __OP_CONV2D_H__ + +#include "OpChef.h" + +class Conv2DChef final : public OpChef +{ +public: + explicit Conv2DChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_CONV_2D; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_Conv2DOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct Conv2DChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_CONV2D_H__ diff --git a/compiler/tflchef/core/src/Op/Cos.cpp b/compiler/tflchef/core/src/Op/Cos.cpp new file mode 100644 index 000000000..547bee1a9 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Cos.cpp @@ -0,0 +1,29 @@ +/* + * 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 "Cos.h" + +flatbuffers::Offset<void> CosChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::CosOptionsBuilder options_builder{fbb}; + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> CosChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new CosChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Cos.h b/compiler/tflchef/core/src/Op/Cos.h new file mode 100644 index 000000000..9bf8cbeab --- /dev/null +++ b/compiler/tflchef/core/src/Op/Cos.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_COS_H__ +#define __OP_COS_H__ + +#include "OpChef.h" + +class CosChef final : public OpChef +{ +public: + explicit CosChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_COS; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_CosOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct CosChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_COS_H__ diff --git a/compiler/tflchef/core/src/Op/DepthwiseConv2D.cpp b/compiler/tflchef/core/src/Op/DepthwiseConv2D.cpp new file mode 100644 index 000000000..e04cf50ff --- /dev/null +++ b/compiler/tflchef/core/src/Op/DepthwiseConv2D.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DepthwiseConv2D.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> DepthwiseConv2DChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_depthwiseconv2d_options()); + + auto options = operation.depthwiseconv2d_options(); + + auto tflite_padding = as_tflite_padding(options.padding()); + auto tflite_activation = as_tflite_activation(options.activation()); + + tflite::DepthwiseConv2DOptionsBuilder options_builder{fbb}; + options_builder.add_padding(tflite_padding); + options_builder.add_stride_w(options.stride_w()); + options_builder.add_stride_h(options.stride_h()); + options_builder.add_depth_multiplier(options.depth_multiplier()); + options_builder.add_fused_activation_function(tflite_activation); + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> +DepthwiseConv2DChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new DepthwiseConv2DChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/DepthwiseConv2D.h b/compiler/tflchef/core/src/Op/DepthwiseConv2D.h new file mode 100644 index 000000000..718ee7943 --- /dev/null +++ b/compiler/tflchef/core/src/Op/DepthwiseConv2D.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_DEPTHWISECONV2D_H__ +#define __OP_DEPTHWISECONV2D_H__ + +#include "OpChef.h" + +class DepthwiseConv2DChef final : public OpChef +{ +public: + explicit DepthwiseConv2DChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override + { + return tflite::BuiltinOperator_DEPTHWISE_CONV_2D; + } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_DepthwiseConv2DOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct DepthwiseConv2DChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_DEPTHWISECONV2D_H__ diff --git a/compiler/tflchef/core/src/Op/Div.cpp b/compiler/tflchef/core/src/Op/Div.cpp new file mode 100644 index 000000000..98eead815 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Div.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Div.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> DivChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_div_options()); + + auto tflite_activation = as_tflite_activation(operation.div_options().activation()); + + tflite::DivOptionsBuilder div_options_builder{fbb}; + div_options_builder.add_fused_activation_function(tflite_activation); + + return div_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> DivChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new DivChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Div.h b/compiler/tflchef/core/src/Op/Div.h new file mode 100644 index 000000000..0d1063cce --- /dev/null +++ b/compiler/tflchef/core/src/Op/Div.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_DIV_H__ +#define __OP_DIV_H__ + +#include "OpChef.h" + +class DivChef final : public OpChef +{ +public: + explicit DivChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_DIV; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_DivOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct DivChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_DIV_H__ diff --git a/compiler/tflchef/core/src/Op/Equal.cpp b/compiler/tflchef/core/src/Op/Equal.cpp new file mode 100644 index 000000000..f7a39f03d --- /dev/null +++ b/compiler/tflchef/core/src/Op/Equal.cpp @@ -0,0 +1,29 @@ +/* + * 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 "Equal.h" + +flatbuffers::Offset<void> EqualChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::EqualOptionsBuilder options_builder{fbb}; + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> EqualChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new EqualChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Equal.h b/compiler/tflchef/core/src/Op/Equal.h new file mode 100644 index 000000000..6e097991d --- /dev/null +++ b/compiler/tflchef/core/src/Op/Equal.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_EQUAL_H__ +#define __OP_EQUAL_H__ + +#include "OpChef.h" + +class EqualChef final : public OpChef +{ +public: + explicit EqualChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_EQUAL; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_EqualOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct EqualChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_EQUAL_H__ diff --git a/compiler/tflchef/core/src/Op/Exp.cpp b/compiler/tflchef/core/src/Op/Exp.cpp new file mode 100644 index 000000000..b3c8d7e73 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Exp.cpp @@ -0,0 +1,30 @@ +/* + * 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 "Exp.h" +#include "Convert.h" + +flatbuffers::Offset<void> ExpChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::ExpOptionsBuilder exp_options_builder{fbb}; + + return exp_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> ExpChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ExpChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Exp.h b/compiler/tflchef/core/src/Op/Exp.h new file mode 100644 index 000000000..422a3310f --- /dev/null +++ b/compiler/tflchef/core/src/Op/Exp.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_EXP_H__ +#define __OP_EXP_H__ + +#include "OpChef.h" + +class ExpChef final : public OpChef +{ +public: + explicit ExpChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_EXP; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_ExpOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ExpChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_ABS_H__ diff --git a/compiler/tflchef/core/src/Op/FloorDiv.cpp b/compiler/tflchef/core/src/Op/FloorDiv.cpp new file mode 100644 index 000000000..0d531bede --- /dev/null +++ b/compiler/tflchef/core/src/Op/FloorDiv.cpp @@ -0,0 +1,30 @@ +/* + * 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 "FloorDiv.h" + +#include <cassert> + +flatbuffers::Offset<void> FloorDivChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::FloorDivOptionsBuilder floor_div_options_builder{fbb}; + return floor_div_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> FloorDivChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new FloorDivChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/FloorDiv.h b/compiler/tflchef/core/src/Op/FloorDiv.h new file mode 100644 index 000000000..151f24314 --- /dev/null +++ b/compiler/tflchef/core/src/Op/FloorDiv.h @@ -0,0 +1,49 @@ +/* + * 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 __OP_FLOORDIV_H__ +#define __OP_FLOORDIV_H__ + +#include "OpChef.h" + +class FloorDivChef final : public OpChef +{ +public: + explicit FloorDivChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_FLOOR_DIV; } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_FloorDivOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct FloorDivChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_FLOORDIV_H__ diff --git a/compiler/tflchef/core/src/Op/FullyConnected.cpp b/compiler/tflchef/core/src/Op/FullyConnected.cpp new file mode 100644 index 000000000..45269916c --- /dev/null +++ b/compiler/tflchef/core/src/Op/FullyConnected.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FullyConnected.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> FullyConnectedChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_fullyconnected_options()); + + auto tflite_activation = as_tflite_activation(operation.fullyconnected_options().activation()); + + tflite::FullyConnectedOptionsBuilder fc_options_builder{fbb}; + fc_options_builder.add_fused_activation_function(tflite_activation); + + return fc_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> FullyConnectedChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new FullyConnectedChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/FullyConnected.h b/compiler/tflchef/core/src/Op/FullyConnected.h new file mode 100644 index 000000000..ea71012e6 --- /dev/null +++ b/compiler/tflchef/core/src/Op/FullyConnected.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_FULLYCONNECTED_H__ +#define __OP_FULLYCONNECTED_H__ + +#include "OpChef.h" + +class FullyConnectedChef final : public OpChef +{ +public: + explicit FullyConnectedChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override + { + return tflite::BuiltinOperator_FULLY_CONNECTED; + } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_FullyConnectedOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct FullyConnectedChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_FULLYCONNECTED_H__ diff --git a/compiler/tflchef/core/src/Op/LogicalNot.cpp b/compiler/tflchef/core/src/Op/LogicalNot.cpp new file mode 100644 index 000000000..26cdef308 --- /dev/null +++ b/compiler/tflchef/core/src/Op/LogicalNot.cpp @@ -0,0 +1,29 @@ +/* + * 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 "LogicalNot.h" + +flatbuffers::Offset<void> LogicalNotChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::LogicalNotOptionsBuilder options_builder{fbb}; + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> LogicalNotChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new LogicalNotChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/LogicalNot.h b/compiler/tflchef/core/src/Op/LogicalNot.h new file mode 100644 index 000000000..d2ca21b93 --- /dev/null +++ b/compiler/tflchef/core/src/Op/LogicalNot.h @@ -0,0 +1,49 @@ +/* + * 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 __OP_LOGICALNOT_H__ +#define __OP_LOGICALNOT_H__ + +#include "OpChef.h" + +class LogicalNotChef final : public OpChef +{ +public: + explicit LogicalNotChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_LOGICAL_NOT; } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_LogicalNotOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct LogicalNotChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_LOGICALNOT_H__ diff --git a/compiler/tflchef/core/src/Op/LogicalOr.cpp b/compiler/tflchef/core/src/Op/LogicalOr.cpp new file mode 100644 index 000000000..483373a81 --- /dev/null +++ b/compiler/tflchef/core/src/Op/LogicalOr.cpp @@ -0,0 +1,29 @@ +/* + * 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 "LogicalOr.h" + +flatbuffers::Offset<void> LogicalOrChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::LogicalOrOptionsBuilder options_builder{fbb}; + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> LogicalOrChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new LogicalOrChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/LogicalOr.h b/compiler/tflchef/core/src/Op/LogicalOr.h new file mode 100644 index 000000000..b84c9a6ab --- /dev/null +++ b/compiler/tflchef/core/src/Op/LogicalOr.h @@ -0,0 +1,49 @@ +/* + * 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 __OP_LOGICALOR_H__ +#define __OP_LOGICALOR_H__ + +#include "OpChef.h" + +class LogicalOrChef final : public OpChef +{ +public: + explicit LogicalOrChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_LOGICAL_OR; } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_LogicalOrOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct LogicalOrChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_LOGICALOR_H__ diff --git a/compiler/tflchef/core/src/Op/MaxPool2D.cpp b/compiler/tflchef/core/src/Op/MaxPool2D.cpp new file mode 100644 index 000000000..666ac98f0 --- /dev/null +++ b/compiler/tflchef/core/src/Op/MaxPool2D.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MaxPool2D.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> MaxPool2DChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_maxpool2d_options()); + + auto options = operation.maxpool2d_options(); + + auto tflite_padding = as_tflite_padding(options.padding()); + auto tflite_activation = as_tflite_activation(options.activation()); + + tflite::Pool2DOptionsBuilder options_builder{fbb}; + options_builder.add_padding(tflite_padding); + options_builder.add_stride_h(options.stride_h()); + options_builder.add_stride_w(options.stride_w()); + options_builder.add_filter_width(options.filter_width()); + options_builder.add_filter_height(options.filter_height()); + options_builder.add_fused_activation_function(tflite_activation); + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> MaxPool2DChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new MaxPool2DChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/MaxPool2D.h b/compiler/tflchef/core/src/Op/MaxPool2D.h new file mode 100644 index 000000000..56960a0d2 --- /dev/null +++ b/compiler/tflchef/core/src/Op/MaxPool2D.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_MAX_POOL_2D_H__ +#define __OP_MAX_POOL_2D_H__ + +#include "OpChef.h" + +class MaxPool2DChef final : public OpChef +{ +public: + explicit MaxPool2DChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_MAX_POOL_2D; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_Pool2DOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct MaxPool2DChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_MAX_POOL_2D_H__ diff --git a/compiler/tflchef/core/src/Op/Mean.cpp b/compiler/tflchef/core/src/Op/Mean.cpp new file mode 100644 index 000000000..def8f7b3b --- /dev/null +++ b/compiler/tflchef/core/src/Op/Mean.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Mean.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> MeanChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_mean_options()); + + auto keep_dims = operation.mean_options().keep_dims(); + + tflite::ReducerOptionsBuilder mean_options_builder{fbb}; + mean_options_builder.add_keep_dims(keep_dims); + + return mean_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> MeanChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new MeanChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Mean.h b/compiler/tflchef/core/src/Op/Mean.h new file mode 100644 index 000000000..9032aef3f --- /dev/null +++ b/compiler/tflchef/core/src/Op/Mean.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_MEAN_H__ +#define __OP_MEAN_H__ + +#include "OpChef.h" + +class MeanChef final : public OpChef +{ +public: + explicit MeanChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_MEAN; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_ReducerOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct MeanChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_MEAN_H__ diff --git a/compiler/tflchef/core/src/Op/Mul.cpp b/compiler/tflchef/core/src/Op/Mul.cpp new file mode 100644 index 000000000..10ec918c2 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Mul.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Mul.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> MulChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_mul_options()); + + auto tflite_activation = as_tflite_activation(operation.mul_options().activation()); + + tflite::MulOptionsBuilder mul_options_builder{fbb}; + mul_options_builder.add_fused_activation_function(tflite_activation); + + return mul_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> MulChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new MulChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Mul.h b/compiler/tflchef/core/src/Op/Mul.h new file mode 100644 index 000000000..7f1d07ac9 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Mul.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_MUL_H__ +#define __OP_MUL_H__ + +#include "OpChef.h" + +class MulChef final : public OpChef +{ +public: + explicit MulChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_MUL; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_MulOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct MulChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_MUL_H__ diff --git a/compiler/tflchef/core/src/Op/Pack.cpp b/compiler/tflchef/core/src/Op/Pack.cpp new file mode 100644 index 000000000..2532ac744 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Pack.cpp @@ -0,0 +1,38 @@ +/* + * 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 "Pack.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> PackChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_pack_options()); + + tflite::PackOptionsBuilder pack_options_builder{fbb}; + pack_options_builder.add_values_count(operation.pack_options().values_count()); + pack_options_builder.add_axis(operation.pack_options().axis()); + + return pack_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> PackChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new PackChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Pack.h b/compiler/tflchef/core/src/Op/Pack.h new file mode 100644 index 000000000..54bdc9338 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Pack.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_PACK_H__ +#define __OP_PACK_H__ + +#include "OpChef.h" + +class PackChef final : public OpChef +{ +public: + explicit PackChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_PACK; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_PackOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct PackChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_PACK_H__ diff --git a/compiler/tflchef/core/src/Op/Pad.cpp b/compiler/tflchef/core/src/Op/Pad.cpp new file mode 100644 index 000000000..d0c471981 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Pad.cpp @@ -0,0 +1,28 @@ +/* + * 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 "Pad.h" + +flatbuffers::Offset<void> PadChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::PadOptionsBuilder pad_options_builder{fbb}; + return pad_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> PadChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new PadChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Pad.h b/compiler/tflchef/core/src/Op/Pad.h new file mode 100644 index 000000000..9da9c9b8a --- /dev/null +++ b/compiler/tflchef/core/src/Op/Pad.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_PAD_H__ +#define __OP_PAD_H__ + +#include "OpChef.h" + +class PadChef final : public OpChef +{ +public: + explicit PadChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_PAD; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_PadOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct PadChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_PAD_H__ diff --git a/compiler/tflchef/core/src/Op/ReLU.cpp b/compiler/tflchef/core/src/Op/ReLU.cpp new file mode 100644 index 000000000..3fb8d3f46 --- /dev/null +++ b/compiler/tflchef/core/src/Op/ReLU.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ReLU.h" + +flatbuffers::Offset<void> ReLUChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + return flatbuffers::Offset<void>(); +} + +std::unique_ptr<OpChef> ReLUChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ReLUChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/ReLU.h b/compiler/tflchef/core/src/Op/ReLU.h new file mode 100644 index 000000000..778458cb8 --- /dev/null +++ b/compiler/tflchef/core/src/Op/ReLU.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_RELU_H__ +#define __OP_RELU_H__ + +#include "OpChef.h" + +class ReLUChef final : public OpChef +{ +public: + explicit ReLUChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_RELU; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_NONE; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ReLUChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_RELU_H__ diff --git a/compiler/tflchef/core/src/Op/ReLU6.cpp b/compiler/tflchef/core/src/Op/ReLU6.cpp new file mode 100644 index 000000000..6fe9bcbfd --- /dev/null +++ b/compiler/tflchef/core/src/Op/ReLU6.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ReLU6.h" + +flatbuffers::Offset<void> ReLU6Chef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + return flatbuffers::Offset<void>(); +} + +std::unique_ptr<OpChef> ReLU6ChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ReLU6Chef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/ReLU6.h b/compiler/tflchef/core/src/Op/ReLU6.h new file mode 100644 index 000000000..45a27cac2 --- /dev/null +++ b/compiler/tflchef/core/src/Op/ReLU6.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_RELU6_H__ +#define __OP_RELU6_H__ + +#include "OpChef.h" + +class ReLU6Chef final : public OpChef +{ +public: + explicit ReLU6Chef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_RELU6; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_NONE; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ReLU6ChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_RELU6_H__ diff --git a/compiler/tflchef/core/src/Op/Reshape.cpp b/compiler/tflchef/core/src/Op/Reshape.cpp new file mode 100644 index 000000000..99555e898 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Reshape.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Reshape.h" +#include "Convert.h" + +#include <cassert> +#include <vector> + +namespace +{ + +std::vector<int32_t> vector_new_shape(const tflchef::ReshapeOptions &options) +{ + std::vector<int32_t> shapes; + + for (int i = 0; i < options.new_shape_size(); ++i) + { + shapes.push_back(options.new_shape(i)); + } + + return shapes; +} + +} // namespace + +flatbuffers::Offset<void> ReshapeChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_reshape_options()); + + auto options = operation.reshape_options(); + auto shapes = vector_new_shape(options); + // Note: 'CreateVector' should be placed before 'options_builder' + // Read flatbuffers.h 'void NotNested()' for more information + auto fb_new_shape = fbb.CreateVector(shapes); + + tflite::ReshapeOptionsBuilder options_builder{fbb}; + + options_builder.add_new_shape(fb_new_shape); + + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> ReshapeChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ReshapeChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Reshape.h b/compiler/tflchef/core/src/Op/Reshape.h new file mode 100644 index 000000000..78e91dada --- /dev/null +++ b/compiler/tflchef/core/src/Op/Reshape.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_RESHAPE_H__ +#define __OP_RESHAPE_H__ + +#include "OpChef.h" + +class ReshapeChef final : public OpChef +{ +public: + explicit ReshapeChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_RESHAPE; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_ReshapeOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ReshapeChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_RESHAPE_H__ diff --git a/compiler/tflchef/core/src/Op/Rsqrt.cpp b/compiler/tflchef/core/src/Op/Rsqrt.cpp new file mode 100644 index 000000000..fa837f6fa --- /dev/null +++ b/compiler/tflchef/core/src/Op/Rsqrt.cpp @@ -0,0 +1,28 @@ +/* + * 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 "Rsqrt.h" + +flatbuffers::Offset<void> RsqrtChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + // No tflite option for Rsqrt. Use void. + return flatbuffers::Offset<void>(); +} + +std::unique_ptr<OpChef> RsqrtChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new RsqrtChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Rsqrt.h b/compiler/tflchef/core/src/Op/Rsqrt.h new file mode 100644 index 000000000..657f51ccb --- /dev/null +++ b/compiler/tflchef/core/src/Op/Rsqrt.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_RSQRT_H__ +#define __OP_RSQRT_H__ + +#include "OpChef.h" + +class RsqrtChef final : public OpChef +{ +public: + explicit RsqrtChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_RSQRT; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_NONE; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct RsqrtChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_RSQRT_H__ diff --git a/compiler/tflchef/core/src/Op/Shape.cpp b/compiler/tflchef/core/src/Op/Shape.cpp new file mode 100644 index 000000000..74b1894da --- /dev/null +++ b/compiler/tflchef/core/src/Op/Shape.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Shape.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> ShapeChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_shape_options()); + + auto tflite_out_type = as_tflite_tensortype(operation.shape_options().out_type()); + + tflite::ShapeOptionsBuilder shape_options_builder{fbb}; + shape_options_builder.add_out_type(tflite_out_type); + + return shape_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> ShapeChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new ShapeChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Shape.h b/compiler/tflchef/core/src/Op/Shape.h new file mode 100644 index 000000000..ddaeb1d95 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Shape.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_SHAPE_H__ +#define __OP_SHAPE_H__ + +#include "OpChef.h" + +class ShapeChef final : public OpChef +{ +public: + explicit ShapeChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_SHAPE; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_ShapeOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct ShapeChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_SHAPE_H__ diff --git a/compiler/tflchef/core/src/Op/Softmax.cpp b/compiler/tflchef/core/src/Op/Softmax.cpp new file mode 100644 index 000000000..a554e0d81 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Softmax.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Softmax.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> SoftmaxChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_softmax_options()); + + auto tflite_beta = operation.softmax_options().beta(); + + tflite::SoftmaxOptionsBuilder soft_options_builder{fbb}; + soft_options_builder.add_beta(tflite_beta); + + return soft_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> SoftmaxChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new SoftmaxChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Softmax.h b/compiler/tflchef/core/src/Op/Softmax.h new file mode 100644 index 000000000..8b3f0ebf6 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Softmax.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_SOFTMAX_H__ +#define __OP_SOFTMAX_H__ + +#include "OpChef.h" + +class SoftmaxChef final : public OpChef +{ +public: + explicit SoftmaxChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_SOFTMAX; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_SoftmaxOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct SoftmaxChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_SOFTMAX_H__ diff --git a/compiler/tflchef/core/src/Op/Sqrt.cpp b/compiler/tflchef/core/src/Op/Sqrt.cpp new file mode 100644 index 000000000..101a8130b --- /dev/null +++ b/compiler/tflchef/core/src/Op/Sqrt.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Sqrt.h" + +flatbuffers::Offset<void> SqrtChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + return flatbuffers::Offset<void>(); +} + +std::unique_ptr<OpChef> SqrtChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new SqrtChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Sqrt.h b/compiler/tflchef/core/src/Op/Sqrt.h new file mode 100644 index 000000000..2f91a99e3 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Sqrt.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_SQRT_H__ +#define __OP_SQRT_H__ + +#include "OpChef.h" + +class SqrtChef final : public OpChef +{ +public: + explicit SqrtChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_SQRT; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_NONE; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct SqrtChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_SQRT_H__ diff --git a/compiler/tflchef/core/src/Op/Sub.cpp b/compiler/tflchef/core/src/Op/Sub.cpp new file mode 100644 index 000000000..0ebb1d26c --- /dev/null +++ b/compiler/tflchef/core/src/Op/Sub.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Sub.h" +#include "Convert.h" + +#include <cassert> + +flatbuffers::Offset<void> SubChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + auto &operation = (*_operation); + + assert(operation.has_sub_options()); + + auto tflite_activation = as_tflite_activation(operation.sub_options().activation()); + + tflite::SubOptionsBuilder sub_options_builder{fbb}; + sub_options_builder.add_fused_activation_function(tflite_activation); + + return sub_options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> SubChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new SubChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Sub.h b/compiler/tflchef/core/src/Op/Sub.h new file mode 100644 index 000000000..dfebc06c0 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Sub.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_SUB_H__ +#define __OP_SUB_H__ + +#include "OpChef.h" + +class SubChef final : public OpChef +{ +public: + explicit SubChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_SUB; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_SubOptions; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct SubChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_SUB_H__ diff --git a/compiler/tflchef/core/src/Op/Tanh.cpp b/compiler/tflchef/core/src/Op/Tanh.cpp new file mode 100644 index 000000000..c25cad8f0 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Tanh.cpp @@ -0,0 +1,28 @@ +/* + * 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 "Tanh.h" + +flatbuffers::Offset<void> TanhChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + // No tflite option for Tanh. Use void. + return flatbuffers::Offset<void>(); +} + +std::unique_ptr<OpChef> TanhChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new TanhChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Tanh.h b/compiler/tflchef/core/src/Op/Tanh.h new file mode 100644 index 000000000..f8f707a04 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Tanh.h @@ -0,0 +1,46 @@ +/* + * 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 __OP_TANH_H__ +#define __OP_TANH_H__ + +#include "OpChef.h" + +class TanhChef final : public OpChef +{ +public: + explicit TanhChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_TANH; } + + tflite::BuiltinOptions type(void) const override { return tflite::BuiltinOptions_NONE; } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct TanhChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_TANH_H__ diff --git a/compiler/tflchef/core/src/Op/Transpose.cpp b/compiler/tflchef/core/src/Op/Transpose.cpp new file mode 100644 index 000000000..caae6cfa8 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Transpose.cpp @@ -0,0 +1,32 @@ +/* + * 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 "Transpose.h" +#include "Convert.h" + +#include <cassert> +#include <vector> + +flatbuffers::Offset<void> TransposeChef::value(flatbuffers::FlatBufferBuilder &fbb) const +{ + tflite::TransposeOptionsBuilder options_builder{fbb}; + return options_builder.Finish().Union(); +} + +std::unique_ptr<OpChef> TransposeChefFactory::create(const tflchef::Operation *operation) const +{ + return std::unique_ptr<OpChef>{new TransposeChef{operation}}; +} diff --git a/compiler/tflchef/core/src/Op/Transpose.h b/compiler/tflchef/core/src/Op/Transpose.h new file mode 100644 index 000000000..bb30f7bc9 --- /dev/null +++ b/compiler/tflchef/core/src/Op/Transpose.h @@ -0,0 +1,49 @@ +/* + * 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 __OP_TRANSPOSE_H__ +#define __OP_TRANSPOSE_H__ + +#include "OpChef.h" + +class TransposeChef final : public OpChef +{ +public: + explicit TransposeChef(const tflchef::Operation *operation) : _operation{operation} + { + // DO NOTHING + } + +public: + tflite::BuiltinOperator code(void) const override { return tflite::BuiltinOperator_TRANSPOSE; } + + tflite::BuiltinOptions type(void) const override + { + return tflite::BuiltinOptions_TransposeOptions; + } + + flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const override; + +private: + const tflchef::Operation *_operation; +}; + +struct TransposeChefFactory final : public OpChefFactory +{ + std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const override; +}; + +#endif // __OP_TRANSPOSE_H__ diff --git a/compiler/tflchef/core/src/OpChef.def b/compiler/tflchef/core/src/OpChef.def new file mode 100644 index 000000000..a25250c46 --- /dev/null +++ b/compiler/tflchef/core/src/OpChef.def @@ -0,0 +1,37 @@ +#ifndef OP_CHEF +#error "Define OP first" +#endif // OP_CHEF + +// Please keep the list in alphabetical order +// OP_CHEF(NAME, FACTORY_CLASS) +OP_CHEF(Abs, AbsChefFactory) +OP_CHEF(Add, AddChefFactory) +OP_CHEF(ArgMax, ArgMaxChefFactory) +OP_CHEF(BatchToSpaceND, BatchToSpaceNDChefFactory) +OP_CHEF(AveragePool2D, AveragePool2DChefFactory) +OP_CHEF(Concatenation, ConcatenationChefFactory) +OP_CHEF(Conv2D, Conv2DChefFactory) +OP_CHEF(Cos, CosChefFactory) +OP_CHEF(DepthwiseConv2D, DepthwiseConv2DChefFactory) +OP_CHEF(Div, DivChefFactory) +OP_CHEF(Equal, EqualChefFactory) +OP_CHEF(Exp, ExpChefFactory) +OP_CHEF(FloorDiv, FloorDivChefFactory) +OP_CHEF(FullyConnected, FullyConnectedChefFactory) +OP_CHEF(LogicalNot, LogicalNotChefFactory) +OP_CHEF(LogicalOr, LogicalOrChefFactory) +OP_CHEF(MaxPool2D, MaxPool2DChefFactory) +OP_CHEF(Mean, MeanChefFactory) +OP_CHEF(Mul, MulChefFactory) +OP_CHEF(Pack, PackChefFactory) +OP_CHEF(Pad, PadChefFactory) +OP_CHEF(ReLU, ReLUChefFactory) +OP_CHEF(ReLU6, ReLU6ChefFactory) +OP_CHEF(Reshape, ReshapeChefFactory) +OP_CHEF(Rsqrt, RsqrtChefFactory) +OP_CHEF(Shape, ShapeChefFactory) +OP_CHEF(Softmax, SoftmaxChefFactory) +OP_CHEF(Sqrt, SqrtChefFactory) +OP_CHEF(Sub, SubChefFactory) +OP_CHEF(Tanh, TanhChefFactory) +OP_CHEF(Transpose, TransposeChefFactory) diff --git a/compiler/tflchef/core/src/OpChef.h b/compiler/tflchef/core/src/OpChef.h new file mode 100644 index 000000000..0b7d9cf08 --- /dev/null +++ b/compiler/tflchef/core/src/OpChef.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_CHEF_H__ +#define __OP_CHEF_H__ + +#include <tflchef.pb.h> +#include <mio/tflite/schema_generated.h> + +#include <memory> + +struct OpChef +{ + virtual ~OpChef() = default; + + virtual tflite::BuiltinOperator code(void) const = 0; + virtual tflite::BuiltinOptions type(void) const = 0; + virtual flatbuffers::Offset<void> value(flatbuffers::FlatBufferBuilder &fbb) const = 0; +}; + +struct OpChefFactory +{ + virtual ~OpChefFactory() = default; + + virtual std::unique_ptr<OpChef> create(const tflchef::Operation *operation) const = 0; +}; + +#endif // __OP_CHEF_H__ diff --git a/compiler/tflchef/core/src/OpChefs.h b/compiler/tflchef/core/src/OpChefs.h new file mode 100644 index 000000000..65dbd4b92 --- /dev/null +++ b/compiler/tflchef/core/src/OpChefs.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OP_CHEFS_H__ +#define __OP_CHEFS_H__ + +#include "Op/Abs.h" +#include "Op/Add.h" +#include "Op/ArgMax.h" +#include "Op/AveragePool2D.h" +#include "Op/BatchToSpaceND.h" +#include "Op/Concatenation.h" +#include "Op/Conv2D.h" +#include "Op/Cos.h" +#include "Op/DepthwiseConv2D.h" +#include "Op/Div.h" +#include "Op/Equal.h" +#include "Op/Exp.h" +#include "Op/FloorDiv.h" +#include "Op/FullyConnected.h" +#include "Op/LogicalOr.h" +#include "Op/LogicalNot.h" +#include "Op/MaxPool2D.h" +#include "Op/Mean.h" +#include "Op/Mul.h" +#include "Op/Pack.h" +#include "Op/Pad.h" +#include "Op/ReLU.h" +#include "Op/ReLU6.h" +#include "Op/Reshape.h" +#include "Op/Rsqrt.h" +#include "Op/Shape.h" +#include "Op/Softmax.h" +#include "Op/Sqrt.h" +#include "Op/Sub.h" +#include "Op/Tanh.h" +#include "Op/Transpose.h" + +#endif // __OP_CHEFS_H__ diff --git a/compiler/tflchef/proto/CMakeLists.txt b/compiler/tflchef/proto/CMakeLists.txt new file mode 100644 index 000000000..c504b11ae --- /dev/null +++ b/compiler/tflchef/proto/CMakeLists.txt @@ -0,0 +1,5 @@ +Protobuf_Generate(TFLCHEF_PROTO "${CMAKE_CURRENT_BINARY_DIR}/generated" "${CMAKE_CURRENT_SOURCE_DIR}" "tflchef.proto") + +add_library(tflchef_proto STATIC ${TFLCHEF_PROTO_SOURCES}) +target_include_directories(tflchef_proto PUBLIC ${TFLCHEF_PROTO_INCLUDE_DIRS}) +target_link_libraries(tflchef_proto libprotobuf) diff --git a/compiler/tflchef/proto/tflchef.proto b/compiler/tflchef/proto/tflchef.proto new file mode 100644 index 000000000..486aa8a67 --- /dev/null +++ b/compiler/tflchef/proto/tflchef.proto @@ -0,0 +1,232 @@ +syntax = "proto2"; + +package tflchef; + +// +// Initial version +// - Our initial version +// +// Version 1 +// - Backward compatible with Initial version +// - Added Graph to represent sub graphs +// - Added name, version(default as 1), graph in ModelRecipe +// + +// This enum value corresponds to TensorType in TensorFlow Lite schema +enum TensorType { + FLOAT32 = 0; + INT32 = 2; + UINT8 = 3; + INT64 = 4; + BOOL = 6; +} + +message TensorShape { + repeated uint32 dim = 3; +} + +message TensorFiller { + optional string tag = 1; + repeated string arg = 2; +} + +message TensorQuantization { + repeated float min = 1; + repeated float max = 2; + repeated float scale = 3; + repeated int64 zero_point = 4; +} + +message Operand { + optional string name = 1; + optional TensorType type = 2; + optional TensorShape shape = 3; + optional TensorFiller filler = 4; + optional TensorQuantization quant = 5; +} + +// This enum value corresponds to Padding in TensorFlow Lite schema +enum Padding { + SAME = 0; + VALID = 1; +} + +// This enum value corresponds to ActivationFunctionType in TensorFlow Lite schema +enum Activation { + NONE = 0; + RELU = 1; + RELU6 = 3; +} + +message Conv2DOptions +{ + optional Padding padding = 1 [default = VALID]; + optional int32 stride_w = 2 [default = 1]; + optional int32 stride_h = 3 [default = 1]; + optional Activation activation = 4 [default = NONE]; +} + +message Pool2DOptions { + optional Padding padding = 1 [default = VALID]; + optional int32 stride_w = 2 [default = 1]; + optional int32 stride_h = 3 [default = 1]; + optional int32 filter_width = 4 [default = 1]; + optional int32 filter_height = 5 [ default = 1]; + optional Activation activation = 6 [default = NONE]; +} + +message ConcatenationOptions { + optional int32 axis = 1 [default = 0]; + optional Activation activation = 2 [default = NONE]; +} + +message ReshapeOptions { + repeated int32 new_shape = 1; +} + +message DepthwiseConv2DOptions +{ + optional Padding padding = 1 [default = VALID]; + optional int32 stride_w = 2 [default = 1]; + optional int32 stride_h = 3 [default = 1]; + optional int32 depth_multiplier = 4 [default = 1]; + optional Activation activation = 5 [default = NONE]; +} + +message SubOptions { + optional Activation activation = 1 [default = NONE]; +} + +message DivOptions { + optional Activation activation = 1 [default = NONE]; +} + +message FloorDivOptions { + // None +} + +message FullyConnectedOptions { + optional Activation activation = 1 [default = NONE]; +} + +message AddOptions { + optional Activation activation = 1 [default = NONE]; +} + +message ArgMaxOptions { + optional TensorType output_type = 1 [default = INT64]; +} + +message PackOptions { + optional int32 values_count = 1; + optional int32 axis = 2 [default = 0]; +} + +message PadOptions { + // None +} + +message SoftmaxOptions { + optional float beta = 1 [default = 0.0]; +} + +message MulOptions { + optional Activation activation = 1 [default = NONE]; +} + +message ReducerOptions { + optional bool keep_dims = 1 [ default = false ]; +} + +message LogicalOrOptions { + // None +} + +message LogicalNotOptions { + // None +} + +message LogicalAndOptions { + // None +} + +message TransposeOptions { + // None +} + +message AbsOptions { + // None +} + +message CosOptions { + // None +} + +message EqualOptions { + // None +} + +message ShapeOptions { + optional TensorType out_type = 1 [default = INT32]; +} + +message BatchToSpaceNDOptions { + // None +} + +message ExpOptions { + // None +} + +message Operation { + optional string type = 1; + repeated string input = 2; + repeated string output = 3; + + optional Conv2DOptions conv2d_options = 100; + optional Pool2DOptions averagepool2d_options = 101; + optional ConcatenationOptions concatenation_options = 102; + optional Pool2DOptions maxpool2d_options = 103; + optional ReshapeOptions reshape_options = 104; + optional DepthwiseConv2DOptions depthwiseconv2d_options = 105; + optional SubOptions sub_options = 106; + optional DivOptions div_options = 107; + optional FullyConnectedOptions fullyconnected_options = 108; + optional AddOptions add_options = 109; + optional ArgMaxOptions argmax_options = 110; + optional PadOptions pad_options = 111; + optional SoftmaxOptions softmax_options = 112; + optional MulOptions mul_options = 113; + optional ReducerOptions mean_options = 114; + optional TransposeOptions transpose_options = 115; + optional PackOptions pack_options = 116; + optional LogicalOrOptions logical_or_options = 117; + optional LogicalNotOptions logical_not_options = 118; + optional LogicalAndOptions logical_and_options = 119; + optional AbsOptions abs_options = 120; + optional CosOptions cos_options = 121; + optional EqualOptions equal_options = 122; + optional ShapeOptions shape_options = 123; + optional FloorDivOptions floordiv_options = 124; + optional BatchToSpaceNDOptions batch_to_space_options = 125; + optional ExpOptions exp_options = 126; +} + +// For additional subgraphs +message Graph { + repeated Operand operand = 1; + repeated Operation operation = 2; + repeated string input = 3; + repeated string output = 4; + optional string name = 5; +} + +message ModelRecipe { + repeated Operand operand = 1; + repeated Operation operation = 2; + repeated string input = 3; + repeated string output = 4; + optional string name = 5; + optional uint32 version = 6 [default = 1]; + repeated Graph graph = 7; +} diff --git a/compiler/tflchef/requires.cmake b/compiler/tflchef/requires.cmake new file mode 100644 index 000000000..3c5bb197f --- /dev/null +++ b/compiler/tflchef/requires.cmake @@ -0,0 +1,4 @@ +require("nnkit") +require("cwrap") +require("mio-tflite") +require("safemain") diff --git a/compiler/tflchef/tests/CMakeLists.txt b/compiler/tflchef/tests/CMakeLists.txt new file mode 100644 index 000000000..5c4dff012 --- /dev/null +++ b/compiler/tflchef/tests/CMakeLists.txt @@ -0,0 +1,129 @@ +if(NOT TARGET nnkit-run) + return() +endif(NOT TARGET nnkit-run) + +if(NOT TARGET nnkit_tflite_backend) + return() +endif(NOT TARGET nnkit_tflite_backend) + +nncc_find_resource(TensorFlowLiteRecipes) +set(TENSORFLOWLITERECIPES_DIR "${TensorFlowLiteRecipes_DIR}") + +file(GLOB RECIPES RELATIVE ${TENSORFLOWLITERECIPES_DIR} "${TENSORFLOWLITERECIPES_DIR}/*/test.recipe") + +foreach(RECIPE IN ITEMS ${RECIPES}) + get_filename_component(RECIPE_PREFIX ${RECIPE} DIRECTORY) + + set(RECIPE_SOURCE_FILE "${RECIPE_PREFIX}.recipe") + set(RECIPE_OUTPUT_FILE "${RECIPE_PREFIX}.tflite") + + # Copy .recipe + add_custom_command(OUTPUT ${RECIPE_SOURCE_FILE} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${TENSORFLOWLITERECIPES_DIR}/${RECIPE}" ${RECIPE_SOURCE_FILE} + DEPENDS "${TENSORFLOWLITERECIPES_DIR}/${RECIPE}" + COMMENT "Generating ${RECIPE_SOURCE_FILE}") + + # Generate .tflite + add_custom_command(OUTPUT ${RECIPE_OUTPUT_FILE} + COMMAND tflchef-file ${RECIPE_SOURCE_FILE} ${RECIPE_OUTPUT_FILE} + DEPENDS tflchef-file ${RECIPE_SOURCE_FILE} + COMMENT "Generating ${RECIPE_OUTPUT_FILE}") + + list(APPEND TESTS ${RECIPE_PREFIX}) + list(APPEND TESTFILES ${RECIPE_OUTPUT_FILE}) +endforeach(RECIPE) + +# Add local files +file(GLOB RECIPES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/test.recipe") + +foreach(RECIPE IN ITEMS ${RECIPES}) + get_filename_component(RECIPE_PREFIX ${RECIPE} DIRECTORY) + + set(RECIPE_SOURCE_FILE "${RECIPE_PREFIX}.recipe") + set(RECIPE_OUTPUT_FILE "${RECIPE_PREFIX}.tflite") + + # Copy .recipe + add_custom_command(OUTPUT ${RECIPE_SOURCE_FILE} + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_SOURCE_DIR}/${RECIPE}" ${RECIPE_SOURCE_FILE} + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${RECIPE}" + COMMENT "Generating ${RECIPE_SOURCE_FILE}") + + # Generate .tflite + add_custom_command(OUTPUT ${RECIPE_OUTPUT_FILE} + COMMAND tflchef-file ${RECIPE_SOURCE_FILE} ${RECIPE_OUTPUT_FILE} + DEPENDS tflchef-file ${RECIPE_SOURCE_FILE} + COMMENT "Generating ${RECIPE_OUTPUT_FILE}") + + list(APPEND TESTS ${RECIPE_PREFIX}) + list(APPEND TESTFILES ${RECIPE_OUTPUT_FILE}) +endforeach(RECIPE) + +# Test tflchef-reverse +file(GLOB GEN_TFLITEFILES RELATIVE ${TENSORFLOWLITERECIPES_DIR} "${TENSORFLOWLITERECIPES_DIR}/*/test.reverse") +# Note: While in development, tflchef-reverse may not handle the operator. +# To separate this linkage scan empty test.reverse for test targets for tflchef-reverse. + +foreach(TFLITEFILE IN ITEMS ${GEN_TFLITEFILES}) + get_filename_component(TFLITE_PREFIX ${TFLITEFILE} DIRECTORY) + + # file from above tflchef-file block + # use tflite file as input of tflchef-reverse generated from tflchef-file + set(RECIPE_OUTPUT_FILE "${TFLITE_PREFIX}.tflite") + set(RECIPE_GEN_OUTPUT_FILE "${TFLITE_PREFIX}.gen.recipe") + set(RECIPE_GEN_OUTPUT_FILE2 "${TFLITE_PREFIX}.gen.tflite") + + # Generate .gen.recipe from generated .tflite + add_custom_command(OUTPUT ${RECIPE_GEN_OUTPUT_FILE} + COMMAND tflchef-reverse ${RECIPE_OUTPUT_FILE} ${RECIPE_GEN_OUTPUT_FILE} + DEPENDS tflchef-reverse ${RECIPE_OUTPUT_FILE} + COMMENT "Generating ${RECIPE_GEN_OUTPUT_FILE}") + + # now we are going to generate .gen.tflite from .gen.recipe + # to check generated .gen.recipe file is correct by using it. + # as weight values may be different, binary comparision is not acceptable. + add_custom_command(OUTPUT ${RECIPE_GEN_OUTPUT_FILE2} + COMMAND tflchef-file ${RECIPE_GEN_OUTPUT_FILE} ${RECIPE_GEN_OUTPUT_FILE2} + DEPENDS tflchef-file ${RECIPE_GEN_OUTPUT_FILE} + COMMENT "Generating ${RECIPE_GEN_OUTPUT_FILE2}") + + list(APPEND TESTS ${TFLITE_PREFIX}.gen) + list(APPEND TESTFILES ${RECIPE_GEN_OUTPUT_FILE2}) +endforeach(TFLITEFILE) + +# Test local tflchef-reverse +file(GLOB GEN_TFLITEFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/test.reverse") + +foreach(TFLITEFILE IN ITEMS ${GEN_TFLITEFILES}) + get_filename_component(TFLITE_PREFIX ${TFLITEFILE} DIRECTORY) + + set(RECIPE_OUTPUT_FILE "${TFLITE_PREFIX}.tflite") + set(RECIPE_GEN_OUTPUT_FILE "${TFLITE_PREFIX}.gen.recipe") + set(RECIPE_GEN_OUTPUT_FILE2 "${TFLITE_PREFIX}.gen.tflite") + + # Generate .gen.recipe from generated .tflite + add_custom_command(OUTPUT ${RECIPE_GEN_OUTPUT_FILE} + COMMAND tflchef-reverse ${RECIPE_OUTPUT_FILE} ${RECIPE_GEN_OUTPUT_FILE} + DEPENDS tflchef-reverse ${RECIPE_OUTPUT_FILE} + COMMENT "Generating ${RECIPE_GEN_OUTPUT_FILE}") + + add_custom_command(OUTPUT ${RECIPE_GEN_OUTPUT_FILE2} + COMMAND tflchef-file ${RECIPE_GEN_OUTPUT_FILE} ${RECIPE_GEN_OUTPUT_FILE2} + DEPENDS tflchef-file ${RECIPE_GEN_OUTPUT_FILE} + COMMENT "Generating ${RECIPE_GEN_OUTPUT_FILE2}") + + list(APPEND TESTS ${TFLITE_PREFIX}.gen) + list(APPEND TESTFILES ${RECIPE_GEN_OUTPUT_FILE2}) +endforeach(TFLITEFILE) + +# Add a dummy target to create a target-level dependency. +# TODO Find a way to create a dependency between tflchef_test and generated testfiles. +add_custom_target(tflchef_testfiles ALL DEPENDS ${TESTFILES}) + +# Using mio_tflite_validate for temporary as it only calls flatbuffer validate +# TODO do testing with running the model with runtime/interpreter +add_test(NAME tflchef_test + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/runvalidate.sh" + $<TARGET_FILE:mio_tflite_validate> + ${TESTS}) diff --git a/compiler/tflchef/tests/explicit_datachef/test.recipe b/compiler/tflchef/tests/explicit_datachef/test.recipe new file mode 100644 index 000000000..bd5213f39 --- /dev/null +++ b/compiler/tflchef/tests/explicit_datachef/test.recipe @@ -0,0 +1,28 @@ +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 1 dim: 1 dim: 10 } +} +operand { + name: "shape" + type: INT32 + shape { dim: 2 } + filler { tag: "explicit" arg: "-1" arg: "10" } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 10 } +} +operation { + type: "Reshape" + reshape_options { + new_shape: -1 + new_shape: 10 + } + input: "ifm" + input: "shape" + output: "ofm" +} +input: "ifm" +output: "ofm" diff --git a/compiler/tflchef/tests/explicit_datachef/test.reverse b/compiler/tflchef/tests/explicit_datachef/test.reverse new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/compiler/tflchef/tests/explicit_datachef/test.reverse diff --git a/compiler/tflchef/tests/multisubgraph/test.recipe b/compiler/tflchef/tests/multisubgraph/test.recipe new file mode 100644 index 000000000..b55af1337 --- /dev/null +++ b/compiler/tflchef/tests/multisubgraph/test.recipe @@ -0,0 +1,72 @@ +version: 1 + +graph { + operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } + } + operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } + } + operation { + type: "ReLU" + input: "ifm" + output: "ofm" + } + input: "ifm" + output: "ofm" + name: "Sub_01" +} + +graph { + operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } + } + operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } + } + operation { + type: "ReLU6" + input: "ifm" + output: "ofm" + } + input: "ifm" + output: "ofm" + name: "Sub_01" +} + +operand { + name: "ifm1" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } +} +operand { + name: "ifm2" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } +} +operation { + type: "Add" + input: "ifm1" + input: "ifm2" + output: "ofm" + add_options { + activation: NONE + } +} +input: "ifm1" +input: "ifm2" +output: "ofm" +name: "Main" diff --git a/compiler/tflchef/tests/readme/test.recipe b/compiler/tflchef/tests/readme/test.recipe new file mode 100644 index 000000000..bc41a3fc0 --- /dev/null +++ b/compiler/tflchef/tests/readme/test.recipe @@ -0,0 +1,44 @@ +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } +} +operand { + name: "ker" + type: FLOAT32 + shape { dim: 1 dim: 1 dim: 1 dim: 2 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "bias" + type: FLOAT32 + shape { dim: 1 } + filler { + tag: "constant" + arg: "1.1" + } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 1 } +} +operation { + type: "Conv2D" + conv2d_options { + padding: VALID + stride_w: 1 + stride_h: 1 + } + input: "ifm" + input: "ker" + input: "bias" + output: "ofm" +} +input: "ifm" +input: "ker" +output: "ofm" diff --git a/compiler/tflchef/tests/readme/test.reverse b/compiler/tflchef/tests/readme/test.reverse new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/compiler/tflchef/tests/readme/test.reverse diff --git a/compiler/tflchef/tests/runall.sh b/compiler/tflchef/tests/runall.sh new file mode 100755 index 000000000..c697f1bc5 --- /dev/null +++ b/compiler/tflchef/tests/runall.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +if [[ $# -le 3 ]]; then + echo "USAGE: $0 [nnkit-run path] [tflite backend path] [working directory] [prefix 0] [prefix 1] ..." + exit 255 +fi + +NNKIT_RUN_PATH="$1"; shift +TFLITE_BACKEND_PATH="$1"; shift +WORKDIR="$1"; shift + +echo "-- Found nnkit-run: ${NNKIT_RUN_PATH}" +echo "-- Found tflite backend: ${TFLITE_BACKEND_PATH}" +echo "-- Found workdir: ${WORKDIR}" + +TESTED=() +PASSED=() +FAILED=() + +pushd "${WORKDIR}" +while [[ $# -ne 0 ]]; do + PREFIX="$1"; shift + + TESTED+=("${PREFIX}") + + PASSED_TAG="${PREFIX}.passed" + + rm -f "${PASSED_TAG}" + + cat > "${PREFIX}.log" <( + exec 2>&1 + + echo "'${NNKIT_RUN_PATH}' --backend '${TFLITE_BACKEND_PATH}' --backend-arg '${PREFIX}.tflite'" + "${NNKIT_RUN_PATH}" --backend "${TFLITE_BACKEND_PATH}" --backend-arg "${PREFIX}.tflite" + + if [[ $? -eq 0 ]]; then + touch "${PASSED_TAG}" + fi + ) + + if [[ -f "${PASSED_TAG}" ]]; then + PASSED+=("$PREFIX") + else + FAILED+=("$PREFIX") + fi +done +popd + +echo "SUMMARY: ${#PASSED[@]} PASS AND ${#FAILED[@]} FAIL AMONG ${#TESTED[@]} TESTS" + +if [[ ${#TESTED[@]} -ne ${#PASSED[@]} ]]; then + echo "FAILED" + for TEST in "${FAILED[@]}" + do + echo "- ${TEST}" + done + exit 255 +fi + +exit 0 diff --git a/compiler/tflchef/tests/runvalidate.sh b/compiler/tflchef/tests/runvalidate.sh new file mode 100755 index 000000000..a1453b399 --- /dev/null +++ b/compiler/tflchef/tests/runvalidate.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +if [[ $# -le 3 ]]; then + echo "USAGE: $0 [mio_tflite_validate path] [prefix 0] " + exit 255 +fi + +MIO_TFLITE_VALIDATE_PATH="$1"; shift + +echo "-- Found mio_tflite_validate: ${NNKIT_RUN_PATH}" + +TESTED=() +PASSED=() +FAILED=() + +pushd "${WORKDIR}" +while [[ $# -ne 0 ]]; do + PREFIX="$1"; shift + + TESTED+=("${PREFIX}") + + PASSED_TAG="${PREFIX}.passed" + + rm -f "${PASSED_TAG}" + + cat > "${PREFIX}.log" <( + exec 2>&1 + + echo "'${MIO_TFLITE_VALIDATE_PATH}' '${PREFIX}.tflite'" + "${MIO_TFLITE_VALIDATE_PATH}" "${PREFIX}.tflite" + + if [[ $? -eq 0 ]]; then + touch "${PASSED_TAG}" + fi + ) + + if [[ -f "${PASSED_TAG}" ]]; then + PASSED+=("$PREFIX") + else + FAILED+=("$PREFIX") + fi +done +popd + +echo "SUMMARY: ${#PASSED[@]} PASS AND ${#FAILED[@]} FAIL AMONG ${#TESTED[@]} TESTS" + +if [[ ${#TESTED[@]} -ne ${#PASSED[@]} ]]; then + echo "FAILED" + for TEST in "${FAILED[@]}" + do + echo "- ${TEST}" + done + exit 255 +fi + +exit 0 diff --git a/compiler/tflchef/tflite/CMakeLists.txt b/compiler/tflchef/tflite/CMakeLists.txt new file mode 100644 index 000000000..645c16144 --- /dev/null +++ b/compiler/tflchef/tflite/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB_RECURSE SOURCES "src/*.cpp") + +add_library(tflchef_tflite STATIC ${SOURCES}) +target_include_directories(tflchef_tflite PUBLIC include) +target_include_directories(tflchef_tflite PRIVATE src) +target_link_libraries(tflchef_tflite tflchef_proto) +target_link_libraries(tflchef_tflite mio_tflite) +target_link_libraries(tflchef_tflite stdex) +target_link_libraries(tflchef_tflite cwrap) diff --git a/compiler/tflchef/tflite/include/tflchef/RawModel.h b/compiler/tflchef/tflite/include/tflchef/RawModel.h new file mode 100644 index 000000000..a8c8fefb7 --- /dev/null +++ b/compiler/tflchef/tflite/include/tflchef/RawModel.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAW_MODEL_H__ +#define __RAW_MODEL_H__ + +#include <mio/tflite/schema_generated.h> + +namespace tflchef +{ + +struct RawModel +{ + virtual ~RawModel() = default; + + virtual const ::tflite::Model *model(void) const = 0; +}; + +/** + * @brief Load TensorFlow Lite model (as a RawModel) from a given path + * + * @note May return a nullptr + */ +std::unique_ptr<RawModel> load_tflite(const std::string &path); + +} // namespace tflchef + +#endif // __RAW_MODEL_H__ diff --git a/compiler/tflchef/tflite/include/tflchef/RecipeChef.h b/compiler/tflchef/tflite/include/tflchef/RecipeChef.h new file mode 100644 index 000000000..2d292c3d5 --- /dev/null +++ b/compiler/tflchef/tflite/include/tflchef/RecipeChef.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RECIPE_CHEF_H__ +#define __RECIPE_CHEF_H__ + +#include <mio/tflite/schema_generated.h> +#include <tflchef.pb.h> + +#include <memory> +#include <string> + +namespace tflchef +{ + +/** + * @brief Create ModelRecipe from tflite::Model + */ +std::unique_ptr<ModelRecipe> generate_recipe(const tflite::Model *model); + +/** + * @brief Write ModelRecipe to file with given name + */ +bool write_recipe(const std::string &filename, std::unique_ptr<ModelRecipe> &recipe); + +} // namespace tflchef + +#endif // __RECIPE_CHEF_H__ diff --git a/compiler/tflchef/tflite/src/Convert.cpp b/compiler/tflchef/tflite/src/Convert.cpp new file mode 100644 index 000000000..dc60e0087 --- /dev/null +++ b/compiler/tflchef/tflite/src/Convert.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Convert.h" + +namespace tflchef +{ + +tflchef::TensorType as_tflchef_type(const tflite::TensorType type) +{ + switch (type) + { + case tflite::TensorType_FLOAT32: + return tflchef::FLOAT32; + case tflite::TensorType_INT32: + return tflchef::INT32; + case tflite::TensorType_INT64: + return tflchef::INT64; + case tflite::TensorType_UINT8: + return tflchef::UINT8; + case tflite::TensorType_BOOL: + return tflchef::BOOL; + // TODO handle other types + // TensorType_FLOAT16 + // TensorType_STRING + // TensorType_INT16 + // TensorType_COMPLEX64 + default: + throw std::runtime_error{"unsupported tensor type"}; + } +} + +tflchef::Activation as_tflchef_activation(const tflite::ActivationFunctionType type) +{ + switch (type) + { + case tflite::ActivationFunctionType_NONE: + return tflchef::NONE; + case tflite::ActivationFunctionType_RELU: + return tflchef::RELU; + case tflite::ActivationFunctionType_RELU6: + return tflchef::RELU6; + // TODO handle other types + // ActivationFunctionType_RELU_N1_TO_1 + // ActivationFunctionType_TANH + // ActivationFunctionType_SIGN_BIT + default: + throw std::runtime_error{"unsupported activation type"}; + } +} + +tflchef::Padding as_tflchef_padding(const tflite::Padding padding) +{ + switch (padding) + { + case tflite::Padding_SAME: + return tflchef::SAME; + case tflite::Padding_VALID: + return tflchef::VALID; + default: + throw std::runtime_error{"unsupported padding"}; + } +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Convert.h b/compiler/tflchef/tflite/src/Convert.h new file mode 100644 index 000000000..8623e7b78 --- /dev/null +++ b/compiler/tflchef/tflite/src/Convert.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONVERT_H__ +#define __CONVERT_H__ + +#include <mio/tflite/schema_generated.h> + +#include <tflchef.pb.h> + +namespace tflchef +{ + +tflchef::TensorType as_tflchef_type(const tflite::TensorType type); +tflchef::Activation as_tflchef_activation(const tflite::ActivationFunctionType type); +tflchef::Padding as_tflchef_padding(const tflite::Padding padding); + +/** + * @brief extract buffer data to std::vector<DT> + */ +template <typename DT> std::vector<DT> extract_buffer(const tflite::Buffer *buffer) +{ + auto buffer_length = buffer->data()->size(); + auto num_elements = buffer_length / sizeof(DT); + std::vector<DT> result(num_elements); + std::memcpy(result.data(), buffer->data()->data(), buffer_length); + return result; +} + +template <typename T> std::vector<T> as_index_vector(const flatbuffers::Vector<T> *flat_array) +{ + std::vector<T> ret(flat_array->Length()); + for (uint32_t i = 0; i < flat_array->Length(); i++) + { + ret[i] = flat_array->Get(i); + } + return ret; +} + +} // namespace tflchef + +#endif // __CONVERT_H__ diff --git a/compiler/tflchef/tflite/src/Op/Abs.cpp b/compiler/tflchef/tflite/src/Op/Abs.cpp new file mode 100644 index 000000000..7d769e344 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Abs.cpp @@ -0,0 +1,40 @@ +/* + * 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 "Abs.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpAbs::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpAbs::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Abs"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Abs.h b/compiler/tflchef/tflite/src/Op/Abs.h new file mode 100644 index 000000000..d99b0d593 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Abs.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_ABS_H__ +#define __TFLITE_OP_ABS_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for abs + */ +class TFliteOpAbs : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_ABS_H__ diff --git a/compiler/tflchef/tflite/src/Op/Add.cpp b/compiler/tflchef/tflite/src/Op/Add.cpp new file mode 100644 index 000000000..7e669ecc9 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Add.cpp @@ -0,0 +1,47 @@ +/* + * 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 "Add.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpAdd::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpAdd::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_AddOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Add"); + + auto op_options = operation->mutable_add_options(); + + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Add.h b/compiler/tflchef/tflite/src/Op/Add.h new file mode 100644 index 000000000..49d945f8b --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Add.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_ADD_H__ +#define __TFLITE_OP_ADD_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for add + */ +class TFliteOpAdd : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_ADD_H__ diff --git a/compiler/tflchef/tflite/src/Op/ArgMax.cpp b/compiler/tflchef/tflite/src/Op/ArgMax.cpp new file mode 100644 index 000000000..f4d1c5e66 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ArgMax.cpp @@ -0,0 +1,54 @@ +/* + * 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 "ArgMax.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpArgMax::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // filler for second input, argmax/dim + const auto &inputs = *op->inputs(); + + const tflite::Tensor *dim_tensor = import->tensors()->Get(inputs[1]); + assert(dim_tensor->type() == tflite::TensorType::TensorType_INT32); + const tflite::Buffer *buffer = import->buffers()->Get(dim_tensor->buffer()); + auto vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[1], vec); +} + +tflchef::Operation *TFliteOpArgMax::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_ArgMaxOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("ArgMax"); + + auto op_options = operation->mutable_argmax_options(); + + op_options->set_output_type(as_tflchef_type(op_params->output_type())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/ArgMax.h b/compiler/tflchef/tflite/src/Op/ArgMax.h new file mode 100644 index 000000000..30068ecf2 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ArgMax.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_ARGMAX_H__ +#define __TFLITE_OP_ARGMAX_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for ArgMax + */ +class TFliteOpArgMax : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_ARGMAX_H__ diff --git a/compiler/tflchef/tflite/src/Op/AveragePool2D.cpp b/compiler/tflchef/tflite/src/Op/AveragePool2D.cpp new file mode 100644 index 000000000..1f269e45e --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/AveragePool2D.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AveragePool2D.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpAveragePool2D::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpAveragePool2D::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_Pool2DOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("AveragePool2D"); + + auto op_options = operation->mutable_averagepool2d_options(); + + op_options->set_padding(as_tflchef_padding(op_params->padding())); + op_options->set_stride_h(op_params->stride_h()); + op_options->set_stride_w(op_params->stride_w()); + op_options->set_filter_height(op_params->filter_height()); + op_options->set_filter_width(op_params->filter_width()); + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/AveragePool2D.h b/compiler/tflchef/tflite/src/Op/AveragePool2D.h new file mode 100644 index 000000000..f9e9fb254 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/AveragePool2D.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_AVERAGEPOOL2D_H__ +#define __TFLITE_OP_AVERAGEPOOL2D_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for AveragePool2D + */ +class TFliteOpAveragePool2D : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_AVERAGEPOOL2D_H__ diff --git a/compiler/tflchef/tflite/src/Op/BatchToSpaceND.cpp b/compiler/tflchef/tflite/src/Op/BatchToSpaceND.cpp new file mode 100644 index 000000000..d5d9606d1 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/BatchToSpaceND.cpp @@ -0,0 +1,53 @@ +/* + * 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 "BatchToSpaceND.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpBatchToSpaceND::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // filler for second, third input + const auto &inputs = *op->inputs(); + + const tflite::Tensor *tensor = import->tensors()->Get(inputs[1]); + assert(tensor->type() == tflite::TensorType::TensorType_INT32); + const tflite::Buffer *buffer = import->buffers()->Get(tensor->buffer()); + auto vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[1], vec); + + tensor = import->tensors()->Get(inputs[2]); + assert(tensor->type() == tflite::TensorType::TensorType_INT32); + buffer = import->buffers()->Get(tensor->buffer()); + vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[2], vec); +} + +tflchef::Operation *TFliteOpBatchToSpaceND::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("BatchToSpaceND"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/BatchToSpaceND.h b/compiler/tflchef/tflite/src/Op/BatchToSpaceND.h new file mode 100644 index 000000000..ae2114c97 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/BatchToSpaceND.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_BATCHTOSPACEND_H__ +#define __TFLITE_OP_BATCHTOSPACEND_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for BatchToSpaceND + */ +class TFliteOpBatchToSpaceND : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_BATCHTOSPACEND_H__ diff --git a/compiler/tflchef/tflite/src/Op/Concatenation.cpp b/compiler/tflchef/tflite/src/Op/Concatenation.cpp new file mode 100644 index 000000000..126402f14 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Concatenation.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Concatenation.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpConcatenation::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpConcatenation::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_ConcatenationOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Concatenation"); + + auto op_options = operation->mutable_concatenation_options(); + + op_options->set_axis(op_params->axis()); + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Concatenation.h b/compiler/tflchef/tflite/src/Op/Concatenation.h new file mode 100644 index 000000000..4a7ea5791 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Concatenation.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_CONCATENATION_H__ +#define __TFLITE_OP_CONCATENATION_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Concatenation + */ +class TFliteOpConcatenation : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_CONCATENATION_H__ diff --git a/compiler/tflchef/tflite/src/Op/Conv2D.cpp b/compiler/tflchef/tflite/src/Op/Conv2D.cpp new file mode 100644 index 000000000..5d48ee24f --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Conv2D.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conv2D.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpConv2D::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + const std::vector<int32_t> &inputs = as_index_vector(op->inputs()); + + bool hasBias = (inputs.size() == 3); + assert(inputs.size() == 2 || hasBias); + + import->set_tensor_filler(inputs.at(1)); // kernel + if (hasBias) + import->set_tensor_filler(inputs.at(2)); // bias +} + +tflchef::Operation *TFliteOpConv2D::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_Conv2DOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Conv2D"); + + auto op_options = operation->mutable_conv2d_options(); + + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + op_options->set_stride_h(op_params->stride_h()); + op_options->set_stride_w(op_params->stride_w()); + op_options->set_padding(as_tflchef_padding(op_params->padding())); + // TODO support dilation + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Conv2D.h b/compiler/tflchef/tflite/src/Op/Conv2D.h new file mode 100644 index 000000000..0216e9ce9 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Conv2D.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_CONV2D_H__ +#define __TFLITE_OP_CONV2D_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Conv2D + */ +class TFliteOpConv2D : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_CONV2D_H__ diff --git a/compiler/tflchef/tflite/src/Op/Cos.cpp b/compiler/tflchef/tflite/src/Op/Cos.cpp new file mode 100644 index 000000000..9f2c49d49 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Cos.cpp @@ -0,0 +1,40 @@ +/* + * 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 "Cos.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpCos::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpCos::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Cos"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Cos.h b/compiler/tflchef/tflite/src/Op/Cos.h new file mode 100644 index 000000000..8f3dbe3a6 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Cos.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_COS_H__ +#define __TFLITE_OP_COS_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Cos + */ +class TFliteOpCos : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_COS_H__ diff --git a/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.cpp b/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.cpp new file mode 100644 index 000000000..b19f9330f --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DepthwiseConv2D.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpDepthwiseConv2D::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + const std::vector<int32_t> &inputs = as_index_vector(op->inputs()); + + bool hasBias = (inputs.size() == 3); + assert(inputs.size() == 2 || hasBias); + + import->set_tensor_filler(inputs.at(1)); // kernel + if (hasBias) + import->set_tensor_filler(inputs.at(2)); // bias +} + +tflchef::Operation *TFliteOpDepthwiseConv2D::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_DepthwiseConv2DOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("DepthwiseConv2D"); + + auto op_options = operation->mutable_depthwiseconv2d_options(); + + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + op_options->set_stride_h(op_params->stride_h()); + op_options->set_stride_w(op_params->stride_w()); + op_options->set_depth_multiplier(op_params->depth_multiplier()); + // TODO support dilation + // op_params->dilation_w_factor() + // op_params->dilation_h_factor() + op_options->set_padding(as_tflchef_padding(op_params->padding())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.h b/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.h new file mode 100644 index 000000000..c172536b4 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/DepthwiseConv2D.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_DEPTHWISECONV2D_H__ +#define __TFLITE_OP_DEPTHWISECONV2D_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for DepthwiseConv2D + */ +class TFliteOpDepthwiseConv2D : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_DEPTHWISECONV2D_H__ diff --git a/compiler/tflchef/tflite/src/Op/Div.cpp b/compiler/tflchef/tflite/src/Op/Div.cpp new file mode 100644 index 000000000..0fd87dc05 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Div.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Div.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpDiv::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpDiv::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_DivOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Div"); + + auto op_options = operation->mutable_div_options(); + + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Div.h b/compiler/tflchef/tflite/src/Op/Div.h new file mode 100644 index 000000000..254a4cd99 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Div.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_DIV_H__ +#define __TFLITE_OP_DIV_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for division + */ +class TFliteOpDiv : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_DIV_H__ diff --git a/compiler/tflchef/tflite/src/Op/Equal.cpp b/compiler/tflchef/tflite/src/Op/Equal.cpp new file mode 100644 index 000000000..a51586228 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Equal.cpp @@ -0,0 +1,40 @@ +/* + * 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 "Equal.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpEqual::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpEqual::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Equal"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Equal.h b/compiler/tflchef/tflite/src/Op/Equal.h new file mode 100644 index 000000000..fd4b40001 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Equal.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_EQUAL_H__ +#define __TFLITE_OP_EQUAL_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Equal + */ +class TFliteOpEqual : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_EQUAL_H__ diff --git a/compiler/tflchef/tflite/src/Op/Exp.cpp b/compiler/tflchef/tflite/src/Op/Exp.cpp new file mode 100644 index 000000000..f715da6ef --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Exp.cpp @@ -0,0 +1,40 @@ +/* + * 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 "Exp.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpExp::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpExp::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Exp"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Exp.h b/compiler/tflchef/tflite/src/Op/Exp.h new file mode 100644 index 000000000..5ff3ddc8b --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Exp.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_EXP_H__ +#define __TFLITE_OP_EXP_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Exp + */ +class TFliteOpExp : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_EXP_H__ diff --git a/compiler/tflchef/tflite/src/Op/FloorDiv.cpp b/compiler/tflchef/tflite/src/Op/FloorDiv.cpp new file mode 100644 index 000000000..492c6941f --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/FloorDiv.cpp @@ -0,0 +1,40 @@ +/* + * 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 "FloorDiv.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpFloorDiv::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpFloorDiv::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("FloorDiv"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/FloorDiv.h b/compiler/tflchef/tflite/src/Op/FloorDiv.h new file mode 100644 index 000000000..5d049a668 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/FloorDiv.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_FLOORDIV_H__ +#define __TFLITE_OP_FLOORDIV_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for floor division + */ +class TFliteOpFloorDiv : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_FLOORDIV_H__ diff --git a/compiler/tflchef/tflite/src/Op/FullyConnected.cpp b/compiler/tflchef/tflite/src/Op/FullyConnected.cpp new file mode 100644 index 000000000..4291c844b --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/FullyConnected.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FullyConnected.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpFullyConnected::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpFullyConnected::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_FullyConnectedOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("FullyConnected"); + + auto op_options = operation->mutable_fullyconnected_options(); + + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/FullyConnected.h b/compiler/tflchef/tflite/src/Op/FullyConnected.h new file mode 100644 index 000000000..8fbe1f3ed --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/FullyConnected.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_FULLYCONNECTED_H__ +#define __TFLITE_OP_FULLYCONNECTED_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for FullyConnected + */ +class TFliteOpFullyConnected : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_FULLYCONNECTED_H__ diff --git a/compiler/tflchef/tflite/src/Op/LogicalNot.cpp b/compiler/tflchef/tflite/src/Op/LogicalNot.cpp new file mode 100644 index 000000000..ecd5b903c --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/LogicalNot.cpp @@ -0,0 +1,40 @@ +/* + * 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 "LogicalNot.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpLogicalNot::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpLogicalNot::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("LogicalNot"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/LogicalNot.h b/compiler/tflchef/tflite/src/Op/LogicalNot.h new file mode 100644 index 000000000..b75d33554 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/LogicalNot.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_LOGICALNOT_H__ +#define __TFLITE_OP_LOGICALNOT_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for LogicalNot + */ +class TFliteOpLogicalNot : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_LOGICALNOT_H__ diff --git a/compiler/tflchef/tflite/src/Op/LogicalOr.cpp b/compiler/tflchef/tflite/src/Op/LogicalOr.cpp new file mode 100644 index 000000000..b91f4cfca --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/LogicalOr.cpp @@ -0,0 +1,40 @@ +/* + * 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 "LogicalOr.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpLogicalOr::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpLogicalOr::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("LogicalOr"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/LogicalOr.h b/compiler/tflchef/tflite/src/Op/LogicalOr.h new file mode 100644 index 000000000..5331a0d65 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/LogicalOr.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_LOGICALOR_H__ +#define __TFLITE_OP_LOGICALOR_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for LogicalOr + */ +class TFliteOpLogicalOr : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_LOGICALOR_H__ diff --git a/compiler/tflchef/tflite/src/Op/MaxPool2D.cpp b/compiler/tflchef/tflite/src/Op/MaxPool2D.cpp new file mode 100644 index 000000000..1366366ac --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/MaxPool2D.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MaxPool2D.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpMaxPool2D::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpMaxPool2D::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_Pool2DOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("MaxPool2D"); + + auto op_options = operation->mutable_maxpool2d_options(); + + op_options->set_padding(as_tflchef_padding(op_params->padding())); + op_options->set_stride_h(op_params->stride_h()); + op_options->set_stride_w(op_params->stride_w()); + op_options->set_filter_height(op_params->filter_height()); + op_options->set_filter_width(op_params->filter_width()); + op_options->set_activation(as_tflchef_activation(op_params->fused_activation_function())); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/MaxPool2D.h b/compiler/tflchef/tflite/src/Op/MaxPool2D.h new file mode 100644 index 000000000..36533f80c --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/MaxPool2D.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_MAXPOOL2D_H__ +#define __TFLITE_OP_MAXPOOL2D_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for MaxPool2D + */ +class TFliteOpMaxPool2D : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_MAXPOOL2D_H__ diff --git a/compiler/tflchef/tflite/src/Op/Mean.cpp b/compiler/tflchef/tflite/src/Op/Mean.cpp new file mode 100644 index 000000000..1c2975781 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Mean.cpp @@ -0,0 +1,54 @@ +/* + * 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 "Mean.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpMean::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // filler for second input + const auto &inputs = *op->inputs(); + + const tflite::Tensor *tensor = import->tensors()->Get(inputs[1]); + assert(tensor->type() == tflite::TensorType::TensorType_INT32); + const tflite::Buffer *buffer = import->buffers()->Get(tensor->buffer()); + auto vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[1], vec); +} + +tflchef::Operation *TFliteOpMean::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_ReducerOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Mean"); + + auto op_options = operation->mutable_mean_options(); + + op_options->set_keep_dims(op_params->keep_dims()); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Mean.h b/compiler/tflchef/tflite/src/Op/Mean.h new file mode 100644 index 000000000..532c40c66 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Mean.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_MEAN_H__ +#define __TFLITE_OP_MEAN_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for mean + */ +class TFliteOpMean : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_MEAN_H__ diff --git a/compiler/tflchef/tflite/src/Op/Pack.cpp b/compiler/tflchef/tflite/src/Op/Pack.cpp new file mode 100644 index 000000000..ddf8c7d5d --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Pack.cpp @@ -0,0 +1,48 @@ +/* + * 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 "Pack.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpPack::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpPack::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_PackOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Pack"); + + auto op_options = operation->mutable_pack_options(); + + op_options->set_axis(op_params->axis()); + op_options->set_values_count(op_params->values_count()); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Pack.h b/compiler/tflchef/tflite/src/Op/Pack.h new file mode 100644 index 000000000..7779f64ed --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Pack.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_PACK_H__ +#define __TFLITE_OP_PACK_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for pack + */ +class TFliteOpPack : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_PACK_H__ diff --git a/compiler/tflchef/tflite/src/Op/Pad.cpp b/compiler/tflchef/tflite/src/Op/Pad.cpp new file mode 100644 index 000000000..2978e4422 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Pad.cpp @@ -0,0 +1,47 @@ +/* + * 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 "Pad.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpPad::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // filler for second input + const auto &inputs = *op->inputs(); + + const tflite::Tensor *tensor = import->tensors()->Get(inputs[1]); + assert(tensor->type() == tflite::TensorType::TensorType_INT32); + const tflite::Buffer *buffer = import->buffers()->Get(tensor->buffer()); + auto vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[1], vec); +} + +tflchef::Operation *TFliteOpPad::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Pad"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Pad.h b/compiler/tflchef/tflite/src/Op/Pad.h new file mode 100644 index 000000000..99998d418 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Pad.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_PAD_H__ +#define __TFLITE_OP_PAD_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for PAD + */ +class TFliteOpPad : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_PAD_H__ diff --git a/compiler/tflchef/tflite/src/Op/ReLU.cpp b/compiler/tflchef/tflite/src/Op/ReLU.cpp new file mode 100644 index 000000000..e4474b6fa --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ReLU.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ReLU.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpReLU::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpReLU::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("ReLU"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/ReLU.h b/compiler/tflchef/tflite/src/Op/ReLU.h new file mode 100644 index 000000000..be1090270 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ReLU.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_RELU_H__ +#define __TFLITE_OP_RELU_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for ReLU + */ +class TFliteOpReLU : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_RELU_H__ diff --git a/compiler/tflchef/tflite/src/Op/ReLU6.cpp b/compiler/tflchef/tflite/src/Op/ReLU6.cpp new file mode 100644 index 000000000..14371884b --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ReLU6.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ReLU6.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpReLU6::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpReLU6::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("ReLU6"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/ReLU6.h b/compiler/tflchef/tflite/src/Op/ReLU6.h new file mode 100644 index 000000000..64ddb6a2e --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/ReLU6.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_RELU6_H__ +#define __TFLITE_OP_RELU6_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for ReLU6 + */ +class TFliteOpReLU6 : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_RELU6_H__ diff --git a/compiler/tflchef/tflite/src/Op/Reshape.cpp b/compiler/tflchef/tflite/src/Op/Reshape.cpp new file mode 100644 index 000000000..663ab3ec3 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Reshape.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Reshape.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpReshape::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + const std::vector<int32_t> &inputs = as_index_vector(op->inputs()); + + bool hasShape = (inputs.size() == 2); + assert(inputs.size() == 1 || hasShape); + + if (hasShape) + { + auto op_params = op->builtin_options_as_ReshapeOptions(); + std::vector<int32_t> new_shape = as_index_vector(op_params->new_shape()); + import->set_tensor_filler(inputs.at(1), new_shape); + } +} + +tflchef::Operation *TFliteOpReshape::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_ReshapeOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Reshape"); + + auto op_options = operation->mutable_reshape_options(); + + std::vector<int32_t> new_shape = as_index_vector(op_params->new_shape()); + + for (auto shape : new_shape) + { + op_options->add_new_shape(shape); + } + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Reshape.h b/compiler/tflchef/tflite/src/Op/Reshape.h new file mode 100644 index 000000000..be9fdac08 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Reshape.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_RESHAPE_H__ +#define __TFLITE_OP_RESHAPE_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Reshape + */ +class TFliteOpReshape : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_RESHAPE_H__ diff --git a/compiler/tflchef/tflite/src/Op/Rsqrt.cpp b/compiler/tflchef/tflite/src/Op/Rsqrt.cpp new file mode 100644 index 000000000..1639214e4 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Rsqrt.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Rsqrt.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpRsqrt::filler(const tflite::Operator *, TFliteImport *, tflchef::ModelRecipe *) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpRsqrt::build(const tflite::Operator *, TFliteImport *, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Rsqrt"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Rsqrt.h b/compiler/tflchef/tflite/src/Op/Rsqrt.h new file mode 100644 index 000000000..5d68344c2 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Rsqrt.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_RSQRT_H__ +#define __TFLITE_OP_RSQRT_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Rsqrt + */ +class TFliteOpRsqrt : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_RSQRT_H__ diff --git a/compiler/tflchef/tflite/src/Op/Softmax.cpp b/compiler/tflchef/tflite/src/Op/Softmax.cpp new file mode 100644 index 000000000..5b5c94f7e --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Softmax.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Softmax.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpSoftmax::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpSoftmax::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_SoftmaxOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Softmax"); + + auto op_options = operation->mutable_softmax_options(); + + op_options->set_beta(op_params->beta()); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Softmax.h b/compiler/tflchef/tflite/src/Op/Softmax.h new file mode 100644 index 000000000..cf168bdd9 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Softmax.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_SOFTMAX_H__ +#define __TFLITE_OP_SOFTMAX_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Softmax + */ +class TFliteOpSoftmax : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_SOFTMAX_H__ diff --git a/compiler/tflchef/tflite/src/Op/Sqrt.cpp b/compiler/tflchef/tflite/src/Op/Sqrt.cpp new file mode 100644 index 000000000..dd6bfcab0 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Sqrt.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Sqrt.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpSqrt::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler + // But input has filler for constant inputs + const auto &inputs = *op->inputs(); + + const tflite::Tensor *tensor = import->tensors()->Get(inputs[0]); + if (tensor->type() == tflite::TensorType::TensorType_FLOAT32) + { + const tflite::Buffer *buffer = import->buffers()->Get(tensor->buffer()); + if (buffer && buffer->data()) + { + auto vec = extract_buffer<float>(buffer); + import->set_tensor_filler(inputs[0], vec); + } + } +} + +tflchef::Operation *TFliteOpSqrt::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Sqrt"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Sqrt.h b/compiler/tflchef/tflite/src/Op/Sqrt.h new file mode 100644 index 000000000..9f0ad04ae --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Sqrt.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_SQRT_H__ +#define __TFLITE_OP_SQRT_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Sqrt + */ +class TFliteOpSqrt : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_SQRT_H__ diff --git a/compiler/tflchef/tflite/src/Op/Sub.cpp b/compiler/tflchef/tflite/src/Op/Sub.cpp new file mode 100644 index 000000000..db77fddf7 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Sub.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Sub.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpSub::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpSub::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as_SubOptions(); + assert(op_params != nullptr); + + auto operation = model_recipe->add_operation(); + + operation->set_type("Sub"); + + auto op_options = operation->mutable_sub_options(); + + auto tflchef_activation = as_tflchef_activation(op_params->fused_activation_function()); + op_options->set_activation(tflchef_activation); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Sub.h b/compiler/tflchef/tflite/src/Op/Sub.h new file mode 100644 index 000000000..2168e5e0d --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Sub.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_SUB_H__ +#define __TFLITE_OP_SUB_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Sub + */ +class TFliteOpSub : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_SUB_H__ diff --git a/compiler/tflchef/tflite/src/Op/Tanh.cpp b/compiler/tflchef/tflite/src/Op/Tanh.cpp new file mode 100644 index 000000000..cab8ca460 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Tanh.cpp @@ -0,0 +1,39 @@ +/* + * 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 "Tanh.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpTanh::filler(const tflite::Operator *, TFliteImport *, tflchef::ModelRecipe *) const +{ + // Nothing to do with filler +} + +tflchef::Operation *TFliteOpTanh::build(const tflite::Operator *, TFliteImport *, + tflchef::ModelRecipe *model_recipe) const +{ + auto operation = model_recipe->add_operation(); + + operation->set_type("Tanh"); + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Tanh.h b/compiler/tflchef/tflite/src/Op/Tanh.h new file mode 100644 index 000000000..7339e4103 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Tanh.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_TANH_H__ +#define __TFLITE_OP_TANH_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Tanh + */ +class TFliteOpTanh : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_TANH_H__ diff --git a/compiler/tflchef/tflite/src/Op/Transpose.cpp b/compiler/tflchef/tflite/src/Op/Transpose.cpp new file mode 100644 index 000000000..ae97a19e2 --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Transpose.cpp @@ -0,0 +1,53 @@ +/* + * 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 "Transpose.h" + +#include "Convert.h" + +namespace tflchef +{ + +void TFliteOpTranspose::filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + const auto &inputs = *op->inputs(); + + const tflite::Tensor *perm_tensor = import->tensors()->Get(inputs[1]); + assert(perm_tensor->type() == tflite::TensorType::TensorType_INT32); + const tflite::Buffer *buffer = import->buffers()->Get(perm_tensor->buffer()); + auto vec = extract_buffer<int32_t>(buffer); + import->set_tensor_filler(inputs[1], vec); +} + +tflchef::Operation *TFliteOpTranspose::build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const +{ + auto op_params = op->builtin_options_as<tflite::TransposeOptions>(); + assert(op_params != nullptr); + (void)op_params; + + auto operation = model_recipe->add_operation(); + + operation->set_type("Transpose"); + + auto op_options = operation->mutable_transpose_options(); + (void)op_options; + + return operation; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/Op/Transpose.h b/compiler/tflchef/tflite/src/Op/Transpose.h new file mode 100644 index 000000000..f0d944b6b --- /dev/null +++ b/compiler/tflchef/tflite/src/Op/Transpose.h @@ -0,0 +1,39 @@ +/* + * 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 __TFLITE_OP_TRANSPOSE_H__ +#define __TFLITE_OP_TRANSPOSE_H__ + +#include "TFliteOpChef.h" + +namespace tflchef +{ + +/** + * @brief tflchef operator builder for Transpose + */ +class TFliteOpTranspose : public TFliteOpChef +{ +public: + void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; + tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const override; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_TRANSPOSE_H__ diff --git a/compiler/tflchef/tflite/src/RawModelLoader.cpp b/compiler/tflchef/tflite/src/RawModelLoader.cpp new file mode 100644 index 000000000..e9ef8ec8b --- /dev/null +++ b/compiler/tflchef/tflite/src/RawModelLoader.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <tflchef/RawModel.h> + +#include <cwrap/Fildes.h> + +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/mman.h> + +namespace +{ + +class MemoryMappedRawModel final : public tflchef::RawModel +{ +public: + /** + * @require fd and data SHOULD be valid + */ + explicit MemoryMappedRawModel(int fd, void *data, size_t size) : _fd{fd}, _data{data}, _size{size} + { + // DO NOTHING + } + +public: + ~MemoryMappedRawModel() + { + munmap(_data, _size); + close(_fd); + } + +public: + MemoryMappedRawModel(const MemoryMappedRawModel &) = delete; + MemoryMappedRawModel(MemoryMappedRawModel &&) = delete; + +public: + const ::tflite::Model *model(void) const override { return ::tflite::GetModel(_data); } + +private: + int _fd = -1; + void *_data = nullptr; + size_t _size = 0; +}; + +} // namespace + +namespace tflchef +{ + +std::unique_ptr<RawModel> load_tflite(const std::string &path) +{ + cwrap::Fildes fildes{open(path.c_str(), O_RDONLY)}; + + if (fildes.get() == -1) + { + // Return nullptr on open failure + return nullptr; + } + + struct stat st; + if (fstat(fildes.get(), &st) == -1) + { + // Return nullptr on fstat failure + return nullptr; + } + + auto size = st.st_size; + auto data = mmap(nullptr, size, PROT_READ, MAP_SHARED, fildes.get(), 0); + + if (data == MAP_FAILED) + { + // Return nullptr on mmap failure + return nullptr; + } + + return std::unique_ptr<tflchef::RawModel>{new MemoryMappedRawModel(fildes.release(), data, size)}; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/RecipeChef.cpp b/compiler/tflchef/tflite/src/RecipeChef.cpp new file mode 100644 index 000000000..407006b26 --- /dev/null +++ b/compiler/tflchef/tflite/src/RecipeChef.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <tflchef/RecipeChef.h> + +#include "Convert.h" +#include "TFliteImport.h" +#include "TFliteOpChef.h" +#include "TFliteOpChefs.h" +#include "TFliteOpRegistry.h" + +#include <fstream> +#include <sstream> + +namespace tflchef +{ + +void set_inputs(TFliteImport *import, tflchef::Operation *operation, const tflite::Operator *op) +{ + auto tensors = import->tensors(); + const std::vector<int32_t> &inputs = as_index_vector(op->inputs()); + + for (auto input : inputs) + { + auto tensor = tensors->Get(input); + std::string name = tensor_name(tensor); + operation->add_input(name); + } +} + +void set_outputs(TFliteImport *import, tflchef::Operation *operation, const tflite::Operator *op) +{ + auto tensors = import->tensors(); + const std::vector<int32_t> &outputs = as_index_vector(op->outputs()); + + for (auto output : outputs) + { + auto tensor = tensors->Get(output); + std::string name = tensor_name(tensor); + operation->add_output(name); + } +} + +/** + * @brief This will build ModelRecipe from tflite::Model + * First to check operand filler options by scanning all operators, + * then translate all operands and operators. + * Last will set network inputs and outputs. + */ +std::unique_ptr<ModelRecipe> generate_recipe(const tflite::Model *model) +{ + std::unique_ptr<ModelRecipe> model_recipe{new ModelRecipe()}; + + TFliteImport tflite_import(model); + + assert(tflite_import.num_subgraph() == 1); + tflite_import.select_sub_graph(0); + + auto tensors = tflite_import.tensors(); + auto buffers = tflite_import.buffers(); + auto operators = tflite_import.operators(); + + // operand fillers for adding all operators + for (uint32_t i = 0; i < operators->Length(); ++i) + { + const auto *op = operators->Get(i); + tflite::BuiltinOperator builtincode = tflite_import.builtin_code(op); + + if (const auto *graph_builder = TFliteOpRegistry::get().lookup(builtincode)) + { + graph_builder->filler(op, &tflite_import, model_recipe.get()); + } + else + { + std::string opcodename = tflite_import.opcode_name(op); + throw std::runtime_error{"Not supported: " + opcodename}; + } + } + + // add all operands(tensors) + for (uint32_t i = 0; i < tensors->Length(); ++i) + { + auto tensor = tensors->Get(i); + + // check buffer + if (tensor->buffer() >= buffers->size()) + throw std::runtime_error{"file load failed"}; + + ::tflchef::Operand *operand = model_recipe->add_operand(); + + operand->set_name(tensor_name(tensor)); + operand->set_type(as_tflchef_type(tensor->type())); + + std::vector<int32_t> dims = as_index_vector(tensor->shape()); + ::tflchef::TensorShape *shape = operand->mutable_shape(); + for (auto dim : dims) + { + shape->add_dim(dim); + } + + // filler for weights, bias and so on + std::vector<int32_t> expvalues; + std::vector<float> expfvalues; + if (tflite_import.get_tensor_filler(i)) + { + tflchef::TensorFiller *filler = operand->mutable_filler(); + // Note: it is OK to use random weights for functionality validation + filler->set_tag("gaussian"); + filler->add_arg("0.0"); // average + filler->add_arg("0.1"); // standard deviation + } + else if (tflite_import.get_tensor_filler(i, expvalues)) + { + tflchef::TensorFiller *filler = operand->mutable_filler(); + filler->set_tag("explicit"); + for (auto value : expvalues) + { + std::ostringstream ss; + ss << value; + filler->add_arg(ss.str()); + } + } + else if (tflite_import.get_tensor_filler(i, expfvalues)) + { + tflchef::TensorFiller *filler = operand->mutable_filler(); + filler->set_tag("explicit"); + for (auto value : expfvalues) + { + std::ostringstream ss; + ss << value; + filler->add_arg(ss.str()); + } + } + + auto quant = tensor->quantization(); + if (quant != nullptr) + { + // Note: Calling 'operand->mutable_quant()' will create empty 'quant' node + // in the recipe file. We want this only when valid parameter exist. + if (quant->min() != nullptr && quant->min()->size() > 0) + { + tflchef::TensorQuantization *chef_quant = operand->mutable_quant(); + for (uint32_t idx = 0; idx < quant->min()->size(); ++idx) + chef_quant->add_min(quant->min()->Get(idx)); + } + if (quant->max() != nullptr && quant->max()->size() > 0) + { + tflchef::TensorQuantization *chef_quant = operand->mutable_quant(); + for (uint32_t idx = 0; idx < quant->max()->size(); idx++) + chef_quant->add_max(quant->max()->Get(idx)); + } + if (quant->scale() != nullptr && quant->scale()->size() > 0) + { + tflchef::TensorQuantization *chef_quant = operand->mutable_quant(); + for (uint32_t idx = 0; idx < quant->scale()->size(); ++idx) + chef_quant->add_scale(quant->scale()->Get(idx)); + } + if (quant->zero_point() != nullptr && quant->zero_point()->size() > 0) + { + tflchef::TensorQuantization *chef_quant = operand->mutable_quant(); + for (uint32_t idx = 0; idx < quant->zero_point()->size(); ++idx) + chef_quant->add_zero_point(quant->zero_point()->Get(idx)); + } + } + } + + // add all operators + for (uint32_t i = 0; i < operators->Length(); ++i) + { + const auto *op = operators->Get(i); + tflite::BuiltinOperator builtincode = tflite_import.builtin_code(op); + + if (const auto *graph_builder = TFliteOpRegistry::get().lookup(builtincode)) + { + auto operation = graph_builder->build(op, &tflite_import, model_recipe.get()); + + // common for all operators: inputs, outputs + set_inputs(&tflite_import, operation, op); + set_outputs(&tflite_import, operation, op); + } + else + { + std::string opcodename = tflite_import.opcode_name(op); + throw std::runtime_error{"Not supported: " + opcodename}; + } + } + + // network inputs/outputs + const std::vector<int32_t> &inputs = tflite_import.inputs(); + const std::vector<int32_t> &outputs = tflite_import.outputs(); + + for (const auto input : inputs) + { + auto tensor = tensors->Get(input); + std::string name = tensor_name(tensor); + + model_recipe->add_input(name); + } + for (const auto output : outputs) + { + auto tensor = tensors->Get(output); + std::string name = tensor_name(tensor); + + model_recipe->add_output(name); + } + + return std::move(model_recipe); +} + +bool write_recipe(const std::string &filename, std::unique_ptr<ModelRecipe> &recipe) +{ + std::fstream fo(filename, std::ios::binary | std::ios::out); + + if (!fo.is_open()) + { + throw std::runtime_error{"file store failed"}; + } + + // Note: SerializeToString() or SerializeToOstream() writes in binary mode + // DebugString() and Utf8DebugString() will print as a human readable text + fo << recipe->Utf8DebugString(); + + fo.close(); + + return true; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/TFliteImport.cpp b/compiler/tflchef/tflite/src/TFliteImport.cpp new file mode 100644 index 000000000..51d9b5ffa --- /dev/null +++ b/compiler/tflchef/tflite/src/TFliteImport.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TFliteImport.h" + +#include "Convert.h" + +#include <sstream> + +namespace tflchef +{ + +const char *kEmptyTensorName = "(noname)"; + +const char *tensor_type(const tflite::Tensor *tensor) +{ + return tflite::EnumNameTensorType(tensor->type()); +} + +const char *tensor_name(const tflite::Tensor *tensor) +{ + auto name = tensor->name(); + if (name) + return name->c_str(); + return kEmptyTensorName; +} + +bool is_valid(const tflite::OperatorCode *opcode) +{ + tflite::BuiltinOperator code = opcode->builtin_code(); + return (tflite::BuiltinOperator_MIN <= code && code <= tflite::BuiltinOperator_MAX); +} + +bool is_custom(const tflite::OperatorCode *opcode) +{ + tflite::BuiltinOperator code = opcode->builtin_code(); + return (code == tflite::BuiltinOperator_CUSTOM); +} + +TFliteImport::TFliteImport(const tflite::Model *model) +{ + _subgraphs = model->subgraphs(); + _buffers = model->buffers(); + + auto opcodes = model->operator_codes(); + for (const ::tflite::OperatorCode *opcode : *opcodes) + { + _op_codes.push_back(opcode); + } +} + +bool TFliteImport::select_sub_graph(uint32_t sgindex) +{ + _tensors = nullptr; + _operators = nullptr; + _inputs.clear(); + _outputs.clear(); + + if (_subgraphs->Length() <= sgindex) + { + assert(false); + return false; + } + + const tflite::SubGraph *subgraph = (*_subgraphs)[sgindex]; + + _tensors = subgraph->tensors(); + _operators = subgraph->operators(); + + _inputs = as_index_vector(subgraph->inputs()); + _outputs = as_index_vector(subgraph->outputs()); + + return true; +} + +tflite::BuiltinOperator TFliteImport::builtin_code(const tflite::Operator *op) const +{ + uint32_t index = op->opcode_index(); + assert(index < _op_codes.size()); + const tflite::OperatorCode *opcode = _op_codes.at(index); + + return opcode->builtin_code(); +} + +std::string TFliteImport::opcode_name(const tflite::Operator *op) const +{ + uint32_t index = op->opcode_index(); + assert(index < _op_codes.size()); + const tflite::OperatorCode *opcode = _op_codes.at(index); + + if (!is_valid(opcode)) + { + std::ostringstream oss; + oss << "(invalid: " << index << ")"; + return oss.str(); + } + + if (is_custom(opcode)) + { + if (!opcode->custom_code()) + return "(invalid custom)"; + + return opcode->custom_code()->c_str(); + } + + tflite::BuiltinOperator code = opcode->builtin_code(); + return EnumNameBuiltinOperator(code); +} + +size_t TFliteImport::buffer_info(const tflite::Tensor *tensor, const uint8_t **buff_data) +{ + *buff_data = nullptr; + + if (tensor->buffer() == 0) + return 0; + + if (auto *buffer = (*_buffers)[tensor->buffer()]) + { + if (auto *array = buffer->data()) + { + if (size_t size = array->size()) + { + *buff_data = reinterpret_cast<const uint8_t *>(array->data()); + return size; + } + } + } + + return 0; +} + +} // namespace tflchef diff --git a/compiler/tflchef/tflite/src/TFliteImport.h b/compiler/tflchef/tflite/src/TFliteImport.h new file mode 100644 index 000000000..fa8196405 --- /dev/null +++ b/compiler/tflchef/tflite/src/TFliteImport.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_IMPORT_H__ +#define __TFLITE_IMPORT_H__ + +#include <mio/tflite/schema_generated.h> + +#include <tflchef.pb.h> + +#include <map> +#include <vector> + +namespace tflchef +{ + +using TFliteSubGraphs_t = flatbuffers::Vector<flatbuffers::Offset<tflite::SubGraph>>; +using TFliteTensors_t = flatbuffers::Vector<flatbuffers::Offset<tflite::Tensor>>; +using TFliteBuffers_t = flatbuffers::Vector<flatbuffers::Offset<tflite::Buffer>>; +using TFliteOperators_t = flatbuffers::Vector<flatbuffers::Offset<tflite::Operator>>; + +const char *tensor_type(const tflite::Tensor *tensor); +const char *tensor_name(const tflite::Tensor *tensor); +bool is_valid(const tflite::OperatorCode *opcode); +bool is_custom(const tflite::OperatorCode *opcode); + +/** + * @brief Loads TF lite file and provides helpers to access attributes + */ +class TFliteImport +{ +public: + TFliteImport(const tflite::Model *model); + + TFliteImport() = delete; + +public: + bool select_sub_graph(uint32_t subgraph); + +public: + const TFliteBuffers_t *buffers() { return _buffers; } + const TFliteTensors_t *tensors() { return _tensors; } + const TFliteOperators_t *operators() { return _operators; } + const std::vector<int32_t> &inputs() const { return _inputs; } + const std::vector<int32_t> &outputs() const { return _outputs; } + + uint32_t num_subgraph() const { return _subgraphs->Length(); } + + tflite::BuiltinOperator builtin_code(const tflite::Operator *op) const; + std::string opcode_name(const tflite::Operator *op) const; + size_t buffer_info(const tflite::Tensor *tensor, const uint8_t **buff_data); + + /** + * @brief This will record the tensor by index, if it needs filler option, + * such as kernel, bias. + */ + void set_tensor_filler(uint32_t tensor_index) { _tensor_filler[tensor_index] = true; } + + /** + * @brief This will store int32 filler values such as reshape information for the tensor + */ + void set_tensor_filler(uint32_t tensor_index, std::vector<int32_t> &expvalues) + { + _tensor_filler_vint32[tensor_index] = expvalues; + } + + void set_tensor_filler(uint32_t tensor_index, std::vector<float> &expvalues) + { + _tensor_filler_vfloat[tensor_index] = expvalues; + } + + /** + * @brief This will return true if the tensor by index, needs a filler option. + */ + bool get_tensor_filler(uint32_t tensor_index) + { + auto it = _tensor_filler.find(tensor_index); + if (it != _tensor_filler.end()) + { + return it->second; + } + return false; + } + + /** + * @brief This will return true if the tensor by index, needs a int array filler option. + */ + bool get_tensor_filler(uint32_t tensor_index, std::vector<int32_t> &expvalues) + { + auto it = _tensor_filler_vint32.find(tensor_index); + if (it != _tensor_filler_vint32.end()) + { + expvalues = it->second; + return true; + } + return false; + } + + bool get_tensor_filler(uint32_t tensor_index, std::vector<float> &expvalues) + { + auto it = _tensor_filler_vfloat.find(tensor_index); + if (it != _tensor_filler_vfloat.end()) + { + expvalues = it->second; + return true; + } + return false; + } + +private: + const TFliteSubGraphs_t *_subgraphs; + const TFliteBuffers_t *_buffers; + const TFliteTensors_t *_tensors; + const TFliteOperators_t *_operators; + + std::vector<const tflite::OperatorCode *> _op_codes; + std::vector<int32_t> _inputs; + std::vector<int32_t> _outputs; + + std::map<uint32_t, bool> _tensor_filler; + std::map<uint32_t, std::vector<int32_t>> _tensor_filler_vint32; + std::map<uint32_t, std::vector<float>> _tensor_filler_vfloat; +}; + +} // namespace tflchef + +#endif // __TFLITE_IMPORT_H__ diff --git a/compiler/tflchef/tflite/src/TFliteOpChef.h b/compiler/tflchef/tflite/src/TFliteOpChef.h new file mode 100644 index 000000000..98564293b --- /dev/null +++ b/compiler/tflchef/tflite/src/TFliteOpChef.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_CHEF_H__ +#define __TFLITE_OP_CHEF_H__ + +#include <mio/tflite/schema_generated.h> + +#include <tflchef.pb.h> + +#include "TFliteImport.h" + +namespace tflchef +{ + +/** + * @brief Interface for each operators to build tflchef + */ +class TFliteOpChef +{ +public: + virtual void filler(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const = 0; + virtual ::tflchef::Operation *build(const tflite::Operator *op, TFliteImport *import, + tflchef::ModelRecipe *model_recipe) const = 0; + virtual ~TFliteOpChef() {} +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_CHEF_H__ diff --git a/compiler/tflchef/tflite/src/TFliteOpChefs.h b/compiler/tflchef/tflite/src/TFliteOpChefs.h new file mode 100644 index 000000000..685d6861b --- /dev/null +++ b/compiler/tflchef/tflite/src/TFliteOpChefs.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_CHEFS_H__ +#define __TFLITE_OP_CHEFS_H__ + +// In alphabet order +#include "Op/Abs.h" +#include "Op/Add.h" +#include "Op/ArgMax.h" +#include "Op/AveragePool2D.h" +#include "Op/BatchToSpaceND.h" +#include "Op/Concatenation.h" +#include "Op/Conv2D.h" +#include "Op/Cos.h" +#include "Op/DepthwiseConv2D.h" +#include "Op/Div.h" +#include "Op/Equal.h" +#include "Op/Exp.h" +#include "Op/FloorDiv.h" +#include "Op/FullyConnected.h" +#include "Op/LogicalNot.h" +#include "Op/LogicalOr.h" +#include "Op/MaxPool2D.h" +#include "Op/Mean.h" +#include "Op/Pack.h" +#include "Op/Pad.h" +#include "Op/ReLU.h" +#include "Op/ReLU6.h" +#include "Op/Reshape.h" +#include "Op/Rsqrt.h" +#include "Op/Softmax.h" +#include "Op/Sqrt.h" +#include "Op/Sub.h" +#include "Op/Tanh.h" +#include "Op/Transpose.h" + +#endif // __TFLITE_OP_CHEFS_H__ diff --git a/compiler/tflchef/tflite/src/TFliteOpRegistry.h b/compiler/tflchef/tflite/src/TFliteOpRegistry.h new file mode 100644 index 000000000..f0aed2113 --- /dev/null +++ b/compiler/tflchef/tflite/src/TFliteOpRegistry.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TFLITE_OP_REGISTRY_H__ +#define __TFLITE_OP_REGISTRY_H__ + +#include "TFliteOpChef.h" +#include "TFliteOpChefs.h" + +#include <memory> + +namespace tflchef +{ + +/** + * @brief tflchef operator registry + */ +class TFliteOpRegistry +{ +public: + /** + * @brief Returns registered TFliteOpChef pointer for BuiltinOperator or + * nullptr if not registered + */ + const TFliteOpChef *lookup(tflite::BuiltinOperator op) const + { + if (_tfliteop_map.find(op) == _tfliteop_map.end()) + return nullptr; + + return _tfliteop_map.at(op).get(); + } + + static TFliteOpRegistry &get() + { + static TFliteOpRegistry me; + return me; + } + +private: + TFliteOpRegistry() + { +#define REG_TFL_OP(OPCODE, CLASS) \ + _tfliteop_map[tflite::BuiltinOperator_##OPCODE] = std::make_unique<CLASS>() + + REG_TFL_OP(ABS, TFliteOpAbs); + REG_TFL_OP(ADD, TFliteOpAdd); + REG_TFL_OP(ARG_MAX, TFliteOpArgMax); + REG_TFL_OP(AVERAGE_POOL_2D, TFliteOpAveragePool2D); + REG_TFL_OP(BATCH_TO_SPACE_ND, TFliteOpBatchToSpaceND); + REG_TFL_OP(CONCATENATION, TFliteOpConcatenation); + REG_TFL_OP(CONV_2D, TFliteOpConv2D); + REG_TFL_OP(COS, TFliteOpCos); + REG_TFL_OP(DEPTHWISE_CONV_2D, TFliteOpDepthwiseConv2D); + REG_TFL_OP(DIV, TFliteOpDiv); + REG_TFL_OP(EQUAL, TFliteOpEqual); + REG_TFL_OP(EXP, TFliteOpExp); + REG_TFL_OP(FLOOR_DIV, TFliteOpFloorDiv); + REG_TFL_OP(FULLY_CONNECTED, TFliteOpFullyConnected); + REG_TFL_OP(LOGICAL_NOT, TFliteOpLogicalNot); + REG_TFL_OP(LOGICAL_OR, TFliteOpLogicalOr); + REG_TFL_OP(MAX_POOL_2D, TFliteOpMaxPool2D); + REG_TFL_OP(MEAN, TFliteOpMean); + REG_TFL_OP(PACK, TFliteOpPack); + REG_TFL_OP(PAD, TFliteOpPad); + REG_TFL_OP(RELU, TFliteOpReLU); + REG_TFL_OP(RELU6, TFliteOpReLU6); + REG_TFL_OP(RESHAPE, TFliteOpReshape); + REG_TFL_OP(RSQRT, TFliteOpRsqrt); + REG_TFL_OP(SOFTMAX, TFliteOpSoftmax); + REG_TFL_OP(SQRT, TFliteOpSqrt); + REG_TFL_OP(SUB, TFliteOpSub); + REG_TFL_OP(TANH, TFliteOpTanh); + REG_TFL_OP(TRANSPOSE, TFliteOpTranspose); + +#undef REG_TFL_OP + } + +private: + std::map<tflite::BuiltinOperator, std::unique_ptr<TFliteOpChef>> _tfliteop_map; +}; + +} // namespace tflchef + +#endif // __TFLITE_OP_REGISTRY_H__ diff --git a/compiler/tflchef/tools/CMakeLists.txt b/compiler/tflchef/tools/CMakeLists.txt new file mode 100644 index 000000000..92e3a6e6e --- /dev/null +++ b/compiler/tflchef/tools/CMakeLists.txt @@ -0,0 +1,6 @@ +# Console-based tool (tflchef) +add_subdirectory(console) +# File-based tool (tflchef-file) +add_subdirectory(file) +# Reverse tool to generate recipe from tflite (tflchef-reverse) +add_subdirectory(reverse) diff --git a/compiler/tflchef/tools/console/CMakeLists.txt b/compiler/tflchef/tools/console/CMakeLists.txt new file mode 100644 index 000000000..d9160c3a2 --- /dev/null +++ b/compiler/tflchef/tools/console/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(tflchef Driver.cpp) +target_link_libraries(tflchef tflchef_core) +target_link_libraries(tflchef safemain) diff --git a/compiler/tflchef/tools/console/Driver.cpp b/compiler/tflchef/tools/console/Driver.cpp new file mode 100644 index 000000000..d6f7ba1ae --- /dev/null +++ b/compiler/tflchef/tools/console/Driver.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tflchef/ModelChef.h" + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <iostream> + +int entry(int argc, char **argv) +{ + int32_t model_version = 1; + + ::tflchef::ModelRecipe model_recipe; + + // Read a model recipe from standard input + { + google::protobuf::io::IstreamInputStream iis{&std::cin}; + if (!google::protobuf::TextFormat::Parse(&iis, &model_recipe)) + { + std::cerr << "ERROR: Failed to parse recipe" << std::endl; + return 255; + } + + if (model_recipe.has_version()) + { + model_version = model_recipe.version(); + } + } + + if (model_version > 1) + { + std::cerr << "ERROR: Unsupported recipe version: " << model_version << std::endl; + return 255; + } + + auto generated_model = tflchef::cook(model_recipe); + + // Write a generated model into standard output + std::cout.write(generated_model.base(), generated_model.size()); + + return 0; +} diff --git a/compiler/tflchef/tools/file/CMakeLists.txt b/compiler/tflchef/tools/file/CMakeLists.txt new file mode 100644 index 000000000..477b7d974 --- /dev/null +++ b/compiler/tflchef/tools/file/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(tflchef-file Driver.cpp) +target_link_libraries(tflchef-file tflchef_core) +target_link_libraries(tflchef-file safemain) diff --git a/compiler/tflchef/tools/file/Driver.cpp b/compiler/tflchef/tools/file/Driver.cpp new file mode 100644 index 000000000..3ef701910 --- /dev/null +++ b/compiler/tflchef/tools/file/Driver.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tflchef/ModelChef.h" + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <fstream> +#include <iostream> + +int entry(int argc, char **argv) +{ + if (argc != 3) + { + std::cerr << "ERROR: Failed to parse arguments" << std::endl; + std::cerr << std::endl; + std::cerr << "USAGE: " << argv[0] << " [recipe] [output]" << std::endl; + return 255; + } + + int32_t model_version = 1; + + ::tflchef::ModelRecipe model_recipe; + + // Load model recipe from a file + { + std::ifstream is{argv[1]}; + google::protobuf::io::IstreamInputStream iis{&is}; + if (!google::protobuf::TextFormat::Parse(&iis, &model_recipe)) + { + std::cerr << "ERROR: Failed to parse recipe '" << argv[1] << "'" << std::endl; + return 255; + } + + if (model_recipe.has_version()) + { + model_version = model_recipe.version(); + } + } + + if (model_version > 1) + { + std::cerr << "ERROR: Unsupported recipe version: " << model_version << ", '" << argv[1] << "'" + << std::endl; + return 255; + } + + auto generated_model = tflchef::cook(model_recipe); + + // Dump generated model into a file + { + std::ofstream os{argv[2], std::ios::binary}; + os.write(generated_model.base(), generated_model.size()); + } + + return 0; +} diff --git a/compiler/tflchef/tools/reverse/CMakeLists.txt b/compiler/tflchef/tools/reverse/CMakeLists.txt new file mode 100644 index 000000000..63cb36c06 --- /dev/null +++ b/compiler/tflchef/tools/reverse/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(tflchef-reverse Driver.cpp) +target_link_libraries(tflchef-reverse tflchef_tflite) +target_link_libraries(tflchef-reverse safemain) diff --git a/compiler/tflchef/tools/reverse/Driver.cpp b/compiler/tflchef/tools/reverse/Driver.cpp new file mode 100644 index 000000000..549756463 --- /dev/null +++ b/compiler/tflchef/tools/reverse/Driver.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <tflchef/RawModel.h> +#include <tflchef/RecipeChef.h> + +#include <memory> +#include <iostream> + +int entry(int argc, char **argv) +{ + if (argc != 3) + { + std::cerr << "ERROR: Failed to parse arguments" << std::endl; + std::cerr << std::endl; + std::cerr << "USAGE: " << argv[0] << " [tflite] [output]" << std::endl; + return 255; + } + + // Load TF lite model from a tflite file + std::unique_ptr<tflchef::RawModel> rawmodel = tflchef::load_tflite(argv[1]); + if (rawmodel == nullptr) + { + std::cerr << "ERROR: Failed to load tflite '" << argv[1] << "'" << std::endl; + return 255; + } + + const tflite::Model *tflmodel = rawmodel->model(); + if (tflmodel == nullptr) + { + std::cerr << "ERROR: Failed to load tflite '" << argv[1] << "'" << std::endl; + return 255; + } + + // Generate ModelRecipe recipe + std::unique_ptr<tflchef::ModelRecipe> recipe = tflchef::generate_recipe(tflmodel); + if (recipe.get() == nullptr) + { + std::cerr << "ERROR: Failed to generate recipe" << std::endl; + return 255; + } + + // Save to a file + bool result = tflchef::write_recipe(argv[2], recipe); + if (!result) + { + std::cerr << "ERROR: Failed to write to recipe '" << argv[2] << "'" << std::endl; + return 255; + } + return 0; +} |