Repository: Theano/Theano

Issue:
Things to fix after the 0.7 release
Things that did not make it in #2663:
- remove `CudaNdarray_SIZEt` and make `CudaNdarray_SIZE` return a `size_t`
- put back more informative error messages for shape mismatches in `Conv2D`



Discussion:

Resolving patch:
diff --git a/theano/sandbox/cuda/basic_ops.py b/theano/sandbox/cuda/basic_ops.py
--- a/theano/sandbox/cuda/basic_ops.py
+++ b/theano/sandbox/cuda/basic_ops.py
@@ -1176,7 +1176,7 @@ def c_code_reduce_ccontig(self, sio, node, name, x, z, fail):
             int verbose = 0;
             dim3 n_threads(
                     std::min(CudaNdarray_SIZE(%(x)s),
-                            NUM_VECTOR_OP_THREADS_PER_BLOCK));
+                             (size_t) NUM_VECTOR_OP_THREADS_PER_BLOCK));
             dim3 n_blocks(1);
             if (verbose) printf("running kernel_reduce_ccontig_%(name)s"
                                 " n_threads.x=%%d, size=%%d, ndim=%%d\\n",
@@ -1739,7 +1739,7 @@ def c_code_reduce_1011(self, sio, node, name, x, z, fail):
         """ % locals()
 
     def c_code_cache_version_apply(self, node):
-        version = [11]  # the version corresponding to the c code in this Op
+        version = [12]  # the version corresponding to the c code in this Op
 
         # now we insert versions for the ops on which we depend...
         scalar_node = Apply(self.scalar_op,
@@ -3343,13 +3343,13 @@ def c_code(self, node, name, inputs, out_, sub):
         if (%(memset_0)s && CudaNdarray_is_c_contiguous(%(out)s))
         {
             cudaError_t err = cudaMemset(%(out)s->devdata, 0,
-                                         CudaNdarray_SIZEt(%(out)s) * 4);
+                                         CudaNdarray_SIZE(%(out)s) * 4);
             if (cudaSuccess != err)
             {
                 PyErr_Format(PyExc_MemoryError,
                              "GpuAlloc: Error memsetting %%ld"
                              " bytes of device memory. %%s",
-                             (long)(CudaNdarray_SIZEt(%(out)s) * 4),
+                             (long)(CudaNdarray_SIZE(%(out)s) * 4),
                              cudaGetErrorString(err));
                 Py_XDECREF(%(out)s);
                 %(out)s = NULL;
@@ -3374,7 +3374,7 @@ def grad(self, inputs, grads):
         return [None for i in inputs]
 
     def c_code_cache_version(self):
-        return (9,)
+        return (10,)
 
     def do_constant_folding(self, node):
         for client in node.outputs[0].clients:
diff --git a/theano/tensor/nnet/conv.py b/theano/tensor/nnet/conv.py
--- a/theano/tensor/nnet/conv.py
+++ b/theano/tensor/nnet/conv.py
@@ -674,22 +674,30 @@ def perform(self, node, inp, out):
         if any(x is None for x in imshp):
             imshp = tuple(img2d.shape[1:])
         if imshp != img2d.shape[1:]:
-            raise ValueError("bad shape", imshp, img2d.shape[1:])
+            raise ValueError("The image shape provided at build time "
+                             "is different from the one passed at run time",
+                             imshp, img2d.shape[1:])
         kshp = self.kshp
         if any(x is None for x in kshp):
             kshp = tuple(filtersflipped.shape[2:])
         if kshp != filtersflipped.shape[2:]:
-            raise ValueError("bad shape", kshp, filtersflipped.shape[2:])
+            raise ValueError("The filter shape provided at build time "
+                             "is different from the one passed at run time",
+                             kshp, filtersflipped.shape[2:])
         bsize = self.bsize
         if bsize is None:
             bsize = img2d.shape[0]
         elif bsize != img2d.shape[0]:
-            raise ValueError("bad shape", bsize, img2d.shape[0])
+            raise ValueError("The batch size provided at build time "
+                             "is different from the one passed at run time",
+                             bsize, img2d.shape[0])
         nkern = self.nkern
         if nkern is None:
             nkern = filtersflipped.shape[0]
         elif nkern != filtersflipped.shape[0]:
-            raise ValueError("bad shape", nkern, filtersflipped.shape[0])
+            raise ValueError("The number of filters provided at build time "
+                             "is different from the one passed at run time",
+                             nkern, filtersflipped.shape[0])
 
         imshp_logical = self.imshp_logical
         if imshp_logical[0] is None:
@@ -984,7 +992,7 @@ def c_headers(self):
         return ['<numpy/noprefix.h>', '<iostream>', '<sstream>']
 
     def c_code_cache_version(self):
-        return (14, self.openmp, blas.blas_header_version())
+        return (15, self.openmp, blas.blas_header_version())
 
     def c_support_code(self):
         return """
@@ -1088,7 +1096,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of rows in the filter "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1100,7 +1109,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of columns in the filter "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1112,7 +1122,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of rows in the output "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1124,7 +1135,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of columns in the output "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1136,7 +1148,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the image stack size (%%ld) "
+            "isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1146,7 +1159,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the kernel stack size (%%ld) "
+            "isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1158,7 +1172,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of rows in the image "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1170,7 +1185,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of columns in the image "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1182,7 +1198,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the batch size (%%ld) "
+            "isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }
@@ -1194,7 +1211,8 @@ def c_code(self, node, name, inp, out, sub):
             d["assert_size"] += """
 if(%(value)s != %(expected)s){
     PyErr_Format(PyExc_ValueError,
-            "the hard coded shape (%%ld) isn't the run time shape (%%ld).",
+            "The hardcoded shape for the number of kernels in the filter "
+            "(%%ld) isn't the run time shape (%%ld).",
             (long)%(value)s, (long)%(expected)s);
     %(fail)s;
 }


Test patch: