昇腾AI原生创新算子挑战赛(S1赛季)复盘- FastGelu算子

  • 正文前感谢昇腾各位工作人员,没有你们的辛勤就没有我们的进步
  • 本文立意交流大赛FastGelu算子编译过程
  • FastGelu算子千万别被公式吓到,其实很简单,应该说中规中矩,是道送分题
    • 算子要求fp16,fp32 ,计算类型符合所有的API公式限制,也就是说不需要类型转换
    • 只有一个输入,一个输出,并不需要大幅度的数据搬迁
    • 唯一需要解决的就是compute的算法设计

cke_13457.png

  • 不过有一点可能是计算的精度限制,在mindspore中有提供一个案例如下,提供了结果

cke_23967.png

  • 通过手搓一段np代码,如下并运行
  • 发现答案有一定的精度误差,可能是mindspore的精度误差,这里也没细追究
input_x = np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]).astype(former)
y = (input_x*np.exp(0.851*(input_x-np.abs(input_x)))/(1+ np.exp(-1.702*np.abs(input_x)))).astype(former_out)

# [[-1.5420423e-01  3.9955850e+00 -9.7664270e-06]
# [ 1.9356586e+00 -1.0070159e-03  8.9999981e+00]] y复制

  • 当然官方测试案例的计算公式也做了测试,结果一致,仍有精度误差
  • 这里不做细追究,有知晓原因的老师还望告知
input_x = np.array([[-1.0, 4.0, -8.0], [2.0, -5.0, 9.0]]).astype(former)

attr = 1.702
attr_opp = 0 - attr
attr_half = attr / 2
abs_x = np.abs(input_x)
mul_abs_x = abs_x * attr_opp
exp_abs_x = np.exp(mul_abs_x)
div_down = exp_abs_x + 1.0

pn_x = input_x - abs_x
mul_pn_x = pn_x * attr_half
exp_pn_x = np.exp(mul_pn_x)
div_up = input_x * exp_pn_x
y = div_up / div_down

[[-1.5420423e-01  3.9955850e+00 -9.7664270e-06]
 [ 1.9356586e+00 -1.0070159e-03  8.9999981e+00]] y
复制

  • compute代码用到了API比较多,但是也不难,只需要查好文档即可
  __aicore__ inline void Compute(int32_t progress) {
    LocalTensor<DTYPE_X> inLocal = inQueueIN.DeQue<DTYPE_X>();
    LocalTensor<DTYPE_X> xLocal = inLocal;
    LocalTensor<DTYPE_Y> outLocal = outQueueOUT.AllocTensor<DTYPE_Y>();
    LocalTensor<DTYPE_Y> tempTensor1 = calcBuf.Get<DTYPE_Y>();

    // y = (input_x*np.exp(0.851*(input_x-np.abs(input_x)))/(1+ np.exp(-1.702*np.abs(input_x)))).astype(former_out)
    Abs(outLocal, xLocal, this->tileLength);
    Sub(outLocal, xLocal, outLocal, this->tileLength);
    Muls(outLocal, outLocal, (DTYPE_Y)0.851, this->tileLength);
    Exp(outLocal, outLocal, this->tileLength);
    Mul(outLocal, outLocal, xLocal, this->tileLength);

    Abs(tempTensor1, xLocal, this->tileLength);
    Muls(tempTensor1, tempTensor1, (DTYPE_Y)(-1.702), this->tileLength);
    Exp(tempTensor1, tempTensor1, this->tileLength);
    Adds(tempTensor1, tempTensor1, (DTYPE_Y)(1), this->tileLength);
    Div(outLocal, outLocal, tempTensor1, this->tileLength);
    outQueueOUT.EnQue<DTYPE_Y>(outLocal);

    inQueueIN.FreeTensor(inLocal);
  }复制

  • 下面粘贴5个测试案例的测试结果
  • 第一个测试案例

cke_109661.png

  • 第二个测试案例

cke_123697.png

  • 第三个测试案例

cke_131550.png

  • 第四个测试案例

cke_144483.png

  • 第五个测试案例

cke_154570.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值