已合并
segment_sum算子支持simd确定性计算以及性能优化 #1831
z30075199创建于 2月11日
segment_sum算子支持simd确定性计算以及性能优化 #1831
已合并
共 15 个文件变更+899-93
| @@ -203,7 +203,7 @@ static aclnnStatus CheckParams(const aclTensor *self, int64_t dim, const aclTens | |||
| 203 | 203 | ||
| 204 | auto indexSize = 1; | 204 | auto indexSize = 1; |
| 205 | auto indexDimNum = index->GetViewShape().GetDimNum(); | 205 | auto indexDimNum = index->GetViewShape().GetDimNum(); |
| 206 | - for (int i = 0; i < indexDimNum ; i++) { | 206 | + for (int i = 0; i < static_cast<int>(indexDimNum) ; i++) { |
| 207 | indexSize *= index->GetViewShape().GetDim(i); | 207 | indexSize *= index->GetViewShape().GetDim(i); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| @@ -51,8 +51,8 @@ static std::string OtherErrMsg(const std::string& error_detail) { | |||
| 51 | return msg; | 51 | return msg; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | -static bool CheckAndUpdateAxis(gert::InferShapeContext* context, int64_t& batch_dims, int64_t& axes_data, | 54 | +static bool CheckAndUpdateAxis(const gert::InferShapeContext* context, int64_t& batch_dims, int64_t& axes_data, |
| 55 | - GatherInfo& gather_info) { | 55 | + const GatherInfo& gather_info) { |
| 56 | int64_t x_real_dim_cnt = gather_info.x_real_dim_cnt; | 56 | int64_t x_real_dim_cnt = gather_info.x_real_dim_cnt; |
| 57 | int64_t index_batch_dims = gather_info.index_batch_dims; | 57 | int64_t index_batch_dims = gather_info.index_batch_dims; |
| 58 | int64_t rank_indices = gather_info.rank_indices; | 58 | int64_t rank_indices = gather_info.rank_indices; |
| @@ -158,7 +158,7 @@ __aicore__ inline INDICES_T Gatherv2Simd<INDICES_T>::GetIndex(int64_t idx, int64 | |||
| 158 | copyLen = startBIdx + maxBSize > endBIdx ? (endBIdx - startBIdx + 1) * gatherSize_ : maxBSize * gatherSize_; | 158 | copyLen = startBIdx + maxBSize > endBIdx ? (endBIdx - startBIdx + 1) * gatherSize_ : maxBSize * gatherSize_; |
| 159 | indicesOffsetBase_ = startBIdx * gatherSize_; | 159 | indicesOffsetBase_ = startBIdx * gatherSize_; |
| 160 | } else { | 160 | } else { |
| 161 | - copyLen = startGIdx + maxIndex_ >= gatherSize_ ? (endBIdx + 1) * gatherSize_ - idx: maxIndex_; | 161 | + copyLen = startGIdx + maxIndex_ >= (endBIdx + 1) * gatherSize_ ? (endBIdx + 1) * gatherSize_ - idx: maxIndex_; |
| 162 | indicesOffsetBase_ = idx; | 162 | indicesOffsetBase_ = idx; |
| 163 | } | 163 | } |
| 164 | curIndexSize_ = copyLen; | 164 | curIndexSize_ = copyLen; |
| @@ -19,7 +19,7 @@ namespace optiling { | |||
| 19 | 19 | ||
| 20 | const static uint64_t SIMD_ATOMIC_SUPPORT_KEY = 2000; | 20 | const static uint64_t SIMD_ATOMIC_SUPPORT_KEY = 2000; |
| 21 | const static uint64_t SIMD_DETERM_KEY = 2002; | 21 | const static uint64_t SIMD_DETERM_KEY = 2002; |
| 22 | -static constexpr int64_t SIMD_INNER_THRES = 32; | 22 | +static constexpr int64_t SIMD_INNER_THRES = 1024; |
| 23 | static constexpr int64_t BLOCK_TILING_THRES = 512; | 23 | static constexpr int64_t BLOCK_TILING_THRES = 512; |
| 24 | static constexpr int64_t INNER_ADD_NUM = 128; | 24 | static constexpr int64_t INNER_ADD_NUM = 128; |
| 25 | static constexpr int64_t BASE_BLOCK_ALIGN = 512; | 25 | static constexpr int64_t BASE_BLOCK_ALIGN = 512; |
| @@ -41,11 +41,9 @@ bool SegmentSumSimdTiling::IsAtomicSupport() | |||
| 41 | 41 | ||
| 42 | bool SegmentSumSimdTiling::IsCapable() | 42 | bool SegmentSumSimdTiling::IsCapable() |
| 43 | { | 43 | { |
| 44 | - bool isFloat = (dataType_ == ge::DT_FLOAT || dataType_ == ge::DT_FLOAT16 || dataType_ == ge::DT_BF16); | ||
| 45 | isAtomicSupport_ = IsAtomicSupport(); | 44 | isAtomicSupport_ = IsAtomicSupport(); |
| 46 | - isDeterministic_ = context_->GetDeterministic() == 1 && isFloat; | 45 | + bool isInnerSimd = innerDim_ > SIMD_INNER_THRES; |
| 47 | - bool isInnerSimd = innerDim_ * valueTypeBytes_ > SIMD_INNER_THRES; | 46 | + return isInnerSimd; |
| 48 | - return isInnerSimd && isAtomicSupport_; | ||
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | 49 | ||
| @@ -152,7 +150,7 @@ void SegmentSumSimdTiling::DoSplitColUBTiling(int64_t availableUbsize) | |||
| 152 | int64_t tmpColSize = BLOCK_TILING_THRES + idTypeBytes_; | 150 | int64_t tmpColSize = BLOCK_TILING_THRES + idTypeBytes_; |
| 153 | int64_t tmpRowNum = availableUbsize / tmpColSize; | 151 | int64_t tmpRowNum = availableUbsize / tmpColSize; |
| 154 | while (tmpRowNum - 1 > normalCoreOutterNum_) { | 152 | while (tmpRowNum - 1 > normalCoreOutterNum_) { |
| 155 | - if (tmpColSize >= innerSizeAlign + idTypeBytes_) { | 153 | + if (tmpColSize >= static_cast<int64_t>(innerSizeAlign + idTypeBytes_)) { |
| 156 | break; | 154 | break; |
| 157 | } | 155 | } |
| 158 | tmpColSize += INNER_ADD_NUM; | 156 | tmpColSize += INNER_ADD_NUM; |
| @@ -187,6 +185,14 @@ void SegmentSumSimdTiling::DoUBTiling() | |||
| 187 | { | 185 | { |
| 188 | int64_t availableUbsize = ubSize_; | 186 | int64_t availableUbsize = ubSize_; |
| 189 | 187 | ||
| 188 | + bool isFloat = (dataType_ == ge::DT_FLOAT || dataType_ == ge::DT_FLOAT16 || dataType_ == ge::DT_BF16); | ||
| 189 | + isDeterministic_ = context_->GetDeterministic() == 1 && isFloat && blockNumInRow_ != 1; | ||
| 190 | + | ||
| 191 | + // 确定性或者atomicAdd不支持的类型,需要一块32B buffer放头尾id | ||
| 192 | + if (!isAtomicSupport_ || isDeterministic_) { | ||
| 193 | + availableUbsize -= ubBlockSize_; | ||
| 194 | + } | ||
| 195 | + | ||
| 190 | availableUbsize -= ubBlockSize_ - idTypeBytes_; // 预留给segmentId对齐 | 196 | availableUbsize -= ubBlockSize_ - idTypeBytes_; // 预留给segmentId对齐 |
| 191 | // 如果inner小于512B,分核及切UB均不使用inner | 197 | // 如果inner小于512B,分核及切UB均不使用inner |
| 192 | if (normalCoreInnerNum_ * valueTypeBytes_ <= BLOCK_TILING_THRES) { | 198 | if (normalCoreInnerNum_ * valueTypeBytes_ <= BLOCK_TILING_THRES) { |
| @@ -231,6 +237,8 @@ void SegmentSumSimdTiling::DoMultCoreAddTiling() | |||
| 231 | tailCoreMultAddInners_ = innerDim_ - (usedCoreNumForMultAdd_ - 1) * normalCoreMultAddInners_; | 237 | tailCoreMultAddInners_ = innerDim_ - (usedCoreNumForMultAdd_ - 1) * normalCoreMultAddInners_; |
| 232 | } | 238 | } |
| 233 | int64_t mulAddUbsize = ubSize_; | 239 | int64_t mulAddUbsize = ubSize_; |
| 240 | + multAddIdsBufferSize_ = Ops::Base::CeilAlign(NUM_TWO * blockNumInRow_ * idTypeBytes_, ubBlockSize_); | ||
| 241 | + mulAddUbsize -= multAddIdsBufferSize_; | ||
| 234 | mulAddUbsize /= blockNumInRow_ * NUM_TWO + 1; | 242 | mulAddUbsize /= blockNumInRow_ * NUM_TWO + 1; |
| 235 | int64_t availableInnerUb = Ops::Base::FloorAlign(mulAddUbsize, static_cast<int64_t>(ubBlockSize_)); | 243 | int64_t availableInnerUb = Ops::Base::FloorAlign(mulAddUbsize, static_cast<int64_t>(ubBlockSize_)); |
| 236 | 244 | ||
| @@ -266,7 +274,6 @@ void SegmentSumSimdTiling::SetTilingData() | |||
| 266 | { | 274 | { |
| 267 | tilingData_ = context_->GetTilingData<SegmentSumSimdTilingData>(); | 275 | tilingData_ = context_->GetTilingData<SegmentSumSimdTilingData>(); |
| 268 | tilingData_->needCoreNum = needCoreNum_; | 276 | tilingData_->needCoreNum = needCoreNum_; |
| 269 | - tilingData_->outerDim = outerDim_; | ||
| 270 | tilingData_->innerDim = innerDim_; | 277 | tilingData_->innerDim = innerDim_; |
| 271 | 278 | ||
| 272 | tilingData_->xBufferSize = xBufferSize_; | 279 | tilingData_->xBufferSize = xBufferSize_; |
| @@ -281,9 +288,7 @@ void SegmentSumSimdTiling::SetTilingData() | |||
| 281 | tilingData_->blockNumInCol = blockNumInCol_; | 288 | tilingData_->blockNumInCol = blockNumInCol_; |
| 282 | 289 | ||
| 283 | tilingData_->normalCoreInnerNum = normalCoreInnerNum_; | 290 | tilingData_->normalCoreInnerNum = normalCoreInnerNum_; |
| 284 | - tilingData_->tailCoreInnerNum = tailCoreInnerNum_; | ||
| 285 | tilingData_->normalCoreOutterNum = normalCoreOutterNum_; | 291 | tilingData_->normalCoreOutterNum = normalCoreOutterNum_; |
| 286 | - tilingData_->tailCoreOutterNum = tailCoreOutterNum_; | ||
| 287 | 292 | ||
| 288 | tilingData_->normalCoreRowUbLoop = normalCoreRowUbLoop_; | 293 | tilingData_->normalCoreRowUbLoop = normalCoreRowUbLoop_; |
| 289 | tilingData_->normalCoreNormalLoopOutters = normalCoreNormalLoopOutters_; | 294 | tilingData_->normalCoreNormalLoopOutters = normalCoreNormalLoopOutters_; |
| @@ -301,7 +306,6 @@ void SegmentSumSimdTiling::SetTilingData() | |||
| 301 | 306 | ||
| 302 | tilingData_->usedCoreNumForMultAdd = usedCoreNumForMultAdd_; | 307 | tilingData_->usedCoreNumForMultAdd = usedCoreNumForMultAdd_; |
| 303 | tilingData_->normalCoreMultAddInners = normalCoreMultAddInners_; | 308 | tilingData_->normalCoreMultAddInners = normalCoreMultAddInners_; |
| 304 | - tilingData_->tailCoreMultAddInners = tailCoreMultAddInners_; | ||
| 305 | 309 | ||
| 306 | tilingData_->normalCoreMultAddInnerLoop = normalCoreMultAddInnerLoop_; | 310 | tilingData_->normalCoreMultAddInnerLoop = normalCoreMultAddInnerLoop_; |
| 307 | tilingData_->normalCoreMultAddNormalLoopInners = normalCoreMultAddNormalLoopInners_; | 311 | tilingData_->normalCoreMultAddNormalLoopInners = normalCoreMultAddNormalLoopInners_; |
| @@ -311,18 +315,22 @@ void SegmentSumSimdTiling::SetTilingData() | |||
| 311 | tilingData_->tailCoreMultAddTailLoopInners = tailCoreMultAddTailLoopInners_; | 315 | tilingData_->tailCoreMultAddTailLoopInners = tailCoreMultAddTailLoopInners_; |
| 312 | 316 | ||
| 313 | tilingData_->multAddXBufferSize = multAddXBufferSize_; | 317 | tilingData_->multAddXBufferSize = multAddXBufferSize_; |
| 318 | + tilingData_->multAddIdsBufferSize = multAddIdsBufferSize_; | ||
| 314 | tilingData_->multAddYBufferSize = multAddYBufferSize_; | 319 | tilingData_->multAddYBufferSize = multAddYBufferSize_; |
| 315 | return; | 320 | return; |
| 316 | } | 321 | } |
| 317 | 322 | ||
| 318 | uint64_t SegmentSumSimdTiling::GetTilingKey() const | 323 | uint64_t SegmentSumSimdTiling::GetTilingKey() const |
| 319 | { | 324 | { |
| 325 | + if (isDeterministic_ || !isAtomicSupport_) { | ||
| 326 | + return SIMD_DETERM_KEY; | ||
| 327 | + } | ||
| 320 | return SIMD_ATOMIC_SUPPORT_KEY; | 328 | return SIMD_ATOMIC_SUPPORT_KEY; |
| 321 | } | 329 | } |
| 322 | 330 | ||
| 323 | ge::graphStatus SegmentSumSimdTiling::GetWorkspaceSize() | 331 | ge::graphStatus SegmentSumSimdTiling::GetWorkspaceSize() |
| 324 | { | 332 | { |
| 325 | - auto useWorkspace = WS_SYS_SIZE; // 可以不用初值 | 333 | + size_t useWorkspace = WS_SYS_SIZE; // 可以不用初值 |
| 326 | if (isDeterministic_ || !isAtomicSupport_) { | 334 | if (isDeterministic_ || !isAtomicSupport_) { |
| 327 | useWorkspace += blockNumInRow_ * NUM_TWO * (innerDim_ * valueTypeBytes_ + idTypeBytes_) + idTypeBytes_; // 对齐idTypeBytes_ 头尾id最好需要间隔 cache line | 335 | useWorkspace += blockNumInRow_ * NUM_TWO * (innerDim_ * valueTypeBytes_ + idTypeBytes_) + idTypeBytes_; // 对齐idTypeBytes_ 头尾id最好需要间隔 cache line |
| 328 | } | 336 | } |
| @@ -346,7 +354,6 @@ void SegmentSumSimdTiling::DumpTilingInfo() | |||
| 346 | info << "tilingKey: " << GetTilingKey(); | 354 | info << "tilingKey: " << GetTilingKey(); |
| 347 | info << ", UB Size: " << ubSize_; | 355 | info << ", UB Size: " << ubSize_; |
| 348 | info << ", needCoreNum: " << tilingData_->needCoreNum; | 356 | info << ", needCoreNum: " << tilingData_->needCoreNum; |
| 349 | - info << ", outerDim: " << tilingData_->outerDim; | ||
| 350 | info << ", innerDim: " << tilingData_->innerDim; | 357 | info << ", innerDim: " << tilingData_->innerDim; |
| 351 | 358 | ||
| 352 | info << ", xBufferSize: " << tilingData_->xBufferSize; | 359 | info << ", xBufferSize: " << tilingData_->xBufferSize; |
| @@ -361,9 +368,7 @@ void SegmentSumSimdTiling::DumpTilingInfo() | |||
| 361 | info << ", blockNumInCol: " << tilingData_->blockNumInCol; | 368 | info << ", blockNumInCol: " << tilingData_->blockNumInCol; |
| 362 | 369 | ||
| 363 | info << ", normalCoreInnerNum: " << tilingData_->normalCoreInnerNum; | 370 | info << ", normalCoreInnerNum: " << tilingData_->normalCoreInnerNum; |
| 364 | - info << ", tailCoreInnerNum: " << tilingData_->tailCoreInnerNum; | ||
| 365 | info << ", normalCoreOutterNum: " << tilingData_->normalCoreOutterNum; | 371 | info << ", normalCoreOutterNum: " << tilingData_->normalCoreOutterNum; |
| 366 | - info << ", tailCoreOutterNum: " << tilingData_->tailCoreOutterNum; | ||
| 367 | 372 | ||
| 368 | info << ", normalCoreRowUbLoop: " << tilingData_->normalCoreRowUbLoop; | 373 | info << ", normalCoreRowUbLoop: " << tilingData_->normalCoreRowUbLoop; |
| 369 | info << ", normalCoreNormalLoopOutters: " << tilingData_->normalCoreNormalLoopOutters; | 374 | info << ", normalCoreNormalLoopOutters: " << tilingData_->normalCoreNormalLoopOutters; |
| @@ -381,7 +386,6 @@ void SegmentSumSimdTiling::DumpTilingInfo() | |||
| 381 | 386 | ||
| 382 | info << ", usedCoreNumForMultAdd: " << tilingData_->usedCoreNumForMultAdd; | 387 | info << ", usedCoreNumForMultAdd: " << tilingData_->usedCoreNumForMultAdd; |
| 383 | info << ", normalCoreMultAddInners: " << tilingData_->normalCoreMultAddInners; | 388 | info << ", normalCoreMultAddInners: " << tilingData_->normalCoreMultAddInners; |
| 384 | - info << ", tailCoreMultAddInners: " << tilingData_->tailCoreMultAddInners; | ||
| 385 | 389 | ||
| 386 | info << ", normalCoreMultAddInnerLoop: " << tilingData_->normalCoreMultAddInnerLoop; | 390 | info << ", normalCoreMultAddInnerLoop: " << tilingData_->normalCoreMultAddInnerLoop; |
| 387 | info << ", normalCoreMultAddNormalLoopInners: " << tilingData_->normalCoreMultAddNormalLoopInners; | 391 | info << ", normalCoreMultAddNormalLoopInners: " << tilingData_->normalCoreMultAddNormalLoopInners; |
| @@ -391,6 +395,7 @@ void SegmentSumSimdTiling::DumpTilingInfo() | |||
| 391 | info << ", tailCoreMultAddTailLoopInners: " << tilingData_->tailCoreMultAddTailLoopInners; | 395 | info << ", tailCoreMultAddTailLoopInners: " << tilingData_->tailCoreMultAddTailLoopInners; |
| 392 | 396 | ||
| 393 | info << ", multAddXBufferSize: " << tilingData_->multAddXBufferSize; | 397 | info << ", multAddXBufferSize: " << tilingData_->multAddXBufferSize; |
| 398 | + info << ", multAddIdsBufferSize: " << tilingData_->multAddIdsBufferSize; | ||
| 394 | info << ", multAddYBufferSize: " << tilingData_->multAddYBufferSize; | 399 | info << ", multAddYBufferSize: " << tilingData_->multAddYBufferSize; |
| 395 | 400 | ||
| 396 | OP_LOGI(context_->GetNodeName(), "%s", info.str().c_str()); | 401 | OP_LOGI(context_->GetNodeName(), "%s", info.str().c_str()); |
| @@ -57,8 +57,8 @@ private: | |||
| 57 | int64_t blockNumInCol_ = 0; | 57 | int64_t blockNumInCol_ = 0; |
| 58 | int64_t normalCoreInnerNum_ = 0; | 58 | int64_t normalCoreInnerNum_ = 0; |
| 59 | int64_t normalCoreOutterNum_ = 0; | 59 | int64_t normalCoreOutterNum_ = 0; |
| 60 | - int64_t tailCoreInnerNum_ = 0; | 60 | + int64_t tailCoreInnerNum_ = 0; // 列尾核列上处理的inner数 |
| 61 | - int64_t tailCoreOutterNum_ = 0; | 61 | + int64_t tailCoreOutterNum_ = 0; // 行尾核行上处理的行数 |
| 62 | 62 | ||
| 63 | int64_t normalCoreRowUbLoop_ = 0; | 63 | int64_t normalCoreRowUbLoop_ = 0; |
| 64 | int64_t normalCoreNormalLoopOutters_ = 0; | 64 | int64_t normalCoreNormalLoopOutters_ = 0; |
| @@ -80,7 +80,7 @@ private: | |||
| 80 | 80 | ||
| 81 | int64_t usedCoreNumForMultAdd_ = 0; | 81 | int64_t usedCoreNumForMultAdd_ = 0; |
| 82 | int64_t normalCoreMultAddInners_ = 0; | 82 | int64_t normalCoreMultAddInners_ = 0; |
| 83 | - int64_t tailCoreMultAddInners_ = 0; | 83 | + int64_t tailCoreMultAddInners_ = 0; // 多核累加尾核处理的inner数 |
| 84 | 84 | ||
| 85 | int64_t normalCoreMultAddInnerLoop_ = 0; | 85 | int64_t normalCoreMultAddInnerLoop_ = 0; |
| 86 | int64_t normalCoreMultAddNormalLoopInners_ = 0; | 86 | int64_t normalCoreMultAddNormalLoopInners_ = 0; |
| @@ -90,6 +90,7 @@ private: | |||
| 90 | int64_t tailCoreMultAddTailLoopInners_ = 0; | 90 | int64_t tailCoreMultAddTailLoopInners_ = 0; |
| 91 | 91 | ||
| 92 | int64_t multAddXBufferSize_ = 0; | 92 | int64_t multAddXBufferSize_ = 0; |
| 93 | + int64_t multAddIdsBufferSize_ = 0; | ||
| 93 | int64_t multAddYBufferSize_ = 0; | 94 | int64_t multAddYBufferSize_ = 0; |
| 94 | 95 | ||
| 95 | bool isDeterministic_ = false; | 96 | bool isDeterministic_ = false; |
| @@ -19,6 +19,10 @@ namespace optiling { | |||
| 19 | 19 | ||
| 20 | static constexpr uint64_t SIMT_DCACHE_SIZE = static_cast<uint64_t>(32 * 1024); | 20 | static constexpr uint64_t SIMT_DCACHE_SIZE = static_cast<uint64_t>(32 * 1024); |
| 21 | static constexpr uint64_t TEMPLATE_SIMT = 1000; | 21 | static constexpr uint64_t TEMPLATE_SIMT = 1000; |
| 22 | +static constexpr uint32_t DOUBLE = 2; | ||
| 23 | +static constexpr uint32_t ROWS_IN_WORKSPACE = 128; | ||
| 24 | +static constexpr uint32_t RESERVED_WS_SIZE = 16 * 1024 * 1024; | ||
| 25 | +static const std::set<ge::DataType> deterministicType = {ge::DT_FLOAT, ge::DT_FLOAT16, ge::DT_BF16}; | ||
| 22 | 26 | ||
| 23 | bool SegmentSumSimtTiling::IsCapable() | 27 | bool SegmentSumSimtTiling::IsCapable() |
| 24 | { | 28 | { |
| @@ -28,9 +32,23 @@ bool SegmentSumSimtTiling::IsCapable() | |||
| 28 | ge::graphStatus SegmentSumSimtTiling::DoOpTiling() | 32 | ge::graphStatus SegmentSumSimtTiling::DoOpTiling() |
| 29 | { | 33 | { |
| 30 | ubSize_ -= SIMT_DCACHE_SIZE; | 34 | ubSize_ -= SIMT_DCACHE_SIZE; |
| 35 | + if (context_->GetDeterministic() && deterministicType.find(dataType_) != deterministicType.end()) { | ||
| 36 | + isDeterministic_ = 1; | ||
| 37 | + } | ||
| 31 | uint64_t outputSize = segmentNum_ * innerDim_; | 38 | uint64_t outputSize = segmentNum_ * innerDim_; |
| 32 | initNumPerCore_ = outputSize / totalCoreNum_; | 39 | initNumPerCore_ = outputSize / totalCoreNum_; |
| 33 | initNumTailCore_ = outputSize - (totalCoreNum_ - 1) * initNumPerCore_; | 40 | initNumTailCore_ = outputSize - (totalCoreNum_ - 1) * initNumPerCore_; |
| 41 | + | ||
| 42 | + segIdsPerCore_ = outerDim_ / totalCoreNum_; | ||
| 43 | + segIdsTailCore_ = outerDim_ - segIdsPerCore_ * (totalCoreNum_-1); | ||
| 44 | + maxSegIdsInUb = (ubSize_ / DOUBLE - ubBlockSize_) / idTypeBytes_; | ||
| 45 | + segIdsPerLoop_ = maxSegIdsInUb > segIdsPerCore_ ? segIdsPerCore_ : maxSegIdsInUb; | ||
| 46 | + segIdsPerLoopTailCore_ = maxSegIdsInUb > segIdsTailCore_ ? segIdsTailCore_ : maxSegIdsInUb; | ||
| 47 | + loopTimes_ = Ops::Base::CeilDiv(segIdsPerCore_, static_cast<uint64_t>(segIdsPerLoop_)); | ||
| 48 | + loopTimesTailCore_ = Ops::Base::CeilDiv(segIdsTailCore_, static_cast<uint64_t>(segIdsPerLoopTailCore_)); | ||
| 49 | + segIdsTailLoop_ = segIdsPerCore_ - (loopTimes_ - 1) * segIdsPerLoop_; | ||
| 50 | + segIdsTailLoopTailCore_ = segIdsTailCore_ - (loopTimesTailCore_ - 1) * segIdsPerLoopTailCore_; | ||
| 51 | + | ||
| 34 | SetTilingData(); | 52 | SetTilingData(); |
| 35 | return ge::GRAPH_SUCCESS; | 53 | return ge::GRAPH_SUCCESS; |
| 36 | } | 54 | } |
| @@ -42,18 +60,30 @@ void SegmentSumSimtTiling::SetTilingData() | |||
| 42 | tilingData_->innerDim = innerDim_; | 60 | tilingData_->innerDim = innerDim_; |
| 43 | tilingData_->initNumPerCore = initNumPerCore_; | 61 | tilingData_->initNumPerCore = initNumPerCore_; |
| 44 | tilingData_->initNumTailCore = initNumTailCore_; | 62 | tilingData_->initNumTailCore = initNumTailCore_; |
| 63 | + tilingData_->isDeterministic = isDeterministic_; | ||
| 64 | + tilingData_->maxSegIdsInUb = maxSegIdsInUb; | ||
| 65 | + tilingData_->loopTimes = loopTimes_; | ||
| 66 | + tilingData_->loopTimesTailCore = loopTimesTailCore_; | ||
| 67 | + tilingData_->segIdsPerLoop = segIdsPerLoop_; | ||
| 68 | + tilingData_->segIdsPerLoopTailCore = segIdsPerLoopTailCore_; | ||
| 69 | + tilingData_->segIdsTailLoop = segIdsTailLoop_; | ||
| 70 | + tilingData_->segIdsTailLoopTailCore = segIdsTailLoopTailCore_; | ||
| 45 | } | 71 | } |
| 46 | 72 | ||
| 47 | uint64_t SegmentSumSimtTiling::GetTilingKey() const | 73 | uint64_t SegmentSumSimtTiling::GetTilingKey() const |
| 48 | { | 74 | { |
| 49 | - uint64_t tilingKey = TEMPLATE_SIMT; | 75 | + return TEMPLATE_SIMT; |
| 50 | - return tilingKey; | ||
| 51 | } | 76 | } |
| 52 | 77 | ||
| 53 | ge::graphStatus SegmentSumSimtTiling::GetWorkspaceSize() | 78 | ge::graphStatus SegmentSumSimtTiling::GetWorkspaceSize() |
| 54 | { | 79 | { |
| 55 | auto currentWorkspace = context_->GetWorkspaceSizes(1); | 80 | auto currentWorkspace = context_->GetWorkspaceSizes(1); |
| 56 | - currentWorkspace[0] = 0; | 81 | + currentWorkspace[0] = RESERVED_WS_SIZE; |
| 82 | + if (isDeterministic_ == 1) { | ||
| 83 | + uint64_t ws_size = ROWS_IN_WORKSPACE * innerDim_ * valueTypeBytes_ + | ||
| 84 | + ROWS_IN_WORKSPACE * idTypeBytes_; | ||
| 85 | + currentWorkspace[0] += ws_size ; | ||
| 86 | + } | ||
| 57 | return ge::GRAPH_SUCCESS; | 87 | return ge::GRAPH_SUCCESS; |
| 58 | } | 88 | } |
| 59 | 89 | ||
| @@ -74,7 +104,16 @@ void SegmentSumSimtTiling::DumpTilingInfo() | |||
| 74 | info << ", outerDim: " << outerDim_; | 104 | info << ", outerDim: " << outerDim_; |
| 75 | info << ", innerDim: " << innerDim_; | 105 | info << ", innerDim: " << innerDim_; |
| 76 | info << ", initNumPerCore: " << initNumPerCore_; | 106 | info << ", initNumPerCore: " << initNumPerCore_; |
| 77 | - info << ", initNumTailCore: " <<initNumTailCore_; | 107 | + info << ", initNumTailCore: " << initNumTailCore_; |
| 108 | + info << ", isDeterministic: " << isDeterministic_; | ||
| 109 | + info << ", segIdsPerCore: " << segIdsPerCore_; | ||
| 110 | + info << ", segIdsTailCore: " << segIdsTailCore_; | ||
| 111 | + info << ", segIdsPerLoop: " << segIdsPerLoop_; | ||
| 112 | + info << ", segIdsPerLoopTailCore: " << segIdsPerLoopTailCore_; | ||
| 113 | + info << ", segIdsTailLoop: " << segIdsTailLoop_; | ||
| 114 | + info << ", segIdsTailLoopTailCore: " << segIdsTailLoopTailCore_; | ||
| 115 | + info << ", loopTimes: " << loopTimes_; | ||
| 116 | + info << ", loopTimesTailCore: " << loopTimesTailCore_; | ||
| 78 | OP_LOGI(context_->GetNodeName(), "%s", info.str().c_str()); | 117 | OP_LOGI(context_->GetNodeName(), "%s", info.str().c_str()); |
| 79 | } | 118 | } |
| 80 | 119 | ||
| @@ -95,7 +95,7 @@ ge::graphStatus SegmentSumBaseTiling::GetShapeAttrsInfo() | |||
| 95 | outerDim_ = dataShape.GetDim(0); | 95 | outerDim_ = dataShape.GetDim(0); |
| 96 | 96 | ||
| 97 | OP_CHECK_IF( | 97 | OP_CHECK_IF( |
| 98 | - outerDim_ != segmentIdsShape.GetDim(0), | 98 | + static_cast<int64_t>(outerDim_) != segmentIdsShape.GetDim(0), |
| 99 | OP_LOGE( | 99 | OP_LOGE( |
| 100 | context_->GetNodeName(), "the dimension 0 of data shape should be same with segment_ids."), | 100 | context_->GetNodeName(), "the dimension 0 of data shape should be same with segment_ids."), |
| 101 | return ge::GRAPH_FAILED); | 101 | return ge::GRAPH_FAILED); |
| @@ -27,7 +27,7 @@ class SegmentSumSimd | |||
| 27 | { | 27 | { |
| 28 | public: | 28 | public: |
| 29 | __aicore__ inline SegmentSumSimd(void){}; | 29 | __aicore__ inline SegmentSumSimd(void){}; |
| 30 | - __aicore__ inline void Init(GM_ADDR x, GM_ADDR segmentIds, GM_ADDR y, GM_ADDR workspace, TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData); | 30 | + __aicore__ inline void Init(GM_ADDR x, GM_ADDR segmentIds, GM_ADDR y, TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData); |
| 31 | __aicore__ inline void Process(); | 31 | __aicore__ inline void Process(); |
| 32 | __aicore__ inline void CopyInX(int32_t copyCount, int32_t burstLen, int64_t xGmOffset); | 32 | __aicore__ inline void CopyInX(int32_t copyCount, int32_t burstLen, int64_t xGmOffset); |
| 33 | __aicore__ inline void CopyInSegmentIds(int32_t burstLen, int64_t segmentIdsGmOffset); | 33 | __aicore__ inline void CopyInSegmentIds(int32_t burstLen, int64_t segmentIdsGmOffset); |
| @@ -72,7 +72,7 @@ private: | |||
| 72 | 72 | ||
| 73 | template <typename T1, typename T2> | 73 | template <typename T1, typename T2> |
| 74 | __aicore__ inline void SegmentSumSimd<T1, T2>::Init( | 74 | __aicore__ inline void SegmentSumSimd<T1, T2>::Init( |
| 75 | - GM_ADDR x, GM_ADDR segmentIds, GM_ADDR y, GM_ADDR workspace, AscendC::TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData) | 75 | + GM_ADDR x, GM_ADDR segmentIds, GM_ADDR y, AscendC::TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData) |
| 76 | { | 76 | { |
| 77 | tilingData_ = tilingData; | 77 | tilingData_ = tilingData; |
| 78 | blockIdx_ = GetBlockIdx(); | 78 | blockIdx_ = GetBlockIdx(); |
| @@ -173,9 +173,8 @@ __aicore__ inline void SegmentSumSimd<T1, T2>::ComputeSumAndCopyOut(LocalTensor< | |||
| 173 | if (curId == preId_) { | 173 | if (curId == preId_) { |
| 174 | Add(yLocal, yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); | 174 | Add(yLocal, yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); |
| 175 | } else if (curId != preId_ && preId_ == -1) { | 175 | } else if (curId != preId_ && preId_ == -1) { |
| 176 | - DataCopy(yLocal, xLocal[i * curLoopInnersAlign], curLoopInnersAlign); // 偏移使用 xLocal[i * curLoopInners]也行,DataCopy搬运数量必须向上对齐 | 176 | + Copy(yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); |
| 177 | preId_ = curId; | 177 | preId_ = curId; |
| 178 | - // Add(yLocal, yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); // 也可以yBuf初始清零然后Add | ||
| 179 | } else { // curId != preId_ | 178 | } else { // curId != preId_ |
| 180 | event_t eventId = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_MTE3)); | 179 | event_t eventId = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_MTE3)); |
| 181 | SetFlag<HardEvent::V_MTE3>(eventId); | 180 | SetFlag<HardEvent::V_MTE3>(eventId); |
| @@ -193,7 +192,7 @@ __aicore__ inline void SegmentSumSimd<T1, T2>::ComputeSumAndCopyOut(LocalTensor< | |||
| 193 | WaitFlag<HardEvent::MTE3_V>(eventId1); | 192 | WaitFlag<HardEvent::MTE3_V>(eventId1); |
| 194 | 193 | ||
| 195 | preId_ = curId; | 194 | preId_ = curId; |
| 196 | - DataCopy(yLocal, xLocal[i * curLoopInnersAlign], curLoopInnersAlign); // 上对齐32B | 195 | + Copy(yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); |
| 197 | } | 196 | } |
| 198 | } | 197 | } |
| 199 | 198 | ||
| @@ -210,21 +209,25 @@ __aicore__ inline void SegmentSumSimd<T1, T2>::Process() | |||
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | LocalTensor<T1> yLocal = yBuf_.Get<T1>(); | 211 | LocalTensor<T1> yLocal = yBuf_.Get<T1>(); |
| 213 | - // Duplicate<T1>(yLocal, 0, normalLoopInners_); | 212 | + |
| 213 | + T2 curId; | ||
| 214 | + int64_t curLoopInners; | ||
| 215 | + int64_t curLoopInnersAlign; | ||
| 216 | + int64_t colOffset; | ||
| 217 | + int64_t curLoopOutters; | ||
| 218 | + int64_t xGmOffset; | ||
| 219 | + int64_t segmentIdsGmOffset; | ||
| 214 | 220 | ||
| 215 | for (int64_t col = 0; col < colUbLoop_; col++) { | 221 | for (int64_t col = 0; col < colUbLoop_; col++) { |
| 216 | isFirstId_ = true; | 222 | isFirstId_ = true; |
| 217 | preId_ = -1; | 223 | preId_ = -1; |
| 218 | - T2 curId; | 224 | + curLoopInners = col == colUbLoop_ - 1 ? tailLoopInners_ : normalLoopInners_; |
| 219 | - int64_t curLoopInners; | 225 | + curLoopInnersAlign = (curLoopInners + blockNumT1_ - 1) / blockNumT1_ * blockNumT1_; |
| 220 | - int64_t colOffset = col * normalLoopInners_; | 226 | + colOffset = col * normalLoopInners_; |
| 221 | for (int64_t row = 0; row < rowUbLoop_; row++) { | 227 | for (int64_t row = 0; row < rowUbLoop_; row++) { |
| 222 | - int64_t curLoopOutters = row == rowUbLoop_ - 1 ? tailLoopOutters_ : normalLoopOutters_; | 228 | + curLoopOutters = row == rowUbLoop_ - 1 ? tailLoopOutters_ : normalLoopOutters_; |
| 223 | - curLoopInners = col == colUbLoop_ - 1 ? tailLoopInners_ : normalLoopInners_; | 229 | + xGmOffset = row * normalLoopOutters_ * tilingData_->innerDim + col * normalLoopInners_; |
| 224 | - int64_t curLoopInnersAlign = (curLoopInners + blockNumT1_ - 1) / blockNumT1_ * blockNumT1_; | 230 | + segmentIdsGmOffset = row * normalLoopOutters_; |
| 225 | - | ||
| 226 | - int64_t xGmOffset = row * normalLoopOutters_ * tilingData_->innerDim + col * normalLoopInners_; | ||
| 227 | - int64_t segmentIdsGmOffset = row * normalLoopOutters_; | ||
| 228 | 231 | ||
| 229 | CopyInX(curLoopOutters, curLoopInners, xGmOffset); | 232 | CopyInX(curLoopOutters, curLoopInners, xGmOffset); |
| 230 | CopyInSegmentIds(curLoopOutters, segmentIdsGmOffset); | 233 | CopyInSegmentIds(curLoopOutters, segmentIdsGmOffset); |
| @@ -0,0 +1,206 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | + | ||
| 19 | +namespace SegmentSum { | ||
| 20 | +using namespace AscendC; | ||
| 21 | + | ||
| 22 | +template <typename T1, typename T2> | ||
| 23 | +class SegmentSumMultiCoreAdd | ||
| 24 | +{ | ||
| 25 | +public: | ||
| 26 | + __aicore__ inline SegmentSumMultiCoreAdd(void){}; | ||
| 27 | + __aicore__ inline void Init(GM_ADDR y, GM_ADDR workspace, TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData); | ||
| 28 | + __aicore__ inline void Process(); | ||
| 29 | + __aicore__ inline void CopyInIds(LocalTensor<T2>& segmentIdsLocal); | ||
| 30 | + __aicore__ inline void CopyInSum(int32_t burstLen, int64_t colOffset); | ||
| 31 | + __aicore__ inline void CopyOutY(LocalTensor<T1>& yLocal, int32_t burstLen, T2 id, int64_t colOffset); | ||
| 32 | + __aicore__ inline void ComputeAndCopyOut(LocalTensor<T2> segmentIdsLocal, LocalTensor<T1>& yLocal, int32_t curLoopInners, int32_t curLoopInnersAlign, int64_t colOffset); | ||
| 33 | + | ||
| 34 | +private: | ||
| 35 | + GlobalTensor<T1> yGm_; | ||
| 36 | + GlobalTensor<T1> sumWorkspace_; | ||
| 37 | + GlobalTensor<T2> segIdWorkspace_; | ||
| 38 | + | ||
| 39 | + TQue<QuePosition::VECIN, BUFFER_NUM> xQue_; | ||
| 40 | + TBuf<QuePosition::VECCALC> segmentIdsBuf_; | ||
| 41 | + TBuf<QuePosition::VECCALC> yBuf_; | ||
| 42 | + | ||
| 43 | + const SegmentSumSimdTilingData* tilingData_; | ||
| 44 | + | ||
| 45 | + uint32_t blockIdx_ = 0; | ||
| 46 | + | ||
| 47 | + int64_t colGmOffset_ = 0; // 当前核处理的数据块在GM列上的偏移 | ||
| 48 | + | ||
| 49 | + int64_t rowUbLoop_ = 0; // 当前核的ub在行上的循环次数 | ||
| 50 | + int64_t colUbLoop_ = 0; // 当前核的ub在列上的循环次数 | ||
| 51 | + | ||
| 52 | + int64_t normalLoopInners_ = 0; // 当前核ub正常循环一次处理的列数 | ||
| 53 | + int64_t tailLoopInners_ = 0; // 当前核ub尾循环一次处理的列数 | ||
| 54 | + | ||
| 55 | + constexpr static int32_t blockNumT1_ = platform::GetUbBlockSize() / sizeof(T1); | ||
| 56 | +}; | ||
| 57 | + | ||
| 58 | +template <typename T1, typename T2> | ||
| 59 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::Init(GM_ADDR y, GM_ADDR workspace, AscendC::TPipe& pipeIn, const SegmentSumSimdTilingData* tilingData) | ||
| 60 | +{ | ||
| 61 | + tilingData_ = tilingData; | ||
| 62 | + blockIdx_ = GetBlockIdx(); | ||
| 63 | + | ||
| 64 | + if (blockIdx_ >= tilingData_->usedCoreNumForMultAdd) { | ||
| 65 | + return; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + colGmOffset_ = blockIdx_ * tilingData_->normalCoreMultAddInners; | ||
| 69 | + rowUbLoop_ = DOUBLE * tilingData_->blockNumInRow; // no need | ||
| 70 | + colUbLoop_ = blockIdx_ == tilingData_->usedCoreNumForMultAdd - 1 ? tilingData_->tailCoreMultAddInnerLoop : tilingData_->normalCoreMultAddInnerLoop; | ||
| 71 | + | ||
| 72 | + normalLoopInners_ = blockIdx_ == tilingData_->usedCoreNumForMultAdd - 1 ? tilingData_->tailCoreMultAddNormalLoopInners : tilingData_->normalCoreMultAddNormalLoopInners; | ||
| 73 | + tailLoopInners_ = blockIdx_ == tilingData_->usedCoreNumForMultAdd - 1 ? tilingData_->tailCoreMultAddTailLoopInners : tilingData_->normalCoreMultAddTailLoopInners; | ||
| 74 | + uint32_t segIdAddrOffset = (tilingData_->blockNumInRow * DOUBLE * tilingData_->innerDim * sizeof(T1) + sizeof(T2) - 1) / sizeof(T2); | ||
| 75 | + | ||
| 76 | + yGm_.SetGlobalBuffer((__gm__ T1*)y + colGmOffset_); | ||
| 77 | + sumWorkspace_.SetGlobalBuffer((__gm__ T1*)workspace + colGmOffset_); | ||
| 78 | + segIdWorkspace_.SetGlobalBuffer((__gm__ T2*)workspace + segIdAddrOffset); | ||
| 79 | + | ||
| 80 | + pipeIn.InitBuffer(xQue_, BUFFER_NUM, tilingData_->multAddXBufferSize); | ||
| 81 | + pipeIn.InitBuffer(segmentIdsBuf_, tilingData_->multAddIdsBufferSize); | ||
| 82 | + pipeIn.InitBuffer(yBuf_, tilingData_->multAddYBufferSize); | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | + | ||
| 86 | +template <typename T1, typename T2> | ||
| 87 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::CopyInIds(LocalTensor<T2>& segmentIdsLocal) | ||
| 88 | +{ | ||
| 89 | + DataCopyPadExtParams<T2> dataCopyPadExtParams; | ||
| 90 | + dataCopyPadExtParams.isPad = false; | ||
| 91 | + dataCopyPadExtParams.leftPadding = 0; | ||
| 92 | + dataCopyPadExtParams.rightPadding = 0; | ||
| 93 | + dataCopyPadExtParams.paddingValue = 0; | ||
| 94 | + | ||
| 95 | + DataCopyExtParams dataCoptExtParams; | ||
| 96 | + dataCoptExtParams.blockCount = 1; | ||
| 97 | + dataCoptExtParams.blockLen = tilingData_->blockNumInRow * DOUBLE * sizeof(T2); | ||
| 98 | + dataCoptExtParams.srcStride = 0; | ||
| 99 | + dataCoptExtParams.dstStride = 0; | ||
| 100 | + DataCopyPad(segmentIdsLocal, segIdWorkspace_, dataCoptExtParams, dataCopyPadExtParams); | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | + | ||
| 104 | +template <typename T1, typename T2> | ||
| 105 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::CopyInSum(int32_t burstLen, int64_t colOffset) | ||
| 106 | +{ | ||
| 107 | + int64_t gmStride = tilingData_->innerDim - burstLen; | ||
| 108 | + LocalTensor<T1> xLocal = xQue_.AllocTensor<T1>(); | ||
| 109 | + DataCopyPadExtParams<T1> dataCopyPadExtParams; | ||
| 110 | + dataCopyPadExtParams.isPad = false; | ||
| 111 | + dataCopyPadExtParams.leftPadding = 0; | ||
| 112 | + dataCopyPadExtParams.rightPadding = 0; | ||
| 113 | + dataCopyPadExtParams.paddingValue = 0; | ||
| 114 | + | ||
| 115 | + DataCopyExtParams dataCoptExtParams; | ||
| 116 | + dataCoptExtParams.blockCount = tilingData_->blockNumInRow * DOUBLE; | ||
| 117 | + dataCoptExtParams.blockLen = burstLen * sizeof(T1); | ||
| 118 | + dataCoptExtParams.srcStride = gmStride * sizeof(T1); | ||
| 119 | + dataCoptExtParams.dstStride = 0; | ||
| 120 | + DataCopyPad(xLocal, sumWorkspace_[colOffset], dataCoptExtParams, dataCopyPadExtParams); | ||
| 121 | + xQue_.EnQue(xLocal); | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | + | ||
| 125 | +template <typename T1, typename T2> | ||
| 126 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::CopyOutY(LocalTensor<T1>& yLocal, int32_t burstLen, T2 id, int64_t colOffset) | ||
| 127 | +{ | ||
| 128 | + DataCopyExtParams dataCoptExtParams; | ||
| 129 | + dataCoptExtParams.blockCount = 1; | ||
| 130 | + dataCoptExtParams.blockLen = burstLen * sizeof(T1); | ||
| 131 | + dataCoptExtParams.srcStride = 0; | ||
| 132 | + dataCoptExtParams.dstStride = 0; | ||
| 133 | + DataCopyPad(yGm_[id * tilingData_->innerDim + colOffset], yLocal, dataCoptExtParams); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | + | ||
| 137 | +template <typename T1, typename T2> | ||
| 138 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::ComputeAndCopyOut(LocalTensor<T2> segmentIdsLocal, LocalTensor<T1>& yLocal, int32_t curLoopInners, int32_t curLoopInnersAlign, int64_t colOffset) | ||
| 139 | +{ | ||
| 140 | + LocalTensor<T1> xLocal = xQue_.DeQue<T1>(); | ||
| 141 | + Copy(yLocal, xLocal[curLoopInnersAlign], curLoopInners); | ||
| 142 | + | ||
| 143 | + // GetValue获取id前需要插同步 | ||
| 144 | + event_t eventId1 = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::MTE2_S)); | ||
| 145 | + SetFlag<HardEvent::MTE2_S>(eventId1); | ||
| 146 | + WaitFlag<HardEvent::MTE2_S>(eventId1); | ||
| 147 | + | ||
| 148 | + T2 preId = segmentIdsLocal.GetValue(1); | ||
| 149 | + | ||
| 150 | + for (int32_t i = 2; i < tilingData_->blockNumInRow * DOUBLE; i++) { | ||
| 151 | + T2 curId = segmentIdsLocal.GetValue(i); | ||
| 152 | + if (curId == preId) { | ||
| 153 | + Add(yLocal, yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); | ||
| 154 | + } else if (curId == -1) { | ||
| 155 | + continue; | ||
| 156 | + } else { // curId != preId | ||
| 157 | + event_t eventId2 = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_MTE3)); | ||
| 158 | + SetFlag<HardEvent::V_MTE3>(eventId2); | ||
| 159 | + WaitFlag<HardEvent::V_MTE3>(eventId2); | ||
| 160 | + | ||
| 161 | + CopyOutY(yLocal, curLoopInners, preId, colOffset); | ||
| 162 | + preId = curId; | ||
| 163 | + | ||
| 164 | + event_t eventId3 = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::MTE3_V)); | ||
| 165 | + SetFlag<HardEvent::MTE3_V>(eventId3); | ||
| 166 | + WaitFlag<HardEvent::MTE3_V>(eventId3); | ||
| 167 | + | ||
| 168 | + Copy(yLocal, xLocal[i * curLoopInnersAlign], curLoopInners); | ||
| 169 | + } | ||
| 170 | + } | ||
| 171 | + event_t eventId4 = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::V_MTE3)); | ||
| 172 | + SetFlag<HardEvent::V_MTE3>(eventId4); | ||
| 173 | + WaitFlag<HardEvent::V_MTE3>(eventId4); | ||
| 174 | + | ||
| 175 | + CopyOutY(yLocal, curLoopInners, preId, colOffset); | ||
| 176 | + xQue_.FreeTensor(xLocal); | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | + | ||
| 180 | +template <typename T1, typename T2> | ||
| 181 | +__aicore__ inline void SegmentSumMultiCoreAdd<T1, T2>::Process() | ||
| 182 | +{ | ||
| 183 | + if (blockIdx_ >= tilingData_->usedCoreNumForMultAdd) { | ||
| 184 | + return; | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + LocalTensor<T2> segmentIdsLocal = segmentIdsBuf_.Get<T2>(); | ||
| 188 | + LocalTensor<T1> yLocal = yBuf_.Get<T1>(); | ||
| 189 | + CopyInIds(segmentIdsLocal); | ||
| 190 | + | ||
| 191 | + int64_t curLoopInners; | ||
| 192 | + int64_t curLoopInnersAlign; | ||
| 193 | + int64_t colOffset; | ||
| 194 | + | ||
| 195 | + for (int64_t col = 0; col < colUbLoop_; col++) { | ||
| 196 | + curLoopInners = col == colUbLoop_ - 1 ? tailLoopInners_ : normalLoopInners_; | ||
| 197 | + curLoopInnersAlign = (curLoopInners + blockNumT1_ - 1) / blockNumT1_ * blockNumT1_; | ||
| 198 | + colOffset = col * normalLoopInners_; | ||
| 199 | + | ||
| 200 | + CopyInSum(curLoopInners, colOffset); | ||
| 201 | + ComputeAndCopyOut(segmentIdsLocal, yLocal, curLoopInners, curLoopInnersAlign, colOffset); | ||
| 202 | + } | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +} | ||
| 206 | + | ||
| @@ -17,12 +17,19 @@ struct SegmentSumSimtTilingData | |||
| 17 | uint64_t innerDim{0}; | 17 | uint64_t innerDim{0}; |
| 18 | uint64_t initNumPerCore{0}; | 18 | uint64_t initNumPerCore{0}; |
| 19 | uint64_t initNumTailCore{0}; | 19 | uint64_t initNumTailCore{0}; |
| 20 | + uint32_t isDeterministic{0}; | ||
| 21 | + uint32_t maxSegIdsInUb{0}; | ||
| 22 | + int32_t loopTimes{0}; // 整核循环次数 | ||
| 23 | + int32_t loopTimesTailCore{0}; // 尾核循环次数 | ||
| 24 | + uint32_t segIdsPerLoop{0}; //整核整循环处理多少id | ||
| 25 | + uint32_t segIdsPerLoopTailCore{0}; //尾核整循环处理多少id | ||
| 26 | + uint32_t segIdsTailLoop{0}; // 整核尾循环处理多少id | ||
| 27 | + uint32_t segIdsTailLoopTailCore{0}; //尾核尾循环处理多少id | ||
| 20 | }; | 28 | }; |
| 21 | 29 | ||
| 22 | struct SegmentSumSimdTilingData | 30 | struct SegmentSumSimdTilingData |
| 23 | { | 31 | { |
| 24 | int64_t needCoreNum{0}; | 32 | int64_t needCoreNum{0}; |
| 25 | - int64_t outerDim{0}; // kernel没用 | ||
| 26 | int64_t innerDim{0}; | 33 | int64_t innerDim{0}; |
| 27 | 34 | ||
| 28 | int64_t xBufferSize{0}; | 35 | int64_t xBufferSize{0}; |
| @@ -37,9 +44,7 @@ struct SegmentSumSimdTilingData | |||
| 37 | int64_t blockNumInCol{0}; // 列切分的核数 | 44 | int64_t blockNumInCol{0}; // 列切分的核数 |
| 38 | 45 | ||
| 39 | int64_t normalCoreInnerNum{0}; // 正常列核列上处理的inner数 | 46 | int64_t normalCoreInnerNum{0}; // 正常列核列上处理的inner数 |
| 40 | - int64_t tailCoreInnerNum{0}; // 列尾核列上处理的inner数 | ||
| 41 | int64_t normalCoreOutterNum{0}; // 正常行核行上处理的行数 | 47 | int64_t normalCoreOutterNum{0}; // 正常行核行上处理的行数 |
| 42 | - int64_t tailCoreOutterNum{0}; // 行尾核行上处理的行数 | ||
| 43 | 48 | ||
| 44 | int64_t normalCoreRowUbLoop{0}; // 正常行核ub在行上的循环次数 | 49 | int64_t normalCoreRowUbLoop{0}; // 正常行核ub在行上的循环次数 |
| 45 | int64_t normalCoreNormalLoopOutters{0}; // 正常行核ub正常循环一次处理的行数 | 50 | int64_t normalCoreNormalLoopOutters{0}; // 正常行核ub正常循环一次处理的行数 |
| @@ -57,7 +62,6 @@ struct SegmentSumSimdTilingData | |||
| 57 | 62 | ||
| 58 | int64_t usedCoreNumForMultAdd{0}; // 多核累加使用的核数 | 63 | int64_t usedCoreNumForMultAdd{0}; // 多核累加使用的核数 |
| 59 | int64_t normalCoreMultAddInners{0}; // 多核累加正常核处理的inner数 | 64 | int64_t normalCoreMultAddInners{0}; // 多核累加正常核处理的inner数 |
| 60 | - int64_t tailCoreMultAddInners{0}; // 多核累加尾核处理的inner数 | ||
| 61 | 65 | ||
| 62 | int64_t normalCoreMultAddInnerLoop{0}; // 多核累加正常核列循环次数 | 66 | int64_t normalCoreMultAddInnerLoop{0}; // 多核累加正常核列循环次数 |
| 63 | int64_t normalCoreMultAddNormalLoopInners{0}; // 多核累加正常核正常循环处理的inner数 | 67 | int64_t normalCoreMultAddNormalLoopInners{0}; // 多核累加正常核正常循环处理的inner数 |
| @@ -67,6 +71,7 @@ struct SegmentSumSimdTilingData | |||
| 67 | int64_t tailCoreMultAddTailLoopInners{0}; // 多核累加尾核尾循环处理的inner数 | 71 | int64_t tailCoreMultAddTailLoopInners{0}; // 多核累加尾核尾循环处理的inner数 |
| 68 | 72 | ||
| 69 | int64_t multAddXBufferSize{0}; | 73 | int64_t multAddXBufferSize{0}; |
| 74 | + int64_t multAddIdsBufferSize{0}; | ||
| 70 | int64_t multAddYBufferSize{0}; | 75 | int64_t multAddYBufferSize{0}; |
| 71 | }; | 76 | }; |
| 72 | 77 | ||
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 20 | + | ||
| 19 | 21 | ||
| 20 | 22 | ||
| 21 | using namespace AscendC; | 23 | using namespace AscendC; |
| @@ -23,6 +25,7 @@ using namespace SegmentSum; | |||
| 23 | 25 | ||
| 24 | 26 | ||
| 25 | 27 | ||
| 28 | + | ||
| 26 | 29 | ||
| 27 | template <typename T> | 30 | template <typename T> |
| 28 | __aicore__ inline void invokeTemplateAllClear( | 31 | __aicore__ inline void invokeTemplateAllClear( |
| @@ -35,12 +38,34 @@ __aicore__ inline void invokeTemplateAllClear( | |||
| 35 | pipeIn.Reset(); | 38 | pipeIn.Reset(); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 41 | +template <typename T1, typename T2> | ||
| 42 | +__aicore__ inline void invokeTemplateSimdDeterm( | ||
| 43 | + GM_ADDR x, GM_ADDR segment_ids, GM_ADDR y, GM_ADDR workspace, const SegmentSumSimdTilingData* tilingData, AscendC::TPipe& pipeIn) | ||
| 44 | +{ | ||
| 45 | + SegmentSumSimdDeterm<T1, T2> op; | ||
| 46 | + op.Init(x, segment_ids, y, workspace, pipeIn, tilingData); | ||
| 47 | + op.Process(); | ||
| 48 | + SyncAll(); | ||
| 49 | + pipeIn.Reset(); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +template <typename T1, typename T2> | ||
| 53 | +__aicore__ inline void invokeTemplateMultiCoreAdd( | ||
| 54 | + GM_ADDR y, GM_ADDR workspace, const SegmentSumSimdTilingData* tilingData, AscendC::TPipe& pipeIn) | ||
| 55 | +{ | ||
| 56 | + SegmentSumMultiCoreAdd<T1, T2> op; | ||
| 57 | + op.Init(y, workspace, pipeIn, tilingData); | ||
| 58 | + op.Process(); | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | + | ||
| 38 | extern "C" __global__ __aicore__ void segment_sum(GM_ADDR x, GM_ADDR segment_ids, | 62 | extern "C" __global__ __aicore__ void segment_sum(GM_ADDR x, GM_ADDR segment_ids, |
| 39 | GM_ADDR output, GM_ADDR workspace, GM_ADDR tiling) | 63 | GM_ADDR output, GM_ADDR workspace, GM_ADDR tiling) |
| 40 | { | 64 | { |
| 41 | REGISTER_TILING_DEFAULT(SegmentSumTilingData); | 65 | REGISTER_TILING_DEFAULT(SegmentSumTilingData); |
| 42 | REGISTER_TILING_FOR_TILINGKEY("TILING_KEY_VAR == 1000", SegmentSumSimtTilingData); | 66 | REGISTER_TILING_FOR_TILINGKEY("TILING_KEY_VAR == 1000", SegmentSumSimtTilingData); |
| 43 | REGISTER_TILING_FOR_TILINGKEY("TILING_KEY_VAR == 2000", SegmentSumSimdTilingData); | 67 | REGISTER_TILING_FOR_TILINGKEY("TILING_KEY_VAR == 2000", SegmentSumSimdTilingData); |
| 68 | + REGISTER_TILING_FOR_TILINGKEY("TILING_KEY_VAR == 2002", SegmentSumSimdTilingData); | ||
| 44 | 69 | ||
| 45 | TPipe pipe; | 70 | TPipe pipe; |
| 46 | KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_MIX_AIV_1_0); | 71 | KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_MIX_AIV_1_0); |
| @@ -48,15 +73,20 @@ extern "C" __global__ __aicore__ void segment_sum(GM_ADDR x, GM_ADDR segment_ids | |||
| 48 | GET_TILING_DATA_WITH_STRUCT(SegmentSumSimtTilingData, simtTilingData, tiling); | 73 | GET_TILING_DATA_WITH_STRUCT(SegmentSumSimtTilingData, simtTilingData, tiling); |
| 49 | const SegmentSumSimtTilingData* __restrict tilingData = &simtTilingData; | 74 | const SegmentSumSimtTilingData* __restrict tilingData = &simtTilingData; |
| 50 | SegmentSumSimt<DTYPE_X, DTYPE_SEGMENT_IDS> op(tilingData, &pipe); | 75 | SegmentSumSimt<DTYPE_X, DTYPE_SEGMENT_IDS> op(tilingData, &pipe); |
| 51 | - op.Init(x, segment_ids, output); | 76 | + op.Init(x, segment_ids, output, workspace); |
| 52 | op.Process(); | 77 | op.Process(); |
| 53 | } else if (TILING_KEY_IS(SIMD_ATOMIC_SUPPORT_TILING_KEY)) { | 78 | } else if (TILING_KEY_IS(SIMD_ATOMIC_SUPPORT_TILING_KEY)) { |
| 54 | GET_TILING_DATA_WITH_STRUCT(SegmentSumSimdTilingData, tilingData, tiling); | 79 | GET_TILING_DATA_WITH_STRUCT(SegmentSumSimdTilingData, tilingData, tiling); |
| 55 | if constexpr (!(std::is_same_v<DTYPE_X, uint32_t> || std::is_same_v<DTYPE_X, uint64_t> || std::is_same_v<DTYPE_X, int64_t>)) { | 80 | if constexpr (!(std::is_same_v<DTYPE_X, uint32_t> || std::is_same_v<DTYPE_X, uint64_t> || std::is_same_v<DTYPE_X, int64_t>)) { |
| 56 | invokeTemplateAllClear<DTYPE_X>(output, &tilingData, pipe); | 81 | invokeTemplateAllClear<DTYPE_X>(output, &tilingData, pipe); |
| 57 | SegmentSumSimd<DTYPE_X, DTYPE_SEGMENT_IDS> op; | 82 | SegmentSumSimd<DTYPE_X, DTYPE_SEGMENT_IDS> op; |
| 58 | - op.Init(x, segment_ids, output, workspace, pipe, &tilingData); | 83 | + op.Init(x, segment_ids, output, pipe, &tilingData); |
| 59 | op.Process(); | 84 | op.Process(); |
| 60 | } | 85 | } |
| 86 | + } else if (TILING_KEY_IS(SIMD_DETERM_TILING_KEY)) { | ||
| 87 | + GET_TILING_DATA_WITH_STRUCT(SegmentSumSimdTilingData, tilingData, tiling); | ||
| 88 | + invokeTemplateAllClear<DTYPE_X>(output, &tilingData, pipe); | ||
| 89 | + invokeTemplateSimdDeterm<DTYPE_X, DTYPE_SEGMENT_IDS>(x, segment_ids, output, workspace, &tilingData, pipe); | ||
| 90 | + invokeTemplateMultiCoreAdd<DTYPE_X, DTYPE_SEGMENT_IDS>(output, workspace, &tilingData, pipe); | ||
| 61 | } | 91 | } |
| 62 | } | 92 | } |


代码结构与可维护性: 变量名 'tailCoreOutterNum_' 存在拼写错误。'Outter' 应为 'Outer'。该拼写错误与同一类中的其他变量名(如 'normalCoreOutterNum_')不一致,且与常见的 'inner'/'outer' 命名惯例不符。这种不一致性会降低代码的可读性和可维护性,可能导致开发者在理解变量含义时产生困惑。
问题类型: 代码结构与可维护性 文件路径:
index/segment_sum/op_host/arch35/segment_sum_simd_tiling.h行号: 61 问题代码:修改建议:
此评论由代码审查工具自动生成