class_docstr: The main class template to implement a recommendation metric.
  This class contains the recommendation tasks information (RecTaskInfo) and
  the actual computation object (RecMetricComputation). RecMetric processes
  all the information related to RecTaskInfo and models, and passes the required
  signals to the computation object, allowing the implementation of
  RecMetricComputation to focus on the mathematical meaning.
  
  A new metric that inherits RecMetric must override the following attributes
  in its own `__init__()`: `_namespace` and `_metrics_computations`. No other
  methods should be overridden.
  
  Args:
      world_size (int): the number of trainers.
      my_rank (int): the rank of this trainer.
      batch_size (int): batch size used by this trainer.
      tasks (List[RecTaskInfo]): the information of the model tasks.
      compute_mode (RecComputeMode): the computation mode. See RecComputeMode.
      window_size (int): the window size for the window metric.
      fused_update_limit (int): the maximum number of updates to be fused.
      compute_on_all_ranks (bool): whether to compute metrics on all ranks. This
          is necessary if the non-leader rank wants to consume global metrics result.
      should_validate_update (bool): whether to check the inputs of `update()` and
          skip the update if the inputs are invalid. Invalid inputs include the case
          where all examples have 0 weights for a batch.
      process_group (Optional[ProcessGroup]): the process group used for the
          communication. Will use the default process group if not specified.
  
  Example::
  
      ne = NEMetric(
          world_size=4,
          my_rank=0,
          batch_size=128,
          tasks=DefaultTaskInfo,
      )
class_docstr_tok: ["The","main","class","template","to","implement","a","recommendation","metric",".","This","class","contains","the","recommendation","tasks","information","(","RecTaskInfo",")","and","the","actual","computation","object","(","RecMetricComputation",")",".","RecMetric","processes","all","the","information","related","to","RecTaskInfo","and","models",",","and","passes","the","required","signals","to","the","computation","object",",","allowing","the","implementation","of","RecMetricComputation","to","focus","on","the","mathematical","meaning",".","A","new","metric","that","inherits","RecMetric","must","override","the","following","attributes","in","its","own","`","__init__","(",")","`",":","`","_namespace","`","and","`","_metrics_computations","`",".","No","other","methods","should","be","overridden",".","Args",":","world_size","(","int",")",":","the","number","of","trainers",".","my_rank","(","int",")",":","the","rank","of","this","trainer",".","batch_size","(","int",")",":","batch","size","used","by","this","trainer",".","tasks","(","List","[","RecTaskInfo","]",")",":","the","information","of","the","model","tasks",".","compute_mode","(","RecComputeMode",")",":","the","computation","mode",".","See","RecComputeMode",".","window_size","(","int",")",":","the","window","size","for","the","window","metric",".","fused_update_limit","(","int",")",":","the","maximum","number","of","updates","to","be","fused",".","compute_on_all_ranks","(","bool",")",":","whether","to","compute","metrics","on","all","ranks",".","This","is","necessary","if","the","non-leader","rank","wants","to","consume","global","metrics","result",".","should_validate_update","(","bool",")",":","whether","to","check","the","inputs","of","`","update","(",")","`","and","skip","the","update","if","the","inputs","are","invalid",".","Invalid","inputs","include","the","case","where","all","examples","have","0","weights","for","a","batch",".","process_group","(","Optional","[","ProcessGroup","]",")",":","the","process","group","used","for","the","communication",".","Will","use","the","default","process","group","if","not","specified",".","Example",":",":","ne","=","NEMetric","(","world_size=4",",","my_rank=0",",","batch_size=128",",","tasks=DefaultTaskInfo",",",")"]
code: def _unfused_tasks_iter(self, compute_scope: str) -> ComputeIterType:
      for task, metric_computation in zip(
          self._tasks, self._metrics_computations
      ):
          metric_computation.pre_compute()
          for metric_report in getattr(
              metric_computation, compute_scope + "compute"
          )():
              # The attribute has_valid_update is a tensor with only 1 value
              # corresponding to whether the task has valid updates or not.
              # If there's no valid update, the calculated metric_report.value
              # will be meaningless, so we mask it with the default value, i.e. 0.
              valid_metric_value = (
                  metric_report.value
                  if not self._should_validate_update
                  or metric_computation.has_valid_update[0] > 0
                  else torch.zeros_like(metric_report.value)
              )
              yield task, metric_report.name, valid_metric_value, compute_scope + metric_report.metric_prefix.value, metric_report.description
  
imports: import abc
  import itertools
  import math
  from collections import defaultdict, deque
  from dataclasses import dataclass
  from enum import Enum
  from typing import Any, Callable, cast, Deque, Dict, Iterator, List, Mapping, Optional, Sequence, Set, Tuple, Type, TypeVar, Union
  import torch
  import torch.distributed
  import torch.nn
  from torch.profiler import record_function
  from torchmetrics import Metric
  from torchrec.distributed.types import get_tensor_size_bytes
  from torchrec.metrics.metrics_config import RecComputeMode, RecTaskInfo
  from torchrec.metrics.metrics_namespace import compose_metric_key, MetricNameBase, MetricNamespaceBase, MetricPrefix
label_desc: Use image node_id 5 for calling the RecMetric obj's underlying member method code with example usage: obj._unfused_tasks_iter(compute_scope) without return types