【2024第一期CANN训练营】全面掌握Ascend C算子

Sinh算子实现分享

近期参加了华为的CANN训练营,学习到了Ascend C的很多知识,训练营也步入尾声,在这里利用所学知识,分享Sinh的算子实现过程

在这里插入图片描述


1. 准备工作

首先我们需要知道一个算子工程有哪些部分组成
在这里插入图片描述
看上去有很多文件,但其实我们只需要修改其中主要的几个文件,也就是host侧的.h和.cpp文件以及kernal侧的.cpp文件,所以新手小白别被吓到!
在这里插入图片描述

2.具体流程

2.1 生成算子工程

首先我们需要通过.json文件生成算子工程,也就是先把框架搭建起来
根据算子的输入输出及其类型,填写如下json文件,sinh整体较为简单,只有一个输入一个输出
在这里插入图片描述
填写完成后在命令行中输入以下命令,框架就搭好了

./msopgen gen -i /home/HwHiAiUser/SinhCustom/SinhCustom.json -c ai_core-ascend310B -lan cpp -out /home/HwHiAiUser/SinhCustom/

2.2 host侧实现

host侧主要是将一些参数以及切分策略传入到kernal侧
tiling注意一定要32字节对齐!!!
关于数据切分的部分对初学者来说十分复杂,可以参考往期训练营培训视频

const uint32_t BLOCK_DIM = 8;
const uint32_t TILE_NUM = 8;
static ge::graphStatus TilingFunc(gert::TilingContext* context)
{
    SinhCustomTilingData tiling;
    uint32_t totalLength = context->GetInputShape(0)->GetOriginShape().GetShapeSize();
    context->SetBlockDim(BLOCK_DIM);
    tiling.set_totalLength(totalLength);
    tiling.set_tileNum(TILE_NUM);
    tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
    context->GetRawTilingData()->SetDataSize(tiling.GetDataSize());
    size_t *currentWorkspace = context->GetWorkspaceSizes(1);
    currentWorkspace[0] = 0;
    return ge::GRAPH_SUCCESS;
}

填写.h文件

#include "register/tilingdata_base.h"

namespace optiling {
BEGIN_TILING_DATA_DEF(SinhCustomTilingData)
  TILING_DATA_FIELD_DEF(uint32_t, totalLength);
  TILING_DATA_FIELD_DEF(uint32_t, tileNum);
END_TILING_DATA_DEF;

REGISTER_TILING_DATA_CLASS(SinhCustom, SinhCustomTilingData)

2.3 kernal侧实现

kernal侧主要运用host侧的切分策略,并进行compute运算
整个算子分析计算过程分为三个阶段:CopyIn,Compute,CopyOut

CopyIn:搬入x到Local内存
Compute:使用Local内存进行计算
CopyOut:搬运Local计算结果到z

这里主要讲解compute的实现
sinh(x) = (exp(x) - exp(-x)) / 2.0
我们需要将这些矢量运算一步步拆解,运算符的使用可以查阅Ascend官方的api

__aicore__ inline void Compute(int32_t progress)
{
	LocalTensor<half> xLocal = inQueueX.DeQue<half>();
	LocalTensor<half> yLocal = outQueueY.AllocTensor<half>();
	
	Exp(yLocal, xLocal, this->tileLength); //exp(x)
	Muls(xLocal, xLocal, (half)(-1.0), this->tileLength); //-x
	Exp(xLocal, xLocal, this->tileLength); //exp(-x)
	Sub(xLocal, yLocal, xLocal, this->tileLength); //exp(x) - exp(-x)
	Muls(yLocal, xLocal, (half)(0.5), this->tileLength);
	
	outQueueY.EnQue<half>(yLocal);
	inQueueX.FreeTensor(xLocal);
}

3.编译测试

三部曲: 编译、安装run包、测试

bash build.sh  
./build_out/custom_opp_ubuntu_aarch64.run
./test/run.sh

总结

通过本次CANN训练营,全面掌握了Ascend C算子的实现和测试流程,学习氛围十分浓厚,感谢工作人员的精心准备和辛勤付出

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 20:04:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 20:04:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 20:04:04       58 阅读
  4. Python语言-面向对象

    2024-07-16 20:04:04       69 阅读

热门阅读

  1. 通讯录-C/C++

    2024-07-16 20:04:04       19 阅读
  2. Docker 三剑客

    2024-07-16 20:04:04       23 阅读
  3. Spring注解的实现原理【简单实现一个注解】

    2024-07-16 20:04:04       20 阅读
  4. 洛谷 P10119 题解

    2024-07-16 20:04:04       20 阅读
  5. 初识C++

    初识C++

    2024-07-16 20:04:04      18 阅读
  6. 删除文件夹下的文件

    2024-07-16 20:04:04       20 阅读
  7. Vue3.0中实现的动态路由权限控制

    2024-07-16 20:04:04       21 阅读
  8. 魁北克:美食的天堂

    2024-07-16 20:04:04       20 阅读
  9. 计算机视觉(CV)技术的优势和挑战

    2024-07-16 20:04:04       16 阅读
  10. JVM参数调优经验

    2024-07-16 20:04:04       22 阅读