Use C++11 to generate better quality random numbers.
PiperOrigin-RevId: 282586370 Change-Id: I7502bd2fbda2592adebe7abaefdf3c4367ba6e35
This commit is contained in:
parent
4855dd694f
commit
9485d6e5ef
@ -20,6 +20,7 @@ limitations under the License.
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -290,11 +291,9 @@ BenchmarkParams BenchmarkTfLiteModel::DefaultParams() {
|
|||||||
return default_params;
|
return default_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
BenchmarkTfLiteModel::BenchmarkTfLiteModel()
|
|
||||||
: BenchmarkTfLiteModel(DefaultParams()) {}
|
|
||||||
|
|
||||||
BenchmarkTfLiteModel::BenchmarkTfLiteModel(BenchmarkParams params)
|
BenchmarkTfLiteModel::BenchmarkTfLiteModel(BenchmarkParams params)
|
||||||
: BenchmarkModel(std::move(params)) {}
|
: BenchmarkModel(std::move(params)),
|
||||||
|
random_engine_(std::random_device()()) {}
|
||||||
|
|
||||||
void BenchmarkTfLiteModel::CleanUp() {
|
void BenchmarkTfLiteModel::CleanUp() {
|
||||||
// Free up any pre-allocated tensor data during PrepareInputData.
|
// Free up any pre-allocated tensor data during PrepareInputData.
|
||||||
@ -453,22 +452,16 @@ TfLiteStatus BenchmarkTfLiteModel::PrepareInputData() {
|
|||||||
}
|
}
|
||||||
InputTensorData t_data;
|
InputTensorData t_data;
|
||||||
if (t->type == kTfLiteFloat32) {
|
if (t->type == kTfLiteFloat32) {
|
||||||
t_data = InputTensorData::Create<float>(num_elements, []() {
|
t_data = CreateInputTensorData<float>(
|
||||||
return static_cast<float>(rand()) / RAND_MAX - 0.5f;
|
num_elements, std::uniform_real_distribution<float>(-0.5f, 0.5f));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteFloat16) {
|
} else if (t->type == kTfLiteFloat16) {
|
||||||
// TODO(b/138843274): Remove this preprocessor guard when bug is fixed.
|
// TODO(b/138843274): Remove this preprocessor guard when bug is fixed.
|
||||||
#if TFLITE_ENABLE_FP16_CPU_BENCHMARKS
|
#if TFLITE_ENABLE_FP16_CPU_BENCHMARKS
|
||||||
#if __GNUC__ && \
|
#if __GNUC__ && \
|
||||||
(__clang__ || __ARM_FP16_FORMAT_IEEE || __ARM_FP16_FORMAT_ALTERNATIVE)
|
(__clang__ || __ARM_FP16_FORMAT_IEEE || __ARM_FP16_FORMAT_ALTERNATIVE)
|
||||||
// __fp16 is available on Clang or when __ARM_FP16_FORMAT_* is defined.
|
// __fp16 is available on Clang or when __ARM_FP16_FORMAT_* is defined.
|
||||||
t_data = InputTensorData::Create<TfLiteFloat16>(
|
t_data = CreateInputTensorData<__fp16>(
|
||||||
num_elements, []() -> TfLiteFloat16 {
|
num_elements, std::uniform_real_distribution<float>(-0.5f, 0.5f));
|
||||||
__fp16 f16_value = static_cast<float>(rand()) / RAND_MAX - 0.5f;
|
|
||||||
TfLiteFloat16 f16_placeholder_value;
|
|
||||||
memcpy(&f16_placeholder_value, &f16_value, sizeof(TfLiteFloat16));
|
|
||||||
return f16_placeholder_value;
|
|
||||||
});
|
|
||||||
#else
|
#else
|
||||||
TFLITE_LOG(FATAL) << "Don't know how to populate tensor " << t->name
|
TFLITE_LOG(FATAL) << "Don't know how to populate tensor " << t->name
|
||||||
<< " of type FLOAT16 on this platform.";
|
<< " of type FLOAT16 on this platform.";
|
||||||
@ -484,33 +477,28 @@ TfLiteStatus BenchmarkTfLiteModel::PrepareInputData() {
|
|||||||
} else if (t->type == kTfLiteInt64) {
|
} else if (t->type == kTfLiteInt64) {
|
||||||
int low = has_value_range ? low_range : 0;
|
int low = has_value_range ? low_range : 0;
|
||||||
int high = has_value_range ? high_range : 99;
|
int high = has_value_range ? high_range : 99;
|
||||||
t_data = InputTensorData::Create<int64_t>(num_elements, [=]() {
|
t_data = CreateInputTensorData<int64_t>(
|
||||||
return static_cast<int64_t>(rand() % (high - low + 1) + low);
|
num_elements, std::uniform_int_distribution<int64_t>(low, high));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteInt32) {
|
} else if (t->type == kTfLiteInt32) {
|
||||||
int low = has_value_range ? low_range : 0;
|
int low = has_value_range ? low_range : 0;
|
||||||
int high = has_value_range ? high_range : 99;
|
int high = has_value_range ? high_range : 99;
|
||||||
t_data = InputTensorData::Create<int32_t>(num_elements, [=]() {
|
t_data = CreateInputTensorData<int32_t>(
|
||||||
return static_cast<int32_t>(rand() % (high - low + 1) + low);
|
num_elements, std::uniform_int_distribution<int32_t>(low, high));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteInt16) {
|
} else if (t->type == kTfLiteInt16) {
|
||||||
int low = has_value_range ? low_range : 0;
|
int low = has_value_range ? low_range : 0;
|
||||||
int high = has_value_range ? high_range : 99;
|
int high = has_value_range ? high_range : 99;
|
||||||
t_data = InputTensorData::Create<int16_t>(num_elements, [=]() {
|
t_data = CreateInputTensorData<int16_t>(
|
||||||
return static_cast<int16_t>(rand() % (high - low + 1) + low);
|
num_elements, std::uniform_int_distribution<int16_t>(low, high));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteUInt8) {
|
} else if (t->type == kTfLiteUInt8) {
|
||||||
int low = has_value_range ? low_range : 0;
|
int low = has_value_range ? low_range : 0;
|
||||||
int high = has_value_range ? high_range : 254;
|
int high = has_value_range ? high_range : 254;
|
||||||
t_data = InputTensorData::Create<uint8_t>(num_elements, [=]() {
|
t_data = CreateInputTensorData<uint8_t>(
|
||||||
return static_cast<uint8_t>(rand() % (high - low + 1) + low);
|
num_elements, std::uniform_int_distribution<uint8_t>(low, high));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteInt8) {
|
} else if (t->type == kTfLiteInt8) {
|
||||||
int low = has_value_range ? low_range : -127;
|
int low = has_value_range ? low_range : -127;
|
||||||
int high = has_value_range ? high_range : 127;
|
int high = has_value_range ? high_range : 127;
|
||||||
t_data = InputTensorData::Create<int8_t>(num_elements, [=]() {
|
t_data = CreateInputTensorData<int8_t>(
|
||||||
return static_cast<int8_t>(rand() % (high - low + 1) + low);
|
num_elements, std::uniform_int_distribution<int8_t>(low, high));
|
||||||
});
|
|
||||||
} else if (t->type == kTfLiteString) {
|
} else if (t->type == kTfLiteString) {
|
||||||
// TODO(haoliang): No need to cache string tensors right now.
|
// TODO(haoliang): No need to cache string tensors right now.
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,6 +19,7 @@ limitations under the License.
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -47,8 +48,7 @@ class BenchmarkTfLiteModel : public BenchmarkModel {
|
|||||||
int high;
|
int high;
|
||||||
};
|
};
|
||||||
|
|
||||||
BenchmarkTfLiteModel();
|
explicit BenchmarkTfLiteModel(BenchmarkParams params = DefaultParams());
|
||||||
explicit BenchmarkTfLiteModel(BenchmarkParams params);
|
|
||||||
~BenchmarkTfLiteModel() override;
|
~BenchmarkTfLiteModel() override;
|
||||||
|
|
||||||
std::vector<Flag> GetFlags() override;
|
std::vector<Flag> GetFlags() override;
|
||||||
@ -80,30 +80,33 @@ class BenchmarkTfLiteModel : public BenchmarkModel {
|
|||||||
struct InputTensorData {
|
struct InputTensorData {
|
||||||
InputTensorData() : data(nullptr, nullptr) {}
|
InputTensorData() : data(nullptr, nullptr) {}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static InputTensorData Create(int num_elements,
|
|
||||||
const std::function<T()>& val_generator) {
|
|
||||||
InputTensorData tmp;
|
|
||||||
tmp.bytes = sizeof(T) * num_elements;
|
|
||||||
T* raw = new T[num_elements];
|
|
||||||
std::generate_n(raw, num_elements, val_generator);
|
|
||||||
// Now initialize the type-erased unique_ptr (with custom deleter) from
|
|
||||||
// 'raw'.
|
|
||||||
tmp.data = std::unique_ptr<void, void (*)(void*)>(
|
|
||||||
static_cast<void*>(raw),
|
|
||||||
[](void* ptr) { delete[] static_cast<T*>(ptr); });
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<void, void (*)(void*)> data;
|
std::unique_ptr<void, void (*)(void*)> data;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Distribution>
|
||||||
|
inline InputTensorData CreateInputTensorData(int num_elements,
|
||||||
|
Distribution distribution) {
|
||||||
|
InputTensorData tmp;
|
||||||
|
tmp.bytes = sizeof(T) * num_elements;
|
||||||
|
T* raw = new T[num_elements];
|
||||||
|
std::generate_n(raw, num_elements,
|
||||||
|
[&]() { return distribution(random_engine_); });
|
||||||
|
// Now initialize the type-erased unique_ptr (with custom deleter) from
|
||||||
|
// 'raw'.
|
||||||
|
tmp.data = std::unique_ptr<void, void (*)(void*)>(
|
||||||
|
static_cast<void*>(raw),
|
||||||
|
[](void* ptr) { delete[] static_cast<T*>(ptr); });
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<InputLayerInfo> inputs_;
|
std::vector<InputLayerInfo> inputs_;
|
||||||
std::vector<InputTensorData> inputs_data_;
|
std::vector<InputTensorData> inputs_data_;
|
||||||
std::unique_ptr<BenchmarkListener> profiling_listener_;
|
std::unique_ptr<BenchmarkListener> profiling_listener_;
|
||||||
std::unique_ptr<BenchmarkListener> gemmlowp_profiling_listener_;
|
std::unique_ptr<BenchmarkListener> gemmlowp_profiling_listener_;
|
||||||
TfLiteDelegatePtrMap delegates_;
|
TfLiteDelegatePtrMap delegates_;
|
||||||
|
|
||||||
|
std::mt19937 random_engine_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace benchmark
|
} // namespace benchmark
|
||||||
|
Loading…
x
Reference in New Issue
Block a user