-
Notifications
You must be signed in to change notification settings - Fork 195
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
Improved and simplified BinaryOperation with "stubborn" location inference #1599
Conversation
This reverts commit 1a77150.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤞 this helps with compilation! I guess this is technically a breaking change? Sounds like it might be fine for LESbrary.jl though.
It is very much breaking! And for the better. I'll bump version. But yeah, since it mostly changes complex abstract operations that previously haven't compiled on the GPU, most code isn't affected. |
Sorry for not following, but I don't see what breaks here for the end user! Could someone give a quick example/explanation? |
Apologies that my explanation was not clear. It's a breaking change because the same user input, such as tke = @at (Center, Center, Center) ((u - U)^2 + (v - V)^2 + w^2) / 2 produces a different object after this update:
Let me know if that makes sense or if another example would be useful. |
@glwagner Thanks! I actually had gotten that, but I was under the impression that the previous syntax wasn't gonna work. (Which would possibly break many scripts I have...) Thanks for the explanation though! (Btw, this PR was super timely. I was planning on opening an issue this week about the order of operations in abstract operations following our discussion out it the past week 👍) |
This was a hard problem to solve. We'll see if this algorithm is sufficient for all cases. Other solutions are welcome. |
I believe this qualifies as a "breaking change" because any code that relied on consistent output from an abstract operation could, in theory, break (for example, a regression test that passes only when output remains constant). It does not change the API however, just the results. |
After some tweaks it does indeed look like tke_ccc = @at (Center, Center, Center) ((u - U)^2 + (v - V)^2 + w^2) / 2 compiles on the GPU! What a journey. |
This PR changes the structure of BinaryOperations and the way that locations are inferred when constructing them.
Before this PR, BinaryOperations stored three interpolation operators: two for each argument, and a third interpolation function applied after the binary operation was computed. The motivation for this design was to ensure that products of fields were always computed at their shared location, while allowing abstract operations to be built at user-specified locations. In other words, users might want something like
which would compute
u * u
at(Face, Center, Center)
, and subsequently interpolate to cell centers. The objectuu
would then be defined at cell centers.The main issue of this design in terms of functionality is that it produces expression trees that interpolate "too eagerly". A common example is a turbulent kinetic energy computation:
Inspection of this object reveals that while
u - U
does not interpolate, the squaring(u - U)^2
would be performed at cell centers:This isn't what we want (usually): instead, we want both
u - U
and subsequent squaring in(u - U)^2
to be performed at(Face, Center, Center)
.This PR addresses this issue by getting rid of the third interpolation in
BinaryOperation
, and changing how locations forBinaryOperation
are inferred. Now, when locations are specified via@at
, they are taken as a "suggestion" that only acts if the two elements of the binary operation have different concrete locations such that a difference needs to be resolved. In other cases (such as a binary operation between fields at common locations, or a binary operation between a field and a number), the location of the members of the operation is preserved. In this way,BinaryOperations
are "stubborn".We thus have results like
and
An added benefit is that the
BinaryOperation
object is simpler. This could help compilation as well...Of course, users do want to be able to specify the location of
BinaryOperations
for output. For this we change how@at
works: now we wrap the entire user-prescribed expression in an interpolation operator that interpolates the result to the user-specified location. If the location of the underlying expression is already at the user-specified location, this is just an identity. But when the underlying operation is a "stubborn"BinaryOperator
, we interpolate:This also means that operations between
ReducedField
andField
also end up at the right place, and we have no need to throw an error if aBinaryOperation
has aNothing
location (in fact, this might be a useful abstraction for binary operations betweenReducedField
).