Lunderberg opened a new pull request, #16067:
URL: https://github.com/apache/tvm/pull/16067

   Some Relax operators have requirements regarding their AST that are stronger 
than are checked by the C++ types being used.  These are similar to checks that 
are present in the `tvm::relax::WellFormed` utility, such as checks forbidding 
the use of undefined variables, which are also stronger than required by the 
underlying C++ types. However, because every operator may have unique 
requirements, it would be unreasonable to expect a writer of a 
`relax::ExprMutator` to be aware of and to maintain all such requirements.
   
   This PR introduces an operation operator attribute `FNormalize`.  If 
defined, this function is used to apply an operator-specific normalization.  
The implementation of `FNormalize` has the following design decisions.
   
   * If no change is required, `FNormalize` should return the input argument 
unmodified.
   
   * `FNormalize` is only responsible for normalization of the operator itself. 
 The expression it returns may be unnormalized (e.g. contain nested 
expressions).
   
   * `FNormalize` receives the `BlockBuilder` as an argument, to allow 
context-dependent normalization.
   
     For example, an operator whose normalization requires in-line expressions 
may use `BlockBuilder::LookupBinding` to perform variable replacement.
   
   * `FNormalize` is applied after `FInferStructInfo`.  `FNormalize` may assume 
that the `relax::Call` passed to `FNormalize` has well-defined struct info.
   
     * Corollary: `FInferStructInfo` may not assume that its `relax::Call` 
argument has been passed through `FNormalize`.
   
       This is a reasonable requirement, because (1) shape inference should 
depend only on the struct info of arguments and not the values themselves, and 
(2) this only impacts operators that use `FNormalize`.
   
   * `FNormalize` should not be used to apply simplifications, and should be 
limited to cases where the same computation may be expressed in multiple 
manners.
   
     For example, replacing a by-variable tuple with an in-line tuple in 
`R.call_tir` is a form of normalization, but replacing `R.add(arg, R.const(0))` 
with `arg` is a form of simplification.
   
     This separation is to ensure that `FNormalize` has minimal overhead, as 
some simplifications may have large computational costs, and `FNormalize` is 
applied as part of all `ExprMutator` usage.  A later PR will introduce an 
attribute `FSimplify`, along with a dedicated pass to apply simplifications.
   
   * Use of `FNormalize` is suppressed while parsing TVMScript. TVMScript must 
be able to generate test cases that trigger specific failure modes, and that 
may include producing un-normalized relax IR.  In addition, TVMScript must be 
stable when passed through a round-trip from IR to text to IR.


-- 
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]

Reply via email to