class_docstr: Create an experiment with time/memory checkpoints
docstr: Print memory stats 
docstr_tok: ["Print","memory","stats"]
code: def print_state(self):
      """Print memory stats"""
  
      if 1:  # align
          cpu_ram_total, cpu_ram_free, cpu_ram_used = self.cpu_ram()
          cpu_ram_util = (
              cpu_ram_used / cpu_ram_total * 100
              if cpu_ram_total
              else 100
          )
          vals = [cpu_ram_total, cpu_ram_free, cpu_ram_used]
      if self.backend != "cpu":
          gpu_ram_total, gpu_ram_free, gpu_ram_used = self.gpu_ram()
          gpu_ram_util = (
              gpu_ram_used / gpu_ram_total * 100
              if gpu_ram_total
              else 100
          )
          vals += [gpu_ram_total, gpu_ram_free, gpu_ram_used]
  
      w = int2width(*map(b2mb, vals)) + 1  # some air
  
      print("\n*** Current state:")
      print(
          f"RAM: {'Used':>{w}} {'Free':>{w}} {'Total':>{w}}    {'Util':>{w}}"
      )
      if 1:
          print(
              f"CPU: {b2mb(cpu_ram_used):{w},.0f} {b2mb(cpu_ram_free):{w},.0f} {b2mb(cpu_ram_total):{w},.0f} MB {cpu_ram_util:6.2f}% "
          )
      if self.backend != "cpu":
          print(
              f"GPU: {b2mb(gpu_ram_used):{w},.0f} {b2mb(gpu_ram_free):{w},.0f} {b2mb(gpu_ram_total):{w},.0f} MB {gpu_ram_util:6.2f}% "
          )
  
imports: import gc
  import logging
  import os
  import psutil
  import sys
  import threading
  import time
  import weakref
  from IPython import get_ipython
  from IPython.core.magics.namespace import NamespaceMagics
  from collections import namedtuple
  from .cell_logger import CellLogger, b2mb, int2width, get_nvml_gpu_id
label_desc: Use image node_id 22 for calling the IPyExperiments obj's underlying member method code with example usage: obj.print_state() without return types