首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2025年6月 CANN Ascend C算子开发能力认证(中级)环境(ascend910b)与代码

2025年6月 CANN Ascend C算子开发能力认证(中级)环境(ascend910b)与代码

作者头像
红目香薰
发布2025-07-10 10:57:14
发布2025-07-10 10:57:14
17800
代码可运行
举报
文章被收录于专栏:CSDNToQQCodeCSDNToQQCode
运行总次数:0
代码可运行

环境说明

我这里使用的是华为的ModelArts的环境直接在线安装的各类环境,没有使用线下的板子,如果有线下的板子需要看看那个型号的,我是:ascend910b,上下文需要对照,如果你是ascend310b的自己改一下啊。

心得分享

这里分享一些要注意的点,当然不是全部,有需求可以私聊我。

1、环境踩坑

如果重启后请一定要重新安装一下环境,并再次执行。

source ~/.bashrc

2、加载一个特殊的文件

不要问,一问一个不吱声,运行就行了。

source /home/ma-user/Ascend/ascend-toolkit/set_env.sh

3、修改文件列表

共计修改4个文件:

  1. SigmoidCustom/SigmoidCustom/CMakePresets.json
  2. SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom_tiling.h
  3. SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom.cpp
  4. SigmoidCustom/SigmoidCustom/op_kernel/sigmoid_custom.cpp

看好四个文件啊,一个都别少,少一个都无法得到最终的正确结果。

4、基础代码

基础代码说的是:

  1. SigmoidCustom/SigmoidCustom/op_host/sigmoid_custom_tiling.h
  2. 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、核心代码(密)

这里的核心代码部分我没有开放,毕竟我搞了一个多星期,很难的好呗,大致方向给了,后面需要自己探索哦。

代码语言:javascript
代码运行次数:0
运行
复制
#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/下运行。

chmod +x -R *

总结

以上6个部分的心得分享在你看完所有学习视频后绝对会用得上的,代码逻辑都明白了自己就能写个差不多了,希望这六条能有点价值,如果还搞不定,那就得让我出手了啊。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境说明
  • 心得分享
    • 1、环境踩坑
    • 2、加载一个特殊的文件
    • 3、修改文件列表
    • 4、基础代码
    • 5、核心代码(密)
    • 6、给予权限
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档