code: def optimize(self):
      fuses = []
      explored = set()
  
      graph = self._graph
      for node in graph.topological_iter():
          if type(node.op) not in CP_OP:
              continue
          if node in explored:
              continue
          if graph.count_predecessors(node) != 1:
              continue
          if node in graph.results:
              continue
  
          selected = [node]
          # add successors
          cur_node = graph.successors(node)[0]
          while (
              graph.count_predecessors(cur_node) == 1
              and type(cur_node.op) in CP_OP
          ):
              selected.append(cur_node)
              if (
                  graph.count_successors(cur_node) != 1
                  or cur_node in graph.results
              ):
                  break
              else:
                  cur_node = graph.successors(cur_node)[0]
          if len(selected) > 1:
              explored.update(selected)
              fuses.append(list(selected))
  
      return self._fuse_nodes(fuses, TensorCpFuseChunk)
  
file_path: mars/mars/optimization/physical/cupy.py
imports: from ...tensor import arithmetic
  from ...tensor.fuse import TensorCpFuseChunk
  from ...utils import lazy_import
  from .core import RuntimeOptimizer, register_optimizer
label_desc: Use image node_id 2 for calling the CupyRuntimeOptimizer obj's underlying member method code with example usage: obj.optimize() and returns: self