For
For
You can refer to this section to develop an operator plugin and map the operators of the ONNX framework to the operators that adapt to the AI processor (CANN operators for short). In this way, Ascend C custom operators can be called from the ONNX framework.
After creating an operator project, the framework/onnx_plugin directory is generated in the operator project path to store the implementation file of the ONNX adaptation plugin. The following uses the custom CANN operator LeakyReluCustom as an example. The operator project directory is as follows:
LeakyReluCustom ├── build.sh // Build entry script ├── cmake ├── CMakeLists.txt // Build script of the operator project ├── CMakePresets.json // Build configuration options ├── framework // Directory for storing the implementation file of the framework adaptation plugin │ ├── onnx_plugin // Directory for storing the implementation file of the ONNX adaptation plugin │ │ ├── CMakeLists.txt │ │ ├── leaky_relu_custom_plugin.cc // Implementation file of the ONNX adaptation plugin │ ├── CMakeLists.txt ├── op_host // Implementation file on the host ├── op_kernel // Implementation file on the kernel └── scripts // Directory of scripts used for custom operator project packing
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include "register/register.h" #include "graph/operator.h" #include "json.hpp" namespace domi { Status ParseParamByOpFunc(const ge::Operator& op_src, ge::Operator& op_dest) { //... } REGISTER_CUSTOM_OP("OpType") .FrameworkType(ONNX) .OriginOpType("OriginOpType") .ParseParamsByOperatorFn(ParseParamByOpFunc) // Registers a function for parsing operator attributes. .ImplyType(ImplyType::TVM); // Sets the implementation type of Ascend C operators to TVM. } |
1
|
Status ParseParamByOpFunc(const ge::Operator& op_src, ge::Operator& op_dest) |
You need to implement attribute parsing and mapping in the callback function as follows:
In the original ONNX model, for parameters of the repeated message type, you can obtain attribute values using the GetAttr(const char *name, ge::AscendString &attr_value) API, cast the attribute values of type AscendString to strings, and then convert the attribute values to the JSON format for attribute field parsing.
The implementation is as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Status ParseOnnxParamsLeakyReluCustom(const ge::Operator& op_src, ge::Operator& op_dest) { // trans op_src to op_dest // if op_src get required attr failed, need to return Failed // if op_src get optional attr failed, need to return Failed or set a default value float negative_slope = 0.01f; string negative_slope_str; AscendString attrs_string; // Obtain the attributes of an ONNX operator using the specified attribute name attribute and assign a value to the object of the AscendString type. if (ge::GRAPH_SUCCESS == op_src.GetAttr("attribute", attrs_string)) { // Cast to the JSON format. json attrs = json::parse(attrs_string.GetString()); for (json attr : attrs["attribute"]) { if (attr["name"] == "alpha" && attr["type"] == kTypeFloat) { negative_slope_str = attr["f"]; // float type in json has accuracy loss, so we use string type to store it negative_slope = atof(negative_slope_str.c_str()); } } } op_dest.SetAttr("negative_slope", negative_slope); return SUCCESS; } |