昇腾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算法描述
- 将多余padding部分用最小值来顶替,进而实现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])__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); }