class_docstr: StrategiesConstructor is used to construct the parallelization plan for the model execution.
  
  Args:
      graph (Graph): a Graph object used for analysis and strategy generation.
      device_mesh (DeviceMesh): a DeviceMesh object which contains the meta information about the cluster.
      solver_options (SolverOptions): a SolverOptions object which specifies the preferences for plan searching.
class_docstr_tok: ["StrategiesConstructor","is","used","to","construct","the","parallelization","plan","for","the","model","execution",".","Args",":","graph","(","Graph",")",":","a","Graph","object","used","for","analysis","and","strategy","generation",".","device_mesh","(","DeviceMesh",")",":","a","DeviceMesh","object","which","contains","the","meta","information","about","the","cluster",".","solver_options","(","SolverOptions",")",":","a","SolverOptions","object","which","specifies","the","preferences","for","plan","searching","."]
docstr: This method is to build the strategy vector for each node in the computation graph.
docstr_tok: ["This","method","is","to","build","the","strategy","vector","for","each","node","in","the","computation","graph","."]
code: def build_strategies_and_cost(self):
      """
      This method is to build the strategy vector for each node in the computation graph.
      """
  
      def _check_no_strategy_for_node(node):
          if node.op in ("placeholder", "get_attr", "output"):
              return False
  
          def _check_no_strategy_for_data(data):
              label = True
              if isinstance(data, torch.Tensor):
                  return False
              elif isinstance(data, (tuple, list)):
                  for d in data:
                      label = label and _check_no_strategy_for_data(d)
              return label
  
          return _check_no_strategy_for_data(node._meta_data)
  
      for node in self.nodes:
          strategies_vector = StrategiesVector(node)
  
          if _check_no_strategy_for_node(node):
              self.no_strategy_nodes.append(node)
  
          # placeholder node
          elif node.op == "placeholder":
              if (
                  self.solver_options.dataloader_option
                  == DataloaderOption.DISTRIBUTED
              ):
                  placeholder_option = "distributed"
              else:
                  assert (
                      self.solver_options.dataloader_option
                      == DataloaderOption.REPLICATED
                  ), f"placeholder_option {self.solver_options.dataloader_option} is not supported"
                  placeholder_option = "replicated"
              placeholder_handler = PlaceholderHandler(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  placeholder_option=placeholder_option,
              )
              placeholder_handler.register_strategy()
  
          # get_attr node
          elif node.op == "get_attr":
              getattr_handler = GetattrHandler(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  shard_option=self.solver_options.shard_option,
                  solver_perference=self.solver_options.solver_perference,
              )
              getattr_handler.register_strategy()
  
          # call_module node
          elif node.op == "call_module":
              target = node.target
              submod = self.root_module.get_submodule(target)
              submod_type = type(submod)
              handler = operator_registry.get(submod_type)(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  shard_option=self.solver_options.shard_option,
                  solver_perference=self.solver_options.solver_perference,
              )
              handler.register_strategy()
              # attach strategies_info to node
              if hasattr(handler, "strategies_info"):
                  setattr(
                      node, "strategies_info", handler.strategies_info
                  )
  
          # call_function node
          elif node.op == "call_function":
              target = node.target
              handler = operator_registry.get(target)(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  shard_option=self.solver_options.shard_option,
                  solver_perference=self.solver_options.solver_perference,
              )
              handler.register_strategy()
              # attach strategies_info to node
              if hasattr(handler, "strategies_info"):
                  setattr(
                      node, "strategies_info", handler.strategies_info
                  )
  
          # call_method node
          elif node.op == "call_method":
              method = getattr(
                  node.args[0]._meta_data.__class__, node.target
              )
              handler = operator_registry.get(method)(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  shard_option=self.solver_options.shard_option,
                  solver_perference=self.solver_options.solver_perference,
              )
              handler.register_strategy()
              # attach strategies_info to node
              if hasattr(handler, "strategies_info"):
                  setattr(
                      node, "strategies_info", handler.strategies_info
                  )
  
          # output node
          elif node.op == "output":
              if (
                  self.solver_options.dataloader_option
                  == DataloaderOption.DISTRIBUTED
              ):
                  output_option = "distributed"
              else:
                  assert (
                      self.solver_options.dataloader_option
                      == DataloaderOption.REPLICATED
                  ), f"placeholder_option {self.solver_options.dataloader_option} is not supported"
                  output_option = "replicated"
              output_handler = OutputHandler(
                  node,
                  self.device_mesh,
                  strategies_vector,
                  output_option=output_option,
              )
              output_handler.register_strategy()
  
          self.remove_duplicated_strategy(strategies_vector)
          setattr(node, "strategies_vector", strategies_vector)
          self.leaf_strategies.append(strategies_vector)
          self.strategy_map[node] = strategies_vector
  
      # remove no strategy nodes
      remove_list = []
      for strategies_vector in self.leaf_strategies:
          if len(strategies_vector) == 0:
              remove_list.append(strategies_vector.node)
  
      for node in remove_list:
          if node.strategies_vector in self.leaf_strategies:
              self.leaf_strategies.remove(node.strategies_vector)
          if node in self.strategy_map:
              self.strategy_map.pop(node)
  
      alias_set = self.generate_alias_set()
      self.alias_set = alias_set
  
file_path: ColossalAI/colossalai/auto_parallel/tensor_shard/solver/strategies_constructor.py
imports: import torch
  from torch.fx import Graph
  from colossalai.auto_parallel.tensor_shard.node_handler import GetattrHandler, OutputHandler, PlaceholderHandler, operator_registry
  from colossalai.auto_parallel.tensor_shard.sharding_strategy import StrategiesVector
  from colossalai.auto_parallel.tensor_shard.utils.factory import find_repeat_blocks
  from colossalai.device.device_mesh import DeviceMesh
  from ..options import DataloaderOption, SolverOptions
label_desc: Use image node_id 4 for calling the StrategiesConstructor obj's underlying member method code with example usage: obj.build_strategies_and_cost() and returns: _check_no_strategy_for_data, False, label, False