diff --git a/src/pystencils/backend/functions.py b/src/pystencils/backend/functions.py index 4380d8c56f494732717469575ad4e122784928dc..39d5019ba4b14de11305563acaa1f9b26f2e60f9 100644 --- a/src/pystencils/backend/functions.py +++ b/src/pystencils/backend/functions.py @@ -36,14 +36,14 @@ class MathFunctions(Enum): Abs = ("abs", 1) - Min = ("min", 2) - Max = ("max", 2) + Min = ("fmin", 2) + Max = ("fmax", 2) Pow = ("pow", 2) - def __init__(self, func_name, arg_count): + def __init__(self, func_name, num_args): self.function_name = func_name - self.arg_count = arg_count + self.num_args = num_args class PsFunction(ABC): @@ -88,12 +88,9 @@ class PsMathFunction(PsFunction): """Homogenously typed mathematical functions.""" def __init__(self, func: MathFunctions) -> None: + super().__init__(func.function_name, func.num_args) self._func = func @property def func(self) -> MathFunctions: return self._func - - @property - def arg_count(self) -> int: - return self._func.arg_count diff --git a/src/pystencils/backend/kernelcreation/freeze.py b/src/pystencils/backend/kernelcreation/freeze.py index 6861ff4c588c0c8f5c92f963db393dc24c27f9b5..26dcc9d8e15066b61b99b5ce1dc7a73de137ba9b 100644 --- a/src/pystencils/backend/kernelcreation/freeze.py +++ b/src/pystencils/backend/kernelcreation/freeze.py @@ -26,7 +26,7 @@ from ..ast.expressions import ( PsConstantExpr, PsArrayInitList, PsSubscript, - PsCast + PsCast, ) from ..constants import PsConstant @@ -40,6 +40,32 @@ class FreezeError(Exception): class FreezeExpressions: + """Convert expressions and kernels expressed in the SymPy language to the code generator's internal representation. + + This class accepts a subset of the SymPy symbolic algebra language complemented with the extensions + implemented in `pystencils.sympyextensions`, and converts it to the abstract syntax tree representation + of the pystencils code generator. It is invoked early during the code generation process. + + TODO: Document the full set of supported SymPy features, with restrictions and caveats + TODO: Properly document the SymPy extensions provided by pystencils + + TODO: This is a (possibly incomplete) list of SymPy language features that still need to be implemented: + + - Augmented Assignments + - AddressOf + - Conditionals (+ frontend class) + - pystencils.integer_functions + - pystencils.sympyextensions.bit_masks + - GPU fast approximations (pystencils.fast_approximation) + - ConditionalFieldAccess + - sp.Piecewise + - sp.floor, sp.ceiling + - sp.log, sp.atan2, sp.sinh, sp.cosh. sp.atan + - sp.Min, sp.Max: multi-argument versions + - Modulus (sp.Mod) + + """ + def __init__(self, ctx: KernelCreationContext): self._ctx = ctx @@ -297,15 +323,19 @@ class FreezeExpressions: func_symbol = PsMathFunction(MathFunctions.Cos) case sp.tan(): func_symbol = PsMathFunction(MathFunctions.Tan) - case sp.Min(): - func_symbol = PsMathFunction(MathFunctions.Min) - case sp.Max(): - func_symbol = PsMathFunction(MathFunctions.Max) case _: raise FreezeError(f"Unsupported function: {func}") args = tuple(self.visit_expr(arg) for arg in func.args) return PsCall(func_symbol, args) - + + def map_Min(self, expr: sp.Min) -> PsCall: + args = tuple(self.visit_expr(arg) for arg in expr.args) + return PsCall(PsMathFunction(MathFunctions.Min), args) + + def map_Max(self, expr: sp.Max) -> PsCall: + args = tuple(self.visit_expr(arg) for arg in expr.args) + return PsCall(PsMathFunction(MathFunctions.Max), args) + def map_CastFunc(self, cast_expr: CastFunc): return PsCast(cast_expr.dtype, self.visit_expr(cast_expr.expr)) diff --git a/src/pystencils/backend/kernelcreation/typification.py b/src/pystencils/backend/kernelcreation/typification.py index 972a47c8c14775bc30a267fbcd8e94d0a2b89dee..d3f0b03313c58f4308eda9eb07bf6d7eb6835c88 100644 --- a/src/pystencils/backend/kernelcreation/typification.py +++ b/src/pystencils/backend/kernelcreation/typification.py @@ -22,7 +22,7 @@ from ..ast.expressions import ( PsLookup, PsCall, PsArrayInitList, - PsCast + PsCast, ) from ..functions import PsMathFunction diff --git a/src/pystencils/fast_approximation.py b/src/pystencils/fast_approximation.py index 1cbbf52f99f8661f7c8727c5176264b3066478ac..9088348fb3ff45d36d2f02d0ac7c2244a3d51c03 100644 --- a/src/pystencils/fast_approximation.py +++ b/src/pystencils/fast_approximation.py @@ -2,9 +2,7 @@ from typing import List, Union import sympy as sp -from pystencils.sympyextensions.astnodes import Node -from pystencils.simp import AssignmentCollection -from pystencils.sympyextensions.assignmentcollection.assignment import Assignment +from pystencils.sympyextensions import AssignmentCollection, Assignment # noinspection PyPep8Naming @@ -44,8 +42,6 @@ def _run(term, visitor): def insert_fast_sqrts(term: Union[sp.Expr, List[sp.Expr], AssignmentCollection, Assignment]): def visit(expr): - if isinstance(expr, Node): - return expr if expr.func == sp.Pow and isinstance(expr.exp, sp.Rational) and expr.exp.q == 2: power = expr.exp.p if power < 0: @@ -61,8 +57,6 @@ def insert_fast_sqrts(term: Union[sp.Expr, List[sp.Expr], AssignmentCollection, def insert_fast_divisions(term: Union[sp.Expr, List[sp.Expr], AssignmentCollection, Assignment]): def visit(expr): - if isinstance(expr, Node): - return expr if expr.func == sp.Mul: div_args = [] other_args = [] diff --git a/src/pystencils/kernelcreation.py b/src/pystencils/kernelcreation.py index d49cf1bf592c3cdac2a078019309c1925ff75f28..595d413c9f4f1ac97954c703971ac65946220333 100644 --- a/src/pystencils/kernelcreation.py +++ b/src/pystencils/kernelcreation.py @@ -34,7 +34,7 @@ __all__ = ["create_kernel"] def create_kernel( - assignments: AssignmentCollection | list[Assignment], + assignments: AssignmentCollection | list[Assignment] | Assignment, config: CreateKernelConfig = CreateKernelConfig(), ): """Create a kernel AST from an assignment collection.""" @@ -42,6 +42,9 @@ def create_kernel( default_dtype=config.default_dtype, index_dtype=config.index_dtype ) + if isinstance(assignments, Assignment): + assignments = [assignments] + if not isinstance(assignments, AssignmentCollection): assignments = AssignmentCollection(assignments) diff --git a/src/pystencils/spatial_coordinates.py b/src/pystencils/spatial_coordinates.py index 794bb713f7d7c4f79251a38b480a09b841408c89..e2cc60b809f8e5dcbf3b2a3a67f8240f422c2f3c 100644 --- a/src/pystencils/spatial_coordinates.py +++ b/src/pystencils/spatial_coordinates.py @@ -7,7 +7,7 @@ x_staggered, y_staggered, z_staggered = x_ + 0.5, y_ + 0.5, z_ + 0.5 def x_vector(ndim): - return sympy.Matrix(DEFAULTS.spatial_counters) + return sympy.Matrix(DEFAULTS.spatial_counters[:ndim]) def x_staggered_vector(ndim): diff --git a/src/pystencils/types/parsing.py b/src/pystencils/types/parsing.py index 8330d1a683af2b8527e90460306a60666edd89d1..e28b83ae7074d3b79c145a8b5b6e47b20120873f 100644 --- a/src/pystencils/types/parsing.py +++ b/src/pystencils/types/parsing.py @@ -92,7 +92,7 @@ def parse_type_string(s: str) -> PsType: def parse_type_name(typename: str, const: bool): match typename: - case "int64" | "int64_t": + case "int" | "int64" | "int64_t": return PsSignedIntegerType(64, const=const) case "int32" | "int32_t": return PsSignedIntegerType(32, const=const) diff --git a/tests/test_Min_Max.py b/tests/test_Min_Max.py index 7fb48b18d1e75f39bef8f069ba1bc5d7cbac782a..ccd7947434e01ed0928a5443ac366feab218117b 100644 --- a/tests/test_Min_Max.py +++ b/tests/test_Min_Max.py @@ -18,7 +18,7 @@ def test_max(dtype, sympy_function): z = dh.add_array('z', values_per_cell=1, dtype=dtype) dh.fill("z", 2.0, ghost_layers=True) - config = pystencils.CreateKernelConfig(default_number_float=dtype) + config = pystencils.CreateKernelConfig(default_dtype=dtype) # test sp.Max with one argument assignment_1 = pystencils.Assignment(x.center, sympy_function(y.center + 3.3)) @@ -63,7 +63,7 @@ def test_max_integer(dtype, sympy_function): z = dh.add_array('z', values_per_cell=1, dtype=dtype) dh.fill("z", 2, ghost_layers=True) - config = pystencils.CreateKernelConfig(default_number_int=dtype) + config = pystencils.CreateKernelConfig(default_dtype=dtype) # test sp.Max with one argument assignment_1 = pystencils.Assignment(x.center, sympy_function(y.center + 3)) diff --git a/tests/test_assignment_collection.py b/tests/test_assignment_collection.py index 69ca33e746d10e4e77c46292dc1611946f7bef21..ced0a36e1a0b4d62aaf5549b0d82dd909ddd8124 100644 --- a/tests/test_assignment_collection.py +++ b/tests/test_assignment_collection.py @@ -4,7 +4,7 @@ import pystencils as ps from pystencils import Assignment, AssignmentCollection from pystencils.sympyextensions.astnodes import Conditional -from pystencils.simp.assignment_collection import SymbolGen +from pystencils.sympyextensions import SymbolGen a, b, c = sp.symbols("a b c") x, y, z, t = sp.symbols("x y z t") diff --git a/tests/test_assignment_from_stencil.py b/tests/test_assignment_from_stencil.py index 6658628e1ac26ce6815cee05cc38aa9eadba2e97..879372ae2234aed2d7b35228e950eb8d2b63920d 100644 --- a/tests/test_assignment_from_stencil.py +++ b/tests/test_assignment_from_stencil.py @@ -1,6 +1,7 @@ import numpy as np import pystencils +from pystencils.sympyextensions.astnodes import assignment_from_stencil def test_assignment_from_stencil(): @@ -13,9 +14,9 @@ def test_assignment_from_stencil(): x, y = pystencils.fields('x, y: [2D]') - assignment = pystencils.sympyextensions.assignmentcollection.assignment.assignment_from_stencil(stencil, x, y) + assignment = assignment_from_stencil(stencil, x, y) assert isinstance(assignment, pystencils.Assignment) assert assignment.rhs == x[0, 1] + 4 * x[-1, 1] + 2 * x[0, 0] + 3 * x[0, -1] - assignment = pystencils.sympyextensions.assignmentcollection.assignment.assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) + assignment = assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) assert isinstance(assignment, pystencils.Assignment) diff --git a/tests/test_astnodes.py b/tests/test_astnodes.py deleted file mode 100644 index 014e3574aedcfc5e49abc709d7b18f5d56aee140..0000000000000000000000000000000000000000 --- a/tests/test_astnodes.py +++ /dev/null @@ -1,86 +0,0 @@ -import sys - -import sympy as sp - -import pystencils as ps -from pystencils import Assignment -from pystencils.sympyextensions.astnodes import Block, LoopOverCoordinate, SkipIteration - -dst = ps.fields('dst(8): double[2D]') -s = sp.symbols('s_:8') -x = sp.symbols('x') -y = sp.symbols('y') - -python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}" - - -def test_kernel_function(): - assignments = [ - Assignment(dst[0, 0](0), s[0]), - Assignment(x, dst[0, 0](2)) - ] - - ast_node = ps.create_kernel(assignments) - - assert ast_node.target == ps.Target.CPU - assert ast_node.backend == ps.Backend.C - # symbols_defined and undefined_symbols will always return an emtpy set - assert ast_node.symbols_defined == set() - assert ast_node.undefined_symbols == set() - assert ast_node.fields_written == {dst} - assert ast_node.fields_read == {dst} - - -def test_skip_iteration(): - # skip iteration is an object which should give back empty data structures. - skipped = SkipIteration() - assert skipped.args == [] - assert skipped.symbols_defined == set() - assert skipped.undefined_symbols == set() - - -def test_block(): - assignments = [ - Assignment(dst[0, 0](0), s[0]), - Assignment(x, dst[0, 0](2)) - ] - bl = Block(assignments) - assert bl.symbols_defined == {dst[0, 0](0), dst[0, 0](2), s[0], x} - - bl.append([Assignment(y, 10)]) - assert bl.symbols_defined == {dst[0, 0](0), dst[0, 0](2), s[0], x, y} - assert len(bl.args) == 3 - - list_iterator = iter([Assignment(s[1], 11)]) - bl.insert_front(list_iterator) - - assert bl.args[0] == Assignment(s[1], 11) - - -def test_loop_over_coordinate(): - assignments = [ - Assignment(dst[0, 0](0), s[0]), - Assignment(x, dst[0, 0](2)) - ] - - body = Block(assignments) - loop = LoopOverCoordinate(body, coordinate_to_loop_over=0, start=0, stop=10, step=1) - - assert loop.body == body - - new_body = Block([assignments[0]]) - loop = loop.new_loop_with_different_body(new_body) - assert loop.body == new_body - - assert loop.start == 0 - assert loop.stop == 10 - assert loop.step == 1 - - loop.replace(loop.start, 2) - loop.replace(loop.stop, 20) - loop.replace(loop.step, 2) - - assert loop.start == 2 - assert loop.stop == 20 - assert loop.step == 2 - diff --git a/tests/test_conditional_field_access.py b/tests/test_conditional_field_access.py index e872164b4339d97307c0cefdff5fd0b41a30616e..1e120304bdb8bf812dbd4719f11327ef69a60e79 100644 --- a/tests/test_conditional_field_access.py +++ b/tests/test_conditional_field_access.py @@ -16,7 +16,7 @@ import sympy as sp import pystencils as ps from pystencils import Field, x_vector from pystencils.sympyextensions.astnodes import ConditionalFieldAccess -from pystencils.simp import sympy_cse +from pystencils.sympyextensions import sympy_cse def add_fixed_constant_boundary_handling(assignments, with_cse): diff --git a/tests/test_custom_backends.py b/tests/test_custom_backends.py deleted file mode 100644 index c7bf7fe243dc6a9df08ba4152cf56ef6ea588bee..0000000000000000000000000000000000000000 --- a/tests/test_custom_backends.py +++ /dev/null @@ -1,51 +0,0 @@ -from subprocess import CalledProcessError - -import pytest - -import pystencils -import pystencils.cpu.cpujit -from pystencils.backends.cbackend import CBackend -from pystencils.backends.cuda_backend import CudaBackend -from pystencils.enums import Target - - -class ScreamingBackend(CBackend): - - def _print(self, node): - normal_code = super()._print(node) - return normal_code.upper() - - -class ScreamingGpuBackend(CudaBackend): - - def _print(self, node): - normal_code = super()._print(node) - return normal_code.upper() - - -def test_custom_backends_cpu(): - z, y, x = pystencils.fields("z, y, x: [2d]") - - normal_assignments = pystencils.AssignmentCollection([pystencils.Assignment( - z[0, 0], x[0, 0] * x[0, 0] * y[0, 0])], []) - - ast = pystencils.create_kernel(normal_assignments, target=Target.CPU) - pystencils.show_code(ast, ScreamingBackend()) - with pytest.raises(CalledProcessError): - pystencils.cpu.cpujit.make_python_function(ast, custom_backend=ScreamingBackend()) - - -def test_custom_backends_gpu(): - pytest.importorskip('cupy') - import cupy - import pystencils.gpu.gpujit - - z, x, y = pystencils.fields("z, y, x: [2d]") - - normal_assignments = pystencils.AssignmentCollection([pystencils.Assignment( - z[0, 0], x[0, 0] * x[0, 0] * y[0, 0])], []) - - ast = pystencils.create_kernel(normal_assignments, target=Target.GPU) - pystencils.show_code(ast, ScreamingGpuBackend()) - with pytest.raises((cupy.cuda.compiler.JitifyException, cupy.cuda.compiler.CompileException)): - pystencils.gpu.gpujit.make_python_function(ast, custom_backend=ScreamingGpuBackend()) diff --git a/tests/test_dtype_check.py b/tests/test_dtype_check.py index 0d73224c60cc2406c630183c55407b468739c6df..4e69b5e60f04494072153fffa9835c06f438a563 100644 --- a/tests/test_dtype_check.py +++ b/tests/test_dtype_check.py @@ -2,6 +2,7 @@ import numpy as np import pytest import pystencils +from pystencils.sympyextensions.astnodes import assignment_from_stencil def test_dtype_check_wrong_type(): @@ -11,7 +12,7 @@ def test_dtype_check_wrong_type(): stencil = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] - assignment = pystencils.sympyextensions.assignmentcollection.assignment.assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) + assignment = assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) kernel = pystencils.create_kernel([assignment]).compile() with pytest.raises(ValueError) as e: @@ -26,7 +27,7 @@ def test_dtype_check_correct_type(): stencil = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] - assignment = pystencils.sympyextensions.assignmentcollection.assignment.assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) + assignment = assignment_from_stencil(stencil, x, y, normalization_factor=1 / np.sum(stencil)) kernel = pystencils.create_kernel([assignment]).compile() kernel(x=array, y=output) assert np.allclose(output[1:-1, 1:-1], np.ones_like(output[1:-1, 1:-1])) diff --git a/tests/test_field.py b/tests/test_field.py index 14c75133608f5dbd4b9baae25c580b64593d64df..3e2c86060fa5f2b755dce99fa4ce047123d67615 100644 --- a/tests/test_field.py +++ b/tests/test_field.py @@ -3,8 +3,8 @@ import pytest import sympy as sp import pystencils as ps -from pystencils import TypedSymbol -from pystencils.typing import create_type +from pystencils import TypedSymbol, DEFAULTS +from pystencils.types import create_type from pystencils.field import Field, FieldType, layout_string_to_tuple @@ -165,10 +165,10 @@ def test_staggered(): assert j1.staggered_vector_access("N") == sp.Matrix([j1.staggered_access("N")]) assert j1.staggered_stencil_name == 'D2Q5' - assert j1.physical_coordinates[0] == TypedSymbol("ctr_0", create_type("int"), nonnegative=True) - assert j1.physical_coordinates[1] == TypedSymbol("ctr_1", create_type("int"), nonnegative=True) - assert j1.physical_coordinates_staggered[0] == TypedSymbol("ctr_0", create_type("int"), nonnegative=True) + 0.5 - assert j1.physical_coordinates_staggered[1] == TypedSymbol("ctr_1", create_type("int"), nonnegative=True) + 0.5 + assert j1.physical_coordinates[0] == DEFAULTS.spatial_counters[0] + assert j1.physical_coordinates[1] == DEFAULTS.spatial_counters[1] + assert j1.physical_coordinates_staggered[0] == DEFAULTS.spatial_counters[0] + 0.5 + assert j1.physical_coordinates_staggered[1] == DEFAULTS.spatial_counters[1] + 0.5 assert j1.index_to_physical(index_coordinates=sp.Matrix([0, 0]), staggered=True)[0] == 0.5 assert j1.index_to_physical(index_coordinates=sp.Matrix([0, 0]), staggered=True)[1] == 0.5 assert j1.physical_to_index(physical_coordinates=sp.Matrix([0, 0]), staggered=True)[0] == -0.5 @@ -201,3 +201,6 @@ def test_staggered(): r = ps.fields('r(2) : double[2D]', field_type=FieldType.STAGGERED_FLUX) assert r[0, 0](0) == r.staggered_access("W") assert -r[1, 0](0) == r.staggered_access("E") + + +# test_staggered() \ No newline at end of file diff --git a/tests/test_finite_differences.py b/tests/test_finite_differences.py index 854c65ba17e6e49a491853517b921ecee6bce06a..234b5a570eba4ecd2df14742fb02c68b730efa8f 100644 --- a/tests/test_finite_differences.py +++ b/tests/test_finite_differences.py @@ -2,7 +2,7 @@ import sympy as sp import pytest import pystencils as ps -from pystencils.sympyextensions.astnodes import LoopOverCoordinate +from pystencils import DEFAULTS from pystencils.fd import diff, diffusion, Discretization2ndOrder from pystencils.fd.spatial import discretize_spatial, fd_stencils_isotropic, fd_stencils_standard, \ fd_stencils_forth_order_isotropic @@ -71,7 +71,7 @@ def test_staggered_laplacian(): def test_staggered_combined(): from pystencils.fd import diff f = ps.fields("f : double[2D]") - x, y = [LoopOverCoordinate.get_loop_counter_symbol(i) for i in range(2)] + x, y = DEFAULTS.spatial_counters[:2] dx = sp.symbols("dx") expr = diff(x * diff(f, 0) + y * diff(f, 1), 0) diff --git a/tests/test_floor_ceil_int_optimization.py b/tests/test_floor_ceil_int_optimization.py index ce06f0559144fd3640acc388680f5ec520c3b03e..b446d596b24b37fcec84eecf0808e69c780d4109 100644 --- a/tests/test_floor_ceil_int_optimization.py +++ b/tests/test_floor_ceil_int_optimization.py @@ -11,7 +11,7 @@ import sympy as sp import pystencils -from pystencils.typing import create_type +from pystencils.types import create_type def test_floor_ceil_int_optimization(): diff --git a/tests/test_gpu.py b/tests/test_gpu.py index 04d616d4ead4b84df6ff1ee46dec83d8ce1c5503..84ef340458d76d971e468e534499032f2fd56cc5 100644 --- a/tests/test_gpu.py +++ b/tests/test_gpu.py @@ -7,7 +7,7 @@ from scipy.ndimage import convolve from pystencils import Assignment, Field, fields, CreateKernelConfig, create_kernel, Target from pystencils.gpu import BlockIndexing -from pystencils.simp import sympy_cse_on_assignment_list +from pystencils.sympyextensions import sympy_cse_on_assignment_list from pystencils.slicing import add_ghost_layers, make_slice, remove_ghost_layers, normalize_slice try: diff --git a/tests/test_half_precision.py b/tests/test_half_precision.py index 6d55d1f0e292fec7b27e9b5837b9771f6890d6b3..a9745459da19dbd206264980ed72987cc7879387 100644 --- a/tests/test_half_precision.py +++ b/tests/test_half_precision.py @@ -29,7 +29,7 @@ def test_half_precison(target): up = ps.Assignment(f3.center, f1.center + 2.1 * f2.center) - config = ps.CreateKernelConfig(target=dh.default_target, default_number_float=np.float32) + config = ps.CreateKernelConfig(target=dh.default_target, default_dtype=np.float32) ast = ps.create_kernel(up, config=config) kernel = ast.compile() diff --git a/tests/test_helpful_errors.py b/tests/test_helpful_errors.py deleted file mode 100644 index 23215a52874abf24e6f50ba1323de1209870976b..0000000000000000000000000000000000000000 --- a/tests/test_helpful_errors.py +++ /dev/null @@ -1,37 +0,0 @@ -""" - -""" - -import pytest - -from pystencils.sympyextensions.astnodes import Block -from pystencils.backends.cbackend import CustomCodeNode, get_headers - - -def test_headers_have_quotes_or_brackets(): - class ErrorNode1(CustomCodeNode): - - def __init__(self): - super().__init__("", [], []) - self.headers = ["iostream"] - - class ErrorNode2(CustomCodeNode): - headers = ["<iostream>", "foo"] - - def __init__(self): - super().__init__("", [], []) - self.headers = ["<iostream>", "foo"] - - class OkNode3(CustomCodeNode): - - def __init__(self): - super().__init__("", [], []) - self.headers = ["<iostream>", '"foo"'] - - with pytest.raises(AssertionError, match='.* does not follow the pattern .*'): - get_headers(Block([ErrorNode1()])) - - with pytest.raises(AssertionError, match='.* does not follow the pattern .*'): - get_headers(ErrorNode2()) - - get_headers(OkNode3()) diff --git a/tests/test_match_subs_for_assignment_collection.py b/tests/test_match_subs_for_assignment_collection.py index ec305fa52d7c4f1651368f95f9d9c412ad1f5236..39ec9883403d6037fb7a5c8afaf976b867f4aefe 100644 --- a/tests/test_match_subs_for_assignment_collection.py +++ b/tests/test_match_subs_for_assignment_collection.py @@ -11,12 +11,13 @@ import sympy as sp import pystencils -from pystencils.typing import TypedSymbol, BasicType +from pystencils.sympyextensions import TypedSymbol +from pystencils.types import create_type def test_wild_typed_symbol(): x = pystencils.fields('x: float32[3d]') - typed_symbol = TypedSymbol('a', BasicType('float64')) + typed_symbol = TypedSymbol('a', create_type('float64')) assert x.center().match(sp.Wild('w1')) assert typed_symbol.match(sp.Wild('w1')) diff --git a/tests/test_nodecollection.py b/tests/test_nodecollection.py deleted file mode 100644 index beaf592b02e7ecad779b22c0663babf7402813ad..0000000000000000000000000000000000000000 --- a/tests/test_nodecollection.py +++ /dev/null @@ -1,13 +0,0 @@ -import sympy as sp - -from pystencils import AssignmentCollection, Assignment -from pystencils.node_collection import NodeCollection -from pystencils.sympyextensions.astnodes import SympyAssignment - - -def test_node_collection_from_assignment_collection(): - x = sp.symbols('x') - assignment_collection = AssignmentCollection([Assignment(x, 2)]) - node_collection = NodeCollection.from_assignment_collection(assignment_collection) - - assert node_collection.all_assignments[0] == SympyAssignment(x, 2) diff --git a/tests/test_pickle_support.py b/tests/test_pickle_support.py index 87268a777be6390533db71ba184dbd9bb7dcbe2d..55ef2fb1cc4b833a73a8639e4cab78287d7169a1 100644 --- a/tests/test_pickle_support.py +++ b/tests/test_pickle_support.py @@ -1,7 +1,7 @@ from copy import copy, deepcopy from pystencils.field import Field -from pystencils.typing import TypedSymbol +from pystencils.sympyextensions import TypedSymbol def test_field_access(): diff --git a/tests/test_simplification_strategy.py b/tests/test_simplification_strategy.py index 40b350af343a85490e945bd6197ce07a99f04ef8..b23fcd1c7c680c6aeac7e425f3ef1057110d85d9 100644 --- a/tests/test_simplification_strategy.py +++ b/tests/test_simplification_strategy.py @@ -2,7 +2,7 @@ import sympy as sp import pystencils as ps from pystencils import Assignment, AssignmentCollection -from pystencils.simp import ( +from pystencils.sympyextensions import ( SimplificationStrategy, apply_on_all_subexpressions, subexpression_substitution_in_existing_subexpressions) diff --git a/tests/test_simplifications.py b/tests/test_simplifications.py index 2814ac14f5fb5734e0d23a92d8e0aaf975691b36..9c7c1edc4ea029ea7eebeeaa04fb309ddf4cd210 100644 --- a/tests/test_simplifications.py +++ b/tests/test_simplifications.py @@ -6,12 +6,15 @@ import sympy as sp import pystencils as ps from pystencils import Assignment, AssignmentCollection, fields -from pystencils.simp import subexpression_substitution_in_main_assignments -from pystencils.simp import add_subexpressions_for_divisions -from pystencils.simp import add_subexpressions_for_sums -from pystencils.simp import add_subexpressions_for_field_reads -from pystencils.simp.simplifications import add_subexpressions_for_constants -from pystencils.typing import BasicType, TypedSymbol +from pystencils.sympyextensions.simplifications import ( + subexpression_substitution_in_main_assignments, + add_subexpressions_for_divisions, + add_subexpressions_for_sums, + add_subexpressions_for_field_reads, + add_subexpressions_for_constants, +) +from pystencils.sympyextensions import TypedSymbol +from pystencils.types import create_type a, b, c, d, x, y, z = sp.symbols("a b c d x y z") s0, s1, s2, s3 = sp.symbols("s_:4") @@ -144,7 +147,7 @@ def test_add_subexpressions_for_field_reads(): ac3 = add_subexpressions_for_field_reads(ac, data_type="float32") assert len(ac3.subexpressions) == 2 assert isinstance(ac3.subexpressions[0].lhs, TypedSymbol) - assert ac3.subexpressions[0].lhs.dtype == BasicType("float32") + assert ac3.subexpressions[0].lhs.dtype == create_type("float32") @pytest.mark.parametrize('target', (ps.Target.CPU, ps.Target.GPU)) @@ -159,7 +162,7 @@ def test_sympy_optimizations(target, dtype): src[0, 0]: 1.0 * (sp.exp(dst[0, 0]) - 1) }) - config = pystencils.config.CreateKernelConfig(target=target, default_number_float=dtype) + config = pystencils.config.CreateKernelConfig(target=target, default_dtype=dtype) ast = ps.create_kernel(assignments, config=config) ps.show_code(ast) diff --git a/tests/test_size_and_layout_checks.py b/tests/test_size_and_layout_checks.py index 08b747f74344c3484315a9d2d5c090ea0940019c..0b653444eabecae301e65aca9132d9ced2263870 100644 --- a/tests/test_size_and_layout_checks.py +++ b/tests/test_size_and_layout_checks.py @@ -5,6 +5,7 @@ import pystencils import sympy as sp from pystencils import Assignment, Field, create_kernel, fields +from pystencils.backend.exceptions import KernelConstraintsError def test_size_check(): @@ -38,9 +39,9 @@ def test_fixed_size_mismatch_check(): update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([update_rule]) - assert 'Differently sized field accesses' in str(e.value) + assert 'Fixed-shape fields of different sizes encountered' in str(e.value) def test_fixed_and_variable_field_check(): @@ -53,9 +54,9 @@ def test_fixed_and_variable_field_check(): update_rule = Assignment(sym_dst(0), sym_src[-1, 1](1) + sym_src[1, -1](2)) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel(update_rule) - assert 'Mixing fixed-shaped and variable-shape fields' in str(e.value) + assert 'Cannot mix fixed- and variable-shape fields' in str(e.value) def test_two_variable_shaped_fields(): @@ -79,19 +80,19 @@ def test_ssa_checks(): f, g = fields("f, g : double[2D]") a, b, c = sp.symbols("a b c") - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(c, f[0, 1]), Assignment(c, f[1, 0]), Assignment(g[0, 0], c)]) assert 'Assignments not in SSA form' in str(e.value) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(c, a + 3), Assignment(a, 42), Assignment(g[0, 0], c)]) assert 'Symbol a is written, after it has been read' in str(e.value) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(c, c + 1), Assignment(g[0, 0], c)]) assert 'Symbol c is written, after it has been read' in str(e.value) @@ -101,13 +102,13 @@ def test_loop_independence_checks(): f, g = fields("f, g : double[2D]") v = fields("v(2) : double[2D]") - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(g[0, 1], f[0, 1]), Assignment(g[0, 0], f[1, 0])]) assert 'Field g is written at two different locations' in str(e.value) # This is not allowed - because this is not SSA (it can be overwritten with allow_double_writes) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(g[0, 2], f[0, 1]), Assignment(g[0, 2], 2 * g[0, 2])]) @@ -116,12 +117,12 @@ def test_loop_independence_checks(): Assignment(g[0, 2], 2 * g[0, 2])], config=pystencils.CreateKernelConfig(allow_double_writes=True)) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(v[0, 2](1), f[0, 1]), Assignment(v[0, 1](0), 4), Assignment(v[0, 2](1), 2 * v[0, 2](1))]) - with pytest.raises(ValueError) as e: + with pytest.raises(KernelConstraintsError) as e: create_kernel([Assignment(g[0, 1], 3), Assignment(f[0, 1], 2 * g[0, 2])]) assert 'Field g is read at (0, 2) and written at (0, 1)' in str(e.value)