昇腾AI原生创新算子挑战赛(S1赛季)复盘-ScatterMax算子
收藏回复举报
昇腾AI原生创新算子挑战赛(S1赛季)复盘-ScatterMax算子
发表于2024-05-25 09:32:34
0 查看
  • 正文前感谢昇腾各位工作人员,没有你们的辛勤就没有我们的进步
  • 本文立意交流大赛ScatterMax算子编译过程
  • 这道题难点在于
    • 如何划分tiling,是以哪个输入变量shape作为划分的标准,从而获得相对应tileLength
    • 如何设计copy_in来满足对var数据的sub操作,是否需要对var数据进行读入
    • 跟ScatterSub 理念几乎一致,具体看ScatterSub详解即可
    • 注意题目里面没有Int8类型,但是测试案例4里有这个类型,所以还是要加上int8

  • 参考了0xcccccccc大神的代码,只能用一个字来形容,妙呀,短小精悍
    • 对原子操作SetAtomicAdd有独到见解
    • 对copy_in数据流设计不需要引入var,并修改var,通过datacopy将updates数据施加原子加法操作,导入Indices指定位置
  • 参考了blankcat代码
    • 比较喜欢DataCopyPadCustom_GM2UB,DataCopyPadCustom_UB2GM 两个API构建
    • gen_data.py的设计

  • gen_data.py修改为max算法
  • 使用torch.max算法描述
def gen_golden_data_simple2():
    dtype = torch.int8
    
    if(is_float_dto(dtype)):
        var = torch.randn(64* 64).reshape(64, 64).to(dtype)*20-10
        indices = torch.randint(0, 200, (5,)).to(torch.int64)
        updates = torch.randn(5*64).reshape(5, 64).to(dtype)*20-10
    else:
        var = torch.randint(-10, 10, (3, 41, 52, 63)).to(dtype)
        indices = torch.randint(0, 3, (3,)).to(torch.int64)
        updates = torch.randint(-10, 10, (3, 41, 52, 63)).to(dtype)
    golden = var.clone()
    for i in range(indices.size(0)):
        index = indices[i]
        golden[index]  = torch.max(golden[index],updates[i])

  • 将多余padding部分用最小值来顶替,进而实现max算法,抗数据干扰
__aicore__ inline void CopyIn(int32_t indices, int32_t j,int32_t progress) {
    LocalTensor<DTYPE_UPDATES> updatesLocal = inQueueUpdates.AllocTensor<DTYPE_UPDATES>();
  
    if (progress == this->tileNum - 1) {
      if (progress == 0) {       
        DataCopyPadCustom_GM2UB(updatesLocal,updatesGm[j * this->lastdim],this->dimLength);
        for(int i = this->dimLength; i < this->tileLength; i++)
        {
          // updatesLocal(i) = static_cast<DTYPE_UPDATES>(0);   
            if constexpr (std::is_same_v<DTYPE_UPDATES, half> || std::is_same_v<DTYPE_UPDATES, float>) {
                updatesLocal(i) = -3.40282346638528859811704183484516925e+38F;
            }
            if constexpr (std::is_same_v<DTYPE_UPDATES, int32_t>) {
                updatesLocal(i) = -2147483647-1;
            }
            if constexpr (std::is_same_v<DTYPE_UPDATES, int8_t>) {
                updatesLocal(i) =  -128;
            }
        }
      } else {
        DataCopy(updatesLocal[0], updatesGm[j * this->lastdim + (progress - 1) * this->tileLength + this->lasttileLength], this->tileLength);    
      }
    } else {
      DataCopy(updatesLocal[0], updatesGm[j * this->lastdim + progress * this->tileLength], this->tileLength);         
    }
    
    inQueueUpdates.EnQue(updatesLocal);

  }

  • 第一个测试案例

cke_111885.png

  • 第二个测试案例

cke_124212.png

  • 第三个测试案例

cke_135064.png

  • 第四个测试案例

cke_147162.png

  • 第五个测试案例

cke_162347.png

我要发帖子