code: def _convert_logical_sharding_to_physical_sharding_spec_for_linear(
      strategy: ShardingStrategy, input_name: str, output_name: str
  ) -> List[ShardingStrategy]:
      """
      This function converts the logical sharding spec to the physical sharding spec for both the input and output of the linear operation. The input and output
      should have the same sharding spec.
  
      Args:
          strategy (ShardingStrategy): the logical strategy generated by the strategy generator.
          input_name (str): the name of the OperationData object for the input.
          output_name (str): the name of the OperationData object for the output.
  
  
      """
      # the result will be a list of strategies
      sharding_strategies = []
  
      # get operation data
      input_op_data = strategy.get_op_data_by_name(input_name)
      output_op_data = strategy.get_op_data_by_name(output_name)
      input_sharding_spec = strategy.get_sharding_spec_by_name(
          input_op_data.name
      )
      output_sharding_spec = strategy.get_sharding_spec_by_name(
          output_op_data.name
      )
  
      # recover the last logical dimension to physical dimension
      last_logical_input_dims = len(input_op_data.logical_shape) - 1
      last_logical_output_dims = len(output_op_data.logical_shape) - 1
      last_physical_input_dims = input_op_data.data.dim() - 1
      last_physical_output_dims = output_op_data.data.dim() - 1
  
      if (
          last_logical_input_dims
          in input_sharding_spec.dim_partition_dict
      ):
          input_last_dim_mapping = {
              last_logical_input_dims: last_physical_input_dims
          }
      else:
          input_last_dim_mapping = {}
  
      if (
          last_logical_output_dims
          in output_sharding_spec.dim_partition_dict
      ):
          output_last_dim_mapping = {
              last_logical_output_dims: last_physical_output_dims
          }
      else:
          output_last_dim_mapping = {}
  
      # get logger for debug message
      logger = get_dist_logger()
  
      # for the input of the linear operation, it can be multi-dimensional. The sharding spec generated is only
      # 2D, where the first dimension is non-matrix dimension and the last dimension is the matrix dimension.
      # the logical non-matrix dimension can belong to the 0th to (N-1)th dimension of the physical input shape.
      # Thus, we enumerate to get all possible cases.
      if 0 in input_sharding_spec.dim_partition_dict:
          # if 0 is in the dim_partition_dict, it means that the
          # the generated sharding strategy does shard the non-matrix dimension,
          # in this case, we need to do enumeration
          num_input_dims = input_op_data.data.dim()
          for i in range(num_input_dims - 1):
              strategy_copy = strategy.clone()
              input_sharding_spec = (
                  strategy_copy.get_sharding_spec_by_name(
                      input_op_data.name
                  )
              )
              output_sharding_spec = (
                  strategy_copy.get_sharding_spec_by_name(
                      output_op_data.name
                  )
              )
              try:
                  # replace the 0th dimension in the logical sharding with ith dimension in the physical sharding
                  input_dim_mapping = {0: i}
                  input_dim_mapping.update(input_last_dim_mapping)
  
                  update_partition_dim(
                      sharding_spec=input_sharding_spec,
                      dim_mapping=input_dim_mapping,
                      physical_shape=input_op_data.data.shape,
                      inplace=True,
                  )
                  output_dim_mapping = {0: i}
                  output_dim_mapping.update(output_last_dim_mapping)
  
                  update_partition_dim(
                      sharding_spec=output_sharding_spec,
                      dim_mapping=output_dim_mapping,
                      physical_shape=output_op_data.data.shape,
                      inplace=True,
                  )
                  strategy_copy.name = f"{strategy.name}_{i}"
                  sharding_strategies.append(strategy_copy)
              except ShardingNotDivisibleError as e:
                  logger.debug(
                      f"Errored occurred when converting the logical sharding spec to the physical one. Error details: {e}"
                  )
      else:
          # the generated sharding strategy does not shard the non-matrix dimension,
          # in this case, we don't need to do enumeration
          # but instead, we still need to convert the logical shape to physical shape
          strategy_copy = strategy.clone()
          input_sharding_spec = strategy_copy.get_sharding_spec_by_name(
              input_op_data.name
          )
          output_sharding_spec = (
              strategy_copy.get_sharding_spec_by_name(
                  output_op_data.name
              )
          )
  
          # after updating, the logical shape will be replaced by the physical shape
          input_dim_mapping = {}
          input_dim_mapping.update(input_last_dim_mapping)
          update_partition_dim(
              sharding_spec=input_sharding_spec,
              dim_mapping=input_dim_mapping,
              physical_shape=input_op_data.data.shape,
              inplace=True,
          )
  
          output_dim_mapping = {}
          output_dim_mapping.update(output_last_dim_mapping)
          update_partition_dim(
              sharding_spec=output_sharding_spec,
              dim_mapping=output_dim_mapping,
              physical_shape=output_op_data.data.shape,
              inplace=True,
          )
          sharding_strategies.append(strategy_copy)
      return sharding_strategies
  
imports: from typing import Dict, List, Union
  import torch
  import torch.nn.functional
  from colossalai.auto_parallel.tensor_shard.utils import transpose_partition_dim, update_partition_dim
  from colossalai.logging import get_dist_logger
  from colossalai.tensor.sharding_spec import ShardingNotDivisibleError
  from ..sharding_strategy import OperationData, OperationDataType, ShardingStrategy
  from .node_handler import MetaInfoModuleHandler, MetaInfoNodeHandler
  from .registry import operator_registry
  from .strategy import LinearProjectionStrategyGenerator, StrategyGenerator
label_desc: Use image node_id 2 for calling a global function with example usage: _convert_logical_sharding_to_physical_sharding_spec_for_linear(strategy, input_name, output_name) and returns: sharding_strategies