Add sub makefile to execute inference on hexagon

Change: 141360232
This commit is contained in:
A. Unique TensorFlower 2016-12-07 14:48:37 -08:00 committed by TensorFlower Gardener
parent 0c7006f56b
commit 25a353f56b
4 changed files with 103 additions and 13 deletions

View File

@ -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)

View File

@ -34,12 +34,13 @@ $(wildcard $(GTEST_DIR)/src/*.cc) \
$(wildcard $(GTEST_DIR)/src/*.h) \ $(wildcard $(GTEST_DIR)/src/*.h) \
$(GTEST_HEADERS) $(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 := \ 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/core/kernels/hexagon/quantized_matmul_op_for_hexagon_test.cc \
tensorflow/contrib/makefile/test/test_main.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 $@ $(GTEST_DIR)/src/gtest-all.cc -o $@
$(LIBDIR)gtest.a: $(OBJDIR)gtest-all.o $(LIBDIR)gtest.a: $(OBJDIR)gtest-all.o
@mkdir -p $(dir $@)
$(AR) $(ARFLAGS) $@ $^ $(AR) $(ARFLAGS) $@ $^
$(QUANTIZATION_TEST_BIN_PATH): $(LIB_PATH) $(LIBDIR)gtest.a $(QUANTIZATION_TEST_OBJS) $(QUANTIZATION_TEST_BIN_PATH): $(LIB_PATH) $(LIBDIR)gtest.a $(QUANTIZATION_TEST_OBJS)

View File

@ -48,6 +48,15 @@ const string PADDING_SAME_STR = "SAME";
const string PADDING_NA = "NA"; const string PADDING_NA = "NA";
const string NULL_OUTPUT_NAME = "NULL"; 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 * graph loading functions
* - LoadGraphFromProto * - LoadGraphFromProto
@ -363,7 +372,7 @@ void GraphTransferer::RegisterConstantNode(
VLOG(1) << "Register constant node: " << node.name(); VLOG(1) << "Register constant node: " << node.name();
CHECK(node_name_to_id_cache_map_.count(node.name()) == 1); CHECK(node_name_to_id_cache_map_.count(node.name()) == 1);
const int id = node_name_to_id_cache_map_[node.name()]; 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(); const int output_node_size = node.num_outputs();
CHECK(output_node_size == 1); CHECK(output_node_size == 1);
// TODO(satok): support multiple outputs? // TODO(satok): support multiple outputs?
@ -404,10 +413,9 @@ int GraphTransferer::RegisterConstantShape(const std::vector<int>& shape) {
VLOG(1) << "Cache constant shape."; VLOG(1) << "Cache constant shape.";
// TODO(satok): Handle non-4dim strides // TODO(satok): Handle non-4dim strides
CHECK(shape.size() == 4); CHECK(shape.size() == 4);
const string shape_name = CONST_SHAPE_PREFIX + std::to_string(shape.at(0)) + const string shape_name = CONST_SHAPE_PREFIX + ToString(shape.at(0)) + 'x' +
'x' + std::to_string(shape.at(1)) + 'x' + ToString(shape.at(1)) + 'x' +
std::to_string(shape.at(2)) + 'x' + ToString(shape.at(2)) + 'x' + ToString(shape.at(3));
std::to_string(shape.at(3));
if (node_name_to_id_cache_map_.count(shape_name) <= 0) { if (node_name_to_id_cache_map_.count(shape_name) <= 0) {
node_name_cache_list_.emplace_back(nullptr); node_name_cache_list_.emplace_back(nullptr);
const int id = node_name_cache_list_.size() - 1; 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) { const int outputs_size) {
VLOG(1) << "Append node params: " << name; VLOG(1) << "Append node params: " << name;
// TODO(satok): store padding as Padding? // 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( node_transfer_params_list_.emplace_back(
NodeTransferParams{name, id, type, type_id, PADDING_PREFIX + padding_str, 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()), inputs_size + static_cast<int>(extra_inputs.size()),
outputs_size <= 0 ? NULL_OUTPUT_NAME : output_name, outputs_size <= 0 ? NULL_OUTPUT_NAME : output_name,
static_cast<int>(outputs_size)}); static_cast<int>(outputs_size)});

View File

@ -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 See the License for the specific language governing permissions and
limitations under the License. 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> #include <memory>
@ -26,9 +29,12 @@ limitations under the License.
namespace tensorflow { 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 #ifdef USE_HEXAGON_LIBS
TEST(GraphTransferer, RunInceptionV3OnHexagonExample) { TEST(GraphTransferer, RunInceptionV3OnHexagonExample) {
// Change file path to absolute path of model file on your local machine
const string filename = const string filename =
"/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb"; "/tmp/tensorflow_inception_v3_stripped_optimized_quantized.pb";
const IGraphTransferOpsDefinitions* ops_definitions = const IGraphTransferOpsDefinitions* ops_definitions =