o
    Xi!                     @  s   d dl mZ d dlZd dlmZmZ d dlZd dlm	Z	m
Z
 d=d	d
Zd>d?ddZd@ddZdAddZdBdCd!d"Zddd#dDd(d)ZdEd+d,ZdFd-d.ZdGd1d2ZdHd6d7ZdId;d<ZdS )J    )annotationsN)CallableSequence)ir	optimizernodesSequence[ir.Node]returnNonec                 C  sJ   | r!| d j }|r|D ]
}|| v r|  qdS | D ]}|  qdS dS )z>Display a list of nodes in the order they appear in the graph.r   N)graphdisplay)r   r   node r   Q/home/ubuntu/.local/lib/python3.10/site-packages/onnxscript/rewriter/_ir_utils.pydisplay_nodes   s   

	r   T   xir.Value | ir.Nodebackwardbooldepth_limitintc                   sb   g d fddt | tjr| d nt | tjr+|  dur+|  d t dS )z[Display the (backward or forward) subgraph from a given value or node upto a certain depth.r   ir.Nodec                   s   | v rd S  |  |k rB r,| jD ]}|d ur)| d ur)| |d  qd S | jD ]}| D ]\}}||d  q5q/d S d S )N   )appendinputsproduceroutputsuses)r   depthinpoutconsumer_r   r   slicevisitr   r   r&       s    


zdisplay_slice.<locals>.visitr   N)r   r   )
isinstancer   NodeValuer   r   )r   r   r   r   r$   r   display_slice   s   r*   valueir.Valueir.TensorProtocol | Nonec                 C  s"   |   }|d urt|g | jS N)r   r   basic_constant_propagationconst_value)r+   r   r   r   r   get_const_value5   s   r1   valir.Value | Nonenp.ndarray | Nonec                 C  s@   | du rdS t | }|durz| W S  ty   Y dS w dS )a  Convenience wrapper to get (optional) numpy value from an optional IR Value.

    This is intended for use in optimizations/rewriting. Note that this does not
    yet handle the distinction between inputs with default values (values that are
    both graph inputs and graph initializers), which should not be treated as a
    constant, and true constant values. The caller should make the distinction, as
    a value does not contain enough information to determine this. (TODO)
    N)r1   numpyFileNotFoundError)r2   r0   r   r   r   get_numpy_value<   s   	
r7   rankint | Sequence[int] | Nonec                 C  s^   t | }|dur-|jdkr-| }|du st|tr!|j|kr!|S t|tr-|j|v r-|S dS )a  Returns element of a single element tensor constant value, and None otherwise.

    If an int rank is specified, it checks that the value has the given rank.
    If the rank is a sequence of ints, it checks that the value has one of the given ranks.

    Thus, `rank=0` checks for a scalar, `rank=1` checks for a 1D tensor, and
    `rank=(0,1)` checks for either a scalar or a 1D tensor.
    Nr   )r7   sizeitemr'   r   ndimr   )r2   r8   np_valr+   r   r   r   get_singleton_valueQ   s   	r>   )rtolr8   expectedfloat | int | Callabler?   float | Nonec                C  sV   t | |d}|du rdS t|r||S t|tr||kS |dus#J tj|||dS )z[Returns True if the value is a single element tensor with given value, and False otherwise.)r8   NF)rel_tol)r>   callabler'   r   mathisclose)r2   r@   r?   r8   scalarr   r   r   is_singleton_valued   s   
rH   	list[int]c                 C  sd   | du rdS t | jtjsdS t| }|du rdS |jt|ks(| jjtjj	kr*dS |
 }||kS )zUReturns True if the value is a 1d int64 tensor with given value, and False otherwise.NF)r'   typer   TypeProtocolr7   r:   lendtypeDataTypeINT64tolist)r2   r@   r=   valuesr   r   r   is_1d_valuex   s   rR   c                 C  s&   | du rdS | j }|duo| |kS )zZReturns True if the value is statically known to have the given rank, and False otherwise.NFshaper8   )r+   r8   rT   r   r   r   has_rank   s   rU   dimir.SymbolicDim | int | Nonec                 C  sR   | du rdS | j }|du rdS |dk r|| 7 }|dk s#|| kr%dS || S )zPReturns the value of the given dimension, or None if it is not statically known.Nr   rS   )r+   rV   rT   r   r   r   get_dim   s   rX   shape1ir.Shape | Noneshape2c                 C  s0   | du s|du r
dS |   s|  rdS | |kS )z.Check if two shapes are semantically the same.NF)has_unknown_dim)rY   r[   r   r   r   
same_shape   s
   r]   dim1ir.SymbolicDim | intdim2c                 C  sp   t | t |ur
dS t| trt|tr| |kS t| tjr$t|tjs&J | jdu s0|jdu r2dS | j|jkS )z2Check if two dimensions are semantically the same.FN)rJ   r'   r   r   SymbolicDimr+   )r^   r`   r   r   r   same_dim   s   rb   )r   r   r	   r
   )Tr   )r   r   r   r   r   r   r	   r
   )r+   r,   r	   r-   )r2   r3   r	   r4   r.   )r2   r3   r8   r9   )
r2   r3   r@   rA   r?   rB   r8   r9   r	   r   )r2   r3   r@   rI   r	   r   )r+   r3   r8   r   r	   r   )r+   r3   rV   r   r	   rW   )rY   rZ   r[   rZ   r	   r   )r^   r_   r`   r_   r	   r   )
__future__r   rE   typingr   r   r5   np
onnxscriptr   r   r   r*   r1   r7   r>   rH   rR   rU   rX   r]   rb   r   r   r   r   <module>   s$   






