class_docstr: Adapter Mixin that can augment a ModelPT subclass with Adapter support.
  
  This mixin class should be used only with a top level ModelPT subclass.
  This mixin class adds several utility methods which should be subclassed and overriden to
  propagated to the submodules as necessary.
  
  An Adapter module is any Pytorch nn.Module that possess a few properties :
  
  - It's input and output dimension are the same, while the hidden dimension need not be the same.
  - The final layer of the Adapter module is zero-initialized, so that the residual connection to the adapter
      yields the original output.
  
  This mixin adds the following instance variables to the class this inherits it:
  
      -   `adapter_layer`: A torch.nn.ModuleDict(), whose keys are the names of the adapter (globally unique),
              and values are the Adapter nn.Module().
      -   `adapter_cfg`: A OmegaConf DictConfig object that holds the config of the adapters that are initialized.
      -   `adapter_global_cfg_key`: A str representing a key in the model config that can be provided by the user.
          The value resolves to `global_cfg`, and can be overridden via `model.cfg.adapters.global_cfg.*`.
  
  .. note::
  
      This module **is** responsible for maintaining its config. At the ModelPT level, it will access and
      write Adapter config information to `self.cfg.adapters`.
class_docstr_tok: ["Adapter","Mixin","that","can","augment","a","ModelPT","subclass","with","Adapter","support",".","This","mixin","class","should","be","used","only","with","a","top","level","ModelPT","subclass",".","This","mixin","class","adds","several","utility","methods","which","should","be","subclassed","and","overriden","to","propagated","to","the","submodules","as","necessary",".","An","Adapter","module","is","any","Pytorch","nn.Module","that","possess","a","few","properties",":","-","It","'s","input","and","output","dimension","are","the","same",",","while","the","hidden","dimension","need","not","be","the","same",".","-","The","final","layer","of","the","Adapter","module","is","zero-initialized",",","so","that","the","residual","connection","to","the","adapter","yields","the","original","output",".","This","mixin","adds","the","following","instance","variables","to","the","class","this","inherits","it",":","-","`","adapter_layer","`",":","A","torch.nn.ModuleDict","(",")",",","whose","keys","are","the","names","of","the","adapter","(","globally","unique",")",",","and","values","are","the","Adapter","nn.Module","(",")",".","-","`","adapter_cfg","`",":","A","OmegaConf","DictConfig","object","that","holds","the","config","of","the","adapters","that","are","initialized",".","-","`","adapter_global_cfg_key","`",":","A","str","representing","a","key","in","the","model","config","that","can","be","provided","by","the","user",".","The","value","resolves","to","`","global_cfg","`",",","and","can","be","overridden","via","`","model.cfg.adapters.global_cfg.","*","`",".","..","note",":",":","This","module","*","*","is","*","*","responsible","for","maintaining","its","config",".","At","the","ModelPT","level",",","it","will","access","and","write","Adapter","config","information","to","`","self.cfg.adapters","`","."]
docstr: Add an Adapter module to this model.
  
  Should be overridden by subclass and super() call must be used - this will setup the config.
  After calling super(), forward this call to modules that implement the mixin.
  
  Args:
      name: A globally unique name for the adapter. Will be used to access, enable and disable adapters.
      cfg: A DictConfig that contains at the bare minimum `__target__` to instantiate a new Adapter module.
docstr_tok: ["Add","an","Adapter","module","to","this","model",".","Should","be","overridden","by","subclass","and","super","(",")","call","must","be","used","-","this","will","setup","the","config",".","After","calling","super","(",")",",","forward","this","call","to","modules","that","implement","the","mixin",".","Args",":","name",":","A","globally","unique","name","for","the","adapter",".","Will","be","used","to","access",",","enable","and","disable","adapters",".","cfg",":","A","DictConfig","that","contains","at","the","bare","minimum","`","__target__","`","to","instantiate","a","new","Adapter","module","."]
code: def add_adapter(
      self, name: str, cfg: Union[DictConfig, AdapterConfig]
  ):
      """
      Add an Adapter module to this model.
  
      Should be overridden by subclass and super() call must be used - this will setup the config.
      After calling super(), forward this call to modules that implement the mixin.
  
      Args:
          name: A globally unique name for the adapter. Will be used to access, enable and disable adapters.
          cfg: A DictConfig that contains at the bare minimum `__target__` to instantiate a new Adapter module.
      """
      # Convert to DictConfig from dict or Dataclass
      if is_dataclass(cfg):
          cfg = OmegaConf.structured(cfg)
  
      if not isinstance(cfg, DictConfig):
          cfg = DictConfig(cfg)
  
      # Resolve the module name and adapter name (if provided for the first time)
      module_name, adapter_name = self.resolve_adapter_module_name_(
          name
      )
  
      # Update the model.cfg with information about the new adapter from cfg
      with open_dict(cfg), open_dict(self.cfg):
          # Construct the minimum config required to be updated by adapter implementations
          if "adapters" not in self.cfg:
              self.cfg.adapters = OmegaConf.create({})
  
          self.cfg.adapters = _prepare_default_adapter_config(
              global_key=self.adapter_global_cfg_key,
              meta_key=self.adapter_metadata_cfg_key,
              cfg=self.cfg.adapters,
          )
  
          # If the adapter is not being restored, force unique name to be provided for all adapters.
          if (
              hasattr(self, "_restoring_adapters")
              and self._restoring_adapters is not True
          ):
              if adapter_name in self.cfg.adapters:
                  raise ValueError(
                      f"Attempting to add multiple adapters with the same name ({adapter_name}) !"
                  )
  
          # Inject the module name in the adapter metadata cfg
          gcfg = self.adapter_global_cfg_key
          mcfg = self.adapter_metadata_cfg_key
          self.cfg.adapters[gcfg][mcfg]["modules"][
              adapter_name
          ] = module_name
  
          # By default, enable the adapter that is being added
          if "enabled" not in cfg:
              cfg["enabled"] = True
  
          # Assign the
          self.cfg.adapters[adapter_name] = OmegaConf.create(cfg)
  
          # Set the global config of adapters
          self.update_adapter_cfg(self.cfg.adapters)
  
          self.check_valid_model_with_adapter_support_()
  
imports: import inspect
  from abc import ABC
  from dataclasses import dataclass, is_dataclass
  from typing import List, Optional, Set, Tuple, Union
  import torch
  import torch.nn
  from hydra.utils import instantiate
  from omegaconf import DictConfig, OmegaConf, open_dict
  from nemo.utils import logging, model_utils
label_desc: Use image node_id 2 for calling the AdapterModelPTMixin obj's underlying member method code with example usage: obj.add_adapter(name, cfg) without return types