aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/framework
diff options
context:
space:
mode:
authorGravatar Asim Shankar <ashankar@google.com>2018-10-08 09:49:38 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-10-08 09:54:04 -0700
commitf435e776216c7a86f619a17064fd6e1deee638b3 (patch)
tree4be6e0a72ce9ee4b656502bc16f320d16c672833 /tensorflow/python/framework
parent411b9baa39636030181fdff15d2e985824b03d61 (diff)
Avoid adding spurious ops when colocating with resource variables.
Prior to this change, tf.colocate_with(v) would insert spurious operations (a ReadVariableOp and an Identity) in the graph when v is a resource variable, and then colocate the operations within the block with those newly added, otherwise disconnected, operations. This commit avoids adding the unnecessary ReadVariableOp/Identity nodes and colocates operations within the block with the VarHandleOp. PiperOrigin-RevId: 216201638
Diffstat (limited to 'tensorflow/python/framework')
-rw-r--r--tensorflow/python/framework/ops.py28
1 files changed, 24 insertions, 4 deletions
diff --git a/tensorflow/python/framework/ops.py b/tensorflow/python/framework/ops.py
index 8bb177939e..77c2bc930e 100644
--- a/tensorflow/python/framework/ops.py
+++ b/tensorflow/python/framework/ops.py
@@ -4140,10 +4140,7 @@ class Graph(object):
if op is None and not ignore_existing:
raise ValueError("Trying to reset colocation (op is None) but "
"ignore_existing is not True")
-
- if op is not None and not isinstance(op, Operation):
- # We always want to colocate with the reference op.
- op = internal_convert_to_tensor_or_indexed_slices(op, as_ref=True).op
+ op = _op_to_colocate_with(op)
# By default, colocate_with resets the device function stack,
# since colocate_with is typically used in specific internal
@@ -6168,4 +6165,27 @@ def _operation_conversion_error(op, dtype=None, name=None, as_ref=False):
name, as_ref))
+def _op_to_colocate_with(v):
+ """Operation object corresponding to v to use for colocation constraints."""
+ if v is None:
+ return None
+ if isinstance(v, Operation):
+ return v
+ # We always want to colocate with the reference op.
+ # When 'v' is a ResourceVariable, the reference op is the handle creating op.
+ #
+ # What this should be is:
+ # if isinstance(v, ResourceVariable):
+ # return v.handle.op
+ # However, that would require a circular import dependency.
+ # As of October 2018, there were attempts underway to remove
+ # colocation constraints altogether. Assuming that will
+ # happen soon, perhaps this hack to work around the circular
+ # import dependency is acceptable.
+ if hasattr(v, "handle") and hasattr(v.handle, "op") and isinstance(
+ v.handle.op, Operation):
+ return v.handle.op
+ return internal_convert_to_tensor_or_indexed_slices(v, as_ref=True).op
+
+
register_tensor_conversion_function(Operation, _operation_conversion_error)