Portability improvements.

Change: 132490206
This commit is contained in:
A. Unique TensorFlower 2016-09-07 14:49:06 -08:00 committed by TensorFlower Gardener
parent 7705791619
commit ed87884e50
10 changed files with 214 additions and 66 deletions

View File

@ -11,6 +11,14 @@ licenses(["notice"]) # Apache 2.0
exports_files(["LICENSE"])
load(
"//tensorflow:tensorflow.bzl",
"if_android",
"if_ios",
"if_mobile",
"if_not_mobile",
)
filegroup(
name = "all_files",
srcs = glob(
@ -100,15 +108,24 @@ cc_library(
name = "session_bundle",
srcs = ["session_bundle.cc"],
hdrs = ["session_bundle.h"],
copts = if_ios(["-DGOOGLE_LOGGING"]),
visibility = ["//visibility:public"],
deps = [
":manifest_proto_cc",
":signature",
] + if_not_mobile([
":manifest_proto_cc",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:tensorflow_opensource",
],
]) + if_mobile([
":manifest_portable_proto",
"//tensorflow/core:meta_graph_portable_proto",
]) + if_android([
"//tensorflow/core:android_lib_lite",
]) + if_ios([
"//tensorflow/core:ios_tensorflow_lib",
]),
)
# This is a lite version of the session_bundle target that does not link in any
@ -118,15 +135,24 @@ cc_library(
name = "session_bundle_lite",
srcs = ["session_bundle.cc"],
hdrs = ["session_bundle.h"],
copts = if_ios(["-DGOOGLE_LOGGING"]),
visibility = ["//visibility:public"],
deps = [
":manifest_proto_cc",
":signature_lite",
] + if_not_mobile([
":manifest_proto_cc",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
],
]) + if_mobile([
":manifest_portable_proto",
"//tensorflow/core:meta_graph_portable_proto",
]) + if_android([
"//tensorflow/core:android_lib_lite",
]) + if_ios([
"//tensorflow/core:ios_tensorflow_lib",
]),
)
cc_test(
@ -188,13 +214,21 @@ cc_library(
name = "signature",
srcs = ["signature.cc"],
hdrs = ["signature.h"],
deps = [
visibility = ["//visibility:public"],
deps = if_not_mobile([
":manifest_proto_cc",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:lib",
"//tensorflow/core:tensorflow_opensource",
],
]) + if_mobile([
":manifest_portable_proto",
"//tensorflow/core:meta_graph_portable_proto",
]) + if_android([
"//tensorflow/core:android_lib_lite",
]) + if_ios([
"//tensorflow/core:ios_tensorflow_lib",
]),
)
# This is a lite version of the signature target that does not link in any
@ -205,12 +239,19 @@ cc_library(
srcs = ["signature.cc"],
hdrs = ["signature.h"],
visibility = ["//visibility:public"],
deps = [
deps = if_not_mobile([
":manifest_proto_cc",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:lib",
],
]) + if_mobile([
":manifest_portable_proto",
"//tensorflow/core:meta_graph_portable_proto",
]) + if_android([
"//tensorflow/core:android_lib_lite",
]) + if_ios([
"//tensorflow/core:ios_tensorflow_lib",
]),
)
cc_test(
@ -254,3 +295,6 @@ tf_proto_library(
cc_api_version = 2,
visibility = ["//visibility:public"],
)
# -----------------------------------------------------------------------------
# Google-internal targets go here (must be at the end).

View File

@ -140,7 +140,7 @@ Status LoadSessionBundleFromPathUsingRunOptions(const SessionOptions& options,
const StringPiece export_dir,
SessionBundle* const bundle) {
LOG(INFO) << "Attempting to load a SessionBundle from: " << export_dir;
LOG(INFO) << "Using RunOptions: " << run_options.DebugString();
LOG(INFO) << "Using RunOptions: " << DebugStringIfAvailable(run_options);
const int64 start_seconds = Env::Default()->NowSeconds();
TF_RETURN_IF_ERROR(
GetMetaGraphDefFromExport(export_dir, &(bundle->meta_graph_def)));
@ -153,20 +153,11 @@ Status LoadSessionBundleFromPathUsingRunOptions(const SessionOptions& options,
if (graph_collection_def.any_list().value_size() != 1) {
return errors::FailedPrecondition(
"Expected exactly one serving GraphDef in : ",
bundle->meta_graph_def.DebugString());
DebugStringIfAvailable(bundle->meta_graph_def));
}
const auto& any = graph_collection_def.any_list().value(0);
if (!any.Is<GraphDef>()) {
return errors::FailedPrecondition(
"Expected Any type_url for: ",
GraphDef::default_instance().descriptor()->full_name(), ". Got: ",
string(any.type_url().data(), any.type_url().size()), ".");
}
GraphDef graph_def;
if (!any.UnpackTo(&graph_def)) {
return errors::FailedPrecondition("Failed to unpack: ",
any.DebugString());
}
TF_RETURN_IF_ERROR(ParseAny(any, &graph_def, "tensorflow.GraphDef"));
TF_RETURN_IF_ERROR(
CreateSessionFromGraphDef(options, graph_def, &bundle->session));
} else {
@ -182,17 +173,8 @@ Status LoadSessionBundleFromPathUsingRunOptions(const SessionOptions& options,
const auto& any_assets = assets_it->second.any_list().value();
for (const auto& any_asset : any_assets) {
AssetFile asset_file;
if (!any_asset.Is<AssetFile>()) {
return errors::FailedPrecondition(
"Expected asset Any type_url for: ",
asset_file.descriptor()->full_name(), ". Got: ",
string(any_asset.type_url().data(), any_asset.type_url().size()),
".");
}
if (!any_asset.UnpackTo(&asset_file)) {
return errors::FailedPrecondition("Failed to unpack: ",
any_asset.DebugString());
}
TF_RETURN_IF_ERROR(
ParseAny(any_asset, &asset_file, "tensorflow.serving.AssetFile"));
asset_files.push_back(asset_file);
}
}
@ -208,7 +190,7 @@ Status LoadSessionBundleFromPathUsingRunOptions(const SessionOptions& options,
if (init_op_it->second.node_list().value_size() != 1) {
return errors::FailedPrecondition(
strings::StrCat("Expected exactly one serving init op in : ",
bundle->meta_graph_def.DebugString()));
DebugStringIfAvailable(bundle->meta_graph_def)));
}
TF_RETURN_IF_ERROR(RunInitOp(run_options, export_dir, asset_files,
init_op_it->second.node_list().value(0),

View File

@ -295,8 +295,7 @@ TEST_F(SessionBundleTest, AssetFileAny_IncorrectType) {
EXPECT_FALSE(status_.ok());
EXPECT_TRUE(
StringPiece(status_.error_message())
.contains(
"Expected asset Any type_url for: tensorflow.serving.AssetFile"))
.contains("Expected Any type_url for: tensorflow.serving.AssetFile"))
<< status_.error_message();
}

View File

@ -53,19 +53,10 @@ Status GetSignatures(const tensorflow::MetaGraphDef& meta_graph_def,
if (it == collection_def.end() || it->second.any_list().value_size() != 1) {
return errors::FailedPrecondition(
strings::StrCat("Expected exactly one signatures proto in : ",
meta_graph_def.DebugString()));
DebugStringIfAvailable(meta_graph_def)));
}
const auto& any = it->second.any_list().value(0);
if (!any.Is<Signatures>()) {
return errors::FailedPrecondition(
"Expected signature Any type_url for: ",
signatures->descriptor()->full_name(), ". Got: ",
string(any.type_url().data(), any.type_url().size()), ".");
}
if (!any.UnpackTo(signatures)) {
return errors::FailedPrecondition("Failed to unpack: ", any.DebugString());
}
return Status::OK();
return ParseAny(any, signatures, "tensorflow.serving.Signatures");
}
Status SetSignatures(const Signatures& signatures,
@ -73,7 +64,12 @@ Status SetSignatures(const Signatures& signatures,
auto& collection_def = *(meta_graph_def->mutable_collection_def());
auto* any_list = collection_def[kSignaturesKey].mutable_any_list();
any_list->mutable_value()->Clear();
#ifdef TENSORFLOW_LITE_PROTOS
signatures.SerializeToString(
any_list->mutable_value()->Add()->mutable_value());
#else
any_list->mutable_value()->Add()->PackFrom(signatures);
#endif
return Status::OK();
}
@ -83,13 +79,14 @@ Status GetClassificationSignature(
Signatures signatures;
TF_RETURN_IF_ERROR(GetSignatures(meta_graph_def, &signatures));
if (!signatures.has_default_signature()) {
return errors::FailedPrecondition(strings::StrCat(
"Expected a default signature in: ", signatures.DebugString()));
return errors::FailedPrecondition(
strings::StrCat("Expected a default signature in: ",
DebugStringIfAvailable(signatures)));
}
if (!signatures.default_signature().has_classification_signature()) {
return errors::FailedPrecondition(
strings::StrCat("Expected a classification signature in: ",
signatures.default_signature().DebugString()));
return errors::FailedPrecondition(strings::StrCat(
"Expected a classification signature in: ",
DebugStringIfAvailable(signatures.default_signature())));
}
*signature = signatures.default_signature().classification_signature();
return Status::OK();
@ -102,14 +99,14 @@ Status GetNamedClassificationSignature(
TF_RETURN_IF_ERROR(GetSignatures(meta_graph_def, &signatures));
const auto& it = signatures.named_signatures().find(name);
if (it == signatures.named_signatures().end()) {
return errors::NotFound(strings::StrCat("Missing signature named \"", name,
"\" in: ",
signatures.DebugString()));
return errors::NotFound(
strings::StrCat("Missing signature named \"", name, "\" in: ",
DebugStringIfAvailable(signatures)));
}
if (!it->second.has_classification_signature()) {
return errors::FailedPrecondition(
strings::StrCat("Expected a classification signature for name \"", name,
"\" in: ", it->second.DebugString()));
"\" in: ", DebugStringIfAvailable(it->second)));
}
*signature = it->second.classification_signature();
return Status::OK();
@ -157,13 +154,14 @@ Status GetRegressionSignature(const tensorflow::MetaGraphDef& meta_graph_def,
Signatures signatures;
TF_RETURN_IF_ERROR(GetSignatures(meta_graph_def, &signatures));
if (!signatures.has_default_signature()) {
return errors::FailedPrecondition(strings::StrCat(
"Expected a default signature in: ", signatures.DebugString()));
return errors::FailedPrecondition(
strings::StrCat("Expected a default signature in: ",
DebugStringIfAvailable(signatures)));
}
if (!signatures.default_signature().has_regression_signature()) {
return errors::FailedPrecondition(
strings::StrCat("Expected a regression signature in: ",
signatures.default_signature().DebugString()));
return errors::FailedPrecondition(strings::StrCat(
"Expected a regression signature in: ",
DebugStringIfAvailable(signatures.default_signature())));
}
*signature = signatures.default_signature().regression_signature();
return Status::OK();
@ -208,11 +206,11 @@ Status GetGenericSignature(const string& name,
if (it == signatures.named_signatures().end()) {
return errors::InvalidArgument(
strings::StrCat("Missing generic signature named \"", name, "\" in ",
signatures.DebugString()));
DebugStringIfAvailable(signatures)));
}
if (!it->second.has_generic_signature()) {
return errors::InvalidArgument(strings::StrCat(
"Expected a generic signature: ", it->second.DebugString()));
"Expected a generic signature: ", DebugStringIfAvailable(it->second)));
}
*signature = it->second.generic_signature();
return Status::OK();
@ -233,9 +231,9 @@ Status GetNamedSignature(const string& name,
TF_RETURN_IF_ERROR(GetSignatures(meta_graph_def, &signatures));
const auto& it = signatures.named_signatures().find(name);
if (it == signatures.named_signatures().end()) {
return errors::NotFound(strings::StrCat("Missing signature named \"", name,
"\" in: ",
signatures.DebugString()));
return errors::NotFound(
strings::StrCat("Missing signature named \"", name, "\" in: ",
DebugStringIfAvailable(signatures)));
}
*signature = it->second;
return Status::OK();

View File

@ -117,6 +117,7 @@ Status BindGenericInputs(const GenericSignature& signature,
Status BindGenericNames(const GenericSignature& signature,
const std::vector<string>& input_names,
std::vector<string>* bound_names);
} // namespace serving
} // namespace tensorflow

View File

@ -499,7 +499,7 @@ TEST(GetSignatures, WrongProtoInAny) {
const auto status = GetSignatures(meta_graph_def, &read_signatures);
EXPECT_FALSE(status.ok());
EXPECT_TRUE(StringPiece(status.error_message())
.contains("Expected signature Any type_url for: "
.contains("Expected Any type_url for: "
"tensorflow.serving.Signatures"))
<< status.error_message();
}

View File

@ -116,6 +116,11 @@ cc_library(
name = "lib_proto_parsing",
srcs = glob(tf_additional_proto_srcs()),
hdrs = [
"lib/core/errors.h",
"lib/core/status.h",
"lib/core/stringpiece.h",
"lib/strings/numbers.h",
"lib/strings/strcat.h",
"platform/init_main.h",
"platform/logging.h",
"platform/macros.h",
@ -124,6 +129,7 @@ cc_library(
"platform/types.h",
],
deps = [
":protos_all_cc",
"//tensorflow/core/platform/default/build_config:proto_parsing",
],
)
@ -680,6 +686,25 @@ cc_library(
alwayslink = 1,
)
cc_library(
name = "ios_tensorflow_test_lib",
testonly = 1,
srcs = if_ios([":android_test_srcs"]),
copts = tf_copts() + ["-Os"],
tags = [
"manual",
"notap",
],
visibility = ["//visibility:public"],
deps = [
":android_test_proto_lib",
":ios_tensorflow_lib",
"//base",
"//tensorflow/core/platform/default/build_config:gtest",
"//third_party/eigen3",
],
)
# Full TensorFlow library with operator support. Use this unless reducing
# binary size (by packaging a reduced operator set) is a concern.
cc_library(
@ -759,6 +784,21 @@ filegroup(
visibility = ["//visibility:public"],
)
# This is like android_test_srcs, minus the things that are already in android_srcs.
filegroup(
name = "android_test_srcs_no_core",
srcs = [
"//tensorflow/core:framework/shape_inference_testutil.cc",
"//tensorflow/core:framework/shape_inference_testutil.h",
"//tensorflow/core:framework/tensor_testutil.cc",
"//tensorflow/core:framework/tensor_testutil.h",
"//tensorflow/core:platform/test.h",
"//tensorflow/core:util/reporter.cc",
"//tensorflow/core:util/reporter.h",
],
visibility = ["//visibility:public"],
)
# Portable library providing testing functionality for TensorFlow.
cc_library(
name = "android_tensorflow_test_lib",

View File

@ -20,6 +20,7 @@ load(
"tf_cc_test",
"tf_cc_tests",
"tf_copts",
"tf_opts_nortti_if_android",
"tf_kernel_libraries",
"tf_kernel_library",
"cc_header_only_library",
@ -2167,6 +2168,30 @@ cc_library(
alwayslink = 1,
)
cc_library(
name = "android_tensorflow_kernels_no_rtti_lite_runtime",
srcs = select({
"//tensorflow:android": [
"//tensorflow/core/kernels:android_core_ops",
"//tensorflow/core/kernels:android_extended_ops",
],
"//conditions:default": [],
}),
copts = tf_copts() + tf_opts_nortti_if_android(),
tags = [
"manual",
"notap",
],
visibility = ["//visibility:public"],
deps = [
"//base",
"//tensorflow/core:android_proto_lib_no_rtti_lite_runtime",
"//tensorflow/core:android_tensorflow_lib_lite_no_rtti_lite_runtime",
"//third_party/eigen3",
],
alwayslink = 1,
)
# -----------------------------------------------------------------------------
# Google-internal targets. These must be at the end for syncrepo.

View File

@ -16,6 +16,8 @@ limitations under the License.
#ifndef TENSORFLOW_PLATFORM_PROTOBUF_H_
#define TENSORFLOW_PLATFORM_PROTOBUF_H_
#include "google/protobuf/any.pb.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/platform/platform.h"
#include "tensorflow/core/platform/types.h"
@ -50,6 +52,49 @@ inline void SetProtobufStringSwapAllowed(string* src, string* dest) {
dest->swap(*src);
}
// Returns the DebugString when available, or a stub message otherwise. Useful
// for messages that are incompatible with proto_text (e.g. those using Any).
#ifdef TENSORFLOW_LITE_PROTOS
template <class T>
string DebugStringIfAvailable(T proto) {
return "[DebugString not available with lite protos]";
}
#else
template <class T>
auto DebugStringIfAvailable(T proto) -> decltype(proto.DebugString()) {
return proto.DebugString();
}
#endif // defined(TENSORFLOW_LITE_PROTOS)
// Utility for parsing an Any value with full or lite protos.
template <class T>
Status ParseAny(const google::protobuf::Any& any, T* message,
const string& type_name) {
#ifdef TENSORFLOW_LITE_PROTOS
if (any.type_url() != strings::StrCat("type.googleapis.com/", type_name)) {
return errors::FailedPrecondition(
"Expected Any type_url for: ", type_name, ". Got: ",
string(any.type_url().data(), any.type_url().size()), ".");
}
if (!message->ParseFromString(any.value())) {
return errors::FailedPrecondition("Failed to unpack: ",
DebugStringIfAvailable(any));
}
#else
CHECK_EQ(type_name, message->descriptor()->full_name());
if (!any.Is<T>()) {
return errors::FailedPrecondition(
"Expected Any type_url for: ", message->descriptor()->full_name(),
". Got: ", string(any.type_url().data(), any.type_url().size()), ".");
}
if (!any.UnpackTo(message)) {
return errors::FailedPrecondition("Failed to unpack: ",
DebugStringIfAvailable(any));
}
#endif
return Status::OK();
}
} // namespace tensorflow
#endif // TENSORFLOW_PLATFORM_PROTOBUF_H_

View File

@ -114,6 +114,20 @@ def if_ios(a):
"//conditions:default": [],
})
def if_mobile(a):
return select({
"//tensorflow:android": a,
"//tensorflow:ios": a,
"//conditions:default": [],
})
def if_not_mobile(a):
return select({
"//tensorflow:android": [],
"//tensorflow:ios": [],
"//conditions:default": a,
})
def tf_copts():
return (["-fno-exceptions", "-DEIGEN_AVOID_STL_ARRAY"] +
if_cuda(["-DGOOGLE_CUDA=1"]) +