code: def _convert_onnxml(
      model, backend, test_input, device, extra_config={}
  ):
      """
      This function converts the specified [ONNX-ML] model into its *backend* counterpart.
      The supported operators can be found at `hummingbird.ml.supported`.
      """
      assert model is not None
      assert_torch_installed()
  
      import onnx
  
      # The conversion requires some test input for tracing.
      # Test inputs can be either provided or generate from the input schema of the model.
      # Generate some test input if necessary.
      if test_input is None:
          import torch
          from onnxconverter_common.data_types import (
              FloatTensorType,
              DoubleTensorType,
              Int32TensorType,
              Int64TensorType,
          )
  
          tvm_backend = None
          if tvm_installed():
              import tvm
  
              tvm_backend = tvm.__name__
  
          # Get the input information from the ONNX schema.
          initial_types = []
          for input in model.graph.input:
              name = input.name if hasattr(input, "name") else None
              data_type = (
                  input.type.tensor_type.elem_type
                  if hasattr(input, "type")
                  and hasattr(input.type, "tensor_type")
                  and hasattr(input.type.tensor_type, "elem_type")
                  else None
              )
              if name is None:
                  raise RuntimeError(
                      "Cannot fetch input name or data_type from the ONNX schema. Please provide some test input."
                  )
              if data_type is None:
                  raise RuntimeError(
                      "Cannot fetch input data_type from the ONNX schema, or data type is not tensor_type. Please provide some test input."
                  )
              if not hasattr(input.type.tensor_type, "shape"):
                  raise RuntimeError(
                      "Cannot fetch input shape from ONNX schema. Please provide some test input."
                  )
              shape = [
                  dim.dim_value
                  for dim in input.type.tensor_type.shape.dim
              ]
  
              if len(shape) == 1:
                  shape = [1, shape[0]]
              assert len(shape) == 2
              # In ONNX dynamic dimensions will have a shape of 0. Fix the 0-shape in the batch dimension if they exist.
              if shape[0] == 0:
                  shape[0] = 1
  
              if data_type == 1:
                  initial_types.append((name, FloatTensorType(shape)))
              elif data_type == 11:
                  initial_types.append((name, DoubleTensorType(shape)))
              elif data_type == 6:
                  initial_types.append((name, Int32TensorType(shape)))
              elif data_type == 7:
                  initial_types.append((name, Int64TensorType(shape)))
              else:
                  raise RuntimeError(
                      "Input data type {} not supported. Please fill an issue at https://github.com/microsoft/hummingbird/, or pass some test_input".format(
                          data_type
                      )
                  )
  
          first_shape = initial_types[0][1].shape
          assert all(
              map(lambda x: x[1].shape == first_shape, initial_types)
          ), "Hummingbird currently supports only inputs with same shape."
          extra_config[constants.N_INPUTS] = len(initial_types)
          extra_config[constants.N_FEATURES] = (
              extra_config[constants.N_INPUTS] * first_shape[1]
          )
  
          # Generate some random input data if necessary for the model conversion.
          if (
              backend == onnx.__name__
              or backend == tvm_backend
              or backend == torch.jit.__name__
          ):
              test_input = []
              for i, it in enumerate(initial_types):
                  if type(it[1]) is FloatTensorType:
                      test_input.append(
                          np.array(
                              np.random.rand(
                                  first_shape[0], first_shape[1]
                              ),
                              dtype=np.float32,
                          )
                      )
                  elif type(it[1]) is DoubleTensorType:
                      test_input.append(
                          np.random.rand(first_shape[0], first_shape[1])
                      )
                  elif type(it[1]) is Int32TensorType:
                      test_input.append(
                          np.array(
                              np.random.randint(100, size=first_shape),
                              dtype=np.int32,
                          )
                      )
                  elif type(it[1]) is Int64TensorType:
                      test_input.append(
                          np.random.randint(100, size=first_shape)
                      )
                  else:
                      raise RuntimeError(
                          "Type {} not supported. Please fill an issue on https://github.com/microsoft/hummingbird/.".format(
                              type(it[1])
                          )
                      )
              if extra_config[constants.N_INPUTS] == 1:
                  test_input = test_input[0]
              else:
                  test_input = tuple(test_input)
              extra_config[constants.TEST_INPUT] = test_input
  
      # Set the number of features. Some converter requires to know in advance the number of features.
      if (
          constants.N_FEATURES not in extra_config
          and test_input is not None
      ):
          if len(test_input.shape) < 2:
              extra_config[constants.N_FEATURES] = 1
          else:
              extra_config[constants.N_FEATURES] = test_input.shape[1]
  
      # Set the initializers. Some converter requires the access to initializers.
      initializers = (
          {}
          if model.graph.initializer is None
          else {in_.name: in_ for in_ in model.graph.initializer}
      )
      extra_config[constants.ONNX_INITIALIZERS] = initializers
  
      # Force constants.TREE_IMPLEMENTATION="tree_trav" as onnxml has a bug with "gemm".
      extra_config[constants.TREE_IMPLEMENTATION] = "tree_trav"
  
      # Parse ONNX model as our internal data structure (i.e., Topology).
      topology = parse_onnx_api_model(model)
  
      # Convert the Topology object into a PyTorch model.
      hb_model = topology_converter(
          topology,
          backend,
          test_input,
          device,
          extra_config=extra_config,
      )
      return hb_model
  
imports: from copy import deepcopy
  import psutil
  import numpy
  from .operator_converters import constants
  from ._parse import parse_sklearn_api_model, parse_onnx_api_model, parse_sparkml_api_model
  from ._topology import convert
  from ._utils import assert_torch_installed, assert_lightgbm_installed, assert_xgboost_installed, pandas_installed, sparkml_installed, is_pandas_dataframe, is_spark_dataframe, tvm_installed
  from .exceptions import MissingConverter, MissingBackend
  from .supported import backends
  from sklearn.utils import all_estimators
  from sklearn.utils.validation import check_is_fitted
  from .None import operator_converters
  from .supported import xgb_operator_list
  from .supported import lgbm_operator_list
label_desc: Use image node_id 8 for calling a global function with example usage: _convert_onnxml(model, backend, test_input, device, extra_config) and returns: hb_model