diff options
author | Asim Shankar <ashankar@google.com> | 2018-10-08 09:49:38 -0700 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2018-10-08 09:54:04 -0700 |
commit | f435e776216c7a86f619a17064fd6e1deee638b3 (patch) | |
tree | 4be6e0a72ce9ee4b656502bc16f320d16c672833 /tensorflow/python/framework | |
parent | 411b9baa39636030181fdff15d2e985824b03d61 (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.py | 28 |
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) |