Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
CCPP_ERROR_FLAG_VARIABLE = 'ccpp_error_flag'
CCPP_ERROR_MSG_VARIABLE = 'ccpp_error_message'
CCPP_LOOP_COUNTER = 'ccpp_loop_counter'
CCPP_LOOP_EXTENT = 'ccpp_loop_extent'
CCPP_BLOCK_NUMBER = 'ccpp_block_number'
CCPP_BLOCK_COUNT = 'ccpp_block_count'
CCPP_BLOCK_SIZES = 'ccpp_block_sizes'
Expand Down
47 changes: 39 additions & 8 deletions scripts/mkstatic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from common import encode_container
from common import CCPP_STAGES
from common import CCPP_ERROR_FLAG_VARIABLE, CCPP_ERROR_MSG_VARIABLE, CCPP_LOOP_COUNTER
from common import CCPP_ERROR_FLAG_VARIABLE, CCPP_ERROR_MSG_VARIABLE, CCPP_LOOP_COUNTER, CCPP_LOOP_EXTENT
from common import CCPP_BLOCK_NUMBER, CCPP_BLOCK_COUNT, CCPP_BLOCK_SIZES, CCPP_INTERNAL_VARIABLES
from common import CCPP_HORIZONTAL_DIMENSION, CCPP_HORIZONTAL_LOOP_EXTENT
from common import FORTRAN_CONDITIONAL_REGEX_WORDS, FORTRAN_CONDITIONAL_REGEX
Expand Down Expand Up @@ -900,6 +900,10 @@ def write(self, metadata_request, metadata_define, arguments):

# First get target names of standard CCPP variables for subcycling and error handling
ccpp_loop_counter_target_name = metadata_request[CCPP_LOOP_COUNTER][0].target
if CCPP_LOOP_EXTENT in metadata_request.keys():
ccpp_loop_extent_target_name = metadata_request[CCPP_LOOP_EXTENT][0].target
else:
ccpp_loop_extent_target_name = None
ccpp_error_flag_target_name = metadata_request[CCPP_ERROR_FLAG_VARIABLE][0].target
ccpp_error_msg_target_name = metadata_request[CCPP_ERROR_MSG_VARIABLE][0].target
#
Expand Down Expand Up @@ -930,10 +934,8 @@ def write(self, metadata_request, metadata_define, arguments):
conditionals = {}
#
for subcycle in self._subcycles:
if subcycle.loop > 1 and ccpp_stage == 'run':
body += '''
associate(cnt => {loop_var_name})
do cnt=1,{loop_cnt}\n\n'''.format(loop_var_name=ccpp_loop_counter_target_name,loop_cnt=subcycle.loop)
subcycle_body = ''
# Call all schemes
for scheme_name in subcycle.schemes:
# actions_before and actions_after capture operations such
# as unit conversions, transformations that have to happen
Expand Down Expand Up @@ -1348,18 +1350,47 @@ def write(self, metadata_request, metadata_define, arguments):
return
end if
'''.format(target_name_flag=ccpp_error_flag_target_name, target_name_msg=ccpp_error_msg_target_name, subroutine_name=subroutine_name)
body += '''
subcycle_body += '''
{subroutine_call}
{error_check}
'''.format(subroutine_call=subroutine_call, error_check=error_check)

module_use += ' use {m}, only: {s}\n'.format(m=module_name, s=subroutine_name)

if subcycle.loop > 1 and ccpp_stage == 'run':
body += '''
# If this subcycle calls any schemes, i.e. has any variables registered
# that need to be passed to the group for this stage, then handle the
# subcycle loops by prepending/appending the necessary code to subcycle_body
subcycle_body_prefix = '''
! Start of next subcycle
'''
subcycle_body_suffix = ''
if self.parents[ccpp_stage]:
# Set subcycle loop extent if requested by any scheme
if ccpp_loop_extent_target_name and ccpp_stage == 'run':
subcycle_body_prefix += '''
! Set loop extent variable for the following subcycle
{loop_extent_var_name} = {loop_cnt_max}\n\n'''.format(loop_extent_var_name=ccpp_loop_extent_target_name,
loop_cnt_max=subcycle.loop)
elif ccpp_loop_extent_target_name:
subcycle_body_prefix += '''
! Set loop extent variable for the following subcycle
{loop_extent_var_name} = 1\n\n'''.format(loop_extent_var_name=ccpp_loop_extent_target_name)
# Create subcycle (Fortran do loop) if needed
if subcycle.loop > 1 and ccpp_stage == 'run':
subcycle_body_prefix += '''
associate(cnt => {loop_var_name})
do cnt=1,{loop_cnt_max}\n\n'''.format(loop_var_name=ccpp_loop_counter_target_name,
loop_cnt_max=subcycle.loop)
subcycle_body_suffix += '''
end do
end associate
'''
else:
subcycle_body_prefix += '''
{loop_var_name} = 1\n'''.format(loop_var_name=ccpp_loop_counter_target_name)

# Add this subcycle's Fortran body to the group body
body += subcycle_body_prefix + subcycle_body + subcycle_body_suffix

# Get list of arguments, module use statement and variable definitions for this subroutine (=stage for the group)
(self.arguments[ccpp_stage], sub_module_use, sub_var_defs) = create_arguments_module_use_var_defs(
Expand Down
2 changes: 2 additions & 0 deletions src/ccpp_types.F90
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module ccpp_types

!> @var The default loop counter indicating outside of a subcycle loop
integer, parameter :: CCPP_DEFAULT_LOOP_CNT = -999
integer, parameter :: CCPP_DEFAULT_LOOP_MAX = -999

!> @var The default values for block and thread numbers indicating invalid data
integer, parameter :: CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER = -999
Expand All @@ -51,6 +52,7 @@ module ccpp_types
integer :: errflg = 0
character(len=512) :: errmsg = ''
integer :: loop_cnt = CCPP_DEFAULT_LOOP_CNT
integer :: loop_max = CCPP_DEFAULT_LOOP_MAX
integer :: blk_no = CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER
integer :: thrd_no = CCPP_DEFAULT_BLOCK_AND_THREAD_NUMBER

Expand Down
6 changes: 6 additions & 0 deletions src/ccpp_types.meta
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
units = index
dimensions = ()
type = integer
[loop_max]
standard_name = ccpp_loop_extent
long_name = loop extent for subcycling loops in CCPP
units = count
dimensions = ()
type = integer
[blk_no]
standard_name = ccpp_block_number
long_name = number of block for explicit data blocking in CCPP
Expand Down