Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
resolve #222
The special methods
__del__
ofESMF.Field
andESMF.Grid
objects feature calls to their respectivedestroy
methods that release the memory allocated by ESMF in Fortran. When these objects go out of scope, the Python garbage collection ought to call these__del__
methods, yet their allocated memory does not seem to be released properly, as repeatedly regridding fields results in running out of memory after a while.After a discussion with @davidhassell, we suspect that the
ESMF.Manager
may be responsible for not making the memory release possible as long as it stays in scope. However, incf
the Manager is initialised but not bound to a variable name (see e.g. https://github.com/ThibHlln/cf-python/blob/d9cde28d9abd9cfeb6575c737560956f40620942/cf/field.py#L15619), so to me it goes out of scope directly in a Python sense. The ESMF documentation says that "The Manager will be created when the first ESMPy object is created if it is not created explicitly by the user". So I suspect that the Manager stays around (as a Fortran object I suppose) even if not bound to a name in Python's namespace (which may also very well be the case for Fields/Grids objects then).In the
cf
regridding, there are ESMF fields and grids created during each call toregrids
/regridc
. If these are explicitly releasing memory (through calls to their destroy methods), this does seem to eliminate the running out of memory when repeatedly calling the regridding methods. Note, calling the destroy methods on these objects several times does not raise an error, if memory was already released, it remains silent. So this PR does just that, i.e. it explicitly releases memory for all ESMF objects as soon as they are not required anymore. This does not provide as explanation for why the destroy calls in Python's garbage collection are not working/not enough, but it seems to be a cheap and harmless solution that solves the problem.I am attaching these field files if you'd like to test the following script:
Before this PR, after the expensive generation of the weights (it may take a short while), the memory was building up very quickly in the loop until running out of memory (using 8GB of RAM for my test), while with the modifications in this PR the memory now remains stable across the loop.