From 25a353f56bb3f03e659d04e7551f0763bdf2a2e6 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" <gardener@tensorflow.org> Date: Wed, 7 Dec 2016 14:48:37 -0800 Subject: [PATCH] Add sub makefile to execute inference on hexagon Change: 141360232 --- .../hexagon_graph_execution/Makefile.in | 74 +++++++++++++++++++ .../sub_makefiles/quantization/Makefile.in | 12 +-- .../core/kernels/hexagon/graph_transferer.cc | 22 ++++-- .../hexagon/hexagon_graph_execution_test.cc | 8 +- 4 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in diff --git a/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in new file mode 100644 index 00000000000..a4cf5f70cde --- /dev/null +++ b/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Copyright 2016 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. +# ============================================================================== +# This sub Makefile compiles libraries under this directory. This is designed to +# be used as a sub Makefile with tensorflow/contrib/makefile/Makefile. +# You can build targets in this file by including this sub makefile like: +# $ make -f tensorflow/contrib/makefile/Makefile TARGET=<target> \ +# SUB_MAKEFILES=\ +# $(pwd)/tensorflow/contrib/makefile/sub_makefiles/hexagon_graph_execution/Makefile.in \ +# (optional: NDK_ROOT=<ndk_root>) hexagon_graph_execution +# TODO(satok): Support more targets + +GTEST_DIR := \ +$(MAKEFILE_DIR)/downloads/googletest/googletest + +GTEST_HEADERS = \ +$(wildcard $(GTEST_DIR)/include/gtest/*.h) \ +$(wildcard $(GTEST_DIR)/include/gtest/internal/*.h) + +GTEST_SRCS := \ +$(wildcard $(GTEST_DIR)/src/*.cc) \ +$(wildcard $(GTEST_DIR)/src/*.h) \ +$(GTEST_HEADERS) + +# CAVEAT: We should disable TENSORFLOW_DISABLE_META while running +# quantized_matmul on Android because it crashes in +# MultiThreadGemm in tensorflow/core/kernels/meta_support.cc +# TODO(satok): Remove once it's fixed +CXXFLAGS += -DTENSORFLOW_DISABLE_META + +GRAPH_EXECUTION_SRCS := \ +tensorflow/core/kernels/hexagon/graph_transferer.cc \ +tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc \ +tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc \ +tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc \ +tensorflow/contrib/makefile/test/test_main.cc + +GRAPH_EXECUTION_OBJS := $(addprefix $(OBJDIR), $(GRAPH_EXECUTION_SRCS:.cc=.o)) + +GRAPH_EXECUTION_NAME := hexagon_graph_execution +GRAPH_EXECUTION_BIN_PATH := $(BINDIR)$(GRAPH_EXECUTION_NAME) + +INCLUDES += \ +-I$(MAKEFILE_DIR)/downloads/googletest/googletest/include + +GRAPH_EXECUTION_INCLUDES := $(INCLUDES) + +$(OBJDIR)gtest-all.o: $(GTEST_SRCS) $(GRAPH_EXECUTION_OBJS) + $(CXX) $(CXXFLAGS) $(GRAPH_EXECUTION_INCLUDES) -I $(GTEST_DIR) -c \ + $(GTEST_DIR)/src/gtest-all.cc -o $@ + +$(LIBDIR)gtest.a: $(OBJDIR)gtest-all.o + @mkdir -p $(dir $@) + $(AR) $(ARFLAGS) $@ $^ + +$(GRAPH_EXECUTION_BIN_PATH): $(LIB_PATH) $(LIBDIR)gtest.a $(GRAPH_EXECUTION_OBJS) + @mkdir -p $(dir $@) + $(CXX) $(CXXFLAGS) $(GRAPH_EXECUTION_INCLUDES) \ + -o $(GRAPH_EXECUTION_BIN_PATH) $(GRAPH_EXECUTION_OBJS) \ + $(LIBFLAGS) $(LIB_PATH) $(LIBDIR)gtest.a $(LDFLAGS) $(LIBS) + +$(GRAPH_EXECUTION_NAME): $(GRAPH_EXECUTION_BIN_PATH) diff --git a/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in b/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in index baf285268c0..ef419136638 100644 --- a/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in +++ b/tensorflow/contrib/makefile/sub_makefiles/quantization/Makefile.in @@ -34,12 +34,13 @@ $(wildcard $(GTEST_DIR)/src/*.cc) \ $(wildcard $(GTEST_DIR)/src/*.h) \ $(GTEST_HEADERS) +# CAVEAT: We should disable TENSORFLOW_DISABLE_META while running +# quantized_matmul on Android because it crashes in +# MultiThreadGemm in tensorflow/core/kernels/meta_support.cc +# TODO(satok): Remove once it's fixed +CXXFLAGS += -DTENSORFLOW_DISABLE_META + QUANTIZATION_TEST_SRCS := \ -tensorflow/core/ops/math_ops.cc \ -tensorflow/core/kernels/quantize_op.cc \ -tensorflow/core/kernels/quantized_conv_ops.cc \ -tensorflow/core/kernels/quantized_matmul_op.cc \ -tensorflow/core/kernels/quantized_matmul_op_test.cc \ tensorflow/core/kernels/hexagon/quantized_matmul_op_for_hexagon_test.cc \ tensorflow/contrib/makefile/test/test_main.cc @@ -59,6 +60,7 @@ $(OBJDIR)gtest-all.o: $(GTEST_SRCS) $(QUANTIZATION_TEST_OBJS) $(GTEST_DIR)/src/gtest-all.cc -o $@ $(LIBDIR)gtest.a: $(OBJDIR)gtest-all.o + @mkdir -p $(dir $@) $(AR) $(ARFLAGS) $@ $^ $(QUANTIZATION_TEST_BIN_PATH): $(LIB_PATH) $(LIBDIR)gtest.a $(QUANTIZATION_TEST_OBJS) diff --git a/tensorflow/core/kernels/hexagon/graph_transferer.cc b/tensorflow/core/kernels/hexagon/graph_transferer.cc index 352c2c63f0d..700521618c4 100644 --- a/tensorflow/core/kernels/hexagon/graph_transferer.cc +++ b/tensorflow/core/kernels/hexagon/graph_transferer.cc @@ -48,6 +48,15 @@ const string PADDING_SAME_STR = "SAME"; const string PADDING_NA = "NA"; const string NULL_OUTPUT_NAME = "NULL"; +// This is a temporary workaround to support android build +// where std::string is not supported even with c++11 option. +template <typename T> +static string ToString(T val) { + std::stringstream stream; + stream << val; + return stream.str(); +} + /** * graph loading functions * - LoadGraphFromProto @@ -363,7 +372,7 @@ void GraphTransferer::RegisterConstantNode( VLOG(1) << "Register constant node: " << node.name(); CHECK(node_name_to_id_cache_map_.count(node.name()) == 1); const int id = node_name_to_id_cache_map_[node.name()]; - const string data_name = DATA_NODE_PREFIX + std::to_string(id); + const string data_name = DATA_NODE_PREFIX + ToString(id); const int output_node_size = node.num_outputs(); CHECK(output_node_size == 1); // TODO(satok): support multiple outputs? @@ -404,10 +413,9 @@ int GraphTransferer::RegisterConstantShape(const std::vector<int>& shape) { VLOG(1) << "Cache constant shape."; // TODO(satok): Handle non-4dim strides CHECK(shape.size() == 4); - const string shape_name = CONST_SHAPE_PREFIX + std::to_string(shape.at(0)) + - 'x' + std::to_string(shape.at(1)) + 'x' + - std::to_string(shape.at(2)) + 'x' + - std::to_string(shape.at(3)); + const string shape_name = CONST_SHAPE_PREFIX + ToString(shape.at(0)) + 'x' + + ToString(shape.at(1)) + 'x' + + ToString(shape.at(2)) + 'x' + ToString(shape.at(3)); if (node_name_to_id_cache_map_.count(shape_name) <= 0) { node_name_cache_list_.emplace_back(nullptr); const int id = node_name_cache_list_.size() - 1; @@ -589,10 +597,10 @@ void GraphTransferer::AppendNodeParams(const string& name, const int id, const int outputs_size) { VLOG(1) << "Append node params: " << name; // TODO(satok): store padding as Padding? - const string output_name = OUTPUTS_NODE_PREFIX + std::to_string(id); + const string output_name = OUTPUTS_NODE_PREFIX + ToString(id); node_transfer_params_list_.emplace_back( NodeTransferParams{name, id, type, type_id, PADDING_PREFIX + padding_str, - INPUTS_NODE_PREFIX + std::to_string(id), + INPUTS_NODE_PREFIX + ToString(id), inputs_size + static_cast<int>(extra_inputs.size()), outputs_size <= 0 ? NULL_OUTPUT_NAME : output_name, static_cast<int>(outputs_size)}); diff --git a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc index 02733bf1b15..2444b93850c 100644 --- a/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc +++ b/tensorflow/core/kernels/hexagon/hexagon_graph_execution_test.cc @@ -12,6 +12,9 @@ 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. ==============================================================================*/ +// Before calling this test program, download a model as follows. +// $ curl https://storage.googleapis.com/download.tensorflow.org/models/tensorflow_inception_v3_stripped_optimized_quantized.pb \ +// -o /tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb #include <memory> @@ -26,9 +29,12 @@ limitations under the License. namespace tensorflow { +// CAVEAT: This test only runs when you specify hexagon library using +// makefile. +// TODO(satok): Make this generic so that this can run without any +// additionanl steps. #ifdef USE_HEXAGON_LIBS TEST(GraphTransferer, RunInceptionV3OnHexagonExample) { - // Change file path to absolute path of model file on your local machine const string filename = "/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb"; const IGraphTransferOpsDefinitions* ops_definitions =