Open benvanik opened 3 years ago
ESRGAN uses a producer[] -> insert[] pattern and results in a lot of fills. Relates to #7729. In these cases we have enough information to track that the entire tensor is overwritten and that the splat can be dropped.
%1350 = stream.async.splat %c0_i8 : i8 -> !stream.resource<transient>{%c4285440}
%1351 = stream.async.update %1325, %1350[%c0 to %c1428480] : !stream.resource<transient>{%c1428480} -> %1350 as !stream.resource<transient>{%c4285440}
%1352 = stream.async.update %1328, %1351[%c1428480 to %c2142720] : !stream.resource<transient>{%c714240} -> %1351 as !stream.resource<transient>{%c4285440}
%1353 = stream.async.update %1334, %1352[%c2142720 to %c2856960] : !stream.resource<transient>{%c714240} -> %1352 as !stream.resource<transient>{%c4285440}
%1354 = stream.async.update %1341, %1353[%c2856960 to %c3571200] : !stream.resource<transient>{%c714240} -> %1353 as !stream.resource<transient>{%c4285440}
%1355 = stream.async.update %1349, %1354[%c3571200 to %c4285440] : !stream.resource<transient>{%c714240} -> %1354 as !stream.resource<transient>{%c4285440}
Note to self: benvanik-concurrent-copies has a WIP implementation of a general write elision pass that does the tracking to find these chains of in-place operations on adjacent ranges. It should really be written as a data-flow analysis, though, and is going to need a rewrite. This would allow us to track divergent execution paths that fill the same regions and track across function calls.
The new stream ops give us enough information to symbolically identify discards:
Here we know by
[%c0, %c256) + [%c256, %296)
that we are overwriting the entire resource. We should be able to transform this into:The only value we need to know is constant here is 0 and the rest can be pure equality.
Another case of this is turning the splat into fills if we do have gaps either on the interior or at the tail (common in padding). For example:
->
Could be done as a canonicalization on update.