/**  * 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.  */ /*! * \file add_example.h * \brief */ #ifndef ADD_EXAMPLE_H #define ADD_EXAMPLE_H #include "kernel_operator.h" #include "kernel_tiling/kernel_tiling.h" #include "add_example_tiling_data.h" #include "add_example_tiling_key.h" namespace NsAddExample { using namespace AscendC; constexpr int32_t BUFFER_NUM = 2; template class AddExample { public: __aicore__ inline AddExample(){}; __aicore__ inline void Init(GM_ADDR x, GM_ADDR y, GM_ADDR z, const AddExampleTilingData* tilingData); __aicore__ inline void Process(); private: __aicore__ inline void CopyIn(int32_t progress); __aicore__ inline void CopyOut(int32_t progress); __aicore__ inline void Compute(const int32_t dataLength); private: TPipe pipe; TQue inputQueueX; TQue inputQueueY; TQue outputQueueZ; GlobalTensor inputGMX; GlobalTensor inputGMY; GlobalTensor outputGMZ; int64_t blockLength_ = 0; int64_t tileNum_ = 0; uint32_t tileLength_ = 0; }; template __aicore__ inline void AddExample::Init(GM_ADDR x, GM_ADDR y, GM_ADDR z, const AddExampleTilingData* tilingData) { blockLength_ = tilingData->totalLength / AscendC::GetBlockNum(); tileNum_ = tilingData->tileNum; tileLength_ = blockLength_ / tileNum_ / BUFFER_NUM; inputGMX.SetGlobalBuffer((__gm__ T*)x + blockLength_ * AscendC::GetBlockIdx(), blockLength_); inputGMY.SetGlobalBuffer((__gm__ T*)y + blockLength_ * AscendC::GetBlockIdx(), blockLength_); outputGMZ.SetGlobalBuffer((__gm__ T*)z + blockLength_ * AscendC::GetBlockIdx(), blockLength_); pipe.InitBuffer(inputQueueX, BUFFER_NUM, tileLength_ * sizeof(T)); pipe.InitBuffer(inputQueueY, BUFFER_NUM, tileLength_ * sizeof(T)); pipe.InitBuffer(outputQueueZ, BUFFER_NUM, tileLength_ * sizeof(T)); } template __aicore__ inline void AddExample::CopyIn(int32_t progress) { AscendC::LocalTensor xLocal = inputQueueX.AllocTensor(); AscendC::LocalTensor yLocal = inputQueueY.AllocTensor(); AscendC::DataCopy(xLocal, inputGMX[progress * tileLength_], tileLength_); AscendC::DataCopy(yLocal, inputGMY[progress * tileLength_], tileLength_); inputQueueX.EnQue(xLocal); inputQueueY.EnQue(yLocal); } template __aicore__ inline void AddExample::CopyOut(int32_t progress) { AscendC::LocalTensor zLocal = outputQueueZ.DeQue(); AscendC::DataCopy(outputGMZ[progress * tileLength_], zLocal, tileLength_); outputQueueZ.FreeTensor(zLocal); } template __aicore__ inline void AddExample::Compute(int32_t progress) { AscendC::LocalTensor xLocal = inputQueueX.DeQue(); AscendC::LocalTensor yLocal = inputQueueY.DeQue(); AscendC::LocalTensor zLocal = outputQueueZ.AllocTensor(); AscendC::Add(zLocal, xLocal, yLocal, tileLength_); outputQueueZ.EnQue(zLocal); inputQueueX.FreeTensor(xLocal); inputQueueY.FreeTensor(yLocal); } template __aicore__ inline void AddExample::Process() { int32_t loopCount = tileNum_ * BUFFER_NUM; for (int32_t i = 0; i < loopCount; i++) { CopyIn(i); Compute(i); CopyOut(i); } } } // namespace NsAddExample #endif // ADD_EXAMPLE_H