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

The send_data math (field buffer update) functions. #1131

Merged
merged 49 commits into from
Feb 23, 2023

Conversation

ngs333
Copy link
Contributor

@ngs333 ngs333 commented Feb 3, 2023

Description
This PR is largely for the field buffer updating math routines to be when selected in
a namelist option in the legacy diag manager. Key parts of the presented code is
intend to supports the modern diag manager out of the box.
Functionality that was originally in send_data_3d was refactored and moved
to their own functions. The added capability of for direct 3D and 4D fields (with
corresponding 4D and 5D) buffers used in the legacy and modern diag manager, respectively.
The functions support R4, R8, I4 and I8 fields and buffers (matching in type) ,
Integer versions of the functions are not allowed in the legacy diag manager and
are commented out for this review .

Most of the code refactored from send_data_3d is in these files:
1. fms_diag_fieldbuff_update.F90
2. include/fms_diag_fieldbuff_update.inc
3. include/fms_diag_fieldbuff_update.fh

To allow the math functions to work with both the legacy and the modern diag_manager,
some refactoring of bounds checking functions was also necessary. This was used also
as an opportunity to remove repetitive code, and some utilities related to array index bounding boxes were introduced. These functions are largely in diag_util.F90

Some conventions:
Some of the code has comments that begin with !TODO: .Those that on the same line also have
text (MDM) , I expect that they be resolved in the modern diag manager.

Some missed opportunities :

  • Given the existence of the R4 and R8 generated buffer update functions, it should be possible to
    remove the copy of the field array used in send_data_3d that was introduced in the EMC mixed mode merge.
  • I was desired to set a pointer to the lowest level (elemental) buffer update math function.
    There were issues implementing this (see this would have removed the innermost if/then/else construct in the buffer update loops. See fms_diag_outfield_type in file fms_daig_outfield.F90.

Fixes # (issue)

How Has This Been Tested?
All former unit tests pass. More unit tests were added. Regression tests are to be done.
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

Miguel R Zuniga and others added 30 commits July 25, 2022 14:44
also corrected new #define typo from last pull.
the lagacy diag_manager. Adds a refactored version of send_data_3d,
modified the buffer bounds checking functions, and necessary changes
in diag_data and diag_util.
…cs.F90).

Fixed CMakeLists.txt; cleaned up fms_diag_outfield_mod.
bointer remapping; plus moving back to original interface some diag_manager.F90
routines. Also removing send_dada_3d_refac() routine from diag_manager.F90.
…rue.

Fixes bug of incorrect pointer bounds remapping (switching order of last
two coordinates).
sned_data_3d and missing some documentation.
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.

I still think you should remove modern from the names of the "modern" functions. If you want to use legacy for the old ones, I supposed that can be acceptable. There are some other comments/changes that need to be done still.

diag_manager/diag_data.F90 Outdated Show resolved Hide resolved
TYPE(fmsDiagOutfield_type), ALLOCATABLE:: ofield_cfg !<Instance used in calling math funcsions.
LOGICAL :: mf_result !<Logical result returned from some math (buffer udate) functions.
LOGICAL, DIMENSION(1,1,1), target :: mask_dummy
REAL :: rmask_threshold
Copy link
Member

Choose a reason for hiding this comment

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

what is this? Should it be a parameter?

Copy link
Contributor Author

@ngs333 ngs333 Feb 10, 2023

Choose a reason for hiding this comment

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

The the current diag_manager send_data_3d, there are several uses of magic numbers 0.5_r4_kind and 0.5_r8_kind. The same value, whatever it is, needs to be passed to one of the math functions. I used READ rmask_threshold to hold and pass the value being used. I will update comments.

Comment on lines 102 to 103
module procedure fms_update_bounds_legacy
module procedure fms_update_bounds_modern
Copy link
Member

Choose a reason for hiding this comment

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

Did we discuss this in an email? The modern and legacy still irk me.

!! of the "array" argument and store it the bounding box argument "bounds"
SUBROUTINE fms_bounds_from_array_4D(bounds, array)
REAL, INTENT( in), DIMENSION(:,:,:,:) :: array !< The 4D input array.
TYPE (fms_diag_ibounds_type), INTENT(inout) :: bounds !< The instance of the bounding box.
Copy link
Member

Choose a reason for hiding this comment

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

Why can't this be the constructor function? If you move this to diag_data, then the variables could be private.

!> @brief Update the the first three (normally x, y, and z) min and
!! max boundaries (array indices) of the input bounding box "bounds" with
!! the six specified bounds values.
SUBROUTINE fms_update_bounds_modern(bounds, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)
Copy link
Member

Choose a reason for hiding this comment

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

I still don't like this name. We are going to have to go through and change this in the future. And by that time, everyone will forget.

Comment on lines 55 to 58
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:) :: field_ptr => null()!< Pointer to the field
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:,:) :: ofb_ptr => null()!< Pointer to the outfield buffer.
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:,:) :: ofc_ptr => null()!< Pointer to the outfield counter.
LOGICAL , pointer, DIMENSION(:,:,:,:) :: mask_ptr => null()!< Pointer to the mask.
Copy link
Member

Choose a reason for hiding this comment

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

We need to talk about these. It turns out there is an implied save here.

Copy link
Member

Choose a reason for hiding this comment

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

Please remove the =>null()

Comment on lines 827 to 829
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:) :: field_ptr => null() !< Pointer to the field
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:,:) :: ofb_ptr => null() !< Pointer to the outfield buffer.
LOGICAL , pointer, DIMENSION(:,:,:,:) :: mask_ptr => null() !< !< Pointer to the mask.
Copy link
Member

Choose a reason for hiding this comment

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

We need to discuss these also...

!> @brief This code will be used by the preprecessor to generate an implementation
!! to the module procudure for the fieldbuff_copy_fieldvals interface.
!! The function may set or add to the output field buffer (argument ofb) with the input
!! field data array (argument field)
Copy link
Member

Choose a reason for hiding this comment

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

Yes but will that show up as the result when the doxygen documentation is created?

test_fms/diag_manager/test_diag_update_buffer.F90 Outdated Show resolved Hide resolved
test_fms/diag_manager/test_diag_update_buffer.F90 Outdated Show resolved Hide resolved
diag_manager/diag_util.F90 Outdated Show resolved Hide resolved
bounds%kmax = UBOUND(array,3)
END SUBROUTINE fms_bounds_from_array_4D

!> @brief Determine the bounds of the first three dimentions
Copy link
Contributor

Choose a reason for hiding this comment

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

typo in dimentions

diag_manager/diag_util.F90 Outdated Show resolved Hide resolved
diag_manager/diag_util.F90 Outdated Show resolved Hide resolved
diag_manager/diag_util.F90 Outdated Show resolved Hide resolved

CHARACTER(len=128) :: error_string1, error_string2
LOGICAL :: lims_not_exact = .true.
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it imply save on lims_not_exact ?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, this should be:

LOGICAL :: lims_not_exact
lims_not_exact = .true.

OR you don't need it at all because 2 lines down, you are setting lims_not_exact anyway. Are you trying to save this variable for next time?

diag_manager/fms_diag_outfield.F90 Show resolved Hide resolved
diag_manager/fms_diag_outfield.F90 Outdated Show resolved Hide resolved
diag_manager/fms_diag_time_reduction.F90 Outdated Show resolved Hide resolved
diag_manager/fms_diag_time_reduction.F90 Outdated Show resolved Hide resolved
ganganoaa
ganganoaa previously approved these changes Feb 10, 2023
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.

If you are going to insist on leaving the variables in fmsDiagIbounds_type public, then it needs to be documented in the code why they are public.

(fms_diag_fieldbuff_update.fh, diang_manager.F90)Please remove => null() on any new pointers that are initialized when they are declared:

type(something), pointer :: var => null()

Instead do something like this:

type(something), pointer :: var
var => null()

This is a question about the variable lims_not_exact that should be addressed

Please add a TODO for the integer pow_value so we can discuss it with the rewrite

There still some doxygen that needs to be addressed in fms_diag_fieldbuff_update.fh

Comment on lines 134 to 139
INTEGER :: imin !< Lower i bound.
INTEGER :: imax !< Upper i bound.
INTEGER :: jmin !< Lower j bound.
INTEGER :: jmax !< Upper j bound.
INTEGER :: kmin !< Lower k bound.
INTEGER :: kmax !< Upper k bound.
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 add documentation about why these variables are public because it goes against the FMS coding standards.

LOGICAL, DIMENSION(:,:,:), INTENT(in), OPTIONAL :: mask
CLASS(*), DIMENSION(:,:,:), INTENT(in), OPTIONAL :: rmask
LOGICAL, DIMENSION(:,:,:), INTENT(in), OPTIONAL, contiguous, target :: mask
CLASS(*), DIMENSION(:,:,:), INTENT(in), OPTIONAL, target :: rmask
CHARACTER(len=*), INTENT(out), OPTIONAL :: err_msg

Copy link
Member

Choose a reason for hiding this comment

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

@ganganoaa We don't require updating old code/variables. It's too onerous on developers because, like you said, it's not obvious what some of the variables are.

Comment on lines 1492 to 1493
REAL(kind=r4_kind), POINTER, DIMENSION(:,:,:) :: rmask_ptr_r4 => null() !< A pointer to r4 type of rmask
REAL(kind=r8_kind), POINTER, DIMENSION(:,:,:) :: rmask_ptr_r8 => null() !<A pointer to r8 type of rmask
Copy link
Member

Choose a reason for hiding this comment

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

Remove the => null()

Copy link
Member

Choose a reason for hiding this comment

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

This still needs to be fixed


CHARACTER(len=128) :: error_string1, error_string2
LOGICAL :: lims_not_exact = .true.
Copy link
Member

Choose a reason for hiding this comment

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

Yes, this should be:

LOGICAL :: lims_not_exact
lims_not_exact = .true.

OR you don't need it at all because 2 lines down, you are setting lims_not_exact anyway. Are you trying to save this variable for next time?

Comment on lines 55 to 58
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:) :: field_ptr => null()!< Pointer to the field
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:,:) :: ofb_ptr => null()!< Pointer to the outfield buffer.
FMS_DIAG_FBU_DATA_TYPE_ , pointer, DIMENSION(:,:,:,:,:) :: ofc_ptr => null()!< Pointer to the outfield counter.
LOGICAL , pointer, DIMENSION(:,:,:,:) :: mask_ptr => null()!< Pointer to the mask.
Copy link
Member

Choose a reason for hiding this comment

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

Please remove the =>null()

@@ -0,0 +1,31 @@
#undef FMS_DIAG_FBU_DATA_TYPE_
Copy link
Member

Choose a reason for hiding this comment

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

@mlee03 can you look at this and make sure it's following your standards.

Copy link
Contributor

Choose a reason for hiding this comment

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

We've been using "kind" macros instead of "type", e.g, FMS_DIAG_FBU_DATA_KIND_ r4_kind. Also we put the macro definitions in the _r4.fh and _r8.fh files (separate files for r4 and r8_kind); the code went into the *.inc files.

@@ -0,0 +1,31 @@
#undef FMS_DIAG_FBU_DATA_TYPE_
Copy link
Contributor

Choose a reason for hiding this comment

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

We've been using "kind" macros instead of "type", e.g, FMS_DIAG_FBU_DATA_KIND_ r4_kind. Also we put the macro definitions in the _r4.fh and _r8.fh files (separate files for r4 and r8_kind); the code went into the *.inc files.

@@ -0,0 +1,31 @@
#undef FMS_DIAG_FBU_DATA_TYPE_
Copy link
Contributor

Choose a reason for hiding this comment

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

We also put in the GNU Lesser General Public License stuff in the *inc and *fh files

@ngs333
Copy link
Contributor Author

ngs333 commented Feb 22, 2023

If you are going to insist on leaving the variables in fmsDiagIbounds_type public, then it needs to be documented in the code why they are public.

(fms_diag_fieldbuff_update.fh, diang_manager.F90)Please remove => null() on any new pointers that are initialized when they are declared:

type(something), pointer :: var => null()

Instead do something like this:

type(something), pointer :: var
var => null()

This is a question about the variable lims_not_exact that should be addressed

Please add a TODO for the integer pow_value so we can discuss it with the rewrite

There still some doxygen that needs to be addressed in fms_diag_fieldbuff_update.fh

These items from @thomas-robinson were addressed in the push of 1PM today; but for exception of the doxygen that needs to be addressed in fms_diag_fieldbuff_update.fh, which is coming shortly.

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.

These are the specific places that needs to be addressed. There may be more => null() too.

diag_manager.F90 L1494 1495 need to remove the => null()

diag_util.F90 L1048 the lims_not_exact variable should not be initialized. See the comment in the review.

fms_diag_fieldbuff_update.fh L882 Needs a doxygen documentation

Comment on lines 1492 to 1493
REAL(kind=r4_kind), POINTER, DIMENSION(:,:,:) :: rmask_ptr_r4 => null() !< A pointer to r4 type of rmask
REAL(kind=r8_kind), POINTER, DIMENSION(:,:,:) :: rmask_ptr_r8 => null() !<A pointer to r8 type of rmask
Copy link
Member

Choose a reason for hiding this comment

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

This still needs to be fixed

@rem1776 rem1776 merged commit 6255971 into NOAA-GFDL:main Feb 23, 2023
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