code: def convert_to_onnx_node(self, function):
      if isinstance(function, chainer.function.FunctionAdapter):
          function = function.function
      func_name = getattr(
          function,
          "custom_function_node_name",
          function.__class__.__name__,
      )
      base_func_name = "{}_{}".format(
          func_name, self.func_name_counts[func_name]
      )
      self.func_name_counts[func_name] += 1
  
      input_names = []
      for input_var in function.inputs:
          # 'input_var' is a VariableNode,
          # so check if it has a Variable/Parameter
          var = input_var.get_variable_or_none()
          if var is None:  # No reference to Variable/Parameter
              # Use VariableNode as is
              input_name = self.context.get_name(input_var)
          else:  # It is a parameter inside a Link or network input
              input_name = self.context.get_name(var)
              if (
                  input_name not in self.explicit_input_names
                  and input_name not in self.outputs
              ):
                  # register input variables to check implicit inputs
                  self.context.implicit_inputs[input_name] = var
          input_names.append(input_name)
  
      # This is to get corresponding VariableNode id from the output
      # Variable of the network
      output_names = []
      for i, output_ref in enumerate(function.outputs):
          if output_ref() is None:
              var = output_ref
          else:
              var = output_ref().get_variable_or_none()
              if var is None:
                  var = output_ref()
          output_name = self.context.get_name(var)
  
          # The context sets unique names on node and param, like "v1".
          # To be more understandable, change the names like function name
          # + number like "FuncitionName_0"
          if not self.context.is_pinned(var):
              if len(function.outputs) == 1:
                  new_name = base_func_name
              else:
                  new_name = "{}_{}".format(base_func_name, i)
              if output_name in self.network_outputs:
                  del self.network_outputs[output_name]
                  self.network_outputs[new_name] = var
              self.context.set_name(var, new_name)
              output_name = new_name
          self.outputs.add(output_name)
  
          output_names.append(output_name)
  
      onnx_helper.set_func_name(base_func_name)
      nodes = self.create_node(
          func_name, function, input_names, output_names
      )
      # Insert constants before computation nodes.
      self.graph.extend(self.context.constants)
      self.context.constants.clear()
      self.graph.extend(nodes)
  
file_path: chainer/onnx_chainer/graph.py
imports: import collections
  from collections import OrderedDict
  import heapq
  import chainer
  from onnx_chainer.functions.converter import FunctionConverterParams
  from onnx_chainer import onnx_helper
label_desc: Use image node_id 4 for calling the Graph obj's underlying member method code with example usage: obj.convert_to_onnx_node(function) without return types