slyubomirsky opened a new issue, #15009: URL: https://github.com/apache/tvm/issues/15009
Per the [previous discussion](https://discuss.tvm.apache.org/t/unity-dealing-with-phase-ordering/14709) of instituting some explicit phase ordering in Relax to account for the fact that some passes already rely on each other, this is a proposal for adopting some of the measures from the discussion. - [ ] **P1.** Add a comment in `transform.h` or a `README.md` in `include/tvm/relax` that describes the known pass dependencies. - [ ] **P2.** Include `LambdaLifting` as a final step after parsing. - [ ] **P3.** Implement phase tracking during the build. - [ ] **P3.1.** Use a module attribute to indicate the phase. The phases will be "ingestion" (0, between parsing and normalization), "optimization" (1, applying high-level optimizations), "lowering" (2, some lower-level optimizations that rely on legalizing operators, eliminating purity tracking, and device-specific properties), and "build" (3, the final lowering of builtins to `PackedFunc`s and preparing for VM code generation). It will be important to mark transition points accordingly (`LambdaLifting` as 0->1, `LegalizeOps` as 1->2, `VMBuiltinLower` as 2->3). - [ ] **P3.2.** Include checks for the expected phase in each pass. This will largely be boilerplate. - [ ] **P3.3.** Modify pass implementations to account for phase invariants. For example, after phase 0, passes do not have to handle inner functions (except for BYOC-specific ones, unless we want to change that). - [ ] **P3.4.** Enforce certain phase invariants in the well-formed checker, tied to the module attribute for phase. * Inner functions should not be permitted after phase 0 (we can make an exception for those used by BYOC or change the implementation of `RunCodegen`). * Dataflow blocks should not permitted after phase 1. * All functions must be marked either impure or use the `relax.force_pure` attribute after phase 2. Additionally, there should be no remaining uses of `call_pure_packed` or `invoke_pure_closure` after phase 2. (These are both already implemented by the `RemovePurityTracking` pass; this would just enforce the invariant.) * There should be no remaining uses of `call_tir` and `call_dps_packed` after phase 2. * We could also consider enforcing that all arithmetic operators will have been legalized after phase 2 (by checking only for a whitelist of builtins that are lowered in phase 3). This list is meant as a starting point for further discussion, as there were still some unresolved disagreements in the earlier thread. By dividing the implementation into steps, this could help make the discussion more concrete by focusing on implementation. In terms of implementation, the biggest question centers on the BYOC passes, which rely on inner functions. This is the only major case where the current implementation of passes differs from what was proposed (namely, eliminating inner functions early on). We should also be certain of which passes are responsible for updating the phase attribute (those proposed above under P3.1 are all non-optional passes, so I would argue they are reasonable candidates). We may also consider trying to enforce some finer-grained ordering constraints (see the "megapasses" in the discussion thread), though there did not seem to be wide support for this; it may suffice to note these constraints in the documentation without enforcing them directly. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
