-
Notifications
You must be signed in to change notification settings - Fork 28
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
Replace ref by literal #2828
base: master
Are you sure you want to change the base?
Replace ref by literal #2828
Conversation
Thanks Hugo. I'm pretty sure we allow any PSyIR expression as an initial value? |
* Thanks Andrew, indeed, BinaryOp can be an valid initial_value
Thanks. I made a test showing the current limit of this MR with respect to non-literal initial value (for example a binary operation). But I don't understand why |
I think that's because we don't support the |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2828 +/- ##
=======================================
Coverage 99.89% 99.89%
=======================================
Files 359 360 +1
Lines 51073 51143 +70
=======================================
+ Hits 51021 51091 +70
Misses 52 52 ☔ View full report in Codecov by Sentry. |
That's ok. I don't deal with "complex" right hand side for now. If this is not a Literal, the parameter is just ignored. |
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 stuff Hugo, thanks for this.
Mostly my comments are about docstrings :-)
As you hint in one of your comments, I'm wondering whether we should always consider all constant symbols that are in scope, rather than explicitly looking at the Routine and Container symbol tables?
I also think it would be better if we quietly skipped constant symbols with a non-Literal value rather than raise an error. That would enable the transformation to do as much as it can rather than aborting early.
Coverage is good and the new test file fully covers the new source file.
If you feel brave, it would be good to try the transformation 'for real' by adding it to the transformation script that we use for NEMO in the integration tests. You could add it immediately after the call to enhance_tree_information
:
PSyclone/examples/nemo/scripts/omp_gpu_trans.py
Lines 85 to 94 in 9b8a0ba
enhance_tree_information(subroutine) | |
normalise_loops( | |
subroutine, | |
hoist_local_arrays=True, | |
convert_array_notation=True, | |
loopify_array_intrinsics=True, | |
convert_range_loops=True, | |
hoist_expressions=True | |
) |
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
I am not sure Andrew about what you meant by : " should we always consider all constant symbols that are in scope, rather than explicitly looking at the Routine and Container symbol tables?" Besides, when you say "quietly skipping" does it mean that if the transformation finds a non-literal symbol it should not even throw a warning? |
avoid error prone string comparison
@arporter I think I addressed all your concerns. Please let me know. Best, Hugo. |
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Show resolved
Hide resolved
## NOTE: (From Andrew) We may want to look at all symbols in scope | ||
# rather than just those in the parent symbol table? | ||
if node.parent is not None and isinstance(node.parent, Container): | ||
if node.parent.symbol_table is not None: |
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.
A Container is always constructed with a SymbolTable so this check should be unnecessary?
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
rbbl = ReplaceReferenceByLiteralTrans() | ||
rbbl.apply(routine_foo) | ||
written_code = fortran_writer(routine_foo.ancestor(Container)) | ||
print(written_code) |
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.
Please rm the print
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.
This one's still here?
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
|
||
""" | ||
_ERROR_MSG = ( | ||
"Psyclone(ReplaceReferenceByLiteral): only " |
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.
For consistency with other transformations, please change this to "ReplaceReferenceByLiteralTrans: only..."
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.
Almost, see my earlier comments about simplifying by using self.name
.
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
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.
Looking good, thanks Hugo. I think it's a good idea to add the warnings to the generated code. In my comment about outer scopes, I was thinking we could just create the mapping for all symbols in scope (by recursing up through parent symbol tables), while ensuring that we don't conform to scoping rules (i.e. the value associated with the innermost scope takes precedence). However, it's a small point and this PR is probably already sufficient as it is.
Just a few minor things to tidy up.
I'll fire off the integration tests now.
As a reminder - please leave it to me to 'resolve' converstations as that makes it much easier to check everything :-)
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
src/psyclone/tests/psyir/transformations/replace_reference_by_literal_trans_test.py
Outdated
Show resolved
Hide resolved
I've created #2879 to run the integration tests (because you can't do it for a PR from a fork). |
Integration tests were green :-) |
Hi @hbrunie, I can't remember: did you say this was ready for review now? (If you could set the label on the PR that really helps me see what I need to do next.) |
Yes sorry, I do it now :-). |
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 Hugo. Very, very nearly there now. Just a little bit more tidying and then this is done.
assert "integer, dimension(10,a) :: array" in written_code | ||
assert "call foo(2 + 3)" in written_code | ||
|
||
|
||
@pytest.mark.xfail |
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 for adding this. We've found (from painful experience) that marking a whole test as 'xfail' often means that it can fail for a reason we don't expect and we don't notice. Therefore, please could you alter it by putting the 'xfail' inside the test. Have a look at e.g. test_apply_gocean_kern
in syir/transformations/inline_trans_test.py
. Also, please add a reason to the xfail (as is done in that example).
if param_table.get(sym_name): | ||
message = ( | ||
"Psyclone(ReplaceReferenceByLiteralTrans):" | ||
+ f" Symbol already found {sym_name}." | ||
f"{ReplaceReferenceByLiteralTrans._ERROR_MSG_START}" |
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.
You can use self.name
here instead of this _ERROR_MSG_START - that will give the name of the Transformation.
message = ( | ||
ReplaceReferenceByLiteralTrans._ERROR_MSG | ||
+ f"{sym_name} is assigned " | ||
ReplaceReferenceByLiteralTrans._ERROR_MSG_ONLY_INITVAL |
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.
self.name here too.
:param param_table: map of parameters to Literal values. | ||
|
||
:return: the new shape with any references to constants replaced by | ||
their Literal values. |
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.
This continued line needs to be indented.
src/psyclone/psyir/transformations/replace_reference_by_literal_trans.py
Outdated
Show resolved
Hide resolved
rbbl = ReplaceReferenceByLiteralTrans() | ||
rbbl.apply(routine_foo) | ||
written_code = fortran_writer(routine_foo.ancestor(Container)) | ||
print(written_code) |
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.
This one's still here?
|
||
""" | ||
_ERROR_MSG = ( | ||
"Psyclone(ReplaceReferenceByLiteral): only " |
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.
Almost, see my earlier comments about simplifying by using self.name
.
Replacing PsyIR Reference by PsyIR Literal when it is easy to do so.
Same file, same subroutine, or subroutine contained in module.
Build a param_table with symbol name and Literal, then go through psyir references and symbol_table array type shapes to look for ref with name contained in param_table.
Issues: