From 2d17a6d187d2f48b4ee58702114169e7dd187d4c Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Sun, 10 Mar 2024 21:17:44 +0100 Subject: [PATCH] a multitude of fixes to test cases --- src/pystencils/backend/functions.py | 13 ++- .../backend/kernelcreation/freeze.py | 42 +++++++-- .../backend/kernelcreation/typification.py | 2 +- src/pystencils/fast_approximation.py | 8 +- src/pystencils/kernelcreation.py | 5 +- src/pystencils/spatial_coordinates.py | 2 +- src/pystencils/types/parsing.py | 2 +- tests/test_Min_Max.py | 4 +- tests/test_assignment_collection.py | 2 +- tests/test_assignment_from_stencil.py | 5 +- tests/test_astnodes.py | 86 ------------------- tests/test_conditional_field_access.py | 2 +- tests/test_custom_backends.py | 51 ----------- tests/test_dtype_check.py | 5 +- tests/test_field.py | 15 ++-- tests/test_finite_differences.py | 4 +- tests/test_floor_ceil_int_optimization.py | 2 +- tests/test_gpu.py | 2 +- tests/test_half_precision.py | 2 +- tests/test_helpful_errors.py | 37 -------- ...st_match_subs_for_assignment_collection.py | 5 +- tests/test_nodecollection.py | 13 --- tests/test_pickle_support.py | 2 +- tests/test_simplification_strategy.py | 2 +- tests/test_simplifications.py | 19 ++-- tests/test_size_and_layout_checks.py | 23 ++--- 26 files changed, 101 insertions(+), 254 deletions(-) delete mode 100644 tests/test_astnodes.py delete mode 100644 tests/test_custom_backends.py delete mode 100644 tests/test_helpful_errors.py delete mode 100644 tests/test_nodecollection.py diff --git a/src/pystencils/backend/functions.py b/src/pystencils/backend/functions.py index 4380d8c56..39d5019ba 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 6861ff4c5..26dcc9d8e 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 972a47c8c..d3f0b0331 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 1cbbf52f9..9088348fb 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 d49cf1bf5..595d413c9 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 794bb713f..e2cc60b80 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 8330d1a68..e28b83ae7 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 7fb48b18d..ccd794743 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 69ca33e74..ced0a36e1 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 6658628e1..879372ae2 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 014e3574a..000000000 --- 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 e872164b4..1e120304b 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 c7bf7fe24..000000000 --- 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 0d73224c6..4e69b5e60 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 14c751336..3e2c86060 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 854c65ba1..234b5a570 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 ce06f0559..b446d596b 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 04d616d4e..84ef34045 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 6d55d1f0e..a9745459d 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 23215a528..000000000 --- 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 ec305fa52..39ec98834 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 beaf592b0..000000000 --- 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 87268a777..55ef2fb1c 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 40b350af3..b23fcd1c7 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 2814ac14f..9c7c1edc4 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 08b747f74..0b653444e 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) -- GitLab