Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

b/t/test_codegen.py: fix 2.00000000000000 == 2 #1553

Merged
merged 1 commit into from
Sep 2, 2024

Conversation

emollier
Copy link
Contributor

In sympy 1.13.0, symbolic representation differentiates between integers and floats. See sympy merge request 25614 for further details. This results in a test case failure in test_codegen.py's test_automatic_augmented_assignments when checking that there is no formal difference between "x = x + x" and "x *= 2.0":

_____________________ test_automatic_augmented_assignments _____________________

    @pytest.mark.codegen_independent
    def test_automatic_augmented_assignments():
        # We test that statements that could be rewritten as augmented assignments
        # are correctly rewritten (using sympy to test for symbolic equality)
        variables = {
            "x": ArrayVariable("x", owner=None, size=10, device=device),
            "y": ArrayVariable("y", owner=None, size=10, device=device),
            "z": ArrayVariable("y", owner=None, size=10, device=device),
            "b": ArrayVariable("b", owner=None, size=10, dtype=bool, device=device),
            "clip": DEFAULT_FUNCTIONS["clip"],
            "inf": DEFAULT_CONSTANTS["inf"],
        }
        statements = [
            # examples that should be rewritten
            # Note that using our approach, we will never get -= or /= but always
            # the equivalent += or *= statements
            ("x = x + 1.0", "x += 1.0"),
            ("x = 2.0 * x", "x *= 2.0"),
            ("x = x - 3.0", "x += -3.0"),
            ("x = x/2.0", "x *= 0.5"),
            ("x = y + (x + 1.0)", "x += y + 1.0"),
            ("x = x + x", "x *= 2.0"),
            ("x = x + y + z", "x += y + z"),
            ("x = x + y + z", "x += y + z"),
            # examples that should not be rewritten
            ("x = 1.0/x", "x = 1.0/x"),
            ("x = 1.0", "x = 1.0"),
            ("x = 2.0*(x + 1.0)", "x = 2.0*(x + 1.0)"),
            ("x = clip(x + y, 0.0, inf)", "x = clip(x + y, 0.0, inf)"),
            ("b = b or False", "b = b or False"),
        ]
        for orig, rewritten in statements:
            scalar, vector = make_statements(orig, variables, np.float32)
            try:  # we augment the assertion error with the original statement
                assert (
                    len(scalar) == 0
                ), f"Did not expect any scalar statements but got {str(scalar)}"
                assert (
                    len(vector) == 1
                ), f"Did expect a single statement but got {str(vector)}"
                statement = vector[0]
                expected_var, expected_op, expected_expr, _ = parse_statement(rewritten)
                assert (
                    expected_var == statement.var
                ), f"expected write to variable {expected_var}, not to {statement.var}"
                assert (
                    expected_op == statement.op
                ), f"expected operation {expected_op}, not {statement.op}"
                # Compare the two expressions using sympy to allow for different order etc.
                sympy_expected = str_to_sympy(expected_expr)
                sympy_actual = str_to_sympy(statement.expr)
>               assert sympy_expected == sympy_actual, (
                    f"RHS expressions '{sympy_to_str(sympy_expected)}' and"
                    f" '{sympy_to_str(sympy_actual)}' are not identical"
                )
E               AssertionError: RHS expressions '2.00000000000000' and '2' are not identical
E               assert 2.00000000000000 == 2

../debian/tmp/usr/lib/python3.12/dist-packages/brian2/tests/test_codegen.py:483: AssertionError

Checking against "x *= 2" resolves the issue, but it may make the test incompatible with earlier sympy versions, so maybe there is some version check or a more generic test to implement in case a larger version coverage is needed.

In sympy 1.13.0, symbolic representation differentiates between
integers and floats.  See [sympy merge request 25614] for further
details.  This results in a test case failure in test_codegen.py's
test_automatic_augmented_assignments when checking that there is no
formal difference between "x = x + x" and "x *= 2.0":

	_____________________ test_automatic_augmented_assignments _____________________

	    @pytest.mark.codegen_independent
	    def test_automatic_augmented_assignments():
	        # We test that statements that could be rewritten as augmented assignments
	        # are correctly rewritten (using sympy to test for symbolic equality)
	        variables = {
	            "x": ArrayVariable("x", owner=None, size=10, device=device),
	            "y": ArrayVariable("y", owner=None, size=10, device=device),
	            "z": ArrayVariable("y", owner=None, size=10, device=device),
	            "b": ArrayVariable("b", owner=None, size=10, dtype=bool, device=device),
	            "clip": DEFAULT_FUNCTIONS["clip"],
	            "inf": DEFAULT_CONSTANTS["inf"],
	        }
	        statements = [
	            # examples that should be rewritten
	            # Note that using our approach, we will never get -= or /= but always
	            # the equivalent += or *= statements
	            ("x = x + 1.0", "x += 1.0"),
	            ("x = 2.0 * x", "x *= 2.0"),
	            ("x = x - 3.0", "x += -3.0"),
	            ("x = x/2.0", "x *= 0.5"),
	            ("x = y + (x + 1.0)", "x += y + 1.0"),
	            ("x = x + x", "x *= 2.0"),
	            ("x = x + y + z", "x += y + z"),
	            ("x = x + y + z", "x += y + z"),
	            # examples that should not be rewritten
	            ("x = 1.0/x", "x = 1.0/x"),
	            ("x = 1.0", "x = 1.0"),
	            ("x = 2.0*(x + 1.0)", "x = 2.0*(x + 1.0)"),
	            ("x = clip(x + y, 0.0, inf)", "x = clip(x + y, 0.0, inf)"),
	            ("b = b or False", "b = b or False"),
	        ]
	        for orig, rewritten in statements:
	            scalar, vector = make_statements(orig, variables, np.float32)
	            try:  # we augment the assertion error with the original statement
	                assert (
	                    len(scalar) == 0
	                ), f"Did not expect any scalar statements but got {str(scalar)}"
	                assert (
	                    len(vector) == 1
	                ), f"Did expect a single statement but got {str(vector)}"
	                statement = vector[0]
	                expected_var, expected_op, expected_expr, _ = parse_statement(rewritten)
	                assert (
	                    expected_var == statement.var
	                ), f"expected write to variable {expected_var}, not to {statement.var}"
	                assert (
	                    expected_op == statement.op
	                ), f"expected operation {expected_op}, not {statement.op}"
	                # Compare the two expressions using sympy to allow for different order etc.
	                sympy_expected = str_to_sympy(expected_expr)
	                sympy_actual = str_to_sympy(statement.expr)
	>               assert sympy_expected == sympy_actual, (
	                    f"RHS expressions '{sympy_to_str(sympy_expected)}' and"
	                    f" '{sympy_to_str(sympy_actual)}' are not identical"
	                )
	E               AssertionError: RHS expressions '2.00000000000000' and '2' are not identical
	E               assert 2.00000000000000 == 2

	../debian/tmp/usr/lib/python3.12/dist-packages/brian2/tests/test_codegen.py:483: AssertionError

Checking against "x *= 2" resolves the issue, but it may make the test
incompatible with earlier sympy versions, so maybe there is some
version check or a more generic test to implement in case a larger
version coverage is needed.

[sympy merge request 25614]: sympy/sympy#25614

Signed-off-by: Étienne Mollier <[email protected]>
@emollier
Copy link
Contributor Author

Note: the failing check seems to choke on missing credentials:

Run docker/login-action@v3
Error: Username and password required

Copy link
Member

@mstimberg mstimberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix! It runs successfully with sympy version 1.12, so it seems that older versions do not have an issue with this.

@mstimberg mstimberg merged commit 5009b85 into brian-team:master Sep 2, 2024
30 of 31 checks passed
@mstimberg mstimberg mentioned this pull request Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants