aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2017-01-17 16:27:46 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-01-17 16:46:56 -0800
commitfecad67e9b92abb45466f46c91c75771164a6b67 (patch)
treeec884af8d193d049679d07522790f7552f0f1267 /tensorflow
parentfb7f551fecfa99f6683c73e7ad1cfa5bcf0fc164 (diff)
Show labels of ranking results of inception inference on HVX
Change: 144771220
Diffstat (limited to 'tensorflow')
-rw-r--r--tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in1
-rw-r--r--tensorflow/core/kernels/hexagon/BUILD2
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transfer_utils.cc49
-rw-r--r--tensorflow/core/kernels/hexagon/graph_transfer_utils.h41
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc25
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h3
-rw-r--r--tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc51
7 files changed, 143 insertions, 29 deletions
diff --git a/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
index 3bad4c42a9..986150cb3f 100644
--- a/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
+++ b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in
@@ -44,6 +44,7 @@ CXXFLAGS += -DTENSORFLOW_DISABLE_META
CXXFLAGS += -D__ANDROID_TYPES_FULL__
GRAPH_EXECUTION_SRCS := \
+tensorflow/core/kernels/hexagon/graph_transfer_utils.cc \
tensorflow/core/kernels/hexagon/graph_transferer.cc \
tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc \
tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc \
diff --git a/tensorflow/core/kernels/hexagon/BUILD b/tensorflow/core/kernels/hexagon/BUILD
index 1222093a7a..9263c062ba 100644
--- a/tensorflow/core/kernels/hexagon/BUILD
+++ b/tensorflow/core/kernels/hexagon/BUILD
@@ -72,12 +72,14 @@ tf_cc_test(
tf_kernel_library(
name = "graph_transferer",
srcs = [
+ "graph_transfer_utils.cc",
"graph_transferer.cc",
"hexagon_control_wrapper.cc",
"hexagon_ops_definitions.cc",
"i_graph_transfer_ops_definitions.cc",
],
hdrs = [
+ "graph_transfer_utils.h",
"graph_transferer.h",
"hexagon_control_wrapper.h",
"hexagon_ops_definitions.h",
diff --git a/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc b/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc
new file mode 100644
index 0000000000..c37e49f242
--- /dev/null
+++ b/tensorflow/core/kernels/hexagon/graph_transfer_utils.cc
@@ -0,0 +1,49 @@
+/* Copyright 2017 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/core/kernels/hexagon/graph_transfer_utils.h"
+
+#include "tensorflow/core/platform/logging.h"
+
+namespace tensorflow {
+
+/* static */ std::priority_queue<std::tuple<float, int, string>>
+GraphTransferUtils::GetTopNFloatResults(const float *const data,
+ const string *const labels,
+ const int element_count) {
+ CHECK(data != nullptr);
+ CHECK(labels != nullptr);
+ std::priority_queue<std::tuple<float, int, string>> queue;
+ for (int i = 0; i < element_count; ++i) {
+ queue.emplace(data[i], i, labels[i]);
+ }
+ return queue;
+}
+
+/* static */ void GraphTransferUtils::DumpTopNFloatResults(
+ const float *const data, const string *const labels,
+ const int element_count, const int top_n) {
+ std::priority_queue<std::tuple<float, int, string>> queue =
+ GetTopNFloatResults(data, labels, element_count);
+ LOG(INFO) << "=== Dump ranking ===";
+ for (int i = 0; i < top_n; ++i) {
+ const std::tuple<float, int, string> &entry = queue.top();
+ LOG(INFO) << i << ": " << std::get<1>(entry) << ", " << std::get<2>(entry)
+ << ", " << std::get<0>(entry);
+ queue.pop();
+ }
+}
+
+} // namespace tensorflow
diff --git a/tensorflow/core/kernels/hexagon/graph_transfer_utils.h b/tensorflow/core/kernels/hexagon/graph_transfer_utils.h
new file mode 100644
index 0000000000..85af9b5ce3
--- /dev/null
+++ b/tensorflow/core/kernels/hexagon/graph_transfer_utils.h
@@ -0,0 +1,41 @@
+/* Copyright 2017 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_PLATFORM_HEXAGON_GRAPH_TRANSFER_UTILS_H_
+#define TENSORFLOW_PLATFORM_HEXAGON_GRAPH_TRANSFER_UTILS_H_
+
+#include <queue>
+
+#include "tensorflow/core/framework/types.h"
+#include "tensorflow/core/platform/macros.h"
+
+namespace tensorflow {
+
+class GraphTransferUtils {
+ public:
+ static std::priority_queue<std::tuple<float, int, string>>
+ GetTopNFloatResults(const float *const data, const string *const labels,
+ const int element_count);
+ static void DumpTopNFloatResults(const float *const data,
+ const string *const labels,
+ const int element_count, const int top_n);
+
+ private:
+ TF_DISALLOW_COPY_AND_ASSIGN(GraphTransferUtils);
+};
+
+} // namespace tensorflow
+
+#endif // TENSORFLOW_PLATFORM_HEXAGON_GRAPH_TRANSFER_UTILS_H_
diff --git a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
index ecebd3c599..561b216378 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
+++ b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc
@@ -15,12 +15,9 @@ limitations under the License.
#include "tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h"
-#include <queue>
-
#ifdef USE_HEXAGON_LIBS
#include "tensorflow/core/platform/hexagon/soc_interface.h"
#include "tensorflow/core/platform/profile_utils/cpu_utils.h"
-#include "tensorflow/core/platform/types.h"
#endif
namespace tensorflow {
@@ -28,7 +25,6 @@ namespace tensorflow {
const bool SHOW_DBG_IN_SOC = false;
const bool DBG_USE_DUMMY_INPUT = false;
const bool DBG_USE_SAMPLE_INPUT = false;
-const bool DBG_SHOW_RESULT = false;
const int64 FLAG_ENABLE_PANDA_BINARY_INPUT = 0x01;
#ifdef USE_HEXAGON_LIBS
@@ -213,12 +209,6 @@ bool HexagonControlWrapper::ReadOutputNode(
// TODO: Accept all results
std::get<2>(output) = DT_FLOAT;
outputs->emplace_back(output);
- if (DBG_SHOW_RESULT) {
- const int byte_size = std::get<1>(output);
- const int element_count = byte_size / sizeof(float);
- const float* float_array = reinterpret_cast<float*>(std::get<0>(output));
- DumpTopNFloatResults(float_array, element_count, 10 /* top_n */);
- }
return true;
}
@@ -240,19 +230,4 @@ bool HexagonControlWrapper::ReadOutputNode(const string,
}
#endif
-void HexagonControlWrapper::DumpTopNFloatResults(const float* data,
- const float element_count,
- const int top_n) {
- std::priority_queue<std::tuple<float, int>> queue;
- for (int i = 0; i < element_count; ++i) {
- queue.emplace(data[i], i);
- }
- LOG(INFO) << "=== Dump ranking ===";
- for (int i = 0; i < top_n; ++i) {
- const std::tuple<float, int>& entry = queue.top();
- LOG(INFO) << i << ": " << std::get<1>(entry) << ", " << std::get<0>(entry);
- queue.pop();
- }
-}
-
} // namespace tensorflow
diff --git a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h
index dfae5aa5e2..0ba0b323cb 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h
+++ b/tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h
@@ -46,9 +46,6 @@ class HexagonControlWrapper final : public ISocControlWrapper {
// CAVEAT: Need offset as HVX library reserves some ids
static constexpr int NODE_ID_OFFSET = 0x10000;
- void DumpTopNFloatResults(const float *data, const float element_count,
- const int top_n);
-
// Dummy float array for input node.
// TODO(satok): Use actual data passed by FillInputNode and remove
std::vector<float> dummy_input_float_;
diff --git a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
index d06fb5fabc..b0e480a7fd 100644
--- a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
+++ b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc
@@ -17,10 +17,15 @@ limitations under the License.
// -o /tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb
// adb push /tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb \
// /data/local/tmp
+// $ curl
+// https://storage.googleapis.com/download.tensorflow.org/models/imagenet_comp_graph_label_strings.txt
+// -o /tmp/imagenet_comp_graph_label_strings.txt
+// adb push /tmp/imagenet_comp_graph_label_strings.txt /data/local/tmp
#include <memory>
#include "tensorflow/core/framework/tensor_testutil.h"
+#include "tensorflow/core/kernels/hexagon/graph_transfer_utils.h"
#include "tensorflow/core/kernels/hexagon/graph_transferer.h"
#include "tensorflow/core/kernels/hexagon/hexagon_control_wrapper.h"
#include "tensorflow/core/kernels/hexagon/hexagon_ops_definitions.h"
@@ -29,6 +34,7 @@ limitations under the License.
#include "tensorflow/core/lib/core/casts.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/io/path.h"
+#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/test.h"
@@ -40,6 +46,42 @@ const bool DBG_DUMP_FLOAT_DATA = false;
const int WIDTH = 299;
const int HEIGHT = 299;
const int DEPTH = 3;
+const int EXPECTED_FIRST_RESULT_ID = 59;
+
+static void DumpTop10Results(
+ const std::vector<ISocControlWrapper::ByteArray>& outputs) {
+ CHECK(outputs.size() == 1);
+ const int byte_size = std::get<1>(outputs.at(0));
+ const int element_count = byte_size / sizeof(float);
+ const float* float_array =
+ reinterpret_cast<float*>(std::get<0>(outputs.at(0)));
+ const string label_filename =
+ "/data/local/tmp/imagenet_comp_graph_label_strings.txt";
+ string label_str;
+ TF_CHECK_OK(ReadFileToString(Env::Default(), label_filename, &label_str));
+ std::vector<string> labels = str_util::Split(label_str, '\n');
+ GraphTransferUtils::DumpTopNFloatResults(
+ float_array, labels.data(),
+ std::min(element_count, static_cast<int>(labels.size())),
+ 10 /* show top_n results */);
+}
+
+static void CheckFirstResult(
+ const std::vector<ISocControlWrapper::ByteArray>& outputs,
+ const int expected_first_id) {
+ EXPECT_GE(outputs.size(), 1);
+ const int byte_size = std::get<1>(outputs.at(0));
+ const int element_count = byte_size / sizeof(float);
+ const float* float_array =
+ reinterpret_cast<float*>(std::get<0>(outputs.at(0)));
+ EXPECT_GE(element_count, 1);
+ std::vector<string> labels(element_count);
+ std::priority_queue<std::tuple<float, int, string>> queue =
+ GraphTransferUtils::GetTopNFloatResults(float_array, labels.data(),
+ element_count);
+ const std::tuple<float, int, string>& entry = queue.top();
+ EXPECT_EQ(expected_first_id, std::get<1>(entry));
+}
// CAVEAT: This test only runs when you specify hexagon library using
// makefile.
@@ -77,12 +119,17 @@ TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
const int fsize = bmp.size();
LOG(INFO) << "Read " << image_filename << ", size = " << fsize << "bytes";
const int64 pixel_count = WIDTH * HEIGHT * DEPTH;
+ CHECK(fsize >= 22 /* pos of height */ + sizeof(int));
+ CHECK(bmp.data() != nullptr);
uint8* const img_bytes = bit_cast<uint8*>(bmp.data());
const int header_size = *(reinterpret_cast<int*>(img_bytes + 10));
+ LOG(INFO) << "header size = " << header_size;
const int size = *(reinterpret_cast<int*>(img_bytes + 14));
+ LOG(INFO) << "image size = " << size;
const int width = *(reinterpret_cast<int*>(img_bytes + 18));
+ LOG(INFO) << "width = " << width;
const int height = *(reinterpret_cast<int*>(img_bytes + 22));
- LOG(INFO) << header_size << ", " << size << ", " << width << ", " << height;
+ LOG(INFO) << "height = " << height;
CHECK(fsize >= (WIDTH + 1) * WIDTH * 3 + header_size);
uint8* const bmp_pixels = &img_bytes[header_size];
@@ -134,6 +181,8 @@ TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
// 5. Read output node's outputs
std::vector<ISocControlWrapper::ByteArray> outputs;
hexagon_control_wrapper.ReadOutputNode("softmax", &outputs);
+ DumpTop10Results(outputs);
+ CheckFirstResult(outputs, EXPECTED_FIRST_RESULT_ID);
// 6. Teardown graph in hexagon
hexagon_control_wrapper.TeardownGraph();