(self, op_tree, ad)
Arguments:
            op_tree (OpTreeNode or Tensor): the op_tree at this grad_node
            ad (Autodiff): the autodiff object with global op_tree, next_error and dicts
Arguments:
            op_tree (OpTreeNode or Tensor): the op_tree at this grad_node
            ad (Autodiff): the autodiff object with global op_tree, next_error and dicts
Arguments : op_tree ( OpTreeNode or Tensor ) : the op_tree at this grad_node ad ( Autodiff ) : the autodiff object with global op_tree next_error and dicts
def __init__(self, op_tree, ad):
        """
        Arguments:
            op_tree (OpTreeNode or Tensor): the op_tree at this grad_node
            ad (Autodiff): the autodiff object with global op_tree, next_error and dicts
        """
        # check op_tree
        assert op_tree is not None

        # attributes
        self.op_tree = op_tree  # forward op_tree
        self.grad_op_tree = None  # backward gradient op_tree
        self.ad = ad  # info about autodiff object
        self.left = None
        self.right = None

        # build GradNode recursively
        if isinstance(op_tree, Tensor):
            # save to ad.map_tensor_grad_node
            if op_tree._original_base not in ad.map_tensor_grad_node:
                ad.map_tensor_grad_node[op_tree._original_base] = self
        elif type(op_tree) == OpTreeNode:
            # init recursively
            if op_tree[1] is not None:
                if (isinstance(op_tree[1], Tensor) and
                        op_tree[1]._original_base in ad.map_tensor_grad_node):
                    # seen tensor before
                    self.left = ad.map_tensor_grad_node[op_tree[1]._original_base]
                else:
                    # build recursively
                    self.left = GradNode(op_tree[1], ad)
            if op_tree[2] is not None:
                if (isinstance(op_tree[2], Tensor) and
                        op_tree[2]._original_base in ad.map_tensor_grad_node):
                    # seen tensor before
                    self.right = ad.map_tensor_grad_node[op_tree[2]._original_base]
                else:
                    # build recursively
                    self.right = GradNode(op_tree[2], ad)
def __init__ ( self , op_tree , ad ) : # check op_tree assert op_tree is not None # attributes self . op_tree = op_tree # forward op_tree self . grad_op_tree = None # backward gradient op_tree self . ad = ad # info about autodiff object self . left = None self . right = None # build GradNode recursively if isinstance ( op_tree , Tensor ) : # save to ad.map_tensor_grad_node if op_tree . _original_base not in ad . map_tensor_grad_node : ad . map_tensor_grad_node [ op_tree . _original_base ] = self elif type ( op_tree ) == OpTreeNode : # init recursively if op_tree [ 1 ] is not None : if ( isinstance ( op_tree [ 1 ] , Tensor ) and op_tree [ 1 ] . _original_base in ad . map_tensor_grad_node ) : # seen tensor before self . left = ad . map_tensor_grad_node [ op_tree [ 1 ] . _original_base ] else : # build recursively self . left = GradNode ( op_tree [ 1 ] , ad ) if op_tree [ 2 ] is not None : if ( isinstance ( op_tree [ 2 ] , Tensor ) and op_tree [ 2 ] . _original_base in ad . map_tensor_grad_node ) : # seen tensor before self . right = ad . map_tensor_grad_node [ op_tree [ 2 ] . _original_base ] else : # build recursively self . right = GradNode ( op_tree [ 2 ] , ad )