
前言
证书开头,并且我要说明的是我一周多的时间,各种参考,各种学习,各种填坑,终于搞出来了。
可以在证书上看到我是6月5日通过的,但是我开始的时候是在5月27日。

真心的不容易,终于在6月5日当天搞定了AscendC::Div函数的使用,最终通过了考试。
环境说明
我这里使用的是华为的ModelArts的环境直接在线安装的各类环境,没有使用线下的板子,如果有线下的板子需要看看那个型号的,我是:ascend910b,上下文需要对照,如果你是ascend310b的自己改一下啊。
心得分享
这里分享一些要注意的点,当然不是全部,有需求可以私聊我。
1、环境踩坑
如果重启后请一定要重新安装一下环境,并再次执行。
source ~/.bashrc
2、加载一个特殊的文件
不要问,一问一个不吱声,运行就行了。
source /home/ma-user/Ascend/ascend-toolkit/set_env.sh
3、修改文件列表
共计修改4个文件:
- SigmoidCustom/SigmoidCustom/CMakePresets.json
- SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom_tiling.h
- SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom.cpp
- SigmoidCustom/SigmoidCustom/op_kernel/sigmoid_custom.cpp
看好四个文件啊,一个都别少,少一个都无法得到最终的正确结果。
4、基础代码
基础代码说的是:
- SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom_tiling.h
- SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom.cpp
这两个文件的代码,相对好理解一些。
sigmoid_custom_tiling.h添加内容
TILING_DATA_FIELD_DEF(uint32_t, totalLength);
TILING_DATA_FIELD_DEF(uint32_t, tileNum);
sigmoid_custom.cpp添加内容:
const uint32_t BLOCK_DIM = 8;
const uint32_t TILE_NUM = 8;
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;
5、核心代码(密)
这里的核心代码部分我没有开放,毕竟我搞了一个多星期,很难的好呗,大致方向给了,后面需要自己探索哦。
6、给予权限
预先给于所有权限,在SigmoidCustom/SigmoidCustom/下运行。
chmod +x -R *
总结
以上6个部分的心得分享在你看完所有学习视频后绝对会用得上的,代码逻辑都明白了自己就能写个差不多了,希望这六条能有点价值,如果还搞不定,那就得让我出手了啊。
前言
证书开头,并且我要说明的是我一周多的时间,各种参考,各种学习,各种填坑,终于搞出来了。
可以在证书上看到我是6月5日通过的,但是我开始的时候是在5月27日。
真心的不容易,终于在6月5日当天搞定了AscendC::Div函数的使用,最终通过了考试。
环境说明
我这里使用的是华为的ModelArts的环境直接在线安装的各类环境,没有使用线下的板子,如果有线下的板子需要看看那个型号的,我是:ascend910b,上下文需要对照,如果你是ascend310b的自己改一下啊。
心得分享
这里分享一些要注意的点,当然不是全部,有需求可以私聊我。
1、环境踩坑
如果重启后请一定要重新安装一下环境,并再次执行。
2、加载一个特殊的文件
不要问,一问一个不吱声,运行就行了。
3、修改文件列表
共计修改4个文件:
看好四个文件啊,一个都别少,少一个都无法得到最终的正确结果。
4、基础代码
基础代码说的是:
这两个文件的代码,相对好理解一些。
sigmoid_custom_tiling.h添加内容
sigmoid_custom.cpp添加内容:
5、核心代码(密)
这里的核心代码部分我没有开放,毕竟我搞了一个多星期,很难的好呗,大致方向给了,后面需要自己探索哦。
#include "kernel_operator.h" using namespace AscendC; constexpr int32_t BUFFER_NUM = 2; class KernelSigmoid { public: __aicore__ inline KernelSigmoid() {} __aicore__ inline void Init(GM_ADDR x, GM_ADDR y, uint32_t totalLength, uint32_t tileNum) { //考生补充初始化代码 ASSERT(GetBlockNum() != 0 && "block dim can not be zero!"); this->blockLength = totalLength / GetBlockNum(); this->tileNum = tileNum; ASSERT(tileNum != 0 && "tile num can not be zero!"); this->tileLength = this->blockLength / tileNum / BUFFER_NUM; xGm.SetGlobalBuffer((__gm__ DTYPE_X *)x + this->blockLength * GetBlockIdx(), this->blockLength); yGm.SetGlobalBuffer((__gm__ DTYPE_Y *)y + this->blockLength * GetBlockIdx(), this->blockLength); pipe.InitBuffer(inQueueX, BUFFER_NUM, this->tileLength * sizeof(half)); pipe.InitBuffer(outQueueY, BUFFER_NUM, this->tileLength * sizeof(half)); pipe.InitBuffer(tmpBuffer1, this->tileLength * sizeof(half)); pipe.InitBuffer(tmpBuffer2, this->tileLength * sizeof(half)); pipe.InitBuffer(tmpBuffer3, this->tileLength * sizeof(half)); pipe.InitBuffer(tmpBuffer4, this->tileLength * sizeof(half)); } __aicore__ inline void Process() { // 补充对“loopCount”的定义,注意对Tiling的处理 int32_t loopCount = this->blockLength / this->tileLength; for (int32_t i = 0; i < loopCount; i++) { CopyIn(i); Compute(i); CopyOut(i); } } private: __aicore__ inline void CopyIn(int32_t progress) { //考生补充算子代码 LocalTensor<DTYPE_X> xLocal = inQueueX.AllocTensor<DTYPE_X>(); DataCopy(xLocal, xGm[progress * this->tileLength ], this->tileLength); inQueueX.EnQue(xLocal); } __aicore__ inline void Compute(int32_t progress) { //考生补充算子计算代码·核心部分,不开放 // 从输入队列中取出当前块的数据 // 从输出队列分配空间用于存储结果 // 获取临时缓冲区用于中间计算 // 获取临时缓冲区用于存储全1向量 // 初始化全1向量 // 定义sigmoid计算使用的常量 DTYPE_X inputVal1 = -1.0; DTYPE_X inputVal2 = 1.0; // 计算步骤1: x = -x Muls(tmpTensor1, xLocal, inputVal1, this->tileLength); // 计算步骤2: exp(-x) Exp(tmpTensor2, tmpTensor1, this->tileLength); // 计算步骤3: 1 + exp(-x) Adds(tmpTensor3, tmpTensor2, inputVal2, this->tileLength); // 计算步骤4: 1 / (1 + exp(-x)) 得到最终的sigmoid结果 // 将结果放入输出队列 // 释放输入数据占用的空间 inQueueX.FreeTensor(xLocal); } __aicore__ inline void CopyOut(int32_t progress) { // 考生补充算子代码 AscendC::LocalTensor<half> yLocal = outQueueY.DeQue<half>(); DataCopy(yGm[progress * this->tileLength], yLocal, this->tileLength); outQueueY.FreeTensor(yLocal); } private: TPipe pipe; //create queue for input, in this case depth is equal to buffer num TQue<QuePosition::VECIN, BUFFER_NUM> inQueueX; //create queue for output, in this case depth is equal to buffer num TQue<QuePosition::VECOUT, BUFFER_NUM> outQueueY; GlobalTensor<half> xGm; GlobalTensor<half> yGm; //考生补充自定义成员变量 TBuf<QuePosition::VECCALC> tmpBuffer1, tmpBuffer2, tmpBuffer3, tmpBuffer4; uint32_t blockLength; uint32_t tileNum; uint32_t tileLength; }; extern "C" __global__ __aicore__ void sigmoid_custom(GM_ADDR x, GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling) { GET_TILING_DATA(tiling_data, tiling); KernelSigmoid op; //补充init和process函数调用内容 op.Init(x, y, tiling_data.totalLength, tiling_data.tileNum); op.Process(); }6、给予权限
预先给于所有权限,在SigmoidCustom/SigmoidCustom/下运行。
总结
以上6个部分的心得分享在你看完所有学习视频后绝对会用得上的,代码逻辑都明白了自己就能写个差不多了,希望这六条能有点价值,如果还搞不定,那就得让我出手了啊。