class_docstr: Prompt Tuning implementation.
  
  Args:
      model_config: The model configuration.
      adapters_config: The adapter configuration.
      base_model_embeddings:
          The embedding layer of the base model (used to initialize the prompt embedding if
          prompt_init='from_string').
code: def add_adapter(self, adapter_name: str, layer_idx: int) -> bool:
      # ignore layer_idx as prompt tunings are only added after the embedding layer
      prompt_tuning_config = self.adapters_config.match(
          adapter_name,
          config_type=PromptTuningConfig,
      )
  
      if prompt_tuning_config is not None:
          adapter = PromptTuning(
              adapter_name=adapter_name,
              prompt_tuning_config=prompt_tuning_config,  # type: ignore
              model_config=self.model_config,
              base_model_embeddings=self.base_model_embeddings,
          )
          adapter.train(
              self.training
          )  # make sure training mode is consistent
          self.prompt_tunings[adapter_name] = adapter
          return True
  
      return False
  
imports: import math
  from typing import Callable, Dict, List, Union
  import numpy
  import torch
  from torch import nn
  from transformers import AutoTokenizer
  from transformers.configuration_utils import PretrainedConfig
  from ..composition import AdapterCompositionBlock
  from ..configuration import ModelAdaptersConfig, PromptTuningConfig
  from ..context import ForwardContext
  from .adapter_layer_base import AdapterLayerBase
label_desc: Use image node_id 2 for calling the PromptTuningLayer obj's underlying member method code with example usage: obj.add_adapter(adapter_name, layer_idx) and returns: False, True