a
    ==icg                     @   sj  d 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dlmZ ddlmZ ddlZddlZddl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mZmZmZmZ ddlmZ dd	l m!Z! ddl"m#  m$Z% ddl&Z&d
d Z'dd Z(G dd de)Z*dd Z+G dd de,Z-e.dg dZ/G dd deZ0e0j1Z1e0j2Z2e0j3Z3e0j4Z4e0j5Z5e0j6Z6dS )zaBackend for running ONNX on Caffe2

To run this, you will need to have Caffe2 installed as well.
    N)core	workspacernn_cellgru_cell)ModelHelper)
caffe2_pb2)TensorProto)BackendDevice
DeviceTypenamedtupledict)	Workspace)	Caffe2Repc                 C   s(   z|  dW S  ty"   |  Y S 0 d S )Nzutf-8)decodeAttributeError)s r   k/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/onnx/backend.pyforce_unicode'   s    r   c                 C   s(   t jtjt jtji}t|| j | j	S N)
r   CPUr   CUDAr   ZGpuDeviceTyper   ZDeviceOptiontypeZ	device_id)devicemr   r   r   get_device_option-   s    r   c                   @   s,   e Zd ZdZedd Zdd fddZdS )	OnnxAttributeszx
    This is a more convenient way to work with ONNX/Caffe2 attributes
    that is not the protobuf representation.
    c                 C   s"   t  }| D ]}t|||j< q
|S r   )r   convertAttributeProtoname)argsdargr   r   r   	from_onnx8   s    zOnnxAttributes.from_onnxc                 C   s   | S r   r   kr   r   r   <lambda>?       zOnnxAttributes.<lambda>c                 c   s8   |   D ]*\}}||dkrtjj|||V  qd S )N )itemscaffe2pythonutilsMakeArgument)selfkmapr$   vr   r   r   r)   ?   s    zOnnxAttributes.caffe2N)__name__
__module____qualname____doc__staticmethodr"   r)   r   r   r   r   r   3   s   
r   c                 C   s   |  dr| jS |  dr | jS |  dr0| jS |  dr@| jS |  drZt| jtjS t	| j
rnt| j
S t	| jrt| jS t	| jrt| jS t	| jrg }| jD ]}|t|tj q|S td| dS )z
    Convert an ONNX AttributeProto into an appropriate Python object
    for the type.

    NB: Tensor attribute gets returned as the straight proto.
    fir   tgzUnsupported ONNX attribute: {}N)HasFieldr5   r6   r   r7   Caffe2Backend_graph_to_netr8   _known_opset_versionlenfloatslistintsstringsgraphsappend
ValueErrorformat)Zonnx_argretvalr8   r   r   r   r   E   s,    












r   c                   @   s   e Zd ZdZdd ZdS )OnnxNodeaX  
    Reimplementation of NodeProto from ONNX, but in a form
    more convenient to work with from Python.

    We may temporarily edit these nodes to get them into Caffe2 form,
    before actually translating into the Caffe2 protobuf, since this
    is easier than decomposing everything, and putting it back together
    when we're ready.
    c                 C   sB   t |j| _t |j| _t|j| _t|j| _	t|j
| _d S r   )strr   op_typer   r"   	attributeattrsr?   inputinputsoutputoutputs)r-   noder   r   r   __init__q   s
    zOnnxNode.__init__N)r0   r1   r2   r3   rQ   r   r   r   r   rG   g   s   	rG   	Caffe2Ops)opsinit_opsinterface_blobsc                       s  e Zd ZdZi Zdddddddd	d
ddddddddddZddiZddiddiddidddddiddidd d!d"d#d$d%Zd&d&d&d'd(d)d*d+Ze	
 Zed,d- Zed.ed/f fd0d1	Zeded2d3Zed4d5 Zed6d7 Zed8d9 Zed:d; Zed<d= Zed>d? Zed@dA ZedBdC ZedDdE ZedFdG ZedHdI ZedJdK ZedfdMdNZedgdOdPZedh fdQdR	ZedSdT Z dUdVhZ!edWdX Z"edYdZ Z#ed[d\ Z$ed]d^ Z%ed.efd_d`Z&edadb Z'edi fdcdd	Z(  Z)S )jr:   	   ZMaxPoolZAveragePoolZPadImageZNegativeZ	SpatialBNZInstanceNormZBatchMatMulZResizeNearestCopyZEQLTGT
ExpandDims	ONNXWhileZ	NumpyTileZGaussianFillZUniformFill)ZGlobalMaxPoolZGlobalAveragePoolZPadZNegZBatchNormalizationInstanceNormalizationZMatMulUpsampleZIdentityr\   ZEqualZLessZGreater	UnsqueezeLoopTileRandomNormalRandomUniformZkernel_shapeZkernelsaxesdimspermr'   )modescalesZoutput_paddingadjsgammascalethen_netelse_net)Zthen_branchZelse_branchminmax)lowhigh)Squeezer^   	Transposer]   ZConvTransposeZSeluIfrb   _create_rnn_variant_create_loop
_create_ifZ_create_upsampleZ_create_gaussian_fill)LSTMGRURNNr_   rs   r]   ra   c                 C   s
   | j  S r   )_dummy_nameZnew_dummy_nameclsr   r   r   
dummy_name   s    zCaffe2Backend.dummy_namer   Nc              	      s  t t| j|||||d g }tt|}t  t|l t|t	r|
 D ]<\}}	 ||	 |tjj|tjj|	j |	jd  qPnzt|jt|ksJ d|jt|jt|t|j|D ]<\}}	 ||	 |tjj|tjj|	j |	jd  qg }
t| j}|| ||}|d |d  D ].}t }|| |j !| |
| q< "|
  fdd|j#D }t$d|j#| W  d    S 1 s0    Y  d S )	N)r   outputs_infoopset_version)r   	elem_typeshapez{}: expected {} but got {}r      c                    s   g | ]}  |qS r   )Z	FetchBlob).0r   wsr   r   
<listcomp>   r&   z*Caffe2Backend.run_node.<locals>.<listcomp>ZOutputs)%superr:   run_noder   r
   r   r   ZDeviceScope
isinstancedictr(   FeedBlobrC   onnxhelperZmake_tensor_value_infomappingZNP_TYPE_TO_TENSOR_TYPEdtyper   SerializeToStringr=   rL   rE   rI   zipCrz   convert_noder   OperatorDefParseFromStringdevice_optionCopyFromZRunOperatorsOncerN   r   )r|   rP   rM   r   r   r~   value_infosr   keyvaluerS   cbackendZops_strr   opZoutput_values	__class__r   r   r      sH    




zCaffe2Backend.run_nodec                 C   sl  |s|j sJ |p|j }t }|j }d|_ dd }|jtjfv r^d|_|j	
|| n|jtjfv rd|_|j	
|| n|jtjtjfv rd|_|j
|| n|jtjtjtjtjtjfv rd|_|j
|| nZ|jtjkr
d|_|j
|| n4|jtjkr.d	|_|j
|j ntd
|j|j }d|_ |j
|j |j| |S )z
        Given an Onnx TensorProto, translate it into a Caffe2 operator
        which produces the given tensor filling op.
        valuesc                 S   s   t j|   S r   )r   numpy_helperto_arrayflattentolist)onnx_tensorr   r   r   tensor2list  s    z<Caffe2Backend._create_tensor_filling_op.<locals>.tensor2listZGivenTensorFillZGivenTensorDoubleFillZGivenTensorInt64FillZGivenTensorIntFillZGivenTensorBoolFillZGivenTensorStringFillzunrecognized tensor type {}r   )r   r   r   r!   add	data_typer   FLOATr   r>   extendDOUBLEZINT64ZUINT32r@   ZUINT8ZINT8ZUINT16ZINT16INT32BOOLSTRINGrA   Zstring_dataRuntimeErrorrE   rd   rN   rC   )r|   r   r   c2_opZ	c2_valuesr   Zc2_shaper   r   r   _create_tensor_filling_op   sN    



z'Caffe2Backend._create_tensor_filling_opc                    s   |D ]\}}}	fdd|D  t  D ]B\}
}|
| |
d | f}t|g|	R  \}}|j||||d q,|r fdd|D }|j|df |  gdd qd S )	Nc                    s   g | ]}d  |f qS )z%s/%s_%sr   )r   prefix)r   name_tor   r   r   +  r&   z5Caffe2Backend._rnn_reform_weights.<locals>.<listcomp>r   startsendsc                    s   g | ]} | qS r   r   r   r6   )
gate_blobsr   r   r   1  r&   z%s/%sr   Zaxis)	enumerater   SliceConcatr}   )r|   reformsr   hidden_sizeinit_netZgatesZreorder_indicesZ	name_fromZ	do_concatZ
extra_dimsr6   xZdim0r   r   Zreordered_gate_blobsr   )r   r   r   r   _rnn_reform_weights(  s    z!Caffe2Backend._rnn_reform_weightsc           "      C   sT  |   }||
 }d| | }|| }|j||| |d|  g|d|  gd}|j||| |d|  g|d|  gd}|j||| |d|  dg|d|  dgd}|j||| |d|  dg|d|  dgd}g }|D ]:\}}||jj||| |d ddg|d ddgd q|dkr|d ur2|}n|j||d }|jj||d dgdgd}|jj||d dgdgd}|jj||g|d	 dd
}|jj|||   gdgd |jj||d tj	j
d}|||||||
| |dkr|j||g|d } n|} |t||| |||	|
|ddd	}!|dkrP|j|!d |g|d |!d< |!S )N   r   r   r   z/input_shapez/batch_size_slicez/seq_len_slicez/dummy_sequence_lensr   r   z/seq_lens_for_reverse)toz/input-reversedFT)Zdrop_statesZforward_onlyz/output-reversed)r}   r   rC   netZShaper`   ReshapeZCastr   ZDataTyper   ZReversePackedSegsr?   )"r|   
input_blobBWRZinitial_states_and_namessequence_lenspred_mhr   
input_sizer   Z	num_gatesdirection_offsetBiBrW_R_reform	make_cellZkeep_outputsr   Zgates_hidden_sizeZbias_offsetZweight_offsetZinitial_states_slicedZinitial_stateZname_suffixZseq_lens_for_reverseZinput_shape
batch_sizeZseq_lenZdummy_sequence_lensrL   rO   r   r   r   _make_rnn_direction4  sv    




z!Caffe2Backend._make_rnn_directionc                    s  |d usJ d|d us J dt |j}|dt|dd}|jdkrht|ddd  n|jd	kr~|d
d|rJ dt|  |dv sJ d|jdv r|j\
 n|jdkr|j\
 dkrd t	
|jj|jj|jj|jjD ]*}|jkr|jjjjd j qBqtdt tdj gg dd jdgd j gg dd jdgd j   gddgd j  dgd |jdkr"dd fdd 
fdd}n|jd	krlfddfd d 
fd!d}nF|jdkrfd"dd#d  
fd$d}|dkr<|dtdtD ]}	j|	 |j|	  q҈d urj d gd g jj!d g|jd gdgd n|d%kr(|d}
|d}jj"|
d |d g  gdd&\}}d urj |g|g jj|  gg d'd\}}jj#||jd g d(d) tdt|jD ]2}	jj"|
|	 ||	 g|j|	  gdd& qd*d+ |jj$D 	d,d+ |jj%D t&	fd-d. fD }g }g }|r||n|'( j) |'( j) t*||t+( j,S )/Nz4cannot convert RNNs without access to the full modelr   	directionforwardry   Zactivations)tanhr   rx   linear_before_resetzunsupported RNN attributes: )r   bidirectionalz"unsupported backwards RNN/GRU/LSTM)ry   rx   rw   r'   r   z3best-effort shape inference for RNN/GRU/LSTM failedzinit-net)r   r   r   r   )rd   r   r   c                  W   s   d S r   r   )r   r   r   r   r     s    z1Caffe2Backend._create_rnn_variant.<locals>.reformc                     s   t j| d i|S )N
activation)r   ZBasicRNNr   kwargs)r   r   r   r     s    z4Caffe2Backend._create_rnn_variant.<locals>.make_cellc                    s8     dfg
d| dddd	dd S )	N
/initial_hr   /i2h_b
/gates_t_b/i2h_w
/gates_t_wc                 S   s   | S r   r   r   r   r   r   r%     r&   ECaffe2Backend._create_rnn_variant.<locals>.make_rnn.<locals>.<lambda>r   r   r   r   r   r|   r   r   	initial_hr   r   r   r   r   r   r   r   make_rnn  s    
z3Caffe2Backend._create_rnn_variant.<locals>.make_rnnc              	      sP   |dddgf|dddgf| ddg f|ddg ff}  ||||g dg d	 d S )
Ni2h_wTr   r   Zgate_t_wFi2h_bZgate_t_b)updateresetrN   )r   r   r   r   r   r   r   r   r   r   r   r   r{   r   r   r     s    

c                     s   t j| d i|S )Nr   )r   rx   r   )r   r   r   r     s    c                    s8     dfg
d| dddd	dd S )	Nr      Z	_bias_i2hZ_bias_gatesz
/i2h_w_prez/gates_t_w_prec                 S   s   | S r   r   r   r   r   r   r%     r&   r   r   r   r   r   r   r     s    
c              	      sP   |dddgf|dddgf| ddg f|ddg ff}  ||||g dg d d S )	Nr   Tr   Z	gates_t_wr   Z	gates_t_b)rL   rN   Zforgetcellr   r   r   r   r   r   r{   r   r   r     s    

c                  _   s   t j| i |S r   )r   rw   r   r   r   r   r     s    c                    s>     dfdfg	d| dddd
dd	 S )
Nr   z
/initial_c   r   r   r   r   c                 S   s   | d | d | d gS )Nr   r   r   r   r   r   r   r   r%     r&   r   r   r   )r   r   r   r|   r   r   	initial_cr   r   r   r   r   r   r   r   r   r     s    
r   r   )r   r   r   r   r   )rc   c                 S   s   h | ]
}|j qS r   r   r   r   r   r   	<setcomp>  r&   z4Caffe2Backend._create_rnn_variant.<locals>.<setcomp>c                 S   s   h | ]}|j D ]}|qqS r   )rN   )r   rP   rN   r   r   r   r     r&   c                 3   s   | ]}| v p|v V  qd S r   r   )r   r   )initializersrO   r   r   	<genexpr>  r&   z4Caffe2Backend._create_rnn_variant.<locals>.<genexpr>)-r   rK   popr   rI   lowerrH   keysrM   	itertoolschaingraphrL   
value_infor   r   tensor_typer   dim	dim_valuer   r   r   ZNetr   r}   rq   ranger=   r   rW   rO   ZVariableLengthSequencePaddingrZ   r   rr   initializerrP   allr   ZProtor   rR   r?   external_input)r|   
init_model
pred_modelnr   rK   r   r   r   r6   Z	outputs_fZ	outputs_bZconcatted_output_Zreshaped_outputZhas_initializersZpred_opsrT   r   )r   r   r   r   r|   r   r   r   r   r   r   r   r   r   rO   r   r   r   r   rt   y  s    








&
&
&

$



&
z!Caffe2Backend._create_rnn_variantc                 C   sH   g }d|j v r||j d  | ||||}|j| t|gg g S )N__control_inputs)rK   r   _common_onnx_node_to_caffe2_opZcontrol_inputrR   )r|   r	  r
  r  r   control_inputsrP   r   r   r   _create_control_op  s    
z Caffe2Backend._create_control_opc                 C   sd   |j D ].}t|jD ]\}}||v r|| |j|< qqt|jD ]\}}||v r@|| |j|< q@d S r   )r   r   rN   external_output)r|   r   Z
remap_dictr   r6   r   outr   r   r   _remove_ssa  s    
zCaffe2Backend._remove_ssac                 C   s   |  ||||}|d d jdks&J |d d }d  }}g }	|jD ]4}
|
jdkrX|
j}|
jdkrh|
j}|
jdkrD|
j}	qD|r|sJ |j}|j}|j}t|t|ksJ t|t|ksJ |jD ]4}
|
jdkr|
jj	
|	 |
jdkr|
jj	
|	 q|S )Nr   rs   rk   rl   r  )r  r   r!   r   r  rA   r  rN   r=   r  r   )r|   r	  r
  r  r   rS   Zif_oprk   rl   r  r!   Zthen_net_outsZelse_net_outsZ
op_outputsr   r   r   rv   !  s0    






zCaffe2Backend._create_ifc           
      C   s   |  ||||}|d d jdks&J |d d }|jtjjddg |jtjjddg |jtjjddg g }|jD ]}|jdkr|j	}qd}	|jD ],}|jdkrt
|jjd	 }	|jj| q|jtjjd
|	g |S )Nr   r[   Zhas_trip_countTZhas_condZdisable_scopesr  bodyr   num_loop_carried_deps)r  r   r!   r   r)   r*   r+   r,   r   rA   r=   r  r  )
r|   r	  r
  r  r   rS   Zwhile_opr  r!   r  r   r   r   ru   ?  s*    




zCaffe2Backend._create_loopc                 C   sD   | dr@|jtdkr@|j|vr4td|jn||j |_d S )Nraw_datas
   __EXTERNALzBTensorProto for value {} referenced raw data but it was not found!)r9   r  bytesr   r   rE   )r|   tpraw_values_dictr   r   r   _substitute_raw_valueW  s    
z#Caffe2Backend._substitute_raw_valuec                 C   s~   |D ]t}|j D ]h}|dr*| |j| |jD ]}| || q0|dr\| |jj| |jD ]}| |j| qbqqd S )Nr7   r8   )	rJ   r9   r  r7   Ztensors _visit_and_substitute_raw_valuesr8   rP   rB   )r|   nodesr  rP   attrr7   r8   r   r   r   r  _  s    




z.Caffe2Backend._visit_and_substitute_raw_valuesc                 C   s.   |j jD ]}| || q| |j j| d S r   )r   r  r  r  rP   )r|   modelr  initr   r   r   _external_value_resolution_passl  s    z-Caffe2Backend._external_value_resolution_passc                 C   s&   |D ]}| |jtj|| qd S r   )r   r   r   r   r   )r|   r  r   r   r  r   r   r   _direct_initialize_parameterst  s    z+Caffe2Backend._direct_initialize_parametersc                 C   s\   |D ]R}|j |v rqtdd |jjjjD }||j tj|t	j
j|jjj d| qd S )Nc                 s   s   | ]}|j V  qd S r   )r  )r   r    r   r   r   r   ~  r&   z:Caffe2Backend._direct_initialize_inputs.<locals>.<genexpr>)r   )r   r?   r   r  r   r  r   npZonesr   r   ZTENSOR_TYPE_TO_NP_TYPEr   )r|   rM   initializedr   r   r  r   r   r   r   _direct_initialize_inputsy  s    
z'Caffe2Backend._direct_initialize_inputsFc                 C   st   g d}|r| d |r$| d ztj| |}W n8 tyn   tdtj dd l	}|| |}Y n0 |S )N)Zfuse_consecutive_transposesZeliminate_nop_transposeZfuse_transpose_into_gemmZlift_lexical_referencesZ
split_initZsplit_predictz?OptimizerWarning: optimizer module not found in ONNX version {}r   )
rC   r   Z	optimizeroptimizer   warningswarnrE   __version__onnxoptimizer)rL   r  predictZpassesr  r)  r   r   r   optimize_onnx  s    

zCaffe2Backend.optimize_onnxc              
   K   s   t j|dd}|dd}t|}W d    n1 s<0    Y  t| td }i }|D ]<}	||	d}
|
 ||	< W d    qb1 s0    Y  qbW d    n1 s0    Y  | j||fd|i|S )Nr)rf   Z__MODEL_PROTOr  )	zipfileZipFileopenr   loadsetnamelistreadprepare)r|   filer   r   zr5   r  Z
blob_namesr  r   Z	blob_filer   r   r   prepare_zip_archive  s    (Jz!Caffe2Backend.prepare_zip_archivec                    sl  | dds&tt| j||fi | d}|jD ]T}|drH|jdkrr|j}|j| jkrt	
d| j|j q0t	
d|j q0|du r|jdkrtd	nd
}ztj|}W n ty   t	
d Y n0 t }tt|}| |||d\}	}
|r| || | |jj|| dd |jjD  | |jj ||  fdd|jjD }t|	|
||}|S )a  
        For Onnx Caffe2Backend, we require that init_graph don't initialize the actual input of the predict_graph,

        for example, if "img" is the input blob for the predict_net, we require that in init_graph and in
        initializer of the predict_graph, "img" is not initalized. We don't have a check for this, since
        there is no way we can know which blob is the input of the predict_graph.
        Zno_check_UNSAFEFNdomainr'   a  This version of onnx-caffe2 targets ONNX operator set version {}, but the model we are trying to import uses version {}.  We will try to import it anyway, but if the model uses operators which had BC-breaking changes in the intervening versions, import will fail.zUnrecognized operator set {}r   z^Model with IR version >= 3 did not specify ONNX operator set version (onnx-caffe2 requires it)r   GShapeInferenceWarning: Inferred shape and existing shape differ in rankc                 S   s   h | ]
}|j qS r   r   )r   r  r   r   r   r     r&   z(Caffe2Backend.prepare.<locals>.<setcomp>c                    s   g | ]}|j  vr|j qS r   r   r   r  r#  r   r   r     r&   z)Caffe2Backend.prepare.<locals>.<listcomp>)r   r   r:   r4  Zopset_importr9   r8  versionr<   r&  r'  rE   Z
ir_versionr   r   Zshape_inferenceZinfer_shapesr   r   r
   _onnx_model_to_caffe2_netr   r!  r   r  r$  rL   r   )r|   r  r   r  r   r   impr   r   r   Zpredict_netZuninitializedrF   r   r;  r   r4    sJ    	


zCaffe2Backend.preparec                 C   sN  t | j}||jrg }|jD ]D}|d ur"t|jj|jj	|jj
D ]}|j|krH||  qHq"|| ||}	g }
|	d D ] }t }|| |
| qg }|	d D ] }t }|| || qt||
g S |j| jv rt| | j|j }n| j}|||t||}t|tr,|S t|tjjsB|g}t|g g S )Nr   r   )r   r:   rz   Zsupport_onnx_importrI   rL   r   r   r   rN   r  r   rC   r   r   r   r   r   rR   _special_operatorsgetattrr  rG   r   collectionsabcIterable)r|   r	  r
  Znode_defr   r   r   r   viZop_strsrT   r   r   rS   Z
translatorr   r   r   _onnx_node_to_caffe2_op  s@    




z%Caffe2Backend._onnx_node_to_caffe2_opAddSubc           
         s   t  }|j|j |j|j |j|_|j j	
td}||kr^td|| j
|_t|jstd fdd}|j|jj|d |dk r|j jv rd}|jD ]}	|	jd	krd
}q|s|jtjjd	dg |S )a  
        This translator performs the basic translation of ONNX nodes into
        Caffe2 operators.  Besides doing a straightforward marshalling from
        one format to another, it also does these extra things:

          - Renames operators based on '_renamed_operators'
          - Renames attributes based on '_global_renamed_attrs' and
            '_per_op_renamed_attrs'

        If you're writing a custom translator, consider calling this first,
        and then fixing things up further.
        ZInfzXDon't know how to translate op {} in ONNX operator set v{} (I only support prior to v{})z!Don't know how to translate op {}c                    s>    j v r&|  j  v r& j  |  S |  jv r: j|  S | S r   )_per_op_renamed_attrs_global_renamed_attrsr#   r|   Zonnx_op_typer   r   r.   2  s    


z:Caffe2Backend._common_onnx_node_to_caffe2_op.<locals>.kmap)r.      F	broadcastTr   )r   r   rL   r   rM   rN   rO   r   rI   _broken_operatorsgetfloatrD   rE   _renamed_operatorsr   r   Z
IsOperatorr!   rK   r)   _broadcast_operatorsr*   r+   r,   )
r|   r	  r
  Z	onnx_noder   r   Zbroken_versionr.   Zalready_broadcastr!   r   rJ  r   r    s4    

z,Caffe2Backend._common_onnx_node_to_caffe2_opc                 C   sh   | d u rt  S t  }|dd | jD  |dd | jD  | jD ]}||j ||j qF|S )Nc                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r   N  r&   z4Caffe2Backend._all_names_in_graph.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r   O  r&   )r1  r   rL   rN   rP   )r   namesrP   r   r   r   _all_names_in_graphH  s    
z!Caffe2Backend._all_names_in_graphc                 C   s   t  }|jD ]~}z| d d ||}W n: ty` } z"td| W Y d }~qW Y d }~n
d }~0 0 |j|j |j|j	 |j
|j q|jdd |jD  |j
dd |jD  |S )NONNX FATAL:c                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r   b  s   z.Caffe2Backend._graph_to_net.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r   d  s   )r   NetDefrP   rE  	Exceptionprintr   r   rT   rS   r  rU   r  rN   rL   )r|   Z
onnx_graphr   r   rP   c2opser   r   r   r;   U  s&    

"zCaffe2Backend._graph_to_netc                    sJ  t t|}ztj|}W n> ty8   td Y n$ tyZ   td	tj
 Y n0 z  j|dd} j|dd}W n$ ty   td |}|}Y n0 t }t }	|jjd |_|jjd |	_|r|j fd	d
|jjD   j |j |jB  g }
||f|	|ffD ]\}}|j| |jjD ]}z ||||}W nZ ty } z@d	||}|
| td|tjd W Y d }~q@W Y d }~n
d }~0 0 |j|j  |j|j! |j"|j# q@|j$dd
 |jj%D  |j"dd
 |jj&D  q$t'|
dkrBtd	t'|
d(|
||	fS )Nr9  z@ShapeInferenceWarning: utils module not found in ONNX version {}T)r  )r*  zOptimizerWarning: onnxoptimizer module not installed. init_model and pred_model models will not be splitted, which can cause a runtime error_initZ_predictc                 3   s   | ]}  |V  qd S r   )r   )r   r  r{   r   r   r     r&   z:Caffe2Backend._onnx_model_to_caffe2_net.<locals>.<genexpr>z.Error while processing node: {}. Exception: {}rT  )r5  c                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r     s   c                 s   s   | ]}|j V  qd S r   r   r:  r   r   r   r     s   r   z2ONNX conversion failed, encountered {} errors:

{}z

))r   r
   r   r+   Zpolish_modelr   r&  r'  r   rE   r(  r+  ModuleNotFoundErrorr   rU  r   r   r   r   r  rz   r   rS  r   r   rP   rE  rV  rC   rW  sysstderrrT   rS   r  rU   r  rN   rL   r=   join)r|   Z
onnx_modelr   r   include_initializersr   r	  r
  r   Zpred_neterrorsr   r  rP   rX  rY  msgr   r{   r   r=  h  sd    

 
$z'Caffe2Backend._onnx_model_to_caffe2_netc                 C   s   | j |||ddS )NT)r   r   r_  )r=  )r|   r  r   r   r   r   r   onnx_graph_to_caffe2_net  s    z&Caffe2Backend.onnx_graph_to_caffe2_netc                 C   s.   t |}|jtjkrdS t|jr*tjS dS )NTF)r
   r   r   r   r   ZIsGPUDeviceTyper   Zhas_gpu_support)r|   Z
device_strr   r   r   r   supports_device  s    zCaffe2Backend.supports_devicec                    sB   t tt| dr>ttt| jr>tt| j||fi |s>dS dS )Nis_compatibleFT)hasattrr   r:   callablerd  )r|   r  r   r   r   r   r   rd    s    zCaffe2Backend.is_compatible)N)FF)r   )r   N)r   )*r0   r1   r2   r<   rM  rP  rI  rH  r?  r   Z	DummyNamerz   classmethodr}   r   r   r   r   rt   r  r  rv   ru   r  r  r   r!  r$  r4   r+  r7  r4  rE  rQ  r  rS  r;   r=  rb  rc  rd  __classcell__r   r   r   r   r:   |   s   		
%4

D
 

	







>
)
4


>
r:   )7r3   rA  r\  r-  r   Zonnx.backendr   Zcaffe2.pythonr   r   r   r   Zcaffe2.python.model_helperr   Zcaffe2.protor   Zcaffe2.python.utilsr)   numpyr"  r   Zonnx.numpy_helperZ	onnx.defsZonnx.shape_inferenceZ
onnx.utilsZonnx.backend.baser	   r
   r   r   Zcaffe2.python.onnx.workspacer   Zcaffe2.python.onnx.backend_repr   Z!caffe2.python._import_c_extensionr*   Z_import_c_extensionr   r&  r   r   r   r   r   objectrG   
namedtuplerR   r:   r4  r7  r   Z	run_modelrc  rd  r   r   r   r   <module>   sP   "      G