class_docstr: Stats for Graphcore IPU devices.
class_docstr_tok: ["Stats","for","Graphcore","IPU","devices","."]
code: def sample(self) -> None:
      try:
          stats = {}
          devices = self._gc_ipu_info.getDevices()
  
          for device in devices:
              device_metrics: Dict[str, str] = dict(device)
  
              pid = device_metrics.get("user process id")
              if pid is None or int(pid) != self._pid:
                  continue
  
              device_id = device_metrics.get("id")
              initial_call = device_id not in self._devices_called
              if device_id is not None:
                  self._devices_called.add(device_id)
  
              for key, value in device_metrics.items():
                  log_metric = (
                      initial_call or key in self.variable_metric_keys
                  )
                  if not log_metric:
                      continue
                  parsed = self.parse_metric(key, value)
                  if parsed is None:
                      continue
                  parsed_key, parsed_value = parsed
                  stats[
                      self.name.format(device_id, parsed_key)
                  ] = parsed_value
  
          self.samples.append(stats)
  
      except Exception as e:
          wandb.termwarn(f"IPU stats error {e}", repeat=False)
  
file_path: wandb/wandb/sdk/internal/system/assets/ipu.py
imports: import threading
  from collections import deque
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union
  import wandb
  from .aggregators import aggregate_mean
  from .asset_registry import asset_registry
  from .interfaces import Interface, Metric, MetricsMonitor
label_desc: Use image node_id 3 for calling the IPUStats obj's underlying member method code with example usage: obj.sample() without return types