reduceSum阻塞vector双buffer使用,流水打不起来
收藏回复举报
reduceSum阻塞vector双buffer使用,流水打不起来
t('forum.solved') 已解决
新人帖
发表于2024-11-29 14:09:46
0 查看

​ 正常流水:

使用reducesum异常流水:

代码只有AscendC::ReduceSum(zLocal[i % 16], p1, p3, k); 这块内容不同

#include "kernel_operator.h"
constexpr int32_t BUFFER_NUM = 2; // tensor num for each queue

class KernelMatmulVec {

public:

__aicore__ inline KernelMatmulVec() {}

__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, GM_ADDR z, uint32_t m, uint32_t k, uint32_t smallCoreN, uint32_t bigCoreN, uint32_t bigCoreNum)

{

this->m = m;

this->k = k;

// this->smallCoreN;

// this->bigCoreN;

// this->bigCoreNum;

// this->coreNum;

uint32_t addrOffset = 0;

uint32_t addrOffsetZ = 0;

//判断是否最后一块是有有偏移量

if (AscendC::GetBlockIdx() >= bigCoreNum){

this->n = smallCoreN;

addrOffset = this->n * this->k * AscendC::GetBlockIdx() + (this->k * bigCoreNum *16);

addrOffsetZ = this->n * AscendC::GetBlockIdx() + bigCoreNum *16 ;

}else{

this->n = bigCoreN;

addrOffset = this->n * this->k * AscendC::GetBlockIdx();

addrOffsetZ = this->n * AscendC::GetBlockIdx();

}

//起始地址

xGm.SetGlobalBuffer((__gm__ DTYPE_X *)x , m * k );

yGm.SetGlobalBuffer((__gm__ DTYPE_Y *)y + addrOffset, this->n * k);

zGm.SetGlobalBuffer((__gm__ DTYPE_Z *)z + addrOffsetZ, this->n * 1);

//AscendC::printf("init-ok-----------------------------------------1\n");

//临时计算结果存储,不涉及搬运

pipe.InitBuffer(tmp1, this->m * this->k * sizeof(DTYPE_Z));

pipe.InitBuffer(tmp2, this->m * this->k * sizeof(DTYPE_Z));

pipe.InitBuffer(tmp3, this->n * sizeof(DTYPE_Z));

// pipe.InitBuffer(reduceRes, this->n * sizeof(DTYPE_Z));

//核内单次搬运空间大小

// AscendC::printf("this->n = %d\n",this->n);

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

pipe.InitBuffer(inQueueY, BUFFER_NUM, this->k * sizeof(DTYPE_Y));

pipe.InitBuffer(outQueueZ, BUFFER_NUM, 16 * sizeof(DTYPE_Z));

}

__aicore__ inline void Process()

{

int32_t loopCount = this->n ;

this->vecLeft = inQueueX.AllocTensor<DTYPE_X>();

AscendC::LocalTensor<DTYPE_Z> zLocal;

AscendC::DataCopy(vecLeft, xGm, this->k);

inQueueX.EnQue(vecLeft);

vecLeft = inQueueX.DeQue<DTYPE_X>();

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

if (i % 16 ==0) {

zLocal = outQueueZ.AllocTensor<DTYPE_Z>();

}

AscendC::LocalTensor<DTYPE_Y> yLocal = inQueueY.AllocTensor<DTYPE_Y>();

AscendC::DataCopy(yLocal, yGm[i * this->k], this->k);

inQueueY.EnQue(yLocal);

yLocal = inQueueY.DeQue<DTYPE_Y>();

auto p1 = tmp1.Get<DTYPE_Z>();

auto p2 = tmp2.Get<DTYPE_Z>();

auto p3 = tmp3.Get<DTYPE_Z>();

AscendC::Cast(p1, vecLeft, AscendC::RoundMode::CAST_NONE, this->k);

AscendC::Cast(p2, yLocal, AscendC::RoundMode::CAST_NONE, this->k);

AscendC::Mul(p1, p1, p2, this->k);

AscendC::ReduceSum<DTYPE_Z>(zLocal[i % 16], p1, p3, k);

// AscendC::WholeReduceSum<DTYPE_Z>(zLocal[i % 16], p1, k, 1, 1, 1, 1);

// AscendC::DumpTensor(zLocal, 1, 16);

if ((i+1) % 16 ==0) {

outQueueZ.EnQue<DTYPE_Z>(zLocal);

zLocal = outQueueZ.DeQue<DTYPE_Z>();

AscendC::DataCopy(zGm[i-15], zLocal, 16);

outQueueZ.FreeTensor(zLocal);

}

inQueueY.FreeTensor(yLocal);

}

inQueueX.FreeTensor(vecLeft);

}

private:

AscendC::TPipe pipe;

AscendC::TQue<AscendC::QuePosition::VECIN, BUFFER_NUM> inQueueX;

AscendC::TQue<AscendC::QuePosition::VECIN, BUFFER_NUM> inQueueY;

AscendC::TQue<AscendC::QuePosition::VECOUT, BUFFER_NUM> outQueueZ;

AscendC::GlobalTensor<DTYPE_X> xGm;

AscendC::GlobalTensor<DTYPE_Y> yGm;

AscendC::GlobalTensor<DTYPE_Z> zGm;

AscendC::LocalTensor<DTYPE_X> vecLeft;

// AscendC::LocalTensor<DTYPE_Z> zLocal;

// AscendC::LocalTensor<DTYPE_Z> reduceResult;

uint32_t m;

uint32_t k;

uint32_t smallCoreN;

uint32_t bigCoreN;

uint32_t bigCoreNum;

uint32_t n;

AscendC::TBuf<AscendC::QuePosition::VECCALC> tmp1, tmp2 ,tmp3;

};

extern "C" __global__ __aicore__ void matmul_vec(GM_ADDR x, GM_ADDR y, GM_ADDR z, GM_ADDR workspace, GM_ADDR tiling) {

GET_TILING_DATA(tiling_data, tiling);

// TODO: user kernel impl

//AscendC::printf("matmul_vec-ok-----------------------------------------1\n");

KernelMatmulVec kernel;

kernel.Init(x, y, z, tiling_data.m, tiling_data.k, tiling_data.smallCoreN, tiling_data.bigCoreN, tiling_data.bigCoreNum);

kernel.Process();

}

【昇腾产品型号】:A800T

【版本信息】:

  • CANN版本: 8.0.T16

  • Python版本:Python 3.10.13

  • 系统版本: Linux version 5.15.0-25-generic   (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38)

【开发需求】

  • 功能需求(必填):  模型开发,算子性能测试

本帖最后由 匿名用户2024/11/29 16:00:59 编辑

我要发帖子