
    ¯wg3                      d Z ddlmZ ddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
mZmZmZmZ ddlZddlmc mZ ddlZddlZddlmZ ddlmZmZmZmZmZ ddlmZ ddlmZm Z m!Z!m"Z" g d	Z#dAd
Z$i Z%ejL                  dBd       Z'ejL                  dCd       Z(ejL                  dDd       Z)ejL                  dEd       Z*	 	 	 	 	 	 dFdZ+dddejX                  jZ                  ddej\                  j^                  dddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dGdZ0d Z1d Z2	 	 	 	 	 	 dH	 	 	 	 	 	 	 dIdZ3d Z4d Z5	 	 	 	 	 	 dJdZ6d Z7d Z8dKdZ9d Z:	 	 dL	 	 	 	 	 dMdZ;dNdZ<d  Z=d! Z>d" Z?	 	 	 	 	 	 dOd#Z@d$ ZAd% ZBej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  iZJdPd&ZKd' ZLdddej\                  j^                  dddejX                  jZ                  df		 dQd(ZMej                   ej                  d)d*d+      ddejX                  jZ                  ddej\                  j^                  ddddddddfd,              ZP ej                  d)d*d-      ejX                  jZ                  df	 	 	 	 	 dRd.       ZQ	 	 	 	 	 	 dSd/ZRd0 ZSd1 ZTddejX                  jZ                  ddej\                  j^                  dddddddddddf	 dTd2ZUd3 ZVd4 ZWd5 ZXdUd6ZYdVd7ZZdWd8Z[	 	 	 	 	 	 dXd9Z\dYd:Z]ej\                  j^                  f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dZd;Z^d[d<Z_	 	 	 	 	 	 d\d=Z`d]d>Zad? Zbd^d@Zcy)_zFunctions to export models into the ONNX IR format.

These models can be loaded with the ONNX library and then
converted to models which run on other deep learning frameworks.
    )annotationsN)AnyCallablecast
CollectionMappingSequence)_C)
_constants_deprecation_exporter_stateserrorssymbolic_helper)GLOBALS)diagnostics	jit_utilsonnx_proto_utilsregistration)is_in_onnx_exportselect_model_mode_for_exportdisable_apex_o2_state_dict_hooksetup_onnx_loggingexporter_contextexportmodel_signaturewarn_on_static_input_changeunpack_quantized_tensorexport_to_pretty_stringunconvertible_opsregister_custom_op_symbolicunregister_custom_op_symbolicc                 "    t         j                  S )z3Returns whether it is in the middle of ONNX export.)r   in_onnx_export     U/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/torch/onnx/utils.pyr   r   3   s    !!!r%   c              #    K   t        |t        j                        st        dt	        |       d      d}t        | d      r| j                  }|t        j                  j                  k(  s|t        j                  j                  k(  rH|rFdt        _
        t        j                  dk  r3t        j                  dt        j                   d       ndt        _
        |t        _        |t        j                  j                  k(  r| j                  d       n.|t        j                  j                   k(  r| j                  d       	 d	 t        | d      r0|t        j                  j                  k(  s| j                  |       y	y	y	# t        | d      r0|t        j                  j                  k(  s| j                  |       w w w xY ww)
a"  A context manager to temporarily set the training mode of ``model``
    to ``mode``, resetting it when we exit the with-block.

    Args:
        model: Same type and meaning as ``model`` arg to :func:`export`.
        mode: Same type and meaning as ``training`` arg to :func:`export`.
    z:'mode' should be a torch.onnx.TrainingMode enum, but got 'z'.FtrainingT   zEYou are exporting the model in training mode with onnx opset version zn. Opset versions lower than opset 12 will not be able to export nodes such as Dropout and BatchNorm correctly.N)
isinstance_C_onnxTrainingMode	TypeErrortypehasattrr(   TRAININGPRESERVEr   export_trainingexport_onnx_opset_versionwarningswarntraining_modetrainEVAL)modelmodeoriginally_trainings      r&   r   r   =   s     dG001HdTVW
 	
 !&uj!#nn 7''000G((1116I&*G#0025&@@A BEE ',G# $7''000KKW))...KK-5*%dg6J6J6S6S.SKK+, /T%75*%dg6J6J6S6S.SKK+, /T%s   EGF 
=G>GGc              #    K   t        | t        j                  j                        si }| j	                         D ]x  }|j
                  j                         D ]/  \  }}t        |      j                  dk(  s||vri ||<   |||   |<   1 ||v sT||   D ]  }|j
                  j                  |        z 	 d  |j                         D ],  \  }}|j                         D ]  \  }}||j
                  |<    . y 	 d  y # |j                         D ],  \  }}|j                         D ]  \  }}||j
                  |<    . w xY w# w xY ww)NO2StateDictHook)
r*   torchjitScriptFunctionmodules_state_dict_hooksitemsr.   __name__pop)r9   model_hooksmodulekeyhookm_maps         r&   r   r   m   sf     eUYY556mmo 	6F#55;;= 4	T:&&*;;[0.0F+/3K',	4
 $&v. 6C,,0056	6	9 "-!2!2!4 9!& 9IC48F,,S199	 "-!2!2!4 9!& 9IC48F,,S199 sD   A2E5E'E5C? 9A E:E >E?AE  EEEc              #  $  K   t         j                  j                         }|s| rt         j                  j                          	 d  |st         j                  j	                          y y # |st         j                  j	                          w w xY wwN)r>   onnxis_onnx_log_enabled
enable_logdisable_log)verboseis_originally_enableds     r&   r   r      sg     !JJ::<

%$JJ""$ %$JJ""$ %s   ABA* "B*#BBc           	   #  0  K   t        | |      5 }t        |       5 }t        |      5 }t        j                         5 }||||f d d d        d d d        d d d        d d d        y # 1 sw Y   "xY w# 1 sw Y   &xY w# 1 sw Y   *xY w# 1 sw Y   y xY wwrL   )r   r   r   r    create_export_diagnostic_context)r9   r:   rQ   mode_ctxapex_ctxlog_ctxdiagnostic_ctxs          r&   r   r      s     	%t
 <	2< 
%	< 
+>>@< ES7N;;< < < < < < < < < < < <sa   BB
A>A2	A&	A2A>B
	B&A/+A22A;7A>>B	B

BBc                L    |s| rt        | d   t              r
| d   }| dd } | |fS )zRObtain the arguments for torch.onnx.export from the model and the input arguments.N)r*   dict)argskwargss     r&   _get_torch_export_argsr^      s4    
 dz$r(D9bCRy<r%   TF)r]   export_paramsrQ   r(   input_namesoutput_namesoperator_export_typeopset_versiondo_constant_foldingdynamic_axeskeep_initializers_as_inputscustom_opsetsexport_modules_as_functionsautograd_inliningc               h   |	t         j                  j                  k7  rt        j                  dt
               |t         j                  j                  k(  rt        j                  dt
               t        |t        j                        r|fn|}|||fz   }t        | ||||||||	|
||||||       y)a5  Exports a model into ONNX format.

    If ``model`` is not a :class:`torch.jit.ScriptModule` nor a
    :class:`torch.jit.ScriptFunction`, this runs
    ``model`` once in order to convert it to a TorchScript graph to be exported
    (the equivalent of :func:`torch.jit.trace`). Thus this has the same limited support
    for dynamic control flow as :func:`torch.jit.trace`.

    Args:
        model: The model to be exported.
        args:

            args can be structured either as:

            1. ONLY A TUPLE OF ARGUMENTS::

                args = (x, y, z)

            The tuple should contain model inputs such that ``model(*args)`` is a valid
            invocation of the model. Any non-Tensor arguments will be hard-coded into the
            exported model; any Tensor arguments will become inputs of the exported model,
            in the order they occur in the tuple.

            2. A TENSOR::

                args = torch.Tensor([1])

            This is equivalent to a 1-ary tuple of that Tensor.

            3. A TUPLE OF ARGUMENTS ENDING WITH A DICTIONARY OF NAMED ARGUMENTS::

                args = (x, {"y": input_y, "z": input_z})

            All but the last element of the tuple will be passed as non-keyword arguments,
            and named arguments will be set from the last element. If a named argument is
            not present in the dictionary, it is assigned the default value, or None if a
            default value is not provided.

            .. warning::
                This behavior will be deprecated in a future release. Please use the
                kwargs argument instead.

            .. note::
                If a dictionary is the last element of the args tuple, it will be
                interpreted as containing named arguments. In order to pass a dict as the
                last non-keyword arg, provide an empty dict as the last element of the args
                tuple. For example, instead of::

                    torch.onnx.export(
                        model,
                        (
                            x,
                            # WRONG: will be interpreted as named arguments
                            {y: z},
                        ),
                        "test.onnx.pb",
                    )

                Write::

                    torch.onnx.export(model, (x, {y: z}, {}), "test.onnx.pb")

        f: Path to the output ONNX model file. E.g. "model.onnx".
        kwargs: Named arguments to the model.
        export_params: If True, all parameters will
            be exported. Set this to False if you want to export an untrained model.
            In this case, the exported model will first take all of its parameters
            as arguments, with the ordering as specified by ``model.state_dict().values()``
        verbose: if True, prints a description of the
            model being exported to stdout. In addition, the final ONNX graph will include the
            field ``doc_string``` from the exported model which mentions the source code locations
            for ``model``. If True, ONNX exporter logging will be turned on.
        training:
            * ``TrainingMode.EVAL``: export the model in inference mode.
            * ``TrainingMode.PRESERVE``: export the model in inference mode if model.training is
                False and in training mode if model.training is True.
            * ``TrainingMode.TRAINING``: export the model in training mode. Disables optimizations
                which might interfere with training.
        input_names (list of str, default empty list): names to assign to the
            input nodes of the graph, in order.
        output_names (list of str, default empty list): names to assign to the
            output nodes of the graph, in order.
        operator_export_type (enum, default OperatorExportTypes.ONNX):

            .. warning::
                This option will be deprecated in a future release. Future exported
                graphs will always use the default opset domain.

            * ``OperatorExportTypes.ONNX``: Export all ops as regular ONNX ops
                (in the default opset domain).
            * ``OperatorExportTypes.ONNX_FALLTHROUGH``: Try to convert all ops
                to standard ONNX ops in the default opset domain. If unable to do so
                (e.g. because support has not been added to convert a particular torch op to ONNX),
                fall back to exporting the op into a custom opset domain without conversion. Applies
                to `custom ops <https://pytorch.org/tutorials/advanced/torch_script_custom_ops.html>`_
                as well as ATen ops. For the exported model to be usable, the runtime must support
                these non-standard ops.
            * ``OperatorExportTypes.ONNX_ATEN``: All ATen ops (in the TorchScript namespace "aten")
                are exported as ATen ops (in opset domain "org.pytorch.aten").
                `ATen <https://pytorch.org/cppdocs/#aten>`_ is PyTorch's built-in tensor library, so
                this instructs the runtime to use PyTorch's implementation of these ops.

                .. warning::

                    Models exported this way are probably runnable only by Caffe2.

                    This may be useful if the numeric differences in implementations of operators are
                    causing large differences in behavior between PyTorch and Caffe2 (which is more
                    common on untrained models).

            * ``OperatorExportTypes.ONNX_ATEN_FALLBACK``: Try to export each ATen op
                (in the TorchScript namespace "aten") as a regular ONNX op. If we are unable to do so
                (e.g. because support has not been added to convert a particular torch op to ONNX),
                fall back to exporting an ATen op. See documentation on OperatorExportTypes.ONNX_ATEN for
                context.
                For example::

                    graph(%0 : Float):
                    %3 : int = prim::Constant[value=0]()
                    # conversion unsupported
                    %4 : Float = aten::triu(%0, %3)
                    # conversion supported
                    %5 : Float = aten::mul(%4, %0)
                    return (%5)

                Assuming ``aten::triu`` is not supported in ONNX, this will be exported as::

                    graph(%0 : Float):
                    %1 : Long() = onnx::Constant[value={0}]()
                    # not converted
                    %2 : Float = aten::ATen[operator="triu"](%0, %1)
                    # converted
                    %3 : Float = onnx::Mul(%2, %0)
                    return (%3)

                .. warning::

                    Models exported this way are probably runnable only by Caffe2.

        opset_version (int, default 17): The version of the
            `default (ai.onnx) opset <https://github.com/onnx/onnx/blob/master/docs/Operators.md>`_
            to target. Must be >= 7 and <= 17.
        do_constant_folding: Apply the constant-folding optimization.
            Constant-folding will replace some of the ops that have all constant inputs
            with pre-computed constant nodes.
        dynamic_axes:

            By default the exported model will have the shapes of all input and output tensors
            set to exactly match those given in ``args``. To specify axes of tensors as
            dynamic (i.e. known only at run-time), set ``dynamic_axes`` to a dict with schema:

            * KEY (str): an input or output name. Each name must also be provided in ``input_names`` or
                ``output_names``.
            * VALUE (dict or list): If a dict, keys are axis indices and values are axis names. If a
                list, each element is an axis index.

            For example::

                class SumModule(torch.nn.Module):
                    def forward(self, x):
                        return torch.sum(x, dim=1)


                torch.onnx.export(
                    SumModule(),
                    (torch.ones(2, 2),),
                    "onnx.pb",
                    input_names=["x"],
                    output_names=["sum"],
                )

            Produces::

                input {
                  name: "x"
                  ...
                      shape {
                        dim {
                          dim_value: 2  # axis 0
                        }
                        dim {
                          dim_value: 2  # axis 1
                ...
                output {
                  name: "sum"
                  ...
                      shape {
                        dim {
                          dim_value: 2  # axis 0
                ...

            While::

                torch.onnx.export(
                    SumModule(),
                    (torch.ones(2, 2),),
                    "onnx.pb",
                    input_names=["x"],
                    output_names=["sum"],
                    dynamic_axes={
                        # dict value: manually named axes
                        "x": {0: "my_custom_axis_name"},
                        # list value: automatic names
                        "sum": [0],
                    },
                )

            Produces::

                input {
                  name: "x"
                  ...
                      shape {
                        dim {
                          dim_param: "my_custom_axis_name"  # axis 0
                        }
                        dim {
                          dim_value: 2  # axis 1
                ...
                output {
                  name: "sum"
                  ...
                      shape {
                        dim {
                          dim_param: "sum_dynamic_axes_1"  # axis 0
                ...

        keep_initializers_as_inputs: If True, all the
            initializers (typically corresponding to parameters) in the
            exported graph will also be added as inputs to the graph. If False,
            then initializers are not added as inputs to the graph, and only
            the non-parameter inputs are added as inputs.
            This may allow for better optimizations (e.g. constant folding) by
            backends/runtimes.

            If True, `deduplicate_initializers` pass will not be executed. This means
            initializers with duplicated values will not be deduplicated and
            will be treated as distinct inputs to the graph. This allows different
            input initializers to be supplied at the runtime following export.

            If ``opset_version < 9``, initializers MUST be part of graph
            inputs and this argument will be ignored and the behavior will be
            equivalent to setting this argument to True.

        custom_opsets (dict[str, int], default empty dict): A dict with schema:

            * KEY (str): opset domain name
            * VALUE (int): opset version

            If a custom opset is referenced by ``model`` but not mentioned in this dictionary,
            the opset version is set to 1. Only custom opset domain name and version should be
            indicated through this argument.

        export_modules_as_functions: Flag to enable
            exporting all ``nn.Module`` forward calls as local functions in ONNX. Or a set to indicate the
            particular types of modules to export as local functions in ONNX.
            This feature requires ``opset_version`` >= 15, otherwise the export will fail. This is because
            ``opset_version`` < 15 implies IR version < 8, which means no local function support.
            Module variables will be exported as function attributes. There are two categories of function
            attributes.

            1. Annotated attributes: class variables that have type annotations via
            `PEP 526-style <https://www.python.org/dev/peps/pep-0526/#class-and-instance-variable-annotations>`_
            will be exported as attributes.
            Annotated attributes are not used inside the subgraph of ONNX local function because
            they are not created by PyTorch JIT tracing, but they may be used by consumers
            to determine whether or not to replace the function with a particular fused kernel.

            2. Inferred attributes: variables that are used by operators inside the module. Attribute names
            will have prefix "inferred::". This is to differentiate from predefined attributes retrieved from
            python module annotations. Inferred attributes are used inside the subgraph of ONNX local function.

            * ``False`` (default): export ``nn.Module`` forward calls as fine grained nodes.
            * ``True``: export all ``nn.Module`` forward calls as local function nodes.
            * Set of type of nn.Module: export ``nn.Module`` forward calls as local function nodes,
                only if the type of the ``nn.Module`` is found in the set.

        autograd_inlining: Flag used to control whether to inline autograd functions.
            Refer to https://github.com/pytorch/pytorch/pull/74765 for more details.

    Raises:
        :class:`torch.onnx.errors.CheckerError`: If the ONNX checker detects an invalid ONNX graph.
        :class:`torch.onnx.errors.UnsupportedOperatorError`: If the ONNX graph cannot be exported because it
            uses an operator that is not supported by the exporter.
        :class:`torch.onnx.errors.OnnxExporterError`: Other errors that can occur during export.
            All errors are subclasses of :class:`errors.OnnxExporterError`.
    z}Setting `operator_export_type` to something other than default is deprecated. The option will be removed in a future release.categoryzSetting `training` to something other than default is deprecated. The option will be removed in a future release. Please set the training mode before exporting the model.N)rb   rc   rd   re   rf   rg   rh   ri   )r+   OperatorExportTypesONNXr4   r5   FutureWarningr,   r0   r*   r>   Tensor_export)r9   r\   fr]   r_   rQ   r(   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   s                    r&   r   r      s    j	 w::???>"	

 7''000* #		
 !u||4D7$Dvi	1#/!$?#$?+!& r%   c                F   | j                         dk7  ry| j                         j                         }|j                  t        j
                  j                               ry|j                  t	        j
                  t        j                  j                                     ryy )Nzprim::ConstantFT)	kindoutputr.   isSubtypeOfr
   ListType	ofTensorsOptionalTypeofTensor)nodeoutput_types     r&   _is_constant_tensor_listr}     ss    yy{&&++-$$&Kr{{4467r{{2??+C+C+EFG Hr%   c                   |j                         D ]M  }|j                         D ]  }t        | |        t        |      s1g }|j	                         j                         D ]b  }| j                  |      }|j                         j                  |       |j                         j                  |       |j                  |       d | j                  d|      j                  |      j	                         j                  t        j                  j!                               }|j                         j                  |       |j	                         j#                  |       P y )Nzprim::ListConstruct)nodesblocks_split_tensor_list_constantsr}   ru   toIValueinsertConstantr{   
moveBeforecopyMetadataappendcreateinsertBeforesetTyper
   rw   rx   replaceAllUsesWith)gblockr{   subblockinputsvalinputlcs           r&   r   r     s    1 	6H(H5	6#D)F{{}--/ %((-

''-

))$/e$	% .7d#..01	  GGI""4(KKM,,R0%1r%   c                   |i }t        j                  |        t        j                  |        t        j                  |        t        j
                  rt        j                  |        t        j                  |        |du rt        j                  |        t        | |        t        j                  |        t        j                  |        t        j                  |       rt        j                  |        t        j                  |        t        j                  |        t        j                  | d       t        j                  |        t        j                  |        t        j                  | d       t        j                  |        t        j                   | |       t        j"                  |        t        j                  |        t        j$                  |        t        j&                  |        t        j(                  |        t*        j,                  j/                          t        j0                  | |       t        j2                  |        t        j4                  r#|g n|}|i n|}t        j6                  | ||       t        j                  |        t        j8                  | |      } t        j                  |        t        j                  |        t        j:                  | dt        j<                         t        j                  |        t        j>                  | t        j<                  |       t        j                  |        t        j@                  |        t        j                  |        t        jB                  |       } t        j                  |        t        j4                  r%t        jD                  | |t        j<                         | S )NFT)#r
   _jit_pass_inline_jit_pass_inline_fork_wait_jit_pass_lintr   ri   (_jit_pass_onnx_autograd_function_process_jit_pass_lower_all_tuples_jit_pass_constant_propagationr   _jit_pass_dce_jit_pass_cse_jit_pass_onnx_lint&_jit_pass_canonicalize_graph_fuser_ops_jit_pass_peephole_jit_pass_fuse_addmm*_jit_pass_onnx_remove_inplace_ops_for_onnx_jit_pass_onnx_preprocess#_jit_pass_prepare_division_for_onnx_jit_pass_onnx_remove_print _jit_pass_onnx_preprocess_caffe2r   _quantized_opsclear'_jit_pass_onnx_unpack_quantized_weights_jit_pass_erase_number_typesonnx_shape_inference&_jit_pass_onnx_set_dynamic_input_shape_jit_pass_onnx#_jit_pass_onnx_scalar_type_analysisr3   _jit_pass_onnx_peephole4_jit_pass_dce_allow_deleting_nodes_with_side_effects_jit_pass_canonicalize)_jit_pass_onnx_graph_shape_type_inference)graphrb   _disable_torch_constant_propfixed_batch_sizeparams_dictre   r`   rG   s           r&   _optimize_graphr   0  s      !!%(e  
33E:!!%( $u,
))%0 . Ue
 

u%--e4e%&E"e%&!!%( 11%@  ' e **51""5)''.""((*..ukB##E*##'/b[)1r|
11%{S5!e%9:E5!e**tW66 ew002B e ;;EBe%%e,Ee##
44; A A	
 Lr%   c                L   t        | d   | d         D ]  \  }}t        |t              rLt        |j	                               t        |j	                               k7  sJd}t        j                  |       bt        |t              ss||k7  syd}t        j                  |        y)aY  Warns that changes to input dictionaries and strings won't take effect in the traced ONNX graph.

    We accept dictionaries and strings as ONNX inputs, but they should be only for
    configuration use. we detect here if these inputs are modified, and if so we warn
    the user that the changes won't take effect in the traced ONNX graph.
    r      aQ  We detected that you are modifying a dictionary that is an input to your model. Note that dictionaries are allowed as inputs in ONNX but they should be handled with care. Usages of dictionaries is not recommended, and should not be used except for configuration use. Also note that the order and values of the keys must remain the same. zvThe model seems to have string inputs/outputs. Note that strings will not appear as inputs/outputs of the ONNX graph. N)zipr*   r[   listkeysr4   r5   str)input_statesr   traced_inputwarnings       r&   r   r     s      #<?LOD '|eT"EJJL!T,*;*;*=%>>]  g&s#$^  g&''r%   c                    |S )zVResolves the arguments that are ignored when export_type != operator_export_type.ONNX.r$   )arg_name	arg_valuerb   s      r&   _resolve_args_by_export_typer     s    r%   c                    |dk  r| du rt        j                  d       y| dn| }| |t        j                  j                  u rd}|S )ae  Decides whether the initializers in the graph should be listed as ONNX graph inputs.

    This method encapsulates the logic to decide whether the initializers in the graph
    should be listed as ONNX graph inputs (i.e., whether to choose ONNX IR v3 or v4).
    If keep_initializers_as_inputs is not specified (None), then we decide whether to keep
    initializers as graph inputs (val_keep_init_as_ip) based on export type. If export type
    is ONNX, then do not keep initializers as input (val_keep_init_as_ip=False). For all other
    export types keep initializers as input (val_keep_init_as_ip=True).
    If keep_initializers_as_inputs is specified, then respect it. Unless opset version <= 8,
    in which case it must be ignored because for opset version <= 8, all initializers MUST be
    part of graph input (only ONNX IR v3 is allowed), i.e. val_keep_init_as_ip=True.

    Special handling is needed for opset version 8 or lower, because irrespective
    of user input for keep_initializers_as_inputs, the graph must follow ONNX IR v3
    semantics, i.e. all initializers must be listed as ONNX graph input.
    	   Fa  Setting 'keep_initializers_as_inputs=False' for opset version8 or lower would lead to an invalid ONNX graph. Therefore, 'keep_initializers_as_inputs=False' is ignored during export.Exported model will have initializers as graph inputs (compliant  to ONNX IR v3).T)r4   r5   r+   rm   rn   )rf   rb   rc   val_keep_init_as_ips       r&   _decide_keep_init_as_inputr     sb    , q&%/MM# +39T  	$+ G$?$?$D$DD#r%   c                    t        d| |      S )Nadd_node_names)r   )r   rb   s     r&   _decide_add_node_namesr     s    '.*> r%   c                    t        d| |      } | r3|1|t        j                  j                  urt	        j
                  d       | S )Nrd   a  It is recommended that constant folding be turned off ('do_constant_folding=False') when exporting the model in training-amenable mode, i.e. with 'training=TrainingMode.TRAIN' or 'training=TrainingMode.PRESERVE' (when model is in training mode). Otherwise, some learnable model parameters may not translate correctly in the exported ONNX model because constant folding mutates model parameters. Please consider turning off constant folding or setting the training=TrainingMode.EVAL.)r   r+   r,   r8   r4   r5   )rd   rb   r(   s      r&   _decide_constant_foldingr     sN    624H 1E1E1J1J!JV	
 r%   c                r    t        | d|       }t        |      rt        j                  |      S t	        d      )Nforwardz/model has no forward method and is not callable)getattrcallableinspect	signature
ValueError)r9   should_be_callables     r&   
_signaturer     s8     	59"#  !344
F
GGr%   c                \   	 t        |       }	 t	        |j
                  j                               }|d   dk(  r|dd  }i }t        |t              r|}nt        |t              rt	        |      }n|g}t        |d   t              r
|d   }|d d }t        |      }||d  D ]_  }||v r|j                  ||          |j
                  |   }	|	j                  |	j                  k7  sE|j                  |	j                         a t        |t              r|}|S t        |      }|S # t        $ r$}t        j                  | d       |cY d }~S d }~ww xY w# t        $ r t        j                  d       Y |S t        $ r0}t        j                  d|j                   d           Y d }~|S d }~ww xY w)Nz, skipping _decide_input_formatr   selfr   rZ   z,No input args, skipping _decide_input_formatzSkipping _decide_input_format
 )r   r   r4   r5   r   
parametersr   r*   tupler[   lenr   defaultempty
IndexError	Exceptionr\   )
r9   r\   sigeordered_list_keys	args_dict	args_listn_nonkeywordoptional_argparams
             r&   _decide_input_formatr   
  s   F !4!4!67Q6) 1!" 5	dD!Ie$T
IIimT*!"I!#2I9~-lm< 	4Ly(  <!89 |4==EKK/$$U]]3	4 'tT2y K 9>i8H KA  :;<8  FDE K  F8DEEKFsG   D" CE $/E E "	E+E
E
EF+3F+;%F&&F+c           
        |y|t               }nt        |      }i }|j                         D ]  \  }}||v rt        d      t        |t              rE|j                         D ci c]%  \  }}|t
        j                  j                  |      ' c}}||<   jt        |t              r7|D ci c]'  }|t
        j                  j                  | d|       ) c}||<   t        dt        |              	 t        |       }	|	j                  j                         D ]  }||vsd||<    |S c c}}w c c}w # t        $ r$}
t        j                  |
 d       |cY d}
~
S d}
~
ww xY w)a  

    dynamic_axes examples:
    (1) dynamic_axes = {"x": {0: "my_custom_axis_name_1"}, "y": {1: "my_custom_axis_name_2"}}
    (2) dynamic_axes = {"x": [0], "y": [1]}

    these will be converted to dynamic_shapes respectively:
    (1) dynamic_shapes = {"x": {0: Dim("my_custom_axis_name_1")}, "y": {1: Dim("my_custom_axis_name_2")}}
    (2) dynamic_shapes = {"x": {0: Dim("x_dim_0")}, "y": {1: Dim("y_dim_1")}}  # auto-generated dim names

    NzzAssinging new input names is not supported yet. Please use model forward signature to specify input names in dynamix_axes._dim_z<dynamic_axes value must be either a dict or a list, but got z., skipping auto filling None on static axes...)setrC   r   r*   r[   r>   r   Dimr   r-   r.   r   r4   r5   r   r   )r9   re   r`   input_names_setdynamic_shapes
input_nameaxeskvr   r   s              r&   $_from_dynamic_axes_to_dynamic_shapesr   0  s   $ %k*,.N(..0 
D(:  dD!37::<*+/1a5<<##A&&*N:& d#FJ*AB5<<##zl%s$;<<*N:& NtTXzl[ ( nn))+ .
^+)-N:&. +**  IJKs*   &*D.,,D48D9 9	E&E!E&!E&c                    t        |t        j                        r|f}t        j                  j	                  | |ddd      \  }}}t        |       t        ||i       }|r||fS |S )NFTstrict_force_outplace_return_inputs_states)r   )r*   r>   rp   r?   _get_trace_graphr   r   )funcr\   rb   return_outstrace_graph	torch_outinputs_statess          r&   _tracer   j  su    $%w,1II,F,F" -G -)KM  .!+/CQSTKI%%r%   c                   t         j                  j                  |       j                         }t        j                         }t        j
                  d       t         j                  j                  | |ddd      \  }}}t        j
                  |       t        |       |t         j                  j                  |       j                         k7  rt        d      ||fS )NFTr   zXstate_dict changed after running the tracer; something weird is happening in your model!)	r>   r?   _unique_state_dictr   is_autocast_cache_enabledset_autocast_cache_enabledr   r   RuntimeError)r9   r\   orig_state_dict_keysprev_autocast_cache_enabledr   r   r   s          r&   _trace_and_get_graph_from_modelr  ~  s     !9977>CCE
 #("A"A"C	$$U+,1II,F,F" -G -)KM 
$$%@A.uyy;;EBGGII:
 	

 	!!r%   c                $   g }t        | j                         |      D ]p  \  }}dt        |j                               v r=t        j
                  j                  |      \  }}|j                  t        |             ^|j                  |d u       r |S )NPackedParams)	r   r   r   r.   r>   r?   _flattenr   r   )method_graphargs_paramsparam_count_listinput_arg_params_in_vars_s          r&   _get_param_count_listr    s    "<#6#6#8+F =S//++K8JGQ##CL1##Kt$;<= r%   c                    fdt         |             }t        |      t        |      z
  }|dk\  sJ |rt        d| d      y)zAtorch.jit._flatten removes None. Check if it did so in this case.c              3     K   t        | t        t        f      r| D ]  } |      E d {     y t        | t              r&| j	                         D ]  } |      E d {     y |  y 7 B7 wrL   )r*   r   r   r[   values)xinnerflattens     r&   r  z._check_flatten_did_not_remove.<locals>.flatten  so     a$' *"5>))*4  *"5>))* G * *s!   'A1A-5A1 A/!A1/A1r   zargs contained z None's after flattening. When exporting a ScriptModule or ScriptFunction, no args may be None because that breaks type propagation.N)r   r   r   )originaljit_flattenedflattened_with_nonenum_noner  s       @r&   _check_flatten_did_not_remover    sa     wx01&'#m*<<Hq==hZ (< <
 	
 r%   c                   t        | t        j                  j                  t        j                  j                  f      rt        t        j                  j                  t        |            d         }t        ||       d }t        | t        j                  j                        r	 | j                  j                  }t        j                  |       t        j                  t        t        j                  | j                         d      }t        j"                  |      \  }}|j%                  d      j                  }	t        |      t        |      z   }
t'        |	|
      }t        j                  j                  |
      \  }}t        j(                  |	t        |      |dd      }||||fS g }| j                  }t        j                  |       t'        ||      }t        j(                  |||dd      }|||d fS t+        | |      \  }}t        j,                  |       t        j                  j/                  |       }t1        |j3                               }t1        |j5                               }t7        |      t7        |      z
  }t1        |j9                               }t;        |      D ]"  \  }}||k\  s|j=                  |||z
            $ t        j                  |       |||d fS # t        $ r}t        d      |d }~ww xY w)Nr   z('forward' method must be a script methodT)preserveParametersr   F)r*   r>   r?   r@   ScriptModuler   r  r  r   r   AttributeErrorr  r
   $_jit_pass_onnx_function_substitution_freeze_moduler   _c_jit_onnx_list_model_parameters_get_methodr  "_propagate_and_assign_input_shapesr  r   r   r   r  r   r   r   	enumeratesetDebugName)r9   r\   flattened_argsr   r   r   freezed_modulerG   paramsr  r	  r
  r  r  
state_dictgraph_inputsuser_input_numparam_namesiinps                       r&   _create_jit_graphr0    s    %%))22EII4J4JKLuyy11%+>qAB%dN;	eUYY334V++ 33E:..R__ehh/DN  ??ONFF!--i8>>L+f5K4\;O++K8JGQ99eGn.>uE &)V33 
//60=55>#3UE
 fi--6udCE95!--e4J*##%&F'L&Z8Nz()KL) >3[^);<=> ++E2&)T))K " V"#MNTUUVs   (K* *	L3K??Lc                    | j                         D cg c]  }|j                          }}|t        |      t        |      z
  d  }t        t	        ||            }|S c c}w rL   )r   	debugNamer   r[   r   )r   r)  r   input_and_param_namesr-  _params_dicts         r&   _get_named_param_dictr5    s[    8=GS]]_GG',A(BS[(P(RSKK01L Hs   Ac                    t        j                  |      }i }|rt        |d   t              r
|d   }|d d } | |i |}t        |t              r|g}|S t        |t
              s|f}|S )NrZ   )copydeepcopyr*   r[   r   r   )r9   r\   
input_argsinput_kwargsexample_outputss        r&   _get_example_outputsr<    s|    t$JLjB6!"~_
Z8<8O/4(*+  /*,r%   c                   t        | t        j                        r&| j                  t        v r| j                         }|r3t        j                  | j                         t        j                        n2t        j                  | j                         t        j                        }|r3t        j                  | j                         t        j                        n5t        j                  | j                         t        | j                           }||z  |z   }|j                  t        | j                           }|||fS | fS )N)dtype)r*   r>   rp   r>  _qtype_vtype_map
dequantizetensorq_scaledoublefloat32q_zero_pointint64to)valuecast_onnx_acceptedq_value_dequantizerB  rE  q_values         r&   r   r     s    %&5;;:J+J"--/ " LL=emmoU]]C 	 " LL++-U[[Ae002:J5;;:WX 	
 %w.=**#3EKK#@*A--xr%   c           	         t        d  t        | dt                     D              st        d |D              r t        j                  j                  | |      S | S )zReturns `torch.jit.trace(model, args)` if model is quantized. Otherwise do nothing and return
    original model.

    This is due to https://github.com/pytorch/pytorch/issues/75761.
    c              3  4   K   | ]  }t        |d         yw)_packed_paramsN)r/   ).0ms     r&   	<genexpr>z)_pre_trace_quant_model.<locals>.<genexpr>,  s      )*#$s   rA   c              3  6   K   | ]  }t        |d d        ywis_quantizedFNr   )rO  args     r&   rQ  z)_pre_trace_quant_model.<locals>.<genexpr>.  s     ASWS.%0A   )anyr   r   r>   r?   trace)r9   r\   s     r&   _pre_trace_quant_modelrZ  &  sO      .MgeY.M.O 	ADA	Ayyud++Lr%   c           
        t        |t        j                  t        t        t
        f      r|f}t        | |      } t        | |      \  }}}}t        ||      }	 t        ||||||
||      }t        | t        j                  j                  t        j                  j                  f      }|r|t!        | |      }d}|D ]  }|t#        |      z  } t        j                  j%                  |      \  }}t'        j(                  |||t*        j,                  |t*        j.                         nt        |t0        t2        f      s|g}n|}t        j                  j%                  t3        |            \  }}t5        d |D              s6t'        j(                  |||t*        j,                  |t*        j.                         t7        |||       t        ||      }|rt*        j.                  t8        j:                  k\  ro|	|	t<        j>                  j@                  k(  rt'        jB                  ||      }t'        jD                  ||t*        j.                        }t'        jF                  |       t*        j,                  r%t'        jH                  ||t*        j.                         t'        jJ                  ||      }t*        j.                  dk  rt'        jL                  |       t'        jN                  |      }t'        jP                  |       tS        ||       |||fS # t        $ r&}t        j                  j                  d|        d}~ww xY w)a  Converts model into an ONNX graph.

    Returns:
        graph: A TorchScript IR Graph with ONNX nodes.
        params_dict: Dict from input param name to param value.
        torch_out: The output tensors resulting from the trace of ``model``.
            If ``model`` is a :class:`torch.jit.ScriptModule` or :class:`torch.jit.ScriptFunction`,
            this will be None, since we are not doing any tracing.
    )r   r   r   re   r`   rG   zTorch IR graph at exception: Nr$   c              3  6   K   | ]  }t        |d d        ywrS  rU  )rO  outs     r&   rQ  z"_model_to_graph.<locals>.<genexpr>  s     Q3736QrW  r   )*r*   r>   rp   intfloatboolrZ  r0  r5  r   r   rM   logr?   r@   r  r<  r   r  r
   "_jit_pass_onnx_assign_output_shaper   r   r3   r   r   rX  _set_input_and_output_namesr   ONNX_CONSTANT_FOLDING_MIN_OPSETr+   r,   r8   _jit_pass_onnx_eval_peephole_jit_pass_onnx_constant_foldr   r   %_jit_pass_onnx_eliminate_unused_items,_jit_pass_onnx_cast_all_constant_to_floating%_jit_pass_filter_non_tensor_arguments#_jit_decay_packed_param_input_types_apply_friendly_debug_names)r9   r\   rQ   r`   ra   rb   rd   r   r   r(   re   r   r)  r   rG   r   r   	is_scriptr;  example_outputs_finalexample_outputout_varsdescoutput_wrappedoutput_tensorsout_descs                             r&   _model_to_graphrt  3  s   D $sE489w"5$/E'8'E$E69f'v6K )E-#%#	
 5599#;#;UYY=S=S"TUI.ud; "- 	MN!%<^%LL!	M++,AB$
--((--	
 )dE]3'[N&N#(99#5#5eN6K#L  Q.QQ11,,11  {LA'v6K 	--556 x7+?+?+D+DD99%MK55; A A
 	??F##
44; A A	
 ::5+NK ((1,
77>::;GK**51  {3+y(([  

6>s   L 	L>!L99L>z2.5z
the futurez"use onnx.printer.to_text() insteadc                d   |
t         j                  }
|i }|
t        _        |t        _        t        | ||      5  t        |||
      }t        ||      }t        |||      }t        | |      }t        | ||||||||	      \  }}}|j                  ||
d||	|||      cddd       S # 1 sw Y   yxY w)a  Similar to :func:`export`, but returns a text representation of the ONNX model.

    Only differences in args listed below. All other args are the same
    as :func:`export`.

    Args:
        add_node_names (bool, default True): Whether or not to set
            NodeProto.name. This makes no difference unless
            ``google_printer=True``.
        google_printer (bool, default False): If False, will return a custom,
            compact representation of the model. If True will return the
            protobuf's `Message::DebugString()`, which is more verbose.

    Returns:
        A UTF-8 str containing a human-readable representation of the ONNX model.
    N)r(   re   F)r   ONNX_DEFAULT_OPSETr   r3   rb   r   r   r   r   r   rt  _pretty_print_onnx)r9   r\   r_   rQ   r(   r`   ra   rb   export_typegoogle_printerrc   rf   rg   r   rd   re   r   val_add_node_namesval_do_constant_foldingr   r   r   s                         r&   r   r     s    H "55(5G%#7G 	%7	3  
8')=}
 40
 #;!5x#
 $E40(7 #%
)
%{I '' 	
/ 
  
  
s   A"B&&B/zavoid using this functionc                   |xs t         j                  }|t        _        	 t	        | |d      5  t        | |      }t        | |      } t        | |      \  }}}}t        j                  |       t        j                  ||       t        j                  |       t        j                  |       ddd       g }j!                         D ]e  }	|	j#                         }
|
j%                  d      r%t&        j(                  j+                  |
j-                  d      |      rU|j/                  |
       g ||fS # 1 sw Y   xY w# t        $ r}t        j                  d      |d}~ww xY w)a  Returns an approximated list of all ops that are yet supported by :mod:`torch.onnx`.

    The list is approximated because some ops may be removed during the conversion
    process and don't need to be converted. Some other ops may have partial support
    that will fail conversion with particular inputs. Please open a Github Issue
    for op support requests.

    Args:
        model: Same as the `model` parameter in :func:`torch.onnx.export`.
        args: Same as the `args` parameter in :func:`torch.onnx.export`.
        training: Same as the `training` parameter in :func:`torch.onnx.export`.
        opset_version: Same as the `opset_version` parameter in :func:`torch.onnx.export`.

    Returns:
        The JIT graph and a list of unconvertible ops in the format of "domain::op".
    F)rQ   Nz_Failed to discover unconvertible ops because of errors during the JIT graph generation process.)zonnx::zprim::r  )r   rv  r   r3   r   r   rZ  r0  r
   r   r   r   r   r   r   OnnxExporterErrorr   rt   
startswithr   registryis_registered_oprstripr   )r9   r\   r(   rc   r   r  rG   r   unsupported_opsr{   	domain_ops              r&   r   r     sZ   0 "BZ%B%BM(5G%eXu= 	K (t4D*5$7E"3E4"@E1a&99%H++E2CCEJ	K* O .IIK	 45
 $$55S!=
 ""9-.  /!!M	K 	K  &&"
 	s/   E  A?D4.E  4D=9E   	E$	EE$c                6     fd}dd} j                         D ci c]H  \  }}|t        j                  j                  t        j                  t        |             ||            J }}}|t        j                  j                  _        t        |t              r.|r,|D ch c]   }t        j                  t        |            " }}n5t        |t              r|rd }	|D 
ch c]
  }
 |	|
       }}
n
t               }|r |        |S c c}}w c c}w c c}
w )Nc                     dfd} fd}j                         D ]$  }|j                  |       |j                  |        & y )N_onnx_attrsc                2    t        | t        |              y rL   )setattr_get_module_attributes)rG   r   	attr_names     r&   )_track_module_attributes_forward_pre_hookzm_setup_trace_module_map.<locals>.__register_attribute_hook.<locals>._track_module_attributes_forward_pre_hookQ  s    FI'=f'EFr%   c                    t        j                         }|sy |j                         }i }t        |       rt	        |       }t        |        t        j                  ||       y rL   )r
   _get_tracing_stater   r/   r   delattr%_jit_pass_onnx_track_scope_attributes)rG   r   ru   tracing_stater   
onnx_attrsr  s         r&   %_track_module_attributes_forward_hookzi_setup_trace_module_map.<locals>.__register_attribute_hook.<locals>._track_module_attributes_forward_hookT  sZ    113M !'')EJvy)$VY7
	*44UJGr%   )rA   register_forward_hookregister_forward_pre_hook)r  r  rP  r  r9   s      @r&   __register_attribute_hookz:_setup_trace_module_map.<locals>.__register_attribute_hookN  sK    !		G	H  	SA##$IJ''(QR	Sr%   c                    | j                  d      }t        t        t        |                  D ]+  \  }}|j	                         rdj                  ||d       c S  | S )a  
        Parse qualified variable name and return the unqualified version.

        Pure numeric atoms are considered inadequate, so this function will look past them,
        and start from the first non-numeric atom.

        Example:
            >>> _unqualified_variable_name("__main__.Foo.bar")
            'bar'
            >>> _unqualified_variable_name("__main__.Foo.bar.0")
            'bar.0'
        .N)splitreversedr   r%  	isnumericjoin)qualified_name
name_atomsr.  atoms       r&   _unqualified_variable_namez;_setup_trace_module_map.<locals>._unqualified_variable_namee  s]     $))#.
Yz%: ;< 	0GAt>>#xx
12//	0 r%   c                    t        | t              rt        j                  |       S t	        dt        |       j
                   d      )NzjOnly type of the `nn.Module` should be passed in the set for argument `export_modules_as_functions`. Got `z`.)r*   r.   r>   typenamer  rD   )r   s    r&   _find_typenamez/_setup_trace_module_map.<locals>._find_typename  sD    !T"~~a((" G,,-R1 r%   )r  r   returnr   )named_modulesr>   r
    _jit_onnx_create_full_scope_namer  r.   r?   r   _trace_module_mapr*   r`  r   )r9   rh   r  r  _n_mtrace_module_maprG   module_typenamesr  r   s   `          r&   _setup_trace_module_mapr  J  s   S.. ))+	 B 	EHH55NN48$&@&D
 	
  *:EII&-t49TGWXVENN4<8XX	/	5:U	 8SS!N1-SS5!#9 Y Ts   AD#%D$Dc                 j    d t         j                  j                  _        t	        j
                          y rL   )r>   r?   r   r  r
   "_jit_pass_onnx_clear_scope_recordsr$   r%   r&   _reset_trace_module_mapr    s     )-EII&))+r%   c                ~   t        j                  t        |             }t        j                  t        j                  j
                        }|D cg c]  } |j                  |d        c} i }|D ]  }	 t        | |      ||<    |S c c}w # t        $ r& t        j                  j                  d| d       Y Jw xY w)NzSkipping module attribute '')typingget_type_hintsr.   r>   nnModulerE   r   r  rM   ra  )rG   r   base_m_annotationsr   attrss        r&   r  r    s    ''V5K..uxx?'9:!_[__Q: E 	vq)E!H L% ;  	JJNN81=>	s   B5B,B<;B<c                ~   t         j                  du sJ |	t        j                  j                  }	t        | t        j                  j                        rt        d      |t         _
        |
t        j                  }
|
t        j                  kD  r:t        j                  d|
 dt        j                   dt         j"                         |r|
dk  rt        d      |st$        j&                  j(                  }|
t         _        |t         _        	 d	t         _        t         j.                  }|t         _        t1               }t        | t        j                  j2                  t        j4                  j6                  f      rt9        | |      }t;        | ||      5  t=        |||
      }t?        ||      }tA        |||      }t        |tB              r|}nd
}tE        | |      }|i }tG        || ||       tI        | |||||||||
      \  }}}|	t        j                  j                  u}|i }tK        jL                  |       i }|r.tK        jN                  ||tQ        |jS                                     }|d	ur"tK        jT                  ||tW        | dd            }tK        jX                  |       |r"|j[                  ||
|||| |||||      \  }} }!}"n!|j[                  i |
|d|| |||||      \  }} }!}"t]        j^                  ||      }|r t        j`                  jc                  d|       t]        jd                  |||	|        d d d        t         j                  sJ dt         _        |t         _        tg                S # 1 sw Y   =xY w# t         j                  sJ dt         _        t         _        tg                w xY w)NFztorch.nn.DataParallel is not supported by ONNX exporter, please use 'attribute' module to unwrap model from torch.nn.DataParallel. Try torch.onnx.export(model.module, ...)z Exporting to ONNX opset version zT is not supported. by 'torch.onnx.export()'. The highest opset version supported is zP. To use a newer opset version, consider 'torch.onnx.export(..., dynamo=True)'. rk      z`export_modules_as_functions` is not supported for `opset_version` < 15.This is because `opset_version` < 15 implies IR version < 8, which means no local function support. T )r   r(   re   r(   zExported graph: )4r   r#   r   ExportTypesPROTOBUF_FILEr*   r>   r  DataParallelr   r   r   rv  #ONNX_TORCHSCRIPT_EXPORTER_MAX_OPSETr4   r5   r   OnnxExporterWarningr+   rm   rn   r3   rb   ri   r   r  r?   r  r  r   r   r   r   r   r   _validate_dynamic_axesrt  r
   r   "_jit_pass_onnx_function_extractionr   r   '_jit_pass_onnx_deduplicate_initializersr   5_jit_pass_onnx_assign_scoped_names_for_node_and_value_export_onnxr   _add_onnxscript_fnrM   ra  _export_filer  )#r9   r\   rr   r_   rQ   r(   r`   ra   rb   rx  rc   rd   re   rf   r   rg   r   r   rh   ri   _autograd_inlining_previous'module_typenames_to_export_as_functionsr   rz  r{  model_file_locationr   r   r   defer_weight_exportnode_attr_to_nameproto
export_mapval_use_external_data_format
node_namess#                                      r&   rq   rq     s    , !!U***&22@@%../3
 	
 $8G "55 zEEE 	.}o >66@6d6d5e f]^ //	
 #}r'9*
 	

  &::?? )6G%#7G y"!%&-&?&?#$5!<?E/eehhoouyy/E/EFG6M273 eXw7 i	M"<+$#
 "8 4" '?#%98'#
 !S!&'#&(#'t4D#!"<\R,;$'!1!)-)E;	 #3#?#?#M#MM   $ "CCEJ "6$&$I$I;))+,%! +$6 HHE:u5
 DDUK &&! '(K'!&'%0( &&! (K'!&'%0 %77E 

159))%KLSi	MV %%%%!&$?!!ai	M i	MV %%%%!&$?!!s&   BN F*M< N <NN 4N<c                L   | j                         D ]  }|j                         D ]|  }|j                         }|t        |j	                               k7  r0|j                          d|j	                          }|j                  |       ||v si|j                  |      ||<   ~  y )Nr  )r   r   r2  r   uniquert   r&  rE   )r   r)  nr   old_namenew_names         r&   rk  rk  x  s    [[] 8 	8A{{}H3qxxz?*&&(1QXXZL1HNN8$6!#)::h#7x 	88r%   c                      fd} |t         j                               |d        |t         j                               |d       y )Nc           	        |y t        |      t        |       kD  r$t        d|t        |      |t        |       fz        t               }t        t	        ||             D ]  \  }\  }}|dk(  r||v rj                  d      }|j                  |j                                |j                  |       |j                         j                  |j                                j                         j                  ||j                                |j                         }|j                  |       |j                         |k7  s|j!                  |        y )Nz<number of %s names provided (%d) exceeded number of %ss (%d)ru   zonnx::Identity)r   r  r   r%  r   r   insertAfterr{   addInputru   r   r.   return_nodereplaceInputaddr2  r&  )		node_list	name_list
descriptoroutput_node_setr.  namer{   identity_noder   s	           r&   	set_namesz._set_input_and_output_names.<locals>.set_names  s+   y>C	N*Ns9~z3y>JK  %(Y	)BC 	(OA|dX%?*$)LL1A$BM!--diik:!**40!((*22499;?%%'44Q8L8L8NO(//1D##D)~~4'!!$'	(r%   r   ru   )r   r   outputs)r   r`   ra   r  s   `   r&   rc  rc    s8    (4 d5<<>"K9d5==?#\8<r%   c           
         	 t        j                  | | j                         t        j                  dt
        i t               g       } ||g| S # t        $ r!}|j                  d    d| df|_         d}~ww xY w)z\
    This trampoline function gets invoked for every symbolic method
    call from C++.
    Nr   r   opsetoriginal_noder   envvalues_in_env	new_nodesr   z (occurred when translating ))	r   GraphContextr   r   r3   r4  r   r-   r\   )r   op_namesymbolic_fnr\   graph_contextr   s         r&   _run_symbolic_methodr    s    
!..'')33$%	
 =0400  VVAYK;G9AFHs   AA 	A:A55A:c                "    | j                         S rL   )addBlock)r{   s    r&   
_add_blockr    s    ==?r%   c                "    | j                         S rL   )addInputToBlock)r   s    r&   _add_input_to_blockr    s      ""r%   c                $    | j                  |      S rL   )registerOutput)r   rH  s     r&   _add_output_to_blockr    s    &&r%   c                    t         j                  j                  | |      }|t        j                  j
                  k(  }|t        j                  j                  k(  }| j                  d      sy|s|r|syy)Naten::FT)r   r  r  r+   rm   	ONNX_ATENONNX_ATEN_FALLBACKr~  )r  rc   rb   is_exportable_aten_opis_onnx_aten_exportis_aten_fallback_exports         r&   _should_aten_fallbackr     sm     )11BB4W.'2M2M2W2WW ; ; N NN  ??8$6?Tr%   c                    | j                         }|j                  d      syt        j                  |      j                  S )Nr  r  )schemar~  r
   parse_schemaoverload_name)r  r  s     r&   _get_aten_op_overload_namer    s3    XXZFX&??6"000r%   c           
     (   t         j                  }|j                         }	|	j                  d      r|	dd }
n|	}
t	        j
                  |
      \  }}t	        j                  | |||t        |||      }t        |
||      r|j                         D ci c]1  }|dz   |j                  |      d   z   t        j                  ||      3 }}|j                         }||d<    |j                  |g|dt        |      i|S 	 |}| d| }t         j"                  j%                  |      }|Q|j'                  |      }|>|j                         D ci c]  }|t        j                  ||       }} ||g|i |S |j                         D ci c]1  }|dz   |j                  |      d   z   t        j                  ||      3 }}|d	k(  r( |j(                  |g|i |d|j                         iS t+        j,                  |||r|j/                               d      c c}w c c}w c c}w # t0        $ r |t2        j4                  j6                  k(  rY y|t2        j4                  j8                  k(  rs|j                         D ci c]1  }|dz   |j                  |      d   z   t        j                  ||      3 nc c}w }} |j                  |g|dt        |      i|cY S  t:        $ r!}|j<                  d    d
| df|_         d}~ww xY w)zRuns a symbolic function.

    The function is used in C++ to export the node to ONNX.

    Returns:
        A single or a tuple of Values.
        None when the node gets cloned as is into the new graph.
    r  NrZ   r  r   r  r  ::rM   z 
(Occurred when translating z).)r   r3   rt   endswithr   parse_node_kindr  r4  r   attributeNameskindOfr   	_node_getoutputsSizeaten_opr  r   r  get_function_groupgetopr   UnsupportedOperatorErrorget_min_supportedr  r+   rm   ONNX_FALLTHROUGHr  r-   r\   )r   r   r{   r   r  r  r  rb   rc   	node_kind
ns_op_name	namespacer  r  r   r  r  domainsymbolic_function_namesymbolic_function_groupr  r   s                         r&   _run_symbolic_functionr    s   & 55M 		I#s^

"22:>Iw** #	M Z8LM ((*
 Gdkk!nQ'')B)B4)KK
 
 ""$"i$}$$

 5T:
 	
 	
6$*82gY!7"."7"7"J"J"#
 #.155mDK& DHCVCVCX>?A00q99  #=C6CUCC ((*
 Gdkk!nQ'')B)B4)KK
 
 #=## $)373C3C3E  --"& $557
 	

 
 	
O
0

$  7#>#>#O#OO!W%@%@%S%SS ,,. C$++a.++_-F-FtQ-OO E  )=(( 9> 	  	  VVAYK=gYbIK	sa   6H AH/ H%.H/ <H/ 6H*.H/ 3-H/ %
H/ /&L/L6J=<)L'	L0LLc                    t        j                  d|       st        j                  d|  d      t	        j
                  |       \  }}|dk(  rt        d|  d| d      y )Nz+^[a-zA-Z0-9-_]+::[a-zA-Z-_]+[a-zA-Z0-9-_]*$zFailed to register operator z. The symbolic name must match the format domain::name, and should start with a letter and contain only alphanumerical charactersrM   z. z domain cannot be modified.)rematchr   r}  r   r	  r   )symbolic_namensr  s      r&   _verify_custom_op_namer!  W  sw    88BMR&&*=/ :( (
 	
 %%m4EB	V|*=/B4?Z[
 	
 r%   c                ~    | j                  d      rd|  } t        |         t        j                  | |      |       y)aC  Registers a symbolic function for a custom operator.

    When the user registers symbolic for custom/contrib ops,
    it is highly recommended to add shape inference for that operator via setType API,
    otherwise the exported graph may have incorrect shape inference in some extreme cases.
    An example of setType is `test_aten_embedding_2` in `test_operators.py`.

    See "Custom Operators" in the module documentation for an example usage.

    Args:
        symbolic_name (str): The name of the custom operator in "<domain>::<op>"
            format.
        symbolic_fn (Callable): A function that takes in the ONNX graph and
            the input arguments to the current operator, and returns new
            operator nodes to add to the graph.
        opset_version (int): The ONNX opset version in which to register.
    r  atenN)r~  r!  r   custom_onnx_symbolic)r  r  rc   s      r&   r    r    g  s=    , %}o.=)CL%%m]CKPr%   c                    | j                  d      rd|  } t        |        t        j                  j	                  | |       y)a-  Unregisters ``symbolic_name``.

    See "Custom Operators" in the module documentation for an example usage.

    Args:
        symbolic_name (str): The name of the custom operator in "<domain>::<op>"
            format.
        opset_version (int): The ONNX opset version in which to unregister.
    r  r#  N)r~  r!  r   r  
unregister)r  rc   s     r&   r!   r!     s<     %}o.=)$$]MBr%   c           	     6   t        |       dk(  ryt        |d      r|t        |      dk(  r5|j                  j                         D cg c]  }|j	                          }}|t        |      dk(  r5|j                  j                         D cg c]  }|j	                          }}t        |xs g |xs g z         }| j                         D ]  \  }}||vrt        j                  d| d       t        |t              s4t        j                  d|        i }	t        |      D ]a  \  }
}t        |t              st        d      ||	v rt        j                  d| d	| d
       Bt        |      dz   t        |
dz         z   |	|<   c |	| |<    yc c}w c c}w )z=Ensures dynamic axes argument is follows the expected format.r   Nr   zProvided key z2 for dynamic axes is not a valid input/output namezNo names were found for specified dynamic axes of provided input.Automatically generated names will be applied to each dynamic axes of input z3The type of axis index is expected to be an integerzDuplicate dynamic axis index z was provided for input r  _dynamic_axes_r   )r   r/   r   r   r2  r  r   rC   r4   r5   r*   r   r%  r^  r   r   )re   r9   r`   ra   r  yvalid_namesrH   rH  
value_dictr.  s              r&   r  r    s   
<AugC$4$927++2D2D2FGQ1;;=GKG S%6!%;38;;3F3F3HIaAKKMILI{(b\-?R@AK #((* +
Uk!MMu$VW eT"MM__b^ce
 J!%( 
M1!!S)$M  
?MM7s:RSVRWWXY %(H/?$?#a!e*$LJqM
M !+L/+ HIs   FFc                    t        j                  t        | t        j                  j
                        r| j                        S |       S rL   )r   r   r*   r>   r  r  r   )r9   s    r&   r   r     s:    #E588??; AF r%   )r  r`  )r:   _C_onnx.TrainingMode)r9   *torch.nn.Module | torch.jit.ScriptFunction)rQ   r`  )r:   r-  rQ   r`  )r\   ztuple[Any, ...]r]   dict[str, Any] | Noner  z-tuple[tuple[Any, ...], dict[str, Any] | None])$r9   zCtorch.nn.Module | torch.jit.ScriptModule | torch.jit.ScriptFunctionr\   ztuple[Any, ...] | torch.Tensorrr   r   r]   r/  r_   r`  rQ   r`  r(   r-  r`   Sequence[str] | Nonera   r0  rb   _C_onnx.OperatorExportTypesrc   
int | Nonerd   r`  re   DMapping[str, Mapping[int, str]] | Mapping[str, Sequence[int]] | Nonerf   bool | Nonerg   zMapping[str, int] | Nonerh   (bool | Collection[type[torch.nn.Module]]ri   r`  r  None)FFNNNN)r   _C.Graphrb   r1  r   r`  r   r`  )rf   r4  rb   r1  rc   r^  )r  inspect.Signature)NN)re   r3  r`   r0  r  r/  )F)r9   r.  r\   zSequence[Any]r  zDtuple[_C.Graph, list[_C.IValue], Any | None, _C.ScriptModule | None])T)r  ztuple[_C.Graph, dict[str, torch.Tensor], torch.Tensor | tuple[torch.Tensor, ...] | list[torch.Tensor] | dict[str, torch.Tensor] | Any | None])r(   r-  rc   r2  r  ztuple[_C.Graph, list[str]])r9   z(torch.nn.Module | torch.jit.ScriptModulerh   r5  r  zset[str])rh   r   )r{   _C.Noder  _C.Block)r   r:  )r   r:  rH  z_C.Valuer  r^  )r  r   rc   r^  rb   r1  )r  r9  r  r   )r   r7  r   r:  r{   r9  r   r   r  zdict[_C.Value, _C.Value]r  zset[_C.Value]r  zlist[_C.Node]r  z+_C.Value | Sequence[_C.Value | None] | None)r  r   )r  r   r  r   rc   r^  )r  r   rc   r^  )r9   ztorch.nn.Module | Callabler  r8  )d__doc__
__future__r   
contextlibr7  r   r  r  r4   r   r   r   r   r   r	   r>   torch._C._onnxr
   _onnxr+   torch.jit._tracetorch.serialization
torch.onnxr   r   r   r   r   torch.onnx._globalsr   torch.onnx._internalr   r   r   r   __all__r   r4  contextmanagerr   r   r   r   r^   r,   r8   rm   rn   r   r}   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r0  r5  r<  quint8uint8qint8int8qint32int32quint4x2r?  r   rZ  rt  _disable_dynamo
deprecatedr   r   r  r  r  rq   rk  rc  r  r  r  r  r   r  r  r!  r    r!   r  r   r$   r%   r&   <module>rP     s   #    	   E E          ( W W""  ,- ,-^  < % % < <
! 3  %)%,%9%9%>%>(,)-8?8S8S8X8X $ $ /3.2LQ")ZNZ
(Z Z
 "Z Z Z #Z &Z 'Z 6Z Z ZZ" "-#Z$ ,%Z& "J'Z( )Z* 
+Zz
12 */"kk5k #'k 	k\':
(!,(5( (V$H#T (,77
 &7 7t("<	
00*50*=J0*I0*f" 
LL%++	KK	LL%++	NNEJJ	 (
   4499!&!!&&A)	A)H .RS !!&& 4499 $!I
 T I
X .IJ &-%9%9%>%> $	A" #A" 	A"
  A" KA"HJ3J!IJ JZ,
8 !!&& 4499 $',)A& "%'AH	8=>2#'
!9T*1  !4499ooo o 	o
 
"o !o o 1od
 QQQ Q<C$)+Xr%   