TBROADCAST
Introduction
Broadcasts data from the current NPU to all ranks in the parallel group. The calling NPU is the root node, and its data is copied to all other NPUs.
Only the root node needs to execute TBROADCAST. Non-root nodes only need to ensure that their destination buffers are allocated and writable during the operation. Calling TBROADCAST on a non-root node is undefined behavior.
Large tile support: When a GlobalTensor exceeds the Unified Buffer (UB) tile capacity in the row and/or column direction, the transfer is automatically tiled through 2D sliding.
Mathematical Semantics
After the operation completes:
Where is the total number of ranks and root is the calling NPU.
Assembly Syntax
Synchronous form:
tbroadcast %group, %src : (!pto.group<...>, !pto.memref<...>)During degradation, UB staging tiles are introduced for the GM→UB→GM data path. C++ built-in APIs require explicitly passing the stagingTileData (or pingTile/pongTile) operand.
Template Parameters
engine:CollEngine::AIV(default)CollEngine::CCU(Ascend 950PR/Ascend 950DT, NPU_ARCH 3510 only)
C++ Built-in APIs
Declared in include/pto/comm/pto_comm_inst.hpp:
// Basic broadcast (single staging tile)
template <CollEngine engine = CollEngine::AIV,
typename ParallelGroupType, typename GlobalSrcData, typename TileData, typename... Args>
PTO_INST RecordEvent TBROADCAST(ParallelGroupType ¶llelGroup, GlobalSrcData &srcGlobalData,
TileData &stagingTileData, Args&... args);
// Ping-pong broadcast (using two staging tiles for double buffering)
template <CollEngine engine = CollEngine::AIV,
typename ParallelGroupType, typename GlobalSrcData, typename TileData, typename... Args>
PTO_INST RecordEvent TBROADCAST(ParallelGroupType ¶llelGroup, GlobalSrcData &srcGlobalData,
TileData &pingTile, TileData &pongTile, Args&... args);When engine == CollEngine::CCU, the first variable parameter must be a CcuTriggerContext that contains the CKE slot virtual address and gate mask. The AIV kernel triggers the CKE gate, and the actual broadcast data path is executed on the CCU engine.
Constraints
- Type constraints:
ParallelGroup::value_type::RawDTypemust be equal toGlobalSrcData::RawDType.TileData::DTypemust be equal toGlobalSrcData::RawDType.
- Memory constraints:
srcGlobalDatamust point to local memory (the current NPU).stagingTileData(orpingTile/pongTile) must be pre-allocated in the UB.
- ParallelGroup constraints:
parallelGroup.tensors[k]must point to the destination buffer of rankk(the remote GM as seen from the root node's perspective).parallelGroup.GetRootIdx()identifies the calling NPU as the broadcast root node.- All target tensors are assumed to have the same shape and stride.
- Tiling mode constraints (when data exceeds a single UB tile):
- If
TileDatahas a staticValidRow,GetShape(DIM_3)must be divisible byValidRow. To support the case of fewer than one row, use a tile with aDYNAMICValidRow. - If
TileDatahas a staticValidCol,GetShape(DIM_4)must be divisible byValidCol. To support the case of fewer than one column, use a tile with aDYNAMICValidCol.
- If
CCU path: Unlike the AIV path (where only the root node calls
TBROADCAST), the CCU path requires all ranks to register and launch the CCU kernel through the host-sideHcclCcuKernelRegister/HcclCcuKernelLaunch. For a complete example, seetests/npu/a5/comm/st/testcase/tbroadcast_ccu/.
Examples
Basic Broadcast
#include <pto/comm/pto_comm_inst.hpp>
using namespace pto;
template <typename T, int ROWS, int COLS, int TILE_ROWS, int TILE_COLS, int NRANKS>
void broadcast(__gm__ T* group_addrs[NRANKS], __gm__ T* my_data, int my_rank) {
// The tile dimensions can differ from the tensor dimensions.
// The 2D sliding tiling path automatically tiles in both the row and column directions.
using TileT = Tile<TileType::Vec, T, TILE_ROWS, TILE_COLS, BLayout::RowMajor, -1, -1>;
using GTensor = GlobalTensor<T, Shape<1,1,1,ROWS,COLS>,
BaseShape2D<T, ROWS, COLS, Layout::ND>, Layout::ND>;
GTensor tensors[NRANKS];
for (int i = 0; i < NRANKS; ++i) {
tensors[i] = GTensor(group_addrs[i]);
}
comm::ParallelGroup<GTensor> group(tensors, NRANKS, my_rank);
GTensor srcG(my_data);
TileT stagingTile(TILE_ROWS, TILE_COLS);
// The current NPU broadcasts its own data to all other NPUs.
comm::TBROADCAST(group, srcG, stagingTile);
}Ping-Pong Broadcast (Double Buffering)
Uses two UB tiles to overlap the TLOAD of the next block with the TSTORE of the current block.
#include <pto/comm/pto_comm_inst.hpp>
using namespace pto;
template <typename T, int ROWS, int COLS, int TILE_ROWS, int TILE_COLS, int NRANKS>
void broadcast_pingpong(__gm__ T* group_addrs[NRANKS], __gm__ T* my_data, int my_rank) {
using TileT = Tile<TileType::Vec, T, TILE_ROWS, TILE_COLS, BLayout::RowMajor, -1, -1>;
using GPerRank = GlobalTensor<T, Shape<1,1,1,ROWS,COLS>,
BaseShape2D<T, ROWS, COLS, Layout::ND>, Layout::ND>;
GPerRank tensors[NRANKS];
for (int i = 0; i < NRANKS; ++i) {
tensors[i] = GPerRank(group_addrs[i]);
}
comm::ParallelGroup<GPerRank> group(tensors, NRANKS, my_rank);
GPerRank srcG(my_data);
TileT pingTile(TILE_ROWS, TILE_COLS);
TileT pongTile(TILE_ROWS, TILE_COLS);
// Ping-pong mode: overlap TLOAD and TSTORE to improve throughput.
comm::TBROADCAST(group, srcG, pingTile, pongTile);
}