diff options
author | A. Unique TensorFlower <gardener@tensorflow.org> | 2017-01-17 16:27:46 -0800 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2017-01-17 16:46:56 -0800 |
commit | fecad67e9b92abb45466f46c91c75771164a6b67 (patch) | |
tree | ec884af8d193d049679d07522790f7552f0f1267 /tensorflow | |
parent | fb7f551fecfa99f6683c73e7ad1cfa5bcf0fc164 (diff) |
Show labels of ranking results of inception inference on HVX
Change: 144771220
Diffstat (limited to 'tensorflow')
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(); |