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

Memory leak fix: pointers in interpolator and horiz_interp #1100

Merged
merged 5 commits into from
Jan 20, 2023

Conversation

laurenchilutti
Copy link
Contributor

Description
In interpolator and horiz_interp, some pointers are being allocated. This PR changes the type from pointer to allocatable. Any use of if associated() has now been changed to if allocated() to accompany this change. There are also instances in the code where we were declaring, for example:

interface assignment(=)
  module procedure horiz_interp_type_eq
end interface

And in that subroutine horiz_interp_type_eq, for example:

horiz_interp_out%faci => horiz_interp_in%faci

I have changed these pointer assignment operators to an equals, with the foresight that this may cause issues. With the old functionality, anytime horiz_interp_out is modified, the value of horiz_interp_in is also modified. With my changes this will not be the case. I tested with the land model and did not run into any issues with this but we will test all models with alpha2 testing.

Fixes #1099

How Has This Been Tested?
Compiled with GNU and Intel, ran with the land model and answers reproduce

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

@laurenchilutti
Copy link
Contributor Author

@rem1776 Could @ganganoaa be added as a reviewer for this PR? Thanks

horiz_interp/horiz_interp_type.F90 Show resolved Hide resolved
horiz_interp_out%wtj = horiz_interp_in%wtj
horiz_interp_out%i_lon = horiz_interp_in%i_lon
horiz_interp_out%j_lat = horiz_interp_in%j_lat
horiz_interp_out%src_dist = horiz_interp_in%src_dist
horiz_interp_out%found_neighbors => horiz_interp_in%found_neighbors
Copy link
Member

Choose a reason for hiding this comment

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

Did you miss this pointer?

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 couln't find any use of this pointer in FMS. Specifically if you grep the repository, you only get the following lines:

logical, dimension(:,:), pointer :: found_neighbors =>NULL() !< indicate whether destination grid

horiz_interp_out%found_neighbors => horiz_interp_in%found_neighbors

So, since it wasn't a pointer being allocated I did not touch that variable at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does my reasoning make sense?

Copy link
Member

Choose a reason for hiding this comment

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

It seems odd because the routine is creating a copy except for this one 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.

I feel a little uncomfortable doing anything with the found_neighbors pointer. I have grepped the entire FMS repository for any use of found_neighbors and the only two times I can find any use of this is:

horiz_interp/horiz_interp_type.F90:72: logical, dimension(:,:), pointer :: found_neighbors =>NULL() !< indicate whether destination grid
horiz_interp/horiz_interp_type.F90:204: horiz_interp_out%found_neighbors => horiz_interp_in%found_neighbors

Since I don't fully understand what this variable is being used for, I would rather not modify it.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd bet its just unused in general, you don't get warnings for unused fields in derived types so it could have never been used and no one noticed. I think we can probably remove it unless we can find some code that actually uses it.

Copy link
Contributor

@ganganoaa ganganoaa Jan 17, 2023

Choose a reason for hiding this comment

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

If we remove this field assignment, it will violate principle of object-to-object copy but if it is never used, we can remove. Instead, we can add something like this:

if (associated(in%var))
if (associated(out%var)) deallocate(out%var)
allocate(out%var(size(in%var))
out%var = in%var
else
out%var => NULL()
end if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@thomas-robinson @ganganoaa @rem1776 i have not done anything to found neighbors yet. the options as I see it are:

  • removing it seems like something that would require a lot of testing since its possible some model somewhere is using it.
  • changing it from pointer to allocatable change this pointer assignment to equals
  • leave it as is
    I don't feel like I have enough familiarity with interpolator code to make this decision. How should I proceed? Who can I consult on what to do?

Copy link
Member

Choose a reason for hiding this comment

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

do this:

if (allocated(horiz_interp_in%found_neighbors))horiz_interp_out%found_neighbors = horiz_interp_in%found_neighbors

and make found_neighbors allocatable instead of a pointer. This is a = routine, so it should be making a copy, not providing pointers.

This is a modernization PR, not a clean up. No need to remove it here. We should note it for potential clean up in a future release.

@ganganoaa
Copy link
Contributor

ganganoaa commented Jan 3, 2023 via email

@ganganoaa
Copy link
Contributor

ganganoaa commented Jan 4, 2023 via email

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 think you need to add if allocated statements and change that last pointer to an allocatable unless it's being used somewhere else as a pointer.

@ganganoaa
Copy link
Contributor

ganganoaa commented Jan 11, 2023 via email

@laurenchilutti
Copy link
Contributor Author

I have updated the found_neighbors field to be allocatable.
Lines 189-191 in hoiz_interp_type.F90 are checking that horiz_interp_in%I_am_initialized is set to .TRUE. %I_am_initialized is set to .TRUE. when these fields are allocated, so I will not be adding an if(allocated(in%field)) before each field assignment in horiz_interp_type_eq.
I added if (allocated(horiz_interp_in%found_neighbors)) before we equate the found_neighbors field because this is not allocated in FMS.

rem1776
rem1776 previously approved these changes Jan 18, 2023
@rem1776
Copy link
Contributor

rem1776 commented Jan 19, 2023

@laurenchilutti It looks like the CI glitched out or something on the last commit. I can see that it ran and passed yesterday here but the status never updated on the actual PR. I tried rerunning the latest jobs but it still didn't update.

I've seen something similar before it might've been a github action outage or something at the time you pushed it, so a new commit could fix it. Maybe you can revert/rebase and then re-push the last commit? Although it might be easier to just make some kind of small change and commit that.

@laurenchilutti
Copy link
Contributor Author

@rem1776 I just added a minor change to a comment in the latest commit to relaunch the CI.

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.

You need to check that all of the variables are allocated in the assignment routine. If they aren't allocated, I think that routine will crash.

horiz_interp/horiz_interp_type.F90 Show resolved Hide resolved
@ganganoaa
Copy link
Contributor

ganganoaa commented Jan 20, 2023 via email

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.

Ignore my last comment because it is taken care of already.

@rem1776 rem1776 merged commit 91e7324 into NOAA-GFDL:main Jan 20, 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.

Allocated Pointers: Potential Memory Leak Issue
4 participants