对cann的算子编译注册工程的说明解析【对应工程1_custom_op】

PZK 发表于 2022/09/01 16:21:01 2022/09/01
【摘要】 详细解析了samples-master/cplusplus/level1_single_api/4_op_dev/1_custom_op/这个算子注册的编译过程,包括最终的.run的产生也被详细解析

对算子编译注册工程的解析

说明:README_CN.md说明了这个工程整体的目录架构和工程编译方式,幸运的话,我们一般可以直接使用./build.sh -t进行编译出AICore的目标安装文件,为build_out/custom_opp__.run。如何生成.run安装文件,已经后续的.run是如何把算子注册进Ascend框架中的,我个人是比较好奇的。因此在此进行算子注册工程的解析。

1、build.sh脚本分析

1.1、脚本的设计思路

  • 传参式设计:使用到shell中的while循环、case.esac选择、shift传参左移操作、break跳出循环操作。
# 从输入中获取传参信息
clean=n
compile_component=$COMPILE_KERNEL_TARGET
while true
do
  case "$1" in
  -h | --help)
# 打印帮助说明
  echo "  --help                show the help info of using this shell"
  echo "  --kernel_so_name=*    so name of aicpu custom operators "
  echo "  --toolchain_dir=*     specify cross compile toolchain directory"
  echo "  clean                 clean compile result directory"
  echo "  -c                    only compile cpu"
  echo "  -t                    only compile tbe"
  exit 0
  ;;
  --so_name=*)
# 设置编译出来的AICPU核心的名字
  so_name=`echo ${1} | cut -d"=" -f2`
  length=${#so_name}
  aicpu_target_name=${so_name:3:($length - 6)}
  export AICPU_KERNEL_TARGET=$aicpu_target_name
  echo "aicpu_target_name=${aicpu_target_name}"
  shift
  ;;
  clean)
# 是否清除之前的编译文件
  clean=y
  shift
  ;;
  -c | -cpu)
# 编译的目标是cpu算子
  compile_component=cpu
  shift
  ;;
  -t | -tbe)
# 编译的组件是tbe算子
  compile_component=tbe
  shift
  ;;
  --toolchain_dir=*)
  tool_dir=`echo ${1} | cut -d"=" -f2`
  export TOOLCHAIN_DIR=$tool_dir
  echo "specified TOOLCHAIN_DIR=$TOOLCHAIN_DIR"
  shift
  ;;
  -*)
  echo "  --help                show the help info of using this shell"
  echo "  --toolchain_dir=*     specify cross compile toolchain directory"
  echo "  --so_name=*           so name of aicpu custom operators generated by compilation"
  echo "  clean                 clean compile result directory"
  echo "  -c                    only compile cpu"
  echo "  -t                    only compile tbe"
  exit 0
  ;;
  *)
  break
  ;;
  esac
done
  • cmake和make编译:多次使用了环境变量设置的export命令,为后续的cmake编译提供了必要的变量依赖
# 设置cpu_so的名字
export AICPU_KERNEL_TARGET=$aicpu_target_name
# 设置编译目标是cpu还是tbe
export COMPILE_KERNEL_TARGET=$compile_option
# 设置ascend的atc下的头文件目录
export ASCEND_TENSOR_COMPILER_INCLUDE=/usr/local/Ascend/ascend-toolkit/latest/atc/include

1.2、整体流程

设置传参
判断是否clean
赋予cmake/util下的必要权限
判断framework/caffe_plugin下是否存在插件
cmake和make
结束

2、Cmake工程分析

侧重分析各个CMakeLists.txt,分析其内部的编译流程,以及如何生成.run安装文件。重点分析.run安装文件内部存在什么文件和命令。

2.1、存在的CMakeLists.txt

# 主
./CMakeLists.txt

./cpukernel/CMakeLists.txt

./op_proto/CMakeLists.txt

./tbe/CMakeLists.txt

./framework/CMakeLists.txt
./framework/onnx_plugin/CMakeLists.txt
./framework/tf_scope_fusion_pass/CMakeLists.txt
./framework/tf_plugin/CMakeLists.txt
./framework/caffe_plugin/CMakeLists.txt

2.2、./CMakeLists.txt解析

按照顺序完成的编译操作如下所示:

  • 设置了C和C++的编译器,进行了指定
  • 包含了CMAKE_SOURCE_DIR/cmake/config.cmake中的所有变量(用SET定义的必要变量)
  • 执行rm -rf ./makepkg
  • 如果COMPILE_KERNEL_TARGET不等于tbe,那么add_subdirectory(cpukernel),也就是编译cpukernel下的文件
  • add_subdirectory(framework)
  • add_subdirectory(op_proto)
  • 如果存在tbe文件夹并且COMPILE_KERNEL_TARGET不等于cpu,那么add_subdirectory(tbe)
  • 设置添加需要编译的模块
    • OP_PROTO_TARGET
    • 【如果不是tbe】AICPU_KERNEL_TARGET + AICPU_CONFIG_JSON_TARGET
    • 【如果不是cpu】config_json
    • 【存在./framework/caffe_plugin】 CAFFE_PLUGIN_TARGET
    • 【存在./framework/tf_plugin】 TF_PLUGIN_TARGET
    • 【存在./framework/tf_scope_fusion_pass】TF_SCOPE_FUSION_PASS_TARGET
    • 【存在./framework/onnx_plugin】 ONNX_PLUGIN_TARGET
  • 【如果不是cpu】,在编译模块前执行如下命令:
    • mkdir -p ./makepkg/packages/op_impl/${PROJECT_DIR}/ai_core/tbe/custom_impl
    • mkdir -p ./makepkg/packages/op_impl/${PROJECT_DIR}/vector_core/tbe/custom_impl
  • 【如果不是tbe】,在编译模块前执行如下命令:
    • mkdir -p ./makepkg/packages/op_impl/${PROJECT_DIR}/cpu/aicpu_kernel/custom_impl
  • 在编译模块前执行如下命令:
    • mkdir -p ./makepkg/packages/fusion_rules/${PROJECT_DIR}/
    • bash ./CMAKE_SOURCE_DIR/cmake/util/gen_impl_and_mrege_json.sh ./ ./build_out
    • cp CMAKE_SOURCE_DIR/scripts/install.sh ./makepkg/
    • cp CMAKE_SOURCE_DIR/scripts/upgrade.sh ./makepkg/
    • cp CMAKE_SOURCE_DIR/scripts/uninstall.sh ./makepkg/
    • cp CMAKE_SOURCE_DIR/scripts/help.sh ./makepkg/
    • 【如果CMAKE_SOURCE_DIR/custom.proto存在】cp CMAKE_SOURCE_DIR/custom.proto ./makepkg/packages
    • chmod u+x ./makepkg/*.sh
    • ./CMAKE_SOURCE_DIR/cmake/util/makeself/makeself.sh --gzip --complevel 4 --nomd5 --sha256 ./makepkg ${RUN_TARGET} “version:1.0” ./install.sh

注意点:

  • 在编译模块前执行的命令都是在build_out/下的命令
  • makeself.sh是一个专门用来打包文件成可执行程序的压缩脚本
    • makeself命令的使用方法是 “makeself 要压缩的目录 要做成的文件名 描述信息 第一个要执行的脚本”

3、.run内部内容和具体安装细节

3.1、内部内容

│  help.sh     ----------->帮助脚本
│  install.sh  ----------->安装脚本
│  uninstall.sh----------->卸载脚本
│  upgrade.sh  ----------->升级脚本
│
└─packages
    │  custom.proto
    │
    ├─framework
    │  └─custom
    │      ├─caffe
    │      │      libcust_caffe_parsers.so              ----------->算子自定义前端解析文件
    │      │
    │      ├─onnx
    │      │      libcust_onnx_parsers.so
    │      │
    │      └─tensorflow
    │              libcust_tf_parsers.so
    │              libcust_tf_scope_fusion.so
    │              npu_supported_ops.json
    │
    ├─fusion_rules
    │  └─custom
    ├─op_impl
    │  └─custom
    │      ├─ai_core
    │      │  └─tbe
    │      │      ├─config
    │      │      │  ├─ascend310
    │      │      │  │      aic-ascend310-ops-info.json  ----------->tbe/op_info_cfg/ai_core/**.ini文件转换整合出的json文件
    │      │      │  ├─ascend310p
    │      │      │  │      aic-ascend310p-ops-info.json
    │      │      │  ├─......
    │      │      │  └─tsnse
    │      │      └─custom_impl
    │      │              add_dsl.py                     ----------->算子实现文件
    │      │              conv2d_tik.py
    │      │              ......
    │      │              __init__.py
    │      │
    │      └─vector_core                                 ----------->预留文件夹
    │          └─tbe
    │              └─custom_impl
    │                      ......
    │                      scatter_nd_add.py
    │                      upsample_tik.py
    │                      __init__.py
    │
    └─op_proto
        └─custom
                libcust_op_proto.so                      ----------->算子注册自定义动态库

3.2、安装过程

具体安装命令在makepkg/install.sh中,具体流程如下所示:

  • 确保安装目录targetdir存在
  • 升级架构,执行命令upgrade framework
    • 最终的目的就是直接复制相应文件到对应的目录下:cp -rf ${sourcedir}/$1/* $targetdir/$1/
  • 执行命令upgrade op_proto
    • 同上
  • 执行命令upgrade op_impl
    • 同上
  • 执行命令upgrade_proto
    • cp -rf ${sourcedir}/custom.proto ${targetdir}/framework/custom/caffe/
  • 如果是root用户,改变特定文件的权限
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。