Add support for subsampling and gradient to GpuDnnConv

This adds a grad() method to GpuDnnConv and adds support for subsampling.  It also allows choosing between convolution and cross-correlation mode (however cross-correlation mode has not been tested).

I've also made a base class that create the cudnn handle to make other ops easier to write.
You got the indentation wrong from this line on up to the end of the function. The idea of this try/except block was to try defining `conv_op`, `conv_op_di` and `conv_op_dk` without shape information (because the test took too long when compiling a separate version for each individual shape), and redefine them with shape information if this fails.
So `corr_op_di = ...` and following up to the end of the function should be unindented by one level.