You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
from loki import Sourcefile, FindNodes, Loop, IntLiteral, SubstituteExpressions
source = Sourcefile.from_file('bar.F90', preprocess=True)
for routine in source.routines:
o = FindNodes(Loop).visit(routine.body)[0]
body_a = SubstituteExpressions().visit(o.body)
body_b = SubstituteExpressions().visit(o.body)
assert body_a[0].rhs.children[0] == body_b[0].rhs.children[0] # Compare equal...
assert body_a[0].rhs.children[0] is not body_b[0].rhs.children[0] # ...but not the same object
subroutine bar()
integer :: c
do i = 1, 5
c = 1 + 3
end do
end subroutine bar
The text was updated successfully, but these errors were encountered:
As a follow-up, here's a bunch of tests that expose the shallow copy problems on a pure expression tree level:
fromloki.expressionimport (
symbolsassym, ExpressionRetriever, parse_expr, SubstituteExpressionsMapper
)
deftest_substitute_expression_mapper():
expr_str='5 * a + 4 * b(c) + a'expr=parse_expr(expr_str)
assertexpr==expr_str# Create a clone of the expr by replacing 'a' with 'x'retriever=ExpressionRetriever(lambdae: isinstance(e, sym.TypedSymbol))
symbols=retriever.retrieve(expr)
assertsymbols== ['a', 'b', 'c', 'a']
expr2=SubstituteExpressionsMapper({symbols[0]: symbols[0].clone(name='x')})(expr)
expr2_str=expr_str.replace('a', 'x')
assertexpr==expr_strassertexpr2==expr2_str# As a first test, let's rename 'c' to 'y' in the original expression by modifying# the object in symbols: That should be the identical object, therefore it should# also affect expr but it should not change expr2symbols[2].name='y'assertsymbols== ['a', 'b', 'y', 'a']
expr_str=expr_str.replace('c', 'y')
assertexpr==expr_strassertexpr2==expr2_str# Fails: str(expr2) is now '5*x + 4*b(y) + x'# Now rename the last 'a' to 'q' in the original expression in-place: That should# affect only the last instance of a to q but keep the first instance of a the same,# and should not change expr2assertexpr.children[1] =='a'expr.children[1].name='q'expr_str=expr_str[:-1] +'q'assertexpr==expr_strassertexpr2==expr2_str# Now do the same in expr2. If SubstituteExpressionsMapper did create unique nodes# again, then we should observe the same behaviourassertexpr2.children[1] =='x'expr2.children[1].name='q'expr2_str==expr2_str[:-1] +'q'assertexpr==expr_strassertexpr2==expr2_str# Fails: str(expr2) is now '5*q + 4*b(c) + q'
Loki seems to be shallow copying literals by not rebuilding the leaf nodes due to the assumption they are constant. @reuterbal identified the issue being due to the code at https://github.com/ecmwf-ifs/loki/blob/main/loki/expression/mappers.py#L552-L563
The reproducer for this issue is as follows:
The text was updated successfully, but these errors were encountered: