ó
V¾÷Xc        
   @` sU  d  Z  d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m	 Z
 d d	 d
 d d d d d d d g
 Z d „  Z d e f d „  ƒ  YZ d% d% d „ Z d% d% d „ Z d% d% d „ Z d% d% d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d  „  Z d! „  Z d" „  Z d# „  Z d$ „  Z d% S(&   s%   Various function for graph rerouting.i    (   t   absolute_import(   t   division(   t   print_function(   t   subgraph(   t   util(   t   opst   swap_tst
   reroute_tst   swap_inputst   reroute_inputst   swap_outputst   reroute_outputst   swap_iost   reroute_iost   remove_control_inputst   add_control_inputsc         C` s  t  j |  ƒ }  t  j | ƒ } t |  ƒ t | ƒ k r] t d j t |  ƒ t | ƒ ƒ ƒ ‚ n  x t |  | ƒ D]Œ \ } } | j | j } } | j | ƒ s¶ t d j | | ƒ ƒ ‚ n  | j ƒ  | j ƒ  } } | j | ƒ sm t d j | | ƒ ƒ ‚ qm qm Wd S(   sI  Make sure the shape and dtype of the two tensor's lists are compatible.

  Args:
    ts0: an object convertible to a list of `tf.Tensor`.
    ts1: an object convertible to a list of `tf.Tensor`.
  Raises:
    ValueError: if any pair of tensors (same index in ts0 and ts1) have
      a dtype or a shape which is not compatible.
  s*   ts0 and ts1 have different sizes: {} != {}s$   Dtypes {} and {} are not compatible.s$   Shapes {} and {} are not compatible.N(	   R   t   make_list_of_tt   lent
   ValueErrort   formatt   zipt   dtypet   is_compatible_witht	   get_shape(   t   ts0t   ts1t   t0t   t1t   dtype0t   dtype1t   shape0t   shape1(    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _check_ts_compatibility'   s    
	t   _RerouteModec           B` s2   e  Z d  Z e d ƒ \ Z Z Z e d „  ƒ Z RS(   s1  Enums for reroute's mode.

  swap: the end of tensors a and b are swapped.
  a2b:  the end of the tensor a are also rerouted to the end of the tensor b
    (the end of b is left dangling).
  b2a:  the end of the tensor b are also rerouted to the end of the tensor a
    (the end of a is left dangling).
  i   c         C` sd   | |  j  k r t t f S| |  j k r2 t t f S| |  j k rK t t f St d j | ƒ ƒ ‚ d S(   sî   Check swap mode.

    Args:
      mode: an integer representing one of the modes.
    Returns:
      A tuple `(a2b, b2a)` boolean indicating what rerouting needs doing.
    Raises:
      ValueError: if mode is outside the enum range.
    s   Unknown _RerouteMode: {}N(   t   swapt   Truet   b2at   Falset   a2bR   R   (   t   clst   mode(    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   checkN   s    


(	   t   __name__t
   __module__t   __doc__t   rangeR"   R&   R$   t   classmethodR)   (    (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR!   C   s   c   
      C` sË   d } | d k	 r | | M} n  | d k	 r8 | | 8} n  i  } xF | D]> } g  t | j ƒ D] \ } }	 |	 | k r[ | ^ q[ | | <qE Wx= | D]5 } x, | | D]  } | j | |  ƒ | d 7} qŸ WqŽ W| S(   si  Reroute the end of the tensors (t0,t1).

  Warning: this function is directly manipulating the internals of the
  `tf.Graph`.

  Args:
    t0: a tf.Tensor.
    t1: a tf.Tensor.
    consumers1: The consumers of t1 which needs to be rerouted.
    can_modify: iterable of operations which can be modified. Any operation
      outside within_ops will be left untouched by this function.
    cannot_modify: iterable of operations which cannot be modified.
      Any operation within cannot_modify will be left untouched by this
      function.
  Returns:
    The number of individual modifications made by the function.
  i    i   N(   t   Nonet	   enumeratet   inputst   _update_input(
   R   R   t
   consumers1t
   can_modifyt   cannot_modifyt   nb_update_inputst   consumers1_indicest	   consumer1t   it   t(    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt
   _reroute_tc   s     c         C` s}  t  j | ƒ \ } } t j |  ƒ }  t j | ƒ } t |  | ƒ | d k	 rd t t j | ƒ ƒ } n  | d k	 rˆ t t j | ƒ ƒ } n  d } g  } xT t |  | ƒ D]C \ }	 }
 t	 |	 j
 ƒ  ƒ } t	 |
 j
 ƒ  ƒ } | j | | f ƒ q¤ Wx‹ t |  | | ƒ D]w \ }	 }
 } |	 |
 k rqþ n  | \ } } | rP| t |	 |
 | | | ƒ 7} n  | rþ | t |
 |	 | | | ƒ 7} qþ qþ W| S(   sS	  Reroute the end of the tensors in each pair (t0,t1) in ts0 x ts1.

  This function is the back-bone of the Graph-Editor. It is essentially a thin
  wrapper on top of the tf.Operation._update_input.

  Given a pair of tensor t0, t1 in ts0 x ts1, this function re-route the end
  of t0 and t1 in three possible ways:
  1) The reroute mode is "a<->b" or "b<->a": the tensors' end are swapped. After
  this operation, the previous consumers of t0 are now consumers of t1 and
  vice-versa.
  2) The reroute mode is "a->b": the tensors' end of t0 are re-routed to the
  tensors's end of t1 (which are left dangling). After this operation, the
  previous consumers of t0 are still consuming t0 but the previous consumers of
  t1 are not also consuming t0. The tensor t1 has no consumer.
  3) The reroute mode is "b->a": this mode is the symmetric of the "a->b" mode.

  Note that this function is re-routing the end of two tensors, not the start.
  Re-routing the start of two tensors is not supported by this library. The
  reason for that is the following: TensorFlow, by design, creates a strong bond
  between an op and its output tensor. This Graph editor follows this design and
  treats an operation A and its generating tensors {t_i} as an entity which
  cannot be broken. In other words, an op cannot be detached from any of its
  output tensors, ever. But it is possible to detach an op from its input
  tensors, which is what this function concerns itself with.

  Warning: this function is directly manipulating the internals of the tf.Graph.

  Args:
    ts0: an object convertible to a list of `tf.Tensor`.
    ts1: an object convertible to a list of `tf.Tensor`.
    mode: what to do with those tensors: "a->b" or "b<->a" for swaping and
      "a->b" or "b->a" for one direction re-routing.
    can_modify: iterable of operations which can be modified. Any operation
      outside within_ops will be left untouched by this function.
    cannot_modify: iterable of operations which cannot be modified.
      Any operation within cannot_modify will be left untouched by this
      function.
  Returns:
    The number of individual modifications made by the function.
  Raises:
    TypeError: if `ts0` or `ts1` cannot be converted to a list of `tf.Tensor`.
    TypeError: if `can_modify` or `cannot_modify` is not `None` and cannot be
      converted to a list of `tf.Operation`.
  i    N(   R!   R)   R   R   R    R/   t	   frozensett   make_list_of_opR   t   sett	   consumerst   appendR;   (   R   R   R(   R4   R5   R&   R$   R6   t   precomputed_consumersR   R   t
   consumers0R3   R?   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _reroute_ts…   s2    -"c         C` s   t  |  | t j | | ƒ S(   s  For each tensor's pair, swap the end of (t0,t1).

  B0 B1     B0 B1
  |  |    =>  X
  A0 A1     A0 A1

  Args:
    ts0: an object convertible to a list of `tf.Tensor`.
    ts1: an object convertible to a list of `tf.Tensor`.
    can_modify: iterable of operations which can be modified. Any operation
      outside within_ops will be left untouched by this function.
    cannot_modify: iterable of operations which cannot be modified.
      Any operation within cannot_modify will be left untouched by this
      function.
  Returns:
    The number of individual modifications made by the function.
  Raises:
    TypeError: if ts0 or ts1 cannot be converted to a list of tf.Tensor.
    TypeError: if can_modify or cannot_modify is not None and cannot be
      converted to a list of tf.Operation.
  (   RC   R!   R"   (   R   R   R4   R5   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   Î   s    c         C` s   t  |  | t j | | ƒ S(   s\  For each tensor's pair, replace the end of t1 by the end of t0.

  B0 B1     B0 B1
  |  |    => |/
  A0 A1     A0 A1

  The end of the tensors in ts1 are left dangling.

  Args:
    ts0: an object convertible to a list of `tf.Tensor`.
    ts1: an object convertible to a list of `tf.Tensor`.
    can_modify: iterable of operations which can be modified. Any operation
      outside within_ops will be left untouched by this function.
    cannot_modify: iterable of operations which cannot be modified. Any
      operation within cannot_modify will be left untouched by this function.
  Returns:
    The number of individual modifications made by the function.
  Raises:
    TypeError: if ts0 or ts1 cannot be converted to a list of tf.Tensor.
    TypeError: if can_modify or cannot_modify is not None and cannot be
      converted to a list of tf.Operation.
  (   RC   R!   R&   (   R   R   R4   R5   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   ç   s    c         C` sw  t  j | ƒ \ } } t |  t j ƒ sE t d j t |  ƒ ƒ ƒ ‚ n  t | t j ƒ su t d j t | ƒ ƒ ƒ ‚ n  t j	 |  | ƒ |  j
 ƒ  } | j
 ƒ  } | rÞ | rÞ | j | j | _ | _ | j | j | _ | _ nF | r| j | _ | j | _ n# | r$| j | _ | j | _ n  d „  } | rC| | | ƒ n  | rY| | | ƒ n  |  j | ƒ | j | ƒ d S(   s¯  Remap in place the inputs of two subgraph views to mimic the reroute.

  This function is meant to used by reroute_inputs only.

  Args:
    sgv0: the first subgraph to have its inputs remapped.
    sgv1: the second subgraph to have its inputs remapped.
    mode: reroute mode, see _reroute_ts(...).
  Raises:
    TypeError: if svg0 or svg1 are not SubGraphView.
    ValueError: if sgv0 and sgv1 do not belong to the same graph.
  s   Expected a SubGraphView, got {}c         S` s\   xU t  | j ƒ D]D \ } } | |  j k r |  j j | ƒ } | j | | j | <q q Wd  S(   N(   R0   t
   _output_tst   _passthrough_tst	   _input_tst   index(   t   at   bR9   R:   t   ii(    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   update_passthrough_outputs$  s    N(   R!   R)   t
   isinstanceR   t   SubGraphViewt	   TypeErrorR   t   typeR   t   check_graphst   copyRF   RE   t   _assign_from(   t   sgv0t   sgv1R(   R&   R$   t   sgv0_t   sgv1_RK   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _reroute_sgv_remap  s2    	c         C` s    t  j |  ƒ }  t  j | ƒ } t j |  | ƒ |  j | j } | t j |  j ƒ 7} | t j | j ƒ 7} t |  j | j | d | ƒt	 |  | | ƒ |  | f S(   sí  Re-route all the inputs of two subgraphs.

  Args:
    sgv0: the first subgraph to have its inputs swapped. This argument is
      converted to a subgraph using the same rules than the function
      subgraph.make_view.
    sgv1: the second subgraph to have its inputs swapped. This argument is
      converted to a subgraph using the same rules than the function
      subgraph.make_view.
    mode: reroute mode, see _reroute_ts(...).
  Returns:
    A tuple `(sgv0, sgv1)` of subgraph views with their inputs swapped.
      Note that the function argument sgv0 and sgv1 are also modified in place.
  Raises:
    StandardError: if sgv0 or sgv1 cannot be converted to a SubGraphView using
      the same rules than the function subgraph.make_view.
  R4   (
   R   t	   make_viewR   RP   R   t   get_consuming_opst   passthroughsRC   R1   RW   (   RS   RT   R(   R4   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _reroute_sgv_inputs8  s    c         C` sd   t  j |  ƒ }  t  j | ƒ } t j |  | ƒ |  j | j } t |  j | j | d | ƒ|  | f S(   sò  Re-route all the outputs of two operations.

  Args:
    sgv0: the first subgraph to have its outputs swapped. This argument is
      converted to a subgraph using the same rules than the function
      subgraph.make_view.
    sgv1: the second subgraph to have its outputs swapped. This argument is
      converted to a subgraph using the same rules than the function
      subgraph.make_view.
    mode: reroute mode, see _reroute_ts(...).
  Returns:
    A tuple `(sgv0, sgv1)` of subgraph views with their outputs swapped.
      Note that the function argument sgv0 and sgv1 are also modified in place.
  Raises:
    StandardError: if sgv0 or sgv1 cannot be converted to a SubGraphView using
      the same rules than the function subgraph.make_view.
  R5   (   R   RX   R   RP   R   RC   t   outputs(   RS   RT   R(   R5   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _reroute_sgv_outputsV  s    c         C` s*   t  |  | | ƒ t |  | | ƒ |  | f S(   s>  Re-route both the inputs and the outputs of the two subgraph views.

  This involves swapping all the inputs/ouputs of the two subgraph views.

  Args:
    sgv0: the first subgraph to be swapped. This argument is converted to a
      subgraph using the same rules than the function subgraph.make_view.
    sgv1: the second subgraph to be swapped. This argument is converted to a
      subgraph using the same rules than the function subgraph.make_view.
    mode: reroute mode, see _reroute_ts(...).
  Returns:
    A tuple `(sgv0, sgv1)` of subgraph views with their outputs and inputs
      swapped.
      Note that the function argument sgv0 and sgv1 are also modified in place.
  Raises:
    StandardError: if sgv0 or sgv1 cannot be converted to a SubGraphView using
      the same rules than the function subgraph.make_view.
  (   R]   R[   (   RS   RT   R(   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   _reroute_sgvp  s    c         C` s   t  |  | t j ƒ S(   s:   Swap all the inputs of sgv0 and sgv1 (see reroute_inputs).(   R[   R!   R"   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   ˆ  s    c         C` s   t  |  | t j ƒ S(   s=   Re-route all the inputs of sgv0 to sgv1 (see reroute_inputs).(   R[   R!   R&   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR	     s    c         C` s   t  |  | t j ƒ S(   s=   Swap all the outputs of sgv0 and sgv1 (see _reroute_outputs).(   R]   R!   R"   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR
   ’  s    c         C` s   t  |  | t j ƒ S(   s@   Re-route all the outputs of sgv0 to sgv1 (see _reroute_outputs).(   R]   R!   R&   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   —  s    c         C` s   t  |  | t j ƒ S(   s;   Swap the inputs and outputs of sgv1 to sgv0 (see _reroute).(   R^   R!   R"   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   œ  s    c         C` s   t  |  | t j ƒ S(   s?   Re-route the inputs and outputs of sgv0 to sgv1 (see _reroute).(   R^   R!   R&   (   RS   RT   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   ¡  s    c         C` s¹   t  |  t j ƒ s* t d t |  ƒ ƒ ‚ n  t j | d t ƒ} x> | D]6 } | |  j k rF t	 d j
 |  j | j ƒ ƒ ‚ qF qF Wg  |  j D] } | | k rŠ | ^ qŠ |  _ |  j ƒ  d S(   s  Remove the control inputs cops from co.

  Warning: this function is directly manipulating the internals of the
  `tf.Graph`.

  Args:
    op: a `tf.Operation` from which to remove the control inputs.
    cops: an object convertible to a list of `tf.Operation`.
  Raises:
    TypeError: if op is not a `tf.Operation`.
    ValueError: if any cop in cops is not a control input of op.
  s    Expected a tf.Operation, got: {}t   allow_graphs   {} is not a control_input of {}N(   RL   t   tf_opst	   OperationRN   RO   R   R=   R%   t   control_inputsR   R   t   namet   _control_inputst   _recompute_node_def(   t   opt   copst   cop(    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   ¦  s    +c         C` s   t  |  t j ƒ s* t d t |  ƒ ƒ ‚ n  t j | d t ƒ} x> | D]6 } | |  j k rF t	 d j
 |  j | j ƒ ƒ ‚ qF qF W|  j | 7_ |  j ƒ  d S(   su  Add the control inputs cops to co.

  Warning: this function is directly manipulating the internals of the tf.Graph.

  Args:
    op: a tf.Operation to which the control inputs are added.
    cops: an object convertible to a list of `tf.Operation`.
  Raises:
    TypeError: if op is not a tf.Operation
    ValueError: if any cop in cops is already a control input of op.
  s    Expected a tf.Operation, got: {}R_   s#   {} is already a control_input of {}N(   RL   R`   Ra   RN   RO   R   R=   R%   Rb   R   R   Rc   Rd   Re   (   Rf   Rg   Rh   (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyR   À  s    N(    R,   t
   __future__R    R   R   t   tensorflow.contrib.graph_editorR   R   t   tensorflow.python.frameworkR   R`   t   __all__R    t   objectR!   R/   R;   RC   R   R   RW   R[   R]   R^   R   R	   R
   R   R   R   R   R   (    (    (    si   /tmp/pip-build-h1VYrz/tensorflow/tensorflow-1.0.1.data/purelib/tensorflow/contrib/graph_editor/reroute.pyt   <module>   sD   		 "I	7										