  
  class GPUStats():
      """ Holds information about system GPU(s) """
      def __init__(self, log=True):
          self.logger = None
          if log:
              # Logger is held internally, as we don't want to log
              # when obtaining system stats on crash
              self.logger = logging.getLogger(__name__)  # pylint: disable=invalid-name
              self.logger.debug("Initializing %s", self.__class__.__name__)
  
          self.plaid = None
          self.initialized = False
          self.device_count = 0
          self.active_devices = list()
          self.handles = list()
          self.driver = None
          self.devices = list()
          self.vram = None
  
          self.initialize(log)
  
          self.driver = self.get_driver()
          self.devices = self.get_devices()
          self.vram = self.get_vram()
          if not self.active_devices:
              if self.logger:
                  self.logger.warning("No GPU detected. Switching to CPU mode")
              return
  
          self.shutdown()
          if self.logger:
              self.logger.debug("Initialized %s", self.__class__.__name__)
 
</s> remove     """ Holds information about system GPU(s) """
 </s> add     """ Holds information and statistics about the GPU(s) available on the currently
    running system.

    Parameters
    ----------
    log: bool, optional
        Whether the class should output information to the logger. There may be occasions where the
        logger has not yet been set up when this class is queried. Attempting to log in these
        instances will raise an error. If GPU stats are being queried prior to the logger being
        available then this parameter should be set to ``False``. Otherwise set to ``True``.
        Default: ``True``
    """ </s> remove         self.shutdown()
        if self.logger:
            self.logger.debug("Initialized %s", self.__class__.__name__)
 </s> add         self._shutdown()
        self._log("debug", "Initialized {}".format(self.__class__.__name__))

    @property
    def device_count(self):
        """int: The number of GPU devices discovered on the system. """
        return self._device_count

    @property
    def _is_plaidml(self):
        """ bool: ``True`` if the backend is plaidML otherwise ``False``. """
        return self._plaid is not None </s> remove                 self.active_devices = list(range(self.device_count))
            if self.logger:
                self.logger.debug("Active GPU Devices: %s", self.active_devices)

    def get_handles(self):
        """ Return all listed Nvidia handles """
        if self.plaid is not None:
            self.handles = self.plaid.devices
 </s> add                 self._active_devices = list(range(self._device_count))
            self._log("debug", "Active GPU Devices: {}".format(self._active_devices))

    def _get_handles(self):
        """ Obtain the internal handle identifiers for the system GPUs and allocate to
        :attr:`_handles`. """
        if self._is_plaidml:
            self._handles = self._plaid.devices </s> remove             self.initialized = False
 </s> add             self._initialized = False </s> remove             self.initialized = True
            self.get_device_count()
            self.get_active_devices()
            self.get_handles()

    def shutdown(self):
        """ Shutdown pynvml """
        if self.initialized:
            self.handles = list()
            if not IS_MACOS and not self.plaid:
 </s> add             self._initialized = True
            self._get_device_count()
            self._get_active_devices()
            self._get_handles()

    def _shutdown(self):
        """ Shutdown pynvml if it was the library used for obtaining stats and set
        :attr:`_initialized` back to ``False``. """
        if self._initialized:
            self._handles = list()
            if not IS_MACOS and not self._is_plaidml:
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
  
  class GPUStats():
      """ Holds information about system GPU(s) """
      def __init__(self, log=True):
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
        # Logger is held internally, as we don't want to log when obtaining system stats on crash
        self._logger = logging.getLogger(__name__) if log else None
        self._log("debug", "Initializing {}".format(self.__class__.__name__))

        self._plaid = None
        self._initialized = False
        self._device_count = 0
        self._active_devices = list()
        self._handles = list()
        self._driver = None
        self._devices = list()
        self._vram = None

        self._initialize(log)

        self._driver = self._get_driver()
        self._devices = self._get_devices()
        self._vram = self._get_vram()
        if not self._active_devices:
            self._log("warning", "No GPU detected. Switching to CPU mode")
              return
  
          self.shutdown()
          if self.logger:
              self.logger.debug("Initialized %s", self.__class__.__name__)
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Core Updates (#1015)

- Remove lib.utils.keras_backend_quiet and replace with get_backend() where relevant
- Document lib.gpu_stats and lib.sys_info
- Remove call to GPUStats.is_plaidml from convert and replace with get_backend()
- lib.gui.menu - typofix 
lib/gpu_stats.py