diff --git a/pystencils/astnodes.py b/pystencils/astnodes.py index 062d3687f582423bd38b8a1c2e9dae3ff95a6bfb..8ec80917af20aefc5883c68ac51f360005b4350b 100644 --- a/pystencils/astnodes.py +++ b/pystencils/astnodes.py @@ -291,7 +291,10 @@ class Block(Node): self._nodes = nodes self.parent = None for n in self._nodes: - n.parent = self + try: + n.parent = self + except AttributeError: + pass @property def args(self): diff --git a/pystencils/backends/cbackend.py b/pystencils/backends/cbackend.py index 9efca1f53a6870d2b0ce2bdd1da547d16beb6a6c..1c7c722cbe273329bc2a15521fbc933b00f56606 100644 --- a/pystencils/backends/cbackend.py +++ b/pystencils/backends/cbackend.py @@ -386,6 +386,13 @@ class CustomSympyPrinter(CCodePrinter): return self._print(expr.args[0]) elif isinstance(expr, fast_inv_sqrt): return "({})".format(self._print(1 / sp.sqrt(expr.args[0]))) + elif isinstance(expr, sp.Abs): + return "abs({})".format(self._print(expr.args[0])) + elif isinstance(expr, sp.Mod): + if expr.is_integer: + return "({} % {})".format(self._print(expr.args[0]), self._print(expr.args[1])) + else: + return "fmod({}, {})".format(self._print(expr.args[0]), self._print(expr.args[1])) elif expr.func in infix_functions: return "(%s %s %s)" % (self._print(expr.args[0]), infix_functions[expr.func], self._print(expr.args[1])) elif expr.func == int_power_of_2: diff --git a/pystencils_tests/test_boundary.py b/pystencils_tests/test_boundary.py index 096b1348fc59181e14eb15042d8db0098e71c521..23770c8ef6d61c15110f94875b0000c3e7d11fac 100644 --- a/pystencils_tests/test_boundary.py +++ b/pystencils_tests/test_boundary.py @@ -3,6 +3,8 @@ from tempfile import TemporaryDirectory import numpy as np +import pytest + from pystencils import Assignment, create_kernel from pystencils.boundaries import BoundaryHandling, Neumann, add_neumann_boundary from pystencils.datahandling import SerialDataHandling @@ -83,5 +85,6 @@ def test_kernel_vs_copy_boundary(): np.testing.assert_almost_equal(python_copy_result, handling_result) with TemporaryDirectory() as tmp_dir: + pytest.importorskip('pyevtk') boundary_handling.geometry_to_vtk(file_name=os.path.join(tmp_dir, 'test_output1'), ghost_layers=False) boundary_handling.geometry_to_vtk(file_name=os.path.join(tmp_dir, 'test_output2'), ghost_layers=True) diff --git a/pystencils_tests/test_buffer_gpu.py b/pystencils_tests/test_buffer_gpu.py index fc27a2331be1690b8bb1d0da043b47b3ba6fcfc9..f9ee96e9b19c147d95f006de4221980900375cb1 100644 --- a/pystencils_tests/test_buffer_gpu.py +++ b/pystencils_tests/test_buffer_gpu.py @@ -22,6 +22,7 @@ FIELD_SIZES = [(4, 3), (9, 3, 7)] def _generate_fields(dt=np.uint8, stencil_directions=1, layout='numpy'): + pytest.importorskip('pycuda') field_sizes = FIELD_SIZES if stencil_directions > 1: field_sizes = [s + (stencil_directions,) for s in field_sizes] @@ -44,7 +45,6 @@ def _generate_fields(dt=np.uint8, stencil_directions=1, layout='numpy'): return fields -@pytest.mark.gpu def test_full_scalar_field(): """Tests fully (un)packing a scalar field (from)to a GPU buffer.""" fields = _generate_fields() @@ -73,7 +73,6 @@ def test_full_scalar_field(): np.testing.assert_equal(src_arr, dst_arr) -@pytest.mark.gpu def test_field_slice(): """Tests (un)packing slices of a scalar field (from)to a buffer.""" fields = _generate_fields() @@ -109,7 +108,6 @@ def test_field_slice(): np.testing.assert_equal(src_arr[pack_slice], dst_arr[unpack_slice]) -@pytest.mark.gpu def test_all_cell_values(): """Tests (un)packing all cell values of the a field (from)to a buffer.""" num_cell_values = 7 @@ -148,7 +146,6 @@ def test_all_cell_values(): np.testing.assert_equal(src_arr, dst_arr) -@pytest.mark.gpu 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 @@ -190,7 +187,6 @@ def test_subset_cell_values(): np.testing.assert_equal(dst_arr, mask_arr.filled(int(0))) -@pytest.mark.gpu def test_field_layouts(): num_cell_values = 7 for layout_str in ['numpy', 'fzyx', 'zyxf', 'reverse_numpy']: diff --git a/pystencils_tests/test_complex_numbers.py b/pystencils_tests/test_complex_numbers.py index 9f9164640f50e417348ee635af620dd891249d77..b1c0569d05e73a786a780d7f4826eedf8d71b533 100644 --- a/pystencils_tests/test_complex_numbers.py +++ b/pystencils_tests/test_complex_numbers.py @@ -57,6 +57,9 @@ def test_complex_numbers(assignment, scalar_dtypes, target): print(code) assert "Not supported" not in code + if target == 'gpu': + pytest.importorskip('pycuda') + kernel = ast.compile() assert kernel is not None @@ -100,6 +103,9 @@ def test_complex_numbers_64(assignment, target): print(code) assert "Not supported" not in code + if target == 'gpu': + pytest.importorskip('pycuda') + kernel = ast.compile() assert kernel is not None @@ -125,6 +131,7 @@ def test_complex_execution(dtype, target, with_complex_argument): }) if target == 'gpu': + pytest.importorskip('pycuda') from pycuda.gpuarray import zeros x_arr = zeros((20, 30), complex_dtype) y_arr = zeros((20, 30), complex_dtype) diff --git a/pystencils_tests/test_cuda_known_functions.py b/pystencils_tests/test_cuda_known_functions.py index fe33b98df27cc6a6c2ec77eda49e704b9afbec5e..99810a55af73907b686f342a8dba1f2053cbabe7 100644 --- a/pystencils_tests/test_cuda_known_functions.py +++ b/pystencils_tests/test_cuda_known_functions.py @@ -1,5 +1,7 @@ import sympy +import pytest + import pystencils from pystencils.astnodes import get_dummy_symbol from pystencils.backends.cuda_backend import CudaSympyPrinter @@ -19,6 +21,7 @@ def test_cuda_known_functions(): ast = pystencils.create_kernel(assignments, 'gpu') print(pystencils.show_code(ast)) + pytest.importorskip('pycuda') kernel = ast.compile() assert(kernel is not None) diff --git a/pystencils_tests/test_datahandling.py b/pystencils_tests/test_datahandling.py index 1b79fdbec5aa8bbbfb90450d2014d058065e998b..55b845f7b941316277cc9595058fdb42b07e665c 100644 --- a/pystencils_tests/test_datahandling.py +++ b/pystencils_tests/test_datahandling.py @@ -3,6 +3,8 @@ from tempfile import TemporaryDirectory import numpy as np +import pytest + import pystencils as ps from pystencils import create_data_handling, create_kernel @@ -128,6 +130,7 @@ def kernel_execution_jacobi(dh, target): def vtk_output(dh): + pytest.importorskip('pyevtk') dh.add_array('scalar_field') dh.add_array('vector_field', values_per_cell=dh.dim) dh.add_array('multiple_scalar_field', values_per_cell=9) @@ -223,6 +226,7 @@ def test_kernel_param(target): def test_vtk_output(): + pytest.importorskip('pyevtk') for domain_shape in [(4, 5), (3, 4, 5)]: dh = create_data_handling(domain_size=domain_shape, periodicity=True) vtk_output(dh) diff --git a/pystencils_tests/test_phasefield_dentritic_3D.ipynb b/pystencils_tests/test_phasefield_dentritic_3D.ipynb index aebdeefdddf53e9736feb7d8673c09bc5d8fa6d0..1a01f103891fb229385d8192f263fb53dd837a78 100644 --- a/pystencils_tests/test_phasefield_dentritic_3D.ipynb +++ b/pystencils_tests/test_phasefield_dentritic_3D.ipynb @@ -1,5 +1,15 @@ { "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pytest\n", + "pytest.importorskip('pycuda')" + ] + }, { "cell_type": "code", "execution_count": 1, diff --git a/pystencils_tests/test_print_infinity.py b/pystencils_tests/test_print_infinity.py index 4b1e488822163e684dcad4009fca1b72c7d87d2c..9e2dbd29b18389265b206513ec6c4625e0722a10 100644 --- a/pystencils_tests/test_print_infinity.py +++ b/pystencils_tests/test_print_infinity.py @@ -17,6 +17,9 @@ def test_print_infinity(type, negative, target): assignment = pystencils.Assignment(x.center, oo) ast = pystencils.create_kernel(assignment, data_type=type, target=target) + if target == 'gpu': + pytest.importorskip('pycuda') + ast.compile() print(ast.compile().code) diff --git a/pystencils_tests/test_random.py b/pystencils_tests/test_random.py index 473aa3d1215449f51e70aa3b09f2c605ed13c313..1b3f89f2f81aa6e079f7bc030f27da74e778dd13 100644 --- a/pystencils_tests/test_random.py +++ b/pystencils_tests/test_random.py @@ -1,5 +1,7 @@ import numpy as np +import pytest + import pystencils as ps from pystencils.rng import PhiloxFourFloats, PhiloxTwoDoubles, AESNIFourFloats, AESNITwoDoubles @@ -12,6 +14,9 @@ philox_reference = np.array([[[3576608082, 1252663339, 1987745383, 348040302], def test_philox_double(): for target in ('cpu', 'gpu'): + if target == 'gpu': + pytest.importorskip('pycuda') + dh = ps.create_data_handling((2, 2), default_ghost_layers=0, default_target=target) f = dh.add_array("f", values_per_cell=2) @@ -39,6 +44,9 @@ def test_philox_double(): def test_philox_float(): for target in ('cpu', 'gpu'): + if target == 'gpu': + pytest.importorskip('pycuda') + dh = ps.create_data_handling((2, 2), default_ghost_layers=0, default_target=target) f = dh.add_array("f", values_per_cell=4) diff --git a/pytest.ini b/pytest.ini index 4e9f5caddfef20639da974ad9327e53fa8b6ced4..0070425966626449378fcd1ff9eabe468256a112 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,7 +3,6 @@ python_files = test_*.py *_test.py scenario_*.py norecursedirs = *.egg-info .git .cache .ipynb_checkpoints htmlcov addopts = --doctest-modules --durations=20 --cov-config pytest.ini markers = - gpu: test that require a gpu kerncraft: tests depending on kerncraft [run]