class_docstr: Mixin that provides save and load functionalities.
code: def __load(self, dirname: str, ancestors: List[Any]) -> None:
      map_location = (
          torch.device("cpu") if not torch.cuda.is_available() else None
      )
      ancestors.append(self)
      for attr in self.saved_attributes:
          assert hasattr(self, attr)
          attr_value = getattr(self, attr)
          if attr_value is None:
              continue
          if isinstance(attr_value, AttributeSavingMixin):
              assert not any(
                  attr_value is ancestor for ancestor in ancestors
              ), "Avoid an infinite loop"
              attr_value.load(os.path.join(dirname, attr))
          else:
              if isinstance(
                  attr_value,
                  (
                      torch.nn.parallel.DistributedDataParallel,
                      torch.nn.DataParallel,
                  ),
              ):
                  attr_value = attr_value.module
              attr_value.load_state_dict(
                  torch.load(
                      os.path.join(dirname, "{}.pt".format(attr)),
                      map_location,
                  )
              )
      ancestors.pop()
  
imports: import contextlib
  import os
  from abc import ABCMeta, abstractmethod, abstractproperty
  from typing import Any, List, Optional, Sequence, Tuple
  import torch
label_desc: Use image node_id 5 for calling the AttributeSavingMixin obj's underlying member method code with example usage: obj.__load(dirname, ancestors) without return types