
    sg7                       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mZ ddl	Z	ddl	m
Z
 ddlmZ ddlmZ  ej                  d      Zd	d
hZej$                   G d d             Zddd	 	 	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZddZ	 d 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!dZd Zd"dZd#dZd$dZd%dZd&dZd'dZd'dZd'dZ y)(zFUtilities for manipulating the torch.Graph object and the torchscript.    )annotationsN)AnyIterableSequence)_C)GLOBALS)registrationz^(.+)_(([ifstgz])|(ty))$inplaceatenc                      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      Zded<   ddZ	dd	 	 	 	 	 ddZ
ddddZeZdd	 	 	 ddZy) 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_nodesc                .    t        | j                  |      S N)getattrr   )selfnames     Q/var/www/html/venv/lib/python3.12/site-packages/torch/onnx/_internal/jit_utils.py__getattr__zGraphContext.__getattr__6   s    tzz4((       outputsc               &    t        | |g|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   opnamer#   raw_argskwargss        r   opzGraphContext.op9   s!    F tVJhJJ6JJr     )overload_namec               4     | j                   dg|||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   operatorr+   argsr(   s        r   aten_opzGraphContext.aten_op^   s9    
 tww

  )	

 
 	
r    c                   |j                   j                   d|j                   }|j                   j                  } t	        j
                  ||      |       t        | |g|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_versions          r   onnxscript_opzGraphContext.onnxscript_opo   sf    F #==//07<<.A--G))-GPt]QXQwQ&QQr    N)r   strreturnr   )r&   r;   r'   torch.Tensor | _C.Valuer#   r   )r/   r;   r+   r;   )r'   r=   r#   r   )__name__
__module____qualname____doc____annotations__dataclassesfieldlistr   r   r)   r1   atr:    r    r   r   r      s    " OOJ%%	!!  0{00FI}F) 	#K#K +#K 	#KJ BD 
 
B 	(R +(R 	(Rr    r   r!   )r#   n_blocksc               J    | j                   |g|d|i|}t        |t              r|d   j                         }n|j                         }g }t	        |      D ]:  }	|j                         }
t        j                  | |
      }|j                  |       < |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addBlockrC   replaceappendtuple)graph_contextr&   r#   rH   inputs
attributesoutput_valuesrK   new_contexts_	new_blocknew_contexts               r   add_op_with_blocksrY      s    > %M$$VTfTgTTM-*Q$$&!!#L8_ )MMO	!))-yIK(	) %-t33r    r"   c          
        |D cg c]  }t        | |       }}|j                         D ci c]  \  }}|	|| }	}}d|vrd|z   }t        | j                  |||	| j                  | j
                  |t        j                        }
| j                  j                  |
       |dk(  r|
j                         S t        |
j                               S c c}w c c}}w )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).
    r3   zonnx::)r   r9   	n_outputsshape_inferencer!   )_const_if_tensoritems_create_noder   r   r   r   onnx_shape_inferencer   rO   outputrP   r#   )rQ   r&   r#   r0   r(   argrR   kvrS   rK   s              r   r%   r%      s    L ?CCs}c2CFC $*<<>C41aQ]!Q$CJC6F"!--#))44	D ""4(!|{{}  - D Ds   C
CCc                ^    ||S t        |t        j                        r|S t        | d|      S )Nzonnx::Constant)value_z)rJ   r   Valuer%   )rQ   rb   s     r   r]   r]     s/    
{
#rxx 
="2C@@r    c                H   t        | t        j                        r'| }|j                  |||      }	|j	                  |	      }	nTt        | t        j
                        r:| }
|
j                  ||      }	|dkD  r!t        d|      D ]  }|	j                           t        	j                               }t        |      |k(  sJ |j                  d      }t        |j                               D ]  \  }}|t        v rt!        |	|||        |rt        j"                  |	||       |	S )z:Creates an node 'domain_op', taking inputs and attributes.r!   zaten::)r   )rJ   r   Graphcreate
insertNodeBlockaddNoderL   	addOutputrP   r#   len
startswithsortedr^   _SKIP_NODE_ATTRIBUTES_add_attribute(_jit_pass_onnx_node_shape_type_inference)graph_or_block	domain_oprR   rS   r   r9   r[   r\   r   rK   r   rV   node_outputsr   keyvalues                   r   r_   r_     s    ."((+||Ivy9%	NBHH	-}}Y/ q=1i( ! ! (L|	))))D Z--/0 4
U''tS%d34 
33D+}UKr    c                r    t        | t              xr& t        | t        t        t        j
                  f       S r   )rJ   r   r;   bytestorchTensor)ry   s    r   _is_onnx_listr~   8  s2    eX& zUELL)0 , r    c                6    | j                         dk(  sJ | d   S )z,Convert a scalar tensor into a Python value.r!   r   )numelxs    r   _scalarr   >  s    779>>Q4Kr    c                    t         j                  |      }|t        d| d      |j                  d      |j                  d      }}t	        |      r|dz  } t        | | d      ||      S )z7Initializes the right attribute based on type of value.zInvalid attribute specifier 'z<' names must be suffixed with type, e.g. 'dim_i' or 'dims_i'r!      srV   )_ATTR_PATTERNmatch
ValueErrorgroupr~   r   )rK   rx   ry   r   mr   kinds          r   rs   rs   D  s    C Ay+C5 1C C
 	
 QWWQZ$DU$74D6$T511r    c                x    | j                         j                  t        j                  j	                               S r   )typeisSubtypeOfr   
TensorTypegetr   s    r   
_is_tensorr   T  s&    668 1 1 344r    c                    t        |       sy t        j                  t        j                  | j                               }|j                         S r   )r   typingcastr   r   r   device)ry   tensor_types     r   get_device_from_valuer   X  s6    e++bmmUZZ\:Kr    c                    d| vrt        d|  d      | j                  dd      \  }}d|v rt        d|  d      ||fS )z(Parse node kind into domain and Op name.r3   zNode kind: z& is invalid. '::' is not in node kind.r!   z) is invalid. '::' should only apear once.)r   split)r   r4   r&   s      r   parse_node_kindr   _  sY    4;tf,RSTTZZa(NFFv~;tf,UVWW6>r    c                    | dk(  S ) Check if the domain is official.r   rG   r4   s    r   is_atenr   i      Vr    c                    | dk(  S )r   primrG   r   s    r   is_primr   n  r   r    c                    | dk(  S )r   onnxrG   r   s    r   is_onnxr   s  r   r    )rQ   r   r&   r;   rR   _C.Valuer#   r   rH   r   r<   z-tuple[Any, tuple[GraphContext, ...], _C.Node])rQ   r   r&   r;   r0   r=   r#   r   )rQ   r   )T)ru   z_C.Graph | _C.Blockrv   r;   rR   r   rS   dictr   r   r9   r   r[   r   r\   boolr<   r   )r   ztorch.Tensor)rK   r   rx   r;   ry   r   r   r   )r   r   r<   r   )ry   r   r<   ztorch.device | None)r   r;   r<   ztuple[str, str])r4   r;   r<   r   )!rA   
__future__r   rC   rer   r   r   r   r|   r   torch.onnx._globalsr   torch.onnx._internalr	   compiler   rr   	dataclassr   rY   r%   r]   r_   r~   r   rs   r   r   r   r   r   r   rG   r    r   <module>r      su   L
 #  	  * *   ' - 

56"F+  ~R ~R ~RJ ,4,4,4 ,4 	,4
 ,4 3,4f 	<!<!<! #<! 	<!~A" !$'$$ $ 	$
 $ $ $ $ $N2 5 

r    