diff --git a/src/psyclone/psyir/nodes/psy_data_node.py b/src/psyclone/psyir/nodes/psy_data_node.py index 4522af7bfd..00eb37a59a 100644 --- a/src/psyclone/psyir/nodes/psy_data_node.py +++ b/src/psyclone/psyir/nodes/psy_data_node.py @@ -715,6 +715,10 @@ def gen_type_bound_call(typename, methodname, argument_list=None, # end calls for child in self.psy_data_body.pop_all_children(): self.parent.children.insert(self.position, child) + # If there is any symbol in the PSyData scope (it could have been + # added by any posterior modification writing to child.scope) it needs + # to be moved together with the nodes + self.scope.symbol_table.merge(self.psy_data_body.symbol_table) if has_var: # Only add PostStart() if there is at least one variable. diff --git a/src/psyclone/tests/psyir/transformations/profile_test.py b/src/psyclone/tests/psyir/transformations/profile_test.py index 00f4a6ab2c..e22cda34f6 100644 --- a/src/psyclone/tests/psyir/transformations/profile_test.py +++ b/src/psyclone/tests/psyir/transformations/profile_test.py @@ -48,15 +48,16 @@ from psyclone.domain.lfric.transformations import LFRicLoopFuseTrans from psyclone.gocean1p0 import GOInvokeSchedule from psyclone.profiler import Profiler -from psyclone.psyir.nodes import (colored, ProfileNode, Loop, Literal, - Assignment, Return, Reference, - KernelSchedule, Routine, Schedule) -from psyclone.psyir.symbols import (SymbolTable, REAL_TYPE, DataSymbol) -from psyclone.psyir.transformations import (ACCKernelsTrans, ProfileTrans, - TransformationError) +from psyclone.psyir.nodes import ( + colored, ProfileNode, Loop, Literal, Assignment, Return, Reference, + OMPDoDirective, KernelSchedule, Routine, Schedule) +from psyclone.psyir.symbols import ( + SymbolTable, REAL_TYPE, DataSymbol, INTEGER_TYPE) +from psyclone.psyir.transformations import ( + ACCKernelsTrans, ProfileTrans, TransformationError) from psyclone.tests.utilities import get_invoke -from psyclone.transformations import (GOceanOMPLoopTrans, - OMPParallelTrans) +from psyclone.transformations import ( + GOceanOMPLoopTrans, OMPParallelTrans, LFRicOMPLoopTrans) # ----------------------------------------------------------------------------- @@ -367,6 +368,35 @@ def test_profile_invokes_lfric(fortran_writer): Profiler._options = [] +def test_profile_with_symbols_declared_in_the_profiler_scope(tmpdir): + ''' Test that Symbols that are declared in the Profiler schedule node end + up in the output code. For example, LFRic OpenMP with reprod reductions + declares symbols in there. ''' + file_name = "15.19.1_three_builtins_two_reductions.f90" + psy, invoke = get_invoke(file_name, "lfric", idx=0) + schedule = invoke.schedule + rtrans = OMPParallelTrans() + otrans = LFRicOMPLoopTrans() + for child in schedule.children: + if isinstance(child, Loop): + otrans.apply(child, {"reprod": True}) + for child in schedule.children: + if isinstance(child, OMPDoDirective): + rtrans.apply(child) + profile_trans = ProfileTrans() + options = {"region_name": (psy.name, invoke.name)} + profile_trans.apply(schedule.children, options=options) + # In addition to the OpenMP symbols, manually add one in that scope + schedule.children[0].psy_data_body.symbol_table.new_symbol( + "profiler_scoped_symbol", symbol_type=DataSymbol, + datatype=INTEGER_TYPE) + code = str(psy.gen) + + assert "omp_lib, only : omp_get_max_threads, omp_get_thread_num" in code + assert "integer :: th_idx" in code + assert "integer :: profiler_scoped_symbol" in code + + # ----------------------------------------------------------------------------- def test_profile_kernels_lfric(fortran_writer): '''Check that all kernels are instrumented correctly in a