When implementing a module pass, I decided to have it run after the default Relay optimization passes, but before transition to TIR. This allowed me to benefit from the simple and canonical Relay representation, while already able to reason about the likely temporary buffers between fused operations.
However, in my top level code that uses relay.build
, I did not see a way to register my pass to be run after the default Relay passes.
My solution is a simple optional hook that allows the user to register a function that takes a module and params (seem to be gone in current TVM), and returns a module:
const runtime::PackedFunc* pfPostPass = runtime::Registry::Get("relay.backend.PostOptPass");
if (pfPostPass) {
Map<String, Constant> argParams;
for (const auto& param : params) {
argParams.Set(param.first, Constant(param.second));
}
relay_module = (*pfPostPass)(relay_module, argParams);
}
It is inserted right after the OptimizeImpl call:
It would be used as follows:
@tvm.register_func("relay.backend.PostOptPass")
def _post_pass(mod, params):
return MyCustomPass()(mod)
Is this something that is useful to anyone else? Would you be open to include this in the code base? Is there a better way to achive this?