Gelu
产品支持情况
功能说明
在神经网络中,GELU是一个重要的激活函数,其灵感来源于Relu和Dropout,在激活中引入了随机正则的思想。计算公式如下:

,化简后可得
函数原型
-
接口框架申请临时空间
template <typename T, bool highPrecision = false, bool highPerformance = false> __aicore__ inline void Gelu(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, const uint32_t dataSize) -
通过sharedTmpBuffer入参传入临时空间
template <typename T, bool highPrecision = false, bool highPerformance = false> __aicore__ inline void Gelu(const LocalTensor<T>& dstLocal, const LocalTensor<T>& srcLocal, const LocalTensor<uint8_t>& sharedTmpBuffer, const uint32_t dataSize)
参数说明
表 1 模板参数说明
表 2 接口参数说明
|
类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
|
类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 |
||
|
类型为LocalTensor,支持的TPosition为VECIN/VECCALC/VECOUT。 临时空间大小BufferSize的获取方式请参考GetGeluMaxMinTmpSize。 |
||
返回值说明
无
约束说明
- 源操作数和目的操作数的Tensor空间可以复用。
- 不支持sharedTmpBuffer与源操作数和目的操作数地址重叠。
- 操作数地址对齐要求请参见通用地址对齐约束。
- 仅支持输入shape为ND格式。
调用示例
#include "kernel_operator.h"
template <typename srcType>
class KernelGelu
{
public:
__aicore__ inline KernelGelu() {}
__aicore__ inline void Init(GM_ADDR src_gm, GM_ADDR dst_gm, uint32_t inputSize)
{
dataSize = inputSize;
src_global.SetGlobalBuffer(reinterpret_cast<__gm__ srcType *>(src_gm), dataSize);
dst_global.SetGlobalBuffer(reinterpret_cast<__gm__ srcType *>(dst_gm), dataSize);
pipe.InitBuffer(inQueueX, 1, dataSize * sizeof(srcType));
pipe.InitBuffer(outQueue, 1, dataSize * sizeof(srcType));
}
__aicore__ inline void Process()
{
CopyIn();
Compute();
CopyOut();
}
private:
__aicore__ inline void CopyIn()
{
AscendC::LocalTensor<srcType> srcLocal = inQueueX.AllocTensor<srcType>();
AscendC::DataCopy(srcLocal, src_global, dataSize);
inQueueX.EnQue(srcLocal);
}
__aicore__ inline void Compute()
{
AscendC::LocalTensor<srcType> dstLocal = outQueue.AllocTensor<srcType>();
AscendC::LocalTensor<srcType> srcLocal = inQueueX.DeQue<srcType>();
AscendC::Gelu(dstLocal, srcLocal, dataSize);
// AscendC::Gelu<srcType, true, false>(dstLocal, srcLocal, dataSize);
// AscendC::Gelu<srcType, false, true>(dstLocal, srcLocal, dataSize);
outQueue.EnQue<srcType>(dstLocal);
inQueueX.FreeTensor(srcLocal);
}
__aicore__ inline void CopyOut()
{
AscendC::LocalTensor<srcType> dstLocal = outQueue.DeQue<srcType>();
AscendC::DataCopy(dst_global, dstLocal, dataSize);
outQueue.FreeTensor(dstLocal);
}
private:
AscendC::GlobalTensor<srcType> src_global;
AscendC::GlobalTensor<srcType> dst_global;
AscendC::TPipe pipe;
AscendC::TQue<AscendC::TPosition::VECIN, 1> inQueueX;
AscendC::TQue<AscendC::TPosition::VECOUT, 1> outQueue;
uint32_t dataSize = 0;
};
template <typename dataType>
__aicore__ void kernel_Gelu_operator(GM_ADDR src_gm, GM_ADDR dst_gm, uint32_t dataSize)
{
KernelGelu<dataType> op;
op.Init(src_gm, dst_gm, dataSize);
op.Process();
}
结果示例如下:
输入数据(srcLocal):
[-1.251 1.074 -6.137 -9.67 -5.066 -9.44 -3.588 -5.758 -7.484
-5.35 -9.62 -4.33 -6.66 -3.732 0.0841 -8.59 -6.3 -4.62
-3.059 -8.34 -8.24 -7.617 -7.93 -3.592 -3.268 -5.406 -9.49
5.633 -5.3 -9.36 -6.715 -5.727 ]
输出数据(dstLocal):
[-0.1411 0.916 -0. -0. -0. -0. -0. -0. -0.
-0. -0. -0. -0. -0. 0.0486 -0. -0. -0.
-0. -0. -0. -0. -0. -0. -0. -0. -0.
5.633 -0. -0. -0. -0. ]