* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <gtest/gtest.h>
#include <mockcpp/mockcpp.hpp>
#define private public
#define protected public
#include "kernel_tpipe_impl.h"
#include <vector>
using namespace AscendC;
using namespace std;
struct PhyTypeParams {
TPosition pos;
Hardware hard;
};
class TEST_GET_PHY_TYPE
: public testing::Test
, public testing::WithParamInterface<PhyTypeParams> {
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(
SET_PHY_TYPE, TEST_GET_PHY_TYPE,
::testing::Values(PhyTypeParams{ TPosition::GM, Hardware::GM }, PhyTypeParams{ TPosition::A1, Hardware::L1 },
PhyTypeParams{ TPosition::A2, Hardware::L0A }, PhyTypeParams{ TPosition::B1, Hardware::L1 },
PhyTypeParams{ TPosition::B2, Hardware::L0B },
#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2002 || __NPU_ARCH__ == 1001)
PhyTypeParams{ TPosition::C1, Hardware::UB }, PhyTypeParams{ TPosition::C2, Hardware::L0C },
PhyTypeParams{ TPosition::CO2, Hardware::UB },
#elif defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2201)
PhyTypeParams{ TPosition::C1, Hardware::L1 }, PhyTypeParams{ TPosition::C2, Hardware::BIAS },
PhyTypeParams{ TPosition::CO2, Hardware::L1 },
#endif
PhyTypeParams{ TPosition::CO1, Hardware::L0C }, PhyTypeParams{ TPosition::VECIN, Hardware::UB },
PhyTypeParams{ TPosition::VECOUT, Hardware::UB },
PhyTypeParams{ TPosition::VECCALC, Hardware::UB }, PhyTypeParams{ TPosition::LCM, Hardware::UB },
PhyTypeParams{ TPosition::SPM, Hardware::L1 }, PhyTypeParams{ TPosition::SHM, Hardware::L1 }));
TEST_P(TEST_GET_PHY_TYPE, GetPhyTypeTest)
{
auto param = GetParam();
auto ret = GetPhyType(param.pos);
EXPECT_EQ(ret, param.hard);
}
struct GetPositionParams {
TPosition pos1;
bool isSrc;
TPosition pos2;
};
class TEST_GET_POSITION
: public testing::Test
, public testing::WithParamInterface<GetPositionParams> {
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(GET_POSITION_TYPE, TEST_GET_POSITION,
::testing::Values(GetPositionParams{ TPosition::A1, true, TPosition::GM },
GetPositionParams{ TPosition::A1, false, TPosition::A1 },
GetPositionParams{ TPosition::A2, true, TPosition::A1 },
GetPositionParams{ TPosition::A2, false, TPosition::A2 },
GetPositionParams{ TPosition::B1, true, TPosition::GM },
GetPositionParams{ TPosition::B1, false, TPosition::B1 },
GetPositionParams{ TPosition::B2, true, TPosition::B1 },
GetPositionParams{ TPosition::B2, false, TPosition::B2 },
GetPositionParams{ TPosition::C1, true, TPosition::GM },
GetPositionParams{ TPosition::C1, false, TPosition::C1 },
GetPositionParams{ TPosition::C2, true, TPosition::C1 },
GetPositionParams{ TPosition::C2, false, TPosition::C2 },
GetPositionParams{ TPosition::CO1, true, TPosition::CO1 },
GetPositionParams{ TPosition::CO1, false, TPosition::CO2 },
GetPositionParams{ TPosition::CO2, true, TPosition::CO2 },
GetPositionParams{ TPosition::CO2, false, TPosition::GM },
GetPositionParams{ TPosition::VECIN, true, TPosition::GM },
GetPositionParams{ TPosition::VECIN, false, TPosition::VECIN },
GetPositionParams{ TPosition::VECOUT, true, TPosition::VECOUT },
GetPositionParams{ TPosition::VECOUT, false, TPosition::GM },
GetPositionParams{ TPosition::SPM, true, TPosition::VECOUT },
GetPositionParams{ TPosition::SPM, false, TPosition::GM },
GetPositionParams{ TPosition::SHM, true, TPosition::VECOUT },
#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2002 || __NPU_ARCH__ == 1001)
GetPositionParams{ TPosition::SHM, false, TPosition::GM }));
#else
GetPositionParams{ TPosition::SHM, false, TPosition::GM },
GetPositionParams{ TPosition::C2PIPE2GM, true, TPosition::B1 },
GetPositionParams{ TPosition::C2PIPE2GM, false, TPosition::C2PIPE2GM }));
#endif
TEST_P(TEST_GET_POSITION, GetPositionTest)
{
auto param = GetParam();
auto ret = GetBufferLogicPos(param.pos1, param.isSrc);
EXPECT_EQ(ret, param.pos2);
}
struct GetQueEvtParams {
Hardware src;
Hardware dst;
bool fwdDirect;
HardEvent evt;
};
class TEST_GET_Q_EVT
: public testing::Test
, public testing::WithParamInterface<GetQueEvtParams> {
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(GET_Q_EVT, TEST_GET_Q_EVT,
::testing::Values(GetQueEvtParams{ Hardware::GM, Hardware::UB, true, HardEvent::MTE2_V },
GetQueEvtParams{ Hardware::GM, Hardware::UB, false, HardEvent::V_MTE2 },
GetQueEvtParams{ Hardware::GM, Hardware::L1, true, HardEvent::MTE2_MTE1 },
GetQueEvtParams{ Hardware::GM, Hardware::L1, false, HardEvent::MTE1_MTE2 },
GetQueEvtParams{ Hardware::GM, Hardware::L0A, true, HardEvent::MTE2_M },
GetQueEvtParams{ Hardware::GM, Hardware::L0A, false, HardEvent::M_MTE2 },
GetQueEvtParams{ Hardware::GM, Hardware::L0B, true, HardEvent::MTE2_M },
GetQueEvtParams{ Hardware::GM, Hardware::L0B, false, HardEvent::M_MTE2 },
GetQueEvtParams{ Hardware::UB, Hardware::GM, true, HardEvent::V_MTE3 },
GetQueEvtParams{ Hardware::UB, Hardware::GM, false, HardEvent::MTE3_V },
GetQueEvtParams{ Hardware::UB, Hardware::L1, true, HardEvent::MTE3_MTE1 },
GetQueEvtParams{ Hardware::UB, Hardware::L1, false, HardEvent::MTE1_MTE3 },
GetQueEvtParams{ Hardware::UB, Hardware::L0C, true, HardEvent::V_V },
GetQueEvtParams{ Hardware::UB, Hardware::L0C, false, HardEvent::MAX },
GetQueEvtParams{ Hardware::L1, Hardware::UB, true, HardEvent::MTE1_V },
GetQueEvtParams{ Hardware::L1, Hardware::UB, false, HardEvent::V_MTE1 },
GetQueEvtParams{ Hardware::L1, Hardware::L0A, true, HardEvent::MTE1_M },
GetQueEvtParams{ Hardware::L1, Hardware::L0A, false, HardEvent::M_MTE1 },
GetQueEvtParams{ Hardware::L1, Hardware::L0B, true, HardEvent::MTE1_M },
GetQueEvtParams{ Hardware::L1, Hardware::L0B, false, HardEvent::M_MTE1 },
GetQueEvtParams{ Hardware::L0A, Hardware::L0C, true, HardEvent::M_V },
GetQueEvtParams{ Hardware::L0A, Hardware::L0C, false, HardEvent::V_M },
GetQueEvtParams{ Hardware::L0C, Hardware::UB, true, HardEvent::M_V },
#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2002 || __NPU_ARCH__ == 1001)
GetQueEvtParams{ Hardware::L0C, Hardware::UB, false, HardEvent::V_M }));
#else
GetQueEvtParams{ Hardware::L0C, Hardware::UB, false, HardEvent::V_M },
GetQueEvtParams{ Hardware::L1, Hardware::FIXBUF, true, HardEvent::MTE1_FIX },
GetQueEvtParams{ Hardware::L1, Hardware::FIXBUF, false,
HardEvent::FIX_MTE1 }));
#endif
TEST_P(TEST_GET_Q_EVT, GetQueEvtTest)
{
auto param = GetParam();
auto ret = GetQueEvt(param.src, param.dst, param.fwdDirect);
EXPECT_EQ(ret, param.evt);
}
class TEST_TPIPE : public testing::Test {
protected:
void SetUp() {}
void TearDown() {}
};
TEST_F(TEST_TPIPE, TPipeConstructionTest)
{
TPipe* pipe = new TPipe();
EXPECT_EQ(pipe->g_tpipeImpl.curBufSize_, 0);
for (int32_t i = 0; i < (int32_t)Hardware::MAX; i++) {
EXPECT_EQ(pipe->g_tpipeImpl.bufPool_[i].maxAddr, 0);
}
for (int32_t i = 0; i < (int32_t)Hardware::MAX; i++) {
EXPECT_TRUE(pipe->g_tpipeImpl.bufPoolBaseAddr_[i].absAddr != nullptr);
EXPECT_EQ(pipe->g_tpipeImpl.bufPoolBaseAddr_[i].phySpace,
ConstDefiner::Instance().bufferInitLen.at(Hardware(i)));
}
delete pipe;
}
TEST_F(TEST_TPIPE, TPipeInitBufferWithTBufTest)
{
TBuf<TPosition::A1> buf;
Hardware hardPos = GetPhyType(TPosition::A1);
uint32_t len = 128;
TPipe pipe;
EXPECT_EQ(pipe.g_tpipeImpl.curBufSize_, 0);
EXPECT_EQ(pipe.g_tpipeImpl.bufPool_[(uint8_t)hardPos].maxAddr, 0);
pipe.InitBuffer(buf, len);
EXPECT_EQ(buf.bufStart, &(pipe.g_tpipeImpl.buf_[0]));
EXPECT_EQ(buf.bufStart->address, 0);
EXPECT_EQ(buf.bufStart->freeBufEvtID, INVALID_TEVENTID);
EXPECT_EQ(buf.bufStart->enQueEvtID, INVALID_TEVENTID);
EXPECT_EQ(buf.bufStart->state, TBufState::FREE);
EXPECT_EQ(buf.bufStart->dataLen, len);
EXPECT_EQ(buf.bufStart->usertag, -1);
EXPECT_EQ(pipe.g_tpipeImpl.curBufSize_, 1);
EXPECT_EQ(pipe.g_tpipeImpl.bufPool_[(uint8_t)hardPos].maxAddr, len);
uint32_t lenGet = 32;
TBufHandle bufHandle = buf.Get(lenGet);
TBufType* bufType = reinterpret_cast<TBufType*>(bufHandle);
EXPECT_EQ(bufType->dataLen, lenGet);
bufHandle = buf.Get();
bufType = reinterpret_cast<TBufType*>(bufHandle);
EXPECT_EQ(bufType->dataLen, len);
LocalTensor<uint32_t> bufTensor = buf.Get<uint32_t>(lenGet);
EXPECT_EQ(bufTensor.GetSize(), lenGet);
EXPECT_EQ(bufTensor.GetLength(), lenGet * sizeof(uint32_t));
bufTensor = buf.Get<uint32_t>();
EXPECT_EQ(bufTensor.GetSize(), len / sizeof(uint32_t));
EXPECT_EQ(bufTensor.GetLength(), len);
}
TEST_F(TEST_TPIPE, TPipeInitBufferWithTQueTest)
{
constexpr TPosition tp[8] = { TPosition::MAX, TPosition::MAX, TPosition::MAX, TPosition::MAX,
TPosition::MAX, TPosition::MAX, TPosition::MAX, TPosition::MAX };
static constexpr AscendC::TQueConfig conf = AscendC::GetTQueConfig(false, false, false, 0, 2, 0, tp, false, false);
TQue<TPosition::VECOUT, 2, &conf> que;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
TPipe pipe;
uint8_t num = 2;
uint32_t len = 128;
pipe.InitBuffer(que, num, len);
EXPECT_EQ(que.head, 0);
EXPECT_EQ(que.tail, 0);
EXPECT_EQ(que.usedCount, 0);
EXPECT_EQ(que.bufStart, &(pipe.g_tpipeImpl.buf_[0]));
EXPECT_EQ(que.bufCursor, 0);
EXPECT_EQ(que.bufUsedCount, 0);
EXPECT_EQ(que.bufNum, 2);
EXPECT_EQ(que.bufLen, num * len);
struct TBufType* buf = que.bufStart;
for (int32_t i = 0; i < num; i++) {
EXPECT_EQ(buf->address, i * len);
EXPECT_EQ(buf->freeBufEvtID, INVALID_TEVENTID);
EXPECT_EQ(buf->enQueEvtID, INVALID_TEVENTID);
EXPECT_EQ(buf->state, TBufState::FREE);
EXPECT_EQ(buf->dataLen, len);
EXPECT_EQ(buf->usertag, -1);
EXPECT_EQ(buf->freeBufEvt, HardEvent::MTE3_V);
buf++;
}
EXPECT_EQ(pipe.g_tpipeImpl.curBufSize_, 2);
EXPECT_EQ(pipe.g_tpipeImpl.bufPool_[(uint8_t)hardPos].maxAddr, num * len);
}
TEST_F(TEST_TPIPE, TPipeReset)
{
TQue<TPosition::VECOUT, 2> que;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
TPipe pipe;
uint8_t num = 2;
uint32_t len = 128;
pipe.InitBuffer(que, num, len);
EXPECT_EQ(pipe.g_tpipeImpl.curBufSize_, 2);
EXPECT_EQ(pipe.g_tpipeImpl.bufPool_[(uint8_t)hardPos].maxAddr, num * len);
pipe.Reset();
EXPECT_EQ(pipe.g_tpipeImpl.curBufSize_, 0);
EXPECT_EQ(pipe.g_tpipeImpl.bufPool_[(uint8_t)hardPos].maxAddr, 0);
}
TEST_F(TEST_TPIPE, TPipeGetAbsAddrWithTbufTest)
{
TPipe pipe;
int32_t offset = 0;
int32_t len = 1024 * 256;
TBuffAddr addr = pipe.GetAbsAddr<TPosition::VECOUT>(offset, len);
Hardware hardPos = GetPhyType(TPosition::VECOUT);
EXPECT_EQ(addr.logicPos, (uint8_t)(TPosition::VECOUT));
EXPECT_EQ(addr.bufferHandle, nullptr);
EXPECT_EQ(addr.bufferAddr, offset);
EXPECT_EQ(addr.dataLen, len);
EXPECT_EQ(addr.absAddr, pipe.g_tpipeImpl.bufPoolBaseAddr_[(uint8_t)hardPos].absAddr + offset);
}
TEST_F(TEST_TPIPE, TPipeGetAbsAddrWithTensorTest)
{
TPipe pipe;
int32_t offset = 0;
int32_t size = 1024 * 64;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
LocalTensor<int32_t> tensor1 = pipe.GetAbsAddr<TPosition::VECOUT, int32_t>(offset, size);
EXPECT_EQ(tensor1.GetPosition(), (uint8_t)(TPosition::VECOUT));
EXPECT_EQ(tensor1.GetBufferHandle(), nullptr);
EXPECT_EQ(tensor1.GetSize(), size);
EXPECT_EQ(tensor1.GetLength(), size * sizeof(int32_t));
EXPECT_EQ(tensor1.GetPhyAddr(), (int32_t*)(pipe.g_tpipeImpl.bufPoolBaseAddr_[(uint8_t)hardPos].absAddr + offset));
}
void TQueMaskTestWrapper()
{
constexpr int32_t depth = 2;
constexpr int32_t defaultMask = 0;
constexpr int32_t nd2NzMask = 1;
constexpr int32_t nz2NdMask = 2;
constexpr int32_t bothMask = 3;
TQue<TPosition::VECOUT, depth> que1;
TQue<TPosition::VECOUT, depth, defaultMask> que2;
TQue<TPosition::VECOUT, depth, nd2NzMask> que3;
TQue<TPosition::VECOUT, depth, nz2NdMask> que4;
TQue<TPosition::VECOUT, depth, bothMask> que5;
}
TEST_F(TEST_TPIPE, TQueMaskTest)
{
MOCKER(TQueMaskTestWrapper).expects(once());
TQueMaskTestWrapper();
EXPECT_NO_THROW(GlobalMockObject::verify());
}
void TQueBindMaskTestWrapper()
{
constexpr int32_t depth = 2;
constexpr int32_t defaultMask = 0;
constexpr int32_t nd2NzMask = 1;
constexpr int32_t nz2NdMask = 2;
constexpr int32_t bothMask = 3;
TQueBind<TPosition::VECOUT, TPosition::A1, depth> que1;
TQueBind<TPosition::VECOUT, TPosition::A1, depth, defaultMask> que2;
TQueBind<TPosition::VECOUT, TPosition::A1, depth, nd2NzMask> que3;
TQueBind<TPosition::VECOUT, TPosition::A1, depth, nz2NdMask> que4;
TQueBind<TPosition::VECOUT, TPosition::A1, depth, bothMask> que5;
}
TEST_F(TEST_TPIPE, TQueBindMaskTest)
{
MOCKER(TQueBindMaskTestWrapper).expects(once());
TQueBindMaskTestWrapper();
EXPECT_NO_THROW(GlobalMockObject::verify());
}
constexpr int32_t A = 9999;
constexpr int32_t R_0 = 0;
constexpr int32_t R_1 = 1;
constexpr int32_t R_2 = 2;
constexpr int32_t R_3 = 3;
#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2002 || __NPU_ARCH__ == 2201 || __NPU_ARCH__ == 3510)
constexpr int32_t R_4 = 4;
constexpr int32_t R_5 = 5;
constexpr int32_t R_6 = 6;
constexpr int32_t R_7 = 7;
#endif
constexpr int32_t M = 9999;
constexpr int32_t F_0 = 0;
constexpr int32_t F_1 = 1;
constexpr int32_t F_2 = 2;
constexpr int32_t F_3 = 3;
struct BufferOperateParams {
vector<int32_t> allocOrFree;
int32_t goldenBufferIdx;
vector<TBufState> goldenBufferState;
vector<int32_t> goldenFreeBufEvtID;
};
class TEST_ALLOC_FREE_BUFFER
: public testing::Test
, public testing::WithParamInterface<BufferOperateParams> {
public:
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(
ALLOC_FREE_BUFFER, TEST_ALLOC_FREE_BUFFER,
::testing::Values(
BufferOperateParams{
{ M }, 0, { TBufState::OCCUPIED, TBufState::FREE, TBufState::FREE, TBufState::FREE }, { -1, -1, -1, -1 } },
BufferOperateParams{ { M, M, M, M },
3,
{ TBufState::OCCUPIED, TBufState::OCCUPIED, TBufState::OCCUPIED, TBufState::OCCUPIED },
{ -1, -1, -1, -1 } },
BufferOperateParams{
{ M, F_0 }, 0, { TBufState::FREE, TBufState::FREE, TBufState::FREE, TBufState::FREE }, { 0, -1, -1, -1 } },
BufferOperateParams{ { M, F_0, M },
1,
{ TBufState::FREE, TBufState::OCCUPIED, TBufState::FREE, TBufState::FREE },
{ 0, -1, -1, -1 } },
BufferOperateParams{ { M, F_0, M, M },
2,
{ TBufState::FREE, TBufState::OCCUPIED, TBufState::OCCUPIED, TBufState::FREE },
{ 0, -1, -1, -1 } },
BufferOperateParams{ { M, M, M, F_1 },
2,
{ TBufState::OCCUPIED, TBufState::FREE, TBufState::OCCUPIED, TBufState::FREE },
{ -1, 0, -1, -1 } },
BufferOperateParams{ { M, M, M, F_1, F_0 },
2,
{ TBufState::FREE, TBufState::FREE, TBufState::OCCUPIED, TBufState::FREE },
{ 1, 0, -1, -1 } },
BufferOperateParams{ { M, M, M, M, F_0 },
3,
{ TBufState::FREE, TBufState::OCCUPIED, TBufState::OCCUPIED, TBufState::OCCUPIED },
{ 0, -1, -1, -1 } },
BufferOperateParams{ { M, M, M, M, F_0, F_1, F_2, F_3 },
3,
{ TBufState::FREE, TBufState::FREE, TBufState::FREE, TBufState::FREE },
{ 0, 1, 2, 3 } }));
TEST_P(TEST_ALLOC_FREE_BUFFER, AllocFreeBufferTest)
{
TPipe pipe;
TQue<TPosition::VECOUT, 2> que;
TBufPool<TPosition::VECCALC> tbufPool;
TBuf<TPosition::VECCALC> tbuf;
int32_t num = 4;
int32_t len = 1024;
uint32_t poolLen = 65536;
pipe.InitBufPool(tbufPool, poolLen);
tbufPool.InitBuffer(que, num, len);
tbufPool.InitBuffer(tbuf, len);
pipe.InitBuffer(que, num, len);
TBufHandle retHandle = nullptr;
auto param = GetParam();
int32_t opTimes = param.allocOrFree.size();
for (int32_t i = 0; i < opTimes; i++) {
if (param.allocOrFree[i] == M) {
retHandle = que.AllocBuffer();
} else {
que.FreeBuffer(reinterpret_cast<TBufHandle>(que.bufStart + param.allocOrFree[i]));
}
}
EXPECT_EQ(reinterpret_cast<TBufHandle>(que.bufStart + param.goldenBufferIdx), retHandle);
for (int32_t i = 0; i < num; i++) {
TBufType* temp = que.bufStart + i;
EXPECT_EQ(temp->state, param.goldenBufferState[i]);
EXPECT_EQ(temp->freeBufEvtID, param.goldenFreeBufEvtID[i]);
}
}
TEST_F(TEST_TPIPE, TQueBuf2TensorTest)
{
TPipe pipe;
TQue<TPosition::VECOUT, 2> que;
int32_t num = 4;
int32_t len = 1024;
pipe.InitBuffer(que, num, len);
TBufType* temp = que.bufStart;
temp->state = TBufState::FREE;
temp->freeBufEvt = HardEvent::V_M;
temp->enQueEvtID = 15;
temp->freeBufEvtID = INVALID_TEVENTID;
temp->address = 0x1234;
temp->dataLen = 4096;
temp->usertag = 7788;
TBufHandle bufHandle = reinterpret_cast<TBufHandle>(temp);
LocalTensor<int32_t> tensor1 = que.Buf2Tensor<int32_t>(bufHandle);
EXPECT_EQ(tensor1.GetBufferHandle(), bufHandle);
EXPECT_EQ(tensor1.GetPosition(), int32_t(TPosition::VECOUT));
EXPECT_EQ(tensor1.GetSize(), 1024);
EXPECT_EQ(tensor1.GetLength(), 4096);
}
TEST_F(TEST_TPIPE, testCustomizeInitBuffer)
{
TPipe pipe;
TQue<TPosition::VECIN, 1> que1;
TQue<TPosition::A1, 1> que2;
TQue<TPosition::A2, 1> que3;
auto addr0 = Std::make_tuple(0, 1024);
auto addr1 = Std::make_tuple(1024, 1024);
auto addr2 = Std::make_tuple(2048, 1024);
auto addr3 = Std::make_tuple(3072, 1024);
auto addr4 = Std::make_tuple(4096, 1024);
auto addr5 = Std::make_tuple(5120, 1024);
pipe.InitBuffer(que1, addr0, addr1, addr2);
pipe.InitBuffer(que2, addr3);
pipe.InitBuffer(que3, addr4, addr5);
TBufHandle handle;
TBufType* buftype;
LocalTensor<uint8_t> tensor;
tensor = que1.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 0);
tensor = que1.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 1024);
tensor = que1.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 2048);
tensor = que2.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 3072);
tensor = que3.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 4096);
tensor = que3.AllocTensor<uint8_t>();
buftype = (TBufType*)tensor.GetBufferHandle();
EXPECT_EQ(tensor.GetSize(), 1024);
EXPECT_EQ(buftype->address, 5120);
}
TEST_F(TEST_TPIPE, TQueSetUserTagTest)
{
TPipe pipe;
TQue<TPosition::VECOUT, 4> que;
int32_t num = 4;
int32_t len = 1024;
pipe.InitBuffer(que, num, len);
vector<LocalTensor<int32_t>> bufHandleVec;
for (int32_t i = 0; i < num; i++) {
LocalTensor<int32_t> tensor = que.Buf2Tensor<int32_t>(que.AllocBuffer());
bufHandleVec.push_back(tensor);
}
vector<TTagType> tagGolden = { 0x1111, 0x2222, 0x3333, 0x4444 };
for (int32_t i = 0; i < num; i++) {
bufHandleVec[i].SetUserTag(tagGolden[i]);
}
for (int32_t i = 0; i < num; i++) {
TBufType* temp = que.bufStart + i;
EXPECT_EQ(temp->usertag, tagGolden[i]);
EXPECT_EQ(bufHandleVec[i].GetUserTag(), tagGolden[i]);
}
}
struct BufferPosParams {
TPosition srcPos;
TPosition dstPos;
Hardware hard;
};
class TEST_GET_BUFFER_POS
: public testing::Test
, public testing::WithParamInterface<BufferPosParams> {
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(GET_BUFFER_POS, TEST_GET_BUFFER_POS,
::testing::Values(BufferPosParams{ TPosition::GM, TPosition::A1, Hardware::L1 },
BufferPosParams{ TPosition::GM, TPosition::B1, Hardware::L1 },
BufferPosParams{ TPosition::GM, TPosition::C1, Hardware::UB },
BufferPosParams{ TPosition::GM, TPosition::VECIN, Hardware::UB },
BufferPosParams{ TPosition::SHM, TPosition::A1, Hardware::L1 },
BufferPosParams{ TPosition::SHM, TPosition::B1, Hardware::L1 },
BufferPosParams{ TPosition::SHM, TPosition::C1, Hardware::UB },
BufferPosParams{ TPosition::SHM, TPosition::VECIN, Hardware::UB },
BufferPosParams{ TPosition::A1, TPosition::A2, Hardware::L0A },
BufferPosParams{ TPosition::B1, TPosition::B2, Hardware::L0B },
BufferPosParams{ TPosition::VECIN, TPosition::VECCALC, Hardware::UB },
BufferPosParams{ TPosition::VECCALC, TPosition::VECOUT, Hardware::UB },
BufferPosParams{ TPosition::VECOUT, TPosition::GM, Hardware::UB },
BufferPosParams{ TPosition::A2, TPosition::CO1, Hardware::L0C },
BufferPosParams{ TPosition::B2, TPosition::CO1, Hardware::L0C },
BufferPosParams{ TPosition::CO2, TPosition::GM, Hardware::UB },
BufferPosParams{ TPosition::VECOUT, TPosition::A1, Hardware::L1 },
BufferPosParams{ TPosition::VECOUT, TPosition::B1, Hardware::L1 },
BufferPosParams{ TPosition::VECOUT, TPosition::C1, Hardware::UB },
BufferPosParams{ TPosition::CO2, TPosition::A1, Hardware::L1 },
BufferPosParams{ TPosition::CO2, TPosition::B1, Hardware::L1 },
BufferPosParams{ TPosition::CO2, TPosition::C1, Hardware::UB },
BufferPosParams{ TPosition::CO2, TPosition::VECIN, Hardware::UB }));
TEST_P(TEST_GET_BUFFER_POS, GetBufferPosTest)
{
auto param = GetParam();
Hardware ret = GetBufferPos(param.srcPos, param.dstPos);
EXPECT_EQ(ret, param.hard);
}
struct BufferLogicPosParams {
TPosition srcPos;
TPosition dstPos;
TPosition logicPos;
};
class TEST_GET_BUFFER_LOGIC_POS
: public testing::Test
, public testing::WithParamInterface<BufferLogicPosParams> {
protected:
void SetUp() {}
void TearDown() {}
};
INSTANTIATE_TEST_CASE_P(
GET_BUFFER_LOGIC_POS, TEST_GET_BUFFER_LOGIC_POS,
::testing::Values(BufferLogicPosParams{ TPosition::GM, TPosition::A1, TPosition::A1 },
BufferLogicPosParams{ TPosition::GM, TPosition::B1, TPosition::B1 },
BufferLogicPosParams{ TPosition::GM, TPosition::C1, TPosition::C1 },
BufferLogicPosParams{ TPosition::GM, TPosition::VECIN, TPosition::VECIN },
BufferLogicPosParams{ TPosition::SHM, TPosition::A1, TPosition::A1 },
BufferLogicPosParams{ TPosition::SHM, TPosition::B1, TPosition::B1 },
BufferLogicPosParams{ TPosition::SHM, TPosition::C1, TPosition::C1 },
BufferLogicPosParams{ TPosition::SHM, TPosition::VECIN, TPosition::VECIN },
BufferLogicPosParams{ TPosition::A1, TPosition::A2, TPosition::A2 },
BufferLogicPosParams{ TPosition::B1, TPosition::B2, TPosition::B2 },
BufferLogicPosParams{ TPosition::VECIN, TPosition::VECCALC, TPosition::VECCALC },
BufferLogicPosParams{ TPosition::VECCALC, TPosition::VECOUT, TPosition::VECOUT },
BufferLogicPosParams{ TPosition::VECOUT, TPosition::GM, TPosition::VECOUT },
BufferLogicPosParams{ TPosition::A2, TPosition::CO1, TPosition::CO1 },
BufferLogicPosParams{ TPosition::B2, TPosition::CO1, TPosition::CO1 },
BufferLogicPosParams{ TPosition::CO1, TPosition::CO2, TPosition::CO1 },
BufferLogicPosParams{ TPosition::CO2, TPosition::GM, TPosition::CO2 },
BufferLogicPosParams{ TPosition::VECOUT, TPosition::A1, TPosition::A1 },
BufferLogicPosParams{ TPosition::VECOUT, TPosition::B1, TPosition::B1 },
BufferLogicPosParams{ TPosition::VECOUT, TPosition::C1, TPosition::C1 },
BufferLogicPosParams{ TPosition::CO2, TPosition::A1, TPosition::A1 },
BufferLogicPosParams{ TPosition::CO2, TPosition::B1, TPosition::B1 },
BufferLogicPosParams{ TPosition::CO2, TPosition::C1, TPosition::C1 },
BufferLogicPosParams{ TPosition::CO2, TPosition::VECIN, TPosition::VECIN }));
TEST_P(TEST_GET_BUFFER_LOGIC_POS, GetBufferLogicPosTest)
{
auto param = GetParam();
TPosition ret = GetPosition(param.srcPos, param.dstPos);
EXPECT_EQ(ret, param.logicPos);
}
class TEST_TBUFPOOL : public testing::Test {
protected:
void SetUp() {}
void TearDown() {}
};
TEST_F(TEST_TBUFPOOL, TpipeInitBufPool)
{
TPipe pipe;
TBufPool<TPosition::VECCALC> tbufPool1, tbufPool2;
TQue<TPosition::VECOUT, 2> que1, que2;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
uint8_t num = 2;
uint32_t len = 128;
uint32_t poolLen = 65536;
pipe.InitBufPool(tbufPool1, poolLen);
pipe.InitBufPool(tbufPool2, poolLen, tbufPool1);
tbufPool1.InitBuffer(que1, num, len);
EXPECT_EQ(tbufPool1.tBufPoolImpl.curBufSize_, 2);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxAddr_, num * len);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxLen_, poolLen);
tbufPool2.InitBuffer(que2, num, len);
EXPECT_EQ(tbufPool2.tBufPoolImpl.curBufSize_, 2);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxAddr_, num * len);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxLen_, poolLen);
EXPECT_EQ(tbufPool1.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(tbufPool2.tBufPoolImpl.startAddr_, 0);
tbufPool1.Reset();
EXPECT_EQ(tbufPool1.tBufPoolImpl.curBufSize_, 0);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxAddr_, 0);
tbufPool2.Reset();
EXPECT_EQ(tbufPool2.tBufPoolImpl.curBufSize_, 0);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxAddr_, 0);
}
TEST_F(TEST_TBUFPOOL, TbufPoolInitBufPool)
{
TPipe pipe;
TBufPool<TPosition::VECCALC> tbufPool1, tbufPool2, tbufPool3;
TQue<TPosition::VECOUT, 2> que1;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
uint8_t num = 2;
uint32_t len = 128;
uint32_t poolLen = 65536;
pipe.InitBufPool(tbufPool1, poolLen * 2);
tbufPool1.InitBuffer(que1, num, len);
tbufPool1.InitBufPool(tbufPool2, poolLen);
tbufPool1.InitBufPool(tbufPool3, poolLen, tbufPool2);
EXPECT_EQ(tbufPool1.tBufPoolImpl.curBufSize_, 2);
EXPECT_EQ(tbufPool1.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxAddr_, num * len + poolLen);
EXPECT_EQ(tbufPool2.tBufPoolImpl.curBufSize_, 0);
EXPECT_EQ(tbufPool2.tBufPoolImpl.startAddr_, num * len);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxAddr_, num * len);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxLen_, poolLen);
EXPECT_EQ(tbufPool3.tBufPoolImpl.curBufSize_, 0);
EXPECT_EQ(tbufPool3.tBufPoolImpl.startAddr_, num * len);
EXPECT_EQ(tbufPool3.tBufPoolImpl.maxAddr_, num * len);
EXPECT_EQ(tbufPool3.tBufPoolImpl.maxLen_, poolLen);
}
TEST_F(TEST_TBUFPOOL, TbufPoolInitBuffer)
{
TPipe pipe;
TBufPool<TPosition::VECCALC> tbufPool;
TQue<TPosition::VECOUT, 2> que;
TBuf<TPosition::VECCALC> tbuf;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
uint8_t num = 2;
uint32_t len = 128;
uint32_t poolLen = 65536;
pipe.InitBufPool(tbufPool, poolLen);
tbufPool.InitBuffer(que, num, len);
tbufPool.InitBuffer(tbuf, len);
EXPECT_EQ(tbufPool.tBufPoolImpl.curBufSize_, 3);
EXPECT_EQ(tbufPool.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(tbufPool.tBufPoolImpl.maxAddr_, 3 * len);
EXPECT_EQ(tbufPool.tBufPoolImpl.maxLen_, poolLen);
}
TEST_F(TEST_TBUFPOOL, TbufPoolInitBufPoolUnalign)
{
TPipe pipe;
TBufPool<TPosition::VECCALC> tbufPool1, tbufPool2, tbufPool3;
TQue<TPosition::VECOUT, 2> que1;
Hardware hardPos = GetPhyType(TPosition::VECOUT);
uint32_t unAligedLen = 65537;
uint32_t unAligedLen2 = 127;
uint32_t aligedLen = 65568;
uint32_t aligedLen2 = 128;
pipe.InitBufPool(tbufPool1, unAligedLen);
tbufPool1.InitBufPool(tbufPool2, unAligedLen2);
EXPECT_EQ(tbufPool1.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxAddr_, aligedLen2);
EXPECT_EQ(tbufPool1.tBufPoolImpl.maxLen_, aligedLen);
EXPECT_EQ(tbufPool2.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxAddr_, 0);
EXPECT_EQ(tbufPool2.tBufPoolImpl.maxLen_, aligedLen2);
}
class MyBufPool {
public:
__aicore__ inline MyBufPool() {
Init();
}
template<class T>
__aicore__ inline bool InitBuffer(T& que, uint8_t num, uint32_t len) {
len = (len + ONE_BLK_SIZE - MIN_BLOCK_LEN) / ONE_BLK_SIZE * ONE_BLK_SIZE;
auto ptr = this->tBufPoolImpl.buf_ + this->tBufPoolImpl.curBufSize_;
auto curPoolAddr = this->tBufPoolImpl.maxAddr_;
que.InitStartBufHandle(reinterpret_cast<TBufHandle>(ptr), num, len);
for (int32_t i = 0; i < num; i++) {
que.InitBufHandle(this, i, reinterpret_cast<TBufHandle>(ptr + i), curPoolAddr + i * len, len);
}
this->tBufPoolImpl.maxAddr_ = curPoolAddr + num * len;
this->tBufPoolImpl.curBufSize_ += num;
return true;
}
template<TPosition bufPos>
__aicore__ inline bool InitBuffer(TBuf<bufPos>& buf, uint32_t len) {
len = (len + ONE_BLK_SIZE - MIN_BLOCK_LEN) / ONE_BLK_SIZE * ONE_BLK_SIZE;
auto ptr = this->tBufPoolImpl.buf_ + this->tBufPoolImpl.curBufSize_;
auto curPoolAddr = this->tBufPoolImpl.maxAddr_;
buf.InitStartBufHandle(reinterpret_cast<TBufHandle>(ptr), 1, len);
buf.InitBufHandle(this, 0, reinterpret_cast<TBufHandle>(ptr), curPoolAddr, len);
this->tBufPoolImpl.maxAddr_ = curPoolAddr + len;
this->tBufPoolImpl.curBufSize_ += 1;
return true;
}
EXTERN_IMPL_BUFPOOL(MyBufPool, TPosition::VECCALC, 16);
};
TEST_F(TEST_TBUFPOOL, MyBufPoolInitBufferCase1) {
TPipe pipe;
TQue<TPosition::VECIN, 1> srcQue0;
MyBufPool myTbufPool;
uint32_t poolLen = 65536 * 3;
uint32_t singleLen = 65536;
pipe.InitBufPool(myTbufPool, poolLen);
myTbufPool.InitBuffer(srcQue0, 1, singleLen);
LocalTensor<half> src0Local = srcQue0.AllocTensor<half>();
srcQue0.FreeTensor(src0Local);
src0Local = srcQue0.AllocTensor<half>();
srcQue0.FreeTensor(src0Local);
EXPECT_EQ(myTbufPool.tBufPoolImpl.curBufSize_, 1);
EXPECT_EQ(myTbufPool.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(myTbufPool.tBufPoolImpl.maxAddr_, singleLen);
}
TEST_F(TEST_TBUFPOOL, MyBufPoolInitBufferCase2) {
TPipe pipe;
TBuf<TPosition::VECIN> srcBuf1;
MyBufPool myTbufPool;
uint32_t poolLen = 65536 * 3;
uint32_t singleLen = 65536 * 2;
pipe.InitBufPool(myTbufPool, poolLen);
myTbufPool.InitBuffer(srcBuf1, singleLen);
EXPECT_EQ(myTbufPool.tBufPoolImpl.curBufSize_, 1);
EXPECT_EQ(myTbufPool.tBufPoolImpl.startAddr_, 0);
EXPECT_EQ(myTbufPool.tBufPoolImpl.maxAddr_, singleLen);
}
TEST_F(TEST_TPIPE, TQueBindEnQueTest)
{
constexpr int32_t depth = 10;
constexpr int32_t len = 1024;
TPipe pipe;
TQueBind<TPosition::GM, TPosition::VECIN, depth> que1;
pipe.InitBuffer(que1, 10, len);
LocalTensor<float> tensor1 = que1.AllocTensor<float>();
LocalTensor<float> tensor2 = que1.AllocTensor<float>();
LocalTensor<float> tensor3 = que1.AllocTensor<float>();
LocalTensor<float> tensor4 = que1.AllocTensor<float>();
LocalTensor<float> tensor5 = que1.AllocTensor<float>();
que1.EnQue<TPosition::GM, TPosition::VECIN>(tensor1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].state, TBufState::ENQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].enQueEvtID, 0);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].freeBufEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].dataLen, tensor1.GetLength());
que1.EnQue<TPosition::VECIN, TPosition::VECOUT>(tensor2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].state, TBufState::ENQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].enQueEvtID, 0);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].freeBufEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].dataLen, tensor2.GetLength());
que1.EnQue<TPosition::VECIN, TPosition::GM>(tensor3);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].state, TBufState::ENQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].enQueEvtID, 0);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].freeBufEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].dataLen, tensor3.GetLength());
que1.EnQue<TPosition::VECIN, TPosition::GM>(tensor4);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].state, TBufState::ENQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].enQueEvtID, 1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].freeBufEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].dataLen, tensor4.GetLength());
que1.EnQue<TPosition::VECIN, TPosition::GM>(tensor5);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].state, TBufState::ENQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].enQueEvtID, 2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].freeBufEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].dataLen, tensor4.GetLength());
auto retTensor1 = que1.DeQue<TPosition::GM, TPosition::VECIN, float>();
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].state, TBufState::DEQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].enQueEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[0].freeBufEvtID, -1);
EXPECT_EQ(retTensor1.GetPhyAddr(), tensor1.GetPhyAddr());
auto retTensor2 = que1.DeQue<TPosition::VECIN, TPosition::VECOUT, float>();
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].state, TBufState::DEQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].enQueEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[1].freeBufEvtID, -1);
EXPECT_EQ(retTensor2.GetPhyAddr(), tensor2.GetPhyAddr());
auto retTensor3 = que1.DeQue<TPosition::VECIN, TPosition::GM, float>();
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].state, TBufState::DEQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].enQueEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[2].freeBufEvtID, -1);
EXPECT_EQ(retTensor3.GetPhyAddr(), tensor3.GetPhyAddr());
auto retTensor4 = que1.DeQue<TPosition::VECIN, TPosition::GM, float>();
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].state, TBufState::DEQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].enQueEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[3].freeBufEvtID, -1);
EXPECT_EQ(retTensor4.GetPhyAddr(), tensor4.GetPhyAddr());
auto retTensor5 = que1.DeQue<TPosition::VECIN, TPosition::GM, float>();
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].state, TBufState::DEQUE);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].freeBufEvt, HardEvent::V_MTE2);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].enQueEvtID, -1);
EXPECT_EQ(pipe.g_tpipeImpl.buf_[4].freeBufEvtID, -1);
EXPECT_EQ(retTensor5.GetPhyAddr(), tensor5.GetPhyAddr());
}
#if defined(__NPU_ARCH__) && (__NPU_ARCH__ == 2002)
extern int32_t logLevel;
struct TQueSyncParams {
int32_t mode;
TEventID id;
std::vector<std::string> golden;
};
class TEST_TQUE_SYNC_PARAMS
: public testing::Test
, public testing::WithParamInterface<TQueSyncParams> {
protected:
void SetUp() {}
void TearDown() {}
void OpenLog()
{
logLevel = 0;
fileName = "tque_sync_test_" + std::to_string(getpid()) + ".txt";
setvbuf(stdout, nullptr, _IONBF, 0);
save_fd = dup(STDOUT_FILENO);
fd = open(fileName.c_str(), (O_RDWR | O_CREAT), 0644);
dup2(fd, STDOUT_FILENO);
}
void CloseLog()
{
logLevel = 3;
close(fd);
dup2(save_fd, STDOUT_FILENO);
}
bool CheckGolden(std::vector<std::string>& goldenVec)
{
std::ifstream resultFile;
std::stringstream streambuffer;
resultFile.open(fileName, std::ios::in);
streambuffer << resultFile.rdbuf();
std::string resultString(streambuffer.str());
for (auto i = 0; i < goldenVec.size(); i++) {
if (resultString.find(goldenVec[i]) == std::string::npos) {
return false;
}
}
return true;
}
void RemoveLogFile()
{
remove(fileName.c_str());
}
private:
std::string fileName;
int save_fd;
int fd;
};
constexpr pipe_t srcPipe[] = {PIPE_MTE2, PIPE_MTE3, PIPE_S, PIPE_V, PIPE_S, PIPE_MTE1};
constexpr pipe_t dstPipe[] = {PIPE_MTE3, PIPE_MTE2, PIPE_MTE3, PIPE_S, PIPE_V, PIPE_M};
INSTANTIATE_TEST_CASE_P(
TQUE_SYNC_PARAMS, TEST_TQUE_SYNC_PARAMS,
::testing::Values(
TQueSyncParams{ 0, 3, { "set_flag(PIPE_MTE2, PIPE_MTE3, 3);" } },
TQueSyncParams{ 1, 3, { "set_flag(PIPE_MTE3, PIPE_MTE2, 3);" } },
TQueSyncParams{ 2, 3, { "wait_flag(PIPE_S, PIPE_MTE3, 3);" } },
TQueSyncParams{ 3, 3, { "wait_flag(PIPE_V, PIPE_S, 3);" } },
TQueSyncParams{ 4, 3, { "set_flag(PIPE_S, PIPE_V, 3);" } },
TQueSyncParams{ 5, 3, { "set_flag(PIPE_MTE1, PIPE_M, 3);" } }
));
TEST_P(TEST_TQUE_SYNC_PARAMS, TQueSyncTest)
{
TPipe pipe;
logLevel = 0;
TQueSyncParams param = GetParam();
OpenLog();
if (param.mode == 0) {
TQueSync<srcPipe[0], dstPipe[0]>().SetFlag(3);
TQueSync<srcPipe[0], dstPipe[0]>().WaitFlag(3);
} else if (param.mode == 1) {
TQueSync<srcPipe[1], dstPipe[1]>().SetFlag(3);
TQueSync<srcPipe[1], dstPipe[1]>().WaitFlag(3);
} else if (param.mode == 2) {
TQueSync<srcPipe[2], dstPipe[2]>().SetFlag(3);
TQueSync<srcPipe[2], dstPipe[2]>().WaitFlag(3);
} else if (param.mode == 3) {
TQueSync<srcPipe[3], dstPipe[3]>().SetFlag(3);
TQueSync<srcPipe[3], dstPipe[3]>().WaitFlag(3);
} else if (param.mode == 4) {
TQueSync<srcPipe[4], dstPipe[4]>().SetFlag(3);
TQueSync<srcPipe[4], dstPipe[4]>().WaitFlag(3);
} else if (param.mode == 5) {
TQueSync<srcPipe[5], dstPipe[5]>().SetFlag(3);
TQueSync<srcPipe[5], dstPipe[5]>().WaitFlag(3);
}
CloseLog();
EXPECT_TRUE(CheckGolden(param.golden));
RemoveLogFile();
}
#endif