In the new external codegen infrastructure, we make significant use of subgraphs denoted by introducing annotations into the relay expressions. The principle is that you can define a subgraph by introducing an annotation op on all of its incoming and outgoing ‘edges’. This is currently used in the AnnotateTarget pass and the PartitionGraph pass to designate subgraphs as being possible to offload to an external codegen (compiler_begin and compiler_end annotations are used).
Ultimately these annotated subgraphs are transformed into functions marked as external by PartitionGraph. However, currently this only works for subgraphs which have a single output. Going forward, we will need to be able to support subgraphs with potentially many outputs to allow us to partition the graph more extensively.
We intend to implement the algorithm described here to support multiple outputs, but this will require the addition of a few extra passes. Approximately speaking, we have three steps:
- Annotate operators (or composite functions) as supported by introducing compiler_begin/compiler_end annotations around them.
- Take these supported operators and merge them together into larger subgraphs which can be offloaded (the algorithm is described in the aforementioned RFC).
- Take the resulting merged subgraphs and turn them into external functions (performed by the PartitionGraph pass).
In all of these the notion of annotated subgraphs is used, so we propose a new bit of infrastructure to extract and manipulate these subgraphs - SubgraphSet (name subject to change…)
A SubgraphSet is initialised using a Relay expression and the subgraph_begin/subgraph_end annotation types (compiler_begin and compiler_end in our case). It will then populate itself with a number of Subgraph objects with information on the nodes they contain as well as the input and output nodes of the Subgraph. It also provides methods to query/manipulate the created Subgraphs.
Having this as a separate utility is valuable as it can then be reused in both the merging and partitioning pass (as well as any future passes that need to work with Subgraphs).
There is a WIP PR here: https://github.com/apache/incubator-tvm/pull/5030.
This is intended as the first step towards supporting multiple outputs in the partitioner. The next step will be an update to PartitionGraph to implement step 3, then followed by a new pass to implement step 2. Concurrently, we will need to add support for composite functions.