o
    ?e?,                     @   s   d Z ddlZddlZddl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ZG dd dZG dd dedg dZdd ZdS )zContains the `Node` class.    N)ops)tensor)tensor_util)backend)base_layer_utils)
json_utils)tf_utils)nest_CONSTANT_VALUEc                   @   s   e Zd ZdZ			dddZedd Zedd Zd	d
 Zdd Z	dd Z
edd Zedd Zedd Zedd Zedd Zedd ZdS )Nodea  A `Node` describes the connectivity between two layers.

  Each time a layer is connected to some new input,
  a node is added to `layer._inbound_nodes`.
  Each time the output of a layer is used by another layer,
  a node is added to `layer._outbound_nodes`.

  Args:
      layer: The Layer for the Layer.__call__ this node represents.
      call_args: The positional arguments the Layer was called with.
      call_kwargs: The keyword arguments the Layer was called with.
      outputs: The outputs of the Layer.__call__
  Nc                 C   s  |d u rg n|}|d u ri n|}|d u rg n|}|| _ | o | | _tdd |}tdd |}tdd || _|| _|| _t| j| jf| _| j o]t	| jdko]t
| jd | _t s{| jD ]}t|tjrztj|ddrzt| qfg | _g | _t| jD ]\}}t|r| j| tt|}|}	| j||	f q| j j|  | jD ]}
|
jj }|d ur|j|  qt	| j jd }tt|D ]\}}t |||d	|_qd
d | jD | _!dd t| jD | _"d S )Nc                 S      | S N tr   r   d/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/keras/engine/node.py<lambda>E       zNode.__init__.<locals>.<lambda>c                 S   r   r   r   r   r   r   r   r   F   r   c                 S   r   r   r   r   r   r   r   r   G   r      r   T)Zignore_call_contextlayer
node_indextensor_indexc                 S      g | ]}t t|qS r   strid.0r   r   r   r   
<listcomp>p       z!Node.__init__.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r   q   r    )#r   is_inputr	   map_structureoutputs	call_argscall_kwargsflatten_flat_argumentslenr   Z
is_tf_type _single_positional_tensor_passedr   Z#executing_eagerly_outside_functions
isinstance
tensor_libTensorr   Zneeds_keras_historyZcreate_keras_history_keras_inputs_keras_inputs_ids_and_indices	enumerateis_keras_tensorappendr   r   _inbound_nodeskeras_inputs_keras_historyZ_outbound_nodesKerasHistoryZflat_input_idsZflat_output_ids)selfr   r$   r%   r#   objiZelekt_idkt_indexktZinbound_layerr   r   r   r   r   __init__3   sb   




zNode.__init__c                 C      | j S )zFTensors input to this node that can be traced back to a `keras.Input`.)r-   r6   r   r   r   r3   s   s   zNode.keras_inputsc                 C   s<   g }| j D ]}|jj}|jj}|dur||j|  q|S )zFReturns all the `Node`s whose output this node immediately depends on.N)r3   r4   r   r   r1   r2   )r6   Z	node_depsr;   r   r   r   r   r   parent_nodesx   s   
zNode.parent_nodesc                 c   s8    | j D ]}|j}|j}|j}|j}||||fV  qdS )zYields tuples representing the data inbound from other nodes.

    Yields:
      tuples like: (inbound_layer, node_index, tensor_index, tensor).
    N)r3   r4   r   r   r   )r6   r;   Zkeras_historyr   r   r   r   r   r   iterate_inbound   s   
zNode.iterate_inboundc                 C   sr   | j r| jd \}}||  fi fS t| j}| jD ]\}}||  ||< qt| j| jf|\}}||fS )z;Maps Keras Tensors to computed Tensors using `tensor_dict`.r   )	r)   r.   popcopyr'   r	   Zpack_sequence_asr$   r%   )r6   Ztensor_dictr9   _Zflat_argumentsr:   argskwargsr   r   r   map_arguments   s   zNode.map_argumentsc           	         s   | j | j}| j|\}}tt| jjdd |}| |fdd t	 z
t
jtjd W n ty[   t	t}td| jj d d t| d	 w  fd
d}t	||}t|sw| jjsw|g}t|}|S )z4Serializes `Node` for Functional API's `get_config`.r   Nc                    sr   t | dr | j}|j} |jj|}|d}|jj||jgS t| tj	r*| 
 S t| tjr7t| 
 S | S )z,Serializes a single Tensor passed to `call`.r4   r   )hasattrr4   r   r   namegetr   r*   npZndarraytolistr+   r,   r   	get_value)r   khr   node_keynew_node_index)make_node_keynode_conversion_mapr   r   _serialize_keras_tensor   s   
z/Node.serialize.<locals>._serialize_keras_tensor)defaultzLayer z- was passed non-JSON-serializable arguments. zArguments had types: z6. They cannot be serialized out when saving the model.c                    s\   t | r!| j}|j}|jj|}|d}|jj||jg}ntd | g}t	|S )Nr   )
r0   r4   r   r   rH   rI   r   r
   r   ZListWrapper)r   rM   r   rN   rO   datarR   rE   rP   rQ   r   r   serialize_first_arg_tensor   s   
z2Node.serialize.<locals>.serialize_first_arg_tensor)r$   r%   r   Z_split_out_first_argdictzipZ_call_fn_argsupdater	   r"   jsondumpsr   Zget_json_type	TypeErrortyperH   r   Z	is_nestedZ#_preserve_input_structure_in_configr   Zconvert_inner_node_data)	r6   rP   rQ   rD   Zinputs	argumentsZkwarg_typesrW   rU   r   rV   r   	serialize   s:   



zNode.serializec                 C   s   | j r| jgS | jd S )Nr   )r!   r#   r$   r>   r   r   r   input_tensors   s   
zNode.input_tensorsc                 C   s   | j r| jgS | jS r   )r!   r#   r>   r   r   r   output_tensors   s   zNode.output_tensorsc                 C   s.   t tj| j}t|dkr| js|d S |S )Nr   r   )r	   r"   r   	int_shapera   r(   r!   )r6   input_shapesr   r   r   rd      s   zNode.input_shapesc                 C   s   t tj| jS r   )r	   r"   r   rc   rb   r>   r   r   r   output_shapes   s   zNode.output_shapesc                 C   r=   r   )r   r>   r   r   r   outbound_layer   s   zNode.outbound_layerc                 C   s$   | j rg S tdd | jd }|S )Nc                 S   s   | j jS r   )r4   r   r   r   r   r   r     s    z%Node.inbound_layers.<locals>.<lambda>r   )r!   r	   r"   r$   )r6   inbound_layersr   r   r   rg      s   
zNode.inbound_layers)NNN)__name__
__module____qualname____doc__r<   propertyr3   r?   r@   rF   r`   ra   rb   rd   re   rf   rg   r   r   r   r   r   $   s2    
@


E




r   c                   @   s   e Zd ZdZdZdS )r5   a}  Tracks the Layer call that created a Tensor, for Keras Graph Networks.

  During construction of Keras Graph Networks, this metadata is added to
  each Tensor produced as the output of a Layer, starting with an
  `InputLayer`. This allows Keras to track how each Tensor was produced, and
  this information is later retraced by the `keras.engine.Network` class to
  reconstruct the Keras Graph Network.

  Attributes:
    layer: The Layer that produced the Tensor.
    node_index: The specific call to the Layer that produced this Tensor. Layers
      can be called multiple times in order to share weights. A new node is
      created every time a Layer is called.
    tensor_index: The output index for this Tensor. Always zero if the Layer
      that produced this Tensor only has one output. Nested structures of
      Tensors are deterministically assigned an index via `nest.flatten`.
  r   N)rh   ri   rj   rk   	__slots__r   r   r   r   r5     s    r5   r   c                 C   s
   t | dS )Nr4   )rG   )r7   r   r   r   r0   !  s   
r0   )rk   collectionsrB   r[   numpyrJ   Ztensorflow.python.frameworkr   r   r+   r   Ztensorflow.python.kerasr   Ztensorflow.python.keras.enginer   Z*tensorflow.python.keras.saving.saved_modelr   Ztensorflow.python.keras.utilsr   Ztensorflow.python.utilr	   r
   r   
namedtupler5   r0   r   r   r   r   <module>   s,    
e