TPUT
Introduction
Remote write operation: writes local data to the memory of a remote NPU. The data is transferred through a UB tile as an intermediate staging buffer.
When the GlobalTensor exceeds the UB tile capacity, TPUT automatically performs 2D sliding — tiling along rows (DIM_3) and columns (DIM_4) to fit the tile, and traverses all outer dimensions (DIM_0, DIM_1, DIM_2).
Mathematical Semantics
For each element (i, j) in the valid region:
Data flow: srcGlobalData (local GM) → stagingTileData (UB) → dstGlobalData (remote GM)
Assembly Syntax
Synchronous form:
tput %dst_remote, %src_local : (!pto.memref<...>, !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.
C++ Built-in APIs
Declared in include/pto/comm/pto_comm_inst.hpp
Single Tile (Automatic Tiling)
template <AtomicType atomicType = AtomicType::AtomicNone,
typename GlobalDstData, typename GlobalSrcData, typename TileData, typename... WaitEvents>
PTO_INST RecordEvent TPUT(GlobalDstData &dstGlobalData, GlobalSrcData &srcGlobalData,
TileData &stagingTileData, WaitEvents&... events);Ping-Pong Double Buffering
Two temporary tiles are used to overlap the TLOAD and TSTORE of adjacent blocks, hiding the DMA transfer latency.
template <AtomicType atomicType = AtomicType::AtomicNone,
typename GlobalDstData, typename GlobalSrcData, typename TileData, typename... WaitEvents>
PTO_INST RecordEvent TPUT(GlobalDstData &dstGlobalData, GlobalSrcData &srcGlobalData,
TileData &pingTile, TileData &pongTile, WaitEvents&... events);Runtime Atomic Type
template <typename GlobalDstData, typename GlobalSrcData, typename TileData, typename... WaitEvents>
PTO_INST RecordEvent TPUT(GlobalDstData &dstGlobalData, GlobalSrcData &srcGlobalData,
TileData &stagingTileData, AtomicType atomicType, WaitEvents&... events);Constraints
- Type constraints:
GlobalSrcData::RawDTypemust be equal toGlobalDstData::RawDType.TileData::DTypemust be equal toGlobalSrcData::RawDType.GlobalSrcData::layoutmust be equal toGlobalDstData::layout.
- Memory constraints:
dstGlobalDatamust point to a remote address (the destination NPU).srcGlobalDatamust point to local memory (the current NPU).stagingTileData/pingTile/pongTilemust be pre-allocated in the Unified Buffer.
- Valid region:
- The transfer size is determined by the shape of the
GlobalTensor(automatically tiled to fit the tile).
- The transfer size is determined by the shape of the
- Atomic operations:
atomicTypesupportsAtomicNoneandAtomicAdd.
- Ping-pong constraints:
pingTileandpongTilemust have the same type and dimensions.- They must be located at non-overlapping UB offsets.
Examples
Basic Usage
#include <pto/comm/pto_comm_inst.hpp>
#include <pto/pto-inst.hpp>
using namespace pto;
template <typename T>
void example_tput(__gm__ T* local_data, __gm__ T* remote_addr) {
using TileT = Tile<TileType::Vec, T, 16, 16>;
using GShape = Shape<1, 1, 1, 16, 16>;
using GStride = BaseShape2D<T, 16, 16, Layout::ND>;
using GTensor = GlobalTensor<T, GShape, GStride, Layout::ND>;
GTensor srcG(local_data);
GTensor dstG(remote_addr);
TileT stagingTile;
TASSIGN(stagingTile, 0);
// Basic remote write.
comm::TPUT(dstG, srcG, stagingTile);
// Remote write with atomic addition.
comm::TPUT<AtomicType::AtomicAdd>(dstG, srcG, stagingTile);
}Ping-Pong Double Buffering
constexpr size_t tileUBBytes = ((64 * 64 * sizeof(float) + 1023) / 1024) * 1024;
TileT pingTile(64, 64);
TileT pongTile(64, 64);
TASSIGN(pingTile, 0);
TASSIGN(pongTile, tileUBBytes); // Non-overlapping UB region.
// Overlap TLOAD[i+1] with TSTORE[i] to improve pipeline utilization.
comm::TPUT(dstG, srcG, pingTile, pongTile);Runtime Atomic Type
// Select the atomic type at runtime instead of using a compile-time template parameter.
comm::TPUT(dstG, srcG, stagingTile, AtomicType::AtomicAdd);