1import numpy 2 3from chainer import _backend 4# TODO(kmaehashi): `from chainer.backends import cuda` causes circular imports. 5# Surprisingly, `import chianer.backends` works as a workaround to avoid, but 6# we should fix circular dependencies themselves around `chainer.backends.*`. 7import chainer.backends 8import chainerx 9 10 11class CpuDevice(_backend.Device): 12 13 """Device for CPU (NumPy) backend""" 14 15 name = '@numpy' 16 xp = numpy 17 supported_array_types = (numpy.ndarray,) 18 19 __hash__ = _backend.Device.__hash__ 20 21 @staticmethod 22 def from_array(array): 23 if isinstance(array, numpy.ndarray): 24 return CpuDevice() 25 return None 26 27 def __eq__(self, other): 28 return isinstance(other, CpuDevice) 29 30 def __repr__(self): 31 return '<{} (numpy)>'.format(self.__class__.__name__) 32 33 def send_array(self, array): 34 return _array_to_cpu(array) 35 36 def is_array_supported(self, array): 37 return isinstance(array, numpy.ndarray) 38 39 40def _to_cpu(array): 41 """Converts an array or arrays to NumPy.""" 42 return _backend._convert_arrays(array, _array_to_cpu) 43 44 45def _array_to_cpu(array): 46 if array is None: 47 return None 48 if isinstance(array, numpy.ndarray): 49 return array 50 if isinstance(array, chainer.backends.intel64.mdarray): 51 return numpy.asarray(array) 52 if isinstance(array, chainerx.ndarray): 53 return chainerx.to_numpy(array, copy=False) 54 if isinstance(array, chainer.backends.cuda.ndarray): 55 with chainer.backends.cuda.get_device_from_array(array): 56 return array.get() 57 if numpy.isscalar(array): 58 return numpy.asarray(array) 59 raise TypeError( 60 'Array cannot be converted into an numpy.ndarray' 61 '\nActual type: {0}.'.format(type(array))) 62