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

Expression mappers: Remove recurse_to_parent option and recurse by default #140

Merged
merged 3 commits into from
Sep 7, 2023

Conversation

reuterbal
Copy link
Collaborator

This fixes the symptom described in #133.

The retrieval function for IR visitors that recurse into expression trees is defined as a static method on the class of each such visitor. While the current way how this is being installed is debatable, it is conceptually correct. However, a later addition allowed to parameterize this retrieval function by providing the option to not recurse to "parents" of expression nodes (the recurse_to_parent option). This causes problems, because multiple instances of the same class may then use different variations and consequently change the behaviour of existing objects.

This option relates to the used of derived type member variables, where e.g., a lookup of symbols would then yield, say a%b%c, a%b and a - but return only a%b%c if that recursion is switched off.

The option has only been switched off in very few places and there wasn't a hard dependency on it's functionality (only true use case was in the derived type flattening where the filtering can be done post-visitor as well). Therefore, I removed the option and made recursion the default behaviour.

@reuterbal reuterbal linked an issue Sep 5, 2023 that may be closed by this pull request
@github-actions
Copy link

github-actions bot commented Sep 5, 2023

Documentation for this branch can be viewed at https://sites.ecmwf.int/docs/loki/140/index.html

@reuterbal reuterbal force-pushed the 133-expression-finder-retrieval-function branch from 0cad410 to da58a0a Compare September 5, 2023 09:24
@codecov
Copy link

codecov bot commented Sep 5, 2023

Codecov Report

Merging #140 (7a1b195) into main (35f8284) will increase coverage by 0.00%.
The diff coverage is 98.57%.

@@           Coverage Diff           @@
##             main     #140   +/-   ##
=======================================
  Coverage   92.10%   92.10%           
=======================================
  Files          89       89           
  Lines       16512    16501   -11     
=======================================
- Hits        15208    15198   -10     
+ Misses       1304     1303    -1     
Flag Coverage Δ
lint_rules 96.22% <100.00%> (+0.08%) ⬆️
loki 92.02% <100.00%> (-0.01%) ⬇️
transformations 91.69% <94.44%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Changed Coverage Δ
transformations/transformations/derived_types.py 94.10% <94.44%> (+0.07%) ⬆️
lint_rules/lint_rules/ifs_coding_standards_2011.py 97.50% <100.00%> (+0.09%) ⬆️
loki/expression/expr_visitors.py 100.00% <100.00%> (+0.65%) ⬆️
loki/expression/mappers.py 92.94% <100.00%> (-0.02%) ⬇️
loki/transform/transform_utilities.py 88.78% <100.00%> (-0.11%) ⬇️

self._retriever = ExpressionRetriever(lambda e: isinstance(e, Expression),
recurse_to_parent=recurse_to_parent)
def __init__(self, **kwargs):
self._retriever = ExpressionRetriever(lambda e: isinstance(e, Expression))
Copy link
Collaborator

Choose a reason for hiding this comment

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

This still makes the behaviour object-bound, instead of class-bound and the fact that this is static is applied post-hoc. I wonder it would be easier instead to just set a static ExpressionRetriever (expression visitor) via a class method and change the ExpressionFinder (IR visitor) to always call self.retriever.retrieve(). So for the sub-classes we would then merely do

class FindTypedSymbols(ExpressionFinder):

    retriever = ExpressionRetriever(lambda x: ...)

without ever touching the __init__ of the derived instance?

@reuterbal reuterbal force-pushed the 133-expression-finder-retrieval-function branch from da58a0a to c4d3f5f Compare September 6, 2023 10:05
@reuterbal reuterbal force-pushed the 133-expression-finder-retrieval-function branch from c4d3f5f to 7a1b195 Compare September 6, 2023 11:02
@reuterbal
Copy link
Collaborator Author

Thanks for the comment, I had overlooked that. I have changed the implementation as suggested, making the retriever a class property.

I took the opportunity to nuke the FindExpressionRoot visitor, which is incompatible with that and essentially required double-traversing the tree and it's use can easily be worked around in a much smarter and more efficient way. I had to do this for one of the linter rules, which as a consequence became much neater and more readable (in my eyes, anyway).

I think this is ready for another look.

Copy link
Collaborator

@mlange05 mlange05 left a comment

Choose a reason for hiding this comment

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

Very nice, and the consistent use of Retriever objects to handle our expression trees in a flexible manner looks very neat to me. GTG from me :shipit:

Custom expression finder that that yields all literals of the types
specified in the config and stops recursion on loop ranges and array subscripts
(to avoid warnings about integer constants in these cases)
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

[no action] Agree on this looking much nicer! 👍

Generic visitor method that will call the :any:`ExpressionRetriever`
only on :class:`pymbolic.primitives.Expression` children, collecting
``(node, expression root, comparison)`` tuples for all matches.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

[no action] Uhhh, nice, although quite advanced interface usage! Still, the level of documentation makes it at least accessible.

@reuterbal reuterbal merged commit 7094446 into main Sep 7, 2023
11 checks passed
@reuterbal reuterbal deleted the 133-expression-finder-retrieval-function branch September 7, 2023 18:38
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.

Hacky or... bad design for ExpressionFinder ?
2 participants