import numpy
import six

from chainer import cuda


class FunctionSet(object):

    """Set of objects with ``parameters`` and ``gradients`` properties.

    :class:`FunctionSet` is useful to collect parameters and gradients of
    multiple parameterized :class:`Function` objects. :class:`FunctionSet`
    itself also implements :attr:`~FunctionSet.parameters` and
    :attr:`~FunctionSet.gradients`, so it can be nested in another
    :class:`FunctionSet` object.

    Function registration is done by just adding an attribute to
    :class:`FunctionSet` object.

    """

    def __init__(self, **functions):
        """Initializes the function set by given functions.

        Args:
            **functions: ``dict`` of ``str`` key and :class:`Function` values.
                The key-value pairs are just set to the :class:`FunctionSet`
                object as attributes.

        """
        for name, func in six.iteritems(functions):
            setattr(self, name, func)

    def collect_parameters(self):
        """Returns a tuple of parameters and gradients.

        Returns:
            Tuple (pair) of two tuples. The first element is a tuple of
            parameter arrays, and the second is a tuple of gradient arrays.

        """
        return self.parameters, self.gradients

    def to_gpu(self, device=None):
        """Migrates all parameters and gradients onto GPU.

        This method calls ``to_gpu`` method of each registered object.

        Args:
            device (int or :class:`pycuda.driver.Device` or ``None``): Device
                ID of GPU. If ``None`` is given, it uses the current device.

        Returns:
            self

        """
        for func in six.itervalues(self.__dict__):
            func.to_gpu(device=device)
        return self

    def to_cpu(self):
        """Migrates all parameters and gradients onto CPU.

        This method calls ``to_cpu`` method of each registered object.

        Returns:
            self

        """
        for func in six.itervalues(self.__dict__):
            func.to_cpu()
        return self

    def copy_parameters_from(self, params):
        """Copies parameters from another source without reallocation.

        Args:
            params (Iterable): Iterable of parameter arrays.

        """
        for dst, src in zip(self.parameters, params):
            if isinstance(dst, numpy.ndarray):
                if isinstance(src, numpy.ndarray):
                    dst.copy(src)
                else:
                    src.get(dst)
            elif isinstance(src, numpy.ndarray):
                dst.set(src)
            else:
                cuda.copy(src, out=dst)

    @property
    def parameters(self):
        """Tuple of parameter arrays of all registered functions.

        The order of parameters is consistent with :meth:`gradients` property.

        """
        return sum((func.parameters for _, func in self._get_sorted_funcs()),
                   ())

    @parameters.setter
    def parameters(self, params):
        param_iter = iter(params)
        for _, func in self._get_sorted_funcs():
            func.parameters = param_iter

    @property
    def gradients(self):
        """Tuple of gradient arrays of all registered functions.

        The order of gradients is consistent with :meth:`parameters` property.

        """
        return sum((func.gradients for _, func in self._get_sorted_funcs()),
                   ())

    @gradients.setter
    def gradients(self, grads):
        grad_iter = iter(grads)
        for _, func in self._get_sorted_funcs():
            func.gradients = grad_iter

    def _get_sorted_funcs(self):
        return sorted(six.iteritems(self.__dict__))

chainer/function_set.py
import numpy
import six

from chainer import cuda


class FunctionSet(object):

    """Set of objects with ``parameters`` and ``gradients`` properties.

    :class:`FunctionSet` is useful to collect parameters and gradients of
    multiple parameterized :class:`Function` objects. :class:`FunctionSet`
    itself also implements :attr:`~FunctionSet.parameters` and
    :attr:`~FunctionSet.gradients`, so it can be nested in another
    :class:`FunctionSet` object.

    Function registration is done by just adding an attribute to
    :class:`FunctionSet` object.

    """

    def __init__(self, **functions):
        """Initializes the function set by given functions.

        Args:
            **functions: ``dict`` of ``str`` key and :class:`Function` values.
                The key-value pairs are just set to the :class:`FunctionSet`
                object as attributes.

        """
        for name, func in six.iteritems(functions):
            setattr(self, name, func)

    def collect_parameters(self):
        """Returns a tuple of parameters and gradients.

        Returns:
            Tuple (pair) of two tuples. The first element is a tuple of
            parameter arrays, and the second is a tuple of gradient arrays.

        """
        return self.parameters, self.gradients

    def to_gpu(self, device=None):
        """Migrates all parameters and gradients onto GPU.

        This method calls ``to_gpu`` method of each registered object.

        Args:
            device (int or :class:`pycuda.driver.Device` or ``None``): Device
                ID of GPU. If ``None`` is given, it uses the current device.

        Returns:
            self

        """
        for func in six.itervalues(self.__dict__):
            func.to_gpu(device=device)
        return self

    def to_cpu(self):
        """Migrates all parameters and gradients onto CPU.

        This method calls ``to_cpu`` method of each registered object.

        Returns:
            self

        """
        for func in six.itervalues(self.__dict__):
            func.to_cpu()
        return self

    def copy_parameters_from(self, params):
        """Copies parameters from another source without reallocation.

        Args:
            params (Iterable): Iterable of parameter arrays.

        """
        for dst, src in zip(self.parameters, params):
            if isinstance(dst, numpy.ndarray):
                if isinstance(src, numpy.ndarray):
                    numpy.copyto(dst, src)
                else:
                    src.get(dst)
            elif isinstance(src, numpy.ndarray):
                dst.set(src)
            else:
                cuda.copy(src, out=dst)

    @property
    def parameters(self):
        """Tuple of parameter arrays of all registered functions.

        The order of parameters is consistent with :meth:`gradients` property.

        """
        return sum((func.parameters for _, func in self._get_sorted_funcs()),
                   ())

    @parameters.setter
    def parameters(self, params):
        param_iter = iter(params)
        for _, func in self._get_sorted_funcs():
            func.parameters = param_iter

    @property
    def gradients(self):
        """Tuple of gradient arrays of all registered functions.

        The order of gradients is consistent with :meth:`parameters` property.

        """
        return sum((func.gradients for _, func in self._get_sorted_funcs()),
                   ())

    @gradients.setter
    def gradients(self, grads):
        grad_iter = iter(grads)
        for _, func in self._get_sorted_funcs():
            func.gradients = grad_iter

    def _get_sorted_funcs(self):
        return sorted(six.iteritems(self.__dict__))

chainer/function_set.py
diff --git a/chainer/function_set.py b/chainer/function_set.py
index ca4ac1ab3466..6c1d5a6e37fb 100644
--- a/chainer/function_set.py
+++ b/chainer/function_set.py
@@ -81,7 +81,7 @@ def copy_parameters_from(self, params):
         for dst, src in zip(self.parameters, params):
             if isinstance(dst, numpy.ndarray):
                 if isinstance(src, numpy.ndarray):
-                    dst.copy(src)
+                    numpy.copyto(dst, src)
                 else:
                     src.get(dst)
             elif isinstance(src, numpy.ndarray):
diff --git a/tests/test_function_set.py b/tests/test_function_set.py
index d4596431adac..0db2de390494 100644
--- a/tests/test_function_set.py
+++ b/tests/test_function_set.py
@@ -102,5 +102,41 @@ def test_pickle_gpu(self):
         fs2.to_cpu()
         self.check_equal_fs(self.fs, fs2)
 
+    def check_copy_parameters_from(self, src_gpu=False, dst_gpu=False):
+        aW = np.random.uniform(-1, 1, (2, 3)).astype(np.float32)
+        ab = np.random.uniform(-1, 1, (2,)).astype(np.float32)
+        bW = np.random.uniform(-1, 1, (2, 3)).astype(np.float32)
+        bb = np.random.uniform(-1, 1, (2,)).astype(np.float32)
+        params = [aW.copy(), ab.copy(), bW.copy(), bb.copy()]
+
+        if dst_gpu:
+            self.fs.to_gpu()
+
+        if src_gpu:
+            params = map(cuda.to_gpu, params)
+
+        self.fs.copy_parameters_from(params)
+        self.fs.to_cpu()
+
+        self.assertTrue((self.fs.a.W == aW).all())
+        self.assertTrue((self.fs.a.b == ab).all())
+        self.assertTrue((self.fs.b.W == bW).all())
+        self.assertTrue((self.fs.b.b == bb).all())
+
+    def test_copy_parameters_from_cpu_to_cpu(self):
+        self.check_copy_parameters_from(False, False)
+
+    @attr.gpu
+    def test_copy_parameters_from_cpu_to_gpu(self):
+        self.check_copy_parameters_from(False, True)
+
+    @attr.gpu
+    def test_copy_parameters_from_gpu_to_cpu(self):
+        self.check_copy_parameters_from(True, False)
+
+    @attr.gpu
+    def test_copy_parameters_from_gpu_to_gpu(self):
+        self.check_copy_parameters_from(True, True)
+
 
 testing.run_module(__name__, __file__)

FunctionSet.copy_parameters_from()
Hi all!

The code in 'FunctionSet.copy_parameters_from()' does not work, when 'src' and 'dst' are both numpy.ndarrays?

``` python
if isinstance(dst, numpy.ndarray):
    if isinstance(src, numpy.ndarray):
        dst.copy(src)  # this gives a ValueError
```

I think this should read

``` python
if isinstance(dst, numpy.ndarray):
    if isinstance(src, numpy.ndarray):
        numpy.copyto(dst, src)
```

My numpy.version.full_version is 1.9.2, the 'copyto' method exists since 1.7.0.

Cheers,
-r

