[IR][Pass][Instrument] Pass Instrument Framework
Proposal
Currently in TVM, there are trace mechanisms and passes time profiling.
/*!
* \brief PassContextNode contains the information that a pass can rely on,
* such as analysis results.
* \sa PassContext
*/
class PassContextNode : public Object {
public:
// Skipped
/*! \brief Trace function to be invoked before and after each pass. */
TraceFunc trace_func;
// Skipped
They have similar semantics that want to profile/trace passes.
This PR tries to generalize and integrate the concepts:
1. Trace is rename to PassInstrumentors with more functionalities:
- Explicitly split RunBeforePass and RunAfterPass into different functions instead of checking in trace call back funcion.
def trace(ir_module, pass_info, is_before): if is_before: # Before Pass Run else: # After Pass Run # ==> pi = tvm.instrument.PassInstrument() @pi.register_run_before_pass def run_before_pass(ir_module, pass_info): # Before Pass Run @pi.regiser_run_after_pass def run_after_pass(ir_module, pass_info): # After Pass Run @pi.register_set_up def set_up(): # Instrumentation environment set up @pi.register_tear_down def tear_down(): # Instrumentation environment clean up
- PassInstrumentor collects a set of PassInstrument instead of single call back
with tvm.transform.PassContext(Trace=_trace): # Call _trace in build flow # ==> pi1 = tvm.instrument.PassInstrument() pi2 = tmv.instrument.PassInstrument() with tvm.transofm.PassContext( pass_instrumentor=tvm.instrument.PassInstrumentor([pi1, pi2]): # Call pi1 and pi2's callbacks in build flow
2. Provide a PassesTimeInstrument that leverages previous passes time profiling c++ code.
TVM_REGISTER_GLOBAL("instrument.MakePassesTimeInstrument").set_body_typed([]() {
auto pi = PassInstrument("PassesTimeInstrument");
// No set up function for this time instrumentation.
pi->RegisterTearDownCallback([]() { PassProfileThreadLocalStore::Get()->root.children.clear(); });
pi->RegisterRunBeforePassCallback([](const IRModule&, const transform::PassInfo& pass_info) {
PassProfile::EnterPass(pass_info->name);
return true;
});
pi->RegisterRunAfterPassCallback(
[](const IRModule&, const transform::PassInfo&) { PassProfile::ExitPass(); });
return pi;
});
3. Inspired by LLVM and MLIR, it might be good to let run_before_pass() determines whether to run a pass with some instrumentation logics. (Return true to run pass; return false to skip pass)
/*!
* \file tvm/ir/instrument.h
*
* This file implements a pass instrument infrastructure, inspired from LLVM and MLIR.
* It inserts instrumentation points between passes run.
*
* Within a pass context (tvm::transfom::PassContext), the instrumentation call sequence will like:
*
* Instrument SetUp
*
* if (Instrument Before Pass)
* Pass Run
* Instrument After Pass
*
* if (Instrument Before Pass)
* Pass Run
* Instrument After Pass
*
* Instrument TearDown
*
*
* Instrument point before pass can determine particular pass is disable or not depends on the
* callback registered.
*/
Some Question Received
Thanks to [tkonolige] and [tqchen]
Q.
[tkonolige]
In order to avoid duplicating code it might be worth unifying this with the runtime profiling framework. I have a branch (which I haven’t submitted yet) that allows users to extend which kinds of information are collected.
[tqchen]
I agree it is important to have pass instrumentations, would be good to know how can it interact with Trace, since some of the callbacks might be similar and we need to unify the interface. On the design side, I think the runtime profiling and pass instrumentation might be different enough that might worth two separate solutions(perhaps a bit of reuse of timer if needed) As the former have more complexity wrt to GPU timer etc, while the later allows more statistics to be collected
A.
I would like to separate runtime profiling and pass instrumentation, too. This PR only focuses on pass profiling mechanisms like the passes time profiling, wants to make it easier to add more passes profiling implementations.
You might notice that this PR introduces a new namespace tvm.intrument. It intends to cover all instrument related (not limited to pass, but this PR only shows pass instrument), instead of mixing instrumentation/profiling code with transformation codes in tvm.transform. RuntimeProfiling could be add to this namespace, eg: tvm.instrument.Runtime.Profiling.