The base class for a rewrite rule. A rewrite rule represents a semantics-preserving transformation of a computation graph. It can be used to represent, for example, the elimination of operators that serve as no-ops (e.g., dropout during inference), as well as inlining of "function" definitions or the dual operation of replacing a complex expression by an equivalent function-call). Unlike the more general GraphTransformer, a rewrite rule is a more local transformation that is triggered on a particular node of the graph.
Each rule has a set of conditions and a body. The conditions have to be satisfied for the body of the rule to be triggered. Therefore, when creating a new rewrite rule, two main functions have to be implemented:
- SatisfyCondition defines the condition checks. It is advisable to add the more selective checks first, because those will lead to discarding fast rules that cannot be applied on a node.
- Apply is the actual body of the rule that will be executed if SatisfyCondition returns true for a particular node. Note that additional, more complex checks can be included in the Apply if putting them in the SatisfyCondition would lead to duplicate work (e.g., when we make a check on a Node attribute but we need that attribute to execute the rule too). In general, simple fast checks are a better fit for SatisfyCondition, whereas more complex ones can be added in the Apply.
In order to avoid evaluating the SatisfyCondition for each rule and each node of the graph, each rewrite rule should specify the target op types for which a rule will be evaluated, by overriding the TargetOpTypes() function. If the op type of a node is not included in the target op types of a rule, that rule would not be considered at all. If the list of op types is left empty, that rule will be triggered for every op type.
Definition at line 36 of file rewrite_rule.h.