class_docstr: Sharding spec for single dimension of the sharded tensor describe the sharding dimension of
  logical device mesh and give a method to compute the difference between them.
  This class is used internally in ShardingSpec.
  
  Argument:
      shard_list(List[int]): if shard_list is None, the dim spec will be 'R' type.
          Otherwise, the element in shard_list means the data will be sharded in that dimension.
docstr: Build a difference mapping for 2D device mesh case. It will be used to
  compute the difference between DimSpec pairs.
docstr_tok: ["Build","a","difference","mapping","for","2D","device","mesh","case",".","It","will","be","used","to","compute","the","difference","between","DimSpec","pairs","."]
code: def build_difference_2d_dict(self):
      """
      Build a difference mapping for 2D device mesh case. It will be used to
      compute the difference between DimSpec pairs.
      """
  
      source_spec_list = ["R", "S0", "S1", "S01"]
      target_spec_list = ["R", "S0", "S1", "S01"]
      difference_dict = {}
      for source_spec in source_spec_list:
          for target_spec in target_spec_list:
              spec_pair = (deepcopy(source_spec), deepcopy(target_spec))
              source_shard_list = self._convert_str_to_shard_list(
                  source_spec
              )
              target_shard_list = self._convert_str_to_shard_list(
                  target_spec
              )
  
              # source same as target
              if source_shard_list == target_shard_list:
                  difference = 0
  
              # all_gather(source) -> target
              elif (
                  len(source_shard_list) == len(target_shard_list) + 1
                  and source_shard_list[:-1] == target_shard_list
              ):
                  difference = ALLGATHER_COST
  
              # shard(source) -> target
              elif (
                  len(source_shard_list) == len(target_shard_list) - 1
                  and source_shard_list == target_shard_list[:-1]
                  and target_shard_list[-1] not in source_shard_list
              ):
                  difference = SHARD_COST
  
              # S1 -> S0 or S0 -> S1
              elif len(source_shard_list) == len(target_shard_list):
                  # source -> R -> target
                  difference = (
                      ALLGATHER_COST + STEP_PENALTY + SHARD_COST
                  )
  
              # R -> S01
              elif len(source_shard_list) == len(target_shard_list) - 2:
                  difference = SHARD_COST + STEP_PENALTY + SHARD_COST
  
              # S01 -> R
              elif len(source_shard_list) == len(target_shard_list) + 2:
                  difference = (
                      ALLGATHER_COST + STEP_PENALTY + ALLGATHER_COST
                  )
  
              # S1 -> S01
              elif len(source_shard_list) == len(target_shard_list) - 1:
                  difference = (
                      ALLGATHER_COST
                      + STEP_PENALTY
                      + SHARD_COST
                      + STEP_PENALTY
                      + SHARD_COST
                  )
  
              # S01 -> S1
              elif len(source_shard_list) == len(target_shard_list) + 1:
                  difference = (
                      ALLGATHER_COST
                      + STEP_PENALTY
                      + ALLGATHER_COST
                      + STEP_PENALTY
                      + SHARD_COST
                  )
  
              else:
                  difference = NAN
              difference_dict[spec_pair] = difference
  
      self.difference_dict = difference_dict
  
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 5 for calling the _DimSpec obj's underlying member method code with example usage: obj.build_difference_2d_dict() without return types