支持AscendCL单算子调用

完成自定义算子的开发部署后,通过单算子API执行的方式调用,添加使用-O0 -g编译选项重新编译算子并部署,并导入算子动态加载路径,最后用msdebug工具加载算子可执行文件进行上板调试。

单算子API执行的详细内容请参考Ascend C自定义算子开发指南中的“单算子API执行”章节。

  1. 参考创建算子工程完成算子工程的创建,并完成kernel侧实现及host侧实现的相关准备。
  2. 参考算子编译部署,完成算子的编译部署。自定义算子编译部署后,会自动生成单算子API,可直接在应用程序中调用。

    算子工程build_out/auto_gen目录下会自动生成单算子API执行所需文件,如下所示:
    ├── aclnn_Xxx.cpp                     //  自动生成的单算子API执行接口实现文件
    ├── aclnn_Xxx.h                       //  自动生成的单算子API执行接口头文件 

  3. 在kernel侧和host侧实现中增加编译选项-O0 -g。

    • 在kernel侧增加编译选项,可在op_kernel/CMakeLists.txt中进行编辑
      add_ops_compile_options(ALL OPTIONS -g -O0)
    • 在host侧增加编译选项,可在op_host/CMakeLists.txt中进行编辑
      add_compile_options(-O0 -g)

  4. 进入自定义算子工程目录下重新编译部署算子。
  5. 单击LINK,获取验证代码的样例工程。

    ├──input                                                 // 存放脚本生成的输入数据目录
    ├──output                                                // 存放算子运行输出数据和真值数据的目录
    ├── inc                           // 头文件目录 
    │   ├── common.h                 // 声明公共方法类,用于读取二进制文件 
    │   ├── operator_desc.h          // 算子描述声明文件,包含算子输入/输出,算子类型以及输入描述与输出描述 
    │   ├── op_runner.h              // 算子运行相关信息声明文件,包含算子输入/输出个数,输入/输出大小等 
    ├── src 
    │   ├── CMakeLists.txt    // 编译规则文件
    │   ├── common.cpp         // 公共函数,读取二进制文件函数的实现文件
    │   ├── main.cpp    // 单算子调用应用的入口
    │   ├── operator_desc.cpp     // 构造算子的输入与输出描述 
    │   ├── op_runner.cpp   // 单算子调用主体流程实现文件
    ├── scripts
    │   ├── verify_result.py    // 真值对比文件
    │   ├── gen_data.py    // 输入数据和真值数据生成脚本文件
    │   ├── acl.json    // acl配置文件

  6. 可选:为单算子调用应用添加-O0 -g编译选项。

    如果需要在算子调用程序中添加断点(如main.cpp),则需要编辑算子工程目录下的CMakeLists文件,如样例工程中的AclNNInvocation/src/CMakeLists.txt。

    # 添加编译选项
    add_compile_options(-O0 -g)

  7. 检查单算子调用主体流程实现文件中同步等待接口的超时参数。

    如在AclNNInvocation/src/op_runner.cpp文件中使用了具有超时参数的同步接口aclrtSynchronizeStreamWithTimeout,则需要适当调整或取消超时参数,否则在调试过程中,程序在断点停止时间过长,调用程序会认为执行失败并中断执行。

    # 在op_runner.cpp中进行接口同步时,假如原定的超时时间为5000毫秒
    aclrtSynchronizeStreamWithTimeout(stream, 5000)
    可参考以下方式进行修改:
    • 手动增大超时时间
      aclrtSynchronizeStreamWithTimeout(stream, 5000000)
    • 使用不带超时参数的同步接口
      aclrtSynchronizeStream(stream)

  8. 编译单算子调用应用并得到可执行文件execute_add_op

    AddCustom自定义算子调用为例,可参考Ascend C自定义算子开发指南中的“单算子API执行”章节,编写算子调用的代码逻辑,并完成编译。

  9. 导入算子动态加载路径。

    将自定义算子工程编译后输出在build_out目录下kernel侧的.o文件路径导入环境变量。

    export LAUNCH_KERNEL_PATH=/{path_to_kernel}/kernel_name.o

    {path_to_kernel}表示对算子kernel侧实现编译后生成的算子二进制文件*.o所在路径,请根据实际情况进行替换。

    kernel侧对算子的多个dtype可能会编译出多个.o文件,任选一个文件导入即可,原则上都会包含源码路径信息。

  10. 使用msdebug工具加载步骤8中得到的单算子可执行文件execute_add_op。

    cd AclNNInvocation/output
    msdebug execute_add_op
    (msdebug) target create "execute_add_op"
    Current executable set to '/home/AclNNInvocation/output/execute_add_op' (aarch64).
    (msdebug)

  11. 断点设置。

    b /home/xx/op_host/add_custom.cpp:24
    • 如果host侧和kernel侧存在同名的算子实现文件,在设置断点时,推荐采用绝对路径进行设置,确保断点打在预期的文件上。
    • 在对host侧源码文件进行打点时,可能会出现找不到实际位置的告警,类似如下提示:
      (msdebug) b /home/xx/op_host/add_custom.cpp:24
      Breakpoint 1: no locations (pending).
      WARNING:  Unable to resolve breakpoint to any actual locations.
      (msdebug)

      在算子运行后,会自动找到实际位置,并自动设置断点。

  12. 运行算子程序,等待直到命中断点。

    (msdebug) run
    Process 3248297 launched: '/home/AclNNInvocation/output/execute_add_op' (aarch64)
    1 location added to breakpoint 1
    1 location added to breakpoint 1
    ... # 省略部分输出
    [INFO]  Create stream success
    Process 3248297 stopped
    * thread #1, name = 'execute_add_', stop reason = breakpoint 1.1
        frame #0: 0x0000ffffd529062c liboptiling.so`optiling::TilingFunc(context=0x0000000008ea4820) at add_custom.cpp:24
       21       const uint32_t totalNum = context->GetInputTensor(0)->GetShapeSize();
       22       
       23       auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
    -> 24       const uint32_t actCoreNum = ascendcPlatform.GetCoreNumAiv();
       25       uint64_t ubSize;
       26       ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
       27  
    (msdebug)

    后续调试过程可参考导入调试信息内存与变量核切换等,与其操作一致。