(op, a, b, out=None, **kwargs)
return node
Build OpTreeNode.

        Arguments:
            a (OpTreeNode, Tensor, numeric): left-hand side operand.
            b (OpTreeNode, Tensor, numeric): right-hand side operand.
            out (Tensor, optional): where the result will be stored. If out is
                                    not None, the op-tree will be executed.
            kwargs: optional argument such as axis of the reducion.
Build OpTreeNode.
Build OpTreeNode .
def build(op, a, b, out=None, **kwargs):
        """
        Build OpTreeNode.

        Arguments:
            a (OpTreeNode, Tensor, numeric): left-hand side operand.
            b (OpTreeNode, Tensor, numeric): right-hand side operand.
            out (Tensor, optional): where the result will be stored. If out is
                                    not None, the op-tree will be executed.
            kwargs: optional argument such as axis of the reducion.
        """
        # check type
        for arg in (a, b):
            if not isinstance(arg, (int, float, Tensor, OpTreeNode, type(None))):
                return NotImplemented
        # get shape
        out_shape = [1, 1]
        if isinstance(a, (OpTreeNode, Tensor)):
            a_shape = a.shape
        elif isinstance(a, (float, int)):
            a_shape = [1, 1]
        else:
            a_shape = [0, 0]
        if isinstance(b, (OpTreeNode, Tensor)):
            b_shape = b.shape
        elif isinstance(b, (float, int)):
            b_shape = [1, 1]
        else:
            b_shape = [0, 0]

        # TODO: fix shape in smarter way
        if len(a_shape) == 1:
            a_shape = a_shape + (1,)
        if len(b_shape) == 1:
            b_shape = b_shape + (1,)

        if op in OpCollection.ew_ops:
            for i in range(2):
                out_shape[i] = max(a_shape[i], b_shape[i])
        elif op in OpCollection.reduction_ops:
            if "axis" in kwargs:
                out_shape = list(a_shape)
                out_shape[kwargs["axis"]] = 1
            else:
                pass  # [1, 1]
        elif op == "assign":
            out_shape = a_shape
        elif op == "dot":
            assert (len(a_shape) == len(b_shape) and len(b_shape) == 2 and
                    a_shape[1] == b_shape[0])
            out_shape = (a_shape[0], b_shape[1])
        elif op == "transpose":
            assert b is None
            out_shape = tuple(reversed(a_shape))
        else:
            raise TypeError("%s is not a valid operation" % op)
        out_shape = tuple(out_shape)

        # build op dict
        op_dict = {"op": op, "shape": out_shape}
        op_dict.update(kwargs)

        node = OpTreeNode(op_dict, a, b)

        # execute explicit assignment
        if op == "assign":
            return node.execute()

        # passing in an out value counts as assignment
        if out is not None:
            return OpTreeNode({"op": "assign"}, out, node).execute()

        # delay execution until assignment
        return node
def build ( op , a , b , out = None , * * kwargs ) : # check type for arg in ( a , b ) : if not isinstance ( arg , ( int , float , Tensor , OpTreeNode , type ( None ) ) ) : return NotImplemented # get shape out_shape = [ 1 , 1 ] if isinstance ( a , ( OpTreeNode , Tensor ) ) : a_shape = a . shape elif isinstance ( a , ( float , int ) ) : a_shape = [ 1 , 1 ] else : a_shape = [ 0 , 0 ] if isinstance ( b , ( OpTreeNode , Tensor ) ) : b_shape = b . shape elif isinstance ( b , ( float , int ) ) : b_shape = [ 1 , 1 ] else : b_shape = [ 0 , 0 ] # TODO: fix shape in smarter way if len ( a_shape ) == 1 : a_shape = a_shape + ( 1 , ) if len ( b_shape ) == 1 : b_shape = b_shape + ( 1 , ) if op in OpCollection . ew_ops : for i in range ( 2 ) : out_shape [ i ] = max ( a_shape [ i ] , b_shape [ i ] ) elif op in OpCollection . reduction_ops : if "axis" in kwargs : out_shape = list ( a_shape ) out_shape [ kwargs [ "axis" ] ] = 1 else : pass # [1, 1] elif op == "assign" : out_shape = a_shape elif op == "dot" : assert ( len ( a_shape ) == len ( b_shape ) and len ( b_shape ) == 2 and a_shape [ 1 ] == b_shape [ 0 ] ) out_shape = ( a_shape [ 0 ] , b_shape [ 1 ] ) elif op == "transpose" : assert b is None out_shape = tuple ( reversed ( a_shape ) ) else : raise TypeError ( "%s is not a valid operation" % op ) out_shape = tuple ( out_shape ) # build op dict op_dict = { "op" : op , "shape" : out_shape } op_dict . update ( kwargs ) node = OpTreeNode ( op_dict , a , b ) # execute explicit assignment if op == "assign" : return node . execute ( ) # passing in an out value counts as assignment if out is not None : return OpTreeNode ( { "op" : "assign" } , out , node ) . execute ( ) # delay execution until assignment return node