class_docstr: Trace all indice information for every node.
  
  Indice is a logical concept. Equal dims can been treated as one indice.
  eg. dim(x1) = [a, b, c]
      dim(x2) = [d, e, f]
      and we have x3 = x1 * x2.
      then a=d, b=e, c=f, due to the broadcast property,
      dim(x1)=dim(x2)=dim(x3)=[a, b, c]
  This class will record every node's dims' indice, compute and source.
  
  Attributes:
      node_list (List)
      indice_trace_list (List): [{"indice": [...], "compute": [...], "source": [...]}, {...}]
      indice_view_list (Dict): not used for now
      indice_count (int): record indice number
  
  Args:
      node_list (List)
class_docstr_tok: ["Trace","all","indice","information","for","every","node",".","Indice","is","a","logical","concept",".","Equal","dims","can","been","treated","as","one","indice",".","eg",".","dim","(","x1",")","=","[","a",",","b",",","c","]","dim","(","x2",")","=","[","d",",","e",",","f","]","and","we","have","x3","=","x1","*","x2",".","then","a=d",",","b=e",",","c=f",",","due","to","the","broadcast","property",",","dim","(","x1",")","=dim","(","x2",")","=dim","(","x3",")","=","[","a",",","b",",","c","]","This","class","will","record","every","node","'s","dims","'","indice",",","compute","and","source",".","Attributes",":","node_list","(","List",")","indice_trace_list","(","List",")",":","[","{","``","indice","''",":","[","...","]",",","``","compute","''",":","[","...","]",",","``","source","''",":","[","...","]","}",",","{","...","}","]","indice_view_list","(","Dict",")",":","not","used","for","now","indice_count","(","int",")",":","record","indice","number","Args",":","node_list","(","List",")"]
docstr: Assign indice for view and reshape op.
  1. get origin shape and target shape by meta info.
  2. compute the real value of -1 in target shape.
  3. determine changed dim, and assign indice for generated dim.
  4. log changed dim and generated dim for restore
  5. inherit computation.
  6. look into view list to see whether the view is associated with other,
     if so assign equal dim according to previous view.
  
  Args:
      node (node)
      node_idx (int)
docstr_tok: ["Assign","indice","for","view","and","reshape","op",".","1.","get","origin","shape","and","target","shape","by","meta","info",".","2.","compute","the","real","value","of","-1","in","target","shape",".","3.","determine","changed","dim",",","and","assign","indice","for","generated","dim",".","4.","log","changed","dim","and","generated","dim","for","restore","5.","inherit","computation",".","6.","look","into","view","list","to","see","whether","the","view","is","associated","with","other",",","if","so","assign","equal","dim","according","to","previous","view",".","Args",":","node","(","node",")","node_idx","(","int",")"]
code: def _assign_view_reshape_indice(
      self, node: Node, node_idx: int
  ) -> None:
      """
      Assign indice for view and reshape op.
      1. get origin shape and target shape by meta info.
      2. compute the real value of -1 in target shape.
      3. determine changed dim, and assign indice for generated dim.
      4. log changed dim and generated dim for restore
      5. inherit computation.
      6. look into view list to see whether the view is associated with other,
         if so assign equal dim according to previous view.
  
      Args:
          node (node)
          node_idx (int)
      """
      # get data, turn into number
      origin_node = node.args[0]
      origin_shape = origin_node.meta["tensor_meta"].shape
      target_shape = []
      unflated_args = flat_list(node.args)
      for i in range(1, len(unflated_args)):
          if isinstance(unflated_args[i], int):
              target_shape.append(unflated_args[i])
          else:
              target_shape.extend(unflated_args[i].meta["fwd_out"])
  
      # compute the value of -1
      if -1 in target_shape:
          origin_product = 1
          for i in origin_shape:
              origin_product *= i
          target_product = -1
          for i in target_shape:
              target_product *= i
          shape_idx = target_shape.index(-1)
          target_shape[shape_idx] = origin_product // target_product
  
      # find same dim
      dim_to_same_dim = []
      dim_from_same_dim = []
      for i in range(len(origin_shape)):
          if origin_shape[i] == target_shape[i]:
              dim_to_same_dim.append(i)
              dim_from_same_dim.append(i)
          else:
              break
      for i in range(-1, -len(origin_shape), -1):
          if origin_shape[i] == target_shape[i]:
              dim_to_same_dim.append(len(target_shape) + i)
              dim_from_same_dim.append(len(origin_shape) + i)
          else:
              break
  
      dim_from = list(
          set(range(len(origin_shape))) - set(dim_from_same_dim)
      )
      dim_to = list(
          set(range(len(target_shape))) - set(dim_to_same_dim)
      )
      assert (
          len(dim_from) == 1
          or len(dim_to) == 1
          or len(dim_from) == len(dim_to)
      )
  
      dim_diff = len(dim_from) - len(dim_to)
      if dim_diff > 0:
          # dim merge
          for i in range(dim_diff):
              self._add_dim(node_idx, -1)
      elif dim_diff < 0:
          # dim expand
          for i in range(-dim_diff):
              self._del_dim(node_idx, -1)
  
      # get new indice
      origin_trace = self._find_indice_trace_from_node(origin_node)
      self._assign_indice_as_input(node, node_idx, origin_node)
      dim_from.reverse()
      for i in dim_from:
          self._del_dim(node_idx, i)
      for i in dim_to:
          self._add_dim(node_idx, i)
      dim_from.reverse()
  
      # inherit indice from current node
      if len(dim_from) != 0 and len(dim_to) != 0:
          if dim_diff == 1:
              if origin_shape[dim_from[0]] == 1:
                  self._inherit_indice(
                      origin_node,
                      dim_from[1],
                      node,
                      dim_to[0],
                      init=False,
                  )
              elif origin_shape[dim_from[1]] == 1:
                  self._inherit_indice(
                      origin_node,
                      dim_from[0],
                      node,
                      dim_to[0],
                      init=False,
                  )
          elif dim_diff == -1:
              if target_shape[dim_to[0]] == 1:
                  self._inherit_indice(
                      origin_node,
                      dim_from[0],
                      node,
                      dim_to[1],
                      init=False,
                  )
              elif target_shape[dim_to[1]] == 1:
                  self._inherit_indice(
                      origin_node,
                      dim_from[0],
                      node,
                      dim_to[0],
                      init=False,
                  )
  
      # log view, not used now
      view_dict = {
          "idx_from": [origin_trace[i] for i in dim_from],
          "dim_from": dim_from,
          "idx_to": [
              self.indice_trace_list[node_idx]["indice"][i]
              for i in dim_to
          ],
          "dim_to": dim_to,
      }
      self.indice_view_list[node] = view_dict
  
imports: import copy
  from typing import Dict, List
  from torch.fx.node import Node
  from .utils import NodeMgr, find_first_tensor_arg, flat_list, get_module_node_name, get_node_name, get_node_shape
label_desc: Use image node_id 42 for calling the TraceIndice obj's underlying member method code with example usage: obj._assign_view_reshape_indice(node, node_idx) without return types