diff --git a/tensorflow/lite/tools/BUILD b/tensorflow/lite/tools/BUILD index 41ccb3df36e..73ae9733536 100644 --- a/tensorflow/lite/tools/BUILD +++ b/tensorflow/lite/tools/BUILD @@ -205,6 +205,31 @@ cc_test( ], ) +cc_library( + name = "logging", + hdrs = ["logging.h"], + copts = common_copts, +) + +cc_library( + name = "tool_params", + srcs = ["tool_params.cc"], + hdrs = ["tool_params.h"], + copts = tflite_copts(), + deps = [":logging"], +) + +cc_test( + name = "tool_params_test", + srcs = ["tool_params_test.cc"], + copts = tflite_copts(), + visibility = ["//visibility:private"], + deps = [ + ":tool_params", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "command_line_flags", srcs = ["command_line_flags.cc"], diff --git a/tensorflow/lite/tools/benchmark/BUILD b/tensorflow/lite/tools/benchmark/BUILD index a979a8a55ef..bc9df478842 100644 --- a/tensorflow/lite/tools/benchmark/BUILD +++ b/tensorflow/lite/tools/benchmark/BUILD @@ -17,6 +17,9 @@ cc_library( name = "logging", hdrs = ["logging.h"], copts = common_copts, + deps = [ + "//tensorflow/lite/tools:logging", + ], ) cc_binary( @@ -107,6 +110,7 @@ cc_test( ":benchmark_performance_options", ":benchmark_tflite_model_lib", ":delegate_provider_hdr", + ":logging", "//tensorflow/lite:framework", "//tensorflow/lite:string_util", "//tensorflow/lite/testing:util", @@ -128,6 +132,7 @@ cc_library( "//tensorflow/lite/profiling:profile_summarizer", "//tensorflow/lite/profiling:profile_summary_formatter", "//tensorflow/lite/profiling:profiler", + "//tensorflow/lite/tools:logging", ], ) @@ -197,12 +202,9 @@ cc_library( cc_library( name = "benchmark_params", - srcs = [ - "benchmark_params.cc", - ], hdrs = ["benchmark_params.h"], copts = common_copts, - deps = [":logging"], + deps = ["//tensorflow/lite/tools:tool_params"], ) cc_library( diff --git a/tensorflow/lite/tools/benchmark/benchmark_params.cc b/tensorflow/lite/tools/benchmark/benchmark_params.cc deleted file mode 100644 index 1dd6a8d519a..00000000000 --- a/tensorflow/lite/tools/benchmark/benchmark_params.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "tensorflow/lite/tools/benchmark/benchmark_params.h" - -#include -#include -#include - -#include "tensorflow/lite/tools/benchmark/logging.h" - -namespace tflite { -namespace benchmark { - -void BenchmarkParam::AssertHasSameType(BenchmarkParam::ParamType a, - BenchmarkParam::ParamType b) { - TFLITE_BENCHMARK_CHECK(a == b) << "Type mismatch while accessing parameter."; -} - -template <> -BenchmarkParam::ParamType BenchmarkParam::GetValueType() { - return BenchmarkParam::ParamType::TYPE_INT32; -} - -template <> -BenchmarkParam::ParamType BenchmarkParam::GetValueType() { - return BenchmarkParam::ParamType::TYPE_BOOL; -} - -template <> -BenchmarkParam::ParamType BenchmarkParam::GetValueType() { - return BenchmarkParam::ParamType::TYPE_FLOAT; -} - -template <> -BenchmarkParam::ParamType BenchmarkParam::GetValueType() { - return BenchmarkParam::ParamType::TYPE_STRING; -} - -void BenchmarkParams::AssertParamExists(const std::string& name) const { - TFLITE_BENCHMARK_CHECK(HasParam(name)) << name << " was not found."; -} - -void BenchmarkParams::Set(const BenchmarkParams& other) { - for (const auto& param : params_) { - const BenchmarkParam* other_param = other.GetParam(param.first); - if (other_param == nullptr) continue; - param.second->Set(*other_param); - } -} - -void BenchmarkParams::Merge(const BenchmarkParams& other, bool overwrite) { - for (const auto& one : other.params_) { - auto it = params_.find(one.first); - if (it == params_.end()) { - AddParam(one.first, one.second->Clone()); - } else if (overwrite) { - it->second->Set(*one.second); - } - } -} - -} // namespace benchmark -} // namespace tflite diff --git a/tensorflow/lite/tools/benchmark/benchmark_params.h b/tensorflow/lite/tools/benchmark/benchmark_params.h index 1b3dabf3f7b..9037c35869f 100644 --- a/tensorflow/lite/tools/benchmark/benchmark_params.h +++ b/tensorflow/lite/tools/benchmark/benchmark_params.h @@ -15,123 +15,12 @@ limitations under the License. #ifndef TENSORFLOW_LITE_TOOLS_BENCHMARK_BENCHMARK_PARAMS_H_ #define TENSORFLOW_LITE_TOOLS_BENCHMARK_BENCHMARK_PARAMS_H_ -#include -#include -#include -#include -#include - -#include "tensorflow/lite/tools/benchmark/logging.h" +#include "tensorflow/lite/tools/tool_params.h" namespace tflite { namespace benchmark { - -template -class TypedBenchmarkParam; - -class BenchmarkParam { - protected: - enum class ParamType { TYPE_INT32, TYPE_FLOAT, TYPE_BOOL, TYPE_STRING }; - template - static ParamType GetValueType(); - - public: - template - static std::unique_ptr Create(const T& default_value) { - return std::unique_ptr( - new TypedBenchmarkParam(default_value)); - } - - template - TypedBenchmarkParam* AsTyped() { - AssertHasSameType(GetValueType(), type_); - return static_cast*>(this); - } - - template - const TypedBenchmarkParam* AsConstTyped() const { - AssertHasSameType(GetValueType(), type_); - return static_cast*>(this); - } - - virtual ~BenchmarkParam() {} - explicit BenchmarkParam(ParamType type) : type_(type) {} - - virtual void Set(const BenchmarkParam&) {} - - virtual std::unique_ptr Clone() const = 0; - - private: - static void AssertHasSameType(ParamType a, ParamType b); - - const ParamType type_; -}; - -template -class TypedBenchmarkParam : public BenchmarkParam { - public: - explicit TypedBenchmarkParam(const T& value) - : BenchmarkParam(GetValueType()), value_(value) {} - - void Set(const T& value) { value_ = value; } - - T Get() const { return value_; } - - void Set(const BenchmarkParam& other) override { - Set(other.AsConstTyped()->Get()); - } - - std::unique_ptr Clone() const override { - return std::unique_ptr(new TypedBenchmarkParam(value_)); - } - - private: - T value_; -}; - -class BenchmarkParams { - public: - void AddParam(const std::string& name, - std::unique_ptr value) { - params_[name] = std::move(value); - } - - bool HasParam(const std::string& name) const { - return params_.find(name) != params_.end(); - } - - bool Empty() const { return params_.empty(); } - - const BenchmarkParam* GetParam(const std::string& name) const { - const auto& entry = params_.find(name); - if (entry == params_.end()) return nullptr; - return entry->second.get(); - } - - template - void Set(const std::string& name, const T& value) { - AssertParamExists(name); - params_.at(name)->AsTyped()->Set(value); - } - - template - T Get(const std::string& name) const { - AssertParamExists(name); - return params_.at(name)->AsTyped()->Get(); - } - - // Set the value of all same parameters from 'other'. - void Set(const BenchmarkParams& other); - - // Merge the value of all parameters from 'other'. 'overwrite' indicates - // whether the value of the same paratmeter is overwrite or not. - void Merge(const BenchmarkParams& other, bool overwrite = false); - - private: - void AssertParamExists(const std::string& name) const; - std::unordered_map> params_; -}; - +using BenchmarkParam = tflite::tools::ToolParam; +using BenchmarkParams = tflite::tools::ToolParams; } // namespace benchmark } // namespace tflite #endif // TENSORFLOW_LITE_TOOLS_BENCHMARK_BENCHMARK_PARAMS_H_ diff --git a/tensorflow/lite/tools/benchmark/benchmark_test.cc b/tensorflow/lite/tools/benchmark/benchmark_test.cc index da4082926a2..4030b1bdc33 100644 --- a/tensorflow/lite/tools/benchmark/benchmark_test.cc +++ b/tensorflow/lite/tools/benchmark/benchmark_test.cc @@ -28,6 +28,7 @@ limitations under the License. #include "tensorflow/lite/tools/benchmark/benchmark_performance_options.h" #include "tensorflow/lite/tools/benchmark/benchmark_tflite_model.h" #include "tensorflow/lite/tools/benchmark/delegate_provider.h" +#include "tensorflow/lite/tools/benchmark/logging.h" #include "tensorflow/lite/tools/command_line_flags.h" namespace { diff --git a/tensorflow/lite/tools/benchmark/logging.h b/tensorflow/lite/tools/benchmark/logging.h index 808090bf21f..ff3287026b2 100644 --- a/tensorflow/lite/tools/benchmark/logging.h +++ b/tensorflow/lite/tools/benchmark/logging.h @@ -16,74 +16,10 @@ limitations under the License. #ifndef TENSORFLOW_LITE_TOOLS_BENCHMARK_LOGGING_H_ #define TENSORFLOW_LITE_TOOLS_BENCHMARK_LOGGING_H_ -// LOG and CHECK macros for benchmarks. +// TODO(b/149482807): completely remove this file from the code base. +#include "tensorflow/lite/tools/logging.h" -#include -#include -#include - -#ifdef _WIN32 -#undef ERROR -#endif - -namespace tflite { -namespace logging { -// A wrapper that logs to stderr. -// -// Used for TFLITE_LOG and TFLITE_BENCHMARK_CHECK macros. -class LoggingWrapper { - public: - enum class LogSeverity : int { - INFO = 0, - WARN = 1, - ERROR = 2, - FATAL = 3, - }; - LoggingWrapper(LogSeverity severity) - : severity_(severity), should_log_(true) {} - LoggingWrapper(LogSeverity severity, bool log) - : severity_(severity), should_log_(log) {} - std::stringstream& Stream() { return stream_; } - ~LoggingWrapper() { - if (should_log_) { - switch (severity_) { - case LogSeverity::INFO: - case LogSeverity::WARN: - std::cout << stream_.str() << std::endl; - break; - case LogSeverity::ERROR: - std::cerr << stream_.str() << std::endl; - break; - case LogSeverity::FATAL: - std::cerr << stream_.str() << std::endl; - std::flush(std::cerr); - std::abort(); - break; - } - } - } - - private: - std::stringstream stream_; - LogSeverity severity_; - bool should_log_; -}; - -} // namespace logging - -} // namespace tflite - -#define TFLITE_LOG(severity) \ - tflite::logging::LoggingWrapper( \ - tflite::logging::LoggingWrapper::LogSeverity::severity) \ - .Stream() - -#define TFLITE_BENCHMARK_CHECK(condition) \ - tflite::logging::LoggingWrapper( \ - tflite::logging::LoggingWrapper::LogSeverity::FATAL, \ - (condition) ? false : true) \ - .Stream() - -#define TFLITE_BENCHMARK_CHECK_EQ(a, b) TFLITE_BENCHMARK_CHECK(a == b) +#define TFLITE_BENCHMARK_CHECK(condition) TFLITE_TOOLS_CHECK(condition) +#define TFLITE_BENCHMARK_CHECK_EQ(a, b) TFLITE_TOOLS_CHECK(a == b) #endif // TENSORFLOW_LITE_TOOLS_BENCHMARK_LOGGING_H_ diff --git a/tensorflow/lite/tools/benchmark/profiling_listener.cc b/tensorflow/lite/tools/benchmark/profiling_listener.cc index 50df69c4b7c..ddd653e757d 100644 --- a/tensorflow/lite/tools/benchmark/profiling_listener.cc +++ b/tensorflow/lite/tools/benchmark/profiling_listener.cc @@ -17,6 +17,8 @@ limitations under the License. #include +#include "tensorflow/lite/tools/logging.h" + namespace tflite { namespace benchmark { @@ -29,7 +31,7 @@ ProfilingListener::ProfilingListener( csv_file_path_(csv_file_path), interpreter_(interpreter), profiler_(max_num_entries) { - TFLITE_BENCHMARK_CHECK(interpreter); + TFLITE_TOOLS_CHECK(interpreter); interpreter_->SetProfiler(&profiler_); // We start profiling here in order to catch events that are recorded during diff --git a/tensorflow/lite/tools/logging.h b/tensorflow/lite/tools/logging.h new file mode 100644 index 00000000000..b832e387993 --- /dev/null +++ b/tensorflow/lite/tools/logging.h @@ -0,0 +1,87 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_TOOLS_LOGGING_H_ +#define TENSORFLOW_LITE_TOOLS_LOGGING_H_ + +// LOG and CHECK macros for tflite tooling. + +#include +#include +#include + +#ifdef _WIN32 +#undef ERROR +#endif + +namespace tflite { +namespace logging { +// A wrapper that logs to stderr. +// +// Used for TFLITE_LOG and TFLITE_BENCHMARK_CHECK macros. +class LoggingWrapper { + public: + enum class LogSeverity : int { + INFO = 0, + WARN = 1, + ERROR = 2, + FATAL = 3, + }; + LoggingWrapper(LogSeverity severity) + : severity_(severity), should_log_(true) {} + LoggingWrapper(LogSeverity severity, bool log) + : severity_(severity), should_log_(log) {} + std::stringstream& Stream() { return stream_; } + ~LoggingWrapper() { + if (should_log_) { + switch (severity_) { + case LogSeverity::INFO: + case LogSeverity::WARN: + std::cout << stream_.str() << std::endl; + break; + case LogSeverity::ERROR: + std::cerr << stream_.str() << std::endl; + break; + case LogSeverity::FATAL: + std::cerr << stream_.str() << std::endl; + std::flush(std::cerr); + std::abort(); + break; + } + } + } + + private: + std::stringstream stream_; + LogSeverity severity_; + bool should_log_; +}; +} // namespace logging +} // namespace tflite + +#define TFLITE_LOG(severity) \ + tflite::logging::LoggingWrapper( \ + tflite::logging::LoggingWrapper::LogSeverity::severity) \ + .Stream() + +#define TFLITE_TOOLS_CHECK(condition) \ + tflite::logging::LoggingWrapper( \ + tflite::logging::LoggingWrapper::LogSeverity::FATAL, \ + (condition) ? false : true) \ + .Stream() + +#define TFLITE_TOOLS_CHECK_EQ(a, b) TFLITE_TOOLS_CHECK((a) == (b)) + +#endif // TENSORFLOW_LITE_TOOLS_LOGGING_H_ diff --git a/tensorflow/lite/tools/make/Makefile b/tensorflow/lite/tools/make/Makefile index 7a77cf2b3f5..7d5582b1f36 100644 --- a/tensorflow/lite/tools/make/Makefile +++ b/tensorflow/lite/tools/make/Makefile @@ -111,7 +111,8 @@ PROFILE_SUMMARIZER_SRCS := \ tensorflow/core/util/stats_calculator.cc CMD_LINE_TOOLS_SRCS := \ - tensorflow/lite/tools/command_line_flags.cc + tensorflow/lite/tools/command_line_flags.cc \ + tensorflow/lite/tools/tool_params.cc CORE_CC_ALL_SRCS := \ $(wildcard tensorflow/lite/*.cc) \ diff --git a/tensorflow/lite/tools/tool_params.cc b/tensorflow/lite/tools/tool_params.cc new file mode 100644 index 00000000000..678b81b7784 --- /dev/null +++ b/tensorflow/lite/tools/tool_params.cc @@ -0,0 +1,76 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/tools/tool_params.h" + +#include +#include +#include + +#include "tensorflow/lite/tools/logging.h" + +namespace tflite { +namespace tools { + +void ToolParam::AssertHasSameType(ToolParam::ParamType a, + ToolParam::ParamType b) { + TFLITE_TOOLS_CHECK(a == b) << "Type mismatch while accessing parameter."; +} + +template <> +ToolParam::ParamType ToolParam::GetValueType() { + return ToolParam::ParamType::TYPE_INT32; +} + +template <> +ToolParam::ParamType ToolParam::GetValueType() { + return ToolParam::ParamType::TYPE_BOOL; +} + +template <> +ToolParam::ParamType ToolParam::GetValueType() { + return ToolParam::ParamType::TYPE_FLOAT; +} + +template <> +ToolParam::ParamType ToolParam::GetValueType() { + return ToolParam::ParamType::TYPE_STRING; +} + +void ToolParams::AssertParamExists(const std::string& name) const { + TFLITE_TOOLS_CHECK(HasParam(name)) << name << " was not found."; +} + +void ToolParams::Set(const ToolParams& other) { + for (const auto& param : params_) { + const ToolParam* other_param = other.GetParam(param.first); + if (other_param == nullptr) continue; + param.second->Set(*other_param); + } +} + +void ToolParams::Merge(const ToolParams& other, bool overwrite) { + for (const auto& one : other.params_) { + auto it = params_.find(one.first); + if (it == params_.end()) { + AddParam(one.first, one.second->Clone()); + } else if (overwrite) { + it->second->Set(*one.second); + } + } +} + +} // namespace tools +} // namespace tflite diff --git a/tensorflow/lite/tools/tool_params.h b/tensorflow/lite/tools/tool_params.h new file mode 100644 index 00000000000..30961473c8c --- /dev/null +++ b/tensorflow/lite/tools/tool_params.h @@ -0,0 +1,134 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef TENSORFLOW_LITE_TOOLS_TOOL_PARAMS_H_ +#define TENSORFLOW_LITE_TOOLS_TOOL_PARAMS_H_ +#include +#include +#include +#include +#include + +namespace tflite { +namespace tools { + +template +class TypedToolParam; + +class ToolParam { + protected: + enum class ParamType { TYPE_INT32, TYPE_FLOAT, TYPE_BOOL, TYPE_STRING }; + template + static ParamType GetValueType(); + + public: + template + static std::unique_ptr Create(const T& default_value) { + return std::unique_ptr(new TypedToolParam(default_value)); + } + + template + TypedToolParam* AsTyped() { + AssertHasSameType(GetValueType(), type_); + return static_cast*>(this); + } + + template + const TypedToolParam* AsConstTyped() const { + AssertHasSameType(GetValueType(), type_); + return static_cast*>(this); + } + + virtual ~ToolParam() {} + explicit ToolParam(ParamType type) : type_(type) {} + + virtual void Set(const ToolParam&) {} + + virtual std::unique_ptr Clone() const = 0; + + private: + static void AssertHasSameType(ParamType a, ParamType b); + + const ParamType type_; +}; + +template +class TypedToolParam : public ToolParam { + public: + explicit TypedToolParam(const T& value) + : ToolParam(GetValueType()), value_(value) {} + + void Set(const T& value) { value_ = value; } + + T Get() const { return value_; } + + void Set(const ToolParam& other) override { + Set(other.AsConstTyped()->Get()); + } + + std::unique_ptr Clone() const override { + return std::unique_ptr(new TypedToolParam(value_)); + } + + private: + T value_; +}; + +// A map-like container for holding values of different types. +class ToolParams { + public: + void AddParam(const std::string& name, std::unique_ptr value) { + params_[name] = std::move(value); + } + + bool HasParam(const std::string& name) const { + return params_.find(name) != params_.end(); + } + + bool Empty() const { return params_.empty(); } + + const ToolParam* GetParam(const std::string& name) const { + const auto& entry = params_.find(name); + if (entry == params_.end()) return nullptr; + return entry->second.get(); + } + + template + void Set(const std::string& name, const T& value) { + AssertParamExists(name); + params_.at(name)->AsTyped()->Set(value); + } + + template + T Get(const std::string& name) const { + AssertParamExists(name); + return params_.at(name)->AsTyped()->Get(); + } + + // Set the value of all same parameters from 'other'. + void Set(const ToolParams& other); + + // Merge the value of all parameters from 'other'. 'overwrite' indicates + // whether the value of the same paratmeter is overwritten or not. + void Merge(const ToolParams& other, bool overwrite = false); + + private: + void AssertParamExists(const std::string& name) const; + std::unordered_map> params_; +}; + +} // namespace tools +} // namespace tflite +#endif // TENSORFLOW_LITE_TOOLS_TOOL_PARAMS_H_ diff --git a/tensorflow/lite/tools/tool_params_test.cc b/tensorflow/lite/tools/tool_params_test.cc new file mode 100644 index 00000000000..3bdead3e7c8 --- /dev/null +++ b/tensorflow/lite/tools/tool_params_test.cc @@ -0,0 +1,71 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/tools/tool_params.h" + +#include +#include + +namespace tflite { +namespace tools { +namespace { + +TEST(ToolParams, SetTest) { + ToolParams params; + params.AddParam("some-int1", ToolParam::Create(13)); + params.AddParam("some-int2", ToolParam::Create(17)); + + ToolParams others; + others.AddParam("some-int1", ToolParam::Create(19)); + others.AddParam("some-bool", ToolParam::Create(true)); + + params.Set(others); + EXPECT_EQ(19, params.Get("some-int1")); + EXPECT_EQ(17, params.Get("some-int2")); + EXPECT_FALSE(params.HasParam("some-bool")); +} + +TEST(ToolParams, MergeTestOverwriteTrue) { + ToolParams params; + params.AddParam("some-int1", ToolParam::Create(13)); + params.AddParam("some-int2", ToolParam::Create(17)); + + ToolParams others; + others.AddParam("some-int1", ToolParam::Create(19)); + others.AddParam("some-bool", ToolParam::Create(true)); + + params.Merge(others, true /* overwrite */); + EXPECT_EQ(19, params.Get("some-int1")); + EXPECT_EQ(17, params.Get("some-int2")); + EXPECT_TRUE(params.Get("some-bool")); +} + +TEST(ToolParams, MergeTestOverwriteFalse) { + ToolParams params; + params.AddParam("some-int1", ToolParam::Create(13)); + params.AddParam("some-int2", ToolParam::Create(17)); + + ToolParams others; + others.AddParam("some-int1", ToolParam::Create(19)); + others.AddParam("some-bool", ToolParam::Create(true)); + + params.Merge(others); // default overwrite is false + EXPECT_EQ(13, params.Get("some-int1")); + EXPECT_EQ(17, params.Get("some-int2")); + EXPECT_TRUE(params.Get("some-bool")); +} +} // namespace +} // namespace tools +} // namespace tflite