code: # coding=utf-8
  
  import copy
  import functools
  from typing import List
  
  import torch
  import torch.distributed._shard.sharding_spec as shard_spec
  
  from .api import (
      _register_sharded_op,
      Shard,
      ShardedTensor,
      ShardedTensorMetadata,
      TensorProperties,
  )
  from .metadata import ShardMetadata  # noqa: F401
  from .partial_tensor import _PartialTensor
  
  
  def empty(sharding_spec: shard_spec.ShardingSpec,
            *size,
            dtype=None,
            layout=torch.strided,
            requires_grad=False,
            pin_memory=False,
            memory_format=torch.contiguous_format,
            process_group=None,
            init_rrefs=False) -> ShardedTensor:
      """
      Returns a :class:`ShardedTensor` filled with uninitialized data.
          Needs to be called on all ranks in an SPMD fashion.
  
      Args:
          sharding_spec (:class:`torch.distributed._shard.sharding_spec.ShardingSpec`): The specification
              describing how to shard the Tensor.
          size (int...): a sequence of integers defining the shape of the output
              tensor. Can be a variable number of arguments or a collection like a list or tuple.
  
      Keyword args:
          dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
              Default: if ``None``, uses a global default (see :func:`torch.set_default_tensor_type`).
          layout (:class:`torch.layout`, optional): the desired layout of returned Tensor.
              Default: ``torch.strided``.
          requires_grad (bool, optional): If autograd should record operations on the
              returned tensor. Default: ``False``.
          pin_memory (bool, optional): If set, returned tensor would be allocated in
              the pinned memory. Works only for CPU tensors. Default: ``False``.
          memory_format (:class:`torch.memory_format`, optional): the desired memory format of
              returned Tensor. Default: ``torch.contiguous_format``.
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
  
      Returns:
          A :class:`ShardedTensor` object on each rank
      """
      return ShardedTensor(
          sharding_spec,
          *size,
          dtype=dtype,
          layout=layout,
          requires_grad=requires_grad,
          pin_memory=pin_memory,
          memory_format=memory_format,
          process_group=process_group,
          init_rrefs=init_rrefs,
      )
  
  def ones(sharding_spec: shard_spec.ShardingSpec,
           *size,
           dtype=None,
           layout=torch.strided,
           requires_grad=False,
           pin_memory=False,
           memory_format=torch.contiguous_format,
           process_group=None,
           init_rrefs=False) -> ShardedTensor:
      """
      Returns a :class:`ShardedTensor` with the scalar value 1.
          Needs to be called on all ranks in an SPMD fashion.
  
      Args:
          sharding_spec (:class:`torch.distributed._shard.sharding_spec.ShardingSpec`): The specification
              describing how to shard the Tensor.
          size (int...): a sequence of integers defining the shape of the output
              tensor. Can be a variable number of arguments or a collection like a list or tuple.
  
      Keyword args:
          dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
              Default: if ``None``, uses a global default (see :func:`torch.set_default_tensor_type`).
          layout (:class:`torch.layout`, optional): the desired layout of returned Tensor.
              Default: ``torch.strided``.
          requires_grad (bool, optional): If autograd should record operations on the
              returned tensor. Default: ``False``.
          pin_memory (bool, optional): If set, returned tensor would be allocated in
              the pinned memory. Works only for CPU tensors. Default: ``False``.
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
  
      Returns:
          A :class:`ShardedTensor` object on each rank
      """
      return full(
          sharding_spec,
          size,
          fill_value=1,
          dtype=dtype,
          layout=layout,
          requires_grad=requires_grad,
          pin_memory=pin_memory,
          memory_format=memory_format,
          process_group=process_group,
          init_rrefs=init_rrefs
      )
  
  def zeros(sharding_spec: shard_spec.ShardingSpec,
            *size,
            dtype=None,
            layout=torch.strided,
            requires_grad=False,
            pin_memory=False,
            memory_format=torch.contiguous_format,
            process_group=None,
            init_rrefs=False) -> ShardedTensor:
      """
      Returns a :class:`ShardedTensor` filled with the scalar value 0.
          Needs to be called on all ranks in an SPMD fashion.
  
      Args:
          sharding_spec (:class:`torch.distributed._shard.sharding_spec.ShardingSpec`): The specification
              describing how to shard the Tensor.
          size (int...): a sequence of integers defining the shape of the output
              tensor. Can be a variable number of arguments or a collection like a list or tuple.
  
      Keyword args:
          dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
              Default: if ``None``, uses a global default (see :func:`torch.set_default_tensor_type`).
          layout (:class:`torch.layout`, optional): the desired layout of returned Tensor.
              Default: ``torch.strided``.
          requires_grad (bool, optional): If autograd should record operations on the
              returned tensor. Default: ``False``.
          pin_memory (bool, optional): If set, returned tensor would be allocated in
              the pinned memory. Works only for CPU tensors. Default: ``False``.
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
  
      Returns:
          A :class:`ShardedTensor` object on each rank
      """
      return full(
          sharding_spec,
          size,
          fill_value=0,
          dtype=dtype,
          layout=layout,
          requires_grad=requires_grad,
          pin_memory=pin_memory,
          memory_format=memory_format,
          process_group=process_group,
          init_rrefs=init_rrefs
      )
  
  def full(sharding_spec: shard_spec.ShardingSpec,
           size,
           fill_value=torch.types.Number,
           dtype=None,
           layout=torch.strided,
           requires_grad=False,
           pin_memory=False,
           memory_format=torch.contiguous_format,
           process_group=None,
           init_rrefs=False) -> ShardedTensor:
      """
      Creates a :class:`ShardedTensor` filled with fill_value. The tensor’s dtype
          is inferred from fill_value. If dtype is specified, it will override the
          inferred type from fill_value. Needs to be called on all ranks in an SPMD fashion.
      Args:
          sharding_spec (:class:`torch.distributed._sharding_spec.ShardingSpec`): The specification
              describing how to shard the Tensor.
          size (int...):  a list, tuple, or `torch.Size` of integers defining the shape of the
              output tensor.
          fill_value (Scalar) – the value to fill the output tensor with.
      Keyword args:
          dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
              Default: if ``None``, uses a global default (see :func:`torch.set_default_tensor_type`).
          layout (:class:`torch.layout`, optional): the desired layout of returned Tensor.
              Default: ``torch.strided``.
          requires_grad (bool, optional): If autograd should record operations on the
              returned tensor. Default: ``False``.
          pin_memory (bool, optional): If set, returned tensor would be allocated in
              the pinned memory. Works only for CPU tensors. Default: ``False``.
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
      Returns:
          A :class:`ShardedTensor` object on each rank
      """
      sharded_tensor = ShardedTensor(
          sharding_spec,
          *size,
          dtype=dtype,
          layout=layout,
          requires_grad=requires_grad,
          pin_memory=pin_memory,
          memory_format=memory_format,
          process_group=process_group,
          init_rrefs=init_rrefs,
      )
      torch.nn.init.constant_(sharded_tensor, fill_value)  # type: ignore[arg-type]
      return sharded_tensor
  
  def rand(sharding_spec: shard_spec.ShardingSpec,
           *size,
           dtype=None,
           layout=torch.strided,
           requires_grad=False,
           pin_memory=False,
           memory_format=torch.contiguous_format,
           process_group=None,
           init_rrefs=False) -> ShardedTensor:
      """
      Creates a :class:`ShardedTensor` filled with fill_value. The tensor’s dtype
          is inferred from fill_value. If dtype is specified, it will override the
          inferred type from fill_value. Needs to be called on all ranks in an SPMD fashion.
  
      Args:
          sharding_spec (:class:`torch.distributed._shard.sharding_spec.ShardingSpec`): The specification
              describing how to shard the Tensor.
          size (int...):  a list, tuple, or `torch.Size` of integers defining the shape of the
              output tensor.
          fill_value (Scalar) – the value to fill the output tensor with.
  
      Keyword args:
          dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
              Default: if ``None``, uses a global default (see :func:`torch.set_default_tensor_type`).
          layout (:class:`torch.layout`, optional): the desired layout of returned Tensor.
              Default: ``torch.strided``.
          requires_grad (bool, optional): If autograd should record operations on the
              returned tensor. Default: ``False``.
          pin_memory (bool, optional): If set, returned tensor would be allocated in
              the pinned memory. Works only for CPU tensors. Default: ``False``.
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
  
      Returns:
          A :class:`ShardedTensor` object on each rank
      """
      sharded_tensor = ShardedTensor(
          sharding_spec,
          *size,
          dtype=dtype,
          layout=layout,
          requires_grad=requires_grad,
          pin_memory=pin_memory,
          memory_format=memory_format,
          process_group=process_group,
          init_rrefs=init_rrefs,
      )
      torch.nn.init.uniform_(sharded_tensor, 0, 1)  # type: ignore[arg-type]
      return sharded_tensor
  
  def init_from_local_shards(
          local_shards: List[Shard],
          *global_size,
          process_group=None,
          init_rrefs=False) -> ShardedTensor:
      """
      Creates an :class:`ShardedTensor` from local shards and the global metadata.
      Needs to be called on all ranks in an SPMD fashion.
  
      Args:
          local_shards (List[:class `torch.distributed._shard.sharded_tensor.Shard`]): A list
              of shards that represent the local shards on this rank.
          global_size (int...):  a list, tuple, or `torch.Size` of integers defining the
              shape of the overall sharded tensor.
  
      Keyword args:
          process_group (ProcessGroup, optional): The process group to work on. If None,
              the default process group will be used.
          init_rrefs (bool, optional): Whether or not to initialize
              :class:`torch.distributed.rpc.RRef`s pointing to remote shards.
              Need to initialize the RPC Framework if specified as ``True``.
              Default: ``False``.
  
      Returns:
          A :class:`ShardedTensor` object handle on this rank
  
  
      Examples:
        Suppose we want construct a sharded tensor on two ranks, global size = (10, 5),
        each shard have a (5, 5) local tensor, we can do it like below:
  
        on rank 0:
          >>> local_shard_metadata = ShardMetadata(
          >>>     shard_offsets=[0, 0]
          >>>     shard_lengths=[5, 5]
          >>>     placement="rank:0/cuda:0"
          >>> )
          >>> local_shards = [Shard(torch.randn(5, 5), local_shard_metadata)]
          >>> sharded_tensor = init_from_local_shards(local_shards, [10, 5])
  
        on rank 1:
          >>> local_shard_metadata = ShardMetadata(
          >>>     shard_offsets=[5, 0]
          >>>     shard_lengths=[5, 5]
          >>>     placement="rank:1/cuda:1"
          >>> )
          >>> local_shards = [Shard(torch.randn(5, 5), local_shard_metadata)]
          >>> sharded_tensor = init_from_local_shards(local_shards, [10, 5])
      """
      return ShardedTensor._init_from_local_shards(
          local_shards,
          *global_size,
          process_group=process_group,
          init_rrefs=init_rrefs
      )
  
  def state_dict_hook(module, destination, prefix, local_metadata):
      """
      Hook to add ShardedTensor to Module's ``state_dict``. Needs to be
      registered to the Module using
      :meth:`torch.nn.Module._register_state_dict_hook`.
      """
      for submodule_name, submodule in module.named_modules():
          for attr_name, attr in submodule.__dict__.items():
              if isinstance(attr, ShardedTensor):
                  destination[prefix + submodule_name + '.' + attr_name] = attr
  
  def pre_load_state_dict_hook(module, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs):
      """
      Pre-load state dict hook to add ShardedTensor to the module.
      """
      for submodule_name, submodule in module.named_modules():
          for attr_name, attr in submodule.__dict__.items():
              key = prefix + submodule_name + '.' + attr_name
              if key in state_dict:
                  if isinstance(state_dict[key], ShardedTensor):
                      setattr(submodule, attr_name, state_dict[key])
  
  def sharded_op_impl(func):
      """
      Provides a way for users to write their own custom sharded operator. This
      can be used to override existing ShardedTensor operators or write a new
      one not supported by ShardedTensor. If the operator in question is covered
      by ``__torch_function__`` dispatch and has a ShardedTensor as any of its
      parameters, the function provided will be invoked for that operator.
  
      Example::
          >>> @sharded_op_impl(torch.nn.functional.linear)
          >>> def my_custom_sharded_linear(types, args, kwargs, process_group):
          >>>   ....
          >>>
          >>> input = torch.rand(10, 32)
          >>> weight = sharded_tensor.rand(32, 16)
          >>> bias = torch.rand(16)
          >>> # This will call 'my_custom_sharded_linear'
          >>> torch.nn.functional.linear(input, weight, bias)
  
      The types, args and kwargs parameters are the same parameters that are
      passed to ``__torch_function__`` dispatch API
      (https://pytorch.org/docs/stable/notes/extending.html#extending-torch).
      There is an additional ``process_group`` parameter which is the
      process_group used for the ShardedTensor and can be used by
      implementations for communications within a sharded implementation.
  
      Args:
          func(Callable): Torch function for which we want to provide a sharded
              implementation (ex: torch.nn.functional.linear)
      """
      def decorator_sharded_func(wrapped_func):
          _register_sharded_op(func, wrapped_func)
  
          @functools.wraps(wrapped_func)
          def wrapper(*args, **kwargs):
              return wrapped_func(*args, **kwargs)
          return wrapper
      return decorator_sharded_func
  
  # Import all builtin sharded ops
  from ._ops import *  # noqa: F403
  
  def _reshard_output(
          module: torch.nn.Module,
          resharding_spec: shard_spec.ShardingSpec) -> torch.nn.Module:
      """
      Hook a module with local shards collection in the forward pass according
      to the given ``resharding_spec``.
  
      Args:
          module (:class:`torch.nn.Module`): Module whose output needs to be resharded.
          resharding_spec (:class:`torch.distributed._shard.sharding_spec.ShardingSpec`):
              The specification describing how the output of the module will be resharded.
  
      Returns:
          A :class:`torch.nn.Module` object with collection API hooked.
      """
      def hook_func(_module, _input, output):
          if isinstance(output, ShardedTensor) or isinstance(output, _PartialTensor):
              return output.reshard(resharding_spec)
          return output
      module.register_forward_hook(hook_func)
      return module
  
  
  def _collect_local_shard(module: torch.nn.Module) -> torch.nn.Module:
      """
      Hook a module with local shards collection in the forward pass.
  
      This API is typically used to convert a sharded representation back to data parallel
      representation. In particular, it returns the local tensor for this Shard. If the
      size along the sharding dimension for the local tensor is 1, this dimension is removed
      from the final result. For example a [4, 16] ShardedTensor across 4 ranks is typically
      a local Tensor of size [16] across each rank and not [1, 16] across each rank.
  
      Args:
          module (:class:`torch.nn.Module`): Module whose output needs to be resharded.
  
      Returns:
          A :class:`torch.nn.Module` object with collection API hooked.
      """
  
      def hook_func(_module, _input, output):
          if isinstance(output, ShardedTensor):
              local_tensor = output.local_tensor()
              # Squeeze the # of dimensions manually.
              if local_tensor.size(output._sharding_spec.dim) == 1:  # type: ignore[attr-defined]
                  local_tensor = local_tensor.squeeze(
                      output._sharding_spec.dim  # type: ignore[attr-defined]
                  )
              return local_tensor
      module.register_forward_hook(hook_func)
      return module
   # -*- coding: utf-8 -*-
  # Owner(s): ["module: autograd"]
  
  from torch.testing._internal.common_utils import TestCase, run_tests, IS_WINDOWS
  import pkgutil
  import torch
  import sys
  from typing import Callable
  import inspect
  import json
  import os
  import unittest
  
  class TestPublicBindings(TestCase):
      def test_no_new_bindings(self):
          """
          This test aims to stop the introduction of new JIT bindings into torch._C
          whose names do not start with _. Such bindings are made available as
          torch.XXX, which may not be desirable.
  
          If your change causes this test to fail, add your new binding to a relevant
          submodule of torch._C, such as torch._C._jit (or other relevant submodule of
          torch._C). If your binding really needs to be available as torch.XXX, add it
          to torch._C and add it to the allowlist below.
  
          If you have removed a binding, remove it from the allowlist as well.
          """
          # This allowlist contains every binding in torch._C that is copied into torch at
          # the time of writing. It was generated with
          #
          #   {elem for elem in dir(torch._C) if not elem.startswith("_")}
          #
          torch_C_allowlist_superset = {
              "AggregationType",
              "AliasDb",
              "AnyType",
              "Argument",
              "ArgumentSpec",
              "autocast_decrement_nesting",
              "autocast_increment_nesting",
              "AVG",
              "BenchmarkConfig",
              "BenchmarkExecutionStats",
              "BFloat16StorageBase",
              "Block",
              "BoolStorageBase",
              "BoolType",
              "BufferDict",
              "ByteStorageBase",
              "CallStack",
              "Capsule",
              "CharStorageBase",
              "ClassType",
              "clear_autocast_cache",
              "Code",
              "CompilationUnit",
              "CompleteArgumentSpec",
              "ComplexDoubleStorageBase",
              "ComplexFloatStorageBase",
              "ComplexType",
              "ConcreteModuleType",
              "ConcreteModuleTypeBuilder",
              "CONV_BN_FUSION",
              "cpp",
              "CudaBFloat16StorageBase",
              "CudaBFloat16TensorBase",
              "CudaBFloat16TensorBase",
              "CudaBoolStorageBase",
              "CudaBoolTensorBase",
              "CudaBoolTensorBase",
              "CudaByteStorageBase",
              "CudaByteTensorBase",
              "CudaByteTensorBase",
              "CudaCharStorageBase",
              "CudaCharTensorBase",
              "CudaCharTensorBase",
              "CudaComplexDoubleStorageBase",
              "CudaComplexDoubleTensorBase",
              "CudaComplexDoubleTensorBase",
              "CudaComplexFloatStorageBase",
              "CudaComplexFloatTensorBase",
              "CudaComplexFloatTensorBase",
              "CudaDoubleStorageBase",
              "CudaDoubleTensorBase",
              "CudaDoubleTensorBase",
              "CudaFloatStorageBase",
              "CudaFloatTensorBase",
              "CudaHalfStorageBase",
              "CudaHalfTensorBase",
              "CudaIntStorageBase",
              "CudaIntTensorBase",
              "CudaIntTensorBase",
              "CudaLongStorageBase",
              "CudaLongTensorBase",
              "CudaLongTensorBase",
              "CudaShortStorageBase",
              "CudaShortTensorBase",
              "CudaShortTensorBase",
              "DeepCopyMemoTable",
              "default_generator",
              "DeserializationStorageContext",
              "device",
              "DeviceObjType",
              "DictType",
              "DisableTorchFunction",
              "DoubleStorageBase",
              "dtype",
              "EnumType",
              "ErrorReport",
              "ExecutionPlan",
              "FatalError",
              "FileCheck",
              "finfo",
              "FloatStorageBase",
              "FloatType",
              "fork",
              "FunctionSchema",
              "FUSE_ADD_RELU",
              "Future",
              "FutureType",
              "Generator",
              "get_autocast_cpu_dtype",
              "get_default_dtype",
              "get_num_interop_threads",
              "get_num_threads",
              "Gradient",
              "Graph",
              "GraphExecutorState",
              "HalfStorageBase",
              "has_cuda",
              "has_cudnn",
              "has_lapack",
              "has_mkl",
              "has_mkldnn",
              "has_mlc",
              "has_openmp",
              "has_spectral",
              "HOIST_CONV_PACKED_PARAMS",
              "iinfo",
              "import_ir_module_from_buffer",
              "import_ir_module",
              "InferredType",
              "init_num_threads",
              "INSERT_FOLD_PREPACK_OPS",
              "InterfaceType",
              "IntStorageBase",
              "IntType",
              "SymIntType",
              "IODescriptor",
              "is_anomaly_enabled",
              "is_autocast_cache_enabled",
              "is_autocast_cpu_enabled",
              "is_autocast_enabled",
              "is_grad_enabled",
              "is_inference_mode_enabled",
              "JITException",
              "layout",
              "ListType",
              "LiteScriptModule",
              "LockingLogger",
              "LoggerBase",
              "LongStorageBase",
              "memory_format",
              "merge_type_from_type_comment",
              "MobileOptimizerType",
              "ModuleDict",
              "Node",
              "NoneType",
              "NoopLogger",
              "NumberType",
              "OperatorInfo",
              "OptionalType",
              "ParameterDict",
              "parse_ir",
              "parse_schema",
              "parse_type_comment",
              "PyObjectType",
              "PyTorchFileReader",
              "PyTorchFileWriter",
              "QInt32StorageBase",
              "QInt8StorageBase",
              "qscheme",
              "QUInt4x2StorageBase",
              "QUInt2x4StorageBase",
              "QUInt8StorageBase",
              "read_vitals",
              "REMOVE_DROPOUT",
              "RRefType",
              "ScriptClass",
              "ScriptClassFunction",
              "ScriptDict",
              "ScriptDictIterator",
              "ScriptDictKeyIterator",
              "ScriptList",
              "ScriptListIterator",
              "ScriptFunction",
              "ScriptMethod",
              "ScriptModule",
              "ScriptModuleSerializer",
              "ScriptObject",
              "ScriptObjectProperty",
              "SerializationStorageContext",
              "set_anomaly_enabled",
              "set_autocast_cache_enabled",
              "set_autocast_cpu_dtype",
              "set_autocast_cpu_enabled",
              "set_autocast_enabled",
              "set_flush_denormal",
              "set_num_interop_threads",
              "set_num_threads",
              "set_vital",
              "ShortStorageBase",
              "Size",
              "StaticModule",
              "Stream",
              "StreamObjType",
              "StringType",
              "SUM",
              "TensorType",
              "ThroughputBenchmark",
              "TracingState",
              "TupleType",
              "Type",
              "unify_type_list",
              "UnionType",
              "Use",
              "Value",
              "autocast_decrement_nesting",
              "autocast_increment_nesting",
              "clear_autocast_cache",
              "cpp",
              "default_generator",
              "device",
              "dtype",
              "finfo",
              "fork",
              "get_default_dtype",
              "get_num_interop_threads",
              "get_num_threads",
              "has_cuda",
              "has_cudnn",
              "has_lapack",
              "has_mkl",
              "has_mkldnn",
              "has_mlc",
              "has_openmp",
              "iinfo",
              "import_ir_module",
              "import_ir_module_from_buffer",
              "init_num_threads",
              "is_anomaly_enabled",
              "is_autocast_enabled",
              "is_grad_enabled",
              "layout",
              "memory_format",
              "merge_type_from_type_comment",
              "parse_ir",
              "parse_schema",
              "parse_type_comment",
              "qscheme",
              "set_anomaly_enabled",
              "set_autocast_enabled",
              'set_autocast_gpu_dtype',
              'get_autocast_gpu_dtype',
              "set_flush_denormal",
              "set_num_interop_threads",
              "set_num_threads",
              "unify_type_list",
              "vitals_enabled",
  
              "wait",
          }
          torch_C_bindings = {elem for elem in dir(torch._C) if not elem.startswith("_")}
  
          # Check that the torch._C bindings are all in the allowlist. Since
          # bindings can change based on how PyTorch was compiled (e.g. with/without
          # CUDA), the two may not be an exact match but the bindings should be
          # a subset of the allowlist.
          difference = torch_C_bindings.difference(torch_C_allowlist_superset)
          msg = f"torch._C had bindings that are not present in the allowlist:\n{difference}"
          self.assertTrue(torch_C_bindings.issubset(torch_C_allowlist_superset), msg)
  
      # AttributeError: module 'torch.distributed' has no attribute '_shard'
      @unittest.skipIf(IS_WINDOWS, "Distributed Attribute Error")
      def test_correct_module_names(self):
          '''
          An API is considered public, if  its  `__module__` starts with `torch.`
          and there is no name in `__module__` or the object itself that starts with “_”.
          Each public package should either:
          - (preferred) Define `__all__` and all callables and classes in there must have their
           `__module__` start with the current submodule's path. Things not in `__all__` should
            NOT have their `__module__` start with the current submodule.
          - (for simple python-only modules) Not define `__all__` and all the elements in `dir(submod)` must have their
            `__module__` that start with the current submodule.
          '''
          failure_list = []
          with open(os.path.join(os.path.dirname(__file__), 'allowlist_for_publicAPI.json')) as json_file:
              # no new entries should be added to this allow_dict.
              # New APIs must follow the public API guidelines.
              allow_dict = json.load(json_file)
  
          def test_module(modname):
              split_strs = modname.split('.')
              mod = sys.modules.get(modname)
              for elem in split_strs:
                  if elem.startswith("_"):
                      return
  
              def add_to_failure_list_if_not_in_allow_dict(modname, elem, elem_module):
                  if modname in allow_dict and elem in allow_dict[modname]:
                      return
                  failure_list.append((modname, elem, elem_module))
  
              # verifies that each public API has the correct module name and naming semantics
              def looks_public_or_not(elem, modname, mod, is_public=True):
                  obj = getattr(mod, elem)
                  if not (isinstance(obj, Callable) or inspect.isclass(obj)):
                      return
                  elem_module = getattr(obj, '__module__', None)
                  elem_modname_starts_with_mod = elem_module is not None and \
                      elem_module.startswith(modname) and '._' not in elem_module
                  # elem's name must NOT begin with an `_` and it's module name
                  # SHOULD start with it's current module since it's a public API
                  looks_public = not elem.startswith('_') and elem_modname_starts_with_mod
                  if is_public != looks_public:
                      add_to_failure_list_if_not_in_allow_dict(modname, elem, elem_module)
  
              if hasattr(modname, '__all__'):
                  public_api = mod.__all__
                  all_api = dir(modname)
                  for elem in all_api:
                      looks_public_or_not(elem, modname, is_public=elem in public_api)
  
              else:
                  all_api = dir(mod)
                  for elem in all_api:
                      if not elem.startswith('_'):
                          looks_public_or_not(elem, modname, mod, is_public=True)
  
          for _, modname, ispkg in pkgutil.walk_packages(path=torch.__path__, prefix=torch.__name__ + '.'):
              test_module(modname)
  
          test_module('torch')
          msg = "Following new APIs ( displayed in the form (module, element, element module) )" \
                " were added that do not meet our guidelines for public API" \
                " Please review  https://docs.google.com/document/d/10yx2-4gs0gTMOimVS403MnoAWkqitS8TUHX73PN8EjE/edit?pli=1#" \
                " for more information:\n" + "\n".join(map(str, failure_list))
  
          # empty lists are considered false in python
          self.assertTrue(not failure_list, msg)
  
  if __name__ == '__main__':
      run_tests()
  
apis: torch.nn.init.uniform_ torch.nn.init.constant_
apis: torch.testing._internal.common_utils.run_tests