Open BradLarson opened 2 years ago
Ok, one of the problem are projections. Essentially, read / write access of struct fields yields with a begin_access
/ end_access
bracket. Adjoint buffer of projections are projections of adjoint buffer. However, we do not do any CSE. As a result, we're ending with propagating the same value (that is being projected several times) over and over again.
I see you specifically included -Onone
, which disables most SIL optimizations. Do you see the same with -O
or without the -Onone
?
@tbkka If I correctly remember @BradLarson's case, the problem was the excessive memory consumption and compilation time. So, either swift-level optimizations or LLVM-level were able to remove extraneous copies, however, only in the case where compilation succeeded. And in some cases it did not due to OOM.
Describe the bug In differentiable mutating functions (although this may also extend to ones with inouts), adding control flow appears to lead to replicated tangent vectors in the generated pullback. This can be seen in the generated SIL, where replicated
alloc_stack
s for the same tangent vector appear in the first basic block of the pullback, one after the other, and then series of redundantstore
,copy_addr
, and the like show up in the subsequent basic blocks.An example that illustrates this is the following single-file reproducer:
where if you build and
-emit-sil
, then look at the pullback ofTest.doSomething(input:)
, you'll see something like the following in bb0:entries like the following in bb2:
and so on. The number of replicated tangent vectors and related instructions scales with the number of instances of control flow in the original function. With large tangent vectors and many
if()
statements, this can generate code that causes LLVM to exhaust all available memory when further handling the resulting SIL.Resulting SIL has been attached to this issue for the above Swift example.
This is not a recent regression, and has been present for at least the last year.
Steps To Reproduce Steps to reproduce the behavior:
swiftc -Onone -emit-sil test.swift -o test.sil
Expected behavior There should be a single instance of the tangent vector for
self
, no redundant operations on it, and adding more control flow to the original function should not cause a steady increase in tangent vector copies and replicated instructions.Environment (please fill out the following information)
Additional resources
An example of the generated SIL is attached as a file. test-sil.txt