Repository: Theano/Theano

Issue:
get_conv_output_shape fails on symbolic shape, breaking dnn_conv
I am calling `theano.tensor.signal.conv.conv2d` and specifying `image_shape` and `filter_shape`, but I still get this optimization error when CuDNN is installed/enabled:

UPDATE: I get the same error if I use dnn_conv directly rather than rely on the optimisation. It looks like the problem is that `get_conv_output_shape` doesn't work with symbolic shapes (despite advertising itself as such) -- it calls list on a symbolic shape vector -- and dnn_conv needs a symbolic output shape to pass to gpu_alloc_empty.

```
ERROR (theano.gof.opt): Optimization failure due to: LocalOptGroup(local_abstractconv_cudnn,local_conv_dnn,local_abstractconv_gemm,local_abstractconv_gradinputs_gemm,local_abstractconv_gradweight_gemm,local_conv_gemm)
ERROR   Optimization failure due to: LocalOptGroup(local_abstractconv_cudnn,local_conv_dnn,local_abstractconv_gemm,local_abstractconv_gradinputs_gemm,local_abstractconv_gradweight_gemm,local_conv_gemm)
ERROR (theano.gof.opt): node: GpuConv{valid, (1, 1), None, (6, 15), True, (1, 20, 15), (6, 15)}(GpuReshape{4}.0, GpuReshape{4}.0)
ERROR   node: GpuConv{valid, (1, 1), None, (6, 15), True, (1, 20, 15), (6, 15)}(GpuReshape{4}.0, GpuReshape{4}.0)
ERROR (theano.gof.opt): TRACEBACK:
ERROR   TRACEBACK:
ERROR (theano.gof.opt): Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/theano/gof/opt.py", line 1787, in process_node
    replacements = lopt.transform(node)
  File "/usr/local/lib/python3.4/dist-packages/theano/gof/opt.py", line 1238, in transform
    repl = opt.transform(node)
  File "/usr/local/lib/python3.4/dist-packages/theano/sandbox/cuda/dnn.py", line 2108, in local_conv_dnn
    direction_hint=direction_hint)
  File "/usr/local/lib/python3.4/dist-packages/theano/sandbox/cuda/dnn.py", line 1153, in dnn_conv
    desc_op.subsample)
  File "/usr/local/lib/python3.4/dist-packages/theano/sandbox/cuda/dnn.py", line 557, in get_out_shape
    subsample)
  File "/usr/local/lib/python3.4/dist-packages/theano/tensor/nnet/abstract_conv2d.py", line 46, in get_conv_output_shape
    bsize, imshp = image_shape[0], list(image_shape[2:])
  File "/usr/local/lib/python3.4/dist-packages/theano/tensor/var.py", line 545, in __iter__
    for i in xrange(theano.tensor.basic.get_vector_length(self)):
  File "/usr/local/lib/python3.4/dist-packages/theano/tensor/basic.py", line 4262, in get_vector_length
    raise ValueError("length not known: %s" % msg)
ValueError: length not known: Subtensor{int64::} [id A] '' 
```



Discussion:
I get the same error if I use dnn_conv directly rather than rely on the optimisation.

It looks like the problem is that `get_conv_output_shape` doesn't work with symbolic shapes (despite advertising itself as such) -- it calls list on a symbolic shape vector.


Resolving patch:
diff --git a/theano/tensor/nnet/abstract_conv2d.py b/theano/tensor/nnet/abstract_conv2d.py
--- a/theano/tensor/nnet/abstract_conv2d.py
+++ b/theano/tensor/nnet/abstract_conv2d.py
@@ -43,8 +43,8 @@ def get_conv_output_shape(image_shape, kernel_shape,
         output channels, height and width of the image. None where undefined.
 
     """
-    bsize, imshp = image_shape[0], list(image_shape[2:])
-    nkern, kshp = kernel_shape[0], list(kernel_shape[2:])
+    bsize, imshp = image_shape[0], image_shape[2:]
+    nkern, kshp = kernel_shape[0], kernel_shape[2:]
     if isinstance(border_mode, tuple):
         out_shp = tuple(get_conv_shape_1axis(
             imshp[i], kshp[i], border_mode[i], subsample[i])


Test patch: