ParseOpToGraphFn
Description
Registers the function for constructing a one-to-many mapping subgraph, that is, mapping an operator to many operators.
Prototype
OpRegistrationData &ParseOpToGraphFn(const ParseOpToGraphFunc &parse_op_to_graph_fn)
Parameters
Parameter |
Input/Output |
Description |
|---|---|---|
parse_op_to_graph_fn |
Input |
Function for constructing a subgraph to map an operator to many operators. For details, see Callback Function ParseOpToGraphFunc. |
Restrictions
To implement one-to-many mapping, you need to map the original operator to the PartitionedCall operator supported by Ascend AI Processor during plugin registration, and use the SetAttr API in the ParseParamsByOperatorFn function to set original_type.
An implementation sample is provided in Example.
Callback Function ParseOpToGraphFunc
You can customize and implement the ParseOpToGraphFunc function to construct one-to-many subgraphs by building an IR model. For details, see Ascend Graph Developer Guide.
The callback function prototype is defined as follows:
Status ParseOpToGraphFunc(const ge::Operator &op, ge::Graph &graph)
Parameter |
Input/Output |
Description |
|---|---|---|
op |
Input |
Data structure of the PartitionedCall operator, which is an object of the Operator class. |
graph |
Output |
Constructed subgraph. |
- Input: Add the index attribute to the Data node. index of the Data node indicates the indexth input edge of the original node.
- Output: Set the output by calling Graph::SetOutputs(), which takes std::vector<std::pair<Operator, std::vector<size_t>>>. The output edges are connected in the configured output order.
Example
The following describes how to map the Add operator to AddN+Abs.
Map the Add operator to the PartitionedCall operator:
Status ParseParams(const ge::Operator &op_src, ge::Operator& op_dest)
{
...
op_dest.SetAttr("original_type", "ai.onnx::11::Add");
}
Construct the one-to-many subgraph:
static Status ParseOpToGraph(const Operator &op, Graph &graph) {
auto data_0 = op::Data().set_attr_index(0);
auto data_1 = op::Data().set_attr_index(1);
auto addn = op::AddN("addn_sum").create_dynamic_input_x(2)
.set_dynamic_input_x(0, data_0)
.set_dynamic_input_x(1, data_1)
.set_attr_N(2);
auto abs = op::Abs("abs_sum").set_input_x(addn);
std::vector<Operator> inputs{data_0, data_1};
std::vector<std::pair<Operator, std::vector<size_t>>> output_indexs;
output_indexs.emplace_back(abs, vector<std::size_t>{0});
graph.SetInputs(inputs).SetOutputs(output_indexs);
return domi::SUCCESS;
}
Register the operator:
REGISTER_CUSTOM_OP("PartitionedCall")
.FrameworkType(xx)
.OriginOpType(xx)
.ParseParamsByOperatorFn(ParseParams)
.ParseOpToGraphFn(ParseOpToGraph)
.ImplyType(ImplyType::TVM);
Figure 1 shows an example of one-to-many mapping of the Add operator.
