From 807d35acdc5939cddb9e95d09144789cd55fed18 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Fri, 26 Apr 2024 16:24:10 -0600 Subject: [PATCH 1/2] handle dimensions for promoted variables --- scripts/ccpp_suite.py | 40 +++++++++++++++++++++++++++++++ scripts/suite_objects.py | 17 +++++++++++-- test/capgen_test/temp_adjust.F90 | 3 ++- test/capgen_test/temp_adjust.meta | 7 ++++++ test/capgen_test/temp_set.F90 | 3 ++- test/capgen_test/temp_set.meta | 7 ++++++ 6 files changed, 73 insertions(+), 4 deletions(-) diff --git a/scripts/ccpp_suite.py b/scripts/ccpp_suite.py index d19ca4e8..993af65f 100644 --- a/scripts/ccpp_suite.py +++ b/scripts/ccpp_suite.py @@ -23,6 +23,7 @@ from parse_tools import init_log, set_log_to_null from suite_objects import CallList, Group, Scheme from metavar import CCPP_LOOP_VAR_STDNAMES +from var_props import find_horizontal_dimension, find_vertical_dimension # pylint: disable=too-many-lines @@ -308,6 +309,45 @@ def find_variable(self, standard_name=None, source_var=None, self.add_variable(var, self.__run_env) # Remove the variable from the group group.remove_variable(standard_name) + # Make sure the variable's dimensions are available + # at the init stage (for allocation) + for group in self.groups: + # only add dimension variables to init phase calling list + if group.name == self.__suite_init_group.name: + horiz_dim = find_horizontal_dimension(var.get_dimensions())[0] + vert_dim = find_vertical_dimension(var.get_dimensions())[0] + if horiz_dim and 'horizontal_loop' in horiz_dim: + # can't use horizontal_loop_being/end/extent in init phase + # must allocate to horizontal_dimension + new_horiz_dim = 'ccpp_constant_one:horizontal_dimension' + else: + new_horiz_dim = horiz_dim + # end if + if horiz_dim: + # make new variable with "correct" dimensions + if vert_dim: + new_dims = [new_horiz_dim, vert_dim] + else: + new_dims = [new_horiz_dim] + # end if + subst_dict = {'dimensions': new_dims} + prop_dict = var.copy_prop_dict(subst_dict=subst_dict) + temp_var = Var(prop_dict, + ParseSource(var.get_prop_value('scheme'), + var.get_prop_value('local_name'), var.context), + self.__run_env) + # Add dimensions if they're not already there + group.add_variable_dimensions(temp_var, [], + adjust_intent=True, + to_dict=group.call_list) + else: + # Add dimensions if they're not already there + group.add_variable_dimensions(var, [], + adjust_intent=True, + to_dict=group.call_list) + # end if + # end if + # end for else: emsg = ("Group, {}, claimed it had created {} " "but variable was not found") diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index f611c5d2..2397996f 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -2230,9 +2230,22 @@ def analyze(self, phase, suite_vars, scheme_library, ddt_library, self.run_env.logger.debug("{}".format(self)) # end if - def allocate_dim_str(self, dims, context): + def allocate_dim_str(self, dims, context, suite_var=False): """Create the dimension string for an allocate statement""" rdims = list() + if suite_var: + # adjust horizontal dimension if horizontal_loop_* specified + horiz_dim = find_horizontal_dimension(dims)[0] + vert_dim = find_vertical_dimension(dims)[0] + if horiz_dim and 'horizontal_loop' in horiz_dim: + new_horiz_dim = 'ccpp_constant_one:horizontal_dimension' + if vert_dim: + dims = [new_horiz_dim, vert_dim] + else: + dims = [new_horiz_dim] + # end if + # end if + # end if for dim in dims: rdparts = list() dparts = dim.split(':') @@ -2500,7 +2513,7 @@ def write(self, outfile, host_arglist, indent, const_mod, if dims: timestep_var = svar.get_prop_value('persistence') if group_type == timestep_var: - alloc_str = self.allocate_dim_str(dims, svar.context) + alloc_str = self.allocate_dim_str(dims, svar.context, suite_var=True) lname = svar.get_prop_value('local_name') outfile.write(alloc_stmt.format(lname, alloc_str), indent+1) diff --git a/test/capgen_test/temp_adjust.F90 b/test/capgen_test/temp_adjust.F90 index 5aba4c0b..988f5a25 100644 --- a/test/capgen_test/temp_adjust.F90 +++ b/test/capgen_test/temp_adjust.F90 @@ -18,7 +18,7 @@ MODULE temp_adjust !! \htmlinclude arg_table_temp_adjust_run.html !! subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & - errmsg, errflg, innie, outie, optsie) + to_promote, errmsg, errflg, innie, outie, optsie) integer, intent(in) :: foo real(kind_phys), intent(in) :: timestep @@ -26,6 +26,7 @@ subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & real(kind_phys), intent(inout) :: ps(:) REAL(kind_phys), intent(in) :: temp_prev(:) REAL(kind_phys), intent(inout) :: temp_layer(foo) + real(kind_phys), intent(in) :: to_promote(:) character(len=512), intent(out) :: errmsg integer, optional, intent(out) :: errflg real(kind_phys), optional, intent(in) :: innie diff --git a/test/capgen_test/temp_adjust.meta b/test/capgen_test/temp_adjust.meta index 17eabcdb..b3190c72 100644 --- a/test/capgen_test/temp_adjust.meta +++ b/test/capgen_test/temp_adjust.meta @@ -50,6 +50,13 @@ units = Pa dimensions = (horizontal_loop_extent) intent = inout +[ to_promote ] + standard_name = promote_this_variable_to_suite + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/capgen_test/temp_set.F90 b/test/capgen_test/temp_set.F90 index fc2a9f39..45284e04 100644 --- a/test/capgen_test/temp_set.F90 +++ b/test/capgen_test/temp_set.F90 @@ -19,7 +19,7 @@ MODULE temp_set !! \htmlinclude arg_table_temp_set_run.html !! SUBROUTINE temp_set_run(ncol, lev, timestep, temp_level, temp, ps, & - errmsg, errflg) + to_promote, errmsg, errflg) !---------------------------------------------------------------- IMPLICIT NONE !---------------------------------------------------------------- @@ -29,6 +29,7 @@ SUBROUTINE temp_set_run(ncol, lev, timestep, temp_level, temp, ps, & real(kind_phys), intent(in) :: timestep real(kind_phys), intent(in) :: ps(:) REAL(kind_phys), INTENT(inout) :: temp_level(:, :) + real(kind_phys), intent(out) :: to_promote(:, :) character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/capgen_test/temp_set.meta b/test/capgen_test/temp_set.meta index c3c919e5..f1dfc60f 100644 --- a/test/capgen_test/temp_set.meta +++ b/test/capgen_test/temp_set.meta @@ -47,6 +47,13 @@ units = Pa dimensions = (horizontal_loop_extent) intent = in +[ to_promote ] + standard_name = promote_this_variable_to_suite + units = K + dimensions = (horizontal_loop_extent, vertical_layer_dimension) + type = real + kind = kind_phys + intent = out [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP From b668b2e7d74e44b5bef76ac9455794d0a8b19ea6 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Thu, 16 May 2024 11:49:59 -0600 Subject: [PATCH 2/2] code clean-up; add test for promoted variable with no horiz dimension --- scripts/ccpp_suite.py | 51 ++++++++++++------------------- scripts/suite_objects.py | 17 ++--------- test/capgen_test/run_test | 2 ++ test/capgen_test/temp_adjust.F90 | 3 +- test/capgen_test/temp_adjust.meta | 7 +++++ test/capgen_test/temp_set.F90 | 3 +- test/capgen_test/temp_set.meta | 7 +++++ test/capgen_test/test_reports.py | 1 + 8 files changed, 42 insertions(+), 49 deletions(-) diff --git a/scripts/ccpp_suite.py b/scripts/ccpp_suite.py index 993af65f..91414cbd 100644 --- a/scripts/ccpp_suite.py +++ b/scripts/ccpp_suite.py @@ -23,7 +23,7 @@ from parse_tools import init_log, set_log_to_null from suite_objects import CallList, Group, Scheme from metavar import CCPP_LOOP_VAR_STDNAMES -from var_props import find_horizontal_dimension, find_vertical_dimension +from var_props import is_horizontal_dimension # pylint: disable=too-many-lines @@ -314,38 +314,25 @@ def find_variable(self, standard_name=None, source_var=None, for group in self.groups: # only add dimension variables to init phase calling list if group.name == self.__suite_init_group.name: - horiz_dim = find_horizontal_dimension(var.get_dimensions())[0] - vert_dim = find_vertical_dimension(var.get_dimensions())[0] - if horiz_dim and 'horizontal_loop' in horiz_dim: - # can't use horizontal_loop_being/end/extent in init phase - # must allocate to horizontal_dimension - new_horiz_dim = 'ccpp_constant_one:horizontal_dimension' - else: - new_horiz_dim = horiz_dim - # end if - if horiz_dim: - # make new variable with "correct" dimensions - if vert_dim: - new_dims = [new_horiz_dim, vert_dim] - else: - new_dims = [new_horiz_dim] + dims = var.get_dimensions() + # replace horizontal loop dimension if necessary + for idx, dim in enumerate(dims): + if is_horizontal_dimension(dim): + if 'horizontal_loop' in dim: + dims[idx] = 'ccpp_constant_one:horizontal_dimension' + # end if # end if - subst_dict = {'dimensions': new_dims} - prop_dict = var.copy_prop_dict(subst_dict=subst_dict) - temp_var = Var(prop_dict, - ParseSource(var.get_prop_value('scheme'), - var.get_prop_value('local_name'), var.context), - self.__run_env) - # Add dimensions if they're not already there - group.add_variable_dimensions(temp_var, [], - adjust_intent=True, - to_dict=group.call_list) - else: - # Add dimensions if they're not already there - group.add_variable_dimensions(var, [], - adjust_intent=True, - to_dict=group.call_list) - # end if + # end for + subst_dict = {'dimensions': dims} + prop_dict = var.copy_prop_dict(subst_dict=subst_dict) + temp_var = Var(prop_dict, + ParseSource(var.get_prop_value('scheme'), + var.get_prop_value('local_name'), var.context), + self.__run_env) + # Add dimensions if they're not already there + group.add_variable_dimensions(temp_var, [], + adjust_intent=True, + to_dict=group.call_list) # end if # end for else: diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 2397996f..f611c5d2 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -2230,22 +2230,9 @@ def analyze(self, phase, suite_vars, scheme_library, ddt_library, self.run_env.logger.debug("{}".format(self)) # end if - def allocate_dim_str(self, dims, context, suite_var=False): + def allocate_dim_str(self, dims, context): """Create the dimension string for an allocate statement""" rdims = list() - if suite_var: - # adjust horizontal dimension if horizontal_loop_* specified - horiz_dim = find_horizontal_dimension(dims)[0] - vert_dim = find_vertical_dimension(dims)[0] - if horiz_dim and 'horizontal_loop' in horiz_dim: - new_horiz_dim = 'ccpp_constant_one:horizontal_dimension' - if vert_dim: - dims = [new_horiz_dim, vert_dim] - else: - dims = [new_horiz_dim] - # end if - # end if - # end if for dim in dims: rdparts = list() dparts = dim.split(':') @@ -2513,7 +2500,7 @@ def write(self, outfile, host_arglist, indent, const_mod, if dims: timestep_var = svar.get_prop_value('persistence') if group_type == timestep_var: - alloc_str = self.allocate_dim_str(dims, svar.context, suite_var=True) + alloc_str = self.allocate_dim_str(dims, svar.context) lname = svar.get_prop_value('local_name') outfile.write(alloc_stmt.format(lname, alloc_str), indent+1) diff --git a/test/capgen_test/run_test b/test/capgen_test/run_test index 6798f584..15f48a53 100755 --- a/test/capgen_test/run_test +++ b/test/capgen_test/run_test @@ -151,6 +151,7 @@ required_vars_temp="${required_vars_temp},horizontal_dimension" required_vars_temp="${required_vars_temp},horizontal_loop_begin" required_vars_temp="${required_vars_temp},horizontal_loop_end" required_vars_temp="${required_vars_temp},index_of_water_vapor_specific_humidity" +required_vars_temp="${required_vars_temp},number_of_tracers" required_vars_temp="${required_vars_temp},potential_temperature" required_vars_temp="${required_vars_temp},potential_temperature_at_interface" required_vars_temp="${required_vars_temp},potential_temperature_increment" @@ -164,6 +165,7 @@ input_vars_temp="${input_vars_temp},horizontal_dimension" input_vars_temp="${input_vars_temp},horizontal_loop_begin" input_vars_temp="${input_vars_temp},horizontal_loop_end" input_vars_temp="${input_vars_temp},index_of_water_vapor_specific_humidity" +input_vars_temp="${input_vars_temp},number_of_tracers" input_vars_temp="${input_vars_temp},potential_temperature" input_vars_temp="${input_vars_temp},potential_temperature_at_interface" input_vars_temp="${input_vars_temp},potential_temperature_increment" diff --git a/test/capgen_test/temp_adjust.F90 b/test/capgen_test/temp_adjust.F90 index 988f5a25..c3cc50f0 100644 --- a/test/capgen_test/temp_adjust.F90 +++ b/test/capgen_test/temp_adjust.F90 @@ -18,7 +18,7 @@ MODULE temp_adjust !! \htmlinclude arg_table_temp_adjust_run.html !! subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & - to_promote, errmsg, errflg, innie, outie, optsie) + to_promote, promote_pcnst, errmsg, errflg, innie, outie, optsie) integer, intent(in) :: foo real(kind_phys), intent(in) :: timestep @@ -27,6 +27,7 @@ subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & REAL(kind_phys), intent(in) :: temp_prev(:) REAL(kind_phys), intent(inout) :: temp_layer(foo) real(kind_phys), intent(in) :: to_promote(:) + real(kind_phys), intent(in) :: promote_pcnst(:) character(len=512), intent(out) :: errmsg integer, optional, intent(out) :: errflg real(kind_phys), optional, intent(in) :: innie diff --git a/test/capgen_test/temp_adjust.meta b/test/capgen_test/temp_adjust.meta index b3190c72..02b5fa73 100644 --- a/test/capgen_test/temp_adjust.meta +++ b/test/capgen_test/temp_adjust.meta @@ -57,6 +57,13 @@ type = real kind = kind_phys intent = in +[ promote_pcnst ] + standard_name = promote_this_variable_with_no_horizontal_dimension + units = K + dimensions = (number_of_tracers) + type = real + kind = kind_phys + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/capgen_test/temp_set.F90 b/test/capgen_test/temp_set.F90 index 45284e04..a780433f 100644 --- a/test/capgen_test/temp_set.F90 +++ b/test/capgen_test/temp_set.F90 @@ -19,7 +19,7 @@ MODULE temp_set !! \htmlinclude arg_table_temp_set_run.html !! SUBROUTINE temp_set_run(ncol, lev, timestep, temp_level, temp, ps, & - to_promote, errmsg, errflg) + to_promote, promote_pcnst, errmsg, errflg) !---------------------------------------------------------------- IMPLICIT NONE !---------------------------------------------------------------- @@ -30,6 +30,7 @@ SUBROUTINE temp_set_run(ncol, lev, timestep, temp_level, temp, ps, & real(kind_phys), intent(in) :: ps(:) REAL(kind_phys), INTENT(inout) :: temp_level(:, :) real(kind_phys), intent(out) :: to_promote(:, :) + real(kind_phys), intent(out) :: promote_pcnst(:) character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg !---------------------------------------------------------------- diff --git a/test/capgen_test/temp_set.meta b/test/capgen_test/temp_set.meta index f1dfc60f..b6c403ce 100644 --- a/test/capgen_test/temp_set.meta +++ b/test/capgen_test/temp_set.meta @@ -54,6 +54,13 @@ type = real kind = kind_phys intent = out +[ promote_pcnst ] + standard_name = promote_this_variable_with_no_horizontal_dimension + units = K + dimensions = (number_of_tracers) + type = real + kind = kind_phys + intent = out [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/capgen_test/test_reports.py b/test/capgen_test/test_reports.py index 8682a7b0..5b50215f 100644 --- a/test/capgen_test/test_reports.py +++ b/test/capgen_test/test_reports.py @@ -79,6 +79,7 @@ def usage(errmsg=None): _REQUIRED_VARS_DDT = _INPUT_VARS_DDT + _OUTPUT_VARS_DDT _PROT_VARS_TEMP = ["horizontal_loop_begin", "horizontal_loop_end", "horizontal_dimension", "vertical_layer_dimension", + "number_of_tracers", # Added for --debug "index_of_water_vapor_specific_humidity", "vertical_interface_dimension"]