a
    h                     @   s
  U 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 d dlmZ d dlm	Z	m
Z
mZmZ d dlZd dlZ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mZmZmZmZmZmZmZ d d
lm Z  e!e"Z#dd Z$dd Z%eej&j'ej(j)f ee	 e*ej+e,d e	eej- f dddZ.dd Z/dd Z0dd Z1ej2j3dddZ4dd Z5dQe6e6e6dd d!Z7e6e6d"d#d$Z8d%d& Z9ej:d ej;d'ej<d(ej=d)ej>d*ej?d+ej@d,ejAd-ejBd.ejCd/ejDd0ejEd1ejFd2ejGd3ejHd4iZId5d6 eIJ D ZKd7d8 ZLe jMe jNejOejPejQejRejSeLeTejUjVjWejUjVjXejUjVjYejUjVjZd9Z[e\e6e
d:e	f f e]d;< d<d= Z^d>d? Z_ejj+e*e\ejj`eae6 f e\e6e6f f d@dAdBZbe\e6e6f ejjce6dCdDdEZdejjcdFdGdHZeG dIdJ dJZfG dKdL dLefZgedMdN ZhG dOdP dPZidS )R    N)Sequence)contextmanager)AnyCallableOptionalUnion)_C)'replace_quantized_ops_with_standard_ops)_tree_map_with_pathDim)ExportedProgram)ConstantArgumentCustomObjArgument	InputKind	InputSpec
OutputKind
OutputSpecTensorArgument)subgraph_rewriterc                 C   s^   g }t |  |D ]F\}}dt| v rJtj|\}}|t| q||d u q|S )NZPackedParams)	zipinputsstrtypetorchjit_flattenappendlen)method_graphargs_paramsparam_count_listZinput_Zarg_params_in_vars_ r#   E/var/www/auris/lib/python3.9/site-packages/torch/_export/converter.py_get_param_count_list"   s    r%   c                 C   sl   t j|  }t  }t d t jj| |dddd\}}}t | |t j|  krdtd||fS )NFT)strictZ_force_outplaceZ_return_inputs_stateszXstate_dict changed after running the tracer; something weird is happening in your model!)r   r   _unique_state_dictkeysZis_autocast_cache_enabledZset_autocast_cache_enabledZ_get_trace_graphRuntimeError)modelargsZorig_state_dict_keysZprev_autocast_cache_enabledZtrace_graph	torch_outZ_inputs_statesr#   r#   r$   _trace_and_get_graph_from_model.   s     

r-   z	_C.IValue)r*   r+   returnc              
   C   s  t | tjjtjjfrFttjt|d }d }t | tjjr
z| jj}W n. t	y~ } zt
d|W Y d }~n
d }~0 0 t| tjttj| jdd}t|\}}|dj}	t|t| }
t|	|
}tj|
\}}t|	t||dd}||||fS g }| j}t| t||}t|||dd}|||d fS t| |\}}t| tj| }t| }t| }t|t| }t| }t|D ]&\}}||kr||||   qt| |||d fS )Nr   z('forward' method must be a script methodT)ZpreserveParametersforwardF)
isinstancer   r   ScriptFunctionScriptModuletupler   r/   graphAttributeErrorr)   r   Z$_jit_pass_onnx_function_substitutionZ_freeze_moduletypingcastZ_cZ_jit_onnx_list_model_parametersZ_get_methodr%   Z"_propagate_and_assign_input_shapesr-   Z_jit_pass_onnx_lintr'   listvaluesr   r   r(   	enumerateZsetDebugName)r*   r+   Zflattened_argsr,   r4   eZfreezed_modulemoduleparamsr   r   r    r!   r"   
state_dictZgraph_inputsZuser_input_numZparam_namesiinpr#   r#   r$   _create_jit_graphJ   sR     







rA   c                 C   s   | | S Nr#   )abr#   r#   r$   list_add|   s    rE   c                 C   s
   | |g S rB   r#   )	containerelementr#   r#   r$   list_append   s    rH   c                 O   s4   |d| }||d }| g |||R i |S )z
    subgraph: GraphModule from sub-block.
    iter_idx: The index of interation.
    len_loop_local_arguments: The number of loop local arguments in args.
    Nr#   )subgraphiter_idxZlen_loop_local_argumentsr+   kwargsZloop_local_argsZglobal_argsr#   r#   r$   execute_subgraph_from_prim_loop   s    rL   )gmc                 C   s"   dd }dd }t | || d S )Nc                 S   sJ   t jjj| |}t jj|}t jjjj||dd}t jjj	|}|S )Ntrunc)Zrounding_mode)
r   opsatensym_sizeintscalar_tensordivScalar_modeZIntTensor)imdimscalesym_size_intrS   Zdiv_scalar_modeZ
int_tensorr#   r#   r$   pattern   s    
z.inplace_optimize_sym_size_div.<locals>.patternc                 S   s   t jjj| |}|| S rB   )r   rO   rP   rQ   rR   )rW   rX   rY   rZ   r#   r#   r$   replacement   s    z2inplace_optimize_sym_size_div.<locals>.replacement)r   Zreplace_pattern)rM   r[   r\   r#   r#   r$   inplace_optimize_sym_size_div   s    	r]   c                 C   s(   t | dkrtd| d  r$dS dS )Nr   zEmpty argument name for codegenFT)r   r)   isdigitnamer#   r#   r$   is_valid_for_codegen   s
    ra   rename)r`   prefixr.   c                 C   s&   |  dd} t| r| S | d|  S )N.r"   )replacera   )r`   rc   r#   r#   r$   normalize_name   s    rf   )r`   r.   c                 C   s   |  d}dd| S )zprim::If -> convert_prim_If::Zconvert_r"   )splitjoin)r`   	name_listr#   r#   r$   ir_name_to_func_name   s    
rk   c                 C   s   |r|  |S | |S rB   )get_attrplaceholder)fx_graphr`   is_top_level_graphr#   r#   r$   #get_node_as_placeholder_or_get_attr   s    
rp                           	   
               c                 C   s   i | ]\}}||qS r#   r#   ).0keyvaluer#   r#   r$   
<dictcomp>       r   c                 C   s$   | j }|tvrtd| t| S )z
    prim::dtype has the signature "Tensor a) -> int", where it gets the dtype of
    the tensor and returns the integer corresponding to this dtype based on the
    enum in ScalarType.h
    zUnsupported dtype )dtype_TORCH_DTYPE_TO_ENUMr)   )tensorr   r#   r#   r$   get_dtype_as_int   s    r   )z	prim::maxz	prim::minzprim::TupleIndexzaten::__is__zaten::__isnot__zaten::__not__zaten::__contains__zprim::dtypez	aten::lenzaten::numelz
aten::sizezaten::storage_offsetzaten::stride.kind_to_standard_operatorsc                 C   s.   |    |    }}| d}|||fS )Nr`   )input	debugNameoutputs)nodeirv_parent_nameirv_name	attr_namer#   r#   r$   &get_ir_value_parent_name_and_attr_name   s    
r   c                 C   s2   g }| |v r$| ||   ||  } qdt|S Nrd   )r   ri   reversed)ZirZref_mapZname_maprj   r#   r#   r$   construct_fqn  s
    
r   )r4   r.   c                    sF   i i i  fdd fdd |  |  fS )a  
    Perform two passes to get a mapping of blocks to a set of FQNs of its lifted attributes.
    When a graph has control flow, the graph will be divided into multiple blocks. We want to convert
    each block to a graph which will be passed into torch.cond. A restriction for torch.cond is that model
    parameters/buffers are expected to be lifted as inputs to the subgraphs. Before converting the model,
    we will run this pass which will:
        1. Figure out which params/buffers are used within blocks through tracing the GetAttr calls.
        2. Process the graph bottom up to find the lifted attributes of each block by taking the union
        of the attributes used in the current block, and the lifted attributes of all its child blocks.

    Returns:
        A mapping of blocks to a set of FQNs of its lifted attributes, and a
        mapping of node names to the FQNs of its lifted attributes.
    c                    sR   |   D ]D}| dkr6t|\}}}||< ||< | D ]} | q>qdS )zI
        First DFS path to construct reference map and name map.
        prim::GetAttrN)nodeskindr   blocks)entryr   r   r   r   block)_dfs_get_attr_dependencynode_to_attr_namenode_to_parent_mapr#   r$   r   *  s    z;get_block_to_lifted_attrs.<locals>._dfs_get_attr_dependencyc                    s   t  }|  D ]Z}| D ]}| |}q| dkr|  }|t  vr|t	| qt
| tjjs|| < |S )z|
        Walk the graph in a bottom-up fashion to build the expected to be
        lifted arguments for each block.
        r   )setr   r   unionr   r   r   r9   addr   r0   r   r   Graph)r   	argumentsr   r   r   )_map_blocks_to_lifted_attrsblocks_to_lifted_attrsr   r   r#   r$   r   :  s    
z>get_block_to_lifted_attrs.<locals>._map_blocks_to_lifted_attrsr#   )r4   r#   )r   r   r   r   r   r$   get_block_to_lifted_attrs	  s    r   )name_to_attribute_fqnr   r.   c                    s   t d fdd}| dkr0t|  }n*| dkrJ|  }ntd| d|d}||}|r~| d	| n|}|S )
Nr_   c                    s$   |  v r |  S t d|  dd S Nz
Attribute 
 not found)
ValueErrorr_   r   r#   r$   rl   \  s    z0get_attribute_fqn_from_ts_node.<locals>.get_attrprim::SetAttrr   z7Unexpected node kind when getting attribute fqn. node:  r`   rd   )r   r   nextr   r   r   r)   r   )r   r   rl   
input_namer   root_attr_nameattr_fqnr#   r   r$   get_attribute_fqn_from_ts_nodeY  s    

r   r   c           
   
   C   s   |   }|dksJ d|  tj|}t|jd\}}|j}z0ttj	|}t||}|rlt||}n|j
}W nB ty }	 z*td|   d|    |	W Y d }	~	n
d }	~	0 0 |S )N(no schema)zgot empty schema for rg   zUnable to find operator z with schema )schemar   r   Zparse_schemar   r`   rh   overload_namegetattrrO   default	Exceptionr)   r   )
r   Z
schema_strr   nsZop_nameoverrideZop_overload_modZop_overload_packetZop_overloadr;   r#   r#   r$   get_op_overloadr  s$    

r   c                	   @   s  e Zd Zeejjejjf ee	ej
f ee	ej
f eejjee	 f ee	ef ee	ef ee	e	f dddZdd Zejjee	 dddZd	d
 Zdd Ze	dddZejjdddZejjdddZdd ZejjdddZdd ZejjdddZejjdddZejjdd d!Zejjdd"d#Z ejjdd$d%Z!ejjdd&d'Z"ejjdd(d)Z#ejjdd*d+Z$ejjdd,d-Z%ejjdd.d/Z&ejjdd0d1Z'ejjdd2d3Z(ejjdd4d5Z)ejjdd6d7Z*ejjdd8d9Z+ejjdd:d;Z,ejjdd<d=Z-ejjdd>d?Z.ejjdd@dAZ/ejjddBdCZ0ejjddDdEZ1ejjddFdGZ2ejjddHdIZ3ejjddJdKZ4dLdM Z5ejjddNdOZ6ejjdPdQdRZ7ejjddSdTZ8ejjddUdVZ9ejjddWdXZ:ejjddYdZZ;ejjdd[d\Z<ejjdd]d^Z=ejjdd_d`Z>ejjddadbZ?ejjddcddZ@ejjddedfZAdgdh ZBdiS )jTS2FXGraphConverterts_graphname_to_paramname_to_bufferr   name_to_non_tensor_attributename_to_constantr   c           
         s   | _ | _| _tj  _g  _g  _i  _	| _
| _i  _| _i  _| _t D ] }t|}	t |	 fdd q\t  _d S )Nc                    s
     | S rB   )_convert_standard_operatorsr   selfr#   r$   <lambda>  r   z.TS2FXGraphConverter.__init__.<locals>.<lambda>)r   r   r   r   fxr   rn   input_specsoutput_specsname_to_noder   r   !name_to_non_tensor_attribute_noder   	subgraphsr   r   r(   rk   setattrr   #name_update_from_subblock_to_parent)
r   r   r   r   r   r   r   r   khandler_func_namer#   r   r$   __init__  s,    


zTS2FXGraphConverter.__init__c                 C   s0   || j v p.|| jv p.|| jv o.t| j| tjS rB   )r   r   r   r0   r   ScriptObject)r   fqnr#   r#   r$   _is_get_attr_node  s    

z%TS2FXGraphConverter._is_get_attr_node)r   r   c              	   C   s   g g  }}|  D ]x}t|| j| j| ji | j| j}|D ]"}t|}|j	|}	|	|j
|< q8| }
| |
}|| j| || q||fS rB   )r   r   r   r   r   r   r   rf   rn   rm   r   convertadd_subgraphr   rl   )r   r   r   subgraph_nodessubgraph_convertersr   subgraph_converterZ	block_argZnormalized_block_arg_nameZplaceholder_noderI   Zsubgraph_namer#   r#   r$   _convert_block_to_subgraph  s,    


z.TS2FXGraphConverter._convert_block_to_subgraphc                 C   sn   t  }| D ]Z}| D ]L}| D ].}| | jv r&| | jvr&||  q&|| 	|}qq|S )aW  
        Identify inputs from the innermost sub-block. This is needed
        for nested sub-blocks when the input is hidden in the nested sub-block.
        E.g., example IR of input is hidden in the nested sub-block.
        Graph[x.1]
        %1 = ...
            Block[]
                Block[x.1]
                    %2 = x.1 ...
        )
r   r   r   r   r   r   r   r   r   _identify_inputs_as_arguments)r   r   r   r   Z
block_nodeZblock_node_inr#   r#   r$   r     s    z1TS2FXGraphConverter._identify_inputs_as_argumentsc                 C   s   t | jtjjS rB   )r0   r   r   r   r   r   r#   r#   r$   ro     s    z&TS2FXGraphConverter.is_top_level_graphr.   c                 C   s   dt | j }|| j|< |S )NZ	subgraph_)r   r   )r   rI   r`   r#   r#   r$   r     s    
z TS2FXGraphConverter.add_subgraphr   c                 C   sV   g }i }t | |jD ]0\}}|jr8| |||j< q|| | qt||fS rB   )r   r   r   Z
kwarg_onlyget_fx_value_by_ir_valuer`   r   r3   )r   r   r   r+   rK   r   Z
schema_argr#   r#   r$   get_args_kwargs  s    z#TS2FXGraphConverter.get_args_kwargs)r   c                 C   s   |  }|| jv r | j| }|S || jv rRt| j| tjrH| j|S | j| S || jv rl| 	| j| S t
d| dd S )NzInput r   )r   r   r   r0   r   r   rn   rl   r   get_fx_value_by_fqnr   )r   r   Z
value_nameZ
input_noder#   r#   r$   r     s    




z,TS2FXGraphConverter.get_fx_value_by_ir_valuec                 C   sl   || j v r| j | }nR|| jv r,| j| }n<|| jv rB| j| }n&|| jv rX| j| }ntd| d|S r   )r   r   r   r   r   )r   r`   fx_noder#   r#   r$   r   .  s    



z'TS2FXGraphConverter.get_fx_value_by_fqnc                 C   sn   |    | j D ]}| | q|   tji | j| j	| j
| j| j| j}t| |j  |S rB   )convert_graph_inputsr   r   convert_nodeconvert_graph_outputsr   r   GraphModuler   r   r   r   r   rn   r]   r4   Zlint)r   r   rM   r#   r#   r$   r   ;  s*    
zTS2FXGraphConverter.convertc              	   C   sb  | j  D ]P}| }|| jv r\t|}| jttj	t
|d|d t| j||  }n|| jv rt|}| jttjt
|d|dd t| j||  }n|| jv rt| j| tjsJ dt|}| jttjt||d|dd t| j||  }nLt| tjrq
n6t|dd	}| jttjt
|d|d | j|}|| j|< q
d S )
Nr_   argtargetT)r   r   
persistentz*Input conversion only handles ScriptObject)r`   Z	class_fqnFr   )rc   )r   r   r   r   rf   r   r   r   r   Z	PARAMETERr   rp   rn   ro   r   BUFFERr   r0   r   r   Z
CUSTOM_OBJr   r   Z	ClassTypeZ
USER_INPUTrm   r   )r   Zgraph_inputr`   Znormalized_namer   r#   r#   r$   r   U  sv    


z(TS2FXGraphConverter.convert_graph_inputsc                    sF   dd } fdd|  D } j|t|}| j|  < d S )Nc                 S   s   | j tjd S )N)r   )tor   floatitem)tr#   r#   r$   to_float_tensor  s    z?TS2FXGraphConverter.convert_aten_Float.<locals>.to_float_tensorc                    s   g | ]}  |qS r#   r   r   r@   r   r#   r$   
<listcomp>  s   z:TS2FXGraphConverter.convert_aten_Float.<locals>.<listcomp>)r   rn   call_functionr3   r   r   r   )r   r   r   inp_listr   r#   r   r$   convert_aten_Float  s    
z&TS2FXGraphConverter.convert_aten_Floatc                    s   |  |tjjjjj\}}|D ]}|dkrt|| ||< qtdd |D rTtjntj	j  fdd}|
  }| j|||}|| j|< dS )z9aten::tensor creates a constant tensor ad-hoc --> GetAttrZrequires_gradc                 s   s   | ]}t |tV  qd S rB   )r0   rR   )r   rC   r#   r#   r$   	<genexpr>  r   z:TS2FXGraphConverter.convert_aten_tensor.<locals>.<genexpr>c                     s2   d|v r$|d d ur$t |d  |d<  | i |S )Nr   )_TORCH_ENUM_TO_DTYPE)r+   rK   Z	to_tensorr#   r$   r     s    z7TS2FXGraphConverter.convert_aten_tensor.<locals>.targetN)r   r   rO   rP   r   r   _schemaboolallZ_refsr   r   rn   r   r   )r   r   r+   rK   r   r   output_namer   r#   r   r$   convert_aten_tensor  s    
z'TS2FXGraphConverter.convert_aten_tensorc                    s   t d t fdd| D } jt|}| j| 	 < | j|
d	 <   s|d jdkr j|
d	  d S )NzConverting aten::append.t, which is a inplace mutation of the list. This makes the converter non-functional: the result depends on the order of the append nodes being converter!c                 3   s   | ]}  |V  qd S rB   r   r   r   r#   r$   r     r   z:TS2FXGraphConverter.convert_aten_append.<locals>.<genexpr>r   rm   )warningswarnr3   r   rn   r   rH   r   r   r   inputsAtro   opr   r   )r   r   r+   r   r#   r   r$   convert_aten_append  s    z'TS2FXGraphConverter.convert_aten_appendc                 C   s   |   }d }|dr|d}|dkr8|d}q|dkrL|d}q|dkr`|d}q|dkrd| }| j|}|| j	|< ||
d }}q|dkr|d}qtd|d nd }|| j|< d S )	Nr   r?   fr   r   Zlifted_tensor_ivalzUnsupported constant type: )r   r   ZhasAttributeZkindOfr?   r  r   rn   rl   r   r   r  r   r   )r   r   r`   r   Zconstant_kindZ
alias_namer   r#   r#   r$   convert_prim_Constant  s*    


z)TS2FXGraphConverter.convert_prim_Constantc                    sD    fdd|  D } j|dt|}| j|  < d S )Nc                    s   g | ]}  |qS r#   r   r   r   r#   r$   r     s   z?TS2FXGraphConverter.convert_prim_CallMethod.<locals>.<listcomp>r`   )r   rn   call_methodr   r3   r   r   r   )r   r   r   r   r#   r   r$   convert_prim_CallMethod  s    
z+TS2FXGraphConverter.convert_prim_CallMethodc                 C   sR   |   }|tjj r>| }| 	 }|| j
|< ntd| dd S )NzUnsupported JitType (z) when get device)r   r   ZisSubtypeOfr   r   Z
TensorTypegetdevicer   r   r   r   )r   r   Z
input_typer  r   r#   r#   r$   convert_prim_device  s    z'TS2FXGraphConverter.convert_prim_devicec                 C   s   t | j|}|  }|| j|< |  rt| |rH| j|| j|< q|| j	vrb| j
| | j	|< | j	| | j|< n| |r| j| | j|< d S rB   )r   r   r   r   ro   r   rn   rl   r   r   r   )r   r   r   r   r#   r#   r$   convert_prim_GetAttr  s     



z(TS2FXGraphConverter.convert_prim_GetAttrc                 C   sb   t | j|}t| d }| |}| |rT| j|}| jt	j
j||f n
|| j|< d S Nrq   )r   r   r3   r   r   r   rn   rl   r   r   rV   Zcopy_r   )r   r   r   
attr_valueZts_graph_tensor_inputZfx_attr_noder#   r#   r$   convert_prim_SetAttr  s    

z(TS2FXGraphConverter.convert_prim_SetAttrc           
      C   s   t |}| ||j\}}| j|||}| dkrN|  }|| j|< n<t	|
 D ].\}}| }| jtj||f}	|	| j|< qZd S r  )r   r   r   rn   r   outputsSizer   r   r   r:   outputsoperatorgetitem)
r   r   r   r+   rK   r   r   r?   outpZnext_fx_noder#   r#   r$   convert_call_function_op*  s    
z,TS2FXGraphConverter.convert_call_function_opc                 C   s   |  | d S rB   _convert_prim_iteratorr   r   r#   r#   r$   convert_prim_TupleConstruct?  s    z/TS2FXGraphConverter.convert_prim_TupleConstructc                 C   s   |  | d S rB   r  r  r#   r#   r$   convert_prim_ListConstructB  s    z.TS2FXGraphConverter.convert_prim_ListConstructc                    s0    fdd|  D }|  }| j|< d S )Nc                    s   g | ]}  |qS r#   r   r   r   r#   r$   r   F  r   z>TS2FXGraphConverter._convert_prim_iterator.<locals>.<listcomp>)r   r   r   r   )r   r   Zoutput_listr   r#   r   r$   r  E  s    z*TS2FXGraphConverter._convert_prim_iteratorc                 C   s   i }d\}}t | D ]R\}}|d dkr8| |}q| |}|d urR|d usZJ d|||< d\}}q|d u r||d u sJ d|  }|| j|< d S )N)NNrr   r   z*DictConstruct has an empty key value pair.zGDictConstruct has an odd number of elements (violating our assumption).)r:   r   r   r   r   r   )r   r   Zoutput_dictr   vr?   r@   r   r#   r#   r$   convert_prim_DictConstructK  s,    

z.TS2FXGraphConverter.convert_prim_DictConstructc                 C   s   |  | d S rB   _convert_prim_unpack_iteratorr  r#   r#   r$   convert_prim_ListUnpackb  s    z+TS2FXGraphConverter.convert_prim_ListUnpackc                 C   s   |  | d S rB   r  r  r#   r#   r$   convert_prim_TupleUnpacke  s    z,TS2FXGraphConverter.convert_prim_TupleUnpackc                 C   sN   t | D ]<\}}| }| | }| jtj||f}|| j	|< qd S rB   )
r:   r  r   r   r   rn   r   r  r  r   )r   r   r?   r  Z	outp_namer@   r   r#   r#   r$   r  h  s
    z1TS2FXGraphConverter._convert_prim_unpack_iteratorc                    sn   t jjjj}t fdd| D } j||dt j	i} jt jjj
j|f}|  }| j|< d S )Nc                 3   s   | ]}  |V  qd S rB   r   r   r   r   r#   r$   r   s  r   z7TS2FXGraphConverter.convert_aten_Int.<locals>.<genexpr>r   )r   rO   rP   Z_to_copyr   r3   r   rn   r   int32Z_local_scalar_denser   r   r   )r   r   r   r+   Zto_copy_noder   r   r#   r   r$   convert_aten_Intp  s    z$TS2FXGraphConverter.convert_aten_Intc                    sT   t jjj}t fdd| D } j||dt ji}|	 
 }| j|< d S )Nc                 3   s   | ]}  |V  qd S rB   r   r  r   r#   r$   r     r   z?TS2FXGraphConverter.convert_prim_NumToTensor.<locals>.<genexpr>r   )r   rO   rP   rS   r3   r   rn   r   longr   r   r   r   r   r   r+   r   r   r#   r   r$   convert_prim_NumToTensor  s
    
z,TS2FXGraphConverter.convert_prim_NumToTensorc                 C   s   |   }d| j|< d S )N )r   r   r   r   r   r   r#   r#   r$   convert_prim_CreateObject  s    z-TS2FXGraphConverter.convert_prim_CreateObjectc                 C   sH   t jjjj}| ||j\}}| j|||}|	 
 }|| j|< d S rB   )r   rO   rP   Zconvolutionr   r   r   rn   r   r   r   r   )r   r   r   r+   rK   r   r   r#   r#   r$   convert_aten__convolution  s
    z-TS2FXGraphConverter.convert_aten__convolutionc                 C   s   t |}|j}| ||\}}|jdkr|d j}|| jv rt| j| tjr| j| }|	 dkrt
|}| j|  |d< | jtjjjjt||}	|  }
|	| j|
< d S | | d S )NZTensor_moderq   )r   r   r   r   r`   r   r0   r   rV   Znumelr8   r   rn   r   rO   rP   rT   rU   r3   r   r   r   r  )r   r   r   r   r+   rK   Z	arg1_nameZtensor_constantZupdated_argsr   r   r#   r#   r$   convert_aten_div  s*    



	
z$TS2FXGraphConverter.convert_aten_divc                    sL   t  fdd| D \}} jtj||f}|  }| j|< d S )Nc                 3   s   | ]}  |V  qd S rB   r   r  r   r#   r$   r     s   z?TS2FXGraphConverter.convert_aten___getitem__.<locals>.<genexpr>)	r3   r   rn   r   r  r  r   r   r   )r   r   Zinput_containerindexr   r   r#   r   r$   convert_aten___getitem__  s    
z,TS2FXGraphConverter.convert_aten___getitem__c                 C   s   t |}| ||j\}}|tjjjjks:|tjjjjkrdd |	 
 D }dd |D }tdd |D }|rt|dksJ t|}d|d< | jtjjjjt|}	| jtjjjj|	f}
|	  }|
| j|< d S | | d S )	Nc                 S   s   g | ]
}|j qS r#   )user)r   Zuser#   r#   r$   r     r   z7TS2FXGraphConverter.convert_aten_to.<locals>.<listcomp>c                 S   s    g | ]}|  d krt|qS )r   )r   r   )r   Z	user_noder#   r#   r$   r     s   c                 s   s   | ]}|j jV  qd S rB   )r   Z
is_mutable)r   r   r#   r#   r$   r     s   z6TS2FXGraphConverter.convert_aten_to.<locals>.<genexpr>rt   Trs   )r   r   r   r   rO   rP   r   r   Z
prim_dtyper   Zusesanyr   r8   rn   r   r3   cloner   r   r   r  )r   r   r   r+   _kwargsZ
user_nodesZuser_targetsZhas_mutable_targetnew_argsr   Z
clone_noder   r#   r#   r$   convert_aten_to  s0     
z#TS2FXGraphConverter.convert_aten_toc                 C   s   |  dkrVt|d tjrFt|d tjrFtjjjj	}q^t
d| nt|}|tjjjj	kr| ||j\}}|  }| jt|| j|< n
| | d S )Nr   r   rq   z#unable to determind the target for )r   r0   r   r   r   ZListTyperO   rP   r   r   r)   r   r   r   r   r   rn   r   rE   r   r  )r   r   r   r+   r/  r   r#   r#   r$   convert_aten_add  s    z$TS2FXGraphConverter.convert_aten_addc                 C   s   t | }|d  | jvr&tdt| }t|  }| D ]V}|	 dkrr|
  |krrtd|	 dkrJ| D ]}| |krtdqqJd S )Nr   zKprim::Loop currently cannot run with dynamic value of number of iterations.rq   z@prim::Loop currently cannot run with dynamic value of condition.rr   )r8   r   r   r   r)   r   r   r  r   r  r   )r   r   r   subblockZcondition_output_namer  r#   r#   r$   _check_prim_loop_support  s*    
z,TS2FXGraphConverter._check_prim_loop_supportc              	      s  t | } |  |d }dd |dd  D } |}| D ]}| j| }qLt |} ||\}}t	|dksJ |d }	 
 s j|	j _ fdd|| D }
t|D ]} jt|d |t	|g|
R i }| dkrJt| D ]>\}}| } jtj||d f j|<  j| |
|< q
t|	jD ]T\}} jtj|||  d f j|< ||} j| |
||  | < qTqd S )Nr   c                 S   s   g | ]}|  qS r#   r   r   r#   r#   r$   r   $  r   z9TS2FXGraphConverter.convert_prim_Loop.<locals>.<listcomp>rr   rq   c                    s   g | ]}  |qS r#   r   r   r`   r   r#   r$   r   =  s   )r8   r   r4  r   r   r   r   r   r   r   ro   r   rangern   r   rL   r  r:   r  r   r  r  r   r*  )r   r   r   Znum_iterationsZloop_local_argumentsZglobal_argumentsr   r   r   r   fx_block_argsrJ   Z	loop_noder?   r  r   r`   Zglobal_argument_indexr#   r   r$   convert_prim_Loop  st    





z%TS2FXGraphConverter.convert_prim_Loop)if_nodec                 C   s4   |  D ]&}| D ]}| dkrtdqqd S )Nr   zDuring converting prim::If to torch.cond, found prim::SetAttr op which is not supported yet. Please file an issue if you come across this error.)r   r   r   r)   )r   r;  r   r   r#   r#   r$   _check_set_attr_in_if_blockk  s    z/TS2FXGraphConverter._check_set_attr_in_if_blockc                    s2    | t| }t|dks&J  |d } |}| D ]}| j| }qFt|} 	||\}}t|dksJ  fdd|D }||d |d t
|f}	 jtj|	i }
| dkr|  }|
 j|< nJ| dkr.t| D ].\}}| } jtj|
|f}| j|< qd S )Nrq   r   rr   c                    s   g | ]}  |qS r#   r6  r7  r   r#   r$   r     r   z7TS2FXGraphConverter.convert_prim_If.<locals>.<listcomp>)r<  r8   r   r   r   r   r   r   r   r   r3   rn   r   r   Zcondr  r   r   r   r:   r  r  r  )r   r   r   	predicater   r   r   r"   r9  r+   Z	cond_noder   r?   r   r  r#   r   r$   convert_prim_Ifu  s2    

z#TS2FXGraphConverter.convert_prim_Ifc                 C   s   |  | d S rB   )_convert_as_noopr  r#   r#   r$   convert_aten_Bool  s    z%TS2FXGraphConverter.convert_aten_Boolc                 C   s   d S rB   r#   r  r#   r#   r$   convert_prim_Enter  s    z&TS2FXGraphConverter.convert_prim_Enterc                 C   s   d S rB   r#   r  r#   r#   r$   convert_prim_Exit  s    z%TS2FXGraphConverter.convert_prim_Exitc                 C   s<   t |}|j}| ||\}}|  }|d | j|< d S )Nr   )r   r   r   r   r   r   )r   r   r   r   r+   r/  r   r#   r#   r$   r?    s
    z$TS2FXGraphConverter._convert_as_noopc                    s6   t jjj}t fdd| D } j|| d S )Nc                 3   s   | ]}  |V  qd S rB   r   r  r   r#   r$   r     r   zMTS2FXGraphConverter.convert_profiler__record_function_exit.<locals>.<genexpr>)r   rO   ZprofilerZ_record_function_exitr3   r   rn   r   )r   r   r   r+   r#   r   r$   &convert_profiler__record_function_exit  s    
z:TS2FXGraphConverter.convert_profiler__record_function_exitc                 C   s@   d}|  t| f}| j||}|  }|| j|< d S )Ntolist)r   r   r   rn   r  r   r   r   r#  r#   r#   r$   convert_prim_tolist  s
    z'TS2FXGraphConverter.convert_prim_tolistc                 C   s   |   }t | j|< d S rB   )r   r   r   rV   r   r&  r#   r#   r$   convert_prim_Uninitialized  s    z.TS2FXGraphConverter.convert_prim_Uninitializedc                    sN   t |  }t fdd| D } j||}|  }| j|< d S )Nc                 3   s   | ]}  |V  qd S rB   r   r  r   r#   r$   r     r   zBTS2FXGraphConverter._convert_standard_operators.<locals>.<genexpr>)	r   r   r3   r   rn   r   r   r   r   r#  r#   r   r$   r     s
    z/TS2FXGraphConverter._convert_standard_operatorsc              
   C   s   |  }t|}t| || j}dt|dd d }td|j	| z|| W n4 t
y } ztd| |W Y d }~n
d }~0 0 d S )Nr%  
rq   z[%s] converts [%s]zTS2EPConverter failed for node )r   rk   r   r  ri   r   rh   logdebug__name__r   r)   )r   r   Z	node_kindr   Zhandler_funcnode_strr;   r#   r#   r$   r     s    z TS2FXGraphConverter.convert_nodec              	   C   sV  g }dd | j  D t| j }|D ]}|| jv r| j| }|  spt|tjj	rp|j
dkrp| jtj|f}|| | jttjt|d|d q&|| jv r|| j|  | jttjt|| j| d|d q&td| dq&t|d	kr
| jg  nHt|d
kr*| j|d	  n(t|d
krF| j| n| j| d S )Nc                 S   s   g | ]}|  qS r#   r5  )r   r  r#   r#   r$   r     r   z=TS2FXGraphConverter.convert_graph_outputs.<locals>.<listcomp>rm   r_   r   )r`   r   zOutput r   r   rq   )r   r  r8   r   r   ro   r0   r   r   Noder   rn   r   r.  r   r   r   r   ZUSER_OUTPUTr   r   r   r   r   r   )r   r+   Zoutp_name_listr   r   r#   r#   r$   r     sZ    





z)TS2FXGraphConverter.convert_graph_outputsN)CrJ  
__module____qualname__r   r   r   r   Blockdictr   rV   r   r   r   r   rL  r8   r   r   ro   r   r   Valuer   r   r   r   r   r   r   r   r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r!  r$  r'  r(  r)  r+  r1  r2  r4  r:  r<  r>  r@  rA  rB  r?  rC  rE  rF  r   r   r   r#   r#   r#   r$   r     sp   


F
?
	!
&N
(	r   c                	       s   e Zd ZdZG dd deZeejj	ejj
f eeejf eeejf eejj
ee f eeef eeef eeef d fddZdd Z fd	d
Z  ZS )ExplainTS2FXGraphConverterz
    Run TS2FXGraphConverter in an explain mode. It collects all failed operators conversions
    and provide that information to users. In order to collect all failed conversions, it
    also mocks some internal attributes (e.g., name_to_node).
    c                       s0   e Zd Z fddZ fddZdd Z  ZS )z$ExplainTS2FXGraphConverter._DictMockc                    s   t  | || _d S rB   )superr   
mock_value)r   Z	dict_datarT  	__class__r#   r$   r   '  s    z-ExplainTS2FXGraphConverter._DictMock.__init__c                    s   t  |s| jS t  |S rB   )rS  __contains__rT  __getitem__r   r   rU  r#   r$   rX  +  s    z0ExplainTS2FXGraphConverter._DictMock.__getitem__c                 C   s   dS NTr#   rY  r#   r#   r$   rW  2  s    z1ExplainTS2FXGraphConverter._DictMock.__contains__)rJ  rM  rN  r   rX  rW  __classcell__r#   r#   rU  r$   	_DictMock&  s   r\  r   c                    sH   t  ||||||| g | _t| jtjd dddd di | _d S )NZmockr   c                   S   s   d S rB   r#   r#   r#   r#   r$   r   T  r   z5ExplainTS2FXGraphConverter.__init__.<locals>.<lambda>r#   )	rS  r   unsupported_node_listrR  r\  r   r   r   rL  )r   r   r   r   r   r   r   r   rU  r#   r$   r   5  s*    
z#ExplainTS2FXGraphConverter.__init__c                 C   s.   |    | j D ]}| | q|   d S rB   )r   r   r   r   r   r  r#   r#   r$   explainZ  s    z"ExplainTS2FXGraphConverter.explainc                    s4   zt  | W n ty.   | j| Y n0 d S rB   )rS  r   r   r]  r   r  rU  r#   r$   r   `  s    z'ExplainTS2FXGraphConverter.convert_node)rJ  rM  rN  __doc__rP  r\  r   r   r   r   rO  r   rV   r   r   r   r^  r   r[  r#   r#   rU  r$   rR    s   


%rR  c                 c   s*   | j }d| _ zd V  W || _ n|| _ 0 d S rZ  )disabled)rH  r`  r#   r#   r$   disable_loggingg  s
    ra  c                   @   s   e Zd Zdeejjejjf ee	df e
eee	f  dddZedddZeedd
dZejjeee	f dddZdd ZdS )TS2EPConverterN.)ts_modelsample_argssample_kwargsc                    s   || _ t||\| _| _}}|| _|| _i | _i | _t| j t	j
jsRt| j  ng }t| j t	j
js| j   D ]4\} t fdd|D r | j|< qt | j|< qti | _i | _|   d S )Nc                 3   s&   | ]} j |j kr |k V  qd S rB   )shaper   )r   paramr   r#   r$   r     s   z*TS2EPConverter.__init__.<locals>.<genexpr>)rc  rA   r   r=   rd  re  r   r   r0   r   r   r1   r8   
parametersr>   itemsr-  name_to_non_tensor_attributesr   lift_get_attr)r   rc  rd  re  r"   Z
param_listr   r#   rh  r$   r   s  s(    zTS2EPConverter.__init__r   c                 C   s   t d t d| j t| j\}}t| j| j| j|| j| j|}|	 }t
| t d|jdd | ||j}t d| t| jtjjs| j  D ].\}}||jvrtd| d ||j|< q|S )	Nz
TS2EPConverter logging starts from here.

INFO: (TORCH_LOGS="export" <cmd>)
    * Log TorchScript IR.

DEBUG: (TORCH_LOGS="+export" <cmd>), additionally
    * Log conversion IR by IR in a format of [<conversion handler name>] converts [<IR>].
        zTorchScript graph

%s
zGraphModule: %sF)print_outputz%szManually populate zN into state_dict ExportedProgram, but it is never used by the ExportedProgram.)rH  infor   r   r   r   r   rk  r   r   r	   Zprint_readableretrace_as_exported_programr0   rc  r   r   r1   r>   rj  r   r   )r   r   r   graph_converterrM   epr   r   r#   r#   r$   r     s@    	

zTS2EPConverter.convertTc           	   	   C   s   t | j\}}t| j| j| j|| j| j|}|  t|j	dkrd}t
|j	D ]D\}}dt|dd d }|d| d|  d| d	7 }qPnd
}|rt| |S )Nr   z2Unsupported nodes are found in the following list:r%  rG  rq   z

    z. z []zSuccess!)r   r   rR  r   r   rk  r   r^  r   r]  r:   ri   r   rh   r   print)	r   rm  r   r   rp  Zexplain_strr?   nrK  r#   r#   r$   r^    s,    	$zTS2EPConverter.explain)rM   r   c                 C   s   t dd | j}tjjj|| j|ddd}|jdd | D  |D ]}|j	
|d  qH|jjD ]R}|jtjkrd|j|v rdt||j tjsJ t||j  dtj|_d |_qd| | |S )	Nc                 S   s    t |tjrtjg|  S d S rB   )r0   r   rV   r   ZAUTOrX   )pathxr#   r#   r$   r     s    z<TS2EPConverter.retrace_as_exported_program.<locals>.<lambda>FT)dynamic_shapesr&   Zpre_dispatchc                 S   s(   i | ] \}}t |tjtjfr||qS r#   )r0   r   rV   r   )r   r   r  r#   r#   r$   r      s   z>TS2EPConverter.retrace_as_exported_program.<locals>.<dictcomp>z& has been erroneously marked as buffer)r
   rd  r   exportZ_traceZ_export
_constantsupdaterj  r>   popZgraph_signaturer   r   r   r   r   r0   rV   r   ZCONSTANT_TENSORr   Zverifiercheck)r   rM   r   rw  rq  r   specr#   r#   r$   ro    s:    z*TS2EPConverter.retrace_as_exported_programc                    sN   i t dfddtjjdfdd fdd  j d S )	N)r   c                    s(   |  d} j}|D ]}t||}q|S r   )rh   rc  r   )r   r`   r  rt  r   r#   r$   rl   (  s
    
z.TS2EPConverter.lift_get_attr.<locals>.get_attrr   c                    s8   |  d}|   } | }|r0| d| n|}|S )Nr`   rd   )r   r   r   )r   r   r   r   r   r   r#   r$   get_fqn/  s
    
z-TS2EPConverter.lift_get_attr.<locals>.get_fqnc                    s   |   D ]}| dkr,|  }d|< | dkr|}|}|  }||< t|tjr~|jvr|j|< n,t|tjr|j	vr|j	|< n
|j
|< | D ]} | qqd S )Nzprim::CreateObjectr%  r   )r   r   r   r   r0   r   rV   r   r   r   rk  r   )r   r   r   r   r   r3  _dfs_get_attrrl   r~  r   r   r#   r$   r  6  s$    


z3TS2EPConverter.lift_get_attr.<locals>._dfs_get_attr)r   r   r   rL  r   r   r#   r  r$   rl    s
    zTS2EPConverter.lift_get_attr)N)T)rJ  rM  rN  r   r   r   r2   r1   r3   r   r   rP  r   r   r   r   ra  rH  r^  r   r   ro  rl  r#   r#   r#   r$   rb  q  s    
$4
/rb  )rb   )jbuiltinsloggingr  r6   r   collections.abcr   
contextlibr   r   r   r   r   r   Ztorch.export._tracer   ZAtorch._export.passes.replace_quantized_ops_with_standard_ops_passr	   Ztorch.export.dynamic_shapesr
   r   Ztorch.export.exported_programr   Ztorch.export.graph_signaturer   r   r   r   r   r   r   Ztorch.fxr   	getLoggerrJ  rH  r%   r-   nnModuler   r1   r3   r   r8   r2   rA   rE   rH   rL   r   r   r]   ra   r   rf   rk   rp   Zuint8Zint8int16r   int64float16float32float64Z	complex32Z	complex64Z
complex128r   Zqint8Zquint8Zbfloat16r   rj  r   r   maxminr  is_is_notnot_containsr   rO   rP   Z	sym_numelrQ   Zsym_storage_offsetZ
sym_strider   rP  __annotations__r   r   rO  r   r   rL  r   r   r   rR  ra  rb  r#   r#   r#   r$   <module>   s   
$	
2	"Q       H
	