Bug#855232: unblock: theano/0.8.2-6
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package theano [1].
The latest upload to unstable fixes three RC bugs:
#848764 (FTBFS), #831540 (FTBFS on i386), and #831541 (FTBFS on s390x).
And two important bugs: #835531 (randomly FTBFS), and #855102.
The problems have been solved by patches, please see the attached debdiff
for details.
Thank you,
Daniel Stender
[1] https://packages.qa.debian.org/t/theano.html
unblock theano/0.8.2-6
-- System Information:
Debian Release: stretch/sid
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 4.8.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=de_DE.utf8, LC_CTYPE=de_DE.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru theano-0.8.2/debian/changelog theano-0.8.2/debian/changelog
--- theano-0.8.2/debian/changelog 2016-07-16 18:42:07.000000000 +0200
+++ theano-0.8.2/debian/changelog 2017-02-15 09:09:46.000000000 +0100
@@ -1,3 +1,38 @@
+theano (0.8.2-6) unstable; urgency=medium
+
+ * Upload to unstable.
+
+ -- Daniel Stender <stender@debian.org> Wed, 15 Feb 2017 09:09:46 +0100
+
+theano (0.8.2-6~exp1) experimental; urgency=medium
+
+ * add disable-overly-environment-dependent-test.patch (Closes: #835531).
+ * add fix-invalid-casts-negative-stride-handling.patch
+ (Closes: #831541,#855102) [thanks again to Rebecca N. Palmer].
+
+ -- Daniel Stender <stender@debian.org> Wed, 15 Feb 2017 00:08:13 +0100
+
+theano (0.8.2-5) unstable; urgency=medium
+
+ * Upload to unstable.
+
+ -- Daniel Stender <stender@debian.org> Tue, 14 Feb 2017 09:47:30 +0100
+
+theano (0.8.2-5~exp1) experimental; urgency=medium
+
+ * add fix-test_fit_int64-for-python3-32bit.patch (Closes: #831540)
+ [thanks to Rebecca N. Palmer].
+ * deb/rules: remove test failsafes completely.
+
+ -- Daniel Stender <stender@debian.org> Mon, 13 Feb 2017 23:53:19 +0100
+
+theano (0.8.2-4) unstable; urgency=medium
+
+ * add fixes-for-numpy-1.12.patch (Closes: #848764) [thanks to
+ Rebecca N. Palmer].
+
+ -- Daniel Stender <stender@debian.org> Mon, 13 Feb 2017 15:04:06 +0100
+
theano (0.8.2-3) unstable; urgency=medium
* Upload to unstable.
diff -Nru theano-0.8.2/debian/patches/disable-overly-environment-dependent-test.patch theano-0.8.2/debian/patches/disable-overly-environment-dependent-test.patch
--- theano-0.8.2/debian/patches/disable-overly-environment-dependent-test.patch 1970-01-01 01:00:00.000000000 +0100
+++ theano-0.8.2/debian/patches/disable-overly-environment-dependent-test.patch 2017-02-14 23:55:31.000000000 +0100
@@ -0,0 +1,23 @@
+Description: Disable overly environment-dependent test
+ Testing speed by wall-clock time is inherently unreliable on a
+ shared machine such as Debian's buildds: don't let it fail the whole build.
+Author: Rebecca N. Palmer <rebecca_palmer@zoho.com>
+Bug-Debian: https://bugs.debian.org/835531
+Forwarded: not-needed
+
+diff --git a/theano/sparse/tests/test_basic.py b/theano/sparse/tests/test_basic.py
+index 8c183b9..03d79f1 100644
+--- a/theano/sparse/tests/test_basic.py
++++ b/theano/sparse/tests/test_basic.py
+@@ -1209,8 +1209,8 @@ class test_structureddot(unittest.TestCase):
+ overhead_tol = 0.002 # seconds
+ overhead_rtol = 1.1 # times as long
+ utt.assert_allclose(scipy_result, theano_result)
+- if (not theano.config.mode in ["DebugMode", "DEBUG_MODE"] and
+- theano.config.cxx):
++
++ if 0:#(not theano.config.mode in ["DebugMode", "DEBUG_MODE"] and theano.config.cxx):
+ self.assertFalse(
+ theano_time > overhead_rtol * scipy_time + overhead_tol,
+ (theano_time,
+
diff -Nru theano-0.8.2/debian/patches/fixes-for-numpy-1.12.patch theano-0.8.2/debian/patches/fixes-for-numpy-1.12.patch
--- theano-0.8.2/debian/patches/fixes-for-numpy-1.12.patch 1970-01-01 01:00:00.000000000 +0100
+++ theano-0.8.2/debian/patches/fixes-for-numpy-1.12.patch 2017-02-13 14:32:53.000000000 +0100
@@ -0,0 +1,80 @@
+Description: fix tests for Numpy 1.12
+ Collected fixes for passing Theano 0.8.2 tests with Numpy 1.12. Partly taken
+ from upstream repo, plus changes by Rebecca Palmer.
+Bug: https://github.com/Theano/Theano/issues/5396
+Bug-Debian: https://bugs.debian.org/848764
+Origin: https://github.com/Theano/Theano/commit/e8e01f4
+Author: Rebecca N. Palmer <rebecca_palmer@zoho.com>
+
+--- a/theano/sparse/tests/test_sp2.py
++++ b/theano/sparse/tests/test_sp2.py
+@@ -61,7 +61,7 @@
+
+
+ class BinomialTester(utt.InferShapeTester):
+- n = tensor.scalar()
++ n = tensor.scalar(dtype='int64')
+ p = tensor.scalar()
+ shape = tensor.lvector()
+ _n = 5
+--- a/theano/tensor/tests/test_elemwise.py
++++ b/theano/tensor/tests/test_elemwise.py
+@@ -414,7 +414,11 @@
+ zv = numpy.bitwise_or.reduce(zv, axis)
+ elif scalar_op == scalar.and_:
+ for axis in reversed(sorted(tosum)):
+- zv = numpy.bitwise_and.reduce(zv, axis)
++ if zv.shape[axis] == 0:
++ # Theano and old numpy use +1 as 'AND of no elements', new numpy uses -1
++ zv = numpy.abs(numpy.bitwise_and.reduce(zv, axis).astype('int8'))
++ else:
++ zv = numpy.bitwise_and.reduce(zv, axis)
+ elif scalar_op == scalar.xor:
+ # There is no identity value for the xor function
+ # So we can't support shape of dimensions 0.
+--- a/theano/tensor/tests/test_extra_ops.py
++++ b/theano/tensor/tests/test_extra_ops.py
+@@ -135,7 +135,7 @@
+ def test_bincountFn(self):
+ w = T.vector('w')
+ def ref(data, w=None, minlength=None):
+- size = data.max() + 1
++ size = int(data.max()) + 1
+ if minlength:
+ size = max(size, minlength)
+ if w is not None:
+--- a/theano/sparse/sandbox/sp2.py
++++ b/theano/sparse/sandbox/sp2.py
+@@ -4,6 +4,7 @@
+ import scipy.sparse
+
+ from theano import gof, tensor
++from theano.tensor import discrete_dtypes, float_dtypes
+ from theano.tensor.opt import register_specialize
+ from theano.sparse.basic import (
+ as_sparse_variable, SparseType, add_s_s, neg,
+@@ -115,6 +116,11 @@
+ n = tensor.as_tensor_variable(n)
+ p = tensor.as_tensor_variable(p)
+ shape = tensor.as_tensor_variable(shape)
++
++ assert n.dtype in discrete_dtypes
++ assert p.dtype in float_dtypes
++ assert shape.dtype in discrete_dtypes
++
+ return gof.Apply(self, [n, p, shape],
+ [SparseType(dtype=self.dtype,
+ format=self.format)()])
+--- a/theano/tensor/signal/tests/test_pool.py
++++ b/theano/tensor/signal/tests/test_pool.py
+@@ -34,8 +34,8 @@
+ if input.shape[-1] % ds[1]:
+ yi += 1
+ out_shp = list(input.shape[:-2])
+- out_shp.append(input.shape[-2] / ds[0] + xi)
+- out_shp.append(input.shape[-1] / ds[1] + yi)
++ out_shp.append(input.shape[-2] // ds[0] + xi)
++ out_shp.append(input.shape[-1] // ds[1] + yi)
+ output_val = numpy.zeros(out_shp)
+ func = numpy.max
+ if mode == 'sum':
diff -Nru theano-0.8.2/debian/patches/fix-invalid-casts-negative-stride-handling.patch theano-0.8.2/debian/patches/fix-invalid-casts-negative-stride-handling.patch
--- theano-0.8.2/debian/patches/fix-invalid-casts-negative-stride-handling.patch 1970-01-01 01:00:00.000000000 +0100
+++ theano-0.8.2/debian/patches/fix-invalid-casts-negative-stride-handling.patch 2017-02-15 00:03:28.000000000 +0100
@@ -0,0 +1,108 @@
+Description: Fix invalid casts and negative stride handling
+ Cast values, not pointers, from int64 to int32. Remember that
+ first-in-index order (numpy) and first-in-memory-order (BLAS) are
+ not always the same thing. Bump c_code_cache_version to make sure
+ existing installs use the fixes.
+Author: Rebecca N. Palmer <rebecca_palmer@zoho.com>
+Bug-Debian: https://bugs.debian.org/855102 https://bugs.debian.org/831541
+Forwarded: no
+
+diff --git a/theano/sparse/opt.py b/theano/sparse/opt.py
+index 6100405..d1c2b54 100644
+--- a/theano/sparse/opt.py
++++ b/theano/sparse/opt.py
+@@ -829,7 +829,11 @@ class UsmmCscDense(gof.Op):
+ npy_intp Sind = PyArray_STRIDES(%(x_ind)s)[0] / PyArray_DESCR(%(x_ind)s)->elsize;
+ npy_intp Sptr = PyArray_STRIDES(%(x_ptr)s)[0] / PyArray_DESCR(%(x_ptr)s)->elsize;
+ npy_intp Sy = PyArray_STRIDES(%(y)s)[1] / PyArray_DESCR(%(y)s)->elsize;
+-
++
++ // blas expects ints; convert here (rather than just making N etc ints) to avoid potential overflow in the negative-stride correction
++ int N32 = N;
++ int Sy32 = Sy;
++ int Szn32 = Szn;
+
+ if (!(%(inplace)s))
+ {
+@@ -859,7 +863,7 @@ class UsmmCscDense(gof.Op):
+ if (Szn < 0)
+ z_row += (N - 1) * Szn;
+
+- %(axpy)s((int*)&N, (%(conv_type)s*)&Amk, (%(conv_type)s*)y_row, (int*)&Sy, (%(conv_type)s*)z_row, (int*)&Szn);
++ %(axpy)s(&N32, (%(conv_type)s*)&Amk, (%(conv_type)s*)y_row, &Sy32, (%(conv_type)s*)z_row, &Szn32);
+ }
+ }
+ }
+@@ -868,7 +872,7 @@ class UsmmCscDense(gof.Op):
+ return rval
+
+ def c_code_cache_version(self):
+- return (1, blas.blas_header_version())
++ return (1, blas.blas_header_version(), 0xdeb1a)
+ usmm_csc_dense = UsmmCscDense(inplace=False)
+ usmm_csc_dense_inplace = UsmmCscDense(inplace=True)
+
+@@ -1748,7 +1752,7 @@ class SamplingDotCSR(gof.Op):
+ ])
+
+ def c_code_cache_version(self):
+- return (2, blas.blas_header_version())
++ return (2, blas.blas_header_version(), 0xdeb1a)
+
+ def c_support_code(self):
+ return blas.blas_header_text()
+@@ -1891,6 +1895,11 @@ PyErr_SetString(PyExc_NotImplementedError, "rank(y) != 2"); %(fail)s;}
+ memcpy(Dzi, Dpi, PyArray_DIMS(%(p_ind)s)[0]*sizeof(dtype_%(p_ind)s));
+ memcpy(Dzp, Dpp, PyArray_DIMS(%(p_ptr)s)[0]*sizeof(dtype_%(p_ptr)s));
+
++ // blas expects ints; convert here (rather than just making K etc ints) to avoid potential overflow in the negative-stride correction
++ int K32 = K;
++ int Sdx32 = Sdx;
++ int Sdy32 = Sdy;
++
+ for (npy_int32 m = 0; m < M; ++m) {
+ for (npy_int32 n_idx = Dpp[m * Sdpp]; n_idx < Dpp[(m+1)*Sdpp]; ++n_idx) {
+ const npy_int32 n = Dpi[n_idx * Sdpi]; // row index of non-null value for column K
+@@ -1898,8 +1907,15 @@ PyErr_SetString(PyExc_NotImplementedError, "rank(y) != 2"); %(fail)s;}
+ const dtype_%(x)s* x_row = (dtype_%(x)s*)(PyArray_BYTES(%(x)s) + PyArray_STRIDES(%(x)s)[0] * m);
+
+ const dtype_%(y)s* y_col = (dtype_%(y)s*)(PyArray_BYTES(%(y)s) + PyArray_STRIDES(%(y)s)[0] * n);
++ // dot expects pointer to the beginning of memory arrays,
++ // so when the stride is negative, we need to get the
++ // last element
++ if (Sdx < 0)
++ x_row += (K - 1) * Sdx;
++ if (Sdy < 0)
++ y_col += (K - 1) * Sdy;
+
+- Dzd[n_idx * Sdzd] = Dpd[n_idx * Sdpd] * %(cdot)s((int*)&K, (const %(conv_type)s*)x_row, (int*)&Sdx, (const %(conv_type)s*)y_col, (int*)&Sdy);
++ Dzd[n_idx * Sdzd] = Dpd[n_idx * Sdpd] * %(cdot)s(&K32, (const %(conv_type)s*)x_row, &Sdx32, (const %(conv_type)s*)y_col, &Sdy32);
+ }
+ }
+ }
+diff --git a/theano/sparse/tests/test_basic.py b/theano/sparse/tests/test_basic.py
+index 8c183b9..03d79f1 100644
+--- a/theano/sparse/tests/test_basic.py
++++ b/theano/sparse/tests/test_basic.py
+@@ -3085,6 +3085,20 @@ class SamplingDotTester(utt.InferShapeTester):
+ assert tested.format == 'csr'
+ assert tested.dtype == expected.dtype
+
++ def test_negative_stride(self):
++ f = theano.function(
++ self.x,
++ sampling_dot(*self.x))
++
++ a2 = [self.a[0][::-1,:], self.a[1][:,::-1], self.a[2]]
++ tested = f(*a2)
++ x, y, p = a2
++ expected = p.multiply(numpy.dot(x, y.T))
++
++ utt.assert_allclose(as_ndarray(expected), tested.toarray())
++ assert tested.format == 'csr'
++ assert tested.dtype == expected.dtype
++
+ def test_infer_shape(self):
+ self._compile_and_check(self.x,
+ [sampling_dot(*self.x)],
+
diff -Nru theano-0.8.2/debian/patches/fix-test_fit_int64-for-python3-32bit.patch theano-0.8.2/debian/patches/fix-test_fit_int64-for-python3-32bit.patch
--- theano-0.8.2/debian/patches/fix-test_fit_int64-for-python3-32bit.patch 1970-01-01 01:00:00.000000000 +0100
+++ theano-0.8.2/debian/patches/fix-test_fit_int64-for-python3-32bit.patch 2017-02-13 23:50:03.000000000 +0100
@@ -0,0 +1,21 @@
+Description: fix for the tests passing on python3 on i386
+Bug-Debian: https://bugs.debian.org/831540
+Forwarded: https://github.com/Theano/Theano/issues/5498
+Author: Rebecca N. Palmer <rebecca_palmer@zoho.com>
+
+--- a/theano/tensor/tests/test_basic.py
++++ b/theano/tensor/tests/test_basic.py
+@@ -6672,11 +6672,11 @@
+ assert scalar_ct.value == val
+
+ vector_ct = constant([val, val])
+- assert vector_ct.dtype == 'int64'
++ assert vector_ct.dtype in ('int32','int64')
+ assert numpy.all(vector_ct.value == val)
+
+ matrix_ct = constant([[val, val]])
+- assert matrix_ct.dtype == 'int64'
++ assert matrix_ct.dtype in ('int32','int64')
+ assert numpy.all(matrix_ct.value == val)
+
+ def test_too_big(self):
diff -Nru theano-0.8.2/debian/patches/series theano-0.8.2/debian/patches/series
--- theano-0.8.2/debian/patches/series 2016-02-25 19:33:41.000000000 +0100
+++ theano-0.8.2/debian/patches/series 2017-02-15 00:01:55.000000000 +0100
@@ -1 +1,5 @@
+fix-invalid-casts-negative-stride-handling.patch
+disable-overly-environment-dependent-test.patch
+fixes-for-numpy-1.12.patch
strip-docs.patch
+fix-test_fit_int64-for-python3-32bit.patch
diff -Nru theano-0.8.2/debian/rules theano-0.8.2/debian/rules
--- theano-0.8.2/debian/rules 2016-07-16 18:42:07.000000000 +0200
+++ theano-0.8.2/debian/rules 2017-02-13 23:53:16.000000000 +0100
@@ -17,11 +17,7 @@
export THEANO_FLAGS=base_compiledir='.pybuild',device=cpu
override_dh_auto_test:
-ifneq (,$(filter i386 s390x,$(DEB_BUILD_ARCH)))
- PYBUILD_SYSTEM=custom PYBUILD_TEST_ARGS='PYTHONPATH=. {interpreter} bin/theano-nose -v' dh_auto_test || true
-else
PYBUILD_SYSTEM=custom PYBUILD_TEST_ARGS='PYTHONPATH=. {interpreter} bin/theano-nose -v' dh_auto_test
-endif
override_dh_installdocs:
dh_installdocs -A README.txt
Reply to: