a
    ==ice7                     @   s&  d dl mZ d dlmZ d dlmZmZ d dlmZ d dl	Z	d dl
Z
d dlZd dlZd dlZd dlmZmZmZmZ dZdZd/d	d
Zdd Zdd Zd0ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Z G dd  d e!Z"d!d" Z#d#d$ Z$d1d%d&Z%d'd( Z&d)d* Z'd+d, Z(d-d. Z)dS )2    )
caffe2_pb2)	viewitems)DecodeErrorMessage)text_formatN)integer_typesbinary_type	text_typestring_typesZoptimizer_iterationZiteration_mutexc                    sl    pg  t  ts g tdd  D s8J d  fdd}|| } ||}| |kpjt| t|kS )zM
    Two ops are identical except for each field in the `ignore_fields`.
    c                 s   s   | ]}t |tV  qd S N)
isinstancer	   ).0f r   d/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/utils.py	<genexpr>        z OpAlmostEqual.<locals>.<genexpr>z*Expect each field is text type, but got {}c                    s,   t | }  D ]}| |r| | q| S r   )copydeepcopyHasFieldZ
ClearField)opfieldignore_fieldsr   r   clean_op#   s
    

zOpAlmostEqual.<locals>.clean_op)r   listallformatstr)Zop_aZop_br   r   r   r   r   OpAlmostEqual   s    
r   c                 C   sP   | j dkr0tj| jtjd| j | j| j| jS tj| jtjd| j	j
S d S )Nr   dtype)numnpasarraydatafloat32reshapeZchannelsheightwidthshapedim)Zblobr   r   r   CaffeBlobToNumpyArray/   s    
r,   c                 C   s\  | j tjjkr(tj| jtjd| j	S | j tjj
krPtj| jtjd| j	S | j tjjkrxtj| jtjd| j	S | j tjjkrtj| jtjd| j	S | j tjjkrtj| jtjd| j	S | j tjjk rtj| jtjd| j	S | j tjjkrtj| jtjd| j	S | j tjjkrFtj| jtjd| j	S tdt| j  d S )Nr    z$Tensor data type not supported yet: )	data_typer   TensorProtoFLOATr#   r$   
float_datar&   r'   dimsDOUBLEdouble_datafloat64INT64
int64_dataint64INT32
int32_dataintINT16int16UINT16uint16INT8int8UINT8uint8RuntimeErrorr   tensorr   r   r   Caffe2TensorToNumpyArray:   sf    rF   c                 C   s  t  }|j| j |r ||_| jtjkrTt jj	|_
|jt|  t n| jtjkrt jj|_
|jt|  tj nb| jtjkrt jj|_
|jt|  tj n,| jtjks| jtjkrt jj|_
|j|  tj  n| jtjkr8t jj|_
|jt|  tj n| jtjkrnt jj|_
|jt|  tj n~| jtjkrt jj |_
|jt|  tj nH| jtj!krt jj"|_
|jt|  tj! nt#dt$| j |S )Nz#Numpy data type not supported yet: )%r   r.   r1   extendr*   namer!   r#   r&   r/   r-   r0   r   flattenZastypefloatr4   r2   r3   r7   r5   r6   r:   int32r8   r9   tolistr<   r;   r>   r=   r@   r?   rB   rA   rC   r   )ZarrrH   rE   r   r   r   NumpyArrayToCaffe2TensorY   s@    

 
 




rM   c              	   C   sV  t  }| |_t|tjj}t|tjrN|j	j
tju rN|j|   |S t|tjrh|  }nt|tjr~t|}t
|tu r||_nt
|tv st
|tu r||_nt|tr||_nt|tr|d|_nnt|t jr|j| nPt|tr| |_n6|rPt dd |D rP|jdd |D  n|rt dd |D r|j!dd |D  n|rt dd |D r|j"dd |D  n|rt d	d |D r|j#| nv|rt d
d |D r|j"dd |D  nD|r<t$d%| |t
|t&dd |D nt$d%| |t
||S )z*Makes an argument based on the value type.utf-8c                 s   s    | ]}t |ttjfv V  qd S r   )typerJ   r#   float_r   vr   r   r   r      r   zMakeArgument.<locals>.<genexpr>c                 s   s(   | ] }t |tju r| n|V  qd S r   )rO   r#   rP   itemrQ   r   r   r   r      s   c                 s   s,   | ]$}t |tv p"t |ttjfv V  qd S r   )rO   r   boolr#   int_rQ   r   r   r   r      s   c                 s   s(   | ] }t |tju r| n|V  qd S r   )rO   r#   rU   rS   rQ   r   r   r   r      s   c                 s   s"   | ]}t |tpt |tV  qd S r   )r   r   r	   rQ   r   r   r   r      s   c                 s   s&   | ]}t |tr|d n|V  qdS )rN   N)r   r	   encoderQ   r   r   r   r      s   c                 s   s   | ]}t |tjV  qd S r   )r   r   NetDefrQ   r   r   r   r      r   c                 s   s   | ]}t |tV  qd S r   )r   r   rQ   r   r   r   r      r   c                 s   s   | ]}|  V  qd S r   )SerializeToStringrQ   r   r   r   r      r   zBUnknown iterable argument type: key={} value={}, value type={}[{}]c                 s   s   | ]}t |V  qd S r   )rO   rQ   r   r   r   r      r   z5Unknown argument type: key={} value={}, value type={})'r   ArgumentrH   r   collectionsabcIterabler#   Zndarrayr!   rO   r&   ZfloatsrG   rI   rL   ZgenericZasscalarrJ   r   r   rT   ir   sr	   rV   rW   nZCopyFromr   rX   r   intsstringsnets
ValueErrorr   set)keyvalueargumentiterabler   r   r   MakeArgument}   sl    










ri   c              	   C   sD   |  }zt || |W S  t jtfy>   || | Y S 0 dS )a,  Reads a protobuffer with the given proto class.

    Inputs:
      cls: a protobuffer class.
      s: a string of either binary or text protobuffer content.

    Outputs:
      proto: the protobuffer of cls

    Throws:
      google.protobuf.message.DecodeError: if we cannot decode the message.
    N)r   Parse
ParseErrorUnicodeDecodeErrorZParseFromString)clsr^   objr   r   r   TryReadProtoWithClass   s    
ro   c                 C   s.   t |D ] \}}t| |u r||   S qdS )zNGets a specific field from a protocol buffer that matches the given class
    N)r   rO   )rn   function_maprm   funcr   r   r   GetContentFromProto   s    rr   c              	   C   sN   t |D ]8\}}zt|| }||W   S  ty>   Y qY q0 qtdd S )Nz$Cannot find a fit protobuffer class.)r   ro   r   )r^   rp   rm   rq   rn   r   r   r   GetContentFromProtoString   s    
rs   c                 C   sr   t |}t| | }W d   n1 s,0    Y  t |d}||  W d   n1 sd0    Y  dS )z:Convert a text file of the given protobuf class to binary.Nw)openro   readwriterX   )Zproto_classfilenameZout_filenamer   protoZfidr   r   r   ConvertProtoToBinary   s    
,rz   c               
   C   s   ddl m} m} | |jdg dg|| jdd | d}|dddf |dddf t	|dddf t	|dddf dS )	z|Get GPU memory usage stats from CUDAContext/HIPContext. This requires flag
       --caffe2_gpu_memory_tracking to be enabledr   	workspacecoreZGetGPUMemoryUsageZ____mem____Zdevice_optionN   )Ztotal_by_gpuZ
max_by_gputotalZ	max_total)
caffe2.pythonr|   r}   RunOperatorOnceCreateOperatorDeviceOptionZGpuDeviceTypeZ	FetchBlobr#   sum)r|   r}   br   r   r   GetGPUMemoryUsageStats   s    
r   c              	   C   s<   ddl m}m} ||jdt| t| |tjd d S )Nr   r{   ZFreer~   )	r   r|   r}   r   r   r   r   r   CPU)Zblobsr|   r}   r   r   r   
ResetBlobs  s    
r   c                   @   s   e Zd ZdZedd ZdS )	DebugModea=  
    This class allows to drop you into an interactive debugger
    if there is an unhandled exception in your python script

    Example of usage:

    def main():
        # your code here
        pass

    if __name__ == '__main__':
        from caffe2.python.utils import DebugMode
        DebugMode.run(main)
    c                 C   sj   z| W S  t y    Y nJ tyd   dd l}td tt d  t |  td  Y n0 d S )Nr   zjEntering interactive debugger. Type "bt" to print the full stacktrace. Type "help" to see command listing.r   )KeyboardInterrupt	Exceptionpdbprintsysexc_infoZpost_mortemexit)rm   rq   r   r   r   r   run'  s    
zDebugMode.runN)__name__
__module____qualname____doc__classmethodr   r   r   r   r   r     s   r   c                 C   s   | |krt d|| |d S )Nz{}. {} != {})r   r   )ar   msgr   r   r   raiseIfNotEqual;  s    r   c                    s   t   fdd}|S )z
    Use this method to decorate your function with DebugMode's functionality

    Example:

    @debug
    def test_foo(self):
        raise Exception("Bar")

    c                     s    fdd}t |S )Nc                      s    i S r   r   r   )argsr   kwargsr   r   rq   N  s    z$debug.<locals>.wrapper.<locals>.func)r   r   )r   r   rq   r   )r   r   r   wrapperL  s    zdebug.<locals>.wrapper)	functoolswraps)r   r   r   r   r   debug@  s    r   c                 C   s   |dur|nt }|dur|nt}ddlm} | |s||jtjdgdJ | j	g |dg||j
jd}| g |g}|||g|g W d   q1 s0    Y  n
| |}|S )z
    Often, a mutex guarded iteration counter is needed. This function creates a
    mutex iter in the net uniquely (if the iter already existing, it does
    nothing)

    This function returns the iter blob
    Nr   )r}   zdevice_type_override:cpu)Z
extra_infor   )r*   rf   r!   )OPTIMIZER_ITERATION_NAMEITERATION_MUTEX_NAMEr   r}   ZBlobIsDefinedZDeviceScoper   r   r   ZConstantFillZDataTyper5   ZCreateMutexZ
AtomicIterZ
GetBlobRef)Zinit_netnetiterZ
iter_mutexZiter_valr}   	iterationr   r   r   BuildUniqueMutexIterU  s(    
2
r   c              
      s   t | t ksJ i  t| D ]b}|| krt| |ttr  vsvJ d| | fdd D d  |< q S )Nz<Failed to resolve {} as Enum: duplicate entries {}={}, {}={}c                    s   g | ]} | kr|qS r   r   )r   re   enumrR   r   r   
<listcomp>  r   z$EnumClassKeyVals.<locals>.<listcomp>r   )rO   diruppergetattrr   r
   valuesr   )rm   kr   r   r   EnumClassKeyValsz  s    


r   c                 C   s   i }| D ]}| dsq|jjD ]r}|jdkr0q |j|jkr`| |jr`t||j||j<  qq |j|jkr t||j}t|dkr |||j<  qq d||j< q|S )z
    Convert a list of arguments to a name, value dictionary. Assumes that
    each argument has a name. Otherwise, the argument is skipped.
    rH   r   N)	r   Z
DESCRIPTORfieldsrH   labelZLABEL_OPTIONALr   ZLABEL_REPEATEDlen)r   Zansargdlist_r   r   r   
ArgsToDict  s"    


r   c                 C   s6   | j dksJ | d| j d fttd| j d  S )Nr   r   ndimZ	transposetuplerangerD   r   r   r   	NHWC2NCHW  s    r   c                 C   s,   | j dksJ | dttd| j  d S )N   )r   )r   r   rD   r   r   r   	NCHW2NHWC  s    r   )N)N)NNr   )*Zcaffe2.protor   Zfuture.utilsr   Zgoogle.protobuf.messager   r   Zgoogle.protobufr   r   rZ   r   r   numpyr#   sixr   r   r	   r
   r   r   r   r,   rF   rM   ri   ro   rr   rs   rz   r   r   objectr   r   r   r   r   r   r   r   r   r   r   r   <module>   sB   

$H$   
%