docstr: IDTransformerCollection could transform the input of a `Embedding(Bag)Collection`.
  It contains the `IDTransformer` of tables in the
  `Embedding(Bag)Collection`.
  
  Args:
      tables: list of `Embedding(Bag)Config` or `EmbeddingBagConfig` one passed to
          `Embedding(Bag)Collection`.
      eviction_config: config of the eviction strategy for IDTransformers.
      transform_config: config of the transform strategy for IDTransformers.
      ps_collection: `PSCollection` of the collection, if `None`, won't do eviction or fetch.
          By default, IDTransformerCollection will evict half the ids when full.
code: def __init__(
      self,
      tables: Union[List[EmbeddingConfig], List[EmbeddingBagConfig]],
      eviction_config=None,
      transform_config=None,
      ps_collection: PSCollection = None,
  ):
      """
      IDTransformerCollection could transform the input of a `Embedding(Bag)Collection`.
      It contains the `IDTransformer` of tables in the
      `Embedding(Bag)Collection`.
  
      Args:
          tables: list of `Embedding(Bag)Config` or `EmbeddingBagConfig` one passed to
              `Embedding(Bag)Collection`.
          eviction_config: config of the eviction strategy for IDTransformers.
          transform_config: config of the transform strategy for IDTransformers.
          ps_collection: `PSCollection` of the collection, if `None`, won't do eviction or fetch.
              By default, IDTransformerCollection will evict half the ids when full.
      """
      self._configs = tables
      self._ps_collection = ps_collection
  
      self._transformers = []
      self._table_names = []
      feature_names = set()
      for config in tables:
          if config.name in self._table_names:
              raise ValueError(f"Duplicate table name {config.name}")
          if not config.feature_names:
              config.feature_names = [config.name]
          self._table_names.append(config.name)
          for feature_name in config.feature_names:
              if feature_name in feature_names:
                  raise ValueError(f"Shared feature not allowed yet.")
          # only rank 0 will have the id transformer
          # and other ranks will gather their to rank 0.
          if dist.get_rank() == 0:
              transformer = IDTransformer(
                  num_embedding=config.num_embeddings,
                  eviction_config=eviction_config,
                  transform_config=transform_config,
              )
          else:
              transformer = None
          self._transformers.append(transformer)
      self._feature_names: List[List[str]] = [
          config.feature_names for config in tables
      ]
      self._ever_evicted = False
      self._time = 0
  
      if dist.get_world_size() > 1:
          self._pg = dist.new_group(backend="gloo")
      self._stream = torch.cuda.Stream()
  
file_path: torchrec/contrib/dynamic_embedding/src/torchrec_dynamic_embedding/id_transformer_collection.py
imports: from typing import List, Tuple, Union
  import torch
  import torch.distributed
  from torchrec import EmbeddingBagConfig, EmbeddingConfig, KeyedJaggedTensor
  from .distributed import broadcast_ids_to_evict, broadcast_transform_result, gather_global_ids, scatter_cache_ids
  from .id_transformer import IDTransformer, TensorList
  from .ps import PSCollection
label_desc: Use image node_id 1 to create a new IDTransformerCollection object  with example: obj = IDTransformerCollection(tables, eviction_config, transform_config, ps_collection)