From c52c491098fffc1b8b5c6c9063fd93a096cc040a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Wed, 31 Oct 2018 19:04:20 +0900 Subject: [PATCH] [enco] TensorFlow Lite frontend (v0.1) (#2076) With this commit, enco tflite frontend is now able to construct coco::Module and coco::Data from "empty" tflite model. Signed-off-by: Jonghyun Park --- contrib/enco/frontend/tflite/src/Entry.cpp | 7 +- .../enco/frontend/tflite/src/RawModelLoader.cpp | 133 +++++++++++++++++++++ contrib/enco/frontend/tflite/src/RawModelLoader.h | 29 +++++ 3 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 contrib/enco/frontend/tflite/src/RawModelLoader.cpp create mode 100644 contrib/enco/frontend/tflite/src/RawModelLoader.h diff --git a/contrib/enco/frontend/tflite/src/Entry.cpp b/contrib/enco/frontend/tflite/src/Entry.cpp index 21e8469..6ce5d9e 100644 --- a/contrib/enco/frontend/tflite/src/Entry.cpp +++ b/contrib/enco/frontend/tflite/src/Entry.cpp @@ -15,6 +15,7 @@ */ #include "Frontend.h" +#include "RawModelLoader.h" #include @@ -23,11 +24,13 @@ #include #include +using nncc::foundation::make_unique; + extern "C" std::unique_ptr make_frontend(const cmdline::View &cmdline) { assert(cmdline.size() == 1); // tflite file name - throw std::runtime_error("Not implemented yet"); + auto model = load_from(cmdline.at(0)); - return nullptr; + return make_unique(std::move(model)); } diff --git a/contrib/enco/frontend/tflite/src/RawModelLoader.cpp b/contrib/enco/frontend/tflite/src/RawModelLoader.cpp new file mode 100644 index 0000000..a19c2be --- /dev/null +++ b/contrib/enco/frontend/tflite/src/RawModelLoader.cpp @@ -0,0 +1,133 @@ +/* + * 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 "RawModelLoader.h" + +#include +#include +#include +#include + +namespace +{ + +class MemoryMappedRawModel final : public 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 +{ + +class OwnedFileDescriptor final +{ +public: + OwnedFileDescriptor(int value) : _value{value} + { + // DO NOTHING + } + +public: + // NOTE Copy is not allowed + OwnedFileDescriptor(const OwnedFileDescriptor &) = delete; + +public: + // NOTE Moave is allowed + OwnedFileDescriptor(OwnedFileDescriptor &&fd) { _value = fd.release(); } + +public: + ~OwnedFileDescriptor() + { + if (_value != -1) + { + // Close on descturction + close(_value); + } + } + +public: + int value(void) const { return _value; } + +public: + int release(void) + { + auto res = _value; + _value = -1; + return res; + } + +private: + int _value = -1; +}; + +} // namespace + +std::unique_ptr load_from(const std::string &path) +{ + OwnedFileDescriptor fd = open(path.c_str(), O_RDONLY); + + if (fd.value() == -1) + { + // Return nullptr on open failure + return nullptr; + } + + struct stat st; + if (fstat(fd.value(), &st) == -1) + { + // Return nullptr on fstat failure + return nullptr; + } + + auto size = st.st_size; + auto data = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd.value(), 0); + + if (data == MAP_FAILED) + { + // Return nullptr on mmap failure + return nullptr; + } + + return std::unique_ptr{new MemoryMappedRawModel(fd.release(), data, size)}; +} diff --git a/contrib/enco/frontend/tflite/src/RawModelLoader.h b/contrib/enco/frontend/tflite/src/RawModelLoader.h new file mode 100644 index 0000000..5d93528 --- /dev/null +++ b/contrib/enco/frontend/tflite/src/RawModelLoader.h @@ -0,0 +1,29 @@ +/* + * 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_LOADER_H__ +#define __RAW_MODEL_LOADER_H__ + +#include "RawModel.h" + +/** + * @brief Load TensorFlow Lite model (as a RawModel) from a given path + * + * @note May return a nullptr + */ +std::unique_ptr load_from(const std::string &path); + +#endif // __RAW_MODEL_LOADER_H__ -- 2.7.4