diff options
Diffstat (limited to 'runtimes/contrib/mlapse')
-rw-r--r-- | runtimes/contrib/mlapse/CMakeLists.txt | 8 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/README.md | 3 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/CMakeLists.txt | 12 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/driver.cc | 280 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.cc | 67 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.h | 50 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.cc | 24 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.h | 77 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.cc | 124 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.h | 63 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.cc | 17 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.h | 75 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/tfl/load.cc | 55 | ||||
-rw-r--r-- | runtimes/contrib/mlapse/tfl/mlapse/tfl/load.h | 40 |
14 files changed, 895 insertions, 0 deletions
diff --git a/runtimes/contrib/mlapse/CMakeLists.txt b/runtimes/contrib/mlapse/CMakeLists.txt new file mode 100644 index 000000000..bba79971a --- /dev/null +++ b/runtimes/contrib/mlapse/CMakeLists.txt @@ -0,0 +1,8 @@ +if(NOT BUILD_MLAPSE) + return() +endif(NOT BUILD_MLAPSE) + +message(STATUS "Build mlapse: TRUE") + +# TODO Add "core" +add_subdirectory(tfl) diff --git a/runtimes/contrib/mlapse/README.md b/runtimes/contrib/mlapse/README.md new file mode 100644 index 000000000..36f14ac39 --- /dev/null +++ b/runtimes/contrib/mlapse/README.md @@ -0,0 +1,3 @@ +# mlapse + +_mlapse_ is a toolkit for model inference latency benchmark. diff --git a/runtimes/contrib/mlapse/tfl/CMakeLists.txt b/runtimes/contrib/mlapse/tfl/CMakeLists.txt new file mode 100644 index 000000000..36f32d7ef --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/CMakeLists.txt @@ -0,0 +1,12 @@ +message(STATUS "Build mlapse-tfl: TRUE") + +file(GLOB_RECURSE SOURCES "*.cc") + +add_executable(mlapse-tfl ${SOURCES}) +target_include_directories(mlapse-tfl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(mlapse-tfl nnfw_lib_tflite) +target_link_libraries(mlapse-tfl nnfw_lib_misc) +target_link_libraries(mlapse-tfl nnfw_lib_cpp14) +target_link_libraries(mlapse-tfl tensorflow-lite) + +install(TARGETS mlapse-tfl DESTINATION bin) diff --git a/runtimes/contrib/mlapse/tfl/driver.cc b/runtimes/contrib/mlapse/tfl/driver.cc new file mode 100644 index 000000000..867a6051a --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/driver.cc @@ -0,0 +1,280 @@ +/* + * 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 "mlapse/benchmark_runner.h" +#include "mlapse/multicast_observer.h" +#include "mlapse/CSV_report_generator.h" + +#include "mlapse/tfl/load.h" + +// From 'nnfw_lib_tflite' +#include <tflite/InterpreterSession.h> +#include <tflite/NNAPISession.h> + +// From 'nnfw_lib_cpp14' +#include <cpp14/memory.h> + +// From C++ Standard Library +#include <cassert> +#include <fstream> +#include <iostream> +#include <vector> + +namespace +{ + +using namespace mlapse; + +class ConsoleReporter final : public mlapse::BenchmarkObserver +{ +public: + ConsoleReporter() = default; + +public: + void notify(const NotificationArg<PhaseBegin> &arg) final + { + _phase = arg.phase; + _count = arg.count; + + std::cout << tag() << " BEGIN" << std::endl; + } + + void notify(const NotificationArg<PhaseEnd> &arg) final + { + std::cout << tag() << " END" << std::endl; + + _phase = mlapse::uninitialized_phase(); + _count = 0; + } + + void notify(const NotificationArg<IterationBegin> &arg) final { _index = arg.index; } + + void notify(const NotificationArg<IterationEnd> &arg) final + { + std::cout << tag() << " " << progress() << " - " << arg.latency.count() << "ms" << std::endl; + } + +private: + std::string progress(void) const + { + return "[" + std::to_string(_index + 1) + "/" + std::to_string(_count) + "]"; + } + + std::string tag(void) const + { + switch (_phase) + { + case Phase::Warmup: + return "WARMUP"; + case Phase::Record: + return "RECORD"; + default: + break; + } + + return "unknown"; + } + + Phase _phase = mlapse::uninitialized_phase(); + uint32_t _count = 0; + uint32_t _index = 0; +}; + +} // namespace + +// Q. Is is worth to make a library for these routines? +namespace +{ + +enum class SessionType +{ + Interp, + NNAPI, +}; + +class SessionBuilder +{ +public: + SessionBuilder(const SessionType &type) : _type{type} + { + // DO NOTHING + } + +public: + std::unique_ptr<nnfw::tflite::Session> with(tflite::Interpreter *interp) const + { + switch (_type) + { + case SessionType::Interp: + return nnfw::cpp14::make_unique<nnfw::tflite::InterpreterSession>(interp); + case SessionType::NNAPI: + return nnfw::cpp14::make_unique<nnfw::tflite::NNAPISession>(interp); + default: + break; + } + + return nullptr; + } + + std::unique_ptr<nnfw::tflite::Session> + with(const std::unique_ptr<tflite::Interpreter> &interp) const + { + return with(interp.get()); + } + +private: + SessionType _type; +}; + +SessionBuilder make_session(const SessionType &type) { return SessionBuilder{type}; } + +} // namespace + +namespace +{ + +// mlapse-tfl +// [REQUIRED] --model <path/to/tflite> +// [OPTIONAL] --warmup-count N (default = 3) +// [OPTIONAL] --record-count N (default = 10) +// [OPTIONAL] --thread N or auto (default = auto) +// [OPTIOANL] --nnapi (default = off) +// [OPTIONAL] --pause N (default = 0) +// [OPTIONAL] --csv-report <path/to/csv> +int entry(const int argc, char **argv) +{ + // Create an observer + mlapse::MulticastObserver observer; + + observer.append(nnfw::cpp14::make_unique<ConsoleReporter>()); + + // Set default parameters + std::string model_path; + bool model_path_initialized = false; + + SessionType session_type = SessionType::Interp; + uint32_t warmup_count = 3; + uint32_t record_count = 10; + int num_thread = -1; // -1 means "auto" + + // Read command-line arguments + std::map<std::string, std::function<uint32_t(const char *const *)>> opts; + + opts["--model"] = [&model_path, &model_path_initialized](const char *const *tok) { + model_path = std::string{tok[0]}; + model_path_initialized = true; + return 1; // # of arguments + }; + + opts["--record-count"] = [&record_count](const char *const *tok) { + record_count = std::stoi(tok[0]); + return 1; // # of arguments + }; + + opts["--thread"] = [](const char *const *tok) { + assert(std::string{tok[0]} == "auto"); + return 1; + }; + + opts["--nnapi"] = [&session_type](const char *const *) { + session_type = SessionType::NNAPI; + return 0; + }; + + opts["--csv-report"] = [&observer](const char *const *tok) { + observer.append(nnfw::cpp14::make_unique<mlapse::CSVReportGenerator>(tok[0])); + return 1; + }; + + { + uint32_t offset = 1; + + while (offset < argc) + { + auto opt = argv[offset]; + + auto it = opts.find(opt); + + if (it == opts.end()) + { + std::cout << "INVALID OPTION: " << opt << std::endl; + return 255; + } + + auto func = it->second; + + auto num_skip = func(argv + offset + 1); + + offset += 1; + offset += num_skip; + } + } + + // Check arguments + if (!model_path_initialized) + { + std::cerr << "ERROR: --model is missing" << std::endl; + return 255; + } + + // Load T/F Lite model + auto model = mlapse::tfl::load_model(model_path); + + if (model == nullptr) + { + std::cerr << "ERROR: Failed to load '" << model_path << "'" << std::endl; + return 255; + } + + auto interp = mlapse::tfl::make_interpreter(model.get()); + + if (interp == nullptr) + { + std::cerr << "ERROR: Failed to create a T/F Lite interpreter" << std::endl; + return 255; + } + + auto sess = make_session(session_type).with(interp); + + if (sess == nullptr) + { + std::cerr << "ERROR: Failed to create a session" << std::endl; + } + + // Run benchmark + mlapse::BenchmarkRunner benchmark_runner{warmup_count, record_count}; + + benchmark_runner.attach(&observer); + benchmark_runner.run(sess); + + return 0; +} + +} // namespace + +int main(int argc, char **argv) +{ + try + { + return entry(argc, argv); + } + catch (const std::exception &e) + { + std::cerr << e.what() << std::endl; + } + + return 255; +} diff --git a/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.cc b/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.cc new file mode 100644 index 000000000..c6237a04f --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.cc @@ -0,0 +1,67 @@ +/* + * 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 "mlapse/CSV_report_generator.h" + +#include <cassert> +#include <stdexcept> + +namespace +{ + +std::string tag(const mlapse::Phase &phase) +{ + switch (phase) + { + case mlapse::Phase::Warmup: + return "WARMUP"; + case mlapse::Phase::Record: + return "STEADY"; + default: + break; + } + + throw std::invalid_argument{"phase"}; +} + +} // namespace + +namespace mlapse +{ + +void CSVReportGenerator::notify(const NotificationArg<PhaseBegin> &arg) +{ + assert(_phase == uninitialized_phase()); + _phase = arg.phase; +} + +void CSVReportGenerator::notify(const NotificationArg<PhaseEnd> &arg) +{ + assert(_phase != uninitialized_phase()); + _phase = uninitialized_phase(); +} + +void CSVReportGenerator::notify(const NotificationArg<IterationBegin> &arg) +{ + // DO NOTHING +} + +void CSVReportGenerator::notify(const NotificationArg<IterationEnd> &arg) +{ + _ofs << tag(_phase) << "," << arg.latency.count() << std::endl; +} + +} // namespace mlapse diff --git a/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.h b/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.h new file mode 100644 index 000000000..8842baf8e --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/CSV_report_generator.h @@ -0,0 +1,50 @@ +/* + * 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 __MLAPSE_CSV_REPORT_GENERATOR_H__ +#define __MLAPSE_CSV_REPORT_GENERATOR_H__ + +#include "mlapse/benchmark_observer.h" + +#include <fstream> +#include <string> + +namespace mlapse +{ + +class CSVReportGenerator final : public BenchmarkObserver +{ +public: + CSVReportGenerator(const std::string &path) : _ofs{path, std::ofstream::out} + { + // DO NOTHING + } + +public: + void notify(const NotificationArg<PhaseBegin> &arg) final; + void notify(const NotificationArg<PhaseEnd> &arg) final; + void notify(const NotificationArg<IterationBegin> &arg) final; + void notify(const NotificationArg<IterationEnd> &arg); + +private: + std::ofstream _ofs; + + Phase _phase = uninitialized_phase(); +}; + +} // namespace mlapse + +#endif // __MLAPSE_MULTICAST_OBSERER_H__ diff --git a/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.cc b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.cc new file mode 100644 index 000000000..f6d596a7b --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.cc @@ -0,0 +1,24 @@ +/* + * 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 "mlapse/benchmark_observer.h" + +namespace mlapse +{ + +Phase uninitialized_phase(void) { return static_cast<Phase>(0); } + +} // namespace mlapse diff --git a/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.h b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.h new file mode 100644 index 000000000..8fc570d24 --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_observer.h @@ -0,0 +1,77 @@ +/* + * 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 __MLAPSE_BENCHMARK_OBSERVER_H__ +#define __MLAPSE_BENCHMARK_OBSERVER_H__ + +#include <cstdint> +#include <chrono> + +namespace mlapse +{ + +enum Phase : int32_t +{ + // 0 denotes "uninitialized value" + Warmup = 1, + Record = 2, +}; + +Phase uninitialized_phase(void); + +enum Notification +{ + PhaseBegin, + PhaseEnd, + IterationBegin, + IterationEnd, +}; + +template <Notification N> struct NotificationArg; + +template <> struct NotificationArg<PhaseBegin> +{ + Phase phase; + uint32_t count; +}; + +template <> struct NotificationArg<PhaseEnd> +{ +}; + +template <> struct NotificationArg<IterationBegin> +{ + uint32_t index; +}; + +template <> struct NotificationArg<IterationEnd> +{ + std::chrono::milliseconds latency; +}; + +struct BenchmarkObserver +{ + virtual ~BenchmarkObserver() = default; + + virtual void notify(const NotificationArg<PhaseBegin> &arg) = 0; + virtual void notify(const NotificationArg<PhaseEnd> &arg) = 0; + virtual void notify(const NotificationArg<IterationBegin> &arg) = 0; + virtual void notify(const NotificationArg<IterationEnd> &arg) = 0; +}; + +} // namespace mlpase + +#endif // __MLAPSE_BENCHMARK_OBSERVER_H__ diff --git a/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.cc b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.cc new file mode 100644 index 000000000..f5fc7302d --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.cc @@ -0,0 +1,124 @@ +/* + * 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 "mlapse/benchmark_runner.h" + +// From 'nnfw_lib_misc' +#include <misc/benchmark.h> + +// From C++ Standard Library +#include <cassert> + +namespace mlapse +{ +void BenchmarkRunner::attach(BenchmarkObserver *observer) +{ + assert(_observer == nullptr); + _observer = observer; +} + +void BenchmarkRunner::run(nnfw::tflite::Session *sess) const +{ + for (auto phase : {Warmup, Record}) + { + uint32_t const count = _count.at(phase); + + // Notify when each phase begins + { + NotificationArg<PhaseBegin> arg; + + arg.phase = phase; + arg.count = count; + + notify(arg); + } + + for (uint32_t n = 0; n < count; ++n) + { + std::chrono::milliseconds elapsed(0); + + sess->prepare(); + + // Notify when each iteration begins + { + NotificationArg<IterationBegin> arg; + + arg.index = n; + + notify(arg); + }; + + nnfw::misc::benchmark::measure(elapsed) << [&](void) { + if (!sess->run()) + { + throw std::runtime_error{"run failed"}; + } + }; + + // Notify when each iteration ends + { + NotificationArg<IterationEnd> arg; + + arg.latency = elapsed; + + notify(arg); + }; + + sess->teardown(); + } + + // Notify when each phase ends + { + NotificationArg<PhaseEnd> arg; + + notify(arg); + } + } +} + +void BenchmarkRunner::notify(const NotificationArg<PhaseBegin> &arg) const +{ + if (_observer) + { + _observer->notify(arg); + } +} + +void BenchmarkRunner::notify(const NotificationArg<PhaseEnd> &arg) const +{ + if (_observer) + { + _observer->notify(arg); + } +} + +void BenchmarkRunner::notify(const NotificationArg<IterationBegin> &arg) const +{ + if (_observer) + { + _observer->notify(arg); + } +} + +void BenchmarkRunner::notify(const NotificationArg<IterationEnd> &arg) const +{ + if (_observer) + { + _observer->notify(arg); + } +} + +} // namespace mlapse diff --git a/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.h b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.h new file mode 100644 index 000000000..fcbb41d1b --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/benchmark_runner.h @@ -0,0 +1,63 @@ +/* + * 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 __MLAPSE_BENCHMARK_RUNNER_H__ +#define __MLAPSE_BENCHMARK_RUNNER_H__ + +#include "mlapse/benchmark_observer.h" + +#include <tflite/Session.h> + +#include <chrono> +#include <map> + +namespace mlapse +{ + +class BenchmarkRunner final +{ +public: + BenchmarkRunner(uint32_t warmup_count, uint32_t record_count) + { + _count[Warmup] = warmup_count; + _count[Record] = record_count; + } + +public: + void attach(BenchmarkObserver *observer); + +public: + void run(nnfw::tflite::Session *sess) const; + +public: + void run(const std::unique_ptr<nnfw::tflite::Session> &sess) const { run(sess.get()); } + +private: + void notify(const NotificationArg<PhaseBegin> &arg) const; + void notify(const NotificationArg<PhaseEnd> &arg) const; + void notify(const NotificationArg<IterationBegin> &arg) const; + void notify(const NotificationArg<IterationEnd> &arg) const; + +private: + std::map<Phase, uint32_t> _count; + +private: + BenchmarkObserver *_observer = nullptr; +}; + +} // namespace mlpase + +#endif // __MLAPSE_BENCHMARK_RUNNER_H__ diff --git a/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.cc b/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.cc new file mode 100644 index 000000000..639acfe45 --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.cc @@ -0,0 +1,17 @@ +/* + * 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 "mlapse/multicast_observer.h" diff --git a/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.h b/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.h new file mode 100644 index 000000000..e4aac50a9 --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/multicast_observer.h @@ -0,0 +1,75 @@ +/* + * 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 __MLAPSE_MULTICAST_OBSERER_H__ +#define __MLAPSE_MULTICAST_OBSERER_H__ + +#include "mlapse/benchmark_observer.h" + +#include <memory> +#include <vector> + +namespace mlapse +{ + +class MulticastObserver final : public BenchmarkObserver +{ +public: + MulticastObserver() = default; + +public: + void append(std::unique_ptr<BenchmarkObserver> &&o) { _observers.emplace_back(std::move(o)); } + +public: + void notify(const NotificationArg<PhaseBegin> &arg) final + { + for (const auto &o : _observers) + { + o->notify(arg); + } + } + + void notify(const NotificationArg<PhaseEnd> &arg) final + { + for (const auto &o : _observers) + { + o->notify(arg); + } + } + + void notify(const NotificationArg<IterationBegin> &arg) final + { + for (const auto &o : _observers) + { + o->notify(arg); + } + } + + void notify(const NotificationArg<IterationEnd> &arg) final + { + for (const auto &o : _observers) + { + o->notify(arg); + } + } + +private: + std::vector<std::unique_ptr<BenchmarkObserver>> _observers; +}; + +} // namespace mlapse + +#endif // __MLAPSE_MULTICAST_OBSERER_H__ diff --git a/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.cc b/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.cc new file mode 100644 index 000000000..9e770aecf --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.cc @@ -0,0 +1,55 @@ +/* + * 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 "mlapse/tfl/load.h" + +#include <tflite/ext/kernels/register.h> + +namespace +{ + +tflite::StderrReporter error_reporter; + +} // namespace + +namespace mlapse +{ +namespace tfl +{ + +std::unique_ptr<tflite::FlatBufferModel> load_model(const std::string &path) +{ + return tflite::FlatBufferModel::BuildFromFile(path.c_str(), &error_reporter); +} + +std::unique_ptr<tflite::Interpreter> make_interpreter(const tflite::FlatBufferModel *model) +{ + // Let's use extended resolver! + nnfw::tflite::BuiltinOpResolver resolver; + tflite::InterpreterBuilder builder(*model, resolver); + + std::unique_ptr<tflite::Interpreter> interpreter; + + if (builder(&interpreter) != kTfLiteOk) + { + return nullptr; + } + + return std::move(interpreter); +} + +} // namespace tfl +} // namespace mlapse diff --git a/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.h b/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.h new file mode 100644 index 000000000..6f5a8f1ea --- /dev/null +++ b/runtimes/contrib/mlapse/tfl/mlapse/tfl/load.h @@ -0,0 +1,40 @@ +/* + * 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 __MLAPSE_TFL_LOAD_H__ +#define __MLAPSE_TFL_LOAD_H__ + +#include <tensorflow/lite/interpreter.h> +#include <tensorflow/lite/model.h> + +#include <memory> + +namespace mlapse +{ +namespace tfl +{ + +std::unique_ptr<tflite::FlatBufferModel> load_model(const std::string &path); + +// WARNING +// +// model SHOULD outlive Interpreter +std::unique_ptr<tflite::Interpreter> make_interpreter(const tflite::FlatBufferModel *model); + +} // namespace tfl +} // namespace mlapse + +#endif // __MLAPSE_TFL_LOAD_H__ |