pto.tassign¶
pto.tassign is part of the Sync And Config instruction set.
Summary¶
Bind a Tile object to an on-chip physical address. In Manual mode, this is how the author controls which tile buffer holds which logical tile variable.
Mechanism¶
TASSIGN maps a tile variable to a physical storage address within the tile buffer space (UB, L0A, L0B, L0C, etc.). The mapping is immediate and persists until the tile is rebound or the program ends.
Without TASSIGN, the compiler/runtime assigns tile buffers automatically (Auto mode). With TASSIGN, the author overrides this assignment for Manual mode code.
The physical address is interpreted by the tile buffer controller on the AI Core. On A2/A3, physical addresses are byte offsets within the declared memory space (UB, L0A, L0B, L0C, Bias, or FBuffer) and the controller routes each access to the appropriate physical buffer based on the address range. On A5, physical addresses follow the same byte-offset model but the address space may be larger (e.g., 256 KB UB vs. 192 KB on A2/A3); the controller similarly routes based on declared capacity and alignment boundaries. On the CPU simulator, addresses are validated against the same logical capacity/alignment model but resolve to heap allocations with no hardware routing.
Syntax¶
tassign %tile, %addr : !pto.tile<...>, index
AS Level 1 (SSA)¶
pto.tassign %tile, %addr : !pto.tile<...>, dtype
AS Level 2 (DPS)¶
pto.tassign ins(%tile, %addr : !pto.tile_buf<...>, dtype)
C++ Intrinsic¶
Declared in include/pto/common/pto_instr.hpp.
Form 1: Runtime address¶
template <typename T, typename AddrType>
PTO_INST void TASSIGN(T& obj, AddrType addr);
Binds obj to the on-chip address addr. The address value is interpreted at runtime; no compile-time bounds checking is performed.
Form 2: Compile-time address (with static bounds check)¶
template <std::size_t Addr, typename T>
PTO_INST void TASSIGN(T& obj);
Binds obj to the on-chip address Addr. Because Addr is a non-type template parameter, the compiler performs static bounds checks at compile time:
| Check | Condition | Error ID | Error Message |
|---|---|---|---|
| Memory space exists | capacity > 0 |
SA-0351 | Memory space is not available on this architecture. |
| Tile fits in memory | tile_size <= capacity |
SA-0352 | Tile storage size exceeds memory space capacity. |
| Address in bounds | Addr + tile_size <= capacity |
SA-0353 | addr + tile_size exceeds memory space capacity (out of bounds). |
| Address aligned | Addr % alignment == 0 |
SA-0354 | addr is not properly aligned for the target memory space. |
The memory space, capacity, and alignment are determined from the tile's TileType:
| TileType | Buffer | Capacity (A2A3) | Capacity (A5) | Capacity (Kirin9030) | Capacity (KirinX90) | Alignment |
|---|---|---|---|---|---|---|
| Vec | UB | 192 KB | 256 KB | 128 KB | 128 KB | 32 B |
| Mat | L1 | 512 KB | 512 KB | 512 KB | 1024 KB | 32 B |
| Left | L0A | 64 KB | 64 KB | 32 KB | 64 KB | 32 B |
| Right | L0B | 64 KB | 64 KB | 32 KB | 64 KB | 32 B |
| Acc | L0C | 128 KB | 256 KB | 64 KB | 128 KB | 32 B |
| Bias | Bias | 1 KB | 4 KB | 1 KB | 1 KB | 32 B |
| Scaling | FBuffer | 2 KB | 4 KB | 7 KB | 6 KB | 32 B |
| ScaleLeft | L0A | N/A | 4 KB | N/A | N/A | 32 B |
| ScaleRight | L0B | N/A | 4 KB | N/A | N/A | 32 B |
Capacities can be overridden at build time via -D flags (e.g., -DPTO_UBUF_SIZE_BYTES=262144). See include/pto/common/buffer_limits.hpp.
Form 2 is only available for Tile and ConvTile types. For GlobalTensor, use Form 1.
Inputs¶
| Operand | Description |
|---|---|
tile |
The tile object to bind |
addr |
The on-chip address to bind (runtime value or compile-time constant) |
Expected Outputs¶
None. The binding takes effect immediately; subsequent tile operations on tile use the bound physical address.
Side Effects¶
Binds the tile variable to a physical address. Using the same physical address for two non-alias tiles simultaneously produces undefined results.
Constraints¶
Constraints
- Two non-alias tiles must not use the same physical address without an intervening
TSYNC. - Configuration state must only be used where later instructions document the dependency.
- Programs must not treat manual placement as a portable substitute for legal PTO behavior.
Exceptions¶
Exceptions
- In Auto mode,
TASSIGN(tile, addr)is a no-op because the compiler/runtime manages placement. - If
objis aGlobalTensor,addrmust be a pointer type matchingGlobalTensor::DType. - Using
TASSIGNwith an out-of-bounds address triggers a compile-time error (Form 2) or undefined behavior (Form 1).
Examples¶
Runtime address¶
#include <pto/pto-inst.hpp>
using namespace pto;
void example() {
using TileT = Tile<TileType::Vec, float, 16, 16>;
TileT a, b, c;
TASSIGN(a, 0x1000);
TASSIGN(b, 0x2000);
TASSIGN(c, 0x3000);
TADD(c, a, b);
}
Compile-time address (with static bounds check)¶
#include <pto/pto-inst.hpp>
using namespace pto;
void example() {
using TileT = Tile<TileType::Vec, float, 16, 16>;
TileT a, b, c;
TASSIGN<0x0000>(a); // OK: 0 + 1024 <= 192KB
TASSIGN<0x0400>(b); // OK: 0x0400 + 1024 <= 192KB
TASSIGN<0x0800>(c); // OK: 0x0800 + 1024 <= 192KB
TADD(c, a, b);
}
Compile-time errors for out-of-bounds placement:
// Compile error: tile size exceeds buffer capacity
void bad1() {
using BigTile = Tile<TileType::Vec, float, 256, 256>; // 256KB
BigTile t;
TASSIGN<0x0>(t); // SA-0352: exceeds 192KB on A2A3
}
// Compile error: address + tile size exceeds capacity
void bad2() {
using TileT = Tile<TileType::Vec, float, 128, 128>; // 64KB
TileT t;
TASSIGN<0x20001>(t); // SA-0353: 0x20001 + 64KB > 192KB
}
Ping-pong L0 buffer allocation¶
void pingpong() {
using L0ATile = TileLeft<half, 64, 128>;
using L0BTile = TileRight<half, 128, 64>;
L0ATile a0, a1;
L0BTile b0, b1;
TASSIGN<0x0000>(a0); // L0A ping
TASSIGN<0x8000>(a1); // L0A pong
TASSIGN<0x0000>(b0); // L0B ping (separate physical memory)
TASSIGN<0x8000>(b1); // L0B pong
}
See Also¶
- Instruction set overview: Sync And Config
- Previous op in instruction set: pto.tsync
- Next op in instruction set: pto.sethf32mode