code: def get_torch_op_time(
      events: List[profiler_util.FunctionEvent], attr: str
  ) -> Union[int, float]:
      """Get time torch operators spent executing for a list of events.
  
      :param events: list of events.
      :param attr: a FunctionEvent attribute. Expecting one of "cpu_time_total", "cuda_time_total".
      """
      if attr not in ["cpu_time_total", "cuda_time_total"]:
          return -1
  
      total = 0
      for e in events:
          # Possible trace_names are torch ops, or tagged code blocks by LudwigProfiler (which are
          # prepended with LUDWIG_TAG).
          if LUDWIG_TAG not in e.trace_name:
              total += getattr(e, attr)
          else:
              total += get_torch_op_time(e.cpu_children, attr)
      return total
  
file_path: ludwig/ludwig/benchmarking/reporting.py
imports: from collections import Counter, defaultdict
  from statistics import mean
  from typing import Any, Dict, List, Tuple, Union
  import torch
  from torch._C._autograd import _KinetoEvent
  from torch.autograd import DeviceType, profiler_util
  from ludwig.benchmarking.profiler_dataclasses import DeviceUsageMetrics, SystemResourceMetrics, TorchProfilerMetrics
  from ludwig.constants import LUDWIG_TAG
label_desc: Use image node_id 4 for calling a global function with example usage: get_torch_op_time(events, attr) and returns: total, unknown