class_docstr: Measures time (resets if given interval elapses) on rank 0
  and propagates result to other ranks.
  Propagation is done asynchronously from previous step
  in order to avoid blocking of a training process.
code: def __init__(
      self, interval: datetime.timedelta, cpu_pg: dist.ProcessGroup
  ) -> None:
      self._interval = interval
      self._cpu_pg = cpu_pg
      self._prev_time: float = perf_counter()
      self._timeout_tensor: torch.Tensor = torch.zeros(
          1, dtype=torch.int
      )
      # pyre-fixme[34]: `Variable[AsyncOperator]` isn't present in the function's parameters.
      self._prev_work: Optional[AsyncOperator] = None
  
imports: import datetime
  import logging
  import os
  from collections import defaultdict
  from contextlib import contextmanager
  from time import perf_counter
  from typing import Any, Dict, Generator, List, Optional, Protocol, runtime_checkable, Sequence, Tuple, TypeVar
  import numpy
  import torch
  import torch.distributed
  from tabulate import tabulate
  from torchtnt.utils.distributed import PGWrapper
label_desc: Use image node_id 1 to create a new FullSyncPeriodicTimer object  with example: obj = FullSyncPeriodicTimer(interval, cpu_pg)