def conv2d(x: AbstractTensor, y: AbstractTensor, stride, padding) -> AbstractTensor:
    'Generic convolution implementation with im2col over AbstractTensors.'
    with tf.name_scope('conv2d'):
        (h_filter, w_filter, in_filters, out_filters) = map(int, y.shape)
        (n_x, c_x, h_x, w_x) = map(int, x.shape)
        if (c_x != in_filters):
            out_filters = in_filters
        if (padding == 'SAME'):
            h_out = int(math.ceil((float(h_x) / float(stride))))
            w_out = int(math.ceil((float(w_x) / float(stride))))
        elif (padding == 'VALID'):
            h_out = int(math.ceil((float(((h_x - h_filter) + 1)) / float(stride))))
            w_out = int(math.ceil((float(((w_x - w_filter) + 1)) / float(stride))))
        else:
            raise ValueError("Don't know padding method '{}'".format(padding))
        x_col = x.im2col(h_filter, w_filter, padding, stride)
        w_col = y.transpose([3, 2, 0, 1]).reshape([int(out_filters), (- 1)])
        out = w_col.matmul(x_col)
        out = out.reshape([out_filters, h_out, w_out, n_x])
        out = out.transpose([3, 0, 1, 2])
        return out
Generic convolution implementation with im2col over AbstractTensors.
def conv2d(x: AbstractTensor, y: AbstractTensor, stride, padding) -> AbstractTensor:
    
    with tf.name_scope('conv2d'):
        (h_filter, w_filter, in_filters, out_filters) = map(int, y.shape)
        (n_x, c_x, h_x, w_x) = map(int, x.shape)
        if (c_x != in_filters):
            out_filters = in_filters
        if (padding == 'SAME'):
            h_out = int(math.ceil((float(h_x) / float(stride))))
            w_out = int(math.ceil((float(w_x) / float(stride))))
        elif (padding == 'VALID'):
            h_out = int(math.ceil((float(((h_x - h_filter) + 1)) / float(stride))))
            w_out = int(math.ceil((float(((w_x - w_filter) + 1)) / float(stride))))
        else:
            raise ValueError("Don't know padding method '{}'".format(padding))
        x_col = x.im2col(h_filter, w_filter, padding, stride)
        w_col = y.transpose([3, 2, 0, 1]).reshape([int(out_filters), (- 1)])
        out = w_col.matmul(x_col)
        out = out.reshape([out_filters, h_out, w_out, n_x])
        out = out.transpose([3, 0, 1, 2])
        return out