-
Notifications
You must be signed in to change notification settings - Fork 48
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
Handle weight files more elegantly #11
Comments
Also the weight file needs to have more complete metadata, not just numbers (can be done outside of ESMPy) |
@JiaweiZhuang / @bekozi - has there been any update on this issue? As I understand it, we need a way to have ESMPy return in memory weights. Has that issue been raised upstream? |
I raised this issue a while ago; not sure if there's any progress also @rokuingh |
Talked with @rokuingh today, and we have a plan for moving this forward. I hope it won't be longer than a few weeks. |
That's great news @bekozi ! Is it planned for some patch version of 7.1.0 or 8.0.0? |
Good question. It will be in 8 but rolled out in a beta snapshot much sooner... |
We have factors in the Python interface now and are working on testing. There are still some compiler-related things to address. Before charging forward, I want to get some input on the interface. The factors themselves are allocated in Fortran, so we need to make sure their deallocation is handled smartly. With bigger grids, we want to minimize copies too. Nothing is fixed now, so open to any suggestions. regrid = Regrid(..., factors=True) # factors is False by default
factor_list, factor_index_list = regrid.get_factors(deep_copy=True) # deep_copy is False by default
# Preferred deallocation method for factors but __del__ will also do this.
regrid.destroy() I am thinking it makes sense to add an option for zero-based factor indexing. Maybe a |
Glad to see progress on this important issue! I have several comments & questions:
I would prefer just returning 3 numpy arrays and use
Those arrays will then construct a Scipy sparse matrix by
My general feeling is that direct ESMF/ESMPy calls should only deal with the very core functionalities that must be done in Fortran-level. Then we rarely, rarely need to update ESMPy's API. Once a new ESMPy function like
|
A zero-copying workflow would be: row, col, S = regrid.get_weights(copy=False)
row -= 1 # modify the Fortran array in-place. Any potential issue?
col -= 1
weights = scipy.sparse.coo_matrix(S, (row, col), copy=False)
regridder = xesmf.Regridder()
regridder.weights = weights # will be done in class __init__ instead
# do not call regrid.destroy() In this case, the |
Thanks for the input! All good stuff.
Out of habit, I prefer to be explicit between shallow and deep copies in Python even when working with NumPy arrays. However, we don't have a policy for naming these in ESMPy. I agree The function will return a With ESMPy, we have tried to stay close to how ESMF implements things under the hood. Hence, the factor and factor index list will take the same form as the regrid store call in ESMF. Mostly this is an attempt to reduce duplication with the docs.
We could add a convenience function or options that would do this. We may want to expose the ESMF sparse matrix utility through Python at some point. In that case, we would want the factor array forms to be compatible with ESMF. I thought at one point to consider a
I don't really know the answer to this. My sense is that it is not worth implementing as in-place NumPy stuff is pretty fast, but it was a question worth posing at least.
This. 😄 Summed up the ESMPy's design mentality. It doesn't feel Pythonic most of the time!
It would. It's mostly an attempt to establish consistency with the named factor arguments to ESMF. I don't feel strongly about it though. In my mind, we should consider a
Good point. The copy flags to these functions are meant to be additional indicators to users that they need to be conscious of ESMF memory.
The safest bet is to deep copy everything as you know. Code that does not explicitly call destroy but creates numerous I'm not quite sure what you mean by other ESMF errors. I think once these arrays are created they should be stable independent of other ESMF usage (in ESMF these arrays are not attached to anything). The same goes for the deallocation. I'm probably not understanding your second question. |
A minor concern is that
It makes perfect sense for ESMPy to stay close to ESMF. I am OK with the current name. Multiple aliases to the same method will probably confuse pure-ESMPy users.
Looks good me if you don't mind adding & maintaining one more function😀
This is exactly what I am concerning about. I am not super familiar with ESMPy's memory management, but from what you said I guess repeated calls to If true, with the zero-copying implementation mentioned above, there will be memory leak if a user repeatedly calls
I guess I more mean "mis-uses" (like the above case) than "errors"... In summary:
|
@bekozi My mistake -- |
This is a downer. I think what we'll need is a follow on issue where we adapt the regrid store interface in ESMF to return vectors for the index lists directly.
Don't mind.
It's hard to guarantee how the Python garbage collection will run. As usual, SO provides a good overview. This is why we introduced the
Thanks for this.
You are correct, and you are forgiven. 😄 Not like I caught it anyway. I'm really hoping to ship these features soon. |
Quick update. We hit an impasse with compilers that we are working through. This was not unexpected. The implementation is working with the standard GNU compiler stack but is unstable on others (i.e. Discover standard modules). The rub with this feature is that the weight arrays are dynamically allocated in Fortran complicating pointer management. @rokuingh and I are working through how best to move the arrays up to Python using Fortran's You can see the |
Thanks very much for the work! I think all xESMF users use conda (with GNU compiler) and won't be affected by this compiler issue. |
@JiaweiZhuang, the in-memory weights branch is ready for testing. A Dockerfile for building ESMF from that branch is available here. For reference, here are links to the docstrings for the new interfaces. ESMF doesn't build docs for branches... In our testing, the factor arrays contain zero elements with no spatial overlap (disjoint geometries) and unmapped action is ignore. Again, sorry for the delay on this. Hopefully we won't encounter too many issues during your implementation. |
@bekozi Aha, finally!! I can use the Dockerfile without problems. Will let you know if I hit any issues. |
@bekozi One minor documentation thing: Simply using the one in ESMF docs should be fine:
I assume that it should be set to |
Noted! Thanks.
Yes, it makes sense to use |
I already have a mostly-working code for in-memory weight retrieval, but it relies on ESMF 8.0.0 that is not publicly released yet. So far I've been building the development branch of ESMF at https://github.com/JiaweiZhuang/Docker_ESMPy. Will push my new code when ESMPy/ESMF 8.0.0 becomes conda-installable. This is of top-priority as the current offline weight approach is quite awkward and hard to test. |
ESMF 8.0.0 is released today and supports online weight retrieval (see release notes):
|
(continuing #2 and #9)
In the just-released v0.1.1, the default behavior is to write weights to disk, and there is a
regridder.clean_weight_file()
method to optionally remove it (demo).This exactly matches how ESMPy works (directly dump weights to disk, not returning a numpy array) but feels a bit odd. A more intuitive workflow is only getting in-memory weights by default, and have a
regridder.save()
method to optionally save it to disk (like themodel.save()
method in Keras).With current ESMPy (up to 7.1.0dev41) I need to do very weird things to implement this new design:
This incurs a lot of unnecessary disk I/O. If ESMPy has the plan to return in-memory weights I will definitely use the new design. Otherwise I'd rather keep the current approach.
@bekozi Any plans on that?
The text was updated successfully, but these errors were encountered: