本节通过单算子模型执行的样例来介绍图模式下图编译和图执行流程。单算子模型执行是指基于图IR执行算子,先编译算子(例如,使用ATC工具将Ascend IR定义的单算子描述文件编译成算子om模型文件),再调用acl接口加载算子模型,最后调用acl接口执行算子。
安装CANN软件后,使用CANN运行用户进行编译、运行时,需要以CANN运行用户登录环境,执行source ${INSTALL_DIR}/set_env.sh命令设置环境变量。${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。以root用户安装为例,安装后文件默认存储路径为:/usr/local/Ascend/cann。
├── aclop_invocation │ ├── add_custom.json // 算子描述文件,用于构造单算子模型文件 │ ├── CMakeLists.txt │ └── main.cpp // 将单算子编译为om文件并加载om文件执行
[
{
"op": "AddCustom",
"input_desc": [
{
"name": "x",
"param_type": "required",
"format": "ND",
"shape": [8, 2048],
"type": "float16"
},
{
"name": "y",
"param_type": "required",
"format":"ND",
"shape": [8, 2048],
"type": "float16"
}
],
"output_desc": [
{
"name": "z",
"param_type": "required",
"format": "ND",
"shape": [8, 2048],
"type": "float16"
}
]
}
]
ATC工具的命令示例如下:
atc --singleop=../add_custom_static_shape.json --output=. --soc_version=<soc_version>
关键参数解释如下(详细参数说明,请参见《ATC离线模型编译工具》。):
AI处理器的型号请通过如下方式获取:
其中,id为设备id,通过npu-smi info -l命令查出的NPU ID即为设备id。
以上命令执行后,会在output参数指定路径下生成*.om后缀的离线模型文件。
您可以参考如下样例编写单算子加载、执行的代码逻辑。
以下是关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考,调用接口后,需增加异常处理的分支,并记录报错日志、提示日志,此处不一一列举。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | // 1.初始化 CHECK_ACL(aclInit(nullptr)); // 2.运行管理资源申请 const int32_t deviceId = 0; CHECK_ACL(aclrtSetDevice(deviceId)); // 3.加载单算子模型文件(*.om文件) CHECK_ACL(aclopSetModelDir(".")); // 4.设置算子的输入,申请内存,然后读取输入数据保存至申请的内存中 // ...... // 5.创建Stream流 aclrtStream stream = nullptr; aclrtCreateStream(&stream); // 6.执行算子 // opType表示算子类型名称,例如AddCustom // inputDesc.size()表示算子输入个数,例如AddCustom算子是2个输入 // inputDesc.data()表示算子输入tensor描述的数组,描述每个输入的format、shape、数据类型 // inputBuffers.data()表示算子输入tensor数据 // outputDesc.size()表示算子输出个数,例如AddCustom算子是1个输出 // outputDesc.data()表示算子输出tensor描述的数组,描述每个输出的format、shape、数据类型 // outputBuffers.data()表示算子输出tensor数据 // opAttr表示算子属性,如果算子没有属性,也需要调用aclopCreateAttr接口创建aclopAttr类型的数据 // stream用于维护一些异步操作的执行顺序 CHECK_ACL(aclopExecuteV2(opType, inputDesc.size(), inputDesc.data(), inputBuffers.data(), outputDesc.size(), outputDesc.data(), outputBuffers.data(), opAttr, stream)); // 7.阻塞应用运行,直到指定Stream中的所有任务都完成 aclrtSynchronizeStream(stream); // 8.处理执行算子后的输出数据,例如在屏幕上显示、写入文件等,由用户根据实际情况自行实现 // ...... // 9.释放stream流 aclrtDestroyStream(stream); // 10.释放运行管理资源 aclRet = aclrtResetDevice(deviceId); aclRet = aclFinalize(); // .... |
export DDK_PATH=${INSTALL_DIR} export NPU_HOST_LIB=${INSTALL_DIR}/{arch-os}/devlib
说明: 若您的开发环境即为运行环境,此拷贝操作可跳过。
chmod +x execute_add_op
./execute_add_op
如果有test pass,表明执行成功。