parameters: (block, op, idx, src_dtype, dest_dtype)
return_statement: return num_cast_ops
docstring: Insert cast op and rename args of input and output.
  
      Args:
          block (Program): The block in which the operator is.
          op (Operator): The operator to insert cast op.
          idx (int): The index of current operator.
          src_dtype (VarType): The input variable dtype of cast op.
          dest_dtype (VarType): The output variable dtype of cast op.
  
      Returns:
          num_cast_op (int): The number of cast ops that have been inserted.
docstring_summary: Insert cast op and rename args of input and output.
docstring_tokens: Insert cast op and rename args of input and output .
function: def _insert_cast_op(block, op, idx, src_dtype, dest_dtype):
      """
      Insert cast op and rename args of input and output.
  
      Args:
          block (Program): The block in which the operator is.
          op (Operator): The operator to insert cast op.
          idx (int): The index of current operator.
          src_dtype (VarType): The input variable dtype of cast op.
          dest_dtype (VarType): The output variable dtype of cast op.
  
      Returns:
          num_cast_op (int): The number of cast ops that have been inserted.
      """
      num_cast_ops = 0
  
      for in_name in op.input_names:
          if src_dtype == core.VarDesc.VarType.FP32 and _keep_fp32_input(op,
                                                                         in_name):
              continue
          for in_var_name in op.input(in_name):
              in_var = block._find_var_recursive(in_var_name)
              if in_var.type not in _valid_types or in_var.dtype == dest_dtype:
                  continue
              if in_var.dtype == src_dtype:
                  cast_name = in_var.name + '.cast_' + _dtype_to_str(dest_dtype)
                  out_var = block.vars.get(cast_name)
                  if out_var is None or out_var.dtype != dest_dtype:
                      op_device = op.attr('op_device')
                      # NOTE(wangxi): optimize for pipeline, reduce one send.
                      # if in_var is stop_gradient and prev_op device is `all`,
                      # set cast_op device to `all`, can reduce send cast_var.
                      # TODO: need remove this after we unified the dynamic
                      # and static pipeline interface.
                      if src_dtype == core.VarDesc.VarType.FP32 and in_var.stop_gradient:
                          prev_op = None
                          if in_var.op is op:
                              prev_op = find_true_prev_op(block.ops, op,
                                                          in_var_name)
                          elif in_var.op is not None:
                              prev_op = in_var.op
  
                          prev_op_device = None
                          if prev_op is not None:
                              prev_op_device = prev_op.attr('op_device')
  
                          if prev_op_device is not None and 'all' in prev_op_device:
                              op_device = prev_op_device
  
                      out_var = block.create_var(
                          name=cast_name,
                          dtype=dest_dtype,
                          persistable=False,
                          stop_gradient=in_var.stop_gradient)
  
                      block._insert_op_without_sync(
                          idx,
                          type="cast",
                          inputs={"X": in_var},
                          outputs={"Out": out_var},
                          attrs={
                              "in_dtype": in_var.dtype,
                              "out_dtype": out_var.dtype,
                              "op_device": op_device
                          })
                      num_cast_ops += 1
                  _rename_arg(op, in_var.name, out_var.name)
              else:
                  if op.has_attr('in_dtype'):
                      op._set_attr('in_dtype', dest_dtype)
      if src_dtype == core.VarDesc.VarType.FP32 and dest_dtype == core.VarDesc.VarType.FP16:
          for out_name in op.output_names:
              if _keep_fp32_output(op, out_name):
                  continue
              for out_var_name in op.output(out_name):
                  out_var = block.var(out_var_name)
                  if out_var.type not in _valid_types:
                      continue
                  if out_var.dtype == core.VarDesc.VarType.FP32:
                      out_var.desc.set_dtype(core.VarDesc.VarType.FP16)
                      if op.has_attr('out_dtype'):
                          op._set_attr('out_dtype', core.VarDesc.VarType.FP16)
      return num_cast_ops
function_tokens: def _insert_cast_op ( block , op , idx , src_dtype , dest_dtype ) : num_cast_ops = 0 for in_name in op . input_names : if src_dtype == core . VarDesc . VarType . FP32 and _keep_fp32_input ( op , in_name ) : continue for in_var_name in op . input ( in_name ) : in_var = block . _find_var_recursive ( in_var_name ) if in_var . type not in _valid_types or in_var . dtype == dest_dtype : continue if in_var . dtype == src_dtype : cast_name = in_var . name + '.cast_' + _dtype_to_str ( dest_dtype ) out_var = block . vars . get ( cast_name ) if out_var is None or out_var . dtype != dest_dtype : op_device = op . attr ( 'op_device' ) # NOTE(wangxi): optimize for pipeline, reduce one send. # if in_var is stop_gradient and prev_op device is `all`, # set cast_op device to `all`, can reduce send cast_var. # TODO: need remove this after we unified the dynamic # and static pipeline interface. if src_dtype == core . VarDesc . VarType . FP32 and in_var . stop_gradient : prev_op = None if in_var . op is op : prev_op = find_true_prev_op ( block . ops , op , in_var_name ) elif in_var . op is not None : prev_op = in_var . op prev_op_device = None if prev_op is not None : prev_op_device = prev_op . attr ( 'op_device' ) if prev_op_device is not None and 'all' in prev_op_device : op_device = prev_op_device out_var = block . create_var ( name = cast_name , dtype = dest_dtype , persistable = False , stop_gradient = in_var . stop_gradient ) block . _insert_op_without_sync ( idx , type = "cast" , inputs = { "X" : in_var } , outputs = { "Out" : out_var } , attrs = { "in_dtype" : in_var . dtype , "out_dtype" : out_var . dtype , "op_device" : op_device } ) num_cast_ops += 1 _rename_arg ( op , in_var . name , out_var . name ) else : if op . has_attr ( 'in_dtype' ) : op . _set_attr ( 'in_dtype' , dest_dtype ) if src_dtype == core . VarDesc . VarType . FP32 and dest_dtype == core . VarDesc . VarType . FP16 : for out_name in op . output_names : if _keep_fp32_output ( op , out_name ) : continue for out_var_name in op . output ( out_name ) : out_var = block . var ( out_var_name ) if out_var . type not in _valid_types : continue if out_var . dtype == core . VarDesc . VarType . FP32 : out_var . desc . set_dtype ( core . VarDesc . VarType . FP16 ) if op . has_attr ( 'out_dtype' ) : op . _set_attr ( 'out_dtype' , core . VarDesc . VarType . FP16 ) return num_cast_ops