ONNX Python Plugin Graph Compilation and Execution Sample
This sample demonstrates the complete path: export a PyTorch custom operator to ONNX,
register a Python parser plugin with onnx_plugin, decompose ThresholdedRelu into
the existing Threshold and Mul operators, compile the graph to an OM model with
ATC, and execute it through the ACL Python API.
Directory layout
onnx_plugin/
├── plugin/
│ └── thresholded_relu_plugin.py # GE ONNX Python plugin
├── export_onnx.py # PyTorch custom operator -> ONNX
├── run_model.py # Load and execute OM with ACL
└── run.sh # Export, compile, and execute
The plugin/ directory is intentionally separate from the other scripts. GE scans
one level of Python files under ASCEND_CUSTOM_OPP_PATH; the exporter and runner
depend on PyTorch, NumPy, or ACL and must not be imported as plugins during ATC
initialization.
Requirements
- CANN installed and its matching
set_env.shsourced; atcavailable inPATHand an Ascend device;- PyTorch, ONNX, and NumPy compatible with the CANN Python environment.
Run the sample
Source the CANN environment and set the SoC model for the target device:
source /path/to/cann/set_env.sh
SOC_VERSION=Ascend910B1 ./run.sh
The default SOC_VERSION is Ascend910B1; override it for the target device, for
example:
SOC_VERSION=Ascend910B2 ./run.sh
SOC_VERSION=Ascend910_9362 ./run.sh
Verified end to end (export, ATC compile, ACL execution, and result comparison) on:
SoC: Ascend910_9362 (Atlas A3) SOC_VERSION=Ascend910_9362
The script performs these steps:
export_onnx.pywritesoutput/thresholded_relu.onnx;ASCEND_CUSTOM_OPP_PATHis set so ATC discovers the plugin file;- ATC compiles the ONNX model to
output/thresholded_relu.om; run_model.pyloads and executes the OM model with ACL and checks the output.
The input is:
[[-1.0, 0.5, 1.5],
[ 2.0, -2.0, 3.0]]
The expected output keeps elements greater than alpha=1.0 and replaces the rest
with 0:
[[0.0, 0.0, 1.5],
[2.0, 0.0, 3.0]]
Run step by step
To inspect export, compilation, or execution separately:
python3 export_onnx.py --output output/thresholded_relu.onnx
export ASCEND_CUSTOM_OPP_PATH="$(pwd)/plugin:${ASCEND_CUSTOM_OPP_PATH:-}"
atc --model=output/thresholded_relu.onnx \
--framework=5 \
--output=output/thresholded_relu \
--soc_version="${SOC_VERSION:-Ascend910B1}"
python3 run_model.py --model output/thresholded_relu.om
The sample uses the decompose callback to build a graph from existing GE/ES
operators and does not provide a new device kernel. It therefore exercises Python
ONNX plugin registration, parsing, subgraph expansion, graph compilation, and graph
execution.
The parse_node and decompose callbacks cooperate in this sample:
parse_noderuns when the ONNX node is converted to the target operator. It relays thealphaattribute onto the target operator and registers the ports of the dynamic-IO targetPartitionedCall(the parser needs port names to wire the graph).- The
sourcereceived bydecomposeis the operator produced byparse_node; thealphait reads was relayed by that callback, sodecomposedepends on the attribute relay and port registration done inparse_node.