refine_transients
CartesianRefineTransients
Bases: ScheduleNodeTransformer
Refine (reduce dimensionality) of transients based on their true use in the cartesian dimensions.
It expects
- All Maps and ForLoop are on a single axis - but doesn't check for it.
It can do
- Looking at usage of a transient in a cartesian axis (e.g. loop over a cartesian axis) it will reduce that axis to 1 if all access are atomic (exactly one element of the array is ever worked on in a single loop)
- It will refuse to merge if the transient is used in multiple loops of for a given axis - regardless of it's access pattern (e.g. even if it could be refine because it's always written first.)
It should but cannot do or will produce bugs if
- With better dataflow analysis, we can reduce the dimensions to the correct lowest
size needed on the axis (e.g. transient[K] and transient[K+1], requires a 2-element
buffer), instead of the defensive no refine strategy used now. We have most of the
info in the
Range - Current action when detecting a valid candidate is to reduce the size of the dimension to 1, rather than removing it. This will effectively, if generic compilers do their job, reduce the cache access significantly. This also has been implemented to not deal with offset/slicing downstream impact of removing an axis. Nevertheless the axis should be removed if it's not used.
- It only knows how to deal with 3D cartesian and 3D cartesian + data dimensions. Anything else will
fail
_reduce_cartesian_axes_size_to_1calculation
More tests
- Test for dataflow with offset
- Test for I/J refine but not in K
- Test for J refine but not in I or K
- Test with dataflow: if/else, while, etc.
- Test with ForScope (FORWARD/BACKWARD) instead of Map
Coding traps
- We reduce the "refined" dimensions to 1 which is functionally eliminating it. This is solid. In the
case of the one we can't eliminate we don't do anything. We could find the "smallest buffer size" needed
and reduce the local dimension to it. BUT if we do this, we have to take into account the offset into
memory (e.g. halo) for the
RebuildMemletsFromContainers!
CollectTransientRangeAccess
Bases: ScheduleNodeVisitor
Unionize all transient arrays access into a single Range.
RebuildMemletsFromContainers
Bases: ScheduleNodeVisitor
Rebuild memlets from containers to ensure they are scoped to the right size.