-
Notifications
You must be signed in to change notification settings - Fork 12
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
extend hoist variables functionality #357
Conversation
Documentation for this branch can be viewed at https://sites.ecmwf.int/docs/loki/357/index.html |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #357 +/- ##
=======================================
Coverage 95.40% 95.40%
=======================================
Files 178 178
Lines 37267 37293 +26
=======================================
+ Hits 35555 35581 +26
Misses 1712 1712
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks great! I left two remarks, please have a look if that makes sense or point out what I'm missing there. Otherwise this is fantastic.
dim_map = {} | ||
assignments = FindNodes(Assignment).visit(routine.body) | ||
for assignment in assignments: | ||
dim_map[assignment.lhs] = assignment.rhs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to point out how to do this in a "single line", or single list comprehension at least. For larger kernels like CLOUDSC with hundreds of assignments I expect you might actually be able to measure a small advantage with below change.
dim_map = {} | |
assignments = FindNodes(Assignment).visit(routine.body) | |
for assignment in assignments: | |
dim_map[assignment.lhs] = assignment.rhs | |
dim_map = { | |
assignment.lhs: assignment.rhs | |
for assignment in FindNodes(Assignment).visit(routine.body) | |
} |
Also, this map might become quite big, so we might want to build a list of candidates first and then create the mapping? Suggestion (untested) would be something like this:
dim_map = {} | |
assignments = FindNodes(Assignment).visit(routine.body) | |
for assignment in assignments: | |
dim_map[assignment.lhs] = assignment.rhs | |
dim_vars = [ | |
dim_var | |
for var in variables | |
for dim_var in FindVariables().visit(var.dimensions) | |
if isinstance(var, sym.Array) | |
] | |
dim_map = { | |
assignment.lhs: assignment.rhs | |
for assignment in FindNodes(Assignment).visit(routine.body) | |
if assignment.lhs in dim_vars | |
} |
@@ -204,12 +205,17 @@ class HoistVariablesTransformation(Transformation): | |||
---------- | |||
as_kwarguments : boolean | |||
Whether to pass the hoisted arguments as `args` or `kwargs`. | |||
remap_dimensions : boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a situation where we wouldn't want to do this? It seems to me like we might not need to make this an option and instead always do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question ... I can't think of a situation we don't want to do that but on the other hand I think having a switch is not a bad idea?!
Anyway, I switched the default but if you insist we can remove this flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, flipping the default should be enough. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks great and gtg from me!
I'll rebase the branch and will merge once green
@@ -204,12 +205,17 @@ class HoistVariablesTransformation(Transformation): | |||
---------- | |||
as_kwarguments : boolean | |||
Whether to pass the hoisted arguments as `args` or `kwargs`. | |||
remap_dimensions : boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, flipping the default should be enough. Thanks!
…lized variables used as dimensions (if wanted via flag)
4fcb538
to
817b1e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me; clean and nicely tested. I left a general comment for later development, but no action needed and GTG from me.
@@ -319,6 +330,33 @@ def driver_variable_declaration(self, routine, variables): | |||
""" | |||
routine.variables += tuple(v.rescope(routine) for v in variables) | |||
|
|||
@staticmethod | |||
def driver_variable_declaration_dim_remapping(routine, variables): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[no action]: Just a general note: we keep hitting this remapping problem in many use cases - so eventually we might want a general utility that can do this. But for this use case this looks great.
to account for possibly uninitialised variables used as dimensions (if wanted via flag)
This
would be transformed to
which would be a problem as
local_nlon
is not initialised.Setting
remap_dimensions=True
the transformation will produce