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
相关推荐
GuWenyue5 小时前
写Agent还要重复封装工具?一套MCP多服务方案,3个能力让AI自动查地图、读写文件、操控浏览器
人工智能·机器学习·开源
GuWenyue6 小时前
90%AI新手不会调参!LangChain双模型流水线实战,一套代码兼顾严谨+创意
人工智能
光锥智能7 小时前
WAIC亮点|兼具泛化能力与作业效率的极智嘉机器人天团
人工智能·机器人
阳光是sunny7 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
甲维斯7 小时前
Kimi K3 重构10000行单文件屎山代码!
人工智能
阳光是sunny7 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
新知图书8 小时前
11.3 详细实现与核心配置(作业批改智能体开发)
人工智能·agent·ai agent·智能体·扣子
深度研习笔记9 小时前
OpenCV工业视觉实战11|多线程解耦+视频流稳流+推理加速,彻底解决卡顿阻塞,实现毫秒级工业实时检测
人工智能·opencv·计算机视觉
delishcomcn9 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹9 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试