TSCATTER
Instruction Diagram
Introduction
TSCATTER provides two operation modes:
- Index-based scatter: Uses element-wise row indices to scatter the rows of the source tile into the destination tile.
- Mask scatter: Scatters source elements to destination positions according to a mask pattern, interleaving zero values between elements. It supports two modes: row-wise scatter (
SCATTER_ROW) and column-wise scatter (SCATTER_COL).
Mathematical Semantics
Index-based Scatter
For each source element (i, j), writes:
If multiple elements map to the same destination position, the final value is implementation-defined (in the current implementation, the last writer wins).
Mask Scatter
For mask mode P, the source elements are scattered and interleaved with zero values. The scatter direction is controlled by ScatterAxis:
SCATTER_ROW (Default)
Scatters along the column direction and expands the column dimension:
Where:
DstTileData::ValidCol=SrcTileData::ValidCol× expansion multipleDstTileData::ValidRow=SrcTileData::ValidRow
SCATTER_COL
Scatters along the row direction and expands the row dimension:
Where:
DstTileData::ValidRow=SrcTileData::ValidRow× expansion multipleDstTileData::ValidCol=SrcTileData::ValidCol
Expansion Multiple
P1010orP0101: expansion multiple = 2P0001,P0010,P0100,P1000: expansion multiple = 4P1111: expansion multiple = 1 (equivalent toTMOV)
Assembly Syntax
Synchronous form:
%dst = tscatter %src, %idx : !pto.tile<...>, !pto.tile<...> -> !pto.tile<...>AS Level 1 (SSA)
%dst = pto.tscatter %src, %idx : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>AS Level 2 (DPS)
pto.tscatter ins(%src, %idx : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)C++ Built-in APIs
Declared in include/pto/common/pto_instr.hpp:
The public include header is
<pto/pto-inst.hpp>, and the internal declaration is located inpto/common/pto_instr.hpp.
Index-based Scatter
template <typename TileDataD, typename TileDataS, typename TileDataI, typename... WaitEvents>
PTO_INST RecordEvent TSCATTER(TileDataD& dst, TileDataS& src, TileDataI& indexes, WaitEvents&... events);Mask Scatter
template <MaskPattern maskPattern = MaskPattern::P1111, auto ScatterType = ScatterAxis::SCATTER_ROW,
typename DstTileData, typename SrcTileData, typename... WaitEvents>
PTO_INST RecordEvent TSCATTER(DstTileData& dst, SrcTileData& src, WaitEvents&... events);MaskPattern Enum
Defined in include/pto/common/type.hpp:
| Value | Mode | Description | Expansion Multiple |
|---|---|---|---|
P0101 | 01010101... | Takes the first of every two elements. | ×2 |
P1010 | 10101010... | Takes the second of every two elements. | ×2 |
P0001 | 00010001... | Takes the first of every four elements. | ×4 |
P0010 | 00100010... | Takes the second of every four elements. | ×4 |
P0100 | 01000100... | Takes the third of every four elements. | ×4 |
P1000 | 10001000... | Takes the fourth of every four elements. | ×4 |
P1111 | 11111111... | Takes all elements (equivalent to TMOV). | ×1 |
ScatterAxis Enum
Defined in include/pto/common/type.hpp:
| Value | Description |
|---|---|
SCATTER_ROW | Scatters along the column direction, and expands the column dimension (default). |
SCATTER_COL | Scatters along the row direction, and expands the row dimension. |
Constraints
Index-based Scatter
- Implementation check (Atlas A2/A3 training products/Atlas A2/A3 inference products):
TileDataD::Loc,TileDataS::Loc, andTileDataI::Locmust beTileType::Vec.TileDataD::DTypeandTileDataS::DTypemust be one of the following:int32_t,int16_t,int8_t,half,float16_t,float32_t,uint32_t,uint16_t,uint8_t,bfloat16_t.TileDataI::DTypemust be one of the following:int16_t,int32_t,uint16_t, oruint32_t.- No boundary check is performed on the
indexesvalues. - Statically valid boundary:
TileDataD::ValidRow <= TileDataD::Rows,TileDataD::ValidCol <= TileDataD::Cols,TileDataS::ValidRow <= TileDataS::Rows,TileDataS::ValidCol <= TileDataS::Cols,TileDataI::ValidRow <= TileDataI::Rows,TileDataI::ValidCol <= TileDataI::Cols. TileDataD::DTypeandTileDataS::DTypemust be the same.- When the size of
TileDataD::DTypeis 4 bytes, the size ofTileDataI::DTypemust be 4 bytes. - When the size of
TileDataD::DTypeis 2 bytes, the size ofTileDataI::DTypemust be 2 bytes. - When the size of
TileDataD::DTypeis 1 byte, the size ofTileDataI::DTypemust be 2 bytes.
- Implementation check (Ascend 950PR/Ascend 950DT):
TileDataD::Loc,TileDataS::Loc, andTileDataI::Locmust beTileType::Vec.TileDataD::DTypeandTileDataS::DTypemust be one of the following:int32_t,int16_t,int8_t,half,float16_t,float32_t,uint32_t,uint16_t,uint8_t,bfloat16_t.TileDataI::DTypemust be one of the following:int16_t,int32_t,uint16_t, oruint32_t.- No boundary check is performed on the
indexesvalues. - Statical valid boundary:
TileDataD::ValidRow <= TileDataD::Rows,TileDataD::ValidCol <= TileDataD::Cols,TileDataS::ValidRow <= TileDataS::Rows,TileDataS::ValidCol <= TileDataS::Cols,TileDataI::ValidRow <= TileDataI::Rows,TileDataI::ValidCol <= TileDataI::Cols. TileDataD::DTypeandTileDataS::DTypemust be the same.- When the size of
TileDataD::DTypeis 4 bytes, the size ofTileDataI::DTypemust be 4 bytes. - When the size of
TileDataD::DTypeis 2 bytes, the size ofTileDataI::DTypemust be 2 bytes. - When the size of
TileDataD::DTypeis 1 byte, the size ofTileDataI::DTypemust be 2 bytes.
Mask Scatter
- Implementation check (Atlas A2/A3 training products/Atlas A2/A3 inference products):
DstTileData::LocandSrcTileData::Locmust beTileType::Vec.DstTileData::DTypeandSrcTileData::DTypemust be one of the following:int32_t,int16_t,int8_t,half,float16_t,float32_t,uint32_t,uint16_t,uint8_t,bfloat16_t.DstTileData::DTypeandSrcTileData::DTypemust be the same.maskPatternmust be within the range fromP0101toP1111.- Statical valid boundary:
DstTileData::ValidCol <= DstTileData::Cols,SrcTileData::ValidCol <= SrcTileData::Cols,DstTileData::ValidRow <= DstTileData::Rows,SrcTileData::ValidRow <= SrcTileData::Rows. - The
P1111mode is equivalent toTMOV: it requiresvalidRowandvalidColto match respectively, and is implemented internally throughTMOV_IMPL.
- Implementation check (Ascend 950PR/Ascend 950DT):
DstTileData::LocandSrcTileData::Locmust beTileType::Vec.DstTileData::DTypeandSrcTileData::DTypemust be one of the following:int32_t,int16_t,int8_t,half,float16_t,float32_t,uint32_t,uint16_t,uint8_t,bfloat16_t.DstTileData::DTypeandSrcTileData::DTypemust be the same.maskPatternmust be within the range fromP0101toP1111.- Statical valid boundary:
DstTileData::ValidRow <= DstTileData::Rows,DstTileData::ValidCol <= DstTileData::Cols,SrcTileData::ValidRow <= SrcTileData::Rows,SrcTileData::ValidCol <= SrcTileData::Cols. - Runtime assertions for
SCATTER_ROWmode:SrcTileData::ValidRowmust be equal toDstTileData::ValidRow.SrcTileData::ValidColmust be equal toDstTileData::ValidCol × expansion multiple, where the expansion multiple depends on the mask mode (1 for P1111, 2 for P1010/P0101, 4 for P0001/P0010/P0100/P1000).
- Runtime assertions for
SCATTER_COLmode:SrcTileData::ValidColmust be equal toDstTileData::ValidCol.SrcTileData::ValidRowmust be equal toDstTileData::ValidRow × expansion multiple, where the expansion multiple depends on the mask mode (1 for P1111, 2 for P1010/P0101, 4 for P0001/P0010/P0100/P1000).
Important Notes
Warning: Before performing the scatter operation, the destination tile buffer is completely initialized to 0 (the entire tile size
Rows × Cols), not limited byValidRowandValidCol. This means:
- The entire UB buffer allocated to
dstTileis written with zero values.- Elements outside the
ValidRow/ValidColrange are also zero after the operation.- Ensure that the UB buffer of the destination tile does not overlap with other active data.
Examples
Index Scatter (Automatic)
#include <pto/pto-inst.hpp>
using namespace pto;
void example_auto() {
using TileT = Tile<TileType::Vec, float, 16, 16>;
using IdxT = Tile<TileType::Vec, uint16_t, 16, 16>;
TileT src, dst;
IdxT idx;
TSCATTER(dst, src, idx);
}Index Scatter (Manual)
#include <pto/pto-inst.hpp>
using namespace pto;
void example_manual() {
using TileT = Tile<TileType::Vec, float, 16, 16>;
using IdxT = Tile<TileType::Vec, uint16_t, 16, 16>;
TileT src, dst;
IdxT idx;
TASSIGN(src, 0x1000);
TASSIGN(dst, 0x2000);
TASSIGN(idx, 0x3000);
TSCATTER(dst, src, idx);
}Mask Scatter (Automatic)
#include <pto/pto-inst.hpp>
using namespace pto;
void example_mask_auto() {
// P1010: destination size = source size × 2.
using SrcTileT = Tile<TileType::Vec, half, 16, 64>;
using DstTileT = Tile<TileType::Vec, half, 16, 128>;
SrcTileT src;
DstTileT dst;
TSCATTER<MaskPattern::P1010>(dst, src);
}
void example_mask_p1000() {
// P1000: destination size = source size × 4.
using SrcTileT = Tile<TileType::Vec, float, 16, 64>;
using DstTileT = Tile<TileType::Vec, float, 16, 256>;
SrcTileT src;
DstTileT dst;
TSCATTER<MaskPattern::P1000>(dst, src);
}
void example_mask_scatter_col() {
// SCATTER_COL: scatter along the row direction, expand the row dimension.
// P1010: destination row count = source row count × 2.
using SrcTileT = Tile<TileType::Vec, half, 64, 16>;
using DstTileT = Tile<TileType::Vec, half, 128, 16>;
SrcTileT src;
DstTileT dst;
TSCATTER<MaskPattern::P1010, ScatterAxis::SCATTER_COL>(dst, src);
}Mask Scatter (Manual)
#include <pto/pto-inst.hpp>
using namespace pto;
void example_mask_manual() {
using SrcTileT = Tile<TileType::Vec, half, 16, 64>;
using DstTileT = Tile<TileType::Vec, half, 16, 128>;
SrcTileT src;
DstTileT dst;
TASSIGN(src, 0x1000);
TASSIGN(dst, 0x2000);
TSCATTER<MaskPattern::P1010>(dst, src);
}
void example_mask_manual_scatter_col() {
// SCATTER_COL manual binding mode
using SrcTileT = Tile<TileType::Vec, half, 64, 16>;
using DstTileT = Tile<TileType::Vec, half, 128, 16>;
SrcTileT src;
DstTileT dst;
TASSIGN(src, 0x1000);
TASSIGN(dst, 0x2000);
TSCATTER<MaskPattern::P1010, ScatterAxis::SCATTER_COL>(dst, src);
}ASM Examples
Automatic Mode
# Automatic mode: the compiler/runtime handles resource placement and scheduling.
%dst = pto.tscatter %src, %idx : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>Manual Mode
# Manual mode: explicitly bind resources first, then issue the instruction.
# Optional (when the instruction contains tile operands):
# pto.tassign %arg0, @tile(0x1000)
# pto.tassign %arg1, @tile(0x2000)
%dst = pto.tscatter %src, %idx : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>PTO Assembly Form
%dst = tscatter %src, %idx : !pto.tile<...>, !pto.tile<...> -> !pto.tile<...>
# AS Level 2 (DPS)
pto.tscatter ins(%src, %idx : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)