TPUSH¶
简介¶
将生产者 tile 推入 TPipe FIFO,用于 Cube-Vector 通信。
本文同时描述 TileData 重载和 GlobalData 提交重载。对于将 FIFO 条目暴露为 GlobalTensor 的 GM 槽位工作流,使用 TALLOC 分配槽位视图,通过普通内存指令写入槽位,然后使用 TPUSH(Pipe&, GlobalData&) 提交该槽位。
操作语义¶
对于 TileData 重载,TPUSH 执行三个步骤:
- 当
Pipe::shouldWaitFree(pipe.prod.tileIndex)为 true 时,等待 FIFO 空间。 - 将生产者 tile 存入当前 FIFO 槽位。
- 为消费者记录数据就绪同步。
生产者 tile 索引会在 FIFO 槽位地址计算完成后递增。
对于 GlobalData 重载,TPUSH 只为已经由 TALLOC 分配的槽位记录数据就绪同步。它本身不会存储 tile 数据。
C++ Intrinsic¶
声明位置: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);
Pipe 通常是 TPush.hpp 中声明的 TPipe:
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;
约束¶
- TileData 生产者:
TileProd::Loc必须是TileType::Acc或TileType::Vec。Direction::DIR_C2V:Cube 生产 accumulator tile,供 vector 消费。Direction::DIR_V2C:Vector 生产 vector tile,供 cube 消费。Direction::DIR_BOTH:同一个 pipe 类型同时支持 C2V 和 V2C 生产者。
- FIFO 槽位:
SlotSize必须足够容纳一个逻辑 FIFO 条目。SlotNum >= 1。Pipe::SyncPeriod由SlotNum派生:(SlotNum <= 2) ? SlotNum : SlotNum / 2。
- 分裂行为:
TileSplitAxis::TILE_NO_SPLIT:不应用子向量偏移。TileSplitAxis::TILE_UP_DOWN:向量子块映射到上下两个行半区。TileSplitAxis::TILE_LEFT_RIGHT:向量子块映射到左右两个列半区。
- 同步:
- 空闲空间等待是稀疏的,并由
Pipe::SyncPeriod控制。 - 每次
TPUSH都会发出数据就绪记录。
- 空闲空间等待是稀疏的,并由
- GlobalData 提交:
gmTensor必须是由TALLOC返回的 FIFO 槽位视图。- 调用
TPUSH(Pipe&, GlobalData&)之前,数据必须已经写入gmTensor。 TPUSH(Pipe&, GlobalData&)忽略 tensor 内容,只将 FIFO 槽位提交给消费者。
- Tile 类型支持:
- TPUSH/TPOP 支持的 Tile 类型:
TileType::Acc(累加器 Tile):Cube 核心使用,用于 C2V 方向通信。TileType::Vec(向量 Tile):Vector 核心使用,用于 V2C 方向通信。TileType::Ctrl(控制 Tile):Vector 核心使用,用于 V2C_CTRL 方向的控制信号通信。
- TPUSH/TPOP 支持的 Tile 类型:
示例¶
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 槽位提交¶
#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 形式示例¶
当前公开的汇编参考尚未为 TPUSH 定义稳定的 PTO-AS 写法。手写 CV FIFO 程序时请使用 C++ intrinsic 形式。