class_docstr: This is a type of PlacementSpec that allows users to specify a generic
  sharding scheme by enumerating exactly how each shard is laid out.
  
  Args:
      shards(List[ShardMetadata]): List of :class:`ShardMetadata` objects representing
          each shard. Note that none of the shards should overlap.
class_docstr_tok: ["This","is","a","type","of","PlacementSpec","that","allows","users","to","specify","a","generic","sharding","scheme","by","enumerating","exactly","how","each","shard","is","laid","out",".","Args",":","shards","(","List","[","ShardMetadata","]",")",":","List","of",":","class",":","`","ShardMetadata","`","objects","representing","each","shard",".","Note","that","none","of","the","shards","should","overlap","."]
code: def __post_init__(self):
      if len(self.shards) == 0:
          raise ValueError(f"Empty shard list provided: {self.shards}")
  
      # Validate each shard has same rank.
      rank = -1
      for shard in self.shards:
          if rank != -1 and rank != len(shard.shard_offsets):
              raise ValueError(
                  f"Found inconsistent ranks for shards: {rank} and {len(shard.shard_offsets)}"
              )
          rank = len(shard.shard_offsets)
  
      validate_non_overlapping_shards_metadata(self.shards)
  
imports: from abc import ABC, abstractmethod
  from dataclasses import dataclass
  import functools
  from typing import Callable, Dict, List, TYPE_CHECKING
  import torch
  from ._internals import check_tensor, get_chunked_dim_size, get_split_size, validate_non_overlapping_shards_metadata
  from torch.distributed._shard.metadata import ShardMetadata
  import torch.distributed._shard.sharded_tensor.metadata
  from torch.distributed._shard.op_registry_utils import _decorator_func
label_desc: Use image node_id 1 for calling the EnumerableShardingSpec obj's underlying member method code with example usage: obj.__post_init__() without return types