Skip to content

Commit

Permalink
Merge pull request #324 from ecmwf-ifs/317-acc-seq-bug
Browse files Browse the repository at this point in the history
get_pragma_parameters: Fix parsing clauses without parentheses in the tail string
  • Loading branch information
mlange05 authored Jun 14, 2024
2 parents 7959f5b + 08e598d commit 181f6b2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
25 changes: 16 additions & 9 deletions loki/ir/pragma_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ def find(cls, string):
.. note::
This allows nested parenthesis by matching pairs of
parantheses starting at the end by pushing and popping
parentheses starting at the end by pushing and popping
from a stack.
"""
string = cls._pattern_quoted_string.sub('', string)
if not string.strip():
# Early bail-out on empty strings
return {}

p_open = [match.start() for match in cls._pattern_opening_parenthesis.finditer(string)]
p_close = [match.start() for match in cls._pattern_closing_parenthesis.finditer(string)]
assert len(p_open) == len(p_close)
Expand Down Expand Up @@ -101,18 +105,21 @@ def _match_spans(open_, close_):
spans.append(p_spans.pop())
if p_spans:
spans += p_spans[::-1]

# Build the list of parameters from the matched spans
parameters = defaultdict(list)
if not spans and string.strip():
for key in string.strip().split(' '):
if key != '':
parameters[key].append(None)
for i, span in enumerate(spans):
keys = string[spans[i-1][1]+1 if i>=1 else 0:span[0]].strip().split(' ')
if len(keys) > 1:
for key in keys[:-1]:
if key != '':
parameters[key].append(None)
for key in keys[:-1]:
if key:
parameters[key].append(None)
parameters[keys[-1]].append(string[span[0]+1:span[1]])

# Tail handling (including strings without any matched spans)
tail_span = spans[-1][1] + 1 if spans else 0
for key in string[tail_span:].strip().split(' '):
if key != '':
parameters[key].append(None)
parameters = {k: v if len(v) > 1 else v[0] for k, v in parameters.items()}
return parameters

Expand Down
41 changes: 40 additions & 1 deletion loki/ir/tests/test_pragma_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from loki import Module, Subroutine, FindNodes, flatten, pprint, fgen
from loki.frontend import available_frontends
from loki.ir import Pragma, Loop, VariableDeclaration, PragmaRegion
from loki.ir import Comment, Pragma, Loop, VariableDeclaration, PragmaRegion
from loki.ir.pragma_utils import (
is_loki_pragma, get_pragma_parameters, attach_pragmas, detach_pragmas,
pragmas_attached, pragma_regions_attached
Expand Down Expand Up @@ -640,3 +640,42 @@ def test_pragmas_map(frontend):
assert 'map( to: a )' in fgen_code
assert 'map( b )' in fgen_code
assert 'map( tofrom: c )' in fgen_code


@pytest.mark.parametrize('frontend', available_frontends())
def test_pragmas_mixed_key_value_attrs(frontend):
"""
Test correct handling of pragmas that contain attributes with and without
values in parentheses (reported in #317).
"""
fcode = """
SUBROUTINE TEST()
IMPLICIT NONE
END SUBROUTINE TEST
""".strip()

routine = Subroutine.from_source(fcode, frontend=frontend)

pragma = Pragma(keyword='acc', content=f'kernels num_gangs ( 1 ) async wait')
assert get_pragma_parameters(pragma, only_loki_pragmas=False) == {
'kernels': None,
'num_gangs': ' 1 ',
'async': None,
'wait': None
}

pragma = Pragma(keyword='acc', content=f'seq routine ({routine.name})')
assert get_pragma_parameters(pragma, only_loki_pragmas=False) == {
'seq': None,
'routine': routine.name
}

pragma = Pragma(keyword='acc', content=f'routine ({routine.name}) seq')
assert get_pragma_parameters(pragma, only_loki_pragmas=False) == {
'seq': None,
'routine': routine.name
}

routine.spec.prepend(pragma)
fgen_code = routine.to_fortran()
assert f'!$acc routine( {routine.name} ) seq' in fgen_code

0 comments on commit 181f6b2

Please sign in to comment.