-
Notifications
You must be signed in to change notification settings - Fork 13
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
Inline elemental functions: skip calls with args being array (slices) #401
Inline elemental functions: skip calls with args being array (slices) #401
Conversation
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 this!
For readability, we could make the checks a bit shorter (suggestions in inline comments).
The test is blowing a bit out of proportion this way and I would prefer splitting the completely separate "array" case into a separate test. I left a suggestion how you can avoid code duplication by moving the module into a joint fixture.
Finally, this requires a rebase due to the refactoring of inline and extract packages.
fcode_arr = """ | ||
subroutine transform_inline_elemental_functions_extended_array(v1, v2, v3, len) | ||
use iso_fortran_env, only: real64 | ||
use multiply_extended_mod, only: multiply, multiply_single_line, add | ||
integer, intent(in) :: len | ||
real(kind=real64), intent(in) :: v1(len) | ||
real(kind=real64), intent(inout) :: v2(len), v3(len) | ||
real(kind=real64), parameter :: param1 = 100. | ||
integer, parameter :: arr_index = 1 | ||
|
||
v2 = multiply(v1(:), 6._real64) + multiply_single_line(v1(:), 3._real64) | ||
v3 = add(param1, 200._real64) + add(v1, 150._real64) + multiply(v1(arr_index), v2(1)) | ||
end subroutine transform_inline_elemental_functions_extended_array | ||
""" |
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.
Let's make the array case a separate test, please.
You can still avoid replicating the module code etc using the following pattern:
@pytest.fixture(name='multiply_extended_mod', params=available_frontends())
def fixture_multiply_extended_mod(request, tmp_path):
fcode_module = """
...
"""
frontend = request.param
module = Module.from_source(fcode_module, frontend=frontend, xmods=[tmp_path])
return module, frontend
def test_transform_inline_elemental_functions_extended_scalar(multiply_extended_mod, tmp_path):
module, frontend = multiply_extended_mod
fcode = "..."
routine = Subroutine.from_source(fcode, frontend=frontend, definitions=[module], xmods=[tmp_path])
...
def test_transform_inline_elemental_functions_extended_arr(multiply_extended_mod, tmp_path):
module, frontend = multiply_extended_mod
fcode_arr = "..."
routine = Subroutine.from_source(fcode_arr, frontend=frontend, definitions=[module], xmods=[tmp_path])
...
loki/transformations/inline.py
Outdated
return | ||
if (expr.procedure_type.is_function and expr.procedure_type.is_elemental): | ||
if any(is_array(val) for val in expr.arg_map.values()): | ||
warning(f'Call to elemental function \'{expr.routine.name}\' with array arguments.' |
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 avoid escaping if you mix quotation marks:
warning(f'Call to elemental function \'{expr.routine.name}\' with array arguments.' | |
warning(f"Call to elemental function '{expr.routine.name}' with array arguments." |
loki/transformations/inline.py
Outdated
@@ -389,6 +393,19 @@ def __init__(self, query, recurse_query=None, inline_elementals_only=False, | |||
def map_inline_call(self, expr, *args, **kwargs): | |||
if not self.visit(expr, *args, **kwargs): | |||
return | |||
if expr.procedure_type is BasicType.DEFERRED or isinstance(expr.routine, StatementFunction): | |||
return |
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.
We could add here a bailout for non-functions and save a few checks further down:
return | |
return | |
if not expr.procedure_type.is_function: | |
return |
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.
Hmm this ends up with errors like:
AttributeError: 'BasicType' object has no attribute 'is_function'
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 should add this below the checks in ll. 396-397
loki/transformations/inline.py
Outdated
if self.inline_elementals_only: | ||
if not (expr.procedure_type.is_function and expr.procedure_type.is_elemental): |
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 would then become
if self.inline_elementals_only: | |
if not (expr.procedure_type.is_function and expr.procedure_type.is_elemental): | |
if self.inline_elementals_only and not expr.procedure_type.is_elemental: |
loki/transformations/inline.py
Outdated
if functions: | ||
if expr.routine not in functions: | ||
return | ||
if (expr.procedure_type.is_function and expr.procedure_type.is_elemental): |
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.
And this would simplify to
if (expr.procedure_type.is_function and expr.procedure_type.is_elemental): | |
if expr.procedure_type.is_elemental: |
Thanks for the quick review! |
… for now, until fixed
4739c2c
to
3346735
Compare
Documentation for this branch can be viewed at https://sites.ecmwf.int/docs/loki/401/index.html |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #401 +/- ##
=======================================
Coverage 95.57% 95.58%
=======================================
Files 201 201
Lines 39810 39874 +64
=======================================
+ Hits 38050 38112 +62
- Misses 1760 1762 +2
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 for taking care of the suggested changes. Looks great 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.
Yes, looks good to me. GTG
We have a problem for things like:
As the fix is not straight-forward/trivial, this PR makes the inline to skip the problematic calls (for now). Thus, this is not a fix to make those problematic calls being inlined correctly!
A more detailed description of the problem: #400