searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

AscendC算子的Pytorch框架集成教程

2024-09-24 10:07:39
108
0

1. 简介

AscendC算子在经过编译后,会生成一个aclnn接口的算子包。本文以一个custom_silu的自定义激活函数算子为例,讲述如何将Pytorch的Aten算子层与aclnn接口绑定,并在Python侧接口成功调用AscendC算子。

2. 安装前置

本文以pytorch的v2.1.0版本为例子。pip安装命令如下。

pip install torch==2.1.0

然后下载华为官方的算子注册仓库,本文是以在op-plugin上修改的方式支持算子。

git clone git@gitee.com:ascend/op-plugin.git

3. 注册算子代码

3.1 算子yaml注册

找到算子注册的yaml目录[op_plugin_functions.yaml]
写入这样的配置。

- func: custom_silu(Tensor self, float k) -> Tensor
    op_api: all_version

func是函数的开头标签,后面写入Pytorch的算子表达式。
表达式格式:函数名字(函数参数) -> 返回类型。
op_api是表示你希望算子放置的命名空间。op_plugin一共定义了两种命名空间:aclop和op_api。op_api使用EXEC_NPU_CMD调用aclnn算子。aclop使用OpCommand调用算子,使用aclopCompileAndExecute执行算子。
自定义算子包,都是基于aclnn封装的,所以使用op_api命名空间。

3.2 cpp代码接口实现

yaml编写之后,torchgen模块会生成算子接口定义的头文件。

namespace op_api {
    at::Tensor custom_silu(const at::Tensor &self, float k);
}

在op_plugin/ops/opapi文件夹下创建一个cpp新文件,例如Custo
SiluKernel.cpp。

#include "op_plugin/AclOpsInterface.h"
#include "op_plugin/OpApiInterface.h"
#include "op_plugin/utils/op_api_common.h"

namespace op_api {
using npu_preparation = at_npu::native::OpPreparation;

at::Tensor custom_silu(const at::Tensor &x, float k)
{
    auto options = x.options();
    at::Tensor result = npu_preparation::apply_tensor_without_format(x.sizes(), options); // 创建输出内存

    // calculate the output result of the NPU
    EXEC_NPU_CMD(aclnnCustomSilu, x, y, result);
    return result;
}
} // namespace op_api

npu_preparation::apply_tensor_without_format是一种快速创建Tensor的封装函数。输出Tensor与输入Tensor的大小和格式保持一致。

aclnnCustomSilu是本文已经实现的aclnn算子包。EXEC_NPU_CMD是封装了动态调用aclnnCustomSiluGetWorkSize的宏,其实现在op-plugin/op_plugin/utils/op_api_common.h。

EXEC_NPU_CMD宏还会自动把输入的Pytorch at::Tensor转换成昇腾的aclTensor,极大地简化了代码。

4. Python接口测试

代码完成后,执行一键编译命令和安装。

bash ci/build.sh --python=3.9 --pytorch=v2.1.0
pip install dist/*.whl

测试你的自定义算子接口。

import torch
import torch_npu

a = torch.rand([1, 100])
b = torch_npu.custom_silu(a, 0.5)

print(b)
0条评论
0 / 1000
c****o
2文章数
0粉丝数
c****o
2 文章 | 0 粉丝
c****o
2文章数
0粉丝数
c****o
2 文章 | 0 粉丝
原创

AscendC算子的Pytorch框架集成教程

2024-09-24 10:07:39
108
0

1. 简介

AscendC算子在经过编译后,会生成一个aclnn接口的算子包。本文以一个custom_silu的自定义激活函数算子为例,讲述如何将Pytorch的Aten算子层与aclnn接口绑定,并在Python侧接口成功调用AscendC算子。

2. 安装前置

本文以pytorch的v2.1.0版本为例子。pip安装命令如下。

pip install torch==2.1.0

然后下载华为官方的算子注册仓库,本文是以在op-plugin上修改的方式支持算子。

git clone git@gitee.com:ascend/op-plugin.git

3. 注册算子代码

3.1 算子yaml注册

找到算子注册的yaml目录[op_plugin_functions.yaml]
写入这样的配置。

- func: custom_silu(Tensor self, float k) -> Tensor
    op_api: all_version

func是函数的开头标签,后面写入Pytorch的算子表达式。
表达式格式:函数名字(函数参数) -> 返回类型。
op_api是表示你希望算子放置的命名空间。op_plugin一共定义了两种命名空间:aclop和op_api。op_api使用EXEC_NPU_CMD调用aclnn算子。aclop使用OpCommand调用算子,使用aclopCompileAndExecute执行算子。
自定义算子包,都是基于aclnn封装的,所以使用op_api命名空间。

3.2 cpp代码接口实现

yaml编写之后,torchgen模块会生成算子接口定义的头文件。

namespace op_api {
    at::Tensor custom_silu(const at::Tensor &self, float k);
}

在op_plugin/ops/opapi文件夹下创建一个cpp新文件,例如Custo
SiluKernel.cpp。

#include "op_plugin/AclOpsInterface.h"
#include "op_plugin/OpApiInterface.h"
#include "op_plugin/utils/op_api_common.h"

namespace op_api {
using npu_preparation = at_npu::native::OpPreparation;

at::Tensor custom_silu(const at::Tensor &x, float k)
{
    auto options = x.options();
    at::Tensor result = npu_preparation::apply_tensor_without_format(x.sizes(), options); // 创建输出内存

    // calculate the output result of the NPU
    EXEC_NPU_CMD(aclnnCustomSilu, x, y, result);
    return result;
}
} // namespace op_api

npu_preparation::apply_tensor_without_format是一种快速创建Tensor的封装函数。输出Tensor与输入Tensor的大小和格式保持一致。

aclnnCustomSilu是本文已经实现的aclnn算子包。EXEC_NPU_CMD是封装了动态调用aclnnCustomSiluGetWorkSize的宏,其实现在op-plugin/op_plugin/utils/op_api_common.h。

EXEC_NPU_CMD宏还会自动把输入的Pytorch at::Tensor转换成昇腾的aclTensor,极大地简化了代码。

4. Python接口测试

代码完成后,执行一键编译命令和安装。

bash ci/build.sh --python=3.9 --pytorch=v2.1.0
pip install dist/*.whl

测试你的自定义算子接口。

import torch
import torch_npu

a = torch.rand([1, 100])
b = torch_npu.custom_silu(a, 0.5)

print(b)
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0