From 63d585b90e5c70f85bcc8e513ffc36353cede138 Mon Sep 17 00:00:00 2001 From: Kenichi Maehashi Date: Tue, 26 Jun 2018 15:45:29 +0900 Subject: [PATCH] Merge pull request #1367 from okuta/improve-memcopy Improve host to device memory copy --- cupy/core/core.pyx | 21 +++++++++++-------- cupy/logic/type_test.py | 4 ++-- .../creation_tests/test_from_data.py | 9 ++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/cupy/core/core.pyx b/cupy/core/core.pyx index c879cfe1e64..8fa11600295 100644 --- a/cupy/core/core.pyx +++ b/cupy/core/core.pyx @@ -3,13 +3,13 @@ from __future__ import division import sys +import ctypes import numpy import six import cupy from cupy.core import flags from cupy.cuda import device -from cupy.cuda import stream try: from cupy.cuda import thrust @@ -2051,6 +2051,7 @@ cpdef ndarray array(obj, dtype=None, bint copy=True, str order='K', # TODO(beam2d): Support subok options cdef Py_ssize_t nvidem cdef ndarray a, src + cdef size_t nbytes if subok: raise NotImplementedError if isinstance(obj, ndarray): @@ -2070,11 +2071,13 @@ cpdef ndarray array(obj, dtype=None, bint copy=True, str order='K', a = a.view() a.shape = (1,) * (ndmin - ndim) + a.shape else: - if order == 'K': - order = 'A' + if order is not None and len(order) >= 1 and order[0] in 'KAka': + if isinstance(obj, numpy.ndarray) and obj.flags.f_contiguous: + order = 'F' + else: + order = 'C' a_cpu = numpy.array(obj, dtype=dtype, copy=False, order=order, ndmin=ndmin) - order = 'C' if a_cpu.flags.c_contiguous else 'F' a_dtype = a_cpu.dtype if a_dtype.char not in '?bhilqBHILQefdFD': raise ValueError('Unsupported dtype %s' % a_dtype) @@ -2082,12 +2085,12 @@ cpdef ndarray array(obj, dtype=None, bint copy=True, str order='K', if a_cpu.ndim == 0: a.fill(a_cpu[()]) return a - mem = pinned_memory.alloc_pinned_memory(a.nbytes) - src_cpu = numpy.frombuffer(mem, a_cpu.dtype, - a_cpu.size).reshape(a_cpu.shape) - src_cpu[...] = a_cpu + nbytes = a.nbytes + mem = pinned_memory.alloc_pinned_memory(nbytes) + src_cpu = numpy.frombuffer(mem, a_dtype, a_cpu.size) + src_cpu[:] = a_cpu.ravel(order) stream = stream_module.get_current_stream() - a.set(src_cpu, stream) + a.data.copy_from_host_async(ctypes.c_void_p(mem.ptr), nbytes) pinned_memory._add_to_watch_list(stream.record(), mem) return a diff --git a/cupy/logic/type_test.py b/cupy/logic/type_test.py index b6be2dd6fe0..a3db06047b6 100644 --- a/cupy/logic/type_test.py +++ b/cupy/logic/type_test.py @@ -86,7 +86,7 @@ def isfortran(a): >>> cupy.isfortran(a) False - >>> b = cupy.array([[1, 2, 3], [4, 5, 6]], order='FORTRAN') + >>> b = cupy.array([[1, 2, 3], [4, 5, 6]], order='F') >>> b array([[1, 2, 3], [4, 5, 6]]) @@ -111,7 +111,7 @@ def isfortran(a): C-ordered arrays evaluate as False even if they are also FORTRAN-ordered. - >>> cupy.isfortran(np.array([1, 2], order='FORTRAN')) + >>> cupy.isfortran(np.array([1, 2], order='F')) False """ diff --git a/tests/cupy_tests/creation_tests/test_from_data.py b/tests/cupy_tests/creation_tests/test_from_data.py index a77c13f3e28..2f6d2567b80 100644 --- a/tests/cupy_tests/creation_tests/test_from_data.py +++ b/tests/cupy_tests/creation_tests/test_from_data.py @@ -22,6 +22,15 @@ def test_array_from_numpy(self, xp, dtype, order): a = testing.shaped_arange((2, 3, 4), numpy, dtype) return xp.array(a, order=order) + @testing.for_orders('CFAK') + @testing.for_all_dtypes() + @testing.with_requires('numpy>=1.10') + @testing.numpy_cupy_array_equal() + def test_array_from_numpy_broad_cast(self, xp, dtype, order): + a = testing.shaped_arange((2, 1, 4), numpy, dtype) + a = numpy.broadcast_to(a, (2, 3, 4)) + return xp.array(a, order=order) + @testing.for_orders('CFAK') @testing.for_all_dtypes() @testing.numpy_cupy_array_equal()