Skip to content

Commit

Permalink
Transformation: Remove obsolete RemoveCallTrafo and rename to drhook
Browse files Browse the repository at this point in the history
  • Loading branch information
mlange05 committed Apr 8, 2024
1 parent a9e4770 commit d1aa9be
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 208 deletions.
2 changes: 1 addition & 1 deletion scripts/loki_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
DataOffloadTransformation, GlobalVariableAnalysis, GlobalVarOffloadTransformation
)
from transformations.derived_types import DerivedTypeArgumentsTransformation
from transformations.utility_routines import DrHookTransformation, RemoveCallsTransformation
from transformations.drhook import DrHookTransformation
from transformations.pool_allocator import TemporariesPoolAllocatorTransformation
from transformations.single_column_claw import ExtractSCATransformation, CLAWTransformation
from transformations.single_column_coalesced import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
)

from conftest import available_frontends
from transformations import DrHookTransformation, RemoveCallsTransformation
from transformations import DrHookTransformation


@pytest.fixture(scope='module', name='config')
Expand Down Expand Up @@ -197,45 +197,3 @@ def test_dr_hook_transformation_remove(frontend, config, source):
assert not drhook_calls
assert not drhook_imports
assert 'zhook_handle' not in item.ir.variables


@pytest.mark.parametrize('include_intrinsics', (True, False))
@pytest.mark.parametrize('kernel_only', (True, False))
@pytest.mark.parametrize('frontend', available_frontends(
xfail=[(OMNI, 'Incomplete source tree impossible with OMNI')]
))
def test_utility_routine_removal(frontend, config, source, include_intrinsics, kernel_only):
"""
Test removal of utility calls and intrinsics with custom patterns.
"""
scheduler_config = SchedulerConfig.from_dict(config)
scheduler = Scheduler(paths=source, config=scheduler_config, frontend=frontend)
scheduler.process(
transformation=RemoveCallsTransformation(
routines=['ABOR1', 'WRITE(NULOUT', 'DR_HOOK'],
include_intrinsics=include_intrinsics, kernel_only=kernel_only
)
)

routine = scheduler['rick_rolled#never_gonna_give'].ir
transformed = routine.to_fortran()
assert '[SUBROUTINE CALL]' not in transformed
assert '[INLINE CONDITIONAL]' not in transformed
assert ('dave' not in transformed) == include_intrinsics
assert ('[WRITE INTRINSIC]' not in transformed) == include_intrinsics
assert 'zhook_handle' not in routine.variables

for r in routine.members:
transformed = r.to_fortran()
assert '[SUBROUTINE CALL]' not in transformed
assert '[INLINE CONDITIONAL]' not in transformed
assert ('dave' not in transformed) == include_intrinsics
assert 'zhook_handle' not in routine.variables

routine = Sourcefile.from_file(source/'never_gonna_give.F90', frontend=frontend)['i_hope_you_havent_let_me_down']
assert 'zhook_handle' in routine.variables
assert len([call for call in FindNodes(CallStatement).visit(routine.body) if call.name == 'dr_hook']) == 2

driver = scheduler['#rick_astley'].ir
drhook_calls = [call for call in FindNodes(CallStatement).visit(driver.body) if call.name == 'dr_hook']
assert len(drhook_calls) == (2 if kernel_only else 0)
2 changes: 1 addition & 1 deletion transformations/transformations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from transformations.single_column_claw import * # noqa
from transformations.single_column_coalesced import * # noqa
from transformations.single_column_coalesced_vector import * # noqa
from transformations.utility_routines import * # noqa
from transformations.drhook import * # noqa
from transformations.scc_cuf import * # noqa
from transformations.pool_allocator import * # noqa

Expand Down
93 changes: 93 additions & 0 deletions transformations/transformations/drhook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

"""
Utility transformations to update or remove calls to DR_HOOK.
"""

from loki import (
FindNodes, Transformer, Transformation, CallStatement,
Conditional, as_tuple, Literal, Intrinsic, Import
)


__all__ = ['DrHookTransformation']


def remove_unused_drhook_import(routine):
"""
Remove unsed DRHOOK imports and corresponding handle.
Parameters
----------
routine : :any:`Subroutine`
The subroutine from which to remove DRHOOK import/handle.
"""

mapper = {}
for imp in FindNodes(Import).visit(routine.spec):
if imp.module.lower() == 'yomhook':
mapper[imp] = None

if mapper:
routine.spec = Transformer(mapper).visit(routine.spec)

#Remove unused zhook_handle
routine.variables = as_tuple(v for v in routine.variables if v != 'zhook_handle')


class DrHookTransformation(Transformation):
"""
Re-write or remove the DrHook label markers in transformed
kernel routines
Parameters
----------
remove : bool
Remove calls to ``DR_HOOK``
mode : str
Transformation mode to insert into DrHook labels
"""
def __init__(self, remove=False, mode=None, **kwargs):
self.remove = remove
self.mode = mode
super().__init__(**kwargs)

def transform_subroutine(self, routine, **kwargs):
"""
Apply transformation to subroutine object
"""
role = kwargs['item'].role

# Leave DR_HOOK annotations in driver routine
if role == 'driver':
return

for r in routine.members:
self.transform_subroutine(r, **kwargs)

mapper = {}
for call in FindNodes(CallStatement).visit(routine.body):
# Lazily changing the DrHook label in-place
if call.name == 'DR_HOOK':
if self.remove:
mapper[call] = None
else:
new_label = f'{call.arguments[0].value.upper()}_{str(self.mode).upper()}'
new_args = (Literal(value=new_label),) + call.arguments[1:]
mapper[call] = call.clone(arguments=new_args)

if self.remove:
for cond in FindNodes(Conditional).visit(routine.body):
if cond.inline and 'LHOOK' in as_tuple(cond.condition):
mapper[cond] = None

routine.body = Transformer(mapper).visit(routine.body)

#Get rid of unused import and variable
if self.remove:
remove_unused_drhook_import(routine)
163 changes: 0 additions & 163 deletions transformations/transformations/utility_routines.py

This file was deleted.

0 comments on commit d1aa9be

Please sign in to comment.