diff --git a/tensorflow/lite/tools/benchmark/BUILD b/tensorflow/lite/tools/benchmark/BUILD index b0eaa4b5a06..8d41299fa57 100644 --- a/tensorflow/lite/tools/benchmark/BUILD +++ b/tensorflow/lite/tools/benchmark/BUILD @@ -124,6 +124,7 @@ cc_library( ":hexagon_delegate_provider", ":logging", ":nnapi_delegate_provider", + ":xnnpack_delegate_provider", "//tensorflow/lite:framework", "//tensorflow/lite:string_util", "//tensorflow/lite/experimental/ruy/profiler", @@ -260,6 +261,20 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "xnnpack_delegate_provider", + srcs = ["xnnpack_delegate_provider.cc"], + copts = tflite_copts(), + visibility = ["//visibility:public"], + deps = [ + ":benchmark_model_lib", + ":delegate_provider_hdr", + ":logging", + "//tensorflow/lite/delegates/xnnpack:xnnpack_delegate", + ], + alwayslink = 1, +) + cc_library( name = "benchmark_utils", srcs = [ diff --git a/tensorflow/lite/tools/benchmark/README.md b/tensorflow/lite/tools/benchmark/README.md index b8011cfbfe3..f510a3d06b6 100644 --- a/tensorflow/lite/tools/benchmark/README.md +++ b/tensorflow/lite/tools/benchmark/README.md @@ -34,6 +34,8 @@ and the following optional parameters: * `run_delay`: `float` (default=-1.0) \ The delay in seconds between subsequent benchmark runs. Non-positive values mean use no delay. +* `use_xnnpack`: `bool` (default=false) \ + Whether to use the XNNPack delegate. * `use_hexagon`: `bool` (default=false) \ Whether to use the Hexagon delegate. Not all devices may support the Hexagon delegate, refer to the TensorFlow Lite documentation for more information diff --git a/tensorflow/lite/tools/benchmark/benchmark_performance_options.cc b/tensorflow/lite/tools/benchmark/benchmark_performance_options.cc index e286b7c9b0c..eccd389af6f 100644 --- a/tensorflow/lite/tools/benchmark/benchmark_performance_options.cc +++ b/tensorflow/lite/tools/benchmark/benchmark_performance_options.cc @@ -79,6 +79,12 @@ void MultiRunStatsRecorder::OnBenchmarkStart(const BenchmarkParams& params) { // requires C++11. std::stringstream sstm; sstm << "cpu w/ " << params.Get("num_threads") << " threads"; + + // Handle cases run on CPU w/ the xnnpack delegate + if (params.Get("use_xnnpack")) { + sstm << " (xnnpack)"; + } + current_run_name_ = sstm.str(); } @@ -238,6 +244,7 @@ void BenchmarkPerformanceOptions::ResetPerformanceOptions() { #if defined(TFLITE_ENABLE_HEXAGON) single_option_run_params_->Set("use_hexagon", false); #endif + single_option_run_params_->Set("use_xnnpack", false); } void BenchmarkPerformanceOptions::CreatePerformanceOptions() { @@ -260,6 +267,13 @@ void BenchmarkPerformanceOptions::CreatePerformanceOptions() { BenchmarkParams params; params.AddParam("num_threads", BenchmarkParam::Create(count)); all_run_params_.emplace_back(std::move(params)); + + BenchmarkParams xnnpack_params; + xnnpack_params.AddParam("use_xnnpack", + BenchmarkParam::Create(true)); + xnnpack_params.AddParam("num_threads", + BenchmarkParam::Create(count)); + all_run_params_.emplace_back(std::move(xnnpack_params)); } } diff --git a/tensorflow/lite/tools/benchmark/benchmark_test.cc b/tensorflow/lite/tools/benchmark/benchmark_test.cc index 463b3b4117b..19e0b71893e 100644 --- a/tensorflow/lite/tools/benchmark/benchmark_test.cc +++ b/tensorflow/lite/tools/benchmark/benchmark_test.cc @@ -62,6 +62,7 @@ BenchmarkParams CreateParams(int32_t num_runs, float min_secs, float max_secs, params.AddParam("input_layer_value_range", BenchmarkParam::Create("")); params.AddParam("use_hexagon", BenchmarkParam::Create(false)); + params.AddParam("use_xnnpack", BenchmarkParam::Create(false)); params.AddParam("use_nnapi", BenchmarkParam::Create(false)); params.AddParam("allow_fp16", BenchmarkParam::Create(false)); params.AddParam("require_full_delegation", diff --git a/tensorflow/lite/tools/benchmark/xnnpack_delegate_provider.cc b/tensorflow/lite/tools/benchmark/xnnpack_delegate_provider.cc new file mode 100644 index 00000000000..63270fc2cd4 --- /dev/null +++ b/tensorflow/lite/tools/benchmark/xnnpack_delegate_provider.cc @@ -0,0 +1,72 @@ +/* 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 + +#include "tensorflow/lite/delegates/xnnpack/xnnpack_delegate.h" +#include "tensorflow/lite/tools/benchmark/benchmark_model.h" +#include "tensorflow/lite/tools/benchmark/delegate_provider.h" +#include "tensorflow/lite/tools/benchmark/logging.h" + +namespace tflite { +namespace benchmark { + +class XnnpackDelegateProvider : public DelegateProvider { + public: + std::vector CreateFlags(BenchmarkParams* params) const final; + + void AddParams(BenchmarkParams* params) const final; + + void LogParams(const BenchmarkParams& params) const final; + + TfLiteDelegatePtr CreateTfLiteDelegate( + const BenchmarkParams& params) const final; + + std::string GetName() const final { return "XNNPACK"; } +}; +REGISTER_DELEGATE_PROVIDER(XnnpackDelegateProvider); + +std::vector XnnpackDelegateProvider::CreateFlags( + BenchmarkParams* params) const { + std::vector flags = { + CreateFlag("use_xnnpack", params, "use XNNPack")}; + return flags; +} + +void XnnpackDelegateProvider::AddParams(BenchmarkParams* params) const { + params->AddParam("use_xnnpack", BenchmarkParam::Create(false)); +} + +void XnnpackDelegateProvider::LogParams(const BenchmarkParams& params) const { + TFLITE_LOG(INFO) << "Use xnnpack : [" << params.Get("use_xnnpack") + << "]"; +} + +TfLiteDelegatePtr XnnpackDelegateProvider::CreateTfLiteDelegate( + const BenchmarkParams& params) const { + TfLiteDelegatePtr delegate(nullptr, [](TfLiteDelegate*) {}); + if (params.Get("use_xnnpack")) { + TfLiteXNNPackDelegateOptions options = + TfLiteXNNPackDelegateOptionsDefault(); + const auto num_threads = params.Get("num_threads"); + // Note that we don't want to use the thread pool for num_threads == 1. + options.num_threads = num_threads > 1 ? num_threads : 0; + delegate = TfLiteDelegatePtr(TfLiteXNNPackDelegateCreate(&options), + &TfLiteXNNPackDelegateDelete); + } + return delegate; +} + +} // namespace benchmark +} // namespace tflite