Cuda fftconv

Added support for a padding argument in conv2d_fft. Tested with the following script.

```python

import theano
import theano.sandbox
import theano.sandbox.cuda
from theano.sandbox.cuda import fftconv

import theano.tensor as T

import numpy as np


def perform_convolution_through_fftconv(inputs, filters, border_mode='valid', want_padding_on_last_input_dimension=False):

	sym_inputs  = T.tensor4()
	sym_filters = T.tensor4()

	sym_outputs = fftconv.conv2d_fft(sym_inputs, sym_filters, image_shape=inputs.shape, filter_shape=filters.shape, border_mode=border_mode, want_padding_on_last_input_dimension=want_padding_on_last_input_dimension)
	f = theano.function([sym_inputs, sym_filters], sym_outputs)
	outputs_on_gpu = f(inputs, filters)
	outputs = np.array(outputs_on_gpu)

	print outputs.shape
	return outputs


def perform_convolution_through_nnet_conv2d(inputs, filters, border_mode='valid'):

	sym_inputs  = T.tensor4()
	sym_filters = T.tensor4()

	sym_outputs = T.nnet.conv.conv2d(sym_inputs, sym_filters, image_shape=inputs.shape, filter_shape=filters.shape, border_mode=border_mode)
	f = theano.function([sym_inputs, sym_filters], sym_outputs)
	outputs = f(inputs, filters)

	print outputs.shape
	return outputs





def run_test():

	nbr_images    = np.random.randint(low=1,high=18)
	nbr_channels  = np.random.randint(low=1,high=18)
	nbr_filters   = np.random.randint(low=1,high=18)
	image_height  = np.random.randint(low=2,high=10)
	image_width   = np.random.randint(low=2,high=10)
	filter_height = np.random.randint(low=1,high=image_height)
	filter_width  = np.random.randint(low=1,high=image_width)

	inputs  = np.random.rand(nbr_images, nbr_channels, image_height, image_width)
	filters = np.random.rand(nbr_filters, nbr_channels, filter_height, filter_width)
	inputs  = inputs.astype(np.float32)
	filters = filters.astype(np.float32)

	border_mode = 'valid'
	#border_mode = 'full'
	reference_outputs = perform_convolution_through_nnet_conv2d(inputs, filters, border_mode=border_mode)

	if image_width % 2 == 0:
		fftconv_outputs = perform_convolution_through_fftconv(inputs, filters, border_mode=border_mode)
	else:
		fftconv_outputs = perform_convolution_through_fftconv(inputs, filters, border_mode=border_mode, want_padding_on_last_input_dimension=True)

	largest_diff = np.max(np.abs(fftconv_outputs - reference_outputs))
	if 0.01 < largest_diff:
		print "Largest difference between fftconv_outputs and reference_outputs is %f\n" % largest_diff
		return False
	else:
		return True


niter = 100
for i in range(niter):
	success = run_test()
	if success:
		print "Passed for %d" % i
	else:
		print "Failed for %d" % i

```