TSCM简介
Vector和Cube之间通过队列(Queue)完成任务间通信和同步。TSCM是数据通路的目的地在TSCM Position时,用来管理执行队列相关操作、相关资源的数据结构。TSCM与TQueBind,TQue属于相同类型结构。TSCM定义如下:
template <TPosition pos, int32_t depth, auto mask = 0> using TSCM = TQueBind<pos, TPosition::TSCM, depth, mask>;表 1模板参数介绍
[!NOTE]说明
- TSCM通过using定义TSCM为TQueBind目的地址为TSCM Position时的别名。
- 支持AllocTensor/EnQue/DeQue/FreeTensor接口。必须严格按照AllocTensor->EnQue->DeQue->FreeTensor的操作执行完整的生命周期,且配对使用。
- 但TSCM并不需要支持TQueBind的所有接口。不支持VacantInQue/HasTensorInQue/GetTensorCountInQue/HasIdleBuffer。
- 由于TSCM分配的Buffer中存储着同步事件eventID,且该结构伴随着与Cube类高阶API如(Matmul高阶API,宏函数调用方式)共同使用,故同一个TPosition上TSCM Buffer的数量与硬件的同步事件eventID以及Matmul对象数量有关。TSCM从VECIN发起的Buffer块数量与Matmul对象数量之和最大为10个。不允许申请的TSCM Buffer超出规格限制,超出规格可能会引起未定义行为。
如下是一个简单的使用示例:
TSCM<TPosition::VECIN, 1> tscm; for () { auto scmTensor = tscm.AllocTensor<float>(); // 在搬运数据从UB->TSCM前分配Buffer DataCopy(scmTensor, ubLocal, 1024); // 将UB数据搬运至TSCM,准备用于Matmul计算 tscm.EnQue(scmTensor); //搬运完成在Matmul计算前,EnQue/DeQue LocalTensor<float> scmLocal = tscm.DeQue<float>(); mm.SetTensorA(scmLocal); mm.SetTensorB(gm_b); mm.IterateAll(gm_c); tscm.FreeTensor(scmLocal); // Matmul计算完成后,释放tensor }与高阶API Matmul配合使用,调用示例如下:
{ typedef matmul::MatmulType<AscendC::TPosition::TSCM, CubeFormat::NZ, half, true, LayoutMode::NONE, false, AscendC::TPosition::VECIN> A_TYPE; typedef matmul::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, half> B_TYPE; typedef matmul::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, float> C_TYPE; typedef matmul::MatmulType<AscendC::TPosition::GM, CubeFormat::ND, float> BIAS_TYPE; matmul::Matmul<A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE> mm1; constexpr uint32_t M = 32; constexpr uint32_t N = 32; constexpr uint32_t K = 32; AscendC::GlobalTensor<half> aGlobal; AscendC::GlobalTensor<half> bGlobal; AscendC::GlobalTensor<float> cGlobal; AscendC::GlobalTensor<float> biasGlobal; aGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ half *>(aGM), M * K); bGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ half *>(bGM), K * N); cGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ float *>(cGM), M * N); TCubeTiling tiling; AscendC::TPipe pipe; AscendC::TSCM<AscendC::TPosition::VECIN, 1> scm; AscendC::TQue<AscendC::TPosition::VECIN, 1> qIn; pipe.InitBuffer(scm, 1, M * K * sizeof(half)); pipe.InitBuffer(qIn, 1, M * K * sizeof(half)); REGIST_MATMUL_OBJ(&pipe, workspaceGM, mm1, &tiling); auto scmTensor = scm.AllocTensor<half>(); auto ubTensor = qIn.AllocTensor<half>(); AscendC::Nd2NzParams intriParams; DataCopy(ubTensor, aGlobal, M * K); qIn.EnQue(ubTensor); AscendC::LocalTensor<half> ubLocal = qIn.DeQue<half>(); AscendC::DataCopy(scmTensor, ubLocal, intriParams); scm.EnQue(scmTensor); AscendC::LocalTensor<half> scmLocal = scm.DeQue<half>(); mm1.SetTensorA(scmLocal); mm1.SetTensorB(bGlobal); mm1.IterateAll(cGlobal); scm.FreeTensor(scmLocal); qIn.FreeTensor(ubLocal); }创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考