Ascend C算子开发能力认证考试伴侣-昇腾Ascend C编程入门教程

Ascend C算子开发能力认证(中级):是开发者在Ascend C算子设计、实现与框架调用能力的权威认证。通过该认证,您将展示您在深度学习框架中的Ascend C算子开发能力,为业界所认可。

Ascend C算子开发能力认证考试伴侣-昇腾Ascend C编程入门教程,在昇腾社区的地址:https://www.hiascend.com/forum/thread-0239124507827469022-1-1.html

Ascend C算子开发视频学习课程:在线课程详情

Ascend C算子开发配套视频学习课程的资料:

1、在线文档:https://hiascend.com/document/redirect/CannCommunityOpdevAscendC

2、课程示例代码:https://gitee.com/ascend/samples/tree/master/operator/ascendc/0_introduction/1_add_frameworklaunch

3、aclnn练习样例:https://gitee.com/ascend/samples/tree/master/operator/ascendc/0_introduction/1_add_frameworklaunch/AclNNInvocation

4、环境搭建:参考Ascend C环境准备帖进行环境搭建

视频学习课程非常详细,但是有时候静不下心来学,在线文档非常详细,但是内容太多了,看不过来。如果想快速通过Ascend C算子开发能力认证考试,那么还可以看下昇腾社区的这篇文档:昇腾Ascend C编程入门教程。

op_kernel代码学习

以下代码来源于昇腾Ascend C编程入门教程,文件位置:op_kernel/add_custom.cpp

初始化

cpp 复制代码
__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, uint32_t totalLength, uint32_t tileNum, float scalar)
    {
        ASSERT(GetBlockNum() != 0 && "block dim can not be zero!");
        this->blockLength = totalLength / GetBlockNum();
        this->tileNum = tileNum;
        this->scalar = static_cast<half>(scalar);
        ASSERT(tileNum != 0 && "tile num can not be zero!");
        this->tileLength = this->blockLength / tileNum / BUFFER_NUM;
        // get start index for current core, core parallel
        xGm.SetGlobalBuffer((__gm__ half*)x + this->blockLength * get_block_idx(), this->blockLength);
        yGm.SetGlobalBuffer((__gm__ half*)y + this->blockLength * get_block_idx(), this->blockLength);
        // pipe alloc memory to queue, the unit is Bytes
        pipe.InitBuffer(inQueueX, BUFFER_NUM, this->tileLength * sizeof(half));
        pipe.InitBuffer(outQueueY, BUFFER_NUM, this->tileLength * sizeof(half));
    }

Process函数

主要实现三个CopyIn、Compute、CopyOut这三stage。

cpp 复制代码
__aicore__ inline void Process()
    {
        // loop count need to be doubled, due to double buffer
        int32_t loopCount = this->tileNum * BUFFER_NUM;
        // tiling strategy, pipeline parallel
        for (int32_t i = 0; i < loopCount; i++) {
            CopyIn(i);
            Compute(i);
            CopyOut(i);
        }
    }

CopyIn函数

cpp 复制代码
__aicore__ inline void CopyIn(int32_t progress)
    {
        // alloc tensor from queue memory
        LocalTensor<half> xLocal = inQueueX.AllocTensor<half>();
        // copy progress_th tile from global tensor to local tensor
        DataCopy(xLocal, xGm[progress * tileLength], tileLength);
        // enque input tensors to VECIN queue
        inQueueX.EnQue(xLocal);
    }

Compute函数

负责从Queue中取出数据,进行计算,并将结果放入Queue

cpp 复制代码
 __aicore__ inline void Compute(int32_t progress)
    {
        // deque input tensors from VECIN queue
        LocalTensor<half> xLocal = inQueueX.DeQue<half>();
        LocalTensor<half> yLocal = outQueueY.AllocTensor<half>();
        // call LeakyRelu instr for computation
        LeakyRelu(yLocal, xLocal, scalar, tileLength);
        // enque the output tensor to VECOUT queue
        outQueueY.EnQue<half>(yLocal);
        // free input tensors for reuse
        inQueueX.FreeTensor(xLocal);
    }

当然,认证考试可能是其它的算子,需要自己写相关的计算代码部分。

CopyOut函数

负责从Queue中将数据取出,并将数据从Local Memory拷贝到Global Memory。

cpp 复制代码
__aicore__ inline void CopyOut(int32_t progress)
    {
        // deque output tensor from VECOUT queue
        LocalTensor<half> yLocal = outQueueY.DeQue<half>();
        // copy progress_th tile from local tensor to global tensor
        DataCopy(yGm[progress * tileLength], yLocal, tileLength);
        // free output tensor for reuse
        outQueueY.FreeTensor(yLocal);
    }

补充init和process函数调用内容

cpp 复制代码
extern "C" __global__ __aicore__ void leakyrelu_custom(GM_ADDR x, GM_ADDR y, GM_ADDR workspace, GM_ADDR tiling)
{
    GET_TILING_DATA(tilingData, tiling);
    KernelLeakyRelu op;
    op.Init(x, y, tilingData.totalLength, tilingData.tileNum, tilingData.scalar);
    op.Process();
}

自定义成员变量

cpp 复制代码
    uint32_t blockLength;
    uint32_t tileNum;
    uint32_t tileLength;

op_host代码学习

以下代码来自于代码示例:https://gitee.com/ascend/samples/tree/master/operator/ascendc/0_introduction/1_add_frameworklaunch/AddCustom

填充tiling结构体

文件位置:op_host/add_custom.cpp ,以下为AddCustom算子的示例

cpp 复制代码
static ge::graphStatus TilingFunc(gert::TilingContext *context)
{
    TilingData tiling;
    uint32_t totalLength = context->GetInputShape(0)->GetOriginShape().GetShapeSize(); //输入数据长度
    context->SetBlockDim(BLOCK_DIM);  //设置block大小
    tiling.set_totalLength(totalLength);  //设置输入数据长度
    tiling.set_tileNum(TILE_NUM); //设置tiling数量
    tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity()); //将tiling数据保存到buffer中
    context->GetRawTilingData()->SetDataSize(tiling.GetDataSize()); //设置tiling数据大小
    size_t *currentWorkspace = context->GetWorkspaceSizes(1); //获取工作空间大小
    currentWorkspace[0] = 0; //设置工作空间大小
    return ge::GRAPH_SUCCESS; //返回成功
}
} // namespace optiling

自行定义tiling结构体成员变量

文件位置op_host/add_custom_tiling.h ,以下为AddCustom算子的示例

cpp 复制代码
namespace optiling {
BEGIN_TILING_DATA_DEF(TilingData)
TILING_DATA_FIELD_DEF(uint32_t, totalLength); //输入张量长度
TILING_DATA_FIELD_DEF(uint32_t, tileNum); //输入张量分块个数
END_TILING_DATA_DEF;

REGISTER_TILING_DATA_CLASS(AddCustom, TilingData)
} // namespace optiling
相关推荐
用户600071819106 分钟前
【翻译】构建 Claude Code 的经验:我们如何使用 Skills
人工智能
没事别瞎琢磨8 分钟前
五、进程执行——spawn、超时与进程树清理
人工智能·node.js
没事别瞎琢磨11 分钟前
四、命令风险分级与审批策略
人工智能·node.js
阿乔外贸日记17 分钟前
埃塞俄比亚出口全流程注意事项
大数据·人工智能·智能手机·云计算·汽车
程序员cxuan21 分钟前
Agents.md 是什么
人工智能·后端·程序员
人工小情绪23 分钟前
Windows 安装 Codex 桌面版,并用 CC Switch 管理配置
人工智能·windows·codex·cc switch
godspeed_lucip26 分钟前
LLM和Agent——专题6:Multi Agent 入门(5)
人工智能·python
网安情报局26 分钟前
告别排队与高延迟:直连GPT全系列,解锁低门槛、高稳定的AI生产力
人工智能·gpt·api·ai大模型
Hali_Botebie27 分钟前
非共轭先验(Non-conjugate Prior)和共轭先验(Conjugate Prior)
人工智能·机器学习
没事别瞎琢磨36 分钟前
三、配置系统——默认值与解析
人工智能·node.js