Portability improvements.
Change: 132490206
This commit is contained in:
parent
7705791619
commit
ed87884e50
@ -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).
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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"]) +
|
||||
|
Loading…
Reference in New Issue
Block a user