Integrating Custom Operators into a Graph for ONNX
The ONNX frontend is different from PyTorch. If the ONNX Parser of GE cannot identify an operator type, it directly reports an error (PARAM_INVALID). Therefore, you need to compile an additional ONNX parsing plugin to map the attributes of the ONNX node to the attributes of the GE operator. The following figure shows the deliverables.

- Phase 1: Operator definition
In the operator definition phase, operator metadata, such as the inputs, outputs, and attributes, is declared for use in subsequent phases.
Implementation by frontend framework:
Frontend Framework
Definition Method
Deliverable
Description
ONNX
NodeProto
Embedded in the ONNX model
Operator definition is natively included within the model itself.
- Phase 2: Frontend integration
This phase maps frontend operator types to GE operator types and converts attributes.
Integration by frontend framework:
Frontend Framework
Integration Method
Deliverable Involved
Key Point
ONNX
Parser plug-in
libonnx_parser_plugin.so
ParseParamsFn must be manually written.
ONNX operator type identifier format: "domain::version::OpType" (for example, "ai.onnx::11::Conv" or "com.example::1::MyOp"). The Parser searches for the mapping in OpRegistry based on this format. If the mapping cannot be found, the parsing fails.
The ONNX parser plug-in requires you to:
- Use REGISTER_CUSTOM_OP to register the mapping from the ONNX operator type to the GE operator type.
- Implement ParseParamsFn to extract attributes from the ONNX NodeProto and set them for the GE operator.
Parser plug-in code:
// framework/onnx/add_custom_parser.cpp #include "register/register.h" #include "proto/onnx/ge_onnx.pb.h" // Attribute parsing function: Map the ONNX NodeProto attributes to the GE operator attributes. // op_src: proto message body on the ONNX node // op_dest: GE operator object, which is used to set attributes static domi::Status ParseMyOp(const google::protobuf::Message *op_src, ge::Operator &op_dest) { // Convert the message to the ONNX NodeProto type. auto *node = dynamic_cast<const ge::onnx::NodeProto *>(op_src); // Traverse all attributes of the ONNX node. for (const auto &attr : node->attribute()) { // Set the alpha attribute in the ONNX model to the GE operator. if (attr.name() == "alpha") { op_dest.SetAttr("alpha", attr.f()); } } return domi::SUCCESS; } // Register the ONNX parser plug-in: Map the ONNX operator type to the GE operator type. // When the ONNX Parser encounters an unrecognized operator, it searches for the parser plug-in based on this registration information. REGISTER_CUSTOM_OP("MyCustomOp") .FrameworkType(domi::ONNX) // Declare it as an ONNX framework plug-in. .OriginOpType({"ai.onnx::11::MyOp", "ai.onnx::13::MyOp"}) // ONNX operator type (multiple versions supported) .ParseParamsFn(ParseMyOp); // Attribute parsing callback functionKey methods of REGISTER_CUSTOM_OP
Method
Function
.FrameworkType(domi::ONNX)
Declares the operator as an ONNX framework plug-in
.OriginOpType("domain::ver::Type")Specifies the ONNX operator type (supporting a list of types, covering multiple versions).
.ParseParamsFn(fn)
Attribute parsing function (Message* → Operator&)
.ParseParamsByOperatorFn(fn)
Attribute parsing for automatic mapping paths (Operator → Operator)
.ParseOpToGraphFn(fn)
Expands a single operator into a subgraph (optional)
.ParseSubgraphPostFn(fn)
Post-processing for operators that contain subgraphs (optional)
In ONNX scenarios, two .so files listed in the table below are required.
Deliverable
Function
Directory
ONNX parser plug-in (.so)
REGISTER_CUSTOM_OP + ParseParamsFn, responsible for attribute mapping from ONNX to GE
Plug-in directory under ASCEND_CUSTOM_OPP_PATH
GE custom operator (.so)
REG_OP + REG_AUTO_MAPPING_OP + execution logic
op_graph/lib/<os>/<arch>/
Deliverable structure example:
custom_opp/ ├── op_graph/ │ ├── include/add_custom.h # REG_OP │ └── lib/linux/x86_64/libcust_opapi.so # GE deliverable ├── framework/ │ └── onnx/ │ └── libonnx_parser_plugin.so # Parser plug-in (an independent .so file)
Precautions:
- The ONNX parser plug-in (.so) must be loaded through ASCEND_CUSTOM_OPP_PATH before ATC compilation. Otherwise, the parser cannot identify the custom operator type.
- If the domain in OriginOpType is left empty, ai.onnx is used by default. A custom domain must be explicitly specified.
- If an ONNX operator can be mapped to a combination of existing GE operators, you can use ParseOpToGraphFn to expand it into a subgraph. In this case, you do not need to compile the custom operator (.so) on the GE.
- Phase 3: Graph construction and integration
In the graph construction and integration phase, the frontend computational graph is converted into a GE computational graph.
Graph integration path by frontend framework:
Frontend Framework
Graph Integration Path
Conversion Mechanism
ONNX
ONNX Model → GE Graph
Parser
This phase is automatically completed by the framework, and you do not need to provide any additional deliverables. After the graph integration is complete, the GE graph already contains the custom operator node.
- Phase 4: Graph compilation
The callback APIs for graph compilation are triggered during GE compilation and are used for shape inference, kernel compilation, and serialization. Callback APIs and triggering timing are described in the table below.
Callback API
Triggering Timing
Application Scenario
InferShape
Compile-time shape inference
All scenarios (optional)
InferDataType
Compile-time data type inference
All scenarios (optional)
Compile
Compile-time RTC kernel compilation
Online compilation/Offline OM
Serialize
Writing data to the OM during ATC compilation
Offline OM
For details about the callback API examples, see Callback APIs.
- Phase 5: Graph execution
This phase is the core of custom operator integration. GE calls back the Execute API during execution.
Callback APIs and triggering timing are described in the table below.
Callback API
Triggering Timing
Application Scenario
Execute
Runtime kernel execution
All scenarios (mandatory)
Deserialize
Restoring binary during OM loading
Offline OM
UpdateHostArgs
Updates upon I/O address changes
Static graph offloading
For details about the callback API examples, see Callback APIs.
Mapping between ONNX graph integration phases and deliverables
Phase |
Deliverable Involved |
Description |
|---|---|---|
Phase 1: Operator definition |
Embedded in the ONNX model |
Built-in by NodeProto |
Phase 2: Frontend integration |
framework/onnx/libonnx_parser_plugin.so |
Parser plug-in |
Phase 3: Graph construction and integration |
None |
Automatic conversion by the parser |
Phase 4: Graph compilation |
op_graph/lib/*/*.so |
Callback implementation in GE deliverables |
Phase 5: Graph execution |
op_graph/lib/*/*.so |
Callback implementation in GE deliverables |
Additional requirements:
- op_graph/include/*.h (REG_OP) is used by the parser to create nodes.
- The parser plug-in and GE deliverables must be loaded at the same time.