-
Notifications
You must be signed in to change notification settings - Fork 137
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
Conversation
…types to allocatable type
@rem1776 Could @ganganoaa be added as a reviewer for this PR? Thanks |
horiz_interp/horiz_interp_type.F90
Outdated
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 |
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.
Did you miss this pointer?
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 couln't find any use of this pointer in FMS. Specifically if you grep the repository, you only get the following lines:
FMS/horiz_interp/horiz_interp_type.F90
Line 72 in 203c8bf
logical, dimension(:,:), pointer :: found_neighbors =>NULL() !< indicate whether destination grid |
FMS/horiz_interp/horiz_interp_type.F90
Line 203 in 203c8bf
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.
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.
Does my reasoning make sense?
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.
It seems odd because the routine is creating a copy except for this one variable.
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 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.
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'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.
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.
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
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.
@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?
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 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.
Yes. That was missed.
horiz_interp_out%found_neighbors => horiz_interp_in%found_neighbors
Ganga
…On 1/3/23 09:15, Tom Robinson wrote:
***@***.**** requested changes on this pull request.
------------------------------------------------------------------------
In horiz_interp/horiz_interp_type.F90
<#1100 (comment)>:
> @@ -189,35 +189,35 @@ subroutine horiz_interp_type_eq(horiz_interp_out, horiz_interp_in)
call mpp_error(FATAL,'horiz_interp_type_eq: horiz_interp_type variable on right hand side is unassigned')
endif
- horiz_interp_out%faci => horiz_interp_in%faci
The functionality of this routine is changing. Can you add doxygen
comments to this clearly stating that this routine creates a /copy/ of
the object. Also doxygen comments for the variables.
------------------------------------------------------------------------
In horiz_interp/horiz_interp_type.F90
<#1100 (comment)>:
> - horiz_interp_out%wti => horiz_interp_in%wti
- 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%faci = horiz_interp_in%faci
+ horiz_interp_out%facj = horiz_interp_in%facj
+ horiz_interp_out%ilon = horiz_interp_in%ilon
+ horiz_interp_out%jlat = horiz_interp_in%jlat
+ horiz_interp_out%area_src = horiz_interp_in%area_src
+ horiz_interp_out%area_dst = horiz_interp_in%area_dst
+ horiz_interp_out%wti = horiz_interp_in%wti
+ 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
Did you miss this pointer?
—
Reply to this email directly, view it on GitHub
<#1100 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A43PSQH5HBRREIEUXKGZHJ3WQQYA5ANCNFSM6AAAAAATPWEFNQ>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I think it is safe since it is not allocated any where.
…On 1/4/23 10:26, laurenchilutti wrote:
***@***.**** commented on this pull request.
------------------------------------------------------------------------
In horiz_interp/horiz_interp_type.F90
<#1100 (comment)>:
> @@ -189,35 +189,35 @@ subroutine horiz_interp_type_eq(horiz_interp_out, horiz_interp_in)
call mpp_error(FATAL,'horiz_interp_type_eq: horiz_interp_type variable on right hand side is unassigned')
endif
- horiz_interp_out%faci => horiz_interp_in%faci
Let me know if these changes are sufficient
—
Reply to this email directly, view it on GitHub
<#1100 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A43PSQDBUJJA65UCFG3TCMLWQWJBXANCNFSM6AAAAAATPWEFNQ>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
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 need to add if allocated
statements and change that last pointer to an allocatable unless it's being used somewhere else as a pointer.
Lauren, the fortran reference verified my assumption and what I have
tested recently.
Thanks.
…On 1/11/23 10:38 AM, laurenchilutti wrote:
***@***.**** commented on this pull request.
------------------------------------------------------------------------
In horiz_interp/horiz_interp_type.F90
<#1100 (comment)>:
> + horiz_interp_out%facj = horiz_interp_in%facj
+ horiz_interp_out%ilon = horiz_interp_in%ilon
+ horiz_interp_out%jlat = horiz_interp_in%jlat
+ horiz_interp_out%area_src = horiz_interp_in%area_src
+ horiz_interp_out%area_dst = horiz_interp_in%area_dst
+ horiz_interp_out%wti = horiz_interp_in%wti
+ 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
@thomas-robinson <https://github.com/thomas-robinson> I wrote a test
program to see if we would get an error if |horiz_interp_type_out| is
unallocated, and there is no error and the program runs fine. I found
a section of the Fortran 2003 standard that seems to indicate that If
a member of horiz_interp_out is unallocated, it will be allocated with
the same shape as horiz_interp_in.
You can see the section of the fortran 2003 standard I am referring to
here <https://wg5-fortran.org/N1601-N1650/N1601.pdf#page=155> in
Section 7.4.1.3 Interpretation of intrinsic assignments
—
Reply to this email directly, view it on GitHub
<#1100 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A43PSQGLLCA6QDXK4XTMXPLWR3HXZANCNFSM6AAAAAATPWEFNQ>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I have updated the |
@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. |
@rem1776 I just added a minor change to a comment in the latest commit to relaunch the CI. |
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.
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.
I think the check before the assignments,
if(.not.horiz_interp_in%I_am_initialized) then
callmpp_error(FATAL,'horiz_interp_type_eq: horiz_interp_type variable on
right hand side is unassigned')
endif
will suffice the requirement. If needed, extra safe-guard can be inserted.
Ganga
…On 1/20/23 10:15 AM, Tom Robinson wrote:
***@***.**** requested changes on this pull request.
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.
------------------------------------------------------------------------
In horiz_interp/horiz_interp_type.F90
<#1100 (comment)>:
> + horiz_interp_out%facj = horiz_interp_in%facj
+ horiz_interp_out%ilon = horiz_interp_in%ilon
+ horiz_interp_out%jlat = horiz_interp_in%jlat
+ horiz_interp_out%area_src = horiz_interp_in%area_src
+ horiz_interp_out%area_dst = horiz_interp_in%area_dst
+ horiz_interp_out%wti = horiz_interp_in%wti
+ 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
You need to do this for all of the allocatable variables.
—
Reply to this email directly, view it on GitHub
<#1100 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A43PSQBS2WZDTNDOWBYX3B3WTKT2FANCNFSM6AAAAAATPWEFNQ>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
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.
Ignore my last comment because it is taken care of already.
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 toif allocated()
to accompany this change. There are also instances in the code where we were declaring, for example:And in that subroutine horiz_interp_type_eq, for example:
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 ofhoriz_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:
make distcheck
passes