o
    0h17                     @  s,  d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	 ddl
Z
ddl
mZ ddlmZ ddlmZ ed	Zd
dhZejG dd dZddddNddZdddOdd ZdPd!d"Z	#dQdRd0d1Zd2d3 ZdSd6d7ZdTd<d=ZdUd>d?ZdVdAdBZdWdEdFZdXdHdIZdXdJdKZ dXdLdMZ!dS )YzFUtilities for manipulating the torch.Graph object and the torchscript.    )annotationsN)IterableSequence)Any)_C)GLOBALS)registrationz^(.+)_(([ifstgz])|(ty))$inplaceatenc                   @  s   e Zd ZU dZded< ded< ded< ded	< d
ed< ded< ded< ejedZded< d*ddZ	ddd+dd Z
d!d"d,d%d&ZeZddd-d'd(Zd)S ).GraphContexta  Extra context for symbolic functions with all methods from torch.Graph.

    NOTE: This class is not meant for external consumption. Please do not depend on
    it outside of torch.onnx as the interface may evolve.

    Attributes:
        graph: The _C.Graph being constructed.
        block: The current _C.Block being constructed.
        opset: The opset version.
        original_node: Current node that is being converted from.
        params_dict: Mapping from graph initializer name to IValue.
        env: Mapping from Torch domain graph Value to ONNX domain graph Value.
        values_in_env: Set of all values in env, for constant-time lookups.
        new_nodes: List that tracks all new nodes that are added (used to make
            sure metadata is propagated to all new nodes).
    z_C.Graphgraphz_C.Blockblockintopset_C.Nodeoriginal_nodezdict[str, _C.IValue]params_dictzdict[_C.Value, _C.Value]envzset[_C.Value]values_in_env)default_factoryzlist[_C.Node]	new_nodesnamestrreturnr   c                 C  s   t | j|S N)getattrr   )selfr    r   R/var/www/vscode/kcb/lib/python3.10/site-packages/torch/onnx/_internal/jit_utils.py__getattr__7   s   zGraphContext.__getattr__   outputsopnameraw_argstorch.Tensor | _C.Valuer"   c                O  s   t | |g|R d|i|S )a  Creates an ONNX operator "opname", taking "raw_args" as inputs and "kwargs" as attributes.

        The set of operators and the inputs/attributes they take
        is documented at https://github.com/onnx/onnx/blob/master/docs/Operators.md

        Args:
            opname: The ONNX operator name, e.g., `Abs` or `Add`, or an operator qualified
                with a namespace, e.g., `aten::add`.
            raw_args: The inputs to the operator; usually provided
                as arguments to the `symbolic` definition.
            outputs: The number of outputs this operator returns.
                By default an operator is assumed to return a single output.
                If `outputs` is greater than one, this functions returns a tuple
                of output `Value`, representing each output of the ONNX operator
                in order.
            kwargs: The attributes of the ONNX operator, whose keys are named
                according to the following convention: `alpha_f` indicates
                the `alpha` attribute with type `f`.  The valid type specifiers are
                `f` (float), `i` (int), `s` (string) or `t` (Tensor).  An attribute
                specified with type float accepts either a single float, or a
                list of floats (e.g., you would say `dims_i` for a `dims` attribute
                that takes a list of integers).

        Returns:
            The value representing the single output of this operator (see the `outputs`
            keyword argument for multi-return nodes).
        r"   )_add_op)r   r#   r"   r$   kwargsr   r   r   op:   s   #zGraphContext.op )overload_nameoperatorr*   c                O  s   | j dg|R ||d|S )z~Generates an ONNX ATen op node.

        This function is for backward compatibility with the old symbolic functions.
        z
aten::ATen)
operator_soverload_name_s)r(   )r   r+   r*   argsr'   r   r   r   aten_op_   s   zGraphContext.aten_opc                O  sH   |j j d|j }|j j}t||| t| |g|R d|i|S )a  Creates an ONNX operator from onnx-script function, taking "raw_args" as inputs and "kwargs" as attributes.

        onnx-script repository: https://github.com/microsoft/onnx-script

        Args:
            onnx_fn: ONNXFunction from onnx-script; An example can be found at
                https://github.com/microsoft/onnx-script#example
            raw_args: The inputs to the operator; usually provided
                as arguments to the `symbolic` definition.
            outputs: The number of outputs this operator returns.
                By default an operator is assumed to return a single output.
                If `outputs` is greater than one, this functions returns a tuple
                of output `Value`, representing each output of the ONNX operator
                in order.
            kwargs: The attributes of the ONNX operator, whose keys are named
                according to the following convention: `alpha_f` indicates
                the `alpha` attribute with type `f`.  The valid type specifiers are
                `f` (float), `i` (int), `s` (string) or `t` (Tensor).  An attribute
                specified with type float accepts either a single float, or a
                list of floats (e.g., you would say `dims_i` for a `dims` attribute
                that takes a list of integers).

        Returns:
            The value representing the single output of this operator (see the `outputs`
            keyword argument for multi-return nodes).
        ::r"   )r   domainr   versionr   custom_onnx_symbolicr&   )r   onnx_fnr"   r$   r'   symbolic_nameopset_versionr   r   r   onnxscript_opp   s   #zGraphContext.onnxscript_opN)r   r   r   r   )r#   r   r$   r%   r"   r   )r+   r   r*   r   )r$   r%   r"   r   )__name__
__module____qualname____doc____annotations__dataclassesfieldlistr   r   r(   r/   atr7   r   r   r   r   r      s"   
 
%r   r    )r"   n_blocksgraph_contextr#   r   inputs_C.Valuer"   r   rA   r   -tuple[Any, tuple[GraphContext, ...], _C.Node]c                O  s|   | j |g|R d|i|}t|tr|d  }n| }g }t|D ]}	| }
tj| |
d}|| q$|t	||fS )aP  Creates an ONNX operator "opname", taking inputs and attributes.

    Args:
        graph_context: The context for the current graph.
        opname: The ONNX operator name, e.g., `Abs` or `Add`, or an operator qualified
            with a namespace, e.g., `aten::add`.
        inputs: The inputs to the operator.
        outputs: The number of outputs this operator returns.
            By default an operator is assumed to return a single output.
            If `outputs` is greater than one, this functions returns a tuple
            of output `Value`, representing each output of the ONNX operator
            in order.
        n_blocks: The number of sub-blocks to create in the node.
        attributes: The attributes of the ONNX operator.

    Returns:
        A tuple of (output_values, new_contexts, node) where:
            output_values: One or more output value of this operator
                (see the `outputs` keyword argument for multi-return nodes).
            new_contexts: A tuple of new graph contexts for each sub-block.
            node: The node representing the operator.
    r"   r   )r   )
r(   
isinstancer   noderangeaddBlockr=   replaceappendtuple)rB   r#   r"   rA   rC   
attributesoutput_valuesrG   new_contexts_	new_blocknew_contextr   r   r   add_op_with_blocks   s   
rS   r!   r.   r%   c             
     s|    fdd|D }dd |  D }d|vrd| }t j||| j j|tjd} j| |dkr8|	 S t
| S )	a@  Creates an ONNX operator "opname", taking "args" as inputs and attributes "kwargs".

    The set of operators and the inputs/attributes they take
    is documented at https://github.com/onnx/onnx/blob/master/docs/Operators.md

    This function is monkey-patched onto Graph.

    Args:
        graph_context: The Torch Graph or Block.
        opname: The ONNX operator name, e.g., `Abs` or `Add`, or an operator qualified
            with a namespace, e.g., `aten::add`.
        args: The inputs to the operator; usually provided
            as arguments to the `symbolic` definition.
        outputs: The number of outputs this operator returns.
            By default an operator is assumed to return a single output.
            If `outputs` is greater than one, this functions returns a tuple
            of output `Value`, representing each output of the ONNX operator
            in order.
        kwargs: The attributes of the ONNX operator, whose keys are named
            according to the following convention: `alpha_f` indicates
            the `alpha` attribute with type `f`.  The valid type specifiers are
            `f` (float), `i` (int), `s` (string) or `t` (Tensor).  An attribute
            specified with type float accepts either a single float, or a
            list of floats (e.g., you would say `dims_i` for a `dims` attribute
            that takes a list of integers).

    Returns:
        (Union[_C.Value, Tuple[_C.Value, ...]])
        The value representing the single output of this operator (see the `outputs`
        keyword argument for multi-return nodes).
    c                   s   g | ]}t  |qS r   )_const_if_tensor).0argrB   r   r   
<listcomp>   s    z_add_op.<locals>.<listcomp>c                 S  s   i | ]\}}|d ur||qS r   r   )rU   kvr   r   r   
<dictcomp>   s    z_add_op.<locals>.<dictcomp>r0   zonnx::)r   r6   	n_outputsshape_inferencer    )items_create_noder   r   r   r   onnx_shape_inferencer   rK   outputrL   r"   )rB   r#   r"   r.   r'   rC   rM   rG   r   rW   r   r&      s$   &
r&   c                 C  s*   |d u r|S t |tjr|S t| d|dS )Nzonnx::Constant)value_z)rF   r   Valuer&   )rB   rV   r   r   r   rT   	  s
   rT   Tgraph_or_block_C.Graph | _C.Block	domain_opr   rM   dictr   r6   r\   r]   boolr   c                 C  s   t | tjr| }||||}	||	}	nt | tjr3| }
|
||}	|dkr3td|D ]}|	  q,t	|	
 }t||ksAJ |d}t| D ]\}}|tv rUqLt|	|||d qL|rgt|	|| |	S )z:Creates an node 'domain_op', taking inputs and attributes.r    zaten::)r
   )rF   r   Graphcreate
insertNodeBlockaddNoderH   	addOutputrL   r"   len
startswithsortedr^   _SKIP_NODE_ATTRIBUTES_add_attribute(_jit_pass_onnx_node_shape_type_inference)rd   rf   rC   rM   r   r6   r\   r]   r   rG   r   rP   node_outputsr
   keyvaluer   r   r   r_     s(   

r_   c                 C  s   t | tot | tttjf S r   )rF   r   r   bytestorchTensor)rw   r   r   r   _is_onnx_list9  s   r{   xtorch.Tensorc                 C  s   |   dksJ | d S )z,Convert a scalar tensor into a Python value.r    r   )numelr|   r   r   r   _scalar?  s   r   rG   rv   rw   r   c                 C  s^   t |}|du rtd| d|d|d}}t|r$|d7 }t| | d||S )z7Initializes the right attribute based on type of value.NzInvalid attribute specifier 'z<' names must be suffixed with type, e.g. 'dim_i' or 'dims_i'r       srP   )_ATTR_PATTERNmatch
ValueErrorgroupr{   r   )rG   rv   rw   r
   mr   kindr   r   r   rs   E  s   

rs   c                 C  s   |   tj S r   )typeisSubtypeOfr   
TensorTypegetr   r   r   r   
_is_tensorU  s   r   torch.device | Nonec                 C  s&   t | sd S ttj|  }| S r   )r   typingcastr   r   r   device)rw   tensor_typer   r   r   get_device_from_valueY  s   r   r   tuple[str, str]c                 C  sH   d| vrt d|  d| dd\}}d|v r t d|  d||fS )z(Parse node kind into domain and Op name.r0   zNode kind: z& is invalid. '::' is not in node kind.r    z) is invalid. '::' should only apear once.)r   split)r   r1   r#   r   r   r   parse_node_kind`  s   r   r1   c                 C     | dkS ) Check if the domain is official.r
   r   r1   r   r   r   is_atenj     r   c                 C  r   )r   primr   r   r   r   r   is_primo  r   r   c                 C  r   )r   onnxr   r   r   r   r   is_onnxt  r   r   )rB   r   r#   r   rC   rD   r"   r   rA   r   r   rE   )rB   r   r#   r   r.   r%   r"   r   )rB   r   )T)rd   re   rf   r   rC   r   rM   rg   r   rg   r6   r   r\   r   r]   rh   r   r   )r|   r}   )rG   r   rv   r   rw   r   r
   rh   )r|   rD   r   rh   )rw   rD   r   r   )r   r   r   r   )r1   r   r   rh   )"r;   
__future__r   r=   rer   collections.abcr   r   r   ry   r   torch.onnx._globalsr   torch.onnx._internalr   compiler   rr   	dataclassr   rS   r&   rT   r_   r{   r   rs   r   r   r   r   r   r   r   r   r   r   <module>   sB   
 3
?'







