U
    T?hu                     @   s   d dl Z d dlZd dlZd dlmZ ejeZej	ej
edr^ejej
ed nejej
ed d dlmZmZmZ e eZG dd deZdS )	    N)Dictz ../tools/symbolic_shape_infer.pyz../toolsz..)SymbolicShapeInferenceget_shape_from_type_protosympyc                       sP   e Zd Zd fdd	Zdeeef edd	d
Zdd Zdd Z	dd Z
  ZS )SymbolicShapeInferenceHelperr   TFc                    s.   t  |||| || _d| _d| _i | _d S )NF)super__init__model_all_shapes_inferred_is_inferred_dynamic_axis_mapping_)selfmodelverboseZint_maxZ
auto_mergeZguess_output_rank	__class__ ]/var/www/html/venv/lib/python3.8/site-packages/onnxruntime/transformers/shape_infer_helper.pyr	      s
    z%SymbolicShapeInferenceHelper.__init__   )dynamic_axis_mappingmax_runsc                 C   s   |dk	st | jr"| j|kr"| jS || _| | j d}| jrttd|  | 	 | _|d7 }|dkr8||kr8qtq8d| _| jS )a  Run shape inference, and try replace dynamic axis from string to integer when mapping is provided.

        Args:
            dynamic_axis_mapping (_type_): a dictionary with name of dynamic axis as key, like {"batch_size" : 4}
            max_runs (int, optional): limit maximum number of runs to avoid infinite loop. Defaults to 200.

        Returns:
            bool: whether all shapes has been inferred or not.
        Nr   zshape infer run    T)
AssertionErrorr   r   r   Z_preprocessr
   Zrun_loggerdebugZ_infer_impl)r   r   r   countr   r   r   infer   s    

z"SymbolicShapeInferenceHelper.inferc                 C   s   g }|  ||}|r|D ]r}t|trt|| jkrB|| j|  q|| jkr^|| j|  q|tj|dd q|dk	st|| q|S )zQOverride it to ensure shape inference by giving the actual value of dynamic axis.T)integerN)	Z
_get_shape
isinstancestrr   appendZsymbolic_dims_r   Symbolr   )r   nodeidxZsympy_shapeshapedimr   r   r   _get_sympy_shape=   s    


z-SymbolicShapeInferenceHelper._get_sympy_shapec                 C   s|   | j s
t|| jkr(tdt|  dS | j| j}t|}|dk	rxt|D ]*\}}t|trL|| j	krL| j	| ||< qL|S )zGet shape of an edge.

        Args:
            edge (str): name of edge

        Returns:
            Optional[List[int]]: the shape, or None if shape is unknown
        zCannot retrieve the shape of N)
r   r   Z	known_vi_printr    typer   	enumerater   r   )r   edgeZ
type_protor%   ir&   r   r   r   get_edge_shapeP   s    	

z+SymbolicShapeInferenceHelper.get_edge_shapec                 C   s>   | j s
t| |}| |}|dks.|dkr6td||kS )a*  Compare shape of two edges.

        Args:
            edge (str): name of edge
            edge_other (str): name of another edge

        Raises:
            Exception: At least one shape is missed for edges to compare

        Returns:
            bool: whether the shape is same or not
        Nz1At least one shape is missed for edges to compare)r   r   r-   	Exception)r   r+   Z
edge_otherr%   Zshape_otherr   r   r   compare_shapeh   s    


z*SymbolicShapeInferenceHelper.compare_shape)r   r   TF)r   )__name__
__module____qualname__r	   r   r    intr   r'   r-   r/   __classcell__r   r   r   r   r      s
   r   )loggingossystypingr   pathdirname__file__	file_pathexistsjoinr!   Zsymbolic_shape_inferr   r   r   	getLoggerr0   r   r   r   r   r   r   <module>   s   
