docstr: Extract node info from a list of nodes
docstr_tok: ["Extract","node","info","from","a","list","of","nodes"]
code: def _extract_node_info(cls, node: List[Node]) -> Tuple[int, ...]:
      """Extract node info from a list of nodes"""
      xbar = 0
      ftime = 0
      btime = 0
      fwd_mem_peak = 0
      for n in node:
          assert isinstance(n, Node), f"{n} is not a Node"
          if (
              n.target == runtime_apply
              or n.target == runtime_comm_spec_apply
          ):
              # in this case we need to calculate memory usage directly based on the statics that hooked in node.meta
              xbar += n.meta["fwd_mem_out"]
              fwd_mem_peak = max(
                  fwd_mem_peak, xbar + n.meta["fwd_mem_tmp"]
              )
          else:
              xbar += calculate_fwd_tmp(n) + calculate_fwd_out(n)
              fwd_mem_peak = max(
                  fwd_mem_peak,
                  xbar
                  + n.meta["fwd_mem_tmp"]
                  + cls._extract_unused_output(n),
              )
  
          # minimum flop count is required
          ftime += max(calculate_fwd_time(n), 1.0)
          btime += max(calculate_bwd_time(n), 1.0)
  
      x = calculate_fwd_out(node[-1])
      xbar = max(x, xbar)
      ftmp = fwd_mem_peak - xbar
      btmp = cls._extract_btmp(node)
      return ftime, btime, x, xbar, ftmp, btmp
  
imports: from copy import deepcopy
  from typing import Any, List, Tuple
  from torch import Tensor
  from torch.fx import Graph, Node
  from colossalai.auto_parallel.passes.runtime_apply_pass import runtime_apply, runtime_comm_spec_apply
  from colossalai.fx.codegen.activation_checkpoint_codegen import _find_nested_ckpt_regions
  from colossalai.fx.profiler import activation_size, calculate_bwd_time, calculate_fwd_out, calculate_fwd_time, calculate_fwd_tmp
  from colossalai.logging import get_dist_logger
  from .ckpt_solver_base import CheckpointSolverBase
  from .operation import Backward, Chain, ForwardCheck, ForwardEnable, ForwardNograd, Loss, Sequence
label_desc: Use image node_id 6 for calling the CheckpointSolverRotor obj's underlying member method code with example usage: obj._extract_node_info(cls, node) and returns: ftime,  btime,  x,  xbar,  ftmp,  btmp