Repository: chainer/chainer

Issue:
Support `broadcast_to`
http://docs.scipy.org/doc/numpy/reference/generated/numpy.broadcast_to.html
I now make a dummy variable...



Discussion:

Resolving patch:
diff --git a/cupy/__init__.py b/cupy/__init__.py
--- a/cupy/__init__.py
+++ b/cupy/__init__.py
@@ -116,6 +116,7 @@
 atleast_3d = manipulation.dims.atleast_3d
 broadcast = manipulation.dims.broadcast
 broadcast_arrays = manipulation.dims.broadcast_arrays
+broadcast_to = manipulation.dims.broadcast_to
 expand_dims = manipulation.dims.expand_dims
 squeeze = manipulation.dims.squeeze
 
diff --git a/cupy/manipulation/dims.py b/cupy/manipulation/dims.py
--- a/cupy/manipulation/dims.py
+++ b/cupy/manipulation/dims.py
@@ -122,6 +122,39 @@ def broadcast_arrays(*args):
     return broadcast(*args).values
 
 
+def broadcast_to(array, shape):
+    """Broadcast an array to a given shape.
+
+    Args:
+        array (cupy.ndarray): Array to broadcast.
+        shape (tuple of int): The shape of the desired array.
+
+    Returns:
+        cupy.ndarray: Broadcasted view.
+
+    .. seealso:: :func:`numpy.broadcast_to`
+
+    """
+    if array.ndim > len(shape):
+        raise ValueError(
+            'input operand has more dimensions than allowed by the axis '
+            'remapping')
+
+    strides = [0] * len(shape)
+    for i in range(array.ndim):
+        j = -i - 1
+        sh = shape[j]
+        a_sh = array.shape[j]
+        if sh == a_sh:
+            strides[j] = array._strides[j]
+        elif a_sh != 1:
+            raise ValueError('Broadcasting failed')
+
+    view = array.view()
+    view._set_shape_and_strides(shape, strides)
+    return view
+
+
 def expand_dims(a, axis):
     """Expands given arrays.
 


Test patch:
diff --git a/tests/cupy_tests/manipulation_tests/test_dims.py b/tests/cupy_tests/manipulation_tests/test_dims.py
--- a/tests/cupy_tests/manipulation_tests/test_dims.py
+++ b/tests/cupy_tests/manipulation_tests/test_dims.py
@@ -65,6 +65,57 @@ def test_broadcast_fail(self, xp):
         b = xp.zeros((3, 2))
         xp.broadcast(a, b)
 
+    @testing.with_requires('numpy>=1.10')
+    @testing.for_all_dtypes()
+    @testing.numpy_cupy_array_equal(accept_error=False)
+    def test_broadcast_to(self, xp, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((3, 1, 4), xp, dtype)
+        b = xp.broadcast_to(a, (2, 3, 3, 4))
+        return b
+
+    @testing.with_requires('numpy>=1.10')
+    @testing.for_all_dtypes()
+    @testing.numpy_cupy_raises()
+    def test_broadcast_to_fail(self, xp, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((3, 1, 4), xp, dtype)
+        xp.broadcast_to(a, (1, 3, 4))
+
+    @testing.with_requires('numpy>=1.10')
+    @testing.for_all_dtypes()
+    @testing.numpy_cupy_raises()
+    def test_broadcast_to_short_shape(self, xp, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((1, 3, 4), xp, dtype)
+        xp.broadcast_to(a, (3, 4))
+
+    @testing.for_all_dtypes()
+    @testing.numpy_cupy_array_equal(accept_error=False)
+    def test_broadcast_to_numpy19(self, xp, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((3, 1, 4), xp, dtype)
+        if xp is cupy:
+            b = xp.broadcast_to(a, (2, 3, 3, 4))
+        else:
+            dummy = xp.empty((2, 3, 3, 4))
+            b, _ = xp.broadcast_arrays(a, dummy)
+        return b
+
+    @testing.for_all_dtypes()
+    def test_broadcast_to_fail_numpy19(self, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((3, 1, 4), cupy, dtype)
+        with self.assertRaises(ValueError):
+            cupy.broadcast_to(a, (1, 3, 4))
+
+    @testing.for_all_dtypes()
+    def test_broadcast_to_short_shape_numpy19(self, dtype):
+        # Note that broadcast_to is only supported on numpy>=1.10
+        a = testing.shaped_arange((1, 3, 4), cupy, dtype)
+        with self.assertRaises(ValueError):
+            cupy.broadcast_to(a, (3, 4))
+
     @testing.numpy_cupy_array_equal()
     def test_expand_dims0(self, xp):
         a = testing.shaped_arange((2, 3), xp)