class_docstr: Sharding spec for a tensor, it contains info of the logical device mesh this tensor belong
  to, the entire shape of the tensor before sharded, and the sharding sequence looks like
  [R, R, S0, S1].
  
  Argument:
      device_mesh(DeviceMesh): A logical view of a physical mesh.
      entire_shape(torch.Size): The entire shape of tensor before sharded.
      dim_partition_dict(Dict[int, List[int]]， optional): The key is the dimension of tensor to be sharded,
          and the value of the key describe which logical axis will be sharded in that dimension.
      sharding_sequence(List[_DimSpec], optional): A straight view of ShardingSpec looks like [R, R, S0, S1].
code: def _sanity_check(self):
      # make sure all axes in logical device mesh only be used once
      dim_check_list = list(
          range(self.device_mesh.logical_mesh_id.dim())
      )
      for dim, shard_list in self.dim_partition_dict.items():
          for element in shard_list:
              if element in dim_check_list:
                  dim_check_list.remove(element)
              else:
                  raise DuplicatedShardingDimensionError(
                      f"find an invalid sharding axis {element} in dim_partition_dict in tensor dimension {dim}."
                  )
  
      # make sure that the dimension is not out of index
      for dim in self.dim_partition_dict.keys():
          if dim >= len(self.entire_shape):
              raise ShardingOutOfIndexError(
                  f"The dim_partition_dict specifies to shard dimension {dim} but the entire_shape only has {len(self.entire_shape)} dimensions"
              )
  
      # make sure that the sharding for a dimension is divisible by the number of devices
      for dim, shard_list in self.dim_partition_dict.items():
          tensor_dim_size = self.entire_shape[dim]
          num_devices = 1
  
          for element in shard_list:
              num_devices *= self.device_mesh.shape[element]
  
          if tensor_dim_size % num_devices != 0:
              raise ShardingNotDivisibleError(
                  f"The size of dimension at index {dim} is {tensor_dim_size}, it cannot be sharded over {num_devices} devices."
              )
  
imports: import operator
  from copy import deepcopy
  from functools import reduce
  import torch
  from colossalai.device.device_mesh import DeviceMesh
  from .utils import merge_same_dim_mesh_list
label_desc: Use image node_id 3 for calling the ShardingSpec obj's underlying member method code with example usage: obj._sanity_check() without return types