o
    ?e8                     @   s   d Z ddl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	lmZ dd
lmZ ddlmZ e	jZdd Zdd Zedg dZedddgZdd Zdd Zedg d						dddZdS )zUtility to lift subgraphs.    N)
func_graph)ops)tensor)	array_ops)op_selector)resource_variable_ops)compat)object_identity)	tf_exportc                 C   s   t | tjr	| jS | S N)
isinstance
tensor_libZTensoropZop_or_tensor r   f/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/eager/lift_to_graph.py_as_operation"   s   r   c                 C   s   t dd tt| D S )Nc                 s   s*    | ]}t |jd kot |j V  qdS )ZConstN)r   typecontrol_inputs).0ir   r   r   	<genexpr>)   s    

z#_constant_inputs.<locals>.<genexpr>)allr   graph_inputsr   r   r   r   r   _constant_inputs(   s   r   _InputMutation	copied_opinput_indexold_graph_tensor_ControlMutationr   old_graph_opc              	      s  g }g }g }t | jD ]'\}}||d}	|	du r-tjd|j|jd}	|td||d ||	 qg }
| j	D ]}||d}|du rN|t
d|d q8|
| q8t|
S t| j= |j| jd}|dur{t|j|jvr{|| |j| j|dd | jD dd	 | jj D | jd
 W d   n1 sw   Y  W d   n1 sw   Y   || < t | jD ]\}} j| ||< q fdd|D  fdd|D fS )a  Copy an op directly to a given graph.

  Generally `op`'s inputs should already have been copied. If this is not the
  case, for example with v1 while_loops, then `_copy_non_source` inserts
  placeholders for the unavailable Tensors and returns a list of required
  mutations.

  Args:
    op: The op to be copied.
    graph: The destination graph.
    op_map: A dict mapping ops and tensors in the old graph to the new one.
    base_graph: The graph we're copying from, for any necessary functions.
  Returns:
    A tuple of (required_inputs, required_control_inputs):
      required_inputs:
        A list of `_InputMutation` tuples containing inputs to `copied_op` which
        must be updated once `old_graph_tensor` has been copied.
      required_control_inputs:
        A list of `_ControlMutation` tuples containing control inputs to
        `copied_op` which must be added once `old_graph_op` has been copied.
  NZunused_control_flow_input)nameshapedtyper   )r   r!   c                 S   s   g | ]}|j qS r   )r$   r   xr   r   r   
<listcomp>~       z$_copy_non_source.<locals>.<listcomp>c                 S   s*   i | ]\}}| d s| ds||qS )_classZ_tpu_replicate)
startswith)r   keyvaluer   r   r   
<dictcomp>   s    z$_copy_non_source.<locals>.<dictcomp>)Zop_typeinputsZdtypesattrsr"   c                       g | ]}|j  d qS r   _replacer   mutationr2   r   r   r'          c                    r0   r1   r3   r5   r2   r   r   r'      r7   )	enumerater.   getr   placeholderr#   r$   appendr   r   r    r   Zcontrol_dependenciesdeviceZ
_functionsr   r   Zas_strr"   Zadd_to_graphZ	create_opZoutputsZnode_defattritems)r   graphop_map
base_graphinput_mutationscontrol_mutationsZcopied_inputsr   Zoriginal_inputZcopied_inputZcopied_control_inputsZoriginal_control_inputZcopied_control_inputfr   or   r2   r   _copy_non_source<   sl   


 

rF   c                 C   s8  |r| |v r|j ||  | jjd}nn| jjdkr]t| r]| jjd }t|j|||d\}}	|s1|	r8td|t	
| jj
 tj|| | j| jjd}W d   n1 sWw   Y  n#t	
| jj
 tj| j| j| jjd}W d   n1 s{w   Y  t| }
|
jrtj||
d	d
 ||| < |j|| j< dS )a  Create a source in a graph based on a Tensor from a different graph.

  This function creates a placeholder analog of `s` in a graph with the
  following behavior:

  1) If s is a captured Tensor or Variable and handle_captures is set to True,
     simply capture it in the new graph as well.

  2) If s is a PlaceholderWithDefault whose default is a constant, preserve
     said default in the new graph.

  3) When applicable, copy resource variable metadata from `s` to the newly
     created placeholder.

  Args:
    s: The source of interest.
    graph: The destination graph.
    op_map: A dict mapping ops and tensors in the old graph to the new one.
    handle_captures: A boolean indicating whether to re-capture s in the new
      graph or simply create a vanilla placeholder.
    inverse_captures: A dict mapping s back to the Tensor or Variable that it
      captures.
    base_graph: The graph being copied from.
  )r"   ZPlaceholderWithDefaultr   r   r?   r@   rA   z4Could not copy source node {} because it has inputs.)inputr#   r"   N)r$   r#   r"   T)Z
graph_mode)capturer   r"   r   r   r.   rF   AssertionErrorformatr   r<   r   Zplaceholder_with_defaultr#   r:   r$   r   Zget_resource_handle_dataZshape_and_typeZ_set_handle_shapes_and_types)sr?   r@   handle_capturesinverse_capturesrA   Zcopied_placeholderdefault_valueZunavailable_inputsZunavailable_control_inputsZbase_handler   r   r   _copy_source   sB   

rP   z__internal__.lift_to_graph)v1Fc                    sN  g }g }	| D ]}
t |
tjr||
 q|	|
 q|p |	d j}|p&t }t|p,g }tdd |D }t	
t|	D ]}|tj|||||d q>g }tg  fdd|	D }t|}|r|r| }| v roqd | || t|D ]#}|jdkrq~|| t fdd| D r||vr|| q~|sf|  |r|tt| |sd|jd	d
 d g }t }g }t |tjrt |tjr|j}|D ]\}}|||< q|j}|  |D ]}|||< qt }|D ]}||v r|| ||j t||||||d q|D ]}||j t||||||d qg }g }t|D ]#}||v s=||v r?q1t ||||d\}}|!| |!| q1|" 1 |D ]}|j#$|j%||j&  q\|D ]}|j'jdkrxqm|j#(||j'  qmW d   n	1 sw   Y  |W  d   S 1 sw   Y  dS )a  Copies the tensor and all its inputs recursively to the outer graph.

  Args:
    tensors: The Tensors to lift.
    graph: The graph to lift to.
    sources: Optional sequence of nodes to start from. If omitted the whole
      subgraph which feeds into `init_tensor` is lifted.
    disallowed_placeholders: An optional set of ops which may not appear in the
      lifted graph. Defaults to all placeholders.
    add_sources: A boolean indicating whether placeholders which are not in
      sources should be allowed.
    handle_captures: A boolean indicating whether to re-capture s in the new
      graph or simply create a vanilla placeholder.
    base_graph: The graph from which to lift ops. This will be inferred if not
      specified.
    op_map: A map contains all the existing nodes that have been lifted to the
      destination graph, so they won't be lifted and copied again.

  Returns:
    A mapping from ops in the current default graph to ops in `graph`.

  Raises:
    UnliftableError: If a placeholder blocks lifting.
  r   c                 s   s    | ]}|j V  qd S r   r   r%   r   r   r   r      s    z lift_to_graph.<locals>.<genexpr>)init_tensorsourcesdisallowed_placeholdersvisited_ops
op_outputsadd_sourcesc                    s    g | ]} t | st |qS r   )r   )r   t)rW   r   r   r'   	  s    
z!lift_to_graph.<locals>.<listcomp>ZTPUReplicateMetadatac                 3   s    | ]}| v V  qd S r   r   r%   )
marked_opsr   r   r     s    c                 S   s   t t| dkS )Nr   )lenr   r   rR   r   r   r   <lambda>(  r(   zlift_to_graph.<locals>.<lambda>)r+   )rL   r?   r@   rM   rN   rA   rG   N))r   r   ZResourceVariabler;   r?   r	   ZObjectIdentityDictionaryZObjectIdentitySetsetcollectionsdefaultdictupdater   Zmap_subgraphpopaddr   r   r   difference_updatenextitersortr   Z	FuncGraphcapturesinternal_capturesZ
as_defaultremover   rP   reversedrF   extendZ_mutation_lockr   Z_update_inputr   r   r!   Z_add_control_input)Ztensorsr?   rT   rU   rX   rM   rA   r@   Zvariable_init_tensorsZinit_tensorsr   rV   rS   Zops_to_copyZops_to_visitZunvisited_opsr   inprg   rN   rh   Zexternal_captureZinternal_capturer   Z
source_opsrL   rB   rC   Znew_input_mutationsZnew_control_mutationsr6   r   )rZ   rW   r   lift_to_graph   s   !


















&rm   )NNFFNN)__doc__r^   Ztensorflow.python.frameworkr   r   r   r   Ztensorflow.python.opsr   r   r   Ztensorflow.python.utilr   r	   Z tensorflow.python.util.tf_exportr
   ZUnliftableErrorr   r   
namedtupler   r    rF   rP   rm   r   r   r   r   <module>   s@   S
<