diff --git a/scripts/ccpp_suite.py b/scripts/ccpp_suite.py index 1182fd43..9657a221 100644 --- a/scripts/ccpp_suite.py +++ b/scripts/ccpp_suite.py @@ -319,6 +319,7 @@ def find_variable(self, standard_name=None, source_var=None, # at the init stage (for allocation) for group in self.groups: # only add dimension variables to init phase calling list + # if they're not module-level "suite" variables if group.name == self.__suite_init_group.name: dims = var.get_dimensions() # replace horizontal loop dimension if necessary @@ -337,6 +338,7 @@ def find_variable(self, standard_name=None, source_var=None, self.__run_env) # Add dimensions if they're not already there group.add_variable_dimensions(temp_var, [], + _API_SUITE_VAR_NAME, adjust_intent=True, to_dict=group.call_list) # end if diff --git a/scripts/metavar.py b/scripts/metavar.py index 8f283df6..7285f6ad 100755 --- a/scripts/metavar.py +++ b/scripts/metavar.py @@ -1739,12 +1739,15 @@ def remove_variable(self, standard_name): del self[standard_name] # end if - def add_variable_dimensions(self, var, ignore_sources, to_dict=None, - adjust_intent=False): + def add_variable_dimensions(self, var, ignore_sources, suite_type, + to_dict=None, adjust_intent=False): """Attempt to find a source for each dimension in and add that Variable to this dictionary or to , if passed. Dimension variables which are found but whose Source is in are not added to this dictionary. + Dimension variabes which are found at the suite level (determined + by ) are also not added to this dictionary because + module-level suite variables are accessible by any phase. Return an error string on failure.""" err_ret = '' @@ -1763,6 +1766,11 @@ def add_variable_dimensions(self, var, ignore_sources, to_dict=None, # end if if not present: dvar = self.find_variable(standard_name=dimname, any_scope=True) + if dvar and dvar.source.ptype == suite_type: + # Do nothing - this is a module-level variable so we don't + # need to add it to any dictionaries + return + # end if if dvar and (dvar.source.ptype not in ignore_sources): if to_dict: to_dict.add_variable(dvar, self.__run_env, diff --git a/scripts/suite_objects.py b/scripts/suite_objects.py index 15b40a65..b1de44b8 100755 --- a/scripts/suite_objects.py +++ b/scripts/suite_objects.py @@ -2339,7 +2339,8 @@ def manage_variable(self, newvar): self.run_env) self.add_variable(local_var, self.run_env, exists_ok=True, gen_unique=True) # Finally, make sure all dimensions are accounted for - emsg = self.add_variable_dimensions(local_var, _API_LOCAL_VAR_TYPES, + emsg = self.add_variable_dimensions(local_var, [_API_LOCAL_VAR_NAME], + _API_SUITE_VAR_NAME, adjust_intent=True, to_dict=self.call_list) if emsg: @@ -2383,6 +2384,11 @@ def allocate_dim_str(self, dims, context): if dvar is None: dvar = self.call_list.find_variable(standard_name=dpart, any_scope=False) + # end if + if dvar is None: + # Check if it's a module-level variable + dvar = self.find_variable(standard_name=dpart, any_scope=True) + # end if if dvar is None: emsg = "Dimension variable, '{}', not found{}" lvar = self.find_local_name(dpart, any_scope=True) diff --git a/test/capgen_test/README.md b/test/capgen_test/README.md index f989cbc0..66587ddf 100644 --- a/test/capgen_test/README.md +++ b/test/capgen_test/README.md @@ -7,6 +7,8 @@ Contains tests for overall capgen capabilities such as: - Dimensions with `ccpp_constant_one:N` and just `N` - Non-standard dimensions (not just horizontal and vertical) (including integer dimensions) - Variables that should be promoted to suite level +- Dimensions that are set in the register phase and used to allocate module-level + interstitial variables ## Building/Running diff --git a/test/capgen_test/temp_adjust.F90 b/test/capgen_test/temp_adjust.F90 index e9733786..4dcf408f 100644 --- a/test/capgen_test/temp_adjust.F90 +++ b/test/capgen_test/temp_adjust.F90 @@ -34,7 +34,7 @@ end subroutine temp_adjust_register !> \section arg_table_temp_adjust_run Argument Table !! \htmlinclude arg_table_temp_adjust_run.html !! - subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & + subroutine temp_adjust_run(foo, timestep, interstitial_var, temp_prev, temp_layer, qv, ps, & to_promote, promote_pcnst, errmsg, errflg, innie, outie, optsie) integer, intent(in) :: foo @@ -45,6 +45,7 @@ subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & REAL(kind_phys), intent(inout) :: temp_layer(foo) real(kind_phys), intent(in) :: to_promote(:) real(kind_phys), intent(in) :: promote_pcnst(:) + integer, intent(out) :: interstitial_var(:) character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg real(kind_phys), optional, intent(in) :: innie @@ -57,6 +58,13 @@ subroutine temp_adjust_run(foo, timestep, temp_prev, temp_layer, qv, ps, & errmsg = '' errflg = 0 + interstitial_var = 6 + if (size(interstitial_var) /= 3) then + errflg = 1 + errmsg = 'interstitial variable not allocated properly!' + return + end if + if (.not. module_level_config) then ! do nothing return @@ -91,8 +99,9 @@ end subroutine temp_adjust_init !> \section arg_table_temp_adjust_finalize Argument Table !! \htmlinclude arg_table_temp_adjust_finalize.html !! - subroutine temp_adjust_finalize (errmsg, errflg) + subroutine temp_adjust_finalize (interstitial_var, errmsg, errflg) + integer, intent(in) :: interstitial_var(:) character(len=512), intent(out) :: errmsg integer, intent(out) :: errflg @@ -100,6 +109,15 @@ subroutine temp_adjust_finalize (errmsg, errflg) errmsg = '' errflg = 0 + if (size(interstitial_var) /= 3) then + errflg = 1 + errmsg = 'interstitial variable not allocated properly!' + return + end if + if (interstitial_var(1) /= 6) then + errflg = 1 + errmsg = 'interstitial variable not set properly!' + end if end subroutine temp_adjust_finalize diff --git a/test/capgen_test/temp_adjust.meta b/test/capgen_test/temp_adjust.meta index e3006508..f754e7c4 100644 --- a/test/capgen_test/temp_adjust.meta +++ b/test/capgen_test/temp_adjust.meta @@ -44,6 +44,12 @@ type = real kind = kind_phys intent = in +[ interstitial_var ] + standard_name = output_only_interstitial_variable + units = 1 + dimensions = (dimension_for_interstitial_variable) + type = integer + intent = out [ temp_prev ] standard_name = potential_temperature_at_previous_timestep units = K @@ -126,6 +132,12 @@ [ccpp-arg-table] name = temp_adjust_finalize type = scheme +[ interstitial_var ] + standard_name = output_only_interstitial_variable + units = 1 + dimensions = (dimension_for_interstitial_variable) + type = integer + intent = in [ errmsg ] standard_name = ccpp_error_message long_name = Error message for error handling in CCPP diff --git a/test/capgen_test/temp_calc_adjust.F90 b/test/capgen_test/temp_calc_adjust.F90 index 61c466f2..cee03dbf 100644 --- a/test/capgen_test/temp_calc_adjust.F90 +++ b/test/capgen_test/temp_calc_adjust.F90 @@ -8,12 +8,25 @@ MODULE temp_calc_adjust IMPLICIT NONE PRIVATE + PUBLIC :: temp_calc_adjust_register PUBLIC :: temp_calc_adjust_init PUBLIC :: temp_calc_adjust_run PUBLIC :: temp_calc_adjust_finalize CONTAINS + !> \section arg_table_temp_calc_adjust_register Argument Table + !! \htmlinclude arg_table_temp_calc_adjust_register.html + !! + SUBROUTINE temp_calc_adjust_register(dim_inter, errmsg, errflg) + integer, intent(out) :: dim_inter + character(len=512), intent(out) :: errmsg + integer, intent(out) :: errflg + + errflg = 0 + errmsg = '' + dim_inter = 3 + END SUBROUTINE temp_calc_adjust_register !> \section arg_table_temp_calc_adjust_run Argument Table !! \htmlinclude arg_table_temp_calc_adjust_run.html !! diff --git a/test/capgen_test/temp_calc_adjust.meta b/test/capgen_test/temp_calc_adjust.meta index 437de934..e014fb6e 100644 --- a/test/capgen_test/temp_calc_adjust.meta +++ b/test/capgen_test/temp_calc_adjust.meta @@ -2,6 +2,30 @@ name = temp_calc_adjust type = scheme dependencies = foo.F90, bar.F90 +[ccpp-arg-table] + name = temp_calc_adjust_register + type = scheme +[ dim_inter ] + standard_name = dimension_for_interstitial_variable + type = integer + units = count + dimensions = () + intent = out +[ errmsg ] + standard_name = ccpp_error_message + long_name = Error message for error handling in CCPP + units = none + dimensions = () + type = character + kind = len=512 + intent = out +[ errflg ] + standard_name = ccpp_error_code + long_name = Error flag for error handling in CCPP + units = 1 + dimensions = () + type = integer + intent = out [ccpp-arg-table] name = temp_calc_adjust_run type = scheme