[TIR] Preserve annotations after lower opaque block#12572
[TIR] Preserve annotations after lower opaque block#12572Hzfengsy merged 2 commits intoapache:mainfrom
Conversation
| @T.prim_func | ||
| def after(A: T.Buffer[8, "float32"], B: T.Buffer[8, "float32"]): | ||
| for i in T.serial(8, annotations={"k_0": 1, "k_1": [2, 3]}): | ||
| for _ in range(1, annotations={"k_3": 3.14}): |
There was a problem hiding this comment.
It‘s a bit tricky to add a unit loop here. Can we keep the current behavior or add an AttrStmt?
There was a problem hiding this comment.
I'm a bit uncertain if haivng an AttrStmt might make sense in our workflow, given it's something in the low-level TIR that we might want to minimize its usage (CC: @tqchen). I'm aware that there could be any implications if we directly remove a unit loop without preserving its annotation too. Not sure what the best approach is.
There was a problem hiding this comment.
On AttrStmt, we should move away from it when possible as an effort to limit the scope and clarify the semantics. Of course, we should also document the set of possible annotatons we use in For so they become manageable
|
|
||
| mod = tvm.IRModule.from_expr(before) | ||
| with tvm.transform.PassContext( | ||
| config={"tir.LowerOpaqueBlock": {"preserved_annotations": ["k_0", "k_1", "k_3"]}} |
There was a problem hiding this comment.
Is it possible to preserve all annotations by default rather than write a pass config?
There was a problem hiding this comment.
A tracing of usages in current test_tir_ and test_meta_schedule_ show that for loop annotations, only software pipeline specified keys are used, they are consumed before lower opaque block. The other keys are mostly meta_schedule.* in block annotations.
What about that for non-pragma keys?
-
Always preserve loop annotations.
-
Always drop block annotations, since they are mostly designed for meta-schedule thus make no sense to subsequent passes, and it seems not clear now how to lower the block's attrs after blocks get eliminated.
For my circumstance the loop annotations are quite useful while block annotations are not used for lowering passes. Could the decision about block annotation get delayed to when it is indeed needed :)?
Hi, there. The change aims to improve customization experience of TIR lowering using annotations.
Currently, we have
LowerOpaqueBlockpass to convert s-tir(schedulable tir with blocks) to non-stir. All annotations are dropped then except those used by legacy TE pragma attributes, they are converted to legacy AttrStmt. For example:This introduce difficulties when we want to leverage schedule phase annotations in lowering passes.
pragma_annotations are converted to legacy AttrStmt, which only acceptsPrimExprtyped value. But the loop/block annotations before are originally much flexible, one could use list/dict to encode more rich compile time hints.AttrStmtloses the roundtrip property of TIR, thus we fail to write testcases of lowering pass with friendly before/after script comparations.ForNode). Or else the developers always have to write separate logics handling attr node and for node.The change just add a pass configuration
"tir.LowerOpaqueBlock": {"preserved_annotations": List[str]}}. For each annotation key value of loop or block:pragma_, keep the original behaviour.preserved_annotationslist, the annotation is preserved.The alternative may be preserve all annotations without any extra configuration. But I think current way take the least impact on overall lowering stream. If we do not add customized pass config into pass context, all things should be same.
cc @Hzfengsy @junrushao1994