Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.
BroadcastTo 算子在单轴广播场景(输入/输出经 MergeAxis 合并后维度为 1)下,原先走通用 tiling 路径(Tiling4BroadcastToAscendC),该路径针对多维场景设计,对单轴场景存在以下问题:
MergeAxis
Tiling4BroadcastToAscendC
[1] → [N]
torch.broadcast_to(torch.tensor([1.0]), (1000000,))
[1,1,1] → [535,535,536]
[1] → [153319760]
[N] → [N]
aclnnBroadcastTo
torch.broadcast_to
broadcast_to_impl
触发条件:在 Tiling4BroadcastTo 中,经 MergeAxis 合并后 outShape.GetDimNum() == 1 时进入 Tiling4SingleAxis。
Tiling4BroadcastTo
outShape.GetDimNum() == 1
Tiling4SingleAxis
Tiling 流程:
Tiling4BroadcastTo ├─ GetShapeInfo (获取输入输出 shape) ├─ MergeAxis (合并相同类型轴) ├─ IsSingleAxisBrcAfterMerge(outShape) ? │ ├─ YES → Tiling4SingleAxis │ └─ NO → Tiling4BroadcastToAscendC (通用路径)
Tiling4SingleAxis 逻辑:
isBrc = (inDim != outDim)
BUFFER_NUM_B=1
BUFFER_NUM_A=2
max(min(blockFactor, bufferSizeElements), minUbElements)
totalTiles = CeilDiv(totalOutElems, tileSize)
blockFactor
11006
11007
brcto::kSyncWorkSpaceSize
TilingData 结构:
struct SingleAxisBrcTilingData { uint64_t shapeSize; // 输出总元素个数 uint32_t tileSize; // 每块 tile 元素个数 uint32_t blockNum; // 使用核数 uint64_t blockFactor; // 主核 tile 块数, 尾核 blockFactor-1 };
模板类:BroadcastSingleAxis<T, IsBrc>,使用 LocalMemAllocator 静态 Tensor 编程 + Mutex 流水线同步。
BroadcastSingleAxis<T, IsBrc>
LocalMemAllocator
Mutex
A 轴(IsBrc=false):
流水线: MTE2(DataCopyPad搬入) → MTE3(DataCopyPad搬出) 同步: Mutex 双 ID 交替 (mutexId0_/mutexId1_), Ping/Pong Double Buffer for (i = 0; i < loopNum; i++) { curMutex = (i & 1) ? mutexId1_ : mutexId0_; curBuf = (i & 1) ? ubPong : ubPing; Lock<MTE2>(curMutex) → DataCopyPad(curBuf, inGM[offset]) → Unlock<MTE2>(curMutex) Lock<MTE3>(curMutex) → DataCopyPad(outGM[offset], curBuf) → Unlock<MTE3>(curMutex) } // MTE2[i+1] 与 MTE3[i] 并行 (不同 mutexId)
B 轴(IsBrc=true):
流水线: MTE2(DataCopyPad标量→scalarBuf) → V(Duplicate广播填充ubPing) → MTE3(循环搬出) 同步: Mutex 单 ID (mutexId0_), MTE2→V→MTE3 串行依赖 Init: ubPing = ubAlloc.Alloc<T>(tileSize) scalarBuf = ubAlloc.Alloc<T>(32/sizeof(T)) CopyDataInWithDMA: Lock<MTE2> → DataCopyPad(scalarBuf, inGM[0]) → Unlock<MTE2> Lock<V> → Duplicate(ubPing, scalarBuf, tileSize) → Unlock<V> Process: Lock<MTE3> → for (loopNum) DataCopyPad(outGM[offset], ubPing) → Unlock<MTE3>
Dispatch 逻辑(broadcast_to.h):
broadcast_to.h
if (TILING_KEY_IS(SINGLE_AXIS) || TILING_KEY_IS(SINGLE_AXIS_BRC)) { GET_TILING_DATA_PTR_WITH_STRUCT(SingleAxisBrcTilingData, saTilingData, tiling); if (TILING_KEY_IS(SINGLE_AXIS)) { BroadcastSingleAxis<DTYPE_X_, false> op; // A轴 } else { BroadcastSingleAxis<DTYPE_X_, true> op; // B轴 } op.Init(x, y, saTilingData); op.Process(); }
inDim == outDim
inDim == 1
Duplicate
[1,5] → [3,5]
tbe.broadcast
auto_schedule
💡 备注(选填)
/assign @tan_xin
Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.
一、背景信息 (必填)
BroadcastTo 算子在单轴广播场景(输入/输出经
MergeAxis合并后维度为 1)下,原先走通用 tiling 路径(Tiling4BroadcastToAscendC),该路径针对多维场景设计,对单轴场景存在以下问题:二、价值/作用 (必填)
[1] → [N](如torch.broadcast_to(torch.tensor([1.0]), (1000000,)))[1,1,1] → [535,535,536](经MergeAxis合并为[1] → [153319760])[N] → [N](A 轴,输入输出 shape 相同)三、设计方案 (必填)
3.1 使能方式
aclnnBroadcastToAPI 调用,host tiling 自动判断是否走单轴路径torch.broadcast_to触发broadcast_to_impl已暴露给其他算子(如 tile)使用,单轴路径自动生效3.2 总体设计
3.2.1 算子支持的数据类型
3.2.2 host 侧设计
触发条件:在
Tiling4BroadcastTo中,经MergeAxis合并后outShape.GetDimNum() == 1时进入Tiling4SingleAxis。Tiling 流程:
Tiling4SingleAxis 逻辑:
isBrc = (inDim != outDim),B 轴为标量广播,A 轴为纯拷贝BUFFER_NUM_B=1,可用全部 UB),A 轴双 buffer(BUFFER_NUM_A=2)max(min(blockFactor, bufferSizeElements), minUbElements),128B 对齐totalTiles = CeilDiv(totalOutElems, tileSize),按核数分配blockFactor,主核多 1 块11006(SINGLE_AXIS),B 轴11007(SINGLE_AXIS_BRC)brcto::kSyncWorkSpaceSize(16MB)TilingData 结构:
struct SingleAxisBrcTilingData { uint64_t shapeSize; // 输出总元素个数 uint32_t tileSize; // 每块 tile 元素个数 uint32_t blockNum; // 使用核数 uint64_t blockFactor; // 主核 tile 块数, 尾核 blockFactor-1 };3.2.3 kernel 侧设计
模板类:
BroadcastSingleAxis<T, IsBrc>,使用LocalMemAllocator静态 Tensor 编程 +Mutex流水线同步。A 轴(IsBrc=false):
B 轴(IsBrc=true):
Dispatch 逻辑(
broadcast_to.h):if (TILING_KEY_IS(SINGLE_AXIS) || TILING_KEY_IS(SINGLE_AXIS_BRC)) { GET_TILING_DATA_PTR_WITH_STRUCT(SingleAxisBrcTilingData, saTilingData, tiling); if (TILING_KEY_IS(SINGLE_AXIS)) { BroadcastSingleAxis<DTYPE_X_, false> op; // A轴 } else { BroadcastSingleAxis<DTYPE_X_, true> op; // B轴 } op.Init(x, y, saTilingData); op.Process(); }3.3 支持硬件
3.4 算子约束限制
MergeAxis合并后维度为 1 时走单轴路径,否则走通用多维路径inDim == outDim(纯拷贝),tileSize 需 128B 对齐inDim == 1(标量广播),Duplicate(tensor版) 要求 tileSize 128B 对齐[1,5] → [3,5],合并后维度 > 1,走通用路径)tbe.broadcast+auto_schedule)💡 备注(选填)