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
{{ message }}
Repository navigation
add_requirement() fails to transitively infer alignment #9328
As #9327 is a problem, I was playing around with add_requirement() and set the alignment of extents, while equating stride to extents of lower dimensions to promise dense storage, like so:
This emits the proper asserts 1 to 1. However, the generated code still seemed to not understand that output.dim(1).stride() must have the same alignment as output.dim(0).extent(), despite the fact that I required them to be equal.
Personally, I'm much more in favor of promising dense storage with add_requirement() over fiddling with overwriting the stride with custom expressions like stride = stride / 16 * 16. To me, intuitively, the strides and extents etc are NOT in control by us, but by the calling code. You can pass a buffer with any configuration. So to me, those are read-only parameters to the pipeline. Setting them inside the schedule seems very counter-intuitive. I'd rather have them literally be read-only const Exprs inside those Buffers, on which we run a few checks to validate compatibility with the pipeline schedule. @abadams@alexreinking thoughts?
I agree with the core API usage issue. The setters are needlessly directional. If I have a matmul (C += A*B) pipeline, do I need to set the inner extent of A to match the outer extent of Band vice-versa? Plus, a declarative syntax obviates the need for hacky division tricks. You could write extent % 32 == 0 rather than extent = extent / 32 * 32. It's not even clear what that assignment means (as you observe).
Only one caveat: moving this way is a breaking change for a lot of old code. I only counted ~100 uses internally and they're all about promising relationships between other min/extent/stride. So it's not an intractable port.
Activity
mcourteaux commentedon Aug 13, 2026
Personally, I'm much more in favor of promising dense storage with
add_requirement()over fiddling with overwriting the stride with custom expressions likestride = stride / 16 * 16. To me, intuitively, the strides and extents etc are NOT in control by us, but by the calling code. You can pass a buffer with any configuration. So to me, those are read-only parameters to the pipeline. Setting them inside the schedule seems very counter-intuitive. I'd rather have them literally be read-onlyconst Exprs inside those Buffers, on which we run a few checks to validate compatibility with the pipeline schedule. @abadams @alexreinking thoughts?alexreinking commentedon Aug 13, 2026
I agree with the core API usage issue. The setters are needlessly directional. If I have a matmul (
C += A*B) pipeline, do I need to set the inner extent ofAto match the outer extent ofBand vice-versa? Plus, a declarative syntax obviates the need for hacky division tricks. You could writeextent % 32 == 0rather thanextent = extent / 32 * 32. It's not even clear what that assignment means (as you observe).Only one caveat: moving this way is a breaking change for a lot of old code. I only counted ~100 uses internally and they're all about promising relationships between other min/extent/stride. So it's not an intractable port.