class_docstr: Analyse time ranges for each TracerEventType, and summarize the time.
code: def _fill_stage_events(  # noqa: C901
      self, node, stage_idx, should_recursive=True
  ):
      if node.type == "Forward":
          stage_name = "Forward"
          self.has_forward = True
      elif node.type == "Backward":
          stage_name = "Backward"
      elif node.type == "Optimization":
          stage_name = "Optimization"
      elif node.type == "Dataloader":
          stage_name = "Dataloader"
      else:
          stage_name = "Other"
  
      if should_recursive:
          stack = []
          if node.type in StageType:
              for children in node.children_node:
                  stack.append(children)
          else:
              stack.append(node)
          while stack:
              current_node = stack.pop()
              for childnode in current_node.children_node:
                  stack.append(childnode)
              for runtimenode in current_node.runtime_node:
                  self.events_per_stage[stage_name]["CPU"][stage_idx][
                      runtimenode.thread_id
                  ][runtimenode.type]["events"].append(runtimenode)
                  self.events_per_stage[stage_name]["CPU"][stage_idx][
                      runtimenode.thread_id
                  ][runtimenode.type]["times"].append(
                      (runtimenode.start_ns, runtimenode.end_ns)
                  )
                  self.events_per_stage[stage_name]["CPU"]["ALL"][
                      runtimenode.thread_id
                  ][runtimenode.type]["events"].append(runtimenode)
                  self.events_per_stage[stage_name]["CPU"]["ALL"][
                      runtimenode.thread_id
                  ][runtimenode.type]["times"].append(
                      (runtimenode.start_ns, runtimenode.end_ns)
                  )
                  for devicenode in runtimenode.device_node:
                      self.has_device = True
                      self.events_per_stage[stage_name]["GPU"][
                          stage_idx
                      ][devicenode.stream_id][devicenode.type][
                          "events"
                      ].append(
                          devicenode
                      )
                      self.events_per_stage[stage_name]["GPU"][
                          stage_idx
                      ][devicenode.stream_id][devicenode.type][
                          "times"
                      ].append(
                          (devicenode.start_ns, devicenode.end_ns)
                      )
                      self.events_per_stage[stage_name]["GPU"]["ALL"][
                          devicenode.stream_id
                      ][devicenode.type]["events"].append(devicenode)
                      self.events_per_stage[stage_name]["GPU"]["ALL"][
                          devicenode.stream_id
                      ][devicenode.type]["times"].append(
                          (devicenode.start_ns, devicenode.end_ns)
                      )
              if (
                  current_node.type == "Forward"
                  or current_node.type == "UserDefined"
              ):
                  continue
              node_type = current_node.type
              if node_type == "PythonUserDefined":
                  node_type = "UserDefined"
              self.events_per_stage[stage_name]["CPU"][stage_idx][
                  current_node.thread_id
              ][node_type]["events"].append(current_node)
              self.events_per_stage[stage_name]["CPU"][stage_idx][
                  current_node.thread_id
              ][node_type]["times"].append(
                  (current_node.start_ns, current_node.end_ns)
              )
              self.events_per_stage[stage_name]["CPU"]["ALL"][
                  current_node.thread_id
              ][node_type]["events"].append(current_node)
              self.events_per_stage[stage_name]["CPU"]["ALL"][
                  current_node.thread_id
              ][node_type]["times"].append(
                  (current_node.start_ns, current_node.end_ns)
              )
  
      else:
          for runtimenode in node.runtime_node:
              self.events_per_stage[stage_name]["CPU"][stage_idx][
                  runtimenode.thread_id
              ][runtimenode.type]["events"].append(runtimenode)
              self.events_per_stage[stage_name]["CPU"][stage_idx][
                  runtimenode.thread_id
              ][runtimenode.type]["times"].append(
                  (runtimenode.start_ns, runtimenode.end_ns)
              )
              self.events_per_stage[stage_name]["CPU"]["ALL"][
                  runtimenode.thread_id
              ][runtimenode.type]["events"].append(runtimenode)
              self.events_per_stage[stage_name]["CPU"]["ALL"][
                  runtimenode.thread_id
              ][runtimenode.type]["times"].append(
                  (runtimenode.start_ns, runtimenode.end_ns)
              )
              for devicenode in runtimenode.device_node:
                  self.has_device = True
                  self.events_per_stage[stage_name]["GPU"][stage_idx][
                      devicenode.stream_id
                  ][devicenode.type]["events"].append(devicenode)
                  self.events_per_stage[stage_name]["GPU"][stage_idx][
                      devicenode.stream_id
                  ][devicenode.type]["times"].append(
                      (devicenode.start_ns, devicenode.end_ns)
                  )
                  self.events_per_stage[stage_name]["GPU"]["ALL"][
                      devicenode.stream_id
                  ][devicenode.type]["events"].append(devicenode)
                  self.events_per_stage[stage_name]["GPU"]["ALL"][
                      devicenode.stream_id
                  ][devicenode.type]["times"].append(
                      (devicenode.start_ns, devicenode.end_ns)
                  )
  
imports: import collections
  from .utils import merge_ranges
  from .utils import merge_self_ranges
  from .utils import rebuild_node_trees
  from .utils import sum_ranges
  from .utils import traverse_tree
label_desc: Use image node_id 3 for calling the OverviewParser obj's underlying member method code with example usage: obj._fill_stage_events(node, stage_idx, should_recursive) without return types