Add a HVX graph execution test for quantized inception v3 model with quantized input
PiperOrigin-RevId: 161105730
This commit is contained in:
parent
2559fda880
commit
06d25a7e62
@ -24,6 +24,9 @@ https://storage.googleapis.com/download.tensorflow.org/models/imagenet_comp_grap
|
|||||||
adb push /tmp/imagenet_comp_graph_label_strings.txt /data/local/tmp
|
adb push /tmp/imagenet_comp_graph_label_strings.txt /data/local/tmp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// define EIGEN_USE_THREADS to include quantization_utils.h
|
||||||
|
#define EIGEN_USE_THREADS
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "tensorflow/core/framework/tensor_shape.pb.h"
|
#include "tensorflow/core/framework/tensor_shape.pb.h"
|
||||||
@ -34,6 +37,7 @@ adb push /tmp/imagenet_comp_graph_label_strings.txt /data/local/tmp
|
|||||||
#include "tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h"
|
#include "tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h"
|
||||||
#include "tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h"
|
#include "tensorflow/core/kernels/hexagon/i_graph_transfer_ops_definitions.h"
|
||||||
#include "tensorflow/core/kernels/i_remote_fused_graph_executor.h"
|
#include "tensorflow/core/kernels/i_remote_fused_graph_executor.h"
|
||||||
|
#include "tensorflow/core/kernels/quantization_utils.h"
|
||||||
#include "tensorflow/core/lib/core/casts.h"
|
#include "tensorflow/core/lib/core/casts.h"
|
||||||
#include "tensorflow/core/lib/core/status.h"
|
#include "tensorflow/core/lib/core/status.h"
|
||||||
#include "tensorflow/core/lib/core/status_test_util.h"
|
#include "tensorflow/core/lib/core/status_test_util.h"
|
||||||
@ -52,6 +56,10 @@ using ByteArray = HexagonControlWrapper::ByteArray;
|
|||||||
constexpr const char* const IMAGE_FILENAME = "/data/local/tmp/img_299x299.bmp";
|
constexpr const char* const IMAGE_FILENAME = "/data/local/tmp/img_299x299.bmp";
|
||||||
constexpr const char* const MODEL_FILENAME =
|
constexpr const char* const MODEL_FILENAME =
|
||||||
"/data/local/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb";
|
"/data/local/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb";
|
||||||
|
constexpr const char* const MODEL_WITH_QUANTIZED_INPUT_FILENAME =
|
||||||
|
"/data/local/tmp/"
|
||||||
|
"tensorflow_inception_v3_stripped_optimized_quantized_with_quantized_input."
|
||||||
|
"pb";
|
||||||
constexpr const char* const FUSED_MODEL_FILENAME =
|
constexpr const char* const FUSED_MODEL_FILENAME =
|
||||||
"/data/local/tmp/"
|
"/data/local/tmp/"
|
||||||
"tensorflow_inception_v3_stripped_optimized_quantized_fused_hexagon.pb";
|
"tensorflow_inception_v3_stripped_optimized_quantized_fused_hexagon.pb";
|
||||||
@ -64,7 +72,7 @@ const int WIDTH = 299;
|
|||||||
const int HEIGHT = 299;
|
const int HEIGHT = 299;
|
||||||
const int DEPTH = 3;
|
const int DEPTH = 3;
|
||||||
const int EXPECTED_FIRST_RESULT_ID = 59;
|
const int EXPECTED_FIRST_RESULT_ID = 59;
|
||||||
const int EXECUTION_REPEAT_COUNT = 3;
|
const int EXECUTION_REPEAT_COUNT = 10;
|
||||||
|
|
||||||
static void CheckHexagonControllerVersion() {
|
static void CheckHexagonControllerVersion() {
|
||||||
HexagonControlWrapper hexagon_control_wrapper;
|
HexagonControlWrapper hexagon_control_wrapper;
|
||||||
@ -165,8 +173,16 @@ static void LoadImage(std::vector<float>* img_floats_ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void QuantizeImage(const std::vector<float>& float_vec,
|
||||||
|
std::vector<quint8>* quint8_vec) {
|
||||||
|
quint8_vec->resize(float_vec.size());
|
||||||
|
for (int i = 0; i < float_vec.size(); ++i) {
|
||||||
|
quint8_vec->at(i) = FloatToQuantized<quint8>(float_vec[i], -1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Tensor BuildImageTensor(const std::vector<float>& img_floats) {
|
static Tensor BuildImageTensor(const std::vector<float>& img_floats) {
|
||||||
LOG(INFO) << "Ioading image finished.";
|
LOG(INFO) << "Loading image finished.";
|
||||||
Tensor img_tensor(DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH});
|
Tensor img_tensor(DT_FLOAT, {1, WIDTH, HEIGHT, DEPTH});
|
||||||
CHECK_EQ(WIDTH * HEIGHT * DEPTH, img_floats.size());
|
CHECK_EQ(WIDTH * HEIGHT * DEPTH, img_floats.size());
|
||||||
CHECK_EQ(img_tensor.TotalBytes(), img_floats.size() * sizeof(float));
|
CHECK_EQ(img_tensor.TotalBytes(), img_floats.size() * sizeof(float));
|
||||||
@ -176,6 +192,18 @@ static Tensor BuildImageTensor(const std::vector<float>& img_floats) {
|
|||||||
return img_tensor;
|
return img_tensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tensor BuildQuantizedImageTensor(
|
||||||
|
const std::vector<quint8>& quantized_img) {
|
||||||
|
LOG(INFO) << "Loading image finished.";
|
||||||
|
Tensor img_tensor(DT_QUINT8, {1, WIDTH, HEIGHT, DEPTH});
|
||||||
|
CHECK_EQ(WIDTH * HEIGHT * DEPTH, quantized_img.size());
|
||||||
|
CHECK_EQ(img_tensor.TotalBytes(), quantized_img.size() * sizeof(quint8));
|
||||||
|
LOG(INFO) << "Copy data to tensor.";
|
||||||
|
std::memcpy(img_tensor.flat<quint8>().data(), quantized_img.data(),
|
||||||
|
img_tensor.TotalBytes());
|
||||||
|
return img_tensor;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ RemoteFusedGraphExecuteInfo
|
/* static */ RemoteFusedGraphExecuteInfo
|
||||||
BuildRemoteFusedGraphExecuteInfoWithGraphTransferInfo(
|
BuildRemoteFusedGraphExecuteInfoWithGraphTransferInfo(
|
||||||
const GraphTransferInfo& graph_transfer_info) {
|
const GraphTransferInfo& graph_transfer_info) {
|
||||||
@ -210,10 +238,8 @@ BuildRemoteFusedGraphExecuteInfoWithGraphTransferInfo(
|
|||||||
return execute_info;
|
return execute_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RunInferenceByHexagonControlWrapper(
|
static void RunInferenceByHexagonControlWrapper(const GraphTransferer& gt,
|
||||||
const GraphTransferer& gt, const std::vector<float>& img_floats) {
|
const Tensor& img_tensor) {
|
||||||
const Tensor img_tensor = BuildImageTensor(img_floats);
|
|
||||||
|
|
||||||
const RemoteFusedGraphExecuteInfo execute_info =
|
const RemoteFusedGraphExecuteInfo execute_info =
|
||||||
BuildRemoteFusedGraphExecuteInfoWithGraphTransferInfo(
|
BuildRemoteFusedGraphExecuteInfoWithGraphTransferInfo(
|
||||||
gt.GetGraphTransferInfo());
|
gt.GetGraphTransferInfo());
|
||||||
@ -229,13 +255,11 @@ static void RunInferenceByHexagonControlWrapper(
|
|||||||
hexagon_control_wrapper.FillInputNode("Mul", img_tensor);
|
hexagon_control_wrapper.FillInputNode("Mul", img_tensor);
|
||||||
|
|
||||||
// 4. Execute graph
|
// 4. Execute graph
|
||||||
profile_utils::CpuUtils::EnableClockCycleProfiling(true);
|
const int64 start_time_us = Env::Default()->NowMicros();
|
||||||
ClockCycleProfiler prof;
|
|
||||||
for (int i = 0; i < EXECUTION_REPEAT_COUNT; ++i) {
|
for (int i = 0; i < EXECUTION_REPEAT_COUNT; ++i) {
|
||||||
prof.Start();
|
|
||||||
hexagon_control_wrapper.ExecuteGraph();
|
hexagon_control_wrapper.ExecuteGraph();
|
||||||
prof.Stop();
|
|
||||||
}
|
}
|
||||||
|
const int64 end_time_us = Env::Default()->NowMicros();
|
||||||
|
|
||||||
// 5-1. Read output node's outputs
|
// 5-1. Read output node's outputs
|
||||||
std::vector<ByteArray> outputs;
|
std::vector<ByteArray> outputs;
|
||||||
@ -244,7 +268,8 @@ static void RunInferenceByHexagonControlWrapper(
|
|||||||
// 5-2. Dump results
|
// 5-2. Dump results
|
||||||
DumpTop10Results(outputs);
|
DumpTop10Results(outputs);
|
||||||
CheckFirstResult(outputs, EXPECTED_FIRST_RESULT_ID);
|
CheckFirstResult(outputs, EXPECTED_FIRST_RESULT_ID);
|
||||||
prof.DumpStatistics("Graph Execution");
|
LOG(INFO) << "Average execution time = "
|
||||||
|
<< (end_time_us - start_time_us) / EXECUTION_REPEAT_COUNT << "us";
|
||||||
|
|
||||||
// 6. Teardown graph in hexagon
|
// 6. Teardown graph in hexagon
|
||||||
hexagon_control_wrapper.TeardownGraph();
|
hexagon_control_wrapper.TeardownGraph();
|
||||||
@ -405,7 +430,43 @@ TEST(GraphTransferer,
|
|||||||
|
|
||||||
std::vector<float> img_floats;
|
std::vector<float> img_floats;
|
||||||
LoadImage(&img_floats);
|
LoadImage(&img_floats);
|
||||||
RunInferenceByHexagonControlWrapper(gt, img_floats);
|
const Tensor img_tensor = BuildImageTensor(img_floats);
|
||||||
|
RunInferenceByHexagonControlWrapper(gt, img_tensor);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GraphTransferer,
|
||||||
|
DISABLED_RunInceptionV3OnHexagonExampleWithHexagonWrapperQuantizedInput) {
|
||||||
|
LOG(INFO) << "Run inception v3 on hexagon with hexagon controller "
|
||||||
|
<< "with quantized input";
|
||||||
|
CheckHexagonControllerVersion();
|
||||||
|
|
||||||
|
const IGraphTransferOpsDefinitions* ops_definitions =
|
||||||
|
&HexagonOpsDefinitions::getInstance();
|
||||||
|
std::vector<std::pair<string, Tensor>> inputs;
|
||||||
|
inputs.emplace_back("Mul", Tensor(DT_QUINT8, {1, WIDTH, HEIGHT, DEPTH}));
|
||||||
|
std::vector<string> output_node_names = {"softmax"};
|
||||||
|
|
||||||
|
GraphTransferer gt;
|
||||||
|
gt.EnableStrictCheckMode(false);
|
||||||
|
profile_utils::CpuUtils::EnableClockCycleProfiling(true);
|
||||||
|
ClockCycleProfiler prof;
|
||||||
|
prof.Start();
|
||||||
|
Status status = gt.LoadGraphFromProtoFile(
|
||||||
|
*ops_definitions, MODEL_WITH_QUANTIZED_INPUT_FILENAME, inputs,
|
||||||
|
output_node_names,
|
||||||
|
/*is_text_proto=*/false,
|
||||||
|
/*shape_inference_for_unknown_shape=*/false,
|
||||||
|
/*dry_run_for_unknown_shape=*/true);
|
||||||
|
ASSERT_TRUE(status.ok()) << status;
|
||||||
|
prof.Stop();
|
||||||
|
prof.DumpStatistics("LoadGraphFromProtoFile");
|
||||||
|
|
||||||
|
std::vector<float> img_floats;
|
||||||
|
LoadImage(&img_floats);
|
||||||
|
std::vector<quint8> quantized_img;
|
||||||
|
QuantizeImage(img_floats, &quantized_img);
|
||||||
|
const Tensor img_tensor = BuildQuantizedImageTensor(quantized_img);
|
||||||
|
RunInferenceByHexagonControlWrapper(gt, img_tensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GraphTransferer,
|
TEST(GraphTransferer,
|
||||||
@ -436,7 +497,8 @@ TEST(GraphTransferer,
|
|||||||
|
|
||||||
std::vector<float> img_floats;
|
std::vector<float> img_floats;
|
||||||
LoadImage(&img_floats);
|
LoadImage(&img_floats);
|
||||||
RunInferenceByHexagonControlWrapper(gt, img_floats);
|
const Tensor img_tensor = BuildImageTensor(img_floats);
|
||||||
|
RunInferenceByHexagonControlWrapper(gt, img_tensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GraphTransferer, RunInceptionV3OnHexagonExampleWithTfRuntime) {
|
TEST(GraphTransferer, RunInceptionV3OnHexagonExampleWithTfRuntime) {
|
||||||
|
Loading…
Reference in New Issue
Block a user