def _process_node(
        name: str,
        node_proto: NodeProto,
        nodes: dict[str, OnnxNode],
        ios: dict[str, OnnxIO],
        connections: dict[str, list[str]],
        graph_idx: int,
        overwrite_input_initializers: bool = False,
    ):
        """Process a node and populate the nodes and connections attributes.

        :param node_proto: ONNX node.
        :param nodes: dictionary to store the nodes.
        :param ios: dictionary to store the inputs, outputs, and initializers.
        :param connections: dictionary to store the connections between nodes.
        :param graph_idx: index of the graph in the model.
        :param overwrite_input_initializers: whether to overwrite the inputs and/or initializers if a node
            output is already present as an one. If False, it will raise an error.
        """
        onnx_node = OnnxNode(
            proto=node_proto,
            op_type=node_proto.op_type,
            inputs=list(node_proto.input),
            outputs=list(node_proto.output),
            graph_idx=graph_idx,
        )
        nodes[name] = onnx_node

        for i in node_proto.input:
            if i == "":
                # some nodes have unnamed, unused inputs
                continue
            if i not in ios:
                raise ValueError(
                    f"Input {i} does not exist in the graph. Please process the nodes in topological order."
                )
            ios[i].destination.append(name)
            parent = ios[i].source
            if not SpecialInput.is_special_input(parent):
                connections[parent].append(name)

        for o in node_proto.output:
            if o == "":
                # some nodes have unnamed, unused outputs
                continue
            if o not in ios:
                ios[o] = OnnxIO(graph_idx=graph_idx)
            elif ios[o].source is not None and not (
                overwrite_input_initializers and SpecialInput.is_special_input(ios[o].source)
            ):
                # if the output's original source is an input/initializer, we can overwrite it
                raise ValueError(f"Output {o} is already connected to another node.")
            ios[o].source = name
            for destination in ios[o].destination:
                connections[name].append(destination)
Process a node and populate the nodes and connections attributes.

        :param node_proto: ONNX node.
        :param nodes: dictionary to store the nodes.
        :param ios: dictionary to store the inputs, outputs, and initializers.
        :param connections: dictionary to store the connections between nodes.
        :param graph_idx: index of the graph in the model.
        :param overwrite_input_initializers: whether to overwrite the inputs and/or initializers if a node
            output is already present as an one. If False, it will raise an error.
        
olive/passes/onnx/onnx_dag.py