Sample Usage Guide
1. Function Description
This sample demonstrates graph construction using dynamic output operators, aimed at helping graph developers quickly understand dynamic output definition and usage.
2. Directory Structure
python/
├── src/
| └── make_split_graph.py // sample file
├── CMakeLists.txt // Build script
├── README.md // README file
├── run_sample.sh // Execution script
3. Usage Instructions
3.1. Prepare CANN Package
- Install
toolkitandopspackages correctly following Environment Preparation - Set environment variables (assuming package is installed at /usr/local/Ascend/)
source /usr/local/Ascend/cann/set_env.sh
3.2. Build and Execute
- Note: Compared with C/C++ graph construction, Python graph construction requires additional LD_LIBRARY_PATH and PYTHONPATH settings (refer to configuration in sample)
bash run_sample.sh -t sample_and_run_python
This command will:
- Automatically generate ES interfaces
- Compile sample program
- Generate dump graph and run the graph
After successful execution, you will see:
[Success] sample execution successful, pbtxt dump generated in current directory. The file starts with ge_onnx_ and can be opened in netron for display
Output File Description
After successful execution, the following files will be generated in current directory:
ge_onnx_*.pbtxt- protobuf text format of graph structure, can be viewed with netron
3.3. Log Printing
If you need log printing to assist debugging during executable program execution, you can set the following environment variables before bash run_sample.sh -t sample_and_run_python to print logs to screen:
export ASCEND_SLOG_PRINT_TO_STDOUT=1 # Print logs to screen
export ASCEND_GLOBAL_LOG_LEVEL=0 # Log level set to debug level
3.4. DUMP Graph During Graph Compilation Process
If you need to DUMP graph to assist debugging graph compilation process during executable program execution, you can set the following environment variables before bash run_sample.sh -t sample_and_run_python to DUMP graph to execution path:
export DUMP_GE_GRAPH=2
4. Core Concepts Introduction
4.1. Graph Construction Steps
- Create graph builder (provides context, workspace and construction-related methods needed for graph construction)
- Add starting nodes (starting nodes refer to nodes without input dependencies, usually including graph inputs (like Data nodes) and weight constants (like Const nodes))
- Add intermediate nodes (intermediate nodes are computation nodes with input dependencies, usually generated by user graph construction logic, and connected using existing nodes as inputs)
- Set graph output (explicitly specify graph output nodes as computation result endpoints)
4.2. Dynamic Output
Concept Explanation: Dynamic output refers to operators whose output count is not fixed; for example, Split operator is a dynamic output operator.
Graph Construction API Features:
- Need a parameter to pass dynamic output count
For example, Split operator prototype is shown below, ES graph construction generated API is Split(), supporting use in Python
REG_OP(Split)
.INPUT(split_dim, TensorType({DT_INT32}))
.INPUT(x, TensorType({DT_COMPLEX128, DT_COMPLEX64, DT_DOUBLE, DT_FLOAT, DT_FLOAT16, DT_INT16,
DT_INT32, DT_INT64, DT_INT8, DT_QINT16, DT_QINT32, DT_QINT8,
DT_QUINT16, DT_QUINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_UINT8,
DT_BF16, DT_BOOL}))
.DYNAMIC_OUTPUT(y, TensorType({DT_COMPLEX128, DT_COMPLEX64, DT_DOUBLE, DT_FLOAT, DT_FLOAT16, DT_INT16,
DT_INT32, DT_INT64, DT_INT8, DT_QINT16, DT_QINT32, DT_QINT8,
DT_QUINT16, DT_QUINT8, DT_UINT16, DT_UINT32, DT_UINT64, DT_UINT8,
DT_BF16, DT_BOOL}))
.REQUIRED_ATTR(num_split, Int)
.OP_END_FACTORY_REG(Split)
Its corresponding function prototype is:
- Function name: Split()
- Parameters: 4 in total, in order: split_dim, x, y_num, num_split
- Return value: output y
Note: Because current IR definition does not explicitly describe "input/attribute → dynamic output count" mapping relationship, graph construction API cannot automatically deduce output count, so output count needs to be manually specified;
Python API:
Split(split_dim: Union[TensorHolder, TensorLike], x: Union[TensorHolder, TensorLike], y_num: int, *, num_split: int) -> List[TensorHolder]:
Note:
- Use TensorLike type to express input, to support case where actual parameter can directly pass numeric values