Create a new graph which compute the targets from the replaced Tensors. Args: target_ts: a single tf.Tensor or an iterable of tf.Tensor. replacement_ts: dictionary mapping from original tensors to replaced tensors dst_scope: the destination scope. src_scope: the source scope.
(target_ts, replacement_ts, dst_scope="",
src_scope="", reuse_dst_scope=False)
| 707 | |
| 708 | |
| 709 | def graph_replace(target_ts, replacement_ts, dst_scope="", |
| 710 | src_scope="", reuse_dst_scope=False): |
| 711 | """Create a new graph which compute the targets from the replaced Tensors. |
| 712 | |
| 713 | Args: |
| 714 | target_ts: a single tf.Tensor or an iterable of tf.Tensor. |
| 715 | replacement_ts: dictionary mapping from original tensors to replaced tensors |
| 716 | dst_scope: the destination scope. |
| 717 | src_scope: the source scope. |
| 718 | reuse_dst_scope: if True the dst_scope is re-used if it already exists. |
| 719 | Otherwise, the scope is given a unique name based on the one given |
| 720 | by appending an underscore followed by a digit (default). |
| 721 | Returns: |
| 722 | A single tf.Tensor or a list of target tf.Tensor, depending on |
| 723 | the type of the input argument `target_ts`. |
| 724 | The returned tensors are recomputed using the tensors from replacement_ts. |
| 725 | Raises: |
| 726 | ValueError: if the targets are not connected to replacement_ts. |
| 727 | """ |
| 728 | # Identify operations in the graph that will change. |
| 729 | # Start forward walk at Tensors that will be replaced, and |
| 730 | # backward walk at the target output Tensors. |
| 731 | flatten_target_ts = util.flatten_tree(target_ts) |
| 732 | # Construct the forward control dependencies edges so that |
| 733 | # the get_walks_intersection_ops can also traverse the |
| 734 | # control dependencies. |
| 735 | graph = util.get_unique_graph(flatten_target_ts, check_types=(tf_ops.Tensor)) |
| 736 | control_ios = util.ControlOutputs(graph) |
| 737 | ops = select.get_walks_intersection_ops( |
| 738 | list(replacement_ts), flatten_target_ts, control_ios=control_ios) |
| 739 | if not ops: |
| 740 | raise ValueError("Targets and replacements are not connected!") |
| 741 | |
| 742 | # Complete ops to avoid malformed control flow. |
| 743 | # TODO(fkp): Consider moving this function deeper (in the transformer?). |
| 744 | _add_control_flow_ops(ops, control_ios) |
| 745 | |
| 746 | # Create a copy of the relevant subgraph |
| 747 | unused_sgv_, info = copy_with_input_replacements( |
| 748 | ops, replacement_ts, None, dst_scope, src_scope, reuse_dst_scope) |
| 749 | # Return the transformed targets but keep the original if the transformed |
| 750 | # counterpart cannot be found |
| 751 | missing_fn = lambda original_t: original_t |
| 752 | return info.transformed(target_ts, missing_fn) |
nothing calls this directly
no test coverage detected