
    Phj                     d   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mZ d dlmZmZmZmZ  ej(                  e      Zd%dee   d	ed
ef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 Z&d Z'd Z(d Z)d Z*d Z+d Z,	 	 	 	 	 	 d&dZ-d  Z.d! Z/d" Z0d'd#Z1d'd$Z2y)(    N)GraphDef)NodeDef)TensorShapeProto)
caffe2_pb2)core	workspace)SetDictTupleListseennamemin_versionc                 t    |J |}|rd||fz  n|}|| v r|dz  }d||fz  }|| v r| j                  |       |S )a  
    Make the name unique by appending a unique number to the name. Used for SSA.

    Args:
        seen (set): Set of names that have already been used (with respect to
            some context).
        name (str): The name to make unique
        min_version (number): Starting index. Is incremented continually until
            it can make the resulting name unique relative to 'seen'.

    Returns:
        x (str): A version of name that is not in seen.
    z%s_%d   )add)r   r   r   ixs        pC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/utils/tensorboard/_caffe2_graph.py_make_unique_namer      s`     A 4)dA
t)	QtQi t) 	HHQKH    c                 "  	
 t        j                  d      t        j                  d      t        j                  d      t        j                  d      t        j                  d      t        j                  d      t        j                  d      	t        j                  d      
t        j                  d	      t        j                  d
      t        j                  d      	
fd}t        | |||       y)a8  
    Convert some of the common names in Caffe2 to tensorflow.

    NOTE: The common names in both Caffe2 and Tensorflow are currently
        hardcoded, if either side changes at some point, then this code should
        change as well.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        blob_name_tracker: Dictionary of all unique blob names (with respect to
            some context).
        ops: List of Caffe2 operators

    Returns:
        None. The _rename_all() call modifies blob_name_tracker and ops in-place.
    z(_w)$z(_w_)z(_bn)$z(_bn_)z(_b)$z(_b_)z(_s)$z(_s_)z(_sum)$z(_sum_)z	(_branch)c                    j                  dj                  d|             }j                  dj                  d|            }j                  dj                  d|            }	j                  dj                  d|            }j                  d	
j                  d
|            }j                  d|      }|S )Nz/weight_z/weightz/batchnorm_z
/batchnormz/bias_z/biasz/scale_z/scalez/sum_z/sumz/branch)sub)r   
inter_namenew_nameBIASBIAS_BNBN_BRANCHSCALESCALE_SUMSUM_WEIGHTWEIGHT_s      r   fz#_rename_tensorflow_style.<locals>.fF   s    [[VZZ	4-HI
WW]BFF<,LM
YYx':)FG
ZZ	599Xz+JK
XXgswwvz'BC
::i4r   N)recompile_rename_all)shapesblob_name_trackeropsr(   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   s       @@@@@@@@@@@r   _rename_tensorflow_styler/   )   s    " ZZ!Fjj"G	I	B
**Y
C::hDJJx EJJx EZZ!F
**Z
 C::j!DZZ%F  )32r   c                    	
 t        j                  |      }t               	i i i dt        dt        t        t
        f   dt
        f	 fdt        ||j                        D ]  \  }
|
j                  u sJ t        |j                        }t        |j                        }|j                  dd= |j                  dd= |j                  j                  
fd|D               |j                  j                  
fd|D                 j                           j                         r"j                          j                         yy)a  
    Convert an operator graph to SSA (i.e. out-of-place).

    i.e. blobs will be renamed so that each blob is produced only once.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        blob_name_tracker: Dictionary of all unique blob names (with respect to
            some context).
        ops: List of Caffe2 operators

    Returns:
        None. Modifies blob_name_tracker and ops in-place.
    r   versionsreturnc                     | |v sJ ||    }| |f	v r	| |f   S t        | |      }|	| |f<   | v r|    |<   r| v r|    |<   |S )N)r   r   )
r   r1   versionr   r-   new_blob_name_tracker
new_shapesr   r,   	versioneds
       r   ssa_namez!_convert_to_ssa.<locals>.ssa_nameg   s    x4.'?i'dG_--
 %T4WE%-	4/"6>#)$<Jx ):!:.?.E!(+r   Nc              3   D   K   | ]  } |j                           y wN)in_versions.0r   ssar9   s     r   	<genexpr>z"_convert_to_ssa.<locals>.<genexpr>   s     KFDs7F    c              3   D   K   | ]  } |j                           y wr;   )out_versionsr=   s     r   r@   z"_convert_to_ssa.<locals>.<genexpr>   s     Ngd$(8(89grA   )r   IRsetstrr
   intzipr?   oplistinputoutputextendclearupdate)r,   r-   r.   irrI   inputsoutputsr6   r7   r   r?   r9   r8   s   ``     @@@@@@r   _convert_to_ssarS   R   s    
BUD,.IJs d38n   $ bff%	SSVV||bhhryy/HHQKIIaL
KFKK
		NgNN & LLN
MM*!  !67 r   c                     t               }| D ]8  }|j                  |j                         |j                  |j                         : |D ci c]  }|| c}S c c}w )z
    Get all the operator input and output blobs and perform dedup on their names.

    Args:
        ops: List of Caffe2 operators to extract inputs and outputs from

    Returns:
        set containing distinct inputs and outputs from 'ops'
    )rE   rO   rK   rL   )r.   namesrI   r   s       r   _get_blob_namesrV      sS     EERXXRYY  $))54D$J5)))s   
Ac                     | j                         D ci c]  \  }} ||      | }}}| j                          | j                  |       yc c}}w )a  
    Rename keys of 'old_dict' according to 'rename_fn'.

    Args:
        old_dict: Dictionary (i.e. containing blob_name -> blob_name
            relationships.)
        rename_fn: Function string -> string for renaming.

    Returns:
        None. Modifies old_dict in-place.
    N)itemsrN   rO   )old_dict	rename_fnkeyvaluenew_dicts        r   _remap_keysr^      sK     9A8HI8H*#u	#%8HHINNOOH Js   Ac                   	 t               	i 	fd|D ]  }t        |j                        }t        |j                        }|j                  dd= |j                  dd= |j                  j	                  fd|D               |j                  j	                  fd|D                t        |        |rt        |       	j                          j                          |D ]  } |j                        |_         y)a  
    Rename all the names in the operators.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        blob_name_tracker: Dictionary of all unique blob names (with respect to
            some context).
        ops: List of Caffe2 operators
        rename_fn: Function string -> string that specifies how to rename

    Returns:
        None. Modifies shapes, blob_name_tracker and ops in-place using the
            specified 'rename_fn'.
    c                 N    | y| v r|    S t         |             }|| <   |S )zCollision-free version of f.Nr4   )r   r   rZ   renamedr   s     r   gz_rename_all.<locals>.g   s:    <7?4= $T9T?; r   Nc              3   .   K   | ]  } |        y wr;    r>   r   rb   s     r   r@   z_rename_all.<locals>.<genexpr>   s     3FD$F   c              3   .   K   | ]  } |        y wr;   rd   re   s     r   r@   z_rename_all.<locals>.<genexpr>   s     5WT4Wrf   )rE   rJ   rK   rL   rM   r^   rN   r   )
r,   r-   r.   rZ   rI   rQ   rR   rb   ra   r   s
      `   @@@r   r+   r+      s     UD*,G bhhryy/HHQKIIaL
3F33
		5W55  %q) 	JJLMMOBGG* r   c                 &    d }t        | |||       y)a  
    For all operators or blobs with name containing "_grad", add a "GRADIENTS/" scope.

    Note: breaks graph execution since the blob -> gradient mapping is
    hardcoded.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        blob_name_tracker: Dictionary of all unique blob names (with respect to
            some context).
        ops: List of Caffe2 operators

    Returns:
        None. Modifies shapes, blob_name_tracker and ops in-place by renaming.
    c                     d| v rd|  S | S )N_gradz
GRADIENTS/rd   r   s    r   r(   z_add_gradient_scope.<locals>.f   s    d?v&&Kr   Nr+   )r,   r-   r.   r(   s       r   _add_gradient_scoperm      s    " )32r   c                 ,    fd}t        | |||       y)a  
    `:i` has a special meaning in Tensorflow. This function replaces all colons with $ to avoid any possible conflicts.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        blob_name_tracker: Dictionary of all unique blob names (with respect to
            some context).
        ops: List of Caffe2 operators
        repl: String representing the text to replace ':' with. Usually this is
            '$'.

    Returns:
        None. Modifies blob_name_tracker in-place.

    c                 (    | j                  d      S )N:)replace)r   repls    r   r(   z_replace_colons.<locals>.f  s    ||C&&r   Nrl   )r,   r-   r.   rr   r(   s      ` r   _replace_colonsrs      s    "' )32r   c                 j   t               }| D ]8  }|j                  |j                         |j                  |j                         : | D ]  }|j                  r|j                  }n|j                  s|j                  r|j                  xs |j                  D cg c]!  }t
        j                  j                  |      # }}t
        j                  j                  |      }t
        j                  j                  ||j                        }n|j                  }|sJ t        ||      |_         yc c}w )a\  
    Give missing operators a name.

    We expect C2 operators to be generally unnamed. This gives them a scope
    (inferred from their outputs) and a name after their type. Duplicates will
    be postfixed by an index.

    Args:
        ops: List of Caffe2 operators to assign names to.

    Returns:
        None: Modifies 'ops' in-place.
    N)rE   rO   rK   rL   r   ospathdirnamecommonprefixjointyper   )r.   r   rI   r   	name_listscopes         r   _fill_missing_operator_namesr}     s     5DBHHBII  7777DYY"((;=99;P;PQ;P4.;PIQGG((3E77<<rww/D77Dt#D$/  Rs   &D0c                    | j                  d      sy| j                  t        j                  k(  s| j                  t        j                  k(  ry| j                  t        j
                  k(  rd| j                   S t        d|       )a  
    Handle the devices.

    Args:
        device_option (caffe2_pb2.DeviceOption): DeviceOption protobuf,
            associated to an operator, that contains information such as
            device_type (optional), cuda_gpu_id (optional), node_name (optional,
            tells which node the operator should execute on). See caffe2.proto
            in caffe2/proto for the full list.

    Returns:
        Formatted string representing device information contained in
            device_option.
    device_type z/cpu:*z/gpu:zUnhandled device)HasFieldr   r   CPUMKLDNNCUDA	device_id	Exceptiondevice_options    r   
_tf_devicer   +  sr     !!-0!!Z^^3$$
(9(99  JOO3}../00
&
66r   c                     t               }|D ]9  }t        j                         }||_        |j                  j	                  |g       ; | d   j
                  j                  j	                  |g       y)a6  
    Convert a list of ints to a TensorShapeProto representing the dimensions of a blob/object.

    Args:
        attr_dict: Dictionary to update (usually attributes of a Node)
        ints: List of integers representing dimensions of some object.

    Returns:
        None. Modifies attr_dict in-place.
    _output_shapesN)r   DimsizedimrM   rJ   shape)	attr_dictintsshape_protor   r   s        r   _add_tf_shaper   F  sc     #$K""$u%  $$**11;-@r   c                    |j                   }|dk(  r#|j                  rt        | |j                         y|j                  d      r|j                  | |   _        y|j                  d      r|j
                  | |   _        y|j                  d      rSt        |j                  t              r|j                  n#t        |j                        j                  d      | |   _        y|j                  r3| |   j                  j                  j                  |j                         y|j                  r3| |   j                  j
                  j                  |j                         y|j                  r:| |   j                  j                  j                  d |j                  D               y| |   j                  j                  j                  g        y)a3  
    Add attributes to a node. Key is the arg.name, and values can be shape, floats, strings, ints or an empty list.

    Args:
        attr_dict: Dictionary to update (usually attributes of a Node)
        arg: Object with name and data fields.

    Returns:
        None. Modifies attr_dict in-place.
    r   Nr(   r   sutf-8c              3   t   K   | ]0  }t        |t              r|nt        |      j                  d        2 yw)r   N)
isinstancebytesrF   encode)r>   r   s     r   r@   z_set_tf_attr.<locals>.<genexpr>}  s/      #
KVaAu%A3q6==+AA;s   68)r   r   r   r   r(   r   r   r   r   rF   r   floatsrJ   rM   strings)r   argks      r   _set_tf_attrr   Y  s]    	AG|i*
||C	!
||C	!
||Cu-CEE3suu:3D3DW3M 	! 	
zz!""3::.
xx!""388,
{{!"" #
KN;;#
 	
 	aLr"r   c                    |j                   sJ |       t               }|j                   |_         |j                  j                  |j                         |j                  |_        t        |j                        |_        | r0|j                  D ]!  }|| vr nt        |j                  | |          # |j                  D ]  }t        |j                  |        |S )a  
    Convert an operator to a node in a TF graph.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        op: The Caffe2 operator to convert to a TF graph node.

    Returns:
        n: The TF graph node created from op.
    )r   r   rK   rM   rz   rI   r   r   devicerL   r   attrr   r   )r,   rI   nrL   r   s        r   _operator_to_noder     s     77B7	AWWAFGGNN28877AD"**+AHiiFV#!&&&.1   vvQVVS! Hr   c                    | sJ g }| j                   D cg c]	  }||vs| }}|j                  |       t        |      }|dk(  rt               }|d   |_        |j
                  j                  | j
                         | j                  |_        t        | j                        |_        | j                  D ]  }t        |j                  |        |j                  |       |S |dkD  r| j                  r| j                  }	nTt!        |      }
t"        j$                  j'                  |
      }t"        j$                  j)                  || j                        }	|	sJ t+        ||	      | _        t        | j                        }|D ]X  }t               }||_        |j
                  j                  | j                  g       d|_        ||_        |j                  |       Z t               }| j                  |_        |j
                  j                  | j
                         | j                  |_        ||_        | j                  D ]  }t        |j                  |        |j                  |       |S c c}w )a"  
    Convert the operators to nodes.

    Args:
        op: Caffe2 operator to convert to node
        inter_blobs: Set of intermediate blobs
        seen: Names that have already been used and are not unique

    Returns:
        nodes: Nodes representing 'op' and the outputs of 'op'
    r   r   Blob)rL   rO   lenr   r   rK   rM   rz   rI   r   r   r   r   r   r   appendrJ   ru   rv   rx   ry   r   )rI   inter_blobsr   nodesorR   len_outputsr   r   r   r{   r|   r   rL   s                 r   _operator_to_node_simpr     s    I2E))<)Qq';q)G<KKg,KaI	rxx wwb../66C% Q@ L? 
q7777DWIGG((3E77<<rww/Dt#D$/B,,- F	AAFGGNNBGG9%ADAHLLO  I	rxx ww66C% QLY =s
   	I0I0c                    |sJ t               }||_        | j                  |g       }t        |      dkD  rd|_        nd|_        |j
                  j                  d |D               |r6|d   d   j                  t        fd|D              rt              |_
        |r||v rt        |j                  ||          |S )a  
    Convert a blob (operator input or output) to a node in a TF graph.

    Args:
        producing_ops: Dictionary of blob name to list of
            (producing_op, blob_index within producing_op.output) mapping.
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        name: String representing the name of this blob.

    Returns:
        n: The TF graph node created from this blob.
    r   r   Placeholderc              3   D   K   | ]  \  }}d |j                   |fz    yw)z%s:%dNrk   )r>   p_opr   s      r   r@   z _blob_to_node.<locals>.<genexpr>  s"     G;a7dii^+;s    c              3   B   K   | ]  }|d    j                   k(    yw)r   Nr   )r>   producerr   s     r   r@   z _blob_to_node.<locals>.<genexpr>  s!     O;xx{((F2;s   )r   r   getr   rI   rK   rM   r   allr   r   r   r   )producing_opsr,   r   r   produced_byr   s        @r   _blob_to_noder     s     K4	AAF  ##D"-K
;! GGNNG;GGQ"00O;OO!&)AH$&.afffTl+Hr   c                 ^    |sy| D ]%  }|j                  d      s|j                  d       ' y)a  
    Remove debug information from operators, they are copious.

    Args:
        ops: List of Caffe2 operators
        perform_clear: Boolean passed from _operators_to_graph_def specifying
            whether to remove the debug information. This boolean is passed into
            this function to reduce the complexity of _operators_to_graph_def.

    Returns:
        None. Modifies the list of Caffe2 operators in-place and removes the
        'debug_info' field.

    N
debug_info)r   
ClearField)r.   perform_clearrI   s      r   _clear_debug_infor     s,     ;;|$MM,' r   c                 V    | j                  d      dk  xs | j                  d      dk  S )a.  
    Blobs with names containing '_m' or 'grad' are part of the backward pass.

        This function references facebookresearch/Detectron/detectron/utils/net.py.

    Args:
        blob: The blob to inspect

    Returns:
        Boolean representing whether this blob is part of the forward pass
    __mr   grad)findblobs    r   _check_if_forwardr     s+     99Ua8499V#4q#88r   c                 &    | j                  d       S )z
    Check if the blob's name starts with '_gpu'.

    Args:
        blob: The blob to inspect

    Returns:
        Boolean representing whether this blob is associated with a gpu
    _gpu)
startswithr   s    r   _check_if_cpur   (  s     v&&&r   c                    t               }t               }| D ]F  }|j                  D ]  }|j                  |        |j                  D ]  }|j                  |        H t	        |j                  |            }t	        |j                  |            }|D ch c]  }|j                  d      s| }	}|D cg c]	  }||	vs| }}||	|fS c c}w c c}w )a]  
    Find the input, intermediate and output nodes of a set of operators.

    Args:
        ops: List of Caffe2 operators to look through

    Returns:
        input_blobs: The input nodes of the set of operators
        inter_blobs: The intermediate nodes of the set of operators
        output_blobs: The output nodes of the set of operators
    _)rE   rK   r   rL   rJ   
differencer   )
r.   in_blobs	out_blobsrI   
input_bloboutput_blobinput_blobsoutput_blobsbr   s
             r   _compute_in_outr   5  s     uHI((JLL$ #99KMM+& %  x**956K	,,X67L*@lall3.?1lK@+D|!q/CA|LD\11 ADs   C/C9	CCc                    |s| S g }| D ]  }t        |j                        }t        |j                        }|j                  dd= |j                  dd= |D cg c]  } ||      s| }}|D 	cg c]  }	 ||	      s|	 }
}	|
s~|j                  j                  |       |j                  j                  |
       |j	                  |        |S c c}w c c}	w )a  
    Filter unwanted operators based on criteria in 'filter_fn'.

    Args:
        ops: List of Caffe2 operators to filter
        filter_fn: Criteria function for whether inputs/outputs in an operator
            should be filtered.
        perform_filter: Boolean passed from _operators_to_graph_def specifying
            whether to filter operators

    Returns:
        new_ops: Subset of ops containing a subset of their inputs and outputs.
    N)rJ   rK   rL   rM   r   )r.   	filter_fnperform_filternew_opsrI   rQ   rR   r   
new_inputsr   new_outputss              r   _filter_opsr   R  s     
Gbhhryy/HHQKIIaL!'8A9Q<a
8"):'QYq\q': HHOOJ'II[)NN2  N 9:s   C&C0C>Cc                    ||j                          ni }|j                  t        |             t        ||       t	        |t
        |      }t	        |t        |      }|rt        | |||       |rt        | |||       |rt        | ||       |rt        | ||       t        |       |rt        | ||       i }t               }	t        |      \  }
}}t               }t        |
      }|D ]  }|rt!        |||      nt#        | |      g}|j$                  j'                  |       |j(                  D ]  }|	j+                  |        t-        |j.                        D ]9  \  }}|	j+                  |       |j1                  |g       j3                  ||f       ;  |r|
}	t5        |	      D ])  }|j$                  j'                  t7        |i |      g       + |S )a:  
    Convert a set of operators to a graph using the main function.

    Args:
        shapes: Dictionary mapping blob names to their shapes/dimensions.
        ops: List of Caffe2 operators, representing some computation graph
        ### **kwargs (model_to_graph_def, nets_to_graph_def, protos_to_graph_def) ###
        colon_replacement: Symbol to replace ':' with. ':i' in TF has a special
            meaning, so we need to replace it with a non-conflicting symbol.
        with_ssa: Boolean
        with_gradient_scope: Boolean
        blob_name_tracker: Dictionary tracking names of blobs (inputs/outputs
            from operators)
        show_simplified: Whether to show a simplified version of the model graph
            Sets all of the following values:
                clear_debug_info: Boolean representing whether to silence debug
                    info (which can be very verbose)
                show_forward_only: Boolean representing whether to only show
                    blobs involved in the forward pass
                show_cpu_only: Boolean representing whether to only show blobs
                    that are not associated with a gpu
                use_tensorflow_naming: Boolean representing whether to convert
                    some common Caffe2 naming conventions to their Tensorflow
                    counterparts
        custom_rename: Function string -> string that defines a custom
            renaming function to use.

    Returns:
        current_graph: GraphDef representing the computation graph formed by the
            set of operators.
    )rN   rO   rV   r   r   r   r   r+   rs   rS   rm   r}   r/   rE   r   r   r   r   noderM   rK   r   	enumeraterL   
setdefaultr   sortedr   )r,   r.   colon_replacementwith_ssawith_gradient_scoper-   show_simplifiedcustom_renamer   blobsr   r   r   current_graphr   rI   nodes_from_opr   r   r   r   s                        r   _operators_to_graph_defr   u  s   R $!_S12c?+
c,o
>C
c=/
:CF-sMB 138IJ 137F$5s; % ):C@8:MEE"1#"6KaJM{D  #2{D9#FB/0 	
 	!!-0((JIIj! #'		2NA{IIk"$$["5<<b!WE 3  u!!=D#I"JK  r   c                     | j                  d      sy| j                  D ]9  }|j                  d      r|j                  j                  | j                         ; y)a  
    Propagate the device options from net to operators.

    Args:
        net_def: A caffe2_pb2.NetDef representing a computation graph. The graph
            consists of Caffe2 operators.

    Returns:
        None. Iterates through all ops contained within the net. For each op,
            modifies the op device_option in-place to be the net device_option
            if the op has no pre-existing device_option, and leaves the op as-is
            if it already has a device_option.
    r   N)r   rI   r   CopyFrom)net_defrI   s     r   _propagate_device_optionr     sI     O,jj{{?+%%g&;&;< r   c                     	 t        j                  |       \  }}|S # t        $ r"}t        j	                  d|       i cY d}~S d}~ww xY w)a  
    Get missing shapes for all blobs contained in the nets.

    Args:
        nets: List of core.Net to extract blob shape information from.

    Returns:
        Dictionary containing blob name to shape/dimensions mapping. The net
            is a computation graph that is composed of operators, and the
            operators have input and output blobs, each with their own dims.
    zFailed to compute shapes: %sN)r   InferShapesAndTypesr   logwarning)netsr,   r   es       r   _try_get_shapesr     sF     11$7	 2A6	s    	AAAAc                 J    | j                   | j                  g}t        |fi |S )a  
    Convert a Caffe2 model to a Tensorflow graph.

    This function extracts 'param_init_net' and 'net' from the model and passes it to nets_to_graph()
    for further processing.

    Args:
        model (cnn.CNNModelHelper, model_helper.ModelHelper): The model to
            extract the nets (instances of core.Net) from.

    Returns:
        Call to nets_to_graph_def() with extracted 'param_init_net', 'net' and
            **kwargs. See _operators_to_graph_def for detailed **kwargs.
    )param_init_netnetnets_to_graph_def)modelkwargsr   s      r   model_to_graph_defr     s(       %)),DT,V,,r   c                     i }| D cg c]%  }t        j                  |j                               ' } }t        j                  |      }t        | |fi |S c c}w )a  
    Convert a set of Caffe2 nets to a Tensorflow graph.

    Args:
        nets: List of core.Nets. core.Net is a wrapper around a NetDef protobuf.
            The corresponding protobuf can be extracted using .Proto().
        shapes: Dictionary mapping blob names to their shapes/dimensions.

    Returns:
        Call to protos_to_graph_def() with the extracted NetDef protobufs and
            **kwargs. See _operators_to_graph_def for detailed **kwargs.
    )copydeepcopyProtoprotos_to_graph_def)r   r,   r   r   s       r   r   r     sQ    " F267$3DMM#))+&$D7]]6"FtV6v66 8s   *Ac                     | D ]  }t        |        t        j                  |xs i       }| D cg c]  }|j                  D ]  }|  }}}t	        ||fi |S c c}}w )a  
    Convert a set of Caffe2 net definitions to a Tensorflow graph.

    Args:
        net_defs: List of caffe2_pb2.NetDef protobufs representing computation
            graphs.
        shapes: Dictionary mapping blob names to their shapes/dimensions.

    Returns:
        Call to _operators_to_graph_def() with the extracted operators from the
            NetDefs and **kwargs. See _operators_to_graph_def for detailed
            **kwargs.
    )r   r   r   rI   r   )net_defsr,   r   r   r   rI   r.   s          r   r   r   $  s_      % ]]6<R(F%
;X'

"2
2XC
;"639&99 <s   A)r   )$TTNFNr;   )3r   loggingru   r)   "tensorboard.compat.proto.graph_pb2r   %tensorboard.compat.proto.node_def_pb2r   )tensorboard.compat.proto.tensor_shape_pb2r   caffe2.protor   caffe2.pythonr   r   typingr	   r
   r   r   	getLogger__name__r   rF   rG   r   r/   rS   rV   r^   r+   rm   rs   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rd   r   r   <module>r     s      	 	 7 9 F # ) ) )g!CH C c 0&3R48n*"",^343.0@76A&)#X8:z F(.9 
'2: L Wt=*,-&7.:r   