docstr: Compare the results of PyTorch model with exported ONNX model
  
  Args:
      model (_ModelType): PyTorch model
      input_args (Sequence[_InputArgsType]): torch input arguments
      input_kwargs (Mapping[str, _InputArgsType]): torch input kwargs
      rtol (float, optional): relative tolerance. Defaults to 1e-3.
      atol (float, optional): absolute tolerance. Defaults to 1e-7.
      has_mutation (bool, optional): Whether the model mutates its input or state.
          `mutation` as `True` incurs extra overhead of cloning the inputs and model.
          Defaults to False.
      additional_test_inputs: Test the models with another dataset input, which
          is designed for dynamic axes testing. Defaults to None. It's a list of
          different input sets in tuples. Inside tuple, the first element is a tuple
          of args, and the second element is a dict of kwargs. Remember to put comma
          even if the following element is not provided.
          For example,
          additional_test_inputs = [((args1, args2), {"kwargs":1}), ((args1,),), ((), {"kwargs":1})]
      skip_dynamic_shapes_check: Whether to skip dynamic shape check. Defaults to False.
          Must be used when tests do not produce dynamic shapes even when dynamic shape feature is enabled.
          This is needed because Torch Dynamo uses the dynamic_shapes flag as a hint, only.
docstr_tok: ["Compare","the","results","of","PyTorch","model","with","exported","ONNX","model","Args",":","model","(","_ModelType",")",":","PyTorch","model","input_args","(","Sequence","[","_InputArgsType","]",")",":","torch","input","arguments","input_kwargs","(","Mapping","[","str",",","_InputArgsType","]",")",":","torch","input","kwargs","rtol","(","float",",","optional",")",":","relative","tolerance",".","Defaults","to","1e-3",".","atol","(","float",",","optional",")",":","absolute","tolerance",".","Defaults","to","1e-7",".","has_mutation","(","bool",",","optional",")",":","Whether","the","model","mutates","its","input","or","state",".","`","mutation","`","as","`","True","`","incurs","extra","overhead","of","cloning","the","inputs","and","model",".","Defaults","to","False",".","additional_test_inputs",":","Test","the","models","with","another","dataset","input",",","which","is","designed","for","dynamic","axes","testing",".","Defaults","to","None",".","It","'s","a","list","of","different","input","sets","in","tuples",".","Inside","tuple",",","the","first","element","is","a","tuple","of","args",",","and","the","second","element","is","a","dict","of","kwargs",".","Remember","to","put","comma","even","if","the","following","element","is","not","provided",".","For","example",",","additional_test_inputs","=","[","(","(","args1",",","args2",")",",","{","``","kwargs","''",":1","}",")",",","(","(","args1",",",")",",",")",",","(","(",")",",","{","``","kwargs","''",":1","}",")","]","skip_dynamic_shapes_check",":","Whether","to","skip","dynamic","shape","check",".","Defaults","to","False",".","Must","be","used","when","tests","do","not","produce","dynamic","shapes","even","when","dynamic","shape","feature","is","enabled",".","This","is","needed","because","Torch","Dynamo","uses","the","dynamic_shapes","flag","as","a","hint",",","only","."]
code: def run_test_with_fx_to_onnx_exporter_and_onnx_runtime(
      self,
      model: _ModelType,
      input_args: Sequence[_InputArgsType],
      *,
      input_kwargs: Optional[Mapping[str, _InputArgsType]] = None,
      rtol: Optional[float] = 1e-3,
      atol: Optional[float] = 1e-7,
      has_mutation: bool = False,
      additional_test_inputs: Optional[
          List[
              Union[
                  Tuple[
                      Sequence[_InputArgsType],
                      Mapping[str, _InputArgsType],
                  ],
                  Tuple[Sequence[_InputArgsType]],
              ]
          ]
      ] = None,
      skip_dynamic_shapes_check: bool = False,
  ):
      """Compare the results of PyTorch model with exported ONNX model
  
      Args:
          model (_ModelType): PyTorch model
          input_args (Sequence[_InputArgsType]): torch input arguments
          input_kwargs (Mapping[str, _InputArgsType]): torch input kwargs
          rtol (float, optional): relative tolerance. Defaults to 1e-3.
          atol (float, optional): absolute tolerance. Defaults to 1e-7.
          has_mutation (bool, optional): Whether the model mutates its input or state.
              `mutation` as `True` incurs extra overhead of cloning the inputs and model.
              Defaults to False.
          additional_test_inputs: Test the models with another dataset input, which
              is designed for dynamic axes testing. Defaults to None. It's a list of
              different input sets in tuples. Inside tuple, the first element is a tuple
              of args, and the second element is a dict of kwargs. Remember to put comma
              even if the following element is not provided.
              For example,
              additional_test_inputs = [((args1, args2), {"kwargs":1}), ((args1,),), ((), {"kwargs":1})]
          skip_dynamic_shapes_check: Whether to skip dynamic shape check. Defaults to False.
              Must be used when tests do not produce dynamic shapes even when dynamic shape feature is enabled.
              This is needed because Torch Dynamo uses the dynamic_shapes flag as a hint, only.
  
      """
  
      # avoid mutable data structure
      if input_kwargs is None:
          input_kwargs = {}
  
      if (
          has_mutation
          and self.model_type
          != pytorch_test_common.TorchModelType.TORCH_EXPORT_EXPORTEDPROGRAM
      ):
          ref_model = _try_clone_model(model)
          ref_input_args, ref_input_kwargs = _try_clone_inputs(
              input_args, input_kwargs
          )
      else:
          ref_model = model
          ref_input_args = input_args
          ref_input_kwargs = input_kwargs
  
      assert isinstance(ref_model, torch.nn.Module) or callable(
          ref_model
      ), "Model must be a torch.nn.Module or callable"
      if (
          self.model_type
          == pytorch_test_common.TorchModelType.TORCH_EXPORT_EXPORTEDPROGRAM
      ):
          ref_model = torch.export.export(
              ref_model, args=ref_input_args
          )
          if (
              self.dynamic_shapes
          ):  # TODO: Support dynamic shapes for torch.export.ExportedProgram
              #       https://github.com/pytorch/pytorch/issues/113705
              pytest.xfail(
                  reason="torch.export.ExportedProgram does not support dynamic shapes"
              )
  
      # Feed args and kwargs into exporter.
      # Note that exporter should flatten kwargs into positional args the exported model;
      # since ONNX doesn't represent kwargs.
      export_error: Optional[torch.onnx.OnnxExporterError] = None
      try:
          onnx_program = torch.onnx.dynamo_export(
              ref_model,
              *ref_input_args,
              **ref_input_kwargs,
              export_options=torch.onnx.ExportOptions(
                  op_level_debug=self.op_level_debug,
                  dynamic_shapes=self.dynamic_shapes,
                  diagnostic_options=torch.onnx.DiagnosticOptions(
                      verbosity_level=logging.DEBUG
                  ),
              ),
          )
      except torch.onnx.OnnxExporterError as e:
          export_error = e
          onnx_program = e.onnx_program
  
      if diagnostics.is_onnx_diagnostics_log_artifact_enabled():
          onnx_program.save_diagnostics(
              f"test_report_{self._testMethodName}"
              f"_op_level_debug_{self.op_level_debug}"
              f"_dynamic_axes_{self.dynamic_shapes}"
              ".sarif"
          )
  
      if export_error is not None:
          raise export_error
  
      if not skip_dynamic_shapes_check:
          assert_dynamic_shapes(onnx_program, self.dynamic_shapes)
  
      _compare_pytorch_onnx_with_ort(
          onnx_program,
          ref_model,
          input_args,
          input_kwargs,
          atol,
          rtol,
          has_mutation=has_mutation,
      )
      # This confirms the exported mode accepts different input shapes
      # when dynamic shape is enabled.
      if additional_test_inputs and self.dynamic_shapes:
          for another_input in additional_test_inputs:
              if len(another_input) > 2:
                  raise ValueError(
                      f"test_inputs should only have tuple args and dictionary kwargs. But receives: {len(another_input)}"
                  )
              additional_input_args = another_input[0]
              additional_input_kwargs = (
                  another_input[1]
                  if len(another_input) == 2
                  and another_input[1] is not None
                  else {}
              )
              _compare_pytorch_onnx_with_ort(
                  onnx_program,
                  ref_model,
                  additional_input_args,
                  additional_input_kwargs,
                  atol,
                  rtol,
                  has_mutation=has_mutation,
              )
  
imports: from __future__ import annotations
  import contextlib
  import copy
  import dataclasses
  import io
  import logging
  import os
  import unittest
  import warnings
  from typing import Any, Callable, Collection, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, Union
  import numpy
  import onnxruntime
  import pytest
  import pytorch_test_common
  import torch
  from torch import export
  from torch.onnx import _constants, verification
  from torch.onnx._internal import _beartype
  from torch.onnx._internal.fx import diagnostics
  from torch.testing._internal import common_utils
  from torch.testing._internal.opinfo import core
  from torch.types import Number
label_desc: Use image node_id 3 for calling the _TestONNXRuntime obj's underlying member method code with example usage: obj.run_test_with_fx_to_onnx_exporter_and_onnx_runtime(model, input_args) without return types