Ascend C 自定义算子实现
收藏回复举报
Ascend C 自定义算子实现
新人帖
发表于2024-07-02 17:41:11
0 查看

实现 Element-wise Hyperbolic Sine 函数算子

实现一个动态大小的逐元素 Sinh 函数自定义算子。

Host 侧算子实现

实现 Host 侧分片策略函数

根据文档,选取合适的 BlockTile 常数,实现 TilingFunc 策略。

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->GetInputShape(0)->GetOriginShape().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;
}

给出 SinhCustomTilingData 数据结构定义,用于向算子传递分片信息。

#include "register/tilingdata_base.h"

namespace optiling {
BEGIN_TILING_DATA_DEF(SinhCustomTilingData)
  TILING_DATA_FIELD_DEF(uint32_t, totalLength);
  TILING_DATA_FIELD_DEF(uint32_t, tileNum);
END_TILING_DATA_DEF;

REGISTER_TILING_DATA_CLASS(SinhCustom, SinhCustomTilingData)

Device 侧算子实现

实现初始化与输入输出相关 Boilerplate 函数

结构按图所示: true

为简便起见,本实现仅考虑了 half 半精度类型的数据,未使用类型展开宏。

实现逐元素 Sinh(x) 核心运算功能

根据文档中所描述的算子功能,实现一个由简单算子组成的逐元素 Sinh 操作,使用之前在初始化中进行计算的 Tiling 分片大小定义给出操作长度。

__aicore__ inline void Compute(int32_t progress) {
  // ... input ...
  Duplicate(yLocal, static_cast<half>(0.0f), this->tileLength);
  Exp(xLocal, xLocal, this->tileLength);
  Add(yLocal, yLocal, xLocal, this->tileLength);
  Reciprocal(xLocal, xLocal, this->tileLength);
  Sub(yLocal, yLocal,  xLocal, this->tileLength);
  Muls(yLocal, yLocal, static_cast<half>(0.5f), this->tileLength);
  // ... output & book keeping ...
}

编译、安装、测试自定义算子

编译自定义算子并安装至环境:

# In `SinhCustom/`
bash build.sh
./build_out/custom_opp_ubuntu_aarch64.run

通过框架测试自定义实现:

# In `AclNNInvocation`
bash run.sh

本帖最后由 匿名用户2024/07/02 17:47:17 编辑

我要发帖子