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
相关推荐
财迅通Ai几秒前
物理AI从产业叙事走向基本面重估 以SENASIC琻捷看端侧感算入口的产业价值
人工智能·senasic琻捷
Geek-Chow1 分钟前
MCP 模型上下文协议:九、深入服务器 · 工具、资源与提示
人工智能
Theo_xx8 分钟前
声学感知基础:Day1.常见音频类型(Chirp、FMCW、OFDM)的区别、联系和选择
人工智能·无线感知·声学感知
DisonTangor9 分钟前
Qwen-Drive-1.0:首个统一 3D 感知、视觉问答与运动规划的自动驾驶视觉语言基础模型
人工智能·3d·自动驾驶
XiaoKe202611 分钟前
数海云擎:以内外双向数智化锻造竞争壁垒,跑通销售全链路
大数据·人工智能·科技·软件需求
m0_5873830016 分钟前
全民健身解决方案软件开发:从架构设计到落地实践
人工智能·数据挖掘·系统架构·需求分析
Zzj_tju17 分钟前
小模型指令微调:数据混合、模板与过拟合的最小复现
人工智能·深度学习·机器学习·语言模型
basketball61619 分钟前
AI Infra 推理部署技术总结:2. vLLM 内核——PagedAttention 与调度器原理
android·人工智能·vllm·ai infra
新知图书27 分钟前
第 1 章 大模型时代 《DeepSeek原生应用与智能体开发实践》
人工智能·智能体
伯恩bourne29 分钟前
Qdrant 快速入门 :数据模型介绍
服务器·数据库·人工智能