本贴为个人Ascend C算子开发能力认证考试(中级)答案
认证地址:Ascend C算子开发能力认证考试(中级)
一.考试题目
实现Ascend C算子Sinh,算子命名为SinhCustom,编写其kernel侧代码、host侧代码,并完成aclnn算子调用测试。
相关算法:sinh(x) = (exp(x) - exp(-x)) / 2.0
要求:
4.1 完成Sinh算子kernel侧核函数相关代码补齐。
4.2 完成Sinh算子host侧Tiling结构体成员变量创建,以及Tiling实现函数的补齐。
4.3 要支持Float16类型输入输出。
二.Ascend C算子开发基本知识
算子:函数到函数的映射,常见的算子有微分算子(求导),积分算子(求积分),梯度算子,散度算子,拉普拉斯算子,哈密顿算子等。
华为昇腾为了降低算子开发难度,特意为开发了Ascend c算子,它使用类c语言语法,降低开发门槛。
三.实现Ascend C算子Sinh
3.1 host侧
主要填充代码:
namespace optiling {
const uint32_t BLOCK_DIM = 8;
const uint32_t TILE_NUM = 8;
static ge::graphStatus TilingFunc(gert::TilingContext* context)
{
SinhCustomTilingData tiling;
uint32_t totalLength = context->GetInputTensor(0)->GetShapeSize();
context->SetBlockDim(BLOCK_DIM);
tiling.set_totalLength(totalLength);
tiling.set_tileNum(TILE_NUM);
tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity());
context->GetRawTilingData()->SetDataSize(tiling.GetDataSize());
size_t *currentWorkspace = context->GetWorkspaceSizes(1);
currentWorkspace[0] = 0;
return ge::GRAPH_SUCCESS;
}
}
主要是cpu运行的代码,这个函数可以处理华为Ascend AI处理器中的张量(Tensor)分块(Tiling)相关的操作。这个函数的目的是设置分块的具体参数,并将这些参数保存到上下文中,以供后续的图执行阶段使用。
3.2 kernel侧
分为三步:CopyIn,Compute,CopyOut。
CopyIn:将数据从内存搬到NPU。
Compute:NPU运算。
CopyOUT:将运算好的数据从NPU搬到内存中。
CopyIn
__aicore__ inline void CopyIn(int32_t progress)
{
LocalTensor<half> xLocal = inQueueX.AllocTensor<half>();
DataCopy(xLocal, xGm[progress * this->tileLength ], this->tileLength);
inQueueX.EnQue(xLocal);
}
Compute(核心代码)
__aicore__ inline void Compute(int32_t progress)
{
LocalTensor<half> xLocal = inQueueX.DeQue<half>();
LocalTensor<half> yLocal = inQueueX.DeQue<half>();
LocalTensor<half> zLocal = outQueueY.AllocTensor<half>();
Exp(zLocal, xLocal, this->tileLength);
half a=-1
Muls(yLocal, xLocal, a, this->tileLength);
Exp(yLocal, yLocal, this->tileLength);
Sub(zLocal, zLocal, yLocal, this->tileLength);
half b = 0.5;
Muls(zLocal, zLocal, b, this->tileLength);
outQueueY.EnQue<half>(zLocal);
inQueueX.FreeTensor(xLocal);
}
CopyOut
__aicore__ inline void CopyOut(int32_t progress)
{
LocalTensor<half> zLocal = outQueueY.DeQue<half>();
DataCopy(zGm[progress * this->tileLength], zLocal, this->tileLength);
outQueueY.FreeTensor(zLocal);
}

1070

被折叠的 条评论
为什么被折叠?



