-
Notifications
You must be signed in to change notification settings - Fork 16
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
Limit the scope of Looplet/Unfurl closures #608
Comments
@willow-ahrens I want to add that I think this issue is also potentially related to "closure" issue that we've had in generating parallel code. In particular, part of the issue there is that we don't know much about the local variables once something has been lowered so we loose track and need to recover what needs to be passed into a closure/function for running parallel code. If everyone had structs describing the local state with types, then at lowering time we could figure out the fields currently in use and just pass those in. |
Right, although the closure issue is also resolved with https://github.com/willow-ahrens/Finch.jl/blob/a7f5b899d49051167aebd7568a65c2840ea6db69/src/util/shims.jl#L59-L208 We can certainly copy the logic from there to inside the compiler, so that as long as we rename state variables correctly we can generate explicit closures at the moment of parallel lowering, based on the variables that we end up using in the code (i.e. lower it and see what variables it uses). You are correct though that this would enable the analysis you describe where it would be possible to write a function that lists all variables that are reachable from a block of finch code, without lowering it. |
In order to support parallelism on more exciting architectures, we must redesign the unfurl function to avoid carrying closed variables from one dimension to another, so that we can re-label those symbols. As an example of the problem, consider the following Gustavson's matmul:
This produces:
We try to
moveto
the workspace to local memory but we end up setting theglobal variable
w_lvl_val = copy(w_lvl_val)
. In general, some loopletstructures currently capture state from previous outer loops, state which is not
captured by
moveto
because it's not accounted for explicitly. The solutionhere is that we need to represent the state of all subfibers (including COO and
Masks) as an explicit struct with field names we can call
moveto
on. This means that each call tounfurl
would occur in the scope of the loop being unrolled, rather than at the top
level call to
instantiate
. More generally, it would benefit the project if wecould distinguish between
instantiate
andunfurl
at every loop nest, toinsert side effects that eagerly expand as soon as a tensor is unfurled, versus
side effects that wait until the last possible moment to expand with
instantiate
. This might clean up some of the lowering for Scalars as well.This may involve a fair amount of code change, but it would be for the better.
For example, the state carried by a COO level would be encapsulated in a more
explicit
COOSubLevel
struct that reflects the current COO index search variables.In the end, this would enable
moveto
to "re-virtualize" tensors upon enteringparallel regions, which is critical for local variables.
Tasks:
The text was updated successfully, but these errors were encountered: