chiwwang commented on a change in pull request #8220: URL: https://github.com/apache/tvm/pull/8220#discussion_r659459311
########## File path: docs/dev/pass_infra.rst ########## @@ -389,6 +396,136 @@ To allow other C++ modules to apply this pass, we declare a free function in TVM_DLL Pass FoldConstant(); +.. _pass_instrument_cpp_backend: + +Pass Instrument +^^^^^^^^^^^^^^^ + +Currently we introduce four instrument points in the life-cycle of ``PassContext``. + +.. code:: c++ + + TVM_DLL void InstrumentEnterPassContext(); + TVM_DLL void InstrumentExitPassContext(); + TVM_DLL bool InstrumentBeforePass(const IRModule& mod, const PassInfo& info) const; + TVM_DLL void InstrumentAfterPass(const IRModule& mod, const PassInfo& info) const; + +``InstrumentEnterPassContext`` is called immediately when entering the scope +of the ``PassContext`` instance. + +``InstrumentExitPassContext`` is called when leaving the scope of ``PassContext``, +or exceptions occur during the execution of passes. +This method is also called when instruments is being overriden by ``override_instruments`` in :py:class:`tvm.transform.PassContext`. +See :ref:`pass_instrument_overriden`. + +``InstrumentBeforePass`` is called before execution. +``InstrumentAfterPass`` is called after executioon if the pass should be run. The behavior is like: + +.. code:: c++ + + if (pass_ctx.InstrumentBeforePass(ir_module, pass_info)) { + new_ir_module = run_pass(ir_module, pass_ctx); + pass_ctx.InstrumentAfterPass(new_ir_module, pass_info); + return new_ir_module; + } + +The ``PassInstrument`` interface allow you to run arbitrary code inside above four methods. +Multiple ``PassInstrument`` instances can be registed into a single +``PassContext``. ``PassInstrument`` instances are called sequentially in the order of +``instruments`` argument passed to ``PassContext``. + +``PassInstrument`` provides following interfaces: + +.. code:: c++ + + namespace instrument { + + class PassInstrumentNode : public Object { + public: + String name; + virtual void EnterPassContext() const = 0; + virtual void ExitPassContext() const = 0; + virtual bool ShouldRun(const IRModule& mod, const transform::PassInfo& info) const = 0; + virtual void RunBeforePass(const IRModule& mod, const transform::PassInfo& info) const = 0; + virtual void RunAfterPass(const IRModule& mod, const transform::PassInfo& info) const = 0; + /* Other fields are omitted. */ + }; + + class PassInstrument : public ObjectRef { + public: + TVM_DEFINE_OBJECT_REF_METHODS(PassInstrument, ObjectRef, PassInstrumentNode); + }; + + } // namespace instrument + +Python frontend are provided to implement ``PassInstrument`` quickly. See :ref:`pass_instrument_py_frontend`. + +Within a ``PassContext``, the call sequence of a ``PassInstrument`` instance is like: + +:: + + with PassContext(instruments=[pi]) # pi = a PassInstrument implementation. + pi.EnterPassContext() + + if pi.ShouldRun(Pass1): + pi.RunBeforePass() + Pass1() + pi.RunAfterPass() + + if pi.ShouldRun(Pass2): + pi.RunBeforePass() + Pass2() + pi.RunAfterPass() + + pi.ExitPassContext() + +Here is a brief introduction of relations between ``PassInstrument`` interfaces +and ``PassContext`` methods. See (`src/ir/transform.cc`_) for more details. + +- ``InstrumentEnterPassContext`` + + * ``EnterPassContext()`` is executed in the order of ``instruments`` passed to the ``PassContext``. + * When an exception raises, ``PassContext`` disable the pass instrumentation + by clearing all registered ``PassInstrument`` instances. + * Then ``PassContext`` execute ``ExitPassContext()`` method of each ``PassInstrument`` + instances which successfully finished ``EnterPassContext()`` + * For example, if ``PassInstrument`` A, B, and C are registered to a ``PassContext`` + and A finished ``EnterPassContext()`` while B throws an exception, then C + is never executed; ``ExitPassContext()`` of A is executed. + +- ``InstrumentExitPassContext`` + + * ``ExitPassContext()`` of each ``PassInstrument`` instances are executed in + the order of ``instruments`` passed to the ``PassContext``. + * While an exception occurs, ``instruments`` is cleared. + * ``PassInstrument`` Instances registered after the one throwing exceptions do not execute ``ExitPassContext``. + +- ``InstrumentBeforePass`` + + * ``ShouldRun`` is executed if the pass is not listed as a required pass. + * ``RunBeforePass`` is executed in the order of ``instruments`` if the pass is not blocked by ``ShouldRun``. + * Note that ``InstrumentBeforePass`` returns a boolean indicating whether or not the pass should be run. + * When an exception occur, it is thrown immediately. + We rely on Python Context Manager to exit ``PassContext`` safely + (meaning ``ExitPassContext`` of each instruments will be run. For C++, please refer to `include/tvm/support/with.h`_.) + +- ``InstrumentAfterPass`` + + * ``RunAfterPass`` is executed in the order of ``instruments`` passed to the ``PassContext``. + * When an exception occur, it is thrown immediately. + We rely on Python Context Manager or ``With`` class(`include/tvm/support/with.h`_) to exit ``PassContext`` safely + +Built-in Instrument +^^^^^^^^^^^^^^^^^^^ + +There are several built-in instruments. Those marked with *TODO* are not implemented yet. + +PassTimmingInstrument (see `src/ir/instrument.cc`_) Review comment: Done. Thanks! -- 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: commits-unsubscr...@tvm.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org