#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from __future__ import division

from collections import Counter, deque
import numpy as np

from singa import tensor
from singa import utils
from .tensor import Tensor
from . import singa_wrap as singa

CTensor = singa.Tensor
training = False


def axis_helper(y_shape, x_shape):
    """
    check which axes the x has been broadcasted
    Args:
        y_shape: the shape of result
        x_shape: the shape of x
    Return:
        a tuple refering the axes
    """
    res = []
    j = len(x_shape) - 1
    for i in range(len(y_shape) - 1, -1, -1):
        if j < 0 or x_shape[j] != y_shape[i]:
            res.append(i)
        j -= 1
    return tuple(res[::-1])


def back_broadcast(y_shape, x_shape, x):
    """
    for a brodcasted tensor, restore its shape of x from y_shape to x_shape
    Args:
        y_shape: the shape of result
        x_shape: the shape of x
        x: the input
    Return:
        a tensor
    """
    if y_shape != x_shape:
        x = tensor.from_raw_tensor(x)
        axis = axis_helper(y_shape, x_shape)
        x = tensor.sum(x, axis)
        x = tensor.reshape(x, x_shape)
        x = x.data
    return x


def infer_dependency(op):
    """
    Infer the dependency of all operations with the
    given op as the last operation.
    Operator A is depending on B if A uses the output(s) of B.

    Args:
        op: an Operator instance, e.g. the loss operation.

    Return:
        a Counter instance with the operation as the key,
        and the number of operations that are depending on it as the value;
        and a Counter instance with the id of the output tensor as the key, and
        the number of operations that are depending on it as the value.
    """

    # current op is not inserted into the dependency_count
    # if the current op is not a terminal op, then this function may just
    # count dependency of a branch.
    op_count = Counter()
    tensor_count = Counter()
    queue = deque([op])
    while len(queue) > 0:
        cur_op = queue.pop()
        for src_op, xid, _, _ in cur_op.src:
            if src_op not in op_count:
                op_count[src_op] = 1
                queue.append(src_op)
            else:
                op_count[src_op] += 1
            tensor_count[xid] += 1
    return op_count, tensor_count


def gradients(y, dy=None):
    """
    Compute the gradients of the output w.r.t the parameters

    Args:
        y: the output tensor, e.g., the loss
        dy: gradient of the target w.r.t y; None indicates the gradient is 1.0;
            it can be used to rescale the loss.

    Return:
        a dictionary storing the gradient tensors of all tensors
            whose stores_grad is true (e.g. parameter tensors)
    """
    grads = {}  # mapping: x->dx if x.stores_grad
    for p, dp in backward(y, dy):
        # TODO: this fn is only helper for test case for now.
        #   1. could implement __hash__ or
        #   2. make grad as a attribute of tensor class
        #      p.grad = dp
        grads[id(p)] = dp
    return grads


def backward(y, dy=None):
    """
    Run the backward propagation starting at y.
    Args:
        y: a Tensor instance, usually the loss
        dy: a number or a Tensor instance, for the gradient of the
            objective/loss w.r.t y, usually None, i.e., 1.0
    Return:
        yeild the parameter (tensor with stores_grad true) and the
            gradient tensors.
    """
    assert isinstance(y, Tensor), "wrong input type."
    op_dep, tensor_dep = infer_dependency(y.creator)
    assert y.size() == 1, ("y must be a Tensor with a single value;"
                           "size of y is % d" % y.size())

    # by default the dy is a tensor with 1.0 for each sample;
    if dy is None:
        dy = float(1.0)
    elif isinstance(dy, Tensor):
        dy = dy.data
    else:
        dy = float(dy)

    # ready is a queue of (operation, dy list)
    ready = deque([(y.creator, (dy,))])
    not_ready = {}  # mapping: op->[dy]

    if y.stores_grad:
        # gradients[y] = dy
        if isinstance(dy, float):
            g = np.array(dy)
        else:
            g = dy
        tg = Tensor(device=g.device(), data=g)
        yield (y, tg)

    while len(ready) > 0:
        op, dys = ready.pop()
        if not op.requires_grad or isinstance(op, Dummy):
            continue
        # if not isinstance(op, tensor.Dummy):
        dxs = op._do_backward(*dys)
        # TODO src and dx must match

        assert len(op.src) == len(dxs), (
            "the number of src ops (=%d) and dx (=%d) not match" %
            (len(op.src), len(dxs)))
        for (src_op, x_id, y, y_stores_grad), dx in zip(op.src, dxs):
            # prefix x is w.r.t op; prefix y is w.r.t src_op.
            # x_id is the python id of one input arg of src_op, denoted as x.
            # y_idx (below) is the index of x among the outputs of src_op.
            # not_ready[src_op][y_idx] records the intermediate gradient
            # of the y_idx'th output of src_op. 'intermediate gradient'
            # indicates that if this output is used in multiple children
            # operations, then we have to add the graident (dx) from all these
            # children operations. When src_op is ready, it means that
            # the gradient of all its outputs are available, i.e. all children
            # operations have been backwarded.
            # y is None if y.stores_grad is false; otherwise it is a Tensor

            if isinstance(src_op, Dummy) and (not src_op.stores_grad):
                continue

            y_idx = src_op.y_id2idx[x_id]
            if src_op not in not_ready:
                # src_op may have mulitple outputs
                not_ready[src_op] = [None for _ in src_op.y_id2idx]
                not_ready[src_op][y_idx] = dx
            else:
                dxs_ = not_ready[src_op]
                if dxs_[y_idx] is None:
                    dxs_[y_idx] = dx
                else:
                    # add the gradient from another children operation that
                    # uses y_idx'th output of src_op as input arg
                    dxs_[y_idx] += dx

            op_dep[src_op] -= 1
            tensor_dep[x_id] -= 1
            if y_stores_grad and tensor_dep[x_id] == 0:
                # store the gradient for final return, e.g. for parameters.
                # it may cause a delay to yield. Only after src_op's all
                # output tensors have recieved the gradients, then output
                g = not_ready[src_op][y_idx]
                tg = Tensor(device=g.device(),
                            data=g,
                            name=src_op.grad_name(y_idx))
                yield (y, tg)

            if op_dep[src_op] == 0:
                if src_op.requires_grad is True:
                    assert not isinstance(
                        src_op, Dummy), "Dummy op does not do backward()"
                    ready.append((src_op, not_ready[src_op]))
                del not_ready[src_op]
        del op  # delete the operation to free all tensors from this op


class Operator(object):
    """
    An operation includes the forward and backward function of
    tensor calculation.
    Steps to add a specific operation Xxxx:
    1. create a subclass of Operator, name it as Xxxx
    2. override the forward() and backward(); The arguments of forward()
       and backward() should only include CTensor;
    """

    op_count = 0

    def __init__(self, name=None):
        if name is None:
            self.name = "{}#{}".format(self.__class__.__name__,
                                       Operator.op_count)
            Operator.op_count += 1
        else:
            self.name = name

    def __call__(self, *xs):
        return self._do_forward(*xs)

    def output_name(self, idx):
        """
        Args:
            idx: index of the output among all outputs

        Return:
            the name of the output tensor
        """
        return "{}:{}".format(self.name, idx)

    def grad_name(self, idx):
        """
        Args:
            idx: index of the output among all outputs

        Return:
            the name of the gradient of the output tensor
        """
        return "{}_g".format(self.output_name(idx))

    def _do_forward(self, *xs):
        """
        Do not call this function from user code. It is called by __call__().
        Args:
            xs, Tensor instance(s)
        Returns:
            Tensor instance(s)
        """
        # TODO add the pre hook
        assert all([isinstance(x, Tensor) for x in xs
                   ]), "xs should include only Tensor instances"

        # need to do backward if any of its input arg needs gradient
        self.requires_grad = any([x.requires_grad for x in xs])

        self.src = []
        for x in xs:
            if x.stores_grad:
                # store the tensor whose gradient needs be returned in
                # backward(), e.g. if x is parameter
                self.src.append((x.creator, id(x), x, x.stores_grad))
            else:
                # for intermediate tensors, they will be released soon;
                # no need to store them --> use None
                self.src.append((x.creator, id(x), None, x.stores_grad))

        # get the CTensor (data) if the input arg is Tensor
        xs = tuple(x.data for x in xs)
        ys = self.forward(*xs)
        if not isinstance(ys, tuple):
            ys = (ys,)
        # create Tensor based on CTensor(data);
        # assume outputs are all Tensor instances
        ys = tuple(
            Tensor(
                device=y.device(),
                data=y,
                requires_grad=self.requires_grad,
                creator=self,
                name=self.output_name(idx),
            ) for idx, y in enumerate(ys))
        # map from python id to output index
        self.y_id2idx = {id(y): i for i, y in enumerate(ys)}
        # TODO add the post hook
        return ys

    def _do_backward(self, *dys):
        dxs = self.backward(*dys)
        if not isinstance(dxs, tuple):
            dxs = (dxs,)
        return dxs

    def forward(self, *xs):
        """Forward propagation.
        Args:
            xs: input args consisting of only CTensors.
        Returns:
            CTensor instance(s)
        """
        raise NotImplementedError

    def backward(self, *dys):
        """ Backward propagation.
        Args:
            dys: input args consisting of only CTensors.
        Returns:
            CTensor instance(s)
        """
        raise NotImplementedError

    def get_params(self):
        return []


class Dummy(Operator):
    """Dummy operation whice serves as a placehoder for autograd
    Args:
        name(string): set it for debug
    """

    def __init__(self, tensor, name=None):
        super(Dummy, self).__init__(name)
        self.src = []
        self.y_id2idx = {id(tensor): 0}
        self.tensor = tensor
        self.requires_grad = False

    def output_name(self, idx):
        return self.name

    def grad_name(self, idx):
        return "{}_g".format(self.name)

    def __getattr__(self, name):
        return self.tensor.__getattribute__(name)


class Mean(Operator):
    """
    Element-wise mean of each of the input CTensors.
    """

    def __init__(self):
        super(Mean, self).__init__()

    def forward(self, *l):
        """
        Args:
            l (a list of CTensor): a list of CTensor for element-wise mean.
        Returns:
            a new CTensor.
        """
        if training:
            self.l = len(l)
        assert (len(l) > 0)
        x = singa.Tensor(list(l[0].shape()), l[0].device())
        x.SetFloatValue(0.0)
        for i in range(len(l)):
            x += l[i]
        return singa.MultFloat(x, 1 / len(l))

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy.
        Returns:
            a list of dx (CTensor).
        """
        return [singa.MultFloat(dy, 1 / self.l)] * self.l


def mean(*l):
    """
    Element-wise mean of each of the input tensors.
    Args:
        l (a list of Tensor): element-wise mean operator.
    Returns:
        a new Tensor.
    """
    return Mean()(*l)[0]


class ReLU(Operator):
    """
    Relu means rectified linear function, i.e, y = max(0, x) is applied to the
    CTensor elementwise.
    """

    def __init__(self):
        super(ReLU, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): input tensor.
        Returns:
            a new CTensor whose element y = x if x >= 0; otherwise 0.
        """
        if training:
            self.input = x
        return singa.ReLU(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy.
        Returns:
            dx (CTensor): dL / dx = dy if x >= 0; otherwise 0.
        """
        return singa.ReLUBackward(dy, self.input)


def relu(x):
    """
    Relu means rectified linear function, i.e, y = max(0, x) is applied to the
    CTensors elementwise.
    Args:
        x (Tensor): input tensor.
    Returns:
        a new Tensor whose element y = x if x >= 0; otherwise 0.
    """
    return ReLU()(x)[0]


class Less(Operator):
    """
    Returns the tensor resulted from performing the less logical operation
    elementwise on the input CTensors x and y.
    """

    def __init__(self):
        super(Less, self).__init__()

    def forward(self, x, y):
        """
        Return a<b, where a and b are CTensor.
        """
        cur = singa.LTFloat(singa.__sub__(x, y), 0)
        if training:
            self.cache = cur
        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss.
        Raises:
            AssertionError: no backward function for this operator.
        """
        assert False, ('no backward function for less')


def less(x, y):
    """
    Return a<b, where a and b are CTensor.
    """
    return Less()(x, y)[0]


class Clip(Operator):
    """
    Clip operator limits the given input within an interval. The interval
    is specified by the inputs 'min' and 'max'.
    """

    def __init__(self, min, max):
        """
        Args:
            min (float): min value, under which element is replaced by min.
            max (float): max value, above which element is replaced by max.
        """
        super(Clip, self).__init__()
        self.max = max
        self.min = min

    def forward(self, x):
        """
        Args:
            x (CTensor): input tensor
        Returns:
            a new CTensor with np.clip(x,min,max)
        """
        self.mask = singa.Tensor(list(x.shape()), x.device())
        self.mask.SetFloatValue(1.0)

        if self.min is not None:
            self.min = float(self.min)
            mask0 = singa.LTFloat(x, self.min)
            mask1 = singa.GEFloat(x, self.min)
            self.mask = singa.__mul__(mask1, self.mask)
            x = singa.__add__(singa.MultFloat(mask0, self.min),
                              singa.__mul__(mask1, x))

        if self.max is not None:
            self.max = float(self.max)
            mask0 = singa.GTFloat(x, self.max)
            mask1 = singa.LEFloat(x, self.max)
            self.mask = singa.__mul__(mask1, self.mask)
            x = singa.__add__(singa.MultFloat(mask0, self.max),
                              singa.__mul__(mask1, x))

        return x

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        return singa.__mul__(dy, self.mask)


def clip(x, min=None, max=None):
    """
    Clip operator limits the given input within an interval. The interval
    is specified by the inputs 'min' and 'max'.
    Args:
        x (Tensor): input tensor
        min (float): Minimum value, under which element is replaced by min.
        max (float): Maximum value, above which element is replaced by max.
    Returns:
        a new Tensor with np.clip(x,min,max).
    """
    return Clip(min, max)(x)[0]


class Identity(Operator):
    """
    Init a identity operator
    """

    def __init__(self):
        super(Identity, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): input tensor.
        Returns:
            the same CTensor x.
        """
        return x

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy.
        Returns:
            dx (CTensor): dL / dx.
        """
        return dy


def identity(x):
    """
    Init a identity operator.
    Args:
        x (Tensor): input tensor.
    Returns:
        the same Tensor with x.
    """
    return Identity()(x)[0]


class Matmul(Operator):
    """
    Init matrix multiplication operator.
    """

    def __init__(self):
        super(Matmul, self).__init__()

    def forward(self, x, w):
        """
        Return `np.matmul(x,w)`, where x and w are CTensor.
        """
        # todo, cannot do Mult for dims more than 2
        if training:
            self.input = (x, w)
        res = singa.Mult(x, w)
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss.
        Returns:
            a tuple for (dx, dw).
        """
        return (
            singa.Mult(dy, singa.DefaultTranspose(self.input[1])),
            singa.Mult(singa.DefaultTranspose(self.input[0]), dy),
        )


def matmul(x, w):
    """
    Return `np.matmul(x,w)`, where x and w are Tensor.
    """
    return Matmul()(x, w)[0]


class Greater(Operator):
    """
    Returns the tensor resulted from performing the greater logical
    operation elementwise on the input tensors A and B.
    """

    def __init__(self):
        super(Greater, self).__init__()

    def forward(self, x, y):
        """
        Return a>b, where a and b are CTensor.
        """
        cur = singa.GTFloat(singa.__sub__(x, y), 0)
        if training:
            self.cache = cur
        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss.
        Raises:
            AssertionError: no backward function for this operator.
        """
        assert False, ('no backward function for greater')


def greater(x, y):
    """
    Return a>b, where a and b are Tensor.
    """
    return Greater()(x, y)[0]


class AddBias(Operator):
    """
    Add Bias to each row / column of the Tensor, depending on the axis arg.
    """

    def __init__(self, axis=0):
        """
        To indicate the calculation axis, 0 for row, 1 for column.
        Args:
            axis (int): 0 or 1, default is 0.
        """
        super(AddBias, self).__init__()
        self.axis = axis

    def forward(self, x, b):
        """
        Args:
            x (CTensor): matrix.
            b (CTensor): bias to be added.
        Return:
            the result Tensor
        """
        if self.axis == 0:
            singa.AddRow(b, x)
        elif self.axis == 1:
            singa.AddColumn(b, x)
        return x

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss.
        Return:
            a tuple for (db, dx), db is data for dL / db, dx is data
            for dL / dx.
        """
        dtype = dy.data_type()
        _dy = dy.AsType(tensor.float32)
        if self.axis == 0:
            return dy, singa.Sum(_dy, 0).AsType(dtype)
        elif self.axis == 1:
            return dy, singa.Sum(_dy, 0).AsType(dtype)


def add_bias(x, b, axis=0):
    """
    Add Bias to each row / column of the Tensor, depending on the axis arg.
    Args:
        x (Tensor): matrix.
        b (Tensor): bias to be added.
        axis (int): 0 or 1, default is 0.
    Return:
        the result Tensor
    """
    assert x.ndim() == 2, "1st arg required 2d tensor. got shape: %s" % (
        x.shape)
    assert b.ndim() == 1, "2nd arg required 1d tensor. got shape: %s" % (
        b.shape)
    assert axis in [0, 1], "allowed axis: 0 or 1"
    return AddBias(axis)(x, b)[0]


class Reshape(Operator):
    """
    Reshape the input tensor similar to np.reshape.
    """

    def __init__(self, shape):
        """
        Args:
            shape (list of int): Specified shape for output. At most one
                dimension of the new shape can be -1. In this case, the
                value is inferred from the size of the tensor and the
                remaining dimensions. A dimension could also be 0,
                in which case the actual dimension value is unchanged
                (i.e. taken from the input tensor).
        """
        super(Reshape, self).__init__()
        self.shape = shape

    def forward(self, x):
        """
        Args:
            x (CTensor): matrix.
        Return:
            the result CTensor
        """
        self._shape = x.shape()
        shape = list(self.shape)
        # handle the shape with 0
        shape = [
            self._shape[i]
            if i < len(self._shape) and shape[i] == 0 else shape[i]
            for i in range(len(shape))
        ]
        # handle the shape with -1
        hidden_shape = int(np.prod(self._shape) // np.abs(np.prod(shape)))
        self.cache = [int(s) if s != -1 else hidden_shape for s in shape]
        return singa.Reshape(x, self.cache)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        return singa.Reshape(dy, self._shape)


def reshape(x, shape):
    """
    Reshape the input tensor similar to mp.reshape.
    Args:
        x (Tensor): matrix.
        shape (list of int): Specified shape for output. At most one
            dimension of the new shape can be -1. In this case, the
            value is inferred from the size of the tensor and the
            remaining dimensions. A dimension could also be 0,
            in which case the actual dimension value is unchanged
            (i.e. taken from the input tensor).
    Return:
        the result Tensor
    """
    return Reshape(shape)(x)[0]


class PRelu(Operator):
    """
    PRelu applies the function `f(x) = slope * x` for x < 0,
    `f(x) = x` for x >= 0 to the data tensor elementwise.
    """

    def __init__(self):
        super(PRelu, self).__init__()

    def forward(self, x, slope):
        """
        Args:
            x (CTensor): matrix.
        Return:
            the result CTensor
        """
        mask0 = singa.LTFloat(x, 0.0)
        res = singa.__mul__(x, mask0)
        res = singa.__mul__(res, slope)
        res += singa.ReLU(x)
        if training:
            self.input = x
            self.slope = slope
            self.mask0 = mask0
            self.shape0 = list(x.shape())
            self.shape1 = list(slope.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        dx1mask = singa.GEFloat(self.input, 0.0)
        dx2 = singa.__mul__(self.mask0, self.slope)
        dx = singa.__add__(dx1mask, dx2)
        dx = singa.__mul__(dy, dx)
        dslope = singa.__mul__(dy, singa.__mul__(self.mask0, self.input))
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx, dslope
        # handle broadcast
        dx = back_broadcast(self.shape3, self.shape0, dx)
        dslope = back_broadcast(self.shape3, self.shape1, dslope)
        return dx, dslope


def prelu(x, slope):
    """
    PRelu applies the function `f(x) = slope * x` for x < 0,
    `f(x) = x` for x >= 0 to the data tensor elementwise.
    Args:
        x (Tensor): matrix.
    Return:
        the result Tensor
    """
    return PRelu()(x, slope)[0]


class Add(Operator):
    """
    Performs element-wise binary addition.
    """

    def __init__(self):
        super(Add, self).__init__()

    def forward(self, a, b):
        """
        Return `a+b`, where a and b are CTensor.
        """
        res = singa.__add__(a, b)
        if training:
            self.shape0 = list(a.shape())
            self.shape1 = list(b.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy(CTensor): dL / dy
        Return:
            a tuple for (dx0, dx1), dx0 is data for dL / da, dx1 is data
            for dL / db.
        """
        dx0, dx1 = dy, dy
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx0, dx1
        # handle broadcast
        dx0 = back_broadcast(self.shape3, self.shape0, dx0)
        dx1 = back_broadcast(self.shape3, self.shape1, dx1)
        return dx0, dx1


def add(a, b):
    """
    Return `a+b`, where a and b are Tensor.
    """
    return Add()(a, b)[0]


class Elu(Operator):
    """
    `f(x) = alpha * (exp(x) - 1.)` for x < 0, `f(x) = x` for x >= 0., is applied to
    the tensor elementwise.
    """

    def __init__(self, alpha=1.):
        """
        Args:
            alpha (float): Coefficient of ELU, default is 1.0
        """
        super(Elu, self).__init__()
        self.alpha = alpha

    def forward(self, x):
        """
        Args:
            x (CTensor): matrix
        Returns:
            a CTensor for the result
        """
        #f(x) = alpha * (exp(x) - 1.) for x < 0, f(x) = x for x >= 0
        if training:
            self.input = x
        x1 = singa.LTFloat(x, 0.0)
        x1 *= x
        x1 = singa.MultFloat(singa.SubFloat(singa.Exp(x1), 1.0), self.alpha)
        x2 = singa.ReLU(x)
        x1 += x2
        return x1

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        dx1mask = singa.LTFloat(self.input, 0.0)
        dx = singa.MultFloat(singa.Exp(self.input), self.alpha)
        dx *= dx1mask

        dx2mask = singa.GEFloat(self.input, 0.0)

        dx += dx2mask
        dx *= dy
        return dx


def elu(x, alpha=1):
    """
    `f(x) = alpha * (exp(x) - 1.)` for x < 0, `f(x) = x` for x >= 0., is applied to
    the tensor elementwise.
    Args:
        x (Tensor): matrix
        alpha (float): Coefficient of ELU, default is 1.0
    Returns:
        a Tensor for the result
    """
    return Elu(alpha)(x)[0]


class Equal(Operator):
    """
    Returns the tensor resulted from performing the equal logical operation
    elementwise on the input tensors x and y.
    """

    def __init__(self):
        super(Equal, self).__init__()

    def forward(self, x, y):
        """
        Return `a=b`, where a and b are CTensor.
        """
        return singa.__eq__(x, y)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no backward function for equal')


def equal(x, y):
    """
    Return `a=b`, where a and b are Tensor.
    """
    return Equal()(x, y)[0]


class SeLU(Operator):
    """
    `y = gamma * (alpha * e^x - alpha)` for x <= 0, `y = gamma * x` for x > 0
    is applied to the tensor elementwise.
    """

    def __init__(self, alpha=1.67326, gamma=1.0507):
        """
        Args:
            alpha (float): Coefficient of SELU default to 1.67326
            gamma (float): Coefficient of SELU default to 1.0507
        """
        super(SeLU, self).__init__()
        self.alpha = alpha
        self.gamma = gamma

    def forward(self, x):
        """
        Args:
            x (CTensor): matrix
        Returns:
            a CTensor for the result
        """
        #y = gamma * (alpha * e^x - alpha) for x <= 0, y = gamma * x for x > 0
        if training:
            self.input = x
        x1 = singa.LEFloat(x, 0.0)
        x1 *= x
        x1 = singa.MultFloat(singa.SubFloat(singa.Exp(x1), 1.0),
                             self.alpha * self.gamma)
        x2 = singa.ReLU(x)
        x2 = singa.MultFloat(x2, self.gamma)
        x1 += x2
        return x1

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        dx1mask = singa.LEFloat(self.input, 0.0)
        dx1 = singa.MultFloat(singa.Exp(self.input), self.gamma * self.alpha)
        dx1 = singa.__mul__(dx1mask, dx1)

        dx2mask = singa.GTFloat(self.input, 0.0)
        dx2 = singa.MultFloat(dx2mask, self.gamma)

        dx = singa.__add__(dx1, dx2)
        dx *= dy
        return dx


def selu(x, alpha=1.67326, gamma=1.0507):
    """
    `y = gamma * (alpha * e^x - alpha)` for x <= 0, `y = gamma * x` for x > 0
    is applied to the tensor elementwise.
    Args:
        x (Tensor): matrix
        alpha (float): Coefficient of SELU default to 1.67326
        gamma (float): Coefficient of SELU default to 1.0507
    Returns:
        a Tensor for the result
    """
    return SeLU(alpha, gamma)(x)[0]


class SoftMax(Operator):
    """
    Apply SoftMax for each row of the Tensor or each column of the Tensor
    according to the parameter axis.
    """

    def __init__(self, axis=1):
        """
        Args:
            axis (int): axis of softmax, default to 1
        """
        super(SoftMax, self).__init__()
        self.axis = axis

    def forward(self, x):
        """
        Args:
            x (CTensor): the input 1d or 2d tensor
        Returns:
            the result CTensor
        """
        self.output = singa.SoftMax(x, self.axis)
        return self.output

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        return singa.SoftMaxBackward(dy, self.axis, self.output)


def softmax(x, axis=1):
    """
    Apply SoftMax for each row of the Tensor or each column of the Tensor
    according to the parameter axis.
    Args:
        x (Tensor): the input 1d or 2d tensor
        axis (int): axis of softmax, default to 1
    Returns:
        the result Tensor
    """
    return SoftMax(axis)(x)[0]


class Sum(Operator):
    """
    Element-wise sum of each of the input tensors
    """

    def __init__(self):
        super(Sum, self).__init__()

    def forward(self, *l):
        """
        Args:
            l (a list of CTensor): element-wise sum operator
        Returns:
            a CTensor for the result
        """
        if training:
            self.l = len(l)
        assert (len(l) > 0)
        x = singa.Tensor(list(l[0].shape()), l[0].device())
        x.SetFloatValue(0.0)
        for i in range(len(l)):
            x += l[i]
        return x

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        return [dy] * self.l


def sum(*l):
    """
    Element-wise sum of each of the input tensors
    Args:
        l (a list of Tensor): element-wise sum operator
    Returns:
        a Tensor for the result
    """
    return Sum()(*l)[0]


class BinaryCrossEntropy(Operator):

    def __init__(self, t):
        super(BinaryCrossEntropy, self).__init__()
        self.t = t.data

    """
    Calculte negative log likelihood loss for a batch of training data.
    """

    def forward(self, x):
        """
        Args:
            x (CTensor): 1d or 2d tensor, the prediction data(output)
                         of current network.
            t (CTensor): 1d or 2d tensor, the target data for training.
        Returns:
            loss (CTensor): scalar.
        """
        posx = singa.AddFloat(x, 0.0001)
        loss = singa.SumAll(singa.__mul__(self.t, singa.Log(posx)))
        negt = singa.AddFloat(singa.MultFloat(self.t, -1.0), 1.0)
        negx = singa.AddFloat(singa.MultFloat(x, -1.0), 1.0001)
        negLoss = singa.SumAll(singa.__mul__(negt, singa.Log(negx)))
        loss += negLoss
        loss /= -x.shape()[0]
        self.x = singa.AddFloat(x, 0.0001)
        return loss

    def backward(self, dy=1.0):
        """
        Args:
            dy (float or CTensor): scalar, accumulate gradient from outside
                                of current network, usually equal to 1.0
        Returns:
            dx (CTensor): data for the dL /dx, L is the loss, x is the output
                          of current network. note that this is true for
                          dy = 1.0
        """

        dx = singa.__div__(self.t, self.x)
        negt = singa.AddFloat(self.t, -1.0)
        negx = singa.AddFloat(self.x, -0.9999)
        dx -= singa.__div__(negt, negx)
        dx *= float(-1.0 / self.x.shape()[0])
        if isinstance(dy, float):
            # dtype of dy: float
            dx *= dy
            return dx
        elif isinstance(dy, CTensor):
            pass  # TODO, broadcast elementwise multiply seems not support


def binary_cross_entropy(x, t):
    return BinaryCrossEntropy(t)(x)[0]


class CrossEntropy(Operator):

    def __init__(self, t):
        super(CrossEntropy, self).__init__()
        self.t = t.data

    """
    Calculte negative log likelihood loss for a batch of training data.
    """

    def forward(self, x):
        """
        Args:
            x (CTensor): 1d or 2d tensor, the prediction data(output)
                         of current network.
            t (CTensor): 1d or 2d tensor, the target data for training.
        Returns:
            loss (CTensor): scalar.
        """
        loss = singa.SumAll(singa.__mul__(self.t, singa.Log(x)))
        loss /= -x.shape()[0]
        self.x = x
        return loss

    def backward(self, dy=1.0):
        """
        Args:
            dy (float or CTensor): scalar, accumulate gradient from outside
                                of current network, usually equal to 1.0
        Returns:
            dx (CTensor): data for the dL /dx, L is the loss, x is the output
                          of current network. note that this is true for
                          dy = 1.0
        """

        dx = singa.__div__(self.t, self.x)
        dx *= float(-1.0 / self.x.shape()[0])
        if isinstance(dy, float):
            # dtype of dy: float
            dx *= dy
            return dx
        elif isinstance(dy, CTensor):
            pass  # TODO, broadcast elementwise multiply seems not support


def cross_entropy(x, t):
    assert x.ndim() == 2, "1st arg required 2d tensor. got shape: " + str(
        x.shape)
    assert t.ndim() <= 2, "2nd arg required <=2d tensor. got shape: " + str(
        t.shape)
    # x is the logits and t is the ground truth.
    return CrossEntropy(t)(x)[0]


class RankingLoss(Operator):

    def __init__(self, M=0.2):
        super().__init__()
        # margin
        self.M = M

    def forward(self, pos, neg):
        # L = max{0, M - fn(pos) + fn(neg)}
        zero = singa.Tensor(list(pos.shape()), pos.device())
        zero.SetFloatValue(0.0)
        val = singa.AddFloat(singa.__sub__(neg, pos), self.M)
        gt_zero = singa.__gt__(val, zero)
        if training:
            self.inputs = (gt_zero,)  # (BS,)
        all_loss = singa.__mul__(gt_zero, val)
        loss = singa.SumAll(all_loss)
        loss /= (pos.shape()[0])
        return loss

    def backward(self, dy=1.0):
        assert training, "enable training mode to do backward"
        # dpos = -1 if M-pos+neg > 0 else 0
        # dneg =  1 if M-pos+neg > 0 else 0
        gt_zero = self.inputs[0]
        dpos_factor = singa.Tensor(list(gt_zero.shape()), gt_zero.device())
        dpos_factor.SetFloatValue(-1.0 / gt_zero.Size())
        dneg_factor = singa.Tensor(list(gt_zero.shape()), gt_zero.device())
        dneg_factor.SetFloatValue(1.0 / gt_zero.Size())
        dpos = singa.__mul__(gt_zero, dpos_factor)
        dneg = singa.__mul__(gt_zero, dneg_factor)
        return dpos, dneg


def ranking_loss(pos, neg, M=0.2):
    assert pos.shape == neg.shape, "input and target shape different: %s, %s" % (
        pos.shape, neg.shape)
    return RankingLoss(M)(pos, neg)[0]


class SoftMaxCrossEntropy(Operator):

    def __init__(self, t):
        super(SoftMaxCrossEntropy, self).__init__()
        self.t = t.data

    def forward(self, x):
        self.p = singa.SoftMax(x)
        ret = singa.CrossEntropyFwd(self.p, self.t)
        loss = singa.SumAll(ret)
        loss /= x.shape()[0]
        return loss

    def backward(self, dy=1.0):
        dx = singa.SoftmaxCrossEntropyBwd(self.p, self.t)
        dx /= float(self.p.shape()[0])
        return dx


def softmax_cross_entropy(x, t):
    assert x.ndim() == 2, "1st arg required 2d tensor. got shape: " + str(
        x.shape)
    assert t.ndim() <= 2, "2nd arg required <=2d tensor. got shape: " + str(
        t.shape)
    # x is the logits and t is the ground truth.
    return SoftMaxCrossEntropy(t)(x)[0]


class MeanSquareError(Operator):

    def __init__(self, t):
        super(MeanSquareError, self).__init__()
        self.t = t.data

    def forward(self, x):
        self.err = singa.__sub__(x, self.t)
        sqr = singa.Square(self.err)
        loss = singa.SumAll(sqr)
        self.n = 1
        for s in x.shape():
            self.n *= s
        loss /= self.n
        return loss

    def backward(self, dy=1.0):
        dx = self.err
        dx *= float(2 / self.n)
        dx *= dy
        return dx


def mse_loss(x, t):
    assert x.shape == t.shape, "input and target shape different: %s, %s" % (
        x.shape, t.shape)
    return MeanSquareError(t)(x)[0]


def ctensor2numpy(x):
    """
    To be used in SoftMax Operator.
    Convert a singa_tensor to numpy_tensor.
    """
    np_array = x.GetFloatValue(int(x.Size()))
    return np_array.reshape(x.shape())


class Flatten(Operator):
    """
    Flattens the input tensor into a 2D matrix. If input tensor has shape
    `(d_0, d_1, ... d_n)` then the output will have shape `(d_0 X d_1 ...
    d_(axis-1), d_axis X d_(axis+1) ... X dn)`.
    """

    def __init__(self, axis=1):
        """
        Args:
            axis (int): Indicate up to which input dimensions (exclusive)
                should be flattened to the outer dimension of the output. The
                value for axis must be in the range [-r, r], where r is the
                rank of the input tensor. Negative value means counting
                dimensions from the back. When axis = 0, the shape of the
                output tensor is `(1, (d_0 X d_1 ... d_n)`, where the shape
                of the input tensor is `(d_0, d_1, ... d_n)`.
        Returns:
            the result CTensor
        """
        super(Flatten, self).__init__()
        self.axis = axis

    def forward(self, x):
        """
        Args:
            x (CTensor): the input tensor
        Returns:
            the result CTensor
        """
        self.shape = list(x.shape())
        shape, axis = self.shape, self.axis
        # the axis must be within this range (0, r-1)
        assert axis <= len(
            shape) - 1 or axis >= 0, "the axis must be within (0, %d-1)" % len(
                shape)
        # calculate the new shape
        new_shape = (1, int(np.prod(shape))) if axis == 0 else (
            int(np.prod(shape[0:axis]).astype(int)),
            int(np.prod(shape[axis:]).astype(int)))
        y = singa.Reshape(x, new_shape)
        return y

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss
        Returns:
            dx (CTensor): data for the dL / dx, L is the loss,
        """
        dx = singa.Reshape(dy, self.shape)
        return dx


def flatten(x, axis=1):
    """
    Flattens the input tensor into a 2D matrix. If input tensor has shape
    `(d_0, d_1, ... d_n)` then the output will have shape `(d_0 X d_1 ...
    d_(axis-1), d_axis X d_(axis+1) ... X dn)`.
    Args:
        x (Tensor): the input tensor
        axis (int): Indicate up to which input dimensions (exclusive)
            should be flattened to the outer dimension of the output. The
            value for axis must be in the range [-r, r], where r is the
            rank of the input tensor. Negative value means counting
            dimensions from the back. When axis = 0, the shape of the
            output tensor is `(1, (d_0 X d_1 ... d_n)`, where the shape
            of the input tensor is `(d_0, d_1, ... d_n)`.
    Returns:
        the result Tensor
    """
    return Flatten(axis)(x)[0]


class ScatterElements(Operator):
    """
    ScatterElements operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Changelog.md#ScatterElements-11

    Example usage:
    data = [
        [0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0],
    ]
    axis = 0
    indices = [
        [1, 0, 2],
        [0, 2, 1],
    ]
    updates = [
        [1.0, 1.1, 1.2],
        [2.0, 2.1, 2.2],
    ]
    output = [
        [2.0, 1.1, 0.0]
        [1.0, 0.0, 2.2]
        [0.0, 2.1, 1.2]
    ]

    """

    def __init__(self, indices, updates, axis=0):
        """
        Args:
            indices (Tensor): index tensor
            updates (Tensor): source tensor
            axis (int): Which axis to scatter on. A negative value means 
                counting dimension from the back. Accepted range is [-r,r-1]
                where r=rank(destination_tensor) 
        """
        super(ScatterElements, self).__init__()
        self.indices = indices
        self.updates = updates
        self.axis = axis

    def forward(self, x):
        x_shape = x.shape()
        x_rank = len(x_shape)
        if isinstance(self.indices, Tensor):
            self.indices = tensor.to_numpy(self.indices)
        elif isinstance(self.indices, (list, tuple)):
            self.indices = np.array(self.indices)
        if isinstance(self.updates, Tensor):
            self.updates = tensor.to_numpy(self.updates)
        elif isinstance(self.updates, (list, tuple)):
            self.updates = np.array(self.updates)
        self.updates.astype(np.int32)
        _x = tensor.to_numpy(tensor.from_raw_tensor(x))
        _x = _x.astype(np.float32)

        assert x_rank == 2, "Only support 2D input."
        assert x_rank == len(
            self.indices.shape
        ), "Index should have the same number of dimensions as output"
        assert -x_rank < self.axis <= x_rank, "Axis is out of range"
        assert np.logical_and(
            -_x.shape[self.axis] < self.indices,
            self.indices <= _x.shape[self.axis]).all(
            ), "The values of the indexes should be between %d and %d" % (
                -_x.shape[self.axis], _x.shape[self.axis] - 1)

        self.axis = self.axis % x_rank
        u_shape = self.updates.shape
        y = _x.copy()
        for i in range(u_shape[0]):
            for j in range(u_shape[1]):
                idx = int(self.indices[i][j])
                if self.axis == 0:
                    y[idx][j] = self.updates[i][j]
                else:
                    y[i][idx] = self.updates[i][j]
        y = tensor.from_numpy(y)
        y.to_device(x.device())
        return y.data

    def backward(self, dy):
        mask = np.ones(dy.shape(), dtype=np.float32)
        u_shape = self.updates.shape
        for i in range(u_shape[0]):
            for j in range(u_shape[1]):
                idx = int(self.indices[i][j])
                if self.axis == 0:
                    mask[idx][j] = 0.
                else:
                    mask[i][idx] = 0.
        mask = tensor.from_numpy(mask)
        mask.to_device(dy.device())
        return singa.__mul__(dy, mask.data)


def scatter_elements(x, indices, updates, axis=0):
    """
    Produces a ScatterElements operator
    Args:
        x (Tensor): input tensor.
        indices (Tensor): index tensor
        updates (Tensor): source tensor
        axis (int): Which axis to scatter on. A negative value means 
            counting dimension from the back. Accepted range is [-r,r-1]
            where r=rank(destination_tensor) 
    Returns:
        the output Tensor.
    """
    return ScatterElements(indices, updates, axis)(x)[0]


class Concat(Operator):
    """
    Concatenate a list of tensors into a single tensor. All input tensors must
    have the same shape, except for the dimension size of the axis to
    concatenate on.
    """

    def __init__(self, axis=0):
        """
        Args:
            axis (int): Which axis to concat on. A negative value means
                counting dimensions from the back. Accepted range is [-r, r-1]
                where r = rank(inputs).
        Returns:
            the result CTensor
        """
        super(Concat, self).__init__()
        self.axis = axis

    def forward(self, *xs):
        """
        Args:
            xs (a list of CTensor): List of tensors for concatenation
        Returns:
            a CTensor for the result
        """
        if self.axis < 0:
            self.axis = self.axis % len(xs[0].shape())
        if training:
            offset = 0
            self.slice_point = []
            for t in xs:
                offset += t.shape()[self.axis]
                self.slice_point.append(offset)
        x = singa.VecTensor(list(xs))
        return singa.ConcatOn(x, self.axis)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss
        Returns:
            dxs (a tuple of CTensor): data for the dL / dxs, L is the loss,
        """
        assert hasattr(
            self, "slice_point"), "Please set training as True before do BP. "
        assert self.slice_point[-1] == dy.shape()[self.axis], "Shape mismatch."
        dxs = []
        last_offset = 0
        for p in self.slice_point:
            dxs.append(singa.SliceOn(dy, last_offset, p, self.axis))
            last_offset = p
        return tuple(dxs)


def cat(xs, axis=0):
    """
    Concatenate a list of tensors into a single tensor. All input tensors must
    have the same shape, except for the dimension size of the axis to
    concatenate on.
    Args:
        xs (a list of Tensor): List of tensors for concatenation
        axis (int): Which axis to concat on. A negative value means
            counting dimensions from the back. Accepted range is [-r, r-1]
            where r = rank(inputs).
    Returns:
        a Tensor for the result
    """
    return Concat(axis)(*xs)[0]


"""
def make_slice(arr, axis, i):  # type: ignore
        slc = [slice(None)] * arr.ndim
        slc[axis] = i
        return slc
"""


class _Conv2d(Operator):
    """
    Init a conv 2d operator
    """

    def __init__(self, handle, odd_padding=(0, 0, 0, 0)):
        """
        Args:
            handle (object): ConvHandle for cpu or CudnnConvHandle for gpu
            odd_padding (tuple of four ints):, the odd paddding is the value
                that cannot be handled by the tuple padding (w, h) mode so
                we need to firstly handle the input, then use the nomal padding
                method.
        """
        super(_Conv2d, self).__init__()
        self.handle = handle
        self.odd_padding = odd_padding

    def forward(self, x, W, b=None):
        """
        Args:
            x (CTensor): input
            W (CTensor): weight
            b (CTensor): bias
        Returns:
            CTensor
        """
        assert x.nDim() == 4, "The dimensions of input should be 4D."
        if self.odd_padding != (0, 0, 0, 0):
            x = utils.handle_odd_pad_fwd(x, self.odd_padding)

        if training:
            if self.handle.bias_term:
                self.inputs = (x, W, b)
            else:
                self.inputs = (x, W)

        if not self.handle.bias_term:
            # create empty bias tensor for Cpp API
            b = CTensor((self.handle.num_filters,), x.device())
            b.SetFloatValue(0.0)

        if (type(self.handle) != singa.ConvHandle):
            return singa.GpuConvForward(x, W, b, self.handle)
        else:
            return singa.CpuConvForward(x, W, b, self.handle)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): dL / dy
        Returns:
            dx (CTensor): dL / dx
        """
        assert training is True and hasattr(
            self, "inputs"), "Please set training as True before do BP. "

        if (type(self.handle) != singa.ConvHandle):
            dx = singa.GpuConvBackwardx(dy, self.inputs[1], self.inputs[0],
                                        self.handle)
            dW = singa.GpuConvBackwardW(dy, self.inputs[0], self.inputs[1],
                                        self.handle)
            db = singa.GpuConvBackwardb(
                dy, self.inputs[2],
                self.handle) if self.handle.bias_term else None
        else:
            dx = singa.CpuConvBackwardx(dy, self.inputs[1], self.inputs[0],
                                        self.handle)
            dW = singa.CpuConvBackwardW(dy, self.inputs[0], self.inputs[1],
                                        self.handle)
            db = singa.CpuConvBackwardb(
                dy, self.inputs[2],
                self.handle) if self.handle.bias_term else None
        if self.odd_padding != (0, 0, 0, 0):
            dx = utils.handle_odd_pad_bwd(dx, self.odd_padding)

        if db:
            return dx, dW, db

        else:
            return dx, dW


def conv2d(handle, x, W, b=None, odd_padding=(0, 0, 0, 0)):
    """
    Conv 2d operator
    Args:
        handle (object): ConvHandle for cpu or CudnnConvHandle for gpu
        x (Tensor): input
        W (Tensor): weight
        b (Tensor): bias
        odd_padding (tuple of four ints):, the odd paddding is the value
            that cannot be handled by the tuple padding (w, h) mode so
            we need to firstly handle the input, then use the nomal padding
            method.
    """
    if b is None:
        return _Conv2d(handle, odd_padding)(x, W)[0]
    else:
        return _Conv2d(handle, odd_padding)(x, W, b)[0]


class _BatchNorm2d(Operator):
    """
    Carries out batch normalization as described in the paper
    https://arxiv.org/abs/1502.03167.
    """

    def __init__(self, handle, running_mean, running_var, name=None):
        """
        Args:
            handle (object): BatchNormHandle for cpu and CudnnBatchNormHandle
                for gpu
            running_mean (float): the running_mean
            running_var (float): the running_var
            name (string): the name assigned to this operator
        """
        super(_BatchNorm2d, self).__init__(name)
        self.handle = handle
        self.running_mean = running_mean.data
        self.running_var = running_var.data

    def forward(self, x, scale, bias):
        """
        Args:
            x (CTensor): the input tensor
            scale (CTensor): the bias tensor
            bias (CTensor): the bias tensor
        Returns:
            the result CTensor
        """
        if training:
            if (type(self.handle) == singa.BatchNormHandle):
                y, mean, var = singa.CpuBatchNormForwardTraining(
                    self.handle, x, scale, bias, self.running_mean,
                    self.running_var)

                self.cache = (x, scale, mean, var, y, bias)
            else:
                y, mean, var = singa.GpuBatchNormForwardTraining(
                    self.handle, x, scale, bias, self.running_mean,
                    self.running_var)

                self.cache = (x, scale, mean, var)

        else:

            if (type(self.handle) == singa.BatchNormHandle):
                y = singa.CpuBatchNormForwardInference(
                    self.handle,
                    x,
                    scale,
                    bias,
                    self.running_mean,
                    self.running_var,
                )
            else:
                y = singa.GpuBatchNormForwardInference(
                    self.handle,
                    x,
                    scale,
                    bias,
                    self.running_mean,
                    self.running_var,
                )
        return y

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss
        Returns:
            dx (CTensor): data for the dL / dx, L is the loss
            ds (CTensor): data for the dL / ds, L is the loss
            db (CTensor): data for the dL / db, L is the loss
        """
        assert training is True and hasattr(
            self, "cache"), "Please set training as True before do BP. "

        if (type(self.handle) == singa.BatchNormHandle):
            x, scale, mean, var, y, bias = self.cache
            dx, ds, db = singa.CpuBatchNormBackwardx(self.handle, y, dy, x,
                                                     scale, bias, mean, var)
        else:
            x, scale, mean, var = self.cache
            dx, ds, db = singa.GpuBatchNormBackward(self.handle, dy, x, scale,
                                                    mean, var)

        return dx, ds, db


def batchnorm_2d(handle, x, scale, bias, running_mean, running_var):
    """
    Carries out batch normalization as described in the paper
    https://arxiv.org/abs/1502.03167.
    Args:
        handle (object): BatchNormHandle for cpu and CudnnBatchNormHandle
            for gpu
        x (Tensor): the input tensor
        scale (Tensor): the bias tensor
        bias (Tensor): the bias tensor
        running_mean (float): the running_mean
        running_var (float): the running_var
    Returns:
        the result Tensor
    """
    return _BatchNorm2d(handle, running_mean, running_var)(x, scale, bias)[0]


class _Pooling2d(Operator):
    """
    Init a pool 2d operator
    """

    def __init__(self, handle, odd_padding=(0, 0, 0, 0)):
        """
        Args:
            handle (object): PoolingHandle for cpu or CudnnPoolingHandle for
                gpu
            odd_padding (tuple of four int): the odd paddding is the value
                that cannot be handled by the tuple padding (w, h) mode so
                it needs to firstly handle the input, then use the normal
                padding method.
        """
        super(_Pooling2d, self).__init__()
        self.handle = handle
        self.odd_padding = odd_padding

    def forward(self, x):
        """
        Args:
            x (CTensor): the input tensor
        Returns:
            the result CTensor
        """
        assert x.nDim() == 4, "The dimensions of input should be 4D."
        if self.odd_padding != (0, 0, 0, 0):
            x = utils.handle_odd_pad_fwd(x, self.odd_padding, True)

        if (type(self.handle) != singa.PoolingHandle):
            y = singa.GpuPoolingForward(self.handle, x)
        else:
            y = singa.CpuPoolingForward(self.handle, x)
        if training:
            self.cache = (x, y)
        return y

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the dL / dy, L is the loss
        Returns:
            dx (CTensor): data for the dL / dx, L is the loss,
        """
        if (type(self.handle) != singa.PoolingHandle):
            dx = singa.GpuPoolingBackward(self.handle, dy, self.cache[0],
                                          self.cache[1])
        else:
            dx = singa.CpuPoolingBackward(self.handle, dy, self.cache[0],
                                          self.cache[1])
        if self.odd_padding != (0, 0, 0, 0):
            dx = utils.handle_odd_pad_bwd(dx, self.odd_padding)

        return dx


def pooling_2d(handle, x, odd_padding=(0, 0, 0, 0)):
    """
    Pooling 2d operator
    Args:
        handle (object): PoolingHandle for cpu or CudnnPoolingHandle for
            gpu
        x (Tensor): input
        odd_padding (tuple of four int): the odd paddding is the value
            that cannot be handled by the tuple padding (w, h) mode so
            it needs to firstly handle the input, then use the normal
            padding method.
    Returns:
        the result Tensor
    """
    return _Pooling2d(handle, odd_padding)(x)[0]


class Tanh(Operator):
    """
    Calculates the hyperbolic tangent of the given input tensor element-wise.
    """

    def __init__(self):
        super(Tanh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        out = singa.Tanh(x)
        if training:
            self.cache = (out,)
        return out

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.__mul__(self.cache[0], self.cache[0])
        dx = singa.MultFloat(dx, -1.0)
        dx = singa.AddFloat(dx, 1.0)
        dx *= dy
        return dx


def tanh(x):
    """
    Calculates the hyperbolic tangent of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Tanh()(x)[0]


class Cos(Operator):
    """
    Calculates the cosine of the given input tensor, element-wise.
    """

    def __init__(self):
        super(Cos, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Cos(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Sin(self.input)
        dx = singa.MultFloat(dx, -1.0)
        dx *= dy
        return dx


def cos(x):
    """
    Calculates the cosine of the given input tensor, element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """

    return Cos()(x)[0]


class Cosh(Operator):
    """
    Calculates the hyperbolic cosine of the given input tensor element-wise.
    """

    def __init__(self):
        super(Cosh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Cosh(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Sinh(self.input)
        dx *= dy
        return dx


def cosh(x):
    """
    Calculates the hyperbolic cosine of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Cosh()(x)[0]


class Acos(Operator):
    """
    Calculates the arccosine (inverse of cosine) of the given input tensor,
    element-wise.
    """

    def __init__(self):
        super(Acos, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Acos(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Square(self.input)
        dx = singa.MultFloat(dx, -1.0)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.PowFloat(dx, -0.5)
        dx = singa.MultFloat(dx, -1.0)
        dx *= dy
        return dx


def acos(x):
    """
    Calculates the arccosine (inverse of cosine) of the given input tensor,
    element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Acos()(x)[0]


class Acosh(Operator):
    """
    Calculates the hyperbolic arccosine of the given input tensor element-wise.
    """

    def __init__(self):
        super(Acosh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Acosh(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.SubFloat(self.input, 1.0)
        dx = singa.Sqrt(dx)
        temp = singa.AddFloat(self.input, 1.0)
        temp = singa.Sqrt(temp)
        dx = singa.__mul__(dx, temp)
        dx = singa.PowFloat(dx, -1.0)
        dx *= dy
        return dx


def acosh(x):
    """
    Calculates the hyperbolic arccosine of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Acosh()(x)[0]


class Sin(Operator):
    """
    Calculates the sine of the given input tensor, element-wise.
    """

    def __init__(self):
        super(Sin, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Sin(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Cos(self.input)
        dx *= dy
        return dx


def sin(x):
    """
    Calculates the sine of the given input tensor, element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Sin()(x)[0]


class Sinh(Operator):
    """
    Calculates the hyperbolic sine of the given input tensor element-wise.
    """

    def __init__(self):
        super(Sinh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Sinh(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Cosh(self.input)
        dx *= dy
        return dx


def sinh(x):
    """
    Calculates the hyperbolic sine of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Sinh()(x)[0]


class Asin(Operator):
    """
    Calculates the arcsine (inverse of sine) of the given input tensor, element-wise.
    """

    def __init__(self):
        super(Asin, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Asin(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Square(self.input)
        dx = singa.MultFloat(dx, -1.0)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.PowFloat(dx, -0.5)
        dx *= dy
        return dx


def asin(x):
    """
    Calculates the arcsine (inverse of sine) of the given input tensor, element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """

    return Asin()(x)[0]


class Asinh(Operator):
    """
    Calculates the hyperbolic arcsine of the given input tensor element-wise.
    """

    def __init__(self):
        super(Asinh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Asinh(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Square(self.input)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.PowFloat(dx, -0.5)
        dx *= dy
        return dx


def asinh(x):
    """
    Calculates the hyperbolic arcsine of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Asinh()(x)[0]


class Tan(Operator):
    """
    Insert single-dimensional entries to the shape of an input tensor (data).
    """

    def __init__(self):
        super(Tan, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Tan(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Cos(self.input)
        dx = singa.Square(dx)
        dx = singa.PowFloat(dx, -1.0)
        dx *= dy
        return dx


def tan(x):
    """
    Calculates the tangent of the given input tensor, element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Tan()(x)[0]


class Atan(Operator):
    """
    Calculates the arctangent (inverse of tangent) of the given input tensor, element-wise.
    """

    def __init__(self):
        super(Atan, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Atan(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Square(self.input)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.PowFloat(dx, -1.0)
        dx *= dy
        return dx


def atan(x):
    """
    Calculates the arctangent (inverse of tangent) of the given input tensor, element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Atan()(x)[0]


class Atanh(Operator):
    """
    Calculates the hyperbolic arctangent of the given input tensor element-wise.
    """

    def __init__(self):
        super(Atanh, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        return singa.Atanh(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Square(self.input)
        dx = singa.MultFloat(dx, -1.0)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.PowFloat(dx, -1.0)
        dx *= dy
        return dx


def atanh(x):
    """
    Calculates the hyperbolic arctangent of the given input tensor element-wise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Atanh()(x)[0]


class Sigmoid(Operator):
    """
    `y = 1 / (1 + exp(-x))`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Sigmoid, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        out = singa.Sigmoid(x)
        if training:
            self.cache = (out,)
        return out

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.MultFloat(self.cache[0], -1.0)
        dx = singa.AddFloat(dx, 1.0)
        dx = singa.__mul__(self.cache[0], dx)
        dx *= dy
        return dx


def sigmoid(x):
    """
    `y = 1 / (1 + exp(-x))`, is applied to the tensor elementwise.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Sigmoid()(x)[0]


class Mul(Operator):
    """
    Performs element-wise binary multiplication (with Numpy-style broadcasting
    support).
    """

    def __init__(self):
        super(Mul, self).__init__()

    def forward(self, a, b):
        """
        Return `np.multiply(a,b)`, where a and b are CTensor.
        """
        # todo we cannot support mul op for int tensors
        _a, _b = a, b
        dtype0 = _a.data_type()
        dtype1 = _b.data_type()
        if dtype0 == singa.kInt or dtype1 == singa.kInt:
            _a = a.AsType(singa.kFloat32)
            _b = b.AsType(singa.kFloat32)
            res = singa.__mul__(_a, _b)
            res = res.AsType(singa.kInt)
        else:
            res = singa.__mul__(_a, _b)
        if training:
            self.input = (_a, _b)
            self.shape0 = list(_a.shape())
            self.shape1 = list(_b.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a tuple for (da, db), da is data for dL / da, db is data
                for dL / db.
        """
        dx0 = singa.__mul__(dy, self.input[1])
        dx1 = singa.__mul__(dy, self.input[0])
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx0, dx1
        # handle broadcast
        dx0 = back_broadcast(self.shape3, self.shape0, dx0)
        dx1 = back_broadcast(self.shape3, self.shape1, dx1)
        return dx0, dx1


def mul(x, y):
    """
    Return `np.multiply(x,y)`, where a and b are Tensor.
    """
    return Mul()(x, y)[0]


class Unsqueeze(Operator):
    """
    Insert single-dimensional entries to the shape of an input tensor (data).
    """

    def __init__(self, axis):
        """
        Args:
            axis (list of int): the dimensions to be inserted.
        """
        super(Unsqueeze, self).__init__()
        if (type(axis) is int):
            self.axis = list(axis)
        else:
            self.axis = axis

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        self.cache = x.shape()
        cur = list(self.cache)
        # todo, need optimize after we have scalar tensor
        if len(self.cache) == 1 and self.axis == [0]:
            return x
        for i in self.axis:
            cur.insert(i, 1)
        return singa.Reshape(x, cur)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        return singa.Reshape(dy, self.cache)


def unsqueeze(x, axis=-1):
    """
    Insert single-dimensional entries to the shape of an input tensor (data).
    Args:
        x (Tensor): Input tensor
        axis (list of int): the dimensions to be inserted.
    Returns:
        Tensor, the output
    """
    return Unsqueeze(axis)(x)[0]


class Transpose(Operator):
    """
    Transpose the input tensor similar to numpy.transpose.
    """

    def __init__(self, perm):
        """
        Args:
            perm (list of ints): A list of integers. By default, reverse the
                dimensions, otherwise permute the axes according to the values given.
        """
        super(Transpose, self).__init__()
        self.perm = list(perm)

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        return singa.Transpose(x, self.perm)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        cur = []
        for i in range(len(self.perm)):
            cur += [self.perm.index(i)]
        return singa.Transpose(dy, cur)


def transpose(x, shape):
    """
    Transpose the input tensor similar to numpy.transpose.
    Args:
        x (Tensor): Input tensor
        perm (list of ints): A list of integers. By default, reverse the
            dimensions, otherwise permute the axes according to the values given.
    Returns:
        Tensor, the output
    """
    return Transpose(shape)(x)[0]


def add_all(*xs):
    assert len(xs) > 2
    y = add(xs[0], xs[1])
    for x in xs[2:]:
        y = add(y, x)
    return


class Abs(Operator):
    """
    `y = abs(x)`, is applied to the tensor elementwise.
    """

    def forward(self, a):
        """
        Return `abs(a)`, where a is CTensor.
        """
        if training:
            self.input = a
        return singa.Abs(a)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Sign(self.input)
        dx *= dy
        return dx


def abs(a):
    """
    Return abs(a), where a is Tensor.
    """
    return Abs()(a)[0]


class Exp(Operator):
    """
    `y = exp(x)`, is applied to the tensor elementwise.
    """

    def forward(self, a):
        """
        Return `exp(a)`, where a is Tensor.
        """
        if training:
            self.input = a
        return singa.Exp(a)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Exp(self.input)
        dx *= dy
        return dx


def exp(a):
    """
    Return `exp(a)`, where a is Tensor.
    """
    return Exp()(a)[0]


class LeakyRelu(Operator):
    """
    `f(x) = alpha * x` for x < 0, `f(x) = x` for x >= 0, is applied to the tensor elementwise.
    """

    def __init__(self, a):
        """
        Args:
            a (float): Coefficient of leakage.
        """
        super(LeakyRelu, self).__init__()
        self.a = a

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = x
        x1 = singa.LTFloat(x, 0.0)
        x1 = singa.__mul__(x, x1)
        x1 = singa.MultFloat(x1, self.a)
        x2 = singa.ReLU(x)
        x1 = singa.__add__(x1, x2)
        return x1

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        # TODO(wangwei) check the correctness
        dx1 = singa.GTFloat(self.input, 0.0)
        dx2 = singa.LTFloat(self.input, 0.0)
        dx2 = singa.MultFloat(dx2, self.a)
        dx = singa.__add__(dx1, dx2)
        dx *= dy
        return dx


def leakyrelu(x, a=0.01):
    """
    `f(x) = alpha * x` for x < 0, `f(x) = x` for x >= 0 is applied to the tensor
    elementwise.
    Args:
        x (Tensor): Input tensor
        a (float): Coefficient of leakage, default to 0.01.
    Returns:
        Tensor, the output
    """
    return LeakyRelu(a)(x)[0]


class Sign(Operator):
    """
    Calculate the sign of the given input tensor element-wise. If input > 0,
    output 1. if input < 0, output -1. if input == 0, output 0.
    """

    def __init__(self):
        super(Sign, self).__init__()

    def forward(self, a):
        """
        Args:
            a (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.input = a
        return singa.Sign(a)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.MultFloat(dy, 0.0)
        return dx


def sign(a):
    """
    Calculate the sign of the given input tensor element-wise. If input > 0,
    output 1. if input < 0, output -1. if input == 0, output 0.
    Args:
        a (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Sign()(a)[0]


class Pow(Operator):
    """
    `f(x) = a^b`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Pow, self).__init__()

    def forward(self, a, b):
        """
        Return `a^b`, where a and b are CTensor.
        """
        res = singa.Pow(a, b)
        if training:
            self.input = (a, b)
            self.shape0 = list(a.shape())
            self.shape1 = list(b.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a tuple for (da, db), da is data for dL / da, db is data
                for dL / db.
        """
        da1 = singa.__mul__(
            self.input[1],
            singa.Pow(self.input[0], singa.SubFloat(self.input[1], 1.0)))
        dx0 = singa.__mul__(da1, dy)
        db1 = singa.__mul__(singa.Pow(self.input[0], self.input[1]),
                            singa.Log(self.input[0]))
        dx1 = singa.__mul__(db1, dy)
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx0, dx1
        # handle broadcast
        dx0 = back_broadcast(self.shape3, self.shape0, dx0)
        dx1 = back_broadcast(self.shape3, self.shape1, dx1)
        return dx0, dx1


def pow(a, b):
    """
    Return `a^b`, where a and b are Tensor.
    """
    return Pow()(a, b)[0]


class SoftSign(Operator):
    """
    Calculates the softsign `(x/(1+|x|))` of the given input tensor element-wise.
    """

    def __init__(self):
        super(SoftSign, self).__init__()

    def forward(self, x):
        """
        Return `(x/(1+|x|))`, where x is CTensor.
        """
        # y = x / (1 + np.abs(x))
        if training:
            self.input = x
        x1 = singa.AddFloat(singa.Abs(x), 1.0)
        y = singa.__div__(x, x1)

        return y

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.AddFloat(singa.Abs(self.input), 1.0)
        dx = singa.PowFloat(singa.Square(dx), -1.0)
        dx = singa.__mul__(dy, dx)
        return dx


def softsign(x):
    """
    Return `(x/(1+|x|))`, where x is Tensor.
    """
    return SoftSign()(x)[0]


class Sqrt(Operator):
    """
    `y = x^0.5`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Sqrt, self).__init__()

    def forward(self, x):
        """
        Return `x^0.5`, where x is CTensor.
        """
        if training:
            self.input = x
        return singa.Sqrt(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.PowFloat(self.input, -0.5)
        dx = singa.MultFloat(dx, 0.5)
        dx = singa.__mul__(dy, dx)
        return dx


def sqrt(x):
    """
    Return `x^0.5`, where x is Tensor.
    """
    return Sqrt()(x)[0]


class SoftPlus(Operator):
    """
    `y = ln(exp(x) + 1)` is applied to the tensor elementwise.
    """

    def __init__(self):
        super(SoftPlus, self).__init__()

    def forward(self, x):
        """
        Return `ln(exp(x) + 1)`, where x is CTensor.
        """
        #f(x) = ln(exp(x) + 1)
        if training:
            self.input = x
        x1 = singa.AddFloat(singa.Exp(x), 1.0)
        y = singa.Log(x1)
        return y

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.Exp(singa.MultFloat(self.input, -1.0))
        dx = singa.PowFloat(singa.AddFloat(dx, 1.0), -1.0)
        dx = singa.__mul__(dy, dx)
        return dx


def softplus(x):
    """
    Return `ln(exp(x) + 1)`, where x is Tensor.
    """
    return SoftPlus()(x)[0]


class Sub(Operator):
    """
    Performs element-wise binary subtraction (with Numpy-style broadcasting
    support).
    """

    def __init__(self):
        super(Sub, self).__init__()

    def forward(self, a, b):
        """
        Return `a-b`, where x is CTensor.
        """
        ori_type = None
        if a.data_type() != singa.kFloat32:
            ori_type = a.data_type()
            a = a.AsType(singa.kFloat32)
            b = b.AsType(singa.kFloat32)
        res = singa.__sub__(a, b)
        if ori_type is not None:
            res = res.AsType(ori_type)
        if training:
            self.shape0 = list(a.shape())
            self.shape1 = list(b.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a tuple for (da, db), da is data for dL / da, db is data
                for dL / db.
        """
        dx0 = dy
        dx1 = singa.MultFloat(dy, -1.0)
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx0, dx1
        # handle broadcast
        dx0 = back_broadcast(self.shape3, self.shape0, dx0)
        dx1 = back_broadcast(self.shape3, self.shape1, dx1)
        return dx0, dx1


def sub(a, b):
    """
    Return a-b, where a and b are Tensor.
    """
    return Sub()(a, b)[0]


# optimize min to support multi inputs
class Min(Operator):
    """
    Element-wise min of each of the input tensors (with Numpy-style
    broadcasting support).
    """

    def __init__(self):
        super(Min, self).__init__()
        self.masks = []

    def _min(self, a, b):
        """
        Args:
            a (CTensor): First operand
            b (CTensor): Second operand
        Returns:
            CTensor, the output
            tuple of CTensor, mask tensor
        """
        m = singa.__sub__(a, b)
        mask0 = singa.LEFloat(m, 0)
        mask1 = singa.GTFloat(m, 0)
        res = singa.__add__(singa.__mul__(mask0, a), singa.__mul__(mask1, b))
        return res, (mask0, mask1)

    def forward(self, *x):
        """
        Args:
            *x (a list of CTensor): List of tensors for max.
        Returns:
            CTensor, the output
        """
        assert (len(x) > 0)
        self.l = len(x)
        if len(x) == 1:
            res, masks = self._min(x[0], x[0])
            self.masks.append(masks)
            return x[0]
        res, masks = self._min(x[0], x[1])
        self.masks.append(masks)
        for i in range(2, len(x)):
            res, masks = self._min(res, x[i])
            self.masks.append(masks)
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a tuple for (*dx), dx is data for dL / dx.
        """
        if self.l == 1:
            return self.masks[0][0]
        else:
            ret = []
            cumulation = None
            for mask0, mask1 in self.masks[::-1]:
                if not cumulation:
                    ret.insert(0, mask1)
                    cumulation = mask0
                else:
                    ret.insert(0, singa.__mul__(cumulation, mask1))
                    cumulation = singa.__mul__(cumulation, mask0)
            ret.insert(0, cumulation)
            return tuple(ret)


def min(*l):
    """
    Element-wise min of each of the input tensors (with Numpy-style
    broadcasting support).
    Args:
        *x (a list of Tensor): List of tensors for max.
    Returns:
        Tensor, the output
    """
    return Min()(*l)[0]


class Log(Operator):
    """
    `y = log(x)`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Log, self).__init__()

    def forward(self, x):
        """
        Return `log(x)`, where x is CTensor.
        """
        if training:
            self.input = x
        return singa.Log(x)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        dx = singa.PowFloat(self.input, -1)
        dx = singa.__mul__(dy, dx)
        return dx


def log(x):
    """
    Return log(x), where x is Tensor.
    """
    return Log()(x)[0]


class HardSigmoid(Operator):
    """
    `y = max(0, min(1, alpha * x + beta))`, is applied to the tensor elementwise.
    """

    def __init__(self, alpha=0.2, gamma=0.5):
        """
        Args:
            alpha (float): Value of alpha.
            gamma (float): Value of beta.
        """
        super(HardSigmoid, self).__init__()
        self.alpha = alpha
        self.gamma = gamma

    def forward(self, x):
        """
        Args:
            x (CTensor): matrix
        Returns:
            a CTensor for the result
        """
        x = singa.AddFloat(singa.MultFloat(x, self.alpha), self.gamma)
        if training:
            self.cache = x

        x = singa.ReLU(x)
        mask1 = singa.LTFloat(x, 1.0)
        mask2 = singa.GEFloat(x, 1.0)

        ans = singa.__add__(singa.__mul__(x, mask1), mask2)
        return singa.ReLU(ans)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        mask0 = singa.GTFloat(self.cache, 0.0)
        mask1 = singa.LTFloat(self.cache, 1.0)
        mask = singa.__mul__(mask0, mask1)
        return singa.__mul__(singa.MultFloat(mask, self.alpha), dy)


def hardsigmoid(x, alpha=0.2, gamma=0.5):
    """
    `y = max(0, min(1, alpha * x + beta))`, is applied to the tensor elementwise.
    Args:
        x (Tensor): matrix
        alpha (float): Value of alpha.
        gamma (float): Value of beta.
    Returns:
        a Tensor for the result
    """
    return HardSigmoid(alpha, gamma)(x)[0]


class Squeeze(Operator):
    """
    Remove single-dimensional entries from the shape of a tensor. Takes a
    parameter axes with a list of axes to squeeze. If axes is not provided,
    all the single dimensions will be removed from the shape. If an axis is
    selected with shape entry not equal to one, an error is raised.
    """

    def __init__(self, axis=[]):
        """
        Args:
            axis (list of ints): List of integers indicating the dimensions
                to squeeze. Negative value means counting dimensions from
                the back. Accepted range is [-r, r-1] where r = rank(data).
        """
        super(Squeeze, self).__init__()
        self.axis = axis

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        self.cache = x.shape()
        newshape = []
        if (self.axis == []):
            newshape = list(filter(lambda i: i != 1, self.cache))
        else:
            for id, i in enumerate(self.axis):
                assert i < len(self.cache)
                self.axis[id] = i % len(self.cache)
                assert self.cache[
                    i] == 1, "the length of axis {} is {}, which should be 1".format(
                        i, self.cache[i])
            for ind, v in enumerate(self.cache):
                if ind not in self.axis:
                    newshape.append(v)
        # todo, need optimize after we have scalar tensor
        if newshape == []:
            return x
        return singa.Reshape(x, newshape)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        return singa.Reshape(dy, self.cache)


def squeeze(x, axis=[]):
    """
    Remove single-dimensional entries from the shape of a tensor. Takes a
    parameter axes with a list of axes to squeeze. If axes is not provided,
    all the single dimensions will be removed from the shape. If an axis is
    selected with shape entry not equal to one, an error is raised.
    Args:
        x (Tensor): Input tensor
        axis (list of ints): List of integers indicating the dimensions
            to squeeze. Negative value means counting dimensions from
            the back. Accepted range is [-r, r-1] where r = rank(data).
    Returns:
        Tensor, the output
    """
    return Squeeze(axis)(x)[0]


class Div(Operator):
    """
    Performs element-wise binary division (with Numpy-style broadcasting support).
    """

    def __init__(self):
        super(Div, self).__init__()

    def forward(self, a, b):
        """
        Return `np.div(a,b)`, where a and b are CTensor.
        """
        ori_type = None
        if a.data_type() != singa.kFloat32:
            ori_type = a.data_type()
            a = a.AsType(singa.kFloat32)
            b = b.AsType(singa.kFloat32)
        res = singa.__mul__(a, singa.PowFloat(b, -1.0))
        # res = singa.__div__(a, b)
        if ori_type is not None:
            res = res.AsType(ori_type)
        if training:
            self.input = (singa.MultFloat(a, -1.0), singa.PowFloat(b, -1.0)
                         )  # -a, 1/b
            self.shape0 = list(a.shape())
            self.shape1 = list(b.shape())
            self.shape3 = list(res.shape())
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a CTensor tuple for (da, db), da is data for dL / da, db is data
                for dL / db.
        """
        #dy/dx_0 = b^(-1)
        #dy/dx_1 = (-a)*b^(-2)
        dx0 = singa.__mul__(dy, self.input[1])
        dx1 = singa.__mul__(self.input[0], singa.PowFloat(self.input[1], 2.0))
        dx1 = singa.__mul__(dy, dx1)
        if (type(dy) == float) or self.shape0 == self.shape1:
            assert self.shape0 == self.shape1, ('should have same shape')
            return dx0, dx1
        # handle broadcast
        dx0 = back_broadcast(self.shape3, self.shape0, dx0)
        dx1 = back_broadcast(self.shape3, self.shape1, dx1)
        return dx0, dx1


def div(a, b):
    """
    Return `np.div(a,b)`, where a and b are Tensor.
    """
    return Div()(a, b)[0]


class Shape(Operator):
    """
    Takes a tensor as input and outputs a tensor containing the shape of the
    input tensor.
    """

    def __init__(self):
        super(Shape, self).__init__()

    def forward(self, x):
        """
        Args:
            x (CTensor): Input tensor
        Returns:
            CTensor, the output
        """
        cur = list(x.shape())
        cur = tensor.from_numpy(np.array(cur))
        cur.to_device(x.device())
        return cur.data

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            list of int, the shape of dy
        """
        return list(dy.shape())


def shape(x):
    """
    Takes a tensor as input and outputs a tensor containing the shape of the
    input tensor.
    Args:
        x (Tensor): Input tensor
    Returns:
        Tensor, the output
    """
    return Shape()(x)[0]


# optimize max to support multi inputs
class Max(Operator):
    """
    Element-wise max of each of the input tensors (with Numpy-style
    broadcasting support).
    """

    def __init__(self):
        super(Max, self).__init__()
        self.masks = []

    def _max(self, a, b):
        """
        Args:
            a (CTensor): First operand
            b (CTensor): Second operand
        Returns:
            CTensor, the output
            tuple of CTensor, mask tensor
        """
        m = singa.__sub__(a, b)
        mask0 = singa.GEFloat(m, 0)
        mask1 = singa.LTFloat(m, 0)
        res = singa.__add__(singa.__mul__(mask0, a), singa.__mul__(mask1, b))
        return res, (mask0, mask1)

    def forward(self, *x):
        """
        Args:
            *x (a list of CTensor): List of tensors for max.
        Returns:
            CTensor, the output
        """
        assert (len(x) > 0)
        self.l = len(x)
        if len(x) == 1:
            res, masks = self._max(x[0], x[0])
            self.masks.append(masks)
            return x[0]
        res, masks = self._max(x[0], x[1])
        self.masks.append(masks)
        for i in range(2, len(x)):
            res, masks = self._max(res, x[i])
            self.masks.append(masks)
        return res

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            a tuple for (*dx), dx is data for dL / dx.
        """
        if self.l == 1:
            return self.masks[0][0]
        else:
            ret = []
            cumulation = None
            for mask0, mask1 in self.masks[::-1]:
                if not cumulation:
                    ret.insert(0, mask1)
                    cumulation = mask0
                else:
                    ret.insert(0, singa.__mul__(cumulation, mask1))
                    cumulation = singa.__mul__(cumulation, mask0)
            ret.insert(0, cumulation)
            return tuple(ret)


def max(*l):
    """
    Element-wise max of each of the input tensors (with Numpy-style broadcasting support).
    Args:
        *x (a list of Tensor): List of tensors for max.
    Returns:
        Tensor, the output
    """
    return Max()(*l)[0]


class And(Operator):
    """
    Returns the tensor resulted from performing the and logical operation elementwise on the input tensors A and B (with Numpy-style broadcasting support).
    """

    def __init__(self):
        super(And, self).__init__()

    def forward(self, a, b):
        """
        Return `np.logical_and(a,b)`, where a and b are CTensor.
        """
        m = singa.__mul__(a, b)
        cur = singa.PowFloat(singa.Sign(m), 2)

        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def _and(a, b):
    """
    Return `np.logical_and(a,b)`, where a and b are Tensor.
    """
    return And()(a, b)[0]


class Or(Operator):
    """
    Returns the tensor resulted from performing the or logical operation elementwise on the input tensors A and B (with Numpy-style broadcasting support).
    """

    def __init__(self):
        super(Or, self).__init__()

    def forward(self, a, b):
        """
        Return `np.logical_or(a,b)`, where a and b are CTensor.
        """
        m = singa.__add__(singa.PowFloat(singa.Sign(a), 2.0),
                          singa.PowFloat(singa.Sign(b), 2.0))
        cur = singa.Sign(m)

        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): data for the `dL / dy`, L is the loss.
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def _or(a, b):
    """
    Return np.logical_or(a,b), where a and b are Tensor.
    """
    return Or()(a, b)[0]


class Not(Operator):
    """
    Returns the negation of the input tensor element-wise.
    """

    def __init__(self):
        super(Not, self).__init__()

    def forward(self, x):
        """
        Return `np.logical_not(x)`, where x is CTensor.
        """
        mask0 = singa.GEFloat(x, 0)
        mask1 = singa.LEFloat(x, 0)
        cur = singa.__mul__(mask0, mask1)

        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def _not(x):
    """
    Return `np.logical_not(x)`, where x is Tensor.
    """
    return Not()(x)[0]


class Xor(Operator):
    """
    Performing the xor logical operation elementwise on the input tensors A and B (with Numpy-style broadcasting support).
    """

    def __init__(self):
        super(Xor, self).__init__()

    def forward(self, a, b):
        """
        Return `np.logical_xor(a,b)`, where a and b are CTensor.
        """
        m = singa.__sub__(singa.PowFloat(singa.Sign(a), 2.0),
                          singa.PowFloat(singa.Sign(b), 2.0))
        cur = singa.PowFloat(singa.Sign(m), 2.0)

        return cur

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def _xor(a, b):
    """
    Return `np.logical_xor(a,b)`, where a and b are Tensor.
    """
    return Xor()(a, b)[0]


class Negative(Operator):
    """
    `y = -x`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Negative, self).__init__()

    def forward(self, x):
        """
        Return `-x`, where x is CTensor.
        """
        #y=-x
        return singa.MultFloat(x, -1)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        return singa.MultFloat(dy, -1)


def negative(x):
    """
    Return `-x`, where x is Tensor.
    """
    return Negative()(x)[0]


class Reciprocal(Operator):
    """
    `y = 1/x`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Reciprocal, self).__init__()

    def forward(self, x):
        """
        Return `1/x`, where x is CTensor.
        """
        #y=1/x elementwise
        if training:
            self.input = x

        return singa.PowFloat(x, -1)

    def backward(self, dy):
        """
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        #dy/dx = -1/x**2
        dx = singa.MultFloat(singa.PowFloat(self.input, -2), -1)
        return singa.__mul__(dy, dx)


def reciprocal(x):
    """
    Return 1/x, where x is Tensor.
    """
    return Reciprocal()(x)[0]


class Gemm(Operator):
    """
    Init a General Matrix multiplication(Gemm) operator. Compute `Y = alpha *
    A' * B' + beta * C`, where input tensor A has shape (M, K) or (K, M), input
    tensor B has shape (K, N) or (N, K), input tensor C is broadcastable to
    shape (M, N), and output tensor Y has shape (M, N).
    `A' = transpose(A)` if transA else A
    `B' = transpose(B)` if transB else B
    """

    def __init__(self, alpha=1.0, beta=1.0, transA=0, transB=0):
        """
        Args:
            alpha (float): Scalar multiplier for the product of input tensors
                A * B.
            beta (float): Scalar multiplier for input tensor C.
            ransA (int): Whether A should be transposed
            transB (int): Whether B should be transposed
        Returns:
            CTensor, the output
        """
        super(Gemm, self).__init__()
        self.alpha = alpha
        self.beta = beta
        self.transA = transA
        self.transB = transB

    def forward(self, A, B, C=None):
        """
        forward propogation of Gemm
        Args:
            A (CTensor): The shape of A should be (M, K) if transA is 0, or
                (K, M) if transA is non-zero.
            B (CTensor): The shape of B should be (K, N) if transB is 0, or
                (N, K) if transB is non-zero.
            C (CTensor): (optional), Optional input tensor C. If not specified,
                the computation is done as if C is a scalar 0. The shape of C
                should be unidirectional broadcastable to (M, N).
        Returns:
            tensor, the output
        """
        _A = singa.DefaultTranspose(A) if self.transA == 1 else A
        _B = singa.DefaultTranspose(B) if self.transB == 1 else B
        if training:
            self.inputs = (_A, _B, C)
        tmpM = singa.MultFloat(singa.Mult(_A, _B), self.alpha)
        if C:
            tmpM = singa.__add__(tmpM, singa.MultFloat(C, self.beta))
        return tmpM

    def backward(self, dy):
        """
        backward propogation of Gemm
        Args:
            dy (CTensor): The shape of A should be (M, K) if transA is 0, or (K, M) if transA is non-zero.
        Returns:
            CTensor, the gradient over A
            CTensor, the gradient over B
            CTensor(optional), the gradient over C
        """
        _A, _B, C = self.inputs
        # y = alpha * A  * B  => da = alpha * dy * BT
        # y = alpha * A  * BT => da = alpha * dy * B
        # y = alpha * AT * B  => da = alpha * B * dyT = alpha * (dy * BT)T
        # y = alpha * AT * BT => da = alpha * BT * dyT = alpha * (dy * B)T
        da = singa.MultFloat(singa.Mult(dy, singa.DefaultTranspose(_B)),
                             self.alpha)
        if self.transA:
            da = singa.DefaultTranspose(da)

        # y = alpha * A  * B  => db = alpha * AT * dy
        # y = alpha * AT * B  => db = alpha * A * dy
        # y = alpha * A  * BT => db = alpha * dyT * A = alpha * (AT * dy)T
        # y = alpha * AT * BT => db = alpha * dyT * AT = alpha * (A * dy)T
        db = singa.MultFloat(singa.Mult(singa.DefaultTranspose(_A), dy),
                             self.alpha)
        if self.transB:
            db = singa.DefaultTranspose(db)
        if C:
            dc = back_broadcast(dy.shape(), C.shape(),
                                singa.MultFloat(dy, self.beta))
            return da, db, dc
        else:
            return da, db


def gemm(A, B, C=None, alpha=1.0, beta=1.0, transA=0, transB=0):
    """
    Init a General Matrix multiplication(Gemm) operator. Compute `Y = alpha *
    A' * B' + beta * C`, where input tensor A has shape (M, K) or (K, M), input
    tensor B has shape (K, N) or (N, K), input tensor C is broadcastable to
    shape (M, N), and output tensor Y has shape (M, N).
    `A' = transpose(A)` if transA else A
    `B' = transpose(B)` if transB else B
    Args:
        A (Tensor): The shape of A should be (M, K) if transA is 0, or
            (K, M) if transA is non-zero.
        B (Tensor): The shape of B should be (K, N) if transB is 0, or
            (N, K) if transB is non-zero.
        C (Tensor): (optional), Optional input tensor C. If not specified,
            the computation is done as if C is a scalar 0. The shape of C
            should be unidirectional broadcastable to (M, N).
        alpha (float): Scalar multiplier for the product of input tensors A * B.
        beta (float): Scalar multiplier for input tensor C.
        ransA (int): Whether A should be transposed
        transB (int): Whether B should be transposed
    Returns:
        Tensor, the output
    """
    if C:
        return Gemm(alpha, beta, transA, transB)(A, B, C)[0]
    else:
        return Gemm(alpha, beta, transA, transB)(A, B)[0]


class GlobalAveragePool(Operator):
    """
    Init a GlobalAveragePool operator
    """

    def __init__(self, data_format='channels_first'):
        """
        Args:
            data_format (string): A string, we support two formats:
                channels_last and channels_first, default is channels_first.
                channels_first means the format of input is (N x C x H x W)
                channels_last means the format of input is (N x H x W x C)
        """
        super(GlobalAveragePool, self).__init__()
        self.data_format = data_format

    def forward(self, x):
        """
        forward propogation of GlobalAveragePool
        Args:
            x (CTensor): the input tensor
        Returns:
            CTensor, the output
        """
        if training:
            self.mask = singa.Tensor(x.shape(), x.device())

        shape = list(x.shape())

        # (N x C x H x W) for channels_first
        if self.data_format == 'channels_first':
            axes = tuple(i for i in range(2, len(shape)))
            self.shape_divisor = 1 / np.prod(shape[2:])
        else:  # (N x H x W x C) for channels_last
            axes = tuple(i for i in range(1, len(shape) - 1))
            self.shape_divisor = 1 / np.prod(shape[1:-1])

        # output shape
        # (N x C x 1 x 1) for channels_first
        # (N x 1 x 1 x C) for channels_last
        for i in axes:
            shape[i] = 1

        x = tensor.from_raw_tensor(x)
        x = tensor.sum(x, axis=axes)
        x = tensor.reshape(x, shape)
        return singa.MultFloat(x.data, self.shape_divisor)

    def backward(self, dy):
        """
        backward propogation of GlobalAveragePool
        Args:
            dy (CTensor): the gradient tensor from upper operations
        Returns:
            CTensor, the gradient over input
        """
        self.mask.SetFloatValue(self.shape_divisor)
        return singa.__mul__(self.mask, dy)


def globalaveragepool(x, data_format='channels_first'):
    """
    GlobalAveragePool operator
    Args:
        x (Tensor): the input tensor
        data_format (string): A string, we support two formats:
            channels_last and channels_first, default is channels_first.
            channels_first means the format of input is (N x C x H x W)
            channels_last means the format of input is (N x H x W x C)
    Returns:
        Tensor, the output
    """
    return GlobalAveragePool(data_format)(x)[0]


class ConstantOfShape(Operator):
    """
    Init a ConstantOfShape, generate a tensor with given value and shape.
    """

    def __init__(self, value=0.):
        """
        Args:
            value (float): (Optional) The value of the output elements. Should
                be a one-element value. If not specified, it defaults to 0 and
                datatype float32
        """
        super(ConstantOfShape, self).__init__()
        self.value = value

    def forward(self, x):
        """
        forward of ConstantOfShape
        Args:
            x: CTensor, 1D tensor. The shape of the expected output tensor.
                All values must be >= 0.
        Returns:
            the output CTensor. If attribute 'value' is specified, the value
                and datatype of the output tensor is taken from 'value'. If
                attribute 'value' is not specified, the value in the output
                defaults to 0, and the datatype defaults to float32.
        """
        x_shape = tensor.to_numpy(tensor.from_raw_tensor(x)).astype(
            np.int64).tolist()
        assert np.min(x_shape) >= 0, ('shape cannot be negative')
        x = CTensor(x_shape, x.device())
        x.SetFloatValue(self.value)
        return x

    def backward(self, dy):
        """
        backward of ConstantOfShape
        Args:
            dy (CTensor): gradient tensor.
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def constant_of_shape(x, value=0):
    """
    Init a ConstantOfShape, generate a tensor with given value and shape.
    Args:
        x: Tensor, 1D tensor. The shape of the expected output tensor.
            All values must be >= 0.
        value (float): (Optional) The value of the output elements. Should
            be a one-element value. If not specified, it defaults to 0 and
            datatype float32
    Returns:
        the output Tensor. If attribute 'value' is specified, the value
            and datatype of the output tensor is taken from 'value'. If
            attribute 'value' is not specified, the value in the output
            defaults to 0, and the datatype defaults to float32.
    """
    return ConstantOfShape(value)(x)[0]


class Dropout(Operator):
    """
    Init a Dropout, which scales the masked input data by the following equation:
    `output = scale * data * mask`, `scale = 1. / (1. - ratio)`.
    """

    def __init__(self, seed=0, ratio=0.5):
        """
        Args:
            seed (int): the random seed
            ratio (float): the ratio of random dropout, with value in [0, 1).
        """
        super(Dropout, self).__init__()
        self.ratio = ratio
        self.seed = int(seed)
        self.init_seed = False

    def forward(self, x):
        """
        forward of Dropout
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        if not self.init_seed:
            x.device().SetRandSeed(self.seed)
            self.init_seed = True
        if training:
            self.scale = 1 / 1 - self.ratio
            self.mask = singa.Tensor(list(x.shape()), x.device())
            singa.Bernoulli(1 - self.ratio, self.mask)
            x = singa.MultFloat(singa.__mul__(self.mask, x), self.scale)
        return x

    def backward(self, dy):
        """
        backward of Dropout
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        if training:
            dy = singa.MultFloat(singa.__mul__(self.mask, dy), self.scale)
        return dy


def dropout(x, seed=0, ratio=0.5):
    """
    Init a Dropout, which scales the masked input data by the following
    equation: `output = scale * data * mask`, `scale = 1. / (1. - ratio)`.
    Args:
        x (Tensor): input tensor.
        ratio (float): the ratio of random dropout, with value in [0, 1).
    Returns:
        the output Tensor.
    """
    return Dropout(seed, ratio)(x)[0]


class ReduceSum(Operator):
    """
    Init a ReduceSum, computes the sum of the input tensor's element along
    the provided axes.
    """

    def __init__(self, axes=None, keepdims=1):
        """
        Args:
            axes (list of int): A list of integers, along which to reduce.
                Accepted range is [-r, r-1] where r = rank(data). The default
                is None, which reduces over all the dimensions of the input tensor.
            keepdims (int): Keep the reduced dimension or not, default 1 mean
                keep reduced dimension.
        """
        super(ReduceSum, self).__init__()
        self.axes = axes
        self.keepdims = keepdims

    def forward(self, x):
        """
        forward of ReduceSum
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        _x = tensor.from_raw_tensor(x)
        x_shape = list(_x.shape)
        # handle the special axes
        if self.axes is None:
            self.axes = [i for i in range(len(x_shape))]  # axes = None
        else:
            self.axes = [i if i >= 0 else len(x_shape) + i for i in self.axes
                        ]  # axes has negative
        self.axes.sort(reverse=True)
        for axis in self.axes:
            _x = tensor.sum(_x, axis)
            x_shape[axis] = 1
        if self.keepdims == 1:
            _x = tensor.reshape(_x, x_shape)
        self.cache = (x_shape, x)
        return _x.data

    def backward(self, dy):
        """
        backward of ReduceSum
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        x_shape, x = self.cache
        dy = singa.Reshape(dy, x_shape)
        scale = np.prod(x_shape) / np.prod(x.shape())
        mask = singa.Tensor(list(x.shape()), x.device())
        mask.SetFloatValue(scale)
        dy = singa.__mul__(mask, dy)
        return dy


def reduce_sum(x, axes=None, keepdims=1):
    """
    Init a ReduceSum, computes the sum of the input tensor's element along
    the provided axes.
    Args:
        x (Tensor): input tensor.
        axes (list of int): A list of integers, along which to reduce.
            Accepted range is [-r, r-1] where r = rank(data). The default
            is None, which reduces over all the dimensions of the input tensor.
        keepdims (int): Keep the reduced dimension or not, default 1 mean
            keep reduced dimension.
    Returns:
        the output Tensor.
    """
    return ReduceSum(axes, keepdims)(x)[0]


class ReduceMean(Operator):
    """
    Init a ReduceMean, computes the mean of the input tensor's element along
    the provided axes.
    """

    def __init__(self, axes=None, keepdims=1):
        """
        Args:
            axes (list of int): A list of integers, along which to reduce.
                Accepted range is [-r, r-1] where r = rank(data). The default
                is None, which reduces over all the dimensions of the input tensor.
            keepdims (int): Keep the reduced dimension or not, default 1 mean
                keep reduced dimension.
        """
        super(ReduceMean, self).__init__()
        self.axes = axes
        self.keepdims = keepdims

    def forward(self, x):
        """
        forward of ReduceMean
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        _x = tensor.from_raw_tensor(x)
        x_shape = list(_x.shape)
        # handle the special axes
        if self.axes is None:
            self.axes = [i for i in range(len(x_shape))]  # axes = None
        else:
            self.axes = [i if i >= 0 else len(x_shape) + i for i in self.axes
                        ]  # axes has negative
        self.axes.sort(reverse=True)
        for axis in self.axes:
            _x = tensor.sum(_x, axis)
            x_shape[axis] = 1
        if self.keepdims == 1:
            _x = tensor.reshape(_x, x_shape)
        self.cache = (x_shape, x)
        scale = np.prod(x_shape) / np.prod(x.shape())
        self.scale = scale
        _x = singa.MultFloat(_x.data, scale)
        return _x

    def backward(self, dy):
        """
        backward of ReduceMean
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        x_shape, x = self.cache
        dy = singa.Reshape(dy, x_shape)
        mask = singa.Tensor(list(x.shape()), x.device())
        mask.SetFloatValue(1.0)
        dy = singa.__mul__(mask, dy)
        dy = singa.MultFloat(dy, self.scale)
        return dy


def reduce_mean(x, axes=None, keepdims=1):
    """
    Init a ReduceMean, computes the mean of the input tensor's element along
    the provided axes.
    Args:
        x (Tensor): input tensor.
        axes (list of int): A list of integers, along which to reduce.
            Accepted range is [-r, r-1] where r = rank(data). The default
            is None, which reduces over all the dimensions of the input tensor.
        keepdims (int): Keep the reduced dimension or not, default 1 mean
            keep reduced dimension.
    Returns:
        the output Tensor.
    """
    return ReduceMean(axes, keepdims)(x)[0]


class Slice(Operator):
    """
    Init a Slice, Produces a slice of the input tensor along multiple axes.
    Similar to numpy: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
    """

    def __init__(self, starts, ends, axes=None, steps=None):
        """
        Args:
            starts (list of int): starting indices of corresponding axis
            ends (list of int): ending indices of corresponding axis
            axes (list of int): axes that `starts` and `ends` apply to.
                Negative value means counting dimensions from the back.
                Accepted range is [-r, r-1] where r = rank(data).
            steps (list of int): slice step of corresponding axis in `axes`.
                Negative value means slicing backward. 'steps' cannot be 0.
                Defaults to 1.
        """
        super(Slice, self).__init__()
        self.starts = starts
        self.ends = ends
        self.axes = axes
        self.steps = steps

    def forward(self, x):
        """
        forward of Slice
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        x_shape = list(x.shape())
        # handle the special axes
        if self.axes is None:
            self.axes = [i for i in range(len(x_shape))]  # axes = None
        else:
            self.axes = [i if i >= 0 else len(x_shape) + i for i in self.axes
                        ]  # axes has negative
        self.cache = []
        # handle the special steps
        if self.steps is None:
            self.steps = [1] * len(x_shape)  # steps = None
        for idx, axis in enumerate(self.axes):
            axis = int(axis)
            start, end, step = self.starts[idx], self.ends[idx], self.steps[idx]
            if end > x_shape[axis]:
                end = x_shape[axis]
            self.cache.append((axis, x_shape[axis], start, end, step))
            xs = []
            for step_idx in range(x_shape[axis])[start:end:step]:
                xs.append(singa.SliceOn(x, step_idx, step_idx + 1, axis))
            assert len(xs) > 0, "Cannot support empty tensor"
            x = singa.VecTensor(xs)
            x = singa.ConcatOn(x, axis)
        return x

    def backward(self, dy):
        """
        backward of Slice
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        for axis, shape, start, end, step in self.cache[::-1]:
            data_idxes = tuple(range(shape)[start:end:step])
            dys = []
            data_idx = 0
            for step_idx in range(shape):
                if step_idx in data_idxes:
                    tmp_tensor = singa.SliceOn(dy, data_idx, data_idx + 1, axis)
                    data_idx += 1
                else:
                    tmp_shape = list(dy.shape())
                    tmp_shape[axis] = 1
                    tmp_tensor = singa.Tensor(tmp_shape, dy.device())
                    tmp_tensor.SetFloatValue(0.)
                dys.append(tmp_tensor)
            dys = singa.VecTensor(dys)
            dy = singa.ConcatOn(dys, axis)
        return dy


def slice(x, starts, ends, axes=None, steps=None):
    """
    Init a Slice, Produces a slice of the input tensor along multiple axes.
    Similar to numpy: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
    Args:
        x (Tensor): input tensor.
        starts (list of int): starting indices of corresponding axis
        ends (list of int): ending indices of corresponding axis
        axes (list of int): axes that `starts` and `ends` apply to.
            Negative value means counting dimensions from the back.
            Accepted range is [-r, r-1] where r = rank(data).
        steps (list of int): slice step of corresponding axis in `axes`.
            Negative value means slicing backward. 'steps' cannot be 0.
            Defaults to 1.
    Returns:
        the output Tensor.
    """
    return Slice(starts, ends, axes, steps)(x)[0]


class Ceil(Operator):
    """
    Ceil takes one input data (Tensor) and produces one output data (Tensor)
    where the ceil is, `y = ceil(x)`, is applied to the tensor elementwise.
    """

    def __init__(self):
        super(Ceil, self).__init__()

    def forward(self, x):
        """
        forward of Ceil
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        return singa.Ceil(x)

    def backward(self, dy):
        """
        backward of Ceil
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        dy = singa.Tensor(dy.shape(), dy.device())
        dy.SetFloatValue(0.)
        return dy


def ceil(x):
    """
    Ceil takes one input data (Tensor) and produces one output data (Tensor)
    where the ceil is, `y = ceil(x)`, is applied to the tensor elementwise.
    Args:
        x (Tensor): input tensor.
    Returns:
        the output Tensor.
    """
    return Ceil()(x)[0]


class Floor(Operator):
    """
    Floor takes one input data (Tensor) and produces one output data (Tensor), 
    where the floor is, `y = floor(x)`, is applied to the tensor elementwise
    """

    def __init__(self):
        super(Floor, self).__init__()

    def forward(self, x):
        """
        forward of floor
        Args: 
            x (CTensor): input tensor
        Returns:
            the output CTensor    
        """
        return singa.Floor(x)

    def backward(self, dy):
        """
        backward of floor. Derivative of floor is 0
        Args: 
            dy (CTensor): gradient tensor
        Returns:
            the gradient tensor over the input tensor. 
        """
        dy = singa.Tensor(dy.shape(), dy.device())
        dy.SetFloatValue(0.)
        return dy


def floor(x):
    """
    floor takes one input data (Tensor) and produces one output data (Tensor)
    the value of floor is `y = floor(x)`, is applied to the tensor elementwise. 
    Args: 
        x(Tensor): input tensor.
    Returns: 
        the output tensor    
    """
    return Floor()(x)[0]


class Split(Operator):
    """
    Init a Split, Split a tensor into a list of tensors, along the specified
    'axis'.
    """

    def __init__(self, axis, parts, num_output=None):
        """
        Args:
            axis (int): which axis to split on. A negative value means
                counting dimensions from the back. Accepted range is
                [-rank, rank-1] where r = rank(input).
            parts (list of int): length of each output, which can be specified
                using argument 'parts'. Otherwise, the tensor is parts to equal
                sized parts.
            num_output (bool): once parts is none, the tensor is split to equal
                sized parts for each output.
        """
        super(Split, self).__init__()
        self.axis = axis
        self.parts = parts
        self.num_output = num_output
        if self.parts is None:
            assert self.num_output is not None, "For (parts, num_output), it at least requires one."

    def forward(self, x):
        """
        forward of Split
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        x_shape = list(x.shape())
        self.axis = self.axis % len(x_shape)
        if self.parts is None:
            self.parts = [x_shape[self.axis] // self.num_output
                         ] * self.num_output
        xs = []
        _s = 0
        for _l in self.parts:
            xs.append(singa.SliceOn(x, _s, _s + _l, self.axis))
            _s += _l
        return tuple(xs)

    def backward(self, *dys):
        """
        backward of Split
        Args:
            dys: list of CTensor, gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        dys = singa.VecTensor(dys)
        dy = singa.ConcatOn(dys, self.axis)
        return dy


def split(x, axis, parts, num_output=None):
    """
    Init a Split, Split a tensor into a list of tensors, along the specified
    'axis'.
    Args:
        x (Tensor): input tensor.
        axis (int): which axis to split on. A negative value means
            counting dimensions from the back. Accepted range is
            [-rank, rank-1] where r = rank(input).
        parts (list of int): length of each output, which can be specified
            using argument 'parts'. Otherwise, the tensor is parts to equal
            sized parts.
        num_output (bool): once parts is none, the tensor is split to equal
            sized parts for each output.
    Returns:
        the output Tensor.
    """
    return Split(axis, parts, num_output)(x)


class Gather(Operator):
    """
    Init a Gather, Given data tensor of rank r >= 1, and indices tensor of
    rank q, gather entries of the axis dimension of data (by default outer-most
    one as axis=0) indexed by indices, and concatenates them in an output tensor of rank `q + (r - 1)`.
    """

    def __init__(self, axis, indices):
        """
        Args:
            axis (int): which axis to slice on. A negative value means counting
                dimensions from the back. Accepted range is [-rank, rank-1]
                where r = rank(input).
            indices (list of int): entries of the axis dimension of data.
        """
        super(Gather, self).__init__()
        self.axis = axis
        self.indices = indices

    def forward(self, x):
        """
        forward of Gather
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        self.x_shape = list(x.shape())
        self.axis = self.axis % len(self.x_shape)  # handle the negative value
        _shape = self.x_shape[self.axis]
        xs = []
        for indice in self.indices:
            # each indice is a sub-indice
            if isinstance(indice, (tuple, list, np.ndarray)):
                sub_xs = []
                for idx in indice:
                    idx = int(idx % _shape)
                    tmp_tensor = singa.SliceOn(x, idx, idx + 1, self.axis)
                    sub_xs.append(tmp_tensor)
                sub_xs = singa.VecTensor(sub_xs)
                tmp_tensor = singa.ConcatOn(sub_xs, self.axis)
                _slice_shape = list(tmp_tensor.shape())
                _slice_shape.insert(self.axis, 1)  # add a new axis to concat
                tmp_tensor = singa.Reshape(tmp_tensor, _slice_shape)
            else:
                indice = int(indice % _shape)
                tmp_tensor = singa.SliceOn(x, indice, indice + 1, self.axis)
            xs.append(tmp_tensor)
        xs = singa.VecTensor(xs)
        return singa.ConcatOn(xs, self.axis)

    def backward(self, dy):
        """
        backward of Gather
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        _shape = self.x_shape[self.axis]

        def construct_dx(dy, axis, indices, _shape):
            dys = []
            data_idx = 0
            data_idxes = tuple(indices)
            for step_idx in range(_shape):
                if step_idx in data_idxes:
                    tmp_tensor = singa.SliceOn(dy, data_idx, data_idx + 1, axis)
                    data_idx += 1
                else:
                    tmp_shape = list(dy.shape())
                    tmp_shape[axis] = 1
                    tmp_tensor = singa.Tensor(tmp_shape, dy.device())
                    tmp_tensor.SetFloatValue(0.)
                dys.append(tmp_tensor)
            dys = singa.VecTensor(dys)
            dy = singa.ConcatOn(dys, axis)
            return dy

        if isinstance(self.indices[0], tuple) or isinstance(
                self.indices[0], list):
            dx = singa.Tensor(self.x_shape, dy.device())
            dx.SetFloatValue(0.)
            for data_idx in range(len(self.indices)):
                # get a piece of the dy and remove its new axis added at forward
                tmp_tensor = singa.SliceOn(dy, data_idx, data_idx + 1,
                                           self.axis)
                _slice_shape = list(tmp_tensor.shape())
                del _slice_shape[self.axis]
                tmp_tensor = singa.Reshape(tmp_tensor, _slice_shape)
                # construct dx and sum them together
                tmp_tensor = construct_dx(tmp_tensor, self.axis,
                                          self.indices[data_idx],
                                          self.x_shape[self.axis])
                dx = singa.__add__(dx, tmp_tensor)
            return dx
        else:
            return construct_dx(dy, self.axis, self.indices, _shape)


def gather(x, axis, indices):
    """
    Init a Gather, Given data tensor of rank r >= 1, and indices tensor of
    rank q, gather entries of the axis dimension of data (by default outer-most
    one as axis=0) indexed by indices, and concatenates them in an output tensor of rank `q + (r - 1)`.
    Args:
        x (Tensor): input tensor.
        axis (int): which axis to slice on. A negative value means counting
            dimensions from the back. Accepted range is [-rank, rank-1]
            where r = rank(input).
        indices (list of int): entries of the axis dimension of data.
    Returns:
        the output Tensor.
    """
    return Gather(axis, indices)(x)[0]


class Tile(Operator):
    """
    Init a Tile, Constructs a tensor by tiling a given tensor. This is the same
    as function tile in Numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
    """

    def __init__(self, repeats):
        """
        Args:
            repeats (list of int): 1D int matrix of the same length as input's
                dimension number, includes numbers of repeated copies along
                input's dimensions.
        """
        super(Tile, self).__init__()
        self.repeats = [repeats] if isinstance(repeats, int) else repeats

    def forward(self, x):
        """
        forward of Tile
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        self.x_shape = list(x.shape())
        # add new axis from head
        if len(self.x_shape) < len(self.repeats):
            append_len = len(self.repeats) - len(self.x_shape)
            new_shape = [1] * append_len + self.x_shape
            x = singa.Reshape(x, new_shape)
        for axis, rp in enumerate(self.repeats):
            if rp == 1:
                continue
            xs = []
            for idx in range(rp):
                xs.append(x.Clone())
            xs = singa.VecTensor(xs)
            x = singa.ConcatOn(xs, axis)
        return x

    def backward(self, dy):
        """
        backward of Tile
        Args:
            dy (CTensor): gradient tensor.
        Returns:
            the gradient tensor over input tensor.
        """
        for axis, rp in enumerate(self.repeats):
            if rp == 1:
                continue
            _slice_shape = list(dy.shape())
            ori_len = _slice_shape[axis] // rp
            _slice_shape[axis] = ori_len
            _dy = singa.Tensor(_slice_shape, dy.device())
            _dy.SetFloatValue(0.)

            for idx in range(rp):
                tmp_tensor = singa.SliceOn(dy, ori_len * idx,
                                           ori_len * (idx + 1), axis)
                _dy = singa.__add__(_dy, tmp_tensor)
            dy = _dy
        # remove the new axis we added at forward
        if len(self.x_shape) < len(self.repeats):
            dy = singa.Reshape(dy, self.x_shape)
        return dy


def tile(x, repeats):
    """
    Init a Tile, Constructs a tensor by tiling a given tensor. This is the same
    as function tile in Numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
    Args:
        x (Tensor): input tensor.
        repeats (list of int): 1D int matrix of the same length as input's
            dimension number, includes numbers of repeated copies along
            input's dimensions.
    Returns:
        the output Tensor.
    """
    return Tile(repeats)(x)[0]


class NonZero(Operator):
    """
    Init a NonZero, Constructs a tensor by tiling a given tensor. This is the same
    as function tile in Numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
    """

    def __init__(self):
        super(NonZero, self).__init__()

    def forward(self, x):
        """
        forward of NonZero
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        y = tensor.to_numpy(tensor.from_raw_tensor(x))
        y = np.array((np.nonzero(y))).astype(np.int32)
        y = tensor.from_numpy(y)
        y.to_device(x.device())
        return y.data

    def backward(self, dy):
        """
        backward of NonZero
        Args:
            dy (CTensor): gradient tensor.
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def nonzero(x):
    """
    Init a NonZero, Constructs a tensor by tiling a given tensor. This is the same
    as function tile in Numpy: https://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
    Args:
        x (Tensor): input tensor.
    Returns:
        the output Tensor.
    """
    return NonZero()(x)[0]


class Cast(Operator):
    """
    The operator casts the elements of a given input tensor to a data type
    specified by the 'to' argument and returns an output tensor of the same
    size in the converted type.
    """

    def __init__(self, to):
        """
        Args:
            to (int): data type, float32 = 0; int = 2.
        """
        super(Cast, self).__init__()
        self.to = to

    def forward(self, x):
        """
        forward of Cast
        Args:
            x (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        if x.data_type() != self.to:
            x = x.AsType(self.to)
        return x

    def backward(self, dy):
        """
        backward of Cast
        Args:
            dy (CTensor), gradient tensor.
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def cast(x, to):
    """
    The operator casts the elements of a given input tensor to a data type
    specified by the 'to' argument and returns an output tensor of the same
    size in the converted type.
    Args:
        x (Tensor): input tensor.
        to (int): data type, float32 = 0; int = 2.
    Returns:
        the output Tensor.
    """
    return Cast(to)(x)[0]


class OneHot(Operator):
    """
    Produces a one-hot tensor based on inputs.
    """

    def __init__(self, axis, depth, values):
        """
        Args:
            axis (int): Axis along which one-hot representation in added.
                Default: axis=-1. axis=-1 means that the additional dimension
                will be inserted as the innermost/last dimension in the output
                tensor.
            depth (int): Scalar specifying the number of classes in one-hot
                tensor. This is also the size of the one-hot dimension
                (specified by 'axis' attribute) added on in the output tensor.
                The values in the 'indices' input tensor are expected to be in
                the range [-depth, depth-1].
            values (float): Rank 1 tensor containing exactly two elements, in
                the format [off_value, on_value], where 'on_value' is the
                value used for filling locations specified in 'indices' input
                tensor,
        """
        super(OneHot, self).__init__()
        self.axis = axis
        self.depth = depth
        self.values = values

    def forward(self, indices):
        """
        forward of OneHot, we borrow this function from onnx
        Args:
            indices (CTensor): Scalar specifying the number of classes in
                one-hot tensor. The values in the 'indices' input tensor are
                expected to be in the range [-depth, depth-1].
        Returns:
            the output CTensor.
        """
        values = tensor.to_numpy(tensor.from_raw_tensor(indices))
        rank = len(values.shape)
        depth_range = np.arange(self.depth)
        if self.axis < 0:
            self.axis += (rank + 1)
        ls = values.shape[0:self.axis]
        rs = values.shape[self.axis:rank]
        targets = np.reshape(depth_range, (1,) * len(ls) + depth_range.shape +
                             (1,) * len(rs))
        values = np.reshape(np.mod(values, self.depth), ls + (1,) + rs)
        np_tensor = np.asarray(targets == values, dtype=np.float32)
        np_tensor = np_tensor * (self.values[1] -
                                 self.values[0]) + self.values[0]
        tmp_tensor = tensor.from_numpy(np_tensor)
        tmp_tensor.to_device(indices.device())
        return tmp_tensor.data

    def backward(self, dy):
        """
        backward of OneHot
        Args:
            dy (CTensor):gradient tensor.
        Raises:
            AssertionError: no backward function for this operator
        """
        assert False, ('no gradient for backward function')


def onehot(axis, indices, depth, values):
    """
    Produces a one-hot tensor based on inputs.
    Args:
        axis (int): Axis along which one-hot representation in added.
            Default: axis=-1. axis=-1 means that the additional dimension
            will be inserted as the innermost/last dimension in the output
            tensor.
        indices (Tensor): Scalar specifying the number of classes in
            one-hot tensor. The values in the 'indices' input tensor are
            expected to be in the range [-depth, depth-1].
        depth (int): Scalar specifying the number of classes in one-hot
            tensor. This is also the size of the one-hot dimension
            (specified by 'axis' attribute) added on in the output tensor.
            The values in the 'indices' input tensor are expected to be in
            the range [-depth, depth-1].
        values (float): Rank 1 tensor containing exactly two elements, in
            the format [off_value, on_value], where 'on_value' is the
            value used for filling locations specified in 'indices' input
            tensor,
    Returns:
        the output Tensor.
    """
    return OneHot(axis, depth, values)(indices)[0]


class _RNN(Operator):
    """ RNN operation with c++ backend
    """

    def __init__(
            self,
            handle,
            return_sequences=False,
            #  batch_first=True,
            use_mask=False,
            seq_lengths=None):
        assert singa.USE_CUDA, "Not able to run without CUDA"
        super(_RNN, self).__init__()
        self.handle = handle
        self.return_sequences = return_sequences
        self.use_mask = use_mask
        if use_mask:
            assert type(seq_lengths) == Tensor, "wrong type for seq_lengths"
        self.seq_lengths = seq_lengths

    def forward(self, x, hx, cx, w):
        if training:
            if self.use_mask:
                (y, hy,
                 cy) = singa.GpuRNNForwardTrainingEx(x, hx, cx, w,
                                                     self.seq_lengths.data,
                                                     self.handle)
            else:
                (y, hy,
                 cy) = singa.GpuRNNForwardTraining(x, hx, cx, w, self.handle)
            self.inputs = {
                'x': x,
                'hx': hx,
                'cx': cx,
                'w': w,
                'y': y,
                'hy': hy,
                'cy': cy
            }
        else:
            if self.use_mask:
                (y, hy,
                 cy) = singa.GpuRNNForwardInferenceEx(x, hx, cx, w,
                                                      self.seq_lengths.data,
                                                      self.handle)
            else:
                (y, hy,
                 cy) = singa.GpuRNNForwardInference(x, hx, cx, w, self.handle)

        if self.return_sequences:
            # (seq, bs, data)
            return y
        else:
            # return last time step of y
            # (seq, bs, data)[-1] -> (bs, data)
            last_y_shape = (y.shape()[1], y.shape()[2])
            last_y = singa.Tensor(list(last_y_shape), x.device())

            src_offset = y.Size() - last_y.Size()
            # def copy_data_to_from(dst, src, size, dst_offset=0, src_offset=0):
            singa.CopyDataToFrom(last_y, y, last_y.Size(), 0, src_offset)
            return last_y

    def backward(self, grad):
        assert training is True and hasattr(
            self, "inputs"), "Please set training as True before do BP. "

        # (seq, bs, hid)
        dy = None
        if self.return_sequences:
            assert grad.shape() == self.inputs['y'].shape(), (
                "grad shape %s != y shape %s" %
                (grad.shape(), self.inputs['y'].shape()))
            dy = grad
        else:
            # grad (bs, directions*hidden) -> dy (seq, bs, directions*hidden)
            #   empty space filled by zeros
            assert grad.shape() == (self.inputs['y'].shape()[1],
                                    self.inputs['y'].shape()[2]), (
                                        "grad y shape %s != last y shape %s" %
                                        (grad.shape(),
                                         (self.inputs['y'].shape()[1],
                                          self.inputs['y'].shape()[2])))
            dy = singa.Tensor(list(self.inputs['y'].shape()), grad.device())
            dy.SetFloatValue(0.0)
            dst_offset = dy.Size() - grad.Size()
            singa.CopyDataToFrom(dy, grad, grad.Size(), dst_offset, 0)

        # states grad are zeros, since states are not used in forward pass
        dhy = singa.Tensor(list(self.inputs['hy'].shape()), grad.device())
        dhy.SetFloatValue(0.0)
        dcy = singa.Tensor(list(self.inputs['cy'].shape()), grad.device())
        dcy.SetFloatValue(0.0)

        if self.use_mask:
            (dx, dhx,
             dcx) = singa.GpuRNNBackwardxEx(self.inputs['y'], dy, dhy, dcy,
                                            self.inputs['w'], self.inputs['hx'],
                                            self.inputs['cx'],
                                            self.seq_lengths.data, self.handle)
            dW = singa.GpuRNNBackwardWEx(self.inputs['x'], self.inputs['hx'],
                                         self.inputs['y'],
                                         self.seq_lengths.data, self.handle)
        else:
            (dx, dhx,
             dcx) = singa.GpuRNNBackwardx(self.inputs['y'], dy, dhy, dcy,
                                          self.inputs['w'], self.inputs['hx'],
                                          self.inputs['cx'], self.handle)
            dW = singa.GpuRNNBackwardW(self.inputs['x'], self.inputs['hx'],
                                       self.inputs['y'], self.handle)

        return dx, dhx, dcx, dW


class CosSim(Operator):
    """
    Init a cos similarity operator
    """

    def __init__(self):
        super(CosSim, self).__init__()

    @classmethod
    def dot(cls, a, b):
        """
        dot multiply
        Args:
            a (CTensor): 2d input tensor.
            b (CTensor): 2d input tensor.
        Returns:
            CTensor: the output CTensor.
        """
        batch_size = a.shape()[0]
        ret = []
        for indice in range(batch_size):
            tmp_a = singa.SliceOn(a, indice, indice + 1, 0)  # 1 * d
            tmp_b = singa.SliceOn(b, indice, indice + 1, 0)  # 1 * d
            tmp_b = singa.DefaultTranspose(tmp_b)
            tmp_tensor = singa.Mult(tmp_a, tmp_b)  # 1 * d * d * 1
            ret.append(tmp_tensor)
        ret = singa.VecTensor(ret)
        ret = singa.ConcatOn(ret, 0)  # b * 1
        return singa.Reshape(ret, [ret.shape()[0]])  # b

    def forward(self, a, b):
        """
        forward of CosSim
        Args:
            a (CTensor): input tensor.
            b (CTensor): input tensor.
        Returns:
            the output CTensor.
        """
        ad = CosSim.dot(a, a)
        bd = CosSim.dot(b, b)
        ap = singa.PowFloat(ad, 0.5)
        bp = singa.PowFloat(bd, 0.5)
        ret = singa.__div__(CosSim.dot(a, b), singa.__mul__(ap, bp))
        if training:
            self.cache = (a, b, ad, bd, ap, bp, ret)
        return ret

    def backward(self, dy):
        """
        backward of CosSim
        follow https://math.stackexchange.com/a/1923705
        Args:
            dy (CTensor): gradient tensor.
        Return:
            the gradient tensor over input tensor.
        """
        a, b, ad, bd, ap, bp, ret = self.cache
        ab = singa.__mul__(ap, bp)
        ab = singa.Reshape(ab, list(ab.shape()) + [1])  # b * 1
        ad = singa.Reshape(ad, list(ad.shape()) + [1])  # b * 1
        bd = singa.Reshape(bd, list(bd.shape()) + [1])  # b * 1
        ret = singa.Reshape(ret, list(ret.shape()) + [1])  # b * 1
        dy = singa.Reshape(dy, list(dy.shape()) + [1])  # boardcast
        da = singa.__sub__(singa.__div__(b, ab),
                           singa.__div__(singa.__mul__(ret, a), ad))
        db = singa.__sub__(singa.__div__(a, ab),
                           singa.__div__(singa.__mul__(ret, b), bd))
        da = singa.__mul__(dy, da)
        db = singa.__mul__(dy, db)
        return da, db


def cossim(a, b):
    """
    Produces a cos similarity operator
    Args:
        a (CTensor): input tensor.
        b (CTensor): input tensor.
    Returns:
        the output Tensor.
    """
    assert a.shape == b.shape, "shape not match for cossim"
    assert a.ndim() == 2, "shape should be in 2d for cossim"
    assert b.ndim() == 2, "shape should be in 2d for cossim"
    return CosSim()(a, b)[0]


class Expand(Operator):
    """
    Expand operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#Expand

    Example usage::
    data = [[1.], [2.], [3.]]

    # dim_changed
    shape = [2, 1, 6]
    output = [[[1., 1., 1., 1., 1., 1.], 
               [2., 2., 2., 2., 2., 2.],
               [3., 3., 3., 3., 3., 3.]],
              [[1., 1., 1., 1., 1., 1.],
               [2., 2., 2., 2., 2., 2.],
               [3., 3., 3., 3., 3., 3.]]]

    # dim_unchanged
    shape = [3, 4]
    output = [[1., 1., 1., 1.],
              [2., 2., 2., 2.],
              [3., 3., 3., 3.]]
    """

    def __init__(self, shape):
        """
        Args:
            shape (list[int]: indicates the shape you want to expand to, 
                following the broadcast rule
        """
        super(Expand, self).__init__()
        self.shape = shape

    def forward(self, x):
        if isinstance(self.shape, np.ndarray):
            self.shape = self.shape.tolist()
        else:
            self.shape = list(self.shape)
        self.x_shape = list(x.shape())
        x_shape = self.x_shape.copy()
        self.dim_changed = True if len(self.shape) != len(x_shape) else False
        if self.dim_changed:
            tmp_tensor = singa.Tensor(self.shape, x.device())
            tmp_tensor.SetFloatValue(1.)
            x = singa.__mul__(x, tmp_tensor)
        else:
            for axis, s_1, s_2 in zip(range(len(self.shape)), self.shape,
                                      x_shape):
                if s_1 == s_2:
                    continue
                xs = [x] * (s_1 // s_2)
                x = singa.VecTensor(xs)
                x = singa.ConcatOn(x, axis)
        return x

    def backward(self, dy):
        x_shape = self.x_shape
        if self.dim_changed:
            dy = tensor.from_raw_tensor(dy)
            if len(self.shape) > len(x_shape):
                x_shape = [1] * (len(self.shape) - len(x_shape)) + x_shape
            for axis, s in zip(range(len(self.shape))[::-1], x_shape[::1]):
                if s == 1:
                    dy = tensor.sum(dy, axis)
            dy = dy.data
        else:
            for axis, s_1, s_2 in zip(
                    range(len(self.shape))[::-1], self.shape[::-1],
                    x_shape[::-1]):
                if s_1 > s_2:
                    duplic = s_1 // s_2
                    dxs = []
                    for i in range(s_2):
                        tmp_tensor = None
                        for j in range(duplic):
                            if not tmp_tensor:
                                tmp_tensor = singa.SliceOn(
                                    dy, j * s_2 + i, j * s_2 + i + 1, axis)
                            else:
                                tmp_tensor += singa.SliceOn(
                                    dy, j * s_2 + i, j * s_2 + i + 1, axis)
                        dxs.append(tmp_tensor)
                    dxs = singa.VecTensor(dxs)
                    dy = singa.ConcatOn(dxs, axis)
        dy = singa.Reshape(dy, self.x_shape)
        return dy


def expand(x, shape):
    """
    Produces a Expand operator
    Args:
        x (Tensor): input tensor.
        shape (list[int]: indicates the shape you want to expand to, 
            following the broadcast rule
    Returns:
        the output Tensor.
    """
    return Expand(shape)(x)[0]


class Pad(Operator):
    """
    Pad operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#Pad

    Example usage::
        data = 
        [
            [1.0, 1.2],
            [2.3, 3.4],
            [4.5, 5.7],
        ] 
        pads = [0, 2, 0, 0]

        # constant mode
        mode = 'constant'
        constant_value = 0.0
        output = 
        [
            [
                [0.0, 0.0, 1.0, 1.2],
                [0.0, 0.0, 2.3, 3.4],
                [0.0, 0.0, 4.5, 5.7],
            ],
        ]

        # reflect mode
        mode = 'reflect'
        output = 
        [
            [
                [1.0, 1.2, 1.0, 1.2],
                [2.3, 3.4, 2.3, 3.4],
                [4.5, 5.7, 4.5, 5.7],
            ],
        ]

        # edge mode
        mode = 'edge'
        output = 
        [
            [
                [1.0, 1.0, 1.0, 1.2],
                [2.3, 2.3, 2.3, 3.4],
                [4.5, 4.5, 4.5, 5.7],
            ],
        ]
    """

    def __init__(self, mode, pads, constant=0.):
        """
        Args:
            mode (string): Supported modes: `constant`(default), `reflect`, `edge`.
            pads (list[int]): list of integers indicating the number of padding elements 
                to add at the beginning each axis.
            constant (float): A scalar value to be used if the mode chosen is 
                `constant`
        """
        super(Pad, self).__init__()
        self.mode = mode
        if self.mode not in ("constant", "reflect", "edge"):
            assert False, ('Only support three modes: constant, reflect, edge')
        self.constant = constant
        self.pads = pads
        self.pad_width = ()

    def forward(self, x):
        if not self.pad_width:
            half_width = len(self.pads) // 2
            for i in range(half_width):
                self.pad_width += ((self.pads[i], self.pads[i + half_width])),

        for axis, pads in zip(range(len(x.shape())), self.pad_width):
            for pad, is_left in zip(pads, (True, False)):
                if pad == 0:
                    continue
                pad_shape = list(x.shape())
                if self.mode == "constant":
                    pad_shape[axis] = pad
                    padding = singa.Tensor(list(pad_shape), x.device())
                    padding.SetFloatValue(self.constant)
                    if is_left:
                        x = singa.ConcatOn(singa.VecTensor([padding, x]), axis)
                    else:
                        x = singa.ConcatOn(singa.VecTensor([x, padding]), axis)
                elif self.mode == "reflect":
                    axis_shape = pad_shape[axis]
                    if is_left:
                        padding = singa.SliceOn(x, 0, pad, axis)
                        x = singa.ConcatOn(singa.VecTensor([padding, x]), axis)
                    else:
                        padding = singa.SliceOn(x, axis_shape - pad, axis_shape,
                                                axis)
                        x = singa.ConcatOn(singa.VecTensor([x, padding]), axis)
                elif self.mode == "edge":
                    axis_shape = pad_shape[axis]
                    if is_left:
                        padding = []
                        for _ in range(pad):
                            padding.append(singa.SliceOn(x, 0, 1, axis))
                        padding.append(x)
                        padding = singa.VecTensor(padding)
                        x = singa.ConcatOn(padding, axis)
                    else:
                        padding = [x]
                        for _ in range(pad):
                            padding.append(
                                singa.SliceOn(x, axis_shape - 1, axis_shape,
                                              axis))
                        padding = singa.VecTensor(padding)
                        x = singa.ConcatOn(padding, axis)
        return x

    def backward(self, dy):
        for axis, pads in zip(range(len(dy.shape())), self.pad_width):
            for pad, is_left in zip(pads, (True, False)):
                if pad == 0:
                    continue
                axis_shape = list(dy.shape())[axis]
                if is_left:
                    dy = singa.SliceOn(dy, pad, axis_shape, axis)
                else:
                    dy = singa.SliceOn(dy, 0, axis_shape - pad, axis)
        return dy


def pad(x, mode, pads, constant=0.):
    """
    Produces a pad operator
    Args:
        x (Tensor): input tensor.
        mode (string): Supported modes: `constant`(default), `reflect`, `edge`.
        pads (list[int]): list of integers indicating the number of padding elements 
            to add at the beginning each axis.
        constant (float): A scalar value to be used if the mode chosen is 
            `constant`
    Returns:
        the output Tensor.
    """
    return Pad(mode, pads, constant)(x)[0]


class UpSample(Operator):
    """
    UpSample operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#upsample

    Example usage::
    data = [[[[1, 2],
              [3, 4],]]]

    # nearest
    scales = [1.0, 1.0, 2.0, 3.0]
    output = [[[[1, 1, 1, 2, 2, 2],
                [1, 1, 1, 2, 2, 2],
                [3, 3, 3, 4, 4, 4],
                [3, 3, 3, 4, 4, 4],]]]
    """

    def __init__(self, mode, scales):
        """
        Args:
            scales (list[int]): The scale array along each dimension. It takes 
                value greater than or equal to 1. 
        """
        super(UpSample, self).__init__()
        self.scales = scales
        self.mode = mode.lower()
        if self.mode != "nearest":
            assert False, "only support nearest mode."

    def forward(self, x):
        if isinstance(self.scales, np.ndarray):
            self.scales = self.scales.tolist()
        else:
            self.scales = list(self.scales)
        self.x_shape = list(x.shape())
        for axis, s in zip(range(len(self.scales)), self.scales):
            s = int(s)
            if s == 1:
                continue
            x = x.Repeat([
                s,
            ], axis)
        return x

    def backward(self, dy):
        x_shape = self.x_shape.copy()
        for axis, s_1, s_2 in zip(
                range(len(self.scales))[::-1], self.scales[::-1],
                x_shape[::-1]):
            s_1 = int(s_1)
            if s_1 != 1:
                duplic = s_1
                dxs = []
                for i in range(s_2):
                    tmp_tensor = None
                    for j in range(duplic):
                        if not tmp_tensor:
                            tmp_tensor = singa.SliceOn(dy, i * duplic + j,
                                                       i * duplic + j + 1, axis)
                        else:
                            tmp_tensor += singa.SliceOn(dy, i * duplic + j,
                                                        i * duplic + j + 1,
                                                        axis)
                    dxs.append(tmp_tensor)
                dxs = singa.VecTensor(dxs)
                dy = singa.ConcatOn(dxs, axis)
        dy = singa.Reshape(dy, self.x_shape)
        return dy


def upsample(x, mode, scales):
    """
    Produces a upsample operator
    Args:
        x (Tensor): input tensor.
        scales (list[int]): The scale array along each dimension. It takes 
                value greater than or equal to 1. 
    Returns:
        the output Tensor.
    """
    return UpSample(mode, scales)(x)[0]


class DepthToSpace(Operator):
    """
    DepthToSpace operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#DepthToSpace

    Example usage::
    blocksize = 2
    # (1, 8, 2, 3) input tensor
    data = [[[[0., 1., 2.],
            [3., 4., 5.]],
            [[9., 10., 11.],
            [12., 13., 14.]],
            [[18., 19., 20.],
            [21., 22., 23.]],
            [[27., 28., 29.],
            [30., 31., 32.]],
            [[36., 37., 38.],
            [39., 40., 41.]],
            [[45., 46., 47.],
            [48., 49., 50.]],
            [[54., 55., 56.],
            [57., 58., 59.]],
            [[63., 64., 65.],
            [66., 67., 68.]]]]

    # DCR mode
    # (1, 2, 4, 6) output tensor
    output = [[[[0., 18., 1., 19., 2., 20.],
                [36., 54., 37., 55., 38., 56.],
                [3., 21., 4., 22., 5., 23.],
                [39., 57., 40., 58., 41., 59.]],
               [[9., 27., 10., 28., 11., 29.],
                [45., 63., 46., 64., 47., 65.],
                [12., 30., 13., 31., 14., 32.],
                [48., 66., 49., 67., 50., 68.]]]]

    # CRD mode
    # (1, 2, 4, 6) output tensor
    output = [[[[0., 9., 1., 10., 2., 11.],
                [18., 27., 19., 28., 20., 29.],
                [3., 12., 4., 13., 5., 14.],
                [21., 30., 22., 31., 23., 32.]],
               [[36., 45., 37., 46., 38., 47.],
                [54., 63., 55., 64., 56., 65.],
                [39., 48., 40., 49., 41., 50.],
                [57., 66., 58., 67., 59., 68.]]]]
    """

    def __init__(self, blocksize, mode="DCR"):
        """
        Args:
            blocksize (int): Blocks of [blocksize, blocksize] are moved.
            mode (string): DCR (default) for depth-column-row order re-
                arrangement. Use CRD for column-row-depth order.
        """
        super(DepthToSpace, self).__init__()
        self.blocksize = blocksize
        self.mode = mode.upper()

    def forward(self, x):
        if training:
            self.x_shape = x.shape()
        b, c, h, w = x.shape()
        blocksize = self.blocksize
        if self.mode == "DCR":
            x = singa.Reshape(
                x, [b, blocksize, blocksize, c // (blocksize**2), h, w])
            x = singa.Transpose(x, [0, 3, 4, 1, 5, 2])
            x = singa.Reshape(
                x, [b, c // (blocksize**2), h * blocksize, w * blocksize])
        elif self.mode == "CRD":
            x = singa.Reshape(
                x, [b, c // (blocksize**2), blocksize, blocksize, h, w])
            x = singa.Transpose(x, [0, 1, 4, 2, 5, 3])
            x = singa.Reshape(
                x, [b, c // (blocksize**2), h * blocksize, w * blocksize])
        else:
            assert False, ("only support two methods: DCR and CRD.")
        return x

    def backward(self, dy):
        b, c, h, w = self.x_shape
        blocksize = self.blocksize
        dy = singa.Reshape(
            dy, [b, c // (blocksize**2), h, blocksize, w, blocksize])
        if self.mode == "DCR":
            dy = singa.Transpose(dy, [0, 3, 5, 1, 2, 4])
        elif self.mode == "CRD":
            dy = singa.Transpose(dy, [0, 1, 3, 5, 2, 4])
        else:
            assert False, ("only support two methods: DCR and CRD.")
        dy = singa.Reshape(dy, self.x_shape)
        return dy


def depth_to_space(x, blocksize, mode="DCR"):
    """
    Produces a DepthToSpace operator
    Args:
        x (Tensor): input tensor.
        blocksize (int): Blocks of [blocksize, blocksize] are moved.
        mode (string): DCR (default) for depth-column-row order re-
            arrangement. Use CRD for column-row-depth order.
    Returns:
        the output Tensor.
    """
    return DepthToSpace(blocksize, mode)(x)[0]


class SpaceToDepth(Operator):
    """
    SpaceToDepth operator following ONNX Operator Schemas, reverse of DepthToSpace
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#SpaceToDepth
    """

    def __init__(self, blocksize, mode="DCR"):
        """
        Args:
            blocksize (int): Blocks of [blocksize, blocksize] are moved.
            mode (string): DCR (default) for depth-column-row order re-
                arrangement. Use CRD for column-row-depth order.
        """
        super(SpaceToDepth, self).__init__()
        self.blocksize = blocksize
        self.mode = mode.upper()

    def forward(self, x):
        blocksize = self.blocksize
        b, c, h, w = x.shape()
        b, c, h, w = b, c * (blocksize**2), h // blocksize, w // blocksize
        if training:
            self.x_shape = (b, c, h, w)
        x = singa.Reshape(
            x, [b, c // (blocksize**2), h, blocksize, w, blocksize])
        if self.mode == "DCR":
            x = singa.Transpose(x, [0, 3, 5, 1, 2, 4])
        elif self.mode == "CRD":
            x = singa.Transpose(x, [0, 1, 3, 5, 2, 4])
        else:
            assert False, ("only support two methods: DCR and CRD.")
        x = singa.Reshape(x, self.x_shape)
        return x

    def backward(self, dy):
        b, c, h, w = self.x_shape
        blocksize = self.blocksize
        if self.mode == "DCR":
            dy = singa.Reshape(
                dy, [b, blocksize, blocksize, c // (blocksize**2), h, w])
            dy = singa.Transpose(dy, [0, 3, 4, 1, 5, 2])
            dy = singa.Reshape(
                dy, [b, c // (blocksize**2), h * blocksize, w * blocksize])
        elif self.mode == "CRD":
            dy = singa.Reshape(
                dy, [b, c // (blocksize**2), blocksize, blocksize, h, w])
            dy = singa.Transpose(dy, [0, 1, 4, 2, 5, 3])
            dy = singa.Reshape(
                dy, [b, c // (blocksize**2), h * blocksize, w * blocksize])
        else:
            assert False, ("only support two methods: DCR and CRD.")
        return dy


def space_to_depth(x, blocksize, mode="DCR"):
    """
    Produces a SpaceToDepth operator
    Args:
        x (Tensor): input tensor.
        blocksize (int): Blocks of [blocksize, blocksize] are moved.
        mode (string): DCR (default) for depth-column-row order re-
            arrangement. Use CRD for column-row-depth order.
    Returns:
        the output Tensor.
    """
    return SpaceToDepth(blocksize, mode)(x)[0]


class Where(Operator):
    """
    Where operator following ONNX Operator Schemas
    https://github.com/onnx/onnx/blob/master/docs/Operators.md#Where
    and Numpy
    https://numpy.org/doc/stable/reference/generated/numpy.where.html
    Example usage::
    condition = [[True, False], 
              [True, True]]
    x = [[1, 2], 
        [3, 4]]
    y =  [[9, 8], 
        [7, 6]]

    output = [[1, 8],
            [3, 4]]
    """

    def __init__(self, condition):
        """
        Args:
            condition (Tensor): When True (nonzero), yield X, otherwise yield Y
        """
        super(Where, self).__init__()
        self.condition = condition

    def forward(self, a, b):
        if isinstance(self.condition, list):
            self.condition = np.array(self.condition)
        if isinstance(self.condition, np.ndarray):
            self.condition = self.condition.astype(np.float32)
            self.condition = tensor.from_numpy(self.condition)
            self.condition.to_device(a.device())
            self.condition = self.condition.data
        self.neg_condition = singa.AddFloat(
            singa.MultFloat(self.condition, -1.), 1.)
        _a, _b = a, b
        dtype0 = _a.data_type()
        dtype1 = _b.data_type()
        if dtype0 == singa.kInt or dtype1 == singa.kInt:
            _a = a.AsType(singa.kFloat32)
            _b = b.AsType(singa.kFloat32)
            res = singa.__add__(singa.__mul__(self.condition, _a),
                                singa.__mul__(self.neg_condition, _b))
            res = res.AsType(singa.kInt)
        else:
            res = singa.__add__(singa.__mul__(self.condition, _a),
                                singa.__mul__(self.neg_condition, _b))
        return res

    def backward(self, dy):
        da = singa.__mul__(self.condition, dy)
        db = singa.__mul__(self.neg_condition, dy)
        return da, db


def where(x, y, condition):
    """
    Produces a Where operator
    Args:
        x (Tensor): input tensor.
        y (Tensor): input tensor.
        condition (Tensor): When True (nonzero), yield X, otherwise yield Y
    Returns:
        the output Tensor.
    """
    return Where(condition)(x, y)[0]


class Round(Operator):
    """
    Element-wise round the input
    """

    def __init__(self):
        super(Round, self).__init__()

    def forward(self, x):
        return singa.Round(x)

    def backward(self, dy):
        dy = singa.Tensor(dy.shape(), dy.device())
        dy.SetFloatValue(0.)
        return dy


def round(x):
    """
    Element-wise round the input
    Args:
        x (Tensor): input tensor.
    Returns:
        the output Tensor.
    """
    return Round()(x)[0]


class Rounde(Operator):
    """
    Element-wise round the input, In case of halfs, round to the nearest even integer
    """

    def __init__(self):
        super(Rounde, self).__init__()

    def forward(self, x):
        return singa.RoundE(x)

    def backward(self, dy):
        dy = singa.Tensor(dy.shape(), dy.device())
        dy.SetFloatValue(0.)
        return dy


def rounde(x):
    """
    Element-wise round the input, In case of halfs, round to the nearest even integer
    Args:
        x (Tensor): input tensor.
    Returns:
        the output Tensor.
    """
    return Rounde()(x)[0]


class Embedding(Operator):
    """
    Init an embedding operator
    """

    def __init__(self):
        super(Embedding, self).__init__()

    def forward(self, x, w):
        """
        forward of embedding
        Args:
            x (CTensor): input tensor.
            w (CTensor): weight tensor.
        Returns:
            the output CTensor.
        """
        x = tensor.to_numpy(tensor.from_raw_tensor(x))
        if training:
            self.cache = (x, w.shape())

        xs = []
        x = x.tolist()
        for indice in x:
            sub_xs = []
            for idx in indice:
                idx = int(idx)
                tmp_tensor = singa.SliceOn(w, idx, idx + 1, 0)
                sub_xs.append(tmp_tensor)
            sub_xs = singa.VecTensor(sub_xs)
            tmp_tensor = singa.ConcatOn(sub_xs, 0)
            tmp_tensor = singa.Reshape(tmp_tensor,
                                       [1] + list(tmp_tensor.shape()))

            xs.append(tmp_tensor)
        xs = singa.VecTensor(xs)
        xs = singa.ConcatOn(xs, 0)
        return xs

    def backward(self, dy):
        """
        backward of embedding
        Args:
            dy (CTensor): gradient tensor.
        Raises:
            the gradient tensor over input tensor.
        """
        x, w_shape = self.cache
        dy_shape = dy.shape()
        # construct the dx
        dx = tensor.sum(tensor.from_raw_tensor(dy), axis=2)

        # construct the dw
        dws = []
        for idx in range(w_shape[0]):
            tmp_tensor = singa.Tensor((1, w_shape[1]), dy.device())
            tmp_tensor.SetFloatValue(0.0)
            dws.append(tmp_tensor)
        dy = singa.Reshape(dy, [dy_shape[0] * dy_shape[1], dy_shape[2]])
        x = x.reshape(-1)
        for idx, val in enumerate(x):
            tmp_tensor = singa.SliceOn(dy, idx, idx + 1, 0)
            dws[val] = singa.__add__(dws[val], tmp_tensor)
        dws = singa.VecTensor(dws)
        return dx.data, singa.ConcatOn(dws, 0)


def embedding(x, w):
    """
    Produces an embedding operator.
    Args:
    Returns:
        the output Tensor.
    """
    return Embedding()(x, w)[0]


class Erf(Operator):
    """
    Apply element-wise math.erf to the input
    """

    def __init__(self):
        super(Erf, self).__init__()

    def forward(self, x):
        return singa.Erf(x)

    def backward(self, dy):
        dx = singa.MultFloat(singa.PowFloat(dy, 2.0), -1.0)
        dx = singa.MultFloat(singa.Exp(dx), 2. / np.pi ** 0.5)
        return dx


def erf(x):
    """
    Apply element-wise math.erf to the input
    Args:
        x (Tensor): input tensor.
    Returns:
        the output Tensor.
    """
    return Erf()(x)[0]


''' alias for Operator and Layers
'''
Operation = Operator
''' import layer at the end to resolve circular import
'''
from singa import layer
Linear = layer.Linear
Conv2d = layer.Conv2d
SeparableConv2d = layer.SeparableConv2d
BatchNorm2d = layer.BatchNorm2d
Pooling2d = layer.Pooling2d
MaxPool2d = layer.MaxPool2d
AvgPool2d = layer.AvgPool2d
MaxPool1d = layer.MaxPool1d
AvgPool1d = layer.AvgPool1d
RNN_Base = layer.RNN_Base
RNN = layer.RNN
LSTM = layer.LSTM
