You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently you're not supposed to do this, because it's technically UB in the LLVM we generate, and it means the output can depend on the schedule. You're supposed to use undef instead for the pure definition, and then write your operation as an update definition on the output Func that reads values that were already in that buffer. But that doesn't always work. It can't work if there are other Funcs in between the input and output, because that would require a pipeline loop.
But people alias inputs and outputs all the time! It has caused several serious bugs in production that I'm aware of.
One solution might be an output.may_alias(input) call. It would error if it can't prove the schedule is safe from aliasing issues. One slightly over-conservative check would be: for every compute_root block that writes to an output and reads from an input that may alias that output, the schedule for the output and any intervening Funcs must not do any redundant recompute (e.g. ShiftInwards), and the operation must be element-wise in every Func between the output and that input.
A lower level check would be using a polyhedral clock vector, and saying that every load from an input coordinate must be earlier in time than any store to that output coordinate. But to do that robustly you start to need to worry about things like ILP solvers. I'd rather it were a simple(ish)-to-state constraint on the schedule.
But those solutions still wouldn't work if the output buffer is e.g. a crop of the input, so you can't line up coordinates like that. Hrm.
The text was updated successfully, but these errors were encountered:
Currently you're not supposed to do this, because it's technically UB in the LLVM we generate, and it means the output can depend on the schedule. You're supposed to use undef instead for the pure definition, and then write your operation as an update definition on the output Func that reads values that were already in that buffer. But that doesn't always work. It can't work if there are other Funcs in between the input and output, because that would require a pipeline loop.
But people alias inputs and outputs all the time! It has caused several serious bugs in production that I'm aware of.
One solution might be an output.may_alias(input) call. It would error if it can't prove the schedule is safe from aliasing issues. One slightly over-conservative check would be: for every compute_root block that writes to an output and reads from an input that may alias that output, the schedule for the output and any intervening Funcs must not do any redundant recompute (e.g. ShiftInwards), and the operation must be element-wise in every Func between the output and that input.
A lower level check would be using a polyhedral clock vector, and saying that every load from an input coordinate must be earlier in time than any store to that output coordinate. But to do that robustly you start to need to worry about things like ILP solvers. I'd rather it were a simple(ish)-to-state constraint on the schedule.
But those solutions still wouldn't work if the output buffer is e.g. a crop of the input, so you can't line up coordinates like that. Hrm.
The text was updated successfully, but these errors were encountered: