def perform(self, node, inp, out_):
        img, topgrad, shape = inp
        img = numpy.asarray(img)
        topgrad = numpy.asarray(topgrad)

        o, = out_

        mode = self.border_mode
        if not ((isinstance(mode, tuple) and min(mode) >= 0) or
                mode in ('valid', 'full', 'half')):
            raise ValueError(
                'invalid border_mode {}, which must be either '
                '"valid", "full", "half", an integer or a pair of'
                ' integers'.format(mode))

        if mode == "full":
            mode = (shape[0] - 1, shape[1] - 1)
        elif mode == "half":
            mode = (shape[0] // 2, shape[1] // 2)
        if isinstance(mode, tuple):
            pad_h, pad_w = map(int, mode)
            mode = "valid"
            new_img = numpy.zeros((img.shape[0], img.shape[1],
                                   img.shape[2] + 2 * pad_h,
                                   img.shape[3] + 2 * pad_w), dtype=img.dtype)
            new_img[:, :, pad_h:img.shape[2] + pad_h, pad_w:img.shape[3] + pad_w] = img
            img = new_img

        if self.subsample[0] > 1 or self.subsample[1] > 1:
            new_shape = (topgrad.shape[0], topgrad.shape[1],
                         img.shape[2] - shape[0] + 1,
                         img.shape[3] - shape[1] + 1)
            new_topgrad = numpy.zeros((new_shape), dtype=topgrad.dtype)
            new_topgrad[:, :, ::self.subsample[0], ::self.subsample[1]] = topgrad
            topgrad = new_topgrad

        topgrad = topgrad.transpose(1, 0, 2, 3)[:, :, ::-1, ::-1]
        img = img.transpose(1, 0, 2, 3)
        kern = self.conv2d(img, topgrad, mode="valid")
        if self.filter_flip:
            kern = kern.transpose(1, 0, 2, 3)[:, :, ::-1, ::-1]
        else:
            kern = kern.transpose(1, 0, 2, 3)
        o[0] = node.outputs[0].type.filter(kern)
dataset/ETHPy150Open rizar/attention-lvcsr/libs/Theano/theano/tensor/nnet/abstract_conv.py/AbstractConv2d_gradWeights.perform/original