o
    Xi$                     @  s   d Z ddlmZ g dZddlZddlZddlZe	e
ZG dd dejjZG dd dejjZG d	d
 d
ejjZG dd dejjZdS )zLift constants to initializers.    )annotations)AddInitializersToInputsPassLiftConstantsToInitializersPass'LiftSubgraphInitializersToMainGraphPass RemoveInitializersFromInputsPassNc                      s8   e Zd ZdZdd fdd	ZdddZdddZ  ZS )r   a  Lift constants to initializers.

    Attributes:
        lift_all_constants: Whether to lift all Constant nodes, including those that does not contain a tensor attribute (e.g. with value_ints etc.)
            Default to False, where only Constants with the ``value`` attribute are lifted.
        size_limit: The minimum size of the tensor to be lifted. If the tensor contains
            number of elements less than size_limit, it will not be lifted. Default is 16.
    F   lift_all_constantsbool
size_limitintc                   s   t    || _|| _d S )N)super__init__r   r
   )selfr   r
   	__class__ _/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/passes/common/constant_manipulation.pyr   !   s   

z(LiftConstantsToInitializersPass.__init__modelir.Modelreturnir.passes.PassResultc           
      C  s  d}t j|jD ]}|jd usJ |jdks|jdvrq	|jd  r,t	d|j
 q	t|j }t|dkrAt	d|j
 q	tt|j \}}|jd j
}|d usXJ t|t js`J | ||||}|d u rmq	t j||jt |j||jd j d}	|	j|jd j |jd usJ |j|	 |jd |	 |jj|dd	 |d7 }t	d
|j
| q	|rt	d| t j j!|t"|dS )Nr   Constant) zonnx.aiz<Constant node '%s' is used as output, so it can't be lifted.   z6Invalid constant node '%s' has more than one attribute)nameshapetypeconst_valuemetadata_propsT)safez0Converted constant node '%s' to initializer '%s'z#Lifted %s constants to initializersmodified)#ir	traversalRecursiveGraphIteratorgraphop_typedomainoutputsis_graph_outputloggerdebugr   set
attributeskeyslennextiteritems
isinstanceAttr"_constant_node_attribute_to_tensorValuer   
TensorTypedtyper   copymetaupdateregister_initializerreplace_all_uses_withremovepasses
PassResultr	   )
r   r   countnodeconstant_node_attribute	attr_name
attr_valueinitializer_nametensorinitializerr   r   r   call&   sX   
	z$LiftConstantsToInitializersPass.callrD   strrE   ir.AttrrF   ir.TensorProtocol | Nonec                 C  s   | j s|dkrtd|j| dS |dkr| }nc|dkr+tj| tjj	|d}nR|dkr<tj|
 tjj	|d}nA|dkrMtj| tjj|d}n0|dkr^tj| tjj|d}n|d	v rqtjtj|jtjd
|d}ntd|j d| d|j| jk rtd|j| j dS |S )z*Convert constant node attribute to tensor.valuez0Constant node '%s' has non-tensor attribute '%s'N	value_int)r8   r   
value_intsvalue_floatvalue_floats)value_stringvalue_strings)r8   )r   zUnsupported constant node 'z' attribute ''z/Tensor from node '%s' has less than %s elements)r   r*   r+   r   	as_tensorr"   rG   as_intDataTypeINT64as_intsas_floatFLOAT	as_floatsStringTensornparrayrM   bytes_
ValueErrorsizer
   )r   rB   rD   rE   rF   rG   r   r   r   r5   [   sL   
zBLiftConstantsToInitializersPass._constant_node_attribute_to_tensor)Fr   )r   r	   r
   r   r   r   r   r   )rD   rJ   rE   rK   rF   rJ   r   rL   )__name__
__module____qualname____doc__r   rI   r5   __classcell__r   r   r   r   r      s
    	
5r   c                   @     e Zd ZdZd	ddZdS )
r   a1  Lift subgraph initializers to main graph.

    This pass lifts the initializers of a subgraph to the main graph.
    It is used to ensure that the initializers are available in the main graph
    for further processing or optimization.

    Initializers that are also graph inputs will not be lifted.
    r   r   r   r   c                 C  s  d}i }|  D ]w}||ju rqt|jD ]i}|d usJ |j| }| r.td|j q| r:td|j q|j	| |}||jjv rh||v rU||  d7  < nd||< | d||  }||jjv sH||_|j
| |d7 }td|j|j qqtjj|t|dS )Nr   z=Initializer '%s' is also a graph input, so it can't be liftedz9Initializer '%s' is used as output, so it can't be liftedr   _z8Lifted initializer '%s' from subgraph '%s' to main graphr    )graphsr%   tupleinitializersis_graph_inputr*   r+   r   r)   popr<   r"   r?   r@   r	   )r   r   rA   registered_initializer_namesr%   r   rH   new_namer   r   r   rI      sL   

#z,LiftSubgraphInitializersToMainGraphPass.callNrc   rd   re   rf   rg   rI   r   r   r   r   r      s    	r   c                   @  ri   )
r   zRemove initializers from inputs.

    This pass finds all graph inputs that have a const_value and removes them from the graph.inputs list.
    r   r   r   r   c                 C  s   d}|  D ]*}t|j }g }|jD ]}||v r|d7 }q|| q|j  |j| qt	d| t
jj|t|dS )Nr   r   z)Removed %s initializers from graph inputsr    )rk   r,   rm   valuesinputsappendclearextendr*   infor"   r?   r@   r	   )r   r   rA   r%   rm   
new_inputsinput_valuer   r   r   rI      s   


z%RemoveInitializersFromInputsPass.callNrc   rr   r   r   r   r   r          r   c                   @  ri   )
r   zAdd initializers to inputs.

    This pass finds all initializers and adds them to the graph.inputs list if they are not already present.
    r   r   r   r   c                 C  sh   d}|  D ]}t|j}|j D ]}||vr"|j| |d7 }qqtd| tj	j
|t|dS )Nr   r   z%Added %s initializers to graph inputsr    )rk   r,   rt   rm   rs   ru   r*   rx   r"   r?   r@   r	   )r   r   rA   r%   
inputs_setrH   r   r   r   rI      s   
z AddInitializersToInputsPass.callNrc   rr   r   r   r   r   r      r{   r   )rg   
__future__r   __all__loggingnumpyr^   onnx_irr"   	getLoggerrd   r*   r?   InPlacePassr   r   r   r   r   r   r   r   <module>   s   
t6