def test_sliced_iteration_llvm(): size = (4, 4) src_arr = np.ones(size) dst_arr = np.zeros_like(src_arr) src_field = Field.create_from_numpy_array('src', src_arr) dst_field = Field.create_from_numpy_array('dst', dst_arr) a, b = sp.symbols("a b") update_rule = Assignment(dst_field[0, 0], (a * src_field[0, 1] + a * src_field[0, -1] + b * src_field[1, 0] + b * src_field[-1, 0]) / 4) x_end = TypedSymbol("x_end", "int") s = make_slice[1:x_end, 1] x_end_value = size[1] - 1 import pystencils.llvm as llvm_generator ast = llvm_generator.create_kernel(sympy_cse_on_assignment_list( [update_rule]), iteration_slice=s) kernel = llvm_generator.make_python_function(ast) kernel(src=src_arr, dst=dst_arr, a=1.0, b=1.0, x_end=x_end_value) expected_result = np.zeros(size) expected_result[1:x_end_value, 1] = 1 np.testing.assert_almost_equal(expected_result, dst_arr)
def test_full_scalar_field(): """Tests fully (un)packing a scalar field (from)to a buffer.""" fields = _generate_fields() for (src_arr, dst_arr, buffer_arr) in fields: src_field = Field.create_from_numpy_array("src_field", src_arr) dst_field = Field.create_from_numpy_array("dst_field", dst_arr) buffer = Field.create_generic("buffer", spatial_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [Assignment(buffer.center(), src_field.center())] pack_code = create_kernel(pack_eqs, data_type={ 'src_field': src_arr.dtype, 'buffer': buffer.dtype }) pack_kernel = pack_code.compile() pack_kernel(buffer=buffer_arr, src_field=src_arr) unpack_eqs = [Assignment(dst_field.center(), buffer.center())] unpack_code = create_kernel(unpack_eqs, data_type={ 'dst_field': dst_arr.dtype, 'buffer': buffer.dtype }) unpack_kernel = unpack_code.compile() unpack_kernel(dst_field=dst_arr, buffer=buffer_arr) np.testing.assert_equal(src_arr, dst_arr)
def test_ghost_layer(): size = (6, 5) src_arr = np.ones(size) dst_arr = np.zeros_like(src_arr) src_field = Field.create_from_numpy_array('src', src_arr, index_dimensions=0) dst_field = Field.create_from_numpy_array('dst', dst_arr, index_dimensions=0) update_rule = Assignment(dst_field[0, 0], src_field[0, 0]) ghost_layers = [(1, 2), (2, 1)] ast = create_cuda_kernel([update_rule], ghost_layers=ghost_layers, indexing_creator=LineIndexing) kernel = make_python_function(ast) gpu_src_arr = gpuarray.to_gpu(src_arr) gpu_dst_arr = gpuarray.to_gpu(dst_arr) kernel(src=gpu_src_arr, dst=gpu_dst_arr) gpu_dst_arr.get(dst_arr) reference = np.zeros_like(src_arr) reference[ghost_layers[0][0]:-ghost_layers[0][1], ghost_layers[1][0]:-ghost_layers[1][1]] = 1 np.testing.assert_equal(reference, dst_arr)
def test_averaging_kernel(): size = (40, 55) src_arr = np.random.rand(*size) src_arr = add_ghost_layers(src_arr) dst_arr = np.zeros_like(src_arr) src_field = Field.create_from_numpy_array('src', src_arr) dst_field = Field.create_from_numpy_array('dst', dst_arr) update_rule = Assignment(dst_field[0, 0], (src_field[0, 1] + src_field[0, -1] + src_field[1, 0] + src_field[-1, 0]) / 4) ast = create_cuda_kernel(sympy_cse_on_assignment_list([update_rule])) kernel = make_python_function(ast) gpu_src_arr = gpuarray.to_gpu(src_arr) gpu_dst_arr = gpuarray.to_gpu(dst_arr) kernel(src=gpu_src_arr, dst=gpu_dst_arr) gpu_dst_arr.get(dst_arr) stencil = np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) / 4.0 reference = convolve(remove_ghost_layers(src_arr), stencil, mode='constant', cval=0.0) reference = add_ghost_layers(reference) np.testing.assert_almost_equal(reference, dst_arr)
def test_jacobi_fixed_field_size(): size = (30, 20) src_field_llvm = np.random.rand(*size) src_field_py = np.copy(src_field_llvm) dst_field_llvm = np.zeros(size) dst_field_py = np.zeros(size) f = Field.create_from_numpy_array("f", src_field_llvm) d = Field.create_from_numpy_array("d", dst_field_llvm) jacobi = Assignment(d[0, 0], (f[1, 0] + f[-1, 0] + f[0, 1] + f[0, -1]) / 4) ast = create_kernel([jacobi]) for x in range(1, size[0] - 1): for y in range(1, size[1] - 1): dst_field_py[ x, y] = 0.25 * (src_field_py[x - 1, y] + src_field_py[x + 1, y] + src_field_py[x, y - 1] + src_field_py[x, y + 1]) jit = generate_and_jit(ast) jit('kernel', dst_field_llvm, src_field_llvm) error = np.sum(np.abs(dst_field_py - dst_field_llvm)) np.testing.assert_almost_equal(error, 0.0)
def test_full_scalar_field(): """Tests fully (un)packing a scalar field (from)to a GPU buffer.""" fields = _generate_fields() for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: src_field = Field.create_from_numpy_array("src_field", src_arr) dst_field = Field.create_from_numpy_array("dst_field", src_arr) buffer = Field.create_generic("buffer", spatial_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [Assignment(buffer.center(), src_field.center())] pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr) unpack_eqs = [Assignment(dst_field.center(), buffer.center())] unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(dst_field=gpu_dst_arr, buffer=gpu_buffer_arr) dst_arr = gpu_dst_arr.get() np.testing.assert_equal(src_arr, dst_arr)
def test_indexed_cuda_kernel(): try: import pycuda except ImportError: pycuda = None if pycuda: from pystencils.gpucuda import make_python_function import pycuda.gpuarray as gpuarray from pystencils.gpucuda.kernelcreation import created_indexed_cuda_kernel arr = np.zeros((3, 4)) dtype = np.dtype([('x', int), ('y', int), ('value', arr.dtype)]) index_arr = np.zeros((3, ), dtype=dtype) index_arr[0] = (0, 2, 3.0) index_arr[1] = (1, 3, 42.0) index_arr[2] = (2, 1, 5.0) indexed_field = Field.create_from_numpy_array('index', index_arr) normal_field = Field.create_from_numpy_array('f', arr) update_rule = Assignment(normal_field[0, 0], indexed_field('value')) ast = created_indexed_cuda_kernel([update_rule], [indexed_field]) kernel = make_python_function(ast) gpu_arr = gpuarray.to_gpu(arr) gpu_index_arr = gpuarray.to_gpu(index_arr) kernel(f=gpu_arr, index=gpu_index_arr) gpu_arr.get(arr) for i in range(index_arr.shape[0]): np.testing.assert_allclose(arr[index_arr[i]['x'], index_arr[i]['y']], index_arr[i]['value'], atol=1e-13) else: print("Did not run test on GPU since no pycuda is available")
def test_flag_condition(): f_arr = np.zeros((2, 2, 2), dtype=np.float64) mask_arr = np.zeros((2, 2), dtype=np.uint64) mask_arr[0, 1] = (1 << 3) mask_arr[1, 0] = (1 << 5) mask_arr[1, 1] = (1 << 3) + (1 << 5) f = Field.create_from_numpy_array('f', f_arr, index_dimensions=1) mask = Field.create_from_numpy_array('mask', mask_arr) v1 = 42.3 v2 = 39.7 v3 = 119.87 assignments = [ Assignment(f(0), flag_cond(3, mask(0), v1)), Assignment(f(1), flag_cond(5, mask(0), v2, v3)) ] kernel = create_kernel(assignments).compile() kernel(f=f_arr, mask=mask_arr) reference = np.zeros((2, 2, 2), dtype=np.float64) reference[0, 1, 0] = v1 reference[1, 1, 0] = v1 reference[0, 0, 1] = v3 reference[0, 1, 1] = v3 reference[1, 0, 1] = v2 reference[1, 1, 1] = v2 np.testing.assert_array_equal(f_arr, reference)
def test_fixed_size_mismatch_check(): """Create kernel with two differently sized but constant fields """ src = np.zeros((20, 21, 9)) dst = np.zeros((21, 21, 9)) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_from_numpy_array("dst", dst, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) with pytest.raises(ValueError) as e: create_kernel([update_rule]) assert 'Differently sized field accesses' in str(e.value)
def test_subset_cell_values(): """Tests (un)packing a subset of cell values of the a field (from)to a buffer.""" num_cell_values = 7 # Cell indices of the field to be (un)packed (from)to the buffer cell_indices = [1, 3, 5, 6] fields = _generate_fields(stencil_directions=num_cell_values) for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: src_field = Field.create_from_numpy_array("src_field", gpu_src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", gpu_src_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=gpu_src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for buffer_idx, cell_idx in enumerate(cell_indices): eq = Assignment(buffer(buffer_idx), src_field(cell_idx)) pack_eqs.append(eq) pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr) unpack_eqs = [] for buffer_idx, cell_idx in enumerate(cell_indices): eq = Assignment(dst_field(cell_idx), buffer(buffer_idx)) unpack_eqs.append(eq) unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(buffer=gpu_buffer_arr, dst_field=gpu_dst_arr) dst_arr = gpu_dst_arr.get() mask_arr = np.ma.masked_where((src_arr - dst_arr) != 0, src_arr) np.testing.assert_equal(dst_arr, mask_arr.filled(int(0)))
def test_fixed_size_mismatch_check(): """Create kernel with two differently sized but constant fields """ src = np.zeros((20, 21, 9)) dst = np.zeros((21, 21, 9)) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_from_numpy_array("dst", dst, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) try: create_kernel([update_rule]) assert False, "Expected ValueError because fields with different sized where passed" except ValueError: pass
def test_subset_cell_values(): """Tests (un)packing a subset of cell values of the a field (from)to a buffer.""" num_cell_values = 19 # Cell indices of the field to be (un)packed (from)to the buffer cell_indices = [1, 5, 7, 8, 10, 12, 13] fields = _generate_fields(num_directions=num_cell_values) for (src_arr, dst_arr, bufferArr) in fields: src_field = Field.create_from_numpy_array("src_field", src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", dst_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for buffer_idx, cell_idx in enumerate(cell_indices): eq = Assignment(buffer(buffer_idx), src_field(cell_idx)) pack_eqs.append(eq) pack_code = create_kernel(pack_eqs, data_type={ 'src_field': src_arr.dtype, 'buffer': buffer.dtype }) pack_kernel = pack_code.compile() pack_kernel(buffer=bufferArr, src_field=src_arr) unpack_eqs = [] for buffer_idx, cell_idx in enumerate(cell_indices): eq = Assignment(dst_field(cell_idx), buffer(buffer_idx)) unpack_eqs.append(eq) unpack_code = create_kernel(unpack_eqs, data_type={ 'dst_field': dst_arr.dtype, 'buffer': buffer.dtype }) unpack_kernel = unpack_code.compile() unpack_kernel(buffer=bufferArr, dst_field=dst_arr) mask_arr = np.ma.masked_where((src_arr - dst_arr) != 0, src_arr) np.testing.assert_equal(dst_arr, mask_arr.filled(int(0)))
def test_all_cell_values(): """Tests (un)packing all cell values of the a field (from)to a buffer.""" num_cell_values = 7 fields = _generate_fields(stencil_directions=num_cell_values) for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: src_field = Field.create_from_numpy_array("src_field", gpu_src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", gpu_src_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=gpu_src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for idx in range(num_cell_values): eq = Assignment(buffer(idx), src_field(idx)) pack_eqs.append(eq) pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr) unpack_eqs = [] for idx in range(num_cell_values): eq = Assignment(dst_field(idx), buffer(idx)) unpack_eqs.append(eq) unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(buffer=gpu_buffer_arr, dst_field=gpu_dst_arr) dst_arr = gpu_dst_arr.get() np.testing.assert_equal(src_arr, dst_arr)
def test_all_cell_values(): """Tests (un)packing all cell values of the a field (from)to a buffer.""" num_cell_values = 19 fields = _generate_fields(num_directions=num_cell_values) for (src_arr, dst_arr, bufferArr) in fields: src_field = Field.create_from_numpy_array("src_field", src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", dst_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for idx in range(num_cell_values): eq = Assignment(buffer(idx), src_field(idx)) pack_eqs.append(eq) pack_code = create_kernel(pack_eqs, data_type={ 'src_field': src_arr.dtype, 'buffer': buffer.dtype }) pack_kernel = pack_code.compile() pack_kernel(buffer=bufferArr, src_field=src_arr) unpack_eqs = [] for idx in range(num_cell_values): eq = Assignment(dst_field(idx), buffer(idx)) unpack_eqs.append(eq) unpack_code = create_kernel(unpack_eqs, data_type={ 'dst_field': dst_arr.dtype, 'buffer': buffer.dtype }) unpack_kernel = unpack_code.compile() unpack_kernel(buffer=bufferArr, dst_field=dst_arr) np.testing.assert_equal(src_arr, dst_arr)
def test_field_layouts(): num_cell_values = 7 for layout_str in ['numpy', 'fzyx', 'zyxf', 'reverse_numpy']: fields = _generate_fields(stencil_directions=num_cell_values, layout=layout_str) for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: src_field = Field.create_from_numpy_array("src_field", gpu_src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", gpu_src_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for idx in range(num_cell_values): eq = Assignment(buffer(idx), src_field(idx)) pack_eqs.append(eq) pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr) unpack_eqs = [] for idx in range(num_cell_values): eq = Assignment(dst_field(idx), buffer(idx)) unpack_eqs.append(eq) unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(buffer=gpu_buffer_arr, dst_field=gpu_dst_arr)
def test_field_layouts(): num_cell_values = 27 for layout_str in ['numpy', 'fzyx', 'zyxf', 'reverse_numpy']: fields = _generate_fields(num_directions=num_cell_values, layout=layout_str) for (src_arr, dst_arr, bufferArr) in fields: src_field = Field.create_from_numpy_array("src_field", src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array("dst_field", dst_arr, index_dimensions=1) buffer = Field.create_generic("buffer", spatial_dimensions=1, index_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [] # Since we are packing all cell values for all cells, then # the buffer index is equivalent to the field index for idx in range(num_cell_values): eq = Assignment(buffer(idx), src_field(idx)) pack_eqs.append(eq) pack_code = create_kernel(pack_eqs, data_type={ 'src_field': src_arr.dtype, 'buffer': buffer.dtype }) pack_kernel = pack_code.compile() pack_kernel(buffer=bufferArr, src_field=src_arr) unpack_eqs = [] for idx in range(num_cell_values): eq = Assignment(dst_field(idx), buffer(idx)) unpack_eqs.append(eq) unpack_code = create_kernel(unpack_eqs, data_type={ 'dst_field': dst_arr.dtype, 'buffer': buffer.dtype }) unpack_kernel = unpack_code.compile() unpack_kernel(buffer=bufferArr, dst_field=dst_arr)
def test_field_slice(): """Tests (un)packing slices of a scalar field (from)to a buffer.""" fields = _generate_fields() for d in ['N', 'S', 'NW', 'SW', 'TNW', 'B']: for (src_arr, gpu_src_arr, gpu_dst_arr, gpu_buffer_arr) in fields: # Extract slice from N direction of the field slice_dir = direction_string_to_offset(d, dim=len(src_arr.shape)) pack_slice = get_slice_before_ghost_layer(slice_dir) unpack_slice = get_ghost_region_slice(slice_dir) src_field = Field.create_from_numpy_array("src_field", src_arr[pack_slice]) dst_field = Field.create_from_numpy_array("dst_field", src_arr[unpack_slice]) buffer = Field.create_generic("buffer", spatial_dimensions=1, field_type=FieldType.BUFFER, dtype=src_arr.dtype) pack_eqs = [Assignment(buffer.center(), src_field.center())] pack_types = { 'src_field': gpu_src_arr.dtype, 'buffer': gpu_buffer_arr.dtype } pack_code = create_cuda_kernel(pack_eqs, type_info=pack_types) pack_kernel = make_python_function(pack_code) pack_kernel(buffer=gpu_buffer_arr, src_field=gpu_src_arr[pack_slice]) # Unpack into ghost layer of dst_field in N direction unpack_eqs = [Assignment(dst_field.center(), buffer.center())] unpack_types = { 'dst_field': gpu_dst_arr.dtype, 'buffer': gpu_buffer_arr.dtype } unpack_code = create_cuda_kernel(unpack_eqs, type_info=unpack_types) unpack_kernel = make_python_function(unpack_code) unpack_kernel(buffer=gpu_buffer_arr, dst_field=gpu_dst_arr[unpack_slice]) dst_arr = gpu_dst_arr.get() np.testing.assert_equal(src_arr[pack_slice], dst_arr[unpack_slice])
def test_indexed_kernel(): arr = np.zeros((3, 4)) dtype = np.dtype([('x', int), ('y', int), ('value', arr.dtype)]) index_arr = np.zeros((3, ), dtype=dtype) index_arr[0] = (0, 2, 3.0) index_arr[1] = (1, 3, 42.0) index_arr[2] = (2, 1, 5.0) indexed_field = Field.create_from_numpy_array('index', index_arr) normal_field = Field.create_from_numpy_array('f', arr) update_rule = Assignment(normal_field[0, 0], indexed_field('value')) ast = create_indexed_kernel([update_rule], [indexed_field]) kernel = make_python_function(ast) kernel(f=arr, index=index_arr) for i in range(index_arr.shape[0]): np.testing.assert_allclose(arr[index_arr[i]['x'], index_arr[i]['y']], index_arr[i]['value'], atol=1e-13)
def test_2d_5pt(): size = [30, 50, 3] kernel_file_path = os.path.join(INPUT_FOLDER, "2d-5pt.c") with open(kernel_file_path) as kernel_file: reference_kernel = kerncraft.kernel.KernelCode(kernel_file.read(), machine=None, filename=kernel_file_path) reference = analysis(reference_kernel) arr = np.zeros(size) a = Field.create_from_numpy_array('a', arr, index_dimensions=1) b = Field.create_from_numpy_array('b', arr, index_dimensions=1) s = sp.Symbol("s") rhs = a[0, -1](0) + a[0, 1] + a[-1, 0] + a[1, 0] update_rule = Assignment(b[0, 0], s * rhs) ast = create_kernel([update_rule]) k = PyStencilsKerncraftKernel(ast) result = analysis(k) for e1, e2 in zip(reference.results['cycles'], result.results['cycles']): assert e1 == e2
def test_size_check(): """Kernel with two fixed-sized fields creating with same size but calling with wrong size""" src = np.zeros((20, 21, 9)) dst = np.zeros_like(src) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_from_numpy_array("dst", dst, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) ast = create_kernel([update_rule]) func = ast.compile() # change size of src field new_shape = [a - 7 for a in src.shape] src = np.zeros(new_shape) dst = np.zeros(new_shape) with pytest.raises(ValueError) as e: func(src=src, dst=dst) assert 'Wrong shape' in str(e.value)
def test_compilation(): machine_file_path = os.path.join(INPUT_FOLDER, "default_machine_file.yaml") machine = kerncraft.machinemodel.MachineModel(path_to_yaml=machine_file_path) kernel_file_path = os.path.join(INPUT_FOLDER, "2d-5pt.c") with open(kernel_file_path) as kernel_file: reference_kernel = kerncraft.kernel.KernelCode(kernel_file.read(), machine=machine, filename=kernel_file_path) reference_kernel.as_code('likwid') size = [30, 50, 3] arr = np.zeros(size) a = Field.create_from_numpy_array('a', arr, index_dimensions=1) b = Field.create_from_numpy_array('b', arr, index_dimensions=1) s = sp.Symbol("s") rhs = a[0, -1](0) + a[0, 1] + a[-1, 0] + a[1, 0] update_rule = Assignment(b[0, 0], s * rhs) ast = create_kernel([update_rule]) mine = generate_benchmark(ast, likwid=False) print(mine)
def test_fixed_sized_field(): for order in ('f', 'c'): for align in (True, False): dt = np.dtype([('e1', np.float32), ('e2', np.double), ('e3', np.double)], align=align) arr = np.zeros((3, 2), dtype=dt, order=order) f = Field.create_from_numpy_array("f", arr) d = Field.create_from_numpy_array("d", arr) update_rules = [Assignment(d[0, 0]['e2'], f[0, 0]['e3'])] result = arr.copy(order=order) assert result.strides == arr.strides arr['e2'] = 0 arr['e3'] = np.random.rand(3, 2) kernel = create_kernel(update_rules).compile() kernel(f=arr, d=result) np.testing.assert_almost_equal(result['e2'], arr['e3']) np.testing.assert_equal(arr['e2'], np.zeros((3, 2)))
def test_size_check(): """Kernel with two fixed-sized fields creating with same size but calling with wrong size""" src = np.zeros((20, 21, 9)) dst = np.zeros_like(src) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_from_numpy_array("dst", dst, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) ast = create_kernel([update_rule]) func = make_python_function(ast) # change size of src field new_shape = [a - 7 for a in src.shape] src = np.zeros(new_shape) dst = np.zeros(new_shape) try: func(src=src, dst=dst) assert False, "Expected ValueError because fields with different sized where passed" except ValueError: pass
def meassure(): size = [30, 50, 3] arr = np.zeros(size) a = Field.create_from_numpy_array('a', arr, index_dimensions=1) b = Field.create_from_numpy_array('b', arr, index_dimensions=1) s = sp.Symbol("s") rhs = a[0, -1](0) + a[0, 1] + a[-1, 0] + a[1, 0] updateRule = Assignment(b[0, 0], s * rhs) print(updateRule) ast = create_kernel([updateRule]) # benchmark = generate_benchmark(ast) # main = benchmark[0] # kernel = benchmark[1] # with open('src/main.cpp', 'w') as file: # file.write(main) # with open('src/kernel.cpp', 'w') as file: # file.write(kernel) func = ast.compile({'omega': 2 / 3}) from pystencils.kerncraft_coupling.generate_benchmark import generate_benchmark from pystencils.kerncraft_coupling import BenchmarkAnalysis from pystencils.kerncraft_coupling.kerncraft_interface import PyStencilsKerncraftKernel, KerncraftParameters from kerncraft.machinemodel import MachineModel from kerncraft.models import ECMData machineFilePath = "../pystencils_tests/kerncraft_inputs/default_machine_file.yaml" machine = MachineModel(path_to_yaml=machineFilePath) benchmark = BenchmarkAnalysis(ast, machine) #TODO what do i want to do with benchmark? kernel = PyStencilsKerncraftKernel(ast) model = ECMData(kernel, machine, KerncraftParameters()) model.analyze() model.report()
def test_fixed_and_variable_field_check(): """Create kernel with two variable sized fields - calling them with different sizes""" src = np.zeros((20, 21, 9)) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_generic("dst", spatial_dimensions=2, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) with pytest.raises(ValueError) as e: create_kernel(update_rule) assert 'Mixing fixed-shaped and variable-shape fields' in str(e.value)
def test_multiple_index_dimensions(): """Sums along the last axis of a numpy array""" src_size = (7, 6, 4) dst_size = src_size[:2] src_arr = np.asfortranarray(np.random.rand(*src_size)) dst_arr = np.zeros(dst_size) src_field = Field.create_from_numpy_array('src', src_arr, index_dimensions=1) dst_field = Field.create_from_numpy_array('dst', dst_arr, index_dimensions=0) offset = (-2, -1) update_rule = Assignment( dst_field[0, 0], sum([src_field[offset[0], offset[1]](i) for i in range(src_size[-1])])) ast = create_cuda_kernel([update_rule]) kernel = make_python_function(ast) gpu_src_arr = gpuarray.to_gpu(src_arr) gpu_dst_arr = gpuarray.to_gpu(dst_arr) kernel(src=gpu_src_arr, dst=gpu_dst_arr) gpu_dst_arr.get(dst_arr) reference = np.zeros_like(dst_arr) gl = np.max(np.abs(np.array(offset, dtype=int))) for x in range(gl, src_size[0] - gl): for y in range(gl, src_size[1] - gl): reference[x, y] = sum([ src_arr[x + offset[0], y + offset[1], i] for i in range(src_size[2]) ]) np.testing.assert_almost_equal(reference, dst_arr)
def main(): size = [20, 200, 200] arr = np.zeros(size) a = Field.create_from_numpy_array('a', arr, index_dimensions=0) b = Field.create_from_numpy_array('b', arr, index_dimensions=0) s = sp.Symbol("s") rhs = a[0, -1, 0] + a[0, 1, 0] + \ a[-1, 0, 0] + a[1, 0, 0] + \ a[0, 0, -1] + a[0, 0, 1] update_rule = Assignment(b[0, 0, 0], s * rhs) ast = create_kernel([update_rule]) input_folder = "./" machine_file_path = os.path.join(input_folder, "SkylakeSP_Gold-5122_allinclusive.yaml") machine = MachineModel(path_to_yaml=machine_file_path) tags = { 'host': os.uname()[1], 'project': 'pystencils', 'kernel': 'jacobi_3D ' + str(size) } report_analysis(ast, [ECM, Roofline, RooflineIACA, Benchmark], machine, tags)
def test_3d_7pt_iaca(): # Make sure you use the intel compiler size = [20, 200, 200] kernel_file_path = os.path.join(INPUT_FOLDER, "3d-7pt.c") machine_file_path = os.path.join(INPUT_FOLDER, "default_machine_file.yaml") machine = kerncraft.machinemodel.MachineModel(path_to_yaml=machine_file_path) with open(kernel_file_path) as kernel_file: reference_kernel = kerncraft.kernel.KernelCode(kernel_file.read(), machine=machine, filename=kernel_file_path) reference_kernel.set_constant('M', size[0]) reference_kernel.set_constant('N', size[1]) assert size[1] == size[2] analysis(reference_kernel, model='ecm') arr = np.zeros(size) a = Field.create_from_numpy_array('a', arr, index_dimensions=0) b = Field.create_from_numpy_array('b', arr, index_dimensions=0) s = sp.Symbol("s") rhs = a[0, -1, 0] + a[0, 1, 0] + a[-1, 0, 0] + a[1, 0, 0] + a[0, 0, -1] + a[0, 0, 1] update_rule = Assignment(b[0, 0, 0], s * rhs) ast = create_kernel([update_rule]) k = PyStencilsKerncraftKernel(ast, machine) analysis(k, model='ecm') assert reference_kernel._flops == k._flops
def test_fixed_and_variable_field_check(): """Create kernel with two variable sized fields - calling them with different sizes""" src = np.zeros((20, 21, 9)) sym_src = Field.create_from_numpy_array("src", src, index_dimensions=1) sym_dst = Field.create_generic("dst", spatial_dimensions=2, index_dimensions=1) update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) try: create_kernel([update_rule]) assert False, "Expected ValueError because fields with different sized where passed" except ValueError: pass
def create_field_from_array_like(field_name, maybe_array, annotations=None): if annotations and isinstance(annotations, dict): index_dimensions = annotations.get('index_dimensions', 0) field_type = annotations.get('field_type', FieldType.GENERIC) elif isinstance(maybe_array, ArrayWrapper): index_dimensions = maybe_array.index_dimensions field_type = maybe_array.field_type maybe_array = maybe_array.array else: index_dimensions = 0 field_type = FieldType.GENERIC if 'tensorflow' in str(type(maybe_array)) and 'Tensor' in str( type(maybe_array)): try: # This fails on eager execution return Field.create_fixed_size( maybe_array.name or field_name, maybe_array.shape, index_dimensions=index_dimensions, dtype=maybe_array.dtype.as_numpy_dtype()) except Exception: return Field.create_fixed_size( field_name, maybe_array.shape, index_dimensions=index_dimensions, dtype=maybe_array.dtype.as_numpy_dtype()) elif 'torch.Tensor' in str(type(maybe_array)): maybe_array = _torch_tensor_to_numpy_shim(maybe_array) field = Field.create_from_numpy_array(field_name, maybe_array, index_dimensions) field.field_type = field_type if hasattr(maybe_array, 'coordinate_transform'): field.coordinate_transform = maybe_array.coordinate_transform if hasattr(maybe_array, 'coordinate_origin'): field.coordinate_origin = maybe_array.coordinate_origin return field