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
相关推荐
中电金信2 小时前
中电金信携手海光推出金融业云原生基础设施联合解决方案
大数据·人工智能
用户5191495848453 小时前
Braintree iOS Drop-in SDK - 一站式支付解决方案
人工智能·aigc
科技小郑3 小时前
吱吱企业即时通讯以安全为基,重塑安全办公新体验
大数据·网络·人工智能·安全·信息与通信·吱吱企业通讯
就叫飞六吧3 小时前
生产环境禁用AI框架工具回调:安全风险与最佳实践
人工智能·安全
胡乱编胡乱赢3 小时前
关于在pycharm终端连接服务器
人工智能·深度学习·pycharm·终端连接服务器
聚客AI3 小时前
⚠️Embedding选型指南:五步搞定数据规模、延迟与精度平衡!
人工智能·llm·掘金·日新计划
h_k100863 小时前
Manus AI与多语言手写识别
人工智能
就是一顿骚操作3 小时前
mcp解读——概述及整体架构
人工智能·大模型
程序猿阿伟3 小时前
《云原生边缘与AI训练场景:2类高频隐蔽Bug的深度排查与架构修复》
人工智能·云原生·bug