o
    Xi                     @  sz   d Z ddlmZ ddlmZmZ ddlmZmZ ddl	Z
ddl	mZ eeeee f  ZG dd dZG d	d
 d
eZdS )z,Convenience methods for constructing the IR.    )annotations)MappingSequence)AnyOptionalN)_conveniencec                   @  s   e Zd ZdZd6d7ddZd8d
dZed9ddZed:ddZed;ddZ		d6dddddddddd<d*d+Z
	d6dddddddddd,	d=d0d1Zd6d>d4d5ZdS )?Tapeuz  Tape class.

    A tape is a recorder that collects nodes and initializers that are created so
    that they can be used for creating a graph.

    Example::

        >>> import onnx_ir as ir

        >>> tape = ir.tape.Tape()
        >>> a = tape.initializer(ir.tensor([1.0, 2.0, 3.0], name="a"))
        >>> b: ir.Value = ir.val("b", dtype=ir.DataType.FLOAT, shape=(3,))
        >>> c: ir.Value = ir.val("c", dtype=ir.DataType.FLOAT, shape=(3,))
        >>> x = tape.op("Add", [a, b])
        >>> y = tape.op("Elu", [x, c], attributes={"alpha": 2.0})
        >>> y.shape = ir.Shape((3,))
        >>> y.dtype = ir.DataType.FLOAT
        >>> model = ir.Model(
        ...     ir.Graph(
        ...         inputs=[b, c],
        ...         outputs=[y],
        ...         nodes=tape.nodes,
        ...         initializers=tape.initializers,
        ...         opset_imports={"": 20},
        ...         name="main_graph",
        ...     ),
        ...     ir_version=10,
        ... )
        >>> print(model)  # doctest: +NORMALIZE_WHITESPACE
        <
            ir_version=10,
            opset_imports={'': 20},
            producer_name=None,
            producer_version=None,
            domain=None,
            model_version=None,
        >
        graph(
            name=main_graph,
            inputs=(
                %"b"<FLOAT,[3]>,
                %"c"<FLOAT,[3]>
            ),
            outputs=(
                %"val_1"<FLOAT,[3]>
            ),
            initializers=(
                %"a"<FLOAT,[3]>{Tensor<FLOAT,[3]>(array([1., 2., 3.], dtype=float32), name='a')}
            ),
        ) {
            0 |  # node_Add_0
                 %"val_0"<?,?> ⬅️ ::Add(%"a"{[1.0, 2.0, 3.0]}, %"b")
            1 |  # node_Elu_1
                 %"val_1"<FLOAT,[3]> ⬅️ ::Elu(%"val_0", %"c") {alpha=2.0}
            return %"val_1"<FLOAT,[3]>
        }

    Attributes:
        graph_like: The graph to append the new nodes and initializers to. When
            it is None, the nodes and initializers are creating without owned by a graph.
            Initializers will not be added to functions because it is not supported by ONNX.
    N
graph_likeir.Graph | ir.Function | NonereturnNonec                 C  s   g | _ g | _t | _|| _d S N)_nodes_initializersset_used_opsetsr	   )selfr	    r   A/home/ubuntu/.local/lib/python3.10/site-packages/onnx_ir/_tape.py__init__T   s   
zTape.__init__strc                 C  s   d| j  d| j dS )NzTape(nodes=z, initializers=))r   r   r   r   r   r   __repr__Z   s   zTape.__repr__Sequence[ir.Node]c                 C  
   t | jS r   )tupler   r   r   r   r   nodes]      
z
Tape.nodesSequence[ir.Value]c                 C  r   r   )r   r   r   r   r   r   initializersa   r   zTape.initializers
UsedOpsetsc                 C  s   | j S r   )r   r   r   r   r   used_opsetse   s   zTape.used_opsets )domainoverloadversiongraphname
doc_stringmetadata_propsoutputop_typeinputsSequence[ir.Value | None]
attributes4Mapping[str, _convenience.SupportedAttrTypes] | Noner$   r%   r&   
int | Noner'   ir.Graph | Noner(   
str | Noner)   r*   dict[str, str] | Noner+   ir.Value | Noneir.Valuec             
   C  s   |d u rd}nt |}|d u rtdd}nt|gd}tj|||fd|i||||p-| j||	|
d}| j| | j	||f |j
d S )Nr      num_outputsoutputsr/   r%   r&   r'   r(   r)   r*   r   )r   convert_attributesdictirNoder	   r   appendr   addr;   )r   r,   r-   r/   r$   r%   r&   r'   r(   r)   r*   r+   attrsoutput_kwargsnoder   r   r   opi   s2   


zTape.op)	r9   r;   r$   r%   r&   r'   r(   r)   r*   r9   r;   Sequence[ir.Value] | Nonec       	      
   C  s   |d u r|d u rt d|d ur|d urt d|d u r"t|d}nt|d}|d u r.d}nt|}tj|||fd|i||||	pD| j|
||d}| j| | j	
||f |jS )Nz/Either num_outputs or outputs must be provided.z?Both num_outputs and outputs cannot be provided simultaneously.r8   r:   r   r/   r<   )
ValueErrorr>   r   r=   r?   r@   r	   r   rA   r   rB   r;   )r   r,   r-   r/   r9   r;   r$   r%   r&   r'   r(   r)   r*   rD   rC   rE   r   r   r   op_multi_out   s:   


zTape.op_multi_outtensorir.TensorProtocolc                 C  sv   |p|j }|d u rtdtdd |jjD }tj||t|j|d}| j	
| t| jtjr9| j| |S )Nz&Name must be provided for initializer.c                 s  s$    | ]}t |tr|n|jV  qd S r   )
isinstanceintvalue).0dr   r   r   	<genexpr>   s   " z#Tape.initializer.<locals>.<genexpr>)r(   shapetypeconst_value)r(   rH   r?   ShaperR   dimsValue
TensorTypedtyper   rA   rL   r	   Graphregister_initializer)r   rJ   r(   rR   rN   r   r   r   initializer   s   
zTape.initializerr   )r	   r
   r   r   )r   r   )r   r   )r   r   )r   r!   )r,   r   r-   r.   r/   r0   r$   r   r%   r   r&   r1   r'   r2   r(   r3   r)   r3   r*   r4   r+   r5   r   r6   )r,   r   r-   r.   r/   r0   r9   r1   r;   rG   r$   r   r%   r   r&   r1   r'   r2   r(   r3   r)   r3   r*   r4   r   r   )rJ   rK   r(   r3   r   r6   )__name__
__module____qualname____doc__r   r   propertyr   r    r"   rF   rI   r\   r   r   r   r   r      sD    ?
./r   c                      s,   e Zd ZdZdddZd fddZ  ZS )BuilderzUAn extension of the tape that provides a more convenient API for constructing the IR.r,   r   r   r   c                   s    fddS )Nc                    s     | |S r   )
_make_node)argskwargsr,   r   r   r   <lambda>   s    z%Builder.__getattr__.<locals>.<lambda>r   )r   r,   r   rf   r   __getattr__   s   zBuilder.__getattr__r-   r   re   dict[str, Any]c                   s   | dd}| dd }| dd}t|trt|}n	t|ts#J |}|dkr@t j|||||d}t|tr>|d |_|S t j||||||d}	t|tr^t	|	|D ]\}}
|
|_qV|	S )	N_domainr#   _version_outputsr7   )r-   r/   r$   r&   r   )r-   r/   r$   r&   r9   )
poprL   r   lenrM   superrF   r(   rI   zip)r   r,   r-   re   r$   r&   r;   r9   rN   valuesr(   	__class__r   r   rc      s4   





zBuilder._make_node)r,   r   r   r   )r,   r   r-   r   re   ri   )r]   r^   r_   r`   rh   rc   __classcell__r   r   rr   r   rb      s    
rb   )r`   
__future__r   collections.abcr   r   typingr   r   onnx_irr?   r   r   r   r   rM   r!   r   rb   r   r   r   r   <module>   s    =