华为Ascend C算子开发(中级)考试

weixin_52406641 2024-10-04 09:35:01 阅读 77

华为Ascend C算子开发(中级)考试题

<code> 提示:这个是河北廊坊Ascend C算子开发考试题和答案,仅供参考,因为不确定其他城市的考试题是否也是一样


文章目录

华为Ascend C算子开发(中级)考试题一、op_host文件夹下的sinh_custom_tiling.h文件二、op_host文件夹下的sinh_custom.cpp文件三、op_kernel文件夹下的sinh_custom.cpp文件


一、op_host文件夹下的sinh_custom_tiling.h文件

请添加图片描述

<code>#include "register/tilingdata_base.h"

namespace optiling { -- -->

BEGIN_TILING_DATA_DEF(SinhCustomTilingData)

//考生自行定义 tiling 结构体成员变量

TILING_DATA_FIELD_DEF(uint32_t, totalLength);

TILING_DATA_FIELD_DEF(uint32_t, tileNum);

END_TILING_DATA_DEF;

REGISTER_TILING_DATA_CLASS(SinhCustom, SinhCustomTilingData)

}

二、op_host文件夹下的sinh_custom.cpp文件

请添加图片描述

<code>#include "sinh_custom_tiling.h"

#include "register/op_def_registry.h"

namespace optiling { -- -->

static ge::graphStatus TilingFunc(gert::TilingContext* context)

{

SinhCustomTilingData tiling;

//考生自行填充

const uint32_t BLOCK_DIM = 8;

const uint32_t TILE_NUM = 8;

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;

}

}

namespace ge {

static ge::graphStatus InferShape(gert::InferShapeContext* context)

{

const gert::Shape* x1_shape = context->GetInputShape(0);

gert::Shape* y_shape = context->GetOutputShape(0);

*y_shape = *x1_shape;

return GRAPH_SUCCESS;

}

}

namespace ops {

class SinhCustom : public OpDef {

public:

explicit SinhCustom(const char* name) : OpDef(name)

{

this->Input("x")

.ParamType(REQUIRED)

.DataType({ ge::DT_FLOAT16})

.Format({ ge::FORMAT_ND})

.UnknownShapeFormat({ ge::FORMAT_ND});

this->Output("y")

.ParamType(REQUIRED)

.DataType({ ge::DT_FLOAT16})

.Format({ ge::FORMAT_ND})

.UnknownShapeFormat({ ge::FORMAT_ND});

this->SetInferShape(ge::InferShape);

this->AICore()

.SetTiling(optiling::TilingFunc);

this->AICore().AddConfig("ascend310b");

}

};

OP_ADD(SinhCustom);

}

三、op_kernel文件夹下的sinh_custom.cpp文件

请添加图片描述

<code>#include "kernel_operator.h"

using namespace AscendC;

constexpr int32_t BUFFER_NUM = 2;

class KernelSinh { -- -->

public:

__aicore__ inline KernelSinh() { }

__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, uint32_t totalLength, uint32_t

tileNum)

{

//考生补充初始化代码

ASSERT(GetBlockNum() != 0 && "block dim can not be zero!");

this->blockLength = totalLength / GetBlockNum();

this->tileNum = tileNum;

ASSERT(tileNum != 0 && "tile num can not be zero!");

this->tileLength = this->blockLength / tileNum / BUFFER_NUM;

xGm.SetGlobalBuffer((__gm__ DTYPE_X *)x + this->blockLength * GetBlockIdx(),

this->blockLength);

yGm.SetGlobalBuffer((__gm__ DTYPE_Y *)y + this->blockLength * GetBlockIdx(),

this->blockLength);

pipe.InitBuffer(inQueueX, BUFFER_NUM, this->tileLength * sizeof(DTYPE_X));

pipe.InitBuffer(outQueueY, BUFFER_NUM, this->tileLength * sizeof(DTYPE_Y));

pipe.InitBuffer(tmpBuffer1, this->tileLength * sizeof(DTYPE_X));

pipe.InitBuffer(tmpBuffer2, this->tileLength * sizeof(DTYPE_X));

pipe.InitBuffer(tmpBuffer3, this->tileLength * sizeof(DTYPE_X));

pipe.InitBuffer(tmpBuffer4, this->tileLength * sizeof(DTYPE_X));

}

__aicore__ inline void Process()

{

//考生补充对“loopCount”的定义,注意对 Tiling 的处理

int32_t loopCount = this->tileNum * BUFFER_NUM;

for (int32_t i = 0; i < loopCount; i++) {

CopyIn(i);

Compute(i);

CopyOut(i);

}

}

private:

__aicore__ inline void CopyIn(int32_t progress)

{

//考生补充算子代码

LocalTensor<DTYPE_X> xLocal = inQueueX.AllocTensor<DTYPE_X>();

DataCopy(xLocal, xGm[progress * this->tileLength], this->tileLength);

inQueueX.EnQue(xLocal);

}

__aicore__ inline void Compute(int32_t progress)

{

//考生补充算子计算代码

LocalTensor<DTYPE_X> xLocal = inQueueX.DeQue<DTYPE_X>();

LocalTensor<DTYPE_Y> yLocal = outQueueY.AllocTensor<DTYPE_Y>();

LocalTensor<DTYPE_X> tmpTensor1 = tmpBuffer1.Get<DTYPE_X>();

LocalTensor<DTYPE_X> tmpTensor2 = tmpBuffer2.Get<DTYPE_X>();

LocalTensor<DTYPE_X> tmpTensor3 = tmpBuffer3.Get<DTYPE_X>();

LocalTensor<DTYPE_X> tmpTensor4 = tmpBuffer4.Get<DTYPE_X>();

DTYPE_X inputVal1 = -1;

DTYPE_X inputVal2 = 0.5;

//sinh(x) = (exp(x) - exp(-x)) / 2.0

Muls(tmpTensor1, xLocal, inputVal1, this->tileLength);

Exp(tmpTensor2, tmpTensor1, this->tileLength);

Exp(tmpTensor3, xLocal, this->tileLength);

Sub(tmpTensor4, tmpTensor3, tmpTensor2, this->tileLength);

Muls(yLocal, tmpTensor4, inputVal2, this->tileLength);

outQueueY.EnQue<DTYPE_Y>(yLocal);

inQueueX.FreeTensor(xLocal);

}

__aicore__ inline void CopyOut(int32_t progress)

{

//考生补充算子代码

LocalTensor<DTYPE_Y> yLocal = outQueueY.DeQue<DTYPE_Y>();

DataCopy(yGm[progress * this->tileLength], yLocal, this->tileLength);

outQueueY.FreeTensor(yLocal);

}

private:

TPipe pipe;

//create queue for input, in this case depth is equal to buffer num

TQue<QuePosition::VECIN, BUFFER_NUM> inQueueX;

//create queue for output, in this case depth is equal to buffer num

TQue<QuePosition::VECOUT, BUFFER_NUM> outQueueY;

GlobalTensor<half> xGm;

GlobalTensor<half> yGm;

//考生补充自定义成员变量

TBuf<QuePosition::VECCALC> tmpBuffer1, tmpBuffer2, tmpBuffer3, tmpBuffer4;

uint32_t blockLength;

uint32_t tileNum;

uint32_t tileLength;

};

extern "C" __global__ __aicore__ void sinh_custom(GM_ADDR x, GM_ADDR y, GM_ADDR

workspace, GM_ADDR tiling) {

GET_TILING_DATA(tiling_data, tiling);

KernelSinh op;

//补充 init 和 process 函数调用内容

op.Init(x, y, tiling_data.totalLength, tiling_data.tileNum);

op.Process();

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。