code: def parse_protobuf(self, protobuf_data):  # noqa: C901
      self.schema_version = protobuf_data.get_version()
      self.span_idx = str(protobuf_data.get_span_indx())
      try:
          self.device_infos = {
              device_id: {
                  "name": device_property.name,
                  "totalGlobalMem": device_property.total_memory,
                  "computeMajor": device_property.major,
                  "computeMinor": device_property.minor,
              }
              for device_id, device_property in protobuf_data.get_device_property().items()
          }
      except Exception:
          print(
              "paddlepaddle-gpu version is needed to get GPU device informations."
          )
          self.device_infos = {}
      self.extra_info = protobuf_data.get_extra_info()
      self.start_in_timeline_ns = float("inf")
      self.has_hostnodes = False
      self.has_devicenodes = False
      self.has_memnodes = False
      node_trees = protobuf_data.get_data()
      new_node_trees = {}
      for threadid, root in node_trees.items():
          stack = []
          new_stack = []
          new_root = HostNode.from_protobuf(root)
          new_node_trees[threadid] = new_root
          stack.append(root)
          new_stack.append(new_root)
          while stack:
              current_node = stack.pop()
              new_current_node = new_stack.pop()
              for child_node in current_node.children_node:
                  if self.has_hostnodes is False:
                      self.has_hostnodes = True
                  new_child_node = HostNode.from_protobuf(child_node)
                  new_current_node.children_node.append(new_child_node)
                  stack.append(child_node)
                  new_stack.append(new_child_node)
              for runtime_node in current_node.runtime_node:
                  new_runtime_node = HostNode.from_protobuf(
                      runtime_node
                  )
                  new_current_node.runtime_node.append(new_runtime_node)
                  for device_node in runtime_node.device_node:
                      new_device_node = DeviceNode.from_protobuf(
                          device_node
                      )
                      new_runtime_node.device_node.append(
                          new_device_node
                      )
              for mem_node in current_node.mem_node:
                  new_mem_node = MemNode.from_protobuf(mem_node)
                  new_current_node.mem_node.append(new_mem_node)
      new_node_tree_list = traverse_tree(new_node_trees)
      for threadid, node_tree_list in new_node_tree_list.items():
          for node in node_tree_list[1:]:  # skip root
              if node.start_ns < self.start_in_timeline_ns:
                  self.start_in_timeline_ns = node.start_ns
      for threadid, node_tree_list in new_node_tree_list.items():
          for node in node_tree_list:
              if node != node_tree_list[0]:  # skip root
                  node.start_ns -= self.start_in_timeline_ns
                  node.end_ns -= self.start_in_timeline_ns
              for runtimenode in node.runtime_node:
                  runtimenode.end_ns -= self.start_in_timeline_ns
                  runtimenode.start_ns -= self.start_in_timeline_ns
                  for device_node in runtimenode.device_node:
                      if self.has_devicenodes is False:
                          self.has_devicenodes = True
                      device_node.start_ns -= self.start_in_timeline_ns
                      device_node.end_ns -= self.start_in_timeline_ns
              for mem_node in node.mem_node:
                  if self.has_memnodes is False:
                      self.has_memnodes = True
                  mem_node.timestamp_ns -= self.start_in_timeline_ns
      self.data = new_node_trees
  
imports: import collections
  import functools
  import json
  import re
  import sys
  import tempfile
  from .utils import traverse_tree
label_desc: Use image node_id 3 for calling the ProfilerResult obj's underlying member method code with example usage: obj.parse_protobuf(protobuf_data) without return types