class_docstr: Saves checkpoints and recovers from them.
  
  Arguments:
  
  checkpoints_dir : str, pathlib.Path
      Path to directory where to save checkpoints.
  recoverables : mapping, optional
      Objects to to recover. They need a (unique) name: this is used
      to connect the parameters in a checkpoint to the correct recoverable.
      The name is also used in the filename of the
      savefile for the objects parameters. These can also be added with
      add_recoverable or add_recoverables or just modifying
      checkpointer.recoverables directly.
  custom_load_hooks : mapping, optional
      A mapping from name [same as in recoverables] to function or method.
      Sets a custom loading hook for a particular object. The
      function/method must be callable with signature (instance, path)
      using positional arguments. This is satisfied by for example:
      `def loader(self, path)`.
  custom_save_hooks : mapping, optional
      Mapping from name [same as in recoverables] to function or method.
      Sets a custom saving hook for a particular object. The
      function/method must be callable with
      signature (instance, path) using positional arguments. This is
      satisfied by for example: def saver(self, path):
  allow_partial_load : bool, optional
      If True, allows loading a checkpoint where a savefile is not found
      for every registered recoverable. In that case, only the found
      savefiles are loaded. When False, loading such a save will raise
      RuntimeError. (default: False)
  
  Example
  -------
  >>> import torch
  >>> #SETUP:
  >>> tempdir = getfixture('tmpdir')
  >>> class Recoverable(torch.nn.Module):
  ...     def __init__(self, param):
  ...         super().__init__()
  ...         self.param = torch.nn.Parameter(torch.tensor([param]))
  ...     def forward(self, x):
  ...         return x * self.param
  >>> recoverable = Recoverable(1.)
  >>> recoverables = {'recoverable': recoverable}
  >>> # SETUP DONE.
  >>> checkpointer = Checkpointer(tempdir, recoverables)
  >>> first_ckpt = checkpointer.save_checkpoint()
  >>> recoverable.param.data = torch.tensor([2.])
  >>> loaded_ckpt = checkpointer.recover_if_possible()
  >>> # Parameter has been loaded:
  >>> assert recoverable.param.data == torch.tensor([1.])
  >>> # With this call, by default, oldest checkpoints are deleted:
  >>> checkpointer.save_and_keep_only()
  >>> assert first_ckpt not in checkpointer.list_checkpoints()
class_docstr_tok: ["Saves","checkpoints","and","recovers","from","them",".","Arguments",":","checkpoints_dir",":","str",",","pathlib.Path","Path","to","directory","where","to","save","checkpoints",".","recoverables",":","mapping",",","optional","Objects","to","to","recover",".","They","need","a","(","unique",")","name",":","this","is","used","to","connect","the","parameters","in","a","checkpoint","to","the","correct","recoverable",".","The","name","is","also","used","in","the","filename","of","the","savefile","for","the","objects","parameters",".","These","can","also","be","added","with","add_recoverable","or","add_recoverables","or","just","modifying","checkpointer.recoverables","directly",".","custom_load_hooks",":","mapping",",","optional","A","mapping","from","name","[","same","as","in","recoverables","]","to","function","or","method",".","Sets","a","custom","loading","hook","for","a","particular","object",".","The","function\/method","must","be","callable","with","signature","(","instance",",","path",")","using","positional","arguments",".","This","is","satisfied","by","for","example",":","`","def","loader","(","self",",","path",")","`",".","custom_save_hooks",":","mapping",",","optional","Mapping","from","name","[","same","as","in","recoverables","]","to","function","or","method",".","Sets","a","custom","saving","hook","for","a","particular","object",".","The","function\/method","must","be","callable","with","signature","(","instance",",","path",")","using","positional","arguments",".","This","is","satisfied","by","for","example",":","def","saver","(","self",",","path",")",":","allow_partial_load",":","bool",",","optional","If","True",",","allows","loading","a","checkpoint","where","a","savefile","is","not","found","for","every","registered","recoverable",".","In","that","case",",","only","the","found","savefiles","are","loaded",".","When","False",",","loading","such","a","save","will","raise","RuntimeError",".","(","default",":","False",")","Example","--","--","--","-",">",">",">","import","torch",">",">",">","#","SETUP",":",">",">",">","tempdir","=","getfixture","(","'tmpdir","'",")",">",">",">","class","Recoverable","(","torch.nn.Module",")",":","...","def","__init__","(","self",",","param",")",":","...","super","(",")",".__init__","(",")","...","self.param","=","torch.nn.Parameter","(","torch.tensor","(","[","param","]",")",")","...","def","forward","(","self",",","x",")",":","...","return","x","*","self.param",">",">",">","recoverable","=","Recoverable","(","1",".",")",">",">",">","recoverables","=","{","'recoverable","'",":","recoverable","}",">",">",">","#","SETUP","DONE",".",">",">",">","checkpointer","=","Checkpointer","(","tempdir",",","recoverables",")",">",">",">","first_ckpt","=","checkpointer.save_checkpoint","(",")",">",">",">","recoverable.param.data","=","torch.tensor","(","[","2",".","]",")",">",">",">","loaded_ckpt","=","checkpointer.recover_if_possible","(",")",">",">",">","#","Parameter","has","been","loaded",":",">",">",">","assert","recoverable.param.data","==","torch.tensor","(","[","1",".","]",")",">",">",">","#","With","this","call",",","by","default",",","oldest","checkpoints","are","deleted",":",">",">",">","checkpointer.save_and_keep_only","(",")",">",">",">","assert","first_ckpt","not","in","checkpointer.list_checkpoints","(",")"]
docstr: Saves a checkpoint.
  
  The whole checkpoint becomes a directory.
  Saves each registered object's parameters in a separate file.
  Also a meta file is added. The meta file by default has just the
  unixtime (seconds since unix epoch), but you can add anything
  relevant yourself. The meta information is later used to pick the
  checkpoint to load.
  
  The value of end_of_epoch is saved in the meta. This can affect how
  epoch counters and dataset iterators load their state.
  
  For multi-process saving there are cases where we may want to run
  saving code on multiple processes (e.g. FSDP where we need to collect
  parameters before saving). This works by creating a save folder
  on the main process and communicating it to all processes, and then
  letting each saver/loader method control whether it should save
  on one or all processes.
  
  Arguments
  ---------
  meta : mapping, optional
      A mapping which is added to the meta file in the checkpoint. The
      key "unixtime" is included by default.
  end_of_epoch : bool, optional
      Whether the checkpoint is at the end of an epoch. True by default.
      May affect loading.
  name : str, optional
      Specify a custom name for your checkpoint.
      The name will still have a prefix added. If no name is given,
      a name is created from a timestamp and a random unique id.
  verbosity : logging level
      Set logging level this save.
  
  Returns
  -------
  Checkpoint
      namedtuple [see above], the saved checkpoint, unless this is run
      on a non-main process, in which case it returns None.
docstr_tok: ["Saves","a","checkpoint",".","The","whole","checkpoint","becomes","a","directory",".","Saves","each","registered","object","'s","parameters","in","a","separate","file",".","Also","a","meta","file","is","added",".","The","meta","file","by","default","has","just","the","unixtime","(","seconds","since","unix","epoch",")",",","but","you","can","add","anything","relevant","yourself",".","The","meta","information","is","later","used","to","pick","the","checkpoint","to","load",".","The","value","of","end_of_epoch","is","saved","in","the","meta",".","This","can","affect","how","epoch","counters","and","dataset","iterators","load","their","state",".","For","multi-process","saving","there","are","cases","where","we","may","want","to","run","saving","code","on","multiple","processes","(","e.g",".","FSDP","where","we","need","to","collect","parameters","before","saving",")",".","This","works","by","creating","a","save","folder","on","the","main","process","and","communicating","it","to","all","processes",",","and","then","letting","each","saver\/loader","method","control","whether","it","should","save","on","one","or","all","processes",".","Arguments","--","--","--","--","-","meta",":","mapping",",","optional","A","mapping","which","is","added","to","the","meta","file","in","the","checkpoint",".","The","key","``","unixtime","''","is","included","by","default",".","end_of_epoch",":","bool",",","optional","Whether","the","checkpoint","is","at","the","end","of","an","epoch",".","True","by","default",".","May","affect","loading",".","name",":","str",",","optional","Specify","a","custom","name","for","your","checkpoint",".","The","name","will","still","have","a","prefix","added",".","If","no","name","is","given",",","a","name","is","created","from","a","timestamp","and","a","random","unique","id",".","verbosity",":","logging","level","Set","logging","level","this","save",".","Returns","--","--","--","-","Checkpoint","namedtuple","[","see","above","]",",","the","saved","checkpoint",",","unless","this","is","run","on","a","non-main","process",",","in","which","case","it","returns","None","."]
code: def save_checkpoint(
      self,
      meta={},
      end_of_epoch=True,
      name=None,
      verbosity=logging.INFO,
  ):
      """Saves a checkpoint.
  
      The whole checkpoint becomes a directory.
      Saves each registered object's parameters in a separate file.
      Also a meta file is added. The meta file by default has just the
      unixtime (seconds since unix epoch), but you can add anything
      relevant yourself. The meta information is later used to pick the
      checkpoint to load.
  
      The value of end_of_epoch is saved in the meta. This can affect how
      epoch counters and dataset iterators load their state.
  
      For multi-process saving there are cases where we may want to run
      saving code on multiple processes (e.g. FSDP where we need to collect
      parameters before saving). This works by creating a save folder
      on the main process and communicating it to all processes, and then
      letting each saver/loader method control whether it should save
      on one or all processes.
  
      Arguments
      ---------
      meta : mapping, optional
          A mapping which is added to the meta file in the checkpoint. The
          key "unixtime" is included by default.
      end_of_epoch : bool, optional
          Whether the checkpoint is at the end of an epoch. True by default.
          May affect loading.
      name : str, optional
          Specify a custom name for your checkpoint.
          The name will still have a prefix added. If no name is given,
          a name is created from a timestamp and a random unique id.
      verbosity : logging level
          Set logging level this save.
  
      Returns
      -------
      Checkpoint
          namedtuple [see above], the saved checkpoint, unless this is run
          on a non-main process, in which case it returns None.
      """
      ckpt_dir = None
      if if_main_process():
          if name is None:
              ckpt_dir = self._new_checkpoint_dirpath()
          else:
              ckpt_dir = self._custom_checkpoint_dirpath(name)
          os.makedirs(ckpt_dir, exist_ok=True)
          saved_meta = self._save_checkpoint_metafile(
              ckpt_dir / METAFNAME, meta, end_of_epoch
          )
  
      # Communicate ckpt_dir to all procs
      communication_list = [ckpt_dir]
      if torch.distributed.is_initialized():
          torch.distributed.broadcast_object_list(
              communication_list, src=0
          )
      ckpt_dir = communication_list[0]
  
      saved_paramfiles = {}
      for name, obj in self.recoverables.items():
          objfname = f"{name}" + PARAMFILE_EXT
          savepath = ckpt_dir / objfname
          saved_paramfiles[name] = savepath
  
          # First see if object has custom save hook:
          if name in self.custom_save_hooks:
              self.custom_save_hooks[name](obj, savepath)
              continue
  
          # Otherwise find the default saver for that type:
          default_hook = get_default_hook(obj, DEFAULT_SAVE_HOOKS)
          if default_hook is not None:
              default_hook(obj, savepath)
              continue
  
          # If we got here, no custom hook or registered default hook
          MSG = f"Don't know how to save {type(obj)}. Register default hook \
                      or add custom hook for this object."
          raise RuntimeError(MSG)
  
      if if_main_process():
          ckpt_type = "end-of-epoch" if end_of_epoch else "intra-epoch"
          logger.log(
              verbosity,
              f"Saved an {ckpt_type} checkpoint in {ckpt_dir}",
          )
          return Checkpoint(ckpt_dir, saved_meta, saved_paramfiles)
  
      # Explicity return None if this is not the main process
      return None
  
imports: import torch
  import collections
  import collections.abc
  import os
  import time
  import yaml
  import pathlib
  import inspect
  import shutil
  import logging
  import warnings
  from packaging import version
  import speechbrain.utils._workarounds
  from speechbrain.utils.distributed import main_process_only, if_main_process, ddp_barrier
label_desc: Use image node_id 4 for calling the Checkpointer obj's underlying member method code with example usage: obj.save_checkpoint(meta, end_of_epoch, name, verbosity) and returns: None, Checkpoint