class_docstr: Sharded implementation of `EmbeddingBagCollection`.
  This is part of the public API to allow for manual data dist pipelining.
code: def _create_input_dist(
      self,
      input_feature_names: List[str],
      features_device: torch.device,
      input_dist_device: Optional[torch.device] = None,
  ) -> None:
      feature_names: List[str] = []
      for sharding in self._sharding_type_to_sharding.values():
          self._input_dists.append(
              sharding.create_input_dist(device=input_dist_device)
          )
          feature_names.extend(sharding.feature_names())
          self._feature_splits.append(len(sharding.feature_names()))
  
      if feature_names == input_feature_names:
          self._has_features_permute = False
      else:
          for f in feature_names:
              self._features_order.append(input_feature_names.index(f))
          self.register_buffer(
              "_features_order_tensor",
              torch.tensor(
                  self._features_order,
                  device=features_device,
                  dtype=torch.int32,
              ),
              persistent=False,
          )
  
imports: from typing import Any, Dict, List, Optional, Type
  import torch
  from fbgemm_gpu.split_table_batched_embeddings_ops_inference import IntNBitTableBatchedEmbeddingBagsCodegen
  from torch import nn
  from torchrec.distributed.embedding_lookup import EmbeddingComputeKernel
  from torchrec.distributed.embedding_sharding import EmbeddingSharding, EmbeddingShardingInfo
  from torchrec.distributed.embedding_types import BaseQuantEmbeddingSharder, FeatureShardingMixIn, GroupedEmbeddingConfig, KJTList, ListOfKJTList
  from torchrec.distributed.embeddingbag import construct_output_kt, create_sharding_infos_by_sharding
  from torchrec.distributed.fused_params import FUSED_PARAM_QUANT_STATE_DICT_SPLIT_SCALE_BIAS, FUSED_PARAM_REGISTER_TBE_BOOL, get_tbes_to_register_from_iterable, is_fused_param_quant_state_dict_split_scale_bias, is_fused_param_register_tbe
  from torchrec.distributed.quant_state import ShardedQuantEmbeddingModuleState
  from torchrec.distributed.sharding.cw_sharding import InferCwPooledEmbeddingSharding
  from torchrec.distributed.sharding.rw_sharding import InferRwPooledEmbeddingSharding
  from torchrec.distributed.sharding.tw_sharding import InferTwEmbeddingSharding
  from torchrec.distributed.types import NullShardedModuleContext, NullShardingContext, ParameterSharding, ShardingEnv, ShardingType
  from torchrec.distributed.utils import copy_to_device
  from torchrec.modules.embedding_configs import data_type_to_sparse_type, dtype_to_data_type, EmbeddingBagConfig
  from torchrec.modules.embedding_modules import EmbeddingBagCollectionInterface
  from torchrec.modules.feature_processor_ import FeatureProcessorsCollection
  from torchrec.quant.embedding_modules import EmbeddingBagCollection, FeatureProcessedEmbeddingBagCollection, MODULE_ATTR_QUANT_STATE_DICT_SPLIT_SCALE_BIAS
  from torchrec.sparse.jagged_tensor import KeyedJaggedTensor, KeyedTensor
label_desc: Use image node_id 5 for calling the ShardedQuantEmbeddingBagCollection obj's underlying member method code with example usage: obj._create_input_dist(input_feature_names, features_device, input_dist_device) without return types