internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: chainer/chainer

Issue:
Show output of nvcc after stacktrace
In the current implementation, `nvcc` prints error messages in stdout/stderr before stack trace is printed. It is hard to read.



Discussion:

Resolving patch:
diff --git a/cupy/cuda/compiler.py b/cupy/cuda/compiler.py
--- a/cupy/cuda/compiler.py
+++ b/cupy/cuda/compiler.py
@@ -34,7 +34,14 @@ def __exit__(self, exc_type, exc_value, traceback):
 
 def _run_nvcc(cmd, cwd):
     try:
-        return subprocess.check_output(cmd, cwd=cwd)
+        return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
+    except subprocess.CalledProcessError as e:
+        msg = ('`nvcc` command returns non-zero exit status. \n'
+               'command: {0}\n'
+               'return-code: {1}\n'
+               'stdout/stderr: \n'
+               '{2}'.format(e.cmd, e.returncode, e.output))
+        raise RuntimeError(msg)
     except OSError as e:
         msg = 'Failed to run `nvcc` command. ' \
               'Check PATH environment variable: ' \


Test patch:
diff --git a/tests/cupy_tests/cuda_tests/test_compiler.py b/tests/cupy_tests/cuda_tests/test_compiler.py
--- a/tests/cupy_tests/cuda_tests/test_compiler.py
+++ b/tests/cupy_tests/cuda_tests/test_compiler.py
@@ -21,3 +21,11 @@ def test_preprocess_without_command(self):
         # Check that error message includes command name `nvcc`
         with self.assertRaisesRegexp(OSError, 'nvcc'):
             compiler.preprocess('')
+
+
+class TestNvccStderr(unittest.TestCase):
+
+    def test(self):
+        # An error message contains the file name `kern.cu`
+        with self.assertRaisesRegexp(RuntimeError, 'kern.cu'):
+            compiler.nvcc('a')
Repository: chainer/chainer

Issue:
Cannot build Chainer with numpy 1.11b3
I cannot install chainer with numpy 1.11b3. It is because `numpy.core` doesn't exist in this version.
We need to restrict version of numpy.



Discussion:

Resolving patch:
diff --git a/chainer_setup_build.py b/chainer_setup_build.py
--- a/chainer_setup_build.py
+++ b/chainer_setup_build.py
@@ -263,6 +263,19 @@ def build_and_run(compiler, source, libraries=[],
         shutil.rmtree(temp_dir, ignore_errors=True)
 
 
+def get_numpy_include_path():
+    import six
+    if hasattr(six.moves.builtins, '__NUMPY_SETUP__'):
+        del six.moves.builtins.__NUMPY_SETUP__
+    import numpy
+    six.moves.reload_module(numpy)
+    try:
+        numpy_include = numpy.get_include()
+    except AttributeError:
+        numpy_include = numpy.get_numpy_include()
+    return numpy_include
+
+
 def make_extensions(options, compiler):
 
     """Produce a list of Extension instances which passed to cythonize()."""
@@ -270,16 +283,8 @@ def make_extensions(options, compiler):
     no_cuda = options['no_cuda']
     settings = get_compiler_setting()
 
-    try:
-        import numpy
-        numpy_include = numpy.get_include()
-    except AttributeError:
-        # if numpy is not installed get the headers from the .egg directory
-        import numpy.core
-        numpy_include = path.join(
-            path.dirname(numpy.core.__file__), 'include')
     include_dirs = settings['include_dirs']
-    include_dirs.append(numpy_include)
+    include_dirs.append(get_numpy_include_path())
 
     settings['include_dirs'] = [
         x for x in include_dirs if path.exists(x)]
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -6,16 +6,19 @@
 
 import chainer_setup_build
 
-
+numpy_version = 'numpy>=1.9.0'
+six_version = 'six>=1.9.0'
 setup_requires = [
-    'numpy>=1.9.0',
+    numpy_version,
+    six_version,
 ]
 install_requires = [
     'filelock',
     'nose',
-    'numpy>=1.9.0',
+    numpy_version,
     'protobuf',
-    'six>=1.9.0']
+    six_version,
+]
 
 
 # Hack for Read the Docs


Test patch:
Repository: chainer/chainer

Issue:
Show detail of error log
When gcc fails to build a stub code, the setup script doesn't show its detail. We need to show details of the error.
https://github.com/pfnet/chainer/blob/master/chainer_setup_build.py#L232

Note that stdout/stderr of gcc is shown in stdout. Its error code is not.



Discussion:

Resolving patch:
diff --git a/chainer_setup_build.py b/chainer_setup_build.py
--- a/chainer_setup_build.py
+++ b/chainer_setup_build.py
@@ -28,17 +28,18 @@ def print_warning(*lines):
 
 
 def check_cuda_version(compiler, settings):
-    out = build_and_run(compiler, '''
-    #include <cuda.h>
-    #include <stdio.h>
-    int main(int argc, char* argv[]) {
-      printf("%d", CUDA_VERSION);
-      return 0;
-    }
-    ''', include_dirs=settings['include_dirs'])
+    try:
+        out = build_and_run(compiler, '''
+        #include <cuda.h>
+        #include <stdio.h>
+        int main(int argc, char* argv[]) {
+          printf("%d", CUDA_VERSION);
+          return 0;
+        }
+        ''', include_dirs=settings['include_dirs'])
 
-    if out is None:
-        print_warning('Cannot check CUDA version')
+    except Exception as e:
+        print_warning('Cannot check CUDA version', str(e))
         return False
 
     cuda_version = int(out)
@@ -53,17 +54,18 @@ def check_cuda_version(compiler, settings):
 
 
 def check_cudnn_version(compiler, settings):
-    out = build_and_run(compiler, '''
-    #include <cudnn.h>
-    #include <stdio.h>
-    int main(int argc, char* argv[]) {
-      printf("%d", CUDNN_VERSION);
-      return 0;
-    }
-    ''', include_dirs=settings['include_dirs'])
+    try:
+        out = build_and_run(compiler, '''
+        #include <cudnn.h>
+        #include <stdio.h>
+        int main(int argc, char* argv[]) {
+          printf("%d", CUDNN_VERSION);
+          return 0;
+        }
+        ''', include_dirs=settings['include_dirs'])
 
-    if out is None:
-        print_warning('Cannot check cuDNN version')
+    except Exception as e:
+        print_warning('Cannot check cuDNN version\n{0}'.format(e))
         return False
 
     cudnn_version = int(out)
@@ -251,15 +253,17 @@ def build_and_run(compiler, source, libraries=(),
                                      libraries=libraries,
                                      library_dirs=library_dirs,
                                      extra_postargs=postargs)
-        except (distutils.errors.LinkError, TypeError):
-            return None
+        except Exception as e:
+            msg = 'Cannot build a stub file.\nOriginal error: {0}'.format(e)
+            raise Exception(msg)
 
         try:
             out = subprocess.check_output(os.path.join(temp_dir, 'a'))
             return out
 
-        except Exception:
-            return None
+        except Exception as e:
+            msg = 'Cannot execute a stub file.\nOriginal error: {0}'.format(e)
+            raise Exception(msg)
 
     finally:
         shutil.rmtree(temp_dir, ignore_errors=True)


Test patch:
Repository: chainer/chainer

Issue:
Support profiler API
CUDA has profiler API to switch the profiler. I need this API on CuPy to measure performance of part of my code.
http://docs.nvidia.com/cuda/profiler-users-guide/#abstract



Discussion:

Resolving patch:
diff --git a/chainer_setup_build.py b/chainer_setup_build.py
--- a/chainer_setup_build.py
+++ b/chainer_setup_build.py
@@ -30,6 +30,7 @@
             'cupy.cuda.device',
             'cupy.cuda.driver',
             'cupy.cuda.memory',
+            'cupy.cuda.profiler',
             'cupy.cuda.function',
             'cupy.cuda.runtime',
             'cupy.util',
@@ -37,6 +38,7 @@
         'include': [
             'cublas_v2.h',
             'cuda.h',
+            'cuda_profiler_api.h',
             'cuda_runtime.h',
             'curand.h',
         ],
diff --git a/cupy/cuda/__init__.py b/cupy/cuda/__init__.py
--- a/cupy/cuda/__init__.py
+++ b/cupy/cuda/__init__.py
@@ -1,7 +1,10 @@
+import contextlib
+
 from cupy.cuda import compiler
 from cupy.cuda import device
 from cupy.cuda import function
 from cupy.cuda import memory
+from cupy.cuda import profiler
 from cupy.cuda import stream
 
 compile_with_cache = compiler.compile_with_cache
@@ -22,3 +25,21 @@
 Event = stream.Event
 Stream = stream.Stream
 get_elapsed_time = stream.get_elapsed_time
+
+
+@contextlib.contextmanager
+def profile():
+    """Enable CUDA profiling during with statement.
+
+    This function enable profiling on entering with statement, and disable
+    profiling on leaving the statement.
+
+    >>> with cupy.cuda.profile():
+    ...    # do something you want to measure
+
+    """
+    profiler.start()
+    try:
+        yield
+    finally:
+        profiler.stop()


Test patch:
diff --git a/tests/cupy_tests/cuda_tests/test_profile.py b/tests/cupy_tests/cuda_tests/test_profile.py
new file mode 100644
--- /dev/null
+++ b/tests/cupy_tests/cuda_tests/test_profile.py
@@ -0,0 +1,30 @@
+import unittest
+
+import mock
+
+from cupy import cuda
+
+
+class TestProfile(unittest.TestCase):
+
+    def test_profile(self):
+        start_patch = mock.patch('cupy.cuda.profiler.start')
+        stop_patch = mock.patch('cupy.cuda.profiler.stop')
+        with start_patch as start, stop_patch as stop:
+            with cuda.profile():
+                pass
+            start.assert_called_once_with()
+            stop.assert_called_once_with()
+
+    def test_err_case(self):
+        start_patch = mock.patch('cupy.cuda.profiler.start')
+        stop_patch = mock.patch('cupy.cuda.profiler.stop')
+        with start_patch as start, stop_patch as stop:
+            try:
+                with cuda.profile():
+                    raise Exception()
+            except Exception:
+                # ignore
+                pass
+            start.assert_called_once_with()
+            stop.assert_called_once_with()
Repository: chainer/chainer

Issue:
ChainList failed to copy its children.
```
#!/usr/bin/env python

from chainer import Chain, ChainList
import chainer.links as L

model0 = ChainList(L.Linear(10, 10))
model1 = model0.copy()
model0.to_gpu(0)
model1.to_gpu(1)
print(model1[0].W.data.device) # => <CUDA Device 0>                                                                                                                                                                

model0 = Chain(c=L.Linear(10, 10))
model1 = model0.copy()
model0.to_gpu(0)
model1.to_gpu(1)
print(model1.c.W.data.device) # => <CUDA Device 1>                                                                                                                                                                 

model0 = L.Linear(10, 10)
model1 = model0.copy()
model0.to_gpu(0)
model1.to_gpu(1)
print(model1.W.data.device) # => <CUDA Device 1>  
```

This issue is reported by @snuke. Thank you!



Discussion:

Resolving patch:
diff --git a/chainer/link.py b/chainer/link.py
--- a/chainer/link.py
+++ b/chainer/link.py
@@ -615,6 +615,7 @@ def add_link(self, link):
 
     def copy(self):
         ret = super(ChainList, self).copy()
+        ret._children = list(ret._children)  # copy
         children = ret._children
         for i, child in enumerate(children):
             child = child.copy()


Test patch:
diff --git a/tests/chainer_tests/test_link.py b/tests/chainer_tests/test_link.py
--- a/tests/chainer_tests/test_link.py
+++ b/tests/chainer_tests/test_link.py
@@ -463,6 +463,34 @@ def test_copy(self):
         self.assertIs(c2[1].x.data, self.l3.x.data)
         self.assertIs(c2[1].x.grad, None)
 
+    @attr.gpu
+    def test_copy_and_send_to_gpu(self):
+        c2 = self.c2.copy()
+        self.c2.to_gpu()
+        self.assertIsInstance(self.c2[0][0].x.data, cuda.cupy.ndarray)
+        self.assertIsInstance(self.c2[0][1].x.data, cuda.cupy.ndarray)
+        self.assertIsInstance(c2[0][0].x.data, numpy.ndarray)
+        self.assertIsInstance(c2[0][1].x.data, numpy.ndarray)
+
+    @attr.gpu
+    def test_copy_and_send_to_gpu_2(self):
+        c2 = self.c2.copy()
+        c2.to_gpu()
+        self.assertIsInstance(self.c2[0][0].x.data, numpy.ndarray)
+        self.assertIsInstance(self.c2[0][1].x.data, numpy.ndarray)
+        self.assertIsInstance(c2[0][0].x.data, cuda.cupy.ndarray)
+        self.assertIsInstance(c2[0][1].x.data, cuda.cupy.ndarray)
+
+    @attr.multi_gpu(2)
+    def test_copy_and_send_to_gpu_multi(self):
+        c2 = self.c2.copy()
+        self.c2.to_gpu(0)
+        c2.to_gpu(1)
+        self.assertEqual(self.c2[0][0].x.data.device.id, 0)
+        self.assertEqual(self.c2[0][1].x.data.device.id, 0)
+        self.assertEqual(c2[0][0].x.data.device.id, 1)
+        self.assertEqual(c2[0][1].x.data.device.id, 1)
+
     def test_to_cpu_on_cpu(self):
         x1 = self.l1.x.data
         gx1 = self.l1.x.grad
Repository: chainer/chainer

Issue:
function_hook is missing in the package
As function_hook is missing in `setup.py`, it is not installed when we install chainer through `pip`.



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -45,6 +45,7 @@
               'chainer.functions.noise',
               'chainer.functions.normalization',
               'chainer.functions.pooling',
+              'chainer.function_hooks',
               'chainer.links',
               'chainer.links.activation',
               'chainer.links.caffe',


Test patch:
Repository: chainer/chainer

Issue:
BatchNormalization does not switch the current GPU automatically
As reported in the forum, the current implementation of BatchNormalization link does not switch the current GPU appropriately during computing the running statistics of batches.
It causes confusing error message like `ValueError: Array device must be same as the current device: array device = 1 while current = 0`.
See for example: https://groups.google.com/forum/#!topic/chainer/T-6s3KD-X-U



Discussion:

Resolving patch:
diff --git a/chainer/links/normalization/batch_normalization.py b/chainer/links/normalization/batch_normalization.py
--- a/chainer/links/normalization/batch_normalization.py
+++ b/chainer/links/normalization/batch_normalization.py
@@ -1,5 +1,6 @@
 import numpy
 
+from chainer import cuda
 from chainer.functions.normalization import batch_normalization
 from chainer import link
 from chainer import variable
@@ -98,16 +99,17 @@ def __call__(self, x, test=False, finetune=False):
             else:
                 decay = self.decay
 
-            m = x.data.size // self.gamma.data.size
-            adjust = m / max(m - 1., 1.)  # unbiased estimation
-            self.avg_mean *= decay
-            func.mean *= 1 - decay  # reuse buffer as a temporary
-            self.avg_mean += func.mean
-            del func.mean
-            self.avg_var *= decay
-            func.var *= (1 - decay) * adjust  # reuse buffer as a temporary
-            self.avg_var += func.var
-            del func.var
+            with cuda.get_device(x.data):
+                m = x.data.size // self.gamma.data.size
+                adjust = m / max(m - 1., 1.)  # unbiased estimation
+                self.avg_mean *= decay
+                func.mean *= 1 - decay  # reuse buffer as a temporary
+                self.avg_mean += func.mean
+                del func.mean
+                self.avg_var *= decay
+                func.var *= (1 - decay) * adjust  # reuse buffer as a temporary
+                self.avg_var += func.var
+                del func.var
         else:
             mean = variable.Variable(self.avg_mean, volatile='auto')
             var = variable.Variable(self.avg_var, volatile='auto')


Test patch:
diff --git a/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py b/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
--- a/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
+++ b/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
@@ -77,6 +77,14 @@ def test_forward_gpu(self):
         self.link.to_gpu()
         self.check_forward(cuda.to_gpu(self.x))
 
+    @attr.multi_gpu(2)
+    def test_forward_multi_gpu(self):
+        with cuda.get_device(1):
+            self.link.to_gpu()
+            x = cuda.to_gpu(self.x)
+        with cuda.get_device(0):
+            self.check_forward(x)
+
     def check_backward(self, x_data, y_grad):
         gradient_check.check_backward(
             self.link, x_data, y_grad, (self.link.gamma, self.link.beta),
Repository: chainer/chainer

Issue:
Warning on python 3.5.0
Chainer doesn't work on python 3.5.0. We need to check python version and show warning when a user uses python 3.5.0.



Discussion:

Resolving patch:
diff --git a/chainer/__init__.py b/chainer/__init__.py
--- a/chainer/__init__.py
+++ b/chainer/__init__.py
@@ -1,6 +1,8 @@
 import collections
 import pkg_resources
+import sys
 import threading
+import warnings
 
 from chainer import flag
 from chainer import function
@@ -12,6 +14,10 @@
 from chainer import variable
 
 
+if sys.version_info[:3] == (3, 5, 0):
+    warnings.warn('Python 3.5.0 is not recommended. Use newer version.')
+
+
 __version__ = pkg_resources.get_distribution('chainer').version
 
 AbstractSerializer = serializer.AbstractSerializer


Test patch:
Repository: chainer/chainer

Issue:
Change a method reporting an error when CuPy is not correctly installed
Currently CuPy raises `importError` with this error message:
`ImportError: cannot import name core`

This is because `core` module is a native module (i mean .so file), and the setup script cannot build it when CUDA environment is not correctly setup. This error doesn't represent its situation. We need to change its message.



Discussion:

Resolving patch:
diff --git a/cupy/__init__.py b/cupy/__init__.py
--- a/cupy/__init__.py
+++ b/cupy/__init__.py
@@ -4,9 +4,19 @@
 import numpy
 import six
 
+try:
+    from cupy import core
+except ImportError:
+    # core is a c-extention module.
+    # When a user cannot import core, it represents that CuPy is not correctly
+    # built.
+    msg = ('CuPy is not correctly installed. Please check your environment, '
+           'uninstall Chainer and reinstall it with `pip install chainer '
+           '--no-cache-dir -vvvv`.')
+    raise six.reraise(RuntimeError, msg, sys.exc_info()[2])
+
 
 from cupy import binary
-from cupy import core
 from cupy import creation
 from cupy import indexing
 from cupy import io


Test patch:
diff --git a/tests/cupy_tests/test_init.py b/tests/cupy_tests/test_init.py
new file mode 100644
--- /dev/null
+++ b/tests/cupy_tests/test_init.py
@@ -0,0 +1,15 @@
+import unittest
+
+from chainer import testing
+
+
+class TestImportError(unittest.TestCase):
+
+    def test_import_error(self):
+        try:
+            import cupy  # noqa
+        except Exception as e:
+            self.assertIsInstance(e, RuntimeError)
+
+
+testing.run_module(__name__, __file__)
Repository: chainer/chainer

Issue:
HuberLoss's backward() should not ignore gy
`HuberLoss`'s `backward()` ignores `gy`, so any computation after `HuberLoss` has no effect for gradients backpropagated by `HuberLoss`. I think such a behavior is not correct.

``` python
>>> x = chainer.Variable(np.zeros((1,1), dtype=np.float32))
>>> t = chainer.Variable(np.ones((1,1), dtype=np.float32))
>>> F.huber_loss(x, t, 1.0).backward()
>>> x.grad
array([[-1.]], dtype=float32)
```

``` python
>>> x = chainer.Variable(np.zeros((1,1), dtype=np.float32))
>>> t = chainer.Variable(np.ones((1,1), dtype=np.float32))
>>> (F.huber_loss(x, t, 1.0) * 0).backward()  # Multiply the loss by zero
>>> x.grad
array([[-1.]], dtype=float32)
```



Discussion:

Resolving patch:
diff --git a/chainer/functions/loss/huber_loss.py b/chainer/functions/loss/huber_loss.py
--- a/chainer/functions/loss/huber_loss.py
+++ b/chainer/functions/loss/huber_loss.py
@@ -31,7 +31,8 @@ def forward(self, inputs):
     def backward(self, inputs, gy):
         xp = cuda.get_array_module(*inputs)
         mask = xp.abs(self.diff) <= self.delta
-        gx = xp.where(mask, self.diff, self.delta * xp.sign(self.diff))
+        gx = gy[0].reshape(gy[0].shape + (1,) * (self.diff.ndim - 1)) * \
+            xp.where(mask, self.diff, self.delta * xp.sign(self.diff))
         return gx, -gx
 
 


Test patch:
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_huber_loss.py b/tests/chainer_tests/functions_tests/loss_tests/test_huber_loss.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_huber_loss.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_huber_loss.py
@@ -18,6 +18,7 @@ def setUp(self):
         self.x = (numpy.random.random(self.shape) - 0.5) * 20
         self.x = self.x.astype(numpy.float32)
         self.t = numpy.random.random(self.shape).astype(numpy.float32)
+        self.gy = numpy.random.random(self.shape[0]).astype(numpy.float32)
 
     def check_forward(self, x_data, t_data):
         x = chainer.Variable(x_data)
@@ -43,19 +44,20 @@ def test_forward_cpu(self):
     def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.t))
 
-    def check_backward(self, x_data, t_data):
+    def check_backward(self, x_data, t_data, y_grad):
         gradient_check.check_backward(
             functions.HuberLoss(delta=1),
-            (x_data, t_data), None, eps=1e-2, atol=1e-3)
+            (x_data, t_data), y_grad, eps=1e-2, atol=1e-3)
 
     @condition.retry(3)
     def test_backward_cpu(self):
-        self.check_backward(self.x, self.t)
+        self.check_backward(self.x, self.t, self.gy)
 
     @attr.gpu
     @condition.retry(3)
     def test_backward_gpu(self):
-        self.check_backward(cuda.to_gpu(self.x), cuda.to_gpu(self.t))
+        self.check_backward(cuda.to_gpu(self.x), cuda.to_gpu(self.t),
+                            cuda.to_gpu(self.gy))
 
 
 testing.run_module(__name__, __file__)
Repository: chainer/chainer

Issue:
Function accepts ndarrays
`Function` only accepts `Variable`. So we always need to wrap `ndarray` with `Variable` by hand.

This code causes an error.

```
x = numpy.array([1.0])
functions.cos(x)
```

This is correct:

```
x = numpy.array([1.0])
functions.cos(chainer.Variable(x))
```

I like former one.



Discussion:

Resolving patch:
diff --git a/chainer/function.py b/chainer/function.py
--- a/chainer/function.py
+++ b/chainer/function.py
@@ -98,8 +98,11 @@ def __call__(self, *inputs):
            not need to take care of device selection.
 
         Args:
-            inputs: Tuple of input :class:`Variable` objects. The volatile
-                flags of all input variables must agree.
+            inputs: Tuple of input :class:`Variable`, :class:`numpy.ndarray` or
+                :class:`cupy.ndarray` objects. The volatile flags of all input
+                variables must agree. If the input is an :class:`numpy.ndarray`
+                or a :class:`cupy.ndarray`, it is automatically wrapped with
+                :class:`Variable`.
 
         Returns:
             One :class:`Variable` object or a tuple of multiple
@@ -107,6 +110,10 @@ def __call__(self, *inputs):
 
         """
 
+        inputs = [x if isinstance(x, chainer.Variable)
+                  else chainer.Variable(x, volatile=flag.AUTO)
+                  for x in inputs]
+
         in_data = tuple([x.data for x in inputs])
         if chainer.is_debug():
             self._stack = traceback.extract_stack()


Test patch:
diff --git a/tests/chainer_tests/test_function.py b/tests/chainer_tests/test_function.py
--- a/tests/chainer_tests/test_function.py
+++ b/tests/chainer_tests/test_function.py
@@ -138,6 +138,32 @@ def test_call_gpu(self):
         self.setup_gpu()
         self.check_call()
 
+    def check_call_ndarray(self):
+        x1 = chainer.Variable(self.x1)
+        x2 = self.x2
+        x1.rank = 1
+        ys = self.f(x1, x2)
+
+        self.assertEqual(len(ys), 2)
+        self.check_check_type_forward()
+
+        for y in ys:
+            self.assertIsInstance(y, chainer.Variable)
+            # rank is (maximum rank in xs) + 1
+            self.assertEqual(y.rank, 2)
+            self.assertFalse(y.volatile)
+            self.assertIs(y.creator, self.f)
+
+        self.assertIsInstance(y.creator.outputs, tuple)
+
+    def test_call_ndarray_cpu(self):
+        self.check_call_ndarray()
+
+    @attr.gpu
+    def test_call_ndarray_gpu(self):
+        self.setup_gpu()
+        self.check_call_ndarray()
+
     def check_call_volatile(self):
         x1 = chainer.Variable(self.x1, volatile=True)
         x2 = chainer.Variable(self.x2, volatile=True)