Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support (and tests) for optional arguments in ccpp_prebuild #552

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cd5eae8
Add optional attribute to variable properties in ccpp_prebuild, parse…
climbfuji Mar 20, 2024
28b15cc
Update test_blocked_data, test_chunked_data to run in debug mode; pro…
climbfuji Mar 22, 2024
853f43d
Add test_prebuild/test_opt_arg
climbfuji Mar 22, 2024
6556d35
Add wrapper to run all prebuild tests
climbfuji Mar 22, 2024
5e4bae1
Fix target_link_libraries for ccpp-framework in src/CMakeLists.txt
climbfuji Mar 22, 2024
363e8e5
Revert me: nasty workaround to inject missing optional attribute int …
climbfuji Mar 22, 2024
f4d4d7f
Add 'optional' attribute in scripts/mkcap.py, update print_def_* rout…
climbfuji Mar 22, 2024
413e9ec
Add support for optional variables and pointers in auto-generated cap…
climbfuji Mar 22, 2024
61b0c61
Merge branch 'main' of https://github.com/NCAR/ccpp-framework into fe…
climbfuji Apr 3, 2024
8709a48
Comment out workaround to inject optional attribute into scheme metadata
climbfuji Apr 3, 2024
f9976d6
Bug fixes and workarounds for allocatable strings with GNU in scripts…
climbfuji Apr 18, 2024
01e2d8d
Issue warning if scheme variable is optional but variable is uncondit…
climbfuji Apr 19, 2024
8138e22
Declare maximum CCPP thread count and use arrays of pointers in ccpp_…
climbfuji Apr 27, 2024
a6e9f04
Merge branch 'main' of https://github.com/NCAR/ccpp-framework into fe…
climbfuji May 10, 2024
f2b9a55
Address self-review
climbfuji May 11, 2024
259a494
Update prebuild tests
climbfuji May 11, 2024
fba4ce0
Update CI
dustinswales May 14, 2024
0e00c17
Update CI w/ GNU v9 and v13
dustinswales May 14, 2024
7d2af1d
Adding additional matrix param for both os's and excluding invalid co…
mwaxmonsky May 15, 2024
c84c9f0
Removing spaces.
mwaxmonsky May 15, 2024
bb20702
Fixing syntax.
mwaxmonsky May 15, 2024
d769bb8
Nullify pointers in declaration in mkcap.py
climbfuji May 16, 2024
b8b754c
Merge pull request #3 from mwaxmonsky/feature/more_gnu_versions_in_CI
dustinswales May 16, 2024
87f9323
Update CI
dustinswales May 16, 2024
caae916
Update CI
dustinswales May 16, 2024
788d251
Update CI
dustinswales May 16, 2024
ba27abd
Update CI
dustinswales May 16, 2024
f73bbe8
Update CI
dustinswales May 16, 2024
3839c63
Update CI
dustinswales May 16, 2024
f1fde4a
Merge branch 'feature/prebuild_optarg_based_on_merge_feature_capgen_i…
dustinswales May 16, 2024
c298399
Merge pull request #3 from dustinswales/feature/more_gnu_versions_in_CI
climbfuji May 16, 2024
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
2 changes: 2 additions & 0 deletions scripts/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
CCPP_BLOCK_COUNT = 'ccpp_block_count'
CCPP_BLOCK_SIZES = 'ccpp_block_sizes'
CCPP_THREAD_NUMBER = 'ccpp_thread_number'
CCPP_THREAD_COUNT = 'ccpp_thread_count'

CCPP_CHUNK_EXTENT = 'ccpp_chunk_extent'
CCPP_HORIZONTAL_LOOP_BEGIN = 'horizontal_loop_begin'
Expand Down Expand Up @@ -60,6 +61,7 @@
CCPP_LOOP_COUNTER : 'cdata%loop_cnt',
CCPP_BLOCK_NUMBER : 'cdata%blk_no',
CCPP_THREAD_NUMBER : 'cdata%thrd_no',
CCPP_THREAD_COUNT : 'cdata%thrd_cnt',
}

STANDARD_CHARACTER_TYPE = 'character'
Expand Down
12 changes: 6 additions & 6 deletions scripts/mkcap.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,24 +338,24 @@ def print_def_local(self, metadata):
if self.type in STANDARD_VARIABLE_TYPES:
if self.kind:
if self.rank:
str = "{s.type}({s._kind}), dimension{s.rank}, pointer :: {s.local_name} => null()"
str = "{s.type}({s._kind}), dimension{s.rank}, pointer :: p"
climbfuji marked this conversation as resolved.
Show resolved Hide resolved
else:
str = "{s.type}({s._kind}), pointer :: {s.local_name} => null()"
str = "{s.type}({s._kind}), pointer :: p"
else:
if self.rank:
str = "{s.type}, dimension{s.rank}, pointer :: {s.local_name} => null()"
str = "{s.type}, dimension{s.rank}, pointer :: p"
else:
str = "{s.type}, pointer :: {s.local_name} => null()"
str = "{s.type}, pointer :: p"
else:
if self.kind:
error_message = "Generating variable definition statements for derived types with" + \
" kind attributes not implemented; variable: {0}".format(self.standard_name)
raise Exception(error_message)
else:
if self.rank:
str = "type({s.type}), dimension{s.rank}, pointer :: {s.local_name} => null()"
str = "type({s.type}), dimension{s.rank}, pointer :: p"
else:
str = "type({s.type}), pointer :: {s.local_name} => null()"
str = "type({s.type}), pointer :: p"
return str.format(s=self)
else:
# If the host variable is potentially unallocated, the active attribute is
Expand Down
52 changes: 40 additions & 12 deletions scripts/mkstatic.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from common import encode_container
from common import CCPP_STAGES
from common import CCPP_T_INSTANCE_VARIABLE, CCPP_ERROR_CODE_VARIABLE, CCPP_ERROR_MSG_VARIABLE, CCPP_LOOP_COUNTER, CCPP_LOOP_EXTENT
from common import CCPP_BLOCK_NUMBER, CCPP_BLOCK_COUNT, CCPP_BLOCK_SIZES, CCPP_THREAD_NUMBER, CCPP_INTERNAL_VARIABLES
from common import CCPP_BLOCK_NUMBER, CCPP_BLOCK_COUNT, CCPP_BLOCK_SIZES, CCPP_THREAD_NUMBER, CCPP_THREAD_COUNT, CCPP_INTERNAL_VARIABLES
from common import CCPP_HORIZONTAL_LOOP_BEGIN, CCPP_HORIZONTAL_LOOP_END, CCPP_CHUNK_EXTENT
from common import CCPP_CONSTANT_ONE, CCPP_HORIZONTAL_DIMENSION, CCPP_HORIZONTAL_LOOP_EXTENT, CCPP_NUM_INSTANCES
from common import FORTRAN_CONDITIONAL_REGEX_WORDS, FORTRAN_CONDITIONAL_REGEX
Expand Down Expand Up @@ -59,6 +59,12 @@
),
}

# Type and variable declarations for arrays of pointers, required for optional/inactive variables
TMPPTR_ARR_TYPE_DECLARATION = '''type :: {pointer_type_name}
{tmpptr_def}
end type {pointer_type_name}'''
TMPPTR_ARR_DECLARATION = '''type({pointer_type_name}), dimension({dims}) :: {localname}_array'''
climbfuji marked this conversation as resolved.
Show resolved Hide resolved

###############################################################################

def extract_parents_and_indices_from_local_name(local_name):
Expand Down Expand Up @@ -182,6 +188,7 @@ def create_arguments_module_use_var_defs(variable_dictionary, metadata_define, t
module_use = []
var_defs = []
local_kind_and_type_vars = []
local_pointer_type_defs = []

# We need to run through this loop twice. In the first pass, process all scalars.
# In the second pass, process all arrays. This is so that any potential dimension
Expand Down Expand Up @@ -222,9 +229,25 @@ def create_arguments_module_use_var_defs(variable_dictionary, metadata_define, t
# and add any local pointers (required for conditionally allocated arrays)
if tmpvars or tmpptrs:
var_defs.append('')
var_defs.append('! Local variables for unit conversions, array transformations, ...')
var_defs.append('! Local variables/pointers for unit conversions, array transformations, ...')
for tmpvar in list(tmpvars) + list(tmpptrs):
var_defs.append(tmpvar.print_def_local(metadata_define))
# Regular variables
if tmpvar in list(tmpvars):
var_defs.append(tmpvar.print_def_local(metadata_define))
# Pointers are more complicated
else:
if tmpvar.type == 'character' and 'len=' in tmpvar.kind:
pointer_type_name = f"{tmpvar.type}_{tmpvar.kind.replace('=','')}_r{len(tmpvar.dimensions)}_ptr_arr_type"
elif tmpvar.kind:
pointer_type_name = f"{tmpvar.type}_{tmpvar.kind}_rank{len(tmpvar.dimensions)}_ptr_arr_type"
else:
pointer_type_name = f"{tmpvar.type}_default_kind_rank{len(tmpvar.dimensions)}_ptr_arr_type"
if not pointer_type_name in local_pointer_type_defs:
var_defs.append(TMPPTR_ARR_TYPE_DECLARATION.format(pointer_type_name=pointer_type_name,
tmpptr_def=tmpvar.print_def_local(metadata_define)))
local_pointer_type_defs.append(pointer_type_name)
var_defs.append(TMPPTR_ARR_DECLARATION.format(pointer_type_name=pointer_type_name,
dims=f'1:{CCPP_INTERNAL_VARIABLES[CCPP_THREAD_COUNT]}', localname=tmpvar.local_name))
# Add special kind variables
if tmpvar.type in STANDARD_VARIABLE_TYPES and tmpvar.kind and not tmpvar.type == STANDARD_CHARACTER_TYPE:
kind_var_standard_name = tmpvar.kind
Expand Down Expand Up @@ -1632,7 +1655,8 @@ def write(self, metadata_request, metadata_define, arguments, debug):
if not conditional == '.true.':
# We don't want the dimstring here - this can lead to dimension mismatches.
# We know for sure that we need to reference the entire de-blocked array anyway.
actions_in += ' {p} => {t}\n'.format(p=tmpptr.local_name, t=tmpvar.local_name, d=dim_string)
actions_in += ' {p} => {t}\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p",
t=tmpvar.local_name, d=dim_string)

if var.actions['out']:
# Add unit conversion after returning from the subroutine, before copying the non-blocked
Expand All @@ -1644,7 +1668,7 @@ def write(self, metadata_request, metadata_define, arguments, debug):

# If the variable is conditionally allocated, nullify pointer
if not conditional == '.true.':
actions_out += ' nullify({p})\n'.format(p=tmpptr.local_name)
actions_out += ' nullify({p})\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

# Add the conditionals for the "before" operations
actions_before += '''
Expand All @@ -1663,7 +1687,8 @@ def write(self, metadata_request, metadata_define, arguments, debug):
if conditional == '.true.':
arg = '{local_name}={var_name},'.format(local_name=var.local_name, var_name=tmpvar.local_name)
else:
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name, ptr_name=tmpptr.local_name)
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name,
ptr_name=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

# Variables stored in blocked data structures but without horizontal dimension not supported at this time (doesn't make sense anyway)
elif ccpp_stage in ['init', 'timestep_init', 'timestep_finalize', 'finalize'] and \
Expand Down Expand Up @@ -1706,7 +1731,8 @@ def write(self, metadata_request, metadata_define, arguments, debug):
d=dim_string)
# If the variable is conditionally allocated, assign pointer
if not conditional == '.true.':
actions_in += ' {p} => {t}{d}\n'.format(p=tmpptr.local_name, t=tmpvar.local_name, d=dim_string)
actions_in += ' {p} => {t}{d}\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p",
t=tmpvar.local_name, d=dim_string)
if var.actions['out']:
# Add unit conversion after returning from the subroutine
actions_out += ' {v}{d} = {c}\n'.format(v=tmpvar.target.replace(dim_string_target_name, ''),
Expand All @@ -1715,7 +1741,7 @@ def write(self, metadata_request, metadata_define, arguments, debug):
kind=kind_string))
# If the variable is conditionally allocated, nullify pointer
if not conditional == '.true.':
actions_out += ' nullify({p})\n'.format(p=tmpptr.local_name)
actions_out += ' nullify({p})\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

if tmpvar.rank:
# Add deallocate statement if the variable has a rank > 0
Expand All @@ -1739,7 +1765,8 @@ def write(self, metadata_request, metadata_define, arguments, debug):
arg = '{local_name}={var_name}{dim_string},'.format(local_name=var.local_name,
var_name=tmpvar.local_name.replace(dim_string_target_name, ''), dim_string=dim_string)
else:
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name, ptr_name=tmpptr.local_name)
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name,
ptr_name=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

# Ordinary variables, no blocked data or unit conversions
elif var_standard_name in arguments[scheme_name][subroutine_name]:
Expand All @@ -1750,12 +1777,12 @@ def write(self, metadata_request, metadata_define, arguments, debug):
actions_out = ''
# If the variable is conditionally allocated, assign pointer
if not conditional == '.true.':
actions_in += ' {p} => {t}{d}\n'.format(p=tmpptr.local_name,
actions_in += ' {p} => {t}{d}\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p",
t=var.target.replace(dim_string_target_name, ''),
d=dim_string)
# If the variable is conditionally allocated, nullify pointer
if not conditional == '.true.':
actions_out += ' nullify({p})\n'.format(p=tmpptr.local_name)
actions_out += ' nullify({p})\n'.format(p=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

if actions_in:
# Add the conditionals for the "before" operations
Expand All @@ -1777,7 +1804,8 @@ def write(self, metadata_request, metadata_define, arguments, debug):
arg = '{local_name}={var_name}{dim_string},'.format(local_name=var.local_name,
var_name=local_vars[var_standard_name]['name'].replace(dim_string_target_name, ''), dim_string=dim_string)
else:
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name, ptr_name=tmpptr.local_name)
arg = '{local_name}={ptr_name},'.format(local_name=var.local_name,
ptr_name=f"{tmpptr.local_name}_array({CCPP_INTERNAL_VARIABLES[CCPP_THREAD_NUMBER]})%p")

else:
arg = ''
Expand Down
4 changes: 4 additions & 0 deletions src/ccpp_types.F90
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ module ccpp_types
integer, parameter :: CCPP_DEFAULT_CHUNK_NUMBER = -999
integer, parameter :: CCPP_DEFAULT_THREAD_NUMBER = -999

!> @var The default maximum number of threads for CCPP
integer, parameter :: CCPP_DEFAULT_THREAD_COUNT = -999

!! \section arg_table_ccpp_t
!! \htmlinclude ccpp_t.html
!!
Expand All @@ -64,6 +67,7 @@ module ccpp_types
integer :: blk_no = CCPP_DEFAULT_BLOCK_NUMBER
integer :: chunk_no = CCPP_DEFAULT_CHUNK_NUMBER
integer :: thrd_no = CCPP_DEFAULT_THREAD_NUMBER
integer :: thrd_cnt = CCPP_DEFAULT_THREAD_COUNT
integer :: ccpp_instance = 1

contains
Expand Down
6 changes: 6 additions & 0 deletions src/ccpp_types.meta
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@
units = index
dimensions = ()
type = integer
[thrd_cnt]
standard_name = ccpp_thread_count
long_name = total number of threads for threading in CCPP
units = index
dimensions = ()
type = integer
[ccpp_instance]
standard_name = ccpp_instance
long_name = ccpp_instance
Expand Down
Loading