Skip to content

Commit

Permalink
update register_constituents error handling; misc review requests
Browse files Browse the repository at this point in the history
  • Loading branch information
Courtney Peverley committed Feb 25, 2024
1 parent e48faa5 commit 2401436
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 88 deletions.
13 changes: 11 additions & 2 deletions scripts/ccpp_capgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,17 @@ def capgen(run_env, return_db=False):
# Pull out the dynamic constituent routines, if any
dyn_const_dict = {}
for table in scheme_tdict:
if scheme_tdict[table].dyn_const_routine is not None:
dyn_const_dict[table] = scheme_tdict[table].dyn_const_routine
routine_name = scheme_tdict[table].dyn_const_routine
if routine_name is not None:
if routine_name not in dyn_const_dict.values():
dyn_const_dict[table] = scheme_tdict[table].dyn_const_routine
else:
# dynamic constituent routines must have unique names
scheme_name = list(dyn_const_dict.keys())[list(dyn_const_dict.values()).index(routine_name)]
errmsg = f"ERROR: Dynamic constituent routine names must be unique. Cannot add " \
f"{routine_name} for {table}. Routine already exists in {scheme_name}. "
raise CCPPError(errmsg)
# end if
# end if
# end for
if run_env.verbose:
Expand Down
2 changes: 1 addition & 1 deletion scripts/ccpp_datafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def _retrieve_dyn_const_routines(table):
result = set()
routines = table.find("dyn_const_routines")
if routines is None:
raise CCPPDatatableError("Could not find 'dyn_const_routine' element")
raise CCPPDatatableError("Could not find 'dyn_const_routines' element")
# end if
for routine in routines:
routine_name = routine.text
Expand Down
159 changes: 75 additions & 84 deletions scripts/constituents.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def num_consts_funcname(self):

def const_name_subname(self):
"""Return the name of the routine that returns a constituent's
given an index"""
standard name given an index"""
return f"{self.name}_const_name"

def copy_const_subname(self):
Expand Down Expand Up @@ -470,7 +470,6 @@ def write_host_routines(cap, host, reg_funcname, init_funcname, num_const_funcna
herrcode, herrmsg = ConstituentVarDict.__errcode_names(err_vars)
err_dummy_str = f"{herrcode}, {herrmsg}"
obj_err_callstr = f"errcode={herrcode}, errmsg={herrmsg}"
obj_err_callstr = obj_err_callstr
# XXgoldyXX: ^ need to generalize host model error var type support
# First up, the registration routine
substmt = f"subroutine {reg_funcname}"
Expand All @@ -483,10 +482,10 @@ def write_host_routines(cap, host, reg_funcname, init_funcname, num_const_funcna
# Conditionally include use statements for dynamic constituent routines
if len(dyn_const_dict) > 0:
cap.comment("Dynamic constituent routines", 2)
for scheme in dyn_const_dict:
cap.write(f"use {scheme}, only: {dyn_const_dict[scheme]}", 2)
# end for
# end if
for scheme in dyn_const_dict:
cap.write(f"use {scheme}, only: {dyn_const_dict[scheme]}", 2)
# end for
cap.blank_line()
cap.comment("Dummy arguments", 2)
cap.write("character(len=*), intent(in) :: suite_list(:)", 2)
Expand Down Expand Up @@ -521,127 +520,119 @@ def write_host_routines(cap, host, reg_funcname, init_funcname, num_const_funcna
errvar_str = ConstituentVarDict.__errcode_callstr(herrcode,
herrmsg, suite)
cap.write(f"num_suite_consts = {funcname}({errvar_str})", 2)
cap.write(f"if ({herrcode} /= 0) then", 2)
cap.write("return", 3)
cap.write("end if", 2)
cap.write("num_consts = num_consts + num_suite_consts", 2)
# end for
# Check for dynamic constituent routines
if len(dyn_const_dict) > 0:
cap.comment("Add in dynamic constituents", 2)
for idx, scheme in enumerate(sorted(dyn_const_dict)):
cap.write(f"if ({herrcode} == 0) then", 2)
cap.write(f"call {dyn_const_dict[scheme]}(dyn_const_prop_{idx}, {obj_err_callstr})", 3)
cap.write(f"num_dyn_consts = num_dyn_consts + size(dyn_const_prop_{idx})", 3)
cap.write(f"call {dyn_const_dict[scheme]}(dyn_const_prop_{idx}, {obj_err_callstr})", 2)
cap.write(f"if ({herrcode} /= 0) then", 2)
cap.write("return", 3)
cap.write("end if", 2)
cap.write(f"num_dyn_consts = num_dyn_consts + size(dyn_const_prop_{idx})", 2)
# end for
cap.write("num_consts = num_consts + num_dyn_consts", 2)
cap.comment("Pack dynamic_constituents array", 2)
cap.write(f"allocate(dynamic_constituents(num_dyn_consts), stat={herrcode})", 2)
cap.write(f"if ({herrcode} /= 0) then", 2)
cap.write(f"{herrmsg} = 'failed to allocate dynamic_constituents'", 3)
cap.write("else", 2)
cap.write("index_start = 1", 3)
cap.write("return", 3)
cap.write("end if", 2)
cap.write("index_start = 0", 2)
for idx, scheme in enumerate(sorted(dyn_const_dict)):
cap.write(f"do index = 1, size(dyn_const_prop_{idx}, 1)", 3)
cap.write(f"dynamic_constituents(index + index_start - 1) = dyn_const_prop_{idx}(index)", 4)
cap.write("end do", 3)
cap.write(f"index_start = size(dyn_const_prop_{idx}, 1) + 1", 3)
cap.write(f"deallocate(dyn_const_prop_{idx})", 3)
cap.write(f"do index = 1, size(dyn_const_prop_{idx}, 1)", 2)
cap.write(f"dynamic_constituents(index + index_start) = dyn_const_prop_{idx}(index)", 3)
cap.write("end do", 2)
cap.write(f"index_start = size(dyn_const_prop_{idx}, 1)", 2)
cap.write(f"deallocate(dyn_const_prop_{idx})", 2)
# end for
cap.write("end if", 2)
# end if
cap.write(f"if ({herrcode} == 0) then", 2)
cap.comment("Initialize constituent data and field object", 3)
cap.comment("Initialize constituent data and field object", 2)
stmt = f"call {const_obj_name}%initialize_table(num_consts)"
cap.write(stmt, 3)
cap.write(stmt, 2)
# Register host model constituents
cap.comment("Add host model constituent metadata", 3)
cap.write("do index = 1, size(host_constituents, 1)", 3)
cap.write(f"if ({herrcode} == 0) then", 4)
cap.write("const_prop => host_constituents(index)", 5)
cap.comment("Add host model constituent metadata", 2)
cap.write("do index = 1, size(host_constituents, 1)", 2)
cap.write("const_prop => host_constituents(index)", 3)
stmt = f"call {const_obj_name}%new_field(const_prop, {obj_err_callstr})"
cap.write(stmt, 5)
cap.write("end if", 4)
cap.write("nullify(const_prop)", 4)
cap.write(f"if ({herrcode} /= 0) then", 4)
cap.write("exit", 5)
cap.write("end if", 4)
cap.write("end do", 3)
cap.write("end if", 2)
cap.write(stmt, 3)
cap.write("nullify(const_prop)", 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
cap.write("end do", 2)
cap.blank_line()
# Register dynamic constituents
if len(dyn_const_dict) > 0:
cap.comment("Add dynamic constituent properties", 2)
cap.write(f"if ({herrcode} == 0) then", 2)
cap.write(f"do index = 1, size(dynamic_constituents, 1)", 3)
cap.write(f"if ({herrcode} == 0) then", 4)
cap.write(f"const_prop => dynamic_constituents(index)", 5)
cap.write(f"do index = 1, size(dynamic_constituents, 1)", 2)
cap.write(f"const_prop => dynamic_constituents(index)", 3)
stmt = f"call {const_obj_name}%new_field(const_prop, {obj_err_callstr})"
cap.write(stmt, 5)
cap.write("end if", 4)
cap.write("nullify(const_prop)", 4)
cap.write(f"if ({herrcode} /= 0) then", 4)
cap.write("exit", 5)
cap.write("end if", 4)
cap.write("end do", 3)
cap.write("end if", 2)
cap.write(stmt, 3)
cap.write("nullify(const_prop)", 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
cap.write("end do", 2)
# end if

# Register suite constituents
for suite in suite_list:
errvar_str = ConstituentVarDict.__errcode_callstr(herrcode,
herrmsg, suite)
cap.write(f"if ({herrcode} == 0) then", 2)
cap.comment(f"Add {suite.name} constituent metadata", 3)
cap.comment(f"Add {suite.name} constituent metadata", 2)
const_dict = suite.constituent_dictionary()
funcname = const_dict.num_consts_funcname()
cap.write(f"num_suite_consts = {funcname}({errvar_str})", 3)
cap.write(f"num_suite_consts = {funcname}({errvar_str})", 2)
cap.write(f"if ({herrcode} /= 0) then", 2)
cap.write("return", 3)
cap.write("end if", 2)
funcname = const_dict.copy_const_subname()
cap.write(f"if ({herrcode} == 0) then", 2)
cap.write("do index = 1, num_suite_consts", 3)
cap.write(f"if ({herrcode} == 0) then", 4)
cap.write(f"allocate(const_prop, stat={herrcode})", 5)
cap.write("end if", 4)
cap.write(f"if ({herrcode} /= 0) then", 4)
cap.write(f'{herrmsg} = "ERROR allocating const_prop"', 5)
cap.write("exit", 5)
cap.write("end if", 4)
cap.write(f"if ({herrcode} == 0) then", 4)
cap.write("do index = 1, num_suite_consts", 2)
cap.write(f"allocate(const_prop, stat={herrcode})", 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write(f'{herrmsg} = "ERROR allocating const_prop"', 4)
cap.write("return", 4)
cap.write("end if", 3)
stmt = f"call {funcname}(index, const_prop, {errvar_str})"
cap.write(stmt, 5)
cap.write("end if", 4)
cap.write(f"if ({herrcode} == 0) then", 4)
cap.write(stmt, 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
stmt = f"call {const_obj_name}%new_field(const_prop, {obj_err_callstr})"
cap.write(stmt, 5)
cap.write("end if", 4)
cap.write("nullify(const_prop)", 4)
cap.write(f"if ({herrcode} /= 0) then", 4)
cap.write("exit", 5)
cap.write("end if", 4)
cap.write("end do", 3)
cap.write("end if", 2)
cap.write(stmt, 3)
cap.write("nullify(const_prop)", 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
cap.write("end do", 2)
cap.blank_line()
# end for
cap.write(f"if ({herrcode} == 0) then", 2)
stmt = f"call {const_obj_name}%lock_table({obj_err_callstr})"
cap.write(stmt, 3)
cap.write(stmt, 2)
cap.write(f"if ({herrcode} /= 0) then", 2)
cap.write("return", 3)
cap.write("end if", 2)
cap.write(f"if ({herrcode} == 0) then", 2)
cap.comment("Set the index for each active constituent", 3)
cap.write(f"do index = 1, SIZE({const_indices_name})", 3)
cap.comment("Set the index for each active constituent", 2)
cap.write(f"do index = 1, SIZE({const_indices_name})", 2)
stmt = f"call {const_obj_name}%const_index(field_ind, {const_names_name}(index), {obj_err_callstr})"
cap.write(stmt, 4)
cap.write("if (field_ind > 0) then", 4)
cap.write(f"{const_indices_name}(index) = field_ind", 5)
cap.write("else", 4)
cap.write(f"{herrcode} = 1", 5)
cap.write(stmt, 3)
cap.write(f"if ({herrcode} /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
cap.write("if (field_ind > 0) then", 3)
cap.write(f"{const_indices_name}(index) = field_ind", 4)
cap.write("else", 3)
cap.write(f"{herrcode} = 1", 4)
stmt = f"{herrmsg} = 'No field index for '//trim({const_names_name}(index))"
cap.write(stmt, 5)
cap.write("end if", 4)
cap.write(f"if ({herrcode} /= 0) then", 4)
cap.write("exit", 5)
cap.write("end if", 4)
cap.write("end do", 3)
cap.write("end if", 2)
cap.write(stmt, 4)
cap.write("return", 4)
cap.write("end if", 3)
cap.write("end do", 2)
cap.write(f"end {substmt}", 1)
# Write constituent_init routine
substmt = f"subroutine {init_funcname}"
Expand Down
2 changes: 1 addition & 1 deletion test/advection_test/test_host.F90
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ subroutine test_host(retval, test_suites)
end if
if (errflg == 0) then
if (const_log) then
write(6, *) "ERROR: dyn_const2 is dry"
write(6, *) "ERROR: dyn_const2 is dry and should be moist"
errflg_final = -1
end if
else
Expand Down

0 comments on commit 2401436

Please sign in to comment.