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

Mixed precision data_override_mod #1323

Merged
merged 25 commits into from
Aug 30, 2023
Merged

Conversation

J-Lentz
Copy link
Contributor

@J-Lentz J-Lentz commented Aug 9, 2023

Mixed precision support has been added to data_override_mod. It has been split into separate implementation and wrapper modules.

How Has This Been Tested?
Github CI and unit tests

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules
  • New check tests, if applicable, are included
  • make distcheck passes

`data_override_mod` has been split into separate implementation and wrapper
modules. Mixed precision support has been added.
@@ -0,0 +1,2 @@
#include "data_override_impl_r4.fh"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a need for this extra file? It seems to slightly overcomplicate things

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 28b3d59. Now the implementation modules are included at the top of data_override.F90 instead.

use fms2_io_mod, only : FmsNetcdfFile_t, open_file, close_file, &
read_data, fms2_io_init, variable_exists, &
get_mosaic_tile_file
module DATA_OVERRIDE_IMPL_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a need for the "IMPL"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As opposed to just calling the macro DATA_OVERRIDE_?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a66917f: _IMPL has been removed from the macro names for DATA_OVERRIDE_0D_, DATA_OVERRIDE_2D_, DATA_OVERRIDE_3D_, DATA_OVERRIDE_UG_1D_, and DATA_OVERRIDE_UG_2D_.

I've left DATA_OVERRIDE_INIT_IMPL_ alone to avoid confusion with the data_override_init wrapper subroutine.

Copy link
Member

@thomas-robinson thomas-robinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Documentation needs to be updated, especially on new routines and new variables.
  2. I'm not sure why there are routines that are used to select calling a r4 or r8 routine instead of using an interface.
  3. (or 2.5) My understanding was that unlimited polymorphism wasn't going to be used and instead we were using macros. This PR uses both. Please work with @mlee03 to decide how to proceed. If you do use class(*) because it is needed/neater or whatever, please make sure you document in the code why that was done.

Comment on lines 69 to 72
integer :: atm_mode = 0
integer :: ocn_mode = 0
integer :: lnd_mode = 0
integer :: ice_mode = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are new variables. They need to be documented with doxygen comments.

Why are they all 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the class(*) dispatcher subroutines because I didn't realize that module procedure x could be used when x is a use'd subroutine (I thought module procedure was only for procedures in the module's contains section). But it actually seems to work fine, so the class(*) subroutines have been replaced by interfaces in b89c8db.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atm_mode, ocn_mode, lnd_mode, and ice_mode all take on values 0 (uninitialized), 4 (r4 mode), and 8 (r8 mode). This will be clarified with doxygen comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments added in eb0137c.

@@ -182,381 +93,35 @@ end function count_ne_1
!! Data_table is initialized here with default values. Users should provide "real" values
!! that will override the default values. Real values can be given using data_table, each
!! line of data_table contains one data_entry. Items of data_entry are comma separated.
subroutine data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
subroutine data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in, mode)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to update the description of this routine, because it looks like all it's doing is calling another routine and setting up the "mode" which is not clearly defined

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in e960b14.

Comment on lines 101 to 102
integer, intent(in), optional :: mode !< r4_kind or r8_kind
integer :: mode_selector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These variables need better documentation. What is mode? The mode of what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meatier comment added in eb0137c.

Comment on lines 119 to 122
if (present(Atm_domain_in)) atm_mode = mode
if (present(Ocean_domain_in)) ocn_mode = mode
if (present(Ice_domain_in)) ice_mode = mode
if (present(Land_domain_in)) lnd_mode = mode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not going to work.

  1. mode is an optional argument, so it should be wrapped in an if (present(mode)) or am i missing something?
  2. The different components do not need to be the same type. If the ocean is running with r4 and the atmosphere in r8, how is this going to support mixed-more? It's not clear to me what this is doing, so it needs better documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Just a careless mistake, fixed in 5dacac8
  2. This would be accomplished with multiple calls to data_override_init, e.g.:
call data_override_init(ocean_domain_in=..., mode=r4_kind)
call data_override_init(atm_domain_in=..., mode=r8_kind)

The doxygen comment does currently state that data_override_init can be called multiple times. I'll add a description of the behavior of the new mode argument.

@@ -569,120 +134,93 @@ subroutine data_override_unset_domains(unset_Atm, unset_Ocean, &

fail_if_not_set = .true. ; if (present(must_be_set)) fail_if_not_set = must_be_set

if (.not.module_is_initialized) call mpp_error(FATAL, &
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the error check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. module_is_initialized now lives in the r4 and r8 versions of the implementation modules, rather than in the wrapper module.
  2. The new atm_mode, ocn_mode, lnd_mode, and ice_mode variables now keep track of what has and hasn't been initialized, so mpp_error still gets called if the user tries to unset an uninitialized domain.

!! that will override the default values. Real values can be given using data_table, each
!! line of data_table contains one data_entry. Items of data_entry are comma separated.
subroutine data_override_init(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
subroutine DATA_OVERRIDE_INIT_IMPL_(Atm_domain_in, Ocean_domain_in, Ice_domain_in, Land_domain_in, Land_domainUG_in)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This routine needs documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doxygen comment added in 2d6bfd6.

@@ -351,8 +274,14 @@ endif
if(use_get_grid_version .EQ. 2) then
call close_file(fileobj)
end if
end subroutine DATA_OVERRIDE_INIT_IMPL_

function count_ne_1(in_1, in_2, in_3)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function needs documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doxygen comment added in 59bf15d.

Comment on lines 280 to 281
logical, intent(in) :: in_1, in_2, in_3
logical :: count_ne_1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these variables need documentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 59bf15d.

if(PRESENT(override)) override = .true.

end subroutine DATA_OVERRIDE_0D_IMPL_

!> @brief This routine performs data override for 2D fields; for usage, see data_override_3d.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want to see data_override_3d_impl_ . Please update this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed "for usage, see data_override_3d" in e960b14.

end module data_override_mod
!> @}
! close documentation grouping
end module
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include the module name here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jesse Lentz added 11 commits August 21, 2023 13:05
@J-Lentz J-Lentz marked this pull request as ready for review August 22, 2023 23:23
@J-Lentz J-Lentz requested a review from rem1776 as a code owner August 22, 2023 23:23
@J-Lentz J-Lentz requested a review from mcallic2 August 22, 2023 23:24
Jesse Lentz added 9 commits August 23, 2023 12:13
`DATA_OVERRIDE_0D_IMPL_`    -> `DATA_OVERRIDE_0D_`
`DATA_OVERRIDE_2D_IMPL_`    -> `DATA_OVERRIDE_2D_`
`DATA_OVERRIDE_3D_IMPL_`    -> `DATA_OVERRIDE_3D_`
`DATA_OVERRIDE_UG_1D_IMPL_` -> `DATA_OVERRIDE_UG_1D_`
`DATA_OVERRIDE_UG_2D_IMPL_` -> `DATA_OVERRIDE_UG_2D_`
@mlee03
Copy link
Contributor

mlee03 commented Aug 25, 2023

cool :) For consistency, could you change DATA_OVERRIDE_KIND_ to start with FMS_DATA_OVERRIDE_KIND_ (or something like that that starts with FMS). Same for GET_GRID_VERSION_KIND_

@J-Lentz
Copy link
Contributor Author

J-Lentz commented Aug 25, 2023

Macro names changed in 2b71679.

Copy link
Contributor

@rem1776 rem1776 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we combine multiple modules in the same file elsewhere in fms, do you know if it gives the right line numbers in tracebacks for includes if you got an error from one of those r4/r8 routines?

Creating two more files just to include the two kind versions doesn't make much more sense either though, so I would add some comments since this switches up the typical mixed precision CPP method. A line or two in the header comments for data_override.F90 and data_override.inc explaining how this include is used as a module in this case specifically would be good.

data_override/Makefile.am Outdated Show resolved Hide resolved
data_override/data_override.F90 Show resolved Hide resolved
@mlee03
Copy link
Contributor

mlee03 commented Aug 29, 2023

@rem1776 @J-Lentz, I can see how using FMS_DATA_OVERRIDE_TYPE and explicitly declaring two versions of the private types (as done in the rest of mixed-precision FMS) could work, but I like how data_override is modified here, it's very clean. And if we in the future add submodules, the changes would be straightforward here. And agree with @rem1776, I now see how the mixed precision implemented here is not the easiest to understand and a bit of comment would be beneficial.

Comments have been added to the tops of `data_override.F90` and
`data_override.inc`. The `module` and `module end` statements have been moved
from the .fh files to `data_override.F90`.
@J-Lentz
Copy link
Contributor Author

J-Lentz commented Aug 30, 2023

I've added brief comments to the tops of data_override.F90 and data_override.inc. And I've moved the module data_override_r* and end module data_override_r* statements to data_override.F90, because Fortran code in .fh files could be confusing and unexpected.

@@ -33,7 +34,16 @@ module get_grid_version_mod

implicit none

real, parameter :: deg_to_radian=PI/180.
Copy link
Contributor

@mlee03 mlee03 Aug 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a private variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was, but I've replaced it with DEG_TO_RAD from constants_mod.

@@ -871,8 +907,8 @@ subroutine data_override_3d(gridname,fieldname_code,data,time,override,data_inde
call mpp_error(FATAL,'data_override: file '//trim(filename)//' is not opened in time_interp_external')
end if
! convert lon_in and lat_in from deg to radian
override_array(curr_position)%lon_in = override_array(curr_position)%lon_in * deg_to_radian
override_array(curr_position)%lat_in = override_array(curr_position)%lat_in * deg_to_radian
override_array(curr_position)%lon_in = override_array(curr_position)%lon_in * DEG_TO_RAD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

real(DEG_TO_RAD,lkind)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in da7da2c.

@@ -129,11 +131,11 @@ program test_get_grid_v1
min_lon, max_lon)

!< Error checking:
if (lon(1,1) .ne. sum(lon_vert_in)/4*deg_to_radian ) then
if (lon(1,1) .ne. sum(lon_vert_in)/4*real(DEG_TO_RAD, lkind) ) then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.0_lkind

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in da7da2c.

@rem1776 rem1776 merged commit dffe74b into NOAA-GFDL:mixedmode Aug 30, 2023
19 checks passed
rem1776 added a commit that referenced this pull request Sep 20, 2023
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants