Repository: chainer/chainer

Issue:
`concat` with the last axis fails on py3
Same problem in `concat` as #253 

@ShigekiKarita reported this problem too. Thanks!
https://gist.github.com/ShigekiKarita/4293f886765a1ed4a144



Discussion:

Resolving patch:
diff --git a/chainer/functions/concat.py b/chainer/functions/concat.py
--- a/chainer/functions/concat.py
+++ b/chainer/functions/concat.py
@@ -68,7 +68,7 @@ def forward_gpu(self, xs):
 
         y = cuda.empty(shape, dtype=xs[0].dtype)
         self.cdimy = y.shape[self.axis]
-        self.rdim = numpy.prod(shape[self.axis + 1:])
+        self.rdim = numpy.prod(shape[self.axis + 1:], dtype=int)
 
         coffset = 0
         kernel = cuda.elementwise(


Test patch:
diff --git a/tests/functions_tests/test_concat.py b/tests/functions_tests/test_concat.py
--- a/tests/functions_tests/test_concat.py
+++ b/tests/functions_tests/test_concat.py
@@ -14,37 +14,21 @@
     cuda.init()
 
 
-class Concat(unittest.TestCase):
-
-    def setUp(self):
-        self.y0 = numpy.arange(42, dtype=numpy.float32).reshape(2, 7, 3)
-        self.xs0 = [self.y0[:, :2], self.y0[:, 2:5], self.y0[:, 5:]]
-
-        self.y1 = numpy.arange(21, dtype=numpy.float32).reshape(7, 3)
-        self.xs1 = [self.y1[:2], self.y1[2:5], self.y1[5:]]
+class ConcatTestBase(object):
 
     def check_forward(self, xs_data, y_data, axis):
         xs = tuple(chainer.Variable(x_data) for x_data in xs_data)
         y = functions.concat(xs, axis=axis)
         gradient_check.assert_allclose(y_data, y.data, atol=0, rtol=0)
 
-    def test_forward_cpu_0(self):
-        self.check_forward(self.xs0, self.y0, axis=1)
-
-    def test_forward_cpu_1(self):
-        self.check_forward(self.xs1, self.y1, axis=0)
-
-    @attr.gpu
-    def test_forward_gpu_0(self):
-        self.check_forward(
-            [cuda.to_gpu(x.copy()) for x in self.xs0],
-            cuda.to_gpu(self.y0), axis=1)
+    def test_forward_cpu(self):
+        self.check_forward(self.xs, self.y, axis=self.axis)
 
     @attr.gpu
-    def test_forward_gpu_1(self):
+    def test_forward_gpu(self):
         self.check_forward(
-            [cuda.to_gpu(x.copy()) for x in self.xs1],
-            cuda.to_gpu(self.y1), axis=0)
+            [cuda.to_gpu(x.copy()) for x in self.xs],
+            cuda.to_gpu(self.y), axis=self.axis)
 
     def check_backward(self, xs_data, axis):
         xs = tuple(chainer.Variable(x_data) for x_data in xs_data)
@@ -55,19 +39,37 @@ def check_backward(self, xs_data, axis):
         for x in xs:
             gradient_check.assert_allclose(x.data, x.grad, atol=0, rtol=0)
 
-    def test_backward_cpu_0(self):
-        self.check_backward(self.xs0, axis=1)
-
-    def test_backward_cpu_1(self):
-        self.check_backward(self.xs1, axis=0)
+    def test_backward_cpu(self):
+        self.check_backward(self.xs, axis=self.axis)
 
     @attr.gpu
-    def test_backward_gpu_0(self):
-        self.check_backward([cuda.to_gpu(x.copy()) for x in self.xs0], axis=1)
+    def test_backward_gpu(self):
+        self.check_backward([cuda.to_gpu(x.copy()) for x in self.xs],
+                            axis=self.axis)
 
-    @attr.gpu
-    def test_backward_gpu_1(self):
-        self.check_backward([cuda.to_gpu(x.copy()) for x in self.xs1], axis=0)
+
+class TestConcat1(unittest.TestCase, ConcatTestBase):
+
+    def setUp(self):
+        self.y = numpy.arange(42, dtype=numpy.float32).reshape(2, 7, 3)
+        self.xs = [self.y[:, :2], self.y[:, 2:5], self.y[:, 5:]]
+        self.axis = 1
+
+
+class TestConcat2(unittest.TestCase, ConcatTestBase):
+
+    def setUp(self):
+        self.y = numpy.arange(21, dtype=numpy.float32).reshape(7, 3)
+        self.xs = [self.y[:2], self.y[2:5], self.y[5:]]
+        self.axis = 0
+
+
+class TestConcatLastAxis(unittest.TestCase, ConcatTestBase):
+
+    def setUp(self):
+        self.y = numpy.arange(2, dtype=numpy.float32)
+        self.xs = [self.y[:1], self.y[1:]]
+        self.axis = 0
 
 
 testing.run_module(__name__, __file__)