Repository: Theano/Theano

Issue:
Intermittent error in TestCGemvNoFlags.test_cgemv
It looks like `theano.tensor.tests.test_blas_c.TestCGemvNoFlags.test_cgemv` fail in a non-deterministic way, see [here](https://travis-ci.org/Theano/Theano/jobs/283891616#L3503).

It looks like the output memory is not always zeroed out when `beta == 0`, so `nan` can result if there were non-finite elements in that memory, whereas the reference (and expected) result is `0`.


Discussion:
Ok. I will fix it today.

Resolving patch:
diff --git a/theano/gpuarray/elemwise.py b/theano/gpuarray/elemwise.py
--- a/theano/gpuarray/elemwise.py
+++ b/theano/gpuarray/elemwise.py
@@ -409,7 +409,7 @@ class GpuDimShuffle(DimShuffle):
 
     """
     _f16_ok = True
-    c_func_name = 'gpu_dimshuffle'
+    c_func_name = 'APPLY_SPECIFIC(gpu_dimshuffle)'
 
     def make_node(self, input):
         ctx_name = infer_context_name(input)
diff --git a/theano/tensor/blas_headers.py b/theano/tensor/blas_headers.py
--- a/theano/tensor/blas_headers.py
+++ b/theano/tensor/blas_headers.py
@@ -1033,7 +1033,7 @@ def openblas_threads_text():
 
 def blas_header_version():
     # Version for the base header
-    version = (7,)
+    version = (9,)
     if detect_macos_sdot_bug():
         if detect_macos_sdot_bug.fix_works:
             # Version with fix
diff --git a/theano/tensor/elemwise.py b/theano/tensor/elemwise.py
--- a/theano/tensor/elemwise.py
+++ b/theano/tensor/elemwise.py
@@ -131,7 +131,7 @@ class DimShuffle(COp):
     check_input = False
     __props__ = ("input_broadcastable", "new_order", "inplace")
     c_func_file = 'c_code/dimshuffle.c'
-    c_func_name = 'cpu_dimshuffle'
+    c_func_name = 'APPLY_SPECIFIC(cpu_dimshuffle)'
 
     @property
     def params_type(self):


Test patch:
diff --git a/theano/tensor/tests/test_blas.py b/theano/tensor/tests/test_blas.py
--- a/theano/tensor/tests/test_blas.py
+++ b/theano/tensor/tests/test_blas.py
@@ -7,7 +7,7 @@
 from numpy import (arange, array, common_type, complex64, complex128, float32,
                    float64, newaxis, shape, transpose, zeros)
 from numpy.testing import assert_array_almost_equal
-
+from itertools import product
 from six.moves import xrange
 
 import theano
@@ -373,6 +373,97 @@ def t(z, x, y, a=1.0, b=0.0, l='c|py', dt='float64'):
             1, 0, 2)), dt='float32')
 
 
+class TestGemmNoFlags(object):
+    gemm = gemm_no_inplace
+    M = 4
+    N = 5
+    K = 6
+    slice_step = 3
+
+    def setUp(self):
+        unittest_tools.seed_rng()
+
+    def get_variable(self, V, to_transpose, to_slice):
+        if to_transpose:
+            V = V.T
+        if to_slice:
+            V = V[::self.slice_step]
+        return V
+
+    def get_function(self, dtype,
+                     transpose_A=False, transpose_B=False, transpose_C=False,
+                     slice_A=False, slice_B=False, slice_C=False):
+        alpha = theano.tensor.scalar(dtype=dtype, name='alpha')
+        beta = theano.tensor.scalar(dtype=dtype, name='beta')
+        A = theano.tensor.matrix(dtype=dtype, name='A')
+        B = theano.tensor.matrix(dtype=dtype, name='B')
+        C = theano.tensor.matrix(dtype=dtype, name='C')
+
+        A1 = self.get_variable(A, transpose_A, slice_A)
+        B1 = self.get_variable(B, transpose_B, slice_B)
+        C1 = self.get_variable(C, transpose_C, slice_C)
+
+        return theano.function([alpha, A, B, beta, C], self.gemm(C1, alpha, A1, B1, beta))
+
+    def generate_value(self, dtype, width, height, to_transpose, to_slice):
+        if to_slice:
+            if to_transpose:
+                shape = (height, width * self.slice_step)
+            else:
+                shape = (width * self.slice_step, height)
+        else:
+            if to_transpose:
+                shape = (height, width)
+            else:
+                shape = (width, height)
+        return np.random.random(shape).astype(dtype)
+
+    def get_data(self, dtype, alpha, beta,
+                 transpose_A=False, transpose_B=False, transpose_C=False,
+                 slice_A=False, slice_B=False, slice_C=False):
+        A = self.generate_value(dtype, self.M, self.N, transpose_A, slice_A)
+        B = self.generate_value(dtype, self.N, self.K, transpose_B, slice_B)
+        C = self.generate_value(dtype, self.M, self.K, transpose_C, slice_C)
+        return (alpha, A, B, beta, C)
+
+    def get_value(self, V, to_transpose, to_slice):
+        if to_transpose:
+            V = V.T
+        if to_slice:
+            V = V[::self.slice_step]
+        return V
+
+    def compute_ref(self, alpha, A, B, beta, C,
+                    transpose_A, transpose_B, transpose_C,
+                    slice_A, slice_B, slice_C):
+        A = self.get_value(A, transpose_A, slice_A)
+        B = self.get_value(B, transpose_B, slice_B)
+        C = self.get_value(C, transpose_C, slice_C)
+        return alpha * np.dot(A, B) + beta * C
+
+    @theano.change_flags({'blas.ldflags': ''})
+    def run_gemm(self, dtype, ALPHA, BETA,
+                 transpose_A, transpose_B, transpose_C,
+                 slice_A, slice_B, slice_C):
+        f = self.get_function(dtype, transpose_A, transpose_B, transpose_C, slice_A, slice_B, slice_C)
+        values = self.get_data(dtype, ALPHA, BETA, transpose_A, transpose_B, transpose_C, slice_A, slice_B, slice_C)
+        assert any(isinstance(node.op, Gemm) for node in f.maker.fgraph.apply_nodes)
+        z_val = f(*values)
+        assert z_val.dtype == dtype
+        assert tuple(z_val.shape) == (self.M, self.K)
+        ref_val = self.compute_ref(*(values + (transpose_A, transpose_B, transpose_C, slice_A, slice_B, slice_C)))
+        unittest_tools.assert_allclose(ref_val, z_val)
+
+    def test_gemm(self):
+        dtypes = ('float32', 'float64')
+        scalars = (0, 1, -2)
+        booleans = (False, True)
+        # dtype, alpha, beta, transA, transB, transC, sliceA, sliceB, sliceC
+        iterables = [dtypes] + ([scalars] * 2) + ([booleans] * 6)
+        for dtype, alpha, beta, tA, tB, tC, sA, sB, sC in product(*iterables):
+            yield (self.run_gemm, dtype, alpha, beta, tA, tB, tC, sA, sB, sC)
+
+
 def test_res_is_a():
     X, Y, Z, a, b = XYZab()
 
diff --git a/theano/tensor/tests/test_blas_c.py b/theano/tensor/tests/test_blas_c.py
--- a/theano/tensor/tests/test_blas_c.py
+++ b/theano/tensor/tests/test_blas_c.py
@@ -344,7 +344,7 @@ def get_function(self, dtype, transpose_A=False, slice_tensors=False):
             A_2 = A_1
             x_2 = x
             y_2 = y
-        return theano.function([alpha, A, x, beta, y], self.gemv(y_2, alpha, A_2, x_2, beta))
+        return theano.function([alpha, A, x, beta, y], self.gemv(y_2, alpha, A_2, x_2, beta), mode=self.mode)
 
     def get_data(self, dtype, alpha, beta, transpose_A=False, slice_tensors=False):
         if slice_tensors: