          if is_live and self._carry_over:
              logger.debug("Processing carry over: %s", self._carry_over)
              self._collect_carry_over(data)
  
          times, loss = zip(*[(data[idx].get("timestamp"), data[idx].get("loss", []))
                              for idx in sorted(data)])
          times, loss = self._process_data(data, times, loss, is_live)
  
          if is_live and not all(len(val) == len(self._loss_labels) for val in loss):
              # TODO Many attempts have been made to fix this for live graph logging, and the issue
              # of non-consistent loss record sizes keeps coming up. In the meantime we shall swallow
              # any loss values that are of incorrect length so graph remains functional. This will,
 
</s> remove         if not is_live or (is_live and not self._data.get(session_id, None)):
            self._data[session_id] = dict(labels=self._loss_labels,
                                          loss=zlib.compress(loss),
                                          loss_shape=loss.shape,
                                          timestamps=zlib.compress(timestamps),
                                          timestamps_shape=timestamps.shape)
 </s> add         if not is_live or (is_live and not self._data.get(session_id)):
            self._data[session_id] = _CacheData(self._loss_labels, timestamps, loss) </s> remove         loss = list(loss)
        timestamps = list(timestamps)
 </s> add         timestamps, loss = zip(*[(data[idx].timestamp, data[idx].loss)
                               for idx in sorted(data)]) </s> remove         if self.is_conda:  # Conda handles Cuda and cuDNN so nothing to do here
 </s> add         if self._env.is_conda:  # Conda handles Cuda and cuDNN so nothing to do here </s> remove         self.required_packages = [pkg for pkg in self.required_packages
                                  if not pkg[0].startswith("tensorflow-rocm")]
 </s> add         self._required_packages = [pkg for pkg in self._required_packages
                                   if not pkg[0].startswith("tensorflow-rocm")] </s> remove     def _process_data(self, data, timestamps, loss, is_live):
 </s> add     def _process_data(self,
                      data: Dict[int, EventData],
                      is_live: bool) -> Tuple[List[float], List[List[float]]]:
        times, loss = self._process_data(data, is_live)
          if is_live and self._carry_over:
              logger.debug("Processing carry over: %s", self._carry_over)
              self._collect_carry_over(data)
  
        times, loss = self._process_data(data, is_live)
        times, loss = self._process_data(data, is_live)
        times, loss = self._process_data(data, is_live)
  
          if is_live and not all(len(val) == len(self._loss_labels) for val in loss):
              # TODO Many attempts have been made to fix this for live graph logging, and the issue
              # of non-consistent loss record sizes keeps coming up. In the meantime we shall swallow
              # any loss values that are of incorrect length so graph remains functional. This will,
keep keep keep keep replace replace replace keep keep keep keep keep
 Bugfixes
  - plugin.train.unbalanced - decoder b
  - gui.stats - crash when log folder deleted
  - setup.py - install gcc=12.1.0 on linux (scipy dep)
  - setup.py - don't test ROCm unless valid
  - typofix - cli_args extract singleprocess help
typing
  - lib.gui.analysis.event_reader
  - lib.gpu_stats.directml - make platform specific
unit tests
  - lib.gui.analysis.event_reader 
lib/gui/analysis/event_reader.py