Hi Fred, I tried it out, but for me, it doesnt find conv() in package cuda_ndarray gpuval = cuda_ndarray.conv(img, kern, mode, subsample). So, made the changes in the test_conv_cuda_ndarray _test_dummy().

I see that the cpu version is computed using py_conv(), which in turn calls scipy.signal.convolve2d. How can the result 'gpuval' now be the same as scipy.signal.convolve2d instead of the scipy.signal.correlate?

Also, this still passes tests for all image, kernel, channel and batch sizes: https://github.com/stencilman/Theano-1/blob/fb66035292ef070b86466bf61c9c42b8faaa0a1c/theano/sandbox/cuda/tests/test_conv_gemm.py
Look what I did on like 117 in file theano/sandbox/cuda/tests/test_conv_cuda_ndarray.py. I rotated the kernel by 180 before convolution, and this now gives the same result as GpuConvMM. So, I think the cuda/c part is completely fine and the corrent arguments are being passed to the cublas function.
- fixed a bug in cafe conv (values of _M, _N, _K)
- added a test that does a check on variety of shapes and sizes of image and kernel
- removed flip form local_conv_gemm in cuda/opt.py is the code never reached there for me
- added flip in the kernel in the test code itself
Some more fix.