TPUSH¶
Introduction¶
Push a producer tile into a TPipe FIFO for Cube-Vector communication.
This page describes all TPUSH overloads for pushing data into a TPipe FIFO: the TileData overload with explicit TileSplitAxis, the simplified TileData overload (reversed parameters, no Split), the GlobalTensor overload, and the TConfig-based overload.
Operation Semantics¶
For the TileData flow:
TPUSH(Pipe&, TileData&, Split)stores the producer tile into the current FIFO slot and records data-ready synchronization for the consumer. The producer tile index is incremented after the slot address is computed.TPOP(Pipe&, TileData&, Split)waits for the producer's data-ready synchronization and loads the current FIFO slot into the consumer tile. The consumer tile index is incremented after the slot address is computed.TFREE(Pipe&, Split)releases FIFO slot space. On the A2A3 platform this interface is a no-op (TPOPalready performs free-space notification internally), while on the A5 platform it releases the FIFO slot space used byTPOP.
For the GlobalData flow:
TALLOC(Pipe&, GlobalData&)allocates a producer FIFO slot fromTPipeand exposes it as aGlobalTensorview. The producer can write data to the slot using instructions such asTSTORE.TPUSH(Pipe&, GlobalData&)records data-ready synchronization for a slot already allocated byTALLOC, committing the FIFO slot to the consumer. It does not store tile data by itself.TPOP(Pipe&, GlobalData&)waits for data-ready, assignsgmTensorto the current FIFO slot address, and increments the consumer tile index. It does not load data into a local tile and does not release the slot. The consumer can read data from the slot using instructions such asTLOAD.TFREE(Pipe&, GlobalData&)releases the FIFO slot view returned byTPOP(Pipe&, GlobalData&), notifying the producer that the slot space is free.
For the TConfig overload TPUSH(Pipe&, TileProd&, TConfig), the TConfig template parameter is used to configure fixpipe parameters for L0C→GM/UB.
C++ Intrinsic¶
Declared in include/pto/common/pto_instr.hpp:
template <typename Pipe, typename TileProd, TileSplitAxis Split,
std::enable_if_t<is_tile_data_v<TileProd>, int> = 0, typename... WaitEvents>
PTO_INST RecordEvent TPUSH(Pipe &pipe, TileProd &tile, WaitEvents &... events);
template <typename Pipe, typename GlobalData, TileSplitAxis Split,
std::enable_if_t<is_global_data_v<GlobalData>, int> = 0, typename... WaitEvents>
PTO_INST RecordEvent TPUSH(Pipe &pipe, GlobalData &gmTensor, WaitEvents &... events);
template <typename Pipe, typename TileProd, typename TConfig, typename... WaitEvents>
PTO_INST RecordEvent TPUSH(Pipe &pipe, TileProd &tile, WaitEvents &... events);
Pipe is typically an TPipe declared in TPush.hpp:
template <uint8_t FlagID, uint8_t DirType, uint32_t SlotSize, uint32_t SlotNum,
uint32_t LocalSlotNum = 2, bool IsNoSplit = false, bool EN_UNIT_FLAG = false>
struct TPipe;
Constraints¶
- TileData producer:
TileProd::Locmust beTileType::Acc,TileType::Vec, orTileType::Ctrl.Direction::DIR_C2V: Cube produces an accumulator tile for vector consumption.Direction::DIR_V2C: Vector produces a vector tile for cube consumption.Direction::DIR_BOTH: both C2V and V2C producers are supported by the same pipe type.
- FIFO slot:
SlotSizemust be large enough for one logical FIFO entry.SlotNum >= 1.
- A2A3 split behavior:
TileSplitAxis::TILE_NO_SPLIT: No sub-vector offset is applied. On A2A3, this mode requires AIV0 and AIV1 to participate in synchronization.TileSplitAxis::TILE_UP_DOWN: Vector subblocks map to row halves.TileSplitAxis::TILE_LEFT_RIGHT: Vector subblocks map to column halves.
- A5 split behavior:
TileSplitAxis::TILE_NO_SPLIT: No sub-vector offset is applied.TileSplitAxis::TILE_UP_DOWN: Data is split into row halves. For C2V direction (L0C→UB path), this mode only supports b32 data type, andvalidRowsmust be even (a multiple of 2); for V2C direction (UB→L1 path),validColsmust be a multiple of 32 bytes.TileSplitAxis::TILE_LEFT_RIGHT: Data is split into two column halves. For C2V direction (L0C→UB path), this mode only supports b32 data type, andvalidColsmust be a multiple of 32; for V2C direction (UB→L1 path),validColsmust be a multiple of 32 bytes.
- Simplified TileData overload:
TPUSH(TileData&, Pipe&)usesTileSplitAxis::TILE_NO_SPLITsemantics internally.TileData::Locmust beTileType::AccorTileType::Vec.
- TConfig overload:
TConfigis a configuration type that determines push behavior (implementation-defined).TileProd::Locmust beTileType::Acc,TileType::Vec, orTileType::Ctrl.
- Synchronization:
- Free-space waits are sparse and controlled by
Pipe::SyncPeriod. - Data-ready record is emitted for each
TPUSH.
- Free-space waits are sparse and controlled by
- GlobalData producer:
gmTensormust be a FIFO slot view returned byTALLOC.- Data must be written into
gmTensorbefore callingTPUSH(Pipe&, GlobalData&). TPUSH(Pipe&, GlobalData&)ignores the tensor contents and only commits the FIFO slot to the consumer.
- Tile Type Support:
- TPUSH/TPOP Supported Tile Types:
TileType::Acc(Accumulator Tile): Used by Cube core for C2V direction communication.TileType::Vec(Vector Tile): Used by Vector core for V2C direction communication.TileType::Ctrl(Control Tile): Used by Vector core for V2C_CTRL direction control signal transmission.
- TPUSH/TPOP Supported Tile Types:
Defining TConfig¶
The TConfig template parameter for the TPUSH(Pipe&, TileProd&, TConfig) overload is a configuration struct that controls fixpipe behavior during push. PTO provides the FixpipeParams struct for this purpose.
Declared in include/pto/common/fixpipe.hpp:
template <LayoutMode_t layoutMode = LayoutMode_t::NZ2ND,
QuantMode_t quantMode = QuantMode_t::NoQuant,
ReluPreMode reluMode = ReluPreMode::NoRelu,
STPhase phase = STPhase::Unspecified,
uint8_t subBlockId = 0,
AtomicType atomicT = AtomicType::AtomicNone,
ClipReluMode_t clipReluMode = ClipReluMode_t::NOCLIP_RELU,
bool isChannelSplit = false>
struct FixpipeParams {
static constexpr LayoutMode_t LayoutMode = layoutMode;
static constexpr QuantMode_t QuantPre = quantMode;
static constexpr ReluPreMode ReluMode = reluMode;
static constexpr STPhase Phase = phase;
static constexpr uint8_t SubBlockId = subBlockId;
static constexpr AtomicType AtomicT = atomicT;
static constexpr ClipReluMode_t ClipReluMode = clipReluMode;
static constexpr bool IsChannelSplit = isChannelSplit;
};
TConfig Fields¶
| Field | Type | Description |
|---|---|---|
LayoutMode |
LayoutMode_t |
Output data layout: NZ2NZ (NZ→NZ), NZ2ND (NZ→row-major), NZ2DN (NZ→column-major). Default: NZ2ND. |
QuantPre |
QuantMode_t |
Quantization/dequantization mode (defined in CANN). Controls the data type conversion during fixpipe push. Default: NoQuant. |
ReluMode |
ReluPreMode |
ReLU activation mode: NoRelu or NormalRelu. Default: NoRelu. |
Phase |
STPhase |
Store phase for unit-flag aware paths: Unspecified, Partial, or Final. Default: Unspecified. |
SubBlockId |
uint8_t |
Sub-block identifier for accumulator-to-vector move mode mapping (A5 only). Default: 0. |
AtomicT |
AtomicType |
Atomic operation type for GM store: AtomicNone or AtomicAdd. Default: AtomicNone. |
ClipReluMode |
ClipReluMode_t |
Clip ReLU mode: NOCLIP_RELU or CLIP_RELU. Default: NOCLIP_RELU. |
IsChannelSplit |
bool |
Whether channel split is enabled. Default: false. |
TConfig Usage Example¶
#include <pto/pto-inst.hpp>
using namespace pto;
template <typename T>
AICORE void example_tconfig_push(__gm__ void *fifoMem)
{
constexpr uint32_t M = 128;
constexpr uint32_t N = 128;
constexpr uint32_t FlagID = 0;
constexpr uint32_t FifoDepth = 2;
using Pipe = TPipe<FlagID, Direction::DIR_C2V, M * N * sizeof(T), FifoDepth>;
using AccTile = TileAcc<float, M, N, M, N>;
// Define TConfig: NZ→row-major layout, dequantize to half, with ReLU
using MyConfig = FixpipeParams<LayoutMode_t::NZ2ND, QuantMode_t::DEQF16, ReluPreMode::NormalRelu>;
Pipe pipe(fifoMem, 0x0, 0x0);
AccTile acc;
TASSIGN(acc, 0x0);
TPUSH<Pipe, AccTile, MyConfig>(pipe, acc);
}
Examples¶
C2V Accumulator Push¶
#include <pto/pto-inst.hpp>
using namespace pto;
template <typename T>
AICORE void example_c2v(__gm__ void *fifoMem)
{
constexpr uint32_t M = 128;
constexpr uint32_t N = 128;
constexpr uint32_t FlagID = 0;
constexpr uint32_t FifoDepth = 2;
using Pipe = TPipe<FlagID, Direction::DIR_C2V, M * N * sizeof(float), FifoDepth>;
using AccTile = TileAcc<float, M, N, M, N>;
Pipe pipe(fifoMem, 0x0, 0x0);
AccTile acc;
TASSIGN(acc, 0x0);
// Fill acc with a cube computation before pushing.
TPUSH<Pipe, AccTile, TileSplitAxis::TILE_NO_SPLIT>(pipe, acc);
}
V2C Vector Push¶
#include <pto/pto-inst.hpp>
using namespace pto;
template <typename T>
AICORE void example_v2c(__gm__ void *fifoMem)
{
constexpr uint32_t M = 128;
constexpr uint32_t N = 128;
constexpr uint32_t FlagID = 0;
constexpr uint32_t FifoDepth = 2;
using Pipe = TPipe<FlagID, Direction::DIR_V2C, M * N * sizeof(T), FifoDepth>;
using VecTile = Tile<TileType::Vec, T, M, N, BLayout::RowMajor, M, N>;
Pipe pipe(fifoMem, 0x0, 0x0);
VecTile tile;
TASSIGN(tile, 0x0);
TPUSH<Pipe, VecTile, TileSplitAxis::TILE_NO_SPLIT>(pipe, tile);
}
GlobalData Slot Commit¶
#include <pto/pto-inst.hpp>
using namespace pto;
template <typename T>
AICORE void example_globaldata(__gm__ void *fifoMem)
{
constexpr uint32_t M = 128;
constexpr uint32_t N = 128;
constexpr uint32_t FlagID = 0;
constexpr uint32_t FifoDepth = 2;
using Pipe = TPipe<FlagID, Direction::DIR_C2V, M * N * sizeof(T), FifoDepth>;
using SlotGlobal = GlobalTensor<T, Shape<1, 1, 1, M, N>, Stride<1, 1, 1, N, 1>>;
using VecTile = Tile<TileType::Vec, T, M, N, BLayout::RowMajor, M, N>;
Pipe pipe(fifoMem, 0x0, 0x0);
SlotGlobal slot;
VecTile tile;
TASSIGN(tile, 0x0);
TALLOC<Pipe, SlotGlobal, TileSplitAxis::TILE_NO_SPLIT>(pipe, slot);
TSTORE(slot, tile);
TPUSH<Pipe, SlotGlobal, TileSplitAxis::TILE_NO_SPLIT>(pipe, slot);
}
ASM Form Examples¶
The current public assembly reference does not define a stable PTO-AS spelling for TPUSH. Use the C++ intrinsic form for manual CV FIFO programming.
```