From af8d68b45d4a86e5a4e52c9bec14000f2104c892 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Thu, 10 Jul 2025 14:38:14 +0100 Subject: [PATCH 1/6] Declare th_idx and omp_num_threads in the Routine scope --- src/psyclone/psyGen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/psyclone/psyGen.py b/src/psyclone/psyGen.py index 1682e7142a..761925c84e 100644 --- a/src/psyclone/psyGen.py +++ b/src/psyclone/psyGen.py @@ -1185,7 +1185,7 @@ def reduction_sum_loop(self): f"'{reduction_access.api_specific_name()}' found in " f"LFRicBuiltIn:reduction_sum_loop(). Expected one of " f"{api_strings}.") - symtab = self.scope.symbol_table + symtab = self.ancestor(Routine).symbol_table thread_idx = symtab.find_or_create_tag( "omp_thread_index", root_name="th_idx", From a69724d4c57bb4ba6240de1544d70574b0c5ac97 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Thu, 10 Jul 2025 15:12:36 +0100 Subject: [PATCH 2/6] Declare omp_get_thread_num in LFRic invoke when there are reductions --- src/psyclone/domain/lfric/lfric_invoke.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/psyclone/domain/lfric/lfric_invoke.py b/src/psyclone/domain/lfric/lfric_invoke.py index f5a73639fc..aaf8983c68 100644 --- a/src/psyclone/domain/lfric/lfric_invoke.py +++ b/src/psyclone/domain/lfric/lfric_invoke.py @@ -309,6 +309,9 @@ def setup_psy_layer_symbols(self): omp_get_max_threads = symtab.find_or_create( "omp_get_max_threads", symbol_type=RoutineSymbol, interface=ImportInterface(omp_lib)) + _ = symtab.find_or_create( + "omp_get_thread_num", symbol_type=RoutineSymbol, + interface=ImportInterface(omp_lib)) assignment = Assignment.create( lhs=Reference(nthreads), From f04f3709e78947ce9a15ad03cd12aaeee9702a9e Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Fri, 11 Jul 2025 15:18:12 +0100 Subject: [PATCH 3/6] #3052 Add a test --- .../psyir/transformations/profile_test.py | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/psyclone/tests/psyir/transformations/profile_test.py b/src/psyclone/tests/psyir/transformations/profile_test.py index 00f4a6ab2c..dcf9746785 100644 --- a/src/psyclone/tests/psyir/transformations/profile_test.py +++ b/src/psyclone/tests/psyir/transformations/profile_test.py @@ -48,15 +48,15 @@ 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.nodes import ( + colored, ProfileNode, Loop, Literal, Assignment, Return, Reference, + OMPDoDirective, KernelSchedule, Routine, Schedule) from psyclone.psyir.symbols import (SymbolTable, REAL_TYPE, DataSymbol) -from psyclone.psyir.transformations import (ACCKernelsTrans, ProfileTrans, - TransformationError) +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 +367,29 @@ def test_profile_invokes_lfric(fortran_writer): Profiler._options = [] +def test_profile_lfric_reprod_reductions(dist_mem): + ''' Test that the openmp symbols that are needed for LFRic reprod + reductions are there.''' + file_name = "15.19.1_three_builtins_two_reductions.f90" + psy, invoke = get_invoke(file_name, "lfric", idx=0, dist_mem=dist_mem) + 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) + code = str(psy.gen) + + assert "omp_lib, only : omp_get_max_threads, omp_get_thread_num" in code + assert "integer :: th_idx" in code + + # ----------------------------------------------------------------------------- def test_profile_kernels_lfric(fortran_writer): '''Check that all kernels are instrumented correctly in a From 1b382422c3d077318e8d4ba8ca4f82a9244b565e Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Tue, 15 Jul 2025 11:01:24 +0100 Subject: [PATCH 4/6] #3053 Fix psy_data_node missing inner scoped symbols --- src/psyclone/psyGen.py | 2 +- src/psyclone/psyir/nodes/psy_data_node.py | 4 ++++ .../tests/psyir/transformations/profile_test.py | 17 ++++++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/psyclone/psyGen.py b/src/psyclone/psyGen.py index 761925c84e..1682e7142a 100644 --- a/src/psyclone/psyGen.py +++ b/src/psyclone/psyGen.py @@ -1185,7 +1185,7 @@ def reduction_sum_loop(self): f"'{reduction_access.api_specific_name()}' found in " f"LFRicBuiltIn:reduction_sum_loop(). Expected one of " f"{api_strings}.") - symtab = self.ancestor(Routine).symbol_table + symtab = self.scope.symbol_table thread_idx = symtab.find_or_create_tag( "omp_thread_index", root_name="th_idx", diff --git a/src/psyclone/psyir/nodes/psy_data_node.py b/src/psyclone/psyir/nodes/psy_data_node.py index 4522af7bfd..8ae18d00b4 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 PSyDataSchedule (it can happen + # by any parent lower_to_language_level writing to self.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 dcf9746785..e22cda34f6 100644 --- a/src/psyclone/tests/psyir/transformations/profile_test.py +++ b/src/psyclone/tests/psyir/transformations/profile_test.py @@ -51,7 +51,8 @@ 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) +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 @@ -367,11 +368,12 @@ def test_profile_invokes_lfric(fortran_writer): Profiler._options = [] -def test_profile_lfric_reprod_reductions(dist_mem): - ''' Test that the openmp symbols that are needed for LFRic reprod - reductions are there.''' +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, dist_mem=dist_mem) + psy, invoke = get_invoke(file_name, "lfric", idx=0) schedule = invoke.schedule rtrans = OMPParallelTrans() otrans = LFRicOMPLoopTrans() @@ -384,10 +386,15 @@ def test_profile_lfric_reprod_reductions(dist_mem): 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 # ----------------------------------------------------------------------------- From 3a25ba22e7959c40c8b2345b4351ae7bddddaa63 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Tue, 15 Jul 2025 11:04:01 +0100 Subject: [PATCH 5/6] #3053 Remove unneeded code --- src/psyclone/domain/lfric/lfric_invoke.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/psyclone/domain/lfric/lfric_invoke.py b/src/psyclone/domain/lfric/lfric_invoke.py index aaf8983c68..f5a73639fc 100644 --- a/src/psyclone/domain/lfric/lfric_invoke.py +++ b/src/psyclone/domain/lfric/lfric_invoke.py @@ -309,9 +309,6 @@ def setup_psy_layer_symbols(self): omp_get_max_threads = symtab.find_or_create( "omp_get_max_threads", symbol_type=RoutineSymbol, interface=ImportInterface(omp_lib)) - _ = symtab.find_or_create( - "omp_get_thread_num", symbol_type=RoutineSymbol, - interface=ImportInterface(omp_lib)) assignment = Assignment.create( lhs=Reference(nthreads), From 661713b79437d73d13b7a094561dfe56bce424d4 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Tue, 15 Jul 2025 11:06:17 +0100 Subject: [PATCH 6/6] #3053 Improve comment --- src/psyclone/psyir/nodes/psy_data_node.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/psyclone/psyir/nodes/psy_data_node.py b/src/psyclone/psyir/nodes/psy_data_node.py index 8ae18d00b4..00eb37a59a 100644 --- a/src/psyclone/psyir/nodes/psy_data_node.py +++ b/src/psyclone/psyir/nodes/psy_data_node.py @@ -715,9 +715,9 @@ 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 PSyDataSchedule (it can happen - # by any parent lower_to_language_level writing to self.scope) - # it needs to be moved together with the nodes + # 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: