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
相关推荐
小马爱打代码11 小时前
Spring AI:ChatMemory 实现聊天记忆功能
java·人工智能·spring
ziwu11 小时前
【植物识别系统】Python+TensorFlow+Django+人工智能+深度学习+卷积神经网络算法
人工智能·深度学习·图像识别
Al leng11 小时前
机器学习中偏差和方差的通俗理解
人工智能·机器学习
Mxsoft61912 小时前
某次数据解析失败,发现IEC61850版本差异,手动校验报文结构救急!
人工智能
智元视界12 小时前
农业AI化:如何让一台无人机懂得“看天种地”?
大数据·人工智能·prompt·无人机·数字化转型·产业升级
丝斯201112 小时前
AI学习笔记整理(26)—— 计算机视觉之目标追踪‌
人工智能·笔记·学习
gallonyin12 小时前
【AI智能体】打造高内聚的 MCP-Filesystem Server
人工智能·架构·智能体
Deepoch12 小时前
Deepoc-M 破局:半导体研发告别试错内耗
大数据·人工智能·数学建模·半导体·具身模型·deepoc
Debroon12 小时前
Function Call 函数调用高阶方法:从零开始,深入理解 AI 函数调用的核心原理与实战技巧
人工智能
超龄超能程序猿13 小时前
提升文本转SQL(Text-to-SQL)精准度的实践指南
数据库·人工智能·sql