a
    
d,                     @   sP   d Z ddlmZ ddlmZ dd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )aJ  Utilities for handling Keras model in graph plugin.

Two canonical types of Keras model are Functional and Sequential.
A model can be serialized as JSON and deserialized to reconstruct a model.
This utility helps with dealing with the serialized Keras model.

They have distinct structures to the configurations in shapes below:
Functional:
  config
    name: Name of the model. If not specified, it is 'model' with
          an optional suffix if there are more than one instance.
    input_layers: Keras.layers.Inputs in the model.
    output_layers: Layer names that are outputs of the model.
    layers: list of layer configurations.
      layer: [*]
        inbound_nodes: inputs to this layer.

Sequential:
  config
    name: Name of the model. If not specified, it is 'sequential' with
          an optional suffix if there are more than one instance.
    layers: list of layer configurations.
      layer: [*]

[*]: Note that a model can be a layer.
Please refer to https://github.com/tensorflow/tfjs-layers/blob/master/src/keras_format/model_serialization.ts
for more complete definition.
    )GraphDef)dtypesc                 c   st   d| fV  |  d drp|  d d}|  d dD ]4}t|D ]&\}}|r^d||f n|}||fV  qFq:dS )aY  Walks the nested keras layer configuration in preorder.

    Args:
      keras_layer: Keras configuration from model.to_json.

    Yields:
      A tuple of (name_scope, layer_config).
      name_scope: a string representing a scope name, similar to that of tf.name_scope.
      layer_config: a dict representing a Keras layer configuration.
     configlayersname%s/%sN)get_walk_layers)keras_layer
name_scopelayerZsub_name_scopeZsublayer r   m/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/tensorboard/plugins/graph/keras_util.pyr
   0   s    
r
   c                 C   s   | rd| |f S |S )a/  Returns scoped name for a node as a string in the form '<scope>/<node
    name>'.

    Args:
      name_scope: a string representing a scope name, similar to that of tf.name_scope.
      node_name: a string representing the current node name.

    Returns
      A string representing a scoped name.
    r   r   )r   	node_namer   r   r   _scoped_nameH   s    r   c                 C   s   |  d dduS )zReturns True if layer is a model.

    Args:
      layer: a dict representing a Keras model configuration.

    Returns:
      bool: True if layer is a model.
    r   r   N)r	   )r   r   r   r   	_is_modelX   s    	r   c                 C   s   t | d tfr| S | gS )a  Normalizes to a list of layers.

    Args:
      maybe_layers: A list of data[1] or a list of list of data.

    Returns:
      List of list of data.

    [1]: A Functional model has fields 'inbound_nodes' and 'output_layers' which can
    look like below:
    - ['in_layer_name', 0, 0]
    - [['in_layer_is_model', 1, 0], ['in_layer_is_model', 1, 1]]
    The data inside the list seems to describe [name, size, index].
    r   )
isinstancelist)Zmaybe_layersr   r   r   _norm_to_list_of_layersd   s    r   c                    sj  | d}| dstdt| | d | d}| d}| d}t|oR|}	t|}
|
r|	rt||D ](\}}t |}t| |d }|||< qpnb|
r|	st| |d d d }nB|
s|r|	rt|d	ksJ d
t| |d }t |}|||< |	r.|r.t|} fdd|D }|| < n2| dd }| d d}t |}|g| < |||fS )a  Updates input_to_in_layer, model_name_to_output, and prev_node_name
    based on the model_layer.

    Args:
      name_scope: a string representing a scope name, similar to that of tf.name_scope.
      model_layer: a dict representing a Keras model configuration.
      input_to_in_layer: a dict mapping Keras.layers.Input to inbound layer.
      model_name_to_output: a dict mapping Keras Model name to output layer of the model.
      prev_node_name: a string representing a previous, in sequential model layout,
                      node name.

    Returns:
      A tuple of (input_to_in_layer, model_name_to_output, prev_node_name).
      input_to_in_layer: a dict mapping Keras.layers.Input to inbound layer.
      model_name_to_output: a dict mapping Keras Model name to output layer of the model.
      prev_node_name: a string representing a previous, in sequential model layout,
                      node name.
    r   r   zlayer is not a model.r   input_layersoutput_layersinbound_nodesr      zhCannot have multi-input Functional model when parent model is not Functional. Number of input layers: %dc                    s   g | ]}t  |d  qS )r   )r   ).0r   r   r   r   
<listcomp>       z!_update_dicts.<locals>.<listcomp>)r	   
ValueErrorr   boolziplenr   )r   Zmodel_layerZinput_to_in_layermodel_name_to_outputprev_node_namelayer_configr   r   r   Zis_functional_modelZis_parent_functional_modelZinput_layerZinbound_nodeZinput_layer_nameZinbound_node_namer   Zlayer_namesZ
last_layerZlast_layer_nameZoutput_noder   r   r   _update_dictsx   sN    









r&   c                 C   s  i }i }t  }d}t| D ]l\}}t|rDt|||||\}}}q|d}t||d}|j }	||	_|ddur|d	d}
|
|	j
d _|d}|durt|tst|d}|j|	j
d _|ddurP|dD ]`}t|}|D ]N\}}}}t||}|||g}|t|k r6|| n|d	 }|	j| qqn|durf|	j| ||v r|	j|| |	j}q|S )
a  Returns a GraphDef representation of the Keras model in a dict form.

    Note that it only supports models that implemented to_json().

    Args:
      keras_layer: A dict from Keras model.to_json().

    Returns:
      A GraphDef representation of the layers in the model.
    Nr   r   
class_nameasciiZkeras_classZdtyper   r   )r   r
   r   r&   r	   r   nodeaddr   encodeattrsr   dictr   Zas_dtypeZas_datatype_enumtyper   r"   inputappend)r   Zinput_to_layerr#   gr$   r   r   r%   r   Znode_defZkeras_cls_nameZdtype_or_policyZtf_dtypeZmaybe_inbound_noder   r   sizeindex_Zinbound_nameZinbound_node_namesZ
input_namer   r   r   keras_model_to_graph_def   sd    







r6   N)__doc__Z"tensorboard.compat.proto.graph_pb2r   Z"tensorboard.compat.tensorflow_stubr   r
   r   r   r   r&   r6   r   r   r   r   <module>   s   I