(Towards/Close #3315, Closes #3590) New implementation of lfric loop fuse trans - #3595
LonelyCat124 wants to merge 31 commits into
Conversation
|
Here is the example of min and max builtins that could be easy targets to fuse: |
|
Some notes from our meeting.
We think most of the the benefit will come from fusing built-ins (particularly those that do MIN/MAX on the same field). We also discussed 'constant propagation' but realised that often, a |
|
I think the new implementation does most of this, what I couldn't work out is why is this necessary: This can be either:
Does that make sense @arporter ? I am also unsure I've done anything re: " I think they can be fused following the rules above, provided that the DA doesn't determine that a halo-exchange is required between them". I'll have to work that out next. |
Yes, sorry, I was a bit slack in how I phrased it. If the iteration space is defined by the same field/operator then we don't have to look at function spaces. We probably still need to worry about stencil accesses. In fact, now that I write that, we need to be careful about kernels that update more than one argument (they are permitted to do this). A first step might be to refuse to fuse such cases. |
|
I think I've added a check in validate for writing to only one field (I think). |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3595 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 403 403
Lines 56790 56938 +148
==========================================
+ Hits 56790 56938 +148 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I think I have most of the basics done now, but there are some remaining hurdles that I'm not sure I understand. The first is this test (not implemented in the pushed version) that fails, but I think we wanted to be able to do: This fails due to an existing test in validate, where we aren't allowed to fuse 2 reduction kernels (we have a setval_c, a max and a min in the input invoke). The other thing I'm not sure about was working out how to avoid fusing loops if there is some dependency between them. I assume I can check if @arporter @sergisiso If you have any idea about either of these let me know. |
|
I've allowed reductions to be fused if the iteration space variable is the same - not sure if this is correct in general? |
|
I've implemented some logic locally to disallow fusing of loops that would need a halo exchange if distributed memory is enabled, however it causes a current test to fail (with distributed memory enabled). The test in question fuses the loops in: where testkern is: My logic must be wrong/missing something, because I refuse to accept this whilst we don't generate halo exchanges between these loops: so I need to check the halo exchange logic more to check I've not missed something else. |
|
I realised that wasn't allowing the test to run to completion without fusing - if I allow that then instead I get (the first loop is coloured but not relevat): Something in PSyclone works out that the Its not required as "we only read annexed dofs and these have been made clean by the redundant computation", however the test states: "Test that we are able to fuse two loops together, perform redundant computation and then colour." which we need to explicitly disallow the fusion first surely? Since to be able to know there isn't a dependency we need to do the redundant computation first? But we need to do the redundant computation on the fused loop I assume (uhoh). |
|
@arporter @sergisiso Ready for a first look now I think. I think at this stage I'm hopeful that all the cases we want to fuse are handled - if I've missed testing anything you can think of we can add more tests. I'm not sure about the split of work between validate and apply - apply has a variety of checks to fall through to the conditional fusing but I couldn't think of another way to implement it at the moment. |
|
Just a comment/the $1M question - is it possible to extend one of the LFRic transformation scripts to exercise this functionality for real in (one of) the ITs? |
I added it into the everything script and will run the lfric ITs and see. |
|
Fusing loops currently causes lfric to crash, not quite sure yet, , i'm guessing its fusing loops with allocations or something maybe |
|
Fixed that bug again - there's still failing test but I want to run ITs again to see if LFRic is happy yet then i'll fix up the tests. |
…sion of any two discontinuous spaces
|
I fixed the remaining bugs (one being caused by the "improvement" to data_sharing_attribute_mixin). The current rules now for fusing LFRicLoops (on top of whatever LoopFuseTrans does, which is mostly require index alignment I think):
@arporter Does this seem reasonable? I can add it to the docs somewhere as appropriate (LFRic developer guide? Or user guide?) |
This now works and compiles and runs lfric_atm without causing the IT to fail so I can only assume its ok? |
Thanks Aidan, it does seem reasonable. Probably it should go in the docstring of the class and then we can pull it into the docs without replicating it. |
Initial implementation for the new lfric loop fuse trans setup.
There are still for sure some things to sort out but it seems to work for our tests and solves ANY_SPACE things.
I'd like to have an investigate of being able to fuse more than 2 LFRicLoops, provided they all meet some criteria (i.e. some_space is provided, they're all on the same field etc., or that they all have the same space at runtime) but I'd need to know if that is useful @christophermaynard @MetBenjaminWent ? Its probably a more substantial implementation but I think its possible.