def test_from_api_id(mock_backend_factory): for api_id in all_api_ids(): with pytest.raises(ImportError): API.from_api_id(api_id) mock_backend_factory.mock(api_id) api = API.from_api_id(api_id) assert api.id == api_id
def test_eq(mock_backend_factory): api_id0 = all_api_ids()[0] api_id1 = all_api_ids()[1] mock_backend_factory.mock(api_id0) mock_backend_factory.mock(api_id1) api0_v1 = API.from_api_id(api_id0) api0_v2 = API.from_api_id(api_id0) api1 = API.from_api_id(api_id1) assert api0_v1 is not api0_v2 and api0_v1 == api0_v2 assert api0_v1 != api1
def test_hash(mock_backend_factory): api_id0 = all_api_ids()[0] api_id1 = all_api_ids()[1] mock_backend_factory.mock(api_id0) mock_backend_factory.mock(api_id1) api0 = API.from_api_id(api_id0) api1 = API.from_api_id(api_id1) d = {api0: 0, api1: 1} assert d[api0] == 0 assert d[api1] == 1
def test_builtin_globals(mock_backend_pycuda): mock_backend_pycuda.add_devices([ PyCUDADeviceInfo(max_threads_per_block=1024), PyCUDADeviceInfo(max_threads_per_block=512) ]) source_template = DefTemplate.from_string( 'mock_source', [], """ KERNEL void test() { int max_total_local_size = ${device_params.max_total_local_size}; } """) api = API.from_api_id(mock_backend_pycuda.api_id) context = Context.from_devices( [api.platforms[0].devices[0], api.platforms[0].devices[1]]) src = MockDefTemplate(kernels=[MockKernel('test', [None])], source_template=source_template) program = Program(context.devices, src) assert 'max_total_local_size = 1024' in program.sources[ context.devices[0]].source assert 'max_total_local_size = 512' in program.sources[ context.devices[1]].source
def test_all(mock_backend): mock_backend.add_devices(['Device2', 'Device3']) api = API.from_api_id(mock_backend.api_id) platform = Platform.from_index(api, 0) devices = Device.all(platform) device_names = {device.name for device in devices} assert device_names == {'Device2', 'Device3'}
def test_bound_multi_device_creation(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices( 'Platform1', ['Device1', 'Device2', 'Device3']) api = API.from_api_id(mock_backend_pyopencl.api_id) platform = api.platforms[0] devices = platform.devices[:] context = Context.from_devices(devices) context2 = Context.from_devices(devices) with pytest.raises( ValueError, match= "All devices in a multi-device must belong to the same context"): BoundMultiDevice.from_bound_devices( [context.devices[0], context2.devices[1]]) with pytest.raises(ValueError, match="All devices in a multi-device must be distinct"): context.devices[[1, 1]] sub_device = context.devices[[2, 1]] assert len(sub_device) == 2 assert sub_device[0].name == 'Device3' assert sub_device[1].name == 'Device2'
def test_device_parameters_cuda(mock_backend_pycuda): device_info = PyCUDADeviceInfo(max_threads_per_block=512, max_block_dim_x=512, max_block_dim_y=512, max_block_dim_z=32, max_grid_dim_x=2**16, max_grid_dim_y=2**16, max_grid_dim_z=256, warp_size=7, max_shared_memory_per_block=58 * 1024, multiprocessor_count=3, compute_capability=10) mock_backend_pycuda.add_devices([device_info]) api = API.from_api_id(mock_backend_pycuda.api_id) d = api.platforms[0].devices[0] assert d.params.type == DeviceType.GPU assert d.params.max_total_local_size == device_info.max_threads_per_block assert d.params.max_local_sizes == (device_info.max_block_dim_x, device_info.max_block_dim_y, device_info.max_block_dim_z) assert d.params.warp_size == device_info.warp_size assert d.params.max_num_groups == (device_info.max_grid_dim_x, device_info.max_grid_dim_y, device_info.max_grid_dim_z) assert d.params.local_mem_size == device_info.max_shared_memory_per_block assert d.params.local_mem_banks == 32 assert d.params.compute_units == device_info.multiprocessor_count
def test_flags(mock_backend_pyopencl): backend = mock_backend_pyopencl normal_flags = backend.pyopencl.mem_flags.READ_WRITE special_flags = normal_flags | backend.pyopencl.mem_flags.ALLOC_HOST_PTR backend.add_platform_with_devices('Apple', ['GeForce', 'Foo', 'Bar']) backend.add_platform_with_devices('Baz', ['GeForce', 'Foo', 'Bar']) # Multi-device on Apple platform with one of the devices being GeForce: need special Buffer flags api = API.from_api_id(backend.api_id) context = Context.from_devices([api.platforms[0].devices[0], api.platforms[0].devices[1]]) buf = Buffer.allocate(context.devices[0], 100) assert buf._buffer_adapter.pyopencl_buffer.flags == special_flags # None of the devices is GeForce context = Context.from_devices([api.platforms[0].devices[1], api.platforms[0].devices[2]]) buf = Buffer.allocate(context.devices[0], 100) assert buf._buffer_adapter.pyopencl_buffer.flags == normal_flags # Only one device context = Context.from_devices([api.platforms[0].devices[0]]) buf = Buffer.allocate(context.device, 100) assert buf._buffer_adapter.pyopencl_buffer.flags == normal_flags # Not an Apple platform context = Context.from_devices([api.platforms[1].devices[0], api.platforms[1].devices[1]]) buf = Buffer.allocate(context.devices[0], 100) assert buf._buffer_adapter.pyopencl_buffer.flags == normal_flags
def check_select_devices(mock_stdin, mock_backend_factory, capsys, platforms_devices, inputs=None, **kwds): # CUDA API has a single fixed platform, so using the OpenCL one backend = mock_backend_factory.mock_pyopencl() for platform_name, device_infos in platforms_devices: platform = backend.add_platform_with_devices(platform_name, device_infos) if inputs is not None: for line in inputs: mock_stdin.line(line) api = API.from_api_id(backend.api_id) try: devices = select_devices(api, **kwds) assert mock_stdin.empty() finally: # Otherwise the output will be shown in the console captured = capsys.readouterr() return devices
def test_all_by_shortcut(mock_backend): api_id = mock_backend.api_id mock_backend.add_devices(['Device1', 'Device2']) apis = API.all_by_shortcut(api_id.shortcut) assert len(apis) == 1 assert apis[0].id == api_id
def test_all(mock_backend_factory): api_id = all_api_ids()[0] mock_backend_factory.mock(api_id) apis = API.all_available() assert len(apis) == 1 assert apis[0].id == api_id
def test_virtual_sizes_error_propagated(mock_backend_pycuda): # Testing for PyCUDA backend only since mocked PyOpenCL backend does not have a way # to set maximum global sizes (PyOpenCL devices don't have a corresponding parameter), # and PyCUDA is enough to test the required code path. device_info = PyCUDADeviceInfo( max_threads_per_block=2**4, max_block_dim_x=2**4, max_block_dim_y=2**4, max_block_dim_z=2**4, max_grid_dim_x=2**10, max_grid_dim_y=2**10, max_grid_dim_z=2**8) mock_backend_pycuda.add_devices([device_info]) api = API.from_api_id(mock_backend_pycuda.api_id) device = api.platforms[0].devices[0] context = Context.from_devices([device]) kernel = MockKernel('test', [None], max_total_local_sizes={0: 16}) src = MockDefTemplate(kernels=[kernel]) # Just enough to fit in the grid limits multiply = StaticKernel(context.device, src, 'test', (2**14, 2**10, 2**8), (2**4, 1, 1)) # Global size is too large to fit on the device, # so virtual size finding fails and the error is propagated to the user. with pytest.raises( VirtualSizeError, match="Bounding global size \\(16384, 2048, 256\\) is too large"): multiply = StaticKernel(context.device, src, 'test', (2**14, 2**11, 2**8), (2**4, 1, 1))
def test_all(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1']) mock_backend_pyopencl.add_platform_with_devices('Platform2', ['Device2']) api = API.from_api_id(mock_backend_pyopencl.api_id) platforms = Platform.all(api) platform_names = {platform.name for platform in platforms} assert platform_names == {'Platform1', 'Platform2'}
def test_from_index(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1']) mock_backend_pyopencl.add_platform_with_devices('Platform2', ['Device2']) api = API.from_api_id(mock_backend_pyopencl.api_id) platform = Platform.from_index(api, 1) assert platform.name == 'Platform2'
def test_max_total_local_sizes(mock_backend): mock_backend.add_devices( ["Device1", "Device2 - tag", "Device3 - tag", "Device4"]) api = API.from_api_id(mock_backend.api_id) context = Context.from_criteria(api, devices_num=2, device_include_masks=["tag"]) # Providing max_total_local_sizes for all possible devices to make sure # only the ones corresponding to the context will get picked up kernel = MockKernel('test', max_total_local_sizes={ 0: 64, 1: 1024, 2: 512, 3: 128 }) src = MockDefTemplate(kernels=[kernel]) program = Program(context.devices, src) # The indices here correspond to the devices in the context, not in the platform assert program.kernel.test.max_total_local_sizes == { context.devices[0]: 1024, context.devices[1]: 512 }
def test_bound_multi_device_issubset(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices( 'Platform1', ['Device1', 'Device2', 'Device3']) api = API.from_api_id(mock_backend_pyopencl.api_id) context = Context.from_devices(api.platforms[0].devices[:]) assert context.devices[[2, 1]].issubset(context.devices)
def test_getitem(mock_backend_pyopencl): api_id = mock_backend_pyopencl.api_id mock_backend_pyopencl.add_platform_with_devices('Platform0', ['Device0']) mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1']) api = API.from_api_id(api_id) assert api.platforms[0].name == 'Platform0' assert api.platforms[1].name == 'Platform1'
def test_device_parameters_opencl_cpu(mock_backend_pyopencl): device_info = PyOpenCLDeviceInfo(type=DeviceType.CPU) mock_backend_pyopencl.add_devices([device_info]) api = API.from_api_id(mock_backend_pyopencl.api_id) d = api.platforms[0].devices[0] assert d.params.local_mem_banks == 1 assert d.params.warp_size == 1
def test_params(mock_backend): mock_backend.add_devices(['Device1']) api = API.from_api_id(mock_backend.api_id) platform = Platform.from_index(api, 0) device = Device.from_index(platform, 0) params1 = device.params params2 = device.params assert params1 is params2 # check caching
def test_all_by_shortcut_none(mock_backend_factory): api_ids = all_api_ids() for api_id in api_ids: backend = mock_backend_factory.mock(api_id) backend.add_devices(['Device1', 'Device2']) apis = API.all_by_shortcut() assert len(apis) == len(api_ids) assert set(api.id for api in apis) == set(api_ids)
def test_all_by_masks(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices('foo-bar', ['Device1']) mock_backend_pyopencl.add_platform_with_devices('bar-baz', ['Device2']) mock_backend_pyopencl.add_platform_with_devices('foo-baz', ['Device3']) api = API.from_api_id(mock_backend_pyopencl.api_id) platforms = Platform.all_by_masks(api, include_masks=['foo'], exclude_masks=['bar']) assert len(platforms) == 1 assert platforms[0].name == 'foo-baz'
def test_device_parameters_opencl_apple_cpu(mock_backend_pyopencl): device_info = PyOpenCLDeviceInfo(type=DeviceType.CPU, max_work_group_size=512) mock_backend_pyopencl.add_platform_with_devices('Apple', [device_info]) api = API.from_api_id(mock_backend_pyopencl.api_id) d = api.platforms[0].devices[0] assert d.params.max_total_local_size == 1 assert d.params.max_local_sizes == (1, 1, 1)
def test_getitem(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices('Platform0', ['Device0']) mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1', 'Device2']) api = API.from_api_id(mock_backend_pyopencl.api_id) p1 = Platform.from_index(api, 1) assert p1.devices[0].name == 'Device1' assert p1.devices[1].name == 'Device2'
def test_from_devices(mock_backend): mock_backend.add_devices(['Device2', 'Device3']) api = API.from_api_id(mock_backend.api_id) platform = api.platforms[0] devices = platform.devices[:] context = Context.from_devices(devices) assert context.platform == platform assert [device.as_unbound() for device in context.devices] == devices
def test_attributes(mock_backend): mock_backend.add_devices(['Device1']) api = API.from_api_id(mock_backend.api_id) p = Platform.from_index(api, 0) d = Device.from_index(p, 0) assert d.platform == p assert d.name == 'Device1' assert d.shortcut == p.shortcut + ',0' assert str(d) == 'device(' + d.shortcut + ')'
def test_device_parameters_cuda_1(mock_backend_pycuda): # CUDA 1.x device_info = PyCUDADeviceInfo(compute_capability=1) mock_backend_pycuda.add_devices([device_info]) api = API.from_api_id(mock_backend_pycuda.api_id) d = api.platforms[0].devices[0] assert d.params.local_mem_banks == 16
def test_eq(mock_backend): mock_backend.add_devices(['Device0', 'Device1']) api = API.from_api_id(mock_backend.api_id) platform = Platform.from_index(api, 0) d0_v1 = Device.from_index(platform, 0) d0_v2 = Device.from_index(platform, 0) d1 = Device.from_index(platform, 1) assert d0_v1 is not d0_v2 and d0_v1 == d0_v2 assert d0_v1 != d1
def test_hash(mock_backend): mock_backend.add_devices(['Device0', 'Device1']) api = API.from_api_id(mock_backend.api_id) platform = Platform.from_index(api, 0) d0 = Device.from_index(platform, 0) d1 = Device.from_index(platform, 1) d = {d0: 0, d1: 1} assert d[d0] == 0 assert d[d1] == 1
def test_deactivate(mock_backend_pyopencl, mock_backend_pycuda): mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1']) mock_backend_pycuda.add_devices(['Device1']) api = API.from_api_id(mock_backend_pyopencl.api_id) context = Context.from_devices(api.platforms[0].devices[0]) with pytest.raises(RuntimeError, match="`deactivate\\(\\)` only works for CUDA API"): context.deactivate() backend_context = mock_backend_pycuda.pycuda_driver.Device( 0).make_context() backend_context.pop() api = API.from_api_id(mock_backend_pycuda.api_id) context = Context.from_backend_contexts(backend_context, take_ownership=True) assert backend_context.is_stacked() context.deactivate() assert not backend_context.is_stacked()
def test_from_devices_different_platforms(mock_backend_pyopencl): mock_backend_pyopencl.add_platform_with_devices('Platform1', ['Device1', 'Device2']) mock_backend_pyopencl.add_platform_with_devices('Platform2', ['Device3', 'Device4']) api = API.from_api_id(mock_backend_pyopencl.api_id) with pytest.raises(ValueError, match="All devices must belong to the same platform"): Context.from_devices( [api.platforms[0].devices[0], api.platforms[1].devices[0]])