From 2e85abd603378a8dd967be093f1280a197a91347 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/On-Device=20Lab=28SR=29/Staff?= =?utf8?q?=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 24 Jun 2019 14:56:34 +0900 Subject: [PATCH] [moco/tf] Introduce configuration infrastructure (#3935) This commit introduces basic configuration infrastructure which allows users to control moco's internal behavior through environment variables. Signed-off-by: Jonghyun Park --- contrib/moco/lib/frontend/tf/CMakeLists.txt | 1 + contrib/moco/lib/frontend/tf/src/Knob.cpp | 123 ++++++++++++++++++++++++++++ contrib/moco/lib/frontend/tf/src/Knob.h | 47 +++++++++++ contrib/moco/lib/frontend/tf/src/Knob.lst | 5 ++ contrib/moco/requires.cmake | 1 + 5 files changed, 177 insertions(+) create mode 100644 contrib/moco/lib/frontend/tf/src/Knob.cpp create mode 100644 contrib/moco/lib/frontend/tf/src/Knob.h create mode 100644 contrib/moco/lib/frontend/tf/src/Knob.lst diff --git a/contrib/moco/lib/frontend/tf/CMakeLists.txt b/contrib/moco/lib/frontend/tf/CMakeLists.txt index 2d6a195..7a9dad2 100644 --- a/contrib/moco/lib/frontend/tf/CMakeLists.txt +++ b/contrib/moco/lib/frontend/tf/CMakeLists.txt @@ -24,6 +24,7 @@ target_link_libraries(moco_tf_frontend PUBLIC loco) target_link_libraries(moco_tf_frontend PRIVATE stdex) target_link_libraries(moco_tf_frontend PRIVATE cwrap) target_link_libraries(moco_tf_frontend PRIVATE moco_log) +target_link_libraries(moco_tf_frontend PRIVATE pepper_strcast) if(NOT ENABLE_TEST) return() diff --git a/contrib/moco/lib/frontend/tf/src/Knob.cpp b/contrib/moco/lib/frontend/tf/src/Knob.cpp new file mode 100644 index 0000000..0e1c7e0 --- /dev/null +++ b/contrib/moco/lib/frontend/tf/src/Knob.cpp @@ -0,0 +1,123 @@ +/* + * 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 "Knob.h" + +#include + +#include +#include + +// Basic Infrastructure to declare and access Knob values +// +// TODO Reuse this infrastructure as a library +namespace +{ + +using KnobName = std::string; + +/** + * @brief Load configuration (from somewhere) + */ +struct KnobLoader +{ + virtual ~KnobLoader() = default; + + virtual bool load(const KnobName &name, bool default_value) const = 0; +}; + +// Template-programming helpers +template T knob_load(const KnobLoader &, const KnobName &, const T &); + +template <> +bool knob_load(const KnobLoader &l, const KnobName &knob_name, const bool &default_value) +{ + return l.load(knob_name, default_value); +} + +/** + * @brief Load configuration from environment variables + * + * Given a prefix P, EnvKnobLoader reads a configuration K from concat(P, K). + * + * For example, let us assume that P is "MY_" and K is "CONFIG". + * + * Then, EnvKnobLoader reads configuration CONFIG from environment variable MY_CONFIG. + */ +class EnvKnobLoader final : public KnobLoader +{ +public: + EnvKnobLoader(const std::string &prefix) : _prefix{prefix} + { + // DO NOTHING + } + +public: + bool load(const KnobName &knob_name, bool default_value) const override + { + auto envvar = _prefix + knob_name; + auto s = std::getenv(envvar.c_str()); + + return pepper::safe_strcast(s, default_value ? 1 : 0) != 0; + } + +private: + /// @brief Environment variable prefix + std::string _prefix; +}; + +} // namespace + +namespace +{ + +/** + * TODO Support Knob Loader Injection + * + * Let us assume that there is a compiler "A" based on moco, and it wants to reuse this + * infrastructure. + * + * Under the current design, users have to set "MOCO_XXX" even though they uses "A", which is + * counter-intuitive. + * + * "Knob Loader Injection" aims to address this issue. "Knob Loader Injection" allows "A" to + * inject its own knob loader that reads "A_XXX" environment variables. + */ +const KnobLoader &knob_loader(void) +{ + static EnvKnobLoader loader{"MOCO_"}; + return loader; +} + +} // namespace + +namespace moco +{ +namespace tf +{ + +#define KNOB_BOOL(NAME, DEFAULT, DESC) \ + template <> typename KnobTrait::ValueType get(void) \ + { \ + static typename KnobTrait::ValueType value = \ + ::knob_load::ValueType>(::knob_loader(), #NAME, DEFAULT); \ + return value; \ + } +#include "Knob.lst" +#undef KNOB_BOOL + +} // namespace tf +} // namespace moco diff --git a/contrib/moco/lib/frontend/tf/src/Knob.h b/contrib/moco/lib/frontend/tf/src/Knob.h new file mode 100644 index 0000000..145a81d --- /dev/null +++ b/contrib/moco/lib/frontend/tf/src/Knob.h @@ -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. + */ + +#ifndef __KNOB_H__ +#define __KNOB_H__ + +namespace moco +{ +namespace tf +{ + +enum class Knob +{ +#define KNOB_BOOL(NAME, DEFAULT, DESC) NAME, +#include "Knob.lst" +#undef KNOB_BOOL +}; + +template struct KnobTrait; + +#define KNOB_BOOL(NAME, DEFAULT, DESC) \ + template <> struct KnobTrait \ + { \ + using ValueType = bool; \ + }; +#include "Knob.lst" +#undef KNOB_BOOL + +template typename KnobTrait::ValueType get(void); + +} // namespace tf +} // namespace moco + +#endif // __KNOB_H__ diff --git a/contrib/moco/lib/frontend/tf/src/Knob.lst b/contrib/moco/lib/frontend/tf/src/Knob.lst new file mode 100644 index 0000000..428716c --- /dev/null +++ b/contrib/moco/lib/frontend/tf/src/Knob.lst @@ -0,0 +1,5 @@ +#ifndef KNOB_BOOL +#error "KNOB_BOOL is not defined" +#endif // KNOB_BOOL + +// KNOB_BOOL(NAME, DEFAULT_VALUE, DESCRIPTION) diff --git a/contrib/moco/requires.cmake b/contrib/moco/requires.cmake index f6e5166..998a5fe 100644 --- a/contrib/moco/requires.cmake +++ b/contrib/moco/requires.cmake @@ -1,5 +1,6 @@ require("tfkit") require("cwrap") +require("pepper-strcast") require("moco-log") # NOTE This is a virtual dependency for backward compatibility. # TODO Remove this virtual dependency -- 2.7.4