Create a helper lib for some utility functions in the benchmark tool.
PiperOrigin-RevId: 259910553
This commit is contained in:
parent
02a4290cbd
commit
5518980ae5
tensorflow/lite/tools/benchmark
@ -87,6 +87,7 @@ cc_library(
|
||||
copts = common_copts,
|
||||
deps = [
|
||||
":benchmark_model_lib",
|
||||
":benchmark_utils",
|
||||
":logging",
|
||||
"//tensorflow/lite:framework",
|
||||
"//tensorflow/lite:string_util",
|
||||
@ -117,6 +118,7 @@ cc_library(
|
||||
copts = common_copts,
|
||||
deps = [
|
||||
":benchmark_params",
|
||||
":benchmark_utils",
|
||||
":logging",
|
||||
"//tensorflow/core:stats_calculator_portable",
|
||||
"//tensorflow/lite:framework",
|
||||
@ -125,4 +127,27 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "benchmark_utils",
|
||||
srcs = [
|
||||
"benchmark_utils.cc",
|
||||
],
|
||||
hdrs = ["benchmark_utils.h"],
|
||||
copts = common_copts,
|
||||
deps = ["//tensorflow/lite/profiling:time"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "benchmark_utils_test",
|
||||
srcs = [
|
||||
"benchmark_utils_test.cc",
|
||||
],
|
||||
copts = common_copts,
|
||||
deps = [
|
||||
":benchmark_utils",
|
||||
"//tensorflow/lite/profiling:time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
tflite_portable_test_suite()
|
||||
|
@ -19,22 +19,9 @@ limitations under the License.
|
||||
#include <sstream>
|
||||
|
||||
#include "tensorflow/lite/profiling/time.h"
|
||||
#include "tensorflow/lite/tools/benchmark/benchmark_utils.h"
|
||||
#include "tensorflow/lite/tools/benchmark/logging.h"
|
||||
|
||||
namespace {
|
||||
void SleepForSeconds(double sleep_seconds) {
|
||||
if (sleep_seconds <= 0.0) {
|
||||
return;
|
||||
}
|
||||
// If requested, sleep between runs for an arbitrary amount of time.
|
||||
// This can be helpful to determine the effect of mobile processor
|
||||
// scaling and thermal throttling.
|
||||
return tflite::profiling::time::SleepForMicros(
|
||||
static_cast<uint64_t>(sleep_seconds * 1e6));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace tflite {
|
||||
namespace benchmark {
|
||||
using tensorflow::Stat;
|
||||
@ -143,7 +130,7 @@ Stat<int64_t> BenchmarkModel::Run(int min_num_times, float min_secs,
|
||||
listeners_.OnSingleRunEnd();
|
||||
|
||||
run_stats.UpdateStat(end_us - start_us);
|
||||
SleepForSeconds(params_.Get<float>("run_delay"));
|
||||
util::SleepForSeconds(params_.Get<float>("run_delay"));
|
||||
now_us = profiling::time::NowMicros();
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ limitations under the License.
|
||||
#include "tensorflow/lite/profiling/buffered_profiler.h"
|
||||
#include "tensorflow/lite/profiling/profile_summarizer.h"
|
||||
#include "tensorflow/lite/string_util.h"
|
||||
#include "tensorflow/lite/tools/benchmark/benchmark_utils.h"
|
||||
#include "tensorflow/lite/tools/benchmark/logging.h"
|
||||
#include "tensorflow/lite/tools/evaluation/utils.h"
|
||||
|
||||
@ -119,39 +120,13 @@ void GemmlowpProfilingListener::OnBenchmarkEnd(
|
||||
}
|
||||
|
||||
std::vector<std::string> Split(const std::string& str, const char delim) {
|
||||
std::istringstream input(str);
|
||||
std::vector<std::string> results;
|
||||
std::string item;
|
||||
while (std::getline(input, item, delim)) {
|
||||
results.push_back(item);
|
||||
if (!util::SplitAndParse(str, delim, &results)) {
|
||||
results.clear();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool SplitAndParse(const std::string& str, char delim, std::vector<T>* values) {
|
||||
std::istringstream input(str);
|
||||
bool first = true;
|
||||
while (!input.eof()) {
|
||||
if (!first) {
|
||||
char c;
|
||||
input >> c;
|
||||
if (c != delim) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
T val;
|
||||
input >> val;
|
||||
if (!input.eof() && !input.good()) {
|
||||
return false;
|
||||
}
|
||||
values->push_back(val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void FillRandomValue(T* ptr, int num_elements,
|
||||
const std::function<T()>& random_func) {
|
||||
@ -197,7 +172,7 @@ bool PopulateInputLayerInfo(
|
||||
|
||||
input.name = names[i];
|
||||
|
||||
TFLITE_BENCHMARK_CHECK(SplitAndParse(shapes[i], ',', &input.shape))
|
||||
TFLITE_BENCHMARK_CHECK(util::SplitAndParse(shapes[i], ',', &input.shape))
|
||||
<< "Incorrect size string specified: " << shapes[i];
|
||||
for (int dim : input.shape) {
|
||||
if (dim == -1) {
|
||||
|
37
tensorflow/lite/tools/benchmark/benchmark_utils.cc
Normal file
37
tensorflow/lite/tools/benchmark/benchmark_utils.cc
Normal file
@ -0,0 +1,37 @@
|
||||
/* Copyright 2019 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_utils.h"
|
||||
|
||||
#include "tensorflow/lite/profiling/time.h"
|
||||
|
||||
namespace tflite {
|
||||
namespace benchmark {
|
||||
namespace util {
|
||||
|
||||
void SleepForSeconds(double sleep_seconds) {
|
||||
if (sleep_seconds <= 0.0) {
|
||||
return;
|
||||
}
|
||||
// If requested, sleep between runs for an arbitrary amount of time.
|
||||
// This can be helpful to determine the effect of mobile processor
|
||||
// scaling and thermal throttling.
|
||||
tflite::profiling::time::SleepForMicros(
|
||||
static_cast<uint64_t>(sleep_seconds * 1e6));
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace benchmark
|
||||
} // namespace tflite
|
52
tensorflow/lite/tools/benchmark/benchmark_utils.h
Normal file
52
tensorflow/lite/tools/benchmark/benchmark_utils.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* Copyright 2019 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_BENCHMARK_BENCHMARK_UTILS_H_
|
||||
#define TENSORFLOW_LITE_TOOLS_BENCHMARK_BENCHMARK_UTILS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace tflite {
|
||||
namespace benchmark {
|
||||
namespace util {
|
||||
|
||||
// A convenient function that wraps tflite::profiling::time::SleepForMicros and
|
||||
// simply return if 'sleep_seconds' is negative.
|
||||
void SleepForSeconds(double sleep_seconds);
|
||||
|
||||
// Split the 'str' according to 'delim', and store each splitted element into
|
||||
// 'values'.
|
||||
template <typename T>
|
||||
bool SplitAndParse(const std::string& str, char delim, std::vector<T>* values) {
|
||||
std::istringstream input(str);
|
||||
for (std::string line; std::getline(input, line, delim);) {
|
||||
std::istringstream to_parse(line);
|
||||
T val;
|
||||
to_parse >> val;
|
||||
if (!to_parse.eof() && !to_parse.good()) {
|
||||
return false;
|
||||
}
|
||||
values->emplace_back(val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace benchmark
|
||||
} // namespace tflite
|
||||
|
||||
#endif // TENSORFLOW_LITE_TOOLS_BENCHMARK_BENCHMARK_UTILS_H_
|
80
tensorflow/lite/tools/benchmark/benchmark_utils_test.cc
Normal file
80
tensorflow/lite/tools/benchmark/benchmark_utils_test.cc
Normal file
@ -0,0 +1,80 @@
|
||||
/* 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_utils.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "tensorflow/lite/profiling/time.h"
|
||||
|
||||
namespace tflite {
|
||||
namespace benchmark {
|
||||
namespace {
|
||||
|
||||
TEST(BenchmarkHelpersTest, SleepForNegativeSeconds) {
|
||||
const auto start_ts = tflite::profiling::time::NowMicros();
|
||||
// The following should return immediately.
|
||||
util::SleepForSeconds(-5.0);
|
||||
const auto end_ts = tflite::profiling::time::NowMicros();
|
||||
|
||||
// As we don't have a mocked clock, we simply expect <1 sec has elapsed, which
|
||||
// is admittedly not quite accurate.
|
||||
EXPECT_LT(end_ts - start_ts, 1000000);
|
||||
}
|
||||
|
||||
TEST(BenchmarkHelpersTest, SleepForSomeSeconds) {
|
||||
const auto start_ts = tflite::profiling::time::NowMicros();
|
||||
// The following should return after 2.0 secs
|
||||
util::SleepForSeconds(2.0);
|
||||
const auto end_ts = tflite::profiling::time::NowMicros();
|
||||
|
||||
// As we don't have a mocked clock, we simply expect >1.9 sec has elapsed.
|
||||
EXPECT_GT(end_ts - start_ts, 1900000);
|
||||
}
|
||||
|
||||
TEST(BenchmarkHelpersTest, SplitAndParseFailed) {
|
||||
std::vector<int> results;
|
||||
const bool splitted = util::SplitAndParse("hello;world", ';', &results);
|
||||
|
||||
EXPECT_FALSE(splitted);
|
||||
}
|
||||
|
||||
TEST(BenchmarkHelpersTest, SplitAndParseString) {
|
||||
std::vector<std::string> results;
|
||||
const bool splitted = util::SplitAndParse("hello,world", ',', &results);
|
||||
|
||||
EXPECT_TRUE(splitted);
|
||||
EXPECT_EQ(2, results.size());
|
||||
|
||||
EXPECT_EQ("hello", results[0]);
|
||||
EXPECT_EQ("world", results[1]);
|
||||
}
|
||||
|
||||
TEST(BenchmarkHelpersTest, SplitAndParseInts) {
|
||||
std::vector<int> results;
|
||||
const bool splitted = util::SplitAndParse("1,2", ',', &results);
|
||||
|
||||
EXPECT_TRUE(splitted);
|
||||
EXPECT_EQ(2, results.size());
|
||||
|
||||
EXPECT_EQ(1, results[0]);
|
||||
EXPECT_EQ(2, results[1]);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace benchmark
|
||||
} // namespace tflite
|
Loading…
Reference in New Issue
Block a user