def test_concat_arrays_to_chainerx(self): device = 'native:0' self.check_concat_arrays( self.int_arrays, device, backend.ChainerxDevice(chainerx.get_device(device)), numpy.int64) self.check_concat_arrays( self.float_arrays, device, backend.ChainerxDevice(chainerx.get_device(device)), numpy.float64)
def test_ascontiguousarray_from_chainerx_array_device(): with chainerx.using_device(chainerx.get_device('native:0')): dev = chainerx.get_device('native:1') # Non default one assert chainerx.get_default_device() is not dev a = chainerx.arange(10, device=dev) b = chainerx.ascontiguousarray(a) assert b.is_contiguous is True assert b.device is dev
def test_chainerx_get_device(): context = chainerx.Context() with chainerx.context_scope(context): device = chainerx.get_device('native:0') assert device.context is context assert device.name == 'native:0' assert device is chainerx.get_device('native', 0) assert device is chainerx.get_device(device) assert chainerx.get_default_device() is chainerx.get_device()
def from_fallback_device(device): # TODO(niboshi): Write unit test assert isinstance(device, _backend.Device) if isinstance(device, _cpu.CpuDevice): return ChainerxDevice(chainerx.get_device('native', 0)) if isinstance(device, cuda.GpuDevice): return ChainerxDevice(chainerx.get_device('cuda', device.device.id)) raise RuntimeError('Only CPU or GPU devices are allowed. ' 'Actual: {}'.format(device))
def from_fallback_device(device): # TODO(niboshi): Write unit test assert isinstance(device, _backend.Device) if isinstance(device, _cpu.CpuDevice): return ChainerxDevice(chainerx.get_device('native', 0)) if isinstance(device, cuda.GpuDevice): return ChainerxDevice( chainerx.get_device('cuda', device.device.id)) raise RuntimeError( 'Only CPU or GPU devices are allowed. ' 'Actual: {}'.format(device))
def _get_device(device_spec): # Called from chainer.backend.get_device if not chainerx.is_available(): return None if isinstance(device_spec, chainerx.Device): return ChainerxDevice(device_spec) if isinstance(device_spec, str): return ChainerxDevice(chainerx.get_device(device_spec)) if (isinstance(device_spec, tuple) and len(device_spec) >= 1 and isinstance(device_spec[0], str)): return ChainerxDevice(chainerx.get_device(*device_spec)) return None
def _array_to_chainerx(array, device=None): # If device is None, appropriate device is chosen according to the input # arrays. assert device is None or isinstance(device, chainerx.Device) if array is None: return None if array.dtype not in chainerx.all_dtypes: raise TypeError( 'Dtype {} is not supported in ChainerX.'.format(array.dtype.name)) if isinstance(array, chainerx.ndarray): if device is None: return array if device is array.device: return array return array.to_device(device) if isinstance(array, numpy.ndarray): if device is None: device = chainerx.get_device('native', 0) return chainerx.array(array, device=device, copy=False) if isinstance(array, cuda.ndarray): if device is None: device = chainerx.get_device('cuda', array.device.id) elif device.backend.name != 'cuda': # cupy to non-cuda backend # TODO(niboshi): Remove conversion to numpy when both CuPy and # ChainerX support the array interface. array = _cpu._to_cpu(array) return chainerx.array(array, device=device, copy=False) elif device.index != array.device.id: # cupy to cuda backend but different device array = cuda.to_gpu(array, device=device.index) # cupy to cuda backend with the same device return chainerx._core._fromrawpointer( array.data.mem.ptr, array.shape, array.dtype, array.strides, device, array.data.ptr - array.data.mem.ptr, array) if isinstance(array, intel64.mdarray): return _array_to_chainerx(numpy.array(array), device) if numpy.isscalar(array): return chainerx.asarray(array) raise TypeError( 'Array cannot be converted into chainerx.ndarray' '\nActual type: {0}.'.format(type(array)))
def from_fallback_device(device): """Returns a :class:`~chainer.backend.ChainerxDevice` corresponding \ to the fallback device. .. seealso:: :data:`~chainer.backend.ChainerxDevice.fallback_device` """ assert isinstance(device, _backend.Device) if isinstance(device, _cpu.CpuDevice): return ChainerxDevice(chainerx.get_device('native', 0)) if isinstance(device, cuda.GpuDevice): return ChainerxDevice(chainerx.get_device('cuda', device.device.id)) raise RuntimeError('Only CPU or GPU devices are allowed. ' 'Actual: {}'.format(device))
def test_init(self, backend_config): name = backend_config.chainerx_device chx_device = chainerx.get_device(name) device = backend.ChainerxDevice(chx_device) self.check_device(device, backend_config) assert device.device is chx_device
def test_check_device_device_spec(shape, device_spec): dtype = 'float32' a = chainerx.empty(shape, dtype, device=device_spec) device = chainerx.get_device(device_spec) array_utils.check_device(a, device_spec) array_utils.check_device(a, device)
def test_backward_default_device(self): # Default device in backward should be determined by arrays, # otherwise, creation routines in backward do not create new arrays # on the proper device. device = chainerx.get_device('cuda:0') shape = (2, 3) dtype = numpy.float32 x1 = chainerx.full(shape, 3, dtype, device=device) x2 = chainerx.full(shape, 5, dtype, device=device).require_grad() backward_call_new_array = [] def backward_call_callback(call_arg): backward_call_new_array.append(chainerx.empty(shape, dtype)) with chainerx.using_device('native:0'): # forward func = self.SimpleFunctionNode(backward_call_callback) y1, y2 = func.apply((x1, x2)) # backward y2.backward() assert backward_call_new_array[0].device is device
def _from_cupy(array): assert cupy is not None assert isinstance(array, cupy.ndarray) device = chainerx.get_device('cuda', array.device.id) return chainerx._core._fromrawpointer(array.data.mem.ptr, array.shape, array.dtype, array.strides, device, array.data.ptr - array.data.mem.ptr, array)
def test_frombuffer_from_device_buffer(device): dtype = 'int32' device_buffer = chainerx.testing._DeviceBuffer( [1, 2, 3, 4, 5, 6], (2, 3), dtype) a = chainerx.frombuffer(device_buffer, dtype) e = chainerx.array([1, 2, 3, 4, 5, 6], dtype) chainerx.testing.assert_array_equal_ex(e, a) assert a.device is chainerx.get_device(device)
def test_from_fallback_device(self, backend_config): # Preparation: it depends on ChainerxDevice.fallback_device tmp_device = backend.ChainerxDevice( chainerx.get_device(backend_config.chainerx_device)) fallback_device = tmp_device.fallback_device # Test device = backend.ChainerxDevice.from_fallback_device(fallback_device) self.check_device(device, backend_config) assert device.fallback_device == fallback_device
def check_device_spec_chainerx(self, device_spec, expected_device_name): device = backend.get_device(device_spec) assert isinstance(device, backend.ChainerxDevice) assert device.xp is chainerx assert isinstance(device.device, chainerx.Device) assert device.device.name == expected_device_name with backend.using_device(device_spec): # TODO(niboshi): Test the Chainer default device assert (chainerx.get_default_device() == chainerx.get_device( expected_device_name))
def _from_cupy(array): assert cupy is not None assert isinstance(array, cupy.ndarray) device = chainerx.get_device('cuda', array.device.id) return chainerx._core._fromrawpointer( array.data.mem.ptr, array.shape, array.dtype, array.strides, device, array.data.ptr - array.data.mem.ptr, array)
def check_device_spec_chainerx(self, device_spec, expected_device_name): device = backend.get_device(device_spec) assert isinstance(device, backend.ChainerxDevice) assert device.xp is chainerx assert isinstance(device.device, chainerx.Device) assert device.device.name == expected_device_name with backend.using_device(device_spec): # TODO(niboshi): Test the Chainer default device assert ( chainerx.get_default_device() == chainerx.get_device(expected_device_name))
def device(self): if self._device is None: if self.use_cuda: device = backend.GpuDevice.from_device_id(self.cuda_device) elif self.use_chainerx: device = backend.ChainerxDevice( chainerx.get_device(self.chainerx_device)) elif self.use_ideep != 'never': device = backend.Intel64Device() else: device = backend.CpuDevice() self._device = device return self._device
def test_to_device(): a = chainerx.ones((2,), chainerx.float32, device='native:0') dst_device = chainerx.get_device('native:1') b0 = a.to_device(dst_device) # by device instance assert b0.device is dst_device chainerx.testing.assert_array_equal_ex(a, b0) b1 = a.to_device('native:1') # by device name assert b1.device is dst_device chainerx.testing.assert_array_equal_ex(a, b1) b2 = a.to_device('native', 1) # by backend name and index assert b2.device is dst_device chainerx.testing.assert_array_equal_ex(a, b2)
def test_array_from_chainerx_array_with_device( src_dtype, dst_dtype, copy, device, dst_device_spec): t = array_utils.create_dummy_ndarray( chainerx, (2,), src_dtype, device=device) a = chainerx.array(t, dtype=dst_dtype, copy=copy, device=dst_device_spec) dst_device = chainerx.get_device(dst_device_spec) if not copy and src_dtype == dst_dtype and device is dst_device: assert t is a else: assert t is not a chainerx.testing.assert_array_equal_ex( a, t.to_device(dst_device).astype(dst_dtype)) assert a.dtype == chainerx.dtype(dst_dtype) assert a.device is dst_device
def test_frombuffer_from_numpy_array(device): obj = array_utils.create_dummy_ndarray( numpy, (2, 3), 'int32', padding=False) a_chx = chainerx.frombuffer(obj, obj.dtype) a_np = numpy.frombuffer(obj, obj.dtype) chainerx.testing.assert_array_equal_ex(a_np, a_chx) assert a_chx.device is chainerx.get_device(device) # test buffer is shared obj += obj chainerx.testing.assert_array_equal_ex(obj.ravel(), a_chx) # test possibly freed memory obj_copy = obj.copy() del obj chainerx.testing.assert_array_equal_ex(obj_copy.ravel(), a_chx)
def _check_array_from_chainerx_array_with_dtype( shape, src_dtype, dst_dtype_spec, copy, device=None): t = array_utils.create_dummy_ndarray( chainerx, shape, src_dtype, device=device) a = chainerx.array(t, dtype=dst_dtype_spec, copy=copy) src_dtype = chainerx.dtype(src_dtype) dst_dtype = src_dtype if dst_dtype_spec is None else chainerx.dtype( dst_dtype_spec) device = chainerx.get_device(device) if (not copy and src_dtype == dst_dtype and device is chainerx.get_default_device()): assert t is a else: assert t is not a chainerx.testing.assert_array_equal_ex(a, t.astype(dst_dtype)) assert a.dtype == dst_dtype assert a.device is chainerx.get_default_device()
def test_asarray_from_chainerx_array_with_device(src_dtype, dst_dtype, device, dst_device_spec): t = array_utils.create_dummy_ndarray(chainerx, (2, ), src_dtype, device=device) a = chainerx.asarray(t, dtype=dst_dtype, device=dst_device_spec) dst_device = chainerx.get_device(dst_device_spec) if ((dst_dtype is None or src_dtype == dst_dtype) and (dst_device_spec is None or device is dst_device)): assert t is a else: assert t is not a if dst_dtype is None: dst_dtype = t.dtype chainerx.testing.assert_array_equal_ex( a, t.to_device(dst_device).astype(dst_dtype)) assert a.dtype == chainerx.dtype(dst_dtype) assert a.device is dst_device
if xp is numpy and isinstance(dtype_spec, chainerx.dtype): dtype_spec = dtype_spec.name # Skip nan/inf -> integer conversion that would cause a cast error. if (not _is_all_finite(obj) and dtype_spec not in (None, Unspecified) and chainerx.dtype(dtype_spec).kind not in ('f', 'c')): return chainerx.testing.ignore() if dtype_spec is Unspecified: return xp.array(obj) else: return xp.array(obj, dtype_spec) @pytest.mark.parametrize('obj', _array_params(_array_params_list)) @pytest.mark.parametrize( 'device', [None, 'native:1', chainerx.get_device('native:1')]) def test_array_from_python_tuple_or_list_with_device(obj, device): a = chainerx.array(obj, 'float32', device=device) b = chainerx.array(obj, 'float32') chainerx.testing.assert_array_equal_ex(a, b) array_utils.check_device(a, device) def _check_array_from_numpy_array(a_chx, a_np, device=None): assert a_chx.offset == 0 array_utils.check_device(a_chx, device) # recovered data should be equal a_np_recovered = chainerx.to_numpy(a_chx) chainerx.testing.assert_array_equal_ex( a_chx, a_np_recovered, strides_check=False)
def test_dummy_ndarray_device_spec(device_spec): a = array_utils.create_dummy_ndarray( chainerx, (2, 3), 'float32', device=device_spec) assert a.device is chainerx.get_device(device_spec)
def test_concat_tuples_to_chainerx(self, backend_config): device = chainerx.get_device('native:0') arrays = self.get_tuple_arrays_to_concat(backend_config) self.check_concat_tuples( arrays, device, backend.ChainerxDevice(device))
def get_device(device_spec: types.DeviceSpec) -> Device: """Returns a device object. Args: device_spec (object): Device specifier. If a :class:`chainer.backend.Device` instance is given, it is returned intact. Otherwise the following values are supported: * ChainerX devices * A string representing a device. (ex. ``'native:0'``, ``'native'``) * A :class:`chainerx.Device` object. * CuPy * A string starts with ``'@cupy:'``. (ex. ``'@cupy:0'``) * A :class:`cupy.cuda.Device` object. * NumPy * The string ``'@numpy'``. * NumPy with Intel Architecture * The string ``'@intel64'``. """ if isinstance(device_spec, Device): return device_spec if isinstance(device_spec, cuda._integer_types): return _get_device_cupy_or_numpy(device_spec) if chainerx.is_available() and isinstance(device_spec, chainerx.Device): return _chainerx.ChainerxDevice(device_spec) if cuda.available and isinstance(device_spec, cuda.Device): return cuda.GpuDevice(device_spec) if isinstance(device_spec, six.string_types): # '-1', '0', '1', ... try: int_device_spec = int(device_spec) except ValueError: pass else: return _get_device_cupy_or_numpy(int_device_spec) if device_spec.startswith('@'): # '@module:...' mod_name, colon, precise_spec = device_spec[1:].partition(':') if mod_name == 'numpy': if not colon: return _cpu.CpuDevice() elif mod_name == 'cupy': if colon: return cuda.GpuDevice.from_device_id(int(precise_spec)) elif mod_name == 'intel64': if not colon: return intel64.Intel64Device() raise ValueError( 'Device specifiers starting with \'@\' must be followed by' ' a module name and depending on the module, module specific' ' precise device specifiers. Actual: {}'.format(device_spec)) else: # String device specifier without '@' prefix is assumed to be a # ChainerX device. if not chainerx.is_available(): raise RuntimeError( 'Tried to parse ChainerX device specifier \'{}\', ' 'but ChainerX is not available. ' 'Note that device specifiers without \'@\' prefix are ' 'assumed to be ChainerX device ' 'specifiers.'.format(device_spec)) return _chainerx.ChainerxDevice(chainerx.get_device(device_spec)) raise TypeError( 'Device specifier must be a backend.Device, cuda.Device,' ' chainerx.Device, integer or a string. Actual: {}'.format( type(device_spec)))
def test_init_chainerx_with_cuda(self): device = chainerx.get_device('cuda:0') array = self._generate_array(chainerx, 'float64', device) assert array.device is device
def check_device(a, device=None): if device is None: device = chainerx.get_default_device() elif isinstance(device, str): device = chainerx.get_device(device) assert a.device is device
def test_chainerx_device(self): chainerx_device = chainerx.get_device('native:0') self.check_device_spec_chainerx(chainerx_device, 'native:0')
def _get_chainerx_device(device_spec): # Returns chainerx.Device if isinstance(device_spec, chainerx.Device): return device_spec return chainerx.get_device(device_spec)
assert array._debug_flat_data == expected_data_list assert array.is_contiguous array_utils.check_device(array, device) @chainerx.testing.parametrize_dtype_specifier('dtype_spec') def test_init(shape, dtype_spec): array = chainerx.ndarray(shape, dtype_spec) _check_array(array, dtype_spec, shape) @pytest.mark.parametrize( 'device', [None, 'native:1', chainerx.get_device('native:1')]) @chainerx.testing.parametrize_dtype_specifier('dtype_spec') def test_init_with_device(shape, dtype_spec, device): array = chainerx.ndarray(shape, dtype_spec, device=device) _check_array(array, dtype_spec, shape, device=device) @pytest.mark.parametrize('value', [ 0, 1, -1, 0.1, 0.9, -0.1, -0.9, 1.1, -1.1, 1.9, -1.9, True, False, float('inf'), -float('inf'), float('nan'), -0.0 ]) @pytest.mark.parametrize('shape', [(), (1, ), (1, 1, 1)]) @pytest.mark.parametrize_device(['native:0', 'cuda:0']) def test_cast_scalar(device, value, shape, dtype): np_dtype = numpy.dtype(dtype)
def test_init_chainerx_with_default_device(self): device = chainerx.get_device('native:1') with chainerx.using_device(device): array = self._generate_array(chainerx, 'float64') assert array.device is device
def test_dummy_ndarray_device_spec(device_spec): a = array_utils.create_dummy_ndarray(chainerx, (2, 3), 'float32', device=device_spec) assert a.device is chainerx.get_device(device_spec)
def get_device(device_spec): # type: (types.DeviceSpec) -> Device """Returns a device object. Args: device_spec (object): Device specifier. If a :class:`chainer.Device` instance is given, it is returned intact. Otherwise the following values are supported: * ChainerX devices * A string representing a device. (ex. ``'native:0'``, ``'native'``) * A :class:`chainerx.Device` object. * CuPy * A string starts with ``'@cupy:'``. (ex. ``'@cupy:0'``) * A :class:`cupy.cuda.Device` object. * NumPy * The string ``'@numpy'``. * NumPy with Intel Architecture * The string ``'@intel64'``. """ if isinstance(device_spec, Device): return device_spec if isinstance(device_spec, cuda._integer_types): return _get_device_cupy_or_numpy(device_spec) if chainerx.is_available() and isinstance(device_spec, chainerx.Device): return _chainerx.ChainerxDevice(device_spec) if cuda.available and isinstance(device_spec, cuda.Device): return cuda.GpuDevice(device_spec) if isinstance(device_spec, six.string_types): # '-1', '0', '1', ... try: int_device_spec = int(device_spec) except ValueError: pass else: return _get_device_cupy_or_numpy(int_device_spec) if device_spec.startswith('@'): # '@module:...' mod_name, colon, precise_spec = device_spec[1:].partition(':') if mod_name == 'numpy': if not colon: return _cpu.CpuDevice() elif mod_name == 'cupy': if colon: return cuda.GpuDevice.from_device_id(int(precise_spec)) elif mod_name == 'intel64': if not colon: return intel64.Intel64Device() elif chainerx.is_available(): return _chainerx.ChainerxDevice(chainerx.get_device(device_spec)) raise ValueError('Invalid device specifier: {}'.format(device_spec))
def get_device(device_spec): # type: (types.DeviceSpec) -> Device """Returns a device object. Args: device_spec (object): Device specifier. If a :class:`chainer.backend.Device` instance is given, it is returned intact. Otherwise the following values are supported: * ChainerX devices * A string representing a device. (ex. ``'native:0'``, ``'native'``) * A :class:`chainerx.Device` object. * CuPy * A string starts with ``'@cupy:'``. (ex. ``'@cupy:0'``) * A :class:`cupy.cuda.Device` object. * NumPy * The string ``'@numpy'``. * NumPy with Intel Architecture * The string ``'@intel64'``. """ if isinstance(device_spec, Device): return device_spec if isinstance(device_spec, cuda._integer_types): return _get_device_cupy_or_numpy(device_spec) if chainerx.is_available() and isinstance(device_spec, chainerx.Device): return _chainerx.ChainerxDevice(device_spec) if cuda.available and isinstance(device_spec, cuda.Device): return cuda.GpuDevice(device_spec) if isinstance(device_spec, six.string_types): # '-1', '0', '1', ... try: int_device_spec = int(device_spec) except ValueError: pass else: return _get_device_cupy_or_numpy(int_device_spec) if device_spec.startswith('@'): # '@module:...' mod_name, colon, precise_spec = device_spec[1:].partition(':') if mod_name == 'numpy': if not colon: return _cpu.CpuDevice() elif mod_name == 'cupy': if colon: return cuda.GpuDevice.from_device_id(int(precise_spec)) elif mod_name == 'intel64': if not colon: return intel64.Intel64Device() elif chainerx.is_available(): return _chainerx.ChainerxDevice(chainerx.get_device(device_spec)) raise ValueError('Invalid device specifier: {}'.format(device_spec))