-
Notifications
You must be signed in to change notification settings - Fork 136
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
coupler mixed precision #1353
coupler mixed precision #1353
Conversation
coupler/atmos_ocean_fluxes.F90
Outdated
logical, intent(in), dimension(:), optional :: flag !< flag | ||
real, intent(in), optional :: mol_wt !< mol_wt | ||
real(r8_kind), intent(in), optional :: mol_wt !< mol_wt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it'd be better if mol_wt was a class(*) here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's where it ends up being used in this routine:
FMS/coupler/atmos_ocean_fluxes.F90
Lines 298 to 302 in 5d8e7ff
if (present(mol_wt)) then | |
call fm_util_set_value('mol_wt', mol_wt) | |
else | |
call fm_util_set_value('mol_wt', 0.0) | |
endif |
But then also again here:
FMS/coupler/atmos_ocean_fluxes.F90
Line 645 in 5d8e7ff
gas_fluxes%bc(n)%mol_wt = fm_util_get_real('mol_wt', scalar = .true.) |
I think fm_util_get_real is r8_kind only right cause of the read in strings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that and because there was no way to tell what precision the user wanted based on the input arguments. I'm wondering if the users will pass in r4_kind mol_wt here because they're assuming that the r4 version of bc will be populated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah to be safe I'll switch it over to a class(*), since it's intent(in) should be fine.
gas_fluxes%bc_r4(n)%atm_tr_index = fm_util_get_integer('atm_tr_index', scalar = .true.) | ||
|
||
! Save the molecular weight. | ||
gas_fluxes%bc_r4(n)%mol_wt = fm_util_get_real('mol_wt', scalar = .true.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should there be a real,r4_kind) around fm_util_get_real? I think fm_util_get_real returns an r8_kind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just left the mol_wt and param fields as r8_kind regardless, this way they are always the value returned by the field manager.
allocate (gas_fluxes%bc(gas_fluxes%num_bcs)) | ||
allocate (gas_fields_atm%bc(gas_fields_atm%num_bcs)) | ||
allocate (gas_fields_ice%bc(gas_fields_ice%num_bcs)) | ||
if(present(use_r4_kind)) use_r4_kind_loc = use_r4_kind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if this should go on top before the while loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean, I have this if for allocation here and then the while loop below has another if within it for the parts that use reals.
@@ -424,7 +424,7 @@ end function aof_set_coupler_flux | |||
!! @throw FATAL, "Num_flags is negative for [name]: [num_flags]" | |||
!! @throw FATAL, "Problem dumping fluxes tracer tree" | |||
!! @throw FATAL, "Number of fluxes does not match across the processors: [gas_fluxes%num_bcs] fluxes" | |||
subroutine atmos_ocean_fluxes_init(gas_fluxes, gas_fields_atm, gas_fields_ice, verbosity) | |||
subroutine atmos_ocean_fluxes_init(gas_fluxes, gas_fields_atm, gas_fields_ice, verbosity, use_r4_kind) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think there will be a case where the user wants these three fluxes to be set at different precisions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not know honestly. It could be added using similar logic later on if we need it.
coupler/coupler_types.F90
Outdated
@@ -412,6 +562,9 @@ subroutine coupler_type_copy_1d_2d(var_in, var_out, is, ie, js, je,& | |||
call mpp_error(FATAL, trim(error_header) // ' Number of output fields exceeds zero') | |||
endif | |||
|
|||
if(associated(var_in%bc) .eq. associated(var_in%bc_r4)) & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could there be a chance both are unassociated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah definitely, thats why its comparing the logical return values. If they are both associated or both not associated it will error out, this way it'll ensure that the r4/r8 field types used are mutually exclusive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the code, the bc's could intentionally be not associated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the previous code would seg fault if you did that, these routines all essentially assume the child type is previously allocated for intent(in) types. edit: i was wrong, its only allocated when num_bc > 0. the loops that use bc/bc_r4 just don't run otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put in a fix, the check for allocation needed to be after the checks for the optional as_needed
argument. I also made updates so that it'll only check for one kind allocated if var%set
is true since it indicates initialization.
& var%bc(n)%field(m)%name, axes(1:3), Time,& | ||
& var%bc(n)%field(m)%long_name, var%bc(n)%field(m)%units ) | ||
if(var%set) then | ||
if(associated(var%bc) .eqv. associated(var%bc_r4)) & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think you missed one lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be all done now
coupler/coupler_types.F90
Outdated
@@ -625,6 +783,12 @@ subroutine CT_spawn_1d_2d(var_in, var, idim, jdim, suffix, as_needed) | |||
if (.not.var_in%set)& | |||
& call mpp_error(FATAL, trim(error_header) // ' The parent type has not been initialized.') | |||
|
|||
! check only one kind is used | |||
if(var_in%set .and. var_in%num_bcs .gt. 0) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the var_in%set needed here since it's checked above? (not that it significantly matters)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope (at least for the spawn routines), took these out with 27c6e87
do i=var%isc-halo,var%iec+halo | ||
var%bc(n)%field(m)%values(i,j) = var_in%bc(n)%field(m)%values(i+i_off,j+j_off) | ||
! num_bcs .lt. 1 -> loop doesn't run but shouldn't error out | ||
if (associated(var_in%bc) .or. var_in%num_bcs .lt. 1) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be clearer if var_in%num_bcs .lt. n1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also wondering if var_in%num_bcs.lt.1 should be separated into its own if else block for clarity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this is a little more clear. Some code within these is outside of loops so needs to run if either part of the conditional is true, otherwise will have to be repeated. could change the logic to use an .and. instead, but that would be more confusing
axis_utils/include/axis_utils2.inc
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, does this need to be merged with the current mixedmode branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be updated, i left that one line deletion in axis utils cause that extra line will mess with the documentation parser.
@@ -319,6 +319,7 @@ foreach(kind ${kinds}) | |||
time_interp/include | |||
tracer_manager/include | |||
interpolator/include | |||
coupler/include |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there one more place to add coupler/include?
YAY! 🥳 |
BREAKING CHANGE: In coupler_types.F90, `coupler_nd_field_type` and `coupler_nd_values_type` have been renamed to indicate real kind value: `coupler_nd_real4/8_field_type` and `coupler_nd_real4/8_values_type`. The `bc` field within `coupler_nd_bc_type` was modified to use r8_kind within the value and field types, and an additional field added `bc_r4` to use r4_kind values. Includes: * feat: eliminate use of real numbers for mixed precision in `block_control` (#1195) * feat: mixed precision field_manager (#1205) * feat: mixed precision random_numbers_mod (#1191) * feat: mixed precision time_manager reals to r8 and clean up (#1196) * feat: mixed Precision tracer_manager (#1212) * Mixed precision monin_obukhov (#1116) * Mixed precision: `monin_obukhov` unit tests (#1272) * mixed-precision diag_integral_mod (#1217) * mixed precision time_interp (#1252) * mixed precision interpolator_mod (#1305) * Mixed precision astronomy (#1092) * Mixed precision `data_override_mod` (#1323) * mixed precision exchange (#1341) * coupler mixed precision (#1353) * Mixed precision topography_mod (#1250) --------- Co-authored-by: rem1776 <[email protected]> Co-authored-by: MiKyung Lee <[email protected]> Co-authored-by: mlee03 <[email protected]> Co-authored-by: Caitlyn McAllister <[email protected]> Co-authored-by: Jesse Lentz <[email protected]>
Description
Adds mixed precision support for the coupler subdirectory.
Majority of the changes are in coupler_types since it uses a few encapsulated types for 1-3 dimensional fields. The atmos_ocean_fluxes module has changes when needed to interact with the right type but does not take any required real arguments. Ensemble manager does not use reals (or the rest of this subdirectory) at all, so no changes have been made.
I noticed that in the FMScoupler only the
coupler_Nd_bc_type
is used so the r4/r8 split happens within it via thebc
andbc_r4
members. This should be less disruptive for other codes using this type since theres nothing being removed for the most part, just the r4 stuff being added and used if needed.Because the r4/r8 divide happens within the type, most routines that don't take reals just check which type has been associated (bc or bc_r4) and then use whats appropriate.
Fixes # (issue)
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Please also note
any relevant details for your test configuration (e.g. compiler, OS). Include
enough information so someone can reproduce your tests.
Checklist:
make distcheck
passes