code: def _add_nodes(
      self,
      graph: Union[ChunkGraph, TileableGraph],
      nodes: List[EntityType],
      visited: Set,
  ):
      # update visited
      visited.update(nodes)
  
      while len(nodes) > 0:
          node = nodes.pop()
          node = self._process_node(node)
  
          # mark node as visited
          visited.add(node)
  
          # add node to graph if possible
          if not graph.contains(node):
              graph.add_node(node)
  
          children = self._select_inputs(node.inputs or [])
          if children:
              node.inputs = children
          for c in children:
              c = self._process_node(c)
              if not graph.contains(c):
                  graph.add_node(c)
              if not graph.has_successor(c, node):
                  graph.add_edge(c, node)
              for out in c.op.outputs:
                  if self._if_add_node(out, visited):
                      nodes.append(out)
  
file_path: mars/mars/core/graph/builder/base.py
imports: from abc import ABC, abstractmethod
  from typing import List, Set, Union, Generator
  from ....typing import EntityType
  from ..entity import EntityGraph, TileableGraph, ChunkGraph
label_desc: Use image node_id 5 for calling the AbstractGraphBuilder obj's underlying member method code with example usage: obj._add_nodes(graph, nodes, visited) without return types