TGATHER
Instruction Diagram
Introduction
Gathers/Selects elements using an index tile or a compile-time mask pattern.
Mathematical Semantics
Index-based gather (conceptual definition):
Assume R = dst.GetValidRow() and C = dst.GetValidCol(). For 0 <= i < R and 0 <= j < C:
The exact index interpretation and boundary behavior are implementation-defined.
Mask-based gather is an implementation-defined selection/reduction operation controlled by pto::MaskPattern.
Assembly Syntax
Index-based gather:
%dst = tgather %src0, %indices : !pto.tile<...> -> !pto.tile<...>Mask-based gather:
%dst = tgather %src {maskPattern = #pto.mask_pattern<P0101>} : !pto.tile<...> -> !pto.tile<...>AS Level 1 (SSA)
%dst = pto.tgather %src, %indices : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>
%dst = pto.tgather %src {maskPattern = #pto.mask_pattern<P0101>}: !pto.tile<...> -> !pto.tile<...>AS Level 2 (DPS)
pto.tgather ins(%src, %indices : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)
pto.tgather ins(%src, {maskPattern = #pto.mask_pattern<P0101>} : !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 Gather
template <typename TileDataD, typename TileDataS0, typename TileDataS1, typename TileDataTmp, typename... WaitEvents>
PTO_INST RecordEvent TGATHER(TileDataD &dst, TileDataS0 &src0, TileDataS1 &src1, TileDataTmp &tmp, WaitEvents &... events);Mask-Based Gather
template <typename DstTileData, typename SrcTileData, MaskPattern maskPattern, typename... WaitEvents>
PTO_INST RecordEvent TGATHER(DstTileData &dst, SrcTileData &src, WaitEvents &... events);Comparison-Based Gather (TGather_cmp)
Gathers the indices of elements that satisfy the comparison condition with the per-row threshold scalar.
template <typename TileDataD, typename TileDataS, typename TileDataS1, typename TileDataC, typename TileDataTmp, CmpMode cmpMode, typename... WaitEvents>
PTO_INST RecordEvent TGATHER(TileDataD &dst, TileDataS &src0, TileDataS1 &k_value, TileDataC &cdst, TileDataTmp &tmp, uint32_t offset, WaitEvents &... events);For each row i of src0, compares each element src0[i, j] with the threshold k_value[i] using cmpMode (GT or EQ). The indices of matching elements are gathered into dst[i]. The number of matches per row is stored in cdst[i]. The offset parameter specifies the starting index value.
Comparison-Based Gather Constraints
- Atlas A2/A3 training products/Atlas A2/A3 inference products:
TileDataD::DTypemust beint32_toruint32_t.TileDataS::DTypemust befloat,half, orint32_t(EQ mode only).TileDataS1::DTypemust beint32_toruint32_t.cmpModemust beCmpMode::GTorCmpMode::EQ.
- Ascend 950PR/Ascend 950DT:
TileDataD::DTypemust beint32_toruint32_t.TileDataS::DTypemust beint16_t,uint16_t,int32_t,uint32_t,half, orfloat.TileDataS1::DTypemust beuint16_toruint32_t.cmpModemust beCmpMode::GTorCmpMode::EQ.
Constraints
- Index-based gather: implementation check (Atlas A2/A3 training products/Atlas A2/A3 inference products):
sizeof(DstTileData::DType)must be 2 or 4 bytes (b16/b32).sizeof(Src1TileData::DType)must be 4 bytes (b32:int32_t,uint32_t).DstTileData::DTypemust be the same type asSrc0TileData::DType.TmpTileData::DTypemust be the same type asSrc1TileData::DType.src1.GetValidCol() == TmpTileData::Colsandsrc1.GetValidRow() == TmpTileData::Rows.dst.GetValidCol() == DstTileData::Cols(contiguous destination storage).
- Index-based gather: implementation check (Ascend 950PR/Ascend 950DT):
DstTileData::DTypemust be a 1-, 2-, or 4-byte type and be one of the following:int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,half,bfloat16_t,float.- The type corresponding to
sizeof(Src1TileData::DType)must be one ofint16_t,uint16_t,int32_t, anduint32_t. DstTileData::DTypemust be the same type asSrc0TileData::DType.src1.GetValidCol() == Src1TileData::Colsanddst.GetValidCol() == DstTileData::Cols.
- Mask-based gather: implementation check (Atlas A2/A3 training products/Atlas A2/A3 inference products):
- The source element size must be
2or4bytes. SrcTileData::DType/DstTileData::DTypemust be one ofint16_t,uint16_t,int32_t,uint32_t,half,bfloat16_t, andfloat.dstandsrcmust both beTileType::Vecand row-major.sizeof(dst element) == sizeof(src element)anddst.GetValidCol() == DstTileData::Cols(contiguous destination storage).
- The source element size must be
- Mask-based gather: implementation check (Ascend 950PR/Ascend 950DT):
- The source element size must be
1,2, or4bytes. dstandsrcmust both beTileType::Vecand row-major.SrcTileData::DType/DstTileData::DTypemust be one ofint8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,half,bfloat16_t,float,float8_e4m3_t,float8_e5m2_t, andhifloat8_t.- The supported data types are restricted to the set defined by the destination (enforced through
static_assertin the implementation), andsizeof(dst element) == sizeof(src element),dst.GetValidCol() == DstTileData::Cols(contiguous destination storage).
- The source element size must be
- Comparison-based gather: implementation check: For the type and
cmpModeconstraints, see C++ Built-in APIs → Comparison-Based Gather Constraints. - Boundary/Validity:
- Index boundaries are not verified through explicit runtime assertions; the behavior of out-of-range indices is defined by the target.
- Temporary tile:
- Index-based gather (Atlas A2/A3 training products/Atlas A2/A3 inference products): The C++ API requires an explicit
tmptile.TileDataTmp::DTypemust be the same type asTileDataS1::DType(int32_toruint32_t).src1.GetValidRow() == TileDataTmp::Rowsandsrc1.GetValidCol() == TileDataTmp::Cols. The tmp tile is used to hold thevmulsintermediate results of the b16 source type forvgather; for the b32 source type, the results are written directly todst, but the API still requirestmp. - Index-based gather (Ascend 950PR/Ascend 950DT): The
tmptile is accepted but not used. The Ascend 950PR/Ascend 950DT hardware handles index-based gather without a temporary buffer. - Comparison-based gather (Atlas A2/A3 training products/Atlas A2/A3 inference products): The C++ API requires an explicit
tmptile, which serves as a merged scratch buffer for three internal regions:- cmpsTmp (comparison result bitmap): offset 0, stored as
uint8_t, size =TileDataTmp::Rows × TileDataTmp::Colsbytes. - indexTmp (index array): offset =
TileDataTmp::Rows × TileDataTmp::Cols × sizeof(uint8_t), stored asTileDataD::DType, size =TileDataS::Rows × TileDataS::Cols × sizeof(TileDataD::DType)bytes. - cvtTmp (converted k-value array): offset =
TileDataTmp::Rows × TileDataTmp::Cols × sizeof(uint8_t)+TileDataS::Rows × TileDataS::Cols × sizeof(TileDataD::DType), stored asTileDataS::DType, size =TileDataS::Rows × sizeof(TileDataS::DType)bytes. The minimum tmp size must satisfy:
- cmpsTmp (comparison result bitmap): offset 0, stored as
- Comparison-based gather (Ascend 950PR/Ascend 950DT): The
tmptile is accepted but not used. Ascend 950PR/Ascend 950DT hardware handles comparison-based gather without a temporary buffer.
- Index-based gather (Atlas A2/A3 training products/Atlas A2/A3 inference products): The C++ API requires an explicit
Examples
Automatic
#include <pto/pto-inst.hpp>
using namespace pto;
void example_auto() {
using SrcT = Tile<TileType::Vec, float, 16, 16>;
using IdxT = Tile<TileType::Vec, int32_t, 16, 16>;
using DstT = Tile<TileType::Vec, float, 16, 16>;
using TmpT = Tile<TileType::Vec, int32_t, 16, 16>;
SrcT src0;
IdxT idx;
DstT dst;
TmpT tmp;
TGATHER(dst, src0, idx, tmp);
}Manual
#include <pto/pto-inst.hpp>
using namespace pto;
void example_manual() {
using SrcT = Tile<TileType::Vec, float, 16, 16>;
using DstT = Tile<TileType::Vec, float, 1, 16>;
SrcT src;
DstT dst;
TASSIGN(src, 0x1000);
TASSIGN(dst, 0x2000);
TGATHER<DstT, SrcT, MaskPattern::P0101>(dst, src);
}ASM Examples
Automatic Mode
# Automatic mode: the compiler/runtime is responsible for resource placement and scheduling.
%dst = pto.tgather %src, %indices : (!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.tgather %src, %indices : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>PTO Assembly Form
%dst = pto.tgather %src, %indices : (!pto.tile<...>, !pto.tile<...>) -> !pto.tile<...>
# AS Level 2 (DPS)
pto.tgather ins(%src, %indices : !pto.tile_buf<...>, !pto.tile_buf<...>) outs(%dst : !pto.tile_buf<...>)