已合并
kirin adv api update #170
乙酸氧铍创建于 1月29日
kirin adv api update #170
已合并
共 37 个文件变更+1-12672
Dimpl/adv_api/detail/activation/geglu/geglu_l300_impl.h+0-102
| @@ -1,102 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file geglu_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace Internal { | ||
| 25 | -constexpr float gegluConstantA = 22.36386; | ||
| 26 | -constexpr float gegluConstantB = -0.071354814; | ||
| 27 | -template <typename T> | ||
| 28 | -__simd_vf__ inline void GeGLUImplVF( | ||
| 29 | - __ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, uint32_t count, const uint16_t repeatTimes) | ||
| 30 | -{ | ||
| 31 | - MicroAPI::RegTensor<half> srcOrigin0; | ||
| 32 | - MicroAPI::RegTensor<half> srcOrigin1; | ||
| 33 | - MicroAPI::RegTensor<float> srcVreg0; | ||
| 34 | - MicroAPI::RegTensor<float> srcVreg1; | ||
| 35 | - MicroAPI::RegTensor<float> tmpReg0; | ||
| 36 | - MicroAPI::RegTensor<float> tmpReg1; | ||
| 37 | - MicroAPI::RegTensor<float> dstVreg; | ||
| 38 | - MicroAPI::MaskReg mask; | ||
| 39 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 40 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 41 | - mask = MicroAPI::UpdateMask<float>(count); | ||
| 42 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 43 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin0, src0 + i * oneRepElm); | ||
| 44 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVreg0, srcOrigin0, mask); | ||
| 45 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin1, src1 + i * oneRepElm); | ||
| 46 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVreg1, srcOrigin1, mask); | ||
| 47 | - } else { | ||
| 48 | - MicroAPI::DataCopy(srcVreg0, src0 + i * oneRepElm); | ||
| 49 | - MicroAPI::DataCopy(srcVreg1, src1 + i * oneRepElm); | ||
| 50 | - } | ||
| 51 | - MicroAPI::Mul(tmpReg0, srcVreg1, srcVreg1, mask); | ||
| 52 | - MicroAPI::Adds(tmpReg0, tmpReg0, gegluConstantA, mask); | ||
| 53 | - MicroAPI::Mul(tmpReg0, tmpReg0, srcVreg1, mask); | ||
| 54 | - MicroAPI::Muls(tmpReg0, tmpReg0, gegluConstantB, mask); | ||
| 55 | - MicroAPI::Exp(tmpReg1, tmpReg0, mask); | ||
| 56 | - MicroAPI::Adds(tmpReg1, tmpReg1, 1.0f, mask); | ||
| 57 | - MicroAPI::Div(tmpReg1, srcVreg1, tmpReg1, mask); | ||
| 58 | - MicroAPI::Mul(dstVreg, srcVreg0, tmpReg1, mask); | ||
| 59 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 60 | - MicroAPI::Cast<half, float, castTraitB32ToB16>((MicroAPI::RegTensor<half>&)dstVreg, dstVreg, mask); | ||
| 61 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 62 | - dst + i * oneRepElm, (MicroAPI::RegTensor<half>&)dstVreg, mask); | ||
| 63 | - } else { | ||
| 64 | - MicroAPI::DataCopy(dst + i * oneRepElm, dstVreg, mask); | ||
| 65 | - } | ||
| 66 | - } | ||
| 67 | -} | ||
| 68 | -} // namespace Internal | ||
| 69 | - | ||
| 70 | -template <typename T, bool isReuseSource = false> | ||
| 71 | -__aicore__ inline void GeGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 72 | - const LocalTensor<T>& srcTensor1, const uint32_t count) | ||
| 73 | -{ | ||
| 74 | - // Only for AI Vector Core. | ||
| 75 | - if ASCEND_IS_AIC { | ||
| 76 | - return; | ||
| 77 | - } | ||
| 78 | - static_assert(SupportType<T, half, float>(), "GeGLU only support half/float data type on current device!"); | ||
| 79 | - ASCENDC_ASSERT((srcTensor0.GetSize() == srcTensor1.GetSize()), | ||
| 80 | - { KERNEL_LOG(KERNEL_ERROR, "Input params.GetSize must be equal with each other!"); }); | ||
| 81 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 82 | - CheckTensorPosition(srcTensor0, "srcTensor0", "VECIN, VECOUT, VECCALC"); | ||
| 83 | - CheckTensorPosition(srcTensor1, "srcTensor1", "VECIN, VECOUT, VECCALC"); | ||
| 84 | - CheckCalCount(count, "count", dstTensor, "dstTensor", "GeGLU"); | ||
| 85 | - CheckCalCount(count, "count", srcTensor0, "srcTensor0", "GeGLU"); | ||
| 86 | - CheckCalCount(count, "count", srcTensor1, "srcTensor1", "GeGLU"); | ||
| 87 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 88 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 89 | - Internal::GeGLUImplVF<T>((__ubuf__ T*)dstTensor.GetPhyAddr(), (__ubuf__ T*)srcTensor0.GetPhyAddr(), | ||
| 90 | - (__ubuf__ T*)srcTensor1.GetPhyAddr(), count, repeatTimes); | ||
| 91 | -} | ||
| 92 | - | ||
| 93 | -template <typename T, bool isReuseSource = false> | ||
| 94 | -__aicore__ inline void GeGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 95 | - const LocalTensor<T>& srcTensor1, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t count) | ||
| 96 | -{ | ||
| 97 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 98 | - GeGLUImpl<T, isReuseSource>(dstTensor, srcTensor0, srcTensor1, count); | ||
| 99 | -} | ||
| 100 | - | ||
| 101 | -} // namespace AscendC | ||
| 102 | - | ||
Dimpl/adv_api/detail/activation/gelu/gelu_l300_impl.h+0-352
| @@ -1,352 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file gelu_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace Internal { | ||
| 25 | - | ||
| 26 | -template <typename T, bool highPrecision> | ||
| 27 | -__simd_vf__ inline void GeluImplVF(__ubuf__ T* dst, __ubuf__ T* src, uint32_t count, const uint16_t repeatTimes) | ||
| 28 | -{ | ||
| 29 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 30 | - constexpr float coefficientsA = 0.044715; | ||
| 31 | - constexpr float coefficientsB = 1.5957691216057308; | ||
| 32 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 33 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 34 | - MicroAPI::RegTensor<T> tmpReg0; | ||
| 35 | - MicroAPI::RegTensor<T> tmpReg1; | ||
| 36 | - MicroAPI::RegTensor<T> tmpReg2; | ||
| 37 | - MicroAPI::RegTensor<T> tmpReg3; | ||
| 38 | - MicroAPI::MaskReg mask; | ||
| 39 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 40 | - mask = MicroAPI::UpdateMask<T>(count); | ||
| 41 | - if constexpr (highPrecision) { | ||
| 42 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 43 | - (MicroAPI::RegTensor<half>&)srcVreg, (__ubuf__ half*)src + i * oneRepElm); | ||
| 44 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVreg, (MicroAPI::RegTensor<half>&)srcVreg, mask); | ||
| 45 | - } else { | ||
| 46 | - MicroAPI::DataCopy(srcVreg, src + i * oneRepElm); | ||
| 47 | - } | ||
| 48 | - // y = (input_x + 0.044715 * input_x ^ 3) * 1.5957691 | ||
| 49 | - MicroAPI::Mul(tmpReg0, srcVreg, srcVreg, mask); | ||
| 50 | - MicroAPI::Mul(tmpReg0, tmpReg0, srcVreg, mask); | ||
| 51 | - MicroAPI::Muls(tmpReg0, tmpReg0, coefficientsA, mask); | ||
| 52 | - MicroAPI::Add(tmpReg0, tmpReg0, srcVreg, mask); | ||
| 53 | - MicroAPI::Muls(tmpReg0, tmpReg0, coefficientsB, mask); | ||
| 54 | - // exp(min(y, 0)) | ||
| 55 | - MicroAPI::Mins(tmpReg1, tmpReg0, 0.0f, mask); | ||
| 56 | - MicroAPI::Exp(tmpReg1, tmpReg1, mask); | ||
| 57 | - // x / (exp^(-abs(y)) + 1) | ||
| 58 | - MicroAPI::Abs(tmpReg2, tmpReg0, mask); | ||
| 59 | - MicroAPI::Muls(tmpReg2, tmpReg2, -1.0f, mask); | ||
| 60 | - MicroAPI::Exp(tmpReg3, tmpReg2, mask); | ||
| 61 | - MicroAPI::Adds(tmpReg3, tmpReg3, 1.0f, mask); | ||
| 62 | - MicroAPI::Div(tmpReg3, srcVreg, tmpReg3, mask); | ||
| 63 | - // x / (exp^(-abs(y)) + 1) * exp(min(y, 0)) | ||
| 64 | - MicroAPI::Mul(dstVreg, tmpReg1, tmpReg3, mask); | ||
| 65 | - if constexpr (highPrecision) { | ||
| 66 | - MicroAPI::Cast<half, float, castTraitB32ToB16>((MicroAPI::RegTensor<half>&)dstVreg, dstVreg, mask); | ||
| 67 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 68 | - (__ubuf__ half*)dst + i * oneRepElm, (MicroAPI::RegTensor<half>&)dstVreg, mask); | ||
| 69 | - } else { | ||
| 70 | - MicroAPI::DataCopy(dst + i * oneRepElm, dstVreg, mask); | ||
| 71 | - } | ||
| 72 | - } | ||
| 73 | -} | ||
| 74 | - | ||
| 75 | -template <typename T> | ||
| 76 | -__simd_callee__ inline void FastGeluCoreAlg(MicroAPI::RegTensor<T>& dstVreg, | ||
| 77 | - MicroAPI::RegTensor<T>& srcVreg, MicroAPI::MaskReg& mask, MicroAPI::RegTensor<T>& stackVreg) | ||
| 78 | -{ | ||
| 79 | - constexpr float coefficients = -1.702f; | ||
| 80 | - constexpr float oneFloatScalar = 1.0f; | ||
| 81 | - MicroAPI::Muls(stackVreg, srcVreg, coefficients, mask); | ||
| 82 | - MicroAPI::Exp(stackVreg, stackVreg, mask); | ||
| 83 | - MicroAPI::Adds(stackVreg, stackVreg, oneFloatScalar, mask); | ||
| 84 | - MicroAPI::Div(dstVreg, srcVreg, stackVreg, mask); | ||
| 85 | -} | ||
| 86 | - | ||
| 87 | -template <typename T = half> | ||
| 88 | -__simd_vf__ inline void FastGeluHighPrecisionAlgVF(__ubuf__ T* dst, __ubuf__ T* src, | ||
| 89 | - const uint32_t dataSize) | ||
| 90 | -{ | ||
| 91 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 92 | - MicroAPI::RegTensor<float> srcVregFloat; | ||
| 93 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 94 | - MicroAPI::RegTensor<float> dstVregFloat; | ||
| 95 | - | ||
| 96 | - constexpr uint32_t stackSize = GetVecLen() / sizeof(float); | ||
| 97 | - uint32_t sreg = dataSize; | ||
| 98 | - | ||
| 99 | - MicroAPI::RegTensor<float> stackVregFloat; | ||
| 100 | - | ||
| 101 | - MicroAPI::MaskReg mask; | ||
| 102 | - | ||
| 103 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(dataSize, stackSize)); | ||
| 104 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 105 | - mask = MicroAPI::UpdateMask<float>(sreg); | ||
| 106 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcVreg, src + i * stackSize); | ||
| 107 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVregFloat, srcVreg, mask); | ||
| 108 | - | ||
| 109 | - FastGeluCoreAlg<float>(dstVregFloat, srcVregFloat, mask, stackVregFloat); | ||
| 110 | - | ||
| 111 | - MicroAPI::Cast<half, float, castTraitB32ToB16>(dstVreg, dstVregFloat, mask); | ||
| 112 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * stackSize, dstVreg, mask); | ||
| 113 | - } | ||
| 114 | -} | ||
| 115 | - | ||
| 116 | -template <typename T = half> | ||
| 117 | -__aicore__ inline void FastGeluHighPrecisionAlg(const LocalTensor<half>& dstLocal, const LocalTensor<half>& srcLocal, | ||
| 118 | - const uint32_t dataSize) | ||
| 119 | -{ | ||
| 120 | - __ubuf__ T* src = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 121 | - __ubuf__ T* dst = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 122 | - | ||
| 123 | - FastGeluHighPrecisionAlgVF<T>(dst, src, dataSize); | ||
| 124 | -} | ||
| 125 | - | ||
| 126 | -template <typename T> | ||
| 127 | -__simd_vf__ inline void FastGeluAlgVF(__ubuf__ T* dst, __ubuf__ T* src, | ||
| 128 | - const uint32_t dataSize) | ||
| 129 | -{ | ||
| 130 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 131 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 132 | - constexpr uint32_t stackSize = GetVecLen() / sizeof(T); | ||
| 133 | - uint32_t sreg = dataSize; | ||
| 134 | - MicroAPI::RegTensor<T> stackVreg; | ||
| 135 | - MicroAPI::MaskReg mask; | ||
| 136 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(dataSize, stackSize)); | ||
| 137 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 138 | - mask = MicroAPI::UpdateMask<T>(sreg); | ||
| 139 | - MicroAPI::DataCopy<T>(srcVreg, src + i * stackSize); | ||
| 140 | - FastGeluCoreAlg<T>(dstVreg, srcVreg, mask, stackVreg); | ||
| 141 | - MicroAPI::DataCopy<T>(dst + i * stackSize, dstVreg, mask); | ||
| 142 | - } | ||
| 143 | -} | ||
| 144 | - | ||
| 145 | -template <typename T> | ||
| 146 | -__aicore__ inline void FastGeluAlg(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 147 | - const uint32_t dataSize) | ||
| 148 | -{ | ||
| 149 | - __ubuf__ T* src = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 150 | - __ubuf__ T* dst = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 151 | - | ||
| 152 | - FastGeluAlgVF<T>(dst, src, dataSize); | ||
| 153 | -} | ||
| 154 | - | ||
| 155 | -template <typename T> | ||
| 156 | -__simd_callee__ inline void FastGeluV2CoreAlg(MicroAPI::RegTensor<T>& dstVreg, | ||
| 157 | - MicroAPI::RegTensor<T>& srcVreg, MicroAPI::MaskReg& mask, MicroAPI::RegTensor<T>& stackVregA, | ||
| 158 | - MicroAPI::RegTensor<T>& stackVregB, MicroAPI::RegTensor<T>& stackVregC) | ||
| 159 | -{ | ||
| 160 | - constexpr float coefficients = 0.000000000001; | ||
| 161 | - constexpr float coefficientsHalf = 0.5; | ||
| 162 | - constexpr float coefficientsA = -0.1444; | ||
| 163 | - constexpr float coefficientsB = -1.769; | ||
| 164 | - constexpr float coefficientsBInv = 1.769; | ||
| 165 | - constexpr float coefficientsC = 0.7071; | ||
| 166 | - constexpr float coefficientsD = 0.5; | ||
| 167 | - MicroAPI::Muls(stackVregA, srcVreg, coefficientsC, mask); | ||
| 168 | - MicroAPI::Abs(stackVregA, stackVregA, mask); | ||
| 169 | - MicroAPI::Mins(stackVregA, stackVregA, coefficientsBInv, mask); | ||
| 170 | - MicroAPI::Adds(stackVregA, stackVregA, coefficientsB, mask); | ||
| 171 | - MicroAPI::Mul(stackVregA, stackVregA, stackVregA, mask); | ||
| 172 | - MicroAPI::Muls(stackVregA, stackVregA, coefficientsA, mask); | ||
| 173 | - MicroAPI::Adds(stackVregA, stackVregA, coefficientsD, mask); | ||
| 174 | - | ||
| 175 | - MicroAPI::Adds(stackVregB, srcVreg, coefficients, mask); | ||
| 176 | - MicroAPI::Abs(stackVregC, stackVregB, mask); | ||
| 177 | - MicroAPI::Div(stackVregB, stackVregB, stackVregC, mask); | ||
| 178 | - | ||
| 179 | - MicroAPI::Mul(stackVregA, stackVregA, stackVregB, mask); | ||
| 180 | - MicroAPI::Adds(stackVregA, stackVregA, coefficientsHalf, mask); | ||
| 181 | - | ||
| 182 | - MicroAPI::Mul(dstVreg, srcVreg, stackVregA, mask); | ||
| 183 | -} | ||
| 184 | - | ||
| 185 | -template <typename T = half> | ||
| 186 | -__simd_vf__ inline void FastGeluV2HighPrecisionAlgVF(__ubuf__ T* dst, __ubuf__ T* src, | ||
| 187 | - const uint32_t dataSize) | ||
| 188 | -{ | ||
| 189 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 190 | - MicroAPI::RegTensor<float> srcVregFloat; | ||
| 191 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 192 | - MicroAPI::RegTensor<float> dstVregFloat; | ||
| 193 | - | ||
| 194 | - constexpr uint32_t stackSize = GetVecLen() / sizeof(float); | ||
| 195 | - uint32_t sreg = dataSize; | ||
| 196 | - | ||
| 197 | - MicroAPI::RegTensor<float> stackVregFloat; | ||
| 198 | - | ||
| 199 | - MicroAPI::MaskReg mask; | ||
| 200 | - | ||
| 201 | - MicroAPI::RegTensor<float> stackVregA; | ||
| 202 | - MicroAPI::RegTensor<float> stackVregB; | ||
| 203 | - MicroAPI::RegTensor<float> stackVregC; | ||
| 204 | - | ||
| 205 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(dataSize, stackSize)); | ||
| 206 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 207 | - mask = MicroAPI::UpdateMask<float>(sreg); | ||
| 208 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcVreg, src + i * stackSize); | ||
| 209 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVregFloat, srcVreg, mask); | ||
| 210 | - | ||
| 211 | - FastGeluV2CoreAlg<float>(dstVregFloat, srcVregFloat, mask, stackVregA, stackVregB, stackVregC); | ||
| 212 | - | ||
| 213 | - MicroAPI::Cast<half, float, castTraitB32ToB16>(dstVreg, dstVregFloat, mask); | ||
| 214 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * stackSize, dstVreg, mask); | ||
| 215 | - } | ||
| 216 | -} | ||
| 217 | - | ||
| 218 | -template <typename T = half> | ||
| 219 | -__aicore__ inline void FastGeluV2HighPrecisionAlg(const LocalTensor<half>& dstLocal, const LocalTensor<half>& srcLocal, | ||
| 220 | - const uint32_t dataSize) | ||
| 221 | -{ | ||
| 222 | - __ubuf__ T* src = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 223 | - __ubuf__ T* dst = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 224 | - | ||
| 225 | - FastGeluV2HighPrecisionAlgVF<T>(dst, src, dataSize); | ||
| 226 | -} | ||
| 227 | - | ||
| 228 | -template <typename T> | ||
| 229 | -__simd_vf__ inline void FastGeluV2AlgVF(__ubuf__ T* dst, __ubuf__ T* src, | ||
| 230 | - const uint32_t dataSize) | ||
| 231 | -{ | ||
| 232 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 233 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 234 | - constexpr uint32_t stackSize = GetVecLen() / sizeof(T); | ||
| 235 | - uint32_t sreg = dataSize; | ||
| 236 | - | ||
| 237 | - MicroAPI::RegTensor<T> stackVregA; | ||
| 238 | - MicroAPI::RegTensor<T> stackVregB; | ||
| 239 | - MicroAPI::RegTensor<T> stackVregC; | ||
| 240 | - MicroAPI::MaskReg mask; | ||
| 241 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(dataSize, stackSize)); | ||
| 242 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 243 | - mask = MicroAPI::UpdateMask<T>(sreg); | ||
| 244 | - MicroAPI::DataCopy<T>(srcVreg, src + i * stackSize); | ||
| 245 | - FastGeluV2CoreAlg<T>(dstVreg, srcVreg, mask, stackVregA, stackVregB, stackVregC); | ||
| 246 | - MicroAPI::DataCopy<T>(dst + i * stackSize, dstVreg, mask); | ||
| 247 | - } | ||
| 248 | -} | ||
| 249 | - | ||
| 250 | -template <typename T> | ||
| 251 | -__aicore__ inline void FastGeluV2Alg(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 252 | - const uint32_t dataSize) | ||
| 253 | -{ | ||
| 254 | - __ubuf__ T* src = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 255 | - __ubuf__ T* dst = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 256 | - | ||
| 257 | - FastGeluV2AlgVF<T>(dst, src, dataSize); | ||
| 258 | -} | ||
| 259 | -} // namespace Internal | ||
| 260 | - | ||
| 261 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 262 | -__aicore__ inline void GeluImpl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, const uint32_t count) | ||
| 263 | -{ | ||
| 264 | - // Only for AI Vector Core. | ||
| 265 | - if ASCEND_IS_AIC { | ||
| 266 | - return; | ||
| 267 | - } | ||
| 268 | - (void)highPerformance; | ||
| 269 | - static_assert(SupportType<T, half, float>(), "Gelu only support half/float data type on current device!"); | ||
| 270 | - CheckTensorPosition(dstLocal, "dstLocal", "VECIN, VECOUT, VECCALC"); | ||
| 271 | - CheckTensorPosition(srcLocal, "srcLocal", "VECIN, VECOUT, VECCALC"); | ||
| 272 | - CheckCalCount(count, "calCount", dstLocal, "dstLocal", "Gelu"); | ||
| 273 | - CheckCalCount(count, "calCount", srcLocal, "srcLocal", "Gelu"); | ||
| 274 | - if constexpr (highPrecision && sizeof(T) == sizeof(half)) { | ||
| 275 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 276 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 277 | - Internal::GeluImplVF<float, true>( | ||
| 278 | - (__ubuf__ float*)dstLocal.GetPhyAddr(), (__ubuf__ float*)srcLocal.GetPhyAddr(), count, repeatTimes); | ||
| 279 | - } else { | ||
| 280 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 281 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 282 | - Internal::GeluImplVF<T, false>( | ||
| 283 | - (__ubuf__ T*)dstLocal.GetPhyAddr(), (__ubuf__ T*)srcLocal.GetPhyAddr(), count, repeatTimes); | ||
| 284 | - } | ||
| 285 | -} | ||
| 286 | - | ||
| 287 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 288 | -__aicore__ inline void GeluImpl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 289 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t count) | ||
| 290 | -{ | ||
| 291 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 292 | - GeluImpl<T, highPrecision, highPerformance>(dstLocal, srcLocal, count); | ||
| 293 | -} | ||
| 294 | - | ||
| 295 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 296 | -__aicore__ inline void FasterGeluImpl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 297 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t dataSize) | ||
| 298 | -{ | ||
| 299 | - (void)sharedTmpBuffer; | ||
| 300 | - (void)highPerformance; | ||
| 301 | - static_assert((SupportType<T, half, float>()), "current data type is not supported on current device!"); | ||
| 302 | - | ||
| 303 | - bool ret = (dataSize <= srcLocal.GetSize()) && (dataSize <= dstLocal.GetSize()) && (dataSize > 0); | ||
| 304 | - ASCENDC_ASSERT( | ||
| 305 | - ret, { KERNEL_LOG(KERNEL_ERROR, "DataSize must bigger than 0 and smaller than or equal to src&dst tensor."); }); | ||
| 306 | - | ||
| 307 | - | ||
| 308 | - if constexpr (highPrecision && (IsSameType<T, half>::value)) { | ||
| 309 | - Internal::FastGeluHighPrecisionAlg(dstLocal, srcLocal, dataSize); | ||
| 310 | - } else { | ||
| 311 | - Internal::FastGeluAlg(dstLocal, srcLocal, dataSize); | ||
| 312 | - } | ||
| 313 | -} | ||
| 314 | - | ||
| 315 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 316 | -__aicore__ inline void FasterGeluImpl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 317 | - const uint32_t dataSize) | ||
| 318 | -{ | ||
| 319 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 320 | - FasterGeluImpl<T, highPrecision, highPerformance>(dstLocal, srcLocal, sharedTmpBuffer, dataSize); | ||
| 321 | -} | ||
| 322 | - | ||
| 323 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 324 | -__aicore__ inline void FasterGeluV2Impl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 325 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t dataSize) | ||
| 326 | -{ | ||
| 327 | - (void)sharedTmpBuffer; | ||
| 328 | - (void)highPerformance; | ||
| 329 | - static_assert((SupportType<T, half, float>()), "current data type is not supported on current device!"); | ||
| 330 | - | ||
| 331 | - bool ret = (dataSize <= srcLocal.GetSize()) && (dataSize <= dstLocal.GetSize()) && (dataSize > 0); | ||
| 332 | - ASCENDC_ASSERT( | ||
| 333 | - ret, { KERNEL_LOG(KERNEL_ERROR, "DataSize must bigger than 0 and smaller than or equal to src&dst tensor."); }); | ||
| 334 | - | ||
| 335 | - | ||
| 336 | - if constexpr (highPrecision && (IsSameType<T, half>::value)) { | ||
| 337 | - Internal::FastGeluV2HighPrecisionAlg(dstLocal, srcLocal, dataSize); | ||
| 338 | - } else { | ||
| 339 | - Internal::FastGeluV2Alg(dstLocal, srcLocal, dataSize); | ||
| 340 | - } | ||
| 341 | -} | ||
| 342 | - | ||
| 343 | -template <typename T, bool highPrecision = false, bool highPerformance = false> | ||
| 344 | -__aicore__ inline void FasterGeluV2Impl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 345 | - const uint32_t dataSize) | ||
| 346 | -{ | ||
| 347 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 348 | - FasterGeluV2Impl<T, highPrecision, highPerformance>(dstLocal, srcLocal, sharedTmpBuffer, dataSize); | ||
| 349 | -} | ||
| 350 | - | ||
| 351 | -} // namespace AscendC | ||
| 352 | - | ||
Dimpl/adv_api/detail/activation/reglu/reglu_l300_impl.h+0-90
| @@ -1,90 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file reglu_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace Internal { | ||
| 25 | -template <typename T> | ||
| 26 | -__simd_vf__ inline void ReGluImplVF( | ||
| 27 | - __ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, uint32_t count, const uint16_t repeatTimes) | ||
| 28 | -{ | ||
| 29 | - MicroAPI::RegTensor<T> srcOrigin0; | ||
| 30 | - MicroAPI::RegTensor<T> srcOrigin1; | ||
| 31 | - MicroAPI::RegTensor<float> srcVreg0; | ||
| 32 | - MicroAPI::RegTensor<float> srcVreg1; | ||
| 33 | - MicroAPI::RegTensor<float> tmpReg0; | ||
| 34 | - MicroAPI::RegTensor<float> dstVreg; | ||
| 35 | - MicroAPI::MaskReg mask; | ||
| 36 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 37 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 38 | - mask = MicroAPI::UpdateMask<float>(count); | ||
| 39 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 40 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin0, src0 + i * oneRepElm); | ||
| 41 | - MicroAPI::Cast<float, T, castTraitB16ToB32>(srcVreg0, srcOrigin0, mask); | ||
| 42 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin1, src1 + i * oneRepElm); | ||
| 43 | - MicroAPI::Cast<float, T, castTraitB16ToB32>(srcVreg1, srcOrigin1, mask); | ||
| 44 | - } else { | ||
| 45 | - MicroAPI::DataCopy(srcVreg0, src0 + i * oneRepElm); | ||
| 46 | - MicroAPI::DataCopy(srcVreg1, src1 + i * oneRepElm); | ||
| 47 | - } | ||
| 48 | - MicroAPI::Maxs(tmpReg0, srcVreg1, 0.0f, mask); | ||
| 49 | - MicroAPI::Mul(dstVreg, srcVreg0, tmpReg0, mask); | ||
| 50 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 51 | - MicroAPI::Cast<T, float, castTraitB32ToB16>((MicroAPI::RegTensor<T>&)dstVreg, dstVreg, mask); | ||
| 52 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 53 | - dst + i * oneRepElm, (MicroAPI::RegTensor<T>&)dstVreg, mask); | ||
| 54 | - } else { | ||
| 55 | - MicroAPI::DataCopy(dst + i * oneRepElm, dstVreg, mask); | ||
| 56 | - } | ||
| 57 | - } | ||
| 58 | -} | ||
| 59 | -} // namespace Internal | ||
| 60 | - | ||
| 61 | -template <typename T, bool isReuseSource = false> | ||
| 62 | -__aicore__ inline void ReGluImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 63 | - const LocalTensor<T>& srcTensor1, const uint32_t count) | ||
| 64 | -{ | ||
| 65 | - // Only for AI Vector Core. | ||
| 66 | - if ASCEND_IS_AIC { | ||
| 67 | - return; | ||
| 68 | - } | ||
| 69 | - static_assert(SupportType<T, half, float, bfloat16_t>(), "ReGlu only support half/float/bfloat16_t data type on current device!"); | ||
| 70 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 71 | - CheckTensorPosition(srcTensor0, "srcTensor0", "VECIN, VECOUT, VECCALC"); | ||
| 72 | - CheckTensorPosition(srcTensor1, "srcTensor1", "VECIN, VECOUT, VECCALC"); | ||
| 73 | - CheckCalCount(count, "count", dstTensor, "dstTensor", "ReGlu"); | ||
| 74 | - CheckCalCount(count, "count", srcTensor0, "srcTensor0", "ReGlu"); | ||
| 75 | - CheckCalCount(count, "count", srcTensor1, "srcTensor1", "ReGlu"); | ||
| 76 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 77 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 78 | - Internal::ReGluImplVF<T>((__ubuf__ T*)dstTensor.GetPhyAddr(), (__ubuf__ T*)srcTensor0.GetPhyAddr(), | ||
| 79 | - (__ubuf__ T*)srcTensor1.GetPhyAddr(), count, repeatTimes); | ||
| 80 | -} | ||
| 81 | - | ||
| 82 | -template <typename T, bool isReuseSource = false> | ||
| 83 | -__aicore__ inline void ReGluImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 84 | - const LocalTensor<T>& srcTensor1, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t count) | ||
| 85 | -{ | ||
| 86 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 87 | - ReGluImpl<T, isReuseSource>(dstTensor, srcTensor0, srcTensor1, count); | ||
| 88 | -} | ||
| 89 | -} // namespace AscendC | ||
| 90 | - | ||
Dimpl/adv_api/detail/activation/sigmoid/sigmoid_l300_impl.h+0-89
| @@ -1,89 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file sigmoid_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace Internal { | ||
| 24 | -/* | ||
| 25 | - * Formula is y= 1 / (1 + exp(-x)) | ||
| 26 | -*/ | ||
| 27 | -template<typename T> | ||
| 28 | -__simd_vf__ inline void SigmoidImplVF(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t count, const uint16_t repeatTimes) | ||
| 29 | -{ | ||
| 30 | - uint32_t sreg = count; | ||
| 31 | - MicroAPI::MaskReg preg; | ||
| 32 | - MicroAPI::RegTensor<T> srcReg; | ||
| 33 | - MicroAPI::RegTensor<float> castReg; | ||
| 34 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 35 | - MicroAPI::RegTensor<float> dstReg; | ||
| 36 | - | ||
| 37 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 38 | - preg = MicroAPI::UpdateMask<float>(sreg); | ||
| 39 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 40 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 41 | - MicroAPI::Cast<float, T, castTraitB16ToB32>(castReg, srcReg, preg); | ||
| 42 | - } else { | ||
| 43 | - MicroAPI::DataCopy(castReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 44 | - } | ||
| 45 | - MicroAPI::Muls(tmpReg, castReg, -1.0f, preg); | ||
| 46 | - MicroAPI::Exp(tmpReg, tmpReg, preg); | ||
| 47 | - | ||
| 48 | - MicroAPI::Adds(tmpReg, tmpReg, 1.0f, preg); | ||
| 49 | - MicroAPI::Duplicate(dstReg, 1.0f, preg); | ||
| 50 | - MicroAPI::Div(dstReg, dstReg, tmpReg, preg); | ||
| 51 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 52 | - MicroAPI::Cast<T, float, castTraitB32ToB16>(srcReg, dstReg, preg); | ||
| 53 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, preg); | ||
| 54 | - } else { | ||
| 55 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, dstReg, preg); | ||
| 56 | - } | ||
| 57 | - } | ||
| 58 | -} | ||
| 59 | -} // namespace Internal | ||
| 60 | - | ||
| 61 | -template<typename T, bool isReuseSource = false> | ||
| 62 | -__aicore__ inline void SigmoidImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 63 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 64 | -{ | ||
| 65 | - // Only for AI Vector Core. | ||
| 66 | - if ASCEND_IS_AIC { | ||
| 67 | - return; | ||
| 68 | - } | ||
| 69 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 70 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Sigmoid"); | ||
| 71 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Sigmoid"); | ||
| 72 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Sigmoid"); | ||
| 73 | - ASCENDC_ASSERT((calCount <= srcTensor.GetSize()), { | ||
| 74 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than srcTensor length %u", calCount, | ||
| 75 | - srcTensor.GetSize()); | ||
| 76 | - }); | ||
| 77 | - ASCENDC_ASSERT((calCount <= dstTensor.GetSize()), { | ||
| 78 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than dstTensor length %u", calCount, | ||
| 79 | - dstTensor.GetSize()); | ||
| 80 | - }); | ||
| 81 | - | ||
| 82 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 83 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 84 | - uint16_t repeatTimes = CeilDivision(calCount, B32_DATA_NUM_PER_REPEAT); | ||
| 85 | - Internal::SigmoidImplVF<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 86 | -} | ||
| 87 | -} // namespace AscendC | ||
| 88 | - | ||
| 89 | - | ||
Dimpl/adv_api/detail/activation/silu/silu_l300_impl.h+0-62
| @@ -1,62 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file silu_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -namespace AscendC { | ||
| 21 | -namespace Internal { | ||
| 22 | -template<typename T> | ||
| 23 | -__simd_vf__ inline void SiluComputeVF(__ubuf__ T* dst, __ubuf__ T* src, uint32_t count, const uint16_t repeatTimes) | ||
| 24 | -{ | ||
| 25 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 26 | - MicroAPI::RegTensor<T> srcVreg; | ||
| 27 | - MicroAPI::RegTensor<T> tmpReg0; | ||
| 28 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 29 | - MicroAPI::MaskReg mask; | ||
| 30 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 31 | - mask = MicroAPI::UpdateMask<T>(count); | ||
| 32 | - MicroAPI::DataCopy(srcVreg, src + i * oneRepElm); | ||
| 33 | - MicroAPI::Muls(tmpReg0, srcVreg, -1.0f, mask); | ||
| 34 | - MicroAPI::Exp(tmpReg0, tmpReg0, mask); | ||
| 35 | - MicroAPI::Adds(tmpReg0, tmpReg0, 1.0f, mask); | ||
| 36 | - MicroAPI::Div(dstVreg, srcVreg, tmpReg0, mask); | ||
| 37 | - MicroAPI::DataCopy(dst + i * oneRepElm, dstVreg, mask); | ||
| 38 | - } | ||
| 39 | -} | ||
| 40 | -} // namespace Internal | ||
| 41 | - | ||
| 42 | -template <typename T, bool isReuseSource = false> | ||
| 43 | -__aicore__ inline void SiluCompute(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 44 | - const uint32_t count) | ||
| 45 | -{ | ||
| 46 | - // Only for AI Vector Core. | ||
| 47 | - if ASCEND_IS_AIC { | ||
| 48 | - return; | ||
| 49 | - } | ||
| 50 | - static_assert(SupportType<T, half, float>(), "Silu only support half/float data type on current device!"); | ||
| 51 | - CheckTensorPosition(dstLocal, "dstLocal", "VECIN, VECOUT, VECCALC"); | ||
| 52 | - CheckTensorPosition(srcLocal, "srcLocal", "VECIN, VECOUT, VECCALC"); | ||
| 53 | - CheckCalCount(count, "count", dstLocal, "dstLocal", "Silu"); | ||
| 54 | - CheckCalCount(count, "count", srcLocal, "srcLocal", "Silu"); | ||
| 55 | - | ||
| 56 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 57 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 58 | - Internal::SiluComputeVF<T>( | ||
| 59 | - (__ubuf__ T*)dstLocal.GetPhyAddr(), (__ubuf__ T*)srcLocal.GetPhyAddr(), count, repeatTimes); | ||
| 60 | -} | ||
| 61 | -} // namespace AscendC | ||
| 62 | - | ||
Dimpl/adv_api/detail/activation/swiglu/swiglu_l300_impl.h+0-113
| @@ -1,113 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file swiglu_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace Internal { | ||
| 25 | -template <typename T> | ||
| 26 | -__simd_vf__ inline void SwiGLUImplVF(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, | ||
| 27 | - const float scalarValue, uint32_t count, const uint16_t repeatTimes) | ||
| 28 | -{ | ||
| 29 | - MicroAPI::RegTensor<float> srcVreg0; | ||
| 30 | - MicroAPI::RegTensor<float> srcVreg1; | ||
| 31 | - MicroAPI::RegTensor<half> srcOrigin0; | ||
| 32 | - MicroAPI::RegTensor<half> srcOrigin1; | ||
| 33 | - MicroAPI::RegTensor<float> tmpReg0; | ||
| 34 | - MicroAPI::RegTensor<float> tmpReg1; | ||
| 35 | - MicroAPI::RegTensor<float> dstVreg; | ||
| 36 | - MicroAPI::MaskReg mask; | ||
| 37 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 38 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 39 | - mask = MicroAPI::UpdateMask<float>(count); | ||
| 40 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 41 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin0, src0 + i * oneRepElm); | ||
| 42 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVreg0, srcOrigin0, mask); | ||
| 43 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin1, src1 + i * oneRepElm); | ||
| 44 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcVreg1, srcOrigin1, mask); | ||
| 45 | - } else { | ||
| 46 | - MicroAPI::DataCopy(srcVreg0, src0 + i * oneRepElm); | ||
| 47 | - MicroAPI::DataCopy(srcVreg1, src1 + i * oneRepElm); | ||
| 48 | - } | ||
| 49 | - MicroAPI::Muls(tmpReg0, srcVreg1, scalarValue, mask); | ||
| 50 | - MicroAPI::Exp(tmpReg1, tmpReg0, mask); | ||
| 51 | - MicroAPI::Adds(tmpReg1, tmpReg1, 1.0f, mask); | ||
| 52 | - MicroAPI::Div(tmpReg1, srcVreg1, tmpReg1, mask); | ||
| 53 | - MicroAPI::Mul(dstVreg, srcVreg0, tmpReg1, mask); | ||
| 54 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 55 | - MicroAPI::Cast<half, float, castTraitB32ToB16>((MicroAPI::RegTensor<half>&)dstVreg, dstVreg, mask); | ||
| 56 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * oneRepElm, (MicroAPI::RegTensor<half>&)dstVreg, mask); | ||
| 57 | - } else { | ||
| 58 | - MicroAPI::DataCopy(dst + i * oneRepElm, dstVreg, mask); | ||
| 59 | - } | ||
| 60 | - } | ||
| 61 | -} | ||
| 62 | -} // namespace Internal | ||
| 63 | - | ||
| 64 | -template <typename T, bool isReuseSource = false> | ||
| 65 | -__aicore__ inline void SwiGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 66 | - const LocalTensor<T>& srcTensor1, const float scalarValue, const uint32_t count) | ||
| 67 | -{ | ||
| 68 | - // Only for AI Vector Core. | ||
| 69 | - if ASCEND_IS_AIC { | ||
| 70 | - return; | ||
| 71 | - } | ||
| 72 | - static_assert(SupportType<T, half, float>(), "SwiGLU only support half/float data type on current device!"); | ||
| 73 | - ASCENDC_ASSERT((srcTensor0.GetSize() == srcTensor1.GetSize()), | ||
| 74 | - { KERNEL_LOG(KERNEL_ERROR, "Input params.GetSize must be equal with each other!"); }); | ||
| 75 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 76 | - CheckTensorPosition(srcTensor0, "srcTensor0", "VECIN, VECOUT, VECCALC"); | ||
| 77 | - CheckTensorPosition(srcTensor1, "srcTensor1", "VECIN, VECOUT, VECCALC"); | ||
| 78 | - CheckCalCount(count, "count", dstTensor, "dstTensor", "SwiGLU"); | ||
| 79 | - CheckCalCount(count, "count", srcTensor0, "srcTensor0", "SwiGLU"); | ||
| 80 | - CheckCalCount(count, "count", srcTensor1, "srcTensor1", "SwiGLU"); | ||
| 81 | - constexpr uint32_t oneRepElm = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 82 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, oneRepElm)); | ||
| 83 | - const float scalar = static_cast<float>(static_cast<float>(-1.0) * static_cast<float>(scalarValue)); | ||
| 84 | - Internal::SwiGLUImplVF<T>((__ubuf__ T*)dstTensor.GetPhyAddr(), (__ubuf__ T*)srcTensor0.GetPhyAddr(), | ||
| 85 | - (__ubuf__ T*)srcTensor1.GetPhyAddr(), scalar, count, repeatTimes); | ||
| 86 | -} | ||
| 87 | - | ||
| 88 | -template <typename T, bool isReuseSource = false> | ||
| 89 | -__aicore__ inline void SwiGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 90 | - const LocalTensor<T>& srcTensor1, const float scalarValue, const LocalTensor<uint8_t>& sharedTmpBuffer, | ||
| 91 | - const uint32_t count) | ||
| 92 | -{ | ||
| 93 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 94 | - SwiGLUImpl<T, isReuseSource>(dstTensor, srcTensor0, srcTensor1, scalarValue, count); | ||
| 95 | -} | ||
| 96 | - | ||
| 97 | -template <typename T, bool isReuseSource = false> | ||
| 98 | -__aicore__ inline void SwiGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 99 | - const LocalTensor<T>& srcTensor1, const float scalarValue, const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 100 | -{ | ||
| 101 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 102 | - SwiGLUImpl<T, isReuseSource>(dstTensor, srcTensor0, srcTensor1, scalarValue, srcTensor0.GetSize()); | ||
| 103 | -} | ||
| 104 | - | ||
| 105 | -template <typename T, bool isReuseSource = false> | ||
| 106 | -__aicore__ inline void SwiGLUImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor0, | ||
| 107 | - const LocalTensor<T>& srcTensor1, const float scalarValue) | ||
| 108 | -{ | ||
| 109 | - SwiGLUImpl<T, isReuseSource>(dstTensor, srcTensor0, srcTensor1, scalarValue, srcTensor0.GetSize()); | ||
| 110 | -} | ||
| 111 | - | ||
| 112 | -} // namespace AscendC | ||
| 113 | - | ||
Dimpl/adv_api/detail/filter/dropout/dropout_l300_impl.h+0-317
| @@ -1,317 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | - | ||
| 12 | -/* ! | ||
| 13 | - * \file dropout_l300_impl.h | ||
| 14 | - * \brief | ||
| 15 | - */ | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace Internal { | ||
| 25 | -__simd_callee__ inline void DropOutBitModeFP32Main(__ubuf__ float* dstUb, __ubuf__ float* srcUb, | ||
| 26 | - __ubuf__ uint8_t* maskUb, MicroAPI::RegTensor<float>& vDivValueReg, uint32_t sreg, uint32_t newRepeatTimes, | ||
| 27 | - uint16_t loopH, uint32_t srcLastAxis, uint32_t maskLastAxis) | ||
| 28 | -{ | ||
| 29 | - constexpr uint32_t unRollConstant = 2; | ||
| 30 | - constexpr uint32_t maskBitToByte = 8; | ||
| 31 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(float); | ||
| 32 | - constexpr uint32_t selOffset = repeatElm / maskBitToByte * unRollConstant / (sizeof(float) / sizeof(uint8_t)); | ||
| 33 | - MicroAPI::RegTensor<float> src0Reg; | ||
| 34 | - MicroAPI::RegTensor<float> src1Reg; | ||
| 35 | - MicroAPI::RegTensor<float> scalarReg; | ||
| 36 | - MicroAPI::RegTensor<float> dst0Reg; | ||
| 37 | - MicroAPI::RegTensor<float> dst1Reg; | ||
| 38 | - MicroAPI::MaskReg maskReg; | ||
| 39 | - MicroAPI::MaskReg selMask0; | ||
| 40 | - MicroAPI::MaskReg selMask1; | ||
| 41 | - MicroAPI::MaskReg tmpMask0; | ||
| 42 | - MicroAPI::MaskReg tmpMask1 = MicroAPI::CreateMask<uint8_t, MicroAPI::MaskPattern::ALL>(); | ||
| 43 | - MicroAPI::Duplicate(scalarReg, (const float&)0); | ||
| 44 | - for (uint16_t i = 0; i < static_cast<uint16_t>(newRepeatTimes); ++i) { | ||
| 45 | - MicroAPI::DataCopy<uint32_t, MicroAPI::MaskDist::DIST_US>( | ||
| 46 | - tmpMask0, (__ubuf__ uint32_t*)maskUb + loopH * (maskLastAxis >> 2) + i * selOffset); | ||
| 47 | - MicroAPI::MaskInterleave<uint16_t>(selMask0, selMask1, tmpMask0, tmpMask1); | ||
| 48 | - maskReg = MicroAPI::UpdateMask<float>(sreg); | ||
| 49 | - MicroAPI::DataCopy<float>(src0Reg, srcUb + loopH * srcLastAxis + i * unRollConstant * repeatElm); | ||
| 50 | - MicroAPI::Select(dst0Reg, src0Reg, scalarReg, selMask0); | ||
| 51 | - MicroAPI::Mul(dst0Reg, dst0Reg, vDivValueReg, selMask0); | ||
| 52 | - MicroAPI::DataCopy<float>(dstUb + loopH * srcLastAxis + i * unRollConstant * repeatElm, dst0Reg, maskReg); | ||
| 53 | - maskReg = MicroAPI::UpdateMask<float>(sreg); | ||
| 54 | - MicroAPI::DataCopy<float>(src1Reg, srcUb + loopH * srcLastAxis + (i * unRollConstant + 1) * repeatElm); | ||
| 55 | - MicroAPI::Select(dst1Reg, src1Reg, scalarReg, selMask1); | ||
| 56 | - MicroAPI::Mul(dst1Reg, dst1Reg, vDivValueReg, selMask1); | ||
| 57 | - MicroAPI::DataCopy<float>(dstUb + loopH * srcLastAxis + (i * unRollConstant + 1) * repeatElm, dst1Reg, maskReg); | ||
| 58 | - } | ||
| 59 | -} | ||
| 60 | - | ||
| 61 | -template <typename T> | ||
| 62 | -__simd_vf__ inline void VFDropOutBitModeCalc(__ubuf__ T* dstUb, __ubuf__ T* srcUb, | ||
| 63 | - __ubuf__ uint8_t* maskUb, const T divValue, const uint32_t dataSize) | ||
| 64 | -{ | ||
| 65 | - MicroAPI::RegTensor<T> vDivValueReg; | ||
| 66 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 67 | - uint32_t repeatTimes = CeilDivision(dataSize, repeatElm); | ||
| 68 | - uint32_t sreg = dataSize; | ||
| 69 | - MicroAPI::Duplicate(vDivValueReg, divValue); | ||
| 70 | - uint32_t tail = repeatTimes & 1; | ||
| 71 | - uint32_t newRepeatTimes = repeatTimes >> 1; | ||
| 72 | - if constexpr (sizeof(T) == 4) { | ||
| 73 | - DropOutBitModeFP32Main(dstUb, srcUb, maskUb, vDivValueReg, sreg, newRepeatTimes, 0, 0, 0); | ||
| 74 | - MicroAPI::MaskReg maskReg; | ||
| 75 | - MicroAPI::MaskReg selMask2; | ||
| 76 | - MicroAPI::RegTensor<float> src2Reg; | ||
| 77 | - MicroAPI::RegTensor<float> dst2Reg; | ||
| 78 | - MicroAPI::RegTensor<float> scalarReg; | ||
| 79 | - MicroAPI::Duplicate(scalarReg, (const T&)0); | ||
| 80 | - uint32_t offset = newRepeatTimes * 2 * repeatElm; | ||
| 81 | - uint32_t selOffset = newRepeatTimes * 4; | ||
| 82 | - for (uint16_t i = 0; i < static_cast<uint16_t>(tail); ++i) { | ||
| 83 | - MicroAPI::DataCopy<uint32_t, MicroAPI::MaskDist::DIST_US>(selMask2, (__ubuf__ uint32_t*)maskUb + selOffset); | ||
| 84 | - MicroAPI::MaskUnPack(selMask2, selMask2); | ||
| 85 | - maskReg = MicroAPI::UpdateMask<float>(sreg); | ||
| 86 | - MicroAPI::DataCopy<float>(src2Reg, srcUb + offset); | ||
| 87 | - MicroAPI::Select(dst2Reg, src2Reg, scalarReg, selMask2); | ||
| 88 | - MicroAPI::Mul(dst2Reg, dst2Reg, vDivValueReg, selMask2); | ||
| 89 | - MicroAPI::DataCopy<float>(dstUb + offset, dst2Reg, maskReg); | ||
| 90 | - } | ||
| 91 | - } else { | ||
| 92 | - MicroAPI::RegTensor<T> src0Reg; | ||
| 93 | - MicroAPI::RegTensor<T> src1Reg; | ||
| 94 | - MicroAPI::RegTensor<T> dstReg; | ||
| 95 | - MicroAPI::MaskReg maskReg; | ||
| 96 | - MicroAPI::MaskReg selMask; | ||
| 97 | - MicroAPI::Duplicate(src1Reg, (const T&)0); | ||
| 98 | - for (uint16_t i = 0; i < static_cast<uint16_t>(repeatTimes); ++i) { | ||
| 99 | - MicroAPI::DataCopy<uint32_t, MicroAPI::MaskDist::DIST_US>(selMask, (__ubuf__ uint32_t*)maskUb + i * 4); | ||
| 100 | - maskReg = MicroAPI::UpdateMask<T>(sreg); | ||
| 101 | - MicroAPI::DataCopy<T>(src0Reg, srcUb + i * repeatElm); | ||
| 102 | - MicroAPI::Select(dstReg, src0Reg, src1Reg, selMask); | ||
| 103 | - MicroAPI::Mul(dstReg, dstReg, vDivValueReg, selMask); | ||
| 104 | - MicroAPI::DataCopy<T>(dstUb + i * repeatElm, dstReg, maskReg); | ||
| 105 | - } | ||
| 106 | - } | ||
| 107 | -} | ||
| 108 | - | ||
| 109 | -template <typename T> | ||
| 110 | -__simd_vf__ inline void VFDropOutBitModeCalcInfo(__ubuf__ T* dstUb, __ubuf__ T* srcUb, | ||
| 111 | - __ubuf__ uint8_t* maskUb, const T divValue, const DropOutShapeInfo info) | ||
| 112 | -{ | ||
| 113 | - MicroAPI::RegTensor<T> vDivValueReg; | ||
| 114 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 115 | - uint32_t repeatTimes = CeilDivision(info.srcLastAxis, repeatElm); | ||
| 116 | - MicroAPI::Duplicate(vDivValueReg, divValue); | ||
| 117 | - uint32_t tail = repeatTimes & 1; | ||
| 118 | - uint32_t newRepeatTimes = repeatTimes >> 1; | ||
| 119 | - for (uint16_t loopH = 0; loopH < static_cast<uint16_t>(info.firstAxis); ++loopH) { | ||
| 120 | - uint32_t width = info.srcLastAxis; | ||
| 121 | - if constexpr (sizeof(T) == 4) { | ||
| 122 | - DropOutBitModeFP32Main(dstUb, srcUb, maskUb, vDivValueReg, width, newRepeatTimes, loopH, | ||
| 123 | - info.srcLastAxis, info.maskLastAxis); | ||
| 124 | - } else { | ||
| 125 | - MicroAPI::RegTensor<T> src0Reg; | ||
| 126 | - MicroAPI::RegTensor<T> scalarReg; | ||
| 127 | - MicroAPI::RegTensor<T> dstReg; | ||
| 128 | - MicroAPI::MaskReg maskReg; | ||
| 129 | - MicroAPI::MaskReg selMask; | ||
| 130 | - MicroAPI::Duplicate(scalarReg, (const T&)0); | ||
| 131 | - for (uint16_t i = 0; i < static_cast<uint16_t>(repeatTimes); ++i) { | ||
| 132 | - MicroAPI::DataCopy<uint32_t, MicroAPI::MaskDist::DIST_US>( | ||
| 133 | - selMask, (__ubuf__ uint32_t*)maskUb + loopH * (info.maskLastAxis >> 2) + i * 4); | ||
| 134 | - maskReg = MicroAPI::UpdateMask<T>(width); | ||
| 135 | - MicroAPI::DataCopy<T>(src0Reg, srcUb + loopH * info.srcLastAxis + i * repeatElm); | ||
| 136 | - MicroAPI::Select(dstReg, src0Reg, scalarReg, selMask); | ||
| 137 | - MicroAPI::Mul(dstReg, dstReg, vDivValueReg, selMask); | ||
| 138 | - MicroAPI::DataCopy<T>(dstUb + loopH * info.srcLastAxis + i * repeatElm, dstReg, maskReg); | ||
| 139 | - } | ||
| 140 | - } | ||
| 141 | - } | ||
| 142 | - if constexpr (sizeof(T) == 4) { | ||
| 143 | - if (tail != 0) { | ||
| 144 | - for (uint16_t loopH = 0; loopH < static_cast<uint16_t>(info.firstAxis); ++loopH) { | ||
| 145 | - uint32_t selOffset = newRepeatTimes * 4; | ||
| 146 | - uint32_t offset = newRepeatTimes * 2 * repeatElm; | ||
| 147 | - uint32_t sreg = info.srcLastAxis - offset; | ||
| 148 | - MicroAPI::MaskReg maskReg; | ||
| 149 | - MicroAPI::MaskReg selMask2; | ||
| 150 | - MicroAPI::RegTensor<float> src2Reg; | ||
| 151 | - MicroAPI::RegTensor<float> dst2Reg; | ||
| 152 | - MicroAPI::RegTensor<float> scalarReg; | ||
| 153 | - MicroAPI::Duplicate(scalarReg, (const T&)0); | ||
| 154 | - MicroAPI::DataCopy<uint32_t, MicroAPI::MaskDist::DIST_US>( | ||
| 155 | - selMask2, (__ubuf__ uint32_t*)maskUb + selOffset + loopH * (info.maskLastAxis >> 2)); | ||
| 156 | - MicroAPI::MaskUnPack(selMask2, selMask2); | ||
| 157 | - maskReg = MicroAPI::UpdateMask<float>(sreg); | ||
| 158 | - MicroAPI::DataCopy<float>(src2Reg, srcUb + offset + loopH * info.srcLastAxis); | ||
| 159 | - MicroAPI::Select(dst2Reg, src2Reg, scalarReg, selMask2); | ||
| 160 | - MicroAPI::Mul(dst2Reg, dst2Reg, vDivValueReg, selMask2); | ||
| 161 | - MicroAPI::DataCopy<float>(dstUb + offset + loopH * info.srcLastAxis, dst2Reg, maskReg); | ||
| 162 | - } | ||
| 163 | - } | ||
| 164 | - } | ||
| 165 | -} | ||
| 166 | - | ||
| 167 | -template <typename T> | ||
| 168 | -__simd_vf__ inline void VFDropOutByteModeCalc(__ubuf__ T* dstUb, __ubuf__ T* srcUb, | ||
| 169 | - __ubuf__ uint8_t* maskUb, const T divValue, const uint32_t dataSize) | ||
| 170 | -{ | ||
| 171 | - MicroAPI::RegTensor<T> vSrcReg; | ||
| 172 | - MicroAPI::RegTensor<T> vDstReg; | ||
| 173 | - MicroAPI::RegTensor<T> vDivValueReg; | ||
| 174 | - MicroAPI::RegTensor<uint8_t> vMaskReg; | ||
| 175 | - MicroAPI::RegTensor<half> vFP16Reg; | ||
| 176 | - MicroAPI::RegTensor<float> vFP32Reg; | ||
| 177 | - | ||
| 178 | - MicroAPI::RegTensor<bfloat16_t> vBF16Reg; | ||
| 179 | - | ||
| 180 | - MicroAPI::MaskReg maskReg; | ||
| 181 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 182 | - uint32_t sreg = dataSize; | ||
| 183 | - uint32_t repeatTimes = CeilDivision(dataSize, repeatElm); | ||
| 184 | - MicroAPI::Duplicate(vDivValueReg, divValue); | ||
| 185 | - for (uint16_t i = 0; i < static_cast<uint16_t>(repeatTimes); ++i) { | ||
| 186 | - maskReg = MicroAPI::UpdateMask<T>(sreg); | ||
| 187 | - MicroAPI::DataCopy(vSrcReg, srcUb + i * repeatElm); | ||
| 188 | - if constexpr (sizeof(T) == 2) { | ||
| 189 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK_B8>(vMaskReg, maskUb + i * repeatElm); | ||
| 190 | - MicroAPI::Cast<half, uint8_t, layoutZMrgZ>(vFP16Reg, vMaskReg, maskReg); | ||
| 191 | - | ||
| 192 | - if constexpr (SupportType<T, half>()) { | ||
| 193 | - MicroAPI::Mul(vDstReg, vFP16Reg, vSrcReg, maskReg); | ||
| 194 | - } else { | ||
| 195 | - MicroAPI::Cast<bfloat16_t, half, MrgZRndR>(vBF16Reg, vFP16Reg, maskReg); | ||
| 196 | - MicroAPI::Mul(vDstReg, vBF16Reg, vSrcReg, maskReg); | ||
| 197 | - } | ||
| 198 | - | ||
| 199 | - MicroAPI::Mul(vDstReg, vFP16Reg, vSrcReg, maskReg); | ||
| 200 | - | ||
| 201 | - } else { | ||
| 202 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK4_B8>(vMaskReg, maskUb + i * repeatElm); | ||
| 203 | - MicroAPI::Cast<half, uint8_t, layoutZMrgZ>(vFP16Reg, vMaskReg, maskReg); | ||
| 204 | - MicroAPI::Cast<float, half, layoutZMrgZ>(vFP32Reg, vFP16Reg, maskReg); | ||
| 205 | - MicroAPI::Mul(vDstReg, vFP32Reg, vSrcReg, maskReg); | ||
| 206 | - } | ||
| 207 | - MicroAPI::Mul(vDstReg, vDivValueReg, vDstReg, maskReg); | ||
| 208 | - MicroAPI::DataCopy(dstUb + i * repeatElm, vDstReg, maskReg); | ||
| 209 | - } | ||
| 210 | -} | ||
| 211 | - | ||
| 212 | -template <typename T> | ||
| 213 | -__simd_vf__ inline void VFDropOutByteModeCalcInfo(__ubuf__ T* dstUb, __ubuf__ T* srcUb, | ||
| 214 | - __ubuf__ uint8_t* maskUb, const T divValue, const DropOutShapeInfo info) | ||
| 215 | -{ | ||
| 216 | - MicroAPI::RegTensor<T> vSrcReg; | ||
| 217 | - MicroAPI::RegTensor<T> vDstReg; | ||
| 218 | - MicroAPI::RegTensor<T> vDivValueReg; | ||
| 219 | - MicroAPI::RegTensor<uint8_t> vMaskReg; | ||
| 220 | - MicroAPI::RegTensor<half> vFP16Reg; | ||
| 221 | - MicroAPI::RegTensor<float> vFP32Reg; | ||
| 222 | - | ||
| 223 | - MicroAPI::RegTensor<bfloat16_t> vBF16Reg; | ||
| 224 | - | ||
| 225 | - MicroAPI::MaskReg maskReg; | ||
| 226 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 227 | - uint32_t loopWNum = CeilDivision(info.srcLastAxis, repeatElm); | ||
| 228 | - MicroAPI::Duplicate(vDivValueReg, divValue); | ||
| 229 | - for (uint16_t loopH = 0; loopH < static_cast<uint16_t>(info.firstAxis); ++loopH) { | ||
| 230 | - uint32_t width = info.srcLastAxis; | ||
| 231 | - for (uint16_t loopW = 0; loopW < static_cast<uint16_t>(loopWNum); ++loopW) { | ||
| 232 | - maskReg = MicroAPI::UpdateMask<T>(width); | ||
| 233 | - MicroAPI::DataCopy<T>(vSrcReg, srcUb + loopH * info.srcLastAxis + loopW * repeatElm); | ||
| 234 | - if constexpr (sizeof(T) == 2) { | ||
| 235 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK_B8>( | ||
| 236 | - vMaskReg, maskUb + loopH * info.maskLastAxis + loopW * repeatElm); | ||
| 237 | - MicroAPI::Cast<half, uint8_t, layoutZMrgZ>(vFP16Reg, vMaskReg, maskReg); | ||
| 238 | - | ||
| 239 | - if constexpr (SupportType<T, half>()) { | ||
| 240 | - MicroAPI::Mul(vDstReg, vFP16Reg, vSrcReg, maskReg); | ||
| 241 | - } else { | ||
| 242 | - MicroAPI::Cast<bfloat16_t, half, MrgZRndR>(vBF16Reg, vFP16Reg, maskReg); | ||
| 243 | - MicroAPI::Mul(vDstReg, vBF16Reg, vSrcReg, maskReg); | ||
| 244 | - } | ||
| 245 | - | ||
| 246 | - MicroAPI::Mul(vDstReg, vFP16Reg, vSrcReg, maskReg); | ||
| 247 | - | ||
| 248 | - } else { | ||
| 249 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK4_B8>( | ||
| 250 | - vMaskReg, maskUb + loopH * info.maskLastAxis + loopW * repeatElm); | ||
| 251 | - MicroAPI::Cast<half, uint8_t, layoutZMrgZ>(vFP16Reg, vMaskReg, maskReg); | ||
| 252 | - MicroAPI::Cast<float, half, layoutZMrgZ>(vFP32Reg, vFP16Reg, maskReg); | ||
| 253 | - MicroAPI::Mul(vDstReg, vFP32Reg, vSrcReg, maskReg); | ||
| 254 | - } | ||
| 255 | - MicroAPI::Mul(vDstReg, vDivValueReg, vDstReg, maskReg); | ||
| 256 | - MicroAPI::DataCopy(dstUb + loopH * info.srcLastAxis + loopW * repeatElm, vDstReg, maskReg); | ||
| 257 | - } | ||
| 258 | - } | ||
| 259 | -} | ||
| 260 | -} // namespace Internal | ||
| 261 | - | ||
| 262 | -template <typename T, bool isInitBitMode = false> | ||
| 263 | -__aicore__ inline void DropOutBitMode(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 264 | - const LocalTensor<uint8_t>& maskLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const T divValue, | ||
| 265 | - const uint32_t dataSize) | ||
| 266 | -{ | ||
| 267 | - static_assert(SupportType<T, half, float, bfloat16_t>(), "current data type is not supported on current device!"); | ||
| 268 | - (void)sharedTmpBuffer; | ||
| 269 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 270 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 271 | - __ubuf__ uint8_t *maskUb = (__ubuf__ uint8_t *)maskLocal.GetPhyAddr(); | ||
| 272 | - | ||
| 273 | - Internal::VFDropOutBitModeCalc<T>(dstUb, srcUb, maskUb, divValue, dataSize); | ||
| 274 | -} | ||
| 275 | - | ||
| 276 | -template <typename T, bool isInitBitMode = false> | ||
| 277 | -__aicore__ inline void DropOutBitMode(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 278 | - const LocalTensor<uint8_t>& maskLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const T divValue, | ||
| 279 | - const DropOutShapeInfo& info) | ||
| 280 | -{ | ||
| 281 | - static_assert(SupportType<T, half, float, bfloat16_t>(), "current data type is not supported on current device!"); | ||
| 282 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 283 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 284 | - __ubuf__ uint8_t *maskUb = (__ubuf__ uint8_t *)maskLocal.GetPhyAddr(); | ||
| 285 | - | ||
| 286 | - Internal::VFDropOutBitModeCalcInfo<T>(dstUb, srcUb, maskUb, divValue, info); | ||
| 287 | -} | ||
| 288 | - | ||
| 289 | -template <typename T> | ||
| 290 | -__aicore__ inline void DropOutByteMode(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 291 | - const LocalTensor<uint8_t>& maskLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const T divValue, | ||
| 292 | - const uint32_t dataSize) | ||
| 293 | -{ | ||
| 294 | - static_assert(SupportType<T, half, float, bfloat16_t>(), "current data type is not supported on current device!"); | ||
| 295 | - (void)sharedTmpBuffer; | ||
| 296 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 297 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 298 | - __ubuf__ uint8_t *maskUb = (__ubuf__ uint8_t *)maskLocal.GetPhyAddr(); | ||
| 299 | - | ||
| 300 | - Internal::VFDropOutByteModeCalc<T>(dstUb, srcUb, maskUb, divValue, dataSize); | ||
| 301 | -} | ||
| 302 | - | ||
| 303 | -template <typename T> | ||
| 304 | -__aicore__ inline void DropOutByteMode(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 305 | - const LocalTensor<uint8_t>& maskLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const T divValue, | ||
| 306 | - const DropOutShapeInfo& info) | ||
| 307 | -{ | ||
| 308 | - static_assert(SupportType<T, half, float, bfloat16_t>(), "current data type is not supported on current device!"); | ||
| 309 | - (void)sharedTmpBuffer; | ||
| 310 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 311 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 312 | - __ubuf__ uint8_t *maskUb = (__ubuf__ uint8_t *)maskLocal.GetPhyAddr(); | ||
| 313 | - | ||
| 314 | - Internal::VFDropOutByteModeCalcInfo<T>(dstUb, srcUb, maskUb, divValue, info); | ||
| 315 | -} | ||
| 316 | -} // namespace AscendC | ||
| 317 | - | ||
Dimpl/adv_api/detail/index/arithprogression/arithprogression_l300_impl.h+0-85
| @@ -1,85 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file arithprogression_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -// Generating an underlying arithmetic sequence through scalar operations. | ||
| 23 | -template <typename RegT, typename ScalarT> | ||
| 24 | -__simd_callee__ inline void GetBaseArithProgression(RegT &dstReg, const ScalarT firstValue, const ScalarT diffValue) | ||
| 25 | -{ | ||
| 26 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<uint8_t>(); | ||
| 27 | - MicroAPI::Arange(dstReg, ScalarT(0)); | ||
| 28 | - MicroAPI::Muls(dstReg, dstReg, diffValue, fullMask); | ||
| 29 | - MicroAPI::Adds(dstReg, dstReg, firstValue, fullMask); | ||
| 30 | -} | ||
| 31 | - | ||
| 32 | -template <typename T, const MicroAPI::RegTrait ®Trait> | ||
| 33 | -__simd_vf__ inline void VfCallArithProgression(__ubuf__ T *dstLocalAddr, const T firstValue, const T diffValue, | ||
| 34 | - const int32_t count, const uint16_t repeatTimes) | ||
| 35 | -{ | ||
| 36 | - MicroAPI::RegTensor<T, regTrait> tmpReg; | ||
| 37 | - MicroAPI::RegTensor<T, regTrait> stepReg; | ||
| 38 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL, regTrait>(); | ||
| 39 | - GetBaseArithProgression(tmpReg, firstValue, diffValue); | ||
| 40 | - uint32_t sreg = static_cast<uint32_t>(count); | ||
| 41 | - MicroAPI::MaskReg preg; | ||
| 42 | - const uint32_t sregLower = static_cast<uint32_t>(regTrait.REG_NUM * ONE_REPEAT_BYTE_SIZE / sizeof(T)); | ||
| 43 | - | ||
| 44 | - MicroAPI::Duplicate(stepReg, static_cast<T>(static_cast<int32_t>(sregLower))); | ||
| 45 | - | ||
| 46 | - MicroAPI::Duplicate(stepReg, static_cast<T>(sregLower)); | ||
| 47 | - | ||
| 48 | - MicroAPI::Muls(stepReg, stepReg, diffValue, fullMask); | ||
| 49 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 50 | - preg = MicroAPI::UpdateMask<T, regTrait>(sreg); | ||
| 51 | - MicroAPI::DataCopy(dstLocalAddr + i * sregLower, tmpReg, preg); | ||
| 52 | - MicroAPI::Add(tmpReg, tmpReg, stepReg, fullMask); | ||
| 53 | - } | ||
| 54 | -} | ||
| 55 | - | ||
| 56 | -template <typename T> | ||
| 57 | -__aicore__ inline void ArithProgressionImpl(const LocalTensor<T> &dstLocal, const T firstValue, const T diffValue, | ||
| 58 | - const int32_t count) | ||
| 59 | -{ | ||
| 60 | - ASCENDC_ASSERT((dstLocal.GetSize() >= count), | ||
| 61 | - { KERNEL_LOG(KERNEL_ERROR, "dst length must equal with Arange length"); }); | ||
| 62 | - ASCENDC_ASSERT((static_cast<float>(diffValue) >= static_cast<float>(0)), | ||
| 63 | - { KERNEL_LOG(KERNEL_ERROR, "diff value mast bigger then 0"); }); | ||
| 64 | - static_assert(SupportType<T, int16_t, int32_t, half, float, int64_t>(), | ||
| 65 | - "current data type is not supported on current device!"); | ||
| 66 | - | ||
| 67 | - __ubuf__ T* dstLocalAddr = (__ubuf__ T*)dstLocal.GetPhyAddr(); | ||
| 68 | - if constexpr(sizeof(T) != 8) { | ||
| 69 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, ONE_REPEAT_BYTE_SIZE / sizeof(T))); | ||
| 70 | - VfCallArithProgression<T, MicroAPI::RegTraitNumOne>(dstLocalAddr, firstValue, diffValue, count, repeatTimes); | ||
| 71 | - } else { | ||
| 72 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(count, 2 * ONE_REPEAT_BYTE_SIZE / sizeof(T))); | ||
| 73 | - VfCallArithProgression<T, MicroAPI::RegTraitNumTwo>(dstLocalAddr, firstValue, diffValue, count, repeatTimes); | ||
| 74 | - } | ||
| 75 | -} | ||
| 76 | - | ||
| 77 | -template <typename T> | ||
| 78 | -__aicore__ inline __in_pipe__(S) __out_pipe__(V, S) void ArithProgression(const LocalTensor<T> &dstLocal, | ||
| 79 | - const T firstValue, const T diffValue, const int32_t count) | ||
| 80 | -{ | ||
| 81 | - ArithProgressionImpl(dstLocal, firstValue, diffValue, count); | ||
| 82 | -} | ||
| 83 | -} // namespace AscendC | ||
| 84 | - | ||
| 85 | - | ||
Dimpl/adv_api/detail/math/acos/acos_l300_impl.h+0-58
| @@ -1,58 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file acos_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -// Compute acos values according to formula: arccos(x) = PI*0.5 - arcsin(x). | ||
| 23 | -template <typename T> | ||
| 24 | -__aicore__ inline void AcosCompute(const LocalTensor<T>& dst, const LocalTensor<T>& src, uint32_t calSize) | ||
| 25 | -{ | ||
| 26 | - constexpr bool convertToCos = true; | ||
| 27 | - AsinCompute<T, convertToCos>(dst, src, calSize); | ||
| 28 | -} | ||
| 29 | - | ||
| 30 | -template <typename T, bool isReuseSource = false> | ||
| 31 | -__aicore__ inline void AcosImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 32 | - const uint32_t calCount) | ||
| 33 | -{ | ||
| 34 | - // Only for AI Vector Core. | ||
| 35 | - if ASCEND_IS_AIC { | ||
| 36 | - return; | ||
| 37 | - } | ||
| 38 | - static_assert(SupportType<T, half, float>(), "Acos only support half/float data type on current device!"); | ||
| 39 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 40 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 41 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Acos"); | ||
| 42 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Acos"); | ||
| 43 | - AcosCompute(dstTensor, srcTensor, calCount); | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -template <typename T, bool isReuseSource = false> | ||
| 47 | -__aicore__ inline void AcosImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 48 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 49 | -{ | ||
| 50 | - // Only for AI Vector Core. | ||
| 51 | - if ASCEND_IS_AIC { | ||
| 52 | - return; | ||
| 53 | - } | ||
| 54 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 55 | - AcosImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 56 | -} | ||
| 57 | -} // namespace AscendC | ||
| 58 | - | ||
Dimpl/adv_api/detail/math/asin/asin_l300_impl.h+0-284
| @@ -1,284 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file asin_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace Internal { | ||
| 23 | -constexpr MicroAPI::CastTrait ASIN_CAST_TRAIT_NONE = {MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::SAT, | ||
| 24 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_NONE}; | ||
| 25 | - | ||
| 26 | -constexpr MicroAPI::CastTrait ASIN_CAST_TRAIT_FLOOR = {MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::SAT, | ||
| 27 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_FLOOR}; | ||
| 28 | - | ||
| 29 | -constexpr MicroAPI::CastTrait ASIN_CAST_TRAIT_RINT = {MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::SAT, | ||
| 30 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 31 | - | ||
| 32 | -// Calculate Taylor Expansion according to (((k_nx^2 + k_n) * x^2 + k_(n-1)) * x^2 +k_(n-2) ……)*x^2 +k_0)*x. | ||
| 33 | -template <typename T, typename RegT> | ||
| 34 | -__simd_callee__ inline void AsinTaylorComputeInner(RegT& dstReg, RegT& srcReg, MicroAPI::MaskReg& mask) | ||
| 35 | -{ | ||
| 36 | - MicroAPI::Muls(dstReg, dstReg, static_cast<T>(kCOEF[ASIN_TAYLOR_EXPAND_COUNT]), mask); | ||
| 37 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[6]), mask); | ||
| 38 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 39 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[5]), mask); | ||
| 40 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 41 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[4]), mask); | ||
| 42 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 43 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[3]), mask); | ||
| 44 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 45 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[2]), mask); | ||
| 46 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 47 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[1]), mask); | ||
| 48 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 49 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(kCOEF[0]), mask); | ||
| 50 | -} | ||
| 51 | - | ||
| 52 | -template <typename T, typename RegT> | ||
| 53 | -__simd_callee__ inline void AsinTaylorCompute(RegT& dstReg, RegT& srcReg, MicroAPI::MaskReg& mask) | ||
| 54 | -{ | ||
| 55 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 56 | - MicroAPI::Mul(dstReg, srcReg, srcReg, mask); | ||
| 57 | - MicroAPI::Mul(tmpReg, srcReg, srcReg, mask); | ||
| 58 | - AsinTaylorComputeInner<T>(dstReg, tmpReg, mask); | ||
| 59 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 60 | -} | ||
| 61 | - | ||
| 62 | -// Calculate Taylor Expansion of Asin based on its square value, and set the source to be sqrt(x). | ||
| 63 | -template <typename T, typename RegT> | ||
| 64 | -__simd_callee__ inline void AsinTaylorComputeBySquareValue(RegT& dstReg, RegT& srcReg, MicroAPI::MaskReg& mask) | ||
| 65 | -{ | ||
| 66 | - MicroAPI::Muls(dstReg, srcReg, static_cast<T>(NUM_ONE), mask); | ||
| 67 | - AsinTaylorComputeInner<T>(dstReg, srcReg, mask); | ||
| 68 | - // Update src to be sqrt(x). | ||
| 69 | - MicroAPI::Sqrt(srcReg, srcReg, mask); | ||
| 70 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 71 | -} | ||
| 72 | - | ||
| 73 | -template <typename T, typename RegT> | ||
| 74 | -__simd_callee__ inline void CalRes2(RegT& resReg, RegT& srcReg, MicroAPI::MaskReg& mask) | ||
| 75 | -{ | ||
| 76 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 77 | - MicroAPI::Mul(tmpReg, srcReg, srcReg, mask); | ||
| 78 | - MicroAPI::Muls(tmpReg, tmpReg, NEG_ONE, mask); | ||
| 79 | - MicroAPI::Adds(tmpReg, tmpReg, NUM_ONE, mask); | ||
| 80 | - MicroAPI::Sqrt(tmpReg, tmpReg, mask); | ||
| 81 | - AsinTaylorCompute<T>(resReg, tmpReg, mask); | ||
| 82 | - MicroAPI::Muls(resReg, resReg, NEG_ONE, mask); | ||
| 83 | - MicroAPI::Adds(resReg, resReg, HALF_PI, mask); | ||
| 84 | -} | ||
| 85 | - | ||
| 86 | -template <typename T, typename RegT> | ||
| 87 | -__simd_callee__ inline void ProcessBranch(RegT& resReg1, RegT& resReg2, RegT& tmpReg, MicroAPI::MaskReg& mask) | ||
| 88 | -{ | ||
| 89 | - MicroAPI::RegTensor<int32_t> s32Reg; | ||
| 90 | - MicroAPI::Mins(tmpReg, tmpReg, BOUNDARY, mask); | ||
| 91 | - MicroAPI::Adds(tmpReg, tmpReg, -BOUNDARY, mask); | ||
| 92 | - MicroAPI::Cast<int32_t, T, ASIN_CAST_TRAIT_FLOOR>(s32Reg, tmpReg, mask); | ||
| 93 | - MicroAPI::Cast<T, int32_t, ASIN_CAST_TRAIT_RINT>(tmpReg, s32Reg, mask); | ||
| 94 | - MicroAPI::Muls(tmpReg, tmpReg, NEG_ONE, mask); | ||
| 95 | - MicroAPI::Mul(resReg1, resReg1, tmpReg, mask); | ||
| 96 | - MicroAPI::Muls(tmpReg, tmpReg, NEG_ONE, mask); | ||
| 97 | - MicroAPI::Adds(tmpReg, tmpReg, NUM_ONE, mask); | ||
| 98 | - MicroAPI::Mul(resReg2, resReg2, tmpReg, mask); | ||
| 99 | - MicroAPI::Add(resReg1, resReg1, resReg2, mask); | ||
| 100 | -} | ||
| 101 | - | ||
| 102 | -// Calculate the sign of given values. | ||
| 103 | -// Algorithm: | ||
| 104 | -// FP16: sign(x) = 2^(15) * x /(2^(-15) + 2^(15) *|x|) | ||
| 105 | -// FP32: sign(x) = 2^(62) * x /(2^(-62) + 2^(62) *|x|) | ||
| 106 | -template <typename T, typename RegT> | ||
| 107 | -__simd_callee__ inline void GetSign(RegT& dstReg, RegT& srcReg, MicroAPI::MaskReg& mask) | ||
| 108 | -{ | ||
| 109 | - MicroAPI::RegTensor<T> denominatorReg; | ||
| 110 | - constexpr float FP16_MAX = 32768; // 2^15 | ||
| 111 | - constexpr float FP16_MIN = 3.0517578125e-05; // 2^-15 | ||
| 112 | - constexpr float FP32_MAX = 4611686018427387904; // 2^62 | ||
| 113 | - constexpr float FP32_MIN = 2.168404344971009e-19; // 2^-62 | ||
| 114 | - constexpr float kFpMax = sizeof(T) == sizeof(float) ? FP32_MAX : FP16_MAX; | ||
| 115 | - constexpr float kFpMin = sizeof(T) == sizeof(float) ? FP32_MIN : FP16_MIN; | ||
| 116 | - MicroAPI::Muls(dstReg, srcReg, static_cast<T>(kFpMax), mask); | ||
| 117 | - MicroAPI::Abs(denominatorReg, dstReg, mask); | ||
| 118 | - MicroAPI::Adds(denominatorReg, denominatorReg, static_cast<T>(kFpMin), mask); | ||
| 119 | - MicroAPI::Div(dstReg, dstReg, denominatorReg, mask); | ||
| 120 | -} | ||
| 121 | - | ||
| 122 | -// Compute asin values based on input types. | ||
| 123 | -// asin(x) = arcsin(sqrt(1-x^2)) - PI*0.5 when x belongs to (-1, -2^(-0.5)) | ||
| 124 | -// asin(x) = the 15th order taylor expansion when x belongs to (-2^(-0.5), 2^(-0.5)) | ||
| 125 | -// asin(x) = PI*0.5 - arcsin(sqrt(1-x^2)) when x belongs to (2^(-0.5), 1) | ||
| 126 | -template <typename T, bool convertToAcos = false> | ||
| 127 | -__simd_vf__ inline void AsinComputeVFF32(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t calSize, | ||
| 128 | - uint16_t repeatTimes, uint16_t stride) | ||
| 129 | -{ | ||
| 130 | - MicroAPI::MaskReg mask; | ||
| 131 | - MicroAPI::RegTensor<T> srcReg; | ||
| 132 | - MicroAPI::RegTensor<T> dstReg; | ||
| 133 | - MicroAPI::RegTensor<T> resReg1; | ||
| 134 | - MicroAPI::RegTensor<T> resReg2; | ||
| 135 | - MicroAPI::RegTensor<T> signReg; | ||
| 136 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 137 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 138 | - mask = MicroAPI::UpdateMask<T>(calSize); | ||
| 139 | - MicroAPI::DataCopy(srcReg, srcUb + i * stride); | ||
| 140 | - // Calculate res2 = PI*0.5 - taylor_compute(sqrt(1 - x^2)) -> resReg2. | ||
| 141 | - CalRes2<T>(resReg2, srcReg, mask); | ||
| 142 | - // Calculate res1 = taylor_compute(abs(x)) -> dst, abs(x) -> resReg1. | ||
| 143 | - MicroAPI::Mul(tmpReg, srcReg, srcReg, mask); | ||
| 144 | - AsinTaylorComputeBySquareValue<T>(resReg1, tmpReg, mask); | ||
| 145 | - // As NPU are not good at scalar process like CPU for if-else statement, the solution here used for handling above | ||
| 146 | - // 3 scenarios is to calculate 0/1 choices combining the results on both options. | ||
| 147 | - // e.g. | ||
| 148 | - // Step1: Calculate both option results of x, no matter which range it's at. | ||
| 149 | - // result1(x), result2(x) | ||
| 150 | - // Step2: Calculate 0/1 choices of both option results of x, no matter which range it's at. | ||
| 151 | - // choice1(x), choice2(x) | ||
| 152 | - // Step3: Combine choice result and options results, since at least one choice should be zero. | ||
| 153 | - // Result = choice1(x) * result1(x) + choice2(x) * result2(x) | ||
| 154 | - // choice1 = -Floor(min(abs(x), BOUNDARY) - BOUNDARY). | ||
| 155 | - // choice2 = 1 - choice1 | ||
| 156 | - // res = res1 * choice1 + res2 * choice2 | ||
| 157 | - ProcessBranch<T>(resReg1, resReg2, tmpReg, mask); | ||
| 158 | - GetSign<T>(signReg, srcReg, mask); | ||
| 159 | - MicroAPI::Mul(dstReg, resReg1, signReg, mask); | ||
| 160 | - if constexpr (convertToAcos) { | ||
| 161 | - // Compute acos values according to formula: arccos(x) = PI*0.5 - arcsin(x). | ||
| 162 | - MicroAPI::Adds(dstReg, dstReg, static_cast<T>(-HALF_PI), mask); | ||
| 163 | - MicroAPI::Muls(dstReg, dstReg, static_cast<T>(NEG_ONE), mask); | ||
| 164 | - } | ||
| 165 | - MicroAPI::DataCopy(dstUb + i * stride, dstReg, mask); | ||
| 166 | - } | ||
| 167 | -} | ||
| 168 | - | ||
| 169 | -template <typename T, bool convertToAcos = false> | ||
| 170 | -__simd_vf__ inline void AsinComputeVFF16(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t calSize, | ||
| 171 | - uint16_t repeatTimes, uint16_t stride) | ||
| 172 | -{ | ||
| 173 | - MicroAPI::MaskReg mask; | ||
| 174 | - MicroAPI::RegTensor<half> srcReg; | ||
| 175 | - MicroAPI::RegTensor<half> dstReg; | ||
| 176 | - MicroAPI::RegTensor<half> halfReg1; | ||
| 177 | - MicroAPI::RegTensor<half> halfReg2; | ||
| 178 | - MicroAPI::RegTensor<half> tmpReg; | ||
| 179 | - MicroAPI::RegTensor<float> floatReg1; | ||
| 180 | - MicroAPI::RegTensor<float> floatReg2; | ||
| 181 | - MicroAPI::RegTensor<int8_t> s8Reg; | ||
| 182 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 183 | - mask = MicroAPI::UpdateMask<float>(calSize); | ||
| 184 | - // Cast src from half to float type for getting more precise results, but only computes by finishing | ||
| 185 | - // taylor expansion computation as it's the majority reason of precision loss. | ||
| 186 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * stride); | ||
| 187 | - MicroAPI::Cast<float, half, ASIN_CAST_TRAIT_NONE>(floatReg2, srcReg, mask); | ||
| 188 | - // Calculate res2 = PI*0.5 - taylor_compute(sqrt(1 - x^2)). | ||
| 189 | - MicroAPI::Mul(floatReg2, floatReg2, floatReg2, mask); | ||
| 190 | - MicroAPI::Muls(floatReg2, floatReg2, NEG_ONE, mask); | ||
| 191 | - MicroAPI::Adds(floatReg2, floatReg2, NUM_ONE, mask); | ||
| 192 | - AsinTaylorComputeBySquareValue<half>(floatReg1, floatReg2, mask); | ||
| 193 | - MicroAPI::Muls(floatReg1, floatReg1, NEG_ONE, mask); | ||
| 194 | - MicroAPI::Adds(floatReg1, floatReg1, HALF_PI, mask); | ||
| 195 | - | ||
| 196 | - // Calculate res1 = taylor_compute(abs(x)). | ||
| 197 | - MicroAPI::Abs(halfReg2, srcReg, mask); | ||
| 198 | - AsinTaylorCompute<half>(dstReg, halfReg2, mask); | ||
| 199 | - | ||
| 200 | - // As NPU are not good at scalar process like CPU for if-else statement, the solution here used for handling above | ||
| 201 | - // 3 scenarios is to calculate 0/1 choices combining the results on both options. | ||
| 202 | - // e.g. | ||
| 203 | - // Step1: Calculate both option results of x, no matter which range it's at. | ||
| 204 | - // result1(x), result2(x) | ||
| 205 | - // Step2: Calculate 0/1 choices of both option results of x, no matter which range it's at. | ||
| 206 | - // choice1(x), choice2(x) | ||
| 207 | - // Step3: Combine choice result and optional result, since at least one choice should be zero. | ||
| 208 | - // Result = choice1(x) * result1(x) + choice2(x) * result2(x) | ||
| 209 | - // choice1 = -Floor(min(abs(x), BOUNDARY) - BOUNDARY). | ||
| 210 | - // choice2 = 1 - choice1 | ||
| 211 | - // res = res1 * choice1 + res2 * choice2 | ||
| 212 | - MicroAPI::Mins(halfReg2, halfReg2, static_cast<half>(BOUNDARY), mask); | ||
| 213 | - MicroAPI::Adds(halfReg2, halfReg2, static_cast<half>(-BOUNDARY), mask); | ||
| 214 | - MicroAPI::Cast<int8_t, half, ASIN_CAST_TRAIT_FLOOR>(s8Reg, halfReg2, mask); | ||
| 215 | - MicroAPI::Cast<half, int8_t, ASIN_CAST_TRAIT_NONE>(halfReg2, s8Reg, mask); | ||
| 216 | - MicroAPI::Muls(halfReg2, halfReg2, static_cast<half>(NEG_ONE), mask); | ||
| 217 | - MicroAPI::Mul(dstReg, dstReg, halfReg2, mask); | ||
| 218 | - MicroAPI::Muls(halfReg2, halfReg2, static_cast<half>(NEG_ONE), mask); | ||
| 219 | - MicroAPI::Adds(halfReg2, halfReg2, static_cast<half>(NUM_ONE), mask); | ||
| 220 | - MicroAPI::Cast<float, half, ASIN_CAST_TRAIT_NONE>(floatReg2, halfReg2, mask); | ||
| 221 | - MicroAPI::Mul(floatReg1, floatReg1, floatReg2, mask); | ||
| 222 | - MicroAPI::Cast<float, half, ASIN_CAST_TRAIT_NONE>(floatReg2, dstReg, mask); | ||
| 223 | - MicroAPI::Add(floatReg1, floatReg2, floatReg1, mask); | ||
| 224 | - GetSign<half>(halfReg1, srcReg, mask); | ||
| 225 | - MicroAPI::Cast<float, half, ASIN_CAST_TRAIT_NONE>(floatReg2, halfReg1, mask); | ||
| 226 | - MicroAPI::Mul(floatReg1, floatReg1, floatReg2, mask); | ||
| 227 | - if constexpr (convertToAcos) { | ||
| 228 | - // Compute acos values according to formula: arccos(x) = PI*0.5 - arcsin(x). | ||
| 229 | - MicroAPI::Adds(floatReg1, floatReg1, -HALF_PI, mask); | ||
| 230 | - MicroAPI::Muls(floatReg1, floatReg1, NEG_ONE, mask); | ||
| 231 | - } | ||
| 232 | - MicroAPI::Cast<half, float, ASIN_CAST_TRAIT_RINT>(dstReg, floatReg1, mask); | ||
| 233 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * stride, dstReg, mask); | ||
| 234 | - } | ||
| 235 | -} | ||
| 236 | -} // namespace Internal | ||
| 237 | - | ||
| 238 | -template <typename T, bool convertToAcos = false> | ||
| 239 | -__aicore__ inline void AsinCompute(const LocalTensor<T>& dst, const LocalTensor<T>& src, uint32_t calSize) | ||
| 240 | -{ | ||
| 241 | - __ubuf__ T *dstUb = (__ubuf__ T *)dst.GetPhyAddr(); | ||
| 242 | - __ubuf__ T *srcUb = (__ubuf__ T *)src.GetPhyAddr(); | ||
| 243 | - | ||
| 244 | - // half dtype will be converted to float to improve precision; | ||
| 245 | - constexpr uint16_t stride = GetVecLen() / sizeof(float); | ||
| 246 | - uint16_t repeatTimes = CeilDivision(calSize, stride); | ||
| 247 | - if constexpr (IsSameType<T, half>::value) { | ||
| 248 | - Internal::AsinComputeVFF16<T, convertToAcos>(dstUb, srcUb, calSize, repeatTimes, stride); | ||
| 249 | - } else if (IsSameType<T, float>::value) { | ||
| 250 | - Internal::AsinComputeVFF32<T, convertToAcos>(dstUb, srcUb, calSize, repeatTimes, stride); | ||
| 251 | - } | ||
| 252 | -} | ||
| 253 | - | ||
| 254 | -template <typename T, bool isReuseSource = false> | ||
| 255 | -__aicore__ inline void AsinImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 256 | - const uint32_t calCount) | ||
| 257 | -{ | ||
| 258 | - // Only for AI Vector Core. | ||
| 259 | - if ASCEND_IS_AIC { | ||
| 260 | - return; | ||
| 261 | - } | ||
| 262 | - static_assert(SupportType<T, half, float>(), "Asin only support half/float data type on current device!"); | ||
| 263 | - | ||
| 264 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 265 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 266 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Asin"); | ||
| 267 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Asin"); | ||
| 268 | - AsinCompute(dstTensor, srcTensor, calCount); | ||
| 269 | -} | ||
| 270 | - | ||
| 271 | -template <typename T, bool isReuseSource = false> | ||
| 272 | -__aicore__ inline void AsinImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 273 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 274 | -{ | ||
| 275 | - // Only for AI Vector Core. | ||
| 276 | - if ASCEND_IS_AIC { | ||
| 277 | - return; | ||
| 278 | - } | ||
| 279 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 280 | - AsinImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 281 | -} | ||
| 282 | -} // namespace AscendC | ||
| 283 | - | ||
| 284 | - | ||
Dimpl/adv_api/detail/math/atan/atan_l300_impl.h+0-416
| @@ -1,416 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file atan_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -enum class AtanAlgo { TAYLOR_EXPANSION = 0, POLYNOMIAL_APPROXIMATION }; | ||
| 23 | - | ||
| 24 | -struct AtanConfig { | ||
| 25 | - AtanAlgo algo = AtanAlgo::TAYLOR_EXPANSION; | ||
| 26 | -}; | ||
| 27 | - | ||
| 28 | -constexpr AtanConfig defaultAtanConfig = { AtanAlgo::TAYLOR_EXPANSION }; | ||
| 29 | - | ||
| 30 | -namespace Internal { | ||
| 31 | -constexpr float ATAN_FP16_MAX = 32768; // 2^15 | ||
| 32 | -constexpr float ATAN_FP16_MIN = 3.0517578125e-05; // 2^-15 | ||
| 33 | -constexpr float ATAN_FP32_MAX = 4611686018427387904; // 2^62 | ||
| 34 | -constexpr float ATAN_FP32_MIN = 2.168404344971009e-19; // 2^-62 | ||
| 35 | -constexpr uint16_t TAYLOR_COUNT_FOUR = 4; // x belongs to (0, tan(pi/8)) | ||
| 36 | -constexpr uint16_t TAYLOR_COUNT_SIX = 6; // x belongs to (tan(pi/8), tan(pi/4)) | ||
| 37 | -constexpr float MIN_INPUT_VALUE = -10000; | ||
| 38 | -constexpr float MAX_INPUT_VALUE = 10000; | ||
| 39 | -// Calculates the Sign of given values. | ||
| 40 | -// Algorithm: | ||
| 41 | -// FP16: sign(x) = 2**(15) * x /(2**(-15) + 2**(15) *|x|) | ||
| 42 | -// FP32: sign(x) = 2**(62) * x /(2**(-62) + 2**(62) *|x|) | ||
| 43 | -template <typename T> | ||
| 44 | -__simd_callee__ inline void Sign(MicroAPI::RegTensor<T>& dstReg, MicroAPI::RegTensor<T>& srcReg, | ||
| 45 | - MicroAPI::RegTensor<T>& denominator, MicroAPI::MaskReg preg) | ||
| 46 | -{ | ||
| 47 | - constexpr float kFpMax = sizeof(T) == sizeof(float) ? ATAN_FP32_MAX : ATAN_FP16_MAX; | ||
| 48 | - constexpr float kFpMin = sizeof(T) == sizeof(float) ? ATAN_FP32_MIN : ATAN_FP16_MIN; | ||
| 49 | - MicroAPI::Muls(dstReg, srcReg, static_cast<T>(kFpMax), preg); | ||
| 50 | - MicroAPI::Abs(denominator, dstReg, preg); | ||
| 51 | - MicroAPI::Adds(denominator, denominator, static_cast<T>(kFpMin), preg); | ||
| 52 | - MicroAPI::Div(dstReg, dstReg, denominator, preg); | ||
| 53 | -} | ||
| 54 | - | ||
| 55 | -// arctan(x) = x - x^3/3 + x^5/5 + ... + (-1)^k*x^(k*2+1)/( k*2+1) | ||
| 56 | -// 1/(k*2+1) | ||
| 57 | -__simd_callee__ inline void TaylorExpand(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 58 | - MicroAPI::RegTensor<float>& squareReg, const uint16_t expandLevel, MicroAPI::MaskReg preg) | ||
| 59 | -{ | ||
| 60 | - // arctan(x) = x - x^3/3 + x^5/5 + ... + (-1)^k*x^(k*2+1)/( k*2+1) | ||
| 61 | - // 1/(k*2+1) | ||
| 62 | - constexpr float factorList[7] = {1, -0.3333333333333333, 0.2, -0.14285714285714285, 0.1111111111111111, | ||
| 63 | - -0.09090909090909091, 0.07692307692307693}; | ||
| 64 | - uint16_t COUNT_SIX = expandLevel == TAYLOR_COUNT_SIX ? 1 : 0; | ||
| 65 | - // The initial value of dstReg is assigned as the coefficient of the last item of expansion. | ||
| 66 | - MicroAPI::Mul(squareReg, srcReg, srcReg, preg); | ||
| 67 | - MicroAPI::Mul(dstReg, srcReg, srcReg, preg); | ||
| 68 | - MicroAPI::Muls(dstReg, dstReg, factorList[expandLevel], preg); | ||
| 69 | - for (uint16_t i = 0; i < COUNT_SIX; ++i) { | ||
| 70 | - // dst*x^2+ the previois expand factor | ||
| 71 | - MicroAPI::Adds(dstReg, dstReg, factorList[6], preg); | ||
| 72 | - MicroAPI::Mul(dstReg, dstReg, squareReg, preg); | ||
| 73 | - MicroAPI::Adds(dstReg, dstReg, factorList[5], preg); | ||
| 74 | - } | ||
| 75 | - // dst*x^2+ the previois expand factor | ||
| 76 | - MicroAPI::Adds(dstReg, dstReg, factorList[4], preg); | ||
| 77 | - MicroAPI::Mul(dstReg, dstReg, squareReg, preg); | ||
| 78 | - MicroAPI::Adds(dstReg, dstReg, factorList[3], preg); | ||
| 79 | - MicroAPI::Mul(dstReg, dstReg, squareReg, preg); | ||
| 80 | - MicroAPI::Adds(dstReg, dstReg, factorList[2], preg); | ||
| 81 | - MicroAPI::Mul(dstReg, dstReg, squareReg, preg); | ||
| 82 | - MicroAPI::Adds(dstReg, dstReg, factorList[1], preg); | ||
| 83 | - MicroAPI::Mul(dstReg, dstReg, squareReg, preg); | ||
| 84 | - MicroAPI::Adds(dstReg, dstReg, factorList[0], preg); | ||
| 85 | - MicroAPI::Mul(dstReg, dstReg, srcReg, preg); | ||
| 86 | -} | ||
| 87 | - | ||
| 88 | -// (x-y)/(1+xy) | ||
| 89 | -__simd_callee__ inline void AtanTransform(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 90 | - MicroAPI::RegTensor<float>& tmpReg, const float transFactor, MicroAPI::MaskReg preg) | ||
| 91 | -{ | ||
| 92 | - // x*y | ||
| 93 | - MicroAPI::Muls(dstReg, srcReg, transFactor, preg); | ||
| 94 | - // x*y + 1 | ||
| 95 | - MicroAPI::Adds(dstReg, dstReg, 1.0f, preg); | ||
| 96 | - // x=x-y | ||
| 97 | - MicroAPI::Adds(tmpReg, srcReg, -transFactor, preg); | ||
| 98 | - // (x-y)/(1+xy) | ||
| 99 | - MicroAPI::Div(dstReg, tmpReg, dstReg, preg); | ||
| 100 | - MicroAPI::Abs(dstReg, dstReg, preg); | ||
| 101 | -} | ||
| 102 | - | ||
| 103 | -__simd_callee__ inline void AtanCompute( | ||
| 104 | - MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& castReg, MicroAPI::MaskReg preg) | ||
| 105 | -{ | ||
| 106 | - constexpr float piByFour = 0.78539816339744830961566084581988; | ||
| 107 | - constexpr float piByEight = 0.39269908169872415480783042290994; | ||
| 108 | - constexpr float tanPiByEight = 0.4142135623730950; | ||
| 109 | - | ||
| 110 | - MicroAPI::RegTensor<float> clipReg; | ||
| 111 | - MicroAPI::RegTensor<float> absReg; | ||
| 112 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 113 | - MicroAPI::RegTensor<float> tmpReg2; | ||
| 114 | - MicroAPI::RegTensor<float> squareReg; | ||
| 115 | - // when x's value is too large the first caculator of TaylorExpand will be overflow. when epsilon is 0.0001, | ||
| 116 | - // the approximate value of `tan(pi/2 - 0.0001)` is 10000 | ||
| 117 | - // Clip x to [MIN_INPUT_VALUE, MAX_INPUT_VALUE] in float | ||
| 118 | - MicroAPI::Mins(clipReg, castReg, MAX_INPUT_VALUE, preg); | ||
| 119 | - MicroAPI::Maxs(clipReg, clipReg, MIN_INPUT_VALUE, preg); | ||
| 120 | - MicroAPI::Abs(absReg, clipReg, preg); | ||
| 121 | - // 1. x in (0, tan(pi/8)) | ||
| 122 | - TaylorExpand(dstReg, absReg, squareReg, TAYLOR_COUNT_FOUR, preg); | ||
| 123 | - // 2. x in (tan(pi/8), tan(pi/4)), atan(x) = pi/8 + atan((x-tan(pi/8)) / (1 + x*tan(pi/8))) | ||
| 124 | - // normalize x to (0, tan(pi/8)) | ||
| 125 | - AtanTransform(tmpReg, absReg, tmpReg2, tanPiByEight, preg); // tan(pi/8) | ||
| 126 | - TaylorExpand(tmpReg2, tmpReg, squareReg, TAYLOR_COUNT_FOUR, preg); | ||
| 127 | - MicroAPI::Adds(tmpReg2, tmpReg2, piByEight, preg); | ||
| 128 | - MicroAPI::Min(dstReg, dstReg, tmpReg2, preg); | ||
| 129 | - // x in (tan(pi/4), +∞), atan(x) = pi/4 + atan((x-1)/(x+1)) | ||
| 130 | - // calculate |(x-1)/(x+1)|, normalize x to (0, tan(pi/4)) | ||
| 131 | - // find the minimum value between atan(|(x-1)/(x+1)|) calculate in (0, tan(pi/8)) and (tan(pi/8), tan(pi/4)) | ||
| 132 | - MicroAPI::Adds(tmpReg2, absReg, 1.0f, preg); | ||
| 133 | - MicroAPI::Adds(tmpReg, absReg, -1.0f, preg); | ||
| 134 | - MicroAPI::Div(tmpReg, tmpReg, tmpReg2, preg); | ||
| 135 | - MicroAPI::Abs(tmpReg, tmpReg, preg); // take the absolute value | ||
| 136 | - // 3. atan(|(x-1)/(x+1)|) | ||
| 137 | - TaylorExpand(tmpReg2, tmpReg, squareReg, TAYLOR_COUNT_FOUR, preg); | ||
| 138 | - // pi/4 + atan(|(x-1)/(x+1)|) | ||
| 139 | - MicroAPI::Adds(tmpReg2, tmpReg2, piByFour, preg); | ||
| 140 | - MicroAPI::Min(dstReg, dstReg, tmpReg2, preg); | ||
| 141 | - // 4.reuse the transform result in step 3, and calculate (x-tan(pi/8)) / (1 + x*tan(pi/8)) | ||
| 142 | - AtanTransform(tmpReg2, tmpReg, squareReg, tanPiByEight, preg); | ||
| 143 | - TaylorExpand(tmpReg, tmpReg2, squareReg, TAYLOR_COUNT_SIX, preg); | ||
| 144 | - // pi/8 + pi/4 + atan((x-tan(pi/8)) / (1 + x*tan(pi/8))) | ||
| 145 | - MicroAPI::Adds(tmpReg, tmpReg, piByEight, preg); | ||
| 146 | - MicroAPI::Adds(tmpReg, tmpReg, piByFour, preg); | ||
| 147 | - MicroAPI::Min(dstReg, dstReg, tmpReg, preg); | ||
| 148 | - Sign(tmpReg, clipReg, tmpReg2, preg); | ||
| 149 | - // dst = sign(x) * dst. | ||
| 150 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, preg); | ||
| 151 | -} | ||
| 152 | - | ||
| 153 | -template <typename T, bool isReuseSource = false> | ||
| 154 | -__simd_vf__ inline void AtanTaylorVFImpl( | ||
| 155 | - __ubuf__ T* dstUb, __ubuf__ T* srcUb, const uint32_t calCount) | ||
| 156 | -{ | ||
| 157 | - uint16_t repeatTimes = CeilDivision(calCount, B32_DATA_NUM_PER_REPEAT); | ||
| 158 | - | ||
| 159 | - uint32_t sreg = calCount; | ||
| 160 | - MicroAPI::MaskReg preg; | ||
| 161 | - MicroAPI::RegTensor<T> srcReg; | ||
| 162 | - MicroAPI::RegTensor<float> castReg; | ||
| 163 | - MicroAPI::RegTensor<float> dstReg; | ||
| 164 | - | ||
| 165 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 166 | - preg = MicroAPI::UpdateMask<float>(sreg); | ||
| 167 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 168 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 169 | - MicroAPI::Cast<float, T, castTraitB16ToB32>(castReg, srcReg, preg); | ||
| 170 | - } else { | ||
| 171 | - MicroAPI::DataCopy(castReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 172 | - } | ||
| 173 | - AtanCompute(dstReg, castReg, preg); | ||
| 174 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 175 | - MicroAPI::Cast<T, float, castTraitB32ToB16>(srcReg, dstReg, preg); | ||
| 176 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>( | ||
| 177 | - dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, preg); | ||
| 178 | - } else { | ||
| 179 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, dstReg, preg); | ||
| 180 | - } | ||
| 181 | - } | ||
| 182 | -} | ||
| 183 | - | ||
| 184 | -// when x < 0, Atan(x) = atan(-x) | ||
| 185 | -// when x belongs to (0, tan(pi/8)), Atan(x) = atan(x) | ||
| 186 | -// when x belongs to (tan(pi/8), tan(pi/4)), Atan(x) = pi/8 + atan((x- tan(pi/8)) / (1+ x*tan(pi/8))) | ||
| 187 | -// when x belongs to (tan(pi/4), +∞), Atan(x) = pi/4 + atan((x-1)/(x+1)) | ||
| 188 | -template <typename T, bool isReuseSource = false> | ||
| 189 | -__aicore__ inline void AtanTaylorImpl( | ||
| 190 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 191 | -{ | ||
| 192 | - __ubuf__ T* dstUb = (__ubuf__ T*)dstTensor.GetPhyAddr(); | ||
| 193 | - __ubuf__ T* srcUb = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 194 | - AtanTaylorVFImpl<T, isReuseSource>(dstUb, srcUb, calCount); | ||
| 195 | -} | ||
| 196 | - | ||
| 197 | -template <typename T, bool isReuseSource = false> | ||
| 198 | -__simd_vf__ inline void AtanPolynomialVFImpl( | ||
| 199 | - __ubuf__ T* dstUb, __ubuf__ T* srcUb, const uint32_t calCount) | ||
| 200 | -{ | ||
| 201 | - constexpr float a1 = -0.333329409; | ||
| 202 | - constexpr float a2 = 0.199887753; | ||
| 203 | - constexpr float a3 = -0.141718030; | ||
| 204 | - constexpr float a4 = 0.105184801; | ||
| 205 | - constexpr float a5 = -0.0725297481; | ||
| 206 | - constexpr float a6 = 0.0398497507; | ||
| 207 | - constexpr float a7 = -0.0143969795; | ||
| 208 | - constexpr float a8 = 0.00245002890; | ||
| 209 | - constexpr float b1 = 1.68325555; | ||
| 210 | - constexpr float b2 = 0.933189452; | ||
| 211 | - constexpr float floatOne = 1.0; | ||
| 212 | - constexpr int32_t signBit = -2147483648; | ||
| 213 | - constexpr uint16_t vlSize = static_cast<uint16_t>(GetVecLen() / sizeof(T)); | ||
| 214 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, vlSize)); | ||
| 215 | - | ||
| 216 | - uint32_t sreg = calCount; | ||
| 217 | - MicroAPI::MaskReg preg0; | ||
| 218 | - MicroAPI::MaskReg preg1; | ||
| 219 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL>(); | ||
| 220 | - MicroAPI::RegTensor<T> vreg0; | ||
| 221 | - MicroAPI::RegTensor<T> vreg1; | ||
| 222 | - MicroAPI::RegTensor<T> vreg2; | ||
| 223 | - MicroAPI::RegTensor<T> vreg3; | ||
| 224 | - MicroAPI::RegTensor<T> vreg4; | ||
| 225 | - MicroAPI::RegTensor<T> vreg5; | ||
| 226 | - MicroAPI::RegTensor<T> vreg6; | ||
| 227 | - MicroAPI::RegTensor<T> vreg7; | ||
| 228 | - MicroAPI::RegTensor<T> vreg8; | ||
| 229 | - MicroAPI::RegTensor<T> vreg9; | ||
| 230 | - MicroAPI::RegTensor<T> vreg10; | ||
| 231 | - MicroAPI::RegTensor<T> vreg11; | ||
| 232 | - MicroAPI::RegTensor<T> vreg12; | ||
| 233 | - MicroAPI::RegTensor<T> vreg13; | ||
| 234 | - MicroAPI::RegTensor<T> vreg14; | ||
| 235 | - MicroAPI::RegTensor<int32_t> vreg15; | ||
| 236 | - | ||
| 237 | - MicroAPI::Duplicate(vreg1, a1, fullMask); | ||
| 238 | - MicroAPI::Duplicate(vreg2, a2, fullMask); | ||
| 239 | - MicroAPI::Duplicate(vreg3, a3, fullMask); | ||
| 240 | - MicroAPI::Duplicate(vreg4, a4, fullMask); | ||
| 241 | - MicroAPI::Duplicate(vreg5, a5, fullMask); | ||
| 242 | - MicroAPI::Duplicate(vreg6, a6, fullMask); | ||
| 243 | - MicroAPI::Duplicate(vreg8, a8, fullMask); | ||
| 244 | - MicroAPI::Duplicate(vreg10, floatOne, fullMask); | ||
| 245 | - | ||
| 246 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 247 | - preg0 = MicroAPI::UpdateMask<T>(sreg); | ||
| 248 | - MicroAPI::DataCopy(vreg0, srcUb + i * vlSize); | ||
| 249 | - // x_con = (if x_abs > 1.0 ? 1.0 / x_abs : x_abs) | ||
| 250 | - MicroAPI::Abs(vreg9, vreg0, preg0); | ||
| 251 | - MicroAPI::Div(vreg11, vreg10, vreg9, preg0); | ||
| 252 | - MicroAPI::CompareScalar<T, CMPMODE::GE>(preg1, vreg9, floatOne, preg0); | ||
| 253 | - MicroAPI::Select(vreg11, vreg11, vreg9, preg1); | ||
| 254 | - | ||
| 255 | - // y = taylor_expansion(x_con) | ||
| 256 | - MicroAPI::Mul(vreg12, vreg11, vreg11, preg0); // s_x = x_con*x_con | ||
| 257 | - MicroAPI::Duplicate(vreg7, a7, preg0); | ||
| 258 | - MicroAPI::MulAddDst(vreg7, vreg8, vreg12, preg0); // y = a8*s_x + a7 | ||
| 259 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg6, preg0); // y = y*s_x + a6 | ||
| 260 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg5, preg0); // y = y*s_x + a5 | ||
| 261 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg4, preg0); // y = y*s_x + a4 | ||
| 262 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg3, preg0); // y = y*s_x + a3 | ||
| 263 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg2, preg0); // y = y*s_x + a2 | ||
| 264 | - MicroAPI::FusedMulDstAdd(vreg7, vreg12, vreg1, preg0); // y = y*s_x + a1 | ||
| 265 | - | ||
| 266 | - MicroAPI::Mul(vreg12, vreg7, vreg12, preg0); // tmp = (y*s_x) | ||
| 267 | - MicroAPI::FusedMulDstAdd(vreg12, vreg11, vreg11, preg0); // y = (y*s_x) * x_con + x_con | ||
| 268 | - | ||
| 269 | - MicroAPI::Duplicate(vreg11, b1, preg0); | ||
| 270 | - MicroAPI::Duplicate(vreg14, b2, preg0); | ||
| 271 | - MicroAPI::Neg(vreg13, vreg12, preg0); // -1.0*y | ||
| 272 | - MicroAPI::MulAddDst(vreg13, vreg11, vreg14, preg0); // y_if = b1*b2 + (-1.0 * y) //vmula | ||
| 273 | - MicroAPI::Select(vreg13, vreg13, vreg12, preg1); // y = (if x_abs > 1.0 ? y_if : y) | ||
| 274 | - | ||
| 275 | - // x_s32 = f32_to_s32(float(x)) | ||
| 276 | - // x_s32_temp = x_s32 & 0x80000000 | ||
| 277 | - MicroAPI::Duplicate(vreg15, signBit, preg0); | ||
| 278 | - MicroAPI::And(vreg15, (MicroAPI::RegTensor<int32_t>&)vreg0, vreg15, preg0); | ||
| 279 | - // y_s32 = f32_to_s32(float(y)) | ||
| 280 | - // y_temp = y_s32 | x_s32_temp | ||
| 281 | - MicroAPI::Or(vreg15, (MicroAPI::RegTensor<int32_t>&)vreg13, vreg15, preg0); | ||
| 282 | - // y = s32_to_f32(y_temp) | ||
| 283 | - MicroAPI::DataCopy(dstUb + i * vlSize, (MicroAPI::RegTensor<T>&)vreg15, preg0); | ||
| 284 | - } | ||
| 285 | -} | ||
| 286 | - | ||
| 287 | -template <typename T, bool isReuseSource = false> | ||
| 288 | -__aicore__ inline void AtanPolynomialImpl( | ||
| 289 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 290 | -{ | ||
| 291 | - __ubuf__ T* dstUb = (__ubuf__ T*)dstTensor.GetPhyAddr(); | ||
| 292 | - __ubuf__ T* srcUb = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 293 | - | ||
| 294 | - AtanPolynomialVFImpl<T, isReuseSource>(dstUb, srcUb, calCount); | ||
| 295 | -} | ||
| 296 | -} // namespace Internal | ||
| 297 | - | ||
| 298 | -template <typename T, bool isReuseSource, const AtanConfig& config> | ||
| 299 | -__aicore__ inline void AtanImpl( | ||
| 300 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 301 | -{ | ||
| 302 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Atan"); | ||
| 303 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Atan"); | ||
| 304 | - ASCENDC_ASSERT((calCount <= srcTensor.GetSize()), { | ||
| 305 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than srcTensor length %u", calCount, | ||
| 306 | - srcTensor.GetSize()); | ||
| 307 | - }); | ||
| 308 | - ASCENDC_ASSERT((calCount <= dstTensor.GetSize()), { | ||
| 309 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than dstTensor length %u", calCount, | ||
| 310 | - dstTensor.GetSize()); | ||
| 311 | - }); | ||
| 312 | - | ||
| 313 | - if constexpr (config.algo == defaultAtanConfig.algo) { | ||
| 314 | - static_assert(SupportType<T, half, float>(), | ||
| 315 | - "Atan with TAYLOR_EXPANSION algorithm only support half/float data type on current device!"); | ||
| 316 | - Internal::AtanTaylorImpl(dstTensor, srcTensor, calCount); | ||
| 317 | - } else { | ||
| 318 | - static_assert(SupportType<T, float>(), | ||
| 319 | - "Atan with POLYNOMIAL_APPROXIMATION algorithm only support float data type on current device!!"); | ||
| 320 | - Internal::AtanPolynomialImpl(dstTensor, srcTensor, calCount); | ||
| 321 | - } | ||
| 322 | -} | ||
| 323 | - | ||
| 324 | -template <typename T, bool isReuseSource = false, const AtanConfig& config = defaultAtanConfig> | ||
| 325 | -__aicore__ inline void AtanImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 326 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 327 | -{ | ||
| 328 | - // Only for AI Vector Core. | ||
| 329 | - if ASCEND_IS_AIC { | ||
| 330 | - return; | ||
| 331 | - } | ||
| 332 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Atan"); | ||
| 333 | - | ||
| 334 | - AtanImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 335 | -} | ||
| 336 | - | ||
| 337 | -/*! | ||
| 338 | - * \ingroup Atan | ||
| 339 | - * \brief compute Atan elementwisely | ||
| 340 | - * \tparam T: half/float | ||
| 341 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 342 | - * this parameter is reserved, please use the default value. | ||
| 343 | - * \param [out] dstTensor: output LocalTensor | ||
| 344 | - * \param [in] srcTensor: input LocalTensor | ||
| 345 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 346 | - * whose required space size should refer to corresponding tiling API, which is defined at atan_tiling.h. | ||
| 347 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 348 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 349 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 350 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 351 | - */ | ||
| 352 | -template <typename T, bool isReuseSource = false, const AtanConfig& config = defaultAtanConfig> | ||
| 353 | -__aicore__ inline void Atan(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 354 | - const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 355 | -{ | ||
| 356 | - Atan<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, srcTensor.GetSize()); | ||
| 357 | -} | ||
| 358 | - | ||
| 359 | - /*! | ||
| 360 | - * \ingroup Atan | ||
| 361 | - * \brief compute Atan elementwisely | ||
| 362 | - * \tparam T: half/float | ||
| 363 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 364 | - * this parameter is reserved, please use the default value. | ||
| 365 | - * \param [out] dstTensor: output LocalTensor | ||
| 366 | - * \param [in] srcTensor: input LocalTensor | ||
| 367 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 368 | - * whose required space size should refer to corresponding tiling API, which is defined at atan_tiling.h. | ||
| 369 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 370 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 371 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 372 | - * \param [in] calCount: the number of elements to be processed. | ||
| 373 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 374 | - */ | ||
| 375 | -template <typename T, bool isReuseSource = false, const AtanConfig& config = defaultAtanConfig> | ||
| 376 | -__aicore__ inline void Atan(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 377 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 378 | -{ | ||
| 379 | - AtanImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 380 | -} | ||
| 381 | - | ||
| 382 | - /*! | ||
| 383 | - * \ingroup Atan | ||
| 384 | - * \brief compute Atan elementwisely | ||
| 385 | - * \tparam T: half/float | ||
| 386 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 387 | - * this parameter is reserved, please use the default value. | ||
| 388 | - * \param [out] dstTensor: output LocalTensor | ||
| 389 | - * \param [in] srcTensor: input LocalTensor | ||
| 390 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 391 | - */ | ||
| 392 | -template <typename T, bool isReuseSource = false, const AtanConfig& config = defaultAtanConfig> | ||
| 393 | -__aicore__ inline void Atan(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor) | ||
| 394 | -{ | ||
| 395 | - Atan<T, isReuseSource, config>(dstTensor, srcTensor, srcTensor.GetSize()); | ||
| 396 | -} | ||
| 397 | - | ||
| 398 | - /*! | ||
| 399 | - * \ingroup Atan | ||
| 400 | - * \brief compute Atan elementwisely | ||
| 401 | - * \tparam T: half/float | ||
| 402 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 403 | - * this parameter is reserved, please use the default value. | ||
| 404 | - * \param [out] dstTensor: output LocalTensor | ||
| 405 | - * \param [in] srcTensor: input LocalTensor | ||
| 406 | - * \param [in] calCount: the number of elements to be processed. | ||
| 407 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 408 | - */ | ||
| 409 | -template <typename T, bool isReuseSource = false, const AtanConfig& config = defaultAtanConfig> | ||
| 410 | -__aicore__ inline void Atan(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 411 | - const uint32_t calCount) | ||
| 412 | -{ | ||
| 413 | - AtanImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 414 | -} | ||
| 415 | -} // namespace AscendC | ||
| 416 | - | ||
Dimpl/adv_api/detail/math/axpy/axpy_l300_impl.h+0-120
| @@ -1,120 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file axpy_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 24 | -namespace AscendC { | ||
| 25 | -namespace AxpyAPI { | ||
| 26 | -constexpr MicroAPI::CastTrait castTraitF162F32 = { | ||
| 27 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 28 | -template<typename T, typename U> | ||
| 29 | -__simd_vf__ inline void AxpyCompute(__ubuf__ T* dst, __ubuf__ U* src, U scalarValue, uint32_t calCount, | ||
| 30 | - uint16_t repeatTimes, uint16_t oneRepSize, uint32_t mainBlockCount, | ||
| 31 | - uint32_t tailCount, uint16_t offset, uint16_t singleMainBlockCtrl) | ||
| 32 | -{ | ||
| 33 | - MicroAPI::MaskReg mask, maskTail; | ||
| 34 | - MicroAPI::RegTensor<T> dstVreg; | ||
| 35 | - MicroAPI::RegTensor<U> srcVreg; | ||
| 36 | - mask = MicroAPI::UpdateMask<T>(mainBlockCount); | ||
| 37 | - maskTail = MicroAPI::UpdateMask<T>(tailCount); | ||
| 38 | - if constexpr (IsSameType<U, half>::value && IsSameType<T, float>::value) { | ||
| 39 | - MicroAPI::RegTensor<float> tempSrcVreg; | ||
| 40 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 41 | - MicroAPI::DataCopy<U, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcVreg, src + i * oneRepSize); | ||
| 42 | - MicroAPI::Cast<float, U, castTraitF162F32>(tempSrcVreg, srcVreg, mask); | ||
| 43 | - MicroAPI::DataCopy(dstVreg, dst + i * oneRepSize); | ||
| 44 | - MicroAPI::Axpy(dstVreg, tempSrcVreg, scalarValue, mask); | ||
| 45 | - MicroAPI::DataCopy(dst + i * oneRepSize, dstVreg, mask); | ||
| 46 | - // unroll | ||
| 47 | - MicroAPI::DataCopy<U, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcVreg, src + i * oneRepSize + offset); | ||
| 48 | - MicroAPI::Cast<float, U, castTraitF162F32>(tempSrcVreg, srcVreg, mask); | ||
| 49 | - MicroAPI::DataCopy(dstVreg, dst + i * oneRepSize + offset); | ||
| 50 | - MicroAPI::Axpy(dstVreg, tempSrcVreg, scalarValue, mask); | ||
| 51 | - MicroAPI::DataCopy(dst + i * oneRepSize + offset, dstVreg, mask); | ||
| 52 | - } | ||
| 53 | - for (uint16_t j = 0; j < singleMainBlockCtrl; ++j) { | ||
| 54 | - MicroAPI::DataCopy<U, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcVreg, src + repeatTimes * oneRepSize * 2); | ||
| 55 | - MicroAPI::Cast<float, U, castTraitF162F32>(tempSrcVreg, srcVreg, mask); | ||
| 56 | - MicroAPI::DataCopy(dstVreg, dst + repeatTimes * oneRepSize * 2); | ||
| 57 | - MicroAPI::Axpy(dstVreg, tempSrcVreg, scalarValue, mask); | ||
| 58 | - MicroAPI::DataCopy(dst + repeatTimes * oneRepSize * 2, dstVreg, mask); | ||
| 59 | - } | ||
| 60 | - MicroAPI::DataCopy<U, MicroAPI::LoadDist::DIST_UNPACK_B16>( | ||
| 61 | - srcVreg, src + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize); | ||
| 62 | - MicroAPI::Cast<float, U, castTraitF162F32>(tempSrcVreg, srcVreg, maskTail); | ||
| 63 | - MicroAPI::DataCopy(dstVreg, dst + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize); | ||
| 64 | - MicroAPI::Axpy(dstVreg, tempSrcVreg, scalarValue, maskTail); | ||
| 65 | - MicroAPI::DataCopy(dst + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize, dstVreg, maskTail); | ||
| 66 | - } else { | ||
| 67 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 68 | - MicroAPI::DataCopy(srcVreg, src + i * oneRepSize); | ||
| 69 | - MicroAPI::DataCopy(dstVreg, dst + i * oneRepSize); | ||
| 70 | - MicroAPI::Axpy(dstVreg, srcVreg, scalarValue, mask); | ||
| 71 | - MicroAPI::DataCopy(dst + i * oneRepSize, dstVreg, mask); | ||
| 72 | - // unroll | ||
| 73 | - MicroAPI::DataCopy(srcVreg, src + i * oneRepSize + offset); | ||
| 74 | - MicroAPI::DataCopy(dstVreg, dst + i * oneRepSize + offset); | ||
| 75 | - MicroAPI::Axpy(dstVreg, srcVreg, scalarValue, mask); | ||
| 76 | - MicroAPI::DataCopy(dst + i * oneRepSize + offset, dstVreg, mask); | ||
| 77 | - } | ||
| 78 | - for (uint16_t j = 0; j < singleMainBlockCtrl; ++j) { | ||
| 79 | - MicroAPI::DataCopy(srcVreg, src + repeatTimes * oneRepSize * 2); | ||
| 80 | - MicroAPI::DataCopy(dstVreg, dst + repeatTimes * oneRepSize * 2); | ||
| 81 | - MicroAPI::Axpy(dstVreg, srcVreg, scalarValue, mask); | ||
| 82 | - MicroAPI::DataCopy(dst + repeatTimes * oneRepSize * 2, dstVreg, mask); | ||
| 83 | - } | ||
| 84 | - MicroAPI::DataCopy(srcVreg, src + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize); | ||
| 85 | - MicroAPI::DataCopy(dstVreg, dst + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize); | ||
| 86 | - MicroAPI::Axpy(dstVreg, srcVreg, scalarValue, maskTail); | ||
| 87 | - MicroAPI::DataCopy(dst + repeatTimes * oneRepSize * 2 + singleMainBlockCtrl * oneRepSize, dstVreg, maskTail); | ||
| 88 | - } | ||
| 89 | -} | ||
| 90 | -}//namespace AxpyAPI | ||
| 91 | -template <typename T, typename U, bool isReuseSource> | ||
| 92 | -__aicore__ inline void AxpyImpl(const LocalTensor<T> &dstLocal, const LocalTensor<U> &srcLocal, const U scalarValue, | ||
| 93 | - const LocalTensor<uint8_t> &sharedTmpBuffer, const uint32_t calCount) | ||
| 94 | -{ | ||
| 95 | - CHECK_FUNC_HIGHLEVEL_API(Axpy, (T, U, isReuseSource), (dstLocal, srcLocal, scalarValue, sharedTmpBuffer, calCount)); | ||
| 96 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 97 | - CheckTensorPosition(dstLocal, "dstLocal", "VECIN, VECOUT, VECCALC"); | ||
| 98 | - CheckTensorPosition(srcLocal, "srcLocal", "VECIN, VECOUT, VECCALC"); | ||
| 99 | - CheckCalCount(calCount, "calCount", dstLocal, "dstLocal", "Axpy"); | ||
| 100 | - CheckCalCount(calCount, "calCount", srcLocal, "srcLocal", "Axpy"); | ||
| 101 | - static_assert(SupportType<T, half, float>(), "Axpy current dst data type is not supported on current device!"); | ||
| 102 | - static_assert(SupportType<U, half, float>(), "Axpy current src data type is not supported on current device!"); | ||
| 103 | - __ubuf__ T *dst = (__ubuf__ T *)dstLocal.GetPhyAddr(); | ||
| 104 | - __ubuf__ U *src = (__ubuf__ U *)srcLocal.GetPhyAddr(); | ||
| 105 | - constexpr uint16_t oneRepSize = GetVecLen() / sizeof(T); | ||
| 106 | - const uint32_t mainBlockCount = oneRepSize; | ||
| 107 | - uint32_t tailCount = calCount % oneRepSize; | ||
| 108 | - uint16_t repeatTimes = calCount / oneRepSize; | ||
| 109 | - if (tailCount == 0 && repeatTimes > 0) { | ||
| 110 | - repeatTimes--; | ||
| 111 | - tailCount += oneRepSize; | ||
| 112 | - } | ||
| 113 | - uint16_t repeatTimesUnRoll = repeatTimes / 2; | ||
| 114 | - uint16_t singleMainBlockCtrl = repeatTimes % 2; | ||
| 115 | - uint16_t offset = repeatTimesUnRoll * oneRepSize; | ||
| 116 | - AxpyAPI::AxpyCompute<T, U>(dst, src, scalarValue, calCount, repeatTimesUnRoll, oneRepSize, mainBlockCount, | ||
| 117 | - tailCount, offset, singleMainBlockCtrl); | ||
| 118 | -} | ||
| 119 | -} // namespace AscendC | ||
| 120 | - | ||
Dimpl/adv_api/detail/math/ceil/ceil_l300_impl.h+0-72
| @@ -1,72 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file ceil_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | -namespace AscendC { | ||
| 20 | -template <typename T, bool isReuseSource = false> | ||
| 21 | -__simd_vf__ inline void CeilCompute(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t calCount, | ||
| 22 | - const uint16_t repeatTimes) | ||
| 23 | -{ | ||
| 24 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 25 | - MicroAPI::RegTensor<T> srcReg; | ||
| 26 | - MicroAPI::RegTensor<T> dstReg; | ||
| 27 | - MicroAPI::MaskReg maskReg; | ||
| 28 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 29 | - maskReg = MicroAPI::UpdateMask<T>(calCount); | ||
| 30 | - MicroAPI::DataCopy<T>(srcReg, srcUb + i * repeatElm); | ||
| 31 | - MicroAPI::Truncate<T, RoundMode::CAST_CEIL>(dstReg, srcReg, maskReg); | ||
| 32 | - MicroAPI::DataCopy<T>(dstUb + i * repeatElm, dstReg, maskReg); | ||
| 33 | - } | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | -template <typename T, bool isReuseSource = false> | ||
| 37 | -__aicore__ inline void CeilImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 38 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 39 | -{ | ||
| 40 | - if ASCEND_IS_AIC { | ||
| 41 | - return; | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 45 | - | ||
| 46 | - CeilImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 47 | -} | ||
| 48 | - | ||
| 49 | -template <typename T, bool isReuseSource = false> | ||
| 50 | -__aicore__ inline void CeilImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 51 | - const uint32_t calCount) | ||
| 52 | -{ | ||
| 53 | - if ASCEND_IS_AIC { | ||
| 54 | - return; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - static_assert(SupportType<T, float, half>(), | ||
| 58 | - "Ceil only support half/float data type on current device"); | ||
| 59 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 60 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 61 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Round"); | ||
| 62 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Round"); | ||
| 63 | - | ||
| 64 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 65 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 66 | - constexpr uint32_t repeatElm = GetVecLen() / sizeof(T); | ||
| 67 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, repeatElm)); | ||
| 68 | - | ||
| 69 | - CeilCompute<T, isReuseSource>(dstUb, srcUb, calCount, repeatTimes); | ||
| 70 | -} | ||
| 71 | -} // namespace AscendC | ||
| 72 | - | ||
Dimpl/adv_api/detail/math/cos/cos_l300_impl.h+0-306
| @@ -1,306 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file cos_L300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace Internal { | ||
| 24 | -// define the number of x div pi | ||
| 25 | -constexpr float COS_PI_FOR_X_TODIV = 0.3183098733425140380859375; | ||
| 26 | -// define the PI for compute | ||
| 27 | -constexpr float PI_0 = 3.140625; | ||
| 28 | -constexpr float COS_KPI_FIRS_PI_MULS = 0.0009670257568359375; | ||
| 29 | -constexpr float COS_KPI_TWI_PI_MULS = 6.2771141529083251953125e-7; | ||
| 30 | -constexpr float COS_KPI_THIR_PI_MULS = 1.21644916362129151821136474609375e-10; | ||
| 31 | -constexpr float COS_KPI_FOR_PI_MULS = -1.0290623200529979163359041220560e-13; | ||
| 32 | -// define the number of down of pi_div | ||
| 33 | -constexpr float COS_PI_DOWN = 1.57079637050628662109375; | ||
| 34 | -// kpi_2 | ||
| 35 | -constexpr float COS_PI_RESDOWN_ADDS_NEG = -0.00000004371139000189375; | ||
| 36 | -// define the number of cos compute | ||
| 37 | -constexpr float COS_RES_MULIT_SCA = 2.604926501e-6; | ||
| 38 | -constexpr float COS_RES_ADDICT_UP = -0.0001980894471; | ||
| 39 | -constexpr float COS_2ADDS = 0.008333049340; | ||
| 40 | -constexpr float COS_3ADDS = -0.1666665792; | ||
| 41 | -constexpr float COS_POINT_FIVE = 0.5; | ||
| 42 | -constexpr float COS_M4_SCA = 4.0; | ||
| 43 | -constexpr float COS_K2_SCA = -2.0; | ||
| 44 | -constexpr float SCALAR_ONE = 1.0; | ||
| 45 | - | ||
| 46 | -__simd_callee__ inline void CosPolynomialApproximation(MicroAPI::RegTensor<float>& dstReg, | ||
| 47 | - MicroAPI::RegTensor<float>& srcReg, MicroAPI::RegTensor<float>& x, MicroAPI::RegTensor<float>& round, | ||
| 48 | - MicroAPI::RegTensor<float>& kpi, MicroAPI::MaskReg mask) | ||
| 49 | -{ | ||
| 50 | - // k = round(x * invpi + 1/2) | ||
| 51 | - MicroAPI::Muls(round, srcReg, COS_PI_FOR_X_TODIV, mask); | ||
| 52 | - MicroAPI::Adds(round, round, COS_POINT_FIVE, mask); | ||
| 53 | - // tie to even | ||
| 54 | - MicroAPI::Truncate<float, RoundMode::CAST_RINT, MicroAPI::MaskMergeMode::ZEROING>(round, round, mask); | ||
| 55 | - // x -= k * pi_0 | ||
| 56 | - MicroAPI::Muls(kpi, round, PI_0, mask); | ||
| 57 | - MicroAPI::Sub(x, srcReg, kpi, mask); | ||
| 58 | - | ||
| 59 | - // x -= k * pi_1 | ||
| 60 | - MicroAPI::Muls(kpi, round, COS_KPI_FIRS_PI_MULS, mask); | ||
| 61 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 62 | - | ||
| 63 | - // x = x + COS_PI_DOWN | ||
| 64 | - MicroAPI::Adds(x, x, COS_PI_DOWN, mask); | ||
| 65 | - | ||
| 66 | - // x -= k * pi_2 | ||
| 67 | - MicroAPI::Muls(kpi, round, COS_KPI_TWI_PI_MULS, mask); | ||
| 68 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 69 | - | ||
| 70 | - // x -= k * pi_3 | ||
| 71 | - MicroAPI::Muls(kpi, round, COS_KPI_THIR_PI_MULS, mask); | ||
| 72 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 73 | - | ||
| 74 | - // x -= k * pi_4 | ||
| 75 | - MicroAPI::Muls(kpi, round, COS_KPI_FOR_PI_MULS, mask); | ||
| 76 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 77 | - | ||
| 78 | - // x = x + COS_PI_RESDOWN_ADDS_NEG | ||
| 79 | - MicroAPI::Adds(x, x, COS_PI_RESDOWN_ADDS_NEG, mask); | ||
| 80 | - | ||
| 81 | - // x^2 = mul(input_x, input_x) | ||
| 82 | - MicroAPI::Mul(kpi, x, x, mask); | ||
| 83 | - // kover2 | ||
| 84 | - MicroAPI::Muls(dstReg, round, COS_POINT_FIVE, mask); | ||
| 85 | - MicroAPI::Truncate<float, RoundMode::CAST_FLOOR, MicroAPI::MaskMergeMode::ZEROING>(dstReg, dstReg, mask); | ||
| 86 | - | ||
| 87 | - // kover2floorm4 | ||
| 88 | - MicroAPI::Muls(dstReg, dstReg, COS_M4_SCA, mask); | ||
| 89 | - // k2 | ||
| 90 | - MicroAPI::Muls(round, round, COS_K2_SCA, mask); | ||
| 91 | - // sign | ||
| 92 | - MicroAPI::Add(dstReg, dstReg, round, mask); | ||
| 93 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_ONE, mask); | ||
| 94 | - | ||
| 95 | - // res_up = mul(x^2, 2.604926501e-6) | ||
| 96 | - MicroAPI::Muls(round, kpi, COS_RES_MULIT_SCA, mask); | ||
| 97 | - MicroAPI::Adds(round, round, COS_RES_ADDICT_UP, mask); | ||
| 98 | - // res_up = mul(res_up, x^2) | ||
| 99 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 100 | - MicroAPI::Adds(round, round, COS_2ADDS, mask); | ||
| 101 | - // res_up = mul(res_up, x^2) | ||
| 102 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 103 | - MicroAPI::Adds(round, round, COS_3ADDS, mask); | ||
| 104 | - // res_up = mul(res_up, x^2) | ||
| 105 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 106 | - MicroAPI::Adds(round, round, SCALAR_ONE, mask); | ||
| 107 | - // sin(x) = xP(x) | ||
| 108 | - MicroAPI::Mul(round, round, x, mask); | ||
| 109 | - MicroAPI::Mul(dstReg, round, dstReg, mask); | ||
| 110 | - MicroAPI::Mins(dstReg, dstReg, SCALAR_ONE, mask); | ||
| 111 | - MicroAPI::Maxs(dstReg, dstReg, -SCALAR_ONE, mask); | ||
| 112 | -} | ||
| 113 | - | ||
| 114 | -template <typename T> | ||
| 115 | -__simd_vf__ inline void CosPolymonial(__ubuf__ T* dst, __ubuf__ T* src, uint32_t calCount, uint16_t repeat) | ||
| 116 | -{ | ||
| 117 | - MicroAPI::RegTensor<T> x; | ||
| 118 | - MicroAPI::RegTensor<float> xTmp; | ||
| 119 | - MicroAPI::RegTensor<float> round; | ||
| 120 | - MicroAPI::RegTensor<float> kpi; | ||
| 121 | - MicroAPI::RegTensor<T> srcReg; | ||
| 122 | - MicroAPI::RegTensor<float> srcTmp; | ||
| 123 | - MicroAPI::RegTensor<T> dstReg; | ||
| 124 | - MicroAPI::RegTensor<float> dstTmp; | ||
| 125 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 126 | - MicroAPI::MaskReg mask; | ||
| 127 | - MicroAPI::MaskReg maskAll = MicroAPI::CreateMask<uint8_t>(); | ||
| 128 | - for (uint16_t i = 0; i < repeat; i++) { | ||
| 129 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 130 | - if constexpr (std::is_same<T, half>::value) { | ||
| 131 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, src + i * oneRepSize); | ||
| 132 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(srcTmp, srcReg, mask); | ||
| 133 | - CosPolynomialApproximation(dstTmp, srcTmp, xTmp, round, kpi, mask); | ||
| 134 | - MicroAPI::Cast<half, float, castTraitB32ToB16>(dstReg, dstTmp, mask); | ||
| 135 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * oneRepSize, dstReg, mask); | ||
| 136 | - } else { | ||
| 137 | - MicroAPI::DataCopy(srcReg, src + i * oneRepSize); | ||
| 138 | - CosPolynomialApproximation(dstReg, srcReg, xTmp, round, kpi, mask); | ||
| 139 | - MicroAPI::DataCopy(dst + i * oneRepSize, dstReg, mask); | ||
| 140 | - } | ||
| 141 | - } | ||
| 142 | -} | ||
| 143 | -} // namespace Internal | ||
| 144 | - | ||
| 145 | -template <typename T> | ||
| 146 | -__aicore__ inline void CosPolynomialImpl(__ubuf__ T *dst, __ubuf__ T *src, uint32_t calCount) | ||
| 147 | -{ | ||
| 148 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 149 | - uint16_t repeat = CeilDivision(calCount, oneRepSize); | ||
| 150 | - Internal::CosPolymonial<T>(dst, src, calCount, repeat); | ||
| 151 | -} | ||
| 152 | - | ||
| 153 | -__aicore__ inline constexpr uint32_t GetCosTmpBufferLiveNode() { | ||
| 154 | - constexpr uint32_t tmpBufferLiveNode = sizeof(float) * 2; | ||
| 155 | - return tmpBufferLiveNode; | ||
| 156 | -} | ||
| 157 | - | ||
| 158 | -template<typename T> | ||
| 159 | -__aicore__ inline uint32_t GetCosTmpBufferSize(const LocalTensor<uint8_t>& sharedTmpBuffer) { | ||
| 160 | - uint32_t sharedTmpBufferSize = sharedTmpBuffer.GetSize() / GetCosTmpBufferLiveNode(); | ||
| 161 | - return AlignUp(sharedTmpBufferSize, GetDataBlockSizeInBytes()) / sizeof(T); | ||
| 162 | -} | ||
| 163 | - | ||
| 164 | -template<typename T, bool isReuseSource = false, const CosConfig &config = defaultCosConfig> | ||
| 165 | -__aicore__ inline void CosImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 166 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 167 | -{ | ||
| 168 | - // Only for AI Vector Core. | ||
| 169 | - if ASCEND_IS_AIC { | ||
| 170 | - return; | ||
| 171 | - } | ||
| 172 | - | ||
| 173 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 174 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Cos"); | ||
| 175 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Cos"); | ||
| 176 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Cos"); | ||
| 177 | - ASCENDC_ASSERT((calCount <= srcTensor.GetSize()), { | ||
| 178 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than srcTensor length %u", calCount, | ||
| 179 | - srcTensor.GetSize()); | ||
| 180 | - }); | ||
| 181 | - ASCENDC_ASSERT((calCount <= dstTensor.GetSize()), { | ||
| 182 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than dstTensor length %u", calCount, | ||
| 183 | - dstTensor.GetSize()); | ||
| 184 | - }); | ||
| 185 | - | ||
| 186 | - if constexpr(config.algo == CosAlgo::POLYNOMIAL_APPROXIMATION) { | ||
| 187 | - CosPolynomialImpl((__ubuf__ T*)dstTensor.GetPhyAddr(), (__ubuf__ T*)srcTensor.GetPhyAddr(), calCount); | ||
| 188 | - } else if constexpr (config.algo == CosAlgo::RADIAN_REDUCTION) { | ||
| 189 | - uint32_t sharedTmpBufferSize = GetCosTmpBufferSize<T>(sharedTmpBuffer); | ||
| 190 | - uint32_t count = calCount; | ||
| 191 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, sharedTmpBufferSize)); | ||
| 192 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 193 | - uint32_t remainCount = count - sharedTmpBufferSize * i; | ||
| 194 | - uint32_t oneRepSize = remainCount < sharedTmpBufferSize ? remainCount : sharedTmpBufferSize; | ||
| 195 | - CosRadianReductionImpl((__ubuf__ T*)dstTensor.GetPhyAddr() + i * sharedTmpBufferSize, | ||
| 196 | - (__ubuf__ T*)srcTensor.GetPhyAddr() + i * sharedTmpBufferSize, | ||
| 197 | - (__ubuf__ uint32_t*)sharedTmpBuffer.GetPhyAddr(), oneRepSize); | ||
| 198 | - } | ||
| 199 | - } | ||
| 200 | -} | ||
| 201 | - | ||
| 202 | -template <typename T, bool isReuseSource = false, const CosConfig &config = defaultCosConfig> | ||
| 203 | -__aicore__ inline void CosImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 204 | - const uint32_t calCount) | ||
| 205 | -{ | ||
| 206 | - // Only for AI Vector Core. | ||
| 207 | - if ASCEND_IS_AIC { | ||
| 208 | - return; | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - // Using the Stack Space to Allocate tmpBuffer | ||
| 212 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 213 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(sharedTmpBuffer); | ||
| 214 | - ASCENDC_ASSERT((ans), { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 215 | - CosImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 216 | -} | ||
| 217 | - | ||
| 218 | -__aicore__ inline void CosCastFullMask( | ||
| 219 | - const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, RoundMode castType) | ||
| 220 | -{ | ||
| 221 | - uint64_t newMask = 64; | ||
| 222 | - Cast<float, float, false>(dstTensor, srcTensor, castType, newMask, 1, | ||
| 223 | - { 1, 1, DEFAULT_REPEAT_STRIDE, DEFAULT_REPEAT_STRIDE }); | ||
| 224 | - PipeBarrier<PIPE_V>(); | ||
| 225 | -} | ||
| 226 | -/*! | ||
| 227 | - * \ingroup Cos | ||
| 228 | - * \brief compute Cos elementwisely | ||
| 229 | - * \tparam T: half/float | ||
| 230 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, only support | ||
| 231 | - * float input data type | ||
| 232 | - * \param [out] dstTensor: output LocalTensor | ||
| 233 | - * \param [in] srcTensor: input LocalTensor | ||
| 234 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 235 | - * whose required space size should refer to corresponding tiling API, which is defined at cos_tiling.h. | ||
| 236 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 237 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 238 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 239 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 240 | - * Input data valid range should be [-65504, 65504] | ||
| 241 | - */ | ||
| 242 | -template <typename T, bool isReuseSource = false, const CosConfig &config> | ||
| 243 | -__aicore__ inline void Cos(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 244 | - const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 245 | -{ | ||
| 246 | - Cos<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, srcTensor.GetSize()); | ||
| 247 | -} | ||
| 248 | - | ||
| 249 | -/*! | ||
| 250 | - * \ingroup Cos | ||
| 251 | - * \brief compute Cos elementwisely | ||
| 252 | - * \tparam T: half/float | ||
| 253 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 254 | - * \param [out] dstTensor: output LocalTensor | ||
| 255 | - * \param [in] srcTensor: input LocalTensor | ||
| 256 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 257 | - * whose required space size should refer to corresponding tiling API, which is defined at cos_tiling.h. | ||
| 258 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 259 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 260 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 261 | - * \param [in] calCount: the number of elements to be processed. | ||
| 262 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 263 | - * Input data valid range should be [-65504, 65504] | ||
| 264 | - */ | ||
| 265 | -template<typename T, bool isReuseSource = false, const CosConfig &config> | ||
| 266 | -__aicore__ inline void Cos(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 267 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 268 | -{ | ||
| 269 | - CosImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 270 | -} | ||
| 271 | - | ||
| 272 | -/*! | ||
| 273 | - * \ingroup Cos | ||
| 274 | - * \brief compute Cos elementwisely | ||
| 275 | - * \tparam T: half/float | ||
| 276 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 277 | - * \param [out] dstTensor: output LocalTensor | ||
| 278 | - * \param [in] srcTensor: input LocalTensor | ||
| 279 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 280 | - * Input data valid range should be [-65504, 65504] | ||
| 281 | - */ | ||
| 282 | -template <typename T, bool isReuseSource = false, const CosConfig &config> | ||
| 283 | -__aicore__ inline void Cos(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor) | ||
| 284 | -{ | ||
| 285 | - Cos<T, isReuseSource, config>(dstTensor, srcTensor, srcTensor.GetSize()); | ||
| 286 | -} | ||
| 287 | - | ||
| 288 | -/*! | ||
| 289 | - * \ingroup Cos | ||
| 290 | - * \brief compute Cos elementwisely | ||
| 291 | - * \tparam T: half/float | ||
| 292 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 293 | - * \param [out] dstTensor: output LocalTensor | ||
| 294 | - * \param [in] srcTensor: input LocalTensor | ||
| 295 | - * \param [in] calCount: the number of elements to be processed. | ||
| 296 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 297 | - * Input data valid range should be [-65504, 65504] | ||
| 298 | - */ | ||
| 299 | -template<typename T, bool isReuseSource = false, const CosConfig &config> | ||
| 300 | -__aicore__ inline void Cos(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 301 | - const uint32_t calCount) | ||
| 302 | -{ | ||
| 303 | - CosImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 304 | -} | ||
| 305 | -} // namespace AscendC | ||
| 306 | - | ||
Dimpl/adv_api/detail/math/cosh/cosh_l300_impl.h+0-98
| @@ -1,98 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file cosh_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace Internal { | ||
| 23 | -// Computes cosh values based on input types. | ||
| 24 | -// According formula: cosh(x) = (e^x + e^(-x))/2 = e^(x-ln2) + 0.25/(e^(x-ln2)). | ||
| 25 | -template <typename T> | ||
| 26 | -__simd_vf__ inline void CoshCompute(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t calCount, uint16_t repeatTimes) | ||
| 27 | -{ | ||
| 28 | - constexpr float scalarNegLnTwo = -0.6931472; | ||
| 29 | - constexpr float scalarBrc = 0.25; | ||
| 30 | - constexpr uint32_t vlSize = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 31 | - MicroAPI::MaskReg coshMask; | ||
| 32 | - MicroAPI::RegTensor<float> brcReg; | ||
| 33 | - MicroAPI::RegTensor<T> srcReg; | ||
| 34 | - MicroAPI::RegTensor<float> castReg; | ||
| 35 | - MicroAPI::RegTensor<float> computeReg0; | ||
| 36 | - MicroAPI::RegTensor<float> computeReg1; | ||
| 37 | - MicroAPI::RegTensor<float> resReg; | ||
| 38 | - MicroAPI::RegTensor<T> dstReg; | ||
| 39 | - MicroAPI::Duplicate(brcReg, scalarBrc); | ||
| 40 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 41 | - coshMask = MicroAPI::UpdateMask<float>(calCount); | ||
| 42 | - if constexpr (SupportBytes<T, 2>()) { | ||
| 43 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * vlSize); | ||
| 44 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(castReg, srcReg, coshMask); | ||
| 45 | - } else { | ||
| 46 | - MicroAPI::DataCopy(castReg, srcUb + i * vlSize); | ||
| 47 | - } | ||
| 48 | - MicroAPI::Adds(castReg, castReg, scalarNegLnTwo, coshMask); | ||
| 49 | - MicroAPI::Exp(computeReg0, castReg, coshMask); | ||
| 50 | - MicroAPI::Div(computeReg1, brcReg, computeReg0, coshMask); | ||
| 51 | - MicroAPI::Add(resReg, computeReg0, computeReg1, coshMask); | ||
| 52 | - if constexpr (SupportBytes<T, 2>()) { | ||
| 53 | - MicroAPI::Cast<half, float, castTraitB32ToB16>(dstReg, resReg, coshMask); | ||
| 54 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * vlSize, dstReg, coshMask); | ||
| 55 | - } else { | ||
| 56 | - MicroAPI::DataCopy(dstUb + i * vlSize, resReg, coshMask); | ||
| 57 | - } | ||
| 58 | - } | ||
| 59 | -} | ||
| 60 | -} // namespace Internal | ||
| 61 | - | ||
| 62 | -template <typename T, bool isReuseSource = false> | ||
| 63 | -__aicore__ inline void CoshImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 64 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 65 | -{ | ||
| 66 | - // Only for AI Vector Core. | ||
| 67 | - if ASCEND_IS_AIC { | ||
| 68 | - return; | ||
| 69 | - } | ||
| 70 | - | ||
| 71 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 72 | - CoshImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 73 | -} | ||
| 74 | - | ||
| 75 | -template <typename T, bool isReuseSource = false> | ||
| 76 | -__aicore__ inline void CoshImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 77 | - const uint32_t calCount) | ||
| 78 | -{ | ||
| 79 | - // Only for AI Vector Core. | ||
| 80 | - if ASCEND_IS_AIC { | ||
| 81 | - return; | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - static_assert(SupportType<T, half, float>(), "Cosh only support half/float data type on current device!"); | ||
| 85 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 86 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 87 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Cosh"); | ||
| 88 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Cosh"); | ||
| 89 | - | ||
| 90 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 91 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 92 | - constexpr int32_t vlSize = static_cast<int32_t>(GetVecLen() / sizeof(float)); | ||
| 93 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, vlSize)); | ||
| 94 | - Internal::CoshCompute<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 95 | -} | ||
| 96 | -} // namespace AscendC | ||
| 97 | - | ||
| 98 | - | ||
Dimpl/adv_api/detail/math/cumsum/regbase/l300/cumsum_l300_impl.h+0-200
| @@ -1,200 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file cumsum_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -namespace AscendC { | ||
| 28 | -template <typename T> | ||
| 29 | -__simd_vf__ inline void CumSumCopyLastRowVF(__ubuf__ T* dst, __ubuf__ T* src, uint32_t len) | ||
| 30 | -{ | ||
| 31 | - constexpr uint16_t sregLower = static_cast<uint16_t>(GetVecLen() / sizeof(T)); | ||
| 32 | - uint32_t count = len; | ||
| 33 | - uint16_t repeatTimes = CeilDivision(count, sregLower); | ||
| 34 | - | ||
| 35 | - MicroAPI::RegTensor<T> srcReg; | ||
| 36 | - MicroAPI::MaskReg preg; | ||
| 37 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 38 | - preg = MicroAPI::UpdateMask<T>(count); | ||
| 39 | - MicroAPI::DataCopy(srcReg, src + i * sregLower); | ||
| 40 | - MicroAPI::DataCopy(dst + i * sregLower, srcReg, preg); | ||
| 41 | - } | ||
| 42 | -} | ||
| 43 | - | ||
| 44 | -template <typename T> | ||
| 45 | -__aicore__ inline void CumSumCopyLastRow(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, uint32_t len) | ||
| 46 | -{ | ||
| 47 | - __ubuf__ T* src = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 48 | - __ubuf__ T* dst = (__ubuf__ T*)dstTensor.GetPhyAddr(); | ||
| 49 | - CumSumCopyLastRowVF<T>(dst, src, len); | ||
| 50 | -} | ||
| 51 | - | ||
| 52 | -template <typename T, const CumSumConfig& config> | ||
| 53 | -__aicore__ inline void CumSumLastDim(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 54 | - LocalTensor<T> tempBuffer, const CumSumInfo& cumSumInfo) | ||
| 55 | -{ | ||
| 56 | - ASCENDC_ASSERT(false, { KERNEL_LOG(KERNEL_ERROR, "current data type is not supported!"); }); | ||
| 57 | -} | ||
| 58 | - | ||
| 59 | -template <typename T = float, const CumSumConfig& config> | ||
| 60 | -__aicore__ inline void CumSumLastDim(const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, | ||
| 61 | - LocalTensor<float> tempBuffer, const CumSumInfo& cumSumInfo) | ||
| 62 | -{ | ||
| 63 | - uint16_t alignOutter = | ||
| 64 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 65 | - LocalTensor<float> tempBuffer2 = tempBuffer[alignOutter * cumSumInfo.inner]; | ||
| 66 | - Internal::Transpose5HDAB(tempBuffer, srcTensor, cumSumInfo); | ||
| 67 | - if constexpr (config.algorithm == CumSumAlgorithm::CUMSUM_ALGORITHM_SKLANSKY) { | ||
| 68 | - Internal::CumSumFirstDimSklansky(tempBuffer, cumSumInfo.inner, alignOutter); | ||
| 69 | - } else { | ||
| 70 | - Internal::CumSumFirstDimBasic(tempBuffer, cumSumInfo.inner, alignOutter); | ||
| 71 | - } | ||
| 72 | - Internal::Transpose5HDBA(tempBuffer2, tempBuffer, cumSumInfo); | ||
| 73 | - Internal::CumSumCopyOut(dstTensor, tempBuffer2, cumSumInfo.outter, cumSumInfo.inner); | ||
| 74 | -} | ||
| 75 | - | ||
| 76 | -template <typename T = half, const CumSumConfig& config> | ||
| 77 | -__aicore__ inline void CumSumLastDim(const LocalTensor<half>& dstTensor, const LocalTensor<half>& srcTensor, | ||
| 78 | - LocalTensor<half> tempBuffer, const CumSumInfo& cumSumInfo) | ||
| 79 | -{ | ||
| 80 | - uint16_t alignOutter = | ||
| 81 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 82 | - LocalTensor<half> tempBuffer2 = tempBuffer[alignOutter * cumSumInfo.inner]; | ||
| 83 | - LocalTensor<float> floatTempBuffer = tempBuffer[alignOutter * cumSumInfo.inner].ReinterpretCast<float>(); | ||
| 84 | - Internal::Transpose5HDAB(tempBuffer, srcTensor, cumSumInfo); | ||
| 85 | - Internal::CumSumCopyWithCast(floatTempBuffer, tempBuffer, cumSumInfo.inner, alignOutter); | ||
| 86 | - if constexpr (config.algorithm == CumSumAlgorithm::CUMSUM_ALGORITHM_SKLANSKY) { | ||
| 87 | - Internal::CumSumFirstDimSklansky(floatTempBuffer, cumSumInfo.inner, alignOutter); | ||
| 88 | - } else { | ||
| 89 | - Internal::CumSumFirstDimBasic(floatTempBuffer, cumSumInfo.inner, alignOutter); | ||
| 90 | - } | ||
| 91 | - Internal::CumSumCopyWithCast(tempBuffer, floatTempBuffer, cumSumInfo.inner, alignOutter); | ||
| 92 | - | ||
| 93 | - if (cumSumInfo.outter % NCHW_CONV_ADDR_LIST_SIZE == 0 && cumSumInfo.inner % NCHW_CONV_ADDR_LIST_SIZE == 0) { | ||
| 94 | - Internal::Transpose5HDBA(dstTensor, tempBuffer, cumSumInfo); | ||
| 95 | - } else { | ||
| 96 | - Internal::Transpose5HDBA(tempBuffer2, tempBuffer, cumSumInfo); | ||
| 97 | - Internal::CumSumCopyOut(dstTensor, tempBuffer2, cumSumInfo.outter, cumSumInfo.inner); | ||
| 98 | - } | ||
| 99 | -} | ||
| 100 | - | ||
| 101 | -template <typename T, const CumSumConfig& config> | ||
| 102 | -__aicore__ inline void CumSumFirstDim(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 103 | - LocalTensor<uint8_t>& sharedTmpBuffer, const CumSumInfo& cumSumInfo) | ||
| 104 | -{ | ||
| 105 | - ASCENDC_ASSERT(false, { KERNEL_LOG(KERNEL_ERROR, "current data type is not supported!"); }); | ||
| 106 | -} | ||
| 107 | - | ||
| 108 | -template <typename T = float, const CumSumConfig& config> | ||
| 109 | -__aicore__ inline void CumSumFirstDim(const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, | ||
| 110 | - LocalTensor<uint8_t>& sharedTmpBuffer, const CumSumInfo& cumSumInfo) | ||
| 111 | -{ | ||
| 112 | - Internal::CumSumCopyOut(dstTensor, srcTensor, cumSumInfo.outter, cumSumInfo.inner); | ||
| 113 | - if constexpr (config.algorithm == CumSumAlgorithm::CUMSUM_ALGORITHM_SKLANSKY) { | ||
| 114 | - Internal::CumSumFirstDimSklansky(dstTensor, cumSumInfo.outter, cumSumInfo.inner); | ||
| 115 | - } else { | ||
| 116 | - // basic implementation | ||
| 117 | - Internal::CumSumFirstDimBasic(dstTensor, cumSumInfo.outter, cumSumInfo.inner); | ||
| 118 | - } | ||
| 119 | -} | ||
| 120 | - | ||
| 121 | -template <typename T = half, const CumSumConfig& config> | ||
| 122 | -__aicore__ inline void CumSumFirstDim(const LocalTensor<half>& dstTensor, const LocalTensor<half>& srcTensor, | ||
| 123 | - LocalTensor<uint8_t>& sharedTmpBuffer, const CumSumInfo& cumSumInfo) | ||
| 124 | -{ | ||
| 125 | - const uint32_t minTmpBufferSize = cumSumInfo.outter * cumSumInfo.inner * sizeof(float); | ||
| 126 | - const uint32_t tmpBufferSize = sharedTmpBuffer.GetSize(); | ||
| 127 | - | ||
| 128 | - ASCENDC_ASSERT((tmpBufferSize >= minTmpBufferSize), { | ||
| 129 | - KERNEL_LOG(KERNEL_ERROR, | ||
| 130 | - "tmpBufferSize can't smaller than minTmpBufferSize, tmpBufferSize is %u, minTmpBufferSize is %u!", | ||
| 131 | - tmpBufferSize, minTmpBufferSize); | ||
| 132 | - }); | ||
| 133 | - | ||
| 134 | - LocalTensor<float> tmpBuffer = sharedTmpBuffer.ReinterpretCast<float>(); | ||
| 135 | - Internal::CumSumCopyWithCast(tmpBuffer, srcTensor, cumSumInfo.outter, cumSumInfo.inner); | ||
| 136 | - if constexpr (config.algorithm == CumSumAlgorithm::CUMSUM_ALGORITHM_SKLANSKY) { | ||
| 137 | - Internal::CumSumFirstDimSklansky(tmpBuffer, cumSumInfo.outter, cumSumInfo.inner); | ||
| 138 | - } else { | ||
| 139 | - // basic implementation | ||
| 140 | - Internal::CumSumFirstDimBasic(tmpBuffer, cumSumInfo.outter, cumSumInfo.inner); | ||
| 141 | - } | ||
| 142 | - Internal::CumSumCopyWithCast(dstTensor, tmpBuffer, cumSumInfo.outter, cumSumInfo.inner); | ||
| 143 | -} | ||
| 144 | - | ||
| 145 | -template <typename T, const CumSumConfig& config> | ||
| 146 | -__aicore__ inline void CumSumImpl(LocalTensor<T>& dstTensor, LocalTensor<T>& lastRowTensor, | ||
| 147 | - const LocalTensor<T>& srcTensor, LocalTensor<uint8_t>& sharedTmpBuffer, | ||
| 148 | - const CumSumInfo& cumSumInfo) | ||
| 149 | -{ | ||
| 150 | - if ASCEND_IS_AIC { | ||
| 151 | - return; | ||
| 152 | - } | ||
| 153 | - | ||
| 154 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 155 | - CHECK_FUNC_HIGHLEVEL_API(CumSum, (T, config), (dstTensor, lastRowTensor, srcTensor, sharedTmpBuffer, cumSumInfo)); | ||
| 156 | - | ||
| 157 | - if constexpr (config.isLastAxis) { | ||
| 158 | - uint32_t minCastTempBufferSize = 0; | ||
| 159 | - if constexpr (sizeof(T) == 2) { // 2 is for half | ||
| 160 | - minCastTempBufferSize = cumSumInfo.inner * NCHW_CONV_ADDR_LIST_SIZE * sizeof(half); | ||
| 161 | - } | ||
| 162 | - const uint32_t minTmpBufferSize = | ||
| 163 | - minCastTempBufferSize | ||
| 164 | - + NCHW_CONV_ADDR_LIST_SIZE * cumSumInfo.inner * sizeof(T) * 2; // both transpose require a tempBuffer | ||
| 165 | - const uint32_t tmpBufferSize = sharedTmpBuffer.GetSize(); | ||
| 166 | - | ||
| 167 | - ASCENDC_ASSERT((tmpBufferSize >= minTmpBufferSize), { | ||
| 168 | - KERNEL_LOG( | ||
| 169 | - KERNEL_ERROR, | ||
| 170 | - "tmpBufferSize can't smaller than minTmpBufferSize, tmpBufferSize is %u, minTmpBufferSize is %u!", | ||
| 171 | - tmpBufferSize, minTmpBufferSize); | ||
| 172 | - }); | ||
| 173 | - | ||
| 174 | - // loop over the outter and process at least 16 rows of data each time. | ||
| 175 | - const uint32_t oneRepeateSize = tmpBufferSize / minTmpBufferSize * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 176 | - const uint32_t rangeM = cumSumInfo.outter / oneRepeateSize; | ||
| 177 | - const uint32_t tailM = cumSumInfo.outter - oneRepeateSize * rangeM; | ||
| 178 | - uint32_t dstLocalOffset = 0; | ||
| 179 | - uint32_t srcLocalOffset = 0; | ||
| 180 | - LocalTensor<T> tmpBuffer = sharedTmpBuffer.ReinterpretCast<T>(); | ||
| 181 | - for (uint32_t i = 0; i < rangeM; i++) { | ||
| 182 | - CumSumLastDim<T, config>(dstTensor[dstLocalOffset], srcTensor[srcLocalOffset], tmpBuffer, | ||
| 183 | - {oneRepeateSize, cumSumInfo.inner}); | ||
| 184 | - dstLocalOffset += cumSumInfo.inner * oneRepeateSize; | ||
| 185 | - srcLocalOffset += cumSumInfo.inner * oneRepeateSize; | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - if (tailM != 0) { | ||
| 189 | - CumSumLastDim<T, config>(dstTensor[dstLocalOffset], srcTensor[srcLocalOffset], tmpBuffer, | ||
| 190 | - {tailM, cumSumInfo.inner}); | ||
| 191 | - } | ||
| 192 | - } else { | ||
| 193 | - CumSumFirstDim<T, config>(dstTensor, srcTensor, sharedTmpBuffer, cumSumInfo); | ||
| 194 | - } | ||
| 195 | - if constexpr (config.outputLastRow) { | ||
| 196 | - CumSumCopyLastRow(lastRowTensor, dstTensor[(cumSumInfo.outter - 1) * cumSumInfo.inner], cumSumInfo.inner); | ||
| 197 | - } | ||
| 198 | -} | ||
| 199 | -} // namespace AscendC | ||
| 200 | - | ||
Dimpl/adv_api/detail/math/cumsum/regbase/l300/cumsum_l300_utils.h+0-788
| @@ -1,788 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file cumsum_l300_utils.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -namespace AscendC { | ||
| 21 | - | ||
| 22 | -namespace Internal { | ||
| 23 | -template <typename T> | ||
| 24 | -__simd_callee__ inline void LoadDataWithT(__ubuf__ T* src, MicroAPI::RegTensor<float>& dstReg, | ||
| 25 | - MicroAPI::MaskReg& dstPreg, uint32_t srcOffset) | ||
| 26 | -{ | ||
| 27 | - if constexpr (IsSameType<T, half>::value || IsSameType<T, bfloat16_t>::value) { | ||
| 28 | - MicroAPI::RegTensor<T> srcOrigin; | ||
| 29 | - DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin, src + srcOffset); | ||
| 30 | - Cast<float, T, layoutZMrgZ>(dstReg, srcOrigin, dstPreg); | ||
| 31 | - } else { // this branch: only support float | ||
| 32 | - DataCopy(dstReg, src + srcOffset); | ||
| 33 | - } | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | -template <typename T> | ||
| 37 | -__simd_callee__ inline void SaveDataWithT(__ubuf__ T* dst, MicroAPI::RegTensor<float>& srcReg, | ||
| 38 | - MicroAPI::MaskReg& dstPreg, uint32_t dstOffset) | ||
| 39 | -{ | ||
| 40 | - if constexpr (IsSameType<T, half>::value || IsSameType<T, bfloat16_t>::value) { | ||
| 41 | - MicroAPI::RegTensor<T> regT; | ||
| 42 | - Cast<T, float, LayoutZMrgZRndRSatNS>(regT, srcReg, dstPreg); | ||
| 43 | - DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + dstOffset, regT, dstPreg); | ||
| 44 | - } else { | ||
| 45 | - DataCopy(dst + dstOffset, srcReg, dstPreg); | ||
| 46 | - } | ||
| 47 | -} | ||
| 48 | - | ||
| 49 | -// process by tempBuffer | ||
| 50 | -// T: fp16-> U: fp32 | ||
| 51 | -// T: fp32-> U: fp16 | ||
| 52 | -template <typename U, typename T> | ||
| 53 | -__simd_vf__ inline void CumSumCopyWithCastVF(__ubuf__ T* src, __ubuf__ U* dst, const uint16_t outter, | ||
| 54 | - const uint16_t inner, uint16_t innerOneRepNum, uint16_t mainRepeatTime, | ||
| 55 | - uint16_t tailRepeatTime, uint32_t tailCount, uint16_t halfOutter, | ||
| 56 | - uint16_t tailOutter) | ||
| 57 | -{ | ||
| 58 | - MicroAPI::RegTensor<float> srcReg; | ||
| 59 | - MicroAPI::RegTensor<float> srcReg1; | ||
| 60 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 61 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<float>(tailCount); | ||
| 62 | - for (uint16_t j = 0; j < halfOutter; ++j) { | ||
| 63 | - for (uint16_t i = 0; i < mainRepeatTime; ++i) { | ||
| 64 | - LoadDataWithT<T>(src, srcReg, fullMask, j * inner + i * innerOneRepNum); | ||
| 65 | - SaveDataWithT<U>(dst, srcReg, fullMask, j * inner + i * innerOneRepNum); | ||
| 66 | - LoadDataWithT<T>(src, srcReg1, fullMask, (j + halfOutter) * inner + i * innerOneRepNum); | ||
| 67 | - SaveDataWithT<U>(dst, srcReg1, fullMask, (j + halfOutter) * inner + i * innerOneRepNum); | ||
| 68 | - } | ||
| 69 | - for (uint16_t i = 0; i < tailRepeatTime; ++i) { | ||
| 70 | - LoadDataWithT<T>(src, srcReg, tailMask, j * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 71 | - SaveDataWithT<U>(dst, srcReg, tailMask, j * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 72 | - LoadDataWithT<T>(src, srcReg1, tailMask, (j + halfOutter) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 73 | - SaveDataWithT<U>(dst, srcReg1, tailMask, (j + halfOutter) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 74 | - } | ||
| 75 | - } | ||
| 76 | - for (uint16_t j = 0; j < tailOutter; ++j) { | ||
| 77 | - for (uint16_t i = 0; i < mainRepeatTime; ++i) { | ||
| 78 | - LoadDataWithT<T>(src, srcReg, fullMask, (j + halfOutter * 2) * inner + i * innerOneRepNum); | ||
| 79 | - SaveDataWithT<U>(dst, srcReg, fullMask, (j + halfOutter * 2) * inner + i * innerOneRepNum); | ||
| 80 | - } | ||
| 81 | - for (uint16_t i = 0; i < tailRepeatTime; ++i) { | ||
| 82 | - LoadDataWithT<T>(src, srcReg, tailMask, | ||
| 83 | - (j + halfOutter * 2) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 84 | - SaveDataWithT<U>(dst, srcReg, tailMask, | ||
| 85 | - (j + halfOutter * 2) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 86 | - } | ||
| 87 | - } | ||
| 88 | -} | ||
| 89 | - | ||
| 90 | -template <typename U, typename T> | ||
| 91 | -__simd_vf__ inline void CumSumCopyWithCast2VF(__ubuf__ T* src, __ubuf__ U* dst, const uint16_t outter, | ||
| 92 | - const uint16_t inner, uint16_t innerOneRepNum, uint16_t mainRepeatTime, | ||
| 93 | - uint16_t tailRepeatTime, uint32_t tailCount) | ||
| 94 | -{ | ||
| 95 | - MicroAPI::RegTensor<float> srcReg; | ||
| 96 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 97 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<float>(tailCount); | ||
| 98 | - for (uint16_t j = 0; j < outter; ++j) { | ||
| 99 | - for (uint16_t i = 0; i < mainRepeatTime; ++i) { | ||
| 100 | - LoadDataWithT<T>(src, srcReg, fullMask, j * inner + i * innerOneRepNum); | ||
| 101 | - SaveDataWithT<U>(dst, srcReg, fullMask, j * inner + i * innerOneRepNum); | ||
| 102 | - } | ||
| 103 | - for (uint16_t i = 0; i < tailRepeatTime; ++i) { | ||
| 104 | - LoadDataWithT<T>(src, srcReg, tailMask, j * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 105 | - SaveDataWithT<U>(dst, srcReg, tailMask, j * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 106 | - } | ||
| 107 | - } | ||
| 108 | -} | ||
| 109 | - | ||
| 110 | -template <typename U, typename T> | ||
| 111 | -__aicore__ inline void CumSumCopyWithCast(const LocalTensor<U>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 112 | - const uint32_t outter, const uint32_t inner) | ||
| 113 | -{ | ||
| 114 | - __ubuf__ T* src = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 115 | - __ubuf__ U* dst = (__ubuf__ U*)dstTensor.GetPhyAddr(); | ||
| 116 | - constexpr uint16_t innerOneRepNum = (uint16_t)(GetVecLen() / sizeof(float)); | ||
| 117 | - uint16_t mainRepeatTime = inner / innerOneRepNum; | ||
| 118 | - uint32_t tailCount = inner % innerOneRepNum; | ||
| 119 | - uint16_t tailRepeatTime = tailCount > 0 ? 1 : 0; | ||
| 120 | - uint16_t halfOutter = static_cast<uint16_t>(outter) / 2; | ||
| 121 | - uint16_t tailOutter = static_cast<uint16_t>(outter) % 2; | ||
| 122 | - if (outter > inner) { | ||
| 123 | - CumSumCopyWithCastVF<U, T>(src, dst, static_cast<uint16_t>(outter), static_cast<uint16_t>(inner), | ||
| 124 | - innerOneRepNum, mainRepeatTime, tailRepeatTime, tailCount, halfOutter, tailOutter); | ||
| 125 | - } else { | ||
| 126 | - CumSumCopyWithCast2VF<U, T>(src, dst, static_cast<uint16_t>(outter), static_cast<uint16_t>(inner), | ||
| 127 | - innerOneRepNum, mainRepeatTime, tailRepeatTime, tailCount); | ||
| 128 | - } | ||
| 129 | -} | ||
| 130 | - | ||
| 131 | -template <typename T> | ||
| 132 | -__simd_vf__ inline void CumSumCopyOutWithBlockVF(__ubuf__ T* src, __ubuf__ T* dst, uint16_t outter, uint16_t inner, | ||
| 133 | - uint16_t mainRepeatTime, uint16_t innerOneRepNum, uint32_t tailCount, | ||
| 134 | - uint16_t tailRepeatTime) | ||
| 135 | -{ | ||
| 136 | - MicroAPI::RegTensor<T> srcReg; | ||
| 137 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL>(); | ||
| 138 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<T>(tailCount); | ||
| 139 | - | ||
| 140 | - for (uint16_t i = 0; i < outter; ++i) { | ||
| 141 | - for (uint16_t j = 0; j < mainRepeatTime; ++j) { | ||
| 142 | - MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY>(srcReg, src + i * inner + j * innerOneRepNum, | ||
| 143 | - 1, fullMask); | ||
| 144 | - MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY>(dst + i * inner + j * innerOneRepNum, srcReg, | ||
| 145 | - 1, fullMask); | ||
| 146 | - } | ||
| 147 | - for (uint16_t j = 0; j < tailRepeatTime; ++j) { | ||
| 148 | - MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY>( | ||
| 149 | - srcReg, src + i * inner + mainRepeatTime * innerOneRepNum, 1, tailMask); | ||
| 150 | - MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY>( | ||
| 151 | - dst + i * inner + mainRepeatTime * innerOneRepNum, srcReg, 1, tailMask); | ||
| 152 | - } | ||
| 153 | - } | ||
| 154 | -} | ||
| 155 | - | ||
| 156 | -template <typename T> | ||
| 157 | -__simd_vf__ inline void CumSumCopyOutVF(__ubuf__ T* src, __ubuf__ T* dst, uint16_t outter, uint16_t inner, | ||
| 158 | - uint16_t mainRepeatTime, uint16_t innerOneRepNum, uint32_t tailCount, | ||
| 159 | - uint16_t tailRepeatTime, uint16_t halfOutter, uint16_t tailOutter) | ||
| 160 | -{ | ||
| 161 | - MicroAPI::RegTensor<T> srcReg; | ||
| 162 | - MicroAPI::RegTensor<T> srcReg1; | ||
| 163 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL>(); | ||
| 164 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<T>(tailCount); | ||
| 165 | - | ||
| 166 | - for (uint16_t j = 0; j < halfOutter; ++j) { | ||
| 167 | - for (uint16_t i = 0; i < mainRepeatTime; ++i) { | ||
| 168 | - MicroAPI::DataCopy(srcReg, src + (j * 2) * inner + i * innerOneRepNum); | ||
| 169 | - MicroAPI::DataCopy(dst + (j * 2) * inner + i * innerOneRepNum, srcReg, fullMask); | ||
| 170 | - MicroAPI::DataCopy(srcReg1, src + (j * 2 + 1) * inner + i * innerOneRepNum); | ||
| 171 | - MicroAPI::DataCopy(dst + (j * 2 + 1) * inner + i * innerOneRepNum, srcReg1, fullMask); | ||
| 172 | - } | ||
| 173 | - for (uint16_t i = 0; i < tailRepeatTime; ++i) { | ||
| 174 | - MicroAPI::DataCopy(srcReg, src + (j * 2) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 175 | - MicroAPI::DataCopy(dst + (j * 2) * inner + (i + mainRepeatTime) * innerOneRepNum, srcReg, tailMask); | ||
| 176 | - MicroAPI::DataCopy(srcReg1, src + (j * 2 + 1) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 177 | - MicroAPI::DataCopy(dst + (j * 2 + 1) * inner + (i + mainRepeatTime) * innerOneRepNum, srcReg1, tailMask); | ||
| 178 | - } | ||
| 179 | - } | ||
| 180 | - | ||
| 181 | - for (uint16_t j = 0; j < tailOutter; ++j) { | ||
| 182 | - for (uint16_t i = 0; i < mainRepeatTime; ++i) { | ||
| 183 | - MicroAPI::DataCopy(srcReg, src + (j + 2 * halfOutter) * inner + i * innerOneRepNum); | ||
| 184 | - MicroAPI::DataCopy(dst + (j + 2 * halfOutter) * inner + i * innerOneRepNum, srcReg, fullMask); | ||
| 185 | - } | ||
| 186 | - for (uint16_t i = 0; i < tailRepeatTime; ++i) { | ||
| 187 | - MicroAPI::DataCopy(srcReg, src + (j + 2 * halfOutter) * inner + (i + mainRepeatTime) * innerOneRepNum); | ||
| 188 | - MicroAPI::DataCopy(dst + (j + 2 * halfOutter) * inner + (i + mainRepeatTime) * innerOneRepNum, srcReg, | ||
| 189 | - tailMask); | ||
| 190 | - } | ||
| 191 | - } | ||
| 192 | -} | ||
| 193 | - | ||
| 194 | -template <typename T> | ||
| 195 | -__aicore__ inline void CumSumCopyOut(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 196 | - const uint32_t outter, const uint32_t inner) | ||
| 197 | -{ | ||
| 198 | - __ubuf__ T* src = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 199 | - __ubuf__ T* dst = (__ubuf__ T*)dstTensor.GetPhyAddr(); | ||
| 200 | - constexpr uint16_t innerOneRepNum = GetVecLen() / sizeof(T); | ||
| 201 | - constexpr uint16_t elePerBlock = ONE_BLK_SIZE / sizeof(T); | ||
| 202 | - uint16_t mainRepeatTime = inner / innerOneRepNum; | ||
| 203 | - uint32_t tailCount = inner % innerOneRepNum; | ||
| 204 | - uint16_t tailRepeatTime = tailCount > 0 ? 1 : 0; | ||
| 205 | - uint16_t halfOutter = outter / 2; | ||
| 206 | - uint16_t tailOutter = outter % 2; | ||
| 207 | - CumSumCopyOutVF<T>(src, dst, outter, inner, mainRepeatTime, innerOneRepNum, tailCount, tailRepeatTime, halfOutter, | ||
| 208 | - tailOutter); | ||
| 209 | -} | ||
| 210 | - | ||
| 211 | -template <typename D, typename T, const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 212 | -__aicore__ inline void TransposeCommonGather(__ubuf__ D* dstAddr, __ubuf__ T* srcAddr, uint32_t forLoop1, | ||
| 213 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2) | ||
| 214 | -{ | ||
| 215 | - ASCENDC_ASSERT(false, { KERNEL_LOG(KERNEL_ERROR, "current data type is not supported!"); }); | ||
| 216 | -} | ||
| 217 | - | ||
| 218 | -// VF for TransposeCommonGather (float, float) | ||
| 219 | -template <typename T, const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 220 | -__simd_vf__ inline void TransposeCommonGatherVFFF(__ubuf__ float* dstAddr, __ubuf__ float* srcAddr, uint32_t forLoop1, | ||
| 221 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2, | ||
| 222 | - uint32_t tail, uint32_t count, uint16_t mainLoop, uint32_t dtypeSize, | ||
| 223 | - uint32_t tailLoop) | ||
| 224 | -{ | ||
| 225 | - MicroAPI::RegTensor<uint32_t, Trait> indexReg; | ||
| 226 | - MicroAPI::RegTensor<T, Trait> srcReg; | ||
| 227 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 228 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 229 | - MicroAPI::MaskReg mainMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 230 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<float, Trait>(count); | ||
| 231 | - MicroAPI::UnalignReg ureg0; | ||
| 232 | - Arange((MicroAPI::RegTensor<int32_t, Trait>&)indexReg, static_cast<int32_t>(0)); | ||
| 233 | - Muls(indexReg, indexReg, srcStride2, indexFullMask); | ||
| 234 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 235 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)(j * forLoop2 * dtypeSize); | ||
| 236 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 237 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + k * vlSize * srcStride2, indexReg, mainMask); | ||
| 238 | - MicroAPI::DataCopyUnAlign(((__ubuf__ float*&)hoistDstAddr), srcReg, ureg0, vlSize); | ||
| 239 | - } | ||
| 240 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 241 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + mainLoop * vlSize * srcStride2, indexReg, tailMask); | ||
| 242 | - MicroAPI::DataCopyUnAlign(((__ubuf__ float*&)hoistDstAddr), srcReg, ureg0, tail); | ||
| 243 | - } | ||
| 244 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ float*&)hoistDstAddr), ureg0, 0); | ||
| 245 | - } | ||
| 246 | -} | ||
| 247 | - | ||
| 248 | -template <typename D = float, typename T = float, const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 249 | -__aicore__ inline void TransposeCommonGather(__ubuf__ float* dstAddr, __ubuf__ float* srcAddr, uint32_t forLoop1, | ||
| 250 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2) | ||
| 251 | -{ | ||
| 252 | - uint32_t tail = forLoop2 % vlSize; | ||
| 253 | - uint32_t count = tail; | ||
| 254 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 255 | - uint32_t dtypeSize = sizeof(float); | ||
| 256 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 257 | - TransposeCommonGatherVFFF<T, Trait, vlSize>(dstAddr, srcAddr, forLoop1, forLoop2, srcStride1, srcStride2, tail, | ||
| 258 | - count, mainLoop, dtypeSize, tailLoop); | ||
| 259 | -} | ||
| 260 | - | ||
| 261 | -// VF for TransposeCommonGather (float, half) | ||
| 262 | -template <const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 263 | -__simd_vf__ inline void TransposeCommonGatherVFFH(__ubuf__ float* dstAddr, __ubuf__ half* srcAddr, uint32_t forLoop1, | ||
| 264 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2, | ||
| 265 | - uint32_t tail, uint32_t count, uint16_t mainLoop, uint32_t dtypeSize, | ||
| 266 | - uint32_t tailLoop) | ||
| 267 | -{ | ||
| 268 | - MicroAPI::RegTensor<uint16_t, Trait> indexReg; | ||
| 269 | - MicroAPI::RegTensor<half, Trait> srcReg; | ||
| 270 | - MicroAPI::RegTensor<float, Trait> vreg; | ||
| 271 | - MicroAPI::RegTensor<uint16_t> zeroReg; | ||
| 272 | - MicroAPI::RegTensor<half> castReg; | ||
| 273 | - MicroAPI::RegTensor<uint16_t> tmpReg; | ||
| 274 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 275 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<half, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 276 | - MicroAPI::MaskReg mainMask = MicroAPI::CreateMask<half, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 277 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<half, Trait>(count); | ||
| 278 | - MicroAPI::Duplicate(zeroReg, static_cast<uint16_t>(0), fullMask); | ||
| 279 | - MicroAPI::UnalignReg ureg0; | ||
| 280 | - Arange((MicroAPI::RegTensor<int16_t, Trait>&)indexReg, static_cast<int16_t>(0)); | ||
| 281 | - Muls(indexReg, indexReg, static_cast<uint16_t>(srcStride2), indexFullMask); | ||
| 282 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 283 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)(j * forLoop2 * dtypeSize); | ||
| 284 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 285 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + k * vlSize * srcStride2, indexReg, mainMask); | ||
| 286 | - MicroAPI::Interleave((MicroAPI::RegTensor<uint16_t>&)castReg, (MicroAPI::RegTensor<uint16_t>&)tmpReg, | ||
| 287 | - (MicroAPI::RegTensor<uint16_t>&)srcReg, (MicroAPI::RegTensor<uint16_t>&)zeroReg); | ||
| 288 | - Cast<float, half, layoutZMrgZ>(vreg, castReg, mainMask); | ||
| 289 | - MicroAPI::DataCopyUnAlign(((__ubuf__ float*&)hoistDstAddr), vreg, ureg0, vlSize); | ||
| 290 | - } | ||
| 291 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 292 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + mainLoop * vlSize * srcStride2, indexReg, tailMask); | ||
| 293 | - MicroAPI::Interleave((MicroAPI::RegTensor<uint16_t>&)castReg, (MicroAPI::RegTensor<uint16_t>&)tmpReg, | ||
| 294 | - (MicroAPI::RegTensor<uint16_t>&)srcReg, (MicroAPI::RegTensor<uint16_t>&)zeroReg); | ||
| 295 | - Cast<float, half, layoutZMrgZ>(vreg, castReg, mainMask); | ||
| 296 | - MicroAPI::DataCopyUnAlign(((__ubuf__ float*&)hoistDstAddr), vreg, ureg0, tail); | ||
| 297 | - } | ||
| 298 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ float*&)hoistDstAddr), ureg0, 0); | ||
| 299 | - } | ||
| 300 | -} | ||
| 301 | - | ||
| 302 | -template <typename D = float, typename T = half, const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 303 | -__aicore__ inline void TransposeCommonGather(__ubuf__ float* dstAddr, __ubuf__ half* srcAddr, uint32_t forLoop1, | ||
| 304 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2) | ||
| 305 | -{ | ||
| 306 | - uint32_t tail = forLoop2 % vlSize; | ||
| 307 | - uint32_t count = tail; | ||
| 308 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 309 | - uint32_t dtypeSize = sizeof(float); | ||
| 310 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 311 | - TransposeCommonGatherVFFH<Trait, vlSize>(dstAddr, srcAddr, forLoop1, forLoop2, srcStride1, srcStride2, tail, count, | ||
| 312 | - mainLoop, dtypeSize, tailLoop); | ||
| 313 | -} | ||
| 314 | - | ||
| 315 | -// VF for TransposeCommonGather (half, float) | ||
| 316 | -template <const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 317 | -__simd_vf__ inline void TransposeCommonGatherVHF(__ubuf__ half* dstAddr, __ubuf__ float* srcAddr, uint32_t forLoop1, | ||
| 318 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2, | ||
| 319 | - uint32_t tail, uint32_t count, uint16_t mainLoop, uint32_t dtypeSize, | ||
| 320 | - uint32_t tailLoop) | ||
| 321 | -{ | ||
| 322 | - MicroAPI::RegTensor<uint32_t, Trait> indexReg; | ||
| 323 | - MicroAPI::RegTensor<float, Trait> srcReg; | ||
| 324 | - MicroAPI::RegTensor<half, Trait> vreg; | ||
| 325 | - MicroAPI::RegTensor<uint16_t> zeroReg; | ||
| 326 | - MicroAPI::RegTensor<half> castReg; | ||
| 327 | - MicroAPI::RegTensor<uint16_t> tmpReg; | ||
| 328 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 329 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 330 | - MicroAPI::MaskReg mainMask = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 331 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<float, Trait>(count); | ||
| 332 | - MicroAPI::Duplicate(zeroReg, static_cast<uint16_t>(0), fullMask); | ||
| 333 | - MicroAPI::UnalignReg ureg0; | ||
| 334 | - Arange((MicroAPI::RegTensor<int32_t, Trait>&)indexReg, static_cast<int32_t>(0)); | ||
| 335 | - Muls(indexReg, indexReg, srcStride2, indexFullMask); | ||
| 336 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 337 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)(j * forLoop2 * dtypeSize); | ||
| 338 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 339 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + k * vlSize * srcStride2, indexReg, mainMask); | ||
| 340 | - Cast<half, float, LayoutZMrgZRndRSatNS>(vreg, srcReg, fullMask); | ||
| 341 | - MicroAPI::DeInterleave((MicroAPI::RegTensor<uint16_t>&)castReg, (MicroAPI::RegTensor<uint16_t>&)tmpReg, | ||
| 342 | - (MicroAPI::RegTensor<uint16_t>&)vreg, (MicroAPI::RegTensor<uint16_t>&)zeroReg); | ||
| 343 | - MicroAPI::DataCopyUnAlign(((__ubuf__ half*&)hoistDstAddr), castReg, ureg0, vlSize); | ||
| 344 | - } | ||
| 345 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 346 | - DataCopyGather(srcReg, srcAddr + j * srcStride1 + mainLoop * vlSize * srcStride2, indexReg, tailMask); | ||
| 347 | - Cast<half, float, LayoutZMrgZRndRSatNS>(vreg, srcReg, fullMask); | ||
| 348 | - MicroAPI::DeInterleave((MicroAPI::RegTensor<uint16_t>&)castReg, (MicroAPI::RegTensor<uint16_t>&)tmpReg, | ||
| 349 | - (MicroAPI::RegTensor<uint16_t>&)vreg, (MicroAPI::RegTensor<uint16_t>&)zeroReg); | ||
| 350 | - MicroAPI::DataCopyUnAlign(((__ubuf__ half*&)hoistDstAddr), castReg, ureg0, tail); | ||
| 351 | - } | ||
| 352 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ half*&)hoistDstAddr), ureg0, 0); | ||
| 353 | - } | ||
| 354 | -} | ||
| 355 | - | ||
| 356 | -template <typename D = half, typename T = float, const MicroAPI::RegTrait& Trait, const uint16_t vlSize> | ||
| 357 | -__aicore__ inline void TransposeCommonGather(__ubuf__ half* dstAddr, __ubuf__ float* srcAddr, uint32_t forLoop1, | ||
| 358 | - uint32_t forLoop2, uint32_t srcStride1, uint32_t srcStride2) | ||
| 359 | -{ | ||
| 360 | - uint32_t tail = forLoop2 % vlSize; | ||
| 361 | - uint32_t count = tail; | ||
| 362 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 363 | - uint32_t dtypeSize = sizeof(half); | ||
| 364 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 365 | - TransposeCommonGatherVHF<Trait, vlSize>(dstAddr, srcAddr, forLoop1, forLoop2, srcStride1, srcStride2, tail, count, | ||
| 366 | - mainLoop, dtypeSize, tailLoop); | ||
| 367 | -} | ||
| 368 | - | ||
| 369 | -/* | ||
| 370 | -scene: { shape:[A, B], format:"ND"} -->{ shape:[B, A], format:"ND"}; | ||
| 371 | -Src: T | ||
| 372 | -Dst: D | ||
| 373 | -1. need cast | ||
| 374 | -TransposeAB [A, B] half => [B, A] float | ||
| 375 | -TransposeAB [A, B] float => [B, A] half | ||
| 376 | -2. no need cast | ||
| 377 | -TransposeAB [A, B] float => [B, A] float | ||
| 378 | -*/ | ||
| 379 | -template <typename D, typename T> | ||
| 380 | -__aicore__ inline void TransposeAB(const LocalTensor<D>& dstTensor, const LocalTensor<T>& srcTensor, uint32_t outer, | ||
| 381 | - uint32_t inner) | ||
| 382 | -{ | ||
| 383 | - uint32_t srcStride1 = 1; | ||
| 384 | - uint32_t srcStride2 = inner; | ||
| 385 | - constexpr uint16_t vlSize = GetVecLen() / sizeof(float); | ||
| 386 | - TransposeCommonGather<D, T, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 387 | - (__ubuf__ D*)dstTensor.GetPhyAddr(), (__ubuf__ T*)srcTensor.GetPhyAddr(), inner, outer, srcStride1, srcStride2); | ||
| 388 | -} | ||
| 389 | - | ||
| 390 | -__simd_vf__ inline void CumSumFirstDimSklanskyVF(__ubuf__ float* dst, uint32_t outer, uint32_t inner, | ||
| 391 | - uint32_t currRound1, uint32_t currRound2, uint16_t indexRepeatTimes, | ||
| 392 | - uint16_t jRepeatTimes, uint16_t repeatTimes, uint16_t sregLower) | ||
| 393 | -{ | ||
| 394 | - MicroAPI::RegTensor<float> src0Reg; | ||
| 395 | - MicroAPI::RegTensor<float> src1Reg; | ||
| 396 | - MicroAPI::RegTensor<float> dstReg; | ||
| 397 | - MicroAPI::MaskReg preg; | ||
| 398 | - | ||
| 399 | - for (uint16_t index = 0; index < indexRepeatTimes; index++) { | ||
| 400 | - // Position of the prefix sum in the previous round | ||
| 401 | - uint32_t line0 = currRound1 - 1 + index * currRound2; | ||
| 402 | - for (uint16_t j = 0; j < jRepeatTimes; j++) { | ||
| 403 | - uint32_t line1 = line0 + j + 1; | ||
| 404 | - uint32_t extent = 1; | ||
| 405 | - if (line1 > outer - 1) { | ||
| 406 | - extent = 0; | ||
| 407 | - } | ||
| 408 | - for (uint16_t k = 0; k < static_cast<uint16_t>(extent); k++) { | ||
| 409 | - uint32_t count = inner; | ||
| 410 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 411 | - preg = MicroAPI::UpdateMask<float>(count); | ||
| 412 | - MicroAPI::DataCopy(src0Reg, dst + line0 * inner + i * sregLower); | ||
| 413 | - MicroAPI::DataCopy(src1Reg, dst + line1 * inner + i * sregLower); | ||
| 414 | - MicroAPI::Add(dstReg, src0Reg, src1Reg, preg); | ||
| 415 | - MicroAPI::DataCopy(dst + line1 * inner + i * sregLower, dstReg, preg); | ||
| 416 | - } | ||
| 417 | - } | ||
| 418 | - } | ||
| 419 | - } | ||
| 420 | -} | ||
| 421 | - | ||
| 422 | -__aicore__ inline void CumSumFirstDimSklansky(const LocalTensor<float>& dstTensor, uint32_t outer, uint32_t inner) | ||
| 423 | -{ | ||
| 424 | - constexpr uint32_t bound = 16; | ||
| 425 | - constexpr uint32_t halfSize = 2; | ||
| 426 | - uint32_t outerAlign = 0; | ||
| 427 | - for (uint32_t i = 0; i < bound; i++) { | ||
| 428 | - if (outer <= (1U << i)) { | ||
| 429 | - outerAlign = (1U << i); | ||
| 430 | - break; | ||
| 431 | - } | ||
| 432 | - } | ||
| 433 | - uint32_t round = outerAlign / halfSize; | ||
| 434 | - | ||
| 435 | - uint32_t currRound = 1; | ||
| 436 | - __ubuf__ float* dst = (__ubuf__ float*)dstTensor.GetPhyAddr(); | ||
| 437 | - constexpr uint16_t sregLower = (uint32_t)(GetVecLen() / sizeof(float)); | ||
| 438 | - uint16_t repeatTimes = CeilDivision(inner, sregLower); | ||
| 439 | - | ||
| 440 | - while (round >= 1) { | ||
| 441 | - uint32_t currRound1 = 1 << (currRound - 1); | ||
| 442 | - uint32_t currRound2 = 1 << currRound; | ||
| 443 | - uint16_t indexRepeatTimes = static_cast<uint16_t>(outerAlign / currRound2); | ||
| 444 | - uint16_t jRepeatTimes = static_cast<uint16_t>(currRound1); | ||
| 445 | - CumSumFirstDimSklanskyVF(dst, outer, inner, currRound1, currRound2, indexRepeatTimes, jRepeatTimes, repeatTimes, | ||
| 446 | - sregLower); | ||
| 447 | - round = round / halfSize; | ||
| 448 | - currRound += 1; | ||
| 449 | - } | ||
| 450 | -} | ||
| 451 | - | ||
| 452 | -// simple implementation that cumulatively adds elements | ||
| 453 | -// VF for CumSumFirstDimBasic | ||
| 454 | -// simple implementation that cumulatively adds elements | ||
| 455 | -// VF for CumSumFirstDimBasic | ||
| 456 | -__simd_vf__ inline void CumSumFirstDimBasicVF(__ubuf__ float* dst, uint16_t outerRepeatTime, uint16_t inner, | ||
| 457 | - uint16_t mainRepeatTime, uint16_t innerOneRepNum, uint16_t tailTime, | ||
| 458 | - uint32_t tailCount, uint16_t halfMainRepeatTime, | ||
| 459 | - uint16_t mainTailRepeatTime, uint16_t innerTailOffset1, | ||
| 460 | - uint16_t innerTailOffset2) | ||
| 461 | -{ | ||
| 462 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 463 | - MicroAPI::MaskReg pregTail = MicroAPI::UpdateMask<float>(tailCount); | ||
| 464 | - MicroAPI::RegTensor<float> srcLeftReg; | ||
| 465 | - MicroAPI::RegTensor<float> srcRightReg; | ||
| 466 | - MicroAPI::RegTensor<float> dstLeftReg; | ||
| 467 | - MicroAPI::RegTensor<float> dstRightReg; | ||
| 468 | - | ||
| 469 | - for (uint16_t j = 0; j < halfMainRepeatTime; ++j) { | ||
| 470 | - MicroAPI::DataCopy(dstLeftReg, dst + j * innerOneRepNum); | ||
| 471 | - MicroAPI::DataCopy(dstRightReg, dst + (j + halfMainRepeatTime) * innerOneRepNum); | ||
| 472 | - for (uint16_t i = 0; i < outerRepeatTime; ++i) { | ||
| 473 | - MicroAPI::DataCopy(srcLeftReg, dst + (i + 1) * inner + j * innerOneRepNum); | ||
| 474 | - MicroAPI::DataCopy(srcRightReg, dst + (i + 1) * inner + (j + halfMainRepeatTime) * innerOneRepNum); | ||
| 475 | - MicroAPI::Add(dstLeftReg, srcLeftReg, dstLeftReg, pregFull); | ||
| 476 | - MicroAPI::Add(dstRightReg, srcRightReg, dstRightReg, pregFull); | ||
| 477 | - MicroAPI::DataCopy(dst + (i + 1) * inner + j * innerOneRepNum, dstLeftReg, pregFull); | ||
| 478 | - MicroAPI::DataCopy(dst + (i + 1) * inner + (j + halfMainRepeatTime) * innerOneRepNum, dstRightReg, | ||
| 479 | - pregFull); | ||
| 480 | - } | ||
| 481 | - } | ||
| 482 | - | ||
| 483 | - MicroAPI::DataCopy(dstLeftReg, dst + innerTailOffset1); | ||
| 484 | - MicroAPI::DataCopy(dstRightReg, dst + innerTailOffset2); | ||
| 485 | - for (uint16_t i = 0; i < outerRepeatTime; ++i) { | ||
| 486 | - for (uint16_t j = 0; j < mainTailRepeatTime; ++j) { | ||
| 487 | - MicroAPI::DataCopy(srcLeftReg, dst + (i + 1) * inner + innerTailOffset1); | ||
| 488 | - MicroAPI::Add(dstLeftReg, srcLeftReg, dstLeftReg, pregFull); | ||
| 489 | - MicroAPI::DataCopy(dst + (i + 1) * inner + innerTailOffset1, dstLeftReg, pregFull); | ||
| 490 | - } | ||
| 491 | - for (uint16_t j = 0; j < tailTime; ++j) { | ||
| 492 | - MicroAPI::DataCopy(srcRightReg, dst + (i + 1) * inner + innerTailOffset2); | ||
| 493 | - MicroAPI::Add(dstRightReg, srcRightReg, dstRightReg, pregTail); | ||
| 494 | - MicroAPI::DataCopy(dst + (i + 1) * inner + innerTailOffset2, dstRightReg, pregTail); | ||
| 495 | - } | ||
| 496 | - } | ||
| 497 | -} | ||
| 498 | - | ||
| 499 | -__simd_vf__ inline void CumSumFirstDimBasic2VF(__ubuf__ float* dst, uint16_t outerRepeatTime, uint16_t inner, | ||
| 500 | - uint16_t mainRepeatTime, uint16_t innerOneRepNum, uint16_t tailTime, | ||
| 501 | - uint32_t tailCount, uint16_t halfMainRepeatTime, | ||
| 502 | - uint16_t mainTailRepeatTime, uint16_t innerTailOffset1, | ||
| 503 | - uint16_t innerTailOffset2) | ||
| 504 | -{ | ||
| 505 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 506 | - MicroAPI::MaskReg pregTail = MicroAPI::UpdateMask<float>(tailCount); | ||
| 507 | - MicroAPI::RegTensor<float> srcLeftReg; | ||
| 508 | - MicroAPI::RegTensor<float> dstLeftReg; | ||
| 509 | - | ||
| 510 | - for (uint16_t j = 0; j < mainRepeatTime; ++j) { | ||
| 511 | - MicroAPI::DataCopy(dstLeftReg, dst + j * innerOneRepNum); | ||
| 512 | - for (uint16_t i = 0; i < outerRepeatTime; ++i) { | ||
| 513 | - MicroAPI::DataCopy(srcLeftReg, dst + (i + 1) * inner + j * innerOneRepNum); | ||
| 514 | - MicroAPI::Add(dstLeftReg, srcLeftReg, dstLeftReg, pregFull); | ||
| 515 | - MicroAPI::DataCopy(dst + (i + 1) * inner + j * innerOneRepNum, dstLeftReg, pregFull); | ||
| 516 | - } | ||
| 517 | - } | ||
| 518 | - | ||
| 519 | - MicroAPI::DataCopy(dstLeftReg, dst + innerTailOffset2); | ||
| 520 | - for (uint16_t i = 0; i < outerRepeatTime; ++i) { | ||
| 521 | - for (uint16_t j = 0; j < tailTime; ++j) { | ||
| 522 | - MicroAPI::DataCopy(srcLeftReg, dst + (i + 1) * inner + innerTailOffset2); | ||
| 523 | - MicroAPI::Add(dstLeftReg, srcLeftReg, dstLeftReg, pregTail); | ||
| 524 | - MicroAPI::DataCopy(dst + (i + 1) * inner + innerTailOffset2, dstLeftReg, pregTail); | ||
| 525 | - } | ||
| 526 | - } | ||
| 527 | -} | ||
| 528 | - | ||
| 529 | -__aicore__ inline void CumSumFirstDimBasic(const LocalTensor<float>& dstTensor, uint32_t outer, uint32_t inner) | ||
| 530 | -{ | ||
| 531 | - __ubuf__ float* dst = (__ubuf__ float*)dstTensor.GetPhyAddr(); | ||
| 532 | - constexpr uint16_t innerOneRepNum = (uint32_t)(GetVecLen() / sizeof(float)); | ||
| 533 | - uint16_t mainRepeatTime = 0; | ||
| 534 | - if constexpr (innerOneRepNum > 0) { | ||
| 535 | - mainRepeatTime = inner / innerOneRepNum; | ||
| 536 | - } | ||
| 537 | - uint16_t outterRepeatTime = static_cast<uint16_t>(outer - 1); | ||
| 538 | - uint32_t tailCount = inner - mainRepeatTime * innerOneRepNum; | ||
| 539 | - uint16_t halfMainRepeatTime = mainRepeatTime / 2; | ||
| 540 | - uint16_t mainTailRepeatTime = mainRepeatTime % 2; | ||
| 541 | - uint16_t tailRepeatTime = tailCount > 0 ? 1 : 0; | ||
| 542 | - uint16_t castedInner = static_cast<uint16_t>(inner); | ||
| 543 | - uint16_t innerTailOffset1 = halfMainRepeatTime * innerOneRepNum * 2; | ||
| 544 | - uint16_t innerTailOffset2 = mainRepeatTime * innerOneRepNum; | ||
| 545 | - CumSumFirstDimBasic2VF(dst, outterRepeatTime, castedInner, mainRepeatTime, innerOneRepNum, tailRepeatTime, | ||
| 546 | - tailCount, halfMainRepeatTime, mainTailRepeatTime, innerTailOffset1, innerTailOffset2); | ||
| 547 | -} | ||
| 548 | - | ||
| 549 | -__aicore__ inline TransDataTo5HDParams ExtractTransDataParam(uint8_t repeatTimes, uint32_t inner, uint16_t alignOutter, | ||
| 550 | - uint32_t oneBlockElementNum, uint16_t dstRepStride, | ||
| 551 | - uint32_t srcRepStride) | ||
| 552 | -{ | ||
| 553 | - repeatTimes = 0; | ||
| 554 | - if (oneBlockElementNum > 0) { | ||
| 555 | - repeatTimes = inner / oneBlockElementNum; | ||
| 556 | - } | ||
| 557 | - if (repeatTimes > 1) { | ||
| 558 | - return TransDataTo5HDParams(false, false, repeatTimes, alignOutter, 1); | ||
| 559 | - } else { | ||
| 560 | - return TransDataTo5HDParams(false, false, repeatTimes, dstRepStride, srcRepStride); | ||
| 561 | - } | ||
| 562 | -} | ||
| 563 | - | ||
| 564 | -template <typename T = float> | ||
| 565 | -__aicore__ inline void Transpose5HDAB(const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, | ||
| 566 | - const CumSumInfo& cumSumInfo) | ||
| 567 | -{ | ||
| 568 | - constexpr uint32_t oneBlockElementNum = ONE_BLK_SIZE / sizeof(float); | ||
| 569 | - uint8_t repeatTimes = 1; | ||
| 570 | - uint16_t dstRepStride = 0; | ||
| 571 | - uint16_t srcRepStride = 0; | ||
| 572 | - uint16_t alignOutter = | ||
| 573 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 574 | - uint64_t transDataTo5HDDstLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 575 | - uint64_t transDataTo5HDSrcLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 576 | - if (cumSumInfo.outter == alignOutter && alignOutter > cumSumInfo.inner) { | ||
| 577 | - repeatTimes = alignOutter / NCHW_CONV_ADDR_LIST_SIZE; | ||
| 578 | - if (repeatTimes > 1) { | ||
| 579 | - dstRepStride = 2; | ||
| 580 | - srcRepStride = cumSumInfo.inner * 2; | ||
| 581 | - } | ||
| 582 | - TransDataTo5HDParams params(false, false, repeatTimes, dstRepStride, srcRepStride); | ||
| 583 | - for (int32_t i = 0; i < cumSumInfo.inner / oneBlockElementNum; i++) { | ||
| 584 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 585 | - transDataTo5HDSrcLocalList[n] = | ||
| 586 | - (uint64_t)srcTensor[i * oneBlockElementNum + n * cumSumInfo.inner].GetPhyAddr(); | ||
| 587 | - } | ||
| 588 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE / 2; n++) { | ||
| 589 | - transDataTo5HDDstLocalList[n * 2] = | ||
| 590 | - (uint64_t)dstTensor[(i * oneBlockElementNum + n) * alignOutter].GetPhyAddr(); | ||
| 591 | - transDataTo5HDDstLocalList[n * 2 + 1] = | ||
| 592 | - (uint64_t)dstTensor[(i * oneBlockElementNum + n) * alignOutter + oneBlockElementNum].GetPhyAddr(); | ||
| 593 | - } | ||
| 594 | - TransDataTo5HD<float>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, params); | ||
| 595 | - } | ||
| 596 | - } else { | ||
| 597 | - TransDataTo5HDParams params = ExtractTransDataParam(repeatTimes, cumSumInfo.inner, alignOutter, | ||
| 598 | - oneBlockElementNum, dstRepStride, srcRepStride); | ||
| 599 | - for (int32_t i = 0; i < alignOutter / NCHW_CONV_ADDR_LIST_SIZE; i++) { | ||
| 600 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 601 | - transDataTo5HDSrcLocalList[n] = | ||
| 602 | - (uint64_t)srcTensor[((i * NCHW_CONV_ADDR_LIST_SIZE | ||
| 603 | - + n % (cumSumInfo.outter - i * NCHW_CONV_ADDR_LIST_SIZE)) | ||
| 604 | - * cumSumInfo.inner)] | ||
| 605 | - .GetPhyAddr(); | ||
| 606 | - } | ||
| 607 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE / 2; n++) { | ||
| 608 | - transDataTo5HDDstLocalList[n * 2] = | ||
| 609 | - (uint64_t)dstTensor[i * NCHW_CONV_ADDR_LIST_SIZE + n * alignOutter].GetPhyAddr(); | ||
| 610 | - transDataTo5HDDstLocalList[n * 2 + 1] = | ||
| 611 | - (uint64_t)dstTensor[i * NCHW_CONV_ADDR_LIST_SIZE + n * alignOutter + oneBlockElementNum] | ||
| 612 | - .GetPhyAddr(); | ||
| 613 | - } | ||
| 614 | - TransDataTo5HD<float>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, params); | ||
| 615 | - } | ||
| 616 | - } | ||
| 617 | -} | ||
| 618 | - | ||
| 619 | -template <typename T = float> | ||
| 620 | -__aicore__ inline void Transpose5HDBA(const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, | ||
| 621 | - const CumSumInfo& cumSumInfo) | ||
| 622 | -{ | ||
| 623 | - constexpr uint32_t oneBlockElementNum = ONE_BLK_SIZE / sizeof(float); | ||
| 624 | - uint8_t repeatTimes = 1; | ||
| 625 | - uint16_t dstRepStride = 0; | ||
| 626 | - uint16_t srcRepStride = 0; | ||
| 627 | - uint16_t alignOutter = | ||
| 628 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 629 | - uint64_t transDataTo5HDDstLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 630 | - uint64_t transDataTo5HDSrcLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 631 | - if (alignOutter > cumSumInfo.inner) { | ||
| 632 | - repeatTimes = alignOutter / NCHW_CONV_ADDR_LIST_SIZE; | ||
| 633 | - if (repeatTimes > 1) { | ||
| 634 | - dstRepStride = cumSumInfo.inner * 2; | ||
| 635 | - srcRepStride = 2; | ||
| 636 | - } else { | ||
| 637 | - dstRepStride = 0; | ||
| 638 | - srcRepStride = 0; | ||
| 639 | - } | ||
| 640 | - TransDataTo5HDParams paramsBack(false, false, repeatTimes, dstRepStride, srcRepStride); | ||
| 641 | - for (int32_t i = 0; i < cumSumInfo.inner / oneBlockElementNum; i++) { | ||
| 642 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE / 2; n++) { | ||
| 643 | - transDataTo5HDSrcLocalList[n] = | ||
| 644 | - (uint64_t)srcTensor[i * oneBlockElementNum * alignOutter + n * alignOutter].GetPhyAddr(); | ||
| 645 | - transDataTo5HDSrcLocalList[n + NCHW_CONV_ADDR_LIST_SIZE / 2] = | ||
| 646 | - (uint64_t)srcTensor[i * oneBlockElementNum * alignOutter + n * alignOutter + oneBlockElementNum] | ||
| 647 | - .GetPhyAddr(); | ||
| 648 | - transDataTo5HDDstLocalList[n * 2] = | ||
| 649 | - (uint64_t)dstTensor[i * oneBlockElementNum + n * cumSumInfo.inner].GetPhyAddr(); | ||
| 650 | - transDataTo5HDDstLocalList[n * 2 + 1] = | ||
| 651 | - (uint64_t)dstTensor[i * oneBlockElementNum + (n + oneBlockElementNum) * cumSumInfo.inner] | ||
| 652 | - .GetPhyAddr(); | ||
| 653 | - } | ||
| 654 | - TransDataTo5HD<float>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, paramsBack); | ||
| 655 | - } | ||
| 656 | - } else { | ||
| 657 | - repeatTimes = cumSumInfo.inner / oneBlockElementNum; | ||
| 658 | - if (repeatTimes > 1) { | ||
| 659 | - dstRepStride = alignOutter; | ||
| 660 | - srcRepStride = 1; | ||
| 661 | - } else { | ||
| 662 | - dstRepStride = 0; | ||
| 663 | - srcRepStride = 0; | ||
| 664 | - } | ||
| 665 | - TransDataTo5HDParams paramsBack(false, false, repeatTimes, srcRepStride, dstRepStride); | ||
| 666 | - for (int32_t i = 0; i < alignOutter / NCHW_CONV_ADDR_LIST_SIZE; i++) { | ||
| 667 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE / 2; n++) { | ||
| 668 | - transDataTo5HDSrcLocalList[n] = | ||
| 669 | - (uint64_t)srcTensor[i * NCHW_CONV_ADDR_LIST_SIZE + n * alignOutter].GetPhyAddr(); | ||
| 670 | - transDataTo5HDSrcLocalList[n + NCHW_CONV_ADDR_LIST_SIZE / 2] = | ||
| 671 | - (uint64_t)srcTensor[i * NCHW_CONV_ADDR_LIST_SIZE + n * alignOutter + oneBlockElementNum] | ||
| 672 | - .GetPhyAddr(); | ||
| 673 | - } | ||
| 674 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE / 2; n++) { | ||
| 675 | - transDataTo5HDDstLocalList[n * 2] = | ||
| 676 | - (uint64_t)dstTensor[(i * NCHW_CONV_ADDR_LIST_SIZE + n) * cumSumInfo.inner].GetPhyAddr(); | ||
| 677 | - transDataTo5HDDstLocalList[n * 2 + 1] = | ||
| 678 | - (uint64_t)dstTensor[(i * NCHW_CONV_ADDR_LIST_SIZE + (n + NCHW_CONV_ADDR_LIST_SIZE / 2)) | ||
| 679 | - * cumSumInfo.inner] | ||
| 680 | - .GetPhyAddr(); | ||
| 681 | - } | ||
| 682 | - TransDataTo5HD<float>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, paramsBack); | ||
| 683 | - } | ||
| 684 | - } | ||
| 685 | -} | ||
| 686 | - | ||
| 687 | -template <typename T = half> | ||
| 688 | -__aicore__ inline void Transpose5HDAB(const LocalTensor<half>& dstTensor, const LocalTensor<half>& srcTensor, | ||
| 689 | - const CumSumInfo& cumSumInfo) | ||
| 690 | -{ | ||
| 691 | - constexpr uint32_t oneBlockElementNum = ONE_BLK_SIZE / sizeof(T); | ||
| 692 | - uint16_t alignOutter = | ||
| 693 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 694 | - uint64_t transDataTo5HDDstLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 695 | - uint64_t transDataTo5HDSrcLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 696 | - uint8_t repeatTimes = 1; | ||
| 697 | - uint16_t dstRepStride = 0; | ||
| 698 | - uint16_t srcRepStride = 0; | ||
| 699 | - if (cumSumInfo.outter == alignOutter && alignOutter > cumSumInfo.inner) { | ||
| 700 | - repeatTimes = alignOutter / NCHW_CONV_ADDR_LIST_SIZE; | ||
| 701 | - if (repeatTimes > 1) { | ||
| 702 | - dstRepStride = 1; | ||
| 703 | - srcRepStride = cumSumInfo.inner; | ||
| 704 | - } | ||
| 705 | - TransDataTo5HDParams params(false, false, repeatTimes, dstRepStride, srcRepStride); | ||
| 706 | - for (int32_t i = 0; i < cumSumInfo.inner / oneBlockElementNum; i++) { | ||
| 707 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 708 | - transDataTo5HDSrcLocalList[n] = | ||
| 709 | - (uint64_t)srcTensor[i * oneBlockElementNum + n * cumSumInfo.inner].GetPhyAddr(); | ||
| 710 | - transDataTo5HDDstLocalList[n] = | ||
| 711 | - (uint64_t)dstTensor[i * oneBlockElementNum * alignOutter + alignOutter * n].GetPhyAddr(); | ||
| 712 | - } | ||
| 713 | - TransDataTo5HD<T>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, params); | ||
| 714 | - } | ||
| 715 | - } else { | ||
| 716 | - TransDataTo5HDParams params = ExtractTransDataParam(repeatTimes, cumSumInfo.inner, alignOutter, | ||
| 717 | - oneBlockElementNum, dstRepStride, srcRepStride); | ||
| 718 | - for (int32_t i = 0; i < alignOutter / NCHW_CONV_ADDR_LIST_SIZE; i++) { | ||
| 719 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 720 | - transDataTo5HDSrcLocalList[n] = | ||
| 721 | - (uint64_t)srcTensor[((i * NCHW_CONV_ADDR_LIST_SIZE | ||
| 722 | - + n % (cumSumInfo.outter - i * NCHW_CONV_ADDR_LIST_SIZE)) | ||
| 723 | - * cumSumInfo.inner)] | ||
| 724 | - .GetPhyAddr(); | ||
| 725 | - transDataTo5HDDstLocalList[n] = | ||
| 726 | - (uint64_t)dstTensor[i * NCHW_CONV_ADDR_LIST_SIZE + alignOutter * n].GetPhyAddr(); | ||
| 727 | - } | ||
| 728 | - TransDataTo5HD<T>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, params); | ||
| 729 | - } | ||
| 730 | - } | ||
| 731 | -} | ||
| 732 | - | ||
| 733 | -template <typename T = half> | ||
| 734 | -__aicore__ inline void Transpose5HDBA(const LocalTensor<half>& dstTensor, const LocalTensor<half>& srcTensor, | ||
| 735 | - const CumSumInfo& cumSumInfo) | ||
| 736 | -{ | ||
| 737 | - constexpr uint32_t oneBlockElementNum = ONE_BLK_SIZE / sizeof(T); | ||
| 738 | - uint16_t alignOutter = | ||
| 739 | - (cumSumInfo.outter + NCHW_CONV_ADDR_LIST_SIZE - 1) / NCHW_CONV_ADDR_LIST_SIZE * NCHW_CONV_ADDR_LIST_SIZE; | ||
| 740 | - uint64_t transDataTo5HDDstLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 741 | - uint64_t transDataTo5HDSrcLocalList[NCHW_CONV_ADDR_LIST_SIZE]; | ||
| 742 | - uint8_t repeatTimes = 1; | ||
| 743 | - uint16_t dstRepStride = 0; | ||
| 744 | - uint16_t srcRepStride = 0; | ||
| 745 | - if (alignOutter > cumSumInfo.inner) { | ||
| 746 | - repeatTimes = alignOutter / oneBlockElementNum; | ||
| 747 | - if (repeatTimes > 1) { | ||
| 748 | - dstRepStride = cumSumInfo.inner; | ||
| 749 | - srcRepStride = 1; | ||
| 750 | - } else { | ||
| 751 | - dstRepStride = 0; | ||
| 752 | - srcRepStride = 0; | ||
| 753 | - } | ||
| 754 | - TransDataTo5HDParams paramsBack(false, false, repeatTimes, dstRepStride, srcRepStride); | ||
| 755 | - for (int32_t i = 0; i < cumSumInfo.inner / NCHW_CONV_ADDR_LIST_SIZE; i++) { | ||
| 756 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 757 | - transDataTo5HDSrcLocalList[n] = | ||
| 758 | - (uint64_t)srcTensor[(i * NCHW_CONV_ADDR_LIST_SIZE + n) * alignOutter].GetPhyAddr(); | ||
| 759 | - transDataTo5HDDstLocalList[n] = | ||
| 760 | - (uint64_t)dstTensor[i * NCHW_CONV_ADDR_LIST_SIZE + n * cumSumInfo.inner].GetPhyAddr(); | ||
| 761 | - } | ||
| 762 | - TransDataTo5HD<T>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, paramsBack); | ||
| 763 | - } | ||
| 764 | - } else { | ||
| 765 | - repeatTimes = cumSumInfo.inner / oneBlockElementNum; | ||
| 766 | - if (repeatTimes > 1) { | ||
| 767 | - srcRepStride = 1; | ||
| 768 | - dstRepStride = alignOutter; | ||
| 769 | - } else { | ||
| 770 | - dstRepStride = 0; | ||
| 771 | - srcRepStride = 0; | ||
| 772 | - } | ||
| 773 | - TransDataTo5HDParams paramsBack(false, false, repeatTimes, srcRepStride, dstRepStride); | ||
| 774 | - for (int32_t i = 0; i < alignOutter / NCHW_CONV_ADDR_LIST_SIZE; i++) { | ||
| 775 | - for (int32_t n = 0; n < NCHW_CONV_ADDR_LIST_SIZE; n++) { | ||
| 776 | - transDataTo5HDSrcLocalList[n] = | ||
| 777 | - (uint64_t)srcTensor[i * NCHW_CONV_ADDR_LIST_SIZE + alignOutter * n].GetPhyAddr(); | ||
| 778 | - transDataTo5HDDstLocalList[n] = | ||
| 779 | - (uint64_t)dstTensor[(i * NCHW_CONV_ADDR_LIST_SIZE + n) * cumSumInfo.inner].GetPhyAddr(); | ||
| 780 | - } | ||
| 781 | - TransDataTo5HD<T>(transDataTo5HDDstLocalList, transDataTo5HDSrcLocalList, paramsBack); | ||
| 782 | - } | ||
| 783 | - } | ||
| 784 | -} | ||
| 785 | -} // namespace Internal | ||
| 786 | -} // namespace AscendC | ||
| 787 | - | ||
| 788 | - | ||
Dimpl/adv_api/detail/math/erf/erf_l300_impl.h+0-401
| @@ -1,401 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file erf_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace ErfAPI { | ||
| 24 | - | ||
| 25 | -constexpr MicroAPI::CastTrait castTraitF162F32 = { | ||
| 26 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 27 | -constexpr MicroAPI::CastTrait castTraitF322F16 = { | ||
| 28 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 29 | - | ||
| 30 | -constexpr uint32_t ERF_C0 = 0x3F8060FE; | ||
| 31 | -constexpr uint32_t ERF_P1[] = { | ||
| 32 | - 0x38EB4C3A, 0xBAAE005B, 0x3C09919F, 0xBD24D99A, | ||
| 33 | - 0x3E235519, 0x3F69B4F9, 0x3F210A14 | ||
| 34 | -}; | ||
| 35 | -constexpr uint32_t ERF_P2[] = { | ||
| 36 | - 0x38B1E96A, 0xBA574D20, 0x3BAAD5EA, 0xBCDC1BE7, | ||
| 37 | - 0x3DE718AF, 0xBEC093AC, 0x3E0375D3 | ||
| 38 | -}; | ||
| 39 | - | ||
| 40 | -// Clip x to [-3.92, 3.92] | ||
| 41 | -__simd_callee__ inline void ErfClip(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg& mask) | ||
| 42 | -{ | ||
| 43 | - constexpr float ERF_BOUNDARY_MAX = 3.92; | ||
| 44 | - MicroAPI::Mins(dstReg, srcReg, ERF_BOUNDARY_MAX, mask); | ||
| 45 | - MicroAPI::Maxs(dstReg, dstReg, -ERF_BOUNDARY_MAX, mask); | ||
| 46 | -} | ||
| 47 | - | ||
| 48 | -// P(x) = (((((0.053443748819x^2+0.75517016694e1)x^2+0.10162808918e3)x^2 | ||
| 49 | -// +0.13938061484e4)x^2+0.50637915060e4)x^2+0.29639384698e5)x | ||
| 50 | -__simd_callee__ inline void ErfComputeP(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg& mask) | ||
| 51 | -{ | ||
| 52 | - constexpr float SCALAR_P0 = 0.29639384698e5; | ||
| 53 | - constexpr float SCALAR_P1 = 0.50637915060e4; | ||
| 54 | - constexpr float SCALAR_P2 = 0.13938061484e4; | ||
| 55 | - constexpr float SCALAR_P3 = 0.10162808918e3; | ||
| 56 | - constexpr float SCALAR_P4 = 0.75517016694e1; | ||
| 57 | - constexpr float SCALAR_P5 = 0.053443748819; | ||
| 58 | - | ||
| 59 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 60 | - MicroAPI::Mul(tmpReg, srcReg, srcReg, mask); | ||
| 61 | - MicroAPI::Muls(dstReg, tmpReg, SCALAR_P5, mask); | ||
| 62 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_P4, mask); | ||
| 63 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 64 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_P3, mask); | ||
| 65 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 66 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_P2, mask); | ||
| 67 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 68 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_P1, mask); | ||
| 69 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 70 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_P0, mask); | ||
| 71 | - MicroAPI::Mul(dstReg, dstReg, srcReg, mask); | ||
| 72 | -} | ||
| 73 | - | ||
| 74 | -// Q(x) = ((((x^2+0.31212858877e2)x^2+0.39856963806e3)x^2+0.30231248150e4)x^2+0.13243365831e5)x^2+0.26267224157e5 | ||
| 75 | -__simd_callee__ inline void ErfComputeQ(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 76 | - MicroAPI::MaskReg& mask) | ||
| 77 | -{ | ||
| 78 | - constexpr float SCALAR_Q0 = 0.26267224157e5; | ||
| 79 | - constexpr float SCALAR_Q1 = 0.13243365831e5; | ||
| 80 | - constexpr float SCALAR_Q2 = 0.30231248150e4; | ||
| 81 | - constexpr float SCALAR_Q3 = 0.39856963806e3; | ||
| 82 | - constexpr float SCALAR_Q4 = 0.31212858877e2; | ||
| 83 | - | ||
| 84 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 85 | - MicroAPI::Mul(tmpReg, srcReg, srcReg, mask); | ||
| 86 | - MicroAPI::Adds(dstReg, tmpReg, SCALAR_Q4, mask); | ||
| 87 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 88 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_Q3, mask); | ||
| 89 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 90 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_Q2, mask); | ||
| 91 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 92 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_Q1, mask); | ||
| 93 | - MicroAPI::Mul(dstReg, dstReg, tmpReg, mask); | ||
| 94 | - MicroAPI::Adds(dstReg, dstReg, SCALAR_Q0, mask); | ||
| 95 | -} | ||
| 96 | - | ||
| 97 | -__simd_callee__ inline void ErfPadeCompute(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 98 | - MicroAPI::MaskReg& mask) | ||
| 99 | -{ | ||
| 100 | - // x = Clip(x), Erf(x) = P(x) / Q(x) | ||
| 101 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 102 | - ErfClip(dstReg, srcReg, mask); | ||
| 103 | - ErfComputeP(tmpReg, dstReg, mask); | ||
| 104 | - ErfComputeQ(dstReg, dstReg, mask); | ||
| 105 | - | ||
| 106 | - MicroAPI::Div(dstReg, tmpReg, dstReg, mask); | ||
| 107 | -} | ||
| 108 | - | ||
| 109 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 110 | - MicroAPI::RegTensor<float>& srcReg2, MicroAPI::RegTensor<float>& srcReg3, MicroAPI::MaskReg& mask) | ||
| 111 | -{ | ||
| 112 | - MicroAPI::RegTensor<float> tmpReg = srcReg1; | ||
| 113 | - MicroAPI::FusedMulDstAdd(tmpReg, srcReg2, srcReg3, mask); | ||
| 114 | - dstReg = tmpReg; | ||
| 115 | -} | ||
| 116 | - | ||
| 117 | -__simd_callee__ inline void ErfSpecialCaseCompute(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 118 | - MicroAPI::RegTensor<float>& tmpReg, MicroAPI::MaskReg& mask) | ||
| 119 | -{ | ||
| 120 | - /* | ||
| 121 | - * if (f5 < int32_as_float(0x3F8060FE)) { | ||
| 122 | - * *y = f26; | ||
| 123 | - * } else { | ||
| 124 | - * float f23 = exp(f26 * log(2.0)); | ||
| 125 | - * float f25 = int32_as_float(0x3F800000) - f23; | ||
| 126 | - * unsigned int r3 = float_as_int32(f4) & 0x80000000; | ||
| 127 | - * unsigned int r4 = r3 | float_as_int32(f25); | ||
| 128 | - * *y = int32_as_float(r4); | ||
| 129 | - * } | ||
| 130 | - */ | ||
| 131 | - constexpr uint32_t ERF_R0 = 0x3F8060FE; | ||
| 132 | - constexpr uint32_t ERF_R1 = 0x3F800000; | ||
| 133 | - constexpr uint32_t ERF_R2 = 0x80000000; | ||
| 134 | - constexpr float LOG2_VAULE = 2.0f; | ||
| 135 | - | ||
| 136 | - MicroAPI::RegTensor<float> tmpF5Reg, tmpF32Reg, tmpF32Reg1; | ||
| 137 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg; | ||
| 138 | - MicroAPI::MaskReg cmpMask; | ||
| 139 | - MicroAPI::Abs(tmpF5Reg, srcReg, mask); | ||
| 140 | - MicroAPI::Duplicate(tmpU32Reg, ERF_R0, mask); | ||
| 141 | - MicroAPI::Compare<float, CMPMODE::LT>(cmpMask, tmpF5Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg, mask); | ||
| 142 | - | ||
| 143 | - MicroAPI::Duplicate(tmpF32Reg, LOG2_VAULE, mask); | ||
| 144 | - MicroAPI::Log(tmpF32Reg, tmpF32Reg, mask); | ||
| 145 | - MicroAPI::Mul(tmpF32Reg, tmpReg, tmpF32Reg, mask); | ||
| 146 | - MicroAPI::Exp(tmpF32Reg, tmpF32Reg, mask); // tmpF32Reg: f23 | ||
| 147 | - MicroAPI::Duplicate(tmpU32Reg, ERF_R1, mask); | ||
| 148 | - MicroAPI::Sub(tmpF32Reg1, (MicroAPI::RegTensor<float> &)tmpU32Reg, tmpF32Reg, mask); //tmpF32Reg1: f25 | ||
| 149 | - | ||
| 150 | - MicroAPI::Duplicate(tmpU32Reg, ERF_R2, mask); | ||
| 151 | - MicroAPI::And(tmpU32Reg, (MicroAPI::RegTensor<uint32_t> &)srcReg, tmpU32Reg, mask); | ||
| 152 | - MicroAPI::Or(tmpU32Reg, tmpU32Reg, (MicroAPI::RegTensor<uint32_t> &)tmpF32Reg1, mask); // tmpU32Reg: r4 | ||
| 153 | - | ||
| 154 | - MicroAPI::Select(dstReg, tmpReg, (MicroAPI::RegTensor<float> &)tmpU32Reg, cmpMask); | ||
| 155 | -} | ||
| 156 | - | ||
| 157 | -__simd_callee__ inline void ErfSubsectionCompute(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 158 | - MicroAPI::MaskReg& mask) | ||
| 159 | -{ | ||
| 160 | - MicroAPI::RegTensor<float> tmpF5Reg, tmpF32Reg, tmpF32Reg1, tmpF32Reg2; | ||
| 161 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg, tmpU32Reg1; | ||
| 162 | - MicroAPI::MaskReg cmpMask; | ||
| 163 | - /* | ||
| 164 | - * float f4 = x; | ||
| 165 | - * float f5 = fabsf(x); | ||
| 166 | - * bool p1 = f5 < int32_as_float(0x3F8060FE); | ||
| 167 | - * bool p2 = f5 >= int32_as_float(0x3F8060FE); | ||
| 168 | - */ | ||
| 169 | - MicroAPI::Abs(tmpF5Reg, srcReg, mask); | ||
| 170 | - MicroAPI::Duplicate(tmpU32Reg, ERF_C0, mask); | ||
| 171 | - MicroAPI::Compare<float, CMPMODE::GE>(cmpMask, tmpF5Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg, mask); | ||
| 172 | - /* | ||
| 173 | - * float f6 = f4 * f4; | ||
| 174 | - * float f7 = p2 ? f5 : f6; | ||
| 175 | - * float f8 = p2 ? int32_as_float(0x38EB4C3A) : int32_as_float(0x28B1E96A); | ||
| 176 | - * float f9 = p2 ? int32_as_float(0xBAAE005B) : int32_as_float(0xBA574D20); | ||
| 177 | - * float f10 = fmaf(f8, f7, f9); | ||
| 178 | - */ | ||
| 179 | - MicroAPI::Mul(tmpF32Reg1, srcReg, srcReg, mask); | ||
| 180 | - MicroAPI::Select(tmpF32Reg, tmpF5Reg, tmpF32Reg1, cmpMask); // tmpF32Reg: f7 | ||
| 181 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[0], mask); | ||
| 182 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[0], mask); | ||
| 183 | - MicroAPI::Select(tmpF32Reg1, | ||
| 184 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); | ||
| 185 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[1], mask); | ||
| 186 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[1], mask); | ||
| 187 | - MicroAPI::Select(tmpF32Reg2, | ||
| 188 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); | ||
| 189 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f10 | ||
| 190 | - /* | ||
| 191 | - * float f11 = p2 ? int32_as_float(0x3C09919F) : int32_as_float(0x3BAAD5EA); | ||
| 192 | - * float f12 = fmaf(f10, f7, f11); | ||
| 193 | - */ | ||
| 194 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[2], mask); // int32_as_float(0x3C09919F) | ||
| 195 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[2], mask); // int32_as_float(0x3BAAD5EA) | ||
| 196 | - MicroAPI::Select(tmpF32Reg2, | ||
| 197 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); // tmpF32Reg2: f11 | ||
| 198 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f12 | ||
| 199 | - /* | ||
| 200 | - * float f13 = p2 ? int32_as_float(0xBD24D99A) : int32_as_float(0xBCDC1BE7); | ||
| 201 | - * float f14 = fmaf(f12, f7, f13); | ||
| 202 | - */ | ||
| 203 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[3], mask); // int32_as_float(0xBD24D99A) | ||
| 204 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[3], mask); // int32_as_float(0xBCDC1BE7) | ||
| 205 | - MicroAPI::Select(tmpF32Reg2, | ||
| 206 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); // tmpF32Reg2: f13 | ||
| 207 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f14 | ||
| 208 | - /* | ||
| 209 | - * float f15 = p2 ? int32_as_float(0x3E235519) : int32_as_float(0x3DE718AF); | ||
| 210 | - * float f16 = fmaf(f14, f7, f15); | ||
| 211 | - */ | ||
| 212 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[4], mask); // int32_as_float(0x3E235519) | ||
| 213 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[4], mask); // int32_as_float(0x3DE718AF) | ||
| 214 | - MicroAPI::Select(tmpF32Reg2, | ||
| 215 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); // tmpF32Reg2: f13 | ||
| 216 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f16 | ||
| 217 | - /* | ||
| 218 | - * float f17 = p2 ? int32_as_float(0x3F69B4F9) : int32_as_float(0xBEC093AC); | ||
| 219 | - * float f18 = fmaf(f16, f7, f17); | ||
| 220 | - */ | ||
| 221 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[5], mask); // int32_as_float(0x3F69B4F9) | ||
| 222 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[5], mask); // int32_as_float(0xBEC093AC) | ||
| 223 | - MicroAPI::Select(tmpF32Reg2, | ||
| 224 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); // tmpF32Reg2: f13 | ||
| 225 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f18 | ||
| 226 | - /* | ||
| 227 | - * float f19 = p2 ? int32_as_float(0x3F210A14) : int32_as_float(0x3E0375D3); | ||
| 228 | - * float f20 = fmaf(f18, f7, f19); | ||
| 229 | - */ | ||
| 230 | - MicroAPI::Duplicate(tmpU32Reg, ERF_P1[6], mask); // int32_as_float(0x3F210A14) | ||
| 231 | - MicroAPI::Duplicate(tmpU32Reg1, ERF_P2[6], mask); // int32_as_float(0x3E0375D3) | ||
| 232 | - MicroAPI::Select(tmpF32Reg2, | ||
| 233 | - (MicroAPI::RegTensor<float> &)tmpU32Reg, (MicroAPI::RegTensor<float> &)tmpU32Reg1, cmpMask); // tmpF32Reg2: f19 | ||
| 234 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg, tmpF32Reg2, mask); // tmpF32Reg1: f20 | ||
| 235 | - /* | ||
| 236 | - * float f21 = -f5; | ||
| 237 | - * float f22 = p2 ? f21 : f4 | ||
| 238 | - * float f26 = fmaf(f20, f22, f22); | ||
| 239 | - */ | ||
| 240 | - MicroAPI::Neg(tmpF32Reg, tmpF5Reg, mask); | ||
| 241 | - MicroAPI::Select(tmpF32Reg2, tmpF32Reg, srcReg, cmpMask); | ||
| 242 | - FMaf(tmpF32Reg1, tmpF32Reg1, tmpF32Reg2, tmpF32Reg2, mask); // tmpF32Reg1: f26 | ||
| 243 | - ErfSpecialCaseCompute(dstReg, srcReg, tmpF32Reg1, mask); | ||
| 244 | -} | ||
| 245 | - | ||
| 246 | -template <typename T, bool isReuseSource = false, const ErfConfig &config = defaultErfConfig> | ||
| 247 | -__simd_vf__ inline void ErfCoreImpl(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t calCount, uint16_t repeatTimes) | ||
| 248 | -{ | ||
| 249 | - MicroAPI::MaskReg mask; | ||
| 250 | - MicroAPI::RegTensor<T> srcReg; | ||
| 251 | - MicroAPI::RegTensor<float> castReg; | ||
| 252 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 253 | - MicroAPI::RegTensor<float> dstReg; | ||
| 254 | - | ||
| 255 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 256 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 257 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 258 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 259 | - MicroAPI::Cast<float, T, castTraitF162F32>(castReg, srcReg, mask); | ||
| 260 | - } else { | ||
| 261 | - MicroAPI::DataCopy(castReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 262 | - } | ||
| 263 | - if constexpr (config.algo == ErfAlgo::PADE_APPROXIMATION) { | ||
| 264 | - ErfPadeCompute(dstReg, castReg, mask); | ||
| 265 | - } else { | ||
| 266 | - ErfSubsectionCompute(dstReg, castReg, mask); | ||
| 267 | - } | ||
| 268 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 269 | - MicroAPI::Cast<T, float, castTraitF322F16>(srcReg, dstReg, mask); | ||
| 270 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, mask); | ||
| 271 | - } else { | ||
| 272 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, dstReg, mask); | ||
| 273 | - } | ||
| 274 | - } | ||
| 275 | -} | ||
| 276 | -} // namespace ErfAPI | ||
| 277 | - | ||
| 278 | -template <typename T, bool isReuseSource = false, const ErfConfig &config = defaultErfConfig> | ||
| 279 | -__aicore__ inline void ErfCheckParams(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 280 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 281 | -{ | ||
| 282 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 283 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Erf"); | ||
| 284 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Erf"); | ||
| 285 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Erf"); | ||
| 286 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Erf"); | ||
| 287 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Erf"); | ||
| 288 | -} | ||
| 289 | - | ||
| 290 | -template <typename T, bool isReuseSource = false, const ErfConfig &config = defaultErfConfig> | ||
| 291 | -__aicore__ inline void ErfImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 292 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 293 | -{ | ||
| 294 | - // Only for AI Vector Core. | ||
| 295 | - if ASCEND_IS_AIC { | ||
| 296 | - return; | ||
| 297 | - } | ||
| 298 | - | ||
| 299 | - ErfCheckParams<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 300 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 301 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 302 | - uint16_t repeatTimes = CeilDivision(calCount, B32_DATA_NUM_PER_REPEAT); | ||
| 303 | - ErfAPI::ErfCoreImpl<T, isReuseSource, config>(dstUb, srcUb, calCount, repeatTimes); | ||
| 304 | -} | ||
| 305 | - | ||
| 306 | -template <typename T, bool isReuseSource = false, const ErfConfig &config = defaultErfConfig> | ||
| 307 | -__aicore__ inline void ErfImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 308 | - const uint32_t calCount) | ||
| 309 | -{ | ||
| 310 | - // Only for AI Vector Core. | ||
| 311 | - if ASCEND_IS_AIC { | ||
| 312 | - return; | ||
| 313 | - } | ||
| 314 | - | ||
| 315 | - // Using the Stack Space to Allocate tmpBuffer | ||
| 316 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 317 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(sharedTmpBuffer); | ||
| 318 | - ASCENDC_ASSERT((ans), { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 319 | - ErfImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 320 | -} | ||
| 321 | - | ||
| 322 | -/*! | ||
| 323 | - * \ingroup Erf | ||
| 324 | - * \brief compute Erf elementwisely | ||
| 325 | - * \tparam T: half/float | ||
| 326 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 327 | - * \tparam defaultErfConfig: the config for Erf, choose different algo | ||
| 328 | - * \param [out] dstTensor: output LocalTensor | ||
| 329 | - * \param [in] srcTensor: input LocalTensor | ||
| 330 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 331 | - * whose required space size should refer to corresponding tiling API, which is defined at erf_tiling.h. | ||
| 332 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 333 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 334 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 335 | - * \param [in] calCount: the number of elements to be processed. | ||
| 336 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 337 | - */ | ||
| 338 | -template <typename T, bool isReuseSource = false, const ErfConfig& config = defaultErfConfig> | ||
| 339 | -__aicore__ inline void Erf(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 340 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 341 | -{ | ||
| 342 | - ErfImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 343 | -} | ||
| 344 | - | ||
| 345 | -/*! | ||
| 346 | - * \ingroup Erf | ||
| 347 | - * \brief compute Erf elementwisely for whole source tensor | ||
| 348 | - * \tparam T: half/float | ||
| 349 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 350 | - * \tparam defaultErfConfig: the config for Erf, choose different algo | ||
| 351 | - * \param [out] dstTensor: output LocalTensor | ||
| 352 | - * \param [in] srcTensor: input LocalTensor | ||
| 353 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 354 | - * whose required space size should refer to corresponding tiling API, which is defined at erf_tiling.h. | ||
| 355 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 356 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 357 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 358 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 359 | - */ | ||
| 360 | -template <typename T, bool isReuseSource = false, const ErfConfig& config = defaultErfConfig> | ||
| 361 | -__aicore__ inline void Erf( | ||
| 362 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 363 | -{ | ||
| 364 | - Erf<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, srcTensor.GetSize()); | ||
| 365 | -} | ||
| 366 | - | ||
| 367 | -/*! | ||
| 368 | - * \ingroup Erf | ||
| 369 | - * \brief compute Erf elementwisely | ||
| 370 | - * \tparam T: half/float | ||
| 371 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 372 | - * \tparam defaultErfConfig: the config for Erf, choose different algo | ||
| 373 | - * \param [out] dstTensor: output LocalTensor | ||
| 374 | - * \param [in] srcTensor: input LocalTensor | ||
| 375 | - * \param [in] calCount: the number of elements to be processed. | ||
| 376 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 377 | - */ | ||
| 378 | -template <typename T, bool isReuseSource = false, const ErfConfig& config = defaultErfConfig> | ||
| 379 | -__aicore__ inline void Erf(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 380 | -{ | ||
| 381 | - ErfImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 382 | -} | ||
| 383 | - | ||
| 384 | -/*! | ||
| 385 | - * \ingroup Erf | ||
| 386 | - * \brief compute Erf elementwisely for whole source tensor | ||
| 387 | - * \tparam T: half/float | ||
| 388 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 389 | - * \tparam defaultErfConfig: the config for Erf, choose different algo | ||
| 390 | - * \param [out] dstTensor: output LocalTensor | ||
| 391 | - * \param [in] srcTensor: input LocalTensor | ||
| 392 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 393 | - */ | ||
| 394 | -template <typename T, bool isReuseSource = false, const ErfConfig& config = defaultErfConfig> | ||
| 395 | -__aicore__ inline void Erf(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor) | ||
| 396 | -{ | ||
| 397 | - Erf<T, isReuseSource, config>(dstTensor, srcTensor, srcTensor.GetSize()); | ||
| 398 | -} | ||
| 399 | -} // namespace AscendC | ||
| 400 | - | ||
| 401 | - | ||
Dimpl/adv_api/detail/math/erfc/erfc_l300_impl.h+0-187
| @@ -1,187 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file erfc_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -namespace AscendC { | ||
| 21 | -namespace ERFC { | ||
| 22 | - | ||
| 23 | -constexpr MicroAPI::CastTrait castTraitF162F32 = { | ||
| 24 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 25 | -constexpr MicroAPI::CastTrait castTraitF322F16 = { | ||
| 26 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 27 | - | ||
| 28 | -__simd_callee__ inline void MulAdds(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 29 | - MicroAPI::RegTensor<float>& srcReg2, const float scalarValue, MicroAPI::MaskReg& mask) | ||
| 30 | -{ | ||
| 31 | - // dst = src1 * src2 + scalerValue | ||
| 32 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 33 | - MicroAPI::Mul(tmpReg, srcReg1, srcReg2, mask); | ||
| 34 | - MicroAPI::Adds(dstReg, tmpReg, scalarValue, mask); | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | -// compute Erfc with xa = |x| + fp32_min | ||
| 38 | -__simd_callee__ inline void ErfcPreCompute(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg mask) | ||
| 39 | -{ | ||
| 40 | - constexpr float SCALAR_ERFC_FP32_MIN = 2.168404344971009e-19; // 2^-62 | ||
| 41 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 42 | - MicroAPI::Abs(tmpReg, srcReg, mask); | ||
| 43 | - MicroAPI::Adds(dstReg, tmpReg, SCALAR_ERFC_FP32_MIN, mask); | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -// compute Erfc R(z) = ((((((((z*r0 + r1)*z + r2)*z + r3)*z + r4)*z + r5)*z + r6)*z + r7)*z + r8) | ||
| 47 | -__simd_callee__ inline void ErfcComputeR(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg mask) | ||
| 48 | -{ | ||
| 49 | - // Specific value used for approximate calculation. | ||
| 50 | - constexpr float R0 = 0.1735313680e-7; | ||
| 51 | - constexpr float R1 = -0.9856738394e-6; | ||
| 52 | - constexpr float R2 = 0.2517003236e-4; | ||
| 53 | - constexpr float R3 = -0.3848015171e-3; | ||
| 54 | - constexpr float R4 = 0.5681528564e0; | ||
| 55 | - constexpr float R5 = 0.5245623129e1; | ||
| 56 | - constexpr float R6 = 0.2107740710e2; | ||
| 57 | - constexpr float R7 = 0.4212761755e2; | ||
| 58 | - constexpr float R8 = 0.4380524149e2; | ||
| 59 | - | ||
| 60 | - MicroAPI::RegTensor<float> rReg; | ||
| 61 | - MicroAPI::Duplicate(rReg, R0, mask); | ||
| 62 | - MulAdds(dstReg, srcReg, rReg, R1, mask); | ||
| 63 | - MulAdds(dstReg, dstReg, srcReg, R2, mask); | ||
| 64 | - MulAdds(dstReg, dstReg, srcReg, R3, mask); | ||
| 65 | - MulAdds(dstReg, dstReg, srcReg, R4, mask); | ||
| 66 | - MulAdds(dstReg, dstReg, srcReg, R5, mask); | ||
| 67 | - MulAdds(dstReg, dstReg, srcReg, R6, mask); | ||
| 68 | - MulAdds(dstReg, dstReg, srcReg, R7, mask); | ||
| 69 | - MulAdds(dstReg, dstReg, srcReg, R8, mask); | ||
| 70 | -} | ||
| 71 | - | ||
| 72 | -// compute Erfc S(z) = (((((z + s1)*z + s2)*z + s3)*z + s4)*z + s5) | ||
| 73 | -__simd_callee__ inline void ErfcComputeS(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg mask) | ||
| 74 | -{ | ||
| 75 | - // Specific value used for approximate calculation. | ||
| 76 | - constexpr float S1 = 0.9349684299e1; | ||
| 77 | - constexpr float S2 = 0.3756930664e2; | ||
| 78 | - constexpr float S3 = 0.8058268949e2; | ||
| 79 | - constexpr float S4 = 0.9155653738e2; | ||
| 80 | - constexpr float S5 = 0.4380524152e2; | ||
| 81 | - | ||
| 82 | - MicroAPI::Adds(dstReg, srcReg, S1, mask); | ||
| 83 | - MulAdds(dstReg, dstReg, srcReg, S2, mask); | ||
| 84 | - MulAdds(dstReg, dstReg, srcReg, S3, mask); | ||
| 85 | - MulAdds(dstReg, dstReg, srcReg, S4, mask); | ||
| 86 | - MulAdds(dstReg, dstReg, srcReg, S5, mask); | ||
| 87 | -} | ||
| 88 | - | ||
| 89 | -__simd_callee__ inline void ErfcClip(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg mask) | ||
| 90 | -{ | ||
| 91 | - constexpr float ERFC_BOUNDARY_MAX = 10.0f; | ||
| 92 | - MicroAPI::Mins(dstReg, srcReg, ERFC_BOUNDARY_MAX, mask); | ||
| 93 | - MicroAPI::Maxs(dstReg, dstReg, -ERFC_BOUNDARY_MAX, mask); | ||
| 94 | -} | ||
| 95 | - | ||
| 96 | -// Compute Erfc: exp(-xa^2) * (R(z) / S(z)) * xb + (1 - xb) | ||
| 97 | -__simd_callee__ inline void ErfcPublicSteps(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg mask) | ||
| 98 | -{ | ||
| 99 | - constexpr float MIN_BOUNDARY = 10.0f; | ||
| 100 | - // Compute xa = |x| + min_pf32, exp(-xa^2) | ||
| 101 | - MicroAPI::RegTensor<float> xaReg, xbReg, zReg, rzReg, szReg; | ||
| 102 | - MicroAPI::RegTensor<float> oneReg, tmpReg; | ||
| 103 | - ErfcPreCompute(xaReg, srcReg, mask); | ||
| 104 | - MicroAPI::Mul(tmpReg, xaReg, xaReg, mask); | ||
| 105 | - MicroAPI::Neg(tmpReg, tmpReg, mask); | ||
| 106 | - MicroAPI::Exp(dstReg, tmpReg, mask); | ||
| 107 | - // Compute z = min(xa, 10), xb = x / xa, exp(-xa^2) * xb | ||
| 108 | - MicroAPI::Mins(zReg, xaReg, MIN_BOUNDARY, mask); | ||
| 109 | - MicroAPI::Div(xbReg, srcReg, xaReg, mask); | ||
| 110 | - MicroAPI::Mul(dstReg, dstReg, xbReg, mask); | ||
| 111 | - // Compute exp(-xa^2) * xb * (R(z) / S(z)) | ||
| 112 | - ErfcComputeR(rzReg, zReg, mask); | ||
| 113 | - ErfcComputeS(szReg, zReg, mask); | ||
| 114 | - MicroAPI::Mul(dstReg, dstReg, rzReg, mask); | ||
| 115 | - MicroAPI::Div(dstReg, dstReg, szReg, mask); | ||
| 116 | - | ||
| 117 | - MicroAPI::Duplicate(oneReg, 1.0f, mask); | ||
| 118 | - MicroAPI::Sub(tmpReg, oneReg, xbReg, mask); | ||
| 119 | - MicroAPI::Add(dstReg, dstReg, tmpReg, mask); | ||
| 120 | -} | ||
| 121 | - | ||
| 122 | -template<typename T> | ||
| 123 | -__simd_vf__ inline void ErfcCoreImpl(__ubuf__ T* dstUb, __ubuf__ T* srcUb, uint32_t calCount, uint16_t repeatTimes) | ||
| 124 | -{ | ||
| 125 | - MicroAPI::RegTensor<T> srcReg; | ||
| 126 | - MicroAPI::RegTensor<float> castReg; | ||
| 127 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 128 | - MicroAPI::RegTensor<float> dstReg; | ||
| 129 | - | ||
| 130 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 131 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 132 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 133 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 134 | - MicroAPI::Cast<float, T, castTraitF162F32>(castReg, srcReg, mask); | ||
| 135 | - } else { | ||
| 136 | - MicroAPI::DataCopy(castReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 137 | - } | ||
| 138 | - ErfcClip(tmpReg, castReg, mask); | ||
| 139 | - ErfcPublicSteps(dstReg, tmpReg, mask); | ||
| 140 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 141 | - MicroAPI::Cast<T, float, castTraitF322F16>(srcReg, dstReg, mask); | ||
| 142 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, mask); | ||
| 143 | - } else { | ||
| 144 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, dstReg, mask); | ||
| 145 | - } | ||
| 146 | - } | ||
| 147 | -} | ||
| 148 | - | ||
| 149 | -} // namespace ERFC | ||
| 150 | - | ||
| 151 | -template <typename T, bool isReuseSource = false> | ||
| 152 | -__aicore__ inline void ErfcImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 153 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 154 | -{ | ||
| 155 | - CheckTensorPos(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECOUT / VECCALC", "Erfc"); | ||
| 156 | - ErfcImpl(dstTensor, srcTensor, calCount); | ||
| 157 | -} | ||
| 158 | - | ||
| 159 | -template <typename T, bool isReuseSource = false> | ||
| 160 | -__aicore__ inline void ErfcImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 161 | - const uint32_t calCount) | ||
| 162 | -{ | ||
| 163 | - // Only for AI Vector Core. | ||
| 164 | - if ASCEND_IS_AIC { | ||
| 165 | - return; | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 169 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "ERFC"); | ||
| 170 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "ERFC"); | ||
| 171 | - ASCENDC_ASSERT((calCount <= srcTensor.GetSize()), { | ||
| 172 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than srcTensor length %u", calCount, | ||
| 173 | - srcTensor.GetSize()); | ||
| 174 | - }); | ||
| 175 | - ASCENDC_ASSERT((calCount <= dstTensor.GetSize()), { | ||
| 176 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than dstTensor length %u", calCount, | ||
| 177 | - dstTensor.GetSize()); | ||
| 178 | - }); | ||
| 179 | - | ||
| 180 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 181 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 182 | - uint16_t repeatTimes = CeilDivision(calCount, B32_DATA_NUM_PER_REPEAT); | ||
| 183 | - ERFC::ErfcCoreImpl<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 184 | -} | ||
| 185 | -} // namespace AscendC | ||
| 186 | - | ||
| 187 | - | ||
Dimpl/adv_api/detail/math/floor/floor_l300_impl.h+0-43
| @@ -1,43 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file floor_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | - | ||
| 23 | -template<typename T, bool isReuseSource = false> | ||
| 24 | -__aicore__ inline void FloorImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 25 | - const uint32_t calCount) | ||
| 26 | -{ | ||
| 27 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 28 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 29 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Floor"); | ||
| 30 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Floor"); | ||
| 31 | - Truncate<T, RoundMode::CAST_FLOOR>(dstTensor, srcTensor, calCount); | ||
| 32 | -} | ||
| 33 | - | ||
| 34 | -template <typename T, bool isReuseSource = false> | ||
| 35 | -__aicore__ inline void FloorImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 36 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 37 | -{ | ||
| 38 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 39 | - FloorImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 40 | -} | ||
| 41 | - | ||
| 42 | -} // namespace AscendC | ||
| 43 | - | ||
Dimpl/adv_api/detail/math/log/log_l300_impl.h+0-82
| @@ -1,82 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file log_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -template <typename T> __simd_vf__ inline void LogImpl(__ubuf__ T *dst, __ubuf__ T *src, const uint32_t calCount) | ||
| 23 | -{ | ||
| 24 | - static_assert((std::is_same_v<T, half> || std::is_same_v<T, float>), | ||
| 25 | - "current data type is not supported on current device!"); | ||
| 26 | - constexpr uint32_t sregLower = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 27 | - uint16_t repeatTimes = CeilDivision(calCount, sregLower); | ||
| 28 | - MicroAPI::RegTensor<T> vreg0; | ||
| 29 | - MicroAPI::RegTensor<T> vreg1; | ||
| 30 | - uint32_t sreg = calCount; | ||
| 31 | - MicroAPI::MaskReg preg; | ||
| 32 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 33 | - preg = MicroAPI::UpdateMask<T>(sreg); | ||
| 34 | - MicroAPI::DataCopy(vreg0, src + i * sregLower); | ||
| 35 | - MicroAPI::Log(vreg1, vreg0, preg); | ||
| 36 | - MicroAPI::DataCopy(dst + i * sregLower, vreg1, preg); | ||
| 37 | - } | ||
| 38 | -} | ||
| 39 | - | ||
| 40 | -template <typename T> | ||
| 41 | -__simd_vf__ inline void LogXImpl(__ubuf__ T *dst, __ubuf__ T *src, const uint32_t calCount, const float LnXRec) | ||
| 42 | -{ | ||
| 43 | - static_assert((std::is_same_v<T, half> || std::is_same_v<T, float>), | ||
| 44 | - "current data type is not supported on current device!"); | ||
| 45 | - constexpr uint32_t sregLower = (uint32_t)(GetVecLen() / sizeof(float)); | ||
| 46 | - uint16_t repeatTimes = CeilDivision(calCount, sregLower); | ||
| 47 | - static constexpr MicroAPI::CastTrait castTraitB16ToB32 = { | ||
| 48 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 49 | - static constexpr MicroAPI::CastTrait castTraitB32ToB16 = { | ||
| 50 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 51 | - if constexpr (std::is_same_v<T, float>) { | ||
| 52 | - MicroAPI::RegTensor<float> vreg0; | ||
| 53 | - MicroAPI::RegTensor<float> vreg1; | ||
| 54 | - uint32_t sreg = calCount; | ||
| 55 | - MicroAPI::MaskReg mask; | ||
| 56 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 57 | - mask = MicroAPI::UpdateMask<T>(sreg); | ||
| 58 | - MicroAPI::DataCopy(vreg0, src + i * sregLower); | ||
| 59 | - MicroAPI::Log(vreg1, vreg0, mask); | ||
| 60 | - MicroAPI::Muls(vreg1, vreg1, LnXRec, mask); | ||
| 61 | - MicroAPI::DataCopy(dst + i * sregLower, vreg1, mask); | ||
| 62 | - } | ||
| 63 | - } else if constexpr (std::is_same_v<T, half>) { | ||
| 64 | - MicroAPI::RegTensor<T> vreg0; | ||
| 65 | - MicroAPI::RegTensor<T> dst0; | ||
| 66 | - MicroAPI::RegTensor<T> dst1; | ||
| 67 | - MicroAPI::RegTensor<float> vreg1; | ||
| 68 | - uint32_t sreg = calCount; | ||
| 69 | - MicroAPI::MaskReg mask; | ||
| 70 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 71 | - mask = MicroAPI::UpdateMask<float>(sreg); | ||
| 72 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(vreg0, src + i * sregLower); | ||
| 73 | - MicroAPI::Cast<float, half, castTraitB16ToB32>(vreg1, vreg0, mask); | ||
| 74 | - MicroAPI::Log(vreg1, vreg1, mask); | ||
| 75 | - MicroAPI::Muls(vreg1, vreg1, LnXRec, mask); | ||
| 76 | - MicroAPI::Cast<half, float, castTraitB32ToB16>(dst0, vreg1, mask); | ||
| 77 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * sregLower, dst0, mask); | ||
| 78 | - } | ||
| 79 | - } | ||
| 80 | -} | ||
| 81 | -} // namespace AscendC | ||
| 82 | - | ||
Dimpl/adv_api/detail/math/power/power_l300_impl.h+0-1484
| @@ -1,1484 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file power_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | -namespace AscendC { | ||
| 24 | -namespace PowerL300Impl { | ||
| 25 | - | ||
| 26 | -constexpr MicroAPI::CastTrait castTraitF16F32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 27 | - MicroAPI::MaskMergeMode::ZEROING }; | ||
| 28 | -constexpr MicroAPI::CastTrait castTraitF32F16 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 29 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT }; | ||
| 30 | -constexpr MicroAPI::CastTrait castTraitF32I32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 31 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 32 | -constexpr MicroAPI::CastTrait castTraitI32F32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 33 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_TRUNC }; | ||
| 34 | -constexpr MicroAPI::CastTrait castTraitI8I16 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, | ||
| 35 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 36 | -constexpr MicroAPI::CastTrait castTraitI16I8 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 37 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 38 | - | ||
| 39 | - | ||
| 40 | -namespace PowF { | ||
| 41 | -constexpr float LOG2_LOWEST_VALUE = 1.175494351e-38f; | ||
| 42 | -constexpr float LOG2_LOWEST_VALUE_MULS = 8388608.0f; | ||
| 43 | - | ||
| 44 | -constexpr float LOG2_REDUCE_COEFF1 = 0.70710678f; | ||
| 45 | -constexpr int32_t LOG2_REDUCE_COEFF2 = 0xff800000; | ||
| 46 | -constexpr float LOG2_REDUCE_FMAF_COEFF1 = 1.19209290e-7f; | ||
| 47 | - | ||
| 48 | -constexpr float LOG2_BEST_FMAF_COEFF1 = 0.37282535f; | ||
| 49 | -constexpr float LOG2_BEST_FMAF_COEFF2 = 0.4097556f; | ||
| 50 | -constexpr float LOG2_BEST_FMAF_COEFF3 = 0.57711965f; | ||
| 51 | -constexpr float LOG2_BEST_FMAF_COEFF4 = 0.96179646f; | ||
| 52 | -constexpr float LOG2_BEST_FMAF_COEFF5 = 2.88539f; | ||
| 53 | -constexpr float LOG2_BEST_FMAF_COEFF6 = 0.00000003851926f; | ||
| 54 | - | ||
| 55 | -constexpr float EXPF_BEST_FMAF_COEFF1 = 0.000152392517f; | ||
| 56 | -constexpr float EXPF_BEST_FMAF_COEFF2 = 0.00133913534f; | ||
| 57 | -constexpr float EXPF_BEST_FMAF_COEFF3 = 0.00961883925f; | ||
| 58 | -constexpr float EXPF_BEST_FMAF_COEFF4 = 0.0555035882f; | ||
| 59 | -constexpr float EXPF_BEST_FMAF_COEFF5 = 0.240226448f; | ||
| 60 | -constexpr float EXPF_BEST_FMAF_COEFF6 = 0.693147182f; | ||
| 61 | - | ||
| 62 | - | ||
| 63 | -constexpr int32_t EXPF_INTERVAL_CMP = -2097152000; | ||
| 64 | -constexpr int32_t EXPF_INTERVAL_CAST = 2130706432; | ||
| 65 | - | ||
| 66 | -constexpr float EXP_OVFL_UNFL_F = 152.0f; | ||
| 67 | -constexpr int32_t INF = 0x7f800000; | ||
| 68 | -constexpr int32_t NEG_INF = 0xff800000; | ||
| 69 | -constexpr int32_t I32_NAN = 0x7f7fffff; | ||
| 70 | -constexpr int32_t F32_NAN = 0x7fc00000; | ||
| 71 | - | ||
| 72 | -constexpr int32_t R10_COEFF = 0x7F800000; | ||
| 73 | -constexpr int32_t R12_COEFF = 0x7FFFFFFF; | ||
| 74 | - | ||
| 75 | - | ||
| 76 | -constexpr int16_t COMPARE_ZERO_OFFSET = 31; | ||
| 77 | -constexpr int16_t SHITF_OFFSET = 23; | ||
| 78 | -constexpr float F32_FRACTIONS = -23.0f; | ||
| 79 | - | ||
| 80 | -struct PowerLogParams { | ||
| 81 | - MicroAPI::RegTensor<float> zeroReg; | ||
| 82 | - MicroAPI::RegTensor<float> oneReg; | ||
| 83 | - MicroAPI::RegTensor<float> fractionReg; | ||
| 84 | - MicroAPI::RegTensor<float> subReg; | ||
| 85 | - MicroAPI::RegTensor<int32_t> intReg; | ||
| 86 | - MicroAPI::RegTensor<float> rReg; | ||
| 87 | - MicroAPI::RegTensor<float> addReg1; | ||
| 88 | - MicroAPI::RegTensor<float> addReg2; | ||
| 89 | -}; | ||
| 90 | - | ||
| 91 | -struct PowerExpParams { | ||
| 92 | - MicroAPI::RegTensor<float> zeroReg; | ||
| 93 | - MicroAPI::RegTensor<float> oneReg; | ||
| 94 | - MicroAPI::RegTensor<float> expReg2; | ||
| 95 | - MicroAPI::RegTensor<float> expReg3; | ||
| 96 | - MicroAPI::RegTensor<float> expReg4; | ||
| 97 | - MicroAPI::RegTensor<float> expReg5; | ||
| 98 | - MicroAPI::RegTensor<float> expReg6; | ||
| 99 | -}; | ||
| 100 | - | ||
| 101 | -__simd_callee__ inline void PowerLogParamsInit(PowerLogParams& params) { | ||
| 102 | - MicroAPI::Duplicate(params.zeroReg, 0.0f); | ||
| 103 | - MicroAPI::Duplicate(params.oneReg, 1.0f); | ||
| 104 | - MicroAPI::Duplicate(params.fractionReg, F32_FRACTIONS); | ||
| 105 | - MicroAPI::Duplicate(params.subReg, LOG2_REDUCE_COEFF1); | ||
| 106 | - MicroAPI::Duplicate(params.intReg, LOG2_REDUCE_COEFF2); | ||
| 107 | - MicroAPI::Duplicate(params.rReg, LOG2_BEST_FMAF_COEFF2); | ||
| 108 | - MicroAPI::Duplicate(params.addReg1, LOG2_BEST_FMAF_COEFF3); | ||
| 109 | - MicroAPI::Duplicate(params.addReg2, LOG2_BEST_FMAF_COEFF4); | ||
| 110 | -} | ||
| 111 | - | ||
| 112 | -__simd_callee__ inline void PowerExpParamsInit(PowerExpParams& params) { | ||
| 113 | - MicroAPI::Duplicate(params.zeroReg, 0.0f); | ||
| 114 | - MicroAPI::Duplicate(params.oneReg, 1.0f); | ||
| 115 | - MicroAPI::Duplicate(params.expReg2, EXPF_BEST_FMAF_COEFF2); | ||
| 116 | - MicroAPI::Duplicate(params.expReg3, EXPF_BEST_FMAF_COEFF3); | ||
| 117 | - MicroAPI::Duplicate(params.expReg4, EXPF_BEST_FMAF_COEFF4); | ||
| 118 | - MicroAPI::Duplicate(params.expReg5, EXPF_BEST_FMAF_COEFF5); | ||
| 119 | - MicroAPI::Duplicate(params.expReg6, EXPF_BEST_FMAF_COEFF6); | ||
| 120 | -} | ||
| 121 | - | ||
| 122 | -__simd_callee__ inline void IsInfNum(MicroAPI::MaskReg &infMask, MicroAPI::RegTensor<float> &srcReg, | ||
| 123 | - MicroAPI::RegTensor<int32_t>& tmpR12Reg, MicroAPI::MaskReg& mask) | ||
| 124 | -{ | ||
| 125 | - MicroAPI::RegTensor<float> tmpFloatReg; | ||
| 126 | - MicroAPI::And((MicroAPI::RegTensor<int32_t>&)tmpFloatReg, (MicroAPI::RegTensor<int32_t>&)srcReg, tmpR12Reg, mask); | ||
| 127 | - MicroAPI::CompareScalar<int32_t, CMPMODE::EQ>(infMask, (MicroAPI::RegTensor<int32_t>&)tmpFloatReg, INF, mask); | ||
| 128 | -} | ||
| 129 | - | ||
| 130 | -__simd_callee__ inline void IsNanNum(MicroAPI::MaskReg &nanMask, MicroAPI::RegTensor<float> &srcReg, MicroAPI::MaskReg& mask) | ||
| 131 | -{ | ||
| 132 | - MicroAPI::Compare<float, CMPMODE::NE>(nanMask, srcReg, srcReg, mask); | ||
| 133 | -} | ||
| 134 | - | ||
| 135 | -__simd_callee__ inline void RFloor(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg& mask) | ||
| 136 | -{ | ||
| 137 | - MicroAPI::Truncate<float, RoundMode::CAST_FLOOR, MicroAPI::MaskMergeMode::ZEROING>(dstReg, srcReg, mask); | ||
| 138 | -} | ||
| 139 | - | ||
| 140 | -__aicore__ inline void CompareNegZero(MicroAPI::MaskReg &filterMask, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg& mask) | ||
| 141 | -{ | ||
| 142 | - MicroAPI::RegTensor<uint32_t> tmpReg; | ||
| 143 | - MicroAPI::ShiftRights(tmpReg, (MicroAPI::RegTensor<uint32_t>&)srcReg, COMPARE_ZERO_OFFSET, mask); | ||
| 144 | - | ||
| 145 | - MicroAPI::CompareScalar<uint32_t, CMPMODE::EQ>(filterMask, tmpReg, 0, mask); | ||
| 146 | - | ||
| 147 | - MicroAPI::CompareScalar<uint32_t, CMPMODE::EQ>(filterMask, tmpReg, 0.0f, mask); | ||
| 148 | - | ||
| 149 | -} | ||
| 150 | - | ||
| 151 | -__aicore__ inline void CopySignF(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 152 | - MicroAPI::RegTensor<float>& srcReg2, MicroAPI::MaskReg& mask, MicroAPI::MaskReg& cmpMask1, MicroAPI::MaskReg &cmpMask2) | ||
| 153 | -{ | ||
| 154 | - MicroAPI::RegTensor<float> tmpFloatReg, tmpFloatReg2; | ||
| 155 | - MicroAPI::CompareScalar<float, CMPMODE::GE>(cmpMask1, srcReg2, 0.0f, mask); | ||
| 156 | - CompareNegZero(cmpMask2, srcReg2, mask); | ||
| 157 | - MicroAPI::MaskAnd(cmpMask1, cmpMask1, cmpMask2, mask); | ||
| 158 | - MicroAPI::Abs(tmpFloatReg, srcReg1, mask); | ||
| 159 | - MicroAPI::Neg(tmpFloatReg2, tmpFloatReg, mask); | ||
| 160 | - MicroAPI::Select(dstReg, tmpFloatReg, tmpFloatReg2, cmpMask1); | ||
| 161 | -} | ||
| 162 | - | ||
| 163 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 164 | - MicroAPI::RegTensor<float>& srcReg2, MicroAPI::RegTensor<float>& srcReg3, MicroAPI::MaskReg& mask) | ||
| 165 | -{ | ||
| 166 | - MicroAPI::RegTensor<float> tmpReg = srcReg1; | ||
| 167 | - MicroAPI::FusedMulDstAdd(tmpReg, srcReg2, srcReg3, mask); | ||
| 168 | - dstReg = tmpReg; | ||
| 169 | -} | ||
| 170 | - | ||
| 171 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 172 | - float scalarValue, MicroAPI::RegTensor<float>& srcReg2, MicroAPI::MaskReg& mask) | ||
| 173 | -{ | ||
| 174 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 175 | - MicroAPI::Duplicate(tmpReg, scalarValue, mask); | ||
| 176 | - FMaf(dstReg, srcReg1, tmpReg, srcReg2, mask); | ||
| 177 | -} | ||
| 178 | - | ||
| 179 | -__simd_callee__ inline void GetLogFExt1(MicroAPI::RegTensor<float>& tmpIReg, MicroAPI::RegTensor<float>& tmpMReg, | ||
| 180 | - MicroAPI::RegTensor<float>& srcReg, PowerLogParams& params, MicroAPI::MaskReg& mask) | ||
| 181 | -{ | ||
| 182 | - MicroAPI::RegTensor<float> tmpAReg, tmpFloatReg; | ||
| 183 | - MicroAPI::RegTensor<int32_t> tmpEReg; | ||
| 184 | - /* init varaiable a and i: | ||
| 185 | - * if (a < 1.175494351e-38f){ // 0x1.0p-126 | ||
| 186 | - * a = a * 8388608.0f; // 0x1.0p+23 | ||
| 187 | - * i = -23.0f; | ||
| 188 | - * } | ||
| 189 | - */ | ||
| 190 | - MicroAPI::MaskReg cmpMask; | ||
| 191 | - MicroAPI::CompareScalar<float, CMPMODE::LT>(cmpMask, srcReg, LOG2_LOWEST_VALUE, mask); | ||
| 192 | - MicroAPI::Muls(tmpAReg, srcReg, LOG2_LOWEST_VALUE_MULS, mask); | ||
| 193 | - MicroAPI::Select(tmpIReg, params.fractionReg, params.zeroReg, cmpMask); | ||
| 194 | - // step 1: e = (__float_as_int (a) - __float_as_int (0.70710678f)) & 0xff800000; | ||
| 195 | - tmpFloatReg = params.subReg; | ||
| 196 | - MicroAPI::Sub(tmpEReg, (MicroAPI::RegTensor<int32_t> &)srcReg, (MicroAPI::RegTensor<int32_t> &)tmpFloatReg, mask); | ||
| 197 | - MicroAPI::And(tmpEReg, tmpEReg, params.intReg, mask); | ||
| 198 | - // step 2: m = __int_as_float (__float_as_int (a) - e); | ||
| 199 | - MicroAPI::Sub((MicroAPI::RegTensor<int32_t> &)tmpMReg, (MicroAPI::RegTensor<int32_t> &)srcReg, tmpEReg, mask); | ||
| 200 | - // step 3: i = fmaf ((float)e, 1.19209290e-7f, i); | ||
| 201 | - MicroAPI::Cast<float, int32_t, castTraitF32I32>(tmpFloatReg, tmpEReg, mask); | ||
| 202 | - MicroAPI::Axpy(tmpIReg, tmpFloatReg, LOG2_REDUCE_FMAF_COEFF1, mask); | ||
| 203 | -} | ||
| 204 | - | ||
| 205 | -__simd_callee__ inline void GetLogFExt2(MicroAPI::RegTensor<float>& logHigh, MicroAPI::RegTensor<float>& logLow, | ||
| 206 | - MicroAPI::RegTensor<float>& tmpIReg, MicroAPI::RegTensor<float>& tmpMReg, PowerLogParams& params, MicroAPI::MaskReg& mask) | ||
| 207 | -{ | ||
| 208 | - // step 4:p = m + 1.0f; m = m - 1.0f; | ||
| 209 | - MicroAPI::RegTensor<float> tmpPReg, tmpFloatReg, tmpFloatReg2; | ||
| 210 | - MicroAPI::Adds(tmpPReg, tmpMReg, 1.0f, mask); | ||
| 211 | - MicroAPI::Adds(tmpMReg, tmpMReg, -1.0f, mask); | ||
| 212 | - // step 5:r = 1.0f / p | ||
| 213 | - MicroAPI::RegTensor<float> tmpRReg; | ||
| 214 | - MicroAPI::Div(tmpRReg, params.oneReg, tmpPReg, mask); | ||
| 215 | - // step 6:qhi = m * r; | ||
| 216 | - MicroAPI::RegTensor<float> tmpQHIReg, tmpQLOReg; | ||
| 217 | - MicroAPI::Mul(tmpQHIReg, tmpMReg, tmpRReg, mask); | ||
| 218 | - // step 7:qhi1 = fmaf (qhi, -m, fmaf (qhi, -2.0f, m)) | ||
| 219 | - MicroAPI::Muls(tmpFloatReg, tmpQHIReg, -2.0f, mask); | ||
| 220 | - MicroAPI::Add(tmpFloatReg, tmpFloatReg, tmpMReg, mask); | ||
| 221 | - MicroAPI::Neg(tmpFloatReg2, tmpMReg, mask); | ||
| 222 | - MicroAPI::Mul(tmpFloatReg2, tmpQHIReg, tmpFloatReg2, mask); | ||
| 223 | - MicroAPI::Add(tmpFloatReg, tmpFloatReg2, tmpFloatReg, mask); | ||
| 224 | - // step 8:qlo = r * qhi1 | ||
| 225 | - MicroAPI::Mul(tmpQLOReg, tmpRReg, tmpFloatReg, mask); | ||
| 226 | - // step 9:s = qhi * qhi; | ||
| 227 | - MicroAPI::RegTensor<float> tmpSReg; | ||
| 228 | - MicroAPI::Mul(tmpSReg, tmpQHIReg, tmpQHIReg, mask); | ||
| 229 | - /* | ||
| 230 | - * step 10: | ||
| 231 | - * r = 0.37282535f; | ||
| 232 | - * r = fmaf (r, s, 0.4097556f) | ||
| 233 | - * r = fmaf (r, s, 0.57711965f) | ||
| 234 | - * r = fmaf (r, s, 0.96179646f) | ||
| 235 | - */ | ||
| 236 | - tmpRReg = params.rReg; | ||
| 237 | - MicroAPI::Axpy<float>(tmpRReg, tmpSReg, LOG2_BEST_FMAF_COEFF1, mask); | ||
| 238 | - MicroAPI::FusedMulDstAdd<float>(tmpRReg, tmpSReg, params.addReg1, mask); | ||
| 239 | - MicroAPI::FusedMulDstAdd<float>(tmpRReg, tmpSReg, params.addReg2, mask); | ||
| 240 | - // step 11:r = r * s | ||
| 241 | - MicroAPI::Mul(tmpRReg, tmpRReg, tmpSReg, mask); | ||
| 242 | - /* | ||
| 243 | - * step 12: | ||
| 244 | - * first_hi = fmaf(2.88539f, qhi, i) | ||
| 245 | - * first_lo = fmaf(2.88539f, qhi, i-first_hi) | ||
| 246 | - */ | ||
| 247 | - MicroAPI::RegTensor<float> tmpFHIReg, tmpFLOReg; | ||
| 248 | - MicroAPI::Muls(tmpFHIReg, tmpQHIReg, LOG2_BEST_FMAF_COEFF5, mask); | ||
| 249 | - MicroAPI::Add(tmpFHIReg, tmpFHIReg, tmpIReg, mask); | ||
| 250 | - MicroAPI::Sub(tmpFLOReg, tmpIReg, tmpFHIReg, mask); | ||
| 251 | - MicroAPI::Axpy(tmpFLOReg, tmpQHIReg, LOG2_BEST_FMAF_COEFF5, mask); | ||
| 252 | - /* | ||
| 253 | - * step 13: | ||
| 254 | - * GOOD: | ||
| 255 | - * last_lo= fmaf(r,qhi,fmaf(2.88539f,qlo,first_lo)); | ||
| 256 | - * sum_lo=fmaf(0.00000003851926f,qhi,last_lo); | ||
| 257 | - * BETTER: | ||
| 258 | - * last_lo= fmaf(r,qhi,fmaf(2.88539f,qlo,r*qlo)); | ||
| 259 | - * sum_lo=fmaf(0.00000003851926f,qhi,last_lo)+first_lo; | ||
| 260 | - * BEST: | ||
| 261 | - * last_lo= fmaf(r,qhi,fmaf(2.88539f,qlo,3.0f*r*qlo)); | ||
| 262 | - * sum_lo=fmaf(0.00000003851926f,qhi,last_lo)+first_lo; | ||
| 263 | - */ | ||
| 264 | - MicroAPI::RegTensor<float> tmpLLOReg, tmpSLOReg; | ||
| 265 | - MicroAPI::Mul(tmpLLOReg, tmpRReg, tmpQLOReg, mask); | ||
| 266 | - MicroAPI::Axpy(tmpLLOReg, tmpQLOReg, LOG2_BEST_FMAF_COEFF5, mask); | ||
| 267 | - MicroAPI::MulAddDst(tmpLLOReg, tmpRReg, tmpQHIReg, mask); | ||
| 268 | - MicroAPI::Axpy(tmpLLOReg, tmpQHIReg, LOG2_BEST_FMAF_COEFF6, mask); | ||
| 269 | - MicroAPI::Add(tmpSLOReg, tmpLLOReg, tmpFLOReg, mask); | ||
| 270 | - /* | ||
| 271 | - * step 14: | ||
| 272 | - * loghi = first_hi+sum_lo; | ||
| 273 | - * loglo = (first_hi - *loghi) + sum_lo; | ||
| 274 | - */ | ||
| 275 | - MicroAPI::Add(logHigh, tmpFHIReg, tmpSLOReg, mask); | ||
| 276 | - MicroAPI::Sub(tmpFloatReg, tmpFHIReg, logHigh, mask); | ||
| 277 | - MicroAPI::Add(logLow, tmpFloatReg, tmpSLOReg, mask); | ||
| 278 | -} | ||
| 279 | - | ||
| 280 | -__simd_callee__ inline void GetExpfUnchecked(MicroAPI::RegTensor<float>& dstReg,MicroAPI::RegTensor<float>& tmPHIReg, | ||
| 281 | - MicroAPI::RegTensor<float>& tmPLOReg, PowerExpParams& params, MicroAPI::MaskReg& mask) | ||
| 282 | -{ | ||
| 283 | - /* | ||
| 284 | - * step 1: | ||
| 285 | - * r = fmaf (0.000152392517f, plo, 0.00133913534f); | ||
| 286 | - * r = fmaf (r, plo, 0.00961883925f); | ||
| 287 | - * r = fmaf (r, plo, 0.0555035882f); | ||
| 288 | - * r = fmaf (r, plo, 0.240226448f); | ||
| 289 | - * r = fmaf (r, plo, 0.693147182f); | ||
| 290 | - * r = fmaf (r, plo, 1.0f); | ||
| 291 | - */ | ||
| 292 | - MicroAPI::RegTensor<float> tmpFloatReg; | ||
| 293 | - MicroAPI::RegTensor<float> tmpRReg = params.expReg2; | ||
| 294 | - MicroAPI::Axpy(tmpRReg, tmPLOReg, EXPF_BEST_FMAF_COEFF1, mask); | ||
| 295 | - MicroAPI::FusedMulDstAdd(tmpRReg, tmPLOReg, params.expReg3, mask); | ||
| 296 | - MicroAPI::FusedMulDstAdd(tmpRReg, tmPLOReg, params.expReg4, mask); | ||
| 297 | - MicroAPI::FusedMulDstAdd(tmpRReg, tmPLOReg, params.expReg5, mask); | ||
| 298 | - MicroAPI::FusedMulDstAdd(tmpRReg, tmPLOReg, params.expReg6, mask); | ||
| 299 | - MicroAPI::FusedMulDstAdd(tmpRReg, tmPLOReg, params.oneReg, mask); | ||
| 300 | - | ||
| 301 | - // step2: r1 = (phi>0.0f) ? 0 : -2097152000; | ||
| 302 | - MicroAPI::RegTensor<float> tmpF1Reg, tmpF2Reg; | ||
| 303 | - MicroAPI::RegTensor<int32_t> tmpR1Reg, tmpR2Reg; | ||
| 304 | - MicroAPI::MaskReg cmpMask; | ||
| 305 | - MicroAPI::CompareScalar<float,CMPMODE::LE>(cmpMask,tmPHIReg, 0, mask); | ||
| 306 | - MicroAPI::Duplicate(tmpR1Reg, EXPF_INTERVAL_CMP, cmpMask); | ||
| 307 | - // step3: r2 = r1 + 2130706432; | ||
| 308 | - MicroAPI::Adds(tmpR2Reg, tmpR1Reg, EXPF_INTERVAL_CAST, mask); | ||
| 309 | - // step4: f1 = r * s32_to_f32(r2); | ||
| 310 | - MicroAPI::Mul(tmpF1Reg, tmpRReg, (MicroAPI::RegTensor<float>&)tmpR2Reg, mask); | ||
| 311 | - /* | ||
| 312 | - * step5: int32_t r5 = cvt_rzi(phi); | ||
| 313 | - * if (phi < 0.0f) return (int32_t)ceilf(phi); | ||
| 314 | - * else return (int32_t)floorf(phi); | ||
| 315 | - */ | ||
| 316 | - MicroAPI::RegTensor<int32_t> tmpR5Reg; | ||
| 317 | - MicroAPI::MaskReg condMask; | ||
| 318 | - MicroAPI::Cast<int32_t, float, castTraitI32F32>(tmpR5Reg, tmPHIReg, mask); | ||
| 319 | - // step6: f2 = s32_to_f32((r5 << 23) - r1); | ||
| 320 | - MicroAPI::RegTensor<int32_t> tmpTReg; | ||
| 321 | - MicroAPI::ShiftLefts(tmpR5Reg, tmpR5Reg, SHITF_OFFSET, mask); | ||
| 322 | - MicroAPI::Sub(tmpTReg, tmpR5Reg, tmpR1Reg, mask); | ||
| 323 | - tmpF2Reg = (MicroAPI::RegTensor<float>&)tmpTReg; | ||
| 324 | - // step7: f1 * f2 | ||
| 325 | - MicroAPI::Mul(dstReg, tmpF1Reg, tmpF2Reg, mask); | ||
| 326 | -} | ||
| 327 | - | ||
| 328 | -__simd_callee__ inline void ComputeExpoOddInt(MicroAPI::MaskReg& oddMask, MicroAPI::RegTensor<float>& expReg, MicroAPI::MaskReg& mask) | ||
| 329 | -{ | ||
| 330 | - // calculate exp is odd or not: expo_odd_int = fmaf (-2.0f, floorf (0.5f * b), b) == 1.0f; | ||
| 331 | - MicroAPI::RegTensor<float> tmpFloatReg; | ||
| 332 | - MicroAPI::Muls(tmpFloatReg, expReg, 0.5f, mask); | ||
| 333 | - RFloor(tmpFloatReg, tmpFloatReg, mask); | ||
| 334 | - FMaf(tmpFloatReg, tmpFloatReg, -2.0f, expReg, mask); | ||
| 335 | - MicroAPI::CompareScalar<float, CMPMODE::EQ>(oddMask, tmpFloatReg, 1.0f, mask); | ||
| 336 | -} | ||
| 337 | - | ||
| 338 | - | ||
| 339 | -__simd_callee__ inline void ProcessSpecialCaseForPowF(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& baseReg, | ||
| 340 | - MicroAPI::RegTensor<float>& expReg, MicroAPI::RegTensor<int32_t>& tmpR10Reg, MicroAPI::RegTensor<int32_t>& tmpR12Reg, MicroAPI::MaskReg& mask) | ||
| 341 | -{ | ||
| 342 | - MicroAPI::RegTensor<float> tmpFloatReg, tmpFloatReg2; | ||
| 343 | - MicroAPI::MaskReg cmpMask1, cmpMask2, curMask; | ||
| 344 | - /* | ||
| 345 | - * bool p3_b_eq_0 = (b==0.0f); | ||
| 346 | - * bool p4_a_eq_1 = (a==1.0f); | ||
| 347 | - * if (p3_b_eq_0 || p4_a_eq_1) | ||
| 348 | - * return 1.0f; | ||
| 349 | - * if (isnan(a) || isnan(b)) | ||
| 350 | - * return NAN; | ||
| 351 | - */ | ||
| 352 | - MicroAPI::CompareScalar<float, CMPMODE::EQ>(cmpMask1, expReg, 0.0f, mask); | ||
| 353 | - MicroAPI::CompareScalar<float, CMPMODE::EQ>(cmpMask2, baseReg, 1.0f, mask); | ||
| 354 | - MicroAPI::MaskOr(cmpMask2, cmpMask1, cmpMask2, mask); | ||
| 355 | - MicroAPI::Duplicate<float, MicroAPI::MaskMergeMode::MERGING>(dstReg, 1.0f, cmpMask2); | ||
| 356 | - MicroAPI::MaskNot(curMask, cmpMask2, mask); | ||
| 357 | - IsNanNum(cmpMask1, baseReg, mask); | ||
| 358 | - IsNanNum(cmpMask2, expReg, mask); | ||
| 359 | - MicroAPI::MaskOr(cmpMask2, cmpMask1, cmpMask2, curMask); | ||
| 360 | - MicroAPI::Duplicate<int32_t, MicroAPI::MaskMergeMode::MERGING>((MicroAPI::RegTensor<int32_t>&)dstReg, F32_NAN, cmpMask2); | ||
| 361 | - MicroAPI::MaskXor(curMask, cmpMask2, curMask, mask); | ||
| 362 | - /* | ||
| 363 | - * if (isinf(a) || (a==0.0f)) | ||
| 364 | - * int32_t r10=f32_to_s32(a); | ||
| 365 | - * int32_t r11=r10^0x7F800000; | ||
| 366 | - * bool p8_a_lower_0 = (b < 0.0f); | ||
| 367 | - * int32_t r12 = (p8_a_lower_0 ? r11 : r10); | ||
| 368 | - * int32_t r13= r12 & 0x7FFFFFFF; | ||
| 369 | - * return s32_to_f32(p1_expo_odd_int?r12:r13); | ||
| 370 | - * | ||
| 371 | - */ | ||
| 372 | - IsInfNum(cmpMask1, baseReg, tmpR12Reg, curMask); | ||
| 373 | - MicroAPI::CompareScalar<float, CMPMODE::EQ>(cmpMask2, baseReg, 0.0f, curMask); | ||
| 374 | - MicroAPI::MaskOr(cmpMask1, cmpMask1, cmpMask2, mask); | ||
| 375 | - MicroAPI::CompareScalar<float, CMPMODE::LT>(cmpMask2, expReg, 0.0f, cmpMask1); | ||
| 376 | - MicroAPI::Xor((MicroAPI::RegTensor<int32_t>&)tmpFloatReg, (MicroAPI::RegTensor<int32_t>&)baseReg, tmpR10Reg, curMask); | ||
| 377 | - MicroAPI::Select(tmpFloatReg, tmpFloatReg, baseReg, cmpMask2); | ||
| 378 | - MicroAPI::And((MicroAPI::RegTensor<int32_t>&)tmpFloatReg2, (MicroAPI::RegTensor<int32_t>&)tmpFloatReg, tmpR12Reg, curMask); | ||
| 379 | - ComputeExpoOddInt(cmpMask2, expReg, mask); | ||
| 380 | - MicroAPI::Select(tmpFloatReg, tmpFloatReg, tmpFloatReg2, cmpMask2); | ||
| 381 | - MicroAPI::Select(dstReg, tmpFloatReg, dstReg, cmpMask1); | ||
| 382 | - MicroAPI::MaskXor(curMask, cmpMask1, curMask, mask); | ||
| 383 | - /* | ||
| 384 | - * if (a < 0.0f) | ||
| 385 | - * float tmp_r=p1_expo_odd_int?(-r):r; | ||
| 386 | - * r = (b != floorf(b)) ? NAN : tmp_r; | ||
| 387 | - * | ||
| 388 | - */ | ||
| 389 | - MicroAPI::Neg(tmpFloatReg, dstReg, curMask); | ||
| 390 | - MicroAPI::Select(tmpFloatReg, tmpFloatReg, dstReg, cmpMask2); | ||
| 391 | - RFloor(tmpFloatReg2, expReg, curMask); | ||
| 392 | - MicroAPI::Compare<float, CMPMODE::NE>(cmpMask1, expReg, tmpFloatReg2, curMask); | ||
| 393 | - MicroAPI::Duplicate<int32_t, MicroAPI::MaskMergeMode::MERGING>( | ||
| 394 | - (MicroAPI::RegTensor<int32_t>&)tmpFloatReg,F32_NAN, cmpMask1); | ||
| 395 | - MicroAPI::CompareScalar<float, CMPMODE::LT>(cmpMask2, baseReg, 0.0f, curMask); | ||
| 396 | - MicroAPI::Select(dstReg, tmpFloatReg, dstReg, cmpMask2); | ||
| 397 | - /* | ||
| 398 | - * if ((a == -1.0f) && isinf(b)) | ||
| 399 | - * r = 1.0f; | ||
| 400 | - * | ||
| 401 | - */ | ||
| 402 | - MicroAPI::CompareScalar<int32_t, CMPMODE::EQ>(cmpMask1, (MicroAPI::RegTensor<int32_t>&)expReg, INF, curMask); | ||
| 403 | - MicroAPI::CompareScalar<int32_t, CMPMODE::EQ>(cmpMask2, (MicroAPI::RegTensor<int32_t>&)expReg, NEG_INF, curMask); | ||
| 404 | - MicroAPI::MaskOr(cmpMask1, cmpMask1, cmpMask2, mask); | ||
| 405 | - MicroAPI::CompareScalar<float, CMPMODE::EQ>(cmpMask2, baseReg, -1.0f, cmpMask1); | ||
| 406 | - MicroAPI::Duplicate<float, MicroAPI::MaskMergeMode::MERGING>(dstReg, 1.0f, cmpMask2); | ||
| 407 | -} | ||
| 408 | - | ||
| 409 | -__simd_callee__ inline void GetExpCore(MicroAPI::RegTensor<float>& dstReg, | ||
| 410 | - MicroAPI::RegTensor<float>& tmpLHIReg, MicroAPI::RegTensor<float>& tmpLLOReg, | ||
| 411 | - MicroAPI::RegTensor<float>& expReg, PowerExpParams& params, MicroAPI::MaskReg& mask) | ||
| 412 | -{ | ||
| 413 | - MicroAPI::RegTensor<float> tmpTHIReg, tmPHIReg, tmPLOReg, tmpRReg; | ||
| 414 | - // step 1: thi = lhi * b; | ||
| 415 | - MicroAPI::Mul(tmpTHIReg, tmpLHIReg, expReg, mask); | ||
| 416 | - // step 2: phi = roundf(thi); | ||
| 417 | - MicroAPI::Truncate<float, RoundMode::CAST_ROUND>(tmPHIReg, tmpTHIReg, mask); | ||
| 418 | - // step 3: plo = fmaf(lhi, b, -phi)+llo*b; | ||
| 419 | - MicroAPI::RegTensor<float> tmpFloatReg, tmpFloatReg2; | ||
| 420 | - MicroAPI::Neg(tmPLOReg, tmPHIReg, mask); | ||
| 421 | - MicroAPI::MulAddDst(tmPLOReg, tmpLHIReg, expReg, mask); | ||
| 422 | - MicroAPI::MulAddDst(tmPLOReg, tmpLLOReg, expReg, mask); | ||
| 423 | - // step 4: my_expf__improved(phi, plo, &r); | ||
| 424 | - GetExpfUnchecked(tmpRReg, tmPHIReg, tmPLOReg, params, mask); | ||
| 425 | - /* | ||
| 426 | - * step 5: | ||
| 427 | - * tmp_r =(thi < 0.0f) ?0.0f : MY_INF_F; | ||
| 428 | - * r = (fabsf(thi) > EXP_OVFL_UNFL_F) ? tmp_r : r; | ||
| 429 | - */ | ||
| 430 | - MicroAPI::MaskReg cmpMask1, cmpMask2; | ||
| 431 | - MicroAPI::CompareScalar<float, CMPMODE::GE>(cmpMask1, tmpTHIReg, 0.0f, mask); | ||
| 432 | - // mode zeroing dup inf/zero reg. | ||
| 433 | - MicroAPI::Duplicate((MicroAPI::RegTensor<int32_t>&)tmpFloatReg, INF, cmpMask1); | ||
| 434 | - MicroAPI::Abs(tmpFloatReg2, tmpTHIReg, mask); | ||
| 435 | - MicroAPI::CompareScalar<float, CMPMODE::GT>(cmpMask2, tmpFloatReg2, EXP_OVFL_UNFL_F, mask); | ||
| 436 | - MicroAPI::Select(dstReg, tmpFloatReg, tmpRReg, cmpMask2); | ||
| 437 | -} | ||
| 438 | - | ||
| 439 | -template<typename T> | ||
| 440 | -__simd_callee__ inline void LoadSrcData(MicroAPI::RegTensor<float>& srcReg, __ubuf__ T* src0, uint16_t index, MicroAPI::MaskReg& mask) | ||
| 441 | -{ | ||
| 442 | - MicroAPI::RegTensor<T> srcTmpReg; | ||
| 443 | - if constexpr (std::is_same<T, half>::value || std::is_same<T, bfloat16_t>::value) { | ||
| 444 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcTmpReg, src0 + index * B32_DATA_NUM_PER_REPEAT); | ||
| 445 | - MicroAPI::Cast<float, T, castTraitF16F32>(srcReg, srcTmpReg, mask); | ||
| 446 | - } else { | ||
| 447 | - MicroAPI::DataCopy(srcReg, src0 + index * B32_DATA_NUM_PER_REPEAT); | ||
| 448 | - } | ||
| 449 | -} | ||
| 450 | - | ||
| 451 | -template<typename T> | ||
| 452 | -__simd_callee__ inline void LoadSrcScalarData(MicroAPI::RegTensor<float>& srcReg, const T scalarValue) | ||
| 453 | -{ | ||
| 454 | - MicroAPI::RegTensor<T> srcTmpReg; | ||
| 455 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T>(); | ||
| 456 | - MicroAPI::Duplicate(srcTmpReg, scalarValue, fullMask); | ||
| 457 | - if constexpr (std::is_same<T, half>::value || std::is_same<T, bfloat16_t>::value) { | ||
| 458 | - MicroAPI::Cast<float, T, castTraitF16F32>(srcReg, srcTmpReg, fullMask); | ||
| 459 | - } else { | ||
| 460 | - srcReg = srcTmpReg; | ||
| 461 | - } | ||
| 462 | -} | ||
| 463 | - | ||
| 464 | -template<typename T> | ||
| 465 | -__simd_callee__ inline void StoreDstData(__ubuf__ T* dst, MicroAPI::RegTensor<float>& dstReg, uint16_t index, MicroAPI::MaskReg& mask) | ||
| 466 | -{ | ||
| 467 | - MicroAPI::RegTensor<T> dstTmpReg; | ||
| 468 | - if constexpr (std::is_same<T, half>::value || std::is_same<T, bfloat16_t>::value) { | ||
| 469 | - MicroAPI::Cast<T, float, castTraitF32F16>(dstTmpReg, dstReg, mask); | ||
| 470 | - MicroAPI::Pack<uint16_t, uint32_t, MicroAPI::HighLowPart::LOWEST>( | ||
| 471 | - (MicroAPI::RegTensor<uint16_t>&)dstTmpReg, (MicroAPI::RegTensor<uint32_t>&)dstTmpReg); | ||
| 472 | - MicroAPI::MaskPack(mask, mask); | ||
| 473 | - MicroAPI::DataCopy(dst + index * B32_DATA_NUM_PER_REPEAT, dstTmpReg, mask); | ||
| 474 | - } else { | ||
| 475 | - MicroAPI::DataCopy(dst + index * B32_DATA_NUM_PER_REPEAT, dstReg, mask); | ||
| 476 | - } | ||
| 477 | -} | ||
| 478 | - | ||
| 479 | -template<typename T> | ||
| 480 | -__simd_vf__ inline void ComputePowFBaseLog1Impl(__ubuf__ float* tmpLHIBuffer, __ubuf__ float* tmpLLOBuffer, | ||
| 481 | - __ubuf__ T* src0, uint32_t calCount, uint16_t repeatTime) | ||
| 482 | -{ | ||
| 483 | - MicroAPI::MaskReg mask; | ||
| 484 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpDstReg; | ||
| 485 | - MicroAPI::RegTensor<float> tmpLHIReg, tmpLLOReg; | ||
| 486 | - | ||
| 487 | - PowerLogParams params; | ||
| 488 | - PowerLogParamsInit(params); | ||
| 489 | - | ||
| 490 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 491 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 492 | - LoadSrcData(tmpBaseReg, src0, i, mask); | ||
| 493 | - | ||
| 494 | - MicroAPI::Abs(tmpDstReg, tmpBaseReg, mask); | ||
| 495 | - GetLogFExt1(tmpLHIReg, tmpLLOReg, tmpDstReg, params, mask); | ||
| 496 | - | ||
| 497 | - MicroAPI::DataCopy(tmpLHIBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLHIReg, mask); | ||
| 498 | - MicroAPI::DataCopy(tmpLLOBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLLOReg, mask); | ||
| 499 | - } | ||
| 500 | -} | ||
| 501 | - | ||
| 502 | -template<typename T> | ||
| 503 | -__simd_vf__ inline void ComputePowFBaseLog1Impl(__ubuf__ float* tmpLHIBuffer, __ubuf__ float* tmpLLOBuffer, | ||
| 504 | - const T scalarValue, uint32_t calCount, uint16_t repeatTime) | ||
| 505 | -{ | ||
| 506 | - MicroAPI::MaskReg mask; | ||
| 507 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpDstReg; | ||
| 508 | - MicroAPI::RegTensor<float> tmpLHIReg, tmpLLOReg; | ||
| 509 | - LoadSrcScalarData(tmpBaseReg, scalarValue); | ||
| 510 | - | ||
| 511 | - PowerLogParams params; | ||
| 512 | - PowerLogParamsInit(params); | ||
| 513 | - | ||
| 514 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 515 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 516 | - MicroAPI::Abs(tmpDstReg, tmpBaseReg, mask); | ||
| 517 | - GetLogFExt1(tmpLHIReg, tmpLLOReg, tmpDstReg, params, mask); | ||
| 518 | - MicroAPI::DataCopy(tmpLHIBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLHIReg, mask); | ||
| 519 | - MicroAPI::DataCopy(tmpLLOBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLLOReg, mask); | ||
| 520 | - } | ||
| 521 | -} | ||
| 522 | - | ||
| 523 | -template<typename T> | ||
| 524 | -__simd_vf__ inline void ComputePowFBaseLog2Impl(__ubuf__ float* tmpLHIBuffer, __ubuf__ float* tmpLLOBuffer, | ||
| 525 | - uint32_t calCount, uint16_t repeatTime) | ||
| 526 | -{ | ||
| 527 | - MicroAPI::MaskReg mask; | ||
| 528 | - MicroAPI::RegTensor<float> tmpLHIReg, tmpLLOReg; | ||
| 529 | - MicroAPI::RegTensor<float> tmpIReg, tmpMReg; | ||
| 530 | - | ||
| 531 | - PowerLogParams params; | ||
| 532 | - PowerLogParamsInit(params); | ||
| 533 | - | ||
| 534 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 535 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 536 | - LoadSrcData(tmpIReg, tmpLHIBuffer, i, mask); | ||
| 537 | - LoadSrcData(tmpMReg, tmpLLOBuffer, i, mask); | ||
| 538 | - | ||
| 539 | - GetLogFExt2(tmpLHIReg, tmpLLOReg, tmpIReg, tmpMReg, params, mask); | ||
| 540 | - | ||
| 541 | - MicroAPI::DataCopy(tmpLHIBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLHIReg, mask); | ||
| 542 | - MicroAPI::DataCopy(tmpLLOBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpLLOReg, mask); | ||
| 543 | - } | ||
| 544 | -} | ||
| 545 | - | ||
| 546 | -template<typename T> | ||
| 547 | -__simd_vf__ inline void ComputePowFExpImpl(__ubuf__ float* tmpExpBuffer, __ubuf__ float* tmpLogHighBuffer, | ||
| 548 | - __ubuf__ float* tmpLogLowBuffer, __ubuf__ T* src1, uint32_t calCount, uint16_t repeatTime) | ||
| 549 | -{ | ||
| 550 | - MicroAPI::MaskReg mask; | ||
| 551 | - MicroAPI::RegTensor<float> tmpLHIReg, tmpLLOReg, tmpExpReg, tmpDstReg; | ||
| 552 | - | ||
| 553 | - PowerExpParams params; | ||
| 554 | - PowerExpParamsInit(params); | ||
| 555 | - | ||
| 556 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 557 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 558 | - LoadSrcData(tmpLHIReg, tmpLogHighBuffer, i, mask); | ||
| 559 | - LoadSrcData(tmpLLOReg, tmpLogLowBuffer, i, mask); | ||
| 560 | - LoadSrcData(tmpExpReg, src1, i, mask); | ||
| 561 | - GetExpCore(tmpDstReg, tmpLHIReg, tmpLLOReg, tmpExpReg, params, mask); | ||
| 562 | - MicroAPI::DataCopy(tmpExpBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpDstReg, mask); | ||
| 563 | - } | ||
| 564 | -} | ||
| 565 | - | ||
| 566 | -template<typename T> | ||
| 567 | -__simd_vf__ inline void ComputePowFExpImpl(__ubuf__ float* tmpExpBuffer, __ubuf__ float* tmpLogHighBuffer, | ||
| 568 | - __ubuf__ float* tmpLogLowBuffer, const T scalarValue, uint32_t calCount, uint16_t repeatTime) | ||
| 569 | -{ | ||
| 570 | - MicroAPI::MaskReg mask; | ||
| 571 | - MicroAPI::RegTensor<float> tmpLHIReg, tmpLLOReg, tmpExpReg, tmpDstReg; | ||
| 572 | - LoadSrcScalarData(tmpExpReg, scalarValue); | ||
| 573 | - | ||
| 574 | - PowerExpParams params; | ||
| 575 | - PowerExpParamsInit(params); | ||
| 576 | - | ||
| 577 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 578 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 579 | - LoadSrcData(tmpLHIReg, tmpLogHighBuffer, i, mask); | ||
| 580 | - LoadSrcData(tmpLLOReg, tmpLogLowBuffer, i, mask); | ||
| 581 | - GetExpCore(tmpDstReg, tmpLHIReg, tmpLLOReg, tmpExpReg, params, mask); | ||
| 582 | - MicroAPI::DataCopy(tmpExpBuffer + i * B32_DATA_NUM_PER_REPEAT, tmpDstReg, mask); | ||
| 583 | - } | ||
| 584 | -} | ||
| 585 | - | ||
| 586 | -template<typename T> | ||
| 587 | -__simd_vf__ inline void ComputePowFSpecialCaseImpl(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, | ||
| 588 | - __ubuf__ float* tmpExpBuffer, uint32_t calCount, uint16_t repeatTime) | ||
| 589 | -{ | ||
| 590 | - MicroAPI::MaskReg mask; | ||
| 591 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 592 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 593 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 594 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 595 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 596 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 597 | - LoadSrcData(tmpBaseReg, src0, i, mask); | ||
| 598 | - LoadSrcData(tmpExpReg, src1, i, mask); | ||
| 599 | - MicroAPI::DataCopy(castDstReg, tmpExpBuffer + i * B32_DATA_NUM_PER_REPEAT); | ||
| 600 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg, mask); | ||
| 601 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 602 | - } | ||
| 603 | -} | ||
| 604 | - | ||
| 605 | -template<typename T> | ||
| 606 | -__simd_vf__ inline void ComputePowFSpecialCaseImpl(__ubuf__ T* dst, __ubuf__ T* src0, const T scalarValue, | ||
| 607 | - __ubuf__ float* tmpExpBuffer, uint32_t calCount, uint16_t repeatTime) | ||
| 608 | -{ | ||
| 609 | - MicroAPI::MaskReg mask; | ||
| 610 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 611 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 612 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 613 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 614 | - LoadSrcScalarData(tmpExpReg, scalarValue); | ||
| 615 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 616 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 617 | - LoadSrcData(tmpBaseReg, src0, i, mask); | ||
| 618 | - MicroAPI::DataCopy(castDstReg, tmpExpBuffer + i * B32_DATA_NUM_PER_REPEAT); | ||
| 619 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg, mask); | ||
| 620 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 621 | - } | ||
| 622 | -} | ||
| 623 | - | ||
| 624 | -template<typename T> | ||
| 625 | -__simd_vf__ inline void ComputePowFSpecialCaseImpl(__ubuf__ T* dst, const T scalarValue, __ubuf__ T* src1, | ||
| 626 | - __ubuf__ float* tmpExpBuffer, uint32_t calCount, uint16_t repeatTime) | ||
| 627 | -{ | ||
| 628 | - MicroAPI::MaskReg mask; | ||
| 629 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 630 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 631 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 632 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 633 | - LoadSrcScalarData(tmpBaseReg, scalarValue); | ||
| 634 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 635 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 636 | - LoadSrcData(tmpExpReg, src1, i, mask); | ||
| 637 | - MicroAPI::DataCopy(castDstReg, tmpExpBuffer + i * B32_DATA_NUM_PER_REPEAT); | ||
| 638 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg, mask); | ||
| 639 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 640 | - } | ||
| 641 | -} | ||
| 642 | - | ||
| 643 | -__aicore__ inline void InitTmpBuffer(__ubuf__ uint32_t*& tmpBuffer, __ubuf__ float*& tmpLogBuffer, | ||
| 644 | - __ubuf__ float*& tmpExpBuffer, const uint32_t alignCount) | ||
| 645 | -{ | ||
| 646 | - tmpLogBuffer = (__ubuf__ float *)tmpBuffer; | ||
| 647 | - tmpExpBuffer = (__ubuf__ float *)((__ubuf__ uint8_t*)tmpLogBuffer + sizeof(float) * alignCount); | ||
| 648 | -} | ||
| 649 | - | ||
| 650 | -template<typename T> | ||
| 651 | -__aicore__ inline void PowFComputeImpl(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, | ||
| 652 | - __ubuf__ uint32_t* tmpBuffer, uint32_t calCount) | ||
| 653 | -{ | ||
| 654 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 655 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 656 | - __ubuf__ float* tmpLowBuffer; | ||
| 657 | - __ubuf__ float* tmpHighBuffer; | ||
| 658 | - | ||
| 659 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 660 | - | ||
| 661 | - InitTmpBuffer(tmpBuffer, tmpHighBuffer, tmpLowBuffer, alignCount); | ||
| 662 | - __ubuf__ float* tmpExpBuffer = tmpHighBuffer; | ||
| 663 | - | ||
| 664 | - ComputePowFBaseLog1Impl<T>(tmpHighBuffer, tmpLowBuffer, src0, calCount, repeatTime); | ||
| 665 | - ComputePowFBaseLog2Impl<T>(tmpHighBuffer, tmpLowBuffer, calCount, repeatTime); | ||
| 666 | - ComputePowFExpImpl<T>(tmpExpBuffer, tmpHighBuffer, tmpLowBuffer, src1, calCount, repeatTime); | ||
| 667 | - ComputePowFSpecialCaseImpl<T>(dst, src0, src1, tmpExpBuffer, calCount, repeatTime); | ||
| 668 | -} | ||
| 669 | - | ||
| 670 | -template<typename T> | ||
| 671 | -__aicore__ inline void PowFComputeImpl(__ubuf__ T* dst, __ubuf__ T* src0, const T& scalarValue, | ||
| 672 | - __ubuf__ uint32_t* tmpBuffer, uint32_t calCount) | ||
| 673 | -{ | ||
| 674 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 675 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 676 | - __ubuf__ float* tmpLowBuffer; | ||
| 677 | - __ubuf__ float* tmpHighBuffer; | ||
| 678 | - | ||
| 679 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 680 | - | ||
| 681 | - InitTmpBuffer(tmpBuffer, tmpHighBuffer, tmpLowBuffer, alignCount); | ||
| 682 | - | ||
| 683 | - __ubuf__ float* tmpExpBuffer = tmpHighBuffer; | ||
| 684 | - | ||
| 685 | - ComputePowFBaseLog1Impl<T>(tmpHighBuffer, tmpLowBuffer, src0, calCount, repeatTime); | ||
| 686 | - ComputePowFBaseLog2Impl<T>(tmpHighBuffer, tmpLowBuffer, calCount, repeatTime); | ||
| 687 | - ComputePowFExpImpl<T>(tmpExpBuffer, tmpHighBuffer, tmpLowBuffer, scalarValue, calCount, repeatTime); | ||
| 688 | - ComputePowFSpecialCaseImpl<T>(dst, src0, scalarValue, tmpExpBuffer, calCount, repeatTime); | ||
| 689 | -} | ||
| 690 | - | ||
| 691 | -template<typename T> | ||
| 692 | -__aicore__ inline void PowFComputeImpl(__ubuf__ T* dst, const T& scalarValue, __ubuf__ T* src1, | ||
| 693 | - __ubuf__ uint32_t* tmpBuffer, uint32_t calCount) | ||
| 694 | -{ | ||
| 695 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 696 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 697 | - __ubuf__ float* tmpLowBuffer; | ||
| 698 | - __ubuf__ float* tmpHighBuffer; | ||
| 699 | - | ||
| 700 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 701 | - | ||
| 702 | - InitTmpBuffer(tmpBuffer, tmpHighBuffer, tmpLowBuffer, alignCount); | ||
| 703 | - __ubuf__ float* tmpExpBuffer = tmpHighBuffer; | ||
| 704 | - | ||
| 705 | - ComputePowFBaseLog1Impl<T>(tmpHighBuffer, tmpLowBuffer, scalarValue, calCount, repeatTime); | ||
| 706 | - ComputePowFBaseLog2Impl<T>(tmpHighBuffer, tmpLowBuffer, calCount, repeatTime); | ||
| 707 | - ComputePowFExpImpl<T>(tmpExpBuffer, tmpHighBuffer, tmpLowBuffer, src1, calCount, repeatTime); | ||
| 708 | - ComputePowFSpecialCaseImpl<T>(dst, scalarValue, src1, tmpExpBuffer, calCount, repeatTime); | ||
| 709 | -} | ||
| 710 | - | ||
| 711 | -/*********** PowF Intrinsic Impl **********/ | ||
| 712 | -__aicore__ inline void GetPowFInstrinsicCore(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& baseReg, | ||
| 713 | - MicroAPI::RegTensor<float>& expReg, MicroAPI::MaskReg& mask) | ||
| 714 | -{ | ||
| 715 | - // Compute dst = exp(exp * ln(|base|)) | ||
| 716 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 717 | - MicroAPI::Abs(tmpReg, baseReg, mask); | ||
| 718 | - MicroAPI::Ln(tmpReg, tmpReg, mask); | ||
| 719 | - MicroAPI::Mul(dstReg, expReg, tmpReg, mask); | ||
| 720 | - MicroAPI::Exp(dstReg, dstReg, mask); | ||
| 721 | -} | ||
| 722 | - | ||
| 723 | -template<typename T> | ||
| 724 | -__aicore__ inline void PowFInstrinsicTensorTensorImpl(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, | ||
| 725 | - uint32_t calCount, uint16_t repeatTime) | ||
| 726 | -{ | ||
| 727 | - MicroAPI::MaskReg mask, tmpMask; | ||
| 728 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 729 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 730 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 731 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 732 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 733 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 734 | - tmpMask = mask; | ||
| 735 | - LoadSrcData(tmpBaseReg, src0, i, mask); | ||
| 736 | - LoadSrcData(tmpExpReg, src1, i, mask); | ||
| 737 | - GetPowFInstrinsicCore(castDstReg, tmpBaseReg, tmpExpReg, mask); | ||
| 738 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg, tmpMask); | ||
| 739 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 740 | - } | ||
| 741 | -} | ||
| 742 | - | ||
| 743 | -template<typename T> | ||
| 744 | -__aicore__ inline void PowFInstrinsicTensorScalarImpl(__ubuf__ T* dst, __ubuf__ T* src0, const T& scalarValue, | ||
| 745 | - uint32_t calCount, uint16_t repeatTime) | ||
| 746 | -{ | ||
| 747 | - MicroAPI::MaskReg mask, tmpMask; | ||
| 748 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 749 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 750 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 751 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 752 | - LoadSrcScalarData(tmpExpReg, scalarValue); | ||
| 753 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 754 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 755 | - tmpMask = mask; | ||
| 756 | - LoadSrcData(tmpBaseReg, src0, i, mask); | ||
| 757 | - GetPowFInstrinsicCore(castDstReg, tmpBaseReg, tmpExpReg, mask); | ||
| 758 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg,tmpMask); | ||
| 759 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 760 | - } | ||
| 761 | -} | ||
| 762 | - | ||
| 763 | -template<typename T> | ||
| 764 | -__aicore__ inline void PowFInstrinsicScalarTensorImpl(__ubuf__ T* dst, const T& scalarValue, __ubuf__ T* src1, | ||
| 765 | - uint32_t calCount, uint16_t repeatTime) | ||
| 766 | -{ | ||
| 767 | - MicroAPI::MaskReg mask, tmpMask; | ||
| 768 | - MicroAPI::RegTensor<float> tmpBaseReg, tmpExpReg, castDstReg; | ||
| 769 | - MicroAPI::RegTensor<int32_t> tmpR10Reg, tmpR12Reg; | ||
| 770 | - MicroAPI::Duplicate(tmpR10Reg, R10_COEFF); | ||
| 771 | - MicroAPI::Duplicate(tmpR12Reg, R12_COEFF); | ||
| 772 | - LoadSrcScalarData(tmpBaseReg, scalarValue); | ||
| 773 | - for(uint16_t i = 0; i < repeatTime; i++) { | ||
| 774 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 775 | - tmpMask = mask; | ||
| 776 | - LoadSrcData(tmpExpReg, src1, i, mask); | ||
| 777 | - GetPowFInstrinsicCore(castDstReg, tmpBaseReg, tmpExpReg, mask); | ||
| 778 | - ProcessSpecialCaseForPowF(castDstReg, tmpBaseReg, tmpExpReg, tmpR10Reg, tmpR12Reg, tmpMask); | ||
| 779 | - StoreDstData(dst, castDstReg, i, mask); | ||
| 780 | - } | ||
| 781 | -} | ||
| 782 | - | ||
| 783 | -template<typename T> | ||
| 784 | -__aicore__ inline void PowFInstrinsicImpl(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, | ||
| 785 | - uint32_t calCount) | ||
| 786 | -{ | ||
| 787 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 788 | - uint16_t repeatTimes = DivCeil(calCount, eleCountPerVL); | ||
| 789 | - VF_CALL<PowFInstrinsicTensorTensorImpl<T>>(dst, src0, src1, calCount, repeatTimes); | ||
| 790 | -} | ||
| 791 | - | ||
| 792 | -template<typename T> | ||
| 793 | -__aicore__ inline void PowFInstrinsicImpl(__ubuf__ T* dst, __ubuf__ T* src0, const T& scalarValue, | ||
| 794 | - uint32_t calCount) | ||
| 795 | -{ | ||
| 796 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 797 | - uint16_t repeatTimes = DivCeil(calCount, eleCountPerVL); | ||
| 798 | - VF_CALL<PowFInstrinsicTensorScalarImpl<T>>(dst, src0, scalarValue, calCount, repeatTimes); | ||
| 799 | -} | ||
| 800 | - | ||
| 801 | -template<typename T> | ||
| 802 | -__aicore__ inline void PowFInstrinsicImpl(__ubuf__ T* dst, const T& scalarValue, __ubuf__ T* src1, | ||
| 803 | - uint32_t calCount) | ||
| 804 | -{ | ||
| 805 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(float); | ||
| 806 | - uint16_t repeatTimes = DivCeil(calCount, eleCountPerVL); | ||
| 807 | - VF_CALL<PowFInstrinsicScalarTensorImpl<T>>(dst, scalarValue, src1, calCount, repeatTimes); | ||
| 808 | -} | ||
| 809 | -} // namespace PowF | ||
| 810 | - | ||
| 811 | -namespace PowI { | ||
| 812 | -constexpr int16_t SHIFT_ONE_BIT = 1; | ||
| 813 | -constexpr int16_t BITS_PER_BYTE = 8; | ||
| 814 | - | ||
| 815 | -template<typename T> | ||
| 816 | -__simd_callee__ inline void GetPowI(MicroAPI::RegTensor<T>& dstReg, MicroAPI::RegTensor<T>& baseReg, | ||
| 817 | - MicroAPI::RegTensor<T>& expReg, MicroAPI::MaskReg& mask) | ||
| 818 | -{ | ||
| 819 | - MicroAPI::RegTensor<T> tmpReg, tmpReg2; | ||
| 820 | - MicroAPI::MaskReg expMask; | ||
| 821 | - // step 1: result1 = result * a; | ||
| 822 | - MicroAPI::Mul(tmpReg, dstReg, baseReg, mask); | ||
| 823 | - MicroAPI::Duplicate(tmpReg2, 1, mask); | ||
| 824 | - // step 2: mask = b & 1; | ||
| 825 | - MicroAPI::And(tmpReg2, expReg, tmpReg2, mask); | ||
| 826 | - // step 3: result = select(mask, result1, result); | ||
| 827 | - MicroAPI::CompareScalar<T, CMPMODE::EQ>(expMask, tmpReg2, 1, mask); | ||
| 828 | - MicroAPI::Select(dstReg, tmpReg, dstReg, expMask); | ||
| 829 | - // step4: b /= 2; | ||
| 830 | - MicroAPI::ShiftRights(expReg, expReg, SHIFT_ONE_BIT, mask); | ||
| 831 | - // step5: a *= a; | ||
| 832 | - MicroAPI::Mul(baseReg, baseReg, baseReg, mask); | ||
| 833 | -} | ||
| 834 | - | ||
| 835 | -template<typename T> | ||
| 836 | -__simd_callee__ inline void ProcessSpecialCaseForPowI(MicroAPI::RegTensor<T>& dstReg, MicroAPI::RegTensor<T>& baseReg, | ||
| 837 | - MicroAPI::RegTensor<T>& expReg, MicroAPI::MaskReg& mask) | ||
| 838 | -{ | ||
| 839 | - MicroAPI::RegTensor<T> tmpRReg; | ||
| 840 | - MicroAPI::MaskReg cmpMask1, cmpMask2, condMask; | ||
| 841 | - /* | ||
| 842 | - * special case 1: | ||
| 843 | - * if (exp == 0) || (base == 1) { | ||
| 844 | - * r = 1; | ||
| 845 | - * } | ||
| 846 | - */ | ||
| 847 | - MicroAPI::CompareScalar<T, CMPMODE::EQ>(cmpMask1, expReg, 0, mask); | ||
| 848 | - MicroAPI::CompareScalar<T, CMPMODE::EQ>(cmpMask2, baseReg, 1, mask); | ||
| 849 | - MicroAPI::MaskOr(condMask, cmpMask1, cmpMask2, mask); | ||
| 850 | - MicroAPI::Duplicate(tmpRReg, 1, mask); | ||
| 851 | - MicroAPI::Select(dstReg, tmpRReg, dstReg, condMask); | ||
| 852 | - MicroAPI::MaskXor(mask, mask, condMask, mask); | ||
| 853 | - | ||
| 854 | - if constexpr (SupportType<T, int8_t, int16_t, int32_t>()) { | ||
| 855 | - /* | ||
| 856 | - * special case 2: | ||
| 857 | - * else if (base != -1 && exp < 0) { | ||
| 858 | - * r = 0; | ||
| 859 | - * } | ||
| 860 | - */ | ||
| 861 | - MicroAPI::CompareScalar<T, CMPMODE::NE>(cmpMask1, baseReg, -1, mask); | ||
| 862 | - MicroAPI::CompareScalar<T, CMPMODE::LT>(cmpMask2, expReg, 0, mask); | ||
| 863 | - MicroAPI::MaskAnd(condMask, cmpMask1, cmpMask2, mask); | ||
| 864 | - MicroAPI::Duplicate(tmpRReg, 0, mask); | ||
| 865 | - MicroAPI::Select(dstReg, tmpRReg, dstReg, condMask); | ||
| 866 | - } | ||
| 867 | -} | ||
| 868 | - | ||
| 869 | -template<typename T> | ||
| 870 | -__simd_callee__ inline void GetPowICompute(MicroAPI::RegTensor<T>& dstReg, MicroAPI::RegTensor<T>& baseReg, | ||
| 871 | - MicroAPI::RegTensor<T>& expReg, MicroAPI::MaskReg& mask, const uint16_t maxLoop) | ||
| 872 | -{ | ||
| 873 | - MicroAPI::RegTensor<T> tmpBaseReg = baseReg; | ||
| 874 | - MicroAPI::RegTensor<T> tmpExpReg = expReg; | ||
| 875 | - MicroAPI::MaskReg tmpMask = mask; | ||
| 876 | - for (uint16_t j = 0; j < maxLoop; j++) { | ||
| 877 | - GetPowI(dstReg, tmpBaseReg, tmpExpReg, mask); | ||
| 878 | - } | ||
| 879 | - ProcessSpecialCaseForPowI(dstReg, baseReg, expReg, tmpMask); | ||
| 880 | -} | ||
| 881 | - | ||
| 882 | -template<typename T> | ||
| 883 | -struct PowICastType { | ||
| 884 | - using type = T; | ||
| 885 | -}; | ||
| 886 | - | ||
| 887 | -template<> | ||
| 888 | -struct PowICastType<int8_t> { | ||
| 889 | - using type = int16_t; | ||
| 890 | -}; | ||
| 891 | - | ||
| 892 | -template<> | ||
| 893 | -struct PowICastType<uint8_t> { | ||
| 894 | - using type = uint16_t; | ||
| 895 | -}; | ||
| 896 | - | ||
| 897 | -template<typename T> | ||
| 898 | -__aicore__ inline uint16_t CountLeadingZeros(T x) { | ||
| 899 | - if (x == 0) return sizeof(T) * 8; | ||
| 900 | - uint16_t count = 0; | ||
| 901 | - T mask = static_cast<T>(1 << (sizeof(T) * 8 - 1)); | ||
| 902 | - while((x & mask) == 0) { | ||
| 903 | - count ++; | ||
| 904 | - x <<= 1; | ||
| 905 | - } | ||
| 906 | - return count; | ||
| 907 | -} | ||
| 908 | - | ||
| 909 | -template<typename T, typename ConvType> | ||
| 910 | -__simd_callee__ inline void LoadSrcData(MicroAPI::RegTensor<ConvType>& dstReg, __ubuf__ T* src, uint16_t index, MicroAPI::MaskReg& mask) | ||
| 911 | -{ | ||
| 912 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(ConvType); | ||
| 913 | - MicroAPI::RegTensor<T> srcTmpReg; | ||
| 914 | - if constexpr (sizeof(T) == 1) { | ||
| 915 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B8>(srcTmpReg, src + index * eleCountPerVL); | ||
| 916 | - MicroAPI::Cast<ConvType, T, castTraitI8I16>(dstReg, srcTmpReg, mask); | ||
| 917 | - } else { | ||
| 918 | - MicroAPI::DataCopy(dstReg, src + index * eleCountPerVL); | ||
| 919 | - } | ||
| 920 | -} | ||
| 921 | - | ||
| 922 | -template<typename T, typename ConvType> | ||
| 923 | -__simd_callee__ inline void StoreDstData(__ubuf__ T* dst, MicroAPI::RegTensor<ConvType>& dstReg, uint16_t index, MicroAPI::MaskReg& mask) | ||
| 924 | -{ | ||
| 925 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(ConvType); | ||
| 926 | - MicroAPI::RegTensor<T> dstTmpReg; | ||
| 927 | - | ||
| 928 | - if constexpr (sizeof(T) == 1) { | ||
| 929 | - MicroAPI::Pack<uint8_t, uint16_t, MicroAPI::HighLowPart::LOWEST>( | ||
| 930 | - (MicroAPI::RegTensor<uint8_t>&)dstTmpReg, (MicroAPI::RegTensor<uint16_t>&)dstReg); | ||
| 931 | - MicroAPI::MaskPack(mask, mask); | ||
| 932 | - MicroAPI::DataCopy(dst + index * eleCountPerVL, dstTmpReg, mask); | ||
| 933 | - } else { | ||
| 934 | - MicroAPI::DataCopy(dst + index * eleCountPerVL, dstReg, mask); | ||
| 935 | - } | ||
| 936 | -} | ||
| 937 | - | ||
| 938 | -template<typename T> | ||
| 939 | -__aicore__ inline uint16_t GetMaxLoop(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, uint32_t calCount) | ||
| 940 | -{ | ||
| 941 | - if constexpr(sizeof(T) == 1) { | ||
| 942 | - return sizeof(T) * BITS_PER_BYTE; | ||
| 943 | - } else { | ||
| 944 | - AscendC::ReduceMax(dstTensor, srcTensor, srcTensor, calCount); | ||
| 945 | - event_t eventIdVToS = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_S)); | ||
| 946 | - SetFlag<HardEvent::V_S>(eventIdVToS); | ||
| 947 | - WaitFlag<HardEvent::V_S>(eventIdVToS); | ||
| 948 | - T maxNum = dstTensor.GetValue(0); | ||
| 949 | - return sizeof(T) * BITS_PER_BYTE - CountLeadingZeros(maxNum); | ||
| 950 | - } | ||
| 951 | -} | ||
| 952 | - | ||
| 953 | -template<typename T> | ||
| 954 | -__simd_vf__ inline void PowIComputeImpl(__ubuf__ T* dst, __ubuf__ T* src0, __ubuf__ T* src1, uint32_t calCount, uint16_t maxLoop) | ||
| 955 | -{ | ||
| 956 | - using ConvType = typename PowICastType<T>::type; | ||
| 957 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(ConvType); | ||
| 958 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 959 | - | ||
| 960 | - MicroAPI::RegTensor<ConvType> baseReg, expReg; | ||
| 961 | - MicroAPI::RegTensor<ConvType> initRetReg, dstReg; | ||
| 962 | - MicroAPI::MaskReg mask; | ||
| 963 | - | ||
| 964 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T>(); | ||
| 965 | - MicroAPI::Duplicate(initRetReg, 1, fullMask); | ||
| 966 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 967 | - mask = MicroAPI::UpdateMask<ConvType>(calCount); | ||
| 968 | - | ||
| 969 | - LoadSrcData(baseReg, src0, i, mask); | ||
| 970 | - LoadSrcData(expReg, src1, i, mask); | ||
| 971 | - dstReg = initRetReg; | ||
| 972 | - GetPowICompute(dstReg, baseReg, expReg, mask, maxLoop); | ||
| 973 | - StoreDstData(dst, dstReg, i, mask); | ||
| 974 | - } | ||
| 975 | -} | ||
| 976 | - | ||
| 977 | -template<typename T> | ||
| 978 | -__simd_vf__ inline void PowIComputeImpl(__ubuf__ T* dst, __ubuf__ T* src0, const T scalarValue, uint32_t calCount, uint16_t maxLoop) | ||
| 979 | -{ | ||
| 980 | - using ConvType = typename PowICastType<T>::type; | ||
| 981 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(ConvType); | ||
| 982 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 983 | - | ||
| 984 | - MicroAPI::RegTensor<ConvType> baseReg, expReg; | ||
| 985 | - MicroAPI::RegTensor<ConvType> initRetReg, dstReg; | ||
| 986 | - MicroAPI::MaskReg mask; | ||
| 987 | - | ||
| 988 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T>(); | ||
| 989 | - MicroAPI::Duplicate(initRetReg, 1, fullMask); | ||
| 990 | - MicroAPI::Duplicate(expReg, scalarValue, fullMask); | ||
| 991 | - | ||
| 992 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 993 | - mask = MicroAPI::UpdateMask<ConvType>(calCount); | ||
| 994 | - LoadSrcData(baseReg, src0, i, mask); | ||
| 995 | - dstReg = initRetReg; | ||
| 996 | - GetPowICompute(dstReg, baseReg, expReg, mask, maxLoop); | ||
| 997 | - StoreDstData(dst, dstReg, i, mask); | ||
| 998 | - } | ||
| 999 | -} | ||
| 1000 | - | ||
| 1001 | -template<typename T> | ||
| 1002 | -__simd_vf__ inline void PowIComputeImpl(__ubuf__ T* dst, const T scalarValue, __ubuf__ T* src1, uint32_t calCount, uint16_t maxLoop) | ||
| 1003 | -{ | ||
| 1004 | - using ConvType = typename PowICastType<T>::type; | ||
| 1005 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(ConvType); | ||
| 1006 | - uint16_t repeatTime = DivCeil(calCount, eleCountPerVL); | ||
| 1007 | - | ||
| 1008 | - MicroAPI::RegTensor<ConvType> baseReg, expReg; | ||
| 1009 | - MicroAPI::RegTensor<ConvType> initRetReg, dstReg; | ||
| 1010 | - MicroAPI::MaskReg mask; | ||
| 1011 | - MicroAPI::MaskReg fullMask = MicroAPI::CreateMask<T>(); | ||
| 1012 | - MicroAPI::Duplicate(initRetReg, 1, fullMask); | ||
| 1013 | - MicroAPI::Duplicate(baseReg, scalarValue, fullMask); | ||
| 1014 | - | ||
| 1015 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 1016 | - mask = MicroAPI::UpdateMask<ConvType>(calCount); | ||
| 1017 | - LoadSrcData(expReg, src1, i, mask); | ||
| 1018 | - dstReg = initRetReg; | ||
| 1019 | - GetPowICompute(dstReg, baseReg, expReg, mask, maxLoop); | ||
| 1020 | - StoreDstData(dst, dstReg, i, mask); | ||
| 1021 | - } | ||
| 1022 | -} | ||
| 1023 | - | ||
| 1024 | -} // namespace PowI | ||
| 1025 | -} // namespace PowerL300Impl | ||
| 1026 | - | ||
| 1027 | -template <typename T, const PowerConfig& config = defaultPowerConfig> | ||
| 1028 | -__aicore__ inline void PowCheckType() | ||
| 1029 | -{ | ||
| 1030 | - if constexpr (config.algo == AscendC::PowerAlgo::DOUBLE_FLOAT_TECH) { | ||
| 1031 | - static_assert(SupportType<T, half, float, bfloat16_t>(), | ||
| 1032 | - "Type must be half/float/bfloat16 in double float tech algorithm." | ||
| 1033 | - ); | ||
| 1034 | - } | ||
| 1035 | - | ||
| 1036 | - if constexpr (config.algo == AscendC::PowerAlgo::INTRINSIC) { | ||
| 1037 | - static_assert(SupportType<T, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, half, float>(), | ||
| 1038 | - "Type must be uint8_t/int8_t/uint16_t/int16_t/uint32_t/int32_t/half/float in intrinsic tech algorithm." | ||
| 1039 | - ); | ||
| 1040 | - } | ||
| 1041 | -} | ||
| 1042 | - | ||
| 1043 | -template <typename T> | ||
| 1044 | -__aicore__ inline constexpr bool IsFloatNum() | ||
| 1045 | -{ | ||
| 1046 | - return SupportType<T, float, half, bfloat16_t>(); | ||
| 1047 | -} | ||
| 1048 | - | ||
| 1049 | -template <typename T> | ||
| 1050 | -__aicore__ inline constexpr bool IsIntegerNum() | ||
| 1051 | -{ | ||
| 1052 | - return SupportType<T, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t>(); | ||
| 1053 | -} | ||
| 1054 | - | ||
| 1055 | -__aicore__ inline constexpr uint32_t GetPowerTmpBufferLiveNode() { | ||
| 1056 | - constexpr uint32_t tmpBufferLiveNode = sizeof(float) * 2; | ||
| 1057 | - return tmpBufferLiveNode; | ||
| 1058 | -} | ||
| 1059 | - | ||
| 1060 | -template<typename T> | ||
| 1061 | -__aicore__ inline uint32_t GetPowTmpBufferSize(const LocalTensor<uint8_t>& sharedTmpBuffer) { | ||
| 1062 | - uint32_t sharedTmpBufferSize = sharedTmpBuffer.GetSize() / GetPowerTmpBufferLiveNode(); | ||
| 1063 | - return AlignUp(sharedTmpBufferSize, GetDataBlockSizeInBytes()); | ||
| 1064 | -} | ||
| 1065 | - | ||
| 1066 | -// PowImpl(tensor, tensor) float/half input | ||
| 1067 | -template<typename T, const PowerConfig& config> | ||
| 1068 | -__aicore__ inline void PowImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1069 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1070 | -{ | ||
| 1071 | - __ubuf__ T* src0 = (__ubuf__ T *)src0Tensor.GetPhyAddr(); | ||
| 1072 | - __ubuf__ T* src1 = (__ubuf__ T *)src1Tensor.GetPhyAddr(); | ||
| 1073 | - __ubuf__ T* dst = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 1074 | - | ||
| 1075 | - if constexpr (IsFloatNum<T>()) { | ||
| 1076 | - if constexpr (config.algo == PowerAlgo::INTRINSIC) { | ||
| 1077 | - PowerL300Impl::PowF::PowFInstrinsicImpl(dst, src0, src1, calCount); | ||
| 1078 | - } else { | ||
| 1079 | - __ubuf__ uint32_t* tmpBuffer = (__ubuf__ uint32_t *)sharedTmpBuffer.GetPhyAddr(); | ||
| 1080 | - uint32_t sharedTmpBufferSize = GetPowTmpBufferSize<T>(sharedTmpBuffer); | ||
| 1081 | - uint32_t count = calCount; | ||
| 1082 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, sharedTmpBufferSize)); | ||
| 1083 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 1084 | - uint32_t remainCount = count - sharedTmpBufferSize * i; | ||
| 1085 | - uint32_t oneRepSize = remainCount < sharedTmpBufferSize ? remainCount : sharedTmpBufferSize; | ||
| 1086 | - PowerL300Impl::PowF::PowFComputeImpl(dst + i * sharedTmpBufferSize, src0 + i * sharedTmpBufferSize, | ||
| 1087 | - src1 + i * sharedTmpBufferSize, tmpBuffer, oneRepSize); | ||
| 1088 | - } | ||
| 1089 | - } | ||
| 1090 | - } else if constexpr (IsIntegerNum<T>()) { | ||
| 1091 | - uint16_t maxLoop = PowerL300Impl::PowI::GetMaxLoop(dstTensor, src1Tensor, calCount); | ||
| 1092 | - event_t eventIdSToV = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::S_V)); | ||
| 1093 | - SetFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1094 | - WaitFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1095 | - PowerL300Impl::PowI::PowIComputeImpl<T>(dst, src0, src1, calCount, maxLoop); | ||
| 1096 | - } | ||
| 1097 | -} | ||
| 1098 | - | ||
| 1099 | -// PowImpl(tensor, scalar) float input | ||
| 1100 | -template<typename T, const PowerConfig& config> | ||
| 1101 | -__aicore__ inline void PowImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1102 | - const T& scalarValue, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1103 | -{ | ||
| 1104 | - __ubuf__ T *base = (__ubuf__ T *)src0Tensor.GetPhyAddr(); | ||
| 1105 | - __ubuf__ T *dst = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 1106 | - | ||
| 1107 | - if constexpr (IsFloatNum<T>()) { | ||
| 1108 | - if constexpr (config.algo == PowerAlgo::INTRINSIC) { | ||
| 1109 | - PowerL300Impl::PowF::PowFInstrinsicImpl(dst, base, scalarValue, calCount); | ||
| 1110 | - } else { | ||
| 1111 | - __ubuf__ uint32_t* tmpBuffer = (__ubuf__ uint32_t *)sharedTmpBuffer.GetPhyAddr(); | ||
| 1112 | - uint32_t sharedTmpBufferSize = GetPowTmpBufferSize<T>(sharedTmpBuffer); | ||
| 1113 | - uint32_t count = calCount; | ||
| 1114 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, sharedTmpBufferSize)); | ||
| 1115 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 1116 | - uint32_t remainCount = count - sharedTmpBufferSize * i; | ||
| 1117 | - uint32_t oneRepSize = remainCount < sharedTmpBufferSize ? remainCount : sharedTmpBufferSize; | ||
| 1118 | - PowerL300Impl::PowF::PowFComputeImpl( | ||
| 1119 | - dst + i * sharedTmpBufferSize, base + i * sharedTmpBufferSize, scalarValue, tmpBuffer, oneRepSize); | ||
| 1120 | - } | ||
| 1121 | - } | ||
| 1122 | - } else if constexpr (IsIntegerNum<T>()) { | ||
| 1123 | - uint16_t maxLoop = sizeof(T) * PowerL300Impl::PowI::BITS_PER_BYTE - PowerL300Impl::PowI::CountLeadingZeros(scalarValue); | ||
| 1124 | - PowerL300Impl::PowI::PowIComputeImpl<T>(dst, base, scalarValue, calCount, maxLoop); | ||
| 1125 | - } | ||
| 1126 | -} | ||
| 1127 | - | ||
| 1128 | -// PowImpl(scalar, tensor) float input | ||
| 1129 | -template<typename T, const PowerConfig& config> | ||
| 1130 | -__aicore__ inline void PowImpl(const LocalTensor<T>& dstTensor, const T& scalarValue, | ||
| 1131 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1132 | -{ | ||
| 1133 | - __ubuf__ T *exp = (__ubuf__ T *)src1Tensor.GetPhyAddr(); | ||
| 1134 | - __ubuf__ T *dst = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 1135 | - | ||
| 1136 | - if constexpr (IsFloatNum<T>()) { | ||
| 1137 | - if constexpr (config.algo == PowerAlgo::INTRINSIC) { | ||
| 1138 | - PowerL300Impl::PowF::PowFInstrinsicImpl(dst, scalarValue, exp, calCount); | ||
| 1139 | - } else { | ||
| 1140 | - __ubuf__ uint32_t* tmpBuffer = (__ubuf__ uint32_t *)sharedTmpBuffer.GetPhyAddr(); | ||
| 1141 | - uint32_t sharedTmpBufferSize = GetPowTmpBufferSize<T>(sharedTmpBuffer); | ||
| 1142 | - uint32_t count = calCount; | ||
| 1143 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, sharedTmpBufferSize)); | ||
| 1144 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 1145 | - uint32_t remainCount = count - sharedTmpBufferSize * i; | ||
| 1146 | - uint32_t oneRepSize = remainCount < sharedTmpBufferSize ? remainCount : sharedTmpBufferSize; | ||
| 1147 | - PowerL300Impl::PowF::PowFComputeImpl(dst + i * sharedTmpBufferSize, scalarValue, | ||
| 1148 | - exp + i * sharedTmpBufferSize, tmpBuffer, oneRepSize); | ||
| 1149 | - } | ||
| 1150 | - } | ||
| 1151 | - } else if constexpr (IsIntegerNum<T>()) { | ||
| 1152 | - uint16_t maxLoop = PowerL300Impl::PowI::GetMaxLoop(dstTensor, src1Tensor, calCount); | ||
| 1153 | - event_t eventIdSToV = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::S_V)); | ||
| 1154 | - SetFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1155 | - WaitFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1156 | - PowerL300Impl::PowI::PowIComputeImpl<T>(dst, scalarValue, exp, calCount, maxLoop); | ||
| 1157 | - } | ||
| 1158 | -} | ||
| 1159 | - | ||
| 1160 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1161 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const T& scalarValue, | ||
| 1162 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1163 | -{ | ||
| 1164 | - if ASCEND_IS_AIC { | ||
| 1165 | - return; | ||
| 1166 | - } | ||
| 1167 | - PowCheckType<T, config>(); | ||
| 1168 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1169 | - CheckTensorPos<T>(src1Tensor, Hardware::UB, "src1Tensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1170 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1171 | - CheckCalCount(calCount, "calCount", src1Tensor, "src1Tensor", "Power"); | ||
| 1172 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Power"); | ||
| 1173 | - | ||
| 1174 | - PowImpl<T, config>(dstTensor, scalarValue, src1Tensor, sharedTmpBuffer, calCount); | ||
| 1175 | -} | ||
| 1176 | - | ||
| 1177 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1178 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1179 | - const T& scalarValue, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1180 | -{ | ||
| 1181 | - if ASCEND_IS_AIC { | ||
| 1182 | - return; | ||
| 1183 | - } | ||
| 1184 | - PowCheckType<T, config>(); | ||
| 1185 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1186 | - CheckTensorPos<T>(src0Tensor, Hardware::UB, "src0Tensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1187 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1188 | - CheckCalCount(calCount, "calCount", src0Tensor, "src0Tensor", "Power"); | ||
| 1189 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Power"); | ||
| 1190 | - | ||
| 1191 | - PowImpl<T, config>(dstTensor, src0Tensor, scalarValue, sharedTmpBuffer, calCount); | ||
| 1192 | -} | ||
| 1193 | - | ||
| 1194 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1195 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1196 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1197 | -{ | ||
| 1198 | - if ASCEND_IS_AIC { | ||
| 1199 | - return; | ||
| 1200 | - } | ||
| 1201 | - PowCheckType<T, config>(); | ||
| 1202 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1203 | - CheckTensorPos<T>(src0Tensor, Hardware::UB, "src0Tensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1204 | - CheckTensorPos<T>(src1Tensor, Hardware::UB, "src1Tensor", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1205 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECOUT / VECCALC", "Power"); | ||
| 1206 | - CheckCalCount(calCount, "calCount", src0Tensor, "src0Tensor", "Power"); | ||
| 1207 | - CheckCalCount(calCount, "calCount", src1Tensor, "src1Tensor", "Power"); | ||
| 1208 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Power"); | ||
| 1209 | - | ||
| 1210 | - PowImpl<T, config>(dstTensor, src0Tensor, src1Tensor, sharedTmpBuffer, calCount); | ||
| 1211 | -} | ||
| 1212 | - | ||
| 1213 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1214 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1215 | - const LocalTensor<T>& src1Tensor, uint32_t calCount) | ||
| 1216 | -{ | ||
| 1217 | - LocalTensor<uint8_t> stackTensor; | ||
| 1218 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(stackTensor); | ||
| 1219 | - ASCENDC_ASSERT((ans), | ||
| 1220 | - { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 1221 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Tensor, stackTensor, calCount); | ||
| 1222 | -} | ||
| 1223 | - | ||
| 1224 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1225 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const T& src0Scalar, | ||
| 1226 | - const LocalTensor<T>& src1Tensor, uint32_t calCount) | ||
| 1227 | -{ | ||
| 1228 | - LocalTensor<uint8_t> stackTensor; | ||
| 1229 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(stackTensor); | ||
| 1230 | - ASCENDC_ASSERT((ans), | ||
| 1231 | - { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 1232 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Scalar, src1Tensor, stackTensor, calCount); | ||
| 1233 | -} | ||
| 1234 | - | ||
| 1235 | -template<typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1236 | -__aicore__ inline void PowerCommonImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1237 | - const T& src1Scalar, uint32_t calCount) | ||
| 1238 | -{ | ||
| 1239 | - LocalTensor<uint8_t> stackTensor; | ||
| 1240 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(stackTensor); | ||
| 1241 | - ASCENDC_ASSERT((ans), | ||
| 1242 | - { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 1243 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Scalar, stackTensor, calCount); | ||
| 1244 | -} | ||
| 1245 | - | ||
| 1246 | -/*! | ||
| 1247 | - * \ingroup Power | ||
| 1248 | - * \brief compute Power elementwisely. | ||
| 1249 | - * \tparam T: input dataType, support half/float | ||
| 1250 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1251 | - * not enabled currently. | ||
| 1252 | - * \param [out] dstTensor: output LocalTensor | ||
| 1253 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1254 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1255 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1256 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1257 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1258 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1259 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1260 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1261 | - */ | ||
| 1262 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1263 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1264 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1265 | -{ | ||
| 1266 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Tensor, sharedTmpBuffer, calCount); | ||
| 1267 | -} | ||
| 1268 | - | ||
| 1269 | -/*! | ||
| 1270 | - * \ingroup Power | ||
| 1271 | - * \brief compute Power elementwisely. | ||
| 1272 | - * \tparam T: input dataType, support half/float | ||
| 1273 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1274 | - * not enabled currently. | ||
| 1275 | - * \param [out] dstTensor: output LocalTensor | ||
| 1276 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1277 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1278 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1279 | - */ | ||
| 1280 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1281 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1282 | - const LocalTensor<T>& src1Tensor, uint32_t calCount) | ||
| 1283 | -{ | ||
| 1284 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Tensor, calCount); | ||
| 1285 | -} | ||
| 1286 | - | ||
| 1287 | -/*! | ||
| 1288 | - * \ingroup Power | ||
| 1289 | - * \brief compute Power elementwisely. | ||
| 1290 | - * \tparam T: input dataType, support half/float | ||
| 1291 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1292 | - * not enabled currently. | ||
| 1293 | - * \param [out] dstTensor: output LocalTensor | ||
| 1294 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1295 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1296 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1297 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1298 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1299 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1300 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1301 | - */ | ||
| 1302 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1303 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, | ||
| 1304 | - const LocalTensor<T>& src1Tensor, const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 1305 | -{ | ||
| 1306 | - Power<T, isReuseSource, config>(dstTensor, src0Tensor, src1Tensor, sharedTmpBuffer, src0Tensor.GetSize()); | ||
| 1307 | -} | ||
| 1308 | - | ||
| 1309 | -/*! | ||
| 1310 | - * \ingroup Power | ||
| 1311 | - * \brief compute Power elementwisely. | ||
| 1312 | - * \tparam T: input dataType, support half/float | ||
| 1313 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1314 | - * not enabled currently. | ||
| 1315 | - * \param [out] dstTensor: output LocalTensor | ||
| 1316 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1317 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1318 | - */ | ||
| 1319 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1320 | -__aicore__ inline void Power( | ||
| 1321 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, const LocalTensor<T>& src1Tensor) | ||
| 1322 | -{ | ||
| 1323 | - Power<T, isReuseSource, config>(dstTensor, src0Tensor, src1Tensor, src0Tensor.GetSize()); | ||
| 1324 | -} | ||
| 1325 | - | ||
| 1326 | -/*! | ||
| 1327 | - * \ingroup Power | ||
| 1328 | - * \brief compute Power elementwisely. | ||
| 1329 | - * \tparam T: input dataType, support half/float | ||
| 1330 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1331 | - * not enabled currently. | ||
| 1332 | - * \param [out] dstTensor: output LocalTensor | ||
| 1333 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1334 | - * \param [in] src1Scalar: exponent Scalar | ||
| 1335 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1336 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1337 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1338 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1339 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1340 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1341 | - */ | ||
| 1342 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1343 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, const T& src1Scalar, | ||
| 1344 | - const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1345 | -{ | ||
| 1346 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Scalar, sharedTmpBuffer, calCount); | ||
| 1347 | -} | ||
| 1348 | - | ||
| 1349 | -/*! | ||
| 1350 | - * \ingroup Power | ||
| 1351 | - * \brief compute Power elementwisely. | ||
| 1352 | - * \tparam T: input dataType, support half/float | ||
| 1353 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1354 | - * not enabled currently. | ||
| 1355 | - * \param [out] dstTensor: output LocalTensor | ||
| 1356 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1357 | - * \param [in] src1Scalar: exponent Scalar | ||
| 1358 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1359 | - */ | ||
| 1360 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1361 | -__aicore__ inline void Power( | ||
| 1362 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, const T& src1Scalar, uint32_t calCount) | ||
| 1363 | -{ | ||
| 1364 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Tensor, src1Scalar, calCount); | ||
| 1365 | -} | ||
| 1366 | - | ||
| 1367 | -/*! | ||
| 1368 | - * \ingroup Power | ||
| 1369 | - * \brief compute Power elementwisely. | ||
| 1370 | - * \tparam T: input dataType, support half/float | ||
| 1371 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1372 | - * not enabled currently. | ||
| 1373 | - * \param [out] dstTensor: output LocalTensor | ||
| 1374 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1375 | - * \param [in] src1Scalar: exponent Scalar | ||
| 1376 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1377 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1378 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1379 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1380 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1381 | - */ | ||
| 1382 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1383 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, const T& src1Scalar, | ||
| 1384 | - const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 1385 | -{ | ||
| 1386 | - Power<T, isReuseSource, config>(dstTensor, src0Tensor, src1Scalar, sharedTmpBuffer, src0Tensor.GetSize()); | ||
| 1387 | -} | ||
| 1388 | - | ||
| 1389 | -/*! | ||
| 1390 | - * \ingroup Power | ||
| 1391 | - * \brief compute Power elementwisely. | ||
| 1392 | - * \tparam T: input dataType, support half/float | ||
| 1393 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1394 | - * not enabled currently. | ||
| 1395 | - * \param [out] dstTensor: output LocalTensor | ||
| 1396 | - * \param [in] src0Tensor: base LocalTensor | ||
| 1397 | - * \param [in] src1Scalar: exponent Scalar | ||
| 1398 | - */ | ||
| 1399 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1400 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const LocalTensor<T>& src0Tensor, const T& src1Scalar) | ||
| 1401 | -{ | ||
| 1402 | - Power<T, isReuseSource, config>(dstTensor, src0Tensor, src1Scalar, src0Tensor.GetSize());; | ||
| 1403 | -} | ||
| 1404 | - | ||
| 1405 | -/*! | ||
| 1406 | - * \ingroup Power | ||
| 1407 | - * \brief compute Power elementwisely. | ||
| 1408 | - * \tparam T: input dataType, support half/float | ||
| 1409 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1410 | - * not enabled currently. | ||
| 1411 | - * \param [out] dstTensor: output LocalTensor | ||
| 1412 | - * \param [in] src0Scalar: base Scalar | ||
| 1413 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1414 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1415 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1416 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1417 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1418 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1419 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1420 | - */ | ||
| 1421 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1422 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const T& src0Scalar, const LocalTensor<T>& src1Tensor, | ||
| 1423 | - const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 1424 | -{ | ||
| 1425 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Scalar, src1Tensor, sharedTmpBuffer, calCount); | ||
| 1426 | -} | ||
| 1427 | - | ||
| 1428 | -/*! | ||
| 1429 | - * \ingroup Power | ||
| 1430 | - * \brief compute Power elementwisely. | ||
| 1431 | - * \tparam T: input dataType, support half/float | ||
| 1432 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1433 | - * not enabled currently. | ||
| 1434 | - * \param [out] dstTensor: output LocalTensor | ||
| 1435 | - * \param [in] src0Scalar: input Scalar | ||
| 1436 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1437 | - * \param [in] calCount: amount of output data to be calculated | ||
| 1438 | - */ | ||
| 1439 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1440 | -__aicore__ inline void Power( | ||
| 1441 | - const LocalTensor<T>& dstTensor, const T& src0Scalar, const LocalTensor<T>& src1Tensor, uint32_t calCount) | ||
| 1442 | -{ | ||
| 1443 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Scalar, src1Tensor, calCount); | ||
| 1444 | -} | ||
| 1445 | - | ||
| 1446 | -/*! | ||
| 1447 | - * \ingroup Power | ||
| 1448 | - * \brief compute Power elementwisely. | ||
| 1449 | - * \tparam T: input dataType, support half/float | ||
| 1450 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1451 | - * not enabled currently. | ||
| 1452 | - * \param [out] dstTensor: output LocalTensor | ||
| 1453 | - * \param [in] src0Scalar: base Scalar | ||
| 1454 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1455 | - * \param [in] sharedTmpBuffer:extra temporary shared space used for intermediate values among calculation process, | ||
| 1456 | - * whose required space size should refer to corresponding tiling API, which is defined at | ||
| 1457 | - * power_tiling.h. Generally, the more space you allocate, the better performance you will achieve, | ||
| 1458 | - * and the performance reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it | ||
| 1459 | - * is not guaranteed that the shared space will be cleared after usage, the data could be anything. | ||
| 1460 | - */ | ||
| 1461 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1462 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const T& src0Scalar, const LocalTensor<T>& src1Tensor, | ||
| 1463 | - const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 1464 | -{ | ||
| 1465 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Scalar, src1Tensor, sharedTmpBuffer, src1Tensor.GetSize()); | ||
| 1466 | -} | ||
| 1467 | - | ||
| 1468 | -/*! | ||
| 1469 | - * \ingroup Power | ||
| 1470 | - * \brief compute Power elementwisely. | ||
| 1471 | - * \tparam T: input dataType, support half/float | ||
| 1472 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 1473 | - * not enabled currently. | ||
| 1474 | - * \param [out] dstTensor: output LocalTensor | ||
| 1475 | - * \param [in] src0Scalar: base Scalar | ||
| 1476 | - * \param [in] src1Tensor: exponent LocalTensor | ||
| 1477 | - */ | ||
| 1478 | -template <typename T, bool isReuseSource = false, const PowerConfig& config = defaultPowerConfig> | ||
| 1479 | -__aicore__ inline void Power(const LocalTensor<T>& dstTensor, const T& src0Scalar, const LocalTensor<T>& src1Tensor) | ||
| 1480 | -{ | ||
| 1481 | - PowerCommonImpl<T, isReuseSource, config>(dstTensor, src0Scalar, src1Tensor, src1Tensor.GetSize()); | ||
| 1482 | -} | ||
| 1483 | -} //namesapce AscendC | ||
| 1484 | - | ||
Dimpl/adv_api/detail/math/sign/sign_l300_impl.h+0-89
| @@ -1,89 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file sign_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace SignInternal { | ||
| 23 | -template <typename T, typename RegT, const MicroAPI::RegTrait& trait = MicroAPI::RegTraitNumOne> | ||
| 24 | -__simd_vf__ inline void SignCoreCompute(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t calCount, uint16_t repeatTime, uint32_t vlSize) | ||
| 25 | -{ | ||
| 26 | - MicroAPI::MaskReg signMask; | ||
| 27 | - MicroAPI::MaskReg cmpMask0; | ||
| 28 | - MicroAPI::MaskReg cmpMask1; | ||
| 29 | - RegT brcZeroReg; | ||
| 30 | - RegT brcOneReg; | ||
| 31 | - RegT brcNegOneReg; | ||
| 32 | - RegT srcReg; | ||
| 33 | - RegT selReg0; | ||
| 34 | - RegT selReg1; | ||
| 35 | - MicroAPI::Duplicate(brcZeroReg, 0); | ||
| 36 | - MicroAPI::Duplicate(brcOneReg, 1); | ||
| 37 | - MicroAPI::Duplicate(brcNegOneReg, -1); | ||
| 38 | - for (uint16_t i = 0; i < repeatTime; ++i) { | ||
| 39 | - signMask = MicroAPI::UpdateMask<T, trait>(calCount); | ||
| 40 | - MicroAPI::DataCopy(srcReg, srcUb + i * vlSize); | ||
| 41 | - MicroAPI::CompareScalar<T, CMPMODE::LT>(cmpMask0, srcReg, 0, signMask); | ||
| 42 | - MicroAPI::CompareScalar<T, CMPMODE::GT>(cmpMask1, srcReg, 0, signMask); | ||
| 43 | - MicroAPI::Select(selReg0, brcNegOneReg, brcZeroReg, cmpMask0); | ||
| 44 | - MicroAPI::Select(selReg1, brcOneReg, selReg0, cmpMask1); | ||
| 45 | - MicroAPI::DataCopy(dstUb + i * vlSize, selReg1, signMask); | ||
| 46 | - } | ||
| 47 | -} | ||
| 48 | -} // namespace SignInternal | ||
| 49 | - | ||
| 50 | -template <typename T, bool isReuseSource = false> | ||
| 51 | -__aicore__ inline void SignCompute(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 52 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 53 | -{ | ||
| 54 | - // Only for AI Vector Core. | ||
| 55 | - if ASCEND_IS_AIC { | ||
| 56 | - return; | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 60 | - SignCompute<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 61 | -} | ||
| 62 | - | ||
| 63 | -template <typename T, bool isReuseSource = false> | ||
| 64 | -__aicore__ inline void SignCompute(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 65 | - const uint32_t calCount) | ||
| 66 | -{ | ||
| 67 | - static_assert(SupportType<T, half, float, int64_t>(), "Sign only support half/float/int64_t data type on current device!"); | ||
| 68 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 69 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 70 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Sign"); | ||
| 71 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Sign"); | ||
| 72 | - constexpr uint32_t SIGN_B64_REPEAT_STRIDE = 2; | ||
| 73 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 74 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 75 | - if constexpr (sizeof(T) == 8) { | ||
| 76 | - using RegT = MicroAPI::RegTensor<T, MicroAPI::RegTraitNumTwo>; | ||
| 77 | - constexpr int32_t vlSize = static_cast<int32_t>(GetVecLen() / sizeof(T) * SIGN_B64_REPEAT_STRIDE); | ||
| 78 | - uint16_t repeatTime = static_cast<uint16_t>(CeilDivision(calCount, vlSize)); | ||
| 79 | - SignInternal::SignCoreCompute<T, RegT, MicroAPI::RegTraitNumTwo>(dstUb, srcUb, calCount, repeatTime, vlSize); | ||
| 80 | - } else { | ||
| 81 | - using RegT = MicroAPI::RegTensor<T>; | ||
| 82 | - constexpr int32_t vlSize = static_cast<int32_t>(GetVecLen() / sizeof(T)); | ||
| 83 | - uint16_t repeatTime = static_cast<uint16_t>(CeilDivision(calCount, vlSize)); | ||
| 84 | - SignInternal::SignCoreCompute<T, RegT>(dstUb, srcUb, calCount, repeatTime, vlSize); | ||
| 85 | - } | ||
| 86 | -} | ||
| 87 | -} // namespace AscendC | ||
| 88 | - | ||
| 89 | - | ||
Dimpl/adv_api/detail/math/sin/sin_l300_impl.h+0-298
| @@ -1,298 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file sin_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace MicroAPI { | ||
| 24 | -namespace Sin { | ||
| 25 | -const uint8_t SIN_FLOAT_NOREUSE_CALC_PROCEDURE = 3; | ||
| 26 | -const uint8_t SIN_FLOAT_REUSE_CALC_PROCEDURE = 2; | ||
| 27 | - | ||
| 28 | -// define the number of x div pi | ||
| 29 | -constexpr float SIN_PI_FOR_X_TODIV = 0.3183098733425140380859375; | ||
| 30 | -// define the PI for compute | ||
| 31 | -constexpr float SIN_PI_V2 = 3.140625; | ||
| 32 | -constexpr float SIN_KPI_FIRS_PI_MULS = 0.0009670257568359375; | ||
| 33 | -constexpr float SIN_KPI_TWI_PI_MULS = 6.2771141529083251953125e-7; | ||
| 34 | -constexpr float SIN_KPI_THIR_PI_MULS = 1.21644916362129151821136474609375e-10; | ||
| 35 | -// define the number of sin compute | ||
| 36 | -constexpr float SIN_RES_MULIT_SCA = 2.604926501e-6; | ||
| 37 | -constexpr float SIN_RES_ADDICT_UP = -0.0001980894471; | ||
| 38 | -constexpr float SIN_2ADDS = 0.008333049340; | ||
| 39 | -constexpr float SIN_3ADDS = -0.1666665792; | ||
| 40 | -constexpr float SIN_POINT_FIVE = 0.5; | ||
| 41 | -constexpr float SIN_M4_SCA = 4.0; | ||
| 42 | -constexpr float SIN_K2_SCA = -2.0; | ||
| 43 | -constexpr float SIN_SCALAR_ONE = 1.0; | ||
| 44 | -constexpr MicroAPI::CastTrait sinCastTraitF16F32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, | ||
| 45 | - MicroAPI::MaskMergeMode::ZEROING }; | ||
| 46 | -constexpr MicroAPI::CastTrait sinCastTraitF32F16 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 47 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT }; | ||
| 48 | - | ||
| 49 | -__simd_callee__ inline void SinPolynomialApproximation(MicroAPI::RegTensor<float> &dstReg, | ||
| 50 | - MicroAPI::RegTensor<float> &srcReg, MicroAPI::RegTensor<float> &x, MicroAPI::RegTensor<float> &round, | ||
| 51 | - MicroAPI::RegTensor<float> &kpi, MicroAPI::MaskReg mask) | ||
| 52 | -{ | ||
| 53 | - // normalized x to [-π/2, π/2] using x = x-round(x/π)*π | ||
| 54 | - // k = round(x * invpi) | ||
| 55 | - MicroAPI::Muls(round, srcReg, SIN_PI_FOR_X_TODIV, mask); | ||
| 56 | - MicroAPI::Truncate<float, RoundMode::CAST_RINT, MicroAPI::MaskMergeMode::ZEROING>(round, round, mask); | ||
| 57 | - // x -= k * pi_0 | ||
| 58 | - MicroAPI::Muls(kpi, round, SIN_PI_V2, mask); | ||
| 59 | - MicroAPI::Sub(x, srcReg, kpi, mask); | ||
| 60 | - // x -= k * pi_1 | ||
| 61 | - MicroAPI::Muls(kpi, round, SIN_KPI_FIRS_PI_MULS, mask); | ||
| 62 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 63 | - // x -= k * pi_2 | ||
| 64 | - MicroAPI::Muls(kpi, round, SIN_KPI_TWI_PI_MULS, mask); | ||
| 65 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 66 | - // x -= k * pi_3 | ||
| 67 | - MicroAPI::Muls(kpi, round, SIN_KPI_THIR_PI_MULS, mask); | ||
| 68 | - MicroAPI::Sub(x, x, kpi, mask); | ||
| 69 | - | ||
| 70 | - /* | ||
| 71 | - sin(x) = (-1)^k*sin(x0) | ||
| 72 | - Finally, use sin(x) = xP(x) to calculate sin(x). | ||
| 73 | - P(x) = (((x^2 * R0 + R1) * x^2 + R2) * x^2 + R3) * x^2 + 1.0 | ||
| 74 | - */ | ||
| 75 | - // x^2 = mul(input_x, input_x) | ||
| 76 | - MicroAPI::Mul(kpi, x, x, mask); | ||
| 77 | - // kover2 | ||
| 78 | - MicroAPI::Muls(dstReg, round, SIN_POINT_FIVE, mask); | ||
| 79 | - MicroAPI::Truncate<float, RoundMode::CAST_FLOOR, MicroAPI::MaskMergeMode::ZEROING>(dstReg, dstReg, mask); | ||
| 80 | - // kover2floorm4 | ||
| 81 | - MicroAPI::Muls(dstReg, dstReg, SIN_M4_SCA, mask); | ||
| 82 | - // k2 | ||
| 83 | - MicroAPI::Muls(round, round, SIN_K2_SCA, mask); | ||
| 84 | - // sign | ||
| 85 | - MicroAPI::Add(dstReg, dstReg, round, mask); | ||
| 86 | - MicroAPI::Adds(dstReg, dstReg, SIN_SCALAR_ONE, mask); | ||
| 87 | - // res_up = mul(x^2, 2.604926501e-6) | ||
| 88 | - MicroAPI::Muls(round, kpi, SIN_RES_MULIT_SCA, mask); | ||
| 89 | - MicroAPI::Adds(round, round, SIN_RES_ADDICT_UP, mask); | ||
| 90 | - // res_up = mul(res_up, x^2) | ||
| 91 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 92 | - MicroAPI::Adds(round, round, SIN_2ADDS, mask); | ||
| 93 | - // res_up = mul(res_up, x^2) | ||
| 94 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 95 | - MicroAPI::Adds(round, round, SIN_3ADDS, mask); | ||
| 96 | - // res_up = mul(res_up, x^2) | ||
| 97 | - MicroAPI::Mul(round, round, kpi, mask); | ||
| 98 | - MicroAPI::Adds(round, round, SIN_SCALAR_ONE, mask); | ||
| 99 | - // res_up = mul(res_up, input_x) | ||
| 100 | - MicroAPI::Mul(round, round, x, mask); | ||
| 101 | - MicroAPI::Mul(dstReg, round, dstReg, mask); | ||
| 102 | -} | ||
| 103 | - | ||
| 104 | -template <typename T> | ||
| 105 | -__simd_vf__ inline void SinPolynomial(__ubuf__ T *dst, __ubuf__ T *src, uint32_t calCount, uint16_t repeat) | ||
| 106 | -{ | ||
| 107 | - MicroAPI::RegTensor<T> x; | ||
| 108 | - MicroAPI::RegTensor<float> xTmp; | ||
| 109 | - MicroAPI::RegTensor<float> round; | ||
| 110 | - MicroAPI::RegTensor<float> kpi; | ||
| 111 | - MicroAPI::RegTensor<T> srcReg; | ||
| 112 | - MicroAPI::RegTensor<float> srcTmp; | ||
| 113 | - MicroAPI::RegTensor<T> dstReg; | ||
| 114 | - MicroAPI::RegTensor<float> dstTmp; | ||
| 115 | - MicroAPI::MaskReg mask; | ||
| 116 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 117 | - MicroAPI::MaskReg maskAll = MicroAPI::CreateMask<uint8_t>(); | ||
| 118 | - for (uint16_t i = 0; i < (uint16_t)repeat; i++) { | ||
| 119 | - mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 120 | - if constexpr (std::is_same<T, half>::value) { | ||
| 121 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, src + i * oneRepSize); | ||
| 122 | - MicroAPI::Cast<float, half, sinCastTraitF16F32>(srcTmp, srcReg, mask); | ||
| 123 | - SinPolynomialApproximation(dstTmp, srcTmp, xTmp, round, kpi, mask); | ||
| 124 | - MicroAPI::Cast<half, float, sinCastTraitF32F16>(dstReg, dstTmp, mask); | ||
| 125 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * oneRepSize, dstReg, mask); | ||
| 126 | - } else { | ||
| 127 | - MicroAPI::DataCopy(srcReg, src + i * oneRepSize); | ||
| 128 | - SinPolynomialApproximation(dstReg, srcReg, xTmp, round, kpi, mask); | ||
| 129 | - MicroAPI::DataCopy(dst + i * oneRepSize, dstReg, mask); | ||
| 130 | - } | ||
| 131 | - } | ||
| 132 | -} | ||
| 133 | - | ||
| 134 | -template <typename T> __aicore__ inline void SinPolynomialImpl(__ubuf__ T *dst, __ubuf__ T *src, uint32_t calCount) | ||
| 135 | -{ | ||
| 136 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 137 | - uint16_t repeat = CeilDivision(calCount, oneRepSize); | ||
| 138 | - SinPolynomial<T>(dst, src, calCount, repeat); | ||
| 139 | -} | ||
| 140 | -} // namespace MicroAPI | ||
| 141 | -} // namespace Sin | ||
| 142 | - | ||
| 143 | -__aicore__ inline constexpr uint32_t GetSinTmpBufferLiveNode() { | ||
| 144 | - constexpr uint32_t tmpBufferLiveNode = sizeof(float) * 2; | ||
| 145 | - return tmpBufferLiveNode; | ||
| 146 | -} | ||
| 147 | - | ||
| 148 | -template <typename T, bool isReuseSource = false, const SinConfig& config = defaultSinConfig> | ||
| 149 | -__aicore__ inline void SinImpl( | ||
| 150 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 151 | -{ | ||
| 152 | - // Only for AI Vector Core. | ||
| 153 | - if ASCEND_IS_AIC { | ||
| 154 | - return; | ||
| 155 | - } | ||
| 156 | - | ||
| 157 | - // Using the Stack Space to Allocate tmpBuffer | ||
| 158 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 159 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(sharedTmpBuffer); | ||
| 160 | - ASCENDC_ASSERT((ans), { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 161 | - SinImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 162 | -} | ||
| 163 | - | ||
| 164 | -template<typename T> | ||
| 165 | -__aicore__ inline uint32_t GetSinTmpBufferSize(const LocalTensor<uint8_t>& sharedTmpBuffer) { | ||
| 166 | - uint32_t sharedTmpBufferSize = sharedTmpBuffer.GetSize() / GetSinTmpBufferLiveNode(); | ||
| 167 | - return AlignUp(sharedTmpBufferSize, GetDataBlockSizeInBytes()) / sizeof(T); | ||
| 168 | -} | ||
| 169 | - | ||
| 170 | -template <typename T, bool isReuseSource = false, const SinConfig &config = defaultSinConfig> | ||
| 171 | -__aicore__ inline void SinImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 172 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 173 | -{ | ||
| 174 | - // Only for AI Vector Core. | ||
| 175 | - if ASCEND_IS_AIC { | ||
| 176 | - return; | ||
| 177 | - } | ||
| 178 | - | ||
| 179 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 180 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Sin"); | ||
| 181 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Sin"); | ||
| 182 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Sin"); | ||
| 183 | - ASCENDC_ASSERT((calCount <= srcTensor.GetSize()), { | ||
| 184 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than srcTensor length %u", calCount, | ||
| 185 | - srcTensor.GetSize()); | ||
| 186 | - }); | ||
| 187 | - ASCENDC_ASSERT((calCount <= dstTensor.GetSize()), { | ||
| 188 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should not be larger than dstTensor length %u", calCount, | ||
| 189 | - dstTensor.GetSize()); | ||
| 190 | - }); | ||
| 191 | - | ||
| 192 | - if constexpr (config.algo == SinAlgo::POLYNOMIAL_APPROXIMATION) { | ||
| 193 | - MicroAPI::Sin::SinPolynomialImpl((__ubuf__ T *)dstTensor.GetPhyAddr(), | ||
| 194 | - (__ubuf__ T *)srcTensor.GetPhyAddr(), calCount); | ||
| 195 | - } else if constexpr (config.algo == SinAlgo::RADIAN_REDUCTION) { | ||
| 196 | - uint32_t sharedTmpBufferSize = GetSinTmpBufferSize<T>(sharedTmpBuffer); | ||
| 197 | - uint32_t count = calCount; | ||
| 198 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, sharedTmpBufferSize)); | ||
| 199 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 200 | - uint32_t remainCount = count - sharedTmpBufferSize * i; | ||
| 201 | - uint32_t oneRepSize = remainCount < sharedTmpBufferSize ? remainCount : sharedTmpBufferSize; | ||
| 202 | - SinRadianReductionImpl((__ubuf__ T*)dstTensor.GetPhyAddr() + i * sharedTmpBufferSize, | ||
| 203 | - (__ubuf__ T*)srcTensor.GetPhyAddr() + i * sharedTmpBufferSize, | ||
| 204 | - (__ubuf__ uint32_t*)sharedTmpBuffer.GetPhyAddr(), oneRepSize); | ||
| 205 | - } | ||
| 206 | - } | ||
| 207 | -} | ||
| 208 | - | ||
| 209 | -__aicore__ inline void SinCastFullMask( | ||
| 210 | - const LocalTensor<float>& dstTensor, const LocalTensor<float>& srcTensor, RoundMode castType) | ||
| 211 | -{ | ||
| 212 | - uint64_t newMask = 64; | ||
| 213 | - Cast<float, float, false>(dstTensor, srcTensor, castType, newMask, 1, | ||
| 214 | - { 1, 1, DEFAULT_REPEAT_STRIDE, DEFAULT_REPEAT_STRIDE }); | ||
| 215 | - PipeBarrier<PIPE_V>(); | ||
| 216 | -} | ||
| 217 | - | ||
| 218 | - /*! | ||
| 219 | - * \ingroup Sin | ||
| 220 | - * \brief compute Sin elementwisely | ||
| 221 | - * \tparam T: half/float | ||
| 222 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, only support | ||
| 223 | - * float input data type | ||
| 224 | - * \param [out] dstTensor: output LocalTensor | ||
| 225 | - * \param [in] srcTensor: input LocalTensor | ||
| 226 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 227 | - * whose required space size should refer to corresponding tiling API, which is defined at sin_tiling.h. | ||
| 228 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 229 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 230 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 231 | - * \param [in] calCount: the number of elements to be processed. | ||
| 232 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 233 | - * Input data valid range should be [-65504, 65504] | ||
| 234 | - */ | ||
| 235 | -template<typename T, bool isReuseSource = false, const SinConfig &config = defaultSinConfig> | ||
| 236 | -__aicore__ inline void Sin(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 237 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 238 | -{ | ||
| 239 | - SinImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 240 | -} | ||
| 241 | - | ||
| 242 | - /*! | ||
| 243 | - * \ingroup Sin | ||
| 244 | - * \brief compute Sin elementwisely | ||
| 245 | - * \tparam T: half/float | ||
| 246 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 247 | - * \param [out] dstTensor: output LocalTensor | ||
| 248 | - * \param [in] srcTensor: input LocalTensor | ||
| 249 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 250 | - * whose required space size should refer to corresponding tiling API, which is defined at sin_tiling.h. | ||
| 251 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 252 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 253 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 254 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 255 | - * Input data valid range should be [-65504, 65504] | ||
| 256 | - */ | ||
| 257 | -template<typename T, bool isReuseSource = false, const SinConfig &config = defaultSinConfig> | ||
| 258 | -__aicore__ inline void Sin(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 259 | - const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 260 | -{ | ||
| 261 | - Sin<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, srcTensor.GetSize()); | ||
| 262 | -} | ||
| 263 | - | ||
| 264 | - /*! | ||
| 265 | - * \ingroup Sin | ||
| 266 | - * \brief compute Sin elementwisely | ||
| 267 | - * \tparam T: half/float | ||
| 268 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 269 | - * \param [out] dstTensor: output LocalTensor | ||
| 270 | - * \param [in] srcTensor: input LocalTensor | ||
| 271 | - * \param [in] calCount: the number of elements to be processed. | ||
| 272 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 273 | - * Input data valid range should be [-65504, 65504] | ||
| 274 | - */ | ||
| 275 | -template<typename T, bool isReuseSource = false, const SinConfig &config = defaultSinConfig> | ||
| 276 | -__aicore__ inline void Sin(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 277 | - const uint32_t calCount) | ||
| 278 | -{ | ||
| 279 | - SinImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 280 | -} | ||
| 281 | - | ||
| 282 | - /*! | ||
| 283 | - * \ingroup Sin | ||
| 284 | - * \brief compute Sin elementwisely | ||
| 285 | - * \tparam T: half/float | ||
| 286 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason | ||
| 287 | - * \param [out] dstTensor: output LocalTensor | ||
| 288 | - * \param [in] srcTensor: input LocalTensor | ||
| 289 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 290 | - * Input data valid range should be [-65504, 65504] | ||
| 291 | - */ | ||
| 292 | -template<typename T, bool isReuseSource = false, const SinConfig &config = defaultSinConfig> | ||
| 293 | -__aicore__ inline void Sin(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor) | ||
| 294 | -{ | ||
| 295 | - Sin<T, isReuseSource, config>(dstTensor, srcTensor, srcTensor.GetSize()); | ||
| 296 | -} | ||
| 297 | -} | ||
| 298 | - | ||
Dimpl/adv_api/detail/math/sincos/sincos_l300_impl.h+0-760
| @@ -1,760 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file sincos_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | -namespace AscendC { | ||
| 20 | -struct SinCosConfig { | ||
| 21 | - bool isReuseSource; | ||
| 22 | -}; | ||
| 23 | -constexpr SinCosConfig DEFAULT_SINCOS_CONFIG = { false }; | ||
| 24 | -namespace SinCosImpl { | ||
| 25 | - | ||
| 26 | -constexpr MicroAPI::CastTrait castTraitF16F32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, | ||
| 27 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN }; | ||
| 28 | -constexpr MicroAPI::CastTrait castTraitF32F16 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 29 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT }; | ||
| 30 | -constexpr MicroAPI::CastTrait castTraitI64F32 = { MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, | ||
| 31 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 32 | -constexpr MicroAPI::CastTrait castTraitF32I64 = { MicroAPI::RegLayout::UNKNOWN, MicroAPI::SatMode::NO_SAT, | ||
| 33 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 34 | -constexpr MicroAPI::CastTrait castTraitI32F32 = { MicroAPI::RegLayout::UNKNOWN, MicroAPI::SatMode::NO_SAT, | ||
| 35 | - MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_ROUND }; | ||
| 36 | - | ||
| 37 | -template <typename T, typename U> | ||
| 38 | -__simd_callee__ inline void AndScalar(MicroAPI::RegTensor<T> &dstReg, MicroAPI::RegTensor<U> &srcReg, | ||
| 39 | - T val, MicroAPI::MaskReg& mask) | ||
| 40 | -{ | ||
| 41 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 42 | - MicroAPI::Duplicate(tmpReg, val, mask); | ||
| 43 | - MicroAPI::And(dstReg, (MicroAPI::RegTensor<T>&)srcReg, tmpReg, mask); | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg, | ||
| 47 | - float scalarValue, MicroAPI::MaskReg& mask) | ||
| 48 | -{ | ||
| 49 | - // dst = dst * src + scalarValue | ||
| 50 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 51 | - MicroAPI::Duplicate(tmpReg, scalarValue); | ||
| 52 | - MicroAPI::FusedMulDstAdd(dstReg, srcReg, tmpReg, mask); | ||
| 53 | -} | ||
| 54 | - | ||
| 55 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 56 | - MicroAPI::RegTensor<float>& srcReg2, MicroAPI::RegTensor<float>& srcReg3, MicroAPI::MaskReg& mask) | ||
| 57 | -{ | ||
| 58 | - // dst = src1 * src2 + src3 | ||
| 59 | - MicroAPI::RegTensor<float> tmpReg = srcReg1; | ||
| 60 | - MicroAPI::FusedMulDstAdd(tmpReg, srcReg2, srcReg3, mask); | ||
| 61 | - dstReg = tmpReg; | ||
| 62 | -} | ||
| 63 | - | ||
| 64 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 65 | - MicroAPI::RegTensor<float>& srcReg2, float scalarValue, MicroAPI::MaskReg& mask) | ||
| 66 | -{ | ||
| 67 | - // dst = src1 * src2 + scalerValue | ||
| 68 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 69 | - MicroAPI::Duplicate(tmpReg, scalarValue, mask); | ||
| 70 | - FMaf(dstReg, srcReg1, srcReg2, tmpReg, mask); | ||
| 71 | -} | ||
| 72 | - | ||
| 73 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 74 | - float scalarValue, MicroAPI::RegTensor<float>& srcReg2, MicroAPI::MaskReg& mask) | ||
| 75 | -{ | ||
| 76 | - // dst = src1 * scalarValue + src2 | ||
| 77 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 78 | - MicroAPI::Duplicate(tmpReg, scalarValue, mask); | ||
| 79 | - FMaf(dstReg, srcReg1, tmpReg, srcReg2, mask); | ||
| 80 | -} | ||
| 81 | - | ||
| 82 | -__simd_callee__ inline void FMaf(MicroAPI::RegTensor<float>& dstReg, MicroAPI::RegTensor<float>& srcReg1, | ||
| 83 | - float scalarValue, float scalarValue2, MicroAPI::MaskReg& mask) | ||
| 84 | -{ | ||
| 85 | - // dst = src1 * scalarValue + scalarValue2 | ||
| 86 | - MicroAPI::RegTensor<float> tmpReg, tmpReg2; | ||
| 87 | - MicroAPI::Duplicate(tmpReg, scalarValue, mask); | ||
| 88 | - MicroAPI::Duplicate(tmpReg2, scalarValue2, mask); | ||
| 89 | - FMaf(dstReg, srcReg1, tmpReg, tmpReg2, mask); | ||
| 90 | -} | ||
| 91 | - | ||
| 92 | -__simd_callee__ inline void BitShiftCombine(MicroAPI::RegTensor<uint32_t> &dstReg, MicroAPI::RegTensor<uint32_t> &srcReg1, | ||
| 93 | - MicroAPI::RegTensor<uint32_t> &srcReg2, MicroAPI::RegTensor<int32_t> &srcRegE, MicroAPI::MaskReg& mask) | ||
| 94 | -{ | ||
| 95 | - // dst = (src1 << e) | (src2 >> (32 - e)); | ||
| 96 | - constexpr uint32_t BITSHIFTS = 32; | ||
| 97 | - | ||
| 98 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg1, tmpU32Reg2; | ||
| 99 | - MicroAPI::ShiftLeft(tmpU32Reg1, srcReg1, (MicroAPI::RegTensor<int32_t>&)srcRegE, mask); | ||
| 100 | - MicroAPI::Duplicate(tmpU32Reg2, BITSHIFTS, mask); | ||
| 101 | - MicroAPI::Sub(tmpU32Reg2, tmpU32Reg2, (MicroAPI::RegTensor<uint32_t>&)srcRegE, mask); | ||
| 102 | - MicroAPI::ShiftRight(tmpU32Reg2, srcReg2, (MicroAPI::RegTensor<int32_t>&)tmpU32Reg2, mask); | ||
| 103 | - MicroAPI::Or(dstReg, tmpU32Reg1, tmpU32Reg2, mask); | ||
| 104 | -} | ||
| 105 | - | ||
| 106 | -__aicore__ inline void GenerateZeroVreg(MicroAPI::RegTensor<uint32_t>& zeroReg) | ||
| 107 | -{ | ||
| 108 | - MicroAPI::MaskReg b32FullMask = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 109 | - MicroAPI::Duplicate(zeroReg, 0, b32FullMask); | ||
| 110 | -} | ||
| 111 | - | ||
| 112 | -__simd_callee__ inline void ReinterpretedU32ToFloatAndCastToU32(MicroAPI::RegTensor<uint32_t> &dstReg, | ||
| 113 | - MicroAPI::RegTensor<uint32_t> &srcReg, MicroAPI::MaskReg &mask) | ||
| 114 | -{ | ||
| 115 | - // dst = (unsigned int) reinterpret_cast<float &>(src); | ||
| 116 | - MicroAPI::RegTensor<float> tmpF32Reg; | ||
| 117 | - MicroAPI::RegTensor<int64_t, MicroAPI::RegTraitNumTwo> tmpI64Reg; | ||
| 118 | - | ||
| 119 | - tmpF32Reg = (MicroAPI::RegTensor<float>&)srcReg; | ||
| 120 | - MicroAPI::Cast<int64_t, float, castTraitF32I64>(tmpI64Reg, tmpF32Reg, mask); | ||
| 121 | - dstReg = (MicroAPI::RegTensor<uint32_t>&)tmpI64Reg.reg[0]; | ||
| 122 | -} | ||
| 123 | - | ||
| 124 | -__simd_callee__ inline void TrigComputeP(MicroAPI::RegTensor<uint32_t> ®PHigh, MicroAPI::RegTensor<uint32_t> ®PLow, | ||
| 125 | - MicroAPI::RegTensor<uint32_t> ®Ia, MicroAPI::RegTensor<uint32_t> ®Mid, MicroAPI::RegTensor<uint32_t> ®Lo, | ||
| 126 | - MicroAPI::RegTensor<uint32_t> ®Hi, MicroAPI::MaskReg &mask) | ||
| 127 | -{ | ||
| 128 | - MicroAPI::RegTensor<uint64_t, MicroAPI::RegTraitNumTwo> tmpU64Reg; | ||
| 129 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg, zeroReg; | ||
| 130 | - MicroAPI::MaskReg carrypMask; | ||
| 131 | - | ||
| 132 | - // step 12: p = (unsigned long long int)ia * lo; | ||
| 133 | - MicroAPI::Mull((MicroAPI::RegTensor<uint32_t>&)regPLow, | ||
| 134 | - (MicroAPI::RegTensor<uint32_t>&)regPHigh, regIa, regLo, mask); | ||
| 135 | - | ||
| 136 | - // step 13: p = (unsigned long long int)ia * mid + (p >> 32); | ||
| 137 | - MicroAPI::Mull((MicroAPI::RegTensor<uint32_t>&)tmpU64Reg.reg[0], | ||
| 138 | - (MicroAPI::RegTensor<uint32_t>&)tmpU64Reg.reg[1], regIa, regMid, mask); | ||
| 139 | - | ||
| 140 | - MicroAPI::AddCarryOut(carrypMask, (MicroAPI::RegTensor<uint32_t>&)regPLow, | ||
| 141 | - (MicroAPI::RegTensor<uint32_t>&)tmpU64Reg.reg[0], (MicroAPI::RegTensor<uint32_t>&)regPHigh, mask); | ||
| 142 | - MicroAPI::Duplicate(zeroReg, 0, mask); | ||
| 143 | - MicroAPI::AddCarryOuts(carrypMask, (MicroAPI::RegTensor<uint32_t>&)regPHigh, | ||
| 144 | - (MicroAPI::RegTensor<uint32_t>&)tmpU64Reg.reg[1], zeroReg, carrypMask, mask); | ||
| 145 | - | ||
| 146 | - // step 14: p = ((unsigned long long int)(ia * hi) << 32) + p; | ||
| 147 | - MicroAPI::Mul(tmpU32Reg, regIa, regHi, mask); | ||
| 148 | - MicroAPI::AddCarryOut(carrypMask, (MicroAPI::RegTensor<uint32_t>&)regPHigh, | ||
| 149 | - (MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpU32Reg, mask); | ||
| 150 | -} | ||
| 151 | - | ||
| 152 | -__simd_callee__ inline void TrigComputeHLQ(MicroAPI::RegTensor<float> ®Dh, MicroAPI::RegTensor<float> ®Dl, | ||
| 153 | - MicroAPI::RegTensor<int32_t> ®Q, MicroAPI::RegTensor<uint32_t> ®PHigh, MicroAPI::RegTensor<uint32_t> ®PLow, | ||
| 154 | - MicroAPI::MaskReg &mask) | ||
| 155 | -{ | ||
| 156 | - constexpr int16_t Q_SHIFT_BITS = 62; | ||
| 157 | - constexpr int16_t B32_BITS = 32; | ||
| 158 | - constexpr uint64_t P_AND_COEFF1 = 0x3fffffffffffffffULL; | ||
| 159 | - constexpr uint64_t P_AND_COEFF2 = 0x2000000000000000ULL; | ||
| 160 | - constexpr uint64_t P_SUBS_COEFF = 0x4000000000000000ULL; | ||
| 161 | - constexpr float P_MULS = 2.0f; | ||
| 162 | - | ||
| 163 | - constexpr float B64_SHIFT_BITS = static_cast<float>(1ULL << 32); | ||
| 164 | - | ||
| 165 | - constexpr uint64_t B64_SHIFT_BITS = 1ULL << 32; | ||
| 166 | - | ||
| 167 | - | ||
| 168 | - MicroAPI::RegTensor<int64_t, MicroAPI::RegTraitNumTwo> tmpI64Reg; | ||
| 169 | - MicroAPI::RegTensor<int32_t> tmpRegQ; | ||
| 170 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg; | ||
| 171 | - MicroAPI::MaskReg tmpMask; | ||
| 172 | - | ||
| 173 | - // step 15: q = (int)(p >> 62); | ||
| 174 | - MicroAPI::ShiftRights((MicroAPI::RegTensor<uint32_t>&)regQ, | ||
| 175 | - (MicroAPI::RegTensor<uint32_t>&)regPHigh, (int16_t)(Q_SHIFT_BITS - B32_BITS), mask); | ||
| 176 | - | ||
| 177 | - // step 16: p = p & 0x3fffffffffffffffULL; | ||
| 178 | - MicroAPI::Duplicate(tmpU32Reg, P_AND_COEFF1 >> B32_BITS, mask); | ||
| 179 | - MicroAPI::And((MicroAPI::RegTensor<uint32_t>&)regPHigh, | ||
| 180 | - (MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpU32Reg, mask); | ||
| 181 | - | ||
| 182 | - /* step 17: | ||
| 183 | - * if (p & 0x2000000000000000ULL) { // fraction >= 0.5 | ||
| 184 | - * p = p - 0x4000000000000000ULL; // fraction - 1.0 | ||
| 185 | - * q = q + 1; | ||
| 186 | - * } | ||
| 187 | - */ | ||
| 188 | - MicroAPI::Duplicate(tmpU32Reg, P_AND_COEFF2 >> B32_BITS, mask); | ||
| 189 | - MicroAPI::And(tmpU32Reg, (MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpU32Reg, mask); | ||
| 190 | - MicroAPI::CompareScalar<uint32_t, CMPMODE::GT>(tmpMask, tmpU32Reg, 0, mask); | ||
| 191 | - MicroAPI::Duplicate(tmpU32Reg, P_SUBS_COEFF >> B32_BITS, mask); | ||
| 192 | - MicroAPI::Sub(tmpU32Reg, (MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpU32Reg, mask); | ||
| 193 | - MicroAPI::Select((MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpU32Reg, | ||
| 194 | - (MicroAPI::RegTensor<uint32_t>&)regPHigh, tmpMask); | ||
| 195 | - MicroAPI::Adds(tmpRegQ, regQ, 1, mask); | ||
| 196 | - MicroAPI::Select(regQ, tmpRegQ, regQ, tmpMask); | ||
| 197 | - | ||
| 198 | - /* compute remainder of x / (pi/2) */ | ||
| 199 | - // step 18: float d_h, d_l; | ||
| 200 | - // step 19: long long int P = (long long int)p; | ||
| 201 | - MicroAPI::RegTensor<float> tmpRegDH, tmpRegDL, tmpF32Reg; | ||
| 202 | - MicroAPI::RegTensor<int32_t> tmpI32Reg, tmpRegPHigh, tmpRegPLow; | ||
| 203 | - MicroAPI::Copy((MicroAPI::RegTensor<uint32_t>&)tmpRegPHigh, regPHigh); | ||
| 204 | - /* | ||
| 205 | - * d_h' = (float)P_high; | ||
| 206 | - * d_l' = (float)(P_low >> 1) * 2; | ||
| 207 | - */ | ||
| 208 | - MicroAPI::Cast<float, int32_t, castTraitI32F32>(tmpRegDH, tmpRegPHigh, mask); | ||
| 209 | - MicroAPI::ShiftRights(tmpU32Reg, regPLow, (int16_t)1, mask); | ||
| 210 | - MicroAPI::Cast<float, int32_t, castTraitI32F32>(tmpRegDL, (MicroAPI::RegTensor<int32_t>&)tmpU32Reg, mask); | ||
| 211 | - MicroAPI::Muls(tmpRegDL, tmpRegDL, P_MULS, mask); | ||
| 212 | - // next: d_l = (float)(P_high - (int)d_h') *(2**32) + (float)P_low | ||
| 213 | - MicroAPI::Cast<int32_t, float, castTraitI32F32>(tmpI32Reg, tmpRegDH, mask); | ||
| 214 | - MicroAPI::Sub(tmpI32Reg, tmpRegPHigh, tmpI32Reg, mask); | ||
| 215 | - MicroAPI::Cast<float, int32_t, castTraitI32F32>(tmpF32Reg, tmpI32Reg, mask); | ||
| 216 | - MicroAPI::Muls(tmpF32Reg, tmpF32Reg, B64_SHIFT_BITS, mask); | ||
| 217 | - MicroAPI::Add(regDl, tmpF32Reg, tmpRegDL, mask); | ||
| 218 | - // then: d_h = d_h' * (2**32) | ||
| 219 | - MicroAPI::Muls(regDh, tmpRegDH, B64_SHIFT_BITS, mask); | ||
| 220 | -} | ||
| 221 | - | ||
| 222 | -__simd_callee__ inline void TrigRedSlowpathFComputeP(MicroAPI::RegTensor<uint32_t> ®PHigh, MicroAPI::RegTensor<uint32_t> ®PLow, | ||
| 223 | - MicroAPI::RegTensor<float> &srcReg, MicroAPI::RegTensor<uint32_t>& oneOverPiFReg, MicroAPI::MaskReg& mask) | ||
| 224 | -{ | ||
| 225 | - constexpr uint32_t TA_AND_COEFF = 0x007fffff; | ||
| 226 | - constexpr uint32_t IA_ADD_COEFF = 0x4f000000; | ||
| 227 | - constexpr int16_t TA_SHIFT_BITS = 23; | ||
| 228 | - constexpr int32_t TA_SHIFT_AND_COEFF = 0x000000ff; | ||
| 229 | - constexpr int16_t I_SHIFT_BITS = 5; | ||
| 230 | - constexpr int32_t E_SUB_COEFF = 126; | ||
| 231 | - constexpr int32_t E_AND_COEFF = 31; | ||
| 232 | - constexpr uint32_t LO_SELECT = 1; | ||
| 233 | - constexpr uint32_t TMP_SELECT = 2; | ||
| 234 | - | ||
| 235 | - MicroAPI::RegTensor<uint32_t> regIa, regHi, regMid, regLo, regTmp, regI; | ||
| 236 | - MicroAPI::RegTensor<int32_t> regE; | ||
| 237 | - MicroAPI::RegTensor<int32_t> tmpI32Reg; | ||
| 238 | - MicroAPI::RegTensor<uint32_t> tmpU32Reg; | ||
| 239 | - | ||
| 240 | - // step 1: unsigned int ta = reinterpret_cast<unsigned int &>(a); | ||
| 241 | - // ta can be obtained by (RegTensor<uint32_t>&)srcReg; | ||
| 242 | - // step 2: ia = (ta&0x007fffff) + 0x4f000000; | ||
| 243 | - AndScalar(regIa, (MicroAPI::RegTensor<uint32_t> &)srcReg, TA_AND_COEFF, mask); | ||
| 244 | - MicroAPI::Adds(regIa, regIa, IA_ADD_COEFF, mask); | ||
| 245 | - | ||
| 246 | - // step 3: ia = (unsigned int) reinterpret_cast<float &>(ia); | ||
| 247 | - ReinterpretedU32ToFloatAndCastToU32(regIa, regIa, mask); | ||
| 248 | - | ||
| 249 | - // step 4: e = ((ta >> 23) & 0x000000ff) - 127; | ||
| 250 | - MicroAPI::ShiftRights(regE, (MicroAPI::RegTensor<int32_t> &)srcReg, TA_SHIFT_BITS, mask); | ||
| 251 | - AndScalar(regE, regE, TA_SHIFT_AND_COEFF, mask); | ||
| 252 | - MicroAPI::Adds(regE, regE, -E_SUB_COEFF, mask); | ||
| 253 | - | ||
| 254 | - // step 5: i = (unsigned int)e >> 5; | ||
| 255 | - MicroAPI::ShiftRights(regI, (MicroAPI::RegTensor<uint32_t>&)regE, I_SHIFT_BITS, mask); | ||
| 256 | - // step 6: e = (unsigned int)e & 31; | ||
| 257 | - MicroAPI::Duplicate(tmpI32Reg, E_AND_COEFF, mask); | ||
| 258 | - MicroAPI::And(regE, (MicroAPI::RegTensor<int32_t>&)regE, tmpI32Reg, mask); | ||
| 259 | - | ||
| 260 | - // step 7:hi = i ? one_over_pi_f [i-1] : 0; | ||
| 261 | - MicroAPI::MaskReg tmpMask; | ||
| 262 | - MicroAPI::RegTensor<uint32_t> tmpRegSelect; | ||
| 263 | - MicroAPI::CompareScalar<uint32_t, CMPMODE::GT>(tmpMask, regI, 0, mask); | ||
| 264 | - MicroAPI::Adds(tmpU32Reg, regI, -1, mask); | ||
| 265 | - MicroAPI::Gather(tmpRegSelect, oneOverPiFReg, tmpU32Reg); | ||
| 266 | - MicroAPI::Duplicate(regHi, 0, mask); | ||
| 267 | - MicroAPI::Select(regHi, tmpRegSelect, regHi, tmpMask); | ||
| 268 | - | ||
| 269 | - // step 8: mid = one_over_pi_f [i+0]; | ||
| 270 | - MicroAPI::Gather(regMid, oneOverPiFReg, regI); | ||
| 271 | - // // step 9: lo = one_over_pi_f [i+1]; | ||
| 272 | - MicroAPI::Adds(tmpU32Reg, regI, LO_SELECT, mask); | ||
| 273 | - MicroAPI::Gather(regLo, oneOverPiFReg, tmpU32Reg); | ||
| 274 | - // step 10: tmp = one_over_pi_f [i+2]; | ||
| 275 | - MicroAPI::Adds(tmpU32Reg, regI, TMP_SELECT, mask); | ||
| 276 | - MicroAPI::Gather(regTmp, oneOverPiFReg, tmpU32Reg); | ||
| 277 | - | ||
| 278 | - /* step 11: | ||
| 279 | - * if(e) { | ||
| 280 | - * hi = (hi << e) | (mid >> (32 - e)); | ||
| 281 | - * mid = (mid << e) | (lo >> (32 - e)); | ||
| 282 | - * lo = (lo << e) | (tmp >> (32 - e)); | ||
| 283 | - * } | ||
| 284 | - */ | ||
| 285 | - MicroAPI::CompareScalar<int32_t, CMPMODE::GT>(tmpMask, regE, 0, mask); | ||
| 286 | - BitShiftCombine(tmpRegSelect, regHi, regMid, regE, mask); | ||
| 287 | - MicroAPI::Select(regHi, tmpRegSelect, regHi, tmpMask); | ||
| 288 | - BitShiftCombine(tmpRegSelect, regMid, regLo, regE, mask); | ||
| 289 | - MicroAPI::Select(regMid, tmpRegSelect, regMid, tmpMask); | ||
| 290 | - BitShiftCombine(tmpRegSelect, regLo, regTmp, regE, mask); | ||
| 291 | - MicroAPI::Select(regLo, tmpRegSelect, regLo, tmpMask); | ||
| 292 | - | ||
| 293 | - TrigComputeP(regPHigh, regPLow, regIa, regMid, regLo, regHi, mask); | ||
| 294 | -} | ||
| 295 | - | ||
| 296 | -__simd_callee__ inline void TrigRedSlowpathFComputeRI(MicroAPI::RegTensor<float> &dstRegR, MicroAPI::RegTensor<int32_t> &dstRegI, | ||
| 297 | - MicroAPI::RegTensor<uint32_t> ®PHigh, MicroAPI::RegTensor<uint32_t> ®PLow, MicroAPI::RegTensor<float> &srcReg, | ||
| 298 | - MicroAPI::MaskReg& mask) | ||
| 299 | -{ | ||
| 300 | - constexpr float R_MUL_COEFF = 3.4061215800865545e-19; | ||
| 301 | - | ||
| 302 | - MicroAPI::RegTensor<int32_t> regQ; | ||
| 303 | - MicroAPI::RegTensor<float> regR, regDh, regDl; | ||
| 304 | - MicroAPI::RegTensor<float> tmpF32Reg; | ||
| 305 | - MicroAPI::RegTensor<int32_t> tmpRegQ; | ||
| 306 | - MicroAPI::MaskReg tmpMask; | ||
| 307 | - | ||
| 308 | - TrigComputeHLQ(regDh, regDl, regQ, regPHigh, regPLow, mask); | ||
| 309 | - | ||
| 310 | - // step 23: r = d_l*3.4061215800865545e-19; | ||
| 311 | - MicroAPI::Muls(regR, regDl, R_MUL_COEFF, mask); | ||
| 312 | - // step 24: r = r + d_h*3.4061215800865545e-19; | ||
| 313 | - MicroAPI::Duplicate(tmpF32Reg, R_MUL_COEFF, mask); | ||
| 314 | - MicroAPI::MulAddDst(regR, regDh, tmpF32Reg, mask); | ||
| 315 | - | ||
| 316 | - /* step 25: | ||
| 317 | - * if (a < 0.0f) { | ||
| 318 | - * r = -r; | ||
| 319 | - * q = -q; | ||
| 320 | - * } | ||
| 321 | - */ | ||
| 322 | - MicroAPI::CompareScalar<float, CMPMODE::LT>(tmpMask, srcReg, 0.0f, mask); | ||
| 323 | - MicroAPI::Neg(tmpF32Reg, regR, mask); | ||
| 324 | - MicroAPI::Select(regR, tmpF32Reg, regR, tmpMask); | ||
| 325 | - MicroAPI::Neg(tmpRegQ, regQ, mask); | ||
| 326 | - MicroAPI::Select(regQ, tmpRegQ, regQ, tmpMask); | ||
| 327 | - | ||
| 328 | - // step 26: *quadrant = q; | ||
| 329 | - dstRegR = regR; | ||
| 330 | - dstRegI = regQ; | ||
| 331 | -} | ||
| 332 | - | ||
| 333 | -__simd_callee__ inline void SinfPoly(MicroAPI::RegTensor<float> &dstReg, MicroAPI::RegTensor<float> &srcRegA, | ||
| 334 | - MicroAPI::RegTensor<float> &srcRegS, MicroAPI::MaskReg& mask) | ||
| 335 | -{ | ||
| 336 | - constexpr float SIN_POLY_COEFF0 = 2.86567956e-6f; | ||
| 337 | - constexpr float SIN_POLY_COEFF1 = -1.98559923e-4f; | ||
| 338 | - constexpr float SIN_POLY_COEFF2 = 8.33338592e-3f; | ||
| 339 | - constexpr float SIN_POLY_COEFF3 = -1.66666672e-1f; | ||
| 340 | - constexpr float SIN_POLY_COEFF5 = 0.0f; | ||
| 341 | - | ||
| 342 | - MicroAPI::RegTensor<float> tmpRegT; | ||
| 343 | - // step 1: r = 2.86567956e-6f; | ||
| 344 | - MicroAPI::Duplicate(dstReg, SIN_POLY_COEFF0, mask); | ||
| 345 | - // step 2: r = r* s+ -1.98559923e-4f; | ||
| 346 | - FMaf(dstReg, srcRegS, SIN_POLY_COEFF1, mask); | ||
| 347 | - // step 3: r = r* s+ 8.33338592e-3f; | ||
| 348 | - FMaf(dstReg, srcRegS, SIN_POLY_COEFF2, mask); | ||
| 349 | - // step 4: r = r* s+ -1.66666672e-1f; | ||
| 350 | - FMaf(dstReg, srcRegS, SIN_POLY_COEFF3, mask); | ||
| 351 | - // step 5: t = a* s+ 0.0f; | ||
| 352 | - FMaf(tmpRegT, srcRegA, srcRegS, SIN_POLY_COEFF5, mask); | ||
| 353 | - // step 6: r = r* t+ a; | ||
| 354 | - MicroAPI::FusedMulDstAdd(dstReg, tmpRegT, srcRegA, mask); | ||
| 355 | -} | ||
| 356 | - | ||
| 357 | -__simd_callee__ inline void CosfPoly(MicroAPI::RegTensor<float> &dstReg, MicroAPI::RegTensor<float> &srcRegS, | ||
| 358 | - MicroAPI::MaskReg& mask) | ||
| 359 | -{ | ||
| 360 | - constexpr float COS_POLY_COEFF0 = 2.44677067e-5f; | ||
| 361 | - constexpr float COS_POLY_COEFF1 = -1.38877297e-3f; | ||
| 362 | - constexpr float COS_POLY_COEFF2 = 4.16666567e-2f; | ||
| 363 | - constexpr float COS_POLY_COEFF3 = -5.00000000e-1f; | ||
| 364 | - constexpr float COS_POLY_COEFF4 = 1.00000000e+0f; | ||
| 365 | - | ||
| 366 | - // step 1: r = 2.44677067e-5f; | ||
| 367 | - MicroAPI::Duplicate(dstReg, COS_POLY_COEFF0, mask); | ||
| 368 | - // step 2: r = r* s+ -1.38877297e-3f; | ||
| 369 | - FMaf(dstReg, srcRegS, COS_POLY_COEFF1, mask); | ||
| 370 | - // step 3: r = r* s+ 4.16666567e-2f; | ||
| 371 | - FMaf(dstReg, srcRegS, COS_POLY_COEFF2, mask); | ||
| 372 | - // step 4: r = r* s+ -5.00000000e-1f; | ||
| 373 | - FMaf(dstReg, srcRegS, COS_POLY_COEFF3, mask); | ||
| 374 | - // step 5: r = r* s+ 1.00000000e+0f; | ||
| 375 | - FMaf(dstReg, srcRegS, COS_POLY_COEFF4, mask); | ||
| 376 | -} | ||
| 377 | - | ||
| 378 | -__simd_callee__ inline void TrigRedFPreporcessForHalf(MicroAPI::RegTensor<float> ®R, MicroAPI::RegTensor<int32_t> ®I, | ||
| 379 | - MicroAPI::RegTensor<float> &srcRegA, MicroAPI::MaskReg& mask) | ||
| 380 | -{ | ||
| 381 | - constexpr float J_MUL_COEFF = 0.636619747f; | ||
| 382 | - constexpr float J_ADD_COEFF = 12582912.0f; | ||
| 383 | - constexpr float J_MUL_COEFF1 = -1.57079601e+00f; | ||
| 384 | - constexpr float J_MUL_COEFF2 = -3.13916473e-07f; | ||
| 385 | - constexpr float J_MUL_COEFF3 = -5.39030253e-15f; | ||
| 386 | - | ||
| 387 | - MicroAPI::RegTensor<float> regJ; | ||
| 388 | - MicroAPI::RegTensor<float> tmpF32Reg; | ||
| 389 | - MicroAPI::RegTensor<int32_t> tmpI32Reg; | ||
| 390 | - | ||
| 391 | - // step 1: a = a * 0.0f + a; convert inf to NAN | ||
| 392 | - MicroAPI::Duplicate(tmpF32Reg, 0.0f, mask); | ||
| 393 | - MicroAPI::FusedMulDstAdd(srcRegA, tmpF32Reg, srcRegA, mask); | ||
| 394 | - | ||
| 395 | - // step 2: j = a*0.636619747f + 12582912.0f; | ||
| 396 | - FMaf(regJ, srcRegA, J_MUL_COEFF, J_ADD_COEFF, mask); | ||
| 397 | - // step 3: i = reinterpret_cast<int&> (j); | ||
| 398 | - regI = (MicroAPI::RegTensor<int32_t>&)regJ; | ||
| 399 | - // step 4: j = j - 12582912.0f; | ||
| 400 | - MicroAPI::Adds(regJ, regJ, -J_ADD_COEFF, mask); | ||
| 401 | - // step 5: r = j* -1.57079601e+00f+ a; // -0x1.921fb0p+00 // pio2_high | ||
| 402 | - FMaf(regR, regJ, J_MUL_COEFF1, srcRegA, mask); | ||
| 403 | - // step 6: r = j* -3.13916473e-07f+ r; // -0x1.5110b4p-22 // pio2_mid | ||
| 404 | - MicroAPI::Duplicate(tmpF32Reg, J_MUL_COEFF2, mask); | ||
| 405 | - MicroAPI::MulAddDst(regR, regJ, tmpF32Reg, mask); | ||
| 406 | - // step 7: r = j* -5.39030253e-15f+ r; // -0x1.846988p-48 // pio2_low | ||
| 407 | - MicroAPI::Duplicate(tmpF32Reg, J_MUL_COEFF3, mask); | ||
| 408 | - MicroAPI::MulAddDst(regR, regJ, tmpF32Reg, mask); | ||
| 409 | -} | ||
| 410 | - | ||
| 411 | -__simd_callee__ inline void TrigRedFComputeP(MicroAPI::MaskReg& tmpMask, MicroAPI::RegTensor<uint32_t> ®PHigh, | ||
| 412 | - MicroAPI::RegTensor<uint32_t> ®PLow, MicroAPI::RegTensor<float> &srcRegA, | ||
| 413 | - MicroAPI::RegTensor<uint32_t> &oneOverPiFReg, MicroAPI::MaskReg& mask) | ||
| 414 | -{ | ||
| 415 | - constexpr float A_ABS_COEFF = 3.1415926535f*0.25f; | ||
| 416 | - MicroAPI::RegTensor<float> tmpF32Reg; | ||
| 417 | - MicroAPI::RegTensor<int32_t> tmpI32Reg; | ||
| 418 | - /* step 8: | ||
| 419 | - * if (std::abs(a) > 3.1415926535f*0.25f) { | ||
| 420 | - * r = trig_red_slowpath_f (a, &i); | ||
| 421 | - * } | ||
| 422 | - */ | ||
| 423 | - MicroAPI::Abs(tmpF32Reg, srcRegA, mask); | ||
| 424 | - MicroAPI::CompareScalar<float, CMPMODE::GT>(tmpMask, tmpF32Reg, A_ABS_COEFF, mask); | ||
| 425 | - TrigRedSlowpathFComputeP(regPHigh, regPLow, srcRegA, oneOverPiFReg, mask); | ||
| 426 | -} | ||
| 427 | - | ||
| 428 | -__simd_callee__ inline void TrigRedFComputeRI(MicroAPI::MaskReg& tmpMask, MicroAPI::RegTensor<float> &dstRegR, | ||
| 429 | - MicroAPI::RegTensor<int32_t> &dstRegI, MicroAPI::RegTensor<uint32_t> ®PHigh, MicroAPI::RegTensor<uint32_t> ®PLow, | ||
| 430 | - MicroAPI::RegTensor<float> &srcRegA, MicroAPI::MaskReg& mask) | ||
| 431 | -{ | ||
| 432 | - constexpr float A_ABS_COEFF = 3.1415926535f*0.25f; | ||
| 433 | - MicroAPI::RegTensor<float> tmpF32Reg; | ||
| 434 | - MicroAPI::RegTensor<int32_t> tmpI32Reg; | ||
| 435 | - /* step 8: | ||
| 436 | - * if (std::abs(a) > 3.1415926535f*0.25f) { | ||
| 437 | - * r = trig_red_slowpath_f (a, &i); | ||
| 438 | - * } | ||
| 439 | - */ | ||
| 440 | - MicroAPI::Abs(tmpF32Reg, srcRegA, mask); | ||
| 441 | - MicroAPI::CompareScalar<float, CMPMODE::GT>(tmpMask, tmpF32Reg, A_ABS_COEFF, mask); | ||
| 442 | - TrigRedSlowpathFComputeRI(dstRegR, dstRegI, regPHigh, regPLow, srcRegA, mask); | ||
| 443 | -} | ||
| 444 | - | ||
| 445 | -/* Compute sine and cosine simultaneously, based on quadrant */ | ||
| 446 | -__simd_callee__ inline void SCFCore(MicroAPI::RegTensor<float> &dstRegSin, MicroAPI::RegTensor<float> &dstRegCos, | ||
| 447 | - MicroAPI::RegTensor<int32_t> ®I, MicroAPI::RegTensor<float> ®R, MicroAPI::MaskReg& mask) | ||
| 448 | -{ | ||
| 449 | - constexpr int32_t I_AND_CONDITION = 2; | ||
| 450 | - | ||
| 451 | - // step 9: float c, s, t; | ||
| 452 | - MicroAPI::RegTensor<float> regC, regS, regT; | ||
| 453 | - MicroAPI::RegTensor<float> tmpF32Reg, tmpF32Reg1; | ||
| 454 | - MicroAPI::RegTensor<int32_t> tmpI32Reg; | ||
| 455 | - // step 10: s = r * r; | ||
| 456 | - MicroAPI::Mul(regS, regR, regR, mask); | ||
| 457 | - // step 11: c = cosf_poly (s); | ||
| 458 | - CosfPoly(regC, regS, mask); | ||
| 459 | - // step 12: s = sinf_poly (r, s); | ||
| 460 | - SinfPoly(tmpF32Reg, regR, regS, mask); | ||
| 461 | - regS = tmpF32Reg; | ||
| 462 | - | ||
| 463 | - /* step 13: | ||
| 464 | - * if (i & 2) { | ||
| 465 | - * s = 0.0f - s; // don't change "sign" of NaNs or create negative zeros | ||
| 466 | - * c = 0.0f - c; // don't change "sign" of NaNs or create negative zeros | ||
| 467 | - * } | ||
| 468 | - */ | ||
| 469 | - MicroAPI::MaskReg tmpMask; | ||
| 470 | - MicroAPI::Duplicate(tmpI32Reg, I_AND_CONDITION, mask); | ||
| 471 | - MicroAPI::And(tmpI32Reg, regI, tmpI32Reg, mask); | ||
| 472 | - MicroAPI::CompareScalar<int32_t, CMPMODE::GT>(tmpMask, tmpI32Reg, 0, mask); | ||
| 473 | - MicroAPI::Duplicate(tmpF32Reg1, 0.0f, mask); | ||
| 474 | - MicroAPI::Sub(tmpF32Reg, tmpF32Reg1, regS, mask); | ||
| 475 | - MicroAPI::Select(regS, tmpF32Reg, regS, tmpMask); | ||
| 476 | - MicroAPI::Sub(tmpF32Reg, tmpF32Reg1, regC, mask); | ||
| 477 | - MicroAPI::Select(regC, tmpF32Reg, regC, tmpMask); | ||
| 478 | - | ||
| 479 | - /* step 14: | ||
| 480 | - * if (i & 1) { | ||
| 481 | - * t = 0.0f - s; // don't change "sign" of NaNs or create negative zeros | ||
| 482 | - * s = c; | ||
| 483 | - * c = t; | ||
| 484 | - * } | ||
| 485 | - */ | ||
| 486 | - MicroAPI::Duplicate(tmpI32Reg, 1, mask); | ||
| 487 | - MicroAPI::And(tmpI32Reg, regI, tmpI32Reg, mask); | ||
| 488 | - MicroAPI::CompareScalar<int32_t, CMPMODE::GT>(tmpMask, tmpI32Reg, 0, mask); | ||
| 489 | - MicroAPI::Duplicate(tmpF32Reg, 0.0f, mask); | ||
| 490 | - MicroAPI::Sub(tmpF32Reg, tmpF32Reg, regS, mask); | ||
| 491 | - MicroAPI::Select(regT, tmpF32Reg, regT, tmpMask); | ||
| 492 | - MicroAPI::Select(regS, regC, regS, tmpMask); | ||
| 493 | - MicroAPI::Select(regC, regT, regC, tmpMask); | ||
| 494 | - | ||
| 495 | - // step 15: *sp = s; //sp is the sin result | ||
| 496 | - dstRegSin = regS; | ||
| 497 | - // step 16: *cp = c; //cp is the cos result | ||
| 498 | - dstRegCos = regC; | ||
| 499 | -} | ||
| 500 | - | ||
| 501 | -__aicore__ inline void InitializeFloatTempBuffer(__ubuf__ uint32_t *&tmpBuffer, __ubuf__ float *&tmpBufferR, | ||
| 502 | - __ubuf__ int32_t *&tmpBufferI, const uint32_t alignCount) | ||
| 503 | -{ | ||
| 504 | - constexpr uint32_t oneOverPiFAlignedLength = 8; | ||
| 505 | - static unsigned int oneOverPiF[6] = | ||
| 506 | - { | ||
| 507 | - 0x28be60db, 0x9391054a, 0x7f09d5f4, | ||
| 508 | - 0x7d4d3770, 0x36d8a566, 0x4f10e410 | ||
| 509 | - }; | ||
| 510 | - | ||
| 511 | - for (uint16_t i = 0; i < 6; ++i) { | ||
| 512 | - tmpBuffer[i] = oneOverPiF[i]; | ||
| 513 | - } | ||
| 514 | - | ||
| 515 | - tmpBufferR = (__ubuf__ float *)((__ubuf__ uint8_t *)tmpBuffer + sizeof(uint32_t) * oneOverPiFAlignedLength); | ||
| 516 | - tmpBufferI = (__ubuf__ int32_t *)((__ubuf__ uint8_t *)tmpBufferR + sizeof(float) * alignCount); | ||
| 517 | -} | ||
| 518 | - | ||
| 519 | -__aicore__ inline void InitializeHalfTempBuffer(__ubuf__ uint32_t *&tmpBuffer, __ubuf__ float *&tmpBufferR, | ||
| 520 | - __ubuf__ int32_t *&tmpBufferI, const uint32_t alignCount) | ||
| 521 | -{ | ||
| 522 | - tmpBufferR = (__ubuf__ float *)((__ubuf__ uint8_t *)tmpBuffer); | ||
| 523 | - tmpBufferI = (__ubuf__ int32_t *)((__ubuf__ uint8_t *)tmpBufferR + sizeof(float) * alignCount); | ||
| 524 | -} | ||
| 525 | - | ||
| 526 | -template <typename T> | ||
| 527 | -__simd_vf__ inline void TrigRedFPreProcessImpl(__ubuf__ float *tmpBufferR, __ubuf__ int32_t *tmpBufferI, | ||
| 528 | - __ubuf__ T *src, uint32_t calCount, uint16_t repeatTimes) | ||
| 529 | -{ | ||
| 530 | - MicroAPI::RegTensor<T> srcReg; | ||
| 531 | - MicroAPI::RegTensor<int32_t> regI; | ||
| 532 | - MicroAPI::RegTensor<float> castReg, regR; | ||
| 533 | - | ||
| 534 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 535 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 536 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, src + i * B32_DATA_NUM_PER_REPEAT); | ||
| 537 | - MicroAPI::Cast<float, T, SinCosImpl::castTraitF16F32>(castReg, srcReg, mask); | ||
| 538 | - TrigRedFPreporcessForHalf(regR, regI, castReg, mask); | ||
| 539 | - | ||
| 540 | - MicroAPI::DataCopy(tmpBufferR + i * B32_DATA_NUM_PER_REPEAT, regR, mask); | ||
| 541 | - MicroAPI::DataCopy(tmpBufferI + i * B32_DATA_NUM_PER_REPEAT, regI, mask); | ||
| 542 | - } | ||
| 543 | -} | ||
| 544 | - | ||
| 545 | -template <typename T> | ||
| 546 | -__simd_vf__ inline void TrigRedFComputePImpl(__ubuf__ uint32_t *tmpBufferRegPHigh, __ubuf__ uint32_t *tmpBufferRegPLow, | ||
| 547 | - __ubuf__ T *src, __ubuf__ uint32_t *tmpBuffer, uint32_t calCount, uint16_t repeatTimes) | ||
| 548 | -{ | ||
| 549 | - MicroAPI::RegTensor<T> srcReg; | ||
| 550 | - MicroAPI::RegTensor<uint32_t> oneOverPiFReg, regPHigh, regPLow, regI; | ||
| 551 | - MicroAPI::RegTensor<float> castReg, regR, tmpF32Reg; | ||
| 552 | - MicroAPI::MaskReg selectMask; | ||
| 553 | - | ||
| 554 | - // Load the array of one_over_pi_f | ||
| 555 | - MicroAPI::DataCopy(oneOverPiFReg, tmpBuffer); | ||
| 556 | - | ||
| 557 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 558 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 559 | - MicroAPI::DataCopy(castReg, src + i * B32_DATA_NUM_PER_REPEAT); | ||
| 560 | - // a = a * 0.0f + a | ||
| 561 | - MicroAPI::Duplicate(tmpF32Reg, 0.0f, mask); | ||
| 562 | - MicroAPI::FusedMulDstAdd(castReg, tmpF32Reg, castReg, mask); | ||
| 563 | - // initilize q and r: *q = 0; r = a; | ||
| 564 | - MicroAPI::Duplicate(regI, 0, mask); | ||
| 565 | - regR = castReg; | ||
| 566 | - // store the origin q and r in ub | ||
| 567 | - MicroAPI::DataCopy((__ubuf__ float *)tmpBufferRegPHigh + i * B32_DATA_NUM_PER_REPEAT, regR, mask); | ||
| 568 | - MicroAPI::DataCopy(tmpBufferRegPLow + i * B32_DATA_NUM_PER_REPEAT, regI, mask); | ||
| 569 | - | ||
| 570 | - TrigRedFComputeP(selectMask, regPHigh, regPLow, castReg, oneOverPiFReg, mask); | ||
| 571 | - | ||
| 572 | - MicroAPI::DataCopy(tmpBufferRegPHigh + i * B32_DATA_NUM_PER_REPEAT, regPHigh, selectMask); | ||
| 573 | - MicroAPI::DataCopy(tmpBufferRegPLow + i * B32_DATA_NUM_PER_REPEAT, regPLow, selectMask); | ||
| 574 | - } | ||
| 575 | -} | ||
| 576 | - | ||
| 577 | -template <typename T> | ||
| 578 | -__simd_vf__ inline void TrigRedFComputeRIImpl(__ubuf__ uint32_t *tmpBufferRegPHigh, __ubuf__ uint32_t *tmpBufferRegPLow, | ||
| 579 | - __ubuf__ T *src, __ubuf__ uint32_t *tmpBuffer, uint32_t calCount, uint16_t repeatTimes) | ||
| 580 | -{ | ||
| 581 | - MicroAPI::RegTensor<T> srcReg; | ||
| 582 | - MicroAPI::RegTensor<uint32_t> regPHigh, regPLow; | ||
| 583 | - MicroAPI::RegTensor<int32_t> regI; | ||
| 584 | - MicroAPI::RegTensor<float> castReg, regR, tmpF32Reg; | ||
| 585 | - MicroAPI::MaskReg selectMask; | ||
| 586 | - | ||
| 587 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 588 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 589 | - MicroAPI::DataCopy(castReg, src + i * B32_DATA_NUM_PER_REPEAT); | ||
| 590 | - MicroAPI::DataCopy(regPHigh, tmpBufferRegPHigh + i * B32_DATA_NUM_PER_REPEAT); | ||
| 591 | - MicroAPI::DataCopy(regPLow, tmpBufferRegPLow + i * B32_DATA_NUM_PER_REPEAT); | ||
| 592 | - // a = a * 0.0f + a | ||
| 593 | - MicroAPI::Duplicate(tmpF32Reg, 0.0f, mask); | ||
| 594 | - MicroAPI::FusedMulDstAdd(castReg, tmpF32Reg, castReg, mask); | ||
| 595 | - | ||
| 596 | - TrigRedFComputeRI(selectMask, regR, regI, regPHigh, regPLow, castReg, mask); | ||
| 597 | - | ||
| 598 | - MicroAPI::DataCopy((__ubuf__ float *)tmpBufferRegPHigh + i * B32_DATA_NUM_PER_REPEAT, regR, selectMask); | ||
| 599 | - MicroAPI::DataCopy((__ubuf__ int32_t *)tmpBufferRegPLow + i * B32_DATA_NUM_PER_REPEAT, regI, selectMask); | ||
| 600 | - } | ||
| 601 | -} | ||
| 602 | - | ||
| 603 | -template <typename T, int mode = 0> | ||
| 604 | -__simd_vf__ inline void SCFCoreImpl(__ubuf__ T *dst, __ubuf__ float *tmpBufferR, __ubuf__ int32_t *tmpBufferI, | ||
| 605 | - uint32_t calCount, uint16_t repeatTimes) | ||
| 606 | -{ | ||
| 607 | - MicroAPI::RegTensor<T> srcReg; | ||
| 608 | - MicroAPI::RegTensor<int32_t> regI; | ||
| 609 | - MicroAPI::RegTensor<float> regR; | ||
| 610 | - MicroAPI::RegTensor<float> dstRegCos, dstRegSin, dstReg; | ||
| 611 | - | ||
| 612 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 613 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 614 | - MicroAPI::DataCopy(regR, tmpBufferR + i * B32_DATA_NUM_PER_REPEAT); | ||
| 615 | - MicroAPI::DataCopy(regI, tmpBufferI + i * B32_DATA_NUM_PER_REPEAT); | ||
| 616 | - | ||
| 617 | - SCFCore(dstRegSin, dstRegCos, regI, regR, mask); | ||
| 618 | - | ||
| 619 | - if constexpr (mode == 0) { | ||
| 620 | - dstReg = dstRegSin; | ||
| 621 | - } else { | ||
| 622 | - dstReg = dstRegCos; | ||
| 623 | - } | ||
| 624 | - | ||
| 625 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 626 | - MicroAPI::Cast<T, float, SinCosImpl::castTraitF32F16>(srcReg, dstReg, mask); | ||
| 627 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + i * B32_DATA_NUM_PER_REPEAT, srcReg, mask); | ||
| 628 | - } else { | ||
| 629 | - MicroAPI::DataCopy(dst + i * B32_DATA_NUM_PER_REPEAT, dstReg, mask); | ||
| 630 | - } | ||
| 631 | - } | ||
| 632 | -} | ||
| 633 | - | ||
| 634 | -template <typename T> | ||
| 635 | -__simd_vf__ inline void BSCFCoreImpl(__ubuf__ T *dstSin, __ubuf__ T *dstCos, __ubuf__ float *tmpBufferR, __ubuf__ int32_t *tmpBufferI, | ||
| 636 | - uint32_t calCount, uint16_t repeatTimes) | ||
| 637 | -{ | ||
| 638 | - MicroAPI::RegTensor<T> srcReg; | ||
| 639 | - MicroAPI::RegTensor<int32_t> regI; | ||
| 640 | - MicroAPI::RegTensor<float> regR; | ||
| 641 | - MicroAPI::RegTensor<float> dstRegCos, dstRegSin; | ||
| 642 | - | ||
| 643 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 644 | - MicroAPI::MaskReg mask = MicroAPI::UpdateMask<float>(calCount); | ||
| 645 | - MicroAPI::DataCopy(regR, tmpBufferR + i * B32_DATA_NUM_PER_REPEAT); | ||
| 646 | - MicroAPI::DataCopy(regI, tmpBufferI + i * B32_DATA_NUM_PER_REPEAT); | ||
| 647 | - | ||
| 648 | - SCFCore(dstRegSin, dstRegCos, regI, regR, mask); | ||
| 649 | - | ||
| 650 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 651 | - MicroAPI::Cast<T, float, SinCosImpl::castTraitF32F16>(srcReg, dstRegSin, mask); | ||
| 652 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstSin + i * B32_DATA_NUM_PER_REPEAT, srcReg, mask); | ||
| 653 | - MicroAPI::Cast<T, float, SinCosImpl::castTraitF32F16>(srcReg, dstRegCos, mask); | ||
| 654 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstCos + i * B32_DATA_NUM_PER_REPEAT, srcReg, mask); | ||
| 655 | - } else { | ||
| 656 | - MicroAPI::DataCopy(dstSin + i * B32_DATA_NUM_PER_REPEAT, dstRegSin, mask); | ||
| 657 | - MicroAPI::DataCopy(dstCos + i * B32_DATA_NUM_PER_REPEAT, dstRegCos, mask); | ||
| 658 | - } | ||
| 659 | - } | ||
| 660 | -} | ||
| 661 | -} // namespace SinCosImpl | ||
| 662 | - | ||
| 663 | -template <typename T> | ||
| 664 | -__aicore__ inline void SinRadianReductionImpl(__ubuf__ T *dst, __ubuf__ T *src, __ubuf__ uint32_t *tmpBuffer, uint32_t calCount) | ||
| 665 | -{ | ||
| 666 | - static_assert((std::is_same_v<T, half> || std::is_same_v<T, float>), | ||
| 667 | - "current data type is not supported on current device!"); | ||
| 668 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 669 | - uint16_t repeatTimes = CeilDivision(calCount, oneRepSize); | ||
| 670 | - __ubuf__ float *tmpBufferR; | ||
| 671 | - __ubuf__ int32_t *tmpBufferI; | ||
| 672 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 673 | - | ||
| 674 | - if constexpr (std::is_same_v<T, float>) { | ||
| 675 | - SinCosImpl::InitializeFloatTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 676 | - SinCosImpl::TrigRedFComputePImpl<T>( | ||
| 677 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, src, tmpBuffer, calCount, repeatTimes); | ||
| 678 | - SinCosImpl::TrigRedFComputeRIImpl<T>( | ||
| 679 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, src, tmpBuffer, calCount, repeatTimes); | ||
| 680 | - } else if constexpr (std::is_same_v<T, half>) { | ||
| 681 | - SinCosImpl::InitializeHalfTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 682 | - SinCosImpl::TrigRedFPreProcessImpl<T>(tmpBufferR, tmpBufferI, src, calCount, repeatTimes); | ||
| 683 | - } | ||
| 684 | - SinCosImpl::SCFCoreImpl<T, 0>(dst, tmpBufferR, tmpBufferI, calCount, repeatTimes); | ||
| 685 | -} | ||
| 686 | - | ||
| 687 | -template <typename T> | ||
| 688 | -__aicore__ inline void CosRadianReductionImpl(__ubuf__ T *dst, __ubuf__ T *src, __ubuf__ uint32_t *tmpBuffer, uint32_t calCount) | ||
| 689 | -{ | ||
| 690 | - static_assert((std::is_same_v<T, half> || std::is_same_v<T, float>), | ||
| 691 | - "current data type is not supported on current device!"); | ||
| 692 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 693 | - uint16_t repeatTimes = CeilDivision(calCount, oneRepSize); | ||
| 694 | - __ubuf__ float *tmpBufferR; | ||
| 695 | - __ubuf__ int32_t *tmpBufferI; | ||
| 696 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 697 | - | ||
| 698 | - if constexpr (std::is_same_v<T, float>) { | ||
| 699 | - SinCosImpl::InitializeFloatTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 700 | - SinCosImpl::TrigRedFComputePImpl<T>( | ||
| 701 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, src, tmpBuffer, calCount, repeatTimes); | ||
| 702 | - SinCosImpl::TrigRedFComputeRIImpl<T>( | ||
| 703 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, src, tmpBuffer, calCount, repeatTimes); | ||
| 704 | - } else if constexpr (std::is_same_v<T, half>) { | ||
| 705 | - SinCosImpl::InitializeHalfTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 706 | - SinCosImpl::TrigRedFPreProcessImpl<T>(tmpBufferR, tmpBufferI, src, calCount, repeatTimes); | ||
| 707 | - } | ||
| 708 | - SinCosImpl::SCFCoreImpl<T, 1>(dst, tmpBufferR, tmpBufferI, calCount, repeatTimes); | ||
| 709 | -} | ||
| 710 | - | ||
| 711 | -template <const SinCosConfig& config, typename T> | ||
| 712 | -__aicore__ inline void SinCosRadianReductionImpl(const LocalTensor<T>& dst0, const LocalTensor<T>& dst1, | ||
| 713 | - const LocalTensor<T>& src, const LocalTensor<uint8_t>& sharedTmpBuffer, uint32_t calCount) | ||
| 714 | -{ | ||
| 715 | - // Only for AI Vector Core. | ||
| 716 | - if ASCEND_IS_AIC { | ||
| 717 | - return; | ||
| 718 | - } | ||
| 719 | - CHECK_FUNC_HIGHLEVEL_API(SinCos, (T, config.isReuseSource), (dst0, dst1, src, sharedTmpBuffer, calCount)); | ||
| 720 | - __ubuf__ T* dstSinAddr = (__ubuf__ T*)dst0.GetPhyAddr(); | ||
| 721 | - __ubuf__ T* dstCosAddr = (__ubuf__ T*)dst1.GetPhyAddr(); | ||
| 722 | - __ubuf__ T* srcAddr = (__ubuf__ T*)src.GetPhyAddr(); | ||
| 723 | - __ubuf__ uint32_t* tmpBuffer = (__ubuf__ uint32_t*)sharedTmpBuffer.GetPhyAddr(); | ||
| 724 | - static_assert((std::is_same_v<T, half> || std::is_same_v<T, float>), | ||
| 725 | - "current data type is not supported on current device!"); | ||
| 726 | - constexpr uint32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 727 | - uint16_t repeatTimes = CeilDivision(calCount, oneRepSize); | ||
| 728 | - __ubuf__ float *tmpBufferR; | ||
| 729 | - __ubuf__ int32_t *tmpBufferI; | ||
| 730 | - uint32_t alignCount = (calCount + 31) / 32 * 32; | ||
| 731 | - | ||
| 732 | - if constexpr (std::is_same_v<T, float>) { | ||
| 733 | - SinCosImpl::InitializeFloatTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 734 | - SinCosImpl::TrigRedFComputePImpl<T>( | ||
| 735 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, srcAddr, tmpBuffer, calCount, repeatTimes); | ||
| 736 | - SinCosImpl::TrigRedFComputeRIImpl<T>( | ||
| 737 | - (__ubuf__ uint32_t *)tmpBufferR, (__ubuf__ uint32_t *)tmpBufferI, srcAddr, tmpBuffer, calCount, repeatTimes); | ||
| 738 | - } else if constexpr (std::is_same_v<T, half>) { | ||
| 739 | - SinCosImpl::InitializeHalfTempBuffer(tmpBuffer, tmpBufferR, tmpBufferI, alignCount); | ||
| 740 | - SinCosImpl::TrigRedFPreProcessImpl<T>(tmpBufferR, tmpBufferI, srcAddr, calCount, repeatTimes); | ||
| 741 | - } | ||
| 742 | - SinCosImpl::BSCFCoreImpl<T>(dstSinAddr, dstCosAddr, tmpBufferR, tmpBufferI, calCount, repeatTimes); | ||
| 743 | -} | ||
| 744 | - | ||
| 745 | -template <const SinCosConfig& config, typename T> | ||
| 746 | -__aicore__ inline void SinCosRadianReductionImpl(const LocalTensor<T>& dst0, const LocalTensor<T>& dst1, | ||
| 747 | - const LocalTensor<T>& src, uint32_t calCount) | ||
| 748 | -{ | ||
| 749 | - // Only for AI Vector Core. | ||
| 750 | - if ASCEND_IS_AIC { | ||
| 751 | - return; | ||
| 752 | - } | ||
| 753 | - LocalTensor<uint8_t> sharedTmpBuffer; | ||
| 754 | - bool ans = PopStackBuffer<uint8_t, TPosition::LCM>(sharedTmpBuffer); | ||
| 755 | - ASCENDC_ASSERT((ans), { KERNEL_LOG(KERNEL_ERROR, "PopStackBuffer Error!"); }); | ||
| 756 | - SinCosRadianReductionImpl<config, T>(dst0, dst1, src, sharedTmpBuffer, calCount); | ||
| 757 | -} | ||
| 758 | -} // namespace AscendC | ||
| 759 | - | ||
| 760 | - | ||
Dimpl/adv_api/detail/math/sinh/sinh_l300_impl.h+0-102
| @@ -1,102 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file sinh_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace SinhInternal { | ||
| 23 | -// Computes sinh values based on input types. | ||
| 24 | -// According formula: sinh(x) = (e^x - e^(-x))/2 = e^(x-ln2) - 0.25/(e^(x-ln2)). | ||
| 25 | -template <typename T> | ||
| 26 | -__simd_vf__ inline void SinhCompute(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t calCount, uint16_t repeatTimes) | ||
| 27 | -{ | ||
| 28 | - constexpr float scalarNegLnTwo = -0.6931472; | ||
| 29 | - constexpr float scalarBrc = 0.25; | ||
| 30 | - constexpr uint32_t vlSize = static_cast<uint32_t>(GetVecLen() / sizeof(float)); | ||
| 31 | - static constexpr MicroAPI::CastTrait sinhCastTraitUpper = { MicroAPI::RegLayout::ZERO, | ||
| 32 | - MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN }; | ||
| 33 | - static constexpr MicroAPI::CastTrait sinhCastTraitLower = { MicroAPI::RegLayout::ZERO, | ||
| 34 | - MicroAPI::SatMode::NO_SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT }; | ||
| 35 | - MicroAPI::MaskReg sinhMask; | ||
| 36 | - MicroAPI::RegTensor<float> dupReg; | ||
| 37 | - MicroAPI::RegTensor<T> srcReg; | ||
| 38 | - MicroAPI::RegTensor<float> castUpperReg; | ||
| 39 | - MicroAPI::RegTensor<float> computeReg0; | ||
| 40 | - MicroAPI::RegTensor<float> computeReg1; | ||
| 41 | - MicroAPI::RegTensor<float> resReg; | ||
| 42 | - MicroAPI::RegTensor<T> dstReg; | ||
| 43 | - MicroAPI::Duplicate(dupReg, scalarBrc); | ||
| 44 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 45 | - sinhMask = MicroAPI::UpdateMask<float>(calCount); | ||
| 46 | - if constexpr (SupportBytes<T, 2>()) { | ||
| 47 | - MicroAPI::DataCopy<half, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * vlSize); | ||
| 48 | - MicroAPI::Cast<float, half, sinhCastTraitUpper>(castUpperReg, srcReg, sinhMask); | ||
| 49 | - } else { | ||
| 50 | - MicroAPI::DataCopy(castUpperReg, srcUb + i * vlSize); | ||
| 51 | - } | ||
| 52 | - MicroAPI::Adds(castUpperReg, castUpperReg, scalarNegLnTwo, sinhMask); | ||
| 53 | - MicroAPI::Exp(computeReg0, castUpperReg, sinhMask); | ||
| 54 | - MicroAPI::Div(computeReg1, dupReg, computeReg0, sinhMask); | ||
| 55 | - MicroAPI::Sub(resReg, computeReg0, computeReg1, sinhMask); | ||
| 56 | - if constexpr (SupportBytes<T, 2>()) { | ||
| 57 | - MicroAPI::Cast<half, float, sinhCastTraitLower>(dstReg, resReg, sinhMask); | ||
| 58 | - MicroAPI::DataCopy<half, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * vlSize, dstReg, sinhMask); | ||
| 59 | - } else { | ||
| 60 | - MicroAPI::DataCopy(dstUb + i * vlSize, resReg, sinhMask); | ||
| 61 | - } | ||
| 62 | - } | ||
| 63 | -} | ||
| 64 | -} // namespace SinhInternal | ||
| 65 | - | ||
| 66 | -template <typename T, bool isReuseSource = false> | ||
| 67 | -__aicore__ inline void SinhImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 68 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 69 | -{ | ||
| 70 | - // Only for AI Vector Core. | ||
| 71 | - if ASCEND_IS_AIC { | ||
| 72 | - return; | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 76 | - SinhImpl<T, isReuseSource>(dstTensor, srcTensor, calCount); | ||
| 77 | -} | ||
| 78 | - | ||
| 79 | -template <typename T, bool isReuseSource = false> | ||
| 80 | -__aicore__ inline void SinhImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 81 | - const uint32_t calCount) | ||
| 82 | -{ | ||
| 83 | - // Only for AI Vector Core. | ||
| 84 | - if ASCEND_IS_AIC { | ||
| 85 | - return; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - static_assert(SupportType<T, half, float>(), "Sinh only support half/float data type on current device!"); | ||
| 89 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 90 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 91 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Sinh"); | ||
| 92 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Sinh"); | ||
| 93 | - | ||
| 94 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 95 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 96 | - constexpr int32_t vlSize = static_cast<int32_t>(GetVecLen() / sizeof(float)); | ||
| 97 | - uint16_t repeatTimes = static_cast<uint16_t>(CeilDivision(calCount, vlSize)); | ||
| 98 | - SinhInternal::SinhCompute<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 99 | -} | ||
| 100 | -} // namespace AscendC | ||
| 101 | - | ||
| 102 | - | ||
Dimpl/adv_api/detail/math/tan/tan_l300_impl.h+0-235
| @@ -1,235 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file tan_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace TanInternal { | ||
| 23 | -constexpr MicroAPI::CastTrait TAN_CAST_TRAIT_F162F32 = { | ||
| 24 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 25 | -constexpr MicroAPI::CastTrait TAN_CAST_TRAIT_F322F16 = { | ||
| 26 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 27 | -// define the number of x div pi | ||
| 28 | -constexpr float PI_FOR_X_TODIV = 0.3183098733425140380859375; | ||
| 29 | -constexpr float KPI_FIRS_PI_MULS = 0.0009670257568359375; | ||
| 30 | -// define the PI for compute | ||
| 31 | -constexpr float PI_V2 = 3.140625; | ||
| 32 | -// define the number of down of pi_div | ||
| 33 | -constexpr float PI_DOWN = 1.57079637050628662109375; | ||
| 34 | -constexpr float PI_DOWN_NEG = -1.57079637050628662109375; | ||
| 35 | -// kpi_2 | ||
| 36 | -constexpr float KPI_TWI_PI_MULS = 6.2771141529083251953125e-7; | ||
| 37 | -constexpr float PI_RESDOWN_ADDS = 0.00000004371139000189375; | ||
| 38 | -constexpr float PI_RESDOWN_ADDS_NEG = -0.00000004371139000189375; | ||
| 39 | -// kpi_3 | ||
| 40 | -constexpr float KPI_THIR_PI_MULS = 1.21644916362129151821136474609375e-10; | ||
| 41 | -// kpi_4 | ||
| 42 | -constexpr float KPI_FOR_PI_MULS = -1.0291767438275201129727065563201904296875e-13; | ||
| 43 | -// define the number of tan_compute | ||
| 44 | -constexpr float TAN_RES_MULIT_SCA = 0.0698520831551998762793; | ||
| 45 | -constexpr float TAN_RES_ADDICT_UP = -6.8711573651634203789; | ||
| 46 | -constexpr float TAN_2ADDS = 61.20362572811089435388; | ||
| 47 | -constexpr float TAN_3ADDS = -24.8048928861126769186219; | ||
| 48 | - | ||
| 49 | -// normalized x to (-pi/2,pi/2) using x = x-round(x/π)*π | ||
| 50 | -__simd_callee__ inline void TanRound(MicroAPI::RegTensor<float> &srcReg, MicroAPI::RegTensor<float> &tmpReg, | ||
| 51 | - MicroAPI::RegTensor<float> &roundReg, MicroAPI::RegTensor<float> &resReg, MicroAPI::RegTensor<float> &downReg1, | ||
| 52 | - MicroAPI::RegTensor<float> &downReg2, MicroAPI::MaskReg mask) | ||
| 53 | -{ | ||
| 54 | - /* | ||
| 55 | - k=round(x/π), x0=x-kπ, x0∈(-π/2, π/2) | ||
| 56 | - π=π_0+π_1+π_2+π_3+π_4 achieve final precision compensation. | ||
| 57 | - Final solution: | ||
| 58 | - k = round(x * invpi) | ||
| 59 | - x -= k * pi_0 | ||
| 60 | - x -= k * pi_1 | ||
| 61 | - down1 = x + pio2_high // pi/2 + x | ||
| 62 | - down2 = x - pio2_high // x - pi/2 | ||
| 63 | - x -= k * pi_2 | ||
| 64 | - down1 -= k * pi_2 | ||
| 65 | - down2 -= k * pi_2 | ||
| 66 | - down1 -= down_adds | ||
| 67 | - down2 += down_adds | ||
| 68 | - x -= k * pi_3 | ||
| 69 | - down1 -= k * pi_3 | ||
| 70 | - down2 -= k * pi_3 | ||
| 71 | - x -= k * pi_4 | ||
| 72 | - down1 -= k * pi_4 | ||
| 73 | - down2 -= k * pi_4 | ||
| 74 | - */ | ||
| 75 | - | ||
| 76 | - // round_pi_div= round(x*0.3183098733425140380859375) | ||
| 77 | - MicroAPI::Muls(roundReg, srcReg, PI_FOR_X_TODIV, mask); | ||
| 78 | - // tie to even | ||
| 79 | - MicroAPI::Truncate<float, RoundMode::CAST_RINT, MicroAPI::MaskMergeMode::ZEROING>(roundReg, roundReg, mask); | ||
| 80 | - | ||
| 81 | - // kpi_0 = round_pi_div*3.140625 | ||
| 82 | - MicroAPI::Muls(tmpReg, roundReg, PI_V2, mask); | ||
| 83 | - // input_x = (x-kpi_0) | ||
| 84 | - MicroAPI::Sub(resReg, srcReg, tmpReg, mask); | ||
| 85 | - | ||
| 86 | - // kpi_1 = muls(round_pi_div, 0.0009670257568359375) | ||
| 87 | - MicroAPI::Muls(tmpReg, roundReg, KPI_FIRS_PI_MULS, mask); | ||
| 88 | - // input_x = sub(input_x, kpi_1) | ||
| 89 | - MicroAPI::Sub(resReg, resReg, tmpReg, mask); | ||
| 90 | - // res_down1 = adds(input_x, 1.57079637050628662109375) | ||
| 91 | - MicroAPI::Adds(downReg1, resReg, PI_DOWN, mask); | ||
| 92 | - // res_down2 = adds(input_x, -1.57079637050628662109375) | ||
| 93 | - MicroAPI::Adds(downReg2, resReg, PI_DOWN_NEG, mask); | ||
| 94 | - | ||
| 95 | - // kpi_2 = muls(round_pi_div, 6.2771141529083251953125e-7) | ||
| 96 | - MicroAPI::Muls(tmpReg, roundReg, KPI_TWI_PI_MULS, mask); | ||
| 97 | - // input_x = sub(input_x, kpi_2) | ||
| 98 | - MicroAPI::Sub(resReg, resReg, tmpReg, mask); | ||
| 99 | - // res_down1 = sub(res_down1, kpi_2) | ||
| 100 | - MicroAPI::Sub(downReg1, downReg1, tmpReg, mask); | ||
| 101 | - // res_down2 = sub(res_down2, kpi_2) | ||
| 102 | - MicroAPI::Sub(downReg2, downReg2, tmpReg, mask); | ||
| 103 | - // res_down1 = adds(res_down1, -0.00000004371139000189375) | ||
| 104 | - MicroAPI::Adds(downReg1, downReg1, PI_RESDOWN_ADDS_NEG, mask); | ||
| 105 | - // res_down2 = adds(res_down2, 0.00000004371139000189375) | ||
| 106 | - MicroAPI::Adds(downReg2, downReg2, PI_RESDOWN_ADDS, mask); | ||
| 107 | - | ||
| 108 | - // kpi_3 = muls(round_pi_div, 1.21644916362129151821136474609375e-10) | ||
| 109 | - MicroAPI::Muls(tmpReg, roundReg, KPI_THIR_PI_MULS, mask); | ||
| 110 | - // input_x =sub(input_x, kpi_3) | ||
| 111 | - MicroAPI::Sub(resReg, resReg, tmpReg, mask); | ||
| 112 | - // res_down1 = sub(res_down1, kpi_3) | ||
| 113 | - MicroAPI::Sub(downReg1, downReg1, tmpReg, mask); | ||
| 114 | - // res_down2 = sub(res_down2, kpi_3) | ||
| 115 | - MicroAPI::Sub(downReg2, downReg2, tmpReg, mask); | ||
| 116 | - | ||
| 117 | - // kpi_4 = muls(round_pi_div, -1.0291767438275201129727065563201904296875e-13) | ||
| 118 | - MicroAPI::Muls(tmpReg, roundReg, KPI_FOR_PI_MULS, mask); | ||
| 119 | - // input_x =sub(input_x, kpi_4) | ||
| 120 | - MicroAPI::Sub(resReg, resReg, tmpReg, mask); | ||
| 121 | - // res_down1 = sub(res_down1, kpi_4) | ||
| 122 | - MicroAPI::Sub(downReg1, downReg1, tmpReg, mask); | ||
| 123 | - // res_down2 = sub(res_down2, kpi_4) | ||
| 124 | - MicroAPI::Sub(downReg2, downReg2, tmpReg, mask); | ||
| 125 | -} | ||
| 126 | - | ||
| 127 | -__simd_callee__ inline void TanPolynomialApproximation(MicroAPI::RegTensor<float> &dstReg, MicroAPI::RegTensor<float> &tmpReg, | ||
| 128 | - MicroAPI::RegTensor<float> &roundReg, MicroAPI::RegTensor<float> &resReg, MicroAPI::RegTensor<float> &downReg1, | ||
| 129 | - MicroAPI::RegTensor<float> &downReg2, MicroAPI::MaskReg mask) | ||
| 130 | -{ | ||
| 131 | - /* | ||
| 132 | - tan(x) = xP(x) / ((π/2 - x)(π/2 + x)Q(x)) | ||
| 133 | - P(x) = (x^2 * R0 + R1) * x^2 + R2 | ||
| 134 | - Q(x) = x^2 * R3 | ||
| 135 | - R0 = 0.0698520831551998762793 | ||
| 136 | - R1 = -6.8711573651634203789 | ||
| 137 | - R2 = 61.20362572811089435388 | ||
| 138 | - R3 = -24.8048928861126769186219 | ||
| 139 | - */ | ||
| 140 | - | ||
| 141 | - // x^2 = mul(input_x, input_x) | ||
| 142 | - MicroAPI::Mul(roundReg, resReg, resReg, mask); | ||
| 143 | - // res_up = muls(x^2, 0.0698520831551998762793) | ||
| 144 | - MicroAPI::Muls(tmpReg, roundReg, TAN_RES_MULIT_SCA, mask); | ||
| 145 | - // res_up = adds(res_up, -6.8711573651634203789) | ||
| 146 | - MicroAPI::Adds(tmpReg, tmpReg, TAN_RES_ADDICT_UP, mask); | ||
| 147 | - // res_up = mul(res_up, x^2) | ||
| 148 | - MicroAPI::Mul(tmpReg, tmpReg, roundReg, mask); | ||
| 149 | - // res_up = adds(res_up, 61.20362572811089435388) | ||
| 150 | - MicroAPI::Adds(tmpReg, tmpReg, TAN_2ADDS, mask); | ||
| 151 | - // res_up = mul(res_up, input_x) | ||
| 152 | - MicroAPI::Mul(tmpReg, tmpReg, resReg, mask); | ||
| 153 | - // res_down = adds(x^2, -24.8048928861126769186219) | ||
| 154 | - MicroAPI::Adds(roundReg, roundReg, TAN_3ADDS, mask); | ||
| 155 | - // res_down = mul(res_down, res_down1) | ||
| 156 | - MicroAPI::Mul(roundReg, roundReg, downReg1, mask); | ||
| 157 | - // res_down = mul(res_down, res_down2) | ||
| 158 | - MicroAPI::Mul(roundReg, roundReg, downReg2, mask); | ||
| 159 | - // res = div(res_up, res_down) | ||
| 160 | - MicroAPI::Div(dstReg, tmpReg, roundReg, mask); | ||
| 161 | -} | ||
| 162 | - | ||
| 163 | -template <typename T> | ||
| 164 | -__simd_vf__ inline void TanCompute(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t sreg, uint16_t repeatTimes) | ||
| 165 | -{ | ||
| 166 | - constexpr uint32_t stride = GetVecLen() / sizeof(float); | ||
| 167 | - | ||
| 168 | - MicroAPI::MaskReg mask; | ||
| 169 | - MicroAPI::RegTensor<T> srcReg; | ||
| 170 | - MicroAPI::RegTensor<float> castReg; | ||
| 171 | - MicroAPI::RegTensor<float> roundReg; | ||
| 172 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 173 | - MicroAPI::RegTensor<float> downReg1; | ||
| 174 | - MicroAPI::RegTensor<float> downReg2; | ||
| 175 | - MicroAPI::RegTensor<float> resReg; | ||
| 176 | - MicroAPI::RegTensor<float> dstReg; | ||
| 177 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 178 | - mask = MicroAPI::UpdateMask<float>(sreg); | ||
| 179 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 180 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * stride); | ||
| 181 | - MicroAPI::Cast<float, T, TAN_CAST_TRAIT_F162F32>(castReg, srcReg, mask); | ||
| 182 | - } else { | ||
| 183 | - MicroAPI::DataCopy(castReg, srcUb + i * stride); | ||
| 184 | - } | ||
| 185 | - // the input is normalized to (-pi/2,pi/2) | ||
| 186 | - TanRound(castReg, tmpReg, roundReg, resReg, downReg1, downReg2, mask); | ||
| 187 | - TanPolynomialApproximation(dstReg, tmpReg, roundReg, resReg, downReg1, downReg2, mask); | ||
| 188 | - | ||
| 189 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 190 | - MicroAPI::Cast<T, float, TAN_CAST_TRAIT_F322F16>(srcReg, dstReg, mask); | ||
| 191 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * stride, srcReg, mask); | ||
| 192 | - } else { | ||
| 193 | - MicroAPI::DataCopy(dstUb + i * stride, dstReg, mask); | ||
| 194 | - } | ||
| 195 | - } | ||
| 196 | -} | ||
| 197 | -} // namespace TanInternal | ||
| 198 | - | ||
| 199 | -template <typename T, bool isReuseSource = false> | ||
| 200 | -__aicore__ inline void TanImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 201 | - const uint32_t calCount) | ||
| 202 | -{ | ||
| 203 | - // Only for AI Vector Core. | ||
| 204 | - if ASCEND_IS_AIC { | ||
| 205 | - return; | ||
| 206 | - } | ||
| 207 | - | ||
| 208 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 209 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 210 | - | ||
| 211 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Tan"); | ||
| 212 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Tan"); | ||
| 213 | - | ||
| 214 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 215 | - constexpr uint32_t stride = GetVecLen() / sizeof(float); | ||
| 216 | - uint16_t repeatTimes = CeilDivision(calCount, stride); | ||
| 217 | - | ||
| 218 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 219 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 220 | - | ||
| 221 | - TanInternal::TanCompute<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 222 | -} | ||
| 223 | - | ||
| 224 | -template <typename T, bool isReuseSource = false> | ||
| 225 | -__aicore__ inline void TanImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 226 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 227 | -{ | ||
| 228 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 229 | - | ||
| 230 | - TanImpl(dstTensor, srcTensor, calCount); | ||
| 231 | -} | ||
| 232 | - | ||
| 233 | -} // namespace AscendC | ||
| 234 | - | ||
| 235 | - | ||
Dimpl/adv_api/detail/math/tanh/tanh_l300_impl.h+0-240
| @@ -1,240 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file tanh_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -namespace TanhInternal { | ||
| 23 | -constexpr float FP32_ZERO_015 = 0.0157296831; | ||
| 24 | -constexpr float FP32_ZERO_NEG_052 = -0.0523029624; | ||
| 25 | -constexpr float FP32_ZERO_133 = 0.133152977; | ||
| 26 | -constexpr float FP32_ZERO_NEG_333 = -0.333327681; | ||
| 27 | -constexpr float FP32_TWENTY = 20.0; | ||
| 28 | -constexpr float FP32_TWO = 2.0; | ||
| 29 | -constexpr float FP32_ZERO_55 = 0.55; | ||
| 30 | -constexpr float FP32_MIN_EXP = -8.8; | ||
| 31 | -constexpr float FP32_MAX_EXP = 8.8; | ||
| 32 | - | ||
| 33 | -constexpr MicroAPI::CastTrait tanhCastTraitF162F32 = { | ||
| 34 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::UNKNOWN, MicroAPI::MaskMergeMode::ZEROING, RoundMode::UNKNOWN}; | ||
| 35 | -constexpr MicroAPI::CastTrait tanhCastTraitF322F16 = { | ||
| 36 | - MicroAPI::RegLayout::ZERO, MicroAPI::SatMode::NO_SAT, MicroAPI::MaskMergeMode::ZEROING, RoundMode::CAST_RINT}; | ||
| 37 | -} | ||
| 38 | - | ||
| 39 | -template <typename T> | ||
| 40 | -__simd_vf__ inline void TanhIntrinsicImpl(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 41 | - const uint32_t calCount, const uint16_t repeatTimes) | ||
| 42 | -{ | ||
| 43 | - uint32_t sreg = calCount; | ||
| 44 | - MicroAPI::MaskReg preg; | ||
| 45 | - MicroAPI::RegTensor<T> srcReg; | ||
| 46 | - MicroAPI::RegTensor<float> castReg; | ||
| 47 | - MicroAPI::RegTensor<float> tmpReg; | ||
| 48 | - MicroAPI::RegTensor<float> dstReg; | ||
| 49 | - | ||
| 50 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 51 | - preg = MicroAPI::UpdateMask<float>(sreg); | ||
| 52 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 53 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 54 | - MicroAPI::Cast<float, T, TanhInternal::tanhCastTraitF162F32>(castReg, srcReg, preg); | ||
| 55 | - } else { | ||
| 56 | - MicroAPI::DataCopy(castReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 57 | - } | ||
| 58 | - MicroAPI::Mins(castReg, castReg, TanhInternal::FP32_MAX_EXP, preg); | ||
| 59 | - MicroAPI::Maxs(castReg, castReg, TanhInternal::FP32_MIN_EXP, preg); | ||
| 60 | - MicroAPI::Muls(tmpReg, castReg, TanhInternal::FP32_TWO, preg); | ||
| 61 | - MicroAPI::Exp(castReg, tmpReg, preg); | ||
| 62 | - | ||
| 63 | - MicroAPI::Adds(dstReg, castReg, -1.0f, preg); | ||
| 64 | - MicroAPI::Adds(tmpReg, castReg, 1.0f, preg); | ||
| 65 | - MicroAPI::Div(dstReg, dstReg, tmpReg, preg); | ||
| 66 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 67 | - MicroAPI::Cast<T, float, TanhInternal::tanhCastTraitF322F16>(srcReg, dstReg, preg); | ||
| 68 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, preg); | ||
| 69 | - } else { | ||
| 70 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, dstReg, preg); | ||
| 71 | - } | ||
| 72 | - } | ||
| 73 | -} | ||
| 74 | - | ||
| 75 | -template <typename T> | ||
| 76 | -__simd_vf__ inline void TanhCompensationImpl(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 77 | - const uint32_t calCount, const uint16_t repeatTimes) | ||
| 78 | -{ | ||
| 79 | - uint32_t sreg = calCount; | ||
| 80 | - MicroAPI::MaskReg preg, cmpMaskReg; | ||
| 81 | - MicroAPI::RegTensor<T> srcReg; | ||
| 82 | - MicroAPI::RegTensor<float> vregInput, vregInputAbs; | ||
| 83 | - MicroAPI::RegTensor<float> vregInputSqr, vregInputMid; | ||
| 84 | - MicroAPI::RegTensor<float> vregOutput; | ||
| 85 | - MicroAPI::RegTensor<float> vregScalar1, vregScalar2; | ||
| 86 | - | ||
| 87 | - MicroAPI::Duplicate(vregScalar1, TanhInternal::FP32_ZERO_133); | ||
| 88 | - MicroAPI::Duplicate(vregScalar2, TanhInternal::FP32_ZERO_NEG_333); | ||
| 89 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 90 | - preg = MicroAPI::UpdateMask<float>(sreg); | ||
| 91 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 92 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcReg, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 93 | - MicroAPI::Cast<float, T, TanhInternal::tanhCastTraitF162F32>(vregInput, srcReg, preg); | ||
| 94 | - } else { | ||
| 95 | - MicroAPI::DataCopy(vregInput, srcUb + i * B32_DATA_NUM_PER_REPEAT); | ||
| 96 | - } | ||
| 97 | - MicroAPI::Mul(vregInputSqr, vregInput, vregInput, preg); | ||
| 98 | - MicroAPI::Muls(vregOutput, vregInputSqr, TanhInternal::FP32_ZERO_015, preg); | ||
| 99 | - MicroAPI::Adds(vregOutput, vregOutput, TanhInternal::FP32_ZERO_NEG_052, preg); | ||
| 100 | - MicroAPI::FusedMulDstAdd(vregOutput, vregInputSqr, vregScalar1, preg); | ||
| 101 | - MicroAPI::FusedMulDstAdd(vregOutput, vregInputSqr, vregScalar2, preg); | ||
| 102 | - MicroAPI::Mul(vregOutput, vregOutput, vregInputSqr, preg); | ||
| 103 | - MicroAPI::FusedMulDstAdd(vregOutput, vregInput, vregInput, preg); | ||
| 104 | - | ||
| 105 | - MicroAPI::Abs(vregInputAbs, vregInput, preg); | ||
| 106 | - MicroAPI::Mins(vregInput, vregInput, TanhInternal::FP32_TWENTY, preg); | ||
| 107 | - MicroAPI::Muls(vregInput, vregInput, TanhInternal::FP32_TWO, preg); | ||
| 108 | - MicroAPI::Exp(vregInput, vregInput, preg); | ||
| 109 | - MicroAPI::Adds(vregInputMid, vregInput, -1.0f, preg); | ||
| 110 | - MicroAPI::Adds(vregInputSqr, vregInput, 1.0f, preg); | ||
| 111 | - MicroAPI::Div(vregInputMid, vregInputMid, vregInputSqr, preg); | ||
| 112 | - | ||
| 113 | - MicroAPI::CompareScalar<float, CMPMODE::LT>(cmpMaskReg, vregInputAbs, TanhInternal::FP32_ZERO_55, preg); | ||
| 114 | - MicroAPI::Select(vregOutput, vregOutput, vregInputMid, cmpMaskReg); | ||
| 115 | - | ||
| 116 | - if constexpr (sizeof(T) == sizeof(half)) { | ||
| 117 | - MicroAPI::Cast<T, float, TanhInternal::tanhCastTraitF322F16>(srcReg, vregOutput, preg); | ||
| 118 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * B32_DATA_NUM_PER_REPEAT, srcReg, preg); | ||
| 119 | - } else { | ||
| 120 | - MicroAPI::DataCopy(dstUb + i * B32_DATA_NUM_PER_REPEAT, vregOutput, preg); | ||
| 121 | - } | ||
| 122 | - } | ||
| 123 | -} | ||
| 124 | - | ||
| 125 | -/* | ||
| 126 | - * Formula is y= (e^(2x)-1)/(e^(2x)+1) | ||
| 127 | - */ | ||
| 128 | -template <typename T, bool isReuseSource = false, const TanhConfig &config = DEFAULT_TANH_CONFIG> | ||
| 129 | -__aicore__ inline void TanhImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 130 | - const uint32_t calCount) | ||
| 131 | -{ | ||
| 132 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 133 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 134 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 135 | - | ||
| 136 | - CheckCalCount(calCount, "calCount", srcTensor, "srcTensor", "Tanh"); | ||
| 137 | - CheckCalCount(calCount, "calCount", dstTensor, "dstTensor", "Tanh"); | ||
| 138 | - | ||
| 139 | - // Only for AI Vector Core. | ||
| 140 | - if ASCEND_IS_AIC { | ||
| 141 | - return; | ||
| 142 | - } | ||
| 143 | - __ubuf__ T *dstUb = (__ubuf__ T *)dstTensor.GetPhyAddr(); | ||
| 144 | - __ubuf__ T *srcUb = (__ubuf__ T *)srcTensor.GetPhyAddr(); | ||
| 145 | - uint16_t repeatTimes = CeilDivision(calCount, B32_DATA_NUM_PER_REPEAT); | ||
| 146 | - if constexpr (config.algo == TanhAlgo::INTRINSIC) { | ||
| 147 | - TanhIntrinsicImpl<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 148 | - } else { | ||
| 149 | - TanhCompensationImpl<T>(dstUb, srcUb, calCount, repeatTimes); | ||
| 150 | - } | ||
| 151 | -} | ||
| 152 | - | ||
| 153 | -template <typename T, bool isReuseSource = false, const TanhConfig &config = DEFAULT_TANH_CONFIG> | ||
| 154 | -__aicore__ inline void TanhImpl(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 155 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 156 | -{ | ||
| 157 | - CheckTensorPosition(sharedTmpBuffer, "sharedTmpBuffer", "VECIN, VECOUT, VECCALC"); | ||
| 158 | - TanhImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 159 | -} | ||
| 160 | - | ||
| 161 | -/*! | ||
| 162 | - * \ingroup Tanh | ||
| 163 | - * \brief compute Tanh elementwisely | ||
| 164 | - * \tparam T: half/float | ||
| 165 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 166 | - * this parameter is reserved, please use the default value. | ||
| 167 | - * \param [out] dstTensor: output LocalTensor | ||
| 168 | - * \param [in] srcTensor: input LocalTensor | ||
| 169 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 170 | - * whose required space size should refer to corresponding tiling API, which is defined at tanh_tiling.h. | ||
| 171 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 172 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 173 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 174 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 175 | - */ | ||
| 176 | -template <typename T, bool isReuseSource = false, const TanhConfig& config = DEFAULT_TANH_CONFIG> | ||
| 177 | -__aicore__ inline void Tanh( | ||
| 178 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const LocalTensor<uint8_t>& sharedTmpBuffer) | ||
| 179 | -{ | ||
| 180 | - Tanh<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, srcTensor.GetSize()); | ||
| 181 | -} | ||
| 182 | - | ||
| 183 | -/*! | ||
| 184 | - * \ingroup Tanh | ||
| 185 | - * \brief compute Tanh elementwisely | ||
| 186 | - * \tparam T: half/float | ||
| 187 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 188 | - * this parameter is reserved, please use the default value. | ||
| 189 | - * \param [out] dstTensor: output LocalTensor | ||
| 190 | - * \param [in] srcTensor: input LocalTensor | ||
| 191 | - * \param [in] sharedTmpBuffer: extra temporary shared space used for intermediate values among calculation process, | ||
| 192 | - * whose required space size should refer to corresponding tiling API, which is defined at tanh_tiling.h. | ||
| 193 | - * Generally, the more space you allocate, the better performance you will achieve, and the performance | ||
| 194 | - * reaches peak when buffer size is maximum(calculated by tiling function). Moreover, it is not guaranteed | ||
| 195 | - * that the shared space will be cleared after usage, the data could be anything. | ||
| 196 | - * \param [in] calCount: the number of elements to be processed. | ||
| 197 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 198 | - */ | ||
| 199 | -template <typename T, bool isReuseSource = false, const TanhConfig& config = DEFAULT_TANH_CONFIG> | ||
| 200 | -__aicore__ inline void Tanh(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 201 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t calCount) | ||
| 202 | -{ | ||
| 203 | - TanhImpl<T, isReuseSource, config>(dstTensor, srcTensor, sharedTmpBuffer, calCount); | ||
| 204 | -} | ||
| 205 | - | ||
| 206 | -/*! | ||
| 207 | - * \ingroup Tanh | ||
| 208 | - * \brief compute Tanh elementwisely | ||
| 209 | - * \tparam T: half/float | ||
| 210 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 211 | - * this parameter is reserved, please use the default value. | ||
| 212 | - * \param [out] dstTensor: output LocalTensor | ||
| 213 | - * \param [in] srcTensor: input LocalTensor | ||
| 214 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 215 | - */ | ||
| 216 | -template <typename T, bool isReuseSource = false, const TanhConfig& config = DEFAULT_TANH_CONFIG> | ||
| 217 | -__aicore__ inline void Tanh(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor) | ||
| 218 | -{ | ||
| 219 | - Tanh<T, isReuseSource, config>(dstTensor, srcTensor, srcTensor.GetSize()); | ||
| 220 | -} | ||
| 221 | - | ||
| 222 | -/*! | ||
| 223 | - * \ingroup Tanh | ||
| 224 | - * \brief compute Tanh elementwisely | ||
| 225 | - * \tparam T: half/float | ||
| 226 | - * \tparam isReuseSource: whether allows API to modify source data, usually for performance reason, | ||
| 227 | - * this parameter is reserved, please use the default value. | ||
| 228 | - * \param [out] dstTensor: output LocalTensor | ||
| 229 | - * \param [in] srcTensor: input LocalTensor | ||
| 230 | - * \param [in] calCount: the number of elements to be processed. | ||
| 231 | - * \note src/dst Tensor must be 32B aligned, and it doesn't allow src/dst/sharedTmpBuffer tensor address overlap. | ||
| 232 | - */ | ||
| 233 | -template <typename T, bool isReuseSource = false, const TanhConfig& config = DEFAULT_TANH_CONFIG> | ||
| 234 | -__aicore__ inline void Tanh(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, const uint32_t calCount) | ||
| 235 | -{ | ||
| 236 | - TanhImpl<T, isReuseSource, config>(dstTensor, srcTensor, calCount); | ||
| 237 | -} | ||
| 238 | -} // namespace AscendC | ||
| 239 | - | ||
| 240 | - | ||
Dimpl/adv_api/detail/normalization/rmsnorm/rmsnorm_l300_impl.h+0-189
| @@ -1,189 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | - | ||
| 12 | - | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | -namespace AscendC { | ||
| 19 | -namespace RmsNormAPI { | ||
| 20 | -constexpr int32_t oneRepSize = GetVecLen() / sizeof(float); | ||
| 21 | - | ||
| 22 | -template <typename T> | ||
| 23 | -__simd_callee__ inline void LoadDataWithT( | ||
| 24 | - __ubuf__ T* src, MicroAPI::RegTensor<float>& dstReg, MicroAPI::MaskReg& mask, uint32_t offset) | ||
| 25 | -{ | ||
| 26 | - if constexpr (IsSameType<T, half>::value) { | ||
| 27 | - MicroAPI::RegTensor<T> srcOrigin; | ||
| 28 | - DataCopy<T, MicroAPI::LoadDist::DIST_UNPACK_B16>(srcOrigin, src + offset); | ||
| 29 | - Cast<float, T, layoutZMrgZ>(dstReg, srcOrigin, mask); | ||
| 30 | - } else { | ||
| 31 | - DataCopy(dstReg, src + offset); | ||
| 32 | - } | ||
| 33 | -} | ||
| 34 | - | ||
| 35 | -template <typename T> | ||
| 36 | -__simd_callee__ inline void SaveDataWithT( | ||
| 37 | - __ubuf__ T* dst, MicroAPI::RegTensor<float>& srcReg, MicroAPI::MaskReg& mask, uint32_t offset) | ||
| 38 | -{ | ||
| 39 | - if constexpr (IsSameType<T, half>::value) { | ||
| 40 | - MicroAPI::RegTensor<T> regT; | ||
| 41 | - MicroAPI::Cast<T, float, LayoutZMrgZRndRSatNS>(regT, srcReg, mask); | ||
| 42 | - MicroAPI::DataCopy<T, MicroAPI::StoreDist::DIST_PACK_B32>(dst + offset, regT, mask); | ||
| 43 | - } else { | ||
| 44 | - MicroAPI::DataCopy(dst + offset, srcReg, mask); | ||
| 45 | - } | ||
| 46 | -} | ||
| 47 | - | ||
| 48 | -template <typename T> | ||
| 49 | -__simd_callee__ inline void ComputeSum(__ubuf__ float* dstLocal, __ubuf__ T* srcLocal, | ||
| 50 | - uint32_t bsLength, uint32_t hLength, uint32_t oriHLength) | ||
| 51 | -{ | ||
| 52 | - uint16_t mainRepeatTime = static_cast<uint16_t>(oriHLength / oneRepSize); | ||
| 53 | - uint32_t tailCount = oriHLength % oneRepSize; | ||
| 54 | - uint16_t tailRepeatTime = static_cast<uint16_t>(CeilDivision(tailCount, oneRepSize)); | ||
| 55 | - MicroAPI::RegTensor<float> srcReg; | ||
| 56 | - MicroAPI::RegTensor<float> dstReg; | ||
| 57 | - MicroAPI::RegTensor<float> dstTailReg; | ||
| 58 | - MicroAPI::MaskReg maskFull = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 59 | - MicroAPI::MaskReg maskOne = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::VL1>(); | ||
| 60 | - MicroAPI::MaskReg maskReg = MicroAPI::UpdateMask<float>(tailCount); | ||
| 61 | - for (uint16_t bsIdx = 0; bsIdx < bsLength; bsIdx++) { | ||
| 62 | - MicroAPI::Duplicate(dstReg, static_cast<float>(0), maskFull); | ||
| 63 | - for (uint16_t i = 0; i < mainRepeatTime; i++) { | ||
| 64 | - LoadDataWithT(srcLocal, srcReg, maskFull, bsIdx * hLength + i * oneRepSize); | ||
| 65 | - // step 1: x² | ||
| 66 | - MicroAPI::Mul(srcReg, srcReg, srcReg, maskFull); | ||
| 67 | - // step 2: ∑x² | ||
| 68 | - MicroAPI::Add(dstReg, dstReg, srcReg, maskFull); | ||
| 69 | - } | ||
| 70 | - for (uint16_t i = 0; i < tailRepeatTime; i++) { | ||
| 71 | - LoadDataWithT(srcLocal, srcReg, maskReg, bsIdx * hLength + mainRepeatTime * oneRepSize); | ||
| 72 | - // step 1: x² | ||
| 73 | - MicroAPI::Mul(srcReg, srcReg, srcReg, maskReg); | ||
| 74 | - // step 2: ∑x² | ||
| 75 | - MicroAPI::Add(dstTailReg, dstReg, srcReg, maskReg); | ||
| 76 | - MicroAPI::Select(dstReg, dstTailReg, dstReg, maskReg); | ||
| 77 | - } | ||
| 78 | - MicroAPI::ReduceSum(dstReg, dstReg, maskFull); | ||
| 79 | - DataCopy<float, MicroAPI::StoreDist::DIST_FIRST_ELEMENT_B32>(dstLocal + bsIdx, dstReg, maskOne); | ||
| 80 | - } | ||
| 81 | -} | ||
| 82 | -template <typename T> | ||
| 83 | -__simd_callee__ inline void ComputeY(__ubuf__ T* dstLocal, __ubuf__ T* srcLocal, __ubuf__ T* gammaLocal, __ubuf__ float* tmpLocal, | ||
| 84 | - uint32_t bsLength, uint32_t hLength, uint32_t oriHLength, const float epsilon, float reciprocalOfHLength) | ||
| 85 | -{ | ||
| 86 | - constexpr float rsqrtExponent = -0.5; | ||
| 87 | - MicroAPI::RegTensor<float> srcReg; | ||
| 88 | - MicroAPI::RegTensor<float> src2Reg; | ||
| 89 | - MicroAPI::RegTensor<float> gammaReg; | ||
| 90 | - MicroAPI::RegTensor<float> dstReg; | ||
| 91 | - MicroAPI::RegTensor<float> dstTailReg; | ||
| 92 | - | ||
| 93 | - static constexpr MicroAPI::LnSpecificMode lnMode = {MicroAPI::MaskMergeMode::ZEROING, LnAlgo::INTRINSIC}; | ||
| 94 | - static constexpr MicroAPI::ExpSpecificMode expMode = {MicroAPI::MaskMergeMode::ZEROING, ExpAlgo::INTRINSIC}; | ||
| 95 | - MicroAPI::MaskReg maskFull = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::ALL>(); | ||
| 96 | - MicroAPI::MaskReg maskOne = MicroAPI::CreateMask<float, MicroAPI::MaskPattern::VL1>(); | ||
| 97 | - MicroAPI::Duplicate(dstReg, static_cast<float>(0), maskFull); | ||
| 98 | - uint16_t mainRepeatTime = static_cast<uint16_t>(oriHLength / oneRepSize); | ||
| 99 | - uint32_t tailCount = oriHLength % oneRepSize; | ||
| 100 | - uint16_t tailRepeatTime = static_cast<uint16_t>(CeilDivision(tailCount, oneRepSize)); | ||
| 101 | - MicroAPI::MaskReg maskReg = MicroAPI::UpdateMask<float>(tailCount); | ||
| 102 | - for (uint16_t bsIdx = 0; bsIdx < bsLength; bsIdx++) { | ||
| 103 | - for (uint16_t i = 0; i < mainRepeatTime; i++) { | ||
| 104 | - LoadDataWithT(srcLocal, srcReg, maskFull, bsIdx * hLength + i * oneRepSize); | ||
| 105 | - LoadDataWithT(gammaLocal, gammaReg, maskFull, i * oneRepSize); | ||
| 106 | - DataCopy<float, MicroAPI::LoadDist::DIST_BRC_B32>(src2Reg, tmpLocal + bsIdx); | ||
| 107 | - // step 3: rms = 1/n*∑ | ||
| 108 | - MicroAPI::Muls(src2Reg, src2Reg, reciprocalOfHLength, maskFull); | ||
| 109 | - // step 4: rms + e | ||
| 110 | - MicroAPI::Adds(src2Reg, src2Reg, epsilon, maskFull); | ||
| 111 | - // step 5: rsqrt: ln + muls + exp | ||
| 112 | - MicroAPI::Ln<float, &lnMode>(src2Reg, src2Reg, maskFull); | ||
| 113 | - MicroAPI::Muls(src2Reg, src2Reg, rsqrtExponent, maskFull); | ||
| 114 | - MicroAPI::Exp<float, &expMode>(src2Reg, src2Reg, maskFull); | ||
| 115 | - // step 6: rms = xi * rsqrt | ||
| 116 | - MicroAPI::Mul(src2Reg, srcReg, src2Reg, maskFull); | ||
| 117 | - // step 7: rms = rms * gamma | ||
| 118 | - MicroAPI::Mul(src2Reg, src2Reg, gammaReg, maskFull); | ||
| 119 | - // save | ||
| 120 | - SaveDataWithT(dstLocal, src2Reg, maskFull, bsIdx * hLength + i * oneRepSize); | ||
| 121 | - } | ||
| 122 | - for (uint16_t i = 0; i < tailRepeatTime; i++) { | ||
| 123 | - LoadDataWithT(srcLocal, srcReg, maskReg, bsIdx * hLength + mainRepeatTime * oneRepSize); | ||
| 124 | - LoadDataWithT(gammaLocal, gammaReg, maskReg, mainRepeatTime * oneRepSize); | ||
| 125 | - DataCopy<float, MicroAPI::LoadDist::DIST_BRC_B32>(src2Reg, tmpLocal + bsIdx); | ||
| 126 | - // step 3: rms = 1/n*∑ | ||
| 127 | - MicroAPI::Muls(src2Reg, src2Reg, reciprocalOfHLength, maskReg); | ||
| 128 | - // step 4: rms + e | ||
| 129 | - MicroAPI::Adds(src2Reg, src2Reg, epsilon, maskReg); | ||
| 130 | - // step 5: rsqrt: ln + muls + exp | ||
| 131 | - MicroAPI::Ln<float, &lnMode>(src2Reg, src2Reg, maskReg); | ||
| 132 | - MicroAPI::Muls(src2Reg, src2Reg, rsqrtExponent, maskReg); | ||
| 133 | - MicroAPI::Exp<float, &expMode>(src2Reg, src2Reg, maskReg); | ||
| 134 | - // step 6: rms = xi * rsqrt | ||
| 135 | - MicroAPI::Mul(src2Reg, srcReg, src2Reg, maskReg); | ||
| 136 | - // step 7: rms = rms * gamma | ||
| 137 | - MicroAPI::Mul(src2Reg, src2Reg, gammaReg, maskReg); | ||
| 138 | - // save | ||
| 139 | - SaveDataWithT(dstLocal, src2Reg, maskReg, bsIdx * hLength + mainRepeatTime * oneRepSize); | ||
| 140 | - } | ||
| 141 | - } | ||
| 142 | -} | ||
| 143 | - | ||
| 144 | -template <typename T> | ||
| 145 | -__simd_vf__ inline void RmsNormImplVf(__ubuf__ T* dstLocal, __ubuf__ T* srcLocal, | ||
| 146 | - __ubuf__ T* gammaLocal, __ubuf__ float* tmpLocal, const float epsilon, const RmsNormTiling tiling) | ||
| 147 | -{ | ||
| 148 | - uint32_t bLength = tiling.bLength; | ||
| 149 | - uint32_t sLength = tiling.sLength; | ||
| 150 | - uint32_t hLength = tiling.hLength; | ||
| 151 | - uint32_t oriHLength = tiling.originalHLength; | ||
| 152 | - float reciprocalOfHLength = tiling.reciprocalOfHLength; | ||
| 153 | - uint16_t loopRound = static_cast<uint16_t>(tiling.loopRound); | ||
| 154 | - uint32_t mainBsLength = tiling.mainBsLength; | ||
| 155 | - uint32_t mainBshLength = tiling.mainBshLength; | ||
| 156 | - | ||
| 157 | - for (uint16_t i = 0; i < loopRound; i++) { | ||
| 158 | - ComputeSum(tmpLocal, srcLocal + i * mainBshLength, mainBsLength, hLength, oriHLength); | ||
| 159 | - MicroAPI::LocalMemBar<MicroAPI::MemType::VEC_STORE, MicroAPI::MemType::VEC_LOAD>(); | ||
| 160 | - ComputeY(dstLocal + i * mainBshLength, srcLocal + i * mainBshLength, gammaLocal, tmpLocal, mainBsLength, hLength, oriHLength, epsilon, reciprocalOfHLength); | ||
| 161 | - } | ||
| 162 | - uint32_t inputTailPos = tiling.inputTailPos; | ||
| 163 | - uint32_t tailBsLength = tiling.tailBsLength; | ||
| 164 | - uint16_t tailRound = static_cast<uint16_t>(CeilDivision(tailBsLength, mainBsLength)); | ||
| 165 | - for (uint16_t i = 0; i < tailRound; i++) { | ||
| 166 | - ComputeSum(tmpLocal, srcLocal + inputTailPos, tailBsLength, hLength, oriHLength); | ||
| 167 | - MicroAPI::LocalMemBar<MicroAPI::MemType::VEC_STORE, MicroAPI::MemType::VEC_LOAD>(); | ||
| 168 | - ComputeY(dstLocal + inputTailPos, srcLocal + inputTailPos, gammaLocal, tmpLocal, tailBsLength, hLength, oriHLength, epsilon, reciprocalOfHLength); | ||
| 169 | - } | ||
| 170 | -} | ||
| 171 | - | ||
| 172 | -template <typename T, bool isBasicBlock = false> | ||
| 173 | -__aicore__ inline void RmsNormImpl(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, | ||
| 174 | - const LocalTensor<T>& gammaLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const T epsilon, | ||
| 175 | - const RmsNormTiling& tiling) | ||
| 176 | -{ | ||
| 177 | - if ASCEND_IS_AIC { | ||
| 178 | - return; | ||
| 179 | - } | ||
| 180 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 181 | - CHECK_FUNC_HIGHLEVEL_API(RmsNorm, (T, isBasicBlock), (dstLocal, srcLocal, gammaLocal, sharedTmpBuffer, epsilon, tiling)); | ||
| 182 | - LocalTensor<float> tmpLocal = sharedTmpBuffer.ReinterpretCast<float>(); | ||
| 183 | - float eps = static_cast<float>(epsilon); | ||
| 184 | - RmsNormImplVf<T>((__ubuf__ T*)dstLocal.GetPhyAddr(), (__ubuf__ T*)srcLocal.GetPhyAddr(), | ||
| 185 | - (__ubuf__ T*)gammaLocal.GetPhyAddr(), (__ubuf__ float*)tmpLocal.GetPhyAddr(), eps, tiling); | ||
| 186 | -} | ||
| 187 | -} // namespace RmsNormAPI | ||
| 188 | -} // namespace AscendC | ||
| 189 | - | ||
Dimpl/adv_api/detail/pad/broadcast/broadcast_gather_l300_impl.h+0-485
| @@ -1,485 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file broadcast_gather_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -template <typename T> | ||
| 23 | -__simd_vf__ inline void VfGenIndex(__ubuf__ T *indexUb, uint32_t sizeI0, uint32_t sizeI1, uint32_t sizeI2, uint32_t strideI0, | ||
| 24 | - uint32_t strideI1, uint32_t strideI2, uint32_t offset) | ||
| 25 | -{ | ||
| 26 | - MicroAPI::RegTensor<T> v0; | ||
| 27 | - MicroAPI::RegTensor<T> v1; | ||
| 28 | - MicroAPI::RegTensor<T> v2; | ||
| 29 | - | ||
| 30 | - MicroAPI::RegTensor<T> voffset; | ||
| 31 | - MicroAPI::RegTensor<T> vr0; | ||
| 32 | - | ||
| 33 | - MicroAPI::RegTensor<T> vd0; | ||
| 34 | - MicroAPI::RegTensor<T> vd1; | ||
| 35 | - MicroAPI::RegTensor<T> vd2; | ||
| 36 | - | ||
| 37 | - MicroAPI::RegTensor<T> vi0; | ||
| 38 | - MicroAPI::RegTensor<T> vi1; | ||
| 39 | - MicroAPI::RegTensor<T> vi2; | ||
| 40 | - | ||
| 41 | - MicroAPI::RegTensor<T> vs0; | ||
| 42 | - MicroAPI::RegTensor<T> vs1; | ||
| 43 | - MicroAPI::RegTensor<T> vs2; | ||
| 44 | - | ||
| 45 | - MicroAPI::MaskReg p0; | ||
| 46 | - | ||
| 47 | - p0 = MicroAPI::CreateMask<T>(); | ||
| 48 | - MicroAPI::Arange(v0, 0); | ||
| 49 | - | ||
| 50 | - MicroAPI::Duplicate(v1, (T)sizeI2, p0); | ||
| 51 | - MicroAPI::Div(vd0, v0, v1, p0); | ||
| 52 | - MicroAPI::Mul(v2, vd0, v1, p0); | ||
| 53 | - MicroAPI::Sub(vi2, v0, v2, p0); | ||
| 54 | - | ||
| 55 | - MicroAPI::Duplicate(v1, (T)sizeI1, p0); | ||
| 56 | - MicroAPI::Div(vd1, vd0, v1, p0); | ||
| 57 | - MicroAPI::Mul(v2, vd1, v1, p0); | ||
| 58 | - MicroAPI::Sub(vi1, vd0, v2, p0); | ||
| 59 | - | ||
| 60 | - MicroAPI::Duplicate(v1, (T)sizeI0, p0); | ||
| 61 | - MicroAPI::Div(vd2, vd1, v1, p0); | ||
| 62 | - MicroAPI::Mul(v2, vd2, v1, p0); | ||
| 63 | - MicroAPI::Sub(vi0, vd1, v2, p0); | ||
| 64 | - | ||
| 65 | - MicroAPI::Duplicate(vs0, (T)strideI0, p0); | ||
| 66 | - MicroAPI::Duplicate(vs1, (T)strideI1, p0); | ||
| 67 | - MicroAPI::Duplicate(vs2, (T)strideI2, p0); | ||
| 68 | - | ||
| 69 | - MicroAPI::Mul(vr0, vs2, vi2, p0); | ||
| 70 | - MicroAPI::MulAddDst(vr0, vs1, vi1, p0); | ||
| 71 | - MicroAPI::MulAddDst(vr0, vs0, vi0, p0); | ||
| 72 | - | ||
| 73 | - MicroAPI::Duplicate(voffset, (T)offset, p0); | ||
| 74 | - MicroAPI::Add(vr0, vr0, voffset, p0); | ||
| 75 | - | ||
| 76 | - MicroAPI::DataCopy(indexUb, vr0, p0); | ||
| 77 | -} | ||
| 78 | - | ||
| 79 | -template <typename T> | ||
| 80 | -__simd_vf__ inline void VfGenIndexForFourDim(__ubuf__ T *indexUb, uint32_t sizeI0, uint32_t sizeI1, uint32_t sizeI2, uint32_t sizeI3, | ||
| 81 | - uint32_t strideI0, uint32_t strideI1, uint32_t strideI2, uint32_t strideI3, uint32_t offset) | ||
| 82 | -{ | ||
| 83 | - MicroAPI::RegTensor<T> v0; | ||
| 84 | - MicroAPI::RegTensor<T> v1; | ||
| 85 | - MicroAPI::RegTensor<T> v2; | ||
| 86 | - | ||
| 87 | - MicroAPI::RegTensor<T> voffset; | ||
| 88 | - MicroAPI::RegTensor<T> vr0; | ||
| 89 | - | ||
| 90 | - MicroAPI::RegTensor<T> vd0; | ||
| 91 | - MicroAPI::RegTensor<T> vd1; | ||
| 92 | - MicroAPI::RegTensor<T> vd2; | ||
| 93 | - MicroAPI::RegTensor<T> vd3; | ||
| 94 | - | ||
| 95 | - MicroAPI::RegTensor<T> vi0; | ||
| 96 | - MicroAPI::RegTensor<T> vi1; | ||
| 97 | - MicroAPI::RegTensor<T> vi2; | ||
| 98 | - MicroAPI::RegTensor<T> vi3; | ||
| 99 | - | ||
| 100 | - MicroAPI::RegTensor<T> vs0; | ||
| 101 | - MicroAPI::RegTensor<T> vs1; | ||
| 102 | - MicroAPI::RegTensor<T> vs2; | ||
| 103 | - MicroAPI::RegTensor<T> vs3; | ||
| 104 | - | ||
| 105 | - MicroAPI::MaskReg p0; | ||
| 106 | - | ||
| 107 | - p0 = MicroAPI::CreateMask<T>(); | ||
| 108 | - MicroAPI::Arange(v0, 0); | ||
| 109 | - | ||
| 110 | - MicroAPI::Duplicate(v1, (T)sizeI3, p0); | ||
| 111 | - MicroAPI::Div(vd0, v0, v1, p0); | ||
| 112 | - MicroAPI::Mul(v2, vd0, v1, p0); | ||
| 113 | - MicroAPI::Sub(vi3, v0, v2, p0); | ||
| 114 | - | ||
| 115 | - MicroAPI::Duplicate(v1, (T)sizeI2, p0); | ||
| 116 | - MicroAPI::Div(vd1, vd0, v1, p0); | ||
| 117 | - MicroAPI::Mul(v2, vd1, v1, p0); | ||
| 118 | - MicroAPI::Sub(vi2, vd0, v2, p0); | ||
| 119 | - | ||
| 120 | - MicroAPI::Duplicate(v1, (T)sizeI1, p0); | ||
| 121 | - MicroAPI::Div(vd2, vd1, v1, p0); | ||
| 122 | - MicroAPI::Mul(v2, vd2, v1, p0); | ||
| 123 | - MicroAPI::Sub(vi1, vd1, v2, p0); | ||
| 124 | - | ||
| 125 | - MicroAPI::Duplicate(v1, (T)sizeI0, p0); | ||
| 126 | - MicroAPI::Div(vd3, vd2, v1, p0); | ||
| 127 | - MicroAPI::Mul(v2, vd3, v1, p0); | ||
| 128 | - MicroAPI::Sub(vi0, vd2, v2, p0); | ||
| 129 | - | ||
| 130 | - MicroAPI::Duplicate(vs0, (T)strideI0, p0); | ||
| 131 | - MicroAPI::Duplicate(vs1, (T)strideI1, p0); | ||
| 132 | - MicroAPI::Duplicate(vs2, (T)strideI2, p0); | ||
| 133 | - MicroAPI::Duplicate(vs3, (T)strideI3, p0); | ||
| 134 | - | ||
| 135 | - MicroAPI::Mul(vr0, vs3, vi3, p0); | ||
| 136 | - MicroAPI::MulAddDst(vr0, vs2, vi2, p0); | ||
| 137 | - MicroAPI::MulAddDst(vr0, vs1, vi1, p0); | ||
| 138 | - MicroAPI::MulAddDst(vr0, vs0, vi0, p0); | ||
| 139 | - | ||
| 140 | - MicroAPI::Duplicate(voffset, (T)offset, p0); | ||
| 141 | - MicroAPI::Add(vr0, vr0, voffset, p0); | ||
| 142 | - | ||
| 143 | - MicroAPI::DataCopy(indexUb, vr0, p0); | ||
| 144 | -} | ||
| 145 | - | ||
| 146 | -template <typename T> | ||
| 147 | -__simd_vf__ inline void VfGatherBrc(__ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ T *indexUb, uint16_t size0, uint16_t size1, | ||
| 148 | - uint16_t size2, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2, uint32_t main, uint32_t tail) | ||
| 149 | -{ | ||
| 150 | - MicroAPI::UnalignReg u0; | ||
| 151 | - MicroAPI::RegTensor<T> vindex0; | ||
| 152 | - MicroAPI::RegTensor<T> vindex; | ||
| 153 | - MicroAPI::RegTensor<T> vstride0; | ||
| 154 | - MicroAPI::RegTensor<T> vstride1; | ||
| 155 | - MicroAPI::RegTensor<T> vstride2; | ||
| 156 | - MicroAPI::RegTensor<T> vbase0; | ||
| 157 | - MicroAPI::RegTensor<T> vbase1; | ||
| 158 | - MicroAPI::RegTensor<T> vbase2; | ||
| 159 | - MicroAPI::RegTensor<T> voffset0; | ||
| 160 | - MicroAPI::RegTensor<T> voffset1; | ||
| 161 | - MicroAPI::RegTensor<T> voffset2; | ||
| 162 | - | ||
| 163 | - MicroAPI::RegTensor<T> vd0; | ||
| 164 | - MicroAPI::RegTensor<T> vd1; | ||
| 165 | - | ||
| 166 | - MicroAPI::MaskReg pa; | ||
| 167 | - MicroAPI::MaskReg p0; | ||
| 168 | - MicroAPI::MaskReg p1; | ||
| 169 | - pa = MicroAPI::CreateMask<T>(); | ||
| 170 | - uint32_t main1 = main; | ||
| 171 | - uint32_t tail1 = tail; | ||
| 172 | - p0 = MicroAPI::UpdateMask<T>(main); | ||
| 173 | - p1 = MicroAPI::UpdateMask<T>(tail); | ||
| 174 | - MicroAPI::Duplicate(vstride0, (T)srcStride0, pa); | ||
| 175 | - MicroAPI::Duplicate(vstride1, (T)srcStride1, pa); | ||
| 176 | - MicroAPI::Duplicate(vstride2, (T)srcStride2, pa); | ||
| 177 | - MicroAPI::DataCopy(vindex0, indexUb); | ||
| 178 | - for (uint16_t i0 = 0; i0 < size0; ++i0) { | ||
| 179 | - MicroAPI::Muls(voffset0, vstride0, (T)i0, p0); | ||
| 180 | - MicroAPI::Add(vbase0, voffset0, vindex0, p0); | ||
| 181 | - for (uint16_t i1 = 0; i1 < size1; ++i1) { | ||
| 182 | - MicroAPI::Muls(voffset1, vstride1, (T)i1, p0); | ||
| 183 | - MicroAPI::Add(vbase1, vbase0, voffset1, p0); | ||
| 184 | - for (uint16_t i2 = 0; i2 < size2; ++i2) { | ||
| 185 | - MicroAPI::Muls(voffset2, vstride2, (T)i2, p0); | ||
| 186 | - MicroAPI::Add(vindex, vbase1, voffset2, p0); | ||
| 187 | - MicroAPI::DataCopyGather(vd0, srcUb, vindex, p0); | ||
| 188 | - MicroAPI::DataCopyUnAlign(dstUb, vd0, u0, main1); | ||
| 189 | - } | ||
| 190 | - MicroAPI::Muls(voffset2, vstride2, (T)size2, p1); | ||
| 191 | - MicroAPI::Add(vindex, vbase1, voffset2, p1); | ||
| 192 | - MicroAPI::DataCopyGather(vd1, srcUb, vindex, p1); | ||
| 193 | - MicroAPI::DataCopyUnAlign(dstUb, vd1, u0, tail1); | ||
| 194 | - } | ||
| 195 | - } | ||
| 196 | - MicroAPI::DataCopyUnAlignPost(dstUb, u0, 0); | ||
| 197 | -} | ||
| 198 | - | ||
| 199 | -template <typename T> | ||
| 200 | -__simd_vf__ inline void VfGatherBrcForFourDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ T *indexUb, uint16_t size0, uint16_t size1, | ||
| 201 | - uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2, uint16_t srcStride3, uint32_t main, | ||
| 202 | - uint32_t tail) | ||
| 203 | -{ | ||
| 204 | - MicroAPI::UnalignReg u0; | ||
| 205 | - MicroAPI::RegTensor<T> vindex0; | ||
| 206 | - MicroAPI::RegTensor<T> vindex; | ||
| 207 | - MicroAPI::RegTensor<T> vstride0; | ||
| 208 | - MicroAPI::RegTensor<T> vstride1; | ||
| 209 | - MicroAPI::RegTensor<T> vstride2; | ||
| 210 | - MicroAPI::RegTensor<T> vstride3; | ||
| 211 | - MicroAPI::RegTensor<T> vbase0; | ||
| 212 | - MicroAPI::RegTensor<T> vbase1; | ||
| 213 | - MicroAPI::RegTensor<T> vbase2; | ||
| 214 | - MicroAPI::RegTensor<T> voffset0; | ||
| 215 | - MicroAPI::RegTensor<T> voffset1; | ||
| 216 | - MicroAPI::RegTensor<T> voffset2; | ||
| 217 | - MicroAPI::RegTensor<T> voffset3; | ||
| 218 | - | ||
| 219 | - MicroAPI::RegTensor<T> vd0; | ||
| 220 | - MicroAPI::RegTensor<T> vd1; | ||
| 221 | - | ||
| 222 | - MicroAPI::MaskReg pa; | ||
| 223 | - MicroAPI::MaskReg p0; | ||
| 224 | - MicroAPI::MaskReg p1; | ||
| 225 | - pa = MicroAPI::CreateMask<T>(); | ||
| 226 | - uint32_t main1 = main; | ||
| 227 | - uint32_t tail1 = tail; | ||
| 228 | - p0 = MicroAPI::UpdateMask<T>(main); | ||
| 229 | - p1 = MicroAPI::UpdateMask<T>(tail); | ||
| 230 | - MicroAPI::Duplicate(vstride0, (T)srcStride0, pa); | ||
| 231 | - MicroAPI::Duplicate(vstride1, (T)srcStride1, pa); | ||
| 232 | - MicroAPI::Duplicate(vstride2, (T)srcStride2, pa); | ||
| 233 | - MicroAPI::Duplicate(vstride3, (T)srcStride3, pa); | ||
| 234 | - MicroAPI::DataCopy(vindex0, indexUb); | ||
| 235 | - for (uint16_t i0 = 0; i0 < size0; ++i0) { | ||
| 236 | - MicroAPI::Muls(voffset0, vstride0, (T)i0, p0); | ||
| 237 | - MicroAPI::Add(vbase0, voffset0, vindex0, p0); | ||
| 238 | - for (uint16_t i1 = 0; i1 < size1; ++i1) { | ||
| 239 | - MicroAPI::Muls(voffset1, vstride1, (T)i1, p0); | ||
| 240 | - MicroAPI::Add(vbase1, vbase0, voffset1, p0); | ||
| 241 | - for (uint16_t i2 = 0; i2 < size2; ++i2) { | ||
| 242 | - MicroAPI::Muls(voffset2, vstride2, (T)i2, p0); | ||
| 243 | - MicroAPI::Add(vbase2, vbase1, voffset2, p0); | ||
| 244 | - for (uint16_t i3 = 0; i3 < size3; ++i3) { | ||
| 245 | - MicroAPI::Muls(voffset3, vstride3, (T)i3, p0); | ||
| 246 | - MicroAPI::Add(vindex, vbase2, voffset3, p0); | ||
| 247 | - MicroAPI::DataCopyGather(vd0, srcUb, vindex, p0); | ||
| 248 | - MicroAPI::DataCopyUnAlign(dstUb, vd0, u0, main1); | ||
| 249 | - } | ||
| 250 | - MicroAPI::Muls(voffset3, vstride3, (T)size3, p1); | ||
| 251 | - MicroAPI::Add(vindex, vbase2, voffset3, p1); | ||
| 252 | - MicroAPI::DataCopyGather(vd1, srcUb, vindex, p1); | ||
| 253 | - MicroAPI::DataCopyUnAlign(dstUb, vd1, u0, tail1); | ||
| 254 | - } | ||
| 255 | - } | ||
| 256 | - } | ||
| 257 | - MicroAPI::DataCopyUnAlignPost(dstUb, u0, 0); | ||
| 258 | -} | ||
| 259 | - | ||
| 260 | -template <typename T> __aicore__ inline void GenGatherIndex(__ubuf__ T *indexUb, uint32_t *size, uint32_t *srcStride) | ||
| 261 | -{ | ||
| 262 | - constexpr uint32_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 263 | - uint32_t sizeI[3]; | ||
| 264 | - uint32_t srcStrideI[3]; | ||
| 265 | - srcStrideI[0] = srcStride[0]; | ||
| 266 | - srcStrideI[1] = srcStride[1]; | ||
| 267 | - srcStrideI[2] = srcStride[2]; | ||
| 268 | - | ||
| 269 | - if (size[2] * size[1] * size[0] < VF_LEN) { | ||
| 270 | - sizeI[0] = size[0]; | ||
| 271 | - sizeI[1] = size[1]; | ||
| 272 | - sizeI[2] = size[2]; | ||
| 273 | - } else if (size[2] * size[1] < VF_LEN) { | ||
| 274 | - sizeI[0] = VF_LEN / (size[2] * size[1]); | ||
| 275 | - sizeI[1] = size[1]; | ||
| 276 | - sizeI[2] = size[2]; | ||
| 277 | - } else if (size[2] < VF_LEN) { | ||
| 278 | - sizeI[0] = 1; | ||
| 279 | - sizeI[1] = VF_LEN / size[2]; | ||
| 280 | - sizeI[2] = size[2]; | ||
| 281 | - } else { | ||
| 282 | - sizeI[0] = 1; | ||
| 283 | - sizeI[1] = 1; | ||
| 284 | - sizeI[2] = VF_LEN; | ||
| 285 | - } | ||
| 286 | - | ||
| 287 | - VfGenIndex<T>(indexUb, sizeI[0], sizeI[1], sizeI[2], srcStrideI[0], srcStrideI[1], | ||
| 288 | - srcStrideI[2], 0); | ||
| 289 | -} | ||
| 290 | - | ||
| 291 | -template <typename T> __aicore__ inline void GenGatherIndexForFourDim(__ubuf__ T *indexUb, uint32_t *size, uint32_t *srcStride) | ||
| 292 | -{ | ||
| 293 | - constexpr uint32_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 294 | - uint32_t sizeI[4]; | ||
| 295 | - uint32_t srcStrideI[4]; | ||
| 296 | - srcStrideI[0] = srcStride[0]; | ||
| 297 | - srcStrideI[1] = srcStride[1]; | ||
| 298 | - srcStrideI[2] = srcStride[2]; | ||
| 299 | - srcStrideI[3] = srcStride[3]; | ||
| 300 | - | ||
| 301 | - if (size[3] * size[2] * size[1] * size[0] < VF_LEN) { | ||
| 302 | - sizeI[0] = size[0]; | ||
| 303 | - sizeI[1] = size[1]; | ||
| 304 | - sizeI[2] = size[2]; | ||
| 305 | - sizeI[3] = size[3]; | ||
| 306 | - } else if (size[3] * size[2] * size[1] < VF_LEN) { | ||
| 307 | - sizeI[0] = VF_LEN / (size[3] * size[2] * size[1]); | ||
| 308 | - sizeI[1] = size[1]; | ||
| 309 | - sizeI[2] = size[2]; | ||
| 310 | - sizeI[3] = size[3]; | ||
| 311 | - } else if (size[3] * size[2] < VF_LEN) { | ||
| 312 | - sizeI[0] = 1; | ||
| 313 | - sizeI[1] = VF_LEN / (size[3] * size[2]); | ||
| 314 | - sizeI[2] = size[2]; | ||
| 315 | - sizeI[3] = size[3]; | ||
| 316 | - } else if (size[3] < VF_LEN) { | ||
| 317 | - sizeI[0] = 1; | ||
| 318 | - sizeI[1] = 1; | ||
| 319 | - sizeI[2] = VF_LEN / size[3]; | ||
| 320 | - sizeI[3] = size[3]; | ||
| 321 | - } else { | ||
| 322 | - sizeI[0] = 1; | ||
| 323 | - sizeI[1] = 1; | ||
| 324 | - sizeI[2] = 1; | ||
| 325 | - sizeI[3] = VF_LEN; | ||
| 326 | - } | ||
| 327 | - | ||
| 328 | - VfGenIndexForFourDim<T>(indexUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], srcStrideI[0], srcStrideI[1], | ||
| 329 | - srcStrideI[2], srcStrideI[3], 0); | ||
| 330 | -} | ||
| 331 | - | ||
| 332 | -template <typename T> | ||
| 333 | -__aicore__ inline void GatherWrapper(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t *size, uint32_t *srcStride) | ||
| 334 | -{ | ||
| 335 | - constexpr uint32_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 336 | - uint16_t sizeI[3]; | ||
| 337 | - uint16_t srcStrideI[3]; | ||
| 338 | - uint32_t main; | ||
| 339 | - uint32_t tail; | ||
| 340 | - uint32_t vlTile0; | ||
| 341 | - uint32_t vlTile1; | ||
| 342 | - uint32_t vlTile2; | ||
| 343 | - | ||
| 344 | - if (size[2] * size[1] < VF_LEN) { | ||
| 345 | - vlTile2 = size[2]; | ||
| 346 | - vlTile1 = size[1]; | ||
| 347 | - vlTile0 = VF_LEN / (vlTile2 * vlTile1); | ||
| 348 | - sizeI[0] = 1; | ||
| 349 | - sizeI[1] = 1; | ||
| 350 | - sizeI[2] = static_cast<uint16_t>(size[0] / vlTile0); | ||
| 351 | - srcStrideI[0] = 0; | ||
| 352 | - srcStrideI[1] = 0; | ||
| 353 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[0] * vlTile0); | ||
| 354 | - main = vlTile2 * vlTile1 * vlTile0; | ||
| 355 | - tail = size[2] * size[1] * size[0] - sizeI[2] * main; | ||
| 356 | - } else if (size[2] < VF_LEN) { | ||
| 357 | - vlTile2 = size[2]; | ||
| 358 | - vlTile1 = VF_LEN / (vlTile2); | ||
| 359 | - sizeI[0] = 1; | ||
| 360 | - sizeI[1] = size[0]; | ||
| 361 | - sizeI[2] = size[1] / vlTile1; | ||
| 362 | - srcStrideI[0] = 0; | ||
| 363 | - srcStrideI[1] = static_cast<uint16_t>(srcStride[0]); | ||
| 364 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[1] * vlTile1); | ||
| 365 | - main = vlTile2 * vlTile1; | ||
| 366 | - tail = size[2] * size[1] - sizeI[2] * main; | ||
| 367 | - } else { | ||
| 368 | - vlTile2 = VF_LEN; | ||
| 369 | - sizeI[0] = size[0]; | ||
| 370 | - sizeI[1] = size[1]; | ||
| 371 | - sizeI[2] = size[2] / vlTile2; | ||
| 372 | - srcStrideI[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 373 | - srcStrideI[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 374 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[2] * vlTile2); | ||
| 375 | - main = vlTile2; | ||
| 376 | - tail = size[2] - sizeI[2] * main; | ||
| 377 | - } | ||
| 378 | - constexpr uint32_t U16_MAX = 65536; | ||
| 379 | - ASCENDC_ASSERT((sizeI[2] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 380 | - ASCENDC_ASSERT((sizeI[1] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 381 | - ASCENDC_ASSERT((sizeI[0] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 382 | - LocalTensor<T> indexUb; | ||
| 383 | - PopStackBuffer<T, TPosition::LCM>(indexUb); | ||
| 384 | - if constexpr (sizeof(T) == sizeof(uint32_t)) { | ||
| 385 | - GenGatherIndex((__ubuf__ int32_t *)indexUb.GetPhyAddr(), size, srcStride); | ||
| 386 | - VfGatherBrc<uint32_t>((__ubuf__ uint32_t *)dstUb, (__ubuf__ uint32_t *)srcUb, | ||
| 387 | - (__ubuf__ uint32_t *)indexUb.GetPhyAddr(), sizeI[0], sizeI[1], sizeI[2], srcStrideI[0], srcStrideI[1], | ||
| 388 | - srcStrideI[2], main, tail); | ||
| 389 | - } else { | ||
| 390 | - GenGatherIndex((__ubuf__ int16_t *)indexUb.GetPhyAddr(), size, srcStride); | ||
| 391 | - VfGatherBrc<uint16_t>((__ubuf__ uint16_t *)dstUb, (__ubuf__ uint16_t *)srcUb, | ||
| 392 | - (__ubuf__ uint16_t *)indexUb.GetPhyAddr(), sizeI[0], sizeI[1], sizeI[2], srcStrideI[0], srcStrideI[1], | ||
| 393 | - srcStrideI[2], main, tail); | ||
| 394 | - } | ||
| 395 | -} | ||
| 396 | - | ||
| 397 | -template <typename T> | ||
| 398 | -__aicore__ inline void GatherWrapperForFourDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t *size, uint32_t *srcStride) | ||
| 399 | -{ | ||
| 400 | - constexpr uint32_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 401 | - uint16_t sizeI[4]; | ||
| 402 | - uint16_t srcStrideI[4]; | ||
| 403 | - uint32_t main; | ||
| 404 | - uint32_t tail; | ||
| 405 | - uint32_t vlTile0; | ||
| 406 | - uint32_t vlTile1; | ||
| 407 | - uint32_t vlTile2; | ||
| 408 | - uint32_t vlTile3; | ||
| 409 | - | ||
| 410 | - if (size[3] * size[2] * size[1] < VF_LEN) { | ||
| 411 | - vlTile3 = size[3]; | ||
| 412 | - vlTile2 = size[2]; | ||
| 413 | - vlTile1 = size[1]; | ||
| 414 | - vlTile0 = VF_LEN / (vlTile3 * vlTile2 * vlTile1); | ||
| 415 | - sizeI[0] = 1; | ||
| 416 | - sizeI[1] = 1; | ||
| 417 | - sizeI[2] = 1; | ||
| 418 | - sizeI[3] = static_cast<uint16_t>(size[0] / vlTile0); | ||
| 419 | - srcStrideI[0] = 0; | ||
| 420 | - srcStrideI[1] = 0; | ||
| 421 | - srcStrideI[2] = 0; | ||
| 422 | - srcStrideI[3] = static_cast<uint16_t>(srcStride[0] * vlTile0); | ||
| 423 | - main = vlTile3 * vlTile2 * vlTile1 * vlTile0; | ||
| 424 | - tail = size[3] * size[2] * size[1] * size[0] - sizeI[3] * main; | ||
| 425 | - } else if (size[3] * size[2] < VF_LEN) { | ||
| 426 | - vlTile3 = size[3]; | ||
| 427 | - vlTile2 = size[2]; | ||
| 428 | - vlTile1 = VF_LEN / (vlTile2 * vlTile3); | ||
| 429 | - sizeI[0] = 1; | ||
| 430 | - sizeI[1] = 1; | ||
| 431 | - sizeI[2] = size[0]; | ||
| 432 | - sizeI[3] = static_cast<uint16_t>(size[1] / vlTile1); | ||
| 433 | - srcStrideI[0] = 0; | ||
| 434 | - srcStrideI[1] = 0; | ||
| 435 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[0]); | ||
| 436 | - srcStrideI[3] = static_cast<uint16_t>(srcStride[1] * vlTile1); | ||
| 437 | - main = vlTile3 * vlTile2 * vlTile1; | ||
| 438 | - tail = size[3] * size[2] * size[1] - sizeI[3] * main; | ||
| 439 | - } else if (size[3] < VF_LEN) { | ||
| 440 | - vlTile3 = size[3]; | ||
| 441 | - vlTile2 = VF_LEN / vlTile3; | ||
| 442 | - sizeI[0] = 1; | ||
| 443 | - sizeI[1] = size[0];; | ||
| 444 | - sizeI[2] = size[1]; | ||
| 445 | - sizeI[3] = static_cast<uint16_t>(size[2] / vlTile2); | ||
| 446 | - srcStrideI[0] = 0; | ||
| 447 | - srcStrideI[1] = static_cast<uint16_t>(srcStride[0]); | ||
| 448 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[1]); | ||
| 449 | - srcStrideI[3] = static_cast<uint16_t>(srcStride[2] * vlTile2); | ||
| 450 | - main = vlTile3 * vlTile2; | ||
| 451 | - tail = size[3] * size[2] - sizeI[3] * main; | ||
| 452 | - } else { | ||
| 453 | - vlTile3 = VF_LEN; | ||
| 454 | - sizeI[0] = size[0]; | ||
| 455 | - sizeI[1] = size[1]; | ||
| 456 | - sizeI[2] = size[2]; | ||
| 457 | - sizeI[3] = static_cast<uint16_t>(size[3] / vlTile3); | ||
| 458 | - srcStrideI[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 459 | - srcStrideI[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 460 | - srcStrideI[2] = static_cast<uint16_t>(srcStride[2]); | ||
| 461 | - srcStrideI[3] = static_cast<uint16_t>(srcStride[3] * vlTile3); | ||
| 462 | - main = vlTile3; | ||
| 463 | - tail = size[3] - sizeI[3] * main; | ||
| 464 | - } | ||
| 465 | - constexpr uint32_t U16_MAX = 65536; | ||
| 466 | - ASCENDC_ASSERT((sizeI[3] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 467 | - ASCENDC_ASSERT((sizeI[2] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 468 | - ASCENDC_ASSERT((sizeI[1] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 469 | - ASCENDC_ASSERT((sizeI[0] <= U16_MAX), { KERNEL_LOG(KERNEL_ERROR, "shape should less than uint16 max"); }); | ||
| 470 | - LocalTensor<T> indexUb; | ||
| 471 | - PopStackBuffer<T, TPosition::LCM>(indexUb); | ||
| 472 | - if constexpr (sizeof(T) == sizeof(uint32_t)) { | ||
| 473 | - GenGatherIndexForFourDim((__ubuf__ int32_t *)indexUb.GetPhyAddr(), size, srcStride); | ||
| 474 | - VfGatherBrcForFourDim<uint32_t>((__ubuf__ uint32_t *)dstUb, (__ubuf__ uint32_t *)srcUb, | ||
| 475 | - (__ubuf__ uint32_t *)indexUb.GetPhyAddr(), sizeI[0], sizeI[1], sizeI[2], sizeI[3], srcStrideI[0], | ||
| 476 | - srcStrideI[1], srcStrideI[2], srcStrideI[3], main, tail); | ||
| 477 | - } else { | ||
| 478 | - GenGatherIndexForFourDim((__ubuf__ int16_t *)indexUb.GetPhyAddr(), size, srcStride); | ||
| 479 | - VfGatherBrcForFourDim<uint16_t>((__ubuf__ uint16_t *)dstUb, (__ubuf__ uint16_t *)srcUb, | ||
| 480 | - (__ubuf__ uint16_t *)indexUb.GetPhyAddr(), sizeI[0], sizeI[1], sizeI[2], sizeI[3], srcStrideI[0], | ||
| 481 | - srcStrideI[1], srcStrideI[2], srcStrideI[3], main, tail); | ||
| 482 | - } | ||
| 483 | -} | ||
| 484 | -} // namespace AscendC | ||
| 485 | - | ||
Dimpl/adv_api/detail/pad/broadcast/broadcast_l300_impl.h+0-1472
| @@ -1,1472 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file broadcast_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace BroadcastInternal { | ||
| 24 | -template <typename T> | ||
| 25 | -__simd_callee__ inline void E2bLoad(MicroAPI::RegTensor<T> &dstReg, __ubuf__ T *srcUb) | ||
| 26 | -{ | ||
| 27 | - if constexpr (sizeof(T) == 2) { | ||
| 28 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_E2B_B16>(dstReg, srcUb); | ||
| 29 | - } else { | ||
| 30 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_E2B_B32>(dstReg, srcUb); | ||
| 31 | - } | ||
| 32 | -} | ||
| 33 | - | ||
| 34 | -template <typename T> | ||
| 35 | -__simd_callee__ inline void BrcLoad(MicroAPI::RegTensor<T> &dstReg, __ubuf__ T *srcUb) | ||
| 36 | -{ | ||
| 37 | - if constexpr (sizeof(T) == 2) { | ||
| 38 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_BRC_B16>(dstReg, srcUb); | ||
| 39 | - } else if constexpr (sizeof(T) == 4) { | ||
| 40 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_BRC_B32>(dstReg, srcUb); | ||
| 41 | - } else { | ||
| 42 | - MicroAPI::DataCopy<T, MicroAPI::LoadDist::DIST_BRC_B8>(dstReg, srcUb); | ||
| 43 | - } | ||
| 44 | -} | ||
| 45 | - | ||
| 46 | -template <typename T> | ||
| 47 | -__simd_vf__ inline void BrcDuplicate(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint32_t dstSize) | ||
| 48 | -{ | ||
| 49 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 50 | - uint16_t repeatTimes = CeilDivision(dstSize, VF_LEN); | ||
| 51 | - uint32_t sreg = dstSize; | ||
| 52 | - | ||
| 53 | - MicroAPI::MaskReg pregCnt; | ||
| 54 | - MicroAPI::RegTensor<T> srcReg; | ||
| 55 | - BrcLoad<T>(srcReg, srcUb); | ||
| 56 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 57 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 58 | - MicroAPI::DataCopy(dstUb + i * VF_LEN, srcReg, pregCnt); | ||
| 59 | - } | ||
| 60 | -} | ||
| 61 | - | ||
| 62 | -template <typename T> | ||
| 63 | -__simd_vf__ inline void GenLastGatherIndex(__ubuf__ T *indexUb, uint32_t size1, uint32_t offset) | ||
| 64 | -{ | ||
| 65 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 66 | - MicroAPI::RegTensor<T> indexReg; | ||
| 67 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 68 | - | ||
| 69 | - MicroAPI::Duplicate(indexReg, (T)size1, pregFull); | ||
| 70 | - MicroAPI::Arange(tmpReg, (T)offset); | ||
| 71 | - MicroAPI::Div(indexReg, tmpReg, indexReg, pregFull); | ||
| 72 | - | ||
| 73 | - MicroAPI::DataCopy(indexUb, indexReg, pregFull); | ||
| 74 | -} | ||
| 75 | - | ||
| 76 | -template <typename T> | ||
| 77 | -__simd_vf__ inline void GenNlastGatherIndex(__ubuf__ T *indexUb, uint32_t size1, uint32_t offset) | ||
| 78 | -{ | ||
| 79 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 80 | - MicroAPI::RegTensor<T> indexReg; | ||
| 81 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 82 | - MicroAPI::RegTensor<T> dstReg; | ||
| 83 | - | ||
| 84 | - MicroAPI::Duplicate(indexReg, (T)size1, pregFull); | ||
| 85 | - MicroAPI::Arange(tmpReg, (T)offset); | ||
| 86 | - MicroAPI::Div(dstReg, tmpReg, indexReg, pregFull); | ||
| 87 | - MicroAPI::Mul(dstReg, indexReg, dstReg, pregFull); | ||
| 88 | - MicroAPI::Sub(indexReg, tmpReg, dstReg, pregFull); | ||
| 89 | - | ||
| 90 | - MicroAPI::DataCopy(indexUb, indexReg, pregFull); | ||
| 91 | -} | ||
| 92 | - | ||
| 93 | -template <typename T, typename IndexT> | ||
| 94 | -__simd_vf__ inline void BrcLastGatherOne( | ||
| 95 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ IndexT *indexUb, uint16_t size0, uint16_t size1) | ||
| 96 | -{ | ||
| 97 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 98 | - uint32_t main = size0 * size1; | ||
| 99 | - | ||
| 100 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<IndexT>(); | ||
| 101 | - MicroAPI::MaskReg pregCnt; | ||
| 102 | - MicroAPI::RegTensor<T> srcReg; | ||
| 103 | - MicroAPI::RegTensor<T> dummyReg; | ||
| 104 | - MicroAPI::RegTensor<IndexT> srcReg1; | ||
| 105 | - MicroAPI::RegTensor<IndexT> srcReg2; | ||
| 106 | - MicroAPI::RegTensor<IndexT> indexReg1; | ||
| 107 | - MicroAPI::RegTensor<IndexT> indexReg2; | ||
| 108 | - | ||
| 109 | - MicroAPI::DataCopy(indexReg1, indexUb); | ||
| 110 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 111 | - MicroAPI::DataCopy(indexReg2, indexUb + VF_LEN_HALF); | ||
| 112 | - } | ||
| 113 | - uint32_t sreg = main; | ||
| 114 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 115 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 116 | - MicroAPI::DataCopyGather(srcReg1, srcUb, indexReg1, pregFull); | ||
| 117 | - MicroAPI::DataCopyGather(srcReg2, srcUb, indexReg2, pregFull); | ||
| 118 | - MicroAPI::DeInterleave( | ||
| 119 | - srcReg, dummyReg, (MicroAPI::RegTensor<T> &)srcReg1, (MicroAPI::RegTensor<T> &)srcReg2); | ||
| 120 | - } else { | ||
| 121 | - MicroAPI::DataCopyGather(srcReg, srcUb, indexReg1, pregCnt); | ||
| 122 | - } | ||
| 123 | - MicroAPI::DataCopy(dstUb, srcReg, pregCnt); | ||
| 124 | -} | ||
| 125 | - | ||
| 126 | -template <typename T, typename IndexT> | ||
| 127 | -__simd_vf__ inline void BrcLastGatherTwo( | ||
| 128 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ IndexT *indexUb, uint16_t size0, uint16_t size1) | ||
| 129 | -{ | ||
| 130 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 131 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 132 | - uint16_t factor = VF_LEN / size1; | ||
| 133 | - uint16_t repeatTimes = CeilDivision(size0, factor) - 1; | ||
| 134 | - uint32_t main = factor * size1; | ||
| 135 | - uint32_t mainBlock = main * repeatTimes; | ||
| 136 | - uint32_t offset = factor * repeatTimes; | ||
| 137 | - uint32_t tail = size0 * size1 - mainBlock; | ||
| 138 | - | ||
| 139 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<IndexT>(); | ||
| 140 | - MicroAPI::RegTensor<T> srcReg; | ||
| 141 | - MicroAPI::RegTensor<T> dummyReg; | ||
| 142 | - MicroAPI::RegTensor<IndexT> indexReg1; | ||
| 143 | - MicroAPI::RegTensor<IndexT> indexReg2; | ||
| 144 | - MicroAPI::RegTensor<IndexT> factorReg; | ||
| 145 | - MicroAPI::RegTensor<IndexT> srcReg1; | ||
| 146 | - MicroAPI::RegTensor<IndexT> srcReg2; | ||
| 147 | - MicroAPI::RegTensor<IndexT> dstReg; | ||
| 148 | - MicroAPI::RegTensor<IndexT> tmpReg; | ||
| 149 | - MicroAPI::UnalignReg ureg0; | ||
| 150 | - | ||
| 151 | - MicroAPI::Duplicate(factorReg, (IndexT)factor, pregFull); | ||
| 152 | - MicroAPI::DataCopy(indexReg1, indexUb); | ||
| 153 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 154 | - MicroAPI::DataCopy(indexReg2, indexUb + VF_LEN_HALF); | ||
| 155 | - } | ||
| 156 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 157 | - MicroAPI::Muls(tmpReg, factorReg, (IndexT)i, pregFull); | ||
| 158 | - MicroAPI::Add(dstReg, tmpReg, indexReg1, pregFull); | ||
| 159 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 160 | - MicroAPI::DataCopyGather(srcReg1, srcUb, dstReg, pregFull); | ||
| 161 | - MicroAPI::Add(dstReg, tmpReg, indexReg2, pregFull); | ||
| 162 | - MicroAPI::DataCopyGather(srcReg2, srcUb, dstReg, pregFull); | ||
| 163 | - MicroAPI::DeInterleave( | ||
| 164 | - srcReg, dummyReg, (MicroAPI::RegTensor<T> &)srcReg1, (MicroAPI::RegTensor<T> &)srcReg2); | ||
| 165 | - } else { | ||
| 166 | - MicroAPI::DataCopyGather(srcReg, srcUb, dstReg, pregFull); | ||
| 167 | - } | ||
| 168 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, main); | ||
| 169 | - } | ||
| 170 | - MicroAPI::Adds(dstReg, indexReg1, (IndexT)offset, pregFull); | ||
| 171 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 172 | - MicroAPI::DataCopyGather(srcReg1, srcUb, dstReg, pregFull); | ||
| 173 | - MicroAPI::Adds(dstReg, indexReg2, (IndexT)offset, pregFull); | ||
| 174 | - MicroAPI::DataCopyGather(srcReg2, srcUb, dstReg, pregFull); | ||
| 175 | - MicroAPI::DeInterleave( | ||
| 176 | - srcReg, dummyReg, (MicroAPI::RegTensor<T> &)srcReg1, (MicroAPI::RegTensor<T> &)srcReg2); | ||
| 177 | - } else { | ||
| 178 | - MicroAPI::DataCopyGather(srcReg, srcUb, dstReg, pregFull); | ||
| 179 | - } | ||
| 180 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, tail); | ||
| 181 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 182 | -} | ||
| 183 | - | ||
| 184 | -template <typename T, typename IndexT> | ||
| 185 | -__simd_vf__ inline void BrcNlastGatherOne( | ||
| 186 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ IndexT *indexUb, uint16_t size0, uint16_t size1) | ||
| 187 | -{ | ||
| 188 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 189 | - uint32_t main = size0 * size1; | ||
| 190 | - | ||
| 191 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<IndexT>(); | ||
| 192 | - MicroAPI::MaskReg pregCnt; | ||
| 193 | - MicroAPI::RegTensor<IndexT> indexReg1; | ||
| 194 | - MicroAPI::RegTensor<IndexT> indexReg2; | ||
| 195 | - MicroAPI::RegTensor<IndexT> srcReg1; | ||
| 196 | - MicroAPI::RegTensor<IndexT> srcReg2; | ||
| 197 | - MicroAPI::RegTensor<T> srcReg; | ||
| 198 | - MicroAPI::RegTensor<T> dummyReg; | ||
| 199 | - MicroAPI::UnalignReg ureg0; | ||
| 200 | - | ||
| 201 | - uint32_t sreg = main; | ||
| 202 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 203 | - MicroAPI::DataCopy(indexReg1, indexUb); | ||
| 204 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 205 | - MicroAPI::DataCopy(indexReg2, indexUb + VF_LEN_HALF); | ||
| 206 | - MicroAPI::DataCopyGather(srcReg1, srcUb, indexReg1, pregFull); | ||
| 207 | - MicroAPI::DataCopyGather(srcReg2, srcUb, indexReg2, pregFull); | ||
| 208 | - MicroAPI::DeInterleave( | ||
| 209 | - srcReg, dummyReg, (MicroAPI::RegTensor<T> &)srcReg1, (MicroAPI::RegTensor<T> &)srcReg2); | ||
| 210 | - } else { | ||
| 211 | - MicroAPI::DataCopyGather(srcReg, srcUb, indexReg1, pregCnt); | ||
| 212 | - } | ||
| 213 | - MicroAPI::DataCopy(dstUb, srcReg, pregCnt); | ||
| 214 | -} | ||
| 215 | - | ||
| 216 | -template <typename T, typename IndexT> | ||
| 217 | -__simd_vf__ inline void BrcNlastGatherTwo( | ||
| 218 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ IndexT *indexUb, uint16_t size0, uint16_t size1) | ||
| 219 | -{ | ||
| 220 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 221 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 222 | - uint16_t factor = VF_LEN / size1; | ||
| 223 | - uint16_t repeatTimes = CeilDivision(size0, factor) - 1; | ||
| 224 | - uint32_t main = factor * size1; | ||
| 225 | - uint32_t mainBlock = main * repeatTimes; | ||
| 226 | - uint32_t tail = size0 * size1 - mainBlock; | ||
| 227 | - | ||
| 228 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<IndexT>(); | ||
| 229 | - MicroAPI::RegTensor<IndexT> indexReg1; | ||
| 230 | - MicroAPI::RegTensor<IndexT> indexReg2; | ||
| 231 | - MicroAPI::RegTensor<IndexT> srcReg1; | ||
| 232 | - MicroAPI::RegTensor<IndexT> srcReg2; | ||
| 233 | - MicroAPI::RegTensor<T> srcReg; | ||
| 234 | - MicroAPI::RegTensor<T> dummyReg; | ||
| 235 | - MicroAPI::UnalignReg ureg0; | ||
| 236 | - | ||
| 237 | - MicroAPI::DataCopy(indexReg1, indexUb); | ||
| 238 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 239 | - MicroAPI::DataCopy(indexReg2, indexUb + VF_LEN_HALF); | ||
| 240 | - MicroAPI::DataCopyGather(srcReg1, srcUb, indexReg1, pregFull); | ||
| 241 | - MicroAPI::DataCopyGather(srcReg2, srcUb, indexReg2, pregFull); | ||
| 242 | - MicroAPI::DeInterleave( | ||
| 243 | - srcReg, dummyReg, (MicroAPI::RegTensor<T> &)srcReg1, (MicroAPI::RegTensor<T> &)srcReg2); | ||
| 244 | - } else { | ||
| 245 | - MicroAPI::DataCopyGather(srcReg, srcUb, indexReg1, pregFull); | ||
| 246 | - } | ||
| 247 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 248 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, main); | ||
| 249 | - } | ||
| 250 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, tail); | ||
| 251 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 252 | -} | ||
| 253 | - | ||
| 254 | -template <typename T> | ||
| 255 | -__simd_vf__ inline void BrcLastE2B(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 256 | -{ | ||
| 257 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 258 | - uint16_t factor = VF_LEN / size1; | ||
| 259 | - uint16_t repeatTimes = CeilDivision(size0, factor); | ||
| 260 | - | ||
| 261 | - MicroAPI::MaskReg pregCnt; | ||
| 262 | - MicroAPI::RegTensor<T> srcReg; | ||
| 263 | - | ||
| 264 | - uint32_t sreg = size0 * size1; | ||
| 265 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 266 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 267 | - E2bLoad<T>(srcReg, srcUb + i * DEFAULT_BLK_NUM); | ||
| 268 | - MicroAPI::DataCopy(dstUb + i * VF_LEN, srcReg, pregCnt); | ||
| 269 | - } | ||
| 270 | -} | ||
| 271 | - | ||
| 272 | -template <typename T> | ||
| 273 | -__simd_vf__ inline void BrcLastE2BLargerThanVL( | ||
| 274 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1, uint16_t size2, uint16_t srcStride0) | ||
| 275 | -{ | ||
| 276 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 277 | - uint16_t factor = VF_LEN / size2; | ||
| 278 | - uint16_t repeatTimes = CeilDivision(size1, factor); | ||
| 279 | - uint32_t preg = size1 * size2; | ||
| 280 | - uint32_t sreg; | ||
| 281 | - MicroAPI::MaskReg pregCnt; | ||
| 282 | - MicroAPI::RegTensor<T> srcReg; | ||
| 283 | - | ||
| 284 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 285 | - sreg = preg; | ||
| 286 | - for (uint16_t j = 0; j < repeatTimes; ++j) { | ||
| 287 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 288 | - E2bLoad<T>(srcReg, srcUb + j * DEFAULT_BLK_NUM + i * srcStride0); | ||
| 289 | - MicroAPI::DataCopy(dstUb + i * size1 * size2 + j * VF_LEN, srcReg, pregCnt); | ||
| 290 | - } | ||
| 291 | - } | ||
| 292 | -} | ||
| 293 | - | ||
| 294 | -template <typename T> | ||
| 295 | -__simd_vf__ inline void BrcLastE2BLessThanVL( | ||
| 296 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1, uint16_t size2, uint16_t srcStride0) | ||
| 297 | -{ | ||
| 298 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 299 | - uint32_t preg = size1 * size2; | ||
| 300 | - uint32_t sreg; | ||
| 301 | - MicroAPI::MaskReg pregCnt; | ||
| 302 | - MicroAPI::RegTensor<T> srcReg; | ||
| 303 | - sreg = preg; | ||
| 304 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 305 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 306 | - E2bLoad<T>(srcReg, srcUb + i * srcStride0); | ||
| 307 | - MicroAPI::DataCopy(dstUb + i * size1 * size2, srcReg, pregCnt); | ||
| 308 | - } | ||
| 309 | -} | ||
| 310 | - | ||
| 311 | -template <typename T> | ||
| 312 | -__simd_vf__ inline void BrcLastE2B(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1, | ||
| 313 | - uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1) | ||
| 314 | -{ | ||
| 315 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 316 | - uint16_t factor = VF_LEN / size3; | ||
| 317 | - uint16_t repeatTimes = CeilDivision(size2, factor); | ||
| 318 | - uint32_t preg = size2 * size3; | ||
| 319 | - uint32_t sreg; | ||
| 320 | - MicroAPI::MaskReg pregCnt; | ||
| 321 | - MicroAPI::RegTensor<T> srcReg; | ||
| 322 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 323 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 324 | - sreg = preg; | ||
| 325 | - for (uint16_t k = 0; k < repeatTimes; ++k) { | ||
| 326 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 327 | - E2bLoad<T>(srcReg, srcUb + i * srcStride0 + j * srcStride1 + k * DEFAULT_BLK_NUM); | ||
| 328 | - MicroAPI::DataCopy( | ||
| 329 | - dstUb + i * size1 * size2 * size3 + j * size2 * size3 + k * VF_LEN, srcReg, pregCnt); | ||
| 330 | - } | ||
| 331 | - } | ||
| 332 | - } | ||
| 333 | -} | ||
| 334 | - | ||
| 335 | -template <typename T> | ||
| 336 | -__simd_vf__ inline void BrcNlastGatherBOne( | ||
| 337 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ uint32_t *indexUb, uint16_t size0, uint16_t size1) | ||
| 338 | -{ | ||
| 339 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 340 | - uint32_t main = size0 * size1; | ||
| 341 | - | ||
| 342 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 343 | - MicroAPI::MaskReg pregCnt; | ||
| 344 | - MicroAPI::RegTensor<T> srcReg; | ||
| 345 | - MicroAPI::RegTensor<uint32_t> indexReg; | ||
| 346 | - | ||
| 347 | - MicroAPI::DataCopy(indexReg, indexUb); | ||
| 348 | - MicroAPI::DataCopyGatherB(srcReg, srcUb, indexReg, pregFull); | ||
| 349 | - uint32_t sreg = main; | ||
| 350 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 351 | - MicroAPI::DataCopy(dstUb, srcReg, pregCnt); | ||
| 352 | -} | ||
| 353 | - | ||
| 354 | -template <typename T> | ||
| 355 | -__simd_vf__ inline void BrcNlastGatherBTwo( | ||
| 356 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, __ubuf__ uint32_t *indexUb, uint16_t size0, uint16_t size1) | ||
| 357 | -{ | ||
| 358 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 359 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 360 | - uint16_t factor = VF_LEN / size1; | ||
| 361 | - uint16_t repeatTimes = CeilDivision(size0, factor) - 1; | ||
| 362 | - uint32_t main = factor * size1; | ||
| 363 | - uint32_t mainBlock = main * repeatTimes; | ||
| 364 | - uint32_t tail = size0 * size1 - mainBlock; | ||
| 365 | - | ||
| 366 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 367 | - MicroAPI::MaskReg pregCnt; | ||
| 368 | - MicroAPI::RegTensor<T> srcReg; | ||
| 369 | - MicroAPI::RegTensor<uint32_t> indexReg; | ||
| 370 | - | ||
| 371 | - MicroAPI::DataCopy(indexReg, indexUb); | ||
| 372 | - MicroAPI::DataCopyGatherB(srcReg, srcUb, indexReg, pregFull); | ||
| 373 | - uint32_t sreg = main; | ||
| 374 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 375 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 376 | - MicroAPI::DataCopy(dstUb + i * main, srcReg, pregCnt); | ||
| 377 | - } | ||
| 378 | - sreg = tail; | ||
| 379 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 380 | - MicroAPI::DataCopy(dstUb + mainBlock, srcReg, pregCnt); | ||
| 381 | -} | ||
| 382 | - | ||
| 383 | -template <typename T> | ||
| 384 | -__simd_vf__ inline void BrcLastLessThanVLAligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 385 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 386 | -{ | ||
| 387 | - MicroAPI::MaskReg pregCnt; | ||
| 388 | - MicroAPI::RegTensor<T> srcReg; | ||
| 389 | - | ||
| 390 | - uint32_t sreg = size2; | ||
| 391 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 392 | - for (uint16_t i = 0; i < size1; ++i) { | ||
| 393 | - for (uint16_t j = 0; j < size0; ++j) { | ||
| 394 | - BrcLoad<T>(srcReg, srcUb + j * srcStride0 + i * srcStride1); | ||
| 395 | - MicroAPI::DataCopy(dstUb + j * size1 * size2 + i * size2, srcReg, pregCnt); | ||
| 396 | - } | ||
| 397 | - } | ||
| 398 | -} | ||
| 399 | - | ||
| 400 | -template <typename T> | ||
| 401 | -__simd_vf__ inline void BrcLastLessThanVLAligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 402 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 403 | -{ | ||
| 404 | - MicroAPI::MaskReg pregCnt; | ||
| 405 | - MicroAPI::RegTensor<T> srcReg; | ||
| 406 | - | ||
| 407 | - uint32_t sreg = size3; | ||
| 408 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 409 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 410 | - for (uint16_t j = 0; j < size2; ++j) { | ||
| 411 | - for (uint16_t k = 0; k < size1; ++k) { | ||
| 412 | - BrcLoad<T>(srcReg, srcUb + i * srcStride0 + j * srcStride2 + k * srcStride1); | ||
| 413 | - MicroAPI::DataCopy( | ||
| 414 | - dstUb + i * size1 * size2 * size3 + k * size2 * size3 + j * size3, srcReg, pregCnt); | ||
| 415 | - } | ||
| 416 | - } | ||
| 417 | - } | ||
| 418 | -} | ||
| 419 | - | ||
| 420 | -template <typename T> | ||
| 421 | -__simd_vf__ inline void BrcNlastLessThanVLAligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 422 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 423 | -{ | ||
| 424 | - MicroAPI::MaskReg pregCnt; | ||
| 425 | - MicroAPI::RegTensor<T> srcReg; | ||
| 426 | - | ||
| 427 | - uint32_t sreg = size3; | ||
| 428 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 429 | - for (uint16_t i = 0; i < size1; ++i) { | ||
| 430 | - for (uint16_t j = 0; j < size0; ++j) { | ||
| 431 | - for (uint16_t k = 0; k < size2; ++k) { | ||
| 432 | - MicroAPI::DataCopy(srcReg, srcUb + i * srcStride1 + j * srcStride0 + k * srcStride2); | ||
| 433 | - MicroAPI::DataCopy( | ||
| 434 | - dstUb + j * size1 * size2 * size3 + i * size2 * size3 + k * size3, srcReg, pregCnt); | ||
| 435 | - } | ||
| 436 | - } | ||
| 437 | - } | ||
| 438 | -} | ||
| 439 | - | ||
| 440 | -template <typename T> | ||
| 441 | -__simd_vf__ inline void BrcLastLessThanVLUnaligned( | ||
| 442 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 443 | -{ | ||
| 444 | - MicroAPI::MaskReg pregCnt; | ||
| 445 | - MicroAPI::RegTensor<T> srcReg; | ||
| 446 | - MicroAPI::UnalignReg ureg0; | ||
| 447 | - | ||
| 448 | - uint32_t sreg = size1; | ||
| 449 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 450 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 451 | - BrcLoad<T>(srcReg, srcUb + i); | ||
| 452 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 453 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size1); | ||
| 454 | - } | ||
| 455 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 456 | -} | ||
| 457 | - | ||
| 458 | -template <typename T> | ||
| 459 | -__simd_vf__ inline void BrcLastLessThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 460 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 461 | -{ | ||
| 462 | - MicroAPI::MaskReg pregCnt; | ||
| 463 | - MicroAPI::RegTensor<T> srcReg; | ||
| 464 | - MicroAPI::UnalignReg ureg0; | ||
| 465 | - | ||
| 466 | - uint32_t sreg = size2; | ||
| 467 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 468 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 469 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 470 | - BrcLoad<T>(srcReg, srcUb + j * srcStride1 + i * srcStride0); | ||
| 471 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 472 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size2); | ||
| 473 | - } | ||
| 474 | - } | ||
| 475 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 476 | -} | ||
| 477 | - | ||
| 478 | -template <typename T> | ||
| 479 | -__simd_vf__ inline void BrcLastLessThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 480 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 481 | -{ | ||
| 482 | - MicroAPI::MaskReg pregCnt; | ||
| 483 | - MicroAPI::RegTensor<T> srcReg; | ||
| 484 | - MicroAPI::UnalignReg ureg0; | ||
| 485 | - | ||
| 486 | - uint32_t sreg = size3; | ||
| 487 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 488 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 489 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 490 | - for (uint16_t k = 0; k < size2; ++k) { | ||
| 491 | - BrcLoad<T>(srcReg, srcUb + i * srcStride0 + j * srcStride1 + k * srcStride2); | ||
| 492 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 493 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size3); | ||
| 494 | - } | ||
| 495 | - } | ||
| 496 | - } | ||
| 497 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 498 | -} | ||
| 499 | - | ||
| 500 | -template <typename T> | ||
| 501 | -__simd_vf__ inline void BrcNlastLessThanVLUnaligned( | ||
| 502 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 503 | -{ | ||
| 504 | - MicroAPI::MaskReg pregCnt; | ||
| 505 | - MicroAPI::RegTensor<T> srcReg; | ||
| 506 | - MicroAPI::UnalignReg ureg0; | ||
| 507 | - | ||
| 508 | - uint32_t sreg = size1; | ||
| 509 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 510 | - MicroAPI::DataCopy(srcReg, srcUb); | ||
| 511 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 512 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size1); | ||
| 513 | - } | ||
| 514 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 515 | -} | ||
| 516 | - | ||
| 517 | -template <typename T> | ||
| 518 | -__simd_vf__ inline void BrcNlastLessThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 519 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 520 | -{ | ||
| 521 | - MicroAPI::MaskReg pregCnt; | ||
| 522 | - MicroAPI::RegTensor<T> srcReg; | ||
| 523 | - MicroAPI::UnalignReg ureg0, ureg1; | ||
| 524 | - | ||
| 525 | - uint32_t sreg = size2; | ||
| 526 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 527 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 528 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 529 | - auto srcUbT = srcUb + i * srcStride0 + j * srcStride1; | ||
| 530 | - MicroAPI::DataCopyUnAlignPre(ureg0, srcUbT); | ||
| 531 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, srcUbT, size2); | ||
| 532 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, size2); | ||
| 533 | - } | ||
| 534 | - } | ||
| 535 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg1, 0); | ||
| 536 | -} | ||
| 537 | - | ||
| 538 | -template <typename T> | ||
| 539 | -__simd_vf__ inline void BrcNlastLessThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 540 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 541 | -{ | ||
| 542 | - MicroAPI::MaskReg pregCnt; | ||
| 543 | - MicroAPI::RegTensor<T> srcReg; | ||
| 544 | - MicroAPI::UnalignReg ureg0, ureg1; | ||
| 545 | - | ||
| 546 | - uint32_t sreg = size3; | ||
| 547 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 548 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 549 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 550 | - for (uint16_t k = 0; k < size2; ++k) { | ||
| 551 | - __ubuf__ T *srcUbTmp = srcUb + i * srcStride0 + j * srcStride1 + k * srcStride2; | ||
| 552 | - MicroAPI::DataCopyUnAlignPre(ureg0, srcUbTmp); | ||
| 553 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, srcUbTmp, size3); | ||
| 554 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, size3); | ||
| 555 | - } | ||
| 556 | - } | ||
| 557 | - } | ||
| 558 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg1, 0); | ||
| 559 | -} | ||
| 560 | - | ||
| 561 | -template <typename T> | ||
| 562 | -__simd_vf__ inline void BrcLastLargerThanVLAligned( | ||
| 563 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 564 | -{ | ||
| 565 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 566 | - uint16_t factor = CeilDivision(size1, VF_LEN); | ||
| 567 | - | ||
| 568 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 569 | - MicroAPI::MaskReg pregCnt; | ||
| 570 | - MicroAPI::RegTensor<T> srcReg; | ||
| 571 | - | ||
| 572 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 573 | - BrcLoad<T>(srcReg, srcUb + i); | ||
| 574 | - uint32_t sreg = size1; | ||
| 575 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 576 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 577 | - MicroAPI::DataCopy(dstUb + i * size1 + j * VF_LEN, srcReg, pregCnt); | ||
| 578 | - } | ||
| 579 | - } | ||
| 580 | -} | ||
| 581 | - | ||
| 582 | -template <typename T> | ||
| 583 | -__simd_vf__ inline void BrcLastLargerThanVLAligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 584 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 585 | -{ | ||
| 586 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 587 | - uint16_t factor = CeilDivision(size2, VF_LEN); | ||
| 588 | - | ||
| 589 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 590 | - MicroAPI::MaskReg pregCnt; | ||
| 591 | - MicroAPI::RegTensor<T> srcReg; | ||
| 592 | - | ||
| 593 | - for (uint16_t i = 0; i < size1; ++i) { | ||
| 594 | - for (uint16_t j = 0; j < size0; ++j) { | ||
| 595 | - BrcLoad<T>(srcReg, srcUb + i * srcStride1 + j * srcStride0); | ||
| 596 | - uint32_t sreg = size2; | ||
| 597 | - for (uint16_t k = 0; k < factor; ++k) { | ||
| 598 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 599 | - MicroAPI::DataCopy(dstUb + j * size1 * size2 + i * size2 + k * VF_LEN, srcReg, pregCnt); | ||
| 600 | - } | ||
| 601 | - } | ||
| 602 | - } | ||
| 603 | -} | ||
| 604 | - | ||
| 605 | -template <typename T> | ||
| 606 | -__simd_vf__ inline void BrcLastLargerThanVLAligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 607 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 608 | -{ | ||
| 609 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 610 | - uint16_t factor = CeilDivision(size3, VF_LEN); | ||
| 611 | - | ||
| 612 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 613 | - MicroAPI::MaskReg pregCnt; | ||
| 614 | - MicroAPI::RegTensor<T> srcReg; | ||
| 615 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 616 | - for (uint16_t j = 0; j < size2; ++j) { | ||
| 617 | - uint32_t sreg = size3; | ||
| 618 | - for (uint16_t k = 0; k < factor; ++k) { | ||
| 619 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 620 | - for (uint16_t t = 0; t < size1; ++t) { | ||
| 621 | - BrcLoad<T>(srcReg, srcUb + i * srcStride0 + j * srcStride2 + t * srcStride1); | ||
| 622 | - MicroAPI::DataCopy( | ||
| 623 | - dstUb + i * size1 * size2 * size3 + t * size2 * size3 + j * size3 + k * VF_LEN, | ||
| 624 | - srcReg, | ||
| 625 | - pregCnt); | ||
| 626 | - } | ||
| 627 | - } | ||
| 628 | - } | ||
| 629 | - } | ||
| 630 | -} | ||
| 631 | - | ||
| 632 | -template <typename T> | ||
| 633 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithBlock( | ||
| 634 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 635 | -{ | ||
| 636 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 637 | - uint16_t factor = CeilDivision(size1, VF_LEN); | ||
| 638 | - | ||
| 639 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 640 | - MicroAPI::MaskReg pregCnt; | ||
| 641 | - MicroAPI::RegTensor<T> srcReg; | ||
| 642 | - | ||
| 643 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 644 | - uint32_t sreg = size1; | ||
| 645 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 646 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 647 | - MicroAPI::DataCopy(srcReg, srcUb + j * VF_LEN); | ||
| 648 | - MicroAPI::DataCopy(dstUb + i * size1 + j * VF_LEN, srcReg, pregCnt); | ||
| 649 | - } | ||
| 650 | - } | ||
| 651 | -} | ||
| 652 | - | ||
| 653 | -template <typename T> | ||
| 654 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithBlock(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 655 | - uint16_t size0, uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 656 | -{ | ||
| 657 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 658 | - uint16_t factor = CeilDivision(size2, VF_LEN); | ||
| 659 | - uint16_t jStride = srcStride1 == 0 ? 0 : VF_LEN; | ||
| 660 | - | ||
| 661 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 662 | - MicroAPI::MaskReg pregCnt; | ||
| 663 | - MicroAPI::RegTensor<T> srcReg; | ||
| 664 | - | ||
| 665 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 666 | - uint32_t sreg = size2; | ||
| 667 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 668 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 669 | - for (uint16_t k = 0; k < size1; ++k) { | ||
| 670 | - MicroAPI::DataCopy(srcReg, srcUb + k * srcStride1 + i * srcStride0 + j * VF_LEN); | ||
| 671 | - MicroAPI::DataCopy(dstUb + i * size1 * size2 + k * size2 + j * VF_LEN, srcReg, pregCnt); | ||
| 672 | - } | ||
| 673 | - } | ||
| 674 | - } | ||
| 675 | -} | ||
| 676 | - | ||
| 677 | -template <typename T> | ||
| 678 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithBlock(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 679 | - uint16_t size0, uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, | ||
| 680 | - uint16_t srcStride2) | ||
| 681 | -{ | ||
| 682 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 683 | - uint16_t factor = CeilDivision(size3, VF_LEN); | ||
| 684 | - | ||
| 685 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 686 | - MicroAPI::MaskReg pregCnt; | ||
| 687 | - MicroAPI::RegTensor<T> srcReg; | ||
| 688 | - for (uint16_t i = 0; i < size1; ++i) { | ||
| 689 | - uint32_t sreg = size3; | ||
| 690 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 691 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 692 | - for (uint16_t k = 0; k < size0; ++k) { | ||
| 693 | - for (uint16_t t = 0; t < size2; ++t) { | ||
| 694 | - MicroAPI::DataCopy(srcReg, srcUb + j * VF_LEN + | ||
| 695 | - i * srcStride1 + k * srcStride0 + t * srcStride2); | ||
| 696 | - MicroAPI::DataCopy(dstUb + k * size1 * size2 * size3 + | ||
| 697 | - i * size2 * size3 + t * size3 + j * VF_LEN, srcReg, pregCnt); | ||
| 698 | - } | ||
| 699 | - } | ||
| 700 | - } | ||
| 701 | - } | ||
| 702 | -} | ||
| 703 | - | ||
| 704 | -template <typename T> | ||
| 705 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithVL( | ||
| 706 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 707 | -{ | ||
| 708 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 709 | - uint16_t factor = CeilDivision(size1, VF_LEN); | ||
| 710 | - | ||
| 711 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 712 | - MicroAPI::RegTensor<T> srcReg; | ||
| 713 | - | ||
| 714 | - for (uint16_t i = 0; i < factor; ++i) { | ||
| 715 | - MicroAPI::DataCopy(srcReg, srcUb + i * VF_LEN); | ||
| 716 | - for (uint16_t j = 0; j < size0; ++j) { | ||
| 717 | - MicroAPI::DataCopy(dstUb + i * VF_LEN + j * size1, srcReg, pregFull); | ||
| 718 | - } | ||
| 719 | - } | ||
| 720 | -} | ||
| 721 | - | ||
| 722 | -template <typename T> | ||
| 723 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithVL(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 724 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 725 | -{ | ||
| 726 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 727 | - uint16_t factor = CeilDivision(size2, VF_LEN); | ||
| 728 | - | ||
| 729 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 730 | - MicroAPI::RegTensor<T> srcReg; | ||
| 731 | - | ||
| 732 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 733 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 734 | - for (uint16_t k = 0; k < size1; ++k) { | ||
| 735 | - MicroAPI::DataCopy(srcReg, srcUb + i * srcStride0 + j * VF_LEN + k * srcStride1); | ||
| 736 | - MicroAPI::DataCopy(dstUb + j * VF_LEN + k * size2 + i * size1 * size2, srcReg, pregFull); | ||
| 737 | - } | ||
| 738 | - } | ||
| 739 | - } | ||
| 740 | -} | ||
| 741 | - | ||
| 742 | -template <typename T> | ||
| 743 | -__simd_vf__ inline void BrcNlastLargerThanVLAlignedWithVL(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 744 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 745 | -{ | ||
| 746 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 747 | - uint16_t factor = CeilDivision(size3, VF_LEN); | ||
| 748 | - | ||
| 749 | - MicroAPI::MaskReg pregFull = MicroAPI::CreateMask<T>(); | ||
| 750 | - MicroAPI::RegTensor<T> srcReg; | ||
| 751 | - | ||
| 752 | - for (uint16_t i = 0; i < size1; ++i) { | ||
| 753 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 754 | - for (uint16_t k = 0; k < size0; ++k) { | ||
| 755 | - for (uint16_t t = 0; t < size2; ++t) { | ||
| 756 | - MicroAPI::DataCopy(srcReg, srcUb + i * srcStride1 + | ||
| 757 | - j * VF_LEN + k * srcStride0 + t * srcStride2); | ||
| 758 | - MicroAPI::DataCopy(dstUb + j * VF_LEN + t * size3 + | ||
| 759 | - i * size2 * size3 + k * size1 * size2 * size3, srcReg, pregFull); | ||
| 760 | - } | ||
| 761 | - } | ||
| 762 | - } | ||
| 763 | - } | ||
| 764 | -} | ||
| 765 | - | ||
| 766 | -template <typename T> | ||
| 767 | -__simd_vf__ inline void BrcLastLargerThanVLUnaligned( | ||
| 768 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 769 | -{ | ||
| 770 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 771 | - uint16_t factor = size1 / VF_LEN; | ||
| 772 | - uint32_t size1tail = size1 - factor * VF_LEN; | ||
| 773 | - | ||
| 774 | - MicroAPI::MaskReg pregCnt; | ||
| 775 | - MicroAPI::RegTensor<T> srcReg; | ||
| 776 | - MicroAPI::UnalignReg ureg0; | ||
| 777 | - | ||
| 778 | - uint32_t sreg = size1tail; | ||
| 779 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 780 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 781 | - BrcLoad<T>(srcReg, srcUb + i); | ||
| 782 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 783 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, VF_LEN); | ||
| 784 | - } | ||
| 785 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 786 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size1tail); | ||
| 787 | - } | ||
| 788 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 789 | -} | ||
| 790 | - | ||
| 791 | -template <typename T> | ||
| 792 | -__simd_vf__ inline void BrcLastLargerThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 793 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 794 | -{ | ||
| 795 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 796 | - uint16_t factor = size2 / VF_LEN; | ||
| 797 | - uint32_t size2tail = size2 - factor * VF_LEN; | ||
| 798 | - | ||
| 799 | - MicroAPI::MaskReg pregCnt; | ||
| 800 | - MicroAPI::RegTensor<T> srcReg; | ||
| 801 | - MicroAPI::UnalignReg ureg0; | ||
| 802 | - | ||
| 803 | - uint32_t sreg = size2tail; | ||
| 804 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 805 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 806 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 807 | - BrcLoad<T>(srcReg, srcUb + j * srcStride1 + i * srcStride0); | ||
| 808 | - for (uint16_t k = 0; k < factor; ++k) { | ||
| 809 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, VF_LEN); | ||
| 810 | - } | ||
| 811 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 812 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size2tail); | ||
| 813 | - } | ||
| 814 | - } | ||
| 815 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 816 | -} | ||
| 817 | - | ||
| 818 | -template <typename T> | ||
| 819 | -__simd_vf__ inline void BrcLastLargerThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 820 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 821 | -{ | ||
| 822 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 823 | - uint16_t factor = size3 / VF_LEN; | ||
| 824 | - uint32_t size3tail = size3 - factor * VF_LEN; | ||
| 825 | - | ||
| 826 | - MicroAPI::MaskReg pregCnt; | ||
| 827 | - MicroAPI::RegTensor<T> srcReg; | ||
| 828 | - MicroAPI::UnalignReg ureg0; | ||
| 829 | - | ||
| 830 | - uint32_t sreg = size3tail; | ||
| 831 | - pregCnt = MicroAPI::UpdateMask<T>(sreg); | ||
| 832 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 833 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 834 | - for (uint16_t k = 0; k < size2; ++k) { | ||
| 835 | - BrcLoad<T>(srcReg, srcUb + i * srcStride0 + j * srcStride1 + k * srcStride2); | ||
| 836 | - for (uint16_t t = 0; t < factor; ++t) { | ||
| 837 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, VF_LEN); | ||
| 838 | - } | ||
| 839 | - MicroAPI::Duplicate(srcReg, srcReg, pregCnt); | ||
| 840 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, size3tail); | ||
| 841 | - } | ||
| 842 | - } | ||
| 843 | - } | ||
| 844 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 845 | -} | ||
| 846 | - | ||
| 847 | -template <typename T> | ||
| 848 | -__simd_vf__ inline void BrcNlastLargerThanVLUnaligned( | ||
| 849 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, uint16_t size1) | ||
| 850 | -{ | ||
| 851 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 852 | - uint16_t factor = size1 / VF_LEN; | ||
| 853 | - uint32_t size1tail = size1 - factor * VF_LEN; | ||
| 854 | - | ||
| 855 | - MicroAPI::RegTensor<T> srcReg; | ||
| 856 | - MicroAPI::RegTensor<T> tmpReg; | ||
| 857 | - MicroAPI::UnalignReg ureg0; | ||
| 858 | - | ||
| 859 | - uint32_t sreg = size1tail; | ||
| 860 | - MicroAPI::DataCopy(tmpReg, srcUb + factor * VF_LEN); | ||
| 861 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 862 | - for (uint16_t j = 0; j < factor; ++j) { | ||
| 863 | - MicroAPI::DataCopy(srcReg, srcUb + j * VF_LEN); | ||
| 864 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg0, VF_LEN); | ||
| 865 | - } | ||
| 866 | - MicroAPI::DataCopyUnAlign(dstUb, tmpReg, ureg0, size1tail); | ||
| 867 | - } | ||
| 868 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg0, 0); | ||
| 869 | -} | ||
| 870 | - | ||
| 871 | -template <typename T> | ||
| 872 | -__simd_vf__ inline void BrcNlastLargerThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 873 | - uint16_t size1, uint16_t size2, uint16_t srcStride0, uint16_t srcStride1) | ||
| 874 | -{ | ||
| 875 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 876 | - uint16_t factor = size2 / VF_LEN; | ||
| 877 | - uint32_t size2tail = size2 - factor * VF_LEN; | ||
| 878 | - | ||
| 879 | - MicroAPI::RegTensor<T> srcReg; | ||
| 880 | - MicroAPI::UnalignReg ureg0, ureg1; | ||
| 881 | - | ||
| 882 | - uint32_t sreg = size2tail; | ||
| 883 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 884 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 885 | - __ubuf__ T *tmpSrcUb = srcUb + i * srcStride0 + j * srcStride1; | ||
| 886 | - MicroAPI::DataCopyUnAlignPre(ureg0, tmpSrcUb); | ||
| 887 | - for (uint16_t k = 0; k < factor; ++k) { | ||
| 888 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, tmpSrcUb, VF_LEN); | ||
| 889 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, VF_LEN); | ||
| 890 | - } | ||
| 891 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, tmpSrcUb, sreg); | ||
| 892 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, sreg); | ||
| 893 | - } | ||
| 894 | - } | ||
| 895 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg1, 0); | ||
| 896 | -} | ||
| 897 | - | ||
| 898 | -template <typename T> | ||
| 899 | -__simd_vf__ inline void BrcNlastLargerThanVLUnaligned(__ubuf__ T *dstUb, __ubuf__ T *srcUb, uint16_t size0, | ||
| 900 | - uint16_t size1, uint16_t size2, uint16_t size3, uint16_t srcStride0, uint16_t srcStride1, uint16_t srcStride2) | ||
| 901 | -{ | ||
| 902 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 903 | - uint16_t factor = size3 / VF_LEN; | ||
| 904 | - uint32_t size3tail = size3 - factor * VF_LEN; | ||
| 905 | - | ||
| 906 | - MicroAPI::RegTensor<T> srcReg; | ||
| 907 | - MicroAPI::UnalignReg ureg0, ureg1; | ||
| 908 | - | ||
| 909 | - uint32_t sreg = size3tail; | ||
| 910 | - for (uint16_t i = 0; i < size0; ++i) { | ||
| 911 | - for (uint16_t j = 0; j < size1; ++j) { | ||
| 912 | - for (uint16_t k = 0; k < size2; ++k) { | ||
| 913 | - __ubuf__ T *tmpSrcUb = srcUb + i * srcStride0 + j * srcStride1 + k * srcStride2; | ||
| 914 | - MicroAPI::DataCopyUnAlignPre(ureg0, tmpSrcUb); | ||
| 915 | - for (uint16_t t = 0; t < factor; ++t) { | ||
| 916 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, tmpSrcUb, VF_LEN); | ||
| 917 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, VF_LEN); | ||
| 918 | - } | ||
| 919 | - MicroAPI::DataCopyUnAlign(srcReg, ureg0, tmpSrcUb, sreg); | ||
| 920 | - MicroAPI::DataCopyUnAlign(dstUb, srcReg, ureg1, sreg); | ||
| 921 | - } | ||
| 922 | - } | ||
| 923 | - } | ||
| 924 | - MicroAPI::DataCopyUnAlignPost(dstUb, ureg1, 0); | ||
| 925 | -} | ||
| 926 | - | ||
| 927 | -template <typename T, int32_t constRank = -1> | ||
| 928 | -__aicore__ inline bool BrcLastWrapperForTwoDim( | ||
| 929 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, const uint32_t *dstShape) | ||
| 930 | -{ | ||
| 931 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 932 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 933 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 934 | - using GatherIndexType = typename ExtractSignedTypeBySize<sizeof(T)>::T; | ||
| 935 | - using BrcIndexType = typename ExtractIndexTypeBySize<sizeof(T)>::T; | ||
| 936 | - | ||
| 937 | - uint16_t sizeI[2]; | ||
| 938 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 939 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 940 | - | ||
| 941 | - if (sizeI[1] == oneBlockElementNum && sizeof(T) != sizeof(uint8_t)) { | ||
| 942 | - BrcLastE2B(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 943 | - } else if (sizeI[1] < VF_LEN_HALF) { | ||
| 944 | - LocalTensor<T> indexLocal; | ||
| 945 | - PopStackBuffer<T, TPosition::LCM>(indexLocal); | ||
| 946 | - __ubuf__ GatherIndexType *indexUb1 = (__ubuf__ GatherIndexType *)indexLocal.GetPhyAddr(); | ||
| 947 | - __ubuf__ GatherIndexType *indexUb2 = (__ubuf__ GatherIndexType *)indexLocal.GetPhyAddr(VF_LEN); | ||
| 948 | - GenLastGatherIndex<GatherIndexType>(indexUb1, sizeI[1], 0); | ||
| 949 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 950 | - GenLastGatherIndex<GatherIndexType>(indexUb2, sizeI[1], VF_LEN_HALF); | ||
| 951 | - } | ||
| 952 | - __ubuf__ BrcIndexType *indexUb = (__ubuf__ BrcIndexType *)indexLocal.GetPhyAddr(); | ||
| 953 | - if (sizeI[0] * sizeI[1] < VF_LEN) { | ||
| 954 | - BrcLastGatherOne<T, BrcIndexType>(dstUb, srcUb, indexUb, sizeI[0], sizeI[1]); | ||
| 955 | - } else if (sizeI[1] < VF_LEN) { | ||
| 956 | - BrcLastGatherTwo<T, BrcIndexType>(dstUb, srcUb, indexUb, sizeI[0], sizeI[1]); | ||
| 957 | - } | ||
| 958 | - } else if (sizeI[1] <= VF_LEN) { | ||
| 959 | - BrcLastLessThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 960 | - } else { | ||
| 961 | - if (sizeI[1] % oneBlockElementNum == 0) { | ||
| 962 | - BrcLastLargerThanVLAligned<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 963 | - } else { | ||
| 964 | - if constexpr (constRank == -1) { | ||
| 965 | - return true; | ||
| 966 | - } else { | ||
| 967 | - BrcLastLargerThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 968 | - } | ||
| 969 | - } | ||
| 970 | - } | ||
| 971 | - return false; | ||
| 972 | -} | ||
| 973 | - | ||
| 974 | -template <typename T, int32_t constRank = -1> | ||
| 975 | -__aicore__ inline bool BrcLastWrapperForThreeDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 976 | - const uint32_t *dstShape, const uint32_t *srcStride) | ||
| 977 | -{ | ||
| 978 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 979 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 980 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 981 | - uint16_t sizeI[3]; | ||
| 982 | - uint16_t stride[3]; | ||
| 983 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 984 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 985 | - sizeI[2] = static_cast<uint16_t>(dstShape[2]); | ||
| 986 | - stride[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 987 | - stride[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 988 | - stride[2] = static_cast<uint16_t>(srcStride[2]); | ||
| 989 | - | ||
| 990 | - if (sizeI[2] == oneBlockElementNum && sizeof(T) != sizeof(uint8_t) && sizeI[1] * sizeI[2] > VF_LEN_HALF && | ||
| 991 | - sizeI[1] % DEFAULT_BLK_NUM == 0 && stride[1] != 0) { | ||
| 992 | - if (sizeI[1] * sizeI[2] > VF_LEN) { | ||
| 993 | - BrcLastE2BLargerThanVL(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0]); | ||
| 994 | - } else { | ||
| 995 | - BrcLastE2BLessThanVL(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0]); | ||
| 996 | - } | ||
| 997 | - } else if (sizeI[2] < VF_LEN_HALF && sizeof(T) != sizeof(uint8_t)) { | ||
| 998 | - uint32_t newDstShape[3] = {dstShape[0], dstShape[1], dstShape[2]}; | ||
| 999 | - uint32_t newSrcStride[3] = {srcStride[0], srcStride[1], srcStride[2]}; | ||
| 1000 | - GatherWrapper(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1001 | - } else if (sizeI[2] <= VF_LEN) { | ||
| 1002 | - if (sizeI[2] % oneBlockElementNum == 0) { | ||
| 1003 | - BrcLastLessThanVLAligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1004 | - } else { | ||
| 1005 | - if constexpr (constRank == -1) { | ||
| 1006 | - return true; | ||
| 1007 | - } else { | ||
| 1008 | - BrcLastLessThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1009 | - } | ||
| 1010 | - } | ||
| 1011 | - } else { | ||
| 1012 | - if (sizeI[2] % oneBlockElementNum == 0) { | ||
| 1013 | - BrcLastLargerThanVLAligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1014 | - } else { | ||
| 1015 | - if constexpr (constRank == -1) { | ||
| 1016 | - return true; | ||
| 1017 | - } else { | ||
| 1018 | - BrcLastLargerThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1019 | - } | ||
| 1020 | - } | ||
| 1021 | - } | ||
| 1022 | - return false; | ||
| 1023 | -} | ||
| 1024 | - | ||
| 1025 | -template <typename T, int32_t constRank = -1> | ||
| 1026 | -__aicore__ inline bool BrcLastWrapperForFourDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1027 | - const uint32_t *dstShape, const uint32_t *srcStride) | ||
| 1028 | -{ | ||
| 1029 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1030 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 1031 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1032 | - uint16_t sizeI[4]; | ||
| 1033 | - uint16_t stride[4]; | ||
| 1034 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 1035 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 1036 | - sizeI[2] = static_cast<uint16_t>(dstShape[2]); | ||
| 1037 | - sizeI[3] = static_cast<uint16_t>(dstShape[3]); | ||
| 1038 | - stride[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 1039 | - stride[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 1040 | - stride[2] = static_cast<uint16_t>(srcStride[2]); | ||
| 1041 | - stride[3] = static_cast<uint16_t>(srcStride[3]); | ||
| 1042 | - | ||
| 1043 | - if (sizeI[3] == oneBlockElementNum && sizeof(T) != sizeof(uint8_t) && | ||
| 1044 | - stride[2] != 0 && sizeI[2] % DEFAULT_BLK_NUM == 0) { | ||
| 1045 | - BrcLastE2B(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1]); | ||
| 1046 | - } else if (sizeI[3] < VF_LEN_HALF && sizeof(T) != sizeof(uint8_t)) { | ||
| 1047 | - uint32_t newDstShape[4] = {dstShape[0], dstShape[1], dstShape[2], dstShape[3]}; | ||
| 1048 | - uint32_t newSrcStride[4] = {srcStride[0], srcStride[1], srcStride[2], srcStride[3]}; | ||
| 1049 | - GatherWrapperForFourDim(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1050 | - } else if (sizeI[3] <= VF_LEN) { | ||
| 1051 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1052 | - BrcLastLessThanVLAligned<T>( | ||
| 1053 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1054 | - } else { | ||
| 1055 | - if constexpr (constRank == -1) { | ||
| 1056 | - return true; | ||
| 1057 | - } else { | ||
| 1058 | - BrcLastLessThanVLUnaligned<T>( | ||
| 1059 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1060 | - } | ||
| 1061 | - } | ||
| 1062 | - } else { | ||
| 1063 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1064 | - BrcLastLargerThanVLAligned<T>( | ||
| 1065 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1066 | - } else { | ||
| 1067 | - if constexpr (constRank == -1) { | ||
| 1068 | - return true; | ||
| 1069 | - } else { | ||
| 1070 | - BrcLastLargerThanVLUnaligned<T>( | ||
| 1071 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1072 | - } | ||
| 1073 | - } | ||
| 1074 | - } | ||
| 1075 | - return false; | ||
| 1076 | -} | ||
| 1077 | - | ||
| 1078 | -template <typename T, int32_t constRank = -1> | ||
| 1079 | -__aicore__ inline bool BrcNlastWrapperForTwoDim( | ||
| 1080 | - __ubuf__ T *dstUb, __ubuf__ T *srcUb, const uint32_t *dstShape) | ||
| 1081 | -{ | ||
| 1082 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1083 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 1084 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1085 | - using GatherIndexType = typename ExtractSignedTypeBySize<sizeof(T)>::T; | ||
| 1086 | - using BrcIndexType = typename ExtractIndexTypeBySize<sizeof(T)>::T; | ||
| 1087 | - uint16_t sizeI[2]; | ||
| 1088 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 1089 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 1090 | - | ||
| 1091 | - if (sizeI[1] < VF_LEN_HALF) { | ||
| 1092 | - LocalTensor<T> indexLocal; | ||
| 1093 | - PopStackBuffer<T, TPosition::LCM>(indexLocal); | ||
| 1094 | - if (sizeI[1] % oneBlockElementNum == 0) { | ||
| 1095 | - event_t eventIdVToS = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_S)); | ||
| 1096 | - SetFlag<HardEvent::V_S>(eventIdVToS); | ||
| 1097 | - WaitFlag<HardEvent::V_S>(eventIdVToS); | ||
| 1098 | - __ubuf__ uint32_t *indexUb = (__ubuf__ uint32_t *)indexLocal.GetPhyAddr(); | ||
| 1099 | - if (sizeI[1] / oneBlockElementNum == 1) { | ||
| 1100 | - indexUb[0] = 0; | ||
| 1101 | - indexUb[1] = 0; | ||
| 1102 | - indexUb[2] = 0; | ||
| 1103 | - indexUb[3] = 0; | ||
| 1104 | - indexUb[4] = 0; | ||
| 1105 | - indexUb[5] = 0; | ||
| 1106 | - indexUb[6] = 0; | ||
| 1107 | - indexUb[7] = 0; | ||
| 1108 | - } else if (sizeI[1] / oneBlockElementNum == 2) { | ||
| 1109 | - indexUb[0] = 0; | ||
| 1110 | - indexUb[1] = 32; | ||
| 1111 | - indexUb[2] = 0; | ||
| 1112 | - indexUb[3] = 32; | ||
| 1113 | - indexUb[4] = 0; | ||
| 1114 | - indexUb[5] = 32; | ||
| 1115 | - indexUb[6] = 0; | ||
| 1116 | - indexUb[7] = 32; | ||
| 1117 | - } else { | ||
| 1118 | - indexUb[0] = 0; | ||
| 1119 | - indexUb[1] = 32; | ||
| 1120 | - indexUb[2] = 64; | ||
| 1121 | - indexUb[3] = 0; | ||
| 1122 | - indexUb[4] = 32; | ||
| 1123 | - indexUb[5] = 64; | ||
| 1124 | - indexUb[6] = 0; | ||
| 1125 | - indexUb[7] = 0; | ||
| 1126 | - } | ||
| 1127 | - event_t eventIdSToV = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::S_V)); | ||
| 1128 | - SetFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1129 | - WaitFlag<HardEvent::S_V>(eventIdSToV); | ||
| 1130 | - if (sizeI[0] * sizeI[1] < VF_LEN) { | ||
| 1131 | - BrcNlastGatherBOne<T>(dstUb, srcUb, (__ubuf__ uint32_t *)indexUb, sizeI[0], sizeI[1]); | ||
| 1132 | - } else if (sizeI[1] < VF_LEN) { | ||
| 1133 | - BrcNlastGatherBTwo<T>(dstUb, srcUb, (__ubuf__ uint32_t *)indexUb, sizeI[0], sizeI[1]); | ||
| 1134 | - } | ||
| 1135 | - } else { | ||
| 1136 | - __ubuf__ GatherIndexType *indexUb1 = (__ubuf__ GatherIndexType *)indexLocal.GetPhyAddr(); | ||
| 1137 | - __ubuf__ GatherIndexType *indexUb2 = (__ubuf__ GatherIndexType *)indexLocal.GetPhyAddr(VF_LEN); | ||
| 1138 | - GenNlastGatherIndex<GatherIndexType>(indexUb1, sizeI[1], 0); | ||
| 1139 | - if constexpr (sizeof(T) == sizeof(uint8_t)) { | ||
| 1140 | - GenNlastGatherIndex<GatherIndexType>(indexUb2, sizeI[1], VF_LEN_HALF); | ||
| 1141 | - } | ||
| 1142 | - __ubuf__ BrcIndexType *indexUb = (__ubuf__ BrcIndexType *)indexLocal.GetPhyAddr(); | ||
| 1143 | - if (sizeI[0] * sizeI[1] < VF_LEN) { | ||
| 1144 | - BrcNlastGatherOne<T, BrcIndexType>(dstUb, srcUb, indexUb, sizeI[0], sizeI[1]); | ||
| 1145 | - } else if (sizeI[1] < VF_LEN) { | ||
| 1146 | - BrcNlastGatherTwo<T, BrcIndexType>(dstUb, srcUb, indexUb, sizeI[0], sizeI[1]); | ||
| 1147 | - } | ||
| 1148 | - } | ||
| 1149 | - } else if (sizeI[1] <= VF_LEN) { | ||
| 1150 | - BrcNlastLessThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 1151 | - } else { | ||
| 1152 | - if (sizeI[1] % oneBlockElementNum == 0) { | ||
| 1153 | - if (sizeI[1] % VF_LEN == 0 && sizeI[0] > DEFAULT_BLK_NUM) { | ||
| 1154 | - BrcNlastLargerThanVLAlignedWithVL<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 1155 | - } else { | ||
| 1156 | - BrcNlastLargerThanVLAlignedWithBlock<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 1157 | - } | ||
| 1158 | - } else { | ||
| 1159 | - if constexpr (constRank == -1) { | ||
| 1160 | - return true; | ||
| 1161 | - } else { | ||
| 1162 | - BrcNlastLargerThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1]); | ||
| 1163 | - } | ||
| 1164 | - } | ||
| 1165 | - } | ||
| 1166 | - return false; | ||
| 1167 | -} | ||
| 1168 | - | ||
| 1169 | -template <typename T, int32_t constRank = -1> | ||
| 1170 | -__aicore__ inline bool BrcNlastWrapperForThreeDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1171 | - const uint32_t *dstShape, const uint32_t *srcStride) | ||
| 1172 | -{ | ||
| 1173 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1174 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 1175 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1176 | - uint16_t sizeI[3]; | ||
| 1177 | - uint16_t stride[3]; | ||
| 1178 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 1179 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 1180 | - sizeI[2] = static_cast<uint16_t>(dstShape[2]); | ||
| 1181 | - stride[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 1182 | - stride[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 1183 | - stride[2] = static_cast<uint16_t>(srcStride[2]); | ||
| 1184 | - | ||
| 1185 | - if (sizeI[2] < VF_LEN_HALF && sizeof(T) != sizeof(uint8_t)) { | ||
| 1186 | - uint32_t newDstShape[3] = {dstShape[0], dstShape[1], dstShape[2]}; | ||
| 1187 | - uint32_t newSrcStride[3] = {srcStride[0], srcStride[1], srcStride[2]}; | ||
| 1188 | - GatherWrapper(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1189 | - } else if (sizeI[2] <= VF_LEN) { | ||
| 1190 | - BrcNlastLessThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1191 | - } else { | ||
| 1192 | - if (sizeI[2] % oneBlockElementNum == 0) { | ||
| 1193 | - if (sizeI[2] % VF_LEN == 0) { | ||
| 1194 | - BrcNlastLargerThanVLAlignedWithVL<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1195 | - } else { | ||
| 1196 | - BrcNlastLargerThanVLAlignedWithBlock<T>( | ||
| 1197 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1198 | - } | ||
| 1199 | - } else { | ||
| 1200 | - if constexpr (constRank == -1) { | ||
| 1201 | - return true; | ||
| 1202 | - } else { | ||
| 1203 | - BrcNlastLargerThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], stride[0], stride[1]); | ||
| 1204 | - } | ||
| 1205 | - } | ||
| 1206 | - } | ||
| 1207 | - return false; | ||
| 1208 | -} | ||
| 1209 | - | ||
| 1210 | -template <typename T, int32_t constRank = -1> | ||
| 1211 | -__aicore__ inline bool BrcNlastWrapperForFourDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1212 | - const uint32_t *dstShape, const uint32_t *srcStride) | ||
| 1213 | -{ | ||
| 1214 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1215 | - constexpr uint32_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 1216 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1217 | - uint16_t sizeI[4]; | ||
| 1218 | - uint16_t stride[4]; | ||
| 1219 | - sizeI[0] = static_cast<uint16_t>(dstShape[0]); | ||
| 1220 | - sizeI[1] = static_cast<uint16_t>(dstShape[1]); | ||
| 1221 | - sizeI[2] = static_cast<uint16_t>(dstShape[2]); | ||
| 1222 | - sizeI[3] = static_cast<uint16_t>(dstShape[3]); | ||
| 1223 | - stride[0] = static_cast<uint16_t>(srcStride[0]); | ||
| 1224 | - stride[1] = static_cast<uint16_t>(srcStride[1]); | ||
| 1225 | - stride[2] = static_cast<uint16_t>(srcStride[2]); | ||
| 1226 | - stride[3] = static_cast<uint16_t>(srcStride[3]); | ||
| 1227 | - | ||
| 1228 | - if (sizeI[3] < VF_LEN_HALF && sizeof(T) != sizeof(uint8_t)) { | ||
| 1229 | - uint32_t newDstShape[4] = {dstShape[0], dstShape[1], dstShape[2], dstShape[3]}; | ||
| 1230 | - uint32_t newSrcStride[4] = {srcStride[0], srcStride[1], srcStride[2], srcStride[3]}; | ||
| 1231 | - GatherWrapperForFourDim(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1232 | - } else if (sizeI[3] <= VF_LEN) { | ||
| 1233 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1234 | - BrcNlastLessThanVLAligned<T>( | ||
| 1235 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1236 | - } else { | ||
| 1237 | - if constexpr (constRank == -1) { | ||
| 1238 | - return true; | ||
| 1239 | - } else { | ||
| 1240 | - BrcNlastLessThanVLUnaligned<T>( | ||
| 1241 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1242 | - } | ||
| 1243 | - } | ||
| 1244 | - } else { | ||
| 1245 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1246 | - if (sizeI[3] % VF_LEN == 0) { | ||
| 1247 | - BrcNlastLargerThanVLAlignedWithVL<T>( | ||
| 1248 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1249 | - } else { | ||
| 1250 | - BrcNlastLargerThanVLAlignedWithBlock<T>( | ||
| 1251 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1252 | - } | ||
| 1253 | - } else { | ||
| 1254 | - if constexpr (constRank == -1) { | ||
| 1255 | - return true; | ||
| 1256 | - } else { | ||
| 1257 | - BrcNlastLargerThanVLUnaligned<T>( | ||
| 1258 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1259 | - } | ||
| 1260 | - } | ||
| 1261 | - } | ||
| 1262 | - return false; | ||
| 1263 | -} | ||
| 1264 | - | ||
| 1265 | -template <typename T> | ||
| 1266 | -__aicore__ inline void BrcNlastWrapperForMoreDim(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1267 | - const uint32_t *dstShape, const uint32_t *dstStride, const uint32_t *srcStride) | ||
| 1268 | -{ | ||
| 1269 | - uint16_t sizeI[4]; | ||
| 1270 | - uint16_t stride[4]; | ||
| 1271 | - sizeI[0] = static_cast<uint16_t>(dstShape[1]); | ||
| 1272 | - sizeI[1] = static_cast<uint16_t>(dstShape[2]); | ||
| 1273 | - sizeI[2] = static_cast<uint16_t>(dstShape[3]); | ||
| 1274 | - sizeI[3] = static_cast<uint16_t>(dstShape[4]); | ||
| 1275 | - stride[0] = static_cast<uint16_t>(srcStride[1]); | ||
| 1276 | - stride[1] = static_cast<uint16_t>(srcStride[2]); | ||
| 1277 | - stride[2] = static_cast<uint16_t>(srcStride[3]); | ||
| 1278 | - stride[3] = static_cast<uint16_t>(srcStride[4]); | ||
| 1279 | - uint32_t totalDim = 9; | ||
| 1280 | - | ||
| 1281 | - __ubuf__ T *srcUbTmp = srcUb; | ||
| 1282 | - __ubuf__ T *dstUbTmp = dstUb; | ||
| 1283 | - for (uint16_t p = 0; p < static_cast<uint16_t>(dstShape[0]); ++p) { | ||
| 1284 | - dstUb = dstUbTmp + p * dstStride[0]; | ||
| 1285 | - srcUb = srcUbTmp + p * srcStride[0]; | ||
| 1286 | - uint32_t newDstShape[4] = { | ||
| 1287 | - dstShape[1], dstShape[2], dstShape[3], dstShape[4]}; | ||
| 1288 | - uint32_t newSrcStride[4] = { | ||
| 1289 | - srcStride[1], srcStride[2], srcStride[3], srcStride[4]}; | ||
| 1290 | - GatherWrapperForFourDim(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1291 | - } | ||
| 1292 | -} | ||
| 1293 | - | ||
| 1294 | -template <typename T> | ||
| 1295 | -__aicore__ inline void BrcNlastWrapperForMoreDimDynamicShape(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1296 | - const uint32_t dim, const uint32_t *dstShape, const uint32_t *dstStride, const uint32_t *srcStride) | ||
| 1297 | -{ | ||
| 1298 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1299 | - constexpr uint16_t VF_LEN_HALF = GetVecLen() / 2 / sizeof(T); | ||
| 1300 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1301 | - uint16_t sizeI[4] = {1, 1, 1, 1}; | ||
| 1302 | - if(dim > 4) { | ||
| 1303 | - sizeI[0] = dstShape[dim - 4]; | ||
| 1304 | - sizeI[1] = dstShape[dim - 3]; | ||
| 1305 | - sizeI[2] = dstShape[dim - 2]; | ||
| 1306 | - sizeI[3] = dstShape[dim - 1]; | ||
| 1307 | - } else { | ||
| 1308 | - for (uint16_t i = 0; i < dim; ++i) { | ||
| 1309 | - sizeI[4 - dim + i] = dstShape[i]; | ||
| 1310 | - } | ||
| 1311 | - } | ||
| 1312 | - uint32_t totalDim = 9; | ||
| 1313 | - uint16_t loops[5] = {1, 1, 1, 1, 1}; | ||
| 1314 | - for (int16_t i = dim - 5, j = 4; i >= 0; --i, --j) { | ||
| 1315 | - loops[j] = static_cast<uint16_t>(dstShape[i]); | ||
| 1316 | - } | ||
| 1317 | - uint16_t stride[4] = {0, 0, 0, 0}; | ||
| 1318 | - if (dim > 4) { | ||
| 1319 | - stride[0] = srcStride[dim - 4]; | ||
| 1320 | - stride[1] = srcStride[dim - 3]; | ||
| 1321 | - stride[2] = srcStride[dim - 2]; | ||
| 1322 | - stride[3] = srcStride[dim - 1]; | ||
| 1323 | - } else { | ||
| 1324 | - for (uint16_t i = 0; i < dim; ++i) { | ||
| 1325 | - stride[4 - dim + i] = srcStride[i]; | ||
| 1326 | - } | ||
| 1327 | - } | ||
| 1328 | - __ubuf__ T *srcUbTmp = srcUb; | ||
| 1329 | - __ubuf__ T *dstUbTmp = dstUb; | ||
| 1330 | - for (uint16_t i = 0; i < loops[0]; ++i) { | ||
| 1331 | - for (uint16_t j = 0; j < loops[1]; ++j) { | ||
| 1332 | - for (uint16_t k = 0; k < loops[2]; ++k) { | ||
| 1333 | - for (uint16_t t = 0; t < loops[3]; ++t) { | ||
| 1334 | - for (uint16_t p = 0; p < loops[4]; ++p) { | ||
| 1335 | - dstUb = dstUbTmp + p * dstStride[(dim - 5 + totalDim) % totalDim] + | ||
| 1336 | - t * dstStride[(dim - 6 + totalDim) % totalDim] + | ||
| 1337 | - k * dstStride[(dim - 7 + totalDim) % totalDim] + | ||
| 1338 | - j * dstStride[(dim - 8 + totalDim) % totalDim] + | ||
| 1339 | - i * dstStride[(dim - 9 + totalDim) % totalDim]; | ||
| 1340 | - srcUb = srcUbTmp + p * srcStride[(dim - 5 + totalDim) % totalDim] + | ||
| 1341 | - t * srcStride[(dim - 6 + totalDim) % totalDim] + | ||
| 1342 | - k * srcStride[(dim - 7 + totalDim) % totalDim] + | ||
| 1343 | - j * srcStride[(dim - 8 + totalDim) % totalDim] + | ||
| 1344 | - i * srcStride[(dim - 9 + totalDim) % totalDim]; | ||
| 1345 | - if (sizeI[3] < VF_LEN_HALF && sizeof(T) != sizeof(uint8_t)) { | ||
| 1346 | - uint32_t newDstShape[4] = { | ||
| 1347 | - dstShape[dim - 4], dstShape[dim - 3], dstShape[dim - 2], dstShape[dim - 1]}; | ||
| 1348 | - uint32_t newSrcStride[4] = { | ||
| 1349 | - srcStride[dim - 4], srcStride[dim - 3], srcStride[dim - 2], srcStride[dim - 1]}; | ||
| 1350 | - GatherWrapperForFourDim(dstUb, srcUb, newDstShape, newSrcStride); | ||
| 1351 | - } else if (sizeI[3] <= VF_LEN) { | ||
| 1352 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1353 | - BrcNlastLessThanVLAligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], | ||
| 1354 | - sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1355 | - } else { | ||
| 1356 | - BrcNlastLessThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], | ||
| 1357 | - sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1358 | - } | ||
| 1359 | - } else { | ||
| 1360 | - if (sizeI[3] % oneBlockElementNum == 0) { | ||
| 1361 | - BrcNlastLargerThanVLAlignedWithBlock<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], | ||
| 1362 | - sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1363 | - } else { | ||
| 1364 | - BrcNlastLargerThanVLUnaligned<T>(dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], | ||
| 1365 | - sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1366 | - } | ||
| 1367 | - } | ||
| 1368 | - } | ||
| 1369 | - } | ||
| 1370 | - } | ||
| 1371 | - } | ||
| 1372 | - } | ||
| 1373 | -} | ||
| 1374 | - | ||
| 1375 | -template <typename T> | ||
| 1376 | -__aicore__ inline void BrcLastWrapperForMoreDimDynamicShape(__ubuf__ T *dstUb, __ubuf__ T *srcUb, | ||
| 1377 | - const uint32_t dim, const uint32_t *dstShape, const uint32_t *dstStride, const uint32_t *srcStride) | ||
| 1378 | -{ | ||
| 1379 | - constexpr uint16_t VF_LEN = GetVecLen() / sizeof(T); | ||
| 1380 | - constexpr uint32_t oneBlockElementNum = GetDataBlockSizeInBytes() / sizeof(T); | ||
| 1381 | - uint16_t sizeI[4] = {1, 1, 1, 1}; | ||
| 1382 | - if(dim > 4) { | ||
| 1383 | - sizeI[0] = dstShape[dim - 4]; | ||
| 1384 | - sizeI[1] = dstShape[dim - 3]; | ||
| 1385 | - sizeI[2] = dstShape[dim - 2]; | ||
| 1386 | - sizeI[3] = dstShape[dim - 1]; | ||
| 1387 | - } else { | ||
| 1388 | - for (uint16_t i = 0; i < dim; ++i) { | ||
| 1389 | - sizeI[4 - dim + i] = dstShape[i]; | ||
| 1390 | - } | ||
| 1391 | - } | ||
| 1392 | - uint32_t totalDim = 9; | ||
| 1393 | - uint16_t loops[5] = {1, 1, 1, 1, 1}; | ||
| 1394 | - for (int16_t i = dim - 5, j = 4; i >= 0; --i, --j) { | ||
| 1395 | - loops[j] = static_cast<uint16_t>(dstShape[i]); | ||
| 1396 | - } | ||
| 1397 | - uint16_t stride[4] = {0, 0, 0, 0}; | ||
| 1398 | - if (dim > 4) { | ||
| 1399 | - stride[0] = srcStride[dim - 4]; | ||
| 1400 | - stride[1] = srcStride[dim - 3]; | ||
| 1401 | - stride[2] = srcStride[dim - 2]; | ||
| 1402 | - stride[3] = srcStride[dim - 1]; | ||
| 1403 | - } else { | ||
| 1404 | - for (uint16_t i = 0; i < dim; ++i) { | ||
| 1405 | - stride[4 - dim + i] = srcStride[i]; | ||
| 1406 | - } | ||
| 1407 | - } | ||
| 1408 | - __ubuf__ T *srcUbTmp = srcUb; | ||
| 1409 | - __ubuf__ T *dstUbTmp = dstUb; | ||
| 1410 | - for (uint16_t i = 0; i < loops[0]; ++i) { | ||
| 1411 | - for (uint16_t j = 0; j < loops[1]; ++j) { | ||
| 1412 | - for (uint16_t k = 0; k < loops[2]; ++k) { | ||
| 1413 | - for (uint16_t t = 0; t < loops[3]; ++t) { | ||
| 1414 | - for (uint16_t p = 0; p < loops[4]; ++p) { | ||
| 1415 | - dstUb = dstUbTmp + p * dstStride[(dim - 5 + totalDim) % totalDim] + | ||
| 1416 | - t * dstStride[(dim - 6 + totalDim) % totalDim] + | ||
| 1417 | - k * dstStride[(dim - 7 + totalDim) % totalDim] + | ||
| 1418 | - j * dstStride[(dim - 8 + totalDim) % totalDim] + | ||
| 1419 | - i * dstStride[(dim - 9 + totalDim) % totalDim]; | ||
| 1420 | - srcUb = srcUbTmp + p * srcStride[(dim - 5 + totalDim) % totalDim] + | ||
| 1421 | - t * srcStride[(dim - 6 + totalDim) % totalDim] + | ||
| 1422 | - k * srcStride[(dim - 7 + totalDim) % totalDim] + | ||
| 1423 | - j * srcStride[(dim - 8 + totalDim) % totalDim] + | ||
| 1424 | - i * srcStride[(dim - 9 + totalDim) % totalDim]; | ||
| 1425 | - if (sizeI[3] <= VF_LEN) { | ||
| 1426 | - BrcLastLessThanVLUnaligned<T>( | ||
| 1427 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1428 | - } else { | ||
| 1429 | - BrcLastLargerThanVLUnaligned<T>( | ||
| 1430 | - dstUb, srcUb, sizeI[0], sizeI[1], sizeI[2], sizeI[3], stride[0], stride[1], stride[2]); | ||
| 1431 | - } | ||
| 1432 | - } | ||
| 1433 | - } | ||
| 1434 | - } | ||
| 1435 | - } | ||
| 1436 | - } | ||
| 1437 | -} | ||
| 1438 | -/* | ||
| 1439 | - * @ingroup GetBroadcastTilingInfo | ||
| 1440 | - * @brief get broadcast tiling information | ||
| 1441 | - * @param [in] rank, the dimension of src and dst | ||
| 1442 | - * @param [in] dstShape, the shape of dst tensor | ||
| 1443 | - * @param [in] srcShape, the shape of src tensor | ||
| 1444 | - * @param [in] srcInnerPad, if srcShape[rank-1] is aligned | ||
| 1445 | - * @param [out] tiling, BroadcastTiling | ||
| 1446 | - */ | ||
| 1447 | -template <typename T, int constRank = -1, uint32_t* constDstShape = nullptr, uint32_t* constSrcShape = nullptr> | ||
| 1448 | -__aicore__ inline void GetBroadcastTilingInfo( | ||
| 1449 | - uint32_t rank, const uint32_t* dstShape, const uint32_t* srcShape, bool srcInnerPad, BroadcastTiling& tiling) | ||
| 1450 | -{ | ||
| 1451 | - GetBroadcastTilingInfoImpl<T, constRank, constDstShape, constSrcShape>(rank, dstShape, srcShape, srcInnerPad, tiling); | ||
| 1452 | -} | ||
| 1453 | - | ||
| 1454 | -/* | ||
| 1455 | - * @ingroup Broadcast | ||
| 1456 | - * @brief https://numpy.org.cn/user/basics/broadcasting.html | ||
| 1457 | - * @param [out] dst, output LocalTensor | ||
| 1458 | - * @param [in] src, input LocalTensor | ||
| 1459 | - * @param [in] dstShape, the shape of dst tensor | ||
| 1460 | - * @param [in] srcShape, the shape of src tensor | ||
| 1461 | - * @param [in] tiling, broadcasttiling ptr | ||
| 1462 | - */ | ||
| 1463 | -template <typename T, int constRank = -1, uint32_t* constDstShape = nullptr, uint32_t* constSrcShape = nullptr, | ||
| 1464 | - bool constSrcInnerPad = false> | ||
| 1465 | -__aicore__ inline void Broadcast(const LocalTensor<T>& dst, const LocalTensor<T>& src, const uint32_t* dstShape, | ||
| 1466 | - const uint32_t* srcShape, BroadcastTiling* tiling) | ||
| 1467 | -{ | ||
| 1468 | - BroadcastImpl<T, constRank, constDstShape, constSrcShape, constSrcInnerPad>(dst, src, dstShape, srcShape, tiling); | ||
| 1469 | -} | ||
| 1470 | -} // namespace BroadcastInternal | ||
| 1471 | -} // namespace AscendC | ||
| 1472 | - | ||
Dimpl/adv_api/detail/quantization/dequant/ascend_dequant_l300_impl.h+0-592
| @@ -1,592 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file ascend_dequant_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -namespace AscendC { | ||
| 22 | -constexpr uint32_t ASCENDC_DEQUANT_B32_VF_LEN = GetVecLen() / sizeof(uint32_t); | ||
| 23 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 24 | -__simd_vf__ inline void DequantPerchannelVFImpl(__ubuf__ half* dstUb, __ubuf__ int32_t* srcUb, | ||
| 25 | - __ubuf__ float* scaleUb, DequantParams params) | ||
| 26 | -{ | ||
| 27 | - uint32_t rowNum = params.m; | ||
| 28 | - uint32_t N = params.n; | ||
| 29 | - uint32_t calCount = params.calCount; | ||
| 30 | - uint32_t oneBlockNum = ONE_BLK_SIZE / sizeof(dstT); | ||
| 31 | - uint32_t dstInner = CeilDivision(N, oneBlockNum) * oneBlockNum; | ||
| 32 | - | ||
| 33 | - MicroAPI::MaskReg preg; | ||
| 34 | - MicroAPI::RegTensor<int32_t> s32vreg; | ||
| 35 | - MicroAPI::RegTensor<float> f32vreg; | ||
| 36 | - MicroAPI::RegTensor<half> b16vreg; | ||
| 37 | - MicroAPI::RegTensor<float> scaleB32Vreg0; | ||
| 38 | - MicroAPI::RegTensor<float> scaleB32Vreg1; | ||
| 39 | - | ||
| 40 | - uint32_t sregLower = ASCENDC_DEQUANT_B32_VF_LEN; | ||
| 41 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(calCount, sregLower)); | ||
| 42 | - | ||
| 43 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 44 | - uint32_t sreg = calCount; | ||
| 45 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 46 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 47 | - MicroAPI::DataCopy<int32_t, MicroAPI::LoadDist::DIST_NORM>(s32vreg, srcUb + i * N + j * sregLower); | ||
| 48 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32vreg, s32vreg, preg); | ||
| 49 | - | ||
| 50 | - MicroAPI::DataCopy<float, MicroAPI::LoadDist::DIST_DINTLV_B32>(scaleB32Vreg0, scaleB32Vreg1, | ||
| 51 | - scaleUb + 2 * j * sregLower); // only half of uint64_t is used | ||
| 52 | - | ||
| 53 | - MicroAPI::Mul(f32vreg, f32vreg, scaleB32Vreg0, preg); | ||
| 54 | - | ||
| 55 | - MicroAPI::Cast<dstT, float, LayoutZMrgZRndRSatS>(b16vreg, f32vreg, preg); | ||
| 56 | - MicroAPI::DataCopy<dstT, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * dstInner + j * sregLower, b16vreg, | ||
| 57 | - preg); | ||
| 58 | - } | ||
| 59 | - } | ||
| 60 | -} | ||
| 61 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 62 | -__aicore__ inline void DequantPerchannelImpl(const LocalTensor<half>& dstTensor, const LocalTensor<int32_t>& srcTensor, | ||
| 63 | - const LocalTensor<uint64_t>& deqScale, DequantParams& params) | ||
| 64 | -{ | ||
| 65 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 66 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 67 | - CheckTensorPosition(deqScale, "deqScale", "VECIN, VECOUT, VECCALC"); | ||
| 68 | - __ubuf__ half* dstUb = (__ubuf__ half*)dstTensor.GetPhyAddr(); | ||
| 69 | - __ubuf__ int32_t* srcUb = (__ubuf__ int32_t*)srcTensor.GetPhyAddr(); | ||
| 70 | - __ubuf__ float* scaleUb = reinterpret_cast<__ubuf__ float*>(deqScale.GetPhyAddr()); | ||
| 71 | - | ||
| 72 | - DequantPerchannelVFImpl<dstT, scaleT, mode>(dstUb, srcUb, scaleUb, params); | ||
| 73 | -} | ||
| 74 | - | ||
| 75 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 76 | -__simd_vf__ inline void DequantPerchannelVFImpl(__ubuf__ dstT* dstUb, __ubuf__ int32_t* srcUb, | ||
| 77 | - __ubuf__ scaleT* scaleUb, DequantParams params) | ||
| 78 | -{ | ||
| 79 | - uint32_t rowNum = params.m; | ||
| 80 | - uint32_t N = params.n; | ||
| 81 | - uint32_t calCount = params.calCount; | ||
| 82 | - uint32_t oneBlockNum = ONE_BLK_SIZE / sizeof(dstT); | ||
| 83 | - uint32_t dstInner = CeilDivision(N, oneBlockNum) * oneBlockNum; | ||
| 84 | - | ||
| 85 | - MicroAPI::MaskReg preg; | ||
| 86 | - MicroAPI::RegTensor<int32_t> s32vreg; | ||
| 87 | - MicroAPI::RegTensor<float> f32vreg; | ||
| 88 | - MicroAPI::RegTensor<dstT> b16vreg; | ||
| 89 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 90 | - MicroAPI::RegTensor<float> scaleB32Vreg; | ||
| 91 | - | ||
| 92 | - uint32_t sregLower = ASCENDC_DEQUANT_B32_VF_LEN; | ||
| 93 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(calCount, sregLower)); | ||
| 94 | - | ||
| 95 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 96 | - uint32_t sreg = calCount; | ||
| 97 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 98 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 99 | - MicroAPI::DataCopy<int32_t, MicroAPI::LoadDist::DIST_NORM>(s32vreg, srcUb + i * N + j * sregLower); | ||
| 100 | - | ||
| 101 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32vreg, s32vreg, preg); | ||
| 102 | - if constexpr (SupportType<scaleT, bfloat16_t>()) { | ||
| 103 | - MicroAPI::DataCopy<bfloat16_t, MicroAPI::LoadDist::DIST_UNPACK_B16>(scaleVreg, | ||
| 104 | - scaleUb + j * sregLower); | ||
| 105 | - MicroAPI::Cast<float, bfloat16_t, layoutZMrgZ>(scaleB32Vreg, scaleVreg, preg); // bf16->fp32 | ||
| 106 | - } else { | ||
| 107 | - MicroAPI::DataCopy<float, MicroAPI::LoadDist::DIST_NORM>(scaleB32Vreg, scaleUb + j * sregLower); | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - MicroAPI::Mul(f32vreg, f32vreg, scaleB32Vreg, preg); | ||
| 111 | - | ||
| 112 | - if constexpr (SupportType<dstT, bfloat16_t, half>()) { | ||
| 113 | - MicroAPI::Cast<dstT, float, LayoutZMrgZRndRSatS>(b16vreg, f32vreg, preg); | ||
| 114 | - MicroAPI::DataCopy<dstT, MicroAPI::StoreDist::DIST_PACK_B32>(dstUb + i * dstInner + j * sregLower, b16vreg, | ||
| 115 | - preg); | ||
| 116 | - } else { // out is fp32 | ||
| 117 | - MicroAPI::DataCopy<float, MicroAPI::StoreDist::DIST_NORM_B32>(dstUb + i * dstInner + j * sregLower, | ||
| 118 | - f32vreg, preg); | ||
| 119 | - } | ||
| 120 | - } | ||
| 121 | - } | ||
| 122 | -} | ||
| 123 | - | ||
| 124 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 125 | -__aicore__ inline void DequantPerchannelImpl(const LocalTensor<dstT>& dstTensor, const LocalTensor<int32_t>& srcTensor, | ||
| 126 | - const LocalTensor<scaleT>& deqScale, DequantParams& params) | ||
| 127 | -{ | ||
| 128 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 129 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 130 | - CheckTensorPosition(deqScale, "deqScale", "VECIN, VECOUT, VECCALC"); | ||
| 131 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 132 | - __ubuf__ int32_t* srcUb = (__ubuf__ int32_t*)srcTensor.GetPhyAddr(); | ||
| 133 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)deqScale.GetPhyAddr(); | ||
| 134 | - | ||
| 135 | - DequantPerchannelVFImpl<dstT, scaleT, mode>(dstUb, srcUb, scaleUb,params); | ||
| 136 | -} | ||
| 137 | - | ||
| 138 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 139 | -__simd_vf__ inline void DequantPertensorVFImpl(__ubuf__ dstT* dstUb, __ubuf__ int32_t* srcUb, | ||
| 140 | - const scaleT deqScale, DequantParams params) | ||
| 141 | -{ | ||
| 142 | - uint32_t rowNum = params.m; | ||
| 143 | - uint32_t N = params.n; | ||
| 144 | - uint32_t calCount = params.calCount; | ||
| 145 | - uint32_t oneBlockNum = ONE_BLK_SIZE / sizeof(dstT); | ||
| 146 | - uint32_t dstInner = CeilDivision(N, oneBlockNum) * oneBlockNum; | ||
| 147 | - | ||
| 148 | - MicroAPI::MaskReg preg; | ||
| 149 | - MicroAPI::RegTensor<int32_t> s32vreg; | ||
| 150 | - MicroAPI::RegTensor<float> f32vreg; | ||
| 151 | - | ||
| 152 | - uint32_t sregLower = ASCENDC_DEQUANT_B32_VF_LEN; | ||
| 153 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(calCount, sregLower)); | ||
| 154 | - | ||
| 155 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 156 | - uint32_t sreg = calCount; | ||
| 157 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 158 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 159 | - MicroAPI::DataCopy<int32_t, MicroAPI::LoadDist::DIST_NORM>(s32vreg, srcUb + i * N + j * sregLower); | ||
| 160 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32vreg, s32vreg, preg); | ||
| 161 | - MicroAPI::Muls(f32vreg, f32vreg, deqScale, preg); | ||
| 162 | - // out is fp32 | ||
| 163 | - MicroAPI::DataCopy<float, MicroAPI::StoreDist::DIST_NORM_B32>(dstUb + i * dstInner + j * sregLower, | ||
| 164 | - f32vreg, preg); | ||
| 165 | - } | ||
| 166 | - } | ||
| 167 | -} | ||
| 168 | - | ||
| 169 | -template <typename dstT, typename scaleT, DeQuantMode mode> | ||
| 170 | -__aicore__ inline void DequantPertensorImpl(const LocalTensor<dstT>& dstTensor, const LocalTensor<int32_t>& srcTensor, | ||
| 171 | - const scaleT deqScale, DequantParams& params) | ||
| 172 | -{ | ||
| 173 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 174 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 175 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 176 | - __ubuf__ int32_t* srcUb = (__ubuf__ int32_t*)srcTensor.GetPhyAddr(); | ||
| 177 | - DequantPertensorVFImpl<dstT, scaleT, mode>(dstUb, srcUb,deqScale, params); | ||
| 178 | -} | ||
| 179 | - | ||
| 180 | -template <typename scaleT> | ||
| 181 | -__simd_callee__ inline void LoadPerTokenScale(__ubuf__ scaleT* addr, MicroAPI::RegTensor<scaleT>& vreg) | ||
| 182 | -{ | ||
| 183 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 184 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_BRC_B16>(vreg, addr); | ||
| 185 | - } else { | ||
| 186 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_BRC_B32>(vreg, addr); | ||
| 187 | - } | ||
| 188 | -} | ||
| 189 | - | ||
| 190 | -template <typename dstT> | ||
| 191 | -__simd_callee__ inline void StoreRes(__ubuf__ dstT* dstAddr, MicroAPI::RegTensor<float>& vreg, | ||
| 192 | - MicroAPI::MaskReg& preg) | ||
| 193 | -{ | ||
| 194 | - if constexpr (SupportType<dstT, half, bfloat16_t>()) { | ||
| 195 | - MicroAPI::RegTensor<dstT> tempVreg; | ||
| 196 | - MicroAPI::Cast<dstT, float, LayoutZMrgZRndRSatS>(tempVreg, vreg, preg); | ||
| 197 | - MicroAPI::DataCopy<dstT, MicroAPI::StoreDist::DIST_PACK_B32>(dstAddr, tempVreg, preg); | ||
| 198 | - } else { | ||
| 199 | - MicroAPI::DataCopy<dstT, MicroAPI::StoreDist::DIST_NORM_B32>(dstAddr, vreg, preg); | ||
| 200 | - } | ||
| 201 | -} | ||
| 202 | - | ||
| 203 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 204 | -__simd_vf__ inline void DeQuantPerTokenForS32VF(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 205 | - __ubuf__ scaleT* scaleUb, const AscendDeQuantParam para) | ||
| 206 | -{ | ||
| 207 | - uint16_t rowNum = para.calCount / para.n; | ||
| 208 | - uint32_t vecLen = ASCENDC_QUANT_B32_VF_LEN; | ||
| 209 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(para.n, vecLen)); | ||
| 210 | - | ||
| 211 | - MicroAPI::MaskReg preg; | ||
| 212 | - MicroAPI::RegTensor<int32_t> srcVreg; | ||
| 213 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 214 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 215 | - MicroAPI::RegTensor<float> scaleF32Vreg; | ||
| 216 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 217 | - LoadPerTokenScale<scaleT>(scaleUb + i, scaleVreg); | ||
| 218 | - uint32_t sreg = para.n; | ||
| 219 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 220 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 221 | - MicroAPI::DataCopy<int32_t, MicroAPI::LoadDist::DIST_NORM>(srcVreg, srcUb + i * para.n + j * vecLen); | ||
| 222 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32Vreg, srcVreg, preg); | ||
| 223 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 224 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(scaleF32Vreg, scaleVreg, preg); | ||
| 225 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, f32Vreg, scaleF32Vreg, preg); | ||
| 226 | - } else { | ||
| 227 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, f32Vreg, scaleVreg, preg); | ||
| 228 | - } | ||
| 229 | - StoreRes<dstT>(dstUb + i * para.n + j * vecLen, f32Vreg, preg); | ||
| 230 | - } | ||
| 231 | - } | ||
| 232 | -} | ||
| 233 | - | ||
| 234 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 235 | -__aicore__ inline void DeQuantPerTokenForS32(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 236 | - const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor, | ||
| 237 | - const AscendDeQuantParam& para) | ||
| 238 | -{ | ||
| 239 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 240 | - __ubuf__ srcT* srcUb = (__ubuf__ srcT*)srcTensor.GetPhyAddr(); | ||
| 241 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)scaleTensor.GetPhyAddr(); | ||
| 242 | - DeQuantPerTokenForS32VF<dstT, srcT, scaleT, config>(dstUb, srcUb, scaleUb, para); | ||
| 243 | -} | ||
| 244 | - | ||
| 245 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 246 | -__simd_vf__ inline void DeQuantPerTokenForF32VF(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 247 | - __ubuf__ scaleT* scaleUb, const AscendDeQuantParam para) | ||
| 248 | -{ | ||
| 249 | - uint16_t rowNum = para.calCount / para.n; | ||
| 250 | - uint32_t vecLen = ASCENDC_QUANT_B32_VF_LEN; | ||
| 251 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(para.n, vecLen)); | ||
| 252 | - | ||
| 253 | - MicroAPI::MaskReg preg; | ||
| 254 | - MicroAPI::RegTensor<float> srcVreg; | ||
| 255 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 256 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 257 | - MicroAPI::RegTensor<float> scaleF32Vreg; | ||
| 258 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 259 | - LoadPerTokenScale<scaleT>(scaleUb + i, scaleVreg); | ||
| 260 | - uint32_t sreg = para.n; | ||
| 261 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 262 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 263 | - MicroAPI::DataCopy<float, MicroAPI::LoadDist::DIST_NORM>(srcVreg, srcUb + i * para.n + j * vecLen); | ||
| 264 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 265 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(scaleF32Vreg, scaleVreg, preg); | ||
| 266 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, srcVreg, scaleF32Vreg, preg); | ||
| 267 | - } else { | ||
| 268 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, srcVreg, scaleVreg, preg); | ||
| 269 | - } | ||
| 270 | - StoreRes<dstT>(dstUb + i * para.n + j * vecLen, f32Vreg, preg); | ||
| 271 | - } | ||
| 272 | - } | ||
| 273 | -} | ||
| 274 | - | ||
| 275 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 276 | -__aicore__ inline void DeQuantPerTokenForF32(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 277 | - const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor, | ||
| 278 | - const AscendDeQuantParam& para) | ||
| 279 | -{ | ||
| 280 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 281 | - __ubuf__ srcT* srcUb = (__ubuf__ srcT*)srcTensor.GetPhyAddr(); | ||
| 282 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)scaleTensor.GetPhyAddr(); | ||
| 283 | - DeQuantPerTokenForF32VF<dstT, srcT, scaleT, config>(dstUb, srcUb, scaleUb, para); | ||
| 284 | -} | ||
| 285 | - | ||
| 286 | -template <typename T> | ||
| 287 | -__simd_callee__ inline void GetPerGroupScale(__ubuf__ T* scaleUb, const int32_t start, const AscendDeQuantParam& para, | ||
| 288 | - const AscendDeQuantConfig& config, MicroAPI::RegTensor<T>& scaleReg) | ||
| 289 | -{ | ||
| 290 | - // use vgather to get perGroup scale/offset | ||
| 291 | - uint32_t groupSize = para.groupSize; | ||
| 292 | - if constexpr (SupportType<T, half, bfloat16_t>()) { | ||
| 293 | - MicroAPI::MaskReg preg = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL>(); | ||
| 294 | - MicroAPI::RegTensor<int16_t> vci_vreg; | ||
| 295 | - MicroAPI::RegTensor<uint16_t> index_vreg; | ||
| 296 | - MicroAPI::RegTensor<uint16_t> gsize_vreg; | ||
| 297 | - MicroAPI::Duplicate(gsize_vreg, static_cast<uint16_t>(groupSize)); | ||
| 298 | - MicroAPI::Arange(vci_vreg, static_cast<int16_t>(start)); | ||
| 299 | - MicroAPI::Div(index_vreg, (MicroAPI::RegTensor<uint16_t> &)vci_vreg, gsize_vreg, preg); | ||
| 300 | - MicroAPI::DataCopyGather(scaleReg, scaleUb, index_vreg, preg); | ||
| 301 | - } else { | ||
| 302 | - MicroAPI::MaskReg preg = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 303 | - MicroAPI::RegTensor<int32_t> vci_vreg; | ||
| 304 | - MicroAPI::RegTensor<uint32_t> index_vreg; | ||
| 305 | - MicroAPI::RegTensor<uint32_t> gsize_vreg; | ||
| 306 | - MicroAPI::Duplicate(gsize_vreg, static_cast<uint32_t>(groupSize)); | ||
| 307 | - MicroAPI::Arange(vci_vreg, static_cast<int32_t>(start)); | ||
| 308 | - MicroAPI::Div(index_vreg, (MicroAPI::RegTensor<uint32_t> &)vci_vreg, gsize_vreg, preg); | ||
| 309 | - MicroAPI::DataCopyGather(scaleReg, scaleUb, index_vreg, preg); | ||
| 310 | - } | ||
| 311 | -} | ||
| 312 | - | ||
| 313 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 314 | -__simd_vf__ inline void DeQuantPerGroupForColS32VF(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 315 | - __ubuf__ scaleT* scaleUb, const AscendDeQuantParam para) | ||
| 316 | -{ | ||
| 317 | - uint16_t rowNum = para.calCount / para.n; | ||
| 318 | - uint32_t vecLen = ASCENDC_QUANT_B32_VF_LEN; | ||
| 319 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(para.n, vecLen)); | ||
| 320 | - uint32_t sreg = para.n; | ||
| 321 | - uint16_t scaleK = static_cast<uint16_t>(CeilDivision(para.n, para.groupSize)); | ||
| 322 | - | ||
| 323 | - MicroAPI::MaskReg preg; | ||
| 324 | - MicroAPI::RegTensor<int32_t> srcVreg; | ||
| 325 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 326 | - MicroAPI::RegTensor<scaleT> oriScaleVreg; | ||
| 327 | - MicroAPI::RegTensor<scaleT> tempVreg; | ||
| 328 | - MicroAPI::RegTensor<int32_t> offsetVreg; | ||
| 329 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 330 | - MicroAPI::RegTensor<float> scaleF32Vreg; | ||
| 331 | - MicroAPI::RegTensor<scaleT> zeroVreg; | ||
| 332 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 333 | - MicroAPI::MaskReg b16FullPreg = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL>(); | ||
| 334 | - MicroAPI::Duplicate(zeroVreg, static_cast<scaleT>(0), b16FullPreg); | ||
| 335 | - } else { | ||
| 336 | - MicroAPI::MaskReg b32FullPreg = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 337 | - MicroAPI::Duplicate(zeroVreg, static_cast<scaleT>(0), b32FullPreg); | ||
| 338 | - } | ||
| 339 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 340 | - sreg = para.n; | ||
| 341 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 342 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 343 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 344 | - GetPerGroupScale<scaleT>(scaleUb + i * scaleK, j * vecLen, para, config, oriScaleVreg); | ||
| 345 | - MicroAPI::Interleave(scaleVreg, tempVreg, oriScaleVreg, zeroVreg); | ||
| 346 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(scaleF32Vreg, scaleVreg, preg); | ||
| 347 | - } else { | ||
| 348 | - GetPerGroupScale<scaleT>(scaleUb + i * scaleK, j * vecLen, para, config, scaleF32Vreg); | ||
| 349 | - } | ||
| 350 | - MicroAPI::DataCopy<int32_t, MicroAPI::LoadDist::DIST_NORM>(srcVreg, srcUb + i * para.n + j * vecLen); | ||
| 351 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32Vreg, srcVreg, preg); | ||
| 352 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, f32Vreg, scaleF32Vreg, preg); | ||
| 353 | - StoreRes<dstT>(dstUb + i * para.n + j * vecLen, f32Vreg, preg); | ||
| 354 | - } | ||
| 355 | - } | ||
| 356 | -} | ||
| 357 | - | ||
| 358 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 359 | -__aicore__ inline void DeQuantPerGroupForColS32(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 360 | - const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor, | ||
| 361 | - const AscendDeQuantParam& para) | ||
| 362 | -{ | ||
| 363 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 364 | - __ubuf__ srcT* srcUb = (__ubuf__ srcT*)srcTensor.GetPhyAddr(); | ||
| 365 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)scaleTensor.GetPhyAddr(); | ||
| 366 | - DeQuantPerGroupForColS32VF<dstT, srcT, scaleT, config>(dstUb, srcUb, scaleUb, para); | ||
| 367 | -} | ||
| 368 | - | ||
| 369 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 370 | -__simd_vf__ inline void DeQuantPerGroupForColF32VF(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 371 | - __ubuf__ scaleT* scaleUb, const AscendDeQuantParam para) | ||
| 372 | -{ | ||
| 373 | - uint16_t rowNum = para.calCount / para.n; | ||
| 374 | - uint32_t vecLen = ASCENDC_QUANT_B32_VF_LEN; | ||
| 375 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(para.n, vecLen)); | ||
| 376 | - uint16_t scaleK = static_cast<uint16_t>(CeilDivision(para.n, para.groupSize)); | ||
| 377 | - | ||
| 378 | - MicroAPI::MaskReg preg; | ||
| 379 | - MicroAPI::RegTensor<float> srcVreg; | ||
| 380 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 381 | - MicroAPI::RegTensor<scaleT> oriScaleVreg; | ||
| 382 | - MicroAPI::RegTensor<scaleT> tempVreg; | ||
| 383 | - MicroAPI::RegTensor<float> offsetVreg; | ||
| 384 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 385 | - MicroAPI::RegTensor<float> scaleF32Vreg; | ||
| 386 | - MicroAPI::RegTensor<dstT> dstVreg; | ||
| 387 | - MicroAPI::RegTensor<scaleT> zeroVreg; | ||
| 388 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 389 | - MicroAPI::MaskReg b16FullPreg = MicroAPI::CreateMask<uint16_t, MicroAPI::MaskPattern::ALL>(); | ||
| 390 | - MicroAPI::Duplicate(zeroVreg, static_cast<scaleT>(0), b16FullPreg); | ||
| 391 | - } else { | ||
| 392 | - MicroAPI::MaskReg b32FullPreg = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 393 | - MicroAPI::Duplicate(zeroVreg, static_cast<scaleT>(0), b32FullPreg); | ||
| 394 | - } | ||
| 395 | - for (uint16_t i = 0; i < static_cast<uint16_t>(rowNum); ++i) { | ||
| 396 | - uint32_t sreg = para.n; | ||
| 397 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 398 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 399 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 400 | - GetPerGroupScale<scaleT>(scaleUb + i * scaleK, j * vecLen, para, config, oriScaleVreg); | ||
| 401 | - MicroAPI::Interleave(scaleVreg, tempVreg, oriScaleVreg, zeroVreg); | ||
| 402 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(scaleF32Vreg, scaleVreg, preg); | ||
| 403 | - } else { | ||
| 404 | - GetPerGroupScale<scaleT>(scaleUb + i * scaleK, j * vecLen, para, config, scaleF32Vreg); | ||
| 405 | - } | ||
| 406 | - MicroAPI::DataCopy<float, MicroAPI::LoadDist::DIST_NORM>(srcVreg, srcUb + i * para.n + j * vecLen); | ||
| 407 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, srcVreg, scaleF32Vreg, preg); | ||
| 408 | - StoreRes<dstT>(dstUb + i * para.n + j * vecLen, f32Vreg, preg); | ||
| 409 | - } | ||
| 410 | - } | ||
| 411 | -} | ||
| 412 | - | ||
| 413 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 414 | -__aicore__ inline void DeQuantPerGroupForColF32(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 415 | - const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor, | ||
| 416 | - const AscendDeQuantParam& para) | ||
| 417 | -{ | ||
| 418 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 419 | - __ubuf__ srcT* srcUb = (__ubuf__ srcT*)srcTensor.GetPhyAddr(); | ||
| 420 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)scaleTensor.GetPhyAddr(); | ||
| 421 | - DeQuantPerGroupForColF32VF<dstT, srcT, scaleT, config>(dstUb, srcUb, scaleUb, para); | ||
| 422 | -} | ||
| 423 | - | ||
| 424 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 425 | -__simd_callee__ inline void DeQuantPerGroupForRowTailBlock(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 426 | - __ubuf__ scaleT* scaleUb, uint16_t repeat, | ||
| 427 | - uint16_t tailRow, uint32_t n, uint32_t vecLen) | ||
| 428 | -{ | ||
| 429 | - MicroAPI::MaskReg preg; | ||
| 430 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 431 | - MicroAPI::RegTensor<float> f32ScaleVreg; | ||
| 432 | - MicroAPI::RegTensor<srcT> srcVreg; | ||
| 433 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 434 | - MicroAPI::MaskReg b32FullPreg = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 435 | - for (uint16_t i = 0; i < tailRow; ++i) { | ||
| 436 | - uint32_t sreg = n; | ||
| 437 | - for (uint16_t j = 0; j < repeat; ++j) { | ||
| 438 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 439 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_UNPACK_B16>(scaleVreg, scaleUb + j * vecLen); | ||
| 440 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(f32ScaleVreg, scaleVreg, b32FullPreg); | ||
| 441 | - } else { | ||
| 442 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_NORM>(f32ScaleVreg, scaleUb + j * vecLen); | ||
| 443 | - } | ||
| 444 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 445 | - MicroAPI::DataCopy<srcT, MicroAPI::LoadDist::DIST_NORM>(srcVreg, srcUb + i * n + j * vecLen); | ||
| 446 | - if constexpr (SupportType<srcT, int32_t>()) { | ||
| 447 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32Vreg, srcVreg, preg); | ||
| 448 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, f32Vreg, f32ScaleVreg, preg); | ||
| 449 | - } else { | ||
| 450 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, srcVreg, f32ScaleVreg, preg); | ||
| 451 | - } | ||
| 452 | - StoreRes<dstT>(dstUb + i * n + j * vecLen, f32Vreg, preg); | ||
| 453 | - } | ||
| 454 | - } | ||
| 455 | -} | ||
| 456 | - | ||
| 457 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 458 | -__simd_vf__ inline void DeQuantPerGroupForRowVF(__ubuf__ dstT* dstUb, __ubuf__ srcT* srcUb, | ||
| 459 | - __ubuf__ scaleT* scaleUb, const AscendDeQuantParam para, uint16_t rowNum, uint16_t tailRow) | ||
| 460 | -{ | ||
| 461 | - uint16_t mainRowGroup = rowNum / para.groupSize; | ||
| 462 | - uint32_t vecLen = ASCENDC_QUANT_B32_VF_LEN; | ||
| 463 | - uint16_t repeat = static_cast<uint16_t>(CeilDivision(para.n, vecLen)); | ||
| 464 | - | ||
| 465 | - MicroAPI::MaskReg preg; | ||
| 466 | - MicroAPI::RegTensor<scaleT> scaleVreg; | ||
| 467 | - MicroAPI::RegTensor<float> f32ScaleVreg; | ||
| 468 | - MicroAPI::RegTensor<srcT> srcVreg; | ||
| 469 | - MicroAPI::RegTensor<float> f32Vreg; | ||
| 470 | - MicroAPI::MaskReg b32FullPreg = MicroAPI::CreateMask<uint32_t, MicroAPI::MaskPattern::ALL>(); | ||
| 471 | - for (uint16_t i = 0; i < mainRowGroup; ++i) { | ||
| 472 | - for (uint16_t j = 0; j < static_cast<uint16_t>(para.groupSize); ++j) { | ||
| 473 | - uint32_t sreg = para.n; | ||
| 474 | - for (uint16_t k = 0; k < repeat; ++k) { | ||
| 475 | - if constexpr (SupportType<scaleT, half, bfloat16_t>()) { | ||
| 476 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_UNPACK_B16>(scaleVreg, scaleUb + i * para.n + k * vecLen); | ||
| 477 | - MicroAPI::Cast<float, scaleT, layoutZMrgZ>(f32ScaleVreg, scaleVreg, b32FullPreg); | ||
| 478 | - } else { | ||
| 479 | - MicroAPI::DataCopy<scaleT, MicroAPI::LoadDist::DIST_NORM>( | ||
| 480 | - f32ScaleVreg, scaleUb + i * para.n + k * vecLen); | ||
| 481 | - } | ||
| 482 | - preg = MicroAPI::UpdateMask<uint32_t>(sreg); | ||
| 483 | - MicroAPI::DataCopy<srcT, MicroAPI::LoadDist::DIST_NORM>( | ||
| 484 | - srcVreg, srcUb + (i * para.groupSize + j) * para.n + k * vecLen); | ||
| 485 | - if constexpr (SupportType<srcT, int32_t>()) { | ||
| 486 | - MicroAPI::Cast<float, int32_t, MrgZRndA>(f32Vreg, srcVreg, preg); | ||
| 487 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, f32Vreg, f32ScaleVreg, preg); | ||
| 488 | - } else { | ||
| 489 | - MicroAPI::Mul<float, MicroAPI::MaskMergeMode::ZEROING>(f32Vreg, srcVreg, f32ScaleVreg, preg); | ||
| 490 | - } | ||
| 491 | - StoreRes<dstT>(dstUb + (i * para.groupSize + j) * para.n + k * vecLen, f32Vreg, preg); | ||
| 492 | - } | ||
| 493 | - } | ||
| 494 | - } | ||
| 495 | - DeQuantPerGroupForRowTailBlock<dstT, srcT, scaleT, config>( | ||
| 496 | - dstUb + mainRowGroup * para.groupSize * para.n, srcUb + mainRowGroup * para.groupSize * para.n, | ||
| 497 | - scaleUb + mainRowGroup * para.n, repeat, tailRow, para.n, vecLen); | ||
| 498 | -} | ||
| 499 | - | ||
| 500 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 501 | -__aicore__ inline void DeQuantPerGroupForRow(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 502 | - const LocalTensor<scaleT>& scaleTensor, const LocalTensor<scaleT>& offsetTensor, | ||
| 503 | - const AscendDeQuantParam& para) | ||
| 504 | -{ | ||
| 505 | - __ubuf__ dstT* dstUb = (__ubuf__ dstT*)dstTensor.GetPhyAddr(); | ||
| 506 | - __ubuf__ srcT* srcUb = (__ubuf__ srcT*)srcTensor.GetPhyAddr(); | ||
| 507 | - __ubuf__ scaleT* scaleUb = (__ubuf__ scaleT*)scaleTensor.GetPhyAddr(); | ||
| 508 | - uint16_t rowNum = para.calCount / para.n; | ||
| 509 | - uint16_t tailRow = rowNum % para.groupSize; | ||
| 510 | - DeQuantPerGroupForRowVF<dstT, srcT, scaleT, config>(dstUb, srcUb, scaleUb, para, rowNum, tailRow); | ||
| 511 | -} | ||
| 512 | - | ||
| 513 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 514 | -__aicore__ inline void AscendDeQuantPerToken(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 515 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const LocalTensor<scaleT>& scaleTensor, | ||
| 516 | - const LocalTensor<scaleT>& offsetTensor, const AscendDeQuantParam& para) | ||
| 517 | -{ | ||
| 518 | - if constexpr (SupportType<srcT, int32_t>()) { | ||
| 519 | - DeQuantPerTokenForS32<dstT, srcT, scaleT, config>(dstTensor, srcTensor, scaleTensor, offsetTensor, para); | ||
| 520 | - } else if constexpr (SupportType<srcT, float>()) { | ||
| 521 | - DeQuantPerTokenForF32<dstT, srcT, scaleT, config>(dstTensor, srcTensor, scaleTensor, offsetTensor, para); | ||
| 522 | - } else { | ||
| 523 | - ASCENDC_ASSERT((false), { KERNEL_LOG(KERNEL_ERROR, "unsupport srcT for AscendDeQuant!"); }); | ||
| 524 | - } | ||
| 525 | -} | ||
| 526 | - | ||
| 527 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 528 | -__aicore__ inline void AscendDeQuantPerGroupForCol(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 529 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const LocalTensor<scaleT>& scaleTensor, | ||
| 530 | - const LocalTensor<scaleT>& offsetTensor, const AscendDeQuantParam& para) | ||
| 531 | -{ | ||
| 532 | - if constexpr (SupportType<srcT, int32_t>()) { | ||
| 533 | - DeQuantPerGroupForColS32<dstT, srcT, scaleT, config>(dstTensor, srcTensor, scaleTensor, offsetTensor, para); | ||
| 534 | - } else if constexpr (SupportType<srcT, float>()) { | ||
| 535 | - DeQuantPerGroupForColF32<dstT, srcT, scaleT, config>(dstTensor, srcTensor, scaleTensor, offsetTensor, para); | ||
| 536 | - } else { | ||
| 537 | - ASCENDC_ASSERT((false), { KERNEL_LOG(KERNEL_ERROR, "unsupport srcT for AscendDeQuant!"); }); | ||
| 538 | - } | ||
| 539 | -} | ||
| 540 | - | ||
| 541 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config> | ||
| 542 | -__aicore__ inline void AscendDeQuantPerGroupForRow(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 543 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const LocalTensor<scaleT>& scaleTensor, | ||
| 544 | - const LocalTensor<scaleT>& offsetTensor, const AscendDeQuantParam& para) | ||
| 545 | -{ | ||
| 546 | - if constexpr (SupportType<srcT, int32_t, float>()) { | ||
| 547 | - DeQuantPerGroupForRow<dstT, srcT, scaleT, config>(dstTensor, srcTensor, scaleTensor, offsetTensor, para); | ||
| 548 | - } else { | ||
| 549 | - ASCENDC_ASSERT((false), { KERNEL_LOG(KERNEL_ERROR, "unsupport srcT for AscendDeQuant!"); }); | ||
| 550 | - } | ||
| 551 | -} | ||
| 552 | - | ||
| 553 | -template <typename dstT, typename srcT, typename scaleT, const AscendDeQuantConfig& config, const AscendDeQuantPolicy& policy> | ||
| 554 | -__aicore__ inline void AscendDequantImpl(const LocalTensor<dstT>& dstTensor, const LocalTensor<srcT>& srcTensor, | ||
| 555 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const LocalTensor<scaleT>& scaleTensor, | ||
| 556 | - const LocalTensor<scaleT>& offsetTensor, const AscendDeQuantParam& para) | ||
| 557 | -{ | ||
| 558 | - if ASCEND_IS_AIC { | ||
| 559 | - return; | ||
| 560 | - } | ||
| 561 | - CheckTensorPosition(dstTensor, "dstTensor", "VECIN, VECOUT, VECCALC"); | ||
| 562 | - CheckTensorPosition(srcTensor, "srcTensor", "VECIN, VECOUT, VECCALC"); | ||
| 563 | - CheckTensorPosition(scaleTensor, "scaleTensor", "VECIN, VECOUT, VECCALC"); | ||
| 564 | - CheckTensorPosition(offsetTensor, "offsetTensor", "VECIN, VECOUT, VECCALC"); | ||
| 565 | - static_assert(SupportType<srcT, int32_t, float>(), | ||
| 566 | - "AscendDequant only support int32_t/float input dtype"); | ||
| 567 | - static_assert(SupportType<dstT, bfloat16_t, half, float>(), | ||
| 568 | - "AscendDequant only support bfloat16_t/half/float output dtype"); | ||
| 569 | - static_assert(SupportType<scaleT, bfloat16_t, half, float>(), | ||
| 570 | - "AscendDequant only support bfloat16_t/half/float scaleT dtype"); | ||
| 571 | - static_assert(((policy == AscendDeQuantPolicy::PER_TOKEN) || (policy == AscendDeQuantPolicy::PER_GROUP)), | ||
| 572 | - "unsupported policy for AscendDequant in current device!"); | ||
| 573 | - ASCENDC_ASSERT((para.calCount <= srcTensor.GetSize() && para.calCount <= dstTensor.GetSize() && para.calCount >= 0), { | ||
| 574 | - KERNEL_LOG(KERNEL_ERROR, "calCount is %u, which should be in [0, min(%u, %u)]", | ||
| 575 | - para.calCount, srcTensor.GetSize(), dstTensor.GetSize()); | ||
| 576 | - }); | ||
| 577 | - if constexpr (policy == AscendDeQuantPolicy::PER_TOKEN) { | ||
| 578 | - AscendDeQuantPerToken<dstT, srcT, scaleT, config>(dstTensor, srcTensor, sharedTmpBuffer, scaleTensor, offsetTensor, para); | ||
| 579 | - } else if constexpr (policy == AscendDeQuantPolicy::PER_GROUP) { | ||
| 580 | - static_assert( | ||
| 581 | - ((config.kDim == 0) || (config.kDim == 1)), "AscendDequant PerGroup only support kDim is axis 0/1!"); | ||
| 582 | - ASCENDC_ASSERT((para.groupSize > 0 && para.groupSize % 32 == 0), | ||
| 583 | - { KERNEL_LOG(KERNEL_ERROR, "groupSize must be an integer multiple of 32 and greater than 0 !"); }); | ||
| 584 | - if constexpr (config.kDim == 1) { | ||
| 585 | - AscendDeQuantPerGroupForCol<dstT, srcT, scaleT, config>(dstTensor, srcTensor, sharedTmpBuffer, scaleTensor, offsetTensor, para); | ||
| 586 | - } else { | ||
| 587 | - AscendDeQuantPerGroupForRow<dstT, srcT, scaleT, config>(dstTensor, srcTensor, sharedTmpBuffer, scaleTensor, offsetTensor, para); | ||
| 588 | - } | ||
| 589 | - } | ||
| 590 | -} | ||
| 591 | -} // namespace AscendC | ||
| 592 | - | ||
Dimpl/adv_api/detail/reduce/sum/sum_l300_impl.h+0-137
| @@ -1,137 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file sum_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | -namespace AscendC { | ||
| 23 | -namespace SumInternal { | ||
| 24 | -template <typename T> | ||
| 25 | -__simd_vf__ inline void SumForOneRepeatTime( | ||
| 26 | - __ubuf__ T* dstUb, __ubuf__ T* srcUb, const SumParams sumParams, uint32_t count, uint32_t offset) | ||
| 27 | -{ | ||
| 28 | - uint32_t calCount; | ||
| 29 | - MicroAPI::MaskReg mask; | ||
| 30 | - MicroAPI::UnalignReg uregOut; | ||
| 31 | - MicroAPI::RegTensor<T> srcReg, dstReg; | ||
| 32 | - | ||
| 33 | - for (int i = 0; i < sumParams.outter; i++) { | ||
| 34 | - calCount = count; | ||
| 35 | - mask = MicroAPI::UpdateMask<T>(calCount); | ||
| 36 | - MicroAPI::DataCopy(srcReg, srcUb + i * offset); | ||
| 37 | - MicroAPI::ReduceSum(dstReg, srcReg, mask); | ||
| 38 | - MicroAPI::DataCopyUnAlign<T, MicroAPI::PostLiteral::POST_MODE_UPDATE>(dstUb, dstReg, uregOut, 1); | ||
| 39 | - } | ||
| 40 | - MicroAPI::DataCopyUnAlignPost(dstUb, uregOut, 0); | ||
| 41 | -} | ||
| 42 | - | ||
| 43 | -template <typename T, bool isFirstRepeat> | ||
| 44 | -__simd_vf__ inline void ReduceSumNextN(__ubuf__ T* dstUb, __ubuf__ T* srcUb, const SumParams sumParams, | ||
| 45 | - uint32_t calCount, uint32_t repeatTimes, uint32_t offset) | ||
| 46 | -{ | ||
| 47 | - uint32_t count; | ||
| 48 | - MicroAPI::MaskReg mask; | ||
| 49 | - MicroAPI::UnalignReg uregIn; | ||
| 50 | - MicroAPI::RegTensor<T> srcReg, dstReg; | ||
| 51 | - constexpr int32_t eleCountPerVL = GetVecLen() / sizeof(T); | ||
| 52 | - for (uint16_t i = 0; i < sumParams.outter; i++) { | ||
| 53 | - count = calCount; | ||
| 54 | - auto dstTmpUb = dstUb + i * offset; | ||
| 55 | - for (uint16_t j = 0; j < repeatTimes; j++) { | ||
| 56 | - mask = MicroAPI::UpdateMask<T>(count); | ||
| 57 | - if constexpr (isFirstRepeat) { | ||
| 58 | - MicroAPI::DataCopy(srcReg, srcUb + i * sumParams.inner + j * eleCountPerVL); | ||
| 59 | - } else { | ||
| 60 | - MicroAPI::DataCopy(srcReg, srcUb + i * offset + j * eleCountPerVL); | ||
| 61 | - } | ||
| 62 | - MicroAPI::ReduceSum(dstReg, srcReg, mask); | ||
| 63 | - MicroAPI::DataCopyUnAlign<T, MicroAPI::PostLiteral::POST_MODE_UPDATE>(dstTmpUb, dstReg, uregIn, 1); | ||
| 64 | - } | ||
| 65 | - MicroAPI::DataCopyUnAlignPost(dstTmpUb, uregIn, 0); | ||
| 66 | - } | ||
| 67 | - MicroAPI::LocalMemBar<MicroAPI::MemType::VEC_STORE, MicroAPI::MemType::VEC_LOAD>(); | ||
| 68 | -} | ||
| 69 | -} // namespace SumInternal | ||
| 70 | - | ||
| 71 | -template <typename T, int32_t reduceDim = -1, bool isReuseSource = false, bool isBasicBlock = false> | ||
| 72 | -__aicore__ inline void SumCheckParams(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 73 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const SumParams& sumParams) | ||
| 74 | -{ | ||
| 75 | - static_assert(SupportType<T, half, float>(), "current data type is not supported on current device!"); | ||
| 76 | - CheckTensorPos<T>(dstTensor, Hardware::UB, "dstTensor", "VECIN / VECCALC / VECOUT", "Sum"); | ||
| 77 | - CheckTensorPos<T>(srcTensor, Hardware::UB, "srcTensor", "VECIN / VECCALC / VECOUT", "Sum"); | ||
| 78 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", "Sum"); | ||
| 79 | - constexpr uint32_t sumInnerAlignLen = 32; | ||
| 80 | - ASCENDC_ASSERT((1 <= sumParams.n) && (sumParams.n <= sumParams.inner), { | ||
| 81 | - KERNEL_LOG(KERNEL_ERROR, "The value of n must be greater than or equal to 1 and less than or equal to inner."); | ||
| 82 | - }); | ||
| 83 | - ASCENDC_ASSERT((sumParams.inner * sizeof(T) % sumInnerAlignLen == 0), | ||
| 84 | - { KERNEL_LOG(KERNEL_ERROR, "The value of inner * sizeof(T) must be an integer multiple of 32."); }); | ||
| 85 | -} | ||
| 86 | - | ||
| 87 | -template <typename T, int32_t reduceDim = -1, bool isReuseSource = false, bool isBasicBlock = false> | ||
| 88 | -__aicore__ inline void SumCompute(const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, | ||
| 89 | - const LocalTensor<uint8_t>& sharedTmpBuffer, const SumParams& sumParams) | ||
| 90 | -{ | ||
| 91 | - // Only for AI Vector Core. | ||
| 92 | - if ASCEND_IS_AIC { | ||
| 93 | - return; | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | - SumCheckParams<T, reduceDim, isReuseSource, isBasicBlock>(dstTensor, srcTensor, sharedTmpBuffer, sumParams); | ||
| 97 | - __ubuf__ T* dstUb = (__ubuf__ T*)dstTensor.GetPhyAddr(); | ||
| 98 | - __ubuf__ T* srcUb = (__ubuf__ T*)srcTensor.GetPhyAddr(); | ||
| 99 | - __ubuf__ T* sharedTmpBufferUb = (__ubuf__ T*)sharedTmpBuffer.GetPhyAddr(); | ||
| 100 | - | ||
| 101 | - constexpr int32_t eleCountPerVL = GetVecLen() / sizeof(T); | ||
| 102 | - uint16_t repeatTimes = CeilDivision(sumParams.n, eleCountPerVL); | ||
| 103 | - uint32_t loopRepeatTimes; | ||
| 104 | - uint32_t calCount = sumParams.n; | ||
| 105 | - | ||
| 106 | - uint32_t totalCnt = 1; | ||
| 107 | - uint32_t dataSize = repeatTimes; | ||
| 108 | - uint32_t offset = AlignUp(CeilDivision(sumParams.inner, eleCountPerVL), 32); | ||
| 109 | - while (dataSize > 1) { | ||
| 110 | - ++totalCnt; | ||
| 111 | - dataSize = CeilDivision(dataSize, eleCountPerVL); | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - if (repeatTimes == 1) { | ||
| 115 | - SumInternal::SumForOneRepeatTime<T>(dstUb, srcUb, sumParams, sumParams.n, sumParams.inner); | ||
| 116 | - return; | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - SumInternal::ReduceSumNextN<T, true>(sharedTmpBufferUb, srcUb, sumParams, calCount, repeatTimes, offset); | ||
| 120 | - | ||
| 121 | - --totalCnt; | ||
| 122 | - loopRepeatTimes = repeatTimes; | ||
| 123 | - while (totalCnt != 0) { | ||
| 124 | - calCount = loopRepeatTimes; | ||
| 125 | - loopRepeatTimes = CeilDivision(loopRepeatTimes, eleCountPerVL); | ||
| 126 | - if (totalCnt == 1) { | ||
| 127 | - SumInternal::SumForOneRepeatTime<T>(dstUb, sharedTmpBufferUb, sumParams, calCount, offset); | ||
| 128 | - } else { | ||
| 129 | - SumInternal::ReduceSumNextN<T, false>( | ||
| 130 | - sharedTmpBufferUb, sharedTmpBufferUb, sumParams, calCount, loopRepeatTimes, offset); | ||
| 131 | - } | ||
| 132 | - --totalCnt; | ||
| 133 | - } | ||
| 134 | -} | ||
| 135 | -} // namespace AscendC | ||
| 136 | - | ||
| 137 | - | ||
Dimpl/adv_api/detail/select/selectwithbytesmask/selectwithbytesmask_l300_impl.h+0-159
| @@ -1,159 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | - | ||
| 12 | - | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | -namespace AscendC { | ||
| 17 | -template <typename T, typename U, CMPMODE cmpMode> | ||
| 18 | -__simd_callee__ inline void RegTensorToMaskReg(MicroAPI::RegTensor<U> &vMaskReg0, MicroAPI::RegTensor<U> &vMaskReg1, | ||
| 19 | - MicroAPI::MaskReg &localMask0, MicroAPI::MaskReg &maskReg0) | ||
| 20 | -{ | ||
| 21 | - MicroAPI::MaskReg maskReg1; | ||
| 22 | - MicroAPI::MaskReg localMask1; | ||
| 23 | - if constexpr (sizeof(U) == 1) { | ||
| 24 | - MicroAPI::CompareScalar<uint8_t, cmpMode>(localMask0, (MicroAPI::RegTensor<uint8_t> &)vMaskReg0, | ||
| 25 | - static_cast<uint8_t>(0), maskReg0); | ||
| 26 | - } else if constexpr (sizeof(T) == 2 && sizeof(U) == 4) { | ||
| 27 | - MicroAPI::MaskUnPack(maskReg1, maskReg0); | ||
| 28 | - MicroAPI::CompareScalar<U, cmpMode>(localMask0, vMaskReg0, static_cast<U>(0), maskReg1); | ||
| 29 | - MicroAPI::CompareScalar<U, cmpMode>(localMask1, vMaskReg1, static_cast<U>(0), maskReg1); | ||
| 30 | - MicroAPI::MaskDeInterleave<T>(localMask0, localMask1, localMask0, localMask1); | ||
| 31 | - } else { | ||
| 32 | - MicroAPI::CompareScalar<U, cmpMode>(localMask0, vMaskReg0, static_cast<U>(0), maskReg0); | ||
| 33 | - } | ||
| 34 | -} | ||
| 35 | - | ||
| 36 | -template <typename T, typename U, bool reverse = false> | ||
| 37 | -__simd_vf__ inline void SelectWithBytesMaskPerAxisImpl(__ubuf__ T *dstUb, __ubuf__ T *src0Ub, T src1, | ||
| 38 | - __ubuf__ U *maskUb, const uint32_t firstAxis, const uint32_t srcLastAxis, const uint32_t maskLastAxis) | ||
| 39 | -{ | ||
| 40 | - MicroAPI::RegTensor<T> vSrcReg0; | ||
| 41 | - MicroAPI::RegTensor<T> vSrcReg1; | ||
| 42 | - MicroAPI::RegTensor<T> vDstReg; | ||
| 43 | - MicroAPI::RegTensor<U> vMaskReg0; | ||
| 44 | - MicroAPI::RegTensor<U> vMaskReg1; | ||
| 45 | - MicroAPI::MaskReg maskReg0; | ||
| 46 | - MicroAPI::MaskReg localMask0; | ||
| 47 | - MicroAPI::Duplicate(vSrcReg1, src1); | ||
| 48 | - uint32_t sreg; | ||
| 49 | - uint32_t sregLower = static_cast<uint32_t>(GetVecLen() / sizeof(T)); | ||
| 50 | - uint16_t repeatTimes = static_cast<uint16_t>(DivCeil(srcLastAxis, sregLower)); | ||
| 51 | - for (uint16_t loopH = 0; loopH < static_cast<uint16_t>(firstAxis); ++loopH) { | ||
| 52 | - sreg = srcLastAxis; | ||
| 53 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 54 | - maskReg0 = MicroAPI::UpdateMask<T>(sreg); | ||
| 55 | - MicroAPI::DataCopy<T>(vSrcReg0, src0Ub + loopH * srcLastAxis + i * sregLower); | ||
| 56 | - if constexpr (sizeof(T) == 2 && sizeof(U) == 1) { | ||
| 57 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK_B8>( | ||
| 58 | - (MicroAPI::RegTensor<uint8_t> &)vMaskReg0, | ||
| 59 | - (__ubuf__ uint8_t *)maskUb + loopH * maskLastAxis + i * sregLower); | ||
| 60 | - } else if constexpr (sizeof(T) == 2 && sizeof(U) == 4) { | ||
| 61 | - MicroAPI::DataCopy<U>(vMaskReg0, maskUb + loopH * maskLastAxis + i * sregLower); | ||
| 62 | - MicroAPI::DataCopy<U>(vMaskReg1, maskUb + loopH * maskLastAxis + i * sregLower + sregLower / 2); | ||
| 63 | - } else if constexpr (sizeof(T) == 4 && sizeof(U) == 1) { | ||
| 64 | - MicroAPI::DataCopy<uint8_t, MicroAPI::LoadDist::DIST_UNPACK4_B8>( | ||
| 65 | - (MicroAPI::RegTensor<uint8_t> &)vMaskReg0, | ||
| 66 | - (__ubuf__ uint8_t *)maskUb + loopH * maskLastAxis + i * sregLower); | ||
| 67 | - } else if constexpr (sizeof(T) == 4 && sizeof(U) == 2) { | ||
| 68 | - MicroAPI::DataCopy<U, MicroAPI::LoadDist::DIST_UNPACK_B16>(vMaskReg0, | ||
| 69 | - maskUb + loopH * maskLastAxis + i * sregLower); | ||
| 70 | - } else if constexpr (sizeof(T) == sizeof(U)) { | ||
| 71 | - MicroAPI::DataCopy<U>(vMaskReg0, maskUb + loopH * maskLastAxis + i * sregLower); | ||
| 72 | - } | ||
| 73 | - | ||
| 74 | - if constexpr (!reverse) { | ||
| 75 | - RegTensorToMaskReg<T, U, CMPMODE::EQ>(vMaskReg0, vMaskReg1, localMask0, maskReg0); | ||
| 76 | - } else { | ||
| 77 | - RegTensorToMaskReg<T, U, CMPMODE::NE>(vMaskReg0, vMaskReg1, localMask0, maskReg0); | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - MicroAPI::Select(vDstReg, vSrcReg0, vSrcReg1, localMask0); | ||
| 81 | - MicroAPI::DataCopy<T>(dstUb + loopH * srcLastAxis + i * sregLower, vDstReg, maskReg0); | ||
| 82 | - } | ||
| 83 | - } | ||
| 84 | -} | ||
| 85 | - | ||
| 86 | -template <typename T, typename U, bool reverse = false> | ||
| 87 | -__aicore__ inline void SelectWithBytesMaskProcess(const LocalTensor<T>& dst, const LocalTensor<T>& src0, T src1, | ||
| 88 | - const LocalTensor<U>& mask, const SelectWithBytesMaskShapeInfo& info) | ||
| 89 | -{ | ||
| 90 | - __ubuf__ T *src0Ub = (__ubuf__ T *)src0.GetPhyAddr(); | ||
| 91 | - __ubuf__ T *dstUb = (__ubuf__ T *)dst.GetPhyAddr(); | ||
| 92 | - __ubuf__ U *maskUb = (__ubuf__ U *)mask.GetPhyAddr(); | ||
| 93 | - const uint32_t firstAxis = static_cast<uint32_t>(info.firstAxis); | ||
| 94 | - const uint32_t srcLastAxis = static_cast<uint32_t>(info.srcLastAxis); | ||
| 95 | - const uint32_t maskLastAxis = static_cast<uint32_t>(info.maskLastAxis); | ||
| 96 | - SelectWithBytesMaskPerAxisImpl<T, U, reverse>(dstUb, src0Ub, src1, maskUb, firstAxis, srcLastAxis, | ||
| 97 | - maskLastAxis); | ||
| 98 | -} | ||
| 99 | - | ||
| 100 | -// Selects Values from two sources and put into dst according to the mask values. | ||
| 101 | -// True: Select scalar, False: select src. | ||
| 102 | -template <typename T, typename U, bool isReuseMask, bool reverse = false> | ||
| 103 | -__aicore__ inline __inout_pipe__(V) void SelectWithBytesMaskImpl(const LocalTensor<T>& dst, const LocalTensor<T>& src0, | ||
| 104 | - T src1, const LocalTensor<U>& mask, const LocalTensor<uint8_t>& sharedTmpBuffer, | ||
| 105 | - const SelectWithBytesMaskShapeInfo& info) | ||
| 106 | -{ | ||
| 107 | - // Only for AI Vector Core. | ||
| 108 | - if ASCEND_IS_AIC { | ||
| 109 | - return; | ||
| 110 | - } | ||
| 111 | - static_assert(SupportType<T, float, half>(), "Select do not support this type on current device"); | ||
| 112 | - static_assert(SupportType<U, bool, uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t>(), | ||
| 113 | - "Select do not support this type on current device"); | ||
| 114 | - CheckTensorPos<T>(dst, Hardware::UB, "dst", "VECIN / VECCALC / VECOUT", "Select"); | ||
| 115 | - CheckTensorPos<T>(src0, Hardware::UB, "src", "VECIN / VECCALC / VECOUT", "Select"); | ||
| 116 | - CheckTensorPos<U>(mask, Hardware::UB, "mask", "VECIN / VECCALC / VECOUT", "Select"); | ||
| 117 | - CheckTensorPos<uint8_t>(sharedTmpBuffer, Hardware::UB, "sharedTmpBuffer", "VECIN / VECCALC / VECOUT", | ||
| 118 | - "Select"); | ||
| 119 | - ASCENDC_ASSERT((info.srcLastAxis * sizeof(T) % ONE_BLK_SIZE == 0), { | ||
| 120 | - KERNEL_LOG(KERNEL_ERROR, "srcLastAxis should be 32B aligned, current srcLastAxis is %u", info.srcLastAxis); | ||
| 121 | - }); | ||
| 122 | - ASCENDC_ASSERT((info.maskLastAxis * sizeof(U) % ONE_BLK_SIZE == 0), { | ||
| 123 | - KERNEL_LOG(KERNEL_ERROR, "maskLastAxis should be 32B aligned, current maskLastAxis is %u", info.maskLastAxis); | ||
| 124 | - }); | ||
| 125 | - ASCENDC_ASSERT((info.maskLastAxis % BLOCK_CUBE == 0), { | ||
| 126 | - KERNEL_LOG(KERNEL_ERROR, "maskLastAxis should be multiples of 16, current maskLastAxis is %u", | ||
| 127 | - info.maskLastAxis); | ||
| 128 | - }); | ||
| 129 | - | ||
| 130 | - const uint32_t firstAxis = info.firstAxis; | ||
| 131 | - const uint32_t srcLastAxis = info.srcLastAxis; | ||
| 132 | - const uint32_t maskLastAxis = info.maskLastAxis; | ||
| 133 | - const uint32_t srcSize = src0.GetSize(); | ||
| 134 | - | ||
| 135 | - ASCENDC_ASSERT((srcSize == firstAxis * srcLastAxis), | ||
| 136 | - { KERNEL_LOG(KERNEL_ERROR, "ShapeInfo must be match with src Tensor size."); }); | ||
| 137 | - ASCENDC_ASSERT((mask.GetSize() == firstAxis * maskLastAxis), | ||
| 138 | - { KERNEL_LOG(KERNEL_ERROR, "ShapeInfo must be match with mask Tensor size."); }); | ||
| 139 | - ASCENDC_ASSERT((maskLastAxis >= srcLastAxis), | ||
| 140 | - { KERNEL_LOG(KERNEL_ERROR, "maskLastAxis must be greater than or equal to srcLastAxis."); }); | ||
| 141 | - | ||
| 142 | - SelectWithBytesMaskProcess<T, U, reverse>(dst, src0, src1, mask, info); | ||
| 143 | -} | ||
| 144 | - | ||
| 145 | -template <typename T, typename U, bool isReuseMask = true> | ||
| 146 | -__aicore__ inline void SelectWithBytesMask(const LocalTensor<T>& dst, const LocalTensor<T>& src0, T src1, | ||
| 147 | - const LocalTensor<U>& mask, const LocalTensor<uint8_t>& sharedTmpBuffer, const SelectWithBytesMaskShapeInfo& info) | ||
| 148 | -{ | ||
| 149 | - SelectWithBytesMaskImpl<T, U, isReuseMask, false>(dst, src0, src1, mask, sharedTmpBuffer, info); | ||
| 150 | -} | ||
| 151 | - | ||
| 152 | -template <typename T, typename U, bool isReuseMask = true> | ||
| 153 | -__aicore__ inline void SelectWithBytesMask(const LocalTensor<T>& dst, T src0, const LocalTensor<T>& src1, | ||
| 154 | - const LocalTensor<U>& mask, const LocalTensor<uint8_t>& sharedTmpBuffer, const SelectWithBytesMaskShapeInfo& info) | ||
| 155 | -{ | ||
| 156 | - SelectWithBytesMaskImpl<T, U, isReuseMask, true>(dst, src1, src0, mask, sharedTmpBuffer, info); | ||
| 157 | -} | ||
| 158 | -} // namespace AscendC | ||
| 159 | - | ||
Dimpl/adv_api/detail/sort/topk/topk_l300_impl.h+0-1610
| @@ -1,1610 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file topk_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - | ||
| 27 | - | ||
| 28 | -namespace AscendC { | ||
| 29 | - | ||
| 30 | -template <typename T, bool isInitIndex = false, enum TopKMode topkMode = TopKMode::TOPK_NORMAL, const TopKConfig& config = defaultTopKConfig> | ||
| 31 | -void TopkInputCheck(const int32_t k, const TopKInfo &topKInfo) | ||
| 32 | -{ | ||
| 33 | - ASCENDC_ASSERT((1 <= k) && (k <= topKInfo.n), { | ||
| 34 | - KERNEL_LOG(KERNEL_ERROR, "The value of k must be greater than or equal to 1 and less than or equal to inner."); | ||
| 35 | - }); | ||
| 36 | - ASCENDC_ASSERT((1 <= topKInfo.n) && (topKInfo.n <= topKInfo.inner), { | ||
| 37 | - KERNEL_LOG(KERNEL_ERROR, "The value of n must be greater than or equal to 1 and less than or equal to inner."); | ||
| 38 | - }); | ||
| 39 | - ASCENDC_ASSERT((topKInfo.inner % TOPK_INNER_ALIGN_LEN == 0), { | ||
| 40 | - KERNEL_LOG(KERNEL_ERROR, "The value of inner must be an integer multiple of 32."); | ||
| 41 | - }); | ||
| 42 | - | ||
| 43 | - if constexpr (config.algo == TopKAlgo::MERGE_SORT) { | ||
| 44 | - ASCENDC_ASSERT((std::is_same<T, half>::value) || (std::is_same<T, float>::value), { | ||
| 45 | - KERNEL_LOG(KERNEL_ERROR, "Type must be half or float in merge sort algorithm."); | ||
| 46 | - }); | ||
| 47 | - } | ||
| 48 | - if constexpr (topkMode == TopKMode::TOPK_NORMAL) { | ||
| 49 | - ASCENDC_ASSERT((topKInfo.inner <= TOPK_NORMAL_INNER_MAX_LEN), { | ||
| 50 | - KERNEL_LOG(KERNEL_ERROR, "The maximum value supported by inner is 4096."); | ||
| 51 | - }); | ||
| 52 | - } | ||
| 53 | - if constexpr (topkMode == TopKMode::TOPK_NSMALL) { | ||
| 54 | - ASCENDC_ASSERT((topKInfo.inner == TOPK_NSMALL_INNER_LEN), { | ||
| 55 | - KERNEL_LOG(KERNEL_ERROR, "The value of inner must be an equal 32."); | ||
| 56 | - }); | ||
| 57 | - } | ||
| 58 | -} | ||
| 59 | - | ||
| 60 | - | ||
| 61 | -template <typename T> | ||
| 62 | -__aicore__ inline void GatherDstValAndDstIdx(const LocalTensor<T> &dstValueLocal, | ||
| 63 | - const LocalTensor<int32_t> &dstIndexLocal, const LocalTensor<T> &tmpLocal, const TopkTiling &tilling, | ||
| 64 | - const int32_t dstOffsetFourBytes, const int outterIdx) | ||
| 65 | -{ | ||
| 66 | - uint64_t rsvdCnt = 0; | ||
| 67 | - struct GatherMaskParams reducev2Params(DEFAULT_BLK_STRIDE, 1, DEFAULT_REPEAT_STRIDE, DEFAULT_BLK_STRIDE); | ||
| 68 | - if constexpr (sizeof(T) == sizeof(float)) { | ||
| 69 | - // Get Value, The index of the odd position is obtained for each repeat. | ||
| 70 | - GatherMask<T>(dstValueLocal[dstOffsetFourBytes], tmpLocal[tilling.innerDataSize], REDUCEV2_MODE_ONE, | ||
| 71 | - true, tilling.maskVreducev2FourBytes, reducev2Params, rsvdCnt); | ||
| 72 | - } else { | ||
| 73 | - int32_t dstOffsetTwoBytes = outterIdx * tilling.kAlignTwoBytes; | ||
| 74 | - // Get Value. The first element is used for every four elements in each repeat. | ||
| 75 | - GatherMask<T>(dstValueLocal[dstOffsetTwoBytes], tmpLocal[tilling.innerDataSize], REDUCEV2_MODE_THREE, | ||
| 76 | - true, tilling.maskVreducev2TwoBytes, reducev2Params, rsvdCnt); | ||
| 77 | - } | ||
| 78 | - // Get Index, The index of the even position is obtained for each repeat. | ||
| 79 | - LocalTensor<int32_t> tempBufferLocal = tmpLocal[tilling.innerDataSize].template ReinterpretCast<int32_t>(); | ||
| 80 | - GatherMask<int32_t>(dstIndexLocal[dstOffsetFourBytes], tempBufferLocal, REDUCEV2_MODE_TWO, true, | ||
| 81 | - tilling.maskVreducev2FourBytes, reducev2Params, rsvdCnt); | ||
| 82 | -} | ||
| 83 | - | ||
| 84 | -template <typename T, bool isInitIndex> | ||
| 85 | -__aicore__ inline void TmpLocalSort32(const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, | ||
| 86 | - const LocalTensor<T> &tmpLocal, const TopkTiling &tilling, const TopKInfo &topKInfo, const bool isLargest, | ||
| 87 | - const int outterIdx) | ||
| 88 | -{ | ||
| 89 | - int offset = outterIdx * topKInfo.inner; | ||
| 90 | - LocalTensor<T> tmpBufferLocal = tmpLocal; | ||
| 91 | - if constexpr (!isInitIndex) { | ||
| 92 | - LocalTensor<uint32_t> tempBufferUint32 = tmpLocal[tilling.srcIndexOffset].template | ||
| 93 | - ReinterpretCast<uint32_t>(); | ||
| 94 | - Sort<T, true>(tmpLocal[tilling.innerDataSize], srcLocal[offset], tempBufferUint32, tmpBufferLocal, tilling.sortRepeat); | ||
| 95 | - } else { | ||
| 96 | - LocalTensor<uint32_t> tempBufferUint32 = srcIndexLocal.template ReinterpretCast<uint32_t>(); | ||
| 97 | - Sort<T, true>(tmpLocal[tilling.innerDataSize], srcLocal[offset], tempBufferUint32, tmpBufferLocal, tilling.sortRepeat); | ||
| 98 | - } | ||
| 99 | -} | ||
| 100 | - | ||
| 101 | -template <typename T, bool isInitIndex, bool isHasfinish> | ||
| 102 | -__aicore__ inline void TopKCompute(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 103 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 104 | - const LocalTensor<T> &tmpLocal, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 105 | - const bool isLargest) | ||
| 106 | -{ | ||
| 107 | - for (int j = 0; j < topKInfo.outter; ++j) { | ||
| 108 | - int32_t dstOffsetFourBytes = j * tilling.kAlignFourBytes; | ||
| 109 | - TmpLocalSort32<T, isInitIndex>(srcLocal, srcIndexLocal, tmpLocal, tilling, topKInfo, isLargest, j); | ||
| 110 | - | ||
| 111 | - GatherDstValAndDstIdx(dstValueLocal, dstIndexLocal, tmpLocal, tilling, dstOffsetFourBytes, j); | ||
| 112 | - | ||
| 113 | - if constexpr (isHasfinish) { | ||
| 114 | - bool finishValue = finishLocal.GetValue(j); | ||
| 115 | - auto eventID = GetTPipePtr()->FetchEventID(HardEvent::S_V); | ||
| 116 | - SetFlag<HardEvent::S_V>(eventID); | ||
| 117 | - WaitFlag<HardEvent::S_V>(eventID); | ||
| 118 | - | ||
| 119 | - if (finishValue) { | ||
| 120 | - Duplicate(dstIndexLocal[dstOffsetFourBytes], static_cast<int32_t>(topKInfo.n), k); | ||
| 121 | - } | ||
| 122 | - } | ||
| 123 | - } | ||
| 124 | -} | ||
| 125 | - | ||
| 126 | -template <typename T> | ||
| 127 | -__aicore__ inline void TopKNSmallGetTopKValue(const LocalTensor<T> &dstValueLocal, | ||
| 128 | - const LocalTensor<int32_t> &dstIndexLocal, const LocalTensor<T> &tmpLocal, const int32_t k, | ||
| 129 | - const TopkTiling &tilling, const TopKInfo &topKInfo) | ||
| 130 | -{ | ||
| 131 | - uint64_t rsvdCnt = 0; | ||
| 132 | - struct GatherMaskParams reducev2Params(DEFAULT_BLK_STRIDE, topKInfo.outter, DEFAULT_REPEAT_STRIDE, 0); | ||
| 133 | - if constexpr (sizeof(T) == sizeof(float)) { | ||
| 134 | - // Get Value, The index of the odd position is obtained for each repeat. | ||
| 135 | - GatherMask<T>(dstValueLocal, tmpLocal, REDUCEV2_MODE_ONE, | ||
| 136 | - true, 2 * k, reducev2Params, rsvdCnt); | ||
| 137 | - } else { | ||
| 138 | - // Get Value. The first element is used for every four elements in each repeat. | ||
| 139 | - GatherMask<T>(dstValueLocal, tmpLocal, REDUCEV2_MODE_THREE, | ||
| 140 | - true, 4 * k, reducev2Params, rsvdCnt); | ||
| 141 | - } | ||
| 142 | - // Get Index, The index of the even position is obtained for each repeat. | ||
| 143 | - LocalTensor<int32_t> tempBufferLocal = tmpLocal.template ReinterpretCast<int32_t>(); | ||
| 144 | - GatherMask<int32_t>(dstIndexLocal, tempBufferLocal, REDUCEV2_MODE_TWO, true, | ||
| 145 | - 2 * k, reducev2Params, rsvdCnt); | ||
| 146 | -} | ||
| 147 | - | ||
| 148 | -template <typename T, bool isInitIndex, bool isHasfinish> | ||
| 149 | -__aicore__ inline void TopKNSmallCompute(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 150 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 151 | - const LocalTensor<T> &tmpLocal, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 152 | - const bool isLargest) | ||
| 153 | -{ | ||
| 154 | - if constexpr (!isInitIndex) { | ||
| 155 | - LocalTensor<uint32_t> tempBufferUint32 = tmpLocal[tilling.innerDataSize].template | ||
| 156 | - ReinterpretCast<uint32_t>(); | ||
| 157 | - Sort32<T>(tmpLocal, srcLocal, tempBufferUint32, topKInfo.outter); | ||
| 158 | - } else { | ||
| 159 | - LocalTensor<uint32_t> tempBufferUint32 = srcIndexLocal.template ReinterpretCast<uint32_t>(); | ||
| 160 | - Sort32<T>(tmpLocal, srcLocal, tempBufferUint32, topKInfo.outter); | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - TopKNSmallGetTopKValue(dstValueLocal, dstIndexLocal, tmpLocal, k, tilling, topKInfo); | ||
| 164 | -} | ||
| 165 | - | ||
| 166 | -namespace MicroAPI { | ||
| 167 | -namespace RadixSelectTopK { | ||
| 168 | - | ||
| 169 | -constexpr uint32_t LOAD_NUMS_PER_ROUND = 256; | ||
| 170 | -constexpr uint32_t BUCKET_BYTES = 512; | ||
| 171 | - | ||
| 172 | -template <typename T> | ||
| 173 | -__aicore__ inline constexpr bool IsFloatNum() | ||
| 174 | -{ | ||
| 175 | - return SupportType<T, float, half, bfloat16_t>(); | ||
| 176 | -} | ||
| 177 | - | ||
| 178 | -template <typename T> | ||
| 179 | -__aicore__ inline constexpr bool NeedTwiddle() | ||
| 180 | -{ | ||
| 181 | - return SupportType<T, int8_t, int16_t, int32_t, int64_t, float, half, bfloat16_t>(); | ||
| 182 | -} | ||
| 183 | - | ||
| 184 | -__aicore__ inline constexpr bool NeedReverse(bool isLargest) | ||
| 185 | -{ | ||
| 186 | - return !isLargest; | ||
| 187 | -} | ||
| 188 | - | ||
| 189 | -template <bool isLargest> | ||
| 190 | -__aicore__ inline constexpr bool NeedReverse() | ||
| 191 | -{ | ||
| 192 | - return !isLargest; | ||
| 193 | -} | ||
| 194 | - | ||
| 195 | -template <typename T> | ||
| 196 | -__aicore__ inline constexpr bool NeedPreProcess(bool isLargest) | ||
| 197 | -{ | ||
| 198 | - return NeedReverse(isLargest) || NeedTwiddle<T>(); | ||
| 199 | -} | ||
| 200 | - | ||
| 201 | -template <typename T, bool isLargest> | ||
| 202 | -__aicore__ inline constexpr bool NeedPreProcess() | ||
| 203 | -{ | ||
| 204 | - return NeedReverse<isLargest>() || NeedTwiddle<T>(); | ||
| 205 | -} | ||
| 206 | - | ||
| 207 | -template <typename T, typename U, bool isLargest> | ||
| 208 | -__simd_vf__ inline void Preprocess(__ubuf__ T *src, __ubuf__ U *dst, uint32_t count) | ||
| 209 | -{ | ||
| 210 | - uint16_t repeatTime = DivCeil(count, GetVecLen() / sizeof(T)); | ||
| 211 | - uint32_t currCount = count; | ||
| 212 | - constexpr uint32_t postUpdateSize = GetVecLen() / sizeof(U); | ||
| 213 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 214 | - MaskReg maskReg = UpdateMask<U>(currCount); | ||
| 215 | - | ||
| 216 | - RegTensor<U> local; | ||
| 217 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>(local, (__ubuf__ U *&)src, postUpdateSize); | ||
| 218 | - if constexpr (NeedTwiddle<T>()) { | ||
| 219 | - AscendC::MicroAPI::Internal::TwiddleIn<T>(local, local, maskReg); | ||
| 220 | - } | ||
| 221 | - if constexpr (NeedReverse<isLargest>()) { | ||
| 222 | - Not(local, local, maskReg); | ||
| 223 | - } | ||
| 224 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>((__ubuf__ U *&)dst, local, postUpdateSize, maskReg); | ||
| 225 | - } | ||
| 226 | -} | ||
| 227 | - | ||
| 228 | -template <typename T, typename U, bool isLargest> | ||
| 229 | -__simd_vf__ inline void PostProcess(__ubuf__ U *src, __ubuf__ U *dst, uint32_t count) | ||
| 230 | -{ | ||
| 231 | - uint16_t repeatTime = DivCeil(count, GetVecLen() / sizeof(T)); | ||
| 232 | - constexpr uint32_t postUpdateSize = GetVecLen() / sizeof(U); | ||
| 233 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 234 | - MaskReg maskReg = UpdateMask<U>(count); | ||
| 235 | - | ||
| 236 | - RegTensor<U> local; | ||
| 237 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>(local, (__ubuf__ U *&)src, postUpdateSize); | ||
| 238 | - if constexpr (NeedReverse<isLargest>()) { | ||
| 239 | - Not(local, local, maskReg); | ||
| 240 | - } | ||
| 241 | - if constexpr (NeedTwiddle<T>()) { | ||
| 242 | - AscendC::MicroAPI::Internal::TwiddleOut<T>(local, local, maskReg); | ||
| 243 | - } | ||
| 244 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>((__ubuf__ U *&)dst, local, postUpdateSize, maskReg); | ||
| 245 | - } | ||
| 246 | -} | ||
| 247 | - | ||
| 248 | -template <typename T, typename U> | ||
| 249 | -__simd_vf__ inline void Preprocess(__ubuf__ T *src, __ubuf__ U *dst, bool isLargest, uint32_t count) | ||
| 250 | -{ | ||
| 251 | - uint16_t repeatTime = DivCeil(count, GetVecLen() / sizeof(T)); | ||
| 252 | - uint32_t currCount = count; | ||
| 253 | - constexpr uint32_t postUpdateSize = GetVecLen() / sizeof(U); | ||
| 254 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 255 | - MaskReg maskReg = UpdateMask<U>(currCount); | ||
| 256 | - | ||
| 257 | - RegTensor<U> local; | ||
| 258 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>(local, (__ubuf__ U *&)src, postUpdateSize); | ||
| 259 | - if constexpr (NeedTwiddle<T>()) { | ||
| 260 | - AscendC::MicroAPI::Internal::TwiddleIn<T>(local, local, maskReg); | ||
| 261 | - } | ||
| 262 | - if (NeedReverse(isLargest)) { | ||
| 263 | - Not(local, local, maskReg); | ||
| 264 | - } | ||
| 265 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>((__ubuf__ U *&)dst, local, postUpdateSize, maskReg); | ||
| 266 | - } | ||
| 267 | -} | ||
| 268 | - | ||
| 269 | -template <typename T, typename U> | ||
| 270 | -__simd_vf__ inline void PostProcess(__ubuf__ U *src, __ubuf__ U *dst, bool isLargest, uint32_t count) | ||
| 271 | -{ | ||
| 272 | - uint16_t repeatTime = DivCeil(count, GetVecLen() / sizeof(T)); | ||
| 273 | - constexpr uint32_t postUpdateSize = GetVecLen() / sizeof(U); | ||
| 274 | - for (uint16_t i = 0; i < repeatTime; i++) { | ||
| 275 | - MaskReg maskReg = UpdateMask<U>(count); | ||
| 276 | - | ||
| 277 | - RegTensor<U> local; | ||
| 278 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>(local, (__ubuf__ U *&)src, postUpdateSize); | ||
| 279 | - if (NeedReverse(isLargest)) { | ||
| 280 | - Not(local, local, maskReg); | ||
| 281 | - } | ||
| 282 | - if constexpr (NeedTwiddle<T>()) { | ||
| 283 | - AscendC::MicroAPI::Internal::TwiddleOut<T>(local, local, maskReg); | ||
| 284 | - } | ||
| 285 | - DataCopy<U, PostLiteral::POST_MODE_UPDATE>((__ubuf__ U *&)dst, local, postUpdateSize, maskReg); | ||
| 286 | - } | ||
| 287 | -} | ||
| 288 | - | ||
| 289 | -template<typename T, bool isReuseSrc, bool isLargest> | ||
| 290 | -__aicore__ inline void InitializeTempBuffer(const LocalTensor<T> &tempBuffer, const uint32_t alignCount, __ubuf__ T *&tmpSrcData, | ||
| 291 | - __ubuf__ int32_t *&tmpSrcIndex, __ubuf__ uint16_t *&tmpHistData, __ubuf__ T *&realWorkData, __ubuf__ T *&sortTmpBuffer) | ||
| 292 | -{ | ||
| 293 | - __ubuf__ uint8_t *tmp = (__ubuf__ uint8_t *)tempBuffer.GetPhyAddr(); | ||
| 294 | - tmpSrcData = (__ubuf__ T*)tmp; | ||
| 295 | - | ||
| 296 | - if constexpr (sizeof(T) == 8) { | ||
| 297 | - uint32_t srcOffset = 0; | ||
| 298 | - if (alignCount < LOAD_NUMS_PER_ROUND) { | ||
| 299 | - srcOffset += sizeof(T) * LOAD_NUMS_PER_ROUND; | ||
| 300 | - } else { | ||
| 301 | - srcOffset += sizeof(T) * alignCount; | ||
| 302 | - } | ||
| 303 | - | ||
| 304 | - tmpSrcIndex = (__ubuf__ int32_t*)((__ubuf__ uint8_t *)tmpSrcData + srcOffset); | ||
| 305 | - } else { | ||
| 306 | - tmpSrcIndex = (__ubuf__ int32_t*)((__ubuf__ uint8_t *)tmpSrcData + sizeof(T) * alignCount); | ||
| 307 | - } | ||
| 308 | - | ||
| 309 | - tmpHistData = (__ubuf__ uint16_t*)(tmpSrcIndex); | ||
| 310 | - | ||
| 311 | - if constexpr (NeedPreProcess<T, isLargest>()) { | ||
| 312 | - if constexpr (!isReuseSrc) { | ||
| 313 | - uint32_t indexSpace = alignCount * sizeof(int32_t); | ||
| 314 | - if (indexSpace < BUCKET_BYTES) { | ||
| 315 | - indexSpace = BUCKET_BYTES; | ||
| 316 | - } | ||
| 317 | - realWorkData = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + indexSpace); | ||
| 318 | - sortTmpBuffer = realWorkData; | ||
| 319 | - } else { | ||
| 320 | - sortTmpBuffer = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + sizeof(int32_t) * alignCount); | ||
| 321 | - } | ||
| 322 | - } else { | ||
| 323 | - sortTmpBuffer = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + sizeof(int32_t) * alignCount); | ||
| 324 | - } | ||
| 325 | -} | ||
| 326 | - | ||
| 327 | -template<typename T, bool isReuseSrc> | ||
| 328 | -__aicore__ inline void InitializeTempBuffer(const LocalTensor<T> &tempBuffer, bool isLargest, const uint32_t alignCount, | ||
| 329 | - __ubuf__ T *&tmpSrcData, __ubuf__ int32_t *&tmpSrcIndex, __ubuf__ uint16_t *&tmpHistData, | ||
| 330 | - __ubuf__ T *&realWorkData, __ubuf__ T *&sortTmpBuffer) | ||
| 331 | -{ | ||
| 332 | - __ubuf__ uint8_t *tmp = (__ubuf__ uint8_t *)tempBuffer.GetPhyAddr(); | ||
| 333 | - tmpSrcData = (__ubuf__ T*)tmp; | ||
| 334 | - | ||
| 335 | - if constexpr (sizeof(T) == 8) { | ||
| 336 | - uint32_t srcOffset = 0; | ||
| 337 | - if (alignCount < LOAD_NUMS_PER_ROUND) { | ||
| 338 | - srcOffset += sizeof(T) * LOAD_NUMS_PER_ROUND; | ||
| 339 | - } else { | ||
| 340 | - srcOffset += sizeof(T) * alignCount; | ||
| 341 | - } | ||
| 342 | - tmpSrcIndex = (__ubuf__ int32_t*)((__ubuf__ uint8_t *)tmpSrcData + srcOffset); | ||
| 343 | - } else { | ||
| 344 | - tmpSrcIndex = (__ubuf__ int32_t*)((__ubuf__ uint8_t *)tmpSrcData + sizeof(T) * alignCount); | ||
| 345 | - } | ||
| 346 | - | ||
| 347 | - tmpHistData = (__ubuf__ uint16_t*)(tmpSrcIndex); | ||
| 348 | - | ||
| 349 | - if (NeedPreProcess<T>(isLargest)) { | ||
| 350 | - if constexpr (!isReuseSrc) { | ||
| 351 | - uint32_t indexSpace = alignCount * sizeof(int32_t); | ||
| 352 | - if (indexSpace < BUCKET_BYTES) { | ||
| 353 | - indexSpace = BUCKET_BYTES; | ||
| 354 | - } | ||
| 355 | - realWorkData = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + indexSpace); | ||
| 356 | - sortTmpBuffer = realWorkData; | ||
| 357 | - } else { | ||
| 358 | - sortTmpBuffer = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + sizeof(int32_t) * alignCount); | ||
| 359 | - } | ||
| 360 | - } else { | ||
| 361 | - sortTmpBuffer = (__ubuf__ T*)((__ubuf__ uint8_t*)tmpSrcIndex + sizeof(int32_t) * alignCount); | ||
| 362 | - } | ||
| 363 | -} | ||
| 364 | - | ||
| 365 | -__simd_callee__ inline void GetLowerstByte(RegTensor<uint8_t>& dst, RegTensor<uint16_t>& src0, RegTensor<uint16_t>& src1) | ||
| 366 | -{ | ||
| 367 | - RegTensor<uint8_t> tmpU8Reg; | ||
| 368 | - DeInterleave(dst, tmpU8Reg, (RegTensor<uint8_t> &)src0, (RegTensor<uint8_t> &)src1); | ||
| 369 | -} | ||
| 370 | - | ||
| 371 | -__simd_callee__ inline void GetLowerstByte(RegTensor<uint8_t>& dst, RegTensor<uint32_t>& src0, RegTensor<uint32_t>& src1, RegTensor<uint32_t>& src2, RegTensor<uint32_t>& src3) | ||
| 372 | -{ | ||
| 373 | - RegTensor<uint16_t> tmpU16Reg0, tmpU16Reg1, tmpU16Reg2; | ||
| 374 | - DeInterleave(tmpU16Reg0, tmpU16Reg1, (RegTensor<uint16_t> &)src0, (RegTensor<uint16_t> &)src1); | ||
| 375 | - DeInterleave(tmpU16Reg2, tmpU16Reg1, (RegTensor<uint16_t> &)src2, (RegTensor<uint16_t> &)src3); | ||
| 376 | - | ||
| 377 | - GetLowerstByte(dst, tmpU16Reg0, tmpU16Reg2); | ||
| 378 | -} | ||
| 379 | - | ||
| 380 | -__simd_callee__ inline void TransToB8Mask(MaskReg& dst, MaskReg& u16Src0, MaskReg& u16Src1) | ||
| 381 | -{ | ||
| 382 | - MaskReg tmpU8Mask; | ||
| 383 | - MaskDeInterleave<uint8_t>(dst, tmpU8Mask, u16Src0, u16Src1); | ||
| 384 | -} | ||
| 385 | - | ||
| 386 | -__simd_callee__ inline void TransToB8Mask(MaskReg& dst, MaskReg& u32Src0, MaskReg& u32Src1, MaskReg& u32Src2, MaskReg& u32Src3) | ||
| 387 | -{ | ||
| 388 | - MaskReg tmpU16LowPart0, tmpU16LowPart1, tmpU16LowPart2; | ||
| 389 | - MaskDeInterleave<uint16_t>(tmpU16LowPart0, tmpU16LowPart1, u32Src0, u32Src1); | ||
| 390 | - MaskDeInterleave<uint16_t>(tmpU16LowPart2, tmpU16LowPart1, u32Src2, u32Src3); | ||
| 391 | - | ||
| 392 | - TransToB8Mask(dst, tmpU16LowPart0, tmpU16LowPart2); | ||
| 393 | -} | ||
| 394 | - | ||
| 395 | -__simd_callee__ inline void CollectGivenPosByte(RegTensor<uint8_t>& colWorkBits, __ubuf__ uint64_t *src, uint16_t byteNum, const int32_t srcOffset, | ||
| 396 | -__ubuf__ uint64_t* tmpLocal) | ||
| 397 | -{ | ||
| 398 | - uint32_t loadCount = GetVecLen() / sizeof(uint32_t); | ||
| 399 | - uint32_t realCount = loadCount / 2; | ||
| 400 | - | ||
| 401 | - int16_t offsets = static_cast<int16_t>((byteNum - 1) * 8); | ||
| 402 | - __ubuf__ uint32_t* srcU32 = (__ubuf__ uint32_t*)src; | ||
| 403 | - __ubuf__ uint32_t* tmpU32 = (__ubuf__ uint32_t*)tmpLocal; | ||
| 404 | - | ||
| 405 | - MaskReg fullMask = CreateMask<uint32_t>(); | ||
| 406 | - MaskReg zeroMask = CreateMask<uint32_t, MaskPattern::ALLF>(); | ||
| 407 | - MaskReg halfMask = CreateMask<uint32_t, MaskPattern::H>(); | ||
| 408 | - | ||
| 409 | - constexpr uint16_t repeatTimes = sizeof(uint64_t); | ||
| 410 | - MaskReg lowMask, highMask, tmpMask; | ||
| 411 | - MaskInterleave<uint32_t>(lowMask, tmpMask, fullMask, zeroMask); | ||
| 412 | - MaskInterleave<uint32_t>(highMask, tmpMask, zeroMask, fullMask); | ||
| 413 | - | ||
| 414 | - int16_t highOffsets = offsets - 32; | ||
| 415 | - if (offsets >= 32) { | ||
| 416 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 417 | - RegTensor<uint32_t> input, output; | ||
| 418 | - DataCopy(input, srcU32 + srcOffset + i * loadCount); | ||
| 419 | - GatherMask(output, input, highMask); | ||
| 420 | - ShiftRights(output, output, highOffsets, halfMask); | ||
| 421 | - | ||
| 422 | - DataCopy(tmpU32 + realCount * i, output, halfMask); | ||
| 423 | - } | ||
| 424 | - } else { | ||
| 425 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 426 | - RegTensor<uint32_t> input, output; | ||
| 427 | - DataCopy(input, srcU32 + srcOffset + i * loadCount); | ||
| 428 | - GatherMask(output, input, lowMask); | ||
| 429 | - ShiftRights(output, output, offsets, halfMask); | ||
| 430 | - | ||
| 431 | - DataCopy(tmpU32 + realCount * i, output, halfMask); | ||
| 432 | - } | ||
| 433 | - } | ||
| 434 | - | ||
| 435 | - MicroAPI::LocalMemBar<MicroAPI::MemType::VEC_STORE, MicroAPI::MemType::VEC_LOAD>(); | ||
| 436 | - RegTensor<uint32_t> work0, work1, work2, work3; | ||
| 437 | - DataCopy(work0, tmpU32); | ||
| 438 | - DataCopy(work1, tmpU32 + loadCount); | ||
| 439 | - DataCopy(work2, tmpU32 + loadCount * 2); | ||
| 440 | - DataCopy(work3, tmpU32 + loadCount * 3); | ||
| 441 | - | ||
| 442 | - GetLowerstByte(colWorkBits, work0, work1, work2, work3); | ||
| 443 | -} | ||
| 444 | - | ||
| 445 | -__simd_callee__ inline void CompareHighBytesBeforePos(MaskReg& filterMask, __ubuf__ uint64_t *&src, MaskReg& maskReg, | ||
| 446 | - uint64_t value, uint16_t byteNum, int32_t srcOffset, __ubuf__ uint64_t* tmpLocal) | ||
| 447 | -{ | ||
| 448 | - __ubuf__ uint32_t* srcU32 = (__ubuf__ uint32_t*)src; | ||
| 449 | - __ubuf__ uint32_t* tmpU32 = (__ubuf__ uint32_t*)tmpLocal; | ||
| 450 | - | ||
| 451 | - uint32_t loadCount = GetVecLen() / sizeof(uint32_t); | ||
| 452 | - uint32_t realCount = loadCount / 2; | ||
| 453 | - int16_t maskOffsets = static_cast<int16_t>(byteNum * 8); | ||
| 454 | - | ||
| 455 | - MaskReg fullMask = CreateMask<uint32_t>(); | ||
| 456 | - MaskReg zeroMask = CreateMask<uint32_t, MaskPattern::ALLF>(); | ||
| 457 | - MaskReg halfMask = CreateMask<uint32_t, MaskPattern::H>(); | ||
| 458 | - | ||
| 459 | - constexpr uint16_t repeatTimes = sizeof(uint64_t); | ||
| 460 | - MaskReg lowMask, highMask, tmpMask; | ||
| 461 | - MaskInterleave<uint32_t>(lowMask, tmpMask, fullMask, zeroMask); | ||
| 462 | - MaskInterleave<uint32_t>(highMask, tmpMask, zeroMask, fullMask); | ||
| 463 | - | ||
| 464 | - int16_t realMaskOffset = maskOffsets - 32; | ||
| 465 | - int16_t reverseMaskOffset = 32 - maskOffsets; | ||
| 466 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 467 | - RegTensor<uint32_t> input, highOut, tHighOut, lowOut; | ||
| 468 | - DataCopy(input, srcU32 + srcOffset + i * loadCount); | ||
| 469 | - | ||
| 470 | - GatherMask(highOut, input, highMask); | ||
| 471 | - | ||
| 472 | - if (maskOffsets > 32) { | ||
| 473 | - ShiftRights(lowOut, highOut, realMaskOffset, halfMask); | ||
| 474 | - Duplicate(highOut, 0, halfMask); | ||
| 475 | - } else { | ||
| 476 | - GatherMask(lowOut, input, lowMask); | ||
| 477 | - ShiftRights(lowOut, lowOut, maskOffsets, halfMask); | ||
| 478 | - ShiftLefts(tHighOut, highOut, reverseMaskOffset, halfMask); | ||
| 479 | - Or(lowOut, lowOut, tHighOut, halfMask); | ||
| 480 | - ShiftRights(highOut, highOut, maskOffsets, halfMask); | ||
| 481 | - } | ||
| 482 | - | ||
| 483 | - DataCopy(tmpU32 + realCount * i, highOut, halfMask); | ||
| 484 | - DataCopy(tmpU32 + realCount * (i + repeatTimes), lowOut, halfMask); | ||
| 485 | - } | ||
| 486 | - MicroAPI::LocalMemBar<MicroAPI::MemType::VEC_STORE, MicroAPI::MemType::VEC_LOAD>(); | ||
| 487 | - RegTensor<uint32_t> highPart0, highPart1, highPart2, highPart3, lowPart0, lowPart1, lowPart2, lowPart3; | ||
| 488 | - DataCopy(highPart0, tmpU32); | ||
| 489 | - DataCopy(highPart1, tmpU32 + loadCount); | ||
| 490 | - DataCopy(highPart2, tmpU32 + loadCount * 2); | ||
| 491 | - DataCopy(highPart3, tmpU32 + loadCount * 3); | ||
| 492 | - DataCopy(lowPart0, tmpU32 + loadCount * 4); | ||
| 493 | - DataCopy(lowPart1, tmpU32 + loadCount * 5); | ||
| 494 | - DataCopy(lowPart2, tmpU32 + loadCount * 6); | ||
| 495 | - DataCopy(lowPart3, tmpU32 + loadCount * 7); | ||
| 496 | - | ||
| 497 | - MaskReg highMask0, highMask1, highMask2, highMask3; | ||
| 498 | - MaskReg lowMask0, lowMask1, lowMask2, lowMask3; | ||
| 499 | - uint32_t highValue = value >> 32; | ||
| 500 | - CompareScalar<uint32_t, CMPMODE::EQ>(highMask0, highPart0, highValue, fullMask); | ||
| 501 | - CompareScalar<uint32_t, CMPMODE::EQ>(highMask1, highPart1, highValue, fullMask); | ||
| 502 | - CompareScalar<uint32_t, CMPMODE::EQ>(highMask2, highPart2, highValue, fullMask); | ||
| 503 | - CompareScalar<uint32_t, CMPMODE::EQ>(highMask3, highPart3, highValue, fullMask); | ||
| 504 | - | ||
| 505 | - uint32_t lowValue = value & 0xffffffff; | ||
| 506 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowMask0, lowPart0, lowValue, fullMask); | ||
| 507 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowMask1, lowPart1, lowValue, fullMask); | ||
| 508 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowMask2, lowPart2, lowValue, fullMask); | ||
| 509 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowMask3, lowPart3, lowValue, fullMask); | ||
| 510 | - | ||
| 511 | - MaskReg highRes, lowRes; | ||
| 512 | - TransToB8Mask(lowRes, lowMask0, lowMask1, lowMask2, lowMask3); | ||
| 513 | - TransToB8Mask(highRes, highMask0, highMask1, highMask2, highMask3); | ||
| 514 | - | ||
| 515 | - MaskReg res; | ||
| 516 | - MaskAnd(res, highRes, lowRes, maskReg); | ||
| 517 | - MaskAnd(filterMask, maskReg, res, maskReg); | ||
| 518 | -} | ||
| 519 | - | ||
| 520 | -__simd_callee__ inline void FilterDataAndGivenByteFromOri( | ||
| 521 | - MaskReg& filterMask, RegTensor<uint8_t>& colWorkBits, __ubuf__ uint64_t *src, MaskReg& maskReg, | ||
| 522 | - uint64_t value, uint16_t byteNum, int32_t srcOffset, __ubuf__ uint64_t* tmpLocal) | ||
| 523 | -{ | ||
| 524 | - CollectGivenPosByte(colWorkBits, src, byteNum, srcOffset * 2, tmpLocal); | ||
| 525 | - CompareHighBytesBeforePos(filterMask, src, maskReg, value, byteNum, srcOffset * 2, tmpLocal); | ||
| 526 | -} | ||
| 527 | - | ||
| 528 | -__simd_callee__ inline void FilterDataAndGivenByteFromOri( | ||
| 529 | - MaskReg& filterMask, RegTensor<uint8_t>& colWorkBits, __ubuf__ uint32_t *src, MaskReg& maskReg, | ||
| 530 | - uint32_t value, uint16_t byteNum, int32_t srcOffset, __ubuf__ uint32_t* tmpLocal) | ||
| 531 | -{ | ||
| 532 | - constexpr uint32_t eleCountPerVL = GetVecLen() / sizeof(uint32_t); | ||
| 533 | - MaskReg fullMask = CreateMask<uint32_t>(); | ||
| 534 | - int16_t byteOffsets = static_cast<int16_t>((byteNum - 1) * 8); | ||
| 535 | - int16_t maskOffsets = static_cast<int16_t>(byteNum * 8); | ||
| 536 | - | ||
| 537 | - RegTensor<uint32_t> input0, input1, input2, input3; | ||
| 538 | - DataCopy(input0, src + srcOffset); | ||
| 539 | - DataCopy(input1, src + srcOffset + eleCountPerVL); | ||
| 540 | - DataCopy(input2, src + srcOffset + eleCountPerVL * 2); | ||
| 541 | - DataCopy(input3, src + srcOffset + eleCountPerVL * 3); | ||
| 542 | - | ||
| 543 | - RegTensor<uint32_t> tmpU32ByteReg0, tmpU32ByteReg1, tmpU32ByteReg2, tmpU32ByteReg3; | ||
| 544 | - ShiftRights(tmpU32ByteReg0, input0, byteOffsets, fullMask); | ||
| 545 | - ShiftRights(tmpU32ByteReg1, input1, byteOffsets, fullMask); | ||
| 546 | - ShiftRights(tmpU32ByteReg2, input2, byteOffsets, fullMask); | ||
| 547 | - ShiftRights(tmpU32ByteReg3, input3, byteOffsets, fullMask); | ||
| 548 | - | ||
| 549 | - GetLowerstByte(colWorkBits, tmpU32ByteReg0, tmpU32ByteReg1, tmpU32ByteReg2, tmpU32ByteReg3); | ||
| 550 | - | ||
| 551 | - RegTensor<uint32_t> tmpU32MaskReg0, tmpU32MaskReg1, tmpU32MaskReg2, tmpU32MaskReg3; | ||
| 552 | - ShiftRights(tmpU32MaskReg0, input0, maskOffsets, fullMask); | ||
| 553 | - ShiftRights(tmpU32MaskReg1, input1, maskOffsets, fullMask); | ||
| 554 | - ShiftRights(tmpU32MaskReg2, input2, maskOffsets, fullMask); | ||
| 555 | - ShiftRights(tmpU32MaskReg3, input3, maskOffsets, fullMask); | ||
| 556 | - | ||
| 557 | - MaskReg mask0, mask1, mask2, mask3; | ||
| 558 | - CompareScalar<uint32_t, CMPMODE::EQ>(mask0, tmpU32MaskReg0, value, fullMask); | ||
| 559 | - CompareScalar<uint32_t, CMPMODE::EQ>(mask1, tmpU32MaskReg1, value, fullMask); | ||
| 560 | - CompareScalar<uint32_t, CMPMODE::EQ>(mask2, tmpU32MaskReg2, value, fullMask); | ||
| 561 | - CompareScalar<uint32_t, CMPMODE::EQ>(mask3, tmpU32MaskReg3, value, fullMask); | ||
| 562 | - | ||
| 563 | - MaskReg res; | ||
| 564 | - TransToB8Mask(res, mask0, mask1, mask2, mask3); | ||
| 565 | - MaskAnd(filterMask, maskReg, res, maskReg); | ||
| 566 | -} | ||
| 567 | - | ||
| 568 | -__simd_callee__ inline void FilterDataAndGivenByteFromOri( | ||
| 569 | - MaskReg& filterMask, RegTensor<uint8_t>& colWorkBits, __ubuf__ uint16_t *src, MaskReg& maskReg, | ||
| 570 | - uint16_t value, uint16_t byteNum, int32_t srcOffset, __ubuf__ uint16_t* tmpLocal) | ||
| 571 | -{ | ||
| 572 | - constexpr uint32_t eleCountPerVL = GetVecLen() / sizeof(uint16_t); | ||
| 573 | - int16_t byteOffsets = static_cast<int16_t>((byteNum - 1) * 8); | ||
| 574 | - int16_t maskOffsets = static_cast<int16_t>(byteNum * 8); | ||
| 575 | - | ||
| 576 | - MaskReg fullMask = CreateMask<uint16_t>(); | ||
| 577 | - | ||
| 578 | - RegTensor<uint16_t> input0, input1; | ||
| 579 | - DataCopy(input0, src + srcOffset); | ||
| 580 | - DataCopy(input1, src + srcOffset + eleCountPerVL); | ||
| 581 | - | ||
| 582 | - RegTensor<uint16_t> tmpBShift0, tmpBShift1; | ||
| 583 | - ShiftRights(tmpBShift0, input0, byteOffsets, fullMask); | ||
| 584 | - ShiftRights(tmpBShift1, input1, byteOffsets, fullMask); | ||
| 585 | - | ||
| 586 | - GetLowerstByte(colWorkBits, tmpBShift0, tmpBShift1); | ||
| 587 | - | ||
| 588 | - RegTensor<uint16_t> tmpMShift0, tmpMShift1; | ||
| 589 | - ShiftRights(tmpMShift0, input0, maskOffsets, fullMask); | ||
| 590 | - ShiftRights(tmpMShift1, input1, maskOffsets, fullMask); | ||
| 591 | - | ||
| 592 | - MaskReg mask0, mask1; | ||
| 593 | - CompareScalar<uint16_t, CMPMODE::EQ>(mask0, tmpMShift0, value, fullMask); | ||
| 594 | - CompareScalar<uint16_t, CMPMODE::EQ>(mask1, tmpMShift1, value, fullMask); | ||
| 595 | - | ||
| 596 | - MaskReg res; | ||
| 597 | - TransToB8Mask(res, mask0, mask1); | ||
| 598 | - MaskAnd(filterMask, maskReg, res, maskReg); | ||
| 599 | -} | ||
| 600 | - | ||
| 601 | -__simd_callee__ inline void FilterDataAndGivenByteFromOri( | ||
| 602 | - MaskReg& filterMask, RegTensor<uint8_t>& colWorkBits, __ubuf__ uint8_t *src, MaskReg& maskReg, | ||
| 603 | - uint8_t value, uint16_t byteNum, int32_t srcOffset, __ubuf__ uint8_t* tmpLocal) | ||
| 604 | -{ | ||
| 605 | - DataCopy(colWorkBits, src + srcOffset); | ||
| 606 | - MaskReg fullMask = CreateMask<uint8_t>(); | ||
| 607 | - MaskAnd(filterMask, maskReg, fullMask, maskReg); | ||
| 608 | -} | ||
| 609 | - | ||
| 610 | -template <typename T> | ||
| 611 | -__simd_vf__ inline void GenerateAccumulateData( | ||
| 612 | - __ubuf__ T *src, __ubuf__ uint16_t *hist, __ubuf__ T *tmpSrcData, | ||
| 613 | - uint32_t count, T value, uint32_t byteNum) | ||
| 614 | -{ | ||
| 615 | - using ConvType = typename AscendC::Internal::ExtractTypeBySize<sizeof(T)>::T; | ||
| 616 | - auto unsignedValue = static_cast<ConvType>(value); | ||
| 617 | - uint16_t repeatTimes = DivCeil(count, GetVecLen()); | ||
| 618 | - ConvType workingUnsignedValue = 0; | ||
| 619 | - if (byteNum != sizeof(T)) { | ||
| 620 | - workingUnsignedValue = unsignedValue >> (byteNum * 8); | ||
| 621 | - } | ||
| 622 | - | ||
| 623 | - RegTensor<uint16_t> acumHistLow, acumHistHigh; | ||
| 624 | - MaskReg b16FullMask = CreateMask<uint16_t>(); | ||
| 625 | - | ||
| 626 | - Duplicate(acumHistLow, 0, b16FullMask); | ||
| 627 | - Duplicate(acumHistHigh, 0, b16FullMask); | ||
| 628 | - | ||
| 629 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 630 | - MaskReg maskReg = UpdateMask<uint8_t>(count); | ||
| 631 | - | ||
| 632 | - MaskReg filterMask; | ||
| 633 | - RegTensor<uint8_t> colWorkBits; | ||
| 634 | - FilterDataAndGivenByteFromOri(filterMask, colWorkBits, src, maskReg, workingUnsignedValue, byteNum, i * GetVecLen(), tmpSrcData); | ||
| 635 | - | ||
| 636 | - Histograms<uint8_t, uint16_t, HistogramsBinType::BIN0, HistogramsType::ACCUMULATE>(acumHistLow, colWorkBits, filterMask); | ||
| 637 | - Histograms<uint8_t, uint16_t, HistogramsBinType::BIN1, HistogramsType::ACCUMULATE>(acumHistHigh, colWorkBits, filterMask); | ||
| 638 | - } | ||
| 639 | - | ||
| 640 | - DataCopy((__ubuf__ uint16_t *&)hist, acumHistLow, b16FullMask); | ||
| 641 | - DataCopy((__ubuf__ uint16_t *&)hist + GetVecLen() / sizeof(uint16_t), acumHistHigh, b16FullMask); | ||
| 642 | -} | ||
| 643 | - | ||
| 644 | -__simd_vf__ inline void GatherGreaterAndEqualKData(__ubuf__ uint64_t *src, __ubuf__ uint64_t *dst, const uint64_t value, uint32_t count) | ||
| 645 | -{ | ||
| 646 | - count *= 2; | ||
| 647 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(uint32_t); | ||
| 648 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 649 | - | ||
| 650 | - auto firstCount = count; | ||
| 651 | - auto secondCount = count; | ||
| 652 | - | ||
| 653 | - uint64_t lowValue = value & 0xffffffff; | ||
| 654 | - uint64_t highValue = value >> 32; | ||
| 655 | - | ||
| 656 | - __ubuf__ uint32_t* u32Src = (__ubuf__ uint32_t*)src; | ||
| 657 | - __ubuf__ uint32_t* u32Dst = (__ubuf__ uint32_t*)dst; | ||
| 658 | - | ||
| 659 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 660 | - MaskReg fullMask = CreateMask<uint32_t>(); | ||
| 661 | - MaskReg zeroMask = CreateMask<uint32_t, MaskPattern::ALLF>(); | ||
| 662 | - MaskReg halfMask = CreateMask<uint32_t, MaskPattern::H>(); | ||
| 663 | - | ||
| 664 | - MaskReg lowMask, highMask, tmpMask; | ||
| 665 | - MaskInterleave<uint32_t>(lowMask, tmpMask, fullMask, zeroMask); | ||
| 666 | - MaskInterleave<uint32_t>(highMask, tmpMask, zeroMask, fullMask); | ||
| 667 | - | ||
| 668 | - UnalignReg unalignReg; | ||
| 669 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 670 | - MaskReg maskReg = UpdateMask<uint32_t>(firstCount); | ||
| 671 | - | ||
| 672 | - RegTensor<uint32_t> in32Data; | ||
| 673 | - DataCopy(in32Data, u32Src + i * eleCountPerVL); | ||
| 674 | - | ||
| 675 | - RegTensor<uint32_t> highPart, lowPart; | ||
| 676 | - GatherMask(lowPart, in32Data, lowMask); | ||
| 677 | - GatherMask(highPart, in32Data, highMask); | ||
| 678 | - | ||
| 679 | - MaskReg highGTMask, highEQMask, lowPartMask; | ||
| 680 | - CompareScalar<uint32_t, CMPMODE::GT>(highGTMask, highPart, highValue, halfMask); | ||
| 681 | - CompareScalar<uint32_t, CMPMODE::EQ>(highEQMask, highPart, highValue, halfMask); | ||
| 682 | - CompareScalar<uint32_t, CMPMODE::GT>(lowPartMask, lowPart, lowValue, halfMask); | ||
| 683 | - | ||
| 684 | - MaskReg cmpMask; | ||
| 685 | - MaskAnd(cmpMask, highEQMask, lowPartMask, halfMask); | ||
| 686 | - MaskOr(cmpMask, highGTMask, cmpMask, halfMask); | ||
| 687 | - | ||
| 688 | - MaskReg cmpResMask0, cmpResMask1; | ||
| 689 | - MaskInterleave<uint32_t>(cmpResMask0, cmpResMask1, cmpMask, cmpMask); | ||
| 690 | - MaskAnd(cmpResMask0, cmpResMask0, maskReg, maskReg); | ||
| 691 | - | ||
| 692 | - RegTensor<uint32_t> out32Data; | ||
| 693 | - GatherMask<uint32_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, cmpResMask0); | ||
| 694 | - DataCopyUnAlign<uint32_t>(u32Dst, out32Data, unalignReg); | ||
| 695 | - } | ||
| 696 | - | ||
| 697 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 698 | - MaskReg maskReg = UpdateMask<uint32_t>(secondCount); | ||
| 699 | - | ||
| 700 | - RegTensor<uint32_t> in32Data; | ||
| 701 | - DataCopy(in32Data, u32Src + i * eleCountPerVL); | ||
| 702 | - | ||
| 703 | - RegTensor<uint32_t> highPart, lowPart; | ||
| 704 | - GatherMask(lowPart, in32Data, lowMask); | ||
| 705 | - GatherMask(highPart, in32Data, highMask); | ||
| 706 | - | ||
| 707 | - MaskReg highEQMask, lowPartMask; | ||
| 708 | - CompareScalar<uint32_t, CMPMODE::EQ>(highEQMask, highPart, highValue, halfMask); | ||
| 709 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowPartMask, lowPart, lowValue, halfMask); | ||
| 710 | - | ||
| 711 | - MaskReg cmpMask; | ||
| 712 | - MaskAnd(cmpMask, highEQMask, lowPartMask, halfMask); | ||
| 713 | - | ||
| 714 | - MaskReg cmpResMask0, cmpResMask1; | ||
| 715 | - MaskInterleave<uint32_t>(cmpResMask0, cmpResMask1, cmpMask, cmpMask); | ||
| 716 | - MaskAnd(cmpResMask0, cmpResMask0, maskReg, maskReg); | ||
| 717 | - | ||
| 718 | - RegTensor<uint32_t> out32Data; | ||
| 719 | - GatherMask<uint32_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, cmpResMask0); | ||
| 720 | - DataCopyUnAlign<uint32_t>(u32Dst, out32Data, unalignReg); | ||
| 721 | - } | ||
| 722 | - | ||
| 723 | - DataCopyUnAlignPost(u32Dst, unalignReg); | ||
| 724 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 725 | -} | ||
| 726 | - | ||
| 727 | -__simd_vf__ inline void GatherGreaterAndEqualKData(__ubuf__ uint32_t *src, __ubuf__ uint32_t *dst, const uint32_t value, uint32_t count) | ||
| 728 | -{ | ||
| 729 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(uint32_t); | ||
| 730 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 731 | - | ||
| 732 | - auto firstCount = count; | ||
| 733 | - auto secondCount = count; | ||
| 734 | - | ||
| 735 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 736 | - UnalignReg unalignReg; | ||
| 737 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 738 | - MaskReg maskReg = UpdateMask<uint32_t>(firstCount); | ||
| 739 | - | ||
| 740 | - RegTensor<uint32_t> in32Data; | ||
| 741 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 742 | - | ||
| 743 | - MaskReg out32Mask; | ||
| 744 | - CompareScalar<uint32_t, CMPMODE::GT>(out32Mask, in32Data, value, maskReg); | ||
| 745 | - | ||
| 746 | - RegTensor<uint32_t> out32Data; | ||
| 747 | - GatherMask<uint32_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, out32Mask); | ||
| 748 | - DataCopyUnAlign(dst, out32Data, unalignReg); | ||
| 749 | - } | ||
| 750 | - | ||
| 751 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 752 | - MaskReg maskReg = UpdateMask<uint32_t>(secondCount); | ||
| 753 | - | ||
| 754 | - RegTensor<uint32_t> in32Data; | ||
| 755 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 756 | - | ||
| 757 | - MaskReg out32Mask; | ||
| 758 | - CompareScalar<uint32_t, CMPMODE::EQ>(out32Mask, in32Data, value, maskReg); | ||
| 759 | - | ||
| 760 | - RegTensor<uint32_t> out32Data; | ||
| 761 | - GatherMask<uint32_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, out32Mask); | ||
| 762 | - DataCopyUnAlign(dst, out32Data, unalignReg); | ||
| 763 | - } | ||
| 764 | - | ||
| 765 | - DataCopyUnAlignPost(dst, unalignReg); | ||
| 766 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 767 | -} | ||
| 768 | - | ||
| 769 | -__simd_vf__ inline void GatherGreaterAndEqualKData(__ubuf__ uint16_t *src, __ubuf__ uint16_t *dst, const uint16_t value, uint32_t count) | ||
| 770 | -{ | ||
| 771 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(uint16_t); | ||
| 772 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 773 | - | ||
| 774 | - auto firstCount = count; | ||
| 775 | - auto secondCount = count; | ||
| 776 | - | ||
| 777 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 778 | - UnalignReg unalignReg0; | ||
| 779 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 780 | - MaskReg maskReg = UpdateMask<uint16_t>(firstCount); | ||
| 781 | - | ||
| 782 | - RegTensor<uint16_t> in32Data; | ||
| 783 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 784 | - | ||
| 785 | - MaskReg out32Mask; | ||
| 786 | - CompareScalar<uint16_t, CMPMODE::GT>(out32Mask, in32Data, value, maskReg); | ||
| 787 | - | ||
| 788 | - RegTensor<uint16_t> out32Data; | ||
| 789 | - GatherMask<uint16_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, out32Mask); | ||
| 790 | - DataCopyUnAlign(dst, out32Data, unalignReg0); | ||
| 791 | - } | ||
| 792 | - | ||
| 793 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 794 | - MaskReg maskReg = UpdateMask<uint16_t>(secondCount); | ||
| 795 | - | ||
| 796 | - RegTensor<uint16_t> in32Data; | ||
| 797 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 798 | - | ||
| 799 | - MaskReg out32Mask; | ||
| 800 | - CompareScalar<uint16_t, CMPMODE::EQ>(out32Mask, in32Data, value, maskReg); | ||
| 801 | - | ||
| 802 | - RegTensor<uint16_t> out32Data; | ||
| 803 | - GatherMask<uint16_t, GatherMaskMode::STORE_REG>(out32Data, in32Data, out32Mask); | ||
| 804 | - DataCopyUnAlign(dst, out32Data, unalignReg0); | ||
| 805 | - } | ||
| 806 | - | ||
| 807 | - DataCopyUnAlignPost(dst, unalignReg0); | ||
| 808 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 809 | -} | ||
| 810 | - | ||
| 811 | -__simd_vf__ inline void GatherGreaterAndEqualKData(__ubuf__ uint8_t *src, __ubuf__ uint8_t *dst, const uint8_t value, uint32_t count) | ||
| 812 | -{ | ||
| 813 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(uint8_t); | ||
| 814 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 815 | - | ||
| 816 | - auto firstCount = count; | ||
| 817 | - auto secondCount = count; | ||
| 818 | - | ||
| 819 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 820 | - UnalignReg unalignReg; | ||
| 821 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 822 | - MaskReg fullMask = UpdateMask<uint8_t>(firstCount); | ||
| 823 | - RegTensor<uint8_t> in8Data; | ||
| 824 | - DataCopy(in8Data, src + i * eleCountPerVL); | ||
| 825 | - | ||
| 826 | - MaskReg out8Mask; | ||
| 827 | - CompareScalar<uint8_t, CMPMODE::GT>(out8Mask, in8Data, value, fullMask); | ||
| 828 | - | ||
| 829 | - RegTensor<uint8_t> out8Data; | ||
| 830 | - GatherMask<uint8_t, GatherMaskMode::STORE_REG>(out8Data, in8Data, out8Mask); | ||
| 831 | - DataCopyUnAlign(dst, out8Data, unalignReg); | ||
| 832 | - } | ||
| 833 | - | ||
| 834 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 835 | - MaskReg fullMask = UpdateMask<uint8_t>(secondCount); | ||
| 836 | - RegTensor<uint8_t> in8Data; | ||
| 837 | - DataCopy(in8Data, src + i * eleCountPerVL); | ||
| 838 | - | ||
| 839 | - MaskReg out8Mask; | ||
| 840 | - CompareScalar<uint8_t, CMPMODE::EQ>(out8Mask, in8Data, value, fullMask); | ||
| 841 | - | ||
| 842 | - RegTensor<uint8_t> out8Data; | ||
| 843 | - GatherMask<uint8_t, GatherMaskMode::STORE_REG>(out8Data, in8Data, out8Mask); | ||
| 844 | - DataCopyUnAlign(dst, out8Data, unalignReg); | ||
| 845 | - } | ||
| 846 | - | ||
| 847 | - DataCopyUnAlignPost(dst, unalignReg); | ||
| 848 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 849 | -} | ||
| 850 | - | ||
| 851 | - | ||
| 852 | -__simd_vf__ inline void GatherGreaterAndEqualKIndex(__ubuf__ uint64_t *src, __ubuf__ int32_t *inputIndex, | ||
| 853 | - __ubuf__ int32_t *dstIndex, const uint64_t value, uint32_t count) | ||
| 854 | -{ | ||
| 855 | - count *= 2; | ||
| 856 | - | ||
| 857 | - constexpr uint16_t eleCountPerVL = GetVecLen() / sizeof(uint32_t); | ||
| 858 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 859 | - constexpr uint16_t numsPerRound = eleCountPerVL / 2; | ||
| 860 | - | ||
| 861 | - auto firstCount = count; | ||
| 862 | - auto secondCount = count; | ||
| 863 | - | ||
| 864 | - uint64_t lowValue = value & 0xffffffff; | ||
| 865 | - uint64_t highValue = value >> 32; | ||
| 866 | - | ||
| 867 | - __ubuf__ uint32_t* u32Src = (__ubuf__ uint32_t*)src; | ||
| 868 | - | ||
| 869 | - MaskReg fullMask = CreateMask<uint32_t>(); | ||
| 870 | - MaskReg zeroMask = CreateMask<uint32_t, MaskPattern::ALLF>(); | ||
| 871 | - MaskReg halfMask = CreateMask<uint32_t, MaskPattern::H>(); | ||
| 872 | - | ||
| 873 | - MaskReg lowMask, highMask, tmpMask; | ||
| 874 | - MaskInterleave<uint32_t>(lowMask, tmpMask, fullMask, zeroMask); | ||
| 875 | - MaskInterleave<uint32_t>(highMask, tmpMask, zeroMask, fullMask); | ||
| 876 | - | ||
| 877 | - UnalignReg unalignReg; | ||
| 878 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 879 | - MaskReg maskReg = UpdateMask<uint32_t>(firstCount); | ||
| 880 | - MaskReg indexMask, tmpMask; | ||
| 881 | - MaskDeInterleave<uint32_t>(indexMask, tmpMask, maskReg, zeroMask); | ||
| 882 | - | ||
| 883 | - RegTensor<uint32_t> in32Data; | ||
| 884 | - DataCopy(in32Data, u32Src + i * eleCountPerVL); | ||
| 885 | - | ||
| 886 | - RegTensor<uint32_t> highPart, lowPart; | ||
| 887 | - GatherMask(lowPart, in32Data, lowMask); | ||
| 888 | - GatherMask(highPart, in32Data, highMask); | ||
| 889 | - | ||
| 890 | - MaskReg highGTMask, highEQMask, lowPartMask; | ||
| 891 | - CompareScalar<uint32_t, CMPMODE::GT>(highGTMask, highPart, highValue, halfMask); | ||
| 892 | - CompareScalar<uint32_t, CMPMODE::EQ>(highEQMask, highPart, highValue, halfMask); | ||
| 893 | - CompareScalar<uint32_t, CMPMODE::GT>(lowPartMask, lowPart, lowValue, halfMask); | ||
| 894 | - | ||
| 895 | - MaskReg cmpMask; | ||
| 896 | - MaskAnd(cmpMask, highEQMask, lowPartMask, halfMask); | ||
| 897 | - MaskOr(cmpMask, highGTMask, cmpMask, halfMask); | ||
| 898 | - MaskAnd(cmpMask, cmpMask, indexMask, indexMask); | ||
| 899 | - | ||
| 900 | - RegTensor<int32_t> index; | ||
| 901 | - DataCopy(index, inputIndex + i * numsPerRound); | ||
| 902 | - | ||
| 903 | - RegTensor<int32_t> outIndex; | ||
| 904 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex, index, cmpMask); | ||
| 905 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex, unalignReg); | ||
| 906 | - } | ||
| 907 | - | ||
| 908 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 909 | - MaskReg maskReg = UpdateMask<uint32_t>(secondCount); | ||
| 910 | - MaskReg indexMask, tmpMask; | ||
| 911 | - MaskDeInterleave<uint32_t>(indexMask, tmpMask, maskReg, zeroMask); | ||
| 912 | - | ||
| 913 | - RegTensor<uint32_t> in32Data; | ||
| 914 | - DataCopy(in32Data, u32Src + i * eleCountPerVL); | ||
| 915 | - | ||
| 916 | - RegTensor<uint32_t> highPart, lowPart; | ||
| 917 | - GatherMask(lowPart, in32Data, lowMask); | ||
| 918 | - GatherMask(highPart, in32Data, highMask); | ||
| 919 | - | ||
| 920 | - MaskReg highEQMask, lowPartMask; | ||
| 921 | - CompareScalar<uint32_t, CMPMODE::EQ>(highEQMask, highPart, highValue, halfMask); | ||
| 922 | - CompareScalar<uint32_t, CMPMODE::EQ>(lowPartMask, lowPart, lowValue, halfMask); | ||
| 923 | - | ||
| 924 | - MaskReg cmpMask; | ||
| 925 | - MaskAnd(cmpMask, highEQMask, lowPartMask, halfMask); | ||
| 926 | - MaskAnd(cmpMask, cmpMask, indexMask, indexMask); | ||
| 927 | - | ||
| 928 | - RegTensor<int32_t> index; | ||
| 929 | - DataCopy(index, inputIndex + i * numsPerRound); | ||
| 930 | - | ||
| 931 | - RegTensor<int32_t> outIndex; | ||
| 932 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex, index, cmpMask); | ||
| 933 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex, unalignReg); | ||
| 934 | - } | ||
| 935 | - | ||
| 936 | - DataCopyUnAlignPost(dstIndex, unalignReg); | ||
| 937 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 938 | -} | ||
| 939 | - | ||
| 940 | -__simd_vf__ inline void GatherGreaterAndEqualKIndex(__ubuf__ uint32_t *src, __ubuf__ int32_t *inputIndex, | ||
| 941 | - __ubuf__ int32_t *dstIndex, const uint32_t value, uint32_t count) | ||
| 942 | -{ | ||
| 943 | - constexpr uint32_t eleCountPerVL = GetVecLen() / sizeof(uint32_t); | ||
| 944 | - uint16_t repeatTimes = DivCeil(count, eleCountPerVL); | ||
| 945 | - | ||
| 946 | - auto firstCount = count; | ||
| 947 | - auto secondCount = count; | ||
| 948 | - | ||
| 949 | - UnalignReg unalignReg; | ||
| 950 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 951 | - MaskReg maskReg = UpdateMask<int32_t>(firstCount); | ||
| 952 | - RegTensor<uint32_t> in32Data; | ||
| 953 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 954 | - | ||
| 955 | - MaskReg out32Mask; | ||
| 956 | - CompareScalar<uint32_t, CMPMODE::GT>(out32Mask, in32Data, value, maskReg); | ||
| 957 | - | ||
| 958 | - RegTensor<int32_t> index; | ||
| 959 | - DataCopy(index, inputIndex + i * eleCountPerVL); | ||
| 960 | - | ||
| 961 | - RegTensor<int32_t> outIndex; | ||
| 962 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex, index, out32Mask); | ||
| 963 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex, unalignReg); | ||
| 964 | - } | ||
| 965 | - | ||
| 966 | - for (uint16_t i = 0; i < repeatTimes; ++i) { | ||
| 967 | - MaskReg maskReg = UpdateMask<int32_t>(secondCount); | ||
| 968 | - RegTensor<uint32_t> in32Data; | ||
| 969 | - DataCopy(in32Data, src + i * eleCountPerVL); | ||
| 970 | - | ||
| 971 | - MaskReg out32Mask; | ||
| 972 | - CompareScalar<uint32_t, CMPMODE::EQ>(out32Mask, in32Data, value, maskReg); | ||
| 973 | - | ||
| 974 | - RegTensor<int32_t> index; | ||
| 975 | - DataCopy(index, inputIndex + i * eleCountPerVL); | ||
| 976 | - | ||
| 977 | - RegTensor<int32_t> outIndex; | ||
| 978 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex, index, out32Mask); | ||
| 979 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex, unalignReg); | ||
| 980 | - } | ||
| 981 | - | ||
| 982 | - DataCopyUnAlignPost(dstIndex, unalignReg); | ||
| 983 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 984 | -} | ||
| 985 | - | ||
| 986 | -__simd_vf__ inline void GatherGreaterAndEqualKIndex(__ubuf__ uint16_t *src, __ubuf__ int32_t *inputIndex, | ||
| 987 | - __ubuf__ int32_t *dstIndex, const uint16_t value, uint32_t count) | ||
| 988 | -{ | ||
| 989 | - constexpr uint32_t u32EleCountPerVL = GetVecLen() / sizeof(int32_t); | ||
| 990 | - constexpr uint32_t u16EleCountPerVL = GetVecLen() / sizeof(uint16_t); | ||
| 991 | - uint16_t dataRepeatTimes = DivCeil(count, u16EleCountPerVL); | ||
| 992 | - uint16_t indexRepeatTImes = DivCeil(count, u32EleCountPerVL); | ||
| 993 | - | ||
| 994 | - auto firstCount = count; | ||
| 995 | - auto secondCount = count; | ||
| 996 | - | ||
| 997 | - UnalignReg unalignReg1; | ||
| 998 | - for (uint16_t i = 0; i < dataRepeatTimes; ++i) { | ||
| 999 | - MaskReg maskReg = UpdateMask<uint16_t>(firstCount); | ||
| 1000 | - RegTensor<uint16_t> in16Data; | ||
| 1001 | - DataCopy(in16Data, src + i * u16EleCountPerVL); | ||
| 1002 | - | ||
| 1003 | - MaskReg out16Mask; | ||
| 1004 | - CompareScalar<uint16_t, CMPMODE::GT>(out16Mask, in16Data, value, maskReg); | ||
| 1005 | - | ||
| 1006 | - MaskReg zero16Mask = CreateMask<uint16_t, MaskPattern::ALLF>(); | ||
| 1007 | - MaskReg out32Mask0, out32Mask1; | ||
| 1008 | - MaskInterleave<uint16_t>(out32Mask0, out32Mask1, out16Mask, zero16Mask); | ||
| 1009 | - | ||
| 1010 | - RegTensor<int32_t> index0, index1; | ||
| 1011 | - DataCopy(index0, inputIndex + i * u16EleCountPerVL); | ||
| 1012 | - DataCopy(index1, inputIndex + i * u16EleCountPerVL + u32EleCountPerVL); | ||
| 1013 | - | ||
| 1014 | - RegTensor<int32_t> outIndex0, outIndex1; | ||
| 1015 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex0, index0, out32Mask0); | ||
| 1016 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex0, unalignReg1); | ||
| 1017 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex1, index1, out32Mask1); | ||
| 1018 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex1, unalignReg1); | ||
| 1019 | - } | ||
| 1020 | - | ||
| 1021 | - for (uint16_t i = 0; i < dataRepeatTimes; ++i) { | ||
| 1022 | - MaskReg maskReg = UpdateMask<uint16_t>(secondCount); | ||
| 1023 | - RegTensor<uint16_t> in16Data; | ||
| 1024 | - DataCopy(in16Data, src + i * u16EleCountPerVL); | ||
| 1025 | - | ||
| 1026 | - MaskReg out16Mask; | ||
| 1027 | - CompareScalar<uint16_t, CMPMODE::EQ>(out16Mask, in16Data, value, maskReg); | ||
| 1028 | - | ||
| 1029 | - MaskReg zero16Mask = CreateMask<uint16_t, MaskPattern::ALLF>(); | ||
| 1030 | - MaskReg out32Mask0, out32Mask1; | ||
| 1031 | - MaskInterleave<uint16_t>(out32Mask0, out32Mask1, out16Mask, zero16Mask); | ||
| 1032 | - | ||
| 1033 | - RegTensor<int32_t> index0, index1; | ||
| 1034 | - DataCopy(index0, inputIndex + i * u16EleCountPerVL ); | ||
| 1035 | - DataCopy(index1, inputIndex + i * u16EleCountPerVL + u32EleCountPerVL); | ||
| 1036 | - | ||
| 1037 | - RegTensor<int32_t> outIndex0, outIndex1; | ||
| 1038 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex0, index0, out32Mask0); | ||
| 1039 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex0, unalignReg1); | ||
| 1040 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex1, index1, out32Mask1); | ||
| 1041 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex1, unalignReg1); | ||
| 1042 | - } | ||
| 1043 | - | ||
| 1044 | - DataCopyUnAlignPost(dstIndex, unalignReg1); | ||
| 1045 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 1046 | -} | ||
| 1047 | - | ||
| 1048 | -__simd_vf__ inline void GatherGreaterAndEqualKIndex(__ubuf__ uint8_t *src, __ubuf__ int32_t *inputIndex, | ||
| 1049 | - __ubuf__ int32_t *dstIndex, const uint8_t value, uint32_t count) | ||
| 1050 | -{ | ||
| 1051 | - constexpr uint16_t u8EleCountPerVL = GetVecLen() / sizeof(uint8_t); | ||
| 1052 | - constexpr uint32_t u32EleCountPerVL = GetVecLen() / sizeof(int32_t); | ||
| 1053 | - | ||
| 1054 | - uint16_t dataRepeatTimes = DivCeil(count, u8EleCountPerVL); | ||
| 1055 | - uint16_t indexRepeatTImes = DivCeil(count, u32EleCountPerVL); | ||
| 1056 | - | ||
| 1057 | - auto firstCount = count; | ||
| 1058 | - auto secondCount = count; | ||
| 1059 | - | ||
| 1060 | - UnalignReg unalignReg; | ||
| 1061 | - for (uint16_t i = 0; i < dataRepeatTimes; ++i) { | ||
| 1062 | - MaskReg maskReg = UpdateMask<uint8_t>(firstCount); | ||
| 1063 | - RegTensor<uint8_t> in8Data; | ||
| 1064 | - DataCopy(in8Data, src + i * u8EleCountPerVL); | ||
| 1065 | - | ||
| 1066 | - MaskReg out8Mask; | ||
| 1067 | - CompareScalar<uint8_t, CMPMODE::GT>(out8Mask, in8Data, value, maskReg); | ||
| 1068 | - | ||
| 1069 | - MaskReg zero8Mask = CreateMask<uint8_t, MaskPattern::ALLF>(); | ||
| 1070 | - MaskReg out16Mask0, out16Mask1; | ||
| 1071 | - MaskInterleave<uint8_t>(out16Mask0, out16Mask1, out8Mask, zero8Mask); | ||
| 1072 | - | ||
| 1073 | - MaskReg zero16Mask = CreateMask<uint16_t, MaskPattern::ALLF>(); | ||
| 1074 | - MaskReg out32Mask0, out32Mask1, out32Mask2, out32Mask3; | ||
| 1075 | - MaskInterleave<uint16_t>(out32Mask0, out32Mask1, out16Mask0, zero16Mask); | ||
| 1076 | - MaskInterleave<uint16_t>(out32Mask2, out32Mask3, out16Mask1, zero16Mask); | ||
| 1077 | - | ||
| 1078 | - RegTensor<int32_t> index0, index1, index2, index3; | ||
| 1079 | - DataCopy(index0, inputIndex + i * GetVecLen()); | ||
| 1080 | - DataCopy(index1, inputIndex + i * GetVecLen() + u32EleCountPerVL); | ||
| 1081 | - DataCopy(index2, inputIndex + i * GetVecLen() + u32EleCountPerVL * 2); | ||
| 1082 | - DataCopy(index3, inputIndex + i * GetVecLen() + u32EleCountPerVL * 3); | ||
| 1083 | - | ||
| 1084 | - RegTensor<int32_t> outIndex0, outIndex1, outIndex2, outIndex3; | ||
| 1085 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex0, index0, out32Mask0); | ||
| 1086 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex0, unalignReg); | ||
| 1087 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex1, index1, out32Mask1); | ||
| 1088 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex1, unalignReg); | ||
| 1089 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex2, index2, out32Mask2); | ||
| 1090 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex2, unalignReg); | ||
| 1091 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex3, index3, out32Mask3); | ||
| 1092 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex3, unalignReg); | ||
| 1093 | - } | ||
| 1094 | - | ||
| 1095 | - for (uint16_t i = 0; i < dataRepeatTimes; ++i) { | ||
| 1096 | - MaskReg maskReg = UpdateMask<uint8_t>(secondCount); | ||
| 1097 | - RegTensor<uint8_t> in8Data; | ||
| 1098 | - DataCopy(in8Data, src + i * u8EleCountPerVL); | ||
| 1099 | - | ||
| 1100 | - MaskReg out8Mask; | ||
| 1101 | - CompareScalar<uint8_t, CMPMODE::EQ>(out8Mask, in8Data, value, maskReg); | ||
| 1102 | - | ||
| 1103 | - MaskReg zero8Mask = CreateMask<uint8_t, MaskPattern::ALLF>(); | ||
| 1104 | - MaskReg out16Mask0, out16Mask1; | ||
| 1105 | - MaskInterleave<uint8_t>(out16Mask0, out16Mask1, out8Mask, zero8Mask); | ||
| 1106 | - | ||
| 1107 | - MaskReg zero16Mask = CreateMask<uint16_t, MaskPattern::ALLF>(); | ||
| 1108 | - MaskReg out32Mask0, out32Mask1, out32Mask2, out32Mask3; | ||
| 1109 | - MaskInterleave<uint16_t>(out32Mask0, out32Mask1, out16Mask0, zero16Mask); | ||
| 1110 | - MaskInterleave<uint16_t>(out32Mask2, out32Mask3, out16Mask1, zero16Mask); | ||
| 1111 | - | ||
| 1112 | - RegTensor<int32_t> index0, index1, index2, index3; | ||
| 1113 | - DataCopy(index0, inputIndex + i * GetVecLen()); | ||
| 1114 | - DataCopy(index1, inputIndex + i * GetVecLen() + u32EleCountPerVL); | ||
| 1115 | - DataCopy(index2, inputIndex + i * GetVecLen() + u32EleCountPerVL * 2); | ||
| 1116 | - DataCopy(index3, inputIndex + i * GetVecLen() + u32EleCountPerVL * 3); | ||
| 1117 | - | ||
| 1118 | - RegTensor<int32_t> outIndex0, outIndex1, outIndex2, outIndex3; | ||
| 1119 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex0, index0, out32Mask0); | ||
| 1120 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex0, unalignReg); | ||
| 1121 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex1, index1, out32Mask1); | ||
| 1122 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex1, unalignReg); | ||
| 1123 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex2, index2, out32Mask2); | ||
| 1124 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex2, unalignReg); | ||
| 1125 | - GatherMask<int32_t, GatherMaskMode::STORE_REG>(outIndex3, index3, out32Mask3); | ||
| 1126 | - DataCopyUnAlign<int32_t, PostLiteral::POST_MODE_UPDATE>(dstIndex, outIndex3, unalignReg); | ||
| 1127 | - } | ||
| 1128 | - | ||
| 1129 | - DataCopyUnAlignPost(dstIndex, unalignReg); | ||
| 1130 | - ClearSpr<SpecialPurposeReg::AR>(); | ||
| 1131 | -} | ||
| 1132 | - | ||
| 1133 | -template <typename T> | ||
| 1134 | -__simd_callee__ inline int32_t GetKPad(int32_t k) | ||
| 1135 | -{ | ||
| 1136 | - constexpr int32_t alignBytes = 32; | ||
| 1137 | - return AlignUp(k, alignBytes / sizeof(T)); | ||
| 1138 | -} | ||
| 1139 | - | ||
| 1140 | -template <typename T> | ||
| 1141 | -__simd_vf__ inline void SaveData(__ubuf__ T *dst, __ubuf__ int32_t *dstIndex, __ubuf__ T *src, __ubuf__ int32_t *srcIndex, | ||
| 1142 | - const uint32_t count) | ||
| 1143 | -{ | ||
| 1144 | - constexpr uint32_t dataCountPerTime = GetVecLen() / sizeof(T); | ||
| 1145 | - uint16_t dataRepeatTimes = DivCeil(count, dataCountPerTime); | ||
| 1146 | - constexpr uint32_t indexCountPerTime = GetVecLen() / sizeof(int32_t); | ||
| 1147 | - uint16_t indexRepeatTimes = DivCeil(count, indexCountPerTime); | ||
| 1148 | - | ||
| 1149 | - uint32_t dCount = count; | ||
| 1150 | - uint32_t iCount = count; | ||
| 1151 | - | ||
| 1152 | - for (uint16_t i = 0; i < dataRepeatTimes; ++i) { | ||
| 1153 | - MaskReg maskReg = UpdateMask<T>(dCount); | ||
| 1154 | - RegTensor<T> reg; | ||
| 1155 | - DataCopy<T, PostLiteral::POST_MODE_UPDATE>(reg, (__ubuf__ T *&)src, dataCountPerTime); | ||
| 1156 | - DataCopy<T, PostLiteral::POST_MODE_UPDATE>((__ubuf__ T *&)dst, reg, dataCountPerTime, maskReg); | ||
| 1157 | - } | ||
| 1158 | - | ||
| 1159 | - for (uint16_t i = 0; i < indexRepeatTimes; ++i) { | ||
| 1160 | - MaskReg maskReg = UpdateMask<int32_t>(iCount); | ||
| 1161 | - RegTensor<int32_t> reg; | ||
| 1162 | - DataCopy<int32_t, PostLiteral::POST_MODE_UPDATE>(reg, (__ubuf__ int32_t *&)srcIndex, indexCountPerTime); | ||
| 1163 | - DataCopy<int32_t, PostLiteral::POST_MODE_UPDATE>((__ubuf__ int32_t *&)dstIndex, reg, indexCountPerTime, maskReg); | ||
| 1164 | - } | ||
| 1165 | -} | ||
| 1166 | - | ||
| 1167 | -template <typename T> | ||
| 1168 | -__simd_vf__ inline void SaveDataUnAlignVF(__ubuf__ T *dst, __ubuf__ int32_t *dstIndex, | ||
| 1169 | - __ubuf__ T *src, __ubuf__ int32_t *srcIndex, const TopKInfo topKInfo, const uint32_t k) | ||
| 1170 | -{ | ||
| 1171 | - uint32_t dataMainCountPerTime = GetVecLen() / sizeof(T); | ||
| 1172 | - uint32_t indexMainCountPerTime = GetVecLen() / sizeof(int32_t); | ||
| 1173 | - | ||
| 1174 | - int32_t kPad = GetKPad<T>(k); | ||
| 1175 | - int32_t kIndexPad = GetKPad<int32_t>(k); | ||
| 1176 | - uint16_t dataMainRepeatTime = DivCeil(kPad, dataMainCountPerTime); | ||
| 1177 | - uint16_t indexMainRepeatTime = DivCeil(kIndexPad, indexMainCountPerTime); | ||
| 1178 | - | ||
| 1179 | - for (uint16_t j = 0; j < static_cast<uint16_t>(topKInfo.outter); ++j) { | ||
| 1180 | - for (uint16_t i = 0; i < dataMainRepeatTime; i++) { | ||
| 1181 | - UnalignReg ureg; | ||
| 1182 | - RegTensor<T> reg; | ||
| 1183 | - auto dstUBT = dst + j * k + i * kPad; | ||
| 1184 | - DataCopy(reg, src + j * kPad + i * kPad); | ||
| 1185 | - DataCopyUnAlign((__ubuf__ T *&)dstUBT, reg, ureg, k); | ||
| 1186 | - DataCopyUnAlignPost(dstUBT, ureg, 0); | ||
| 1187 | - } | ||
| 1188 | - | ||
| 1189 | - for (uint16_t i = 0; i < indexMainRepeatTime; i++) { | ||
| 1190 | - UnalignReg ureg; | ||
| 1191 | - RegTensor<int32_t> reg; | ||
| 1192 | - auto dstUBT = dstIndex + j * k + i * kIndexPad; | ||
| 1193 | - DataCopy(reg, srcIndex + j * kIndexPad + i * kIndexPad); | ||
| 1194 | - DataCopyUnAlign((__ubuf__ int32_t *&)dstUBT, reg, ureg, k); | ||
| 1195 | - DataCopyUnAlignPost(dstUBT, ureg, 0); | ||
| 1196 | - } | ||
| 1197 | - } | ||
| 1198 | -} | ||
| 1199 | - | ||
| 1200 | -template <typename T> | ||
| 1201 | -__aicore__ inline void SaveDataUnAlign(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1202 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const TopKInfo &topKInfo, const uint32_t k) | ||
| 1203 | -{ | ||
| 1204 | - __ubuf__ T *src = (__ubuf__ T *)srcLocal.GetPhyAddr(); | ||
| 1205 | - __ubuf__ int32_t *srcIndex = (__ubuf__ int32_t *)srcIndexLocal.GetPhyAddr(); | ||
| 1206 | - __ubuf__ T *dst = (__ubuf__ T *)dstValueLocal.GetPhyAddr(); | ||
| 1207 | - __ubuf__ int32_t *dstIndex = (__ubuf__ int32_t *)dstIndexLocal.GetPhyAddr(); | ||
| 1208 | - | ||
| 1209 | - SaveDataUnAlignVF<T>(dst, dstIndex, src, srcIndex, topKInfo, k); | ||
| 1210 | -} | ||
| 1211 | - | ||
| 1212 | -template <typename T, bool isInitIndex = false, bool isReuseSrc = false, const TopKConfig &config = defaultTopKConfig> | ||
| 1213 | -__aicore__ inline void TopKRaidxSelect(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1214 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<T> &tempBuffer, | ||
| 1215 | - const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, const bool isLargest) | ||
| 1216 | -{ | ||
| 1217 | - using ConvType = typename AscendC::Internal::ExtractTypeBySize<sizeof(T)>::T; | ||
| 1218 | - | ||
| 1219 | - constexpr bool isOrderFromTemplate = config.order != TopKOrder::UNSET; | ||
| 1220 | - constexpr bool isLargestInTemplate = config.order == TopKOrder::LARGEST; | ||
| 1221 | - | ||
| 1222 | - __ubuf__ ConvType *src = (__ubuf__ ConvType *)srcLocal.GetPhyAddr(); | ||
| 1223 | - __ubuf__ int32_t *srcIndex = (__ubuf__ int32_t *)srcIndexLocal.GetPhyAddr(); | ||
| 1224 | - __ubuf__ ConvType *dst = (__ubuf__ ConvType *)dstValueLocal.GetPhyAddr(); | ||
| 1225 | - __ubuf__ int32_t *dstIndex = (__ubuf__ int32_t *)dstIndexLocal.GetPhyAddr(); | ||
| 1226 | - __ubuf__ uint8_t *tmp = (__ubuf__ uint8_t *)tempBuffer.GetPhyAddr(); | ||
| 1227 | - | ||
| 1228 | - // temp data for storing values which are greater and equal than the topk value, same size with src | ||
| 1229 | - __ubuf__ ConvType *tmpSrcData; | ||
| 1230 | - // temp data for storing indexes related tmpSrcData, same size with srcIndex | ||
| 1231 | - __ubuf__ int32_t *tmpSrcIndex; | ||
| 1232 | - // temp data for storing accumulate data, 512B | ||
| 1233 | - __ubuf__ uint16_t *tmpHistData; | ||
| 1234 | - // temp data for storing work src values | ||
| 1235 | - __ubuf__ ConvType *realWorkData = src; | ||
| 1236 | - // temp data for sort | ||
| 1237 | - __ubuf__ ConvType *sortTmpBuffer; | ||
| 1238 | - | ||
| 1239 | - uint32_t count = topKInfo.inner; | ||
| 1240 | - uint32_t realCount = topKInfo.n; | ||
| 1241 | - | ||
| 1242 | - if constexpr (isOrderFromTemplate) { | ||
| 1243 | - InitializeTempBuffer<T, isReuseSrc, isLargestInTemplate>(tempBuffer, count, (__ubuf__ T*&)tmpSrcData, | ||
| 1244 | - tmpSrcIndex, tmpHistData, (__ubuf__ T*&)realWorkData, (__ubuf__ T*&)sortTmpBuffer); | ||
| 1245 | - | ||
| 1246 | - if constexpr (NeedPreProcess<T, isLargestInTemplate>()) { | ||
| 1247 | - Preprocess<T, ConvType, isLargestInTemplate>((__ubuf__ T*)src, realWorkData, count); | ||
| 1248 | - } | ||
| 1249 | - } else { | ||
| 1250 | - InitializeTempBuffer<T, isReuseSrc>(tempBuffer, isLargest, count, (__ubuf__ T*&)tmpSrcData, tmpSrcIndex, | ||
| 1251 | - tmpHistData, (__ubuf__ T*&)realWorkData, (__ubuf__ T*&)sortTmpBuffer); | ||
| 1252 | - | ||
| 1253 | - if (NeedPreProcess<T>(isLargest)) { | ||
| 1254 | - Preprocess<T, ConvType>((__ubuf__ T*)src, realWorkData, isLargest, count); | ||
| 1255 | - } | ||
| 1256 | - } | ||
| 1257 | - | ||
| 1258 | - constexpr uint16_t typeBytes = sizeof(T); | ||
| 1259 | - int32_t remainK = k; | ||
| 1260 | - ConvType kthValue = 0; | ||
| 1261 | - event_t eventVS = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_S)); | ||
| 1262 | - | ||
| 1263 | - for (uint16_t i = typeBytes; i > 0 && remainK > 0; --i) { | ||
| 1264 | - GenerateAccumulateData<ConvType>(realWorkData, tmpHistData, tmpSrcData, realCount, kthValue, i); | ||
| 1265 | - | ||
| 1266 | - SetFlag<HardEvent::V_S>(eventVS); | ||
| 1267 | - WaitFlag<HardEvent::V_S>(eventVS); | ||
| 1268 | - | ||
| 1269 | - int32_t expValue = tmpHistData[255] - remainK; | ||
| 1270 | - int16_t left = 0; | ||
| 1271 | - int16_t right = 255; | ||
| 1272 | - bool found = false; | ||
| 1273 | - while (left <= right) { | ||
| 1274 | - int16_t mid = left + (right - left) / 2; | ||
| 1275 | - if (tmpHistData[mid] == expValue) { | ||
| 1276 | - kthValue |= (static_cast<ConvType>(mid + 1) << ((i - 1) * 8)); | ||
| 1277 | - remainK = 0; | ||
| 1278 | - found = true; | ||
| 1279 | - break; | ||
| 1280 | - } else if (tmpHistData[mid] > expValue) { | ||
| 1281 | - right = mid - 1; | ||
| 1282 | - } else { | ||
| 1283 | - left = mid + 1; | ||
| 1284 | - } | ||
| 1285 | - } | ||
| 1286 | - if (!found) { | ||
| 1287 | - if (right >= 0){ | ||
| 1288 | - kthValue |= (static_cast<ConvType>(right + 1) << ((i - 1) * 8)); | ||
| 1289 | - remainK -= (tmpHistData[255] - tmpHistData[right + 1]); | ||
| 1290 | - } else { | ||
| 1291 | - remainK = tmpHistData[0] - expValue; | ||
| 1292 | - } | ||
| 1293 | - } | ||
| 1294 | - } | ||
| 1295 | - | ||
| 1296 | - GatherGreaterAndEqualKData(realWorkData, tmpSrcData, kthValue, realCount); | ||
| 1297 | - GatherGreaterAndEqualKIndex(realWorkData, srcIndex, tmpSrcIndex, kthValue, realCount); | ||
| 1298 | - | ||
| 1299 | - if constexpr (config.sorted) { | ||
| 1300 | - static constexpr SortConfig sortConfig = {SortType::RADIX_SORT, true}; | ||
| 1301 | - | ||
| 1302 | - LocalTensor<ConvType> valueTensor = tempBuffer.template ReinterpretCast<ConvType>(); | ||
| 1303 | - LocalTensor<ConvType> sortDataSrc = valueTensor[(__ubuf__ T*)tmpSrcData - (__ubuf__ T*)tmp]; | ||
| 1304 | - | ||
| 1305 | - LocalTensor<int32_t> indexTensor = tempBuffer.template ReinterpretCast<int32_t>(); | ||
| 1306 | - LocalTensor<int32_t> sortIndexSrc = indexTensor[(__ubuf__ int32_t*)tmpSrcIndex - (__ubuf__ int32_t*)tmp]; | ||
| 1307 | - | ||
| 1308 | - LocalTensor<uint8_t> tmpTensor = tempBuffer.template ReinterpretCast<uint8_t>(); | ||
| 1309 | - LocalTensor<uint8_t> sortBufferTensor = tmpTensor[(__ubuf__ uint8_t*)sortTmpBuffer - (__ubuf__ uint8_t*)tmp]; | ||
| 1310 | - | ||
| 1311 | - LocalTensor<ConvType> dstValueTensor = dstValueLocal.template ReinterpretCast<ConvType>(); | ||
| 1312 | - LocalTensor<int32_t> dstIndexTensor = dstIndexLocal.template ReinterpretCast<int32_t>(); | ||
| 1313 | - Sort<ConvType, int32_t, false, sortConfig>(dstValueTensor, dstIndexTensor, sortDataSrc, sortIndexSrc, sortBufferTensor, static_cast<uint32_t>(k)); | ||
| 1314 | - } else { | ||
| 1315 | - SaveData<T>((__ubuf__ T*)dst, dstIndex, (__ubuf__ T*)tmpSrcData, tmpSrcIndex, static_cast<uint32_t>(k)); | ||
| 1316 | - } | ||
| 1317 | - | ||
| 1318 | - if constexpr (isOrderFromTemplate) { | ||
| 1319 | - if constexpr (NeedPreProcess<T, isLargestInTemplate>()) { | ||
| 1320 | - PostProcess<T, ConvType, isLargestInTemplate>(dst, dst, k); | ||
| 1321 | - } | ||
| 1322 | - } else { | ||
| 1323 | - if (NeedPreProcess<T>(isLargest)) { | ||
| 1324 | - PostProcess<T, ConvType>(dst, dst, isLargest, k); | ||
| 1325 | - } | ||
| 1326 | - } | ||
| 1327 | -} | ||
| 1328 | - | ||
| 1329 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false, const TopKConfig &config = defaultTopKConfig> | ||
| 1330 | -__aicore__ inline void TopKNormal(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1331 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1332 | - const LocalTensor<T> &tempBuffer, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 1333 | - const bool isLargest = true) | ||
| 1334 | -{ | ||
| 1335 | - // if isInitIndex is false, The index of the input data needs to be generated here. | ||
| 1336 | - LocalTensor<int32_t> realIndexSrc(srcIndexLocal); | ||
| 1337 | - uint32_t initIndexTempBufferSize = 0; | ||
| 1338 | - if constexpr (!isInitIndex) { | ||
| 1339 | - LocalTensor<int32_t> indexSrcTmp = tempBuffer.template ReinterpretCast<int32_t>(); | ||
| 1340 | - CreateVecIndex(indexSrcTmp, static_cast<int32_t>(0), topKInfo.inner); | ||
| 1341 | - realIndexSrc = indexSrcTmp; | ||
| 1342 | - initIndexTempBufferSize += sizeof(int32_t) * topKInfo.inner / sizeof(T); | ||
| 1343 | - } | ||
| 1344 | - | ||
| 1345 | - int32_t kPad = GetKPad<T>(k); | ||
| 1346 | - int32_t indexKPad = GetKPad<int32_t>(k); | ||
| 1347 | - for (int32_t i = 0; i < topKInfo.outter; ++i) { | ||
| 1348 | - TopKRaidxSelect<T, isInitIndex, isReuseSrc, config>(dstValueLocal[i * kPad], dstIndexLocal[i * indexKPad], | ||
| 1349 | - srcLocal[i * topKInfo.inner], realIndexSrc, tempBuffer[initIndexTempBufferSize], k, tilling, topKInfo, isLargest); | ||
| 1350 | - } | ||
| 1351 | -} | ||
| 1352 | - | ||
| 1353 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false, const TopKConfig &config = defaultTopKConfig> | ||
| 1354 | -__aicore__ inline void TopKNSmall(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1355 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1356 | - const LocalTensor<T> &tempBuffer, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 1357 | - const bool isLargest = true) | ||
| 1358 | -{ | ||
| 1359 | - // if isInitIndex is false, The index of the input data needs to be generated here. | ||
| 1360 | - LocalTensor<int32_t> realIndexSrc(srcIndexLocal); | ||
| 1361 | - LocalTensor<T> tmpDstValueLocal(dstValueLocal); | ||
| 1362 | - LocalTensor<int32_t> tmpDstIndexLocal(dstIndexLocal); | ||
| 1363 | - | ||
| 1364 | - uint32_t initIndexTempBufferSize = 0; | ||
| 1365 | - if constexpr (!isInitIndex) { | ||
| 1366 | - LocalTensor<int32_t> indexLocalTmp = tempBuffer.template ReinterpretCast<int32_t>(); | ||
| 1367 | - CreateVecIndex(indexLocalTmp, static_cast<int32_t>(0), topKInfo.inner); | ||
| 1368 | - if (topKInfo.outter > 1) { | ||
| 1369 | - Copy(indexLocalTmp[topKInfo.inner], indexLocalTmp, topKInfo.inner, topKInfo.outter - 1, {1, 1, 4, 0}); | ||
| 1370 | - } | ||
| 1371 | - realIndexSrc = indexLocalTmp; | ||
| 1372 | - initIndexTempBufferSize += sizeof(int32_t) * (topKInfo.inner * topKInfo.outter) / sizeof(T); | ||
| 1373 | - } | ||
| 1374 | - | ||
| 1375 | - int32_t kPad = GetKPad<T>(k); | ||
| 1376 | - int32_t indexKPad = GetKPad<int32_t>(k); | ||
| 1377 | - event_t eventVS = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_S)); | ||
| 1378 | - for (int32_t i = 0; i < topKInfo.outter; ++i) { | ||
| 1379 | - TopKRaidxSelect<T, isInitIndex, isReuseSrc, config>(tmpDstValueLocal[i * kPad], tmpDstIndexLocal[i * indexKPad], | ||
| 1380 | - srcLocal[i * topKInfo.inner], realIndexSrc[i * topKInfo.inner], tempBuffer[initIndexTempBufferSize], | ||
| 1381 | - k, tilling, topKInfo, isLargest); | ||
| 1382 | - } | ||
| 1383 | - SetFlag<HardEvent::V_S>(eventVS); | ||
| 1384 | - WaitFlag<HardEvent::V_S>(eventVS); | ||
| 1385 | - SaveDataUnAlign<T>(dstValueLocal, dstIndexLocal, tmpDstValueLocal, tmpDstIndexLocal, topKInfo, k); | ||
| 1386 | -} | ||
| 1387 | - | ||
| 1388 | -} // namespace RadixSelectTopK | ||
| 1389 | -} // namespace MicroAPI | ||
| 1390 | - | ||
| 1391 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false> | ||
| 1392 | -__aicore__ inline void TopKNormal(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1393 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1394 | - const LocalTensor<T> &tempBuffer, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 1395 | - const bool isLargest = true) | ||
| 1396 | -{ | ||
| 1397 | - // if isInitIndex is false, The index of the input data needs to be generated here. | ||
| 1398 | - if constexpr (!isInitIndex) { | ||
| 1399 | - LocalTensor<int32_t> indexLocalTmp = tempBuffer[tilling.srcIndexOffset].template ReinterpretCast<int32_t>(); | ||
| 1400 | - CreateVecIndex(indexLocalTmp, static_cast<int32_t>(0), topKInfo.inner); | ||
| 1401 | - } | ||
| 1402 | - if (!isLargest) { | ||
| 1403 | - Muls(srcLocal, srcLocal, T(-1), topKInfo.outter * topKInfo.inner); | ||
| 1404 | - } | ||
| 1405 | - | ||
| 1406 | - TopKCompute<T, isInitIndex, isHasfinish>(dstValueLocal, dstIndexLocal, srcLocal, srcIndexLocal, | ||
| 1407 | - finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1408 | - | ||
| 1409 | - if (!isLargest) { | ||
| 1410 | - Muls(dstValueLocal, dstValueLocal, T(-1), tilling.maskOffset); | ||
| 1411 | - Muls(srcLocal, srcLocal, T(-1), topKInfo.outter * topKInfo.inner); | ||
| 1412 | - } | ||
| 1413 | -} | ||
| 1414 | - | ||
| 1415 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false> | ||
| 1416 | -__aicore__ inline void TopKNSmall(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1417 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1418 | - const LocalTensor<T> &tempBuffer, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 1419 | - const bool isLargest = true) | ||
| 1420 | -{ | ||
| 1421 | - // if isInitIndex is false, The index of the input data needs to be generated here. | ||
| 1422 | - if constexpr (!isInitIndex) { | ||
| 1423 | - LocalTensor<int32_t> indexLocalTmp = tempBuffer[tilling.innerDataSize].template | ||
| 1424 | - ReinterpretCast<int32_t>(); | ||
| 1425 | - CreateVecIndex(indexLocalTmp, static_cast<int32_t>(0), topKInfo.inner); | ||
| 1426 | - if (topKInfo.outter > 1) { | ||
| 1427 | - Copy(indexLocalTmp[topKInfo.inner], indexLocalTmp, topKInfo.inner, topKInfo.outter - 1, {1, 1, 4, 0}); | ||
| 1428 | - } | ||
| 1429 | - } | ||
| 1430 | - // if isLargest if false, sort Ascending | ||
| 1431 | - if (!isLargest) { | ||
| 1432 | - Muls(srcLocal, srcLocal, T(-1), topKInfo.outter * topKInfo.inner); | ||
| 1433 | - } | ||
| 1434 | - | ||
| 1435 | - TopKNSmallCompute<T, isInitIndex, isHasfinish>(dstValueLocal, dstIndexLocal, srcLocal, srcIndexLocal, | ||
| 1436 | - finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1437 | - | ||
| 1438 | - if (!isLargest) { | ||
| 1439 | - Muls(dstValueLocal, dstValueLocal, T(-1), tilling.maskOffset); | ||
| 1440 | - Muls(srcLocal, srcLocal, T(-1), topKInfo.outter * topKInfo.inner); | ||
| 1441 | - } | ||
| 1442 | -} | ||
| 1443 | - | ||
| 1444 | -/* | ||
| 1445 | - * @ingroup TopK | ||
| 1446 | - * @brief Get the top k maximum or minimum values and their corresponding indices of the last dimension. | ||
| 1447 | - * @tparam T: Data type to be sorted, half or float. | ||
| 1448 | - * @tparam isInitIndex: Whether to transfer the index of the input data. | ||
| 1449 | - If the value is true, srcIndexLocal is the index of the input data. | ||
| 1450 | - If the value is false, the index is generated by the Topk API. | ||
| 1451 | - * @tparam isHasfinish: The isHasfinish parameter is used to specify that the sorting of some rows is invalid. | ||
| 1452 | - If the value is true, enable the function. If the value is false, disable the function. | ||
| 1453 | - In normal mode, isHasfinish can be set to true or false. | ||
| 1454 | - In small mode, isHasfinish can only be set to false. | ||
| 1455 | - * @tparam isReuseSrc: Whether temporary variables can reuse the input memory. | ||
| 1456 | - This parameter is reserved. Use the default value false. | ||
| 1457 | - * @tparam topkMode: Normal mode or small mode, | ||
| 1458 | - Small mode is recommended when the inner axis length is 32. Performance will be high. | ||
| 1459 | - * @param [out] dstValueLocal: Used to store k sorted values. | ||
| 1460 | - * @param [out] dstIndexLocal: Used to store indexes corresponding to sorted k values. | ||
| 1461 | - * @param [in] srcLocal: Input data to hold values to be sorted. | ||
| 1462 | - * @param [in] srcIndexLocal: The input data is used to store the index corresponding to the value of srcLocal. | ||
| 1463 | - * @param [in] finishLocal: Used to specify that the sort of some rows is an invalid sort with shape of (outter, 1). | ||
| 1464 | - * @param [in] tmpLocal: Temporary space for storing intermediate variables during internal calculation. | ||
| 1465 | - * @param [in] k: Obtain the first k maximum or minimum values and their corresponding indexes. | ||
| 1466 | - * @param [in] tilling: Tiling information required for TopK calculation. | ||
| 1467 | - * @param [in] topKInfo: Shape information of srcLocal. | ||
| 1468 | - * @param [in] isLargest: Descending or ascending order. The value true indicates descending order, | ||
| 1469 | - and the value false indicates ascending order. | ||
| 1470 | - */ | ||
| 1471 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false, | ||
| 1472 | - enum TopKMode topkMode = TopKMode::TOPK_NORMAL, const TopKConfig& config = defaultTopKConfig> | ||
| 1473 | -__aicore__ inline void TopK(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1474 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1475 | - const LocalTensor<uint8_t> &tmpLocal, const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, | ||
| 1476 | - const bool isLargest = true) | ||
| 1477 | -{ | ||
| 1478 | - // Only for AI Vector Core. | ||
| 1479 | - if ASCEND_IS_AIC { | ||
| 1480 | - return; | ||
| 1481 | - } | ||
| 1482 | - | ||
| 1483 | - | ||
| 1484 | - TopkInputCheck<T, isInitIndex, topkMode, config>(k, topKInfo); | ||
| 1485 | - | ||
| 1486 | - LocalTensor<T> tempBuffer = tmpLocal.template ReinterpretCast<T>(); | ||
| 1487 | - | ||
| 1488 | - if constexpr (config.algo == TopKAlgo::RADIX_SELECT) { | ||
| 1489 | - static_assert((SupportType<T, uint8_t, int8_t, uint16_t, int16_t, half, float, bfloat16_t, uint32_t, int32_t, | ||
| 1490 | - uint64_t, int64_t>()), | ||
| 1491 | - "Type must be uint8_t/int8_t/uint16_t/int16_t/half/float/bfloat16_t/uint32_t/int32_t/uint64_t/int64_t in " | ||
| 1492 | - "topk radix select algorithm."); | ||
| 1493 | - static_assert((!isHasfinish), "Topk radix select algorithm cannot support to set finish flag."); | ||
| 1494 | - if constexpr (topkMode == TopKMode::TOPK_NORMAL) { | ||
| 1495 | - MicroAPI::RadixSelectTopK::TopKNormal<T, isInitIndex, isHasfinish, isReuseSrc, config>(dstValueLocal, | ||
| 1496 | - dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1497 | - } | ||
| 1498 | - | ||
| 1499 | - if constexpr (topkMode == TopKMode::TOPK_NSMALL) { | ||
| 1500 | - MicroAPI::RadixSelectTopK::TopKNSmall<T, isInitIndex, isHasfinish, isReuseSrc, config>(dstValueLocal, | ||
| 1501 | - dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1502 | - } | ||
| 1503 | - return; | ||
| 1504 | - } | ||
| 1505 | - | ||
| 1506 | - if constexpr (config.algo == TopKAlgo::MERGE_SORT) { | ||
| 1507 | - static_assert((SupportType<T, half, float>()), "Type must be half/float in topk merge select algorithm."); | ||
| 1508 | - if constexpr (topkMode == TopKMode::TOPK_NORMAL) { | ||
| 1509 | - TopKNormal<T, isInitIndex, isHasfinish, isReuseSrc>(dstValueLocal, dstIndexLocal, srcLocal, | ||
| 1510 | - srcIndexLocal, finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1511 | - } | ||
| 1512 | - if constexpr (topkMode == TopKMode::TOPK_NSMALL) { | ||
| 1513 | - TopKNSmall<T, isInitIndex, isHasfinish, isReuseSrc>(dstValueLocal, dstIndexLocal, srcLocal, | ||
| 1514 | - srcIndexLocal, finishLocal, tempBuffer, k, tilling, topKInfo, isLargest); | ||
| 1515 | - } | ||
| 1516 | - } | ||
| 1517 | -} | ||
| 1518 | - | ||
| 1519 | -/* | ||
| 1520 | - * @ingroup TopK | ||
| 1521 | - * @brief Get the top k maximum or minimum values and their corresponding indices of the last dimension. | ||
| 1522 | - * @tparam T: Data type to be sorted, half or float. | ||
| 1523 | - * @tparam isInitIndex: Whether to transfer the index of the input data. | ||
| 1524 | - If the value is true, srcIndexLocal is the index of the input data. | ||
| 1525 | - If the value is false, the index is generated by the Topk API. | ||
| 1526 | - * @tparam isHasfinish: The isHasfinish parameter is used to specify that the sorting of some rows is invalid. | ||
| 1527 | - If the value is true, enable the function. If the value is false, disable the function. | ||
| 1528 | - In normal mode, isHasfinish can be set to true or false. | ||
| 1529 | - In small mode, isHasfinish can only be set to false. | ||
| 1530 | - * @tparam isReuseSrc: Whether temporary variables can reuse the input memory. | ||
| 1531 | - This parameter is reserved. Use the default value false. | ||
| 1532 | - * @tparam topkMode: Normal mode or small mode, | ||
| 1533 | - Small mode is recommended when the inner axis length is 32. Performance will be high. | ||
| 1534 | - * @param [out] dstValueLocal: Used to store k sorted values. | ||
| 1535 | - * @param [out] dstIndexLocal: Used to store indexes corresponding to sorted k values. | ||
| 1536 | - * @param [in] srcLocal: Input data to hold values to be sorted. | ||
| 1537 | - * @param [in] srcIndexLocal: The input data is used to store the index corresponding to the value of srcLocal. | ||
| 1538 | - * @param [in] finishLocal: Used to specify that the sort of some rows is an invalid sort with shape of (outter, 1). | ||
| 1539 | - * @param [in] k: Obtain the first k maximum or minimum values and their corresponding indexes. | ||
| 1540 | - * @param [in] tilling: Tiling information required for TopK calculation. | ||
| 1541 | - * @param [in] topKInfo: Shape information of srcLocal. | ||
| 1542 | - * @param [in] isLargest: Descending or ascending order. The value true indicates descending order, | ||
| 1543 | - and the value false indicates ascending order. | ||
| 1544 | - */ | ||
| 1545 | -template <typename T, bool isInitIndex = false, bool isHasfinish = false, bool isReuseSrc = false, | ||
| 1546 | - enum TopKMode topkMode = TopKMode::TOPK_NORMAL, const TopKConfig& config = defaultTopKConfig> | ||
| 1547 | -__aicore__ inline void TopK(const LocalTensor<T> &dstValueLocal, const LocalTensor<int32_t> &dstIndexLocal, | ||
| 1548 | - const LocalTensor<T> &srcLocal, const LocalTensor<int32_t> &srcIndexLocal, const LocalTensor<bool> &finishLocal, | ||
| 1549 | - const int32_t k, const TopkTiling &tilling, const TopKInfo &topKInfo, const bool isLargest = true) | ||
| 1550 | -{ | ||
| 1551 | - // Only for AI Vector Core. | ||
| 1552 | - if ASCEND_IS_AIC { | ||
| 1553 | - return; | ||
| 1554 | - } | ||
| 1555 | - | ||
| 1556 | - LocalTensor<T> stackTensor; | ||
| 1557 | - PopStackBuffer<T, TPosition::LCM>(stackTensor); | ||
| 1558 | - | ||
| 1559 | - // float: tmpLocalSize = inner * 16 / sizeof(float) = inner * 4 | ||
| 1560 | - // half: tmpLocalSize = inner * 16 / sizeof(half) = inner * 8 | ||
| 1561 | - | ||
| 1562 | - auto stackTensorSize = stackTensor.GetSize(); | ||
| 1563 | - bool ans = stackTensorSize >= tilling.tmpLocalSize; | ||
| 1564 | - ASCENDC_ASSERT(ans, { | ||
| 1565 | - KERNEL_LOG(KERNEL_ERROR, | ||
| 1566 | - "The pop stack buffer is insufficient, topk api need %d, but only %d exists.", | ||
| 1567 | - tilling.tmpLocalSize, | ||
| 1568 | - stackTensorSize); | ||
| 1569 | - }); | ||
| 1570 | - | ||
| 1571 | - TopkInputCheck<T, isInitIndex, topkMode, config>(k, topKInfo); | ||
| 1572 | - | ||
| 1573 | - stackTensor.SetSize(tilling.tmpLocalSize); | ||
| 1574 | - | ||
| 1575 | - if constexpr (config.algo == TopKAlgo::RADIX_SELECT) { | ||
| 1576 | - static_assert((SupportType<T, uint8_t, int8_t, uint16_t, int16_t, half, float, bfloat16_t, uint32_t, int32_t, | ||
| 1577 | - uint64_t, int64_t>()), | ||
| 1578 | - "Type must be uint8_t/int8_t/uint16_t/int16_t/half/float/bfloat16_t/uint32_t/int32_t/uint64_t/int64_t in " | ||
| 1579 | - "topk radix select algorithm."); | ||
| 1580 | - static_assert((!isHasfinish), "Topk radix select algorithm cannot support to set finish flag."); | ||
| 1581 | - if constexpr (topkMode == TopKMode::TOPK_NORMAL) { | ||
| 1582 | - MicroAPI::RadixSelectTopK::TopKNormal<T, isInitIndex, isHasfinish, isReuseSrc, config>(dstValueLocal, | ||
| 1583 | - dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, stackTensor, k, tilling, topKInfo, isLargest); | ||
| 1584 | - } | ||
| 1585 | - | ||
| 1586 | - if constexpr (topkMode == TopKMode::TOPK_NSMALL) { | ||
| 1587 | - MicroAPI::RadixSelectTopK::TopKNSmall<T, isInitIndex, isHasfinish, isReuseSrc, config>(dstValueLocal, | ||
| 1588 | - dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, stackTensor, k, tilling, topKInfo, isLargest); | ||
| 1589 | - } | ||
| 1590 | - return; | ||
| 1591 | - } | ||
| 1592 | - | ||
| 1593 | - if constexpr (config.algo == TopKAlgo::MERGE_SORT) { | ||
| 1594 | - static_assert((SupportType<T, half, float>()), "Type must be half/float in topk merge select algorithm."); | ||
| 1595 | - if constexpr (topkMode == TopKMode::TOPK_NORMAL) { | ||
| 1596 | - TopKNormal<T, isInitIndex, isHasfinish, isReuseSrc>( | ||
| 1597 | - dstValueLocal, dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, stackTensor, k, tilling, | ||
| 1598 | - topKInfo, isLargest); | ||
| 1599 | - } | ||
| 1600 | - if constexpr (topkMode == TopKMode::TOPK_NSMALL) { | ||
| 1601 | - TopKNSmall<T, isInitIndex, isHasfinish, isReuseSrc>( | ||
| 1602 | - dstValueLocal, dstIndexLocal, srcLocal, srcIndexLocal, finishLocal, stackTensor, k, tilling, | ||
| 1603 | - topKInfo, isLargest); | ||
| 1604 | - } | ||
| 1605 | - } | ||
| 1606 | -} | ||
| 1607 | - | ||
| 1608 | -} // namespace AscendC | ||
| 1609 | - | ||
| 1610 | - | ||
Dimpl/adv_api/detail/transpose/confusion_transpose/confusion_transpose_l300_impl.h+0-555
| @@ -1,555 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | -* Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -* This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -* CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -* Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -* See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -*/ | ||
| 10 | - | ||
| 11 | -/* ! | ||
| 12 | - * \file confusion_transpose_l300_impl.h | ||
| 13 | - * \brief | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | -namespace AscendC { | ||
| 19 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 20 | -__simd_vf__ inline void ConfusionTransposeCommonGatherVF(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 21 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2, uint32_t tail, | ||
| 22 | - uint32_t count, uint16_t mainLoop, uint32_t dtypeSize, uint32_t tailLoop) | ||
| 23 | -{ | ||
| 24 | - MicroAPI::RegTensor<U, Trait> indexReg; | ||
| 25 | - MicroAPI::RegTensor<T, Trait> MainVreg; | ||
| 26 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<U, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 27 | - MicroAPI::MaskReg mainMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 28 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<T, Trait>(count); | ||
| 29 | - MicroAPI::UnalignReg ureg0; | ||
| 30 | - Arange((MicroAPI::RegTensor<X, Trait> &)indexReg, static_cast<X>(0)); | ||
| 31 | - Muls(indexReg, indexReg, static_cast<U>(srcStride2), indexFullMask); | ||
| 32 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop0); i++) { | ||
| 33 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 34 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)((i * forLoop1 + j) * forLoop2 * dtypeSize); | ||
| 35 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 36 | - DataCopyGather(MainVreg, srcAddr + i * srcStride0 + j * srcStride1 + k * vlSize * srcStride2, | ||
| 37 | - indexReg, mainMask); | ||
| 38 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, ureg0, vlSize); | ||
| 39 | - } | ||
| 40 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 41 | - DataCopyGather(MainVreg, srcAddr + i * srcStride0 + j * srcStride1 + mainLoop * vlSize * srcStride2, | ||
| 42 | - indexReg, tailMask); | ||
| 43 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, ureg0, tail); | ||
| 44 | - } | ||
| 45 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ T *&)hoistDstAddr), ureg0, 0); | ||
| 46 | - } | ||
| 47 | - } | ||
| 48 | -} | ||
| 49 | - | ||
| 50 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 51 | -__aicore__ inline void ConfusionTransposeCommonGather(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 52 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2) | ||
| 53 | -{ | ||
| 54 | - uint32_t tail = forLoop2 % vlSize; | ||
| 55 | - uint32_t count = tail; | ||
| 56 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 57 | - uint32_t dtypeSize = sizeof(T); | ||
| 58 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 59 | - ConfusionTransposeCommonGatherVF<T, X, U, Trait, vlSize>(dstAddr, srcAddr, forLoop0, | ||
| 60 | - forLoop1, forLoop2, srcStride0, srcStride1, srcStride2, tail, count, mainLoop, dtypeSize, tailLoop); | ||
| 61 | -} | ||
| 62 | - | ||
| 63 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 64 | -__simd_vf__ inline void ConfusionTransposeCommonGatherB8VF(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 65 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2, uint32_t tail, | ||
| 66 | - uint32_t count, uint16_t mainLoop, uint32_t dtypeSize, uint32_t tailLoop) | ||
| 67 | -{ | ||
| 68 | - MicroAPI::RegTensor<U, Trait> indexReg; | ||
| 69 | - MicroAPI::RegTensor<T, Trait> vreg0; | ||
| 70 | - MicroAPI::RegTensor<T, Trait> vreg1; | ||
| 71 | - MicroAPI::RegTensor<T, Trait> vreg2; | ||
| 72 | - MicroAPI::RegTensor<T, Trait> vreg3; | ||
| 73 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<U, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 74 | - MicroAPI::MaskReg mainMask = MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 75 | - MicroAPI::MaskReg tailMask0 = MicroAPI::UpdateMask<U, Trait>(count); | ||
| 76 | - MicroAPI::MaskReg tailMask1 = MicroAPI::UpdateMask<U, Trait>(count); | ||
| 77 | - MicroAPI::UnalignReg ureg0; | ||
| 78 | - Arange((MicroAPI::RegTensor<X, Trait> &)indexReg, static_cast<X>(0)); | ||
| 79 | - Muls(indexReg, indexReg, static_cast<U>(srcStride2), indexFullMask); | ||
| 80 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop0); i++) { | ||
| 81 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 82 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)((i * forLoop1 + j) * forLoop2 * dtypeSize); | ||
| 83 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 84 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg0, | ||
| 85 | - srcAddr + i * srcStride0 + j * srcStride1 + k * vlSize * srcStride2, indexReg, mainMask); | ||
| 86 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg1, | ||
| 87 | - srcAddr + i * srcStride0 + j * srcStride1 + k * vlSize * srcStride2 + vlSize / 2 * srcStride2, | ||
| 88 | - indexReg, mainMask); | ||
| 89 | - DeInterleave(vreg2, vreg3, vreg0, vreg1); | ||
| 90 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), vreg2, ureg0, vlSize); | ||
| 91 | - } | ||
| 92 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 93 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg0, | ||
| 94 | - srcAddr + i * srcStride0 + j * srcStride1 + mainLoop * vlSize * srcStride2, indexReg, | ||
| 95 | - tailMask0); | ||
| 96 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg1, | ||
| 97 | - srcAddr + i * srcStride0 + j * srcStride1 + mainLoop * vlSize * srcStride2 + | ||
| 98 | - vlSize / 2 * srcStride2, | ||
| 99 | - indexReg, tailMask1); | ||
| 100 | - DeInterleave(vreg2, vreg3, vreg0, vreg1); | ||
| 101 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), vreg2, ureg0, tail); | ||
| 102 | - } | ||
| 103 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ T *&)hoistDstAddr), ureg0, 0); | ||
| 104 | - } | ||
| 105 | - } | ||
| 106 | -} | ||
| 107 | - | ||
| 108 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 109 | -__aicore__ inline void ConfusionTransposeCommonGatherB8(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 110 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2) | ||
| 111 | -{ | ||
| 112 | - uint32_t tail = forLoop2 % vlSize; | ||
| 113 | - uint32_t count = tail; | ||
| 114 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 115 | - uint32_t dtypeSize = sizeof(T); | ||
| 116 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 117 | - ConfusionTransposeCommonGatherB8VF<T, X, U, Trait, vlSize>(dstAddr, srcAddr, forLoop0, | ||
| 118 | - forLoop1, forLoop2, srcStride0, srcStride1, srcStride2, tail, count, mainLoop, dtypeSize, tailLoop); | ||
| 119 | -} | ||
| 120 | - | ||
| 121 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 122 | -__simd_vf__ inline void ConfusionTransposeComplexGatherVF(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 123 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2, uint32_t factor, | ||
| 124 | - uint32_t mainSize, uint16_t mainLoop, uint32_t tail, uint32_t tailLoop, uint32_t mainCount, uint32_t tailCount, | ||
| 125 | - uint32_t count, uint32_t dtypeSize) | ||
| 126 | -{ | ||
| 127 | - MicroAPI::RegTensor<U, Trait> indexReg0; | ||
| 128 | - MicroAPI::RegTensor<U, Trait> indexReg1; | ||
| 129 | - MicroAPI::RegTensor<U, Trait> indexReg2; | ||
| 130 | - MicroAPI::RegTensor<U, Trait> indexReg3; | ||
| 131 | - MicroAPI::RegTensor<U, Trait> indexReg4; | ||
| 132 | - MicroAPI::RegTensor<U, Trait> indexReg5; | ||
| 133 | - MicroAPI::RegTensor<T, Trait> MainVreg; | ||
| 134 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<U, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 135 | - MicroAPI::MaskReg mainMask = MicroAPI::UpdateMask<T, Trait>(mainCount); | ||
| 136 | - MicroAPI::MaskReg tailMask = MicroAPI::UpdateMask<T, Trait>(tailCount); | ||
| 137 | - MicroAPI::UnalignReg ureg0; | ||
| 138 | - Arange((MicroAPI::RegTensor<X, Trait> &)indexReg0, static_cast<X>(0)); | ||
| 139 | - Duplicate(indexReg1, static_cast<U>(forLoop2)); | ||
| 140 | - Div(indexReg2, indexReg0, indexReg1, indexFullMask); | ||
| 141 | - Muls(indexReg3, indexReg2, static_cast<U>(srcStride1), indexFullMask); | ||
| 142 | - // k%c: k - k/c*c | ||
| 143 | - Mul(indexReg4, indexReg2, indexReg1, indexFullMask); | ||
| 144 | - Sub(indexReg4, indexReg0, indexReg4, indexFullMask); | ||
| 145 | - Muls(indexReg4, indexReg4, static_cast<U>(srcStride2), indexFullMask); | ||
| 146 | - Add(indexReg5, indexReg3, indexReg4, indexFullMask); | ||
| 147 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop0); i++) { | ||
| 148 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)(i * forLoop1 * forLoop2 * dtypeSize); | ||
| 149 | - for (uint16_t j = 0; j < static_cast<uint16_t>(mainLoop); j++) { | ||
| 150 | - DataCopyGather(MainVreg, srcAddr + i * srcStride0 + j * srcStride1 * factor, indexReg5, mainMask); | ||
| 151 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, ureg0, mainSize); | ||
| 152 | - } | ||
| 153 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 154 | - DataCopyGather(MainVreg, srcAddr + i * srcStride0 + mainLoop * srcStride1 * factor, indexReg5, | ||
| 155 | - tailMask); | ||
| 156 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, ureg0, tail); | ||
| 157 | - } | ||
| 158 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ T *&)hoistDstAddr), ureg0, 0); | ||
| 159 | - } | ||
| 160 | -} | ||
| 161 | - | ||
| 162 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 163 | -__aicore__ inline void ConfusionTransposeComplexGather(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 164 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2) | ||
| 165 | -{ | ||
| 166 | - uint32_t factor = vlSize / forLoop2; | ||
| 167 | - uint32_t mainSize = factor * forLoop2; | ||
| 168 | - uint16_t mainLoop = forLoop1 / factor; | ||
| 169 | - uint32_t tail = forLoop1 % factor * forLoop2; | ||
| 170 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 171 | - uint32_t mainCount = mainSize; | ||
| 172 | - uint32_t tailCount = tail; | ||
| 173 | - | ||
| 174 | - uint32_t count = tail; | ||
| 175 | - uint32_t dtypeSize = sizeof(T); | ||
| 176 | - ConfusionTransposeComplexGatherVF<T, X, U, Trait, vlSize>(dstAddr, srcAddr, forLoop0, forLoop1, forLoop2, | ||
| 177 | - srcStride0, srcStride1, srcStride2, factor, mainSize, mainLoop, tail, tailLoop, mainCount, tailCount, | ||
| 178 | - count, dtypeSize); | ||
| 179 | -} | ||
| 180 | - | ||
| 181 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 182 | -__simd_vf__ inline void ConfusionTransposeComplexGatherB8VF(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 183 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2, uint32_t factor, | ||
| 184 | - uint32_t mainSize, uint16_t mainLoop, uint32_t tail, uint32_t tailLoop, uint32_t mainCount, uint32_t tailCount, | ||
| 185 | - uint32_t dtypeSize, uint32_t halfVlSize) | ||
| 186 | -{ | ||
| 187 | - MicroAPI::RegTensor<U, Trait> indexReg0; | ||
| 188 | - MicroAPI::RegTensor<U, Trait> indexReg1; | ||
| 189 | - MicroAPI::RegTensor<U, Trait> indexReg2; | ||
| 190 | - MicroAPI::RegTensor<U, Trait> indexReg3; | ||
| 191 | - MicroAPI::RegTensor<U, Trait> indexReg4; | ||
| 192 | - MicroAPI::RegTensor<U, Trait> indexReg5; | ||
| 193 | - MicroAPI::RegTensor<U, Trait> indexReg6; | ||
| 194 | - MicroAPI::RegTensor<U, Trait> indexReg7; | ||
| 195 | - MicroAPI::RegTensor<U, Trait> indexReg8; | ||
| 196 | - MicroAPI::RegTensor<U, Trait> indexReg9; | ||
| 197 | - MicroAPI::RegTensor<U, Trait> indexReg10; | ||
| 198 | - MicroAPI::RegTensor<T, Trait> vreg0; | ||
| 199 | - MicroAPI::RegTensor<T, Trait> vreg1; | ||
| 200 | - MicroAPI::RegTensor<T, Trait> vreg2; | ||
| 201 | - MicroAPI::RegTensor<T, Trait> vreg3; | ||
| 202 | - MicroAPI::MaskReg indexFullMask = MicroAPI::CreateMask<U, MicroAPI::MaskPattern::ALL, Trait>(); | ||
| 203 | - MicroAPI::MaskReg mainMask0 = MicroAPI::UpdateMask<U, Trait>(mainCount); | ||
| 204 | - MicroAPI::MaskReg mainMask1 = MicroAPI::UpdateMask<U, Trait>(mainCount); | ||
| 205 | - MicroAPI::MaskReg tailMask0 = MicroAPI::UpdateMask<U, Trait>(tailCount); | ||
| 206 | - MicroAPI::MaskReg tailMask1 = MicroAPI::UpdateMask<U, Trait>(tailCount); | ||
| 207 | - MicroAPI::UnalignReg ureg0; | ||
| 208 | - Arange((MicroAPI::RegTensor<X, Trait> &)indexReg0, static_cast<X>(0)); | ||
| 209 | - Duplicate(indexReg1, static_cast<U>(forLoop2)); | ||
| 210 | - Div(indexReg2, indexReg0, indexReg1, indexFullMask); | ||
| 211 | - Muls(indexReg3, indexReg2, static_cast<U>(srcStride1), indexFullMask); | ||
| 212 | - // k%c: k - k/c*c | ||
| 213 | - Mul(indexReg4, indexReg2, indexReg1, indexFullMask); | ||
| 214 | - Sub(indexReg4, indexReg0, indexReg4, indexFullMask); | ||
| 215 | - Muls(indexReg4, indexReg4, static_cast<U>(srcStride2), indexFullMask); | ||
| 216 | - Add(indexReg5, indexReg3, indexReg4, indexFullMask); | ||
| 217 | - | ||
| 218 | - // the other half vl index | ||
| 219 | - Arange((MicroAPI::RegTensor<X, Trait> &)indexReg6, static_cast<X>(halfVlSize)); | ||
| 220 | - Div(indexReg7, indexReg6, indexReg1, indexFullMask); | ||
| 221 | - Muls(indexReg8, indexReg7, static_cast<U>(srcStride1), indexFullMask); | ||
| 222 | - // k%c: k - k/c*c | ||
| 223 | - Mul(indexReg9, indexReg7, indexReg1, indexFullMask); | ||
| 224 | - Sub(indexReg9, indexReg6, indexReg9, indexFullMask); | ||
| 225 | - Muls(indexReg9, indexReg9, static_cast<U>(srcStride2), indexFullMask); | ||
| 226 | - Add(indexReg10, indexReg8, indexReg9, indexFullMask); | ||
| 227 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop0); i++) { | ||
| 228 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)(i * forLoop1 * forLoop2 * dtypeSize); | ||
| 229 | - for (uint16_t j = 0; j < static_cast<uint16_t>(mainLoop); j++) { | ||
| 230 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg0, | ||
| 231 | - srcAddr + i * srcStride0 + j * srcStride1 * factor, indexReg5, mainMask0); | ||
| 232 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg1, | ||
| 233 | - srcAddr + i * srcStride0 + j * srcStride1 * factor, indexReg10, mainMask1); | ||
| 234 | - DeInterleave(vreg2, vreg3, vreg0, vreg1); | ||
| 235 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), vreg2, ureg0, mainSize); | ||
| 236 | - } | ||
| 237 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 238 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg0, | ||
| 239 | - srcAddr + i * srcStride0 + mainLoop * srcStride1 * factor, indexReg5, tailMask0); | ||
| 240 | - DataCopyGather((MicroAPI::RegTensor<U, Trait> &)vreg1, | ||
| 241 | - srcAddr + i * srcStride0 + mainLoop * srcStride1 * factor, indexReg10, tailMask1); | ||
| 242 | - DeInterleave(vreg2, vreg3, vreg0, vreg1); | ||
| 243 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), vreg2, ureg0, tail); | ||
| 244 | - } | ||
| 245 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ T *&)hoistDstAddr), ureg0, 0); | ||
| 246 | - } | ||
| 247 | -} | ||
| 248 | - | ||
| 249 | -template <typename T, typename X, typename U, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 250 | -__aicore__ inline void ConfusionTransposeComplexGatherB8(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 251 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t srcStride2) | ||
| 252 | -{ | ||
| 253 | - uint32_t factor = vlSize / forLoop2; | ||
| 254 | - uint32_t mainSize = factor * forLoop2; | ||
| 255 | - uint16_t mainLoop = forLoop1 / factor; | ||
| 256 | - uint32_t tail = forLoop1 % factor * forLoop2; | ||
| 257 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 258 | - uint32_t mainCount = mainSize; | ||
| 259 | - uint32_t tailCount = tail; | ||
| 260 | - uint32_t dtypeSize = sizeof(T); | ||
| 261 | - uint32_t halfVlSize = vlSize / 2; | ||
| 262 | - | ||
| 263 | - ConfusionTransposeComplexGatherB8VF<T, X, U, Trait, vlSize>(dstAddr, srcAddr, forLoop0, forLoop1, forLoop2, | ||
| 264 | - srcStride0, srcStride1, srcStride2, factor, mainSize, mainLoop, tail, tailLoop, mainCount, tailCount, | ||
| 265 | - dtypeSize, halfVlSize); | ||
| 266 | -} | ||
| 267 | - | ||
| 268 | -template <typename T, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 269 | -__simd_vf__ inline void ConfusionTransposeCopySrcToDst(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t totalCount) | ||
| 270 | -{ | ||
| 271 | - uint32_t count = totalCount; | ||
| 272 | - uint32_t forLoop = (totalCount + vlSize - 1) / vlSize; | ||
| 273 | - MicroAPI::RegTensor<T, Trait> vreg0; | ||
| 274 | - MicroAPI::MaskReg mainMask; | ||
| 275 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop); i++) { | ||
| 276 | - mainMask = MicroAPI::UpdateMask<T, Trait>(count); | ||
| 277 | - DataCopy(vreg0, srcAddr + i * vlSize); | ||
| 278 | - DataCopy(dstAddr + i * vlSize, vreg0, mainMask); | ||
| 279 | - } | ||
| 280 | -} | ||
| 281 | - | ||
| 282 | -template <typename T, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 283 | -__simd_vf__ inline void ConfusionTransposeCommonDataCopyVF(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 284 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1, uint32_t tail, uint32_t count, | ||
| 285 | - uint16_t mainLoop, uint32_t dtypeSize, uint32_t tailLoop) | ||
| 286 | -{ | ||
| 287 | - MicroAPI::RegTensor<T, Trait> MainVreg; | ||
| 288 | - MicroAPI::UnalignReg DstUreg; | ||
| 289 | - MicroAPI::UnalignReg SrcUreg; | ||
| 290 | - for (uint16_t i = 0; i < static_cast<uint16_t>(forLoop0); i++) { | ||
| 291 | - for (uint16_t j = 0; j < static_cast<uint16_t>(forLoop1); j++) { | ||
| 292 | - uint64_t hoistSrcAddr = (uint64_t)srcAddr + (uint64_t)((i * srcStride0 + j * srcStride1) * dtypeSize); | ||
| 293 | - uint64_t hoistDstAddr = (uint64_t)dstAddr + (uint64_t)((i * forLoop1 + j) * forLoop2 * dtypeSize); | ||
| 294 | - for (uint16_t k = 0; k < static_cast<uint16_t>(mainLoop); k++) { | ||
| 295 | - MicroAPI::DataCopyUnAlignPre(SrcUreg, ((__ubuf__ T *&)hoistSrcAddr)); | ||
| 296 | - MicroAPI::DataCopyUnAlign(MainVreg, SrcUreg, ((__ubuf__ T *&)hoistSrcAddr), vlSize); | ||
| 297 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, DstUreg, vlSize); | ||
| 298 | - } | ||
| 299 | - for (uint16_t k = 0; k < static_cast<uint16_t>(tailLoop); k++) { | ||
| 300 | - MicroAPI::DataCopyUnAlignPre(SrcUreg, ((__ubuf__ T *&)hoistSrcAddr)); | ||
| 301 | - MicroAPI::DataCopyUnAlign(MainVreg, SrcUreg, ((__ubuf__ T *&)hoistSrcAddr), tail); | ||
| 302 | - MicroAPI::DataCopyUnAlign(((__ubuf__ T *&)hoistDstAddr), MainVreg, DstUreg, tail); | ||
| 303 | - } | ||
| 304 | - MicroAPI::DataCopyUnAlignPost(((__ubuf__ T *&)hoistDstAddr), DstUreg, 0); | ||
| 305 | - } | ||
| 306 | - } | ||
| 307 | -} | ||
| 308 | - | ||
| 309 | -template <typename T, const MicroAPI::RegTrait &Trait, const uint16_t vlSize> | ||
| 310 | -__aicore__ inline void ConfusionTransposeCommonDataCopy(__ubuf__ T *dstAddr, __ubuf__ T *srcAddr, uint32_t forLoop0, | ||
| 311 | - uint32_t forLoop1, uint32_t forLoop2, uint32_t srcStride0, uint32_t srcStride1) | ||
| 312 | -{ | ||
| 313 | - uint32_t tail = forLoop2 % vlSize; | ||
| 314 | - uint32_t count = tail; | ||
| 315 | - uint16_t mainLoop = forLoop2 / vlSize; | ||
| 316 | - uint32_t dtypeSize = sizeof(T); | ||
| 317 | - uint32_t tailLoop = tail > 0 ? 1 : 0; | ||
| 318 | - ConfusionTransposeCommonDataCopyVF<T, Trait, vlSize>(dstAddr, srcAddr, forLoop0, | ||
| 319 | - forLoop1, forLoop2, srcStride0, srcStride1, tail, count, mainLoop, dtypeSize, tailLoop); | ||
| 320 | -} | ||
| 321 | - | ||
| 322 | -/* | ||
| 323 | -scene 13:{ shape:[H, W], format:"ND"} -->{ shape:[W, H], format:"ND"}; | ||
| 324 | - { shape:[N, H, W], format:"ND"} -->{ shape:[N, W, H], format:"ND"}; | ||
| 325 | -*/ | ||
| 326 | -template <typename T> | ||
| 327 | -__aicore__ inline void ConfusionTranspose021( | ||
| 328 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, ConfusionTranspose021Tiling& tiling) | ||
| 329 | -{ | ||
| 330 | - constexpr uint16_t vlSize = | ||
| 331 | - IsSameType<T, int64_t>::value ? GetVecLen() / sizeof(float) : GetVecLen() / sizeof(T); | ||
| 332 | - if ((tiling.dim1 == 1) || (tiling.dim2 == 1)) { | ||
| 333 | - uint32_t totalCount = tiling.dim0 * tiling.dim1 * tiling.dim2; | ||
| 334 | - ConfusionTransposeCopySrcToDst<T, MicroAPI::RegTraitNumOne, vlSize>((__ubuf__ T *)dstTensor.GetPhyAddr(), | ||
| 335 | - (__ubuf__ T *)srcTensor.GetPhyAddr(), totalCount); | ||
| 336 | - } else { | ||
| 337 | - uint32_t srcStride0 = tiling.dim1 * tiling.dim2; | ||
| 338 | - uint32_t srcStride1 = 1; | ||
| 339 | - uint32_t srcStride2 = tiling.dim2; | ||
| 340 | - if (tiling.dim1 > vlSize / 2) { | ||
| 341 | - if constexpr (SupportBytes<T, 4>()) { | ||
| 342 | - ConfusionTransposeCommonGather<T, int32_t, uint32_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 343 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 344 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 345 | - } else if constexpr (SupportBytes<T, 2>()) { | ||
| 346 | - ConfusionTransposeCommonGather<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 347 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 348 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 349 | - } else if constexpr (SupportBytes<T, 1>()) { | ||
| 350 | - ConfusionTransposeCommonGatherB8<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 351 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 352 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 353 | - } | ||
| 354 | - } else { | ||
| 355 | - if constexpr (SupportBytes<T, 4>()) { | ||
| 356 | - ConfusionTransposeComplexGather<T, int32_t, uint32_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 357 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 358 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 359 | - } else if constexpr (SupportBytes<T, 2>()) { | ||
| 360 | - ConfusionTransposeComplexGather<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 361 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 362 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 363 | - } else if constexpr (SupportBytes<T, 1>()) { | ||
| 364 | - ConfusionTransposeComplexGatherB8<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 365 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim0, | ||
| 366 | - tiling.dim2, tiling.dim1, srcStride0, srcStride1, srcStride2); | ||
| 367 | - } | ||
| 368 | - } | ||
| 369 | - } | ||
| 370 | -} | ||
| 371 | - | ||
| 372 | -/* | ||
| 373 | -scene 14: { shape:[N, H, W], format:"ND"} -->{ shape:[H, N, W], format:"ND"}; | ||
| 374 | -*/ | ||
| 375 | -template <typename T> | ||
| 376 | -__aicore__ inline void ConfusionTranspose102( | ||
| 377 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, ConfusionTranspose102Tiling& tiling) | ||
| 378 | -{ | ||
| 379 | - constexpr uint16_t vlSize = | ||
| 380 | - IsSameType<T, int64_t>::value ? GetVecLen() / sizeof(float) : GetVecLen() / sizeof(T); | ||
| 381 | - if ((tiling.dim0 == 1) || (tiling.dim1 == 1)) { | ||
| 382 | - uint32_t totalCount = tiling.dim0 * tiling.dim1 * tiling.dim2; | ||
| 383 | - ConfusionTransposeCopySrcToDst<T, MicroAPI::RegTraitNumOne, vlSize>((__ubuf__ T *)dstTensor.GetPhyAddr(), | ||
| 384 | - (__ubuf__ T *)srcTensor.GetPhyAddr(), totalCount); | ||
| 385 | - } else { | ||
| 386 | - uint32_t srcStride0 = tiling.dim2; | ||
| 387 | - uint32_t srcStride1 = tiling.dim1 * tiling.dim2; | ||
| 388 | - uint32_t srcStride2 = 1; | ||
| 389 | - if (tiling.dim2 > vlSize / 2) { | ||
| 390 | - ConfusionTransposeCommonDataCopy<T, MicroAPI::RegTraitNumOne, vlSize>((__ubuf__ T *)dstTensor.GetPhyAddr(), | ||
| 391 | - (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim1, tiling.dim0, tiling.dim2, srcStride0, srcStride1); | ||
| 392 | - } else { | ||
| 393 | - if constexpr (SupportBytes<T, 4>()) { | ||
| 394 | - ConfusionTransposeComplexGather<T, int32_t, uint32_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 395 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim1, | ||
| 396 | - tiling.dim0, tiling.dim2, srcStride0, srcStride1, srcStride2); | ||
| 397 | - } else if constexpr (SupportBytes<T, 2>()) { | ||
| 398 | - ConfusionTransposeComplexGather<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 399 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim1, | ||
| 400 | - tiling.dim0, tiling.dim2, srcStride0, srcStride1, srcStride2); | ||
| 401 | - } else if constexpr (SupportBytes<T, 1>()) { | ||
| 402 | - ConfusionTransposeComplexGatherB8<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 403 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim1, | ||
| 404 | - tiling.dim0, tiling.dim2, srcStride0, srcStride1, srcStride2); | ||
| 405 | - } | ||
| 406 | - } | ||
| 407 | - } | ||
| 408 | -} | ||
| 409 | - | ||
| 410 | -/* | ||
| 411 | -scene 15: { shape:[N, H, W], format:"ND"} -->{ shape:[W, H, N], format:"ND"}; | ||
| 412 | -*/ | ||
| 413 | -template <typename T> | ||
| 414 | -__aicore__ inline void ConfusionTranspose210( | ||
| 415 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, ConfusionTranspose210Tiling& tiling) | ||
| 416 | -{ | ||
| 417 | - constexpr uint16_t vlSize = | ||
| 418 | - IsSameType<T, int64_t>::value ? GetVecLen() / sizeof(float) : GetVecLen() / sizeof(T); | ||
| 419 | - ConfusionTranspose021Tiling tiling021 = { 1, tiling.dim1, tiling.dim2 }; | ||
| 420 | - if (tiling.dim0 == 1 || tiling.dim1 == 1 || tiling.dim2 == 1) { | ||
| 421 | - ConfusionTranspose021Tiling tiling021 = { 1, tiling.dim1, tiling.dim2 }; | ||
| 422 | - if (tiling.dim1 == 1) { | ||
| 423 | - tiling021.dim1 = tiling.dim0; | ||
| 424 | - } else if (tiling.dim2 == 1) { | ||
| 425 | - tiling021.dim1 = tiling.dim0; | ||
| 426 | - tiling021.dim2 = tiling.dim1; | ||
| 427 | - } | ||
| 428 | - ConfusionTranspose021(dstTensor, srcTensor, tiling021); | ||
| 429 | - } else { | ||
| 430 | - uint32_t srcStride0 = 1; | ||
| 431 | - uint32_t srcStride1 = tiling.dim2; | ||
| 432 | - uint32_t srcStride2 = tiling.dim1 * tiling.dim2; | ||
| 433 | - if (tiling.dim0 > vlSize / 2) { | ||
| 434 | - if constexpr (SupportBytes<T, 4>()) { | ||
| 435 | - ConfusionTransposeCommonGather<T, int32_t, uint32_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 436 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 437 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 438 | - } else if constexpr (SupportBytes<T, 2>()) { | ||
| 439 | - ConfusionTransposeCommonGather<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 440 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 441 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 442 | - } else if constexpr (SupportBytes<T, 1>()) { | ||
| 443 | - ConfusionTransposeCommonGatherB8<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 444 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 445 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 446 | - } | ||
| 447 | - } else { | ||
| 448 | - if constexpr (SupportBytes<T, 4>()) { | ||
| 449 | - ConfusionTransposeComplexGather<T, int32_t, uint32_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 450 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 451 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 452 | - } else if constexpr (SupportBytes<T, 2>()) { | ||
| 453 | - ConfusionTransposeComplexGather<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 454 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 455 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 456 | - } else if constexpr (SupportBytes<T, 1>()) { | ||
| 457 | - ConfusionTransposeComplexGatherB8<T, int16_t, uint16_t, MicroAPI::RegTraitNumOne, vlSize>( | ||
| 458 | - (__ubuf__ T *)dstTensor.GetPhyAddr(), (__ubuf__ T *)srcTensor.GetPhyAddr(), tiling.dim2, | ||
| 459 | - tiling.dim1, tiling.dim0, srcStride0, srcStride1, srcStride2); | ||
| 460 | - } | ||
| 461 | - } | ||
| 462 | - } | ||
| 463 | -} | ||
| 464 | - | ||
| 465 | -template <typename T> | ||
| 466 | -__aicore__ inline void ConfusionTransposeND2NZWithInlv( | ||
| 467 | - const LocalTensor<T>& dstTensor, const LocalTensor<T>& srcTensor, ConfusionTranspose210Tiling& tiling) | ||
| 468 | -{ | ||
| 469 | - ConfusionTransposeND2NZWithInlvImpl((__ubuf__ T*) dstTensor.GetPhyAddr(), (__ubuf__ T*) srcTensor.GetPhyAddr(), tiling); | ||
| 470 | -} | ||
| 471 | - | ||
| 472 | -template <typename T> | ||
| 473 | -__simd_vf__ inline void ConfusionTransposeND2NZWithInlvVFImpl(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, uint32_t regWidth, | ||
| 474 | - uint32_t c0Size, uint32_t factor, uint32_t height, uint32_t width, uint32_t tailWidth, uint16_t repeatTimes) | ||
| 475 | -{ | ||
| 476 | - AscendC::MicroAPI::RegTensor<T> vSrcReg0; | ||
| 477 | - AscendC::MicroAPI::RegTensor<T> vSrcReg1; | ||
| 478 | - AscendC::MicroAPI::RegTensor<T> vDstReg0; | ||
| 479 | - AscendC::MicroAPI::RegTensor<T> vDstReg1; | ||
| 480 | - AscendC::MicroAPI::MaskReg mask = AscendC::MicroAPI::CreateMask<T, MicroAPI::MaskPattern::ALL>(); | ||
| 481 | - uint32_t srcOffset = 0; | ||
| 482 | - uint32_t dstOffset = 0; | ||
| 483 | - const uint16_t heightLoopNum = height / factor; | ||
| 484 | - for (uint16_t i = 0; i < repeatTimes; i++) { | ||
| 485 | - srcOffset = i * regWidth; | ||
| 486 | - dstOffset = i * regWidth * heightLoopNum * factor; | ||
| 487 | - for (uint16_t j = 0; j < heightLoopNum; j++) { | ||
| 488 | - uint64_t rowStrideAddr = uint64_t(srcAddr + srcOffset + factor * j * width); | ||
| 489 | - uint64_t nerborStrideAddr = uint64_t(srcAddr + srcOffset + (factor * j + 1) * width); | ||
| 490 | - | ||
| 491 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 492 | - vSrcReg0, (__ubuf__ T*&)rowStrideAddr, 1, 0, mask); | ||
| 493 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 494 | - vSrcReg1, (__ubuf__ T*&)nerborStrideAddr, 1, 0, mask); | ||
| 495 | - AscendC::MicroAPI::Interleave<T>(vDstReg0, vDstReg1, vSrcReg0, vSrcReg1); | ||
| 496 | - | ||
| 497 | - uint64_t dstRowStrideAddr = uint64_t(dstAddr + dstOffset + j * c0Size); | ||
| 498 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 499 | - (__ubuf__ T*&)dstRowStrideAddr, vDstReg0, heightLoopNum, 0, mask); | ||
| 500 | - | ||
| 501 | - uint64_t dstNerborStrideAddr = uint64_t(dstAddr + dstOffset + regWidth * heightLoopNum + j * c0Size); | ||
| 502 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 503 | - (__ubuf__ T*&)dstNerborStrideAddr, vDstReg1, heightLoopNum, 0, mask); | ||
| 504 | - } | ||
| 505 | - } | ||
| 506 | - | ||
| 507 | - if (tailWidth) { | ||
| 508 | - if (repeatTimes != 0) { | ||
| 509 | - srcOffset += regWidth; | ||
| 510 | - dstOffset += regWidth * heightLoopNum * factor; | ||
| 511 | - } | ||
| 512 | - const uint32_t regWidthHalf = 128; | ||
| 513 | - for (uint16_t j = 0; j < heightLoopNum; j++) { | ||
| 514 | - uint64_t rowStrideAddr = uint64_t(srcAddr + srcOffset + factor * j * width); | ||
| 515 | - uint64_t nerborStrideAddr = uint64_t(srcAddr + srcOffset + (factor * j + 1) * width); | ||
| 516 | - uint32_t mask_size = tailWidth * factor; | ||
| 517 | - if (tailWidth > regWidthHalf) { | ||
| 518 | - mask_size = regWidth; | ||
| 519 | - } | ||
| 520 | - AscendC::MicroAPI::MaskReg mask = AscendC::MicroAPI::UpdateMask<T>(mask_size); | ||
| 521 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 522 | - vSrcReg0, (__ubuf__ T*&)rowStrideAddr, 1, 0, mask); | ||
| 523 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 524 | - vSrcReg1, (__ubuf__ T*&)nerborStrideAddr, 1, 0, mask); | ||
| 525 | - AscendC::MicroAPI::Interleave<T>(vDstReg0, vDstReg1, vSrcReg0, vSrcReg1); | ||
| 526 | - | ||
| 527 | - uint64_t dstRowStrideAddr = uint64_t(dstAddr + dstOffset + j * c0Size); | ||
| 528 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 529 | - (__ubuf__ T*&)dstRowStrideAddr, vDstReg0, heightLoopNum, 0, mask); | ||
| 530 | - | ||
| 531 | - if (tailWidth > regWidthHalf) { | ||
| 532 | - mask_size = tailWidth * factor - regWidth; | ||
| 533 | - AscendC::MicroAPI::MaskReg mask1 = AscendC::MicroAPI::UpdateMask<T>(mask_size); | ||
| 534 | - uint64_t dstNerborStrideAddr = uint64_t(dstAddr + dstOffset + regWidth * heightLoopNum + j * c0Size); | ||
| 535 | - AscendC::MicroAPI::DataCopy<T, MicroAPI::DataCopyMode::DATA_BLOCK_COPY, MicroAPI::PostLiteral::POST_MODE_NORMAL>( | ||
| 536 | - (__ubuf__ T*&)dstNerborStrideAddr, vDstReg1, heightLoopNum, 0, mask1); | ||
| 537 | - } | ||
| 538 | - } | ||
| 539 | - } | ||
| 540 | -} | ||
| 541 | - | ||
| 542 | -template <typename T> | ||
| 543 | -__aicore__ inline void ConfusionTransposeND2NZWithInlvImpl(__ubuf__ T* dstAddr, __ubuf__ T* srcAddr, ConfusionTranspose210Tiling& tiling) | ||
| 544 | -{ | ||
| 545 | - constexpr uint32_t regWidth = 256; // vf reg length | ||
| 546 | - constexpr uint32_t c0Size = 32; // factal size | ||
| 547 | - constexpr uint32_t factor = 2; // row factor | ||
| 548 | - uint32_t height = tiling.dim1; | ||
| 549 | - uint32_t width = tiling.dim2; | ||
| 550 | - uint32_t tailWidth = width % regWidth; | ||
| 551 | - uint16_t repeatTimes = width / regWidth; | ||
| 552 | - ConfusionTransposeND2NZWithInlvVFImpl<T>(dstAddr, srcAddr, regWidth, c0Size, factor, height, width, tailWidth, repeatTimes); | ||
| 553 | -} | ||
| 554 | -} // namespace AscendC | ||
| 555 | - | ||
| @@ -174,6 +174,7 @@ __aicore__ constexpr inline float Cast(const T& bVal) | |||
| 174 | return 0.0f; | 174 | return 0.0f; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | +template <typename T> | ||
| 177 | __aicore__ constexpr inline float ToFloat(const T& bVal) | 178 | __aicore__ constexpr inline float ToFloat(const T& bVal) |
| 178 | { | 179 | { |
| 179 | ASCENDC_ASSERT((false), { KERNEL_LOG(KERNEL_ERROR, "unsupport ToFloat"); }); | 180 | ASCENDC_ASSERT((false), { KERNEL_LOG(KERNEL_ERROR, "unsupport ToFloat"); }); |