适配开发
支持Ascend C实现自定义算子Kernel,并集成在PyTorch框架,通过PyTorch的API实现算子调用。
前提条件
完成CANN软件的安装具体请参见《CANN 软件安装指南》(商用版)或《CANN 软件安装指南》(社区版),完成PyTorch框架的安装具体请参见《Ascend Extension for PyTorch 软件安装指南》。
适配文件结构
├ examples │ ├ cpp_extension │ │ ├ op_extension // 包含Python脚本, 用于初始化模块 │ │ ├ csrc // C++目录 │ │ │ ├ kernel // 算子kernel实现 │ │ │ ├ host // 算子注册torch │ │ │ │ ├ tiling // 算子tiling实现 │ │ ├ test // 测试用例目录 │ │ ├ CMakeLists.txt // CMake文件 │ │ ├ setup.py // setup文件 │ │ ├ README.md // 模块使用说明
操作步骤

以下流程以add_custom kernel算子适配为例进行说明。
- kernel算子实现。
- 在./cpp_extension/csrc/kernel目录下完成kernel算子实现,具体可参考《CANN Ascend C算子开发指南》。
- 在CMakeLists.txt中配置对应kernel的编译选项。
Ascend C编写的算子,是否需要workspace具有不同编译选项。以下示例中提供了两种算子的实现:
- 不需要workspace:add_custom算子。
- 需要workspace:matmul_leakyrelu_custom算子。
- add_custom算子示例:
ascendc_library(no_workspace_kernel STATIC csrc/kernel/add_custom.cpp )
- matmul_leakyrelu_custom算子示例:
ascendc_library(workspace_kernel STATIC csrc/kernel/matmul_leakyrelu_custom.cpp ) ascendc_compile_definitions(workspace_kernel PRIVATE -DHAVE_WORKSPACE -DHAVE_TILING )
- 在./cpp_extension/csrc/host目录下,封装实现的kernel算子,注册为PyTorch的API,子目录tiling存放算子的tiling函数。以下示例以自定义torch.ops.npu.my_add API(封装add_custom kernel算子)为例:
- Aten IR定义。PyTorch通过TORCH_LIBRARY宏将C++算子实现绑定到Python。Python侧可以通过torch.ops.namespace.op_name方式进行调用。如果在相同namespace下的不同API,定义在不同文件,需要遵循PyTorch官方规则使用TORCH_LIBRARY_FRAGMENT。自定义my_add API注册在npu命名空间如下:
TORCH_LIBRARY_FRAGMENT(npu, m) { m.def("my_add(Tensor x, Tensor y) -> Tensor"); }
通过此注册,Python侧可通过torch.ops.npu.my_add调用自定义的API。
- Aten IR实现。
- 按需包含头文件。注意需要包含对应的核函数调用接口声明所在的头文件,aclrtlaunch_{kernel_name}.h(该头文件为Ascend C工程框架自动生成),kernel_name为算子核函数的名称。
- 算子适配,根据Aten IR定义适配算子,包括按需实现输出Tensor申请,workspace申请,调用kernel算子等。torch_npu的算子下发和执行是异步的,通过TASKQUEUE实现。以下示例中通过EXEC_KERNEL_CMD宏封装了算子的ACLRT_LAUNCH_KERNEL方法,将算子执行入队到torch_npu的TASKQUEUE。
#include "utils.h" #include "aclrtlaunch_add_custom.h" at::Tensor run_add_custom(const at::Tensor &x, const at::Tensor &y) { at::Tensor z = at::empty_like(x); uint32_t blockDim = 8; uint32_t totalLength = 1; for (uint32_t size : x.sizes()) { totalLength *= size; } EXEC_KERNEL_CMD(add_custom, blockDim, x, y, z, totalLength); return z; }
- Aten IR注册。
- Aten IR定义。
- 运行自定义算子。
- 设置编译的AI处理器型号,将CMakeLists.txt内的SOC_VERSION修改为所需产品型号。对应代码位置如下:
set(SOC_VERSION "Ascendxxxyy" CACHE STRING "system on chip type")
需将Ascendxxxyy修改为对应产品型号。
SOC_VERSION获取方法如下:
- 非
Atlas A3 训练系列产品/Atlas A3 推理系列产品 :在安装昇腾AI处理器的服务器执行npu-smi info命令进行查询,获取Name信息。实际配置值为AscendName,例如Name取值为xxxyy,实际配置值为Ascendxxxyy。 Atlas A3 训练系列产品/Atlas A3 推理系列产品 :在安装昇腾AI处理器的服务器执行npu-smi info -t board -i id -c chip_id命令进行查询,获取Chip Name和NPU Name信息,实际配置值为Chip Name_NPU Name。例如Chip Name取值为Ascendxxx,NPU Name取值为1234,实际配置值为Ascendxxx_1234。其中:
- id:设备id,通过npu-smi info -l命令查出的NPU ID即为设备id。
- chip_id:芯片id,通过npu-smi info -m命令查出的Chip ID即为芯片id。
- 非
- 运行setup脚本,编译生成whl包。
编译工程通过setuptools为用户封装好编译算子kernel和集成到PyTorch,如果需要更多的编译配置,可按需更改CMakeLists.txt文件。
python setup.py bdist_wheel
- 安装whl包。
cd dist pip install *.whl
- 运行样例。
cd test python test.py
- 设置编译的AI处理器型号,将CMakeLists.txt内的SOC_VERSION修改为所需产品型号。对应代码位置如下:
父主题: kernel直调算子适配