o
    Ih                     @   s  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 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$deej%j&ej'j(f dee	 de)ej*e+d e	e
ej, f fddZ-dd Z.dd Z/dd Z0dej1j2fddZ3dd Z4dQd!e5d"e5de5fd#d$Z6d!e5de5fd%d&Z7d'd( Z8ej9d ej:d)ej;d*ej<d+ej=d,ej>d-ej?d.ej@d/ejAd0ejBd1ejCd2ejDd3ejEd4ejFd5ejGd6iZHd7d8 eHI D ZJd9d: ZKe jLe jMejNejOejPejQejReKeSejTjUjVejTjUjWejTjUjXejTjUjYd;ZZd<d= Z[d>d? Z\d@ejj*de)e]ejj^e_e5 f e]e5e5f f fdAdBZ`dCe]e5e5f dDejjade5fdEdFZbdDejjafdGdHZcG dIdJ dJZdG dKdL dLedZeedMdN ZfG dOdP dPZgdS )R    N)Sequence)contextmanager)Any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 ]#\}}dt| v r%tj|\}}|t| q	||d u q	|S )NPackedParams)	zipinputsstrtypetorchjit_flattenappendlen)method_graphargs_paramsparam_count_listinput_arg_params_in_vars_ r%   K/var/www/vscode/kcb/lib/python3.10/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r2td||fS )NFT)strict_force_outplace_return_inputs_stateszXstate_dict changed after running the tracer; something weird is happening in your model!)r   r   _unique_state_dictkeysis_autocast_cache_enabledset_autocast_cache_enabled_get_trace_graphRuntimeError)modelargsorig_state_dict_keysprev_autocast_cache_enabledtrace_graph	torch_out_inputs_statesr%   r%   r&   _trace_and_get_graph_from_model.   s    

r8   r1   r2   returnz	_C.IValuec              
   C   s  t | tjjtjjfrttjt|d }d }t | tjjr}z| jj}W n t	y7 } zt
d|d }~ww 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)preserveParametersforwardF)
isinstancer   r   ScriptFunctionScriptModuletupler   r;   graphAttributeErrorr0   r   $_jit_pass_onnx_function_substitution_freeze_moduletypingcast_c_jit_onnx_list_model_parameters_get_methodr'   "_propagate_and_assign_input_shapesr8   _jit_pass_onnx_lintr+   listvaluesr   r   r,   	enumeratesetDebugName)r1   r2   flattened_argsr6   r@   efreezed_modulemoduleparamsr   r   r    r#   r$   
state_dictgraph_inputsuser_input_numparam_namesiinpr%   r%   r&   _create_jit_graphJ   sX   







rZ   c                 C   s   | | S Nr%   )abr%   r%   r&   list_add|   s   r^   c                 C   s
   | |g S r[   r%   )	containerelementr%   r%   r&   list_append   s   
ra   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_idxlen_loop_local_argumentsr2   kwargsloop_local_argsglobal_argsr%   r%   r&   execute_subgraph_from_prim_loop   s   rh   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)rounding_mode)
r   opsatensym_sizeintscalar_tensordivScalar_modeIntTensor)imdimscalesym_size_intrp   div_scalar_mode
int_tensorr%   r%   r&   pattern   s   
z.inplace_optimize_sym_size_div.<locals>.patternc                 S   s   t jjj| |}|| S r[   )r   rl   rm   rn   ro   )ru   rv   rw   rx   r%   r%   r&   replacement   s   z2inplace_optimize_sym_size_div.<locals>.replacement)r   replace_pattern)ri   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   r0   isdigitnamer%   r%   r&   is_valid_for_codegen   s
   r   renamer   prefixc                 C   s&   |  dd} t| r| S | d|  S )N.r$   )replacer   )r   r   r%   r%   r&   normalize_name   s   r   c                 C   s   |  d}dd| S )zprim::If -> convert_prim_If::convert_r$   )splitjoin)r   	name_listr%   r%   r&   ir_name_to_func_name   s   
r   c                 C   s   |r|  |S | |S r[   )get_attrplaceholder)fx_graphr   is_top_level_graphr%   r%   r&   #get_node_as_placeholder_or_get_attr   s   

r                           	   
               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_ENUMr0   )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::stridec                 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   s8   g }| |v r| ||   ||  } | |v sdt|S Nr   )r   r   reversed)irref_mapname_mapr   r%   r%   r&   construct_fqn  s   r   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krt|\}}}||< ||< | 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 ]-}| D ]	}| |}q| dkr4|  }|t  vr4|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   rL   addr   r<   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%   )r@   r%   )r   r   r   r   r   r&   get_block_to_lifted_attrs	  s   r   name_to_attribute_fqnr   c                    s   dt f fdd}| dkrt|  }n| dkr%|  }ntd| d|d}||}|rA| d| }|S |}|S )	Nr   c                    s    |  v r |  S t d|  dNz
Attribute 
 not found)
ValueErrorr   r   r%   r&   r   \  s   z0get_attribute_fqn_from_ts_node.<locals>.get_attrprim::SetAttrr   z7Unexpected node kind when getting attribute fqn. node:  r   )r   r   nextr   r   r   r0   r   )r   r   r   
input_namer   root_attr_nameattr_fqnr%   r   r&   get_attribute_fqn_from_ts_nodeY  s   

r   c           
   
   C   s   |   }|dksJ d|  tj|}t|jd\}}|j}zttj	|}t||}|r8t||}W |S |j
}W |S  tyX }	 ztd|   d|    |	d }	~	ww )N(no schema)zgot empty schema for r   zUnable to find operator z with schema )schemar   r   parse_schemar   r   r   overload_namegetattrrl   default	Exceptionr0   r   )
r   
schema_strr   nsop_nameoverrideop_overload_modop_overload_packetop_overloadrP   r%   r%   r&   get_op_overloadr  s*   
r   c                   @   s  e Zd Zdeejjejjf dee	ej
f dee	ej
f deejjee	 f dee	ef dee	ef dee	e	f fdd	Zd
d Zdejjdee	 fddZdd Zdd Zde	fddZdejjfddZdejjfddZdd ZdejjfddZd d! Zdejjfd"d#Zdejjfd$d%Zdejjfd&d'Zdejjfd(d)Z dejjfd*d+Z!dejjfd,d-Z"dejjfd.d/Z#dejjfd0d1Z$dejjfd2d3Z%dejjfd4d5Z&dejjfd6d7Z'dejjfd8d9Z(dejjfd:d;Z)dejjfd<d=Z*dejjfd>d?Z+dejjfd@dAZ,dejjfdBdCZ-dejjfdDdEZ.dejjfdFdGZ/dejjfdHdIZ0dejjfdJdKZ1dejjfdLdMZ2dejjfdNdOZ3dejjfdPdQZ4dRdS Z5dejjfdTdUZ6dVejjfdWdXZ7dejjfdYdZZ8dejjfd[d\Z9dejjfd]d^Z:dejjfd_d`Z;dejjfdadbZ<dejjfdcddZ=dejjfdedfZ>dejjfdgdhZ?dejjfdidjZ@dejjfdkdlZAdmdn ZBdoS )p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 r[   )_convert_standard_operators)r   selfr%   r&   <lambda>  s   
 z.TS2FXGraphConverter.__init__.<locals>.<lambda>)r   r   r   r   fxr   r   input_specsoutput_specsname_to_noder   r   !name_to_non_tensor_attribute_noder   	subgraphsr   kind_to_standard_operatorsr,   r   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 r[   )r   r   r   r<   r   ScriptObject)r   fqnr%   r%   r&   _is_get_attr_node  s   

z%TS2FXGraphConverter._is_get_attr_noder   r   c              	   C   s   g g }}|  D ]<}t|| j| j| ji | j| j}|D ]}t|}|j	|}	|	|j
|< q| }
| |
}|| j| || q	||fS r[   )r   r   r   r   r   r   r   r   r   r   r   convertadd_subgraphr   r   )r   r   r   subgraph_nodessubgraph_convertersr   subgraph_converter	block_argnormalized_block_arg_nameplaceholder_noderb   subgraph_namer%   r%   r&   _convert_block_to_subgraph  s,   


z.TS2FXGraphConverter._convert_block_to_subgraphc                 C   sn   t  }| D ]-}| D ]&}| 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   
block_nodeblock_node_inr%   r%   r&   r    s   
z1TS2FXGraphConverter._identify_inputs_as_argumentsc                 C   s   t | jtjjS r[   )r<   r   r   r   r   r   r%   r%   r&   r     s   z&TS2FXGraphConverter.is_top_level_graphr9   c                 C   s   dt | j }|| j|< |S )N	subgraph_)r   r   )r   rb   r   r%   r%   r&   r     s   
z TS2FXGraphConverter.add_subgraphc                 C   sV   g }i }t | |jD ]\}}|jr| |||j< q|| | qt||fS r[   )r   r   r   
kwarg_onlyget_fx_value_by_ir_valuer   r   r?   )r   r   r   r2   re   r   
schema_argr%   r%   r&   get_args_kwargs  s   z#TS2FXGraphConverter.get_args_kwargsr   c                 C   s|   |  }|| jv r| j| }|S || jv r)t| j| tjr$| j|S | j| S || jv r6| 	| j| S t
d| d)NzInput r   )r   r   r   r<   r   r   r   r   r   get_fx_value_by_fqnr   )r   r   
value_name
input_noder%   r%   r&   r    s   




z,TS2FXGraphConverter.get_fx_value_by_ir_valuec                 C   sp   || j v r| j | }|S || jv r| j| }|S || jv r$| j| }|S || jv r0| j| }|S td| d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 r[   )convert_graph_inputsr   r   convert_nodeconvert_graph_outputsr   r   GraphModuler   r   r   r   r   r   r~   r@   lint)r   r   ri   r%   r%   r&   r   ;  s*   
zTS2FXGraphConverter.convertc              	   C   sZ  | j  D ]}| }|| jv r-t|}| jttj	t
|d|d t| j||  }nx|| jv rPt|}| jttjt
|d|dd t| j||  }nU|| jv rt| j| tjsbJ dt|}| jttjt||d|dd t| j||  }n$t| tjrqt|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   	class_fqnFr   )r   )r   r   r   r   r   r   r   r   r   	PARAMETERr   r   r   r   r   BUFFERr   r<   r   r   
CUSTOM_OBJr   r   	ClassType
USER_INPUTr   r   )r   graph_inputr   normalized_namer  r%   r%   r&   r  U  sx   



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                       g | ]}  |qS r%   r  r   rY   r   r%   r&   
<listcomp>      
z:TS2FXGraphConverter.convert_aten_Float.<locals>.<listcomp>)r   r   call_functionr?   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 r*tjntj	j  fdd}|
  }| j|||}|| j|< dS )z9aten::tensor creates a constant tensor ad-hoc --> GetAttrrequires_gradc                 s   s    | ]}t |tV  qd S r[   )r<   ro   )r   r\   r%   r%   r&   	<genexpr>      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)r2   re   	to_tensorr%   r&   r    s   z7TS2FXGraphConverter.convert_aten_tensor.<locals>.targetN)r  r   rl   rm   r   r   _schemaboolall_refsr   r   r   r/  r   )r   r   r2   re   r   r  output_namer  r%   r6  r&   convert_aten_tensor  s   
z'TS2FXGraphConverter.convert_aten_tensorc                    s   t d t fdd| D } jt|}| j| 	 < | j|
d	 <   sD|d jdkrF j|
d	  d S d S 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       | ]}  |V  qd S r[   r+  r,  r   r%   r&   r3    r4  z:TS2FXGraphConverter.convert_aten_append.<locals>.<genexpr>r   r   )warningswarnr?   r   r   r/  ra   r   r   r   inputsAtr   opr   r   )r   r   r2   r  r%   r   r&   convert_aten_append  s   z'TS2FXGraphConverter.convert_aten_appendc                 C   s   |   }d }|dra|d}|dkr|d}nG|dkr&|d}n=|dkr0|d}n3|dkrMd| }| j|}|| j	|< ||
d}}n|dkrW|d}ntd|d d }|| j|< d S )	Nr   rX   fr   r(  lifted_tensor_ivalzUnsupported constant type: )r   r   hasAttributekindOfrX   rD  r   r   r   r   r(  rF  r   r   )r   r   r   r   constant_kind
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                    r*  r%   r+  r,  r   r%   r&   r-    r.  z?TS2FXGraphConverter.convert_prim_CallMethod.<locals>.<listcomp>r   )r   r   call_methodr   r?   r   r   r   )r   r   r0  r  r%   r   r&   convert_prim_CallMethod  s   
z+TS2FXGraphConverter.convert_prim_CallMethodc                 C   sP   |   }|tjj r | }| 	 }|| j
|< d S td| d)NzUnsupported JitType (z) when get device)r   r   isSubtypeOfr   r   
TensorTypegetdevicer   r   r   r   )r   r   
input_typerQ  r<  r%   r%   r&   convert_prim_device  s   z'TS2FXGraphConverter.convert_prim_devicec                 C   s   t | j|}|  }|| j|< |  r<| |r%| j|| j|< d S || j	vr2| j
| | j	|< | j	| | j|< d S | |rK| j| | j|< d S d S r[   )r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r<  r%   r%   r&   convert_prim_GetAttr  s"   



z(TS2FXGraphConverter.convert_prim_GetAttrc                 C   sd   t | j|}t| d }| |}| |r+| j|}| jt	j
j||f d S || j|< d S Nr   )r   r   r?   r   r  r   r   r   r/  r   rt   copy_r   )r   r   r   
attr_valuets_graph_tensor_inputfx_attr_noder%   r%   r&   convert_prim_SetAttr  s   

z(TS2FXGraphConverter.convert_prim_SetAttrc           
      C   s   t |}| ||j\}}| j|||}| dkr(|  }|| j|< d S t	|
 D ]\}}| }| jtj||f}	|	| j|< q.d S rU  )r   r  r8  r   r/  outputsSizer   r   r   rM   outputsoperatorgetitem)
r   r   r  r2   re   r  r<  rX   outpnext_fx_noder%   r%   r&   convert_call_function_op*  s   
z,TS2FXGraphConverter.convert_call_function_opc                 C      |  | d S r[   _convert_prim_iteratorr   r   r%   r%   r&   convert_prim_TupleConstruct?     z/TS2FXGraphConverter.convert_prim_TupleConstructc                 C   rb  r[   rc  re  r%   r%   r&   convert_prim_ListConstructB  rg  z.TS2FXGraphConverter.convert_prim_ListConstructc                    s0    fdd|  D }|  }| j|< d S )Nc                    r*  r%   r+  r,  r   r%   r&   r-  F  r   z>TS2FXGraphConverter._convert_prim_iterator.<locals>.<listcomp>)r   r   r   r   )r   r   output_listr<  r%   r   r&   rd  E  s   z*TS2FXGraphConverter._convert_prim_iteratorc                 C   s   i }d\}}t | D ])\}}|d dkr| |}q| |}|d ur)|d us-J d|||< d\}}q|d u r>|d u sBJ d|  }|| j|< d S )N)NNr   r   z*DictConstruct has an empty key value pair.zGDictConstruct has an odd number of elements (violating our assumption).)rM   r   r  r   r   r   )r   r   output_dictr   vrX   rY   r<  r%   r%   r&   convert_prim_DictConstructK  s    

z.TS2FXGraphConverter.convert_prim_DictConstructc                 C   rb  r[   _convert_prim_unpack_iteratorre  r%   r%   r&   convert_prim_ListUnpackb  rg  z+TS2FXGraphConverter.convert_prim_ListUnpackc                 C   rb  r[   rm  re  r%   r%   r&   convert_prim_TupleUnpacke  rg  z,TS2FXGraphConverter.convert_prim_TupleUnpackc                 C   sN   t | D ]\}}| }| | }| jtj||f}|| j	|< qd S r[   )
rM   r\  r   r  r   r   r/  r]  r^  r   )r   r   rX   r_  	outp_namerY   r  r%   r%   r&   rn  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   r>  r[   r+  r   r   r   r%   r&   r3  s  r4  z7TS2FXGraphConverter.convert_aten_Int.<locals>.<genexpr>r   )r   rl   rm   _to_copyr   r?   r   r   r/  int32_local_scalar_denser   r   r   )r   r   r  r2   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   r>  r[   r+  rr  r   r%   r&   r3    r4  z?TS2FXGraphConverter.convert_prim_NumToTensor.<locals>.<genexpr>r   )r   rl   rm   rp   r?   r   r   r/  longr   r   r   r   r   r  r2   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 r[   )r   rl   rm   convolutionr   r  r8  r   r/  r   r   r   )r   r   r  r2   re   r  r<  r%   r%   r&   convert_aten__convolution  s
   z-TS2FXGraphConverter.convert_aten__convolutionc                 C   s   t |}|j}| ||\}}|jdkrZ|d j}|| jv rZt| j| tjrZ| j| }|	 dkrZt
|}| j|  |d< | jtjjjjt||}	|  }
|	| j|
< d S | | d S )NTensor_moder   )r   r8  r  r   r   r   r<   r   rt   numelrK   r'  r   r/  rl   rm   rq   rr   r?   r   r   r   ra  )r   r   r  r   r2   re   	arg1_nametensor_constant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   r>  r[   r+  rr  r   r%   r&   r3    s    

z?TS2FXGraphConverter.convert_aten___getitem__.<locals>.<genexpr>)	r?   r   r   r/  r]  r^  r   r   r   )r   r   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rpdd |	 
 D }dd |D }tdd |D }|rpt|dksBJ 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   user%   r%   r&   r-    s    z7TS2FXGraphConverter.convert_aten_to.<locals>.<listcomp>c                 S   s    g | ]}|  d krt|qS )r   )r   r   )r   	user_noder%   r%   r&   r-    s
    c                 s   s    | ]}|j jV  qd S r[   )r8  
is_mutable)r   r  r%   r%   r&   r3    s    
z6TS2FXGraphConverter.convert_aten_to.<locals>.<genexpr>r   Tr   )r   r  r8  r   rl   rm   r%  r   
prim_dtyper   usesanyr   rK   r   r/  r?   cloner   r   r   ra  )r   r   r  r2   _kwargs
user_nodesuser_targetshas_mutable_targetnew_argsr  
clone_noder<  r%   r%   r&   convert_aten_to  s0    
z#TS2FXGraphConverter.convert_aten_toc                 C   s   |  dkr*t|d tjr#t|d tjr#tjjjj	}nt
d| t|}|tjjjj	krQ| ||j\}}|  }| jt|| j|< d S | | d S )Nr   r   r   z#unable to determind the target for )r   r<   rA  r   r   ListTyperl   rm   r   r(  r0   r   r  r8  r   r   r   r/  r^   r   ra  )r   r   r  r2   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 ]+}|	 dkr9|
  |kr9td|	 dkrP| D ]}| |krOtdqCq%d S )Nr   zKprim::Loop currently cannot run with dynamic value of number of iterations.r   z@prim::Loop currently cannot run with dynamic value of condition.r   )rK   r   r   r   r0   r   r   r\  r   r[  r   )r   r   r   subblock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| }q&t |} ||\}}t	|dksEJ |d }	 
 sU j|	j _ fdd|| D }
t|D ]n} jt|d |t	|g|
R i }| dkrt| D ]\}}| } jtj||d f j|<  j| |
|< qt|	jD ])\}} jtj|||  d f j|< ||} j| |
||  | < qqdd S )Nr   c                 S      g | ]}|  qS r%   r   r,  r%   r%   r&   r-  $      z9TS2FXGraphConverter.convert_prim_Loop.<locals>.<listcomp>r   r   c                    r*  r%   r  r   r   r   r%   r&   r-  =  s    )rK   r   r  r  r  r   r   r   r  r   r   r   ranger   r/  rh   r[  rM   r\  r   r]  r^  r   r  )r   r   r   num_iterationsloop_local_argumentsglobal_argumentsr   r   r  r  fx_block_argsrc   	loop_noderX   r_  r<  r   global_argument_indexr%   r   r&   convert_prim_Loop  sx   





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   r0   )r   r  r   r   r%   r%   r&   _check_set_attr_in_if_blockk  s   z/TS2FXGraphConverter._check_set_attr_in_if_blockc                    s6    | t| }t|dksJ  |d } |}| D ]
}| j| }q#t|} 	||\}}t|dksBJ  fdd|D }||d |d t
|f}	 jtj|	i }
| dkrs|  }|
 j|< d S | dkrt| D ]\}}| } jtj|
|f}| j|< qd S d S )Nr   r   r   c                    r*  r%   r  r  r   r%   r&   r-    r   z7TS2FXGraphConverter.convert_prim_If.<locals>.<listcomp>)r  rK   r   r   r  r  r   r   r   r  r?   r   r/  r   condr[  r   r   r   rM   r\  r]  r^  )r   r   r   	predicater   r   r   r$   r  r2   	cond_noder<  rX   r   r^  r%   r   r&   convert_prim_Ifu  s6   

z#TS2FXGraphConverter.convert_prim_Ifc                 C   rb  r[   )_convert_as_noopre  r%   r%   r&   convert_aten_Bool  rg  z%TS2FXGraphConverter.convert_aten_Boolc                 C      d S r[   r%   re  r%   r%   r&   convert_prim_Enter  s   z&TS2FXGraphConverter.convert_prim_Enterc                 C   r  r[   r%   re  r%   r%   r&   convert_prim_Exit  s   z%TS2FXGraphConverter.convert_prim_Exitc                 C   s<   t |}|j}| ||\}}|  }|d | j|< d S )Nr   )r   r8  r  r   r   r   )r   r   r  r   r2   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   r>  r[   r+  rr  r   r%   r&   r3    r4  zMTS2FXGraphConverter.convert_profiler__record_function_exit.<locals>.<genexpr>)r   rl   profiler_record_function_exitr?   r   r   r/  )r   r   r  r2   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   r   rL  r   r   r   ry  r%   r%   r&   convert_prim_tolist  s
   z'TS2FXGraphConverter.convert_prim_tolistc                 C   s   |   }t | j|< d S r[   )r   r   r   rt   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   r>  r[   r+  rr  r   r%   r&   r3    r4  zBTS2FXGraphConverter._convert_standard_operators.<locals>.<genexpr>)	r   r   r?   r   r   r/  r   r   r   ry  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 d S  t
y@ } ztd| |d }~ww )Nr{  
r   z[%s] converts [%s]zTS2EPConverter failed for node )r   r   r   ra  r   r   r   logdebug__name__r   r0   )r   r   	node_kindr   handler_funcnode_strrP   r%   r%   r&   r    s   z TS2FXGraphConverter.convert_nodec              	   C   sT  g }dd | j  D t| j }|D ]b}|| jv rM| j| }|  s8t|tjj	r8|j
dkr8| jtj|f}|| | jttjt|d|d q|| jv rn|| j|  | jttjt|| j| d|d qtd| dt|d	kr| jg  d S t|d
kr| j|d	  d S t|d
kr| j| d S | j| d S )Nc                 S   r  r%   r  )r   r_  r%   r%   r&   r-    r  z=TS2FXGraphConverter.convert_graph_outputs.<locals>.<listcomp>r   r   r  )r   r   zOutput r   r   r   )r   r\  rK   r   r   r   r<   r   r   NoderB  r   r/  r  r   r   r   r   USER_OUTPUTr   r   r   r   r   r   )r   r2   outp_name_listr<  r  r%   r%   r&   r    sX   






z)TS2FXGraphConverter.convert_graph_outputsN)Cr  
__module____qualname__r   r   r   r   Blockdictr   rt   r   r   r   r   r  rK   r  r  r   r   r  Valuer  r  r   r  r   r  r1  r=  rC  rK  rM  rS  rT  rZ  ra  rf  rh  rd  rl  ro  rp  rn  rw  rz  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     s    



F
?
	!
&N
(	r   c                       s   e Zd ZdZG dd deZdeejj	ejj
f deeejf deeejf deejj
ee f deeef d	eeef d
eeef f 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 r[   )superr   
mock_value)r   	dict_datar  	__class__r%   r&   r   '  s   
z-ExplainTS2FXGraphConverter._DictMock.__init__c                    s   t  |s	| jS t  |S r[   )r  __contains__r  __getitem__r   r   r  r%   r&   r  +  s   z0ExplainTS2FXGraphConverter._DictMock.__getitem__c                 C   s   dS NTr%   r  r%   r%   r&   r  2  s   z1ExplainTS2FXGraphConverter._DictMock.__contains__)r  r  r  r   r  r  __classcell__r%   r%   r  r&   	_DictMock&  s    r  r   r   r   r   r   r   r   c                    sH   t  ||||||| g | _t| jtjd dddd di | _d S )Nmockr/  c                   S   r  r[   r%   r%   r%   r%   r&   r   T  s    z5ExplainTS2FXGraphConverter.__init__.<locals>.<lambda>r%   )	r  r   unsupported_node_listr  r  r   r   r   r  )r   r   r   r   r   r   r   r   r  r%   r&   r   5  s*   

z#ExplainTS2FXGraphConverter.__init__c                 C   s.   |    | j D ]}| | q	|   d S r[   )r  r   r   r  r  re  r%   r%   r&   explainZ  s   z"ExplainTS2FXGraphConverter.explainc                    s4   z	t  | W d S  ty   | j| Y d S w r[   )r  r  r   r  r   re  r  r%   r&   r  `  s
   z'ExplainTS2FXGraphConverter.convert_node)r  r  r  __doc__r  r  r   r   r   r   r  r   rt   r   r   r   r  r  r  r%   r%   r  r&   r    s(    


%r  c                 c   s*    | j }d| _ z	d V  W || _ d S || _ w r  )disabled)r  r  r%   r%   r&   disable_loggingg  s   r  c                
   @   s   e Zd Z	ddeejjejjf dee	df de
eee	f  fddZdefd	d
ZeedddZdejjdeee	f fddZdd ZdS )TS2EPConverterNts_modelsample_args.sample_kwargsc                    s   || _ t||\| _| _}}|| _|| _i | _i | _t| j t	j
js)t| j  ng }t| j t	j
jsU| j   D ]\} t fdd|D rO | j|< q: | j|< q:i | _i | _|   d S )Nc                 3   s(    | ]} j |j kr |k V  qd S r[   )shaper:  )r   paramr   r%   r&   r3    s    
z*TS2EPConverter.__init__.<locals>.<genexpr>)r  rZ   r   rS   r  r  r   r   r<   r   r   r=   rK   
parametersrT   itemsr  name_to_non_tensor_attributesr   lift_get_attr)r   r  r  r  r$   
param_listr   r%   r  r&   r   s  s(   zTS2EPConverter.__init__r9   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sh| j  D ]\}}||jvrgtd| d ||j|< qP|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.)r  infor   r   r   r   r   r  r   r   r   print_readableretrace_as_exported_programr<   r  r   r   r=   rT   r  r?  r@  )r   r   r   graph_converterri   epr   r   r%   r%   r&   r     sB   	


zTS2EPConverter.convertTc           	   	   C   s   t | j\}}t| j| j| j|| j| j|}|  t|j	dkrLd}t
|j	D ]"\}}dt|dd d }|d| d|  d| d	7 }q(nd
}|rTt| |S )Nr   z2Unsupported nodes are found in the following list:r{  r  r   z

    z. z []zSuccess!)r   r   r  r   r   r  r   r  r   r  rM   r   r   r   r   print)	r   r  r   r   r  explain_strrX   nr  r%   r%   r&   r    s.   	"zTS2EPConverter.explainri   r   c                 C   s   t dd | j}tjjj|| j|ddd}|jdd | D  |D ]	}|j	
|d  q$|jjD ]&}|jtjkrX|j|v rXt||j tjsTJ t||j  dtj|_q2| | |S )	Nc                 S   s    t |tjrtjg|  S d S r[   )r<   r   rt   r
   AUTOrv   )pathxr%   r%   r&   r     s    z<TS2EPConverter.retrace_as_exported_program.<locals>.<lambda>FT)dynamic_shapesr(   pre_dispatchc                 S   s(   i | ]\}}t |tjtjfr||qS r%   )r<   r   rt   r   )r   r   rk  r%   r%   r&   r      s    z>TS2EPConverter.retrace_as_exported_program.<locals>.<dictcomp>z& has been erroneously marked as buffer)r	   r  r   export_trace_export
_constantsupdater  rT   popgraph_signaturer   r   r   r  r  r<   rt   r   CONSTANT_TENSORverifiercheck)r   ri   r   r  r  r   specr%   r%   r&   r    s:   z*TS2EPConverter.retrace_as_exported_programc                    sN   i dt ffdddtjjffdd fdd  j d S )	Nr   c                    s(   |  d} j}|D ]}t||}q
|S r   )r   r  r   )r   r   rk  r  r   r%   r&   r   '  s
   
z.TS2EPConverter.lift_get_attr.<locals>.get_attrr   c                    s<   |  d}|   } | }|r| d| }|S |}|S )Nr   r   )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rU|}|}|  }||< t|tjr?|jvr>|j|< nt|tjrP|j	vrO|j	|< n|j
|< | D ]} | qYqd S )Nzprim::CreateObjectr{  r   )r   r   r   r   r<   r   rt   r   r   r   r  r   )r   r   r<  r   r   r  _dfs_get_attrr   r  r   r   r%   r&   r  5  s,   





z3TS2EPConverter.lift_get_attr.<locals>._dfs_get_attr)r   r   r   r  r   r   r%   r  r&   r    s
   zTS2EPConverter.lift_get_attrr[   )T)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&   r  q  s$    

$4

.r  )r   )hbuiltinsloggingr]  rD   r?  collections.abcr   
contextlibr   r   r   r   r   torch.export._tracer   Atorch._export.passes.replace_quantized_ops_with_standard_ops_passr   torch.export.dynamic_shapesr	   r
   torch.export.exported_programr   torch.export.graph_signaturer   r   r   r   r   r   r   torch.fxr   	getLoggerr  r  r'   r8   nnModuler   r=   r?   r   rK   r>   rZ   r^   ra   rh   r   r  r~   r   r   r   r   r   uint8int8int16rt  int64float16float32float64	complex32	complex64
complex128r9  qint8quint8bfloat16r   r  r5  r   maxminr^  is_is_notnot_containsr   rl   rm   	sym_numelrn   sym_storage_offset
sym_strider   r   r   r  r  r   r   r  r   r   r   r  r  r  r%   r%   r%   r&   <module>   s   $	

2"
P

       H
	