diff --git a/.gitignore b/.gitignore
index 5afe375f46f07b3b557ae23f75740b337517d3bd..1ef4c297ee4f369775c13b32a46a55887de719e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ __pycache__
*.swp
.vscode/
cmake_build/
+tensorflow/contrib/cmake/_build/
.idea/**
/build/
[Bb]uild/
@@ -30,6 +31,7 @@ Podfile.lock
xcuserdata/**
/api_init_files_list.txt
/estimator_api_init_files_list.txt
+*.whl
# Android
.gradle
diff --git a/CODEOWNERS b/CODEOWNERS
index b9f0313cc6d59d3fbdcd014e1a528126d863075a..78f80c8d718983f00fd5010c3fe5d561124d3714 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,53 +1,64 @@
-# NOTE: Disabled temporarily because it's too noisy on pushes.
# Where component owners are known, add them here.
-# /tensorflow/core/platform/windows/ @mrry
-# /tensorflow/java/ @asimshankar
-# /tensorflow/tensorboard/ @jart @dandelionmane
-# /tensorflow/tools/docs/ @markdaoust
+/tenosrflow/core/debug @caisq
+/tensorflow/core/platform/windows/ @mrry
+/tensorflow/go @asimshankar
+/tensorflow/java/ @asimshankar
+/tensorflow/python/debug @caisq
+/tensorflow/python/tools/api/generator/ @annarev
+/tensorflow/tensorboard/ @jart
+/tensorflow/tools/docs/ @markdaoust
# contrib
-# NEED OWNER: /tensorflow/contrib/avro/
-# /tensorflow/contrib/batching/ @alextp @chrisolston
-# /tensorflow/contrib/bayesflow/ @ebrevdo @rsepassi @jvdillon
-# /tensorflow/contrib/boosted_trees/ @sshrdp @yk5 @nataliaponomareva
-# /tensorflow/contrib/cmake/ @mrry @benoitsteiner
-# /tensorflow/contrib/copy_graph/ @tucker @poxvoculi
-# /tensorflow/contrib/crf/ @kentonl
-# /tensorflow/contrib/data/ @mrry
-# /tensorflow/contrib/distributions/ @jvdillon @langmore @rsepassi
-# /tensorflow/contrib/factorization/ @agarwal-ashish @xavigonzalvo
-# /tensorflow/contrib/ffmpeg/ @fredbertsch
-# NEED OWNER: /tensorflow/contrib/framework/
-# /tensorflow/contrib/graph_editor/ @purpledog
+# NEED OWNER: /tensorflow/contrib/all_reduce
+/tensorflow/contrib/batching/ @alextp @chrisolston
+/tensorflow/contrib/bayesflow/ @ebrevdo @rsepassi @jvdillon
+/tensorflow/contrib/boosted_trees/ @sshrdp @yk5 @nataliaponomareva
+/tensorflow/contrib/checkpoint/ @allenlavoie
+/tensorflow/contrib/contrib/cluster_resolver/ @frankchn
+/tensorflow/contrib/cmake/ @mrry
+/tensorflow/contrib/copy_graph/ @tucker @poxvoculi
+/tensorflow/contrib/crf/ @kentonl
+/tensorflow/contrib/data/ @mrry
+/tensorflow/tensorflow/contrib/distribute @joshl @priyag @sourabhbajaj @frankchn
+/tensorflow/contrib/distributions/ @jvdillon @langmore @rsepassi
+/tensorflow/contrib/eager @alextp @asimshankar
+/tensorflow/contrib/factorization/ @agarwal-ashish @xavigonzalvo
+/tensorflow/contrib/ffmpeg/ @fredbertsch
+/tensorflow/contrib/framework/ @ebrevdo
+/tensorflow/contrib/gan/ @joel-shor
+/tensorflow/contrib/graph_editor/ @purpledog
# NEED OWNER: /tensorflow/contrib/grid_rnn/
-# /tensorflow/contrib/hvx/ @satok16
-# /tensorflow/contrib/integrate/ @shoyer
-# /tensorflow/contrib/kernel_methods/ @petrosmol
-# /tensorflow/contrib/ios_examples/ @petewarden
-# /tensorflow/contrib/labeled_tensor/ @shoyer
-# /tensorflow/contrib/layers/ @fchollet @martinwicke
-# /tensorflow/contrib/learn/ @martinwicke @ispirmustafa @alextp
-# /tensorflow/contrib/linalg/ @langmore
-# /tensorflow/contrib/linear_optimizer/ @petrosmol @andreasst @katsiapis
-# /tensorflow/contrib/lookup/ @ysuematsu @andreasst
-# /tensorflow/contrib/losses/ @alextp @ispirmustafa
-# /tensorflow/contrib/makefile/ @petewarden @satok16 @wolffg
-# /tensorflow/contrib/metrics/ @alextp @honkentuber @ispirmustafa
-# /tensorflow/contrib/nccl/ @cwhipkey @zheng-xq
-# /tensorflow/contrib/opt/ @strategist333
-# /tensorflow/contrib/pi_examples/ @maciekcc
-# /tensorflow/contrib/quantization/ @petewarden @cwhipkey @keveman
-# /tensorflow/contrib/rnn/ @ebrevdo
-# /tensorflow/contrib/saved_model/ @nfiedel @sukritiramesh
-# /tensorflow/contrib/seq2seq/ @lukaszkaiser
-# /tensorflow/contrib/session_bundle/ @nfiedel @sukritiramesh
-# /tensorflow/contrib/slim/ @sguada @thenbasilmanran
-# /tensorflow/contrib/stateless/ @girving
-# /tensorflow/contrib/tensor_forest/ @gilberthendry @thomascolthurst @yupbank
-# /tensorflow/contrib/testing/ @dandelionmane
-# /tensorflow/contrib/timeseries/ @allenlavoie
-# /tensorflow/contrib/tpu/ @frankchn @saeta @jhseu
-# /tensorflow/contrib/training/ @joel-shor @ebrevdo
-# /tensorflow/contrib/util/ @sherrym
+/tensorflow/contrib/hvx/ @satok16
+/tensorflow/contrib/integrate/ @shoyer
+/tensorflow/contrib/kernel_methods/ @petrosmol
+/tensorflow/contrib/ios_examples/ @petewarden
+/tensorflow/contrib/labeled_tensor/ @shoyer
+/tensorflow/contrib/layers/ @fchollet @martinwicke
+/tensorflow/contrib/learn/ @martinwicke @ispirmustafa @alextp
+/tensorflow/contrib/linalg/ @langmore
+/tensorflow/contrib/linear_optimizer/ @petrosmol @andreasst @katsiapis
+/tensorflow/contrib/lookup/ @ysuematsu @andreasst
+/tensorflow/contrib/losses/ @alextp @ispirmustafa
+/tensorflow/contrib/makefile/ @petewarden @satok16 @wolffg
+/tensorflow/contrib/metrics/ @alextp @honkentuber @ispirmustafa
+/tensorflow/contrib/nccl/ @cwhipkey @zheng-xq
+/tensorflow/contrib/opt/ @strategist333 @alextp
+/tensorflow/contrib/pi_examples/ @maciekcc
+/tensorflow/contrib/quantization/ @petewarden
+/tensorflow/contrib/rnn/ @ebrevdo @scottzhu
+/tensorflow/contrib/saved_model/ @nfiedel @sukritiramesh @allenl
+/tensorflow/contrib/seq2seq/ @ebrevdo @lmthang
+/tensorflow/contrib/session_bundle/ @nfiedel @sukritiramesh
+/tensorflow/contrib/slim/ @sguada @thenbasilmanran
+/tensorflow/contrib/stateless/ @girving @alextp
+/tensorflow/contrib/tensor_forest/ @gilberthendry @thomascolthurst @yupbank
+/tensorflow/contrib/tensorrt/ @aaroey
+# NEED OWNER: /tensorflow/contrib/testing/
+/tensorflow/contrib/timeseries/ @allenlavoie
+/tensorflow/contrib/tpu/ @frankchn @saeta @jhseu @sourabhbajaj
+/tensorflow/contrib/training/ @joel-shor @ebrevdo
+/tensorflow/contrib/util/ @sherrym
+
+/third_party/systemlibs/ @perfinion
diff --git a/README.md b/README.md
index 16d354ca7b150814f11fd825d6a22c84cebc2a01..e3092e551e32d7f01e9bebd65323d1b5691f0269 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,8 @@ The TensorFlow project strives to abide by generally accepted best practices in
| **Windows CPU** | [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/windows-cpu.html) | [pypi](https://pypi.org/project/tf-nightly/) |
| **Windows GPU** | [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/windows-gpu.html) | [pypi](https://pypi.org/project/tf-nightly-gpu/) |
| **Android** | [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/android.html) | [](https://bintray.com/google/tensorflow/tensorflow/_latestVersion) |
+| **Raspberry Pi 0 and 1** | [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/rpi01-py2.html) [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/rpi01-py3.html) | [Py2](https://storage.googleapis.com/tensorflow-nightly/tensorflow-1.10.0-cp27-none-linux_armv6l.whl) [Py3](https://storage.googleapis.com/tensorflow-nightly/tensorflow-1.10.0-cp34-none-linux_armv6l.whl) |
+| **Raspberry Pi 2 and 3** | [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/rpi23-py2.html) [](https://storage.googleapis.com/tensorflow-kokoro-build-badges/rpi23-py3.html) | [Py2](https://storage.googleapis.com/tensorflow-nightly/tensorflow-1.10.0-cp27-none-linux_armv7l.whl) [Py3](https://storage.googleapis.com/tensorflow-nightly/tensorflow-1.10.0-cp34-none-linux_armv7l.whl) |
### Community Supported Builds
@@ -100,16 +102,16 @@ The TensorFlow project strives to abide by generally accepted best practices in
| **IBM ppc64le CPU** | [](http://powerci.osuosl.org/job/TensorFlow_Ubuntu_16.04_CPU/) | TBA |
| **IBM ppc64le GPU** | [](http://powerci.osuosl.org/job/TensorFlow_Ubuntu_16.04_PPC64LE_GPU/) | TBA |
| **Linux CPU with Intel® MKL-DNN** Nightly | [](https://tensorflow-ci.intel.com/job/tensorflow-mkl-linux-cpu/) | [Nightly](https://tensorflow-ci.intel.com/job/tensorflow-mkl-build-whl-nightly/) |
-| **Linux CPU with Intel® MKL-DNN** Python 2.7
**Linux CPU with Intel® MKL-DNN** Python 3.5
**Linux CPU with Intel® MKL-DNN** Python 3.6 | [](https://tensorflow-ci.intel.com/job/tensorflow-mkl-build-release-whl/lastStableBuild)|[1.9.0 py2.7](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.9.0-cp27-cp27mu-linux_x86_64.whl)
[1.9.0 py3.5](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.9.0-cp35-cp35m-linux_x86_64.whl)
[1.9.0 py3.6](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.9.0-cp36-cp36m-linux_x86_64.whl) |
+| **Linux CPU with Intel® MKL-DNN** Python 2.7
**Linux CPU with Intel® MKL-DNN** Python 3.5
**Linux CPU with Intel® MKL-DNN** Python 3.6 | [](https://tensorflow-ci.intel.com/job/tensorflow-mkl-build-release-whl/lastStableBuild)|[1.10.0 py2.7](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.10.0-cp27-cp27mu-linux_x86_64.whl)
[1.10.0 py3.5](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.10.0-cp35-cp35m-linux_x86_64.whl)
[1.10.0 py3.6](https://storage.googleapis.com/intel-optimized-tensorflow/tensorflow-1.10.0-cp36-cp36m-linux_x86_64.whl) |
## For more information
-* [Tensorflow Blog](https://medium.com/tensorflow)
+* [TensorFlow Blog](https://medium.com/tensorflow)
* [TensorFlow Course at Stanford](https://web.stanford.edu/class/cs20si)
* [TensorFlow Model Zoo](https://github.com/tensorflow/models)
* [TensorFlow MOOC on Udacity](https://www.udacity.com/course/deep-learning--ud730)
* [TensorFlow Roadmap](https://www.tensorflow.org/community/roadmap)
-* [Tensorflow Twitter](https://twitter.com/tensorflow)
+* [TensorFlow Twitter](https://twitter.com/tensorflow)
* [TensorFlow Website](https://www.tensorflow.org)
* [TensorFlow White Papers](https://www.tensorflow.org/about/bib)
* [TensorFlow YouTube Channel](https://www.youtube.com/channel/UC0rqucBdTuFTjJiefW5t-IQ)
diff --git a/configure.py b/configure.py
index 10fee6993eb52f71e2d0ad4d4c23eb3b53adc537..361bd4764dc5c1900be7378f51c00aedf6f2ce41 100644
--- a/configure.py
+++ b/configure.py
@@ -45,7 +45,7 @@ _DEFAULT_TENSORRT_PATH_LINUX = '/usr/lib/%s-linux-gnu' % platform.machine()
_TF_OPENCL_VERSION = '1.2'
_DEFAULT_COMPUTECPP_TOOLKIT_PATH = '/usr/local/computecpp'
_DEFAULT_TRISYCL_INCLUDE_DIR = '/usr/local/triSYCL/include'
-_SUPPORTED_ANDROID_NDK_VERSIONS = [10, 11, 12, 13, 14, 15]
+_SUPPORTED_ANDROID_NDK_VERSIONS = [10, 11, 12, 13, 14, 15, 16]
_DEFAULT_PROMPT_ASK_ATTEMPTS = 10
@@ -1543,6 +1543,10 @@ def main():
if environ_cp.get('TF_DOWNLOAD_CLANG') != '1':
# Set up which clang we should use as the cuda / host compiler.
set_clang_cuda_compiler_path(environ_cp)
+ else:
+ # Use downloaded LLD for linking.
+ write_to_bazelrc('build:cuda_clang --config=download_clang_use_lld')
+ write_to_bazelrc('test:cuda_clang --config=download_clang_use_lld')
else:
# Set up which gcc nvcc should use as the host compiler
# No need to set this on Windows
diff --git a/tensorflow/BUILD b/tensorflow/BUILD
index 9cc4c4567b4b2ea6bc29919bfa03c190c9005fbc..386e0096ff705c2eaa98f42833ef650bac6fc8d8 100644
--- a/tensorflow/BUILD
+++ b/tensorflow/BUILD
@@ -12,6 +12,7 @@ exports_files([
# The leakr files are used by //third_party/cloud_tpu.
"leakr_badwords.dic",
"leakr_badfiles.dic",
+ "leakr_file_type_recipe.ftrcp",
])
load("//tensorflow:tensorflow.bzl", "tf_cc_shared_object")
@@ -23,11 +24,25 @@ load(
"//tensorflow/python/tools/api/generator:api_gen.bzl",
"gen_api_init_files", # @unused
)
+load("//tensorflow/python/tools/api/generator:api_gen.bzl", "get_compat_files")
+load(
+ "//tensorflow/python/tools/api/generator:api_init_files.bzl",
+ "TENSORFLOW_API_INIT_FILES", # @unused
+)
+load(
+ "//tensorflow/python/tools/api/generator:api_init_files_v1.bzl",
+ "TENSORFLOW_API_INIT_FILES_V1", # @unused
+)
load(
"//third_party/ngraph:build_defs.bzl",
"if_ngraph",
)
+# @unused
+TENSORFLOW_API_INIT_FILES_V2 = (
+ TENSORFLOW_API_INIT_FILES + get_compat_files(TENSORFLOW_API_INIT_FILES_V1, 1)
+)
+
# Config setting used when building for products
# which requires restricted licenses to be avoided.
config_setting(
@@ -423,12 +438,20 @@ config_setting(
visibility = ["//visibility:public"],
)
+# This flag specifies whether TensorFlow 2.0 API should be built instead
+# of 1.* API. Note that TensorFlow 2.0 API is currently under development.
+config_setting(
+ name = "api_version_2",
+ define_values = {"tf_api_version": "2"},
+)
+
package_group(
name = "internal",
packages = [
"-//third_party/tensorflow/python/estimator",
"//learning/meta_rank/...",
"//tensorflow/...",
+ "//tensorflow_estimator/...",
"//tensorflow_fold/llgtm/...",
"//third_party/py/tensor2tensor/...",
],
@@ -586,12 +609,39 @@ exports_files(
)
gen_api_init_files(
- name = "tensorflow_python_api_gen",
+ name = "tf_python_api_gen_v1",
srcs = ["api_template.__init__.py"],
api_version = 1,
+ output_dir = "_api/v1/",
+ output_files = TENSORFLOW_API_INIT_FILES_V1,
+ output_package = "tensorflow._api.v1",
root_init_template = "api_template.__init__.py",
)
+gen_api_init_files(
+ name = "tf_python_api_gen_v2",
+ srcs = ["api_template.__init__.py"],
+ api_version = 2,
+ compat_api_versions = [1],
+ output_dir = "_api/v2/",
+ output_files = TENSORFLOW_API_INIT_FILES_V2,
+ output_package = "tensorflow._api.v2",
+ root_init_template = "api_template.__init__.py",
+)
+
+genrule(
+ name = "root_init_gen",
+ srcs = select({
+ "api_version_2": [":tf_python_api_gen_v2"],
+ "//conditions:default": [":tf_python_api_gen_v1"],
+ }),
+ outs = ["__init__.py"],
+ cmd = select({
+ "api_version_2": "cp $(@D)/_api/v2/__init__.py $(OUTS)",
+ "//conditions:default": "cp $(@D)/_api/v1/__init__.py $(OUTS)",
+ }),
+)
+
py_library(
name = "tensorflow_py",
srcs = ["//tensorflow/python/estimator/api:estimator_python_api_gen"],
@@ -606,7 +656,10 @@ py_library(
py_library(
name = "tensorflow_py_no_contrib",
- srcs = [":tensorflow_python_api_gen"],
+ srcs = select({
+ "api_version_2": [":tf_python_api_gen_v2"],
+ "//conditions:default": [":tf_python_api_gen_v1"],
+ }) + [":root_init_gen"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
deps = ["//tensorflow/python:no_contrib"],
diff --git a/tensorflow/api_template.__init__.py b/tensorflow/api_template.__init__.py
index 779f65d5b17c350833f67f07985b00e8eb561e72..53a72b84430ac703323e8235b4e3393d1c9898bc 100644
--- a/tensorflow/api_template.__init__.py
+++ b/tensorflow/api_template.__init__.py
@@ -18,11 +18,12 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+import os as _os
+
# pylint: disable=g-bad-import-order
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
try:
- import os # pylint: disable=g-import-not-at-top
# Add `estimator` attribute to allow access to estimator APIs via
# "tf.estimator..."
from tensorflow.python.estimator.api import estimator # pylint: disable=g-import-not-at-top
@@ -30,9 +31,8 @@ try:
# Add `estimator` to the __path__ to allow "from tensorflow.estimator..."
# style imports.
from tensorflow.python.estimator import api as estimator_api # pylint: disable=g-import-not-at-top
- __path__ += [os.path.dirname(estimator_api.__file__)]
+ __path__ += [_os.path.dirname(estimator_api.__file__)]
del estimator_api
- del os
except (ImportError, AttributeError):
print('tf.estimator package not installed.')
@@ -45,6 +45,12 @@ del LazyLoader
from tensorflow.python.platform import flags # pylint: disable=g-import-not-at-top
app.flags = flags # pylint: disable=undefined-variable
+# Make sure directory containing top level submodules is in
+# the __path__ so that "from tensorflow.foo import bar" works.
+_tf_api_dir = _os.path.dirname(_os.path.dirname(app.__file__)) # pylint: disable=undefined-variable
+if _tf_api_dir not in __path__:
+ __path__.append(_tf_api_dir)
+
del absolute_import
del division
del print_function
@@ -54,6 +60,12 @@ del print_function
# must come from this module. So python adds these symbols for the
# resolution to succeed.
# pylint: disable=undefined-variable
-del python
-del core
+try:
+ del python
+ del core
+except NameError:
+ # Don't fail if these modules are not available.
+ # For e.g. we are using this file for compat.v1 module as well and
+ # 'python', 'core' directories are not under compat/v1.
+ pass
# pylint: enable=undefined-variable
diff --git a/tensorflow/c/BUILD b/tensorflow/c/BUILD
index 8a9301d584775cff3ae315e6fd856b00d1734248..43c279bd800d79eeaf9a25bbc1978148f93c0a50 100644
--- a/tensorflow/c/BUILD
+++ b/tensorflow/c/BUILD
@@ -117,6 +117,7 @@ tf_cuda_library(
deps = [
":c_api",
":c_api_internal",
+ "//tensorflow/c/eager:c_api",
"//tensorflow/compiler/jit/legacy_flags:mark_for_compilation_pass_flags",
"//tensorflow/contrib/tpu:all_ops",
"//tensorflow/core:core_cpu",
@@ -127,6 +128,15 @@ tf_cuda_library(
],
)
+cc_library(
+ name = "c_api_headers",
+ hdrs = [
+ "c_api.h",
+ ],
+ copts = tf_copts(),
+ visibility = ["//tensorflow:__subpackages__"],
+)
+
exports_files(
[
"version_script.lds",
@@ -194,6 +204,7 @@ tf_cuda_cc_test(
"//tensorflow:darwin": ["-headerpad_max_install_names"],
"//conditions:default": [],
}),
+ tags = ["noasan"],
# We must ensure that the dependencies can be dynamically linked since
# the shared library must be able to use core:framework.
# linkstatic = tf_kernel_tests_linkstatic(),
diff --git a/tensorflow/c/c_api.cc b/tensorflow/c/c_api.cc
index b8adf6c1279e72d0c2056368253aa0cb470216e5..173bbea596a4276559f5cd67824e5cc75313985c 100644
--- a/tensorflow/c/c_api.cc
+++ b/tensorflow/c/c_api.cc
@@ -1240,7 +1240,7 @@ void TF_SetAttrTypeList(TF_OperationDescription* desc, const char* attr_name,
void TF_SetAttrFuncName(TF_OperationDescription* desc, const char* attr_name,
const char* value, size_t length) {
tensorflow::NameAttrList func_name;
- func_name.set_name(std::string(value, value + length));
+ func_name.set_name(string(value, value + length));
desc->node_builder.Attr(attr_name, func_name);
}
@@ -2065,7 +2065,7 @@ static void GraphImportGraphDefLocked(TF_Graph* graph, const GraphDef& def,
for (int i = 0; i < size; ++i) {
TensorId id = results.missing_unused_input_map_keys[i];
- tf_results->missing_unused_key_names_data.push_back(std::string(id.first));
+ tf_results->missing_unused_key_names_data.emplace_back(id.first);
tf_results->missing_unused_key_names[i] =
tf_results->missing_unused_key_names_data.back().c_str();
tf_results->missing_unused_key_indexes[i] = id.second;
diff --git a/tensorflow/c/c_api_experimental.cc b/tensorflow/c/c_api_experimental.cc
index 69b3ffe2a1f620e346405607ecf742fb863aa644..c046bd66cda593e4feaf02f9e8068d4b59cf3e19 100644
--- a/tensorflow/c/c_api_experimental.cc
+++ b/tensorflow/c/c_api_experimental.cc
@@ -79,6 +79,18 @@ TF_Buffer* TF_CreateConfig(unsigned char enable_xla_compilation,
auto* gpu_options = config.mutable_gpu_options();
gpu_options->set_allow_growth(gpu_memory_allow_growth);
+ // TODO(b/113217601): This is needed for EagerContext::runner_ to use a
+ // threadpool, so that we avoid the possibility of running the runner_ in the
+ // threadpool of GPU event mgr, as that can trigger more callbacks to be
+ // scheduled on that same threadpool, causing a deadlock in cases where the
+ // caller of event_mgr->ThenExecute() blocks on the completion of the callback
+ // (as in the case of ConstOp kernel creation on GPU, which involves copying a
+ // CPU tensor to GPU).
+ // Setting a larger thread pool does not help with the Swift caller, as we use
+ // a different TFE context for each thread of execution (for running graph
+ // functions, and their send/recvs corountines).
+ config.set_inter_op_parallelism_threads(1);
+
TF_Buffer* ret = TF_NewBuffer();
TF_CHECK_OK(MessageToBuffer(config, ret));
return ret;
@@ -8494,3 +8506,201 @@ void TF_EnqueueNamedTensor(TF_Session* session, int tensor_id,
/*run_metadata*/ nullptr, status);
VLOG(1) << "Enqueuing is done.";
}
+
+TFE_Context* TFE_CreateContextFromSession(TF_Session* session,
+ TF_Status* status) {
+ auto* opts = TFE_NewContextOptions();
+
+ // Reduce GPU memory allocation, and set appropriate config options for TFE
+ // context.
+ auto* config =
+ TF_CreateConfig(/*xla*/ false, /* gpu_memory_allow_growth */ true);
+ TFE_ContextOptionsSetConfig(opts, config->data, config->length, status);
+ if (!status->status.ok()) {
+ CHECK(!config);
+ TFE_DeleteContextOptions(opts);
+ return nullptr;
+ }
+
+ auto* ctx = TFE_NewContextFromSession(opts, session, status);
+ TF_DeleteBuffer(config);
+ TFE_DeleteContextOptions(opts);
+ return ctx;
+}
+
+// TODO: retrieve the device string via TFE_ContextListDevices()
+static const char DEFAULT_CPU_DEVICE[] =
+ "/job:localhost/replica:0/task:0/device:CPU:0";
+
+static TFE_TensorHandle* createTFEQueue(TFE_Context* ctx, TF_DataType inputType,
+ int tensor_id, TF_Status* status) {
+ std::unique_ptr queueOp(
+ TFE_NewOp(ctx, "FIFOQueueV2", status), TFE_DeleteOp);
+ TFE_OpSetDevice(queueOp.get(), DEFAULT_CPU_DEVICE, status);
+ if (!status->status.ok()) return nullptr;
+ // TODO: use NAMED_TENSOR_QUEUE_CAPACITY in S4TF compiler.
+ TFE_OpSetAttrInt(queueOp.get(), "capacity", 1);
+ TFE_OpSetAttrTypeList(queueOp.get(), "component_types", &inputType, 1);
+ auto shared_name = tensorflow::strings::StrCat("fifo_queue_", tensor_id);
+ TFE_OpSetAttrString(queueOp.get(), "shared_name", shared_name.data(),
+ shared_name.size());
+ TFE_OpSetAttrString(queueOp.get(), "container", "", 0);
+
+ // TODO: consider making this an unknown shape.
+ const int64_t* dims_ptr = nullptr;
+ int num_dims = 0;
+ TFE_OpSetAttrShapeList(queueOp.get(), "shapes", &dims_ptr, &num_dims,
+ /*num_values*/ 0, status);
+ if (!status->status.ok()) return nullptr;
+
+ int num_retvals = 1;
+ TFE_TensorHandle* queue = nullptr;
+ TFE_Execute(queueOp.get(), &queue, &num_retvals, status);
+ if (!status->status.ok()) return nullptr;
+ CHECK_EQ(num_retvals, 1);
+
+ return queue;
+}
+
+static void createTFEEnqueue(TFE_Context* ctx, TF_DataType inputType,
+ TFE_TensorHandle* queue, TFE_TensorHandle* tensor,
+ TF_Status* status) {
+ TFE_Op* op = TFE_NewOp(ctx, "QueueEnqueueV2", status);
+ if (!status->status.ok()) return;
+ std::unique_ptr op_deleter(op, TFE_DeleteOp);
+ TFE_OpSetDevice(op, DEFAULT_CPU_DEVICE, status);
+ if (!status->status.ok()) return;
+ TFE_OpAddInput(op, queue, status);
+ if (!status->status.ok()) return;
+ TFE_OpAddInput(op, tensor, status);
+ if (!status->status.ok()) return;
+ TFE_OpSetAttrTypeList(op, "Tcomponents", &inputType, 1);
+ TFE_OpSetAttrInt(op, "timeout_ms", -1);
+
+ int num_retvals = 0;
+ TFE_Execute(op, nullptr /*retvals*/, &num_retvals, status);
+ if (!status->status.ok()) return;
+ CHECK_EQ(num_retvals, 0);
+}
+
+static TFE_TensorHandle* createTFEDequeue(TFE_Context* ctx,
+ TF_DataType inputType,
+ TFE_TensorHandle* queue,
+ TF_Status* status) {
+ TFE_Op* op = TFE_NewOp(ctx, "QueueDequeueV2", status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr op_deleter(op, TFE_DeleteOp);
+ TFE_OpSetDevice(op, DEFAULT_CPU_DEVICE, status);
+ if (!status->status.ok()) return nullptr;
+
+ TFE_OpAddInput(op, queue, status);
+ if (!status->status.ok()) return nullptr;
+ TFE_OpSetAttrTypeList(op, "component_types", &inputType, 1);
+ TFE_OpSetAttrInt(op, "timeout_ms", -1);
+ TFE_TensorHandle* ret;
+ int num_retvals = 1;
+ TFE_Execute(op, &ret, &num_retvals, status);
+ if (!status->status.ok()) return nullptr;
+ CHECK_EQ(num_retvals, 1);
+ return ret;
+}
+
+TFE_TensorHandle* TFE_DequeueNamedTensor(TF_Session* session, int tensor_id,
+ TF_DataType inputType,
+ TF_Status* status) {
+ assert(session);
+ VLOG(1) << "Dequeuing data tensor with id " << tensor_id;
+
+ auto ctx = TFE_CreateContextFromSession(session, status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr ctx_deleter(
+ ctx, TFE_DeleteContext);
+
+ TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ auto* ret = createTFEDequeue(ctx, inputType, queue, status);
+ return ret;
+}
+
+TFE_TensorHandle* TFE_DequeueNamedTensorFromCtx(TFE_Context* ctx, int tensor_id,
+ TF_DataType inputType,
+ TF_Status* status) {
+ TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ auto* ret = createTFEDequeue(ctx, inputType, queue, status);
+
+ return ret;
+}
+
+void TFE_EnqueueNamedTensor(TF_Session* session, int tensor_id,
+ TFE_TensorHandle* tensor, TF_Status* status) {
+ assert(session);
+ VLOG(1) << "Enqueuing data tensor with id " << tensor_id;
+
+ auto ctx = TFE_CreateContextFromSession(session, status);
+ if (!status->status.ok()) return;
+ std::unique_ptr ctx_deleter(
+ ctx, TFE_DeleteContext);
+
+ TF_DataType inputType = TFE_TensorHandleDataType(tensor);
+ TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
+ if (!status->status.ok()) return;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ createTFEEnqueue(ctx, inputType, queue, tensor, status);
+}
+
+void TFE_EnqueueNamedTensorFromCtx(TFE_Context* ctx, int tensor_id,
+ TFE_TensorHandle* tensor,
+ TF_Status* status) {
+ VLOG(1) << "Enqueuing data tensor with id " << tensor_id;
+
+ TF_DataType inputType = TFE_TensorHandleDataType(tensor);
+ TFE_TensorHandle* queue = createTFEQueue(ctx, inputType, tensor_id, status);
+ if (!status->status.ok()) return;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ createTFEEnqueue(ctx, inputType, queue, tensor, status);
+}
+
+void TFE_EnqueueVariantTensor(TF_Session* session, int tensor_id,
+ TFE_TensorHandle* tensor, TF_Status* status) {
+ VLOG(1) << "Enqueuing variant tensor with id " << tensor_id;
+
+ auto ctx = TFE_CreateContextFromSession(session, status);
+ if (!status->status.ok()) return;
+ std::unique_ptr ctx_deleter(
+ ctx, TFE_DeleteContext);
+
+ TFE_TensorHandle* queue = createTFEQueue(ctx, TF_VARIANT, tensor_id, status);
+ if (!status->status.ok()) return;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ createTFEEnqueue(ctx, TF_VARIANT, queue, tensor, status);
+}
+
+TFE_TensorHandle* TFE_DequeueVariantTensor(TF_Session* session, int tensor_id,
+ TF_Status* status) {
+ VLOG(1) << "Dequeuing variant tensor with id " << tensor_id;
+
+ auto ctx = TFE_CreateContextFromSession(session, status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr ctx_deleter(
+ ctx, TFE_DeleteContext);
+
+ TFE_TensorHandle* queue = createTFEQueue(ctx, TF_VARIANT, tensor_id, status);
+ if (!status->status.ok()) return nullptr;
+ std::unique_ptr
+ queue_deleter(queue, TFE_DeleteTensorHandle);
+
+ return createTFEDequeue(ctx, TF_VARIANT, queue, status);
+}
diff --git a/tensorflow/c/c_api_experimental.h b/tensorflow/c/c_api_experimental.h
index 6617c5a572e90e78369f73d714f39942f213040f..522c91f67efdf10118268842dee3beb334fb720d 100644
--- a/tensorflow/c/c_api_experimental.h
+++ b/tensorflow/c/c_api_experimental.h
@@ -20,6 +20,7 @@ limitations under the License.
#include
#include "tensorflow/c/c_api.h"
+#include "tensorflow/c/eager/c_api.h"
// --------------------------------------------------------------------------
// Experimental C API for TensorFlow.
@@ -131,6 +132,48 @@ TF_CAPI_EXPORT extern void TF_EnqueueNamedTensor(TF_Session* session,
TF_Tensor* tensor,
TF_Status* status);
+// TODO: remove this API in favor of the next one.
+TF_CAPI_EXPORT extern TFE_Context* TFE_NewContextFromSession(
+ const TFE_ContextOptions* opts, TF_Session* sess, TF_Status* status);
+
+// Creates from `session` a new eager context to run a graph function or
+// sends/recvs, so that these concurrent TFE executions can share (via
+// `session` and its associated device mgr) the same set of fifo queue resource
+// ops, used for host<->TF tensor transfers. This way the sends/recvs calls and
+// graph function execution can access the same fifo queue resource handles
+// (associated with devices managed by the device manager, which can be obtained
+// from `session`).
+//
+// TODO: Remove this function once we migrate away from using session.
+TF_CAPI_EXPORT extern TFE_Context* TFE_CreateContextFromSession(
+ TF_Session* session, TF_Status* status);
+
+// TODO: Retire this API in favor of the next one.
+TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_DequeueNamedTensor(
+ TF_Session* session, int tensor_id, TF_DataType inputType,
+ TF_Status* status);
+
+TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_DequeueNamedTensorFromCtx(
+ TFE_Context* ctx, int tensor_id, TF_DataType inputType, TF_Status* status);
+
+TF_CAPI_EXPORT extern void TFE_EnqueueNamedTensor(TF_Session* session,
+ int tensor_id,
+ TFE_TensorHandle* tensor,
+ TF_Status* status);
+
+TF_CAPI_EXPORT extern void TFE_EnqueueNamedTensorFromCtx(
+ TFE_Context* ctx, int tensor_id, TFE_TensorHandle* tensor,
+ TF_Status* status);
+
+// TODO: consider folding the 2 APIs below into the ones above.
+TF_CAPI_EXPORT extern void TFE_EnqueueVariantTensor(TF_Session* session,
+ int tensor_id,
+ TFE_TensorHandle* tensor,
+ TF_Status* status);
+
+TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_DequeueVariantTensor(
+ TF_Session* session, int tensor_id, TF_Status* status);
+
#ifdef __cplusplus
} /* end extern "C" */
#endif
diff --git a/tensorflow/c/c_api_test.cc b/tensorflow/c/c_api_test.cc
index aa2a537f03be31ae45ff3d6f7815b449d661cf9c..03516c39dc970aa23967107d3a0446da94669465 100644
--- a/tensorflow/c/c_api_test.cc
+++ b/tensorflow/c/c_api_test.cc
@@ -259,8 +259,8 @@ TEST(CAPI, DeprecatedSession) {
TF_Run(session, run_options, nullptr, nullptr, 0, nullptr, nullptr, 0,
nullptr, 0, run_metadata, s);
EXPECT_EQ(TF_INVALID_ARGUMENT, TF_GetCode(s)) << TF_Message(s);
- EXPECT_EQ(std::string("Session was not created with a graph before Run()!"),
- std::string(TF_Message(s)));
+ EXPECT_EQ("Session was not created with a graph before Run()!",
+ string(TF_Message(s)));
TF_DeleteBuffer(run_metadata);
TF_DeleteBuffer(run_options);
@@ -1224,8 +1224,8 @@ class CApiColocationTest : public ::testing::Test {
TF_OperationGetAttrMetadata(op, tensorflow::kColocationAttrName, s_);
if (expected.empty()) {
ASSERT_EQ(TF_INVALID_ARGUMENT, TF_GetCode(s_)) << TF_Message(s_);
- EXPECT_EQ(std::string("Operation 'add' has no attr named '_class'."),
- std::string(TF_Message(s_)));
+ EXPECT_EQ("Operation 'add' has no attr named '_class'.",
+ string(TF_Message(s_)));
return;
}
EXPECT_EQ(TF_OK, TF_GetCode(s_)) << TF_Message(s_);
@@ -1369,16 +1369,16 @@ TEST(CAPI, SavedModel) {
input.flat()(i) = example.SerializeAsString();
}
- const tensorflow::string input_op_name =
- std::string(tensorflow::ParseTensorName(input_name).first);
+ const tensorflow::string input_op_name(
+ tensorflow::ParseTensorName(input_name).first);
TF_Operation* input_op =
TF_GraphOperationByName(graph, input_op_name.c_str());
ASSERT_TRUE(input_op != nullptr);
csession.SetInputs({{input_op, TF_TensorFromTensor(input, s)}});
ASSERT_EQ(TF_OK, TF_GetCode(s)) << TF_Message(s);
- const tensorflow::string output_op_name =
- std::string(tensorflow::ParseTensorName(output_name).first);
+ const tensorflow::string output_op_name(
+ tensorflow::ParseTensorName(output_name).first);
TF_Operation* output_op =
TF_GraphOperationByName(graph, output_op_name.c_str());
ASSERT_TRUE(output_op != nullptr);
diff --git a/tensorflow/c/checkpoint_reader.cc b/tensorflow/c/checkpoint_reader.cc
index 74bc25a491ac01cb725d1c004197e48727c30230..d3311f0cd06f2b151c3567735eb41b5baf72e102 100644
--- a/tensorflow/c/checkpoint_reader.cc
+++ b/tensorflow/c/checkpoint_reader.cc
@@ -125,7 +125,7 @@ CheckpointReader::BuildV2VarMaps() {
const auto& slice_proto = entry.slices(i);
CHECK(filtered_keys
.insert(EncodeTensorNameSlice(
- std::string(v2_reader_->key()) /* full var's name */,
+ string(v2_reader_->key()) /* full var's name */,
TensorSlice(slice_proto)))
.second);
}
@@ -138,11 +138,11 @@ CheckpointReader::BuildV2VarMaps() {
new TensorSliceReader::VarToDataTypeMap);
v2_reader_->Seek(kHeaderEntryKey);
for (v2_reader_->Next(); v2_reader_->Valid(); v2_reader_->Next()) {
- if (filtered_keys.count(std::string(v2_reader_->key())) > 0) continue;
+ if (filtered_keys.count(string(v2_reader_->key())) > 0) continue;
CHECK(entry.ParseFromArray(v2_reader_->value().data(),
v2_reader_->value().size()))
<< entry.InitializationErrorString();
- string key = std::string(v2_reader_->key());
+ string key(v2_reader_->key());
(*var_to_shape_map)[key] = TensorShape(entry.shape());
(*var_to_data_type_map)[key] = DataType(entry.dtype());
}
diff --git a/tensorflow/c/eager/c_api.cc b/tensorflow/c/eager/c_api.cc
old mode 100644
new mode 100755
index dfb1c9a37644c726e1eabab775593596d5b556b9..349d9bcd7ca3991c7c3621f347af6025778612b7
--- a/tensorflow/c/eager/c_api.cc
+++ b/tensorflow/c/eager/c_api.cc
@@ -244,8 +244,8 @@ void TFE_ContextOptionsSetConfig(TFE_ContextOptions* options, const void* proto,
}
void TFE_ContextOptionsSetAsync(TFE_ContextOptions* options,
- unsigned char async) {
- options->async = async;
+ unsigned char enable) {
+ options->async = enable;
}
void TFE_ContextOptionsSetDevicePlacementPolicy(
TFE_ContextOptions* options, TFE_ContextDevicePlacementPolicy policy) {
@@ -253,9 +253,9 @@ void TFE_ContextOptionsSetDevicePlacementPolicy(
}
TF_CAPI_EXPORT extern void TFE_ContextSetAsyncForThread(TFE_Context* ctx,
- unsigned char async,
+ unsigned char enable,
TF_Status* status) {
- status->status = ctx->context.SetAsyncForThread(async);
+ status->status = ctx->context.SetAsyncForThread(enable);
}
void TFE_DeleteContextOptions(TFE_ContextOptions* options) { delete options; }
@@ -273,7 +273,20 @@ TFE_Context* TFE_NewContext(const TFE_ContextOptions* opts, TF_Status* status) {
new tensorflow::IntraProcessRendezvous(device_mgr.get());
return new TFE_Context(opts->session_options.options, opts->policy,
- opts->async, std::move(device_mgr), r);
+ opts->async, device_mgr.release(),
+ /*device_mgr_owned*/ true, r);
+}
+
+TFE_Context* TFE_NewContextFromSession(const TFE_ContextOptions* opts,
+ TF_Session* sess, TF_Status* status) {
+ const tensorflow::DeviceMgr* device_mgr = nullptr;
+ status->status = sess->session->LocalDeviceManager(&device_mgr);
+ if (!status->status.ok()) return nullptr;
+ tensorflow::Rendezvous* r =
+ new tensorflow::IntraProcessRendezvous(device_mgr);
+ return new TFE_Context(opts->session_options.options, opts->policy,
+ opts->async, device_mgr, /*device_mgr_owned*/ false,
+ r);
}
void TFE_DeleteContext(TFE_Context* ctx) { delete ctx; }
@@ -386,6 +399,19 @@ const char* TFE_TensorHandleDeviceName(TFE_TensorHandle* h, TF_Status* status) {
: d->name().c_str();
}
+TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_TensorHandleCopySharingTensor(
+ TFE_TensorHandle* h, TF_Status* status) {
+ if (h == nullptr || h->handle == nullptr) {
+ status->status = tensorflow::errors::InvalidArgument(
+ "The passed in handle is a nullptr");
+ return nullptr;
+ }
+
+ h->handle->Ref();
+
+ return new TFE_TensorHandle(h->handle);
+}
+
TF_Tensor* TFE_TensorHandleResolve(TFE_TensorHandle* h, TF_Status* status) {
if (h == nullptr || h->handle == nullptr) {
status->status = tensorflow::errors::InvalidArgument(
diff --git a/tensorflow/c/eager/c_api.h b/tensorflow/c/eager/c_api.h
old mode 100644
new mode 100755
index a0ebc6fa0a22ed61be91c2974352c2988fb4cd92..337447eec9581b01fa775affc49097986824a360
--- a/tensorflow/c/eager/c_api.h
+++ b/tensorflow/c/eager/c_api.h
@@ -76,7 +76,7 @@ typedef enum TFE_ContextDevicePlacementPolicy {
// Sets the default execution mode (sync/async). Note that this can be
// overridden per thread using TFE_ContextSetAsyncForThread.
TF_CAPI_EXPORT extern void TFE_ContextOptionsSetAsync(TFE_ContextOptions*,
- unsigned char async);
+ unsigned char enable);
TF_CAPI_EXPORT extern void TFE_ContextOptionsSetDevicePlacementPolicy(
TFE_ContextOptions*, TFE_ContextDevicePlacementPolicy);
@@ -114,7 +114,7 @@ TFE_ContextGetDevicePlacementPolicy(TFE_Context*);
// Overrides the execution mode (sync/async) for the current thread.
TF_CAPI_EXPORT extern void TFE_ContextSetAsyncForThread(TFE_Context*,
- unsigned char async,
+ unsigned char enable,
TF_Status* status);
// A tensorflow.ServerDef specifies remote workers (in addition to the current
@@ -171,6 +171,12 @@ TF_CAPI_EXPORT extern int64_t TFE_TensorHandleDim(TFE_TensorHandle* h,
TF_CAPI_EXPORT extern const char* TFE_TensorHandleDeviceName(
TFE_TensorHandle* h, TF_Status* status);
+// Return a pointer to a new TFE_TensorHandle that shares the underlying tensor
+// with `h`. On success, `status` is set to OK. On failure, `status` reflects
+// the error and a nullptr is returned.
+TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_TensorHandleCopySharingTensor(
+ TFE_TensorHandle* h, TF_Status* status);
+
// This function will block till the operation that produces `h` has
// completed. The memory returned might alias the internal memory used by
// TensorFlow. Hence, callers should not mutate this memory (for example by
diff --git a/tensorflow/c/eager/c_api_internal.h b/tensorflow/c/eager/c_api_internal.h
index a5c0681e2e4eddae08954d9d0178ca96a3f8f29a..104d52430cf7aa14d4d2a335a1b96e667f21ce87 100644
--- a/tensorflow/c/eager/c_api_internal.h
+++ b/tensorflow/c/eager/c_api_internal.h
@@ -62,15 +62,14 @@ struct TFE_ContextOptions {
};
struct TFE_Context {
- explicit TFE_Context(const tensorflow::SessionOptions& opts,
- TFE_ContextDevicePlacementPolicy default_policy,
- bool async,
- std::unique_ptr device_mgr,
- tensorflow::Rendezvous* rendezvous)
+ TFE_Context(const tensorflow::SessionOptions& opts,
+ TFE_ContextDevicePlacementPolicy default_policy, bool async,
+ const tensorflow::DeviceMgr* device_mgr, bool device_mgr_owned,
+ tensorflow::Rendezvous* rendezvous)
: context(opts,
static_cast(
default_policy),
- async, std::move(device_mgr), rendezvous) {}
+ async, device_mgr, device_mgr_owned, rendezvous) {}
tensorflow::EagerContext context;
};
diff --git a/tensorflow/c/eager/c_api_test.cc b/tensorflow/c/eager/c_api_test.cc
index 7126227cf529023eadf38984668a40118641bb1b..55331022b9dbd0696928fa44430f340f371432ac 100644
--- a/tensorflow/c/eager/c_api_test.cc
+++ b/tensorflow/c/eager/c_api_test.cc
@@ -1528,4 +1528,29 @@ TEST(CAPI, StringAttributes) {
TFE_DeleteContext(ctx);
TF_DeleteStatus(status);
}
+
+TEST(CAPI, TestTFE_TensorHandleCopySharingUnderlyingTensorHandle) {
+ TFE_TensorHandle* h = TestMatrixTensorHandle();
+ EXPECT_EQ(TF_FLOAT, TFE_TensorHandleDataType(h));
+
+ std::unique_ptr status(
+ TF_NewStatus(), TF_DeleteStatus);
+
+ TFE_TensorHandle* h_shares_tensor =
+ TFE_TensorHandleCopySharingTensor(h, status.get());
+ ASSERT_EQ(TF_OK, TF_GetCode(status.get())) << TF_Message(status.get());
+
+ TF_Tensor* t = TFE_TensorHandleResolve(h_shares_tensor, status.get());
+ ASSERT_EQ(16, TF_TensorByteSize(t));
+ float data[4] = {0};
+ memcpy(&data[0], TF_TensorData(t), TF_TensorByteSize(t));
+ EXPECT_EQ(1.0, data[0]);
+ EXPECT_EQ(2.0, data[1]);
+ EXPECT_EQ(3.0, data[2]);
+ EXPECT_EQ(4.0, data[3]);
+ TF_DeleteTensor(t);
+
+ TFE_DeleteTensorHandle(h);
+ TFE_DeleteTensorHandle(h_shares_tensor);
+}
} // namespace
diff --git a/tensorflow/c/eager/tape.h b/tensorflow/c/eager/tape.h
index 1adb0458c35193117b5fa5cfe9ceffbaaf699af7..ce038a4b57b2699c6d09fcf75ef41cecec4e97b8 100644
--- a/tensorflow/c/eager/tape.h
+++ b/tensorflow/c/eager/tape.h
@@ -440,6 +440,15 @@ Status InitialGradients(const VSpace& vspace,
return Status::OK();
}
+gtl::FlatMap>* FunctionsAcceptingNoneForIndicesMap() {
+ static auto* const m = new gtl::FlatMap>({
+ {"SoftmaxCrossEntropyWithLogits", {1}},
+ {"SparseSoftmaxCrossEntropyWithLogits", {1}},
+ {"FusedBatchNorm", {1, 2, 3, 4}},
+ });
+ return m;
+}
+
} // namespace
// If over kMinAggregateCount gradients are accumulated and the total
@@ -485,10 +494,6 @@ Status GradientTape::ComputeGradient(
VLOG(1) << " " << t;
}
}
- gtl::FlatMap> functions_accept_none_for_indices({
- {"SoftmaxCrossEntropyWithLogits", {1}},
- {"FusedBatchNorm", {1, 2, 3, 4}},
- });
while (!op_stack.empty()) {
const int64 op = op_stack.back();
VLOG(1) << "Popped " << op;
@@ -509,8 +514,8 @@ Status GradientTape::ComputeGradient(
auto grad_it = gradients.find(id);
if (grad_it == gradients.end()) {
auto func_name_it =
- functions_accept_none_for_indices.find(trace.op_type);
- if (func_name_it != functions_accept_none_for_indices.end() &&
+ FunctionsAcceptingNoneForIndicesMap()->find(trace.op_type);
+ if (func_name_it != FunctionsAcceptingNoneForIndicesMap()->end() &&
func_name_it->second.find(i) != func_name_it->second.end()) {
out_gradients.push_back(nullptr);
} else {
diff --git a/tensorflow/cc/framework/cc_op_gen.cc b/tensorflow/cc/framework/cc_op_gen.cc
index c20ea95a15e3f53b9b26716ed7b624fa853017c9..a32d1b1eb50fc715084f5ee663a732770db1883c 100644
--- a/tensorflow/cc/framework/cc_op_gen.cc
+++ b/tensorflow/cc/framework/cc_op_gen.cc
@@ -466,7 +466,7 @@ string AvoidCPPKeywords(StringPiece name) {
if (IsCPPKeyword(name)) {
return strings::StrCat(name, "_");
}
- return std::string(name);
+ return string(name);
}
void InferArgAttributes(const OpDef::ArgDef& arg,
diff --git a/tensorflow/cc/framework/ops.h b/tensorflow/cc/framework/ops.h
index a085e1d6e2de5ad63d11eb8979ae64c26b91366f..0717e7dd4b358d6c212070374bcc3fd2f91ed0ab 100644
--- a/tensorflow/cc/framework/ops.h
+++ b/tensorflow/cc/framework/ops.h
@@ -150,7 +150,7 @@ class Input {
Initializer(const std::initializer_list& v, const TensorShape& shape) {
typedef typename RealType::type RealT;
Tensor t(DataTypeToEnum::v(), shape);
- if (t.NumElements() != v.size()) {
+ if (t.NumElements() != static_cast(v.size())) {
status = errors::InvalidArgument(
"Cannot construct a tensor with ", t.NumElements(),
" from an initializer list with ", v.size(), " elements");
diff --git a/tensorflow/cc/framework/scope.cc b/tensorflow/cc/framework/scope.cc
index 8c886f31711eb014fb9e9d600c9c78cf22073f71..7f6ac4cae78d8d6e118837fce9ae5270336cdc89 100644
--- a/tensorflow/cc/framework/scope.cc
+++ b/tensorflow/cc/framework/scope.cc
@@ -225,7 +225,7 @@ std::unordered_set Scope::Impl::GetColocationConstraints(
for (const string& entry : node_constraints) {
StringPiece s(entry);
if (str_util::ConsumePrefix(&s, kColocationGroupPrefix)) {
- current_constraints.insert(std::string(s));
+ current_constraints.emplace(s);
}
}
} else {
diff --git a/tensorflow/cc/saved_model/loader.cc b/tensorflow/cc/saved_model/loader.cc
index 3830416159158cca8bfb8422c2959b49fa42406d..c6abe2f41b9b5ec2faee6f65b429ff606f8ac08e 100644
--- a/tensorflow/cc/saved_model/loader.cc
+++ b/tensorflow/cc/saved_model/loader.cc
@@ -148,7 +148,7 @@ Status RunMainOp(const RunOptions& run_options, const string& export_dir,
AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);
RunMetadata run_metadata;
const StringPiece main_op_name = main_op_it->second.node_list().value(0);
- return RunOnce(run_options, inputs, {}, {main_op_name.ToString()},
+ return RunOnce(run_options, inputs, {}, {string(main_op_name)},
nullptr /* outputs */, &run_metadata, session);
}
return Status::OK();
@@ -182,12 +182,12 @@ Status RunRestore(const RunOptions& run_options, const string& export_dir,
variables_path_tensor.scalar()() = variables_path;
std::vector> inputs = {
- {variable_filename_const_op_name.ToString(), variables_path_tensor}};
+ {string(variable_filename_const_op_name), variables_path_tensor}};
AddAssetsTensorsToInputs(export_dir, asset_file_defs, &inputs);
RunMetadata run_metadata;
- return RunOnce(run_options, inputs, {}, {restore_op_name.ToString()},
+ return RunOnce(run_options, inputs, {}, {string(restore_op_name)},
nullptr /* outputs */, &run_metadata, session);
}
diff --git a/tensorflow/compiler/aot/BUILD b/tensorflow/compiler/aot/BUILD
index 2220d0786d3757abc378d1a3d0ddc704bba6a4f3..6c29f09cde7ee17c11cb44ce48d8e9128daae4d0 100644
--- a/tensorflow/compiler/aot/BUILD
+++ b/tensorflow/compiler/aot/BUILD
@@ -32,7 +32,6 @@ cc_library(
deps = [
":embedded_protocol_buffers",
"//tensorflow/compiler/tf2xla",
- "//tensorflow/compiler/tf2xla:common",
"//tensorflow/compiler/tf2xla:cpu_function_runtime",
"//tensorflow/compiler/tf2xla:tf2xla_proto",
"//tensorflow/compiler/tf2xla:tf2xla_util",
@@ -56,6 +55,8 @@ cc_library(
"//tensorflow/core:lib_internal",
"//tensorflow/core:protos_all_cc",
"@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
+ "@com_google_absl//absl/types:span",
],
)
@@ -72,6 +73,7 @@ tf_cc_test(
"//tensorflow/core:lib",
"//tensorflow/core:test",
"//tensorflow/core:test_main",
+ "@com_google_absl//absl/strings",
"@llvm//:support", # fixdeps: keep
"@llvm//:x86_code_gen", # fixdeps: keep
],
@@ -100,6 +102,7 @@ cc_library(
"//tensorflow/core:graph",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
+ "@com_google_absl//absl/strings",
],
)
@@ -189,12 +192,13 @@ cc_library(
srcs = ["embedded_protocol_buffers.cc"],
hdrs = ["embedded_protocol_buffers.h"],
deps = [
- "//tensorflow/compiler/tf2xla:common",
"//tensorflow/compiler/xla:statusor",
"//tensorflow/compiler/xla:util",
"//tensorflow/compiler/xla/service/llvm_ir:llvm_util",
"//tensorflow/core:lib",
"@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
+ "@com_google_absl//absl/types:span",
"@llvm//:core",
"@llvm//:support",
"@llvm//:target",
diff --git a/tensorflow/compiler/aot/codegen.cc b/tensorflow/compiler/aot/codegen.cc
index 44291d977f8e97bdcba8131363e65956cad60cb7..b17bc658fa06b9feb7edb292bd89ef31e6309169 100644
--- a/tensorflow/compiler/aot/codegen.cc
+++ b/tensorflow/compiler/aot/codegen.cc
@@ -20,18 +20,18 @@ limitations under the License.
#include
#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/str_replace.h"
+#include "absl/types/span.h"
#include "tensorflow/compiler/aot/embedded_protocol_buffers.h"
#include "tensorflow/compiler/tf2xla/cpu_function_runtime.h"
-#include "tensorflow/compiler/tf2xla/str_util.h"
#include "tensorflow/compiler/tf2xla/tf2xla_util.h"
#include "tensorflow/compiler/xla/service/compiler.h"
#include "tensorflow/compiler/xla/service/cpu/buffer_info_util.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/xla_data.pb.h"
#include "tensorflow/core/lib/core/errors.h"
-#include "tensorflow/core/lib/gtl/array_slice.h"
-#include "tensorflow/core/lib/strings/str_util.h"
-#include "tensorflow/core/lib/strings/strcat.h"
namespace tensorflow {
namespace tfcompile {
@@ -135,14 +135,14 @@ Status AddRewritesForShape(int i, const xla::Shape& shape,
indices = "[0]";
} else {
for (int dim = 0; dim < shape.dimensions_size(); ++dim) {
- dim_vars.push_back(strings::StrCat("size_t dim", dim));
- dim_sizes += strings::StrCat("[", shape.dimensions(dim), "]");
- indices += strings::StrCat("[dim", dim, "]");
+ dim_vars.push_back(absl::StrCat("size_t dim", dim));
+ dim_sizes += absl::StrCat("[", shape.dimensions(dim), "]");
+ indices += absl::StrCat("[dim", dim, "]");
}
}
- rewrites->push_back({"{{I}}", strings::StrCat(i)});
+ rewrites->push_back({"{{I}}", absl::StrCat(i)});
rewrites->push_back({"{{TYPE}}", type});
- rewrites->push_back({"{{DIM_VARS}}", str_util::Join(dim_vars, ", ")});
+ rewrites->push_back({"{{DIM_VARS}}", absl::StrJoin(dim_vars, ", ")});
rewrites->push_back({"{{DIM_SIZES}}", dim_sizes});
rewrites->push_back({"{{INDICES}}", indices});
return Status::OK();
@@ -158,8 +158,9 @@ Status AddRewritesForShape(int i, const xla::Shape& shape,
// text-templating mechanism.
string RewriteWithName(const string& name, string code,
const std::vector>& rewrites) {
- str_util::ReplaceAllPairs(&code, rewrites);
- return str_util::StringReplace(code, "{{NAME}}", name, /*replace_all=*/true);
+ absl::StrReplaceAll(rewrites, &code);
+ absl::StrReplaceAll({{"{{NAME}}", name}}, &code);
+ return code;
}
// Generate methods for args (inputs).
@@ -193,7 +194,7 @@ Status GenArgMethods(const tf2xla::Config& config, const xla::ProgramShape& ps,
arg_data({{I}}))){{INDICES}};
}
)";
- *methods += RewriteWithName(strings::StrCat(i), code, rewrites);
+ *methods += RewriteWithName(absl::StrCat(i), code, rewrites);
if (!config.feed(i).name().empty()) {
*methods += RewriteWithName("_" + config.feed(i).name(), code, rewrites);
}
@@ -234,7 +235,7 @@ Status GenResultMethods(const tf2xla::Config& config,
result_data({{I}}))){{INDICES}};
}
)";
- *methods += RewriteWithName(strings::StrCat(i), code, rewrites);
+ *methods += RewriteWithName(absl::StrCat(i), code, rewrites);
if (!config.fetch(i).name().empty()) {
*methods += RewriteWithName("_" + config.fetch(i).name(), code, rewrites);
}
@@ -303,8 +304,8 @@ std::vector BufferInfosToCppExpression(
string encoded_second_as_str =
encoded.second == ~0ULL
? "~0ULL"
- : strings::StrCat(encoded.second, "ULL");
- return strings::StrCat(
+ : absl::StrCat(encoded.second, "ULL");
+ return absl::StrCat(
"::tensorflow::cpu_function_runtime::BufferInfo({",
encoded.first, "ULL, ", encoded_second_as_str, "})");
});
@@ -351,13 +352,13 @@ Status GenerateHeader(const CodegenOpts& opts, const tf2xla::Config& config,
// Create rewrite strings for namespace start and end.
string ns_start;
for (const string& n : opts.namespaces) {
- ns_start += strings::StrCat("namespace ", n, " {\n");
+ ns_start += absl::StrCat("namespace ", n, " {\n");
}
ns_start += "\n";
string ns_end("\n");
for (int i = opts.namespaces.size() - 1; i >= 0; --i) {
const string& n = opts.namespaces[i];
- ns_end += strings::StrCat("} // end namespace ", n, "\n");
+ ns_end += absl::StrCat("} // end namespace ", n, "\n");
}
// Generate metadata.
@@ -567,15 +568,15 @@ class {{CLASS}} : public tensorflow::XlaCompiledCpuFunction {
)";
// The replacement strategy is naive, but good enough for our purposes.
const std::vector> rewrites = {
- {"{{ARG_BYTES_ALIGNED}}", strings::StrCat(arg_bytes_aligned)},
- {"{{ARG_BYTES_TOTAL}}", strings::StrCat(arg_bytes_total)},
+ {"{{ARG_BYTES_ALIGNED}}", absl::StrCat(arg_bytes_aligned)},
+ {"{{ARG_BYTES_TOTAL}}", absl::StrCat(arg_bytes_total)},
{"{{ARG_NAMES_CODE}}", arg_names_code},
- {"{{ARG_NUM}}", strings::StrCat(arg_index_table.size())},
- {"{{ARG_INDEX_TABLE}}", str_util::Join(arg_index_table, ", ")},
+ {"{{ARG_NUM}}", absl::StrCat(arg_index_table.size())},
+ {"{{ARG_INDEX_TABLE}}", absl::StrJoin(arg_index_table, ", ")},
{"{{ASSIGN_PROFILE_COUNTERS_SIZE}}", assign_profile_counters_size},
{"{{CLASS}}", opts.class_name},
{"{{DECLS_FROM_OBJ_FILE}}",
- str_util::Join(metadata_result.header_variable_decls, "\n")},
+ absl::StrJoin(metadata_result.header_variable_decls, "\n")},
{"{{ENTRY}}", compile_result.entry_point},
{"{{HLO_PROFILE_PRINTER_DATA_SHIM_EXPRESSION}}",
metadata_result.hlo_profile_printer_data_access_shim},
@@ -589,25 +590,25 @@ class {{CLASS}} : public tensorflow::XlaCompiledCpuFunction {
{"{{PROGRAM_SHAPE}}", xla::ShapeUtil::HumanString(ps)},
{"{{PROGRAM_SHAPE_SHIM_EXPRESSION}}",
metadata_result.program_shape_access_shim},
- {"{{RESULT_INDEX}}", strings::StrCat(result_index)},
+ {"{{RESULT_INDEX}}", absl::StrCat(result_index)},
{"{{RESULT_NAMES_CODE}}", result_names_code},
- {"{{TEMP_BYTES_ALIGNED}}", strings::StrCat(temp_bytes_aligned)},
- {"{{TEMP_BYTES_TOTAL}}", strings::StrCat(temp_bytes_total)},
- {"{{NUM_BUFFERS}}", strings::StrCat(buffer_infos.size())},
+ {"{{TEMP_BYTES_ALIGNED}}", absl::StrCat(temp_bytes_aligned)},
+ {"{{TEMP_BYTES_TOTAL}}", absl::StrCat(temp_bytes_total)},
+ {"{{NUM_BUFFERS}}", absl::StrCat(buffer_infos.size())},
{"{{BUFFER_INFOS_AS_STRING}}",
- str_util::Join(buffer_infos_as_strings, ",\n")}};
- str_util::ReplaceAllPairs(header, rewrites);
+ absl::StrJoin(buffer_infos_as_strings, ",\n")}};
+ absl::StrReplaceAll(rewrites, header);
return Status::OK();
}
static string CreateUniqueIdentifier(const CodegenOpts& opts,
- StringPiece suffix) {
+ absl::string_view suffix) {
string result = "__tfcompile";
for (const string& n : opts.namespaces) {
- strings::StrAppend(&result, "_", n);
+ absl::StrAppend(&result, "_", n);
}
- strings::StrAppend(&result, "_", opts.class_name, "_", suffix);
+ absl::StrAppend(&result, "_", opts.class_name, "_", suffix);
return result;
}
@@ -677,7 +678,7 @@ Status ParseCppClass(const string& cpp_class, string* class_name,
return Status::OK();
}
-Status ValidateCppIdent(StringPiece ident, StringPiece msg) {
+Status ValidateCppIdent(absl::string_view ident, absl::string_view msg) {
if (ident.empty()) {
return errors::InvalidArgument("empty identifier: ", msg);
}
diff --git a/tensorflow/compiler/aot/codegen.h b/tensorflow/compiler/aot/codegen.h
index 83f2d3ee11d09d66f16d7ecdc11945ebe994a82a..90410c46a8e36e44454f1219ad76d0fb0937070d 100644
--- a/tensorflow/compiler/aot/codegen.h
+++ b/tensorflow/compiler/aot/codegen.h
@@ -19,9 +19,9 @@ limitations under the License.
#include
#include
+#include "absl/strings/string_view.h"
#include "tensorflow/compiler/aot/compile.h"
#include "tensorflow/compiler/tf2xla/tf2xla.pb.h"
-#include "tensorflow/core/lib/core/stringpiece.h"
namespace tensorflow {
namespace tfcompile {
@@ -96,7 +96,7 @@ Status ParseCppClass(const string& cpp_class, string* class_name,
// ValidateCppIdent returns OK iff ident is a valid C++ identifier. The msg is
// appended to error messages.
-Status ValidateCppIdent(StringPiece ident, StringPiece msg);
+Status ValidateCppIdent(absl::string_view ident, absl::string_view msg);
} // namespace tfcompile
} // namespace tensorflow
diff --git a/tensorflow/compiler/aot/codegen_test.cc b/tensorflow/compiler/aot/codegen_test.cc
index 60d59ae996e8f7ec490c98aeab05182626e61976..bb288d23000527be74f01630d20bbf82e50007ce 100644
--- a/tensorflow/compiler/aot/codegen_test.cc
+++ b/tensorflow/compiler/aot/codegen_test.cc
@@ -18,13 +18,13 @@ limitations under the License.
#include
#include
+#include "absl/strings/match.h"
+#include "absl/strings/string_view.h"
#include "llvm/Support/TargetSelect.h"
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/core/status_test_util.h"
-#include "tensorflow/core/lib/core/stringpiece.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"
@@ -34,9 +34,9 @@ namespace {
using ::tensorflow::cpu_function_runtime::BufferInfo;
-void ExpectErrorContains(const Status& status, StringPiece str) {
+void ExpectErrorContains(const Status& status, absl::string_view str) {
EXPECT_NE(Status::OK(), status);
- EXPECT_TRUE(str_util::StrContains(status.error_message(), str))
+ EXPECT_TRUE(absl::StrContains(status.error_message(), str))
<< "expected error: " << status.error_message() << " to contain: " << str;
}
diff --git a/tensorflow/compiler/aot/embedded_protocol_buffers.cc b/tensorflow/compiler/aot/embedded_protocol_buffers.cc
index 8fb2fad31c680c5dbbd058a1b9a9265607224429..3c32d533f63f202fc9409f36709e0d29d1d7e002 100644
--- a/tensorflow/compiler/aot/embedded_protocol_buffers.cc
+++ b/tensorflow/compiler/aot/embedded_protocol_buffers.cc
@@ -19,6 +19,7 @@ limitations under the License.
#include
#include "absl/memory/memory.h"
+#include "absl/strings/str_replace.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
@@ -27,7 +28,6 @@ limitations under the License.
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "tensorflow/compiler/tf2xla/str_util.h"
#include "tensorflow/compiler/xla/service/llvm_ir/llvm_util.h"
#include "tensorflow/compiler/xla/util.h"
@@ -38,11 +38,11 @@ using xla::llvm_ir::AsStringRef;
static void AddEmbeddedProtocolBufferToLlvmModule(
llvm::Module* module, const ::tensorflow::protobuf::MessageLite& proto,
- StringPiece unique_identifier, string* protobuf_array_symbol_name,
+ absl::string_view unique_identifier, string* protobuf_array_symbol_name,
int64* protobuf_array_size) {
string protobuf_array_contents = proto.SerializeAsString();
*protobuf_array_symbol_name =
- strings::StrCat(unique_identifier, "_protobuf_array_contents");
+ absl::StrCat(unique_identifier, "_protobuf_array_contents");
*protobuf_array_size = protobuf_array_contents.size();
llvm::Constant* protobuf_array_initializer =
@@ -55,9 +55,9 @@ static void AddEmbeddedProtocolBufferToLlvmModule(
protobuf_array_initializer, AsStringRef(*protobuf_array_symbol_name));
}
-static string CreateCPPShimExpression(StringPiece qualified_cpp_protobuf_name,
- StringPiece protobuf_array_symbol_name,
- int64 protobuf_array_size) {
+static string CreateCPPShimExpression(
+ absl::string_view qualified_cpp_protobuf_name,
+ absl::string_view protobuf_array_symbol_name, int64 protobuf_array_size) {
string code =
"[]() {\n"
" {{PROTOBUF_NAME}}* proto = new {{PROTOBUF_NAME}};\n"
@@ -65,14 +65,13 @@ static string CreateCPPShimExpression(StringPiece qualified_cpp_protobuf_name,
" return proto;\n"
" }()";
- str_util::ReplaceAllPairs(
- &code,
+ return absl::StrReplaceAll(
+ code,
{
- {"{{ARRAY_SYMBOL}}", strings::StrCat(protobuf_array_symbol_name)},
- {"{{ARRAY_SIZE}}", strings::StrCat(protobuf_array_size)},
- {"{{PROTOBUF_NAME}}", strings::StrCat(qualified_cpp_protobuf_name)},
+ {"{{ARRAY_SYMBOL}}", absl::StrCat(protobuf_array_symbol_name)},
+ {"{{ARRAY_SIZE}}", absl::StrCat(protobuf_array_size)},
+ {"{{PROTOBUF_NAME}}", absl::StrCat(qualified_cpp_protobuf_name)},
});
- return code;
}
static StatusOr CodegenModule(llvm::TargetMachine* target_machine,
@@ -94,10 +93,10 @@ static StatusOr CodegenModule(llvm::TargetMachine* target_machine,
}
static StatusOr>
-GetTargetMachineFromTriple(StringPiece target_triple) {
+GetTargetMachineFromTriple(absl::string_view target_triple) {
std::string error;
std::string normalized_triple =
- llvm::Triple::normalize(AsStringRef(target_triple));
+ llvm::Triple::normalize(AsStringRef(absl::string_view(target_triple)));
const llvm::Target* target =
llvm::TargetRegistry::lookupTarget(normalized_triple, error);
if (target == nullptr) {
@@ -111,8 +110,8 @@ GetTargetMachineFromTriple(StringPiece target_triple) {
}
StatusOr CreateEmbeddedProtocolBuffers(
- StringPiece target_triple,
- gtl::ArraySlice protobufs_to_embed) {
+ absl::string_view target_triple,
+ absl::Span protobufs_to_embed) {
TF_ASSIGN_OR_RETURN(std::unique_ptr target_machine,
GetTargetMachineFromTriple(target_triple));
@@ -136,8 +135,8 @@ StatusOr CreateEmbeddedProtocolBuffers(
protobuf_to_embed.qualified_cpp_protobuf_name,
protobuf_array_symbol_name, protobuf_array_size);
- cpp_variable_decl = strings::StrCat("extern \"C\" char ",
- protobuf_array_symbol_name, "[];");
+ cpp_variable_decl =
+ absl::StrCat("extern \"C\" char ", protobuf_array_symbol_name, "[];");
} else {
cpp_shim = "nullptr";
}
diff --git a/tensorflow/compiler/aot/embedded_protocol_buffers.h b/tensorflow/compiler/aot/embedded_protocol_buffers.h
index 4e194a6aba9a9efcad27c47c42e148d8e537ae68..cf5c04ac4bdff73b76a365c346f7db60ce2d8197 100644
--- a/tensorflow/compiler/aot/embedded_protocol_buffers.h
+++ b/tensorflow/compiler/aot/embedded_protocol_buffers.h
@@ -20,8 +20,8 @@ limitations under the License.
#ifndef TENSORFLOW_COMPILER_AOT_EMBEDDED_PROTOCOL_BUFFERS_H_
#define TENSORFLOW_COMPILER_AOT_EMBEDDED_PROTOCOL_BUFFERS_H_
+#include "absl/types/span.h"
#include "tensorflow/compiler/xla/statusor.h"
-#include "tensorflow/core/lib/gtl/array_slice.h"
#include "tensorflow/core/platform/protobuf.h"
namespace tensorflow {
@@ -83,8 +83,8 @@ struct ProtobufToEmbed {
// is stored in the object_file_data field in the returned
// EmbeddedProtocolBuffers instance.
StatusOr CreateEmbeddedProtocolBuffers(
- StringPiece target_triple,
- gtl::ArraySlice protobufs_to_embed);
+ absl::string_view target_triple,
+ absl::Span protobufs_to_embed);
} // namespace tfcompile
} // namespace tensorflow
diff --git a/tensorflow/compiler/aot/tests/BUILD b/tensorflow/compiler/aot/tests/BUILD
index 0ecc3feeb6fef1dd691ab2785b3221075a79ba88..8d94f5495cdb64fdb8a453c5b591564dd4990dcf 100644
--- a/tensorflow/compiler/aot/tests/BUILD
+++ b/tensorflow/compiler/aot/tests/BUILD
@@ -67,7 +67,12 @@ genrule(
"test_graph_tfmatmulandadd.pb",
"test_graph_tfsplits.pb",
],
- cmd = "$(location :make_test_graphs) --out_dir $(@D)",
+ # Set CUDA_VISIBLE_DEVICES='' to prevent the code we launch from using any
+ # GPUs which might be present. This is important because builds may run
+ # concurrently with tests, and tests need to be able to assume that they
+ # have control of the full GPU.
+ cmd = "CUDA_VISIBLE_DEVICES='' " +
+ "$(location :make_test_graphs) --out_dir $(@D)",
tags = ["manual"],
tools = [":make_test_graphs"],
)
@@ -187,6 +192,9 @@ tf_library(
cpp_class = "MatMulAndAddCompWithProfiling",
enable_xla_hlo_profiling = True,
graph = "test_graph_tfmatmulandadd.pb",
+ tags = [
+ "manual",
+ ],
)
tf_library(
@@ -226,5 +234,6 @@ tf_cc_test(
"//tensorflow/core:test",
"//tensorflow/core:test_main",
"//third_party/eigen3",
+ "@com_google_absl//absl/strings",
],
)
diff --git a/tensorflow/compiler/aot/tests/tfcompile_test.cc b/tensorflow/compiler/aot/tests/tfcompile_test.cc
index 0c0c676ece78565e03578d3e33633c7e23b77669..dd2b151098f2054571ac32b8b506cbc00659588a 100644
--- a/tensorflow/compiler/aot/tests/tfcompile_test.cc
+++ b/tensorflow/compiler/aot/tests/tfcompile_test.cc
@@ -16,6 +16,7 @@ limitations under the License.
#define EIGEN_USE_THREADS
#define EIGEN_USE_CUSTOM_THREAD_POOL
+#include "absl/strings/str_split.h"
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#include "tensorflow/compiler/aot/tests/test_graph_tfadd.h"
#include "tensorflow/compiler/aot/tests/test_graph_tfadd_with_ckpt.h"
@@ -32,7 +33,6 @@ limitations under the License.
#include "tensorflow/compiler/xla/shape_util.h"
#include "tensorflow/compiler/xla/test.h"
#include "tensorflow/compiler/xla/xla_data.pb.h"
-#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/platform/test.h"
namespace tensorflow {
@@ -546,7 +546,7 @@ TEST(TFCompileTest, HloProfiling) {
VLOG(1) << "HLO profile string:\n" << hlo_profile_as_string;
std::vector hlo_profile_lines =
- tensorflow::str_util::Split(hlo_profile_as_string, '\n');
+ absl::StrSplit(hlo_profile_as_string, '\n');
auto header = HasSubstr("Execution profile for");
auto total_cycles_profile_line = HasSubstr("[total]");
diff --git a/tensorflow/compiler/aot/tfcompile.bzl b/tensorflow/compiler/aot/tfcompile.bzl
index 326f73b975aec3a7a6bc7cdc9a92f540ad545ad6..792b7fe14abf91626a0aeb75cdbe319b123ec10c 100644
--- a/tensorflow/compiler/aot/tfcompile.bzl
+++ b/tensorflow/compiler/aot/tfcompile.bzl
@@ -105,12 +105,18 @@ def tf_library(
freeze_file = freeze_name + ".pb"
# First run tfcompile to generate the list of out_nodes.
+ #
+ # Here and below, we set CUDA_VISIBLE_DEVICES='' to prevent the code we
+ # launch from using any GPUs which might be present. This is important
+ # because builds may run concurrently with tests, and tests need to be
+ # able to assume that they have control of the full GPU.
out_nodes_file = "out_nodes_" + freeze_name
native.genrule(
name = ("gen_" + out_nodes_file),
srcs = [config],
outs = [out_nodes_file],
- cmd = ("$(location " + tfcompile_tool + ")" +
+ cmd = ("CUDA_VISIBLE_DEVICES='' " +
+ "$(location " + tfcompile_tool + ")" +
" --config=$(location " + config + ")" +
" --dump_fetch_nodes > $@"),
tools = [tfcompile_tool],
@@ -142,9 +148,12 @@ def tf_library(
out_nodes_file,
] + freeze_saver_srcs,
outs = [freeze_file],
- cmd = ("$(location " +
- "//tensorflow/python/tools:freeze_graph)" +
- freeze_args),
+ cmd = (
+ "CUDA_VISIBLE_DEVICES='' " +
+ "$(location " +
+ "//tensorflow/python/tools:freeze_graph)" +
+ freeze_args
+ ),
tools = ["//tensorflow/python/tools:freeze_graph"],
tags = tags,
)
@@ -177,16 +186,19 @@ def tf_library(
metadata_object_file,
function_object_file,
],
- cmd = ("$(location " + tfcompile_tool + ")" +
- " --graph=$(location " + tfcompile_graph + ")" +
- " --config=$(location " + config + ")" +
- " --entry_point=" + ep +
- " --cpp_class=" + cpp_class +
- " --target_triple=" + target_llvm_triple() +
- " --out_header=$(@D)/" + header_file +
- " --out_metadata_object=$(@D)/" + metadata_object_file +
- " --out_function_object=$(@D)/" + function_object_file +
- " " + flags + " " + profiling_flag),
+ cmd = (
+ "CUDA_VISIBLE_DEVICES='' " +
+ "$(location " + tfcompile_tool + ")" +
+ " --graph=$(location " + tfcompile_graph + ")" +
+ " --config=$(location " + config + ")" +
+ " --entry_point=" + ep +
+ " --cpp_class=" + cpp_class +
+ " --target_triple=" + target_llvm_triple() +
+ " --out_header=$(@D)/" + header_file +
+ " --out_metadata_object=$(@D)/" + metadata_object_file +
+ " --out_function_object=$(@D)/" + function_object_file +
+ " " + flags + " " + profiling_flag
+ ),
tools = [tfcompile_tool],
visibility = visibility,
testonly = testonly,
@@ -216,14 +228,17 @@ def tf_library(
outs = [
session_module_pb,
],
- cmd = ("$(location " + tfcompile_tool + ")" +
- " --graph=$(location " + tfcompile_graph + ")" +
- " --config=$(location " + config + ")" +
- " --entry_point=" + ep +
- " --cpp_class=" + cpp_class +
- " --target_triple=" + target_llvm_triple() +
- " --out_session_module=$(@D)/" + session_module_pb +
- " " + flags),
+ cmd = (
+ "CUDA_VISIBLE_DEVICES='' " +
+ "$(location " + tfcompile_tool + ")" +
+ " --graph=$(location " + tfcompile_graph + ")" +
+ " --config=$(location " + config + ")" +
+ " --entry_point=" + ep +
+ " --cpp_class=" + cpp_class +
+ " --target_triple=" + target_llvm_triple() +
+ " --out_session_module=$(@D)/" + session_module_pb +
+ " " + flags
+ ),
tools = [tfcompile_tool],
visibility = visibility,
testonly = testonly,
diff --git a/tensorflow/compiler/aot/tfcompile_main.cc b/tensorflow/compiler/aot/tfcompile_main.cc
index 839e1588b7be6c91cf30c87bbaf75402446bd169..b95b063348c5cdfdcaed635ba527e9f0bfd6092d 100644
--- a/tensorflow/compiler/aot/tfcompile_main.cc
+++ b/tensorflow/compiler/aot/tfcompile_main.cc
@@ -18,6 +18,9 @@ limitations under the License.
#include
#include
+#include "absl/strings/match.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
#include "tensorflow/compiler/aot/codegen.h"
#include "tensorflow/compiler/aot/compile.h"
#include "tensorflow/compiler/aot/flags.h"
@@ -32,9 +35,7 @@ limitations under the License.
#include "tensorflow/core/graph/graph.h"
#include "tensorflow/core/graph/tensor_id.h"
#include "tensorflow/core/lib/core/errors.h"
-#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/strings/numbers.h"
-#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/logging.h"
@@ -55,7 +56,7 @@ const char kUsageHeader[] =
"\n";
Status ReadProtoFile(const string& fname, protobuf::Message* proto) {
- if (str_util::EndsWith(fname, ".pbtxt")) {
+ if (absl::EndsWith(fname, ".pbtxt")) {
return ReadTextProto(Env::Default(), fname, proto);
} else {
return ReadBinaryProto(Env::Default(), fname, proto);
@@ -75,7 +76,7 @@ Status Main(const MainFlags& flags) {
for (const tf2xla::Fetch& fetch : config.fetch()) {
nodes.insert(fetch.id().node_name());
}
- std::cout << str_util::Join(nodes, ",");
+ std::cout << absl::StrJoin(nodes, ",");
return Status::OK();
}
@@ -91,8 +92,9 @@ Status Main(const MainFlags& flags) {
// Write output files.
Env* env = Env::Default();
const std::vector& obj = compile_result.aot->object_file_data();
- TF_RETURN_IF_ERROR(WriteStringToFile(env, flags.out_function_object,
- StringPiece(obj.data(), obj.size())));
+ TF_RETURN_IF_ERROR(
+ WriteStringToFile(env, flags.out_function_object,
+ absl::string_view(obj.data(), obj.size())));
CodegenOpts codegen_opts;
codegen_opts.gen_name_to_index = flags.gen_name_to_index;
codegen_opts.gen_program_shape = flags.gen_program_shape;
diff --git a/tensorflow/compiler/jit/BUILD b/tensorflow/compiler/jit/BUILD
index 2466c218c82dbd504043dbfff70fb3ba88d38e3b..352f63bc98000d250107f11954da814886ca9c52 100644
--- a/tensorflow/compiler/jit/BUILD
+++ b/tensorflow/compiler/jit/BUILD
@@ -310,6 +310,51 @@ tf_cc_test(
],
)
+cc_library(
+ name = "resource_operation_safety_analysis",
+ srcs = ["resource_operation_safety_analysis.cc"],
+ hdrs = ["resource_operation_safety_analysis.h"],
+ deps = [
+ "//tensorflow/compiler/jit/graphcycles",
+ "//tensorflow/compiler/tf2xla:resource_operation_table",
+ "//tensorflow/core:framework",
+ "//tensorflow/core:graph",
+ "//tensorflow/core:lib",
+ "//tensorflow/core:protos_all_cc",
+ "@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
+ "@com_google_absl//absl/types:optional",
+ ],
+)
+
+tf_cc_test(
+ name = "resource_operation_safety_analysis_test",
+ srcs = ["resource_operation_safety_analysis_test.cc"],
+ deps = [
+ ":common",
+ ":resource_operation_safety_analysis",
+ "//tensorflow/cc:cc_ops",
+ "//tensorflow/cc:cc_ops_internal",
+ "//tensorflow/cc:function_ops",
+ "//tensorflow/cc:functional_ops",
+ "//tensorflow/cc:ops",
+ "//tensorflow/cc:resource_variable_ops",
+ "//tensorflow/cc:sendrecv_ops",
+ "//tensorflow/compiler/jit/kernels:xla_launch_op",
+ "//tensorflow/compiler/tf2xla:xla_compiler",
+ "//tensorflow/compiler/tf2xla/kernels:xla_ops",
+ "//tensorflow/core:core_cpu",
+ "//tensorflow/core:framework",
+ "//tensorflow/core:framework_internal",
+ "//tensorflow/core:graph",
+ "//tensorflow/core:lib",
+ "//tensorflow/core:test",
+ "//tensorflow/core:test_main",
+ "//tensorflow/core:testlib",
+ "@com_google_absl//absl/strings",
+ ],
+)
+
cc_library(
name = "compilation_passes",
srcs = [
@@ -317,6 +362,7 @@ cc_library(
"deadness_analysis.cc",
"deadness_analysis_internal.h",
"encapsulate_subgraphs_pass.cc",
+ "encapsulate_xla_computations_pass.cc",
"mark_for_compilation_pass.cc",
"mark_for_compilation_pass_test_helper.cc",
"partially_decluster_pass.cc",
@@ -325,6 +371,7 @@ cc_library(
"build_xla_launch_ops_pass.h",
"deadness_analysis.h",
"encapsulate_subgraphs_pass.h",
+ "encapsulate_xla_computations_pass.h",
"mark_for_compilation_pass.h",
"mark_for_compilation_pass_test_helper.h",
"partially_decluster_pass.h",
@@ -335,11 +382,10 @@ cc_library(
":union_find",
":xla_cluster_util",
"//tensorflow/compiler/jit/graphcycles",
- "//tensorflow/compiler/jit/kernels:parallel_check_op",
"//tensorflow/compiler/jit/legacy_flags:mark_for_compilation_pass_flags",
- "//tensorflow/compiler/jit/ops:parallel_check_op",
"//tensorflow/compiler/jit/ops:xla_ops",
"//tensorflow/compiler/tf2xla:dump_graph",
+ "//tensorflow/compiler/tf2xla:resource_operation_table",
"//tensorflow/compiler/tf2xla:xla_compiler",
"//tensorflow/compiler/xla:status_macros",
"//tensorflow/compiler/xla:util",
@@ -351,6 +397,9 @@ cc_library(
"//tensorflow/core:lib_internal",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core/kernels:bounds_check",
+ "@com_google_absl//absl/algorithm:container",
+ "@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
],
)
@@ -359,11 +408,13 @@ cc_library(
srcs = ["xla_cluster_util.cc"],
hdrs = ["xla_cluster_util.h"],
deps = [
+ ":resource_operation_safety_analysis",
"//tensorflow/compiler/jit/graphcycles",
"//tensorflow/core:framework",
"//tensorflow/core:graph",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core/kernels:bounds_check",
+ "@com_google_absl//absl/strings",
"@com_google_absl//absl/types:optional",
],
)
@@ -426,6 +477,7 @@ tf_cc_test(
size = "small",
srcs = [
"encapsulate_subgraphs_pass_test.cc",
+ "encapsulate_xla_computations_pass_test.cc",
"mark_for_compilation_pass_test.cc",
"partially_decluster_pass_test.cc",
],
@@ -433,13 +485,17 @@ tf_cc_test(
":common",
":compilation_passes",
":xla_cluster_util",
+ ":xla_gpu_device",
"//tensorflow/cc:cc_ops",
"//tensorflow/cc:cc_ops_internal",
"//tensorflow/cc:function_ops",
"//tensorflow/cc:ops",
+ "//tensorflow/cc:resource_variable_ops",
"//tensorflow/cc:sendrecv_ops",
"//tensorflow/compiler/jit/kernels:xla_launch_op",
+ "//tensorflow/compiler/tf2xla:test_util",
"//tensorflow/compiler/tf2xla:xla_compiler",
+ "//tensorflow/compiler/tf2xla/cc:xla_jit_ops",
"//tensorflow/compiler/tf2xla/kernels:xla_ops",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
@@ -448,6 +504,9 @@ tf_cc_test(
"//tensorflow/core:test",
"//tensorflow/core:test_main",
"//tensorflow/core:testlib",
+ "//tensorflow/core/grappler/optimizers/data:graph_utils",
+ "@com_google_absl//absl/memory",
+ "@com_google_absl//absl/strings",
],
)
@@ -518,6 +577,7 @@ cc_library(
"//tensorflow/core/grappler:grappler_item",
"//tensorflow/core/grappler/optimizers:custom_graph_optimizer",
"//tensorflow/core/grappler/optimizers:custom_graph_optimizer_registry",
+ "@com_google_absl//absl/strings",
],
)
@@ -528,6 +588,9 @@ tf_cuda_cc_test(
":common",
":xla_cluster_util",
":xla_fusion_optimizer",
+ "//tensorflow/cc:cc_ops",
+ "//tensorflow/cc:ops",
+ "//tensorflow/cc:resource_variable_ops",
"//tensorflow/core:graph",
"//tensorflow/core:test",
"//tensorflow/core:test_main",
diff --git a/tensorflow/compiler/jit/create_xla_launch_op.cc b/tensorflow/compiler/jit/create_xla_launch_op.cc
index 1b1ce78ed2b79d0948b6fc951f82a2cebe8009e5..56b034a30b7bddb023e54ead22c91a7a18095d2d 100644
--- a/tensorflow/compiler/jit/create_xla_launch_op.cc
+++ b/tensorflow/compiler/jit/create_xla_launch_op.cc
@@ -126,7 +126,8 @@ Status GetBodyAndConstantsAndResources(FunctionLibraryRuntime* flr,
const DataTypeVector& arg_types = (*fbody)->arg_types;
std::vector const_args(arg_types.size());
// If we can't analyze the const args. Bail out.
- TF_RETURN_IF_ERROR(BackwardsConstAnalysis(*((*fbody)->graph), &const_args));
+ TF_RETURN_IF_ERROR(BackwardsConstAnalysis(
+ *((*fbody)->graph), &const_args, /*compile_time_const_nodes=*/nullptr));
for (int i = 0; i < const_args.size(); ++i) {
if (const_args[i]) {
@@ -208,8 +209,13 @@ Status CreateXlaLaunchOp(FunctionLibraryRuntime* flr, const NodeDef& node_def,
// device memory.
// XlaLaunch kernel keeps all outputs (including constants, which it copies),
- // in device memory
+ // in device memory except for resources.
MemoryTypeVector output_memory_types(fbody->ret_types.size(), DEVICE_MEMORY);
+ for (int i = 0; i < fbody->ret_types.size(); ++i) {
+ if (fbody->ret_types[i] == DT_RESOURCE) {
+ output_memory_types[i] = HOST_MEMORY;
+ }
+ }
// Create the kernel.
NameAttrList function;
diff --git a/tensorflow/compiler/jit/deadness_analysis.cc b/tensorflow/compiler/jit/deadness_analysis.cc
index 0ca0f949dcd13992ccd9504d75ca65d2aff72a19..9128b48da3fe9dd3d85d146e16c153c1b3bebf4c 100644
--- a/tensorflow/compiler/jit/deadness_analysis.cc
+++ b/tensorflow/compiler/jit/deadness_analysis.cc
@@ -14,6 +14,7 @@ limitations under the License.
==============================================================================*/
#include "tensorflow/compiler/jit/deadness_analysis.h"
+#include "absl/strings/str_join.h"
#include "tensorflow/compiler/jit/deadness_analysis_internal.h"
#include "tensorflow/core/graph/algorithm.h"
#include "tensorflow/core/graph/tensor_id.h"
@@ -107,7 +108,7 @@ class Predicate {
virtual string ToString() const = 0;
int64 hash() const { return hash_; }
- virtual gtl::ArraySlice GetOperands() const = 0;
+ virtual absl::Span GetOperands() const = 0;
virtual Kind kind() const = 0;
virtual ~Predicate() {}
@@ -128,7 +129,7 @@ class Predicate {
};
int64 HashPredicateSequence(Predicate::Kind kind,
- gtl::ArraySlice preds) {
+ absl::Span preds) {
int64 hash = ::tensorflow::hash()(kind);
for (Predicate* pred : preds) {
hash = Hash64Combine(hash, pred->hash());
@@ -153,13 +154,15 @@ class AndPredicate : public Predicate {
std::back_inserter(operands_str),
[](Predicate* pred) { return pred->ToString(); });
- return strings::StrCat("(", str_util::Join(operands_str, " & "), ")");
+ return absl::StrCat("(", absl::StrJoin(operands_str, " & "), ")");
}
Kind kind() const override { return Kind::kAnd; }
- gtl::ArraySlice GetOperands() const override { return operands_; }
- gtl::ArraySlice operands() const { return operands_; }
+ absl::Span GetOperands() const override {
+ return operands_;
+ }
+ absl::Span operands() const { return operands_; }
private:
std::vector operands_;
@@ -182,12 +185,14 @@ class OrPredicate : public Predicate {
std::back_inserter(operands_str),
[](Predicate* pred) { return pred->ToString(); });
- return strings::StrCat("(", str_util::Join(operands_str, " | "), ")");
+ return absl::StrCat("(", absl::StrJoin(operands_str, " | "), ")");
}
Kind kind() const override { return Kind::kOr; }
- gtl::ArraySlice GetOperands() const override { return operands_; }
- gtl::ArraySlice operands() const { return operands_; }
+ absl::Span GetOperands() const override {
+ return operands_;
+ }
+ absl::Span operands() const { return operands_; }
private:
std::vector operands_;
@@ -201,12 +206,14 @@ class NotPredicate : public Predicate {
operands_({operand}) {}
string ToString() const override {
- return strings::StrCat("~", operand()->ToString());
+ return absl::StrCat("~", operand()->ToString());
}
Kind kind() const override { return Kind::kNot; }
Predicate* operand() const { return operands_[0]; }
- gtl::ArraySlice GetOperands() const override { return operands_; }
+ absl::Span GetOperands() const override {
+ return operands_;
+ }
private:
std::array operands_;
@@ -233,13 +240,15 @@ class AndRecurrencePredicate : public Predicate {
Predicate* step() const { return operands_[1]; }
string ToString() const override {
- return strings::StrCat("{", start()->ToString(), ",&,", step()->ToString(),
- "}");
+ return absl::StrCat("{", start()->ToString(), ",&,", step()->ToString(),
+ "}");
}
Kind kind() const override { return Kind::kAndRecurrence; }
- gtl::ArraySlice GetOperands() const override { return operands_; }
+ absl::Span GetOperands() const override {
+ return operands_;
+ }
private:
std::array operands_;
@@ -258,12 +267,12 @@ class SymbolPredicate : public Predicate {
must_be_true_(must_be_true) {}
string ToString() const override {
- return must_be_true() ? strings::StrCat("*", tensor_id_.ToString())
+ return must_be_true() ? absl::StrCat("*", tensor_id_.ToString())
: tensor_id_.ToString();
}
Kind kind() const override { return Kind::kSymbol; }
- gtl::ArraySlice GetOperands() const override { return {}; }
+ absl::Span GetOperands() const override { return {}; }
// If `must_be_true()` is true this SymbolPredicate represents the proposition
// "tensor_id() is live and evaluates to true".
@@ -312,11 +321,11 @@ template
// them.
class PredicateFactory {
public:
- Predicate* MakeAndPredicate(gtl::ArraySlice operands) {
+ Predicate* MakeAndPredicate(absl::Span operands) {
return MakeAndOrImpl(operands, /*is_and=*/true);
}
- Predicate* MakeOrPredicate(gtl::ArraySlice operands) {
+ Predicate* MakeOrPredicate(absl::Span operands) {
return MakeAndOrImpl(operands, /*is_and=*/false);
}
@@ -373,7 +382,7 @@ class PredicateFactory {
new PredicateT(std::forward(args)...));
}
- Predicate* MakeAndOrImpl(gtl::ArraySlice operands, bool is_and);
+ Predicate* MakeAndOrImpl(absl::Span operands, bool is_and);
// Predicate instances are interned, meaning that there is only a single
// instance of a Predicate object with a given content. This makes checking
@@ -386,7 +395,7 @@ class PredicateFactory {
// for the owning pointers to predicate instances.
using SignatureForAndOr =
- std::pair>;
+ std::pair>;
using SignatureForNot = Predicate*;
using SignatureForAndRec = std::pair;
using SignatureForSymbol = std::pair;
@@ -421,8 +430,8 @@ class PredicateFactory {
};
// Common code to create AndPredicate or OrPredicate instances.
-Predicate* PredicateFactory::MakeAndOrImpl(gtl::ArraySlice operands,
- bool is_and) {
+Predicate* PredicateFactory::MakeAndOrImpl(
+ absl::Span operands, bool is_and) {
Predicate::Kind pred_kind =
is_and ? Predicate::Kind::kAnd : Predicate::Kind::kOr;
gtl::FlatSet simplified_ops_set;
@@ -473,7 +482,7 @@ Predicate* PredicateFactory::MakeAndOrImpl(gtl::ArraySlice operands,
// NB! Because we'll use a non-owning reference to simplified_ops in the
// key for interned_and_or_instances_ we need to be careful to std::move()
// it all the way through.
- gtl::ArraySlice operands_slice = simplified_ops;
+ absl::Span operands_slice = simplified_ops;
std::unique_ptr new_pred =
is_and ? Make(std::move(simplified_ops))
: Make(std::move(simplified_ops));
@@ -495,7 +504,7 @@ class DeadnessAnalysisImpl : public DeadnessAnalysis {
: graph_(*graph), vlog_(VLOG_IS_ON(2)) {}
Status Populate();
- Status PopulateWithReversePostOrder(gtl::ArraySlice rpo);
+ Status PopulateWithReversePostOrder(absl::Span rpo);
bool HasInputsWithMismatchingDeadness(const Node& node) override;
void Print() const override;
gtl::FlatMap PredicateMapAsString() const;
@@ -526,7 +535,7 @@ class DeadnessAnalysisImpl : public DeadnessAnalysis {
}
}
- void SetPredicate(Node* n, gtl::ArraySlice output_idxs, Predicate* pred,
+ void SetPredicate(Node* n, absl::Span output_idxs, Predicate* pred,
std::vector* should_revisit) {
for (int output_idx : output_idxs) {
SetPredicate(n, output_idx, pred, should_revisit);
@@ -624,7 +633,7 @@ Predicate* DeduceStepPredicate(PredicateFactory* predicate_factory,
}
std::vector and_ops;
- gtl::ArraySlice recurrent_pred_ops =
+ absl::Span recurrent_pred_ops =
backedge_predicate->GetOperands();
bool found_sym = false;
@@ -783,7 +792,7 @@ Status DeadnessAnalysisImpl::Populate() {
}
Status DeadnessAnalysisImpl::PopulateWithReversePostOrder(
- gtl::ArraySlice rpo) {
+ absl::Span rpo) {
// This an abstract interpretation over the deadness propagation semantics of
// the graph executor.
//
@@ -923,7 +932,7 @@ Status ComputePredicates(const Graph& graph,
}
Status ComputePredicates(const Graph& graph,
- gtl::ArraySlice reverse_post_order,
+ absl::Span reverse_post_order,
PredicateMapTy* out_predicate_map) {
DeadnessAnalysisImpl impl(&graph);
TF_RETURN_IF_ERROR(impl.PopulateWithReversePostOrder(reverse_post_order));
diff --git a/tensorflow/compiler/jit/deadness_analysis_internal.h b/tensorflow/compiler/jit/deadness_analysis_internal.h
index 401d6e406ab3db81d0cbd69b480d5962dab1f357..3df2679c629ce801fc6c9006415dcd27b40c078e 100644
--- a/tensorflow/compiler/jit/deadness_analysis_internal.h
+++ b/tensorflow/compiler/jit/deadness_analysis_internal.h
@@ -32,7 +32,7 @@ Status ComputePredicates(const Graph& graph, PredicateMapTy* out_predicate_map);
// specified in `reverse_post_order` which must be a valid RPO for the graph
// minus NextIteration->Merge edges.
Status ComputePredicates(const Graph& graph,
- gtl::ArraySlice reverse_post_order,
+ absl::Span reverse_post_order,
PredicateMapTy* out_predicate_map);
} // namespace deadness_analysis_internal
} // namespace tensorflow
diff --git a/tensorflow/compiler/jit/deadness_analysis_test.cc b/tensorflow/compiler/jit/deadness_analysis_test.cc
index cc9f1023985560be0bce5971931d2ec8e742b377..28a56044d5e3795fc3ecf5d1092491b87cb90f01 100644
--- a/tensorflow/compiler/jit/deadness_analysis_test.cc
+++ b/tensorflow/compiler/jit/deadness_analysis_test.cc
@@ -32,7 +32,6 @@ limitations under the License.
#include "tensorflow/core/graph/graph_def_builder.h"
#include "tensorflow/core/graph/graph_def_builder_util.h"
#include "tensorflow/core/lib/core/status_test_util.h"
-#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/platform/test.h"
namespace tensorflow {
diff --git a/tensorflow/compiler/jit/encapsulate_subgraphs_pass.cc b/tensorflow/compiler/jit/encapsulate_subgraphs_pass.cc
index f150bf1819d407e1c6a279673a89de4307b5426b..e0632ff7e48ccea99d469f62ec9d0a3fe8295024 100644
--- a/tensorflow/compiler/jit/encapsulate_subgraphs_pass.cc
+++ b/tensorflow/compiler/jit/encapsulate_subgraphs_pass.cc
@@ -22,6 +22,8 @@ limitations under the License.
#include
#include
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
#include "tensorflow/compiler/jit/graphcycles/graphcycles.h"
#include "tensorflow/compiler/jit/mark_for_compilation_pass.h"
#include "tensorflow/compiler/jit/shape_inference_helpers.h"
@@ -36,6 +38,7 @@ limitations under the License.
#include "tensorflow/core/framework/graph_to_functiondef.h"
#include "tensorflow/core/framework/node_def_builder.h"
#include "tensorflow/core/framework/node_def_util.h"
+#include "tensorflow/core/framework/tensor.pb.h"
#include "tensorflow/core/graph/algorithm.h"
#include "tensorflow/core/graph/control_flow.h"
#include "tensorflow/core/graph/graph.h"
@@ -44,8 +47,6 @@ limitations under the License.
#include "tensorflow/core/lib/gtl/flatset.h"
#include "tensorflow/core/lib/gtl/map_util.h"
#include "tensorflow/core/lib/hash/hash.h"
-#include "tensorflow/core/lib/strings/str_util.h"
-#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/core/public/version.h"
#include "tensorflow/core/util/device_name_utils.h"
@@ -58,6 +59,22 @@ const char* const kXlaNumResourceArgsAttr = "_XlaNumResourceArgs";
const char* const kXlaHostTransferSequencerAttr =
"_xla_host_transfer_sequencer";
+void SortControlInputs(GraphDef* gdef) {
+ int64 num_nodes = gdef->node_size();
+ for (int64 i = 0; i < num_nodes; ++i) {
+ NodeDef* node = gdef->mutable_node(i);
+ // Stable sort control inputs and leave the order of data inputs unchanged.
+ std::stable_sort(node->mutable_input()->begin(),
+ node->mutable_input()->end(),
+ [](const string& a, const string& b) {
+ bool a_is_control = absl::StartsWith(a, "^");
+ bool b_is_control = absl::StartsWith(b, "^");
+ return (!a_is_control && b_is_control) ||
+ (a_is_control && b_is_control && a < b);
+ });
+ }
+}
+
namespace {
bool AreAllParentsGuaranteedConst(
@@ -755,7 +772,7 @@ Status Encapsulator::Subgraph::RecordArg(
if (inserted) {
NodeDef arg_def;
NodeDefBuilder builder(
- strings::StrCat(src_node->name(), "_", src_slot, "_arg"), kArgOp);
+ absl::StrCat(src_node->name(), "_", src_slot, "_arg"), kArgOp);
DataType dtype = edge->dst()->input_type(edge->dst_input());
builder.Attr("T", dtype);
builder.Attr("index", arg_index);
@@ -790,7 +807,7 @@ Status Encapsulator::Subgraph::RecordResult(
if (inserted) {
NodeDef ret_def;
NodeDefBuilder builder(
- strings::StrCat(src_node->name(), "_", src_slot, "_retval"), kRetValOp);
+ absl::StrCat(src_node->name(), "_", src_slot, "_retval"), kRetValOp);
DataType dtype = src_node->output_type(src_slot);
builder.Attr("T", dtype);
builder.Attr("index", ret_index);
@@ -950,16 +967,15 @@ Status Encapsulator::Subgraph::AddHostComputes(
}
NodeDef host_compute_def;
- NodeDefBuilder builder(strings::StrCat("outside_compilation_",
- oc_subgraph_name, "_host_compute"),
+ NodeDefBuilder builder(absl::StrCat("outside_compilation_",
+ oc_subgraph_name, "_host_compute"),
kHostComputeOp);
builder.Input(inputs);
builder.Attr("Tinputs", input_dtypes);
builder.Attr("Toutputs", output_dtypes);
builder.Attr("ancestors", host_compute_ancestors);
- builder.Attr("key",
- strings::StrCat("host_compute_channel_", subgraph_name, "_",
- oc_subgraph_name));
+ builder.Attr("key", absl::StrCat("host_compute_channel_", subgraph_name,
+ "_", oc_subgraph_name));
builder.Attr("_outside_compilation_subgraph", oc_subgraph_name);
Status s = builder.Finalize(&host_compute_def);
if (!s.ok()) return s;
@@ -1017,8 +1033,7 @@ Status Encapsulator::Subgraph::MakeSequencingNode(const string& subgraph_name,
Graph* graph_out) {
if (sequencer_ == nullptr) {
NodeDef seq_def;
- NodeDefBuilder builder(strings::StrCat(subgraph_name, "_sequencer"),
- "NoOp");
+ NodeDefBuilder builder(absl::StrCat(subgraph_name, "_sequencer"), "NoOp");
builder.Attr(kXlaHostTransferSequencerAttr, subgraph_name);
builder.Device(device_);
Status s = builder.Finalize(&seq_def);
@@ -1091,10 +1106,10 @@ Status Encapsulator::Subgraph::BuildFunctionDef(
if (VLOG_IS_ON(1)) {
VLOG(2) << "Build function def " << name;
- dump_graph::DumpGraphToFile(
- strings::StrCat("encapsulate_fdef_graph_", name), *graph_, library);
- dump_graph::DumpFunctionDefToFile(
- strings::StrCat("encapsulate_fdef_", name), fdef);
+ dump_graph::DumpGraphToFile(absl::StrCat("encapsulate_fdef_graph_", name),
+ *graph_, library);
+ dump_graph::DumpFunctionDefToFile(absl::StrCat("encapsulate_fdef_", name),
+ fdef);
}
if (!reuse_existing_functions || library->Find(name) == nullptr) {
@@ -1130,8 +1145,8 @@ Status Encapsulator::Subgraph::AddShapeInferenceInfo(
host_compute->AddAttr("shapes", shapes);
} else {
string inference_graph_name =
- strings::StrCat("_outside_compilation_shape_inference_", subgraph_name,
- "_", outside_compilation_subgraph_name);
+ absl::StrCat("_outside_compilation_shape_inference_", subgraph_name,
+ "_", outside_compilation_subgraph_name);
FunctionDef fdef;
TF_RETURN_IF_ERROR(
GraphToFunctionDef(*inference_graph, inference_graph_name, &fdef));
@@ -1155,10 +1170,10 @@ Status Encapsulator::Subgraph::ReplaceFunctionDef(
if (VLOG_IS_ON(1)) {
VLOG(2) << "Replace function def " << name;
dump_graph::DumpGraphToFile(
- strings::StrCat("replace_encapsulate_fdef_graph_", name), *graph_,
+ absl::StrCat("replace_encapsulate_fdef_graph_", name), *graph_,
library);
dump_graph::DumpFunctionDefToFile(
- strings::StrCat("replace_encapsulate_fdef_", name), fdef);
+ absl::StrCat("replace_encapsulate_fdef_", name), fdef);
}
TF_RETURN_IF_ERROR(library->ReplaceFunction(name, fdef));
@@ -1186,8 +1201,7 @@ Status Encapsulator::Subgraph::AddHostComputeKeyPlaceholder(
GraphDefBuilder::Options options(graph_out, /*status=*/nullptr);
NodeDef key_def;
NodeDefBuilder builder(
- strings::StrCat(call_node_def_.name(), "_key_placeholder"),
- "Placeholder");
+ absl::StrCat(call_node_def_.name(), "_key_placeholder"), "Placeholder");
builder.Attr("dtype", DT_STRING);
builder.Attr("shape", shape_proto);
builder.Attr("_host_compute_call_node", call_node_def_.name());
@@ -1221,16 +1235,16 @@ Status Encapsulator::Subgraph::AddRecvAtHostNode(
}
NodeDef recv_def;
- NodeDefBuilder builder(strings::StrCat("outside_compilation_", subgraph_name,
- "_", oc_subgraph_name, "_recv"),
+ NodeDefBuilder builder(absl::StrCat("outside_compilation_", subgraph_name,
+ "_", oc_subgraph_name, "_recv"),
kRecvAtHostOp);
builder.Device(device_);
builder.Attr("Toutputs", dtypes);
// The correct device_ordinal will be inserted during replication in a
// subsequent rewrite.
builder.Attr("device_ordinal", 0);
- builder.Attr("key", strings::StrCat("host_compute_channel_", subgraph_name,
- "_", oc_subgraph_name));
+ builder.Attr("key", absl::StrCat("host_compute_channel_", subgraph_name, "_",
+ oc_subgraph_name));
builder.Attr(group_attribute, subgraph_name);
builder.Attr(outside_compilation_attribute, oc_subgraph_name);
builder.Input(host_compute_key_placeholder_->name(), 0, DT_STRING);
@@ -1276,13 +1290,13 @@ Status Encapsulator::Subgraph::AddSendFromHostNode(
}
NodeDef send_def;
- NodeDefBuilder builder(strings::StrCat("outside_compilation_", subgraph_name,
- "_", oc_subgraph_name, "_send"),
+ NodeDefBuilder builder(absl::StrCat("outside_compilation_", subgraph_name,
+ "_", oc_subgraph_name, "_send"),
kSendFromHostOp);
builder.Device(device_);
builder.Attr("Tinputs", dtypes);
- builder.Attr("key", strings::StrCat("host_compute_channel_", subgraph_name,
- "_", oc_subgraph_name));
+ builder.Attr("key", absl::StrCat("host_compute_channel_", subgraph_name, "_",
+ oc_subgraph_name));
// The correct device_ordinal will be inserted during replication in a
// subsequent rewrite.
builder.Attr("device_ordinal", 0);
@@ -1516,7 +1530,7 @@ Status Encapsulator::SplitIntoSubgraphs(FunctionLibraryDefinition* library) {
// Dump subgraphs.
for (auto& entry : subgraphs_) {
dump_graph::DumpGraphToFile(
- strings::StrCat("encapsulate_subgraphs_subgraph_", entry.first),
+ absl::StrCat("encapsulate_subgraphs_subgraph_", entry.first),
*entry.second.GetGraph(), library);
}
}
@@ -2052,7 +2066,7 @@ struct PathDetails {
struct SubgraphAndClusterHash {
inline std::size_t operator()(const SubgraphAndCluster& v) const {
return hash()(
- strings::StrCat(v.subgraph, v.outside_compilation_cluster));
+ absl::StrCat(v.subgraph, v.outside_compilation_cluster));
}
};
@@ -2504,7 +2518,8 @@ Status EncapsulateSubgraphsPass::Run(
const int num_args = input_permutation->size();
std::vector const_args(num_args);
- TF_RETURN_IF_ERROR(BackwardsConstAnalysis(**subgraph, &const_args));
+ TF_RETURN_IF_ERROR(BackwardsConstAnalysis(
+ **subgraph, &const_args, /*compile_time_const_nodes=*/nullptr));
DataTypeVector arg_types(num_args);
TF_RETURN_IF_ERROR(GetArgTypes(**subgraph, &arg_types));
diff --git a/tensorflow/compiler/jit/encapsulate_subgraphs_pass.h b/tensorflow/compiler/jit/encapsulate_subgraphs_pass.h
index 926589546fec72048485d30966f31b24e44b1245..90354a801afb26b003e00c4529069fdc61bbca32 100644
--- a/tensorflow/compiler/jit/encapsulate_subgraphs_pass.h
+++ b/tensorflow/compiler/jit/encapsulate_subgraphs_pass.h
@@ -102,6 +102,12 @@ extern const char* const kXlaNumConstantArgsAttr;
// Name of the attribute containing the number of resource variable arguments.
extern const char* const kXlaNumResourceArgsAttr;
+// Sorts each node's control inputs by their names. This guarantees that for two
+// structually equivalent GraphDefs, we get the same traversal ordering on
+// node's control input fields.
+// TODO(hpucha): Move the utilities to a more appropriate place.
+void SortControlInputs(GraphDef* gdef);
+
class EncapsulateSubgraphsPass : public GraphOptimizationPass {
public:
Status Run(const GraphOptimizationPassOptions& options) override;
diff --git a/tensorflow/compiler/jit/encapsulate_subgraphs_pass_test.cc b/tensorflow/compiler/jit/encapsulate_subgraphs_pass_test.cc
index c0543a00792235c5dd090e81930d8c219dc7f1a3..49958093b8dcf35e8adcdfd2f7dfce8558d5db6f 100644
--- a/tensorflow/compiler/jit/encapsulate_subgraphs_pass_test.cc
+++ b/tensorflow/compiler/jit/encapsulate_subgraphs_pass_test.cc
@@ -16,8 +16,10 @@ limitations under the License.
#include
#include
+#include "absl/strings/str_cat.h"
#include "tensorflow/compiler/jit/encapsulate_subgraphs_pass.h"
+#include "absl/strings/match.h"
#include "tensorflow/cc/framework/ops.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/function_testlib.h"
@@ -25,7 +27,6 @@ limitations under the License.
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/graph/graph_def_builder.h"
#include "tensorflow/core/lib/core/status_test_util.h"
-#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/util/equal_graph_def.h"
@@ -48,7 +49,7 @@ Status AddGraphDefToFunctionLibrary(const GraphDefBuilder& graphdef_builder,
FunctionDef* fdef = library->add_function();
TF_RETURN_IF_ERROR(GraphToFunctionDef(
*graph,
- strings::StrCat("_outside_compilation_shape_inference_", name_suffix),
+ absl::StrCat("_outside_compilation_shape_inference_", name_suffix),
fdef));
return Status::OK();
}
@@ -65,18 +66,18 @@ bool EqualProtoMap(const ::tensorflow::protobuf::Map& a,
const auto iter = b.find(elt_a.first);
if (iter == b.end()) {
if (diff) {
- *diff = strings::StrCat(
- map_name, " expected: contains element with key '",
- key_to_string(elt_a.first), "' got: map has no such element");
+ *diff = absl::StrCat(map_name, " expected: contains element with key '",
+ key_to_string(elt_a.first),
+ "' got: map has no such element");
}
return false;
}
if (!compare(elt_a.first, elt_a.second, iter->second)) {
if (diff) {
- *diff = strings::StrCat(map_name, " expected: element with key '",
- key_to_string(elt_a.first), "' has value '",
- value_to_string(elt_a.second), "' got: '",
- value_to_string(iter->second), "'");
+ *diff = absl::StrCat(map_name, " expected: element with key '",
+ key_to_string(elt_a.first), "' has value '",
+ value_to_string(elt_a.second), "' got: '",
+ value_to_string(iter->second), "'");
}
return false;
}
@@ -85,9 +86,9 @@ bool EqualProtoMap(const ::tensorflow::protobuf::Map& a,
const auto iter = a.find(elt_b.first);
if (iter == a.end()) {
if (diff) {
- *diff = strings::StrCat(map_name, " got: contains element with key '",
- key_to_string(elt_b.first),
- "' expected: map has no such element");
+ *diff = absl::StrCat(map_name, " got: contains element with key '",
+ key_to_string(elt_b.first),
+ "' expected: map has no such element");
}
return false;
}
@@ -99,38 +100,38 @@ bool EqualFunctionNodeDef(const NodeDef& a, const NodeDef& b,
const string& diff_preamble, string* diff) {
if (a.op() != b.op()) {
if (diff) {
- *diff = strings::StrCat(diff_preamble, " mismatch for node ", a.name(),
- ", expected op '", a.op(), "' got '", b.op());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ ", expected op '", a.op(), "' got '", b.op());
}
return false;
}
if (a.device() != b.device()) {
if (diff) {
- *diff = strings::StrCat(diff_preamble, " mismatch for node ", a.name(),
- ", expected device '", a.device(), "' got '",
- b.device());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ ", expected device '", a.device(), "' got '",
+ b.device());
}
return false;
}
if (a.input_size() != b.input_size()) {
if (diff) {
- *diff = strings::StrCat(diff_preamble, " mismatch for node ", a.name(),
- ", expected ", a.input_size(), " inputs got ",
- b.input_size(), " expected:\n", a.DebugString(),
- "\ngot:\n", b.DebugString());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ ", expected ", a.input_size(), " inputs got ",
+ b.input_size(), " expected:\n", a.DebugString(),
+ "\ngot:\n", b.DebugString());
}
return false;
}
std::unordered_set control_input_a;
std::unordered_set control_input_b;
for (int i = 0; i < a.input_size(); ++i) {
- if (str_util::StartsWith(a.input(i), "^")) {
- if (!str_util::StartsWith(b.input(i), "^")) {
+ if (absl::StartsWith(a.input(i), "^")) {
+ if (!absl::StartsWith(b.input(i), "^")) {
if (diff) {
- *diff = strings::StrCat(
- diff_preamble, " mismatch for node ", a.name(), " input ", i,
- ", expected control input ", a.input(i), " got ", b.input(i),
- " expected:\n", a.DebugString(), "\ngot:\n", b.DebugString());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ " input ", i, ", expected control input ",
+ a.input(i), " got ", b.input(i), " expected:\n",
+ a.DebugString(), "\ngot:\n", b.DebugString());
}
return false;
}
@@ -138,19 +139,19 @@ bool EqualFunctionNodeDef(const NodeDef& a, const NodeDef& b,
control_input_b.insert(b.input(i));
} else if (a.input(i) != b.input(i)) {
if (diff) {
- *diff = strings::StrCat(diff_preamble, " mismatch for node ", a.name(),
- " input ", i, ", expected ", a.input(i),
- " got ", b.input(i), " expected:\n",
- a.DebugString(), "\ngot:\n", b.DebugString());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ " input ", i, ", expected ", a.input(i), " got ",
+ b.input(i), " expected:\n", a.DebugString(),
+ "\ngot:\n", b.DebugString());
}
return false;
}
}
if (control_input_a != control_input_b) {
if (diff) {
- *diff = strings::StrCat(diff_preamble, " mismatch for node ", a.name(),
- " control inputs differ expected:\n",
- a.DebugString(), "\ngot:\n", b.DebugString());
+ *diff = absl::StrCat(diff_preamble, " mismatch for node ", a.name(),
+ " control inputs differ expected:\n",
+ a.DebugString(), "\ngot:\n", b.DebugString());
}
return false;
}
@@ -170,18 +171,17 @@ bool EqualFunctionNodeDef(const NodeDef& a, const NodeDef& b,
return av.DebugString() == bv.DebugString();
}
},
- strings::StrCat(diff_preamble, " attr mismatch for node ", a.name()),
- diff);
+ absl::StrCat(diff_preamble, " attr mismatch for node ", a.name()), diff);
}
bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
string* diff) {
if (a.signature().DebugString() != b.signature().DebugString()) {
if (diff) {
- *diff = strings::StrCat("Signature mismatch for function ",
- a.signature().name(), ", expected:\n",
- a.signature().DebugString(), "\ngot:\n",
- b.signature().DebugString());
+ *diff =
+ absl::StrCat("Signature mismatch for function ", a.signature().name(),
+ ", expected:\n", a.signature().DebugString(), "\ngot:\n",
+ b.signature().DebugString());
}
return false;
}
@@ -191,7 +191,7 @@ bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
[](const string& key, const AttrValue& av, const AttrValue& bv) {
return av.DebugString() == bv.DebugString();
},
- strings::StrCat("attr mismatch for function ", a.signature().name()),
+ absl::StrCat("attr mismatch for function ", a.signature().name()),
diff)) {
return false;
}
@@ -201,7 +201,7 @@ bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
[](const string& key, const string& av, const string& bv) {
return av == bv;
},
- strings::StrCat("ret mismatch for function ", a.signature().name()),
+ absl::StrCat("ret mismatch for function ", a.signature().name()),
diff)) {
return false;
}
@@ -211,7 +211,7 @@ bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
if (a.node_def(i).name() == b.node_def(j).name()) {
if (!EqualFunctionNodeDef(
a.node_def(i), b.node_def(j),
- strings::StrCat("Function ", a.signature().name()), diff)) {
+ absl::StrCat("Function ", a.signature().name()), diff)) {
return false;
}
found = true;
@@ -220,9 +220,9 @@ bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
}
if (!found) {
if (diff) {
- *diff = strings::StrCat("Function ", a.signature().name(),
- ", expected: has node '", a.node_def(i).name(),
- "' got: no node of that name");
+ *diff = absl::StrCat("Function ", a.signature().name(),
+ ", expected: has node '", a.node_def(i).name(),
+ "' got: no node of that name");
}
return false;
}
@@ -237,9 +237,9 @@ bool EqualFunctionDef(const FunctionDef& a, const FunctionDef& b,
}
if (!found) {
if (diff) {
- *diff = strings::StrCat("Function ", a.signature().name(),
- ", got: has node '", b.node_def(i).name(),
- "' expected: no node of that name");
+ *diff = absl::StrCat("Function ", a.signature().name(),
+ ", got: has node '", b.node_def(i).name(),
+ "' expected: no node of that name");
}
return false;
}
@@ -258,8 +258,8 @@ bool EqualFunctionDefLibrary(const FunctionDefLibrary& expected,
auto it = actual_index.find(expected_function.signature().name());
if (it == actual_index.end()) {
if (diff) {
- *diff = strings::StrCat("Did not find expected function '",
- expected_function.signature().name(), "'");
+ *diff = absl::StrCat("Did not find expected function '",
+ expected_function.signature().name(), "'");
}
return false;
}
@@ -269,9 +269,9 @@ bool EqualFunctionDefLibrary(const FunctionDefLibrary& expected,
if (!actual_index.empty()) {
if (diff != nullptr) {
- *diff = strings::StrCat("Found unexpected function '",
- actual_index.begin()->second->signature().name(),
- "'");
+ *diff =
+ absl::StrCat("Found unexpected function '",
+ actual_index.begin()->second->signature().name(), "'");
}
return false;
}
@@ -379,7 +379,7 @@ Node* InputShaped(const GraphDefBuilder::Options& opts) {
return ops::SourceOp("InputTestShaped", opts);
}
-Node* KnownShapeBase(DataType dtype, const gtl::ArraySlice& shape,
+Node* KnownShapeBase(DataType dtype, absl::Span shape,
const GraphDefBuilder::Options& opts) {
if (opts.HaveError()) return nullptr;
NodeBuilder node_builder(opts.GetNameForOp("Const"), "Const",
@@ -394,7 +394,7 @@ Node* KnownShapeBase(DataType dtype, const gtl::ArraySlice& shape,
.FinalizeBuilder(&node_builder);
}
-Node* KnownShape(const gtl::ArraySlice& shape,
+Node* KnownShape(absl::Span shape,
const GraphDefBuilder::Options& opts) {
return KnownShapeBase(DT_FLOAT, shape, opts);
}
@@ -417,14 +417,12 @@ Node* KeyPlaceholder(const string& call_node,
}
Node* RecvAtHost(ops::NodeOut key_input, const string& cluster,
- const string& oc_cluster,
- const gtl::ArraySlice& dtypes,
+ const string& oc_cluster, absl::Span dtypes,
const GraphDefBuilder::Options& opts) {
if (opts.HaveError()) return nullptr;
- string key =
- strings::StrCat("host_compute_channel_", cluster, "_", oc_cluster);
- string name = strings::StrCat("outside_compilation_", cluster, "_",
- oc_cluster, "_recv");
+ string key = absl::StrCat("host_compute_channel_", cluster, "_", oc_cluster);
+ string name =
+ absl::StrCat("outside_compilation_", cluster, "_", oc_cluster, "_recv");
NodeBuilder node_builder(opts.WithName(name).GetNameForOp("_XlaRecvAtHost"),
"_XlaRecvAtHost", opts.op_registry());
node_builder.Input(std::move(key_input));
@@ -441,10 +439,9 @@ Node* SendFromHost(ops::NodeOut key_input, const string& cluster,
const std::vector& inputs,
const GraphDefBuilder::Options& opts) {
if (opts.HaveError()) return nullptr;
- string key =
- strings::StrCat("host_compute_channel_", cluster, "_", oc_cluster);
- string name = strings::StrCat("outside_compilation_", cluster, "_",
- oc_cluster, "_send");
+ string key = absl::StrCat("host_compute_channel_", cluster, "_", oc_cluster);
+ string name =
+ absl::StrCat("outside_compilation_", cluster, "_", oc_cluster, "_send");
NodeBuilder node_builder(opts.WithName(name).GetNameForOp("_XlaSendFromHost"),
"_XlaSendFromHost", opts.op_registry());
node_builder.Input(inputs);
@@ -683,8 +680,8 @@ std::vector> GraphEdges(const Graph& graph) {
for (const Edge* edge : graph.edges()) {
if (edge->src()->IsSource() || edge->dst()->IsSink()) continue;
edges.emplace_back(
- strings::StrCat(edge->src()->name(), ":", edge->src_output()),
- strings::StrCat(edge->dst()->name(), ":", edge->dst_input()));
+ absl::StrCat(edge->src()->name(), ":", edge->src_output()),
+ absl::StrCat(edge->dst()->name(), ":", edge->dst_input()));
}
std::sort(edges.begin(), edges.end());
return edges;
@@ -768,7 +765,7 @@ TEST(EncapsulateSubgraphsWithGuaranteeConstOpTest, Simple) {
Graph* graph = graph_ptr->get();
for (const Node* n : graph->nodes()) {
if (n->type_string() == "_Arg" &&
- str_util::StartsWith(n->name(), "const")) {
+ absl::StartsWith(n->name(), "const")) {
++guaranteed_consts;
EXPECT_TRUE(HasGuaranteeConstAttr(*n));
} else {
@@ -813,7 +810,7 @@ TEST(EncapsulateSubgraphsWithGuaranteeConstOpTest, Add) {
Graph* graph = graph_ptr->get();
for (const Node* n : graph->nodes()) {
if (n->type_string() == "_Arg" &&
- str_util::StartsWith(n->name(), "const")) {
+ absl::StartsWith(n->name(), "const")) {
++guaranteed_consts;
EXPECT_TRUE(HasGuaranteeConstAttr(*n));
} else {
@@ -892,13 +889,13 @@ TEST(EncapsulateSubgraphsTest, OneFunctionOneOutside) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"C:o:0", "c:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT, DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT, DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}},
{"c"}},
},
@@ -1038,26 +1035,26 @@ TEST(EncapsulateSubgraphsTest, OneFunctionTwoOutside) {
{{"outside_compilation_O2_host_compute"},
"XlaHostCompute",
{"F:o:0", "D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT, DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
+ {{"Tinputs", absl::Span({DT_FLOAT, DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
{"ancestors",
- gtl::ArraySlice({"outside_compilation_O1_host_compute"})},
+ absl::Span({"outside_compilation_O1_host_compute"})},
{"key", "host_compute_channel_F1_O2"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O2"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O2"}},
{"F", "outside_compilation_O1_host_compute"}},
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"C:o:0", "D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT, DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT, DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}},
{"D"}},
},
@@ -1190,13 +1187,13 @@ TEST(EncapsulateSubgraphsTest, TwoFunctionsTwoOutside) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"C:o:0", "D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT, DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT, DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}},
{"D"}},
},
@@ -1213,13 +1210,13 @@ TEST(EncapsulateSubgraphsTest, TwoFunctionsTwoOutside) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"G:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F2_O1"},
{"shape_inference_graph", ""},
{"shapes",
- gtl::ArraySlice({shape_proto_expected})},
+ absl::Span({shape_proto_expected})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"g_0_retval", "G:o:0"}, {"i_0_retval", "I:o:0"}});
@@ -1364,13 +1361,13 @@ TEST(EncapsulateSubgraphsTest, TwoFunctionsTwoOutsideDependencyFromOutside) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"C:o:0", "D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT, DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT, DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}},
{"D"}},
},
@@ -1386,13 +1383,13 @@ TEST(EncapsulateSubgraphsTest, TwoFunctionsTwoOutsideDependencyFromOutside) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"G:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F2_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F2_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"i_0_retval", "I:o:0"}});
@@ -1495,13 +1492,13 @@ TEST(EncapsulateSubgraphsTest, OutsideCompilationNoInputs) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{},
- {{"Tinputs", gtl::ArraySlice({})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph", ""},
{"shapes",
- gtl::ArraySlice({shape_proto_expected})},
+ absl::Span({shape_proto_expected})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"f_0_retval", "F:o:0"}});
@@ -1579,13 +1576,13 @@ TEST(EncapsulateSubgraphsTest, OutsideCompilationControlInput) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{},
- {{"Tinputs", gtl::ArraySlice({})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph", ""},
{"shapes",
- gtl::ArraySlice({shape_proto_expected})},
+ absl::Span({shape_proto_expected})},
{"_outside_compilation_subgraph", "O1"}},
{"D"}},
},
@@ -1661,12 +1658,12 @@ TEST(EncapsulateSubgraphsTest, OutsideCompilationNoOutputs) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph", ""},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"f_0_retval", "F:o:0"}});
@@ -1742,12 +1739,12 @@ TEST(EncapsulateSubgraphsTest, OutsideCompilationControlOutput) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph", ""},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"f_0_retval", "F:o:0"}});
@@ -1846,13 +1843,13 @@ TEST(EncapsulateSubgraphsTest,
{{"outside_compilation_O2_host_compute"},
"XlaHostCompute",
{"F:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O2"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O2"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O2"}}},
},
{{"h_0_retval", "H:o:0"}});
@@ -1955,13 +1952,13 @@ TEST(EncapsulateSubgraphsTest,
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}}},
},
{{"h_0_retval", "H:o:0"}});
@@ -2066,37 +2063,37 @@ TEST(EncapsulateSubgraphsTest, OutsideCompilationClusterDependency) {
{{"outside_compilation_O1_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({DT_FLOAT})},
- {"ancestors", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({DT_FLOAT})},
+ {"ancestors", absl::Span({})},
{"key", "host_compute_channel_F1_O1"},
{"shape_inference_graph",
"_outside_compilation_shape_inference_F1_O1"},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O1"}}},
{{"outside_compilation_O2_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice({DT_FLOAT})},
- {"Toutputs", gtl::ArraySlice({})},
+ {{"Tinputs", absl::Span({DT_FLOAT})},
+ {"Toutputs", absl::Span({})},
{"ancestors",
- gtl::ArraySlice({"outside_compilation_O1_host_compute"})},
+ absl::Span({"outside_compilation_O1_host_compute"})},
{"key", "host_compute_channel_F1_O2"},
{"shape_inference_graph", ""},
- {"shapes", gtl::ArraySlice({})},
+ {"shapes", absl::Span({})},
{"_outside_compilation_subgraph", "O2"}},
{"outside_compilation_O1_host_compute"}},
{{"outside_compilation_O3_host_compute"},
"XlaHostCompute",
{"D:o:0"},
- {{"Tinputs", gtl::ArraySlice